diff options
Diffstat (limited to 'sesman/session.c')
-rw-r--r-- | sesman/session.c | 168 |
1 files changed, 159 insertions, 9 deletions
diff --git a/sesman/session.c b/sesman/session.c index 6fa63c3a..7a6173bf 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -42,6 +42,16 @@ #include "xauth.h" #include "xrdp_sockets.h" +#include <string.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" #ifndef PR_SET_NO_NEW_PRIVS @@ -161,6 +171,82 @@ session_get_bydata(const 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 +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 +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 @@ -330,14 +416,14 @@ 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_check_ports(display)) { i++; - if (i > 40) + if (i > 60) { log_message(LOG_LEVEL_ERROR, "X server for display %d startup timeout", @@ -388,6 +474,57 @@ session_start_chansrv(char *username, int display) } /******************************************************************************/ +static int +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(LOG_LEVEL_ERROR, + "X server for host %s and display %d startup timeout", + host, display); + break; + } + g_sleep(250); + } + return 0; +} + +/******************************************************************************/ +static const char * +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(LOG_LEVEL_ERROR, + "Hostname allocation timeout"); + break; + } + g_sleep(250); + } + + return hostname; +} + +/******************************************************************************/ /* called with the main thread */ static int session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, @@ -468,6 +605,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, if (display == 0) { + log_message(LOG_LEVEL_ALWAYS, "Unable to allocate display for user %s", s->username); g_free(temp->item); g_free(temp); return 0; @@ -543,17 +681,25 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, } else if (window_manager_pid == 0) { - wait_for_xserver(display); + if (session_was_already_running) { + g_exit(0); + } + char* remote_server = wait_for_remote_hostname(s->username); + wait_for_remote_xserver(remote_server, display); env_set_user(s->username, 0, display, g_cfg->env_names, g_cfg->env_values); - if (session_was_already_running) { - g_exit(0); - } - 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(s->username, display, "/opt/trinity/bin/starttde"); + g_exit(0); + auth_set_env(data); if (s->directory != 0) { @@ -619,6 +765,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, } else { + g_free(remote_server); log_message(LOG_LEVEL_ERROR, "another Xserver might " "already be active on display %d - see log", display); } @@ -726,6 +873,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, /* fire up Xorg */ pid_t serverpid; serverpid = raptor_sm_run_remote_server(s->username, pp1); + log_message(LOG_LEVEL_ALWAYS, "new server pid code was %d during login for user %s", serverpid, s->username); if (serverpid >= 0) { if (!session_was_already_running) { @@ -841,7 +989,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, } else { - wait_for_xserver(display); + char* remote_server = wait_for_remote_hostname(s->username); + wait_for_remote_xserver(remote_server, display); + free(remote_server); chansrv_pid = session_start_chansrv(s->username, display); log_message(LOG_LEVEL_ALWAYS, "waiting for window manager " "(pid %d) to exit", window_manager_pid); |