summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineering.com>2019-03-02 19:39:52 -0600
committerTimothy Pearson <tpearson@raptorengineering.com>2019-03-02 19:49:22 -0600
commit315b8914c853078d8bb04a7d16e47d19128ca318 (patch)
tree5e64fe8ea46443663d287360c5b6b45aea095fb1
parent58e06a0aa7db8e0762b31304ead0c3e0df5a7be4 (diff)
downloadxrdp-proprietary-315b8914c853078d8bb04a7d16e47d19128ca318.tar.gz
xrdp-proprietary-315b8914c853078d8bb04a7d16e47d19128ca318.zip
Second batch of initial commits:
* Add server/group pamming * Partially fix immediate exit after login Still will not compile due to libraptorsmiface being too new
-rw-r--r--common/defines.h2
-rw-r--r--common/trans.c50
-rw-r--r--sesman/chansrv/chansrv.c4
-rw-r--r--sesman/scp_v0.c12
-rw-r--r--sesman/scp_v1.c9
-rw-r--r--sesman/session.c168
-rw-r--r--xrdp/xrdp_mm.c36
-rw-r--r--xup/xup.c104
8 files changed, 368 insertions, 17 deletions
diff --git a/common/defines.h b/common/defines.h
index d87ddae7..74723f45 100644
--- a/common/defines.h
+++ b/common/defines.h
@@ -21,6 +21,8 @@
#ifndef DEFINES_H
#define DEFINES_H
+#define DISABLE_UNIX_DOMAIN_SOCKETS 1
+
/* check for debug */
#ifdef XRDP_DEBUG
#define DEBUG(args) g_writeln args;
diff --git a/common/trans.c b/common/trans.c
index 5909e4eb..84fafe43 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -512,6 +512,7 @@ trans_force_read(struct trans *self, int size)
}
/*****************************************************************************/
+#if 0
int
trans_force_write_s(struct trans *self, struct stream *out_s)
{
@@ -571,6 +572,55 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
}
return 0;
}
+#else
+// DEBUG
+/*****************************************************************************/
+int
+trans_force_write_s(struct trans* self, struct stream* out_s)
+{
+ int size;
+ int total;
+ int sent;
+
+ if (self->status != TRANS_STATUS_UP)
+ {
+ return 1;
+ }
+ size = (int)(out_s->end - out_s->data);
+ total = 0;
+ while (total < size)
+ {
+ sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0);
+ if (sent == -1)
+ {
+ if (g_tcp_last_error_would_block(self->sck))
+ {
+ if (!g_tcp_can_send(self->sck, 10))
+ {
+ /* check for term here */
+ }
+ }
+ else
+ {
+ /* error */
+ self->status = TRANS_STATUS_DOWN;
+ return 2;
+ }
+ }
+ else if (sent == 0)
+ {
+ /* error */
+ self->status = TRANS_STATUS_DOWN;
+ return 3;
+ }
+ else
+ {
+ total = total + sent;
+ }
+ }
+ return 0;
+}
+#endif
/*****************************************************************************/
int
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 12614f51..3a99cf6c 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -1468,7 +1468,6 @@ channel_thread_loop(void *in_val)
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);
- exit(0); // RAPTOR session management
/* create new listener */
error = setup_listen();
@@ -1678,7 +1677,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)
@@ -1686,6 +1685,7 @@ read_ini(void)
g_use_unix_socket = 1;
}
}
+#endif
}
}
diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c
index cc3712cc..13a1bfc8 100644
--- a/sesman/scp_v0.c
+++ b/sesman/scp_v0.c
@@ -30,6 +30,8 @@
#include "sesman.h"
+#include "libraptorsmiface.h"
+
extern struct config_sesman *g_cfg; /* in sesman.c */
/******************************************************************************/
@@ -79,6 +81,16 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
s_item = session_get_bydata(s->username, s->width, s->height,
s->bpp, s->type, s->client_ip);
+ // RAPTOR session management
+ pid_t serverpid = raptor_sm_get_pid_for_username(s->username);
+ if (serverpid < 0) {
+ // Session NOT already running
+ if (s_item != 0) {
+ log_message( LOG_LEVEL_INFO, "++ [FIXME] scp claimed there was an active session, but the authoritative RAPTOR database disagrees: username %s", s->username);
+ }
+ s_item = 0;
+ }
+
if (s_item != 0)
{
display = s_item->display;
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index 60f82112..607aeca5 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -33,6 +33,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, const char *f);
@@ -109,6 +111,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);
+ if (serverpid < 0) {
+ // Session NOT already running
+ scount = 0;
+ }
+
if (scount == 0)
{
/* no disconnected sessions - start a new one */
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);
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 1bb7ea15..d62947fa 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -21,6 +21,7 @@
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
+#include <string.h>
#include "xrdp.h"
#include "log.h"
@@ -494,6 +495,7 @@ static int
xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
{
char text[256];
+ char raptortext[256];
const char *name;
const char *value;
int i;
@@ -526,14 +528,24 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
{
char* rsmip = raptor_sm_get_ip_for_username(self->login_username, true);
+ if (strcmp(rsmip, "ERROR") == 0) {
+ g_snprintf(raptortext, 255, "[LICENSE] Instantaneous limit exceeded.");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
+ g_snprintf(raptortext, 255, "[LICENSE] Login for user %s denied.", self->login_username);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
+ g_free(rsmip);
+ raptor_sm_session_terminated(self->login_username);
+ return 1;
+ }
int allocdisplay = raptor_sm_get_display_for_username(self->login_username);
if ((raptor_sm_sesslimit_reached(self->login_username)) && (allocdisplay < 0)) {
- g_snprintf(text, 255, "[LICENSE] Maximum concurrent session");
- xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text);
- g_snprintf(text, 255, "[LICENSE] limit exceeded for group.");
- xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text);
- g_snprintf(text, 255, "[LICENSE] Login for user %s denied.", self->login_username);
- xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text);
+ g_snprintf(raptortext, 255, "[LICENSE] Maximum concurrent session");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
+ g_snprintf(raptortext, 255, "[LICENSE] limit exceeded for group.");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
+ g_snprintf(raptortext, 255, "[LICENSE] Login for user %s denied.", self->login_username);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
+ g_free(rsmip);
raptor_sm_session_terminated(self->login_username);
return 1;
}
@@ -542,10 +554,14 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
self->display = allocdisplay;
}
self->mod->mod_set_param(self->mod, "ip", rsmip);
+#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
+ use_uds = 0;
+#else
use_uds = 1;
if (g_strcmp(rsmip, "127.0.0.1") != 0) {
use_uds = 0;
}
+#endif
}
g_free(rsmip);
@@ -1432,7 +1448,11 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port)
self->usechansrv = 1;
/* connect channel redir */
+#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
+ if (0)
+#else
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
+#endif
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
@@ -1577,7 +1597,11 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
self->wm->dragging = 0;
/* connect channel redir */
+#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
+ if (0)
+#else
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
+#endif
{
g_snprintf(port, 255, XRDP_CHANSRV_STR, display);
}
diff --git a/xup/xup.c b/xup/xup.c
index 91eb0563..a96c362c 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -32,6 +32,98 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+#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>
+
+/******************************************************************************/
+/**
++ *
++ * @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_port(const char* host, const char* port)
+{
+ int x_running;
+ int sck;
+
+ x_running = 0;
+ x_running += check_port_status(host, port);
+
+ return x_running;
+}
+
+/******************************************************************************/
+static int
+wait_for_remote_xserver(const char* host, const char* port)
+{
+ int i;
+
+ /* give X a bit to start */
+ /* wait up to 15 secs for x server to start */
+ i = 0;
+ while (!x_server_running_check_remote_port(host, port))
+ {
+ i++;
+ if (i > 60)
+ {
+ break;
+ }
+ g_sleep(250);
+ }
+ return 0;
+}
+
+
static int
lib_mod_process_message(struct mod *mod, struct stream *s);
@@ -164,6 +256,18 @@ lib_mod_connect(struct mod *mod)
return 1;
}
+ char text[256];
+ g_snprintf(text, 255, "allocating resources on %s, please wait...\n\r", mod->ip);
+ mod->server_msg(mod, text, 0);
+
+ // Prevent an immediate RDP exit
+ wait_for_remote_xserver(mod->ip, mod->port);
+
+ // FIXME CRITICAL
+ // Prevent an immediate RDP exit
+ // Why is this still needed even after waiting for the X11rdp server to start!?!?
+ g_sleep(5000);
+
if (g_strcmp(mod->ip, "") == 0)
{
mod->server_msg(mod, "error - no ip set", 0);