summaryrefslogtreecommitdiffstats
path: root/sesman/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'sesman/session.c')
-rw-r--r--sesman/session.c168
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);