raise and lower permissions levels

pull/435/head
JacobBarthelmeh 2022-07-25 09:26:05 -07:00
parent d16f642734
commit 85109e66cf
3 changed files with 120 additions and 1 deletions

View File

@ -26,6 +26,7 @@
#ifdef __linux__
#define _XOPEN_SOURCE
#define _GNU_SOURCE
#endif
#include <unistd.h>
@ -57,6 +58,8 @@ struct WOLFSSHD_AUTH {
CallbackCheckPassword CheckPasswordCb;
CallbackCheckPublicKey CheckPublicKeyCb;
WOLFSSHD_CONFIG* conf;
int gid;
int uid;
void* heap;
};
@ -653,7 +656,17 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
{
int ret;
if (auth == NULL)
return WOLFSSH_USERAUTH_FAILURE;
ret = DoCheckUser(usr, auth);
/* temporarily elevate permissions */
if (wolfSSHD_RaisePermissions(auth) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure to raise permissions for auth");
ret = WOLFSSH_USERAUTH_FAILURE;
}
if (ret == WOLFSSH_USERAUTH_SUCCESS && type == WOLFSSH_USERAUTH_PASSWORD) {
int rc;
@ -699,6 +712,11 @@ static int RequestAuthentication(const char* usr, int type, const byte* data,
}
}
if (wolfSSHD_ReducePermissions(auth) != 0) {
/* stop everything if not able to reduce permissions level */
exit(1);
}
return ret;
}
@ -816,6 +834,8 @@ WOLFSSHD_AUTH * wolfSSHD_CreateUserAuth(void* heap, WOLFSSHD_CONFIG* conf)
auth = (WOLFSSHD_AUTH*)WMALLOC(sizeof(WOLFSSHD_AUTH), heap, DYNTYPE_SSHD);
if (auth != NULL) {
int ret;
struct passwd* pwInfo;
const char* usr = "sshd";
auth->heap = heap;
auth->conf = conf;
@ -844,6 +864,20 @@ WOLFSSHD_AUTH * wolfSSHD_CreateUserAuth(void* heap, WOLFSSHD_CONFIG* conf)
}
}
if (ret == WS_SUCCESS) {
pwInfo = getpwnam(usr);
if (pwInfo == NULL) {
/* user name not found on system */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] No sshd user found to use");
ret = WS_FATAL_ERROR;
}
}
if (ret == WS_SUCCESS) {
auth->gid = pwInfo->pw_gid;
auth->uid = pwInfo->pw_uid;
}
/* error case in setting one of the default callbacks */
if (ret != WS_SUCCESS) {
(void)wolfSSHD_FreeUserAuth(auth);
@ -864,4 +898,53 @@ int wolfSSHD_FreeUserAuth(WOLFSSHD_AUTH* auth)
}
return WS_SUCCESS;
}
/* return 0 on success */
int wolfSSHD_RaisePermissions(WOLFSSHD_AUTH* auth)
{
int ret = 0;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
if (auth) {
if (setegid(0) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error rasing gid");
ret = WS_FATAL_ERROR;
}
if (seteuid(0) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error rasing uid");
ret = WS_FATAL_ERROR;
}
}
else {
ret = WS_BAD_ARGUMENT;
}
return ret;
}
/* return 0 on success */
int wolfSSHD_ReducePermissions(WOLFSSHD_AUTH* auth)
{
int ret = 0;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Lowering permissions level");
if (auth) {
if (setegid(auth->gid) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting sshd gid");
ret = WS_FATAL_ERROR;
}
if (seteuid(auth->uid) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting sshd uid");
ret = WS_FATAL_ERROR;
}
}
else {
ret = WS_BAD_ARGUMENT;
}
return ret;
}
#endif /* WOLFSSH_SSHD */

View File

@ -56,4 +56,6 @@ typedef int (*CallbackCheckPublicKey)(const char* usr, const byte* key,
WOLFSSHD_AUTH * wolfSSHD_CreateUserAuth(void* heap, WOLFSSHD_CONFIG* conf);
int wolfSSHD_FreeUserAuth(WOLFSSHD_AUTH* auth);
int wolfSSHD_ReducePermissions(WOLFSSHD_AUTH* auth);
int wolfSSHD_RaisePermissions(WOLFSSHD_AUTH* auth);
#endif /* WOLFAUTH_H */

View File

@ -336,13 +336,30 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh)
byte channelBuffer[EXAMPLE_BUFFER_SZ];
userName = wolfSSH_GetUsername(ssh);
/* temporarily elevate permissions to get users information */
if (wolfSSHD_RaisePermissions(conn->auth) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failure to raise permissions for auth");
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");
if (wolfSSHD_ReducePermissions(conn->auth) != 0) {
/* stop everything if not able to reduce permissions level */
exit(1);
}
return WS_FATAL_ERROR;
}
if (wolfSSHD_ReducePermissions(conn->auth) != 0) {
/* stop everything if not able to reduce permissions level */
exit(1);
}
ChildRunning = 1;
childPid = forkpty(&childFd, NULL, NULL, NULL);
@ -354,15 +371,24 @@ static int SHELL_Subsystem(WOLFSSHD_CONNECTION* conn, WOLFSSH* ssh)
else if (childPid == 0) {
/* Child process */
const char *args[] = {"-sh", NULL};
char cmd[80];
signal(SIGINT, SIG_DFL);
setgid(p_passwd->pw_gid);
setuid(p_passwd->pw_uid);
if (system("env") != 0) {
printf("0 return value from system call\n");
}
setenv("HOME", p_passwd->pw_dir, 1);
setenv("LOGNAME", p_passwd->pw_name, 1);
/* @TODO this needs reworked, can just exit into root */
WMEMSET(cmd, 0, sizeof(cmd));
XSNPRINTF(cmd, sizeof(cmd), "su %s", userName);
printf("executing command [%s]\n", cmd);
system(cmd);
rc = chdir(p_passwd->pw_dir);
if (rc != 0) {
return WS_FATAL_ERROR;
@ -609,7 +635,7 @@ static int wolfSSHD_PendingConnection(WS_SOCKET_T fd)
else {
printf("Found write or error data\n");
ret = 0; /* nothing to read */
}
}
}
// printf("Timeout waiting for connection\n");
return ret;
@ -724,6 +750,14 @@ int main(int argc, char** argv)
}
}
/* seperate privlage permisions */
if (ret == WS_SUCCESS) {
if (wolfSSHD_ReducePermissions(auth) != 0) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Error lowering permissions level");
ret = WS_FATAL_ERROR;
}
}
if (ret == WS_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Starting to listen on port %d", port);
tcp_listen(&listenFd, &port, 1);