From b42a3b9fe6b9530201eb4a6e3eddafe649918ac1 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 3 May 2018 08:04:48 +0200 Subject: Don't use PAM_RUSER and PAM_RHOST. Not made for this. Introduce our own PAM types (PAM_TYPE_X2GO_USER, _X2GO_SERVER, _X2GO_COMMAND). --- src/pam-x2go-children.c | 15 +++---- src/pam-x2go-children.h | 4 +- src/pam-x2go.c | 115 +++++++++++++++++++++++++++++------------------- 3 files changed, 79 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/pam-x2go-children.c b/src/pam-x2go-children.c index d719a53..fdf79b9 100644 --- a/src/pam-x2go-children.c +++ b/src/pam-x2go-children.c @@ -40,7 +40,7 @@ #include "auth-check-path.h" void -pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rhost, const char* ruser, const char* rsession) +pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rhost, const char* ruser, const char* rcommand) { dup2(stdinpipe[0], 0); @@ -50,7 +50,7 @@ pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rh args[0] = (char *)auth_check_path; args[1] = (char *)rhost; args[2] = (char *)ruser; - args[3] = (char *)rsession; + args[3] = (char *)rcommand; args[4] = NULL; struct passwd * pwdent = getpwnam(username); @@ -84,7 +84,7 @@ pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rh } int -session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruser, const char * rhost, const char * rsession, const char * password) +session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruser, const char * rhost, const char * rcommand, const char * password) { /* Socket stuff */ int socketfd = 0; @@ -128,15 +128,15 @@ session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruse return EXIT_FAILURE; } - if (rsession[0] == '\0') { - rsession = "TERMINAL"; + if (rcommand[0] == '\0') { + rcommand = "TERMINAL"; } /* Build this up as a buffer so we can just write it and see that very, very clearly */ buffer_len += strlen(ruser) + 1; /* Add one for the space */ buffer_len += strlen(rhost) + 1; /* Add one for the space */ - buffer_len += strlen(rsession) + 1; /* Add one for the space */ + buffer_len += strlen(rcommand) + 1; /* Add one for the space */ buffer_len += strlen(password) + 1; /* Add one for the NULL */ if (buffer_len < 5) { @@ -157,7 +157,7 @@ session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruse goto cleanup; } - buffer_fill = snprintf(buffer, buffer_len, "%s %s %s %s", ruser, rhost, rsession, password); + buffer_fill = snprintf(buffer, buffer_len, "%s %s %s %s", ruser, rhost, rcommand, password); if (buffer_fill > buffer_len) { /* This really shouldn't happen, but if for some reason we have an difference between they way that the lengths are calculated we want @@ -230,4 +230,3 @@ cleanup: _exit(EXIT_FAILURE); } - diff --git a/src/pam-x2go-children.h b/src/pam-x2go-children.h index f46c3cf..1d7ee34 100644 --- a/src/pam-x2go-children.h +++ b/src/pam-x2go-children.h @@ -20,7 +20,9 @@ #ifndef _PAM_X2GO_CHILDREN_H_ #define _PAM_X2GO_CHILDREN_H_ -#define PAM_TYPE_SESSIONTYPE 1234 +#define PAM_TYPE_X2GO_USER 1234 +#define PAM_TYPE_X2GO_SERVER 1235 +#define PAM_TYPE_X2GO_COMMAND 1236 #define ALL_GOOD_SIGNAL "Ar, ready to authenticate cap'n" void diff --git a/src/pam-x2go.c b/src/pam-x2go.c index 6401433..53d937a 100644 --- a/src/pam-x2go.c +++ b/src/pam-x2go.c @@ -43,7 +43,9 @@ static int unpriveleged_kill (struct passwd * pwdent); -static char * global_session = NULL; +static char * global_x2go_user = NULL; +static char * global_x2go_server = NULL; +static char * global_x2go_command = NULL; /* FIXME? This is a work around to the fact that PAM seems to be clearing the auth token between authorize and open_session. Which then requires us to save it. Seems like we're the wrong people to do it, but we have @@ -56,7 +58,7 @@ get_item (pam_handle_t * pamh, int type) { /* Check to see if we just have the value. If we do, great let's dup it some we're consistently allocating memory */ - if (type != PAM_TYPE_SESSIONTYPE) { + if ((type == PAM_USER) || (type == PAM_AUTHTOK)) { /* If it's not a session type we can use the PAM functions because the PAM functions don't support session type */ char * value = NULL; @@ -69,10 +71,15 @@ get_item (pam_handle_t * pamh, int type) return global_password; } } else { - /* Here we only have session type, so we can see if the global session type is - useful for us, if we have it */ - if (global_session != NULL) { - return global_session; + /* Here we deal with all X2Go specific parameters */ + if ((type == PAM_TYPE_X2GO_USER) && (global_x2go_user != NULL)) { + return global_x2go_user; + } + if ((type == PAM_TYPE_X2GO_SERVER) && (global_x2go_server != NULL)) { + return global_x2go_server; + } + if ((type == PAM_TYPE_X2GO_COMMAND) && (global_x2go_command != NULL)) { + return global_x2go_command; } } /* Now we need to prompt */ @@ -88,17 +95,17 @@ get_item (pam_handle_t * pamh, int type) case PAM_USER: message.msg = "login:"; break; - case PAM_RUSER: + case PAM_TYPE_X2GO_USER: message.msg = "remote login:"; break; - case PAM_RHOST: + case PAM_TYPE_X2GO_SERVER: message.msg = "remote host:"; break; case PAM_AUTHTOK: message.msg = "password:"; message.msg_style = PAM_PROMPT_ECHO_OFF; break; - case PAM_TYPE_SESSIONTYPE: + case PAM_TYPE_X2GO_COMMAND: message.msg = "x2gosession:"; break; default: @@ -130,7 +137,7 @@ get_item (pam_handle_t * pamh, int type) } } - if (type == PAM_RHOST) { + if (type == PAM_TYPE_X2GO_SERVER) { char * subloc = strstr(promptval, "://"); if (subloc != NULL) { char * original = promptval; @@ -148,19 +155,35 @@ get_item (pam_handle_t * pamh, int type) char * retval = NULL; if (promptval != NULL) { /* Can't believe it really would be at this point, but let's be sure */ - if (type != PAM_TYPE_SESSIONTYPE) { + if ((type == PAM_USER) || (type == PAM_AUTHTOK)) { /* We can only use the PAM functions if it's not the session type */ pam_set_item(pamh, type, (const void *)promptval); /* We're returning the value saved by PAM so we can clear promptval */ pam_get_item(pamh, type, (const void **)&retval); } - if (type == PAM_TYPE_SESSIONTYPE) { + if (type == PAM_TYPE_X2GO_USER) { + /* The server can be saved globally */ + if (global_x2go_user != NULL) { + free(global_x2go_user); + } + global_x2go_user = strdup(promptval); + retval = global_x2go_user; + } + if (type == PAM_TYPE_X2GO_SERVER) { + /* The server can be saved globally */ + if (global_x2go_server != NULL) { + free(global_x2go_server); + } + global_x2go_server = strdup(promptval); + retval = global_x2go_server; + } + if (type == PAM_TYPE_X2GO_COMMAND) { /* The session type can be saved globally so we can use it for open */ - if (global_session != NULL) { - free(global_session); + if (global_x2go_command != NULL) { + free(global_x2go_command); } - global_session = strdup(promptval); - retval = global_session; + global_x2go_command = strdup(promptval); + retval = global_x2go_command; } if (type == PAM_AUTHTOK) { /* We also save the password globally if we've got one */ @@ -205,15 +228,15 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv) char * password = NULL; char * ruser = NULL; char * rhost = NULL; - char * rsession = NULL; + char * rcommand = NULL; int retval = PAM_IGNORE; /* Get all the values, or prompt for them, or return with an auth error */ GET_ITEM(username, PAM_USER); - GET_ITEM(ruser, PAM_RUSER); - GET_ITEM(rhost, PAM_RHOST); - GET_ITEM(rsession, PAM_TYPE_SESSIONTYPE); + GET_ITEM(ruser, PAM_TYPE_X2GO_USER); + GET_ITEM(rhost, PAM_TYPE_X2GO_SERVER); + GET_ITEM(rcommand, PAM_TYPE_X2GO_COMMAND); GET_ITEM(password, PAM_AUTHTOK); int stdinpipe[2]; @@ -225,32 +248,32 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv) /* At this point we should have the values, let's check the auth */ pid_t pid; switch (pid = fork()) { - case 0: { /* child */ - pam_sm_authenticate_helper (stdinpipe, username, rhost, ruser, rsession); - break; - } - case -1: { /* fork'n error! */ - retval = PAM_SYSTEM_ERR; - break; - } - default: { - int forkret = 0; - int bytesout = 0; + case 0: { /* child */ + pam_sm_authenticate_helper (stdinpipe, username, rhost, ruser, rcommand); + break; + } + case -1: { /* fork'n error! */ + retval = PAM_SYSTEM_ERR; + break; + } + default: { + int forkret = 0; + int bytesout = 0; - bytesout += write(stdinpipe[1], password, strlen(password)); - bytesout += write(stdinpipe[1], "\n", 1); + bytesout += write(stdinpipe[1], password, strlen(password)); + bytesout += write(stdinpipe[1], "\n", 1); - close(stdinpipe[1]); + close(stdinpipe[1]); - if (waitpid(pid, &forkret, 0) < 0 || bytesout == 0) { - retval = PAM_SYSTEM_ERR; - } else if (forkret == 0) { - retval = PAM_SUCCESS; - } else { - retval = PAM_AUTH_ERR; + if (waitpid(pid, &forkret, 0) < 0 || bytesout == 0) { + retval = PAM_SYSTEM_ERR; + } else if (forkret == 0) { + retval = PAM_SUCCESS; + } else { + retval = PAM_AUTH_ERR; + } } } - } /* Return our status */ done: @@ -270,15 +293,15 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv char * password = NULL; char * ruser = NULL; char * rhost = NULL; - char * rsession = NULL; + char * rcommand = NULL; int retval = PAM_SUCCESS; /* Get all the values, or prompt for them, or return with an auth error */ GET_ITEM(username, PAM_USER); - GET_ITEM(ruser, PAM_RUSER); - GET_ITEM(rhost, PAM_RHOST); - GET_ITEM(rsession, PAM_TYPE_SESSIONTYPE); + GET_ITEM(ruser, PAM_TYPE_X2GO_USER); + GET_ITEM(rhost, PAM_TYPE_X2GO_SERVER); + GET_ITEM(rcommand, PAM_TYPE_X2GO_COMMAND); GET_ITEM(password, PAM_AUTHTOK); struct passwd * pwdent = getpwnam(username); @@ -300,7 +323,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv pid_t pid = fork(); if (pid == 0) { - int ret = session_socket_handler(pwdent, sessionready[1], ruser, rhost, rsession, password); + int ret = session_socket_handler(pwdent, sessionready[1], ruser, rhost, rcommand, password); close(sessionready[1]); _exit(ret); -- cgit v1.2.3