refactor chroot call

pull/441/head
JacobBarthelmeh 2022-08-29 13:17:26 -07:00
parent 8a286ad727
commit 0ef7ca2145
2 changed files with 75 additions and 92 deletions

View File

@ -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 #ifdef WOLFSSH_SFTP
#define TEST_SFTP_TIMEOUT 1 #define TEST_SFTP_TIMEOUT 1
/* handle SFTP operations /* handle SFTP operations
* returns 0 on success * 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]; byte tmp[1];
int ret = WS_SUCCESS; int ret = WS_SUCCESS;
int error = WS_SUCCESS; int error = WS_SUCCESS;
WS_SOCKET_T sockfd; WS_SOCKET_T sockfd;
int select_ret = 0; 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 */ /* temporarily elevate permissions to get users information */
if (wolfSSHD_AuthRaisePermissions(conn->auth) != WS_SUCCESS) { if (wolfSSHD_AuthRaisePermissions(conn->auth) != WS_SUCCESS) {
@ -308,18 +322,32 @@ static int SFTP_Subsystem(WOLFSSH* ssh, WOLFSSHD_CONNECTION* conn)
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
p_passwd = getpwnam((const char *)userName); /* set starting SFTP directory */
if (p_passwd == NULL) { if (ret == WS_SUCCESS) {
if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { if (wolfSSH_SFTP_SetDefaultPath(ssh, pPasswd->pw_dir) != WS_SUCCESS) {
/* stop everything if not able to reduce permissions level */ wolfSSH_Log(WS_LOG_ERROR,
exit(1); "[SSHD] Error setting SFTP default home path");
ret = WS_FATAL_ERROR;
} }
return WS_FATAL_ERROR;
} }
if (wolfSSHD_AuthReducePermissionsUser(conn->auth, p_passwd->pw_uid, if (ret == WS_SUCCESS) {
p_passwd->pw_gid) != 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"); wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user ID");
if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) {
/* stop everything if not able to reduce permissions level */ /* stop everything if not able to reduce permissions level */
@ -378,12 +406,10 @@ static int SFTP_Subsystem(WOLFSSH* ssh, WOLFSSHD_CONNECTION* conn)
#endif #endif
static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh, static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
char* forcedCmd) WPASSWD* pPasswd, WOLFSSHD_CONFIG* usrConf)
{ {
WS_SOCKET_T sshFd = 0; WS_SOCKET_T sshFd = 0;
int rc; int rc;
const char *userName;
struct passwd *p_passwd;
WS_SOCKET_T childFd = 0; WS_SOCKET_T childFd = 0;
pid_t childPid; pid_t childPid;
#ifndef EXAMPLE_BUFFER_SZ #ifndef EXAMPLE_BUFFER_SZ
@ -391,10 +417,13 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
#endif #endif
byte shellBuffer[EXAMPLE_BUFFER_SZ]; byte shellBuffer[EXAMPLE_BUFFER_SZ];
byte channelBuffer[EXAMPLE_BUFFER_SZ]; byte channelBuffer[EXAMPLE_BUFFER_SZ];
char* forcedCmd;
userName = wolfSSH_GetUsername(ssh); forcedCmd = wolfSSHD_ConfigGetForcedCmd(usrConf);
if (userName == NULL) { if (forcedCmd != NULL && XSTRCMP(forcedCmd, "internal-sftp") == 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure get user name"); wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Only SFTP connections allowed for user "
"%s", wolfSSH_GetUsername(ssh));
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
@ -404,10 +433,9 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
p_passwd = getpwnam((const char *)userName); ChildRunning = 1;
if (p_passwd == NULL) { if (SetupChroot(usrConf) < 0) {
/* Not actually a user on the system. */ wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting chroot");
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Invalid user name found");
if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) {
/* stop everything if not able to reduce permissions level */ /* stop everything if not able to reduce permissions level */
exit(1); exit(1);
@ -416,9 +444,8 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh,
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
ChildRunning = 1; if (wolfSSHD_AuthReducePermissionsUser(conn->auth, pPasswd->pw_uid,
if (wolfSSHD_AuthReducePermissionsUser(conn->auth, p_passwd->pw_uid, pPasswd->pw_gid) != WS_SUCCESS) {
p_passwd->pw_gid) != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user ID"); wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user ID");
if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) { if (wolfSSHD_AuthReducePermissions(conn->auth) != WS_SUCCESS) {
/* stop everything if not able to reduce permissions level */ /* 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(SIGINT, SIG_DFL);
signal(SIGCHLD, SIG_DFL); signal(SIGCHLD, SIG_DFL);
setenv("HOME", p_passwd->pw_dir, 1); setenv("HOME", pPasswd->pw_dir, 1);
setenv("LOGNAME", p_passwd->pw_name, 1); setenv("LOGNAME", pPasswd->pw_name, 1);
rc = chdir(p_passwd->pw_dir); rc = chdir(pPasswd->pw_dir);
if (rc != 0) { if (rc != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error going to user home dir");
return WS_FATAL_ERROR; return WS_FATAL_ERROR;
} }
/* default to /bin/sh if user shell is not set */ /* default to /bin/sh if user shell is not set */
WMEMSET(cmd, 0, sizeof(cmd)); 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"); XSNPRINTF(cmd, sizeof(cmd), "%s", "/bin/sh");
} }
else { else {
XSNPRINTF(cmd, sizeof(cmd),"%s", p_passwd->pw_shell); XSNPRINTF(cmd, sizeof(cmd),"%s", pPasswd->pw_shell);
} }
errno = 0; errno = 0;
if (forcedCmd) { if (forcedCmd) {
ret = execv(forcedCmd, NULL); args[0] = NULL;
ret = execv(forcedCmd, (char**)args);
} }
else { else {
ret = execv(cmd, (char**)args); ret = execv(cmd, (char**)args);
@ -648,8 +677,8 @@ static void* HandleConnection(void* arg)
} }
if (ret == WS_SUCCESS || ret == WS_SFTP_COMPLETE) { if (ret == WS_SUCCESS || ret == WS_SFTP_COMPLETE) {
WPASSWD* pPasswd;
WOLFSSHD_CONFIG* usrConf; WOLFSSHD_CONFIG* usrConf;
char* cmd;
char* usr; char* usr;
/* get configuration for user */ /* get configuration for user */
@ -662,69 +691,22 @@ static void* HandleConnection(void* arg)
ret = WS_FATAL_ERROR; ret = WS_FATAL_ERROR;
} }
if (ret == WS_SUCCESS || ret == WS_SFTP_COMPLETE) {
#ifdef WOLFSSH_SFTP pPasswd = getpwnam((const char *)usr);
/* set starting SFTP directory */ if (pPasswd == NULL) {
if (ret == WS_SFTP_COMPLETE) { wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error igetting user info");
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");
ret = WS_FATAL_ERROR; 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) { if (ret != WS_FATAL_ERROR) {
/* check for any forced command set for the user */ /* check for any forced command set for the user */
cmd = wolfSSHD_ConfigGetForcedCmd(usrConf);
switch (wolfSSH_GetSessionType(ssh)) { switch (wolfSSH_GetSessionType(ssh)) {
case WOLFSSH_SESSION_SHELL: case WOLFSSH_SESSION_SHELL:
#ifdef WOLFSSH_SHELL #ifdef WOLFSSH_SHELL
if (ret == WS_SUCCESS) { if (ret == WS_SUCCESS) {
if (cmd != NULL && XSTRCMP(cmd, "internal-sftp") == 0) { wolfSSH_Log(WS_LOG_INFO, "[SSHD] Entering new shell");
wolfSSH_Log(WS_LOG_ERROR, SHELL_Subsystem(conn, ssh, pPasswd, usrConf);
"[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);
}
} }
#else #else
wolfSSH_Log(WS_LOG_ERROR, wolfSSH_Log(WS_LOG_ERROR,
@ -738,7 +720,7 @@ static void* HandleConnection(void* arg)
switch (ret) { switch (ret) {
case WS_SFTP_COMPLETE: case WS_SFTP_COMPLETE:
#ifdef WOLFSSH_SFTP #ifdef WOLFSSH_SFTP
ret = SFTP_Subsystem(ssh, conn); ret = SFTP_Subsystem(conn, ssh, pPasswd, usrConf);
#else #else
err_sys("SFTP not compiled in. Please use " err_sys("SFTP not compiled in. Please use "
"--enable-sftp"); "--enable-sftp");

View File

@ -50,6 +50,7 @@ extern "C" {
#endif #endif
#define WUID_T uid_t #define WUID_T uid_t
#define WGID_T gid_t #define WGID_T gid_t
#define WPASSWD struct passwd
#endif #endif
/* setup memory handling */ /* setup memory handling */