From 0ef7ca2145590c8b760cdc9a9aebe757c4d890d0 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Mon, 29 Aug 2022 13:17:26 -0700 Subject: [PATCH] refactor chroot call --- apps/wolfsshd/wolfsshd.c | 166 +++++++++++++++++---------------------- wolfssh/port.h | 1 + 2 files changed, 75 insertions(+), 92 deletions(-) diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index d92209db..8ed9cf63 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -280,27 +280,41 @@ static int SetupCTX(WOLFSSHD_CONFIG* conf, WOLFSSH_CTX** ctx) } +/* return 1 if set, 0 if not set and negative values on error */ +static int SetupChroot(WOLFSSHD_CONFIG* usrConf) +{ + int ret = 0; + char* chrootPath; + + /* check for chroot set */ + chrootPath = wolfSSHD_ConfigGetChroot(usrConf); + if (chrootPath != NULL) { + ret = 1; + wolfSSH_Log(WS_LOG_INFO, "[SSHD] chroot to path %s", chrootPath); + if (chroot(chrootPath) != 0) { + wolfSSH_Log(WS_LOG_ERROR, + "[SSHD] chroot failed to path %s", chrootPath); + ret = WS_FATAL_ERROR; + } + } + return ret; +} + + #ifdef WOLFSSH_SFTP #define TEST_SFTP_TIMEOUT 1 /* handle SFTP operations * returns 0 on success */ -static int SFTP_Subsystem(WOLFSSH* ssh, WOLFSSHD_CONNECTION* conn) +static int SFTP_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, + WPASSWD* pPasswd, WOLFSSHD_CONFIG* usrConf) { byte tmp[1]; int ret = WS_SUCCESS; int error = WS_SUCCESS; WS_SOCKET_T sockfd; int select_ret = 0; - const char *userName; - struct passwd *p_passwd; - - userName = wolfSSH_GetUsername(ssh); - if (userName == NULL) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure get user name"); - return WS_FATAL_ERROR; - } /* temporarily elevate permissions to get users information */ if (wolfSSHD_AuthRaisePermissions(conn->auth) != WS_SUCCESS) { @@ -308,18 +322,32 @@ static int SFTP_Subsystem(WOLFSSH* ssh, WOLFSSHD_CONNECTION* conn) return WS_FATAL_ERROR; } - p_passwd = getpwnam((const char *)userName); - if (p_passwd == NULL) { - if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { - /* stop everything if not able to reduce permissions level */ - exit(1); + /* set starting SFTP directory */ + if (ret == WS_SUCCESS) { + if (wolfSSH_SFTP_SetDefaultPath(ssh, pPasswd->pw_dir) != WS_SUCCESS) { + wolfSSH_Log(WS_LOG_ERROR, + "[SSHD] Error setting SFTP default home path"); + ret = WS_FATAL_ERROR; } - - return WS_FATAL_ERROR; } - if (wolfSSHD_AuthReducePermissionsUser(conn->auth, p_passwd->pw_uid, - p_passwd->pw_gid) != WS_SUCCESS) { + if (ret == WS_SUCCESS) { + error = SetupChroot(usrConf); + if (error == 1) { + /* chroot was executed */ + if (wolfSSH_SFTP_SetDefaultPath(ssh, "/") != WS_SUCCESS) { + wolfSSH_Log(WS_LOG_ERROR, + "[SSHD] Error setting SFTP default path"); + ret = WS_FATAL_ERROR; + } + } + else if (error < 0) { + ret = error; /* error case with setup chroot */ + } + } + + if (wolfSSHD_AuthReducePermissionsUser(conn->auth, pPasswd->pw_uid, + pPasswd->pw_gid) != WS_SUCCESS) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user ID"); if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { /* stop everything if not able to reduce permissions level */ @@ -378,12 +406,10 @@ static int SFTP_Subsystem(WOLFSSH* ssh, WOLFSSHD_CONNECTION* conn) #endif static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, - char* forcedCmd) + WPASSWD* pPasswd, WOLFSSHD_CONFIG* usrConf) { WS_SOCKET_T sshFd = 0; int rc; - const char *userName; - struct passwd *p_passwd; WS_SOCKET_T childFd = 0; pid_t childPid; #ifndef EXAMPLE_BUFFER_SZ @@ -391,10 +417,13 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, #endif byte shellBuffer[EXAMPLE_BUFFER_SZ]; byte channelBuffer[EXAMPLE_BUFFER_SZ]; + char* forcedCmd; - userName = wolfSSH_GetUsername(ssh); - if (userName == NULL) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure get user name"); + forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf); + if (forcedCmd != NULL && XSTRCMP(forcedCmd, "internal-sftp") == 0) { + wolfSSH_Log(WS_LOG_ERROR, + "[SSHD] Only SFTP connections allowed for user " + "%s", wolfSSH_GetUsername(ssh)); return WS_FATAL_ERROR; } @@ -404,10 +433,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, return WS_FATAL_ERROR; } - p_passwd = getpwnam((const char *)userName); - if (p_passwd == NULL) { - /* Not actually a user on the system. */ - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Invalid user name found"); + ChildRunning = 1; + if (SetupChroot(usrConf) < 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting chroot"); if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { /* stop everything if not able to reduce permissions level */ exit(1); @@ -416,9 +444,8 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, return WS_FATAL_ERROR; } - ChildRunning = 1; - if (wolfSSHD_AuthReducePermissionsUser(conn->auth, p_passwd->pw_uid, - p_passwd->pw_gid) != WS_SUCCESS) { + if (wolfSSHD_AuthReducePermissionsUser(conn->auth, pPasswd->pw_uid, + pPasswd->pw_gid) != WS_SUCCESS) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user ID"); if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { /* stop everything if not able to reduce permissions level */ @@ -444,25 +471,27 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); - setenv("HOME", p_passwd->pw_dir, 1); - setenv("LOGNAME", p_passwd->pw_name, 1); - rc = chdir(p_passwd->pw_dir); + setenv("HOME", pPasswd->pw_dir, 1); + setenv("LOGNAME", pPasswd->pw_name, 1); + rc = chdir(pPasswd->pw_dir); if (rc != 0) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error going to user home dir"); return WS_FATAL_ERROR; } /* default to /bin/sh if user shell is not set */ WMEMSET(cmd, 0, sizeof(cmd)); - if (XSTRLEN(p_passwd->pw_shell) == 0) { + if (XSTRLEN(pPasswd->pw_shell) == 0) { XSNPRINTF(cmd, sizeof(cmd), "%s", "/bin/sh"); } else { - XSNPRINTF(cmd, sizeof(cmd),"%s", p_passwd->pw_shell); + XSNPRINTF(cmd, sizeof(cmd),"%s", pPasswd->pw_shell); } errno = 0; if (forcedCmd) { - ret = execv(forcedCmd, NULL); + args[0] = NULL; + ret = execv(forcedCmd, (char**)args); } else { ret = execv(cmd, (char**)args); @@ -648,8 +677,8 @@ static void* HandleConnection(void* arg) } if (ret == WS_SUCCESS || ret == WS_SFTP_COMPLETE) { + WPASSWD* pPasswd; WOLFSSHD_CONFIG* usrConf; - char* cmd; char* usr; /* get configuration for user */ @@ -662,69 +691,22 @@ static void* HandleConnection(void* arg) ret = WS_FATAL_ERROR; } - - #ifdef WOLFSSH_SFTP - /* set starting SFTP directory */ - if (ret == WS_SFTP_COMPLETE) { - struct passwd *p_passwd; - p_passwd = getpwnam((const char *)usr); - if (p_passwd == NULL || wolfSSH_SFTP_SetDefaultPath(ssh, - p_passwd->pw_dir) != WS_SUCCESS) { - wolfSSH_Log(WS_LOG_ERROR, - "[SSHD] Error setting SFTP default home path"); + if (ret == WS_SUCCESS || ret == WS_SFTP_COMPLETE) { + pPasswd = getpwnam((const char *)usr); + if (pPasswd == NULL) { + wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error igetting user info"); ret = WS_FATAL_ERROR; } } - #endif - /* check for chroot set */ - cmd = wolfSSHD_ConfigGetChroot(usrConf); - if (cmd != NULL) { - if (wolfSSHD_AuthRaisePermissions(conn->auth) != WS_SUCCESS) { - wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure to raise permissions " - "for auth"); - ret = WS_FATAL_ERROR; - } - else { - if (chroot(cmd) != 0) { - wolfSSH_Log(WS_LOG_ERROR, - "[SSHD] chroot failed to path %s", cmd); - ret = WS_FATAL_ERROR; - } - - if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { - exit(1); - } - } - - #ifdef WOLFSSH_SFTP - if (ret == WS_SFTP_COMPLETE) { - if (wolfSSH_SFTP_SetDefaultPath(ssh, "/") != WS_SUCCESS) { - wolfSSH_Log(WS_LOG_ERROR, - "[SSHD] Error setting SFTP default path"); - ret = WS_FATAL_ERROR; - } - } - #endif - } if (ret != WS_FATAL_ERROR) { /* check for any forced command set for the user */ - cmd = wolfSSHD_ConfigGetForcedCmd(usrConf); switch (wolfSSH_GetSessionType(ssh)) { case WOLFSSH_SESSION_SHELL: #ifdef WOLFSSH_SHELL if (ret == WS_SUCCESS) { - if (cmd != NULL && XSTRCMP(cmd, "internal-sftp") == 0) { - wolfSSH_Log(WS_LOG_ERROR, - "[SSHD] Only SFTP connections allowed for user " - "%s", usr); - ret = WS_FATAL_ERROR; - } - else { - wolfSSH_Log(WS_LOG_INFO, - "[SSHD] Entering new shell"); - SHELL_Subsystem(conn, ssh, cmd); - } + wolfSSH_Log(WS_LOG_INFO, "[SSHD] Entering new shell"); + SHELL_Subsystem(conn, ssh, pPasswd, usrConf); } #else wolfSSH_Log(WS_LOG_ERROR, @@ -738,7 +720,7 @@ static void* HandleConnection(void* arg) switch (ret) { case WS_SFTP_COMPLETE: #ifdef WOLFSSH_SFTP - ret = SFTP_Subsystem(ssh, conn); + ret = SFTP_Subsystem(conn, ssh, pPasswd, usrConf); #else err_sys("SFTP not compiled in. Please use " "--enable-sftp"); diff --git a/wolfssh/port.h b/wolfssh/port.h index 5652d77b..7f255d61 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -50,6 +50,7 @@ extern "C" { #endif #define WUID_T uid_t #define WGID_T gid_t + #define WPASSWD struct passwd #endif /* setup memory handling */