diff options
Diffstat (limited to 'sesman')
-rw-r--r-- | sesman/Makefile.am | 8 | ||||
-rw-r--r-- | sesman/chansrv/Makefile.am | 8 | ||||
-rw-r--r-- | sesman/chansrv/chansrv.c | 42 | ||||
-rw-r--r-- | sesman/scp_v0.c | 43 | ||||
-rw-r--r-- | sesman/scp_v1.c | 9 | ||||
-rw-r--r-- | sesman/sesman.ini | 10 | ||||
-rw-r--r-- | sesman/session.c | 261 | ||||
-rwxr-xr-x | sesman/startwm.sh | 4 |
8 files changed, 316 insertions, 69 deletions
diff --git a/sesman/Makefile.am b/sesman/Makefile.am index e4b63eb4..c126059a 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -8,7 +8,8 @@ AM_CFLAGS = \ INCLUDES = \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/sesman/libscp + -I$(top_srcdir)/sesman/libscp \ + -I$(top_srcdir)/raptorsmiface if SESMAN_NOPAM AUTH_C = verify_user.c @@ -47,8 +48,9 @@ xrdp_sesman_SOURCES = \ $(AUTH_C) xrdp_sesman_LDADD = \ - $(top_builddir)/common/libcommon.la \ - $(top_builddir)/sesman/libscp/libscp.la \ + $(top_srcdir)/common/libcommon.la \ + $(top_srcdir)/sesman/libscp/libscp.la \ + $(top_srcdir)/raptorsmiface/libraptorsmiface.la \ $(AUTH_LIB) \ -lpthread diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am index 0beb7f0a..9d52d950 100644 --- a/sesman/chansrv/Makefile.am +++ b/sesman/chansrv/Makefile.am @@ -19,7 +19,7 @@ AM_CFLAGS = \ INCLUDES = \ -I$(top_srcdir)/common \ - $(EXTRA_INCLUDES) + -I$(top_srcdir)/raptorsmiface sbin_PROGRAMS = \ xrdp-chansrv @@ -37,6 +37,6 @@ xrdp_chansrv_LDFLAGS = \ xrdp_chansrv_LDADD = \ -L/usr/X11R6/lib \ - $(top_builddir)/common/libcommon.la \ - -lX11 -lXfixes \ - $(EXTRA_LIBS) + $(top_srcdir)/common/libcommon.la \ + $(top_srcdir)/raptorsmiface/libraptorsmiface.la \ + -lX11 -lXfixes diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 10a42ef9..c7917d03 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -32,6 +32,8 @@ #include "rail.h" #include "xcommon.h" +#include "libraptorsmiface.h" + static struct trans* g_lis_trans = 0; static struct trans* g_con_trans = 0; static struct trans* g_api_lis_trans = 0; @@ -68,6 +70,32 @@ struct xrdp_api_data int flags; }; +//#if 0 +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +void dprint(const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + char debug[1024]; + vsprintf(debug, fmt, argp); + FILE *fp = fopen("/chansrv.debug", "a"); + if (fp != NULL) + { + fputs(debug, fp); + fclose(fp); + } + va_end(argp); +} +#undef LOG +#define LOG(_a, _params) \ +{ \ + dprint _params; \ + dprint("\n"); \ +} +//#endif + /*****************************************************************************/ /* add data to chan_item, on its way to the client */ /* returns error */ @@ -215,6 +243,7 @@ send_init_response_message(void) out_uint32_le(s, 2); /* msg id */ out_uint32_le(s, 8); /* size */ s_mark_end(s); +LOG(1, ("send_init_response_message: calling trans_force_write")); return trans_force_write(g_con_trans); } @@ -340,10 +369,8 @@ process_message_channel_setup(struct stream* s) { dev_redir_init(); } - if (g_rail_index >= 0) - { - rail_init(); - } + // Use the display number to mark session connected in the Raptor session management database + raptor_sm_set_session_state(g_display_num, SM_STATUS_CONNECTED); return rv; } @@ -464,6 +491,7 @@ process_message(void) } if (rv != 0) { + LOG(0, ("process_message: error in process_message: rv %d", rv)); break; } s->p = next_msg; @@ -755,6 +783,8 @@ channel_thread_loop(void* in_val) /* delete g_con_trans */ trans_delete(g_con_trans); g_con_trans = 0; + // Use the display number to mark session disconnected in the Raptor session management database + raptor_sm_set_session_state(g_display_num, SM_STATUS_RUNNING); /* create new listener */ error = setup_listen(); if (error != 0) @@ -940,6 +970,7 @@ read_ini(void) { name = (char*)list_get_item(names, index); value = (char*)list_get_item(values, index); +#ifndef DISABLE_UNIX_DOMAIN_SOCKETS if (g_strcasecmp(name, "ListenAddress") == 0) { if (g_strcasecmp(value, "127.0.0.1") == 0) @@ -947,6 +978,7 @@ read_ini(void) g_use_unix_socket = 1; } } +#endif } } list_delete(names); @@ -1092,6 +1124,8 @@ main(int argc, char** argv) break; } } + // Use the display number to mark session disconnected in the Raptor session management database + raptor_sm_set_session_state(g_display_num, SM_STATUS_RUNNING); /* cleanup */ main_cleanup(); LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index dac04ad3..092585cf 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -27,6 +27,8 @@ #include "sesman.h" +#include "libraptorsmiface.h" + extern struct config_sesman* g_cfg; /* in sesman.c */ /******************************************************************************/ @@ -40,39 +42,18 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) data = auth_userpass(s->username, s->password); if (s->type == SCP_GW_AUTHENTICATION) { - /* this is just authentication in a gateway situation */ - /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ - if (data) - { - if (1 == access_login_allowed(s->username)) - { - /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(c, 0); - log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", - s->username); - /* g_writeln("Connection allowed"); */ - } - else - { - scp_v0s_replyauthentication(c,3); - log_message(LOG_LEVEL_INFO, "Username okey but group problem for " - "user: %s", s->username); - /* g_writeln("user password ok, but group problem"); */ + s_item = session_get_bydata(s->username, s->width, s->height, s->bpp, s->type); + + // RAPTOR session management + pid_t serverpid = raptor_sm_get_pid_for_username(s->username, RAPTOR_SM_SERVER_PID_FIELD); + if (serverpid < 0) { + // Session NOT already running + if (s_item != 0) { + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ [FIXME] scp claimed there was an active session, but the authoritative RAPTOR database disagrees: username %s", s->username); } + s_item = 0; } - else - { - /* g_writeln("username or password error"); */ - log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", - s->username); - scp_v0s_replyauthentication(c, 2); - } - auth_end(data); - } - else if (data) - { - s_item = session_get_bydata(s->username, s->width, s->height, - s->bpp, s->type); + if (s_item != 0) { display = s_item->display; diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index f93f89ee..d83dd7bc 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -30,6 +30,8 @@ //#include "libscp_types.h" #include "libscp.h" +#include "libraptorsmiface.h" + extern struct config_sesman* g_cfg; /* in sesman.c */ static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); @@ -106,6 +108,13 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) /* list disconnected sessions */ slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); + // RAPTOR session management + pid_t serverpid = raptor_sm_get_pid_for_username(s->username, RAPTOR_SM_SERVER_PID_FIELD); + if (serverpid < 0) { + // Session NOT already running + scount = 0; + } + if (scount == 0) { /* no disconnected sessions - start a new one */ diff --git a/sesman/sesman.ini b/sesman/sesman.ini index f2a210a4..7f194074 100644 --- a/sesman/sesman.ini +++ b/sesman/sesman.ini @@ -13,7 +13,7 @@ TerminalServerAdmins=tsadmins [Sessions] X11DisplayOffset=10 -MaxSessions=10 +MaxSessions=1000000 KillDisconnected=0 IdleTimeLimit=0 DisconnectedTimeLimit=0 @@ -24,12 +24,18 @@ LogLevel=DEBUG EnableSyslog=1 SyslogLevel=DEBUG +#[X11rdp] +#param1=-bs +#param2=-ac +#param3=-nolisten +#param4=tcp +#param5=-uds + [X11rdp] param1=-bs param2=-ac param3=-nolisten param4=tcp -param5=-uds [Xvnc] param1=-bs diff --git a/sesman/session.c b/sesman/session.c index 94c5bf91..46037187 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -31,6 +31,17 @@ #include <errno.h> //#include <time.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <netdb.h> + +#include "libraptorsmiface.h" + extern tbus g_sync_event; extern unsigned char g_fixedkey[8]; extern struct config_sesman* g_cfg; /* in sesman.c */ @@ -144,6 +155,82 @@ session_get_bydata(char* name, int width, int height, int bpp, int type) /******************************************************************************/ /** * + * @brief checks if there's a server running on a host and port + * @param display the display to check + * @return 0 if the port is closed, 1 if it is open + * + */ +static int DEFAULT_CC +check_port_status(const char* host, const char* port) +{ + char text[256]; + int x_running; + int sck; + + struct sockaddr_in servaddr; + int soc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + g_memset( &servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(atoi(port)); + + struct hostent* hostaddr; + hostaddr = gethostbyname(host); + g_memcpy(&servaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length); + + int res = connect(soc, (struct sockaddr*)&servaddr, sizeof(servaddr)); + + close(soc); + + if (res == -1) + { + // Port is closed, no server there! + return 0; + } + else { + // Port is open + return 1; + } +} + +/******************************************************************************/ +/** + * + * @brief checks if there's a server running on a remote display + * @param display the display to check + * @return 0 if there isn't a display running, nonzero otherwise + * + */ +static int DEFAULT_CC +x_server_running_check_remote_ports(const char* host, int display) +{ + char text[256]; + int x_running; + int sck; + + x_running = 0; + /* check 59xx */ + { + g_sprintf(text, "59%2.2d", display); + x_running += check_port_status(host, text); + } + /* check 60xx */ + { + g_sprintf(text, "60%2.2d", display); + x_running += check_port_status(host, text); + } + /* check 62xx */ + { + g_sprintf(text, "62%2.2d", display); + x_running += check_port_status(host, text); + } + + return x_running; +} + +/******************************************************************************/ +/** + * * @brief checks if there's a server running on a display * @param display the display to check * @return 0 if there isn't a display running, nonzero otherwise @@ -332,12 +419,13 @@ wait_for_xserver(int display) int i; /* give X a bit to start */ - /* wait up to 10 secs for x server to start */ + /* wait up to 15 secs for x server to start */ i = 0; - while (!x_server_running(display)) + //while (!x_server_running(display)) + while (!x_server_running_check_ports(display)) { i++; - if (i > 40) + if (i > 60) { log_message(LOG_LEVEL_ERROR, "X server for display %d startup timeout", @@ -350,6 +438,57 @@ wait_for_xserver(int display) } /******************************************************************************/ +static int APP_CC +wait_for_remote_xserver(const char* host, int display) +{ + int i; + + /* give X a bit to start */ + /* wait up to 15 secs for x server to start */ + i = 0; + //while (!x_server_running(display)) + while (!x_server_running_check_remote_ports(host, display)) + { + i++; + if (i > 60) + { + log_message(&(g_cfg->log), LOG_LEVEL_ERROR, + "X server for host %s and display %d startup timeout", + host, display); + break; + } + g_sleep(250); + } + return 0; +} + +/******************************************************************************/ +static const char * APP_CC +wait_for_remote_hostname(char* username) +{ + int i; + + /* wait up to 5 secs for hostname to appear */ + i = 0; + const char * hostname = raptor_sm_get_hostname_for_username(username, false); + while (strcmp(hostname, "") == 0) + { + g_free(hostname); + hostname = raptor_sm_get_hostname_for_username(username, false); + i++; + if (i > 20) + { + log_message(&(g_cfg->log), LOG_LEVEL_ERROR, + "Hostname allocation timeout"); + break; + } + g_sleep(250); + } + + return hostname; +} + +/******************************************************************************/ /* called with the main thread */ static int APP_CC session_start_fork(int width, int height, int bpp, char* username, @@ -382,6 +521,8 @@ session_start_fork(int width, int height, int bpp, char* username, g_memset(text,0,sizeof(char) * 256); g_memset(passwd_file,0,sizeof(char) * 256); +log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_start_fork for user %s", username); + /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) { @@ -405,9 +546,24 @@ session_start_fork(int width, int height, int bpp, char* username, "item - user %s", username); return 0; } - display = session_get_aval_display_from_chain(); + char session_was_already_running = 0; + int allocdisplay = raptor_sm_get_display_for_username(username); + if (allocdisplay >= 0) { + session_was_already_running = 1; + display = allocdisplay; + } + else { + int allocdisplay = raptor_sm_get_new_unique_display(g_cfg->sess.x11_display_offset, g_cfg->sess.max_sessions); + if (allocdisplay < 0) { + display = 0; + } + else { + display = allocdisplay; + } + } if (display == 0) { + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "Unable to allocate display for user %s", username); g_free(temp->item); g_free(temp); return 0; @@ -428,10 +584,45 @@ session_start_fork(int width, int height, int bpp, char* username, } else if (wmpid == 0) /* child (child sesman) xserver */ { - wait_for_xserver(display); + char* remote_server = wait_for_remote_hostname(username); + wait_for_remote_xserver(remote_server, display); env_set_user(username, 0, display); - if (x_server_running(display)) + + //if (x_server_running(display)) + if (x_server_running_check_remote_ports(remote_server, display)) { + g_free(remote_server); + +// // RAPTOR session management +// raptor_sm_run_remote_desktop(username, display, "/opt/trinity/bin/starttde"); +// g_exit(0); + + struct list * wm_params = (struct list *)NULL; + char ** pp2 = (char **)NULL; + wm_params = list_create(); + wm_params->auto_free = 1; + /* these are the must have parameters */ + list_add_item(wm_params, (long)g_strdup("/opt/trinity/bin/starttde")); + + /* make sure it ends with a zero */ + list_add_item(wm_params, 0); + pp2 = (char**)wm_params->items; + + pid_t wmpid; + wmpid = raptor_sm_run_remote_server(username, pp2, RAPTOR_SM_WM_PID_FIELD, display); + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "new window manager pid code was %d for user %s", wmpid, username); + + if (wmpid >= 0) { + raptor_sm_wm_started(username, wmpid, RAPTOR_SM_WM_PID_FIELD); + + // Wait for PID exit and remove information from the session database + raptor_sm_wait_for_pid_exit(username, wmpid); + raptor_sm_wm_terminated(username); + raptor_sm_terminate_server(username); + } + + g_exit(0); + auth_set_env(data); if (directory != 0) { @@ -498,8 +689,9 @@ session_start_fork(int width, int height, int bpp, char* username, } else { - log_message(LOG_LEVEL_ERROR, "another Xserver might " - "already be active on display %d - see log", display); + g_free(remote_server); + log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "another Xserver is " + "already active on display %d", display); } log_message(LOG_LEVEL_DEBUG,"aborting connection..."); g_exit(0); @@ -550,6 +742,8 @@ session_start_fork(int width, int height, int bpp, char* username, list_add_item(xserver_params, (long)g_strdup(geometry)); list_add_item(xserver_params, (long)g_strdup("-depth")); list_add_item(xserver_params, (long)g_strdup(depth)); + list_add_item(xserver_params, (long)g_strdup("-reset")); +// list_add_item(xserver_params, (long)g_strdup("-terminate")); // WARNING this breaks TDE! /* additional parameters from sesman.ini file */ //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, @@ -559,8 +753,31 @@ session_start_fork(int width, int height, int bpp, char* username, /* make sure it ends with a zero */ list_add_item(xserver_params, 0); pp1 = (char**)xserver_params->items; - log_message(LOG_LEVEL_INFO,"X11rdp start:%s",dumpItemsToString(xserver_params, execvpparams, 2048)); - g_execvp("X11rdp", pp1); + + pid_t serverpid; + serverpid = raptor_sm_run_remote_server(username, pp1, RAPTOR_SM_SERVER_PID_FIELD, -1); + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "new server pid code was %d during login for user %s", serverpid, username); + + if (serverpid >= 0) { + if (!session_was_already_running) { + char *friendlyscreen = g_strdup(screen); + friendlyscreen[0] = ' '; + raptor_sm_server_started(username, serverpid, atoi(friendlyscreen), RAPTOR_SM_SERVER_PID_FIELD); + g_free(friendlyscreen); + + // Wait for PID exit and remove information from the session database + raptor_sm_wait_for_pid_exit(username, serverpid); + raptor_sm_session_terminated(username); + } + } + else { + raptor_sm_session_terminated(username); + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "max concurrent session limit " + "exceeded in group. login for user %s denied", username); + g_exit(1); + } + + g_exit(0); } else { @@ -589,7 +806,10 @@ session_start_fork(int width, int height, int bpp, char* username, } else /* parent (child sesman)*/ { - wait_for_xserver(display); + //wait_for_xserver(display); + char* remote_server = wait_for_remote_hostname(username); + wait_for_remote_xserver(remote_server, display); + free(remote_server); g_snprintf(text, 255, "%d", display); g_setenv("XRDP_SESSVC_DISPLAY", text, 1); g_snprintf(text, 255, ":%d.0", display); @@ -663,6 +883,7 @@ session_start(int width, int height, int bpp, char* username, char* password, long data, tui8 type, char* domain, char* program, char* directory, char* client_ip) { +log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_start"); int display; /* lock mutex */ @@ -717,19 +938,11 @@ session_reconnect(int display, char* username) int APP_CC session_sync_start(void) { - if (g_sync_cmd == 0) - { - g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, - g_sync_username, g_sync_password, - g_sync_data, g_sync_type, g_sync_domain, - g_sync_program, g_sync_directory, - g_sync_client_ip); - } - else - { - /* g_sync_width is really display */ - g_sync_result = session_reconnect_fork(g_sync_width, g_sync_username); - } +log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 259.0] In session_sync_start"); + g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp, + g_sync_username, g_sync_password, + g_sync_data, g_sync_type, g_sync_domain, + g_sync_program, g_sync_directory, g_sync_client_ip); lock_sync_sem_release(); return 0; } diff --git a/sesman/startwm.sh b/sesman/startwm.sh index 02fc7956..85b99860 100755 --- a/sesman/startwm.sh +++ b/sesman/startwm.sh @@ -3,7 +3,7 @@ # change the order in line below to run to run whatever window manager you # want, default to kde -SESSIONS="gnome-session blackbox fluxbox startxfce4 startkde xterm" +SESSIONS="starttde gnome-session blackbox fluxbox startxfce4 startkde xterm" #start the window manager wm_start() @@ -81,6 +81,8 @@ post_start() #PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" #export PATH=$PATH +export PATH=/opt/trinity/sbin:/opt/trinity/bin:$PATH + # for PATH and LANG from /etc/environment # pam will auto process the environment file if /etc/pam.d/xrdp-sesman # includes |