diff --git a/sesman/sesman.c b/sesman/sesman.c index 2af57885..8771c9fa 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -27,8 +27,12 @@ #include "parse.h" #include "os_calls.h" -int DEFAULT_CC +long DEFAULT_CC auth_userpass(char* user, char* pass); +int DEFAULT_CC +auth_start_session(long in_val); +int DEFAULT_CC +auth_end(long in_val); static int g_sck; static int g_pid; @@ -41,6 +45,7 @@ struct session_item int width; int height; int bpp; + long data; }; static unsigned char s_fixedkey[8] = { 23, 82, 107, 6, 35, 78, 88, 7 }; @@ -150,6 +155,10 @@ cterm(int s) int i; int pid; + if (g_getpid() != g_pid) + { + return; + } pid = g_waitchild(); if (pid > 0) { @@ -157,6 +166,7 @@ cterm(int s) { if (session_items[i].pid == pid) { + auth_end(session_items[i].data); g_memset(session_items + i, 0, sizeof(struct session_item)); } } @@ -187,7 +197,8 @@ check_password_file(char* filename, char* password) /******************************************************************************/ static int DEFAULT_CC -start_session(int width, int height, int bpp, char* username, char* password) +start_session(int width, int height, int bpp, char* username, char* password, + long data) { int display; int pid; @@ -217,6 +228,7 @@ start_session(int width, int height, int bpp, char* username, char* password) { return 0; } + auth_start_session(data); wmpid = 0; pid = g_fork(); if (pid == -1) @@ -288,6 +300,7 @@ start_session(int width, int height, int bpp, char* username, char* password) g_waitpid(wmpid); g_sigterm(xpid); g_sigterm(wmpid); + g_sleep(1000); g_exit(0); } } @@ -296,13 +309,13 @@ start_session(int width, int height, int bpp, char* username, char* password) } else /* parent */ { - g_signal_child_stop(cterm); /* SIGCHLD */ session_items[display].pid = pid; g_strcpy(session_items[display].name, username); session_items[display].display = display; session_items[display].width = width; session_items[display].height = height; session_items[display].bpp = bpp; + session_items[display].data = data; g_sleep(5000); } return display; @@ -331,7 +344,6 @@ main(int argc, char** argv) int i; int size; int version; - int ok; int width; int height; int bpp; @@ -344,12 +356,14 @@ main(int argc, char** argv) char user[256]; char pass[256]; struct session_item* s_item; + long data; + g_memset(&session_items, 0, sizeof(session_items)); + g_pid = g_getpid(); g_signal(2, sesman_shutdown); /* SIGINT */ g_signal(9, sesman_shutdown); /* SIGKILL */ g_signal(15, sesman_shutdown); /* SIGTERM */ - g_memset(&session_items, 0, sizeof(session_items)); - g_pid = g_getpid(); + g_signal_child_stop(cterm); /* SIGCHLD */ if (argc == 1) { g_printf("xrdp session manager v0.1\n"); @@ -403,29 +417,33 @@ start session\n"); in_uint16_be(in_s, width); in_uint16_be(in_s, height); in_uint16_be(in_s, bpp); - ok = auth_userpass(user, pass); + data = auth_userpass(user, pass); display = 0; - if (ok) + if (data) { s_item = find_session_item(user, width, height, bpp); if (s_item != 0) { display = s_item->display; + auth_end(data); + data = 0; } else { - display = start_session(width, height, bpp, user, pass); + display = start_session(width, height, bpp, user, pass, + data); } if (display == 0) { - ok = 0; + auth_end(data); + data = 0; } } init_stream(out_s, 8192); out_uint32_be(out_s, 0); /* version */ out_uint32_be(out_s, 14); /* size */ out_uint16_be(out_s, 3); /* cmd */ - out_uint16_be(out_s, ok); /* data */ + out_uint16_be(out_s, data != 0); /* data */ out_uint16_be(out_s, display); /* data */ s_mark_end(out_s); tcp_force_send(in_sck, out_s->data, @@ -498,9 +516,9 @@ start session\n"); in_uint16_be(in_s, code); if (code == 3) { - in_uint16_be(in_s, ok); + in_uint16_be(in_s, data); in_uint16_be(in_s, display); - g_printf("ok %d display %d\n", ok, display); + g_printf("ok %d display %d\n", data, display); } } } diff --git a/sesman/startwm.sh b/sesman/startwm.sh index 2b9c75b0..b190631c 100755 --- a/sesman/startwm.sh +++ b/sesman/startwm.sh @@ -2,3 +2,4 @@ startkde #blackbox #fvwm95 +#xterm diff --git a/sesman/verify_user.c b/sesman/verify_user.c index 7ee660d5..9a7c1164 100644 --- a/sesman/verify_user.c +++ b/sesman/verify_user.c @@ -88,3 +88,18 @@ auth_userpass(char* user, char* pass) } return 1; } + +/******************************************************************************/ +/* returns error */ +int DEFAULT_CC +auth_start_session(void) +{ + return 0; +} + +/******************************************************************************/ +int DEFAULT_CC +auth_end(void) +{ + return 0; +} diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c index 2bf19f64..e58576fe 100644 --- a/sesman/verify_user_pam.c +++ b/sesman/verify_user_pam.c @@ -27,8 +27,17 @@ struct t_user_pass { - char* user; - char* pass; + char user[256]; + char pass[256]; +}; + +struct t_auth_info +{ + struct t_user_pass user_pass; + int session_opened; + int did_setcred; + struct pam_conv pamc; + pam_handle_t* ph; }; /******************************************************************************/ @@ -66,33 +75,113 @@ verify_pam_conv(int num_msg, const struct pam_message** msg, } /******************************************************************************/ -/* returns boolean */ -int DEFAULT_CC +static void DEFAULT_CC +get_service_name(char* service_name) +{ + service_name[0] = 0; + if (g_file_exist("/etc/pam.d/sesman")) + { + g_strncpy(service_name, "sesman", 255); + } + else + { + g_strncpy(service_name, "gdm", 255); + } +} + +/******************************************************************************/ +/* returns long, zero is no go */ +long DEFAULT_CC auth_userpass(char* user, char* pass) { int error; - int null_tok; - struct t_user_pass user_pass; - struct pam_conv pamc; - pam_handle_t* ph; + struct t_auth_info* auth_info; + char service_name[256]; - user_pass.user = user; - user_pass.pass = pass; - pamc.conv = &verify_pam_conv; - pamc.appdata_ptr = &user_pass; - error = pam_start("gdm", 0, &pamc, &ph); + get_service_name(service_name); + auth_info = g_malloc(sizeof(struct t_auth_info), 1); + g_strncpy(auth_info->user_pass.user, user, 255); + g_strncpy(auth_info->user_pass.pass, pass, 255); + auth_info->pamc.conv = &verify_pam_conv; + auth_info->pamc.appdata_ptr = &(auth_info->user_pass); + error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph)); if (error != PAM_SUCCESS) { - g_printf("pam_start failed\n\r"); + g_printf("pam_start failed: %s\n\r", pam_strerror(auth_info->ph, error)); + g_free(auth_info); return 0; } - null_tok = 0; - error = pam_authenticate(ph, null_tok); + error = pam_authenticate(auth_info->ph, 0); if (error != PAM_SUCCESS) { - pam_end(ph, PAM_SUCCESS); + g_printf("pam_authenticate failed: %s\n\r", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); return 0; } - pam_end(ph, PAM_SUCCESS); - return 1; + error = pam_acct_mgmt(auth_info->ph, 0); + if (error != PAM_SUCCESS) + { + g_printf("pam_acct_mgmt failed: %s\n\r", + pam_strerror(auth_info->ph, error)); + g_free(auth_info); + return 0; + } + return (long)auth_info; +} + +/******************************************************************************/ +/* returns error */ +int DEFAULT_CC +auth_start_session(long in_val) +{ + struct t_auth_info* auth_info; + int error; + + auth_info = (struct t_auth_info*)in_val; + error = pam_setcred(auth_info->ph, PAM_ESTABLISH_CRED); + if (error != PAM_SUCCESS) + { + g_printf("pam_setcred failed: %s\n\r", pam_strerror(auth_info->ph, error)); + return 1; + } + auth_info->did_setcred = 1; + error = pam_open_session(auth_info->ph, 0); + if (error != PAM_SUCCESS) + { + g_printf("pam_open_session failed: %s\n\r", + pam_strerror(auth_info->ph, error)); + return 1; + } + auth_info->session_opened = 1; + return 0; +} + +/******************************************************************************/ +/* returns error */ +/* cleanup */ +int DEFAULT_CC +auth_end(long in_val) +{ + struct t_auth_info* auth_info; + + auth_info = (struct t_auth_info*)in_val; + if (auth_info != 0) + { + if (auth_info->ph != 0) + { + if (auth_info->session_opened) + { + pam_close_session(auth_info->ph, 0); + } + if (auth_info->did_setcred) + { + pam_setcred(auth_info->ph, PAM_DELETE_CRED); + } + pam_end(auth_info->ph, PAM_SUCCESS); + auth_info->ph = 0; + } + } + g_free(auth_info); + return 0; } diff --git a/sesman/verify_user_pam_userpass.c b/sesman/verify_user_pam_userpass.c index df097823..85f45d75 100644 --- a/sesman/verify_user_pam_userpass.c +++ b/sesman/verify_user_pam_userpass.c @@ -68,3 +68,18 @@ auth_userpass(char* user, char* pass) } return 1; } + +/******************************************************************************/ +/* returns error */ +int DEFAULT_CC +auth_start_session(void) +{ + return 0; +} + +/******************************************************************************/ +int DEFAULT_CC +auth_end(void) +{ + return 0; +}