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
master
Timothy Pearson 6 years ago
parent 58e06a0aa7
commit 315b8914c8

@ -21,6 +21,8 @@
#ifndef DEFINES_H #ifndef DEFINES_H
#define DEFINES_H #define DEFINES_H
#define DISABLE_UNIX_DOMAIN_SOCKETS 1
/* check for debug */ /* check for debug */
#ifdef XRDP_DEBUG #ifdef XRDP_DEBUG
#define DEBUG(args) g_writeln args; #define DEBUG(args) g_writeln args;

@ -512,6 +512,7 @@ trans_force_read(struct trans *self, int size)
} }
/*****************************************************************************/ /*****************************************************************************/
#if 0
int int
trans_force_write_s(struct trans *self, struct stream *out_s) 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; 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 int

@ -1468,7 +1468,6 @@ channel_thread_loop(void *in_val)
g_con_trans = 0; g_con_trans = 0;
/* use the display number to mark session disconnected in the Raptor session management database */ /* 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); raptor_sm_set_session_state(g_display_num, SM_STATUS_RUNNING);
exit(0); // RAPTOR session management
/* create new listener */ /* create new listener */
error = setup_listen(); error = setup_listen();
@ -1678,7 +1677,7 @@ read_ini(void)
{ {
name = (char *)list_get_item(names, index); name = (char *)list_get_item(names, index);
value = (char *)list_get_item(values, index); value = (char *)list_get_item(values, index);
#ifndef DISABLE_UNIX_DOMAIN_SOCKETS
if (g_strcasecmp(name, "ListenAddress") == 0) if (g_strcasecmp(name, "ListenAddress") == 0)
{ {
if (g_strcasecmp(value, "127.0.0.1") == 0) if (g_strcasecmp(value, "127.0.0.1") == 0)
@ -1686,6 +1685,7 @@ read_ini(void)
g_use_unix_socket = 1; g_use_unix_socket = 1;
} }
} }
#endif
} }
} }

@ -30,6 +30,8 @@
#include "sesman.h" #include "sesman.h"
#include "libraptorsmiface.h"
extern struct config_sesman *g_cfg; /* in sesman.c */ 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_item = session_get_bydata(s->username, s->width, s->height,
s->bpp, s->type, s->client_ip); 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) if (s_item != 0)
{ {
display = s_item->display; display = s_item->display;

@ -33,6 +33,8 @@
//#include "libscp_types.h" //#include "libscp_types.h"
#include "libscp.h" #include "libscp.h"
#include "libraptorsmiface.h"
extern struct config_sesman *g_cfg; /* in sesman.c */ extern struct config_sesman *g_cfg; /* in sesman.c */
static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f); 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 */ /* list disconnected sessions */
slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); 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) if (scount == 0)
{ {
/* no disconnected sessions - start a new one */ /* no disconnected sessions - start a new one */

@ -42,6 +42,16 @@
#include "xauth.h" #include "xauth.h"
#include "xrdp_sockets.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" #include "libraptorsmiface.h"
#ifndef PR_SET_NO_NEW_PRIVS #ifndef PR_SET_NO_NEW_PRIVS
@ -158,6 +168,82 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
return 0; return 0;
} }
/******************************************************************************/
/**
*
* @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;
}
/******************************************************************************/ /******************************************************************************/
/** /**
* *
@ -330,14 +416,14 @@ wait_for_xserver(int display)
int i; int i;
/* give X a bit to start */ /* 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; i = 0;
while (!x_server_running(display)) while (!x_server_running_check_ports(display))
{ {
i++; i++;
if (i > 40) if (i > 60)
{ {
log_message(LOG_LEVEL_ERROR, log_message(LOG_LEVEL_ERROR,
"X server for display %d startup timeout", "X server for display %d startup timeout",
@ -387,6 +473,57 @@ session_start_chansrv(char *username, int display)
return chansrv_pid; return chansrv_pid;
} }
/******************************************************************************/
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 */ /* called with the main thread */
static int static int
@ -468,6 +605,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
if (display == 0) if (display == 0)
{ {
log_message(LOG_LEVEL_ALWAYS, "Unable to allocate display for user %s", s->username);
g_free(temp->item); g_free(temp->item);
g_free(temp); g_free(temp);
return 0; return 0;
@ -543,17 +681,25 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
} }
else if (window_manager_pid == 0) 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, env_set_user(s->username,
0, 0,
display, display,
g_cfg->env_names, g_cfg->env_names,
g_cfg->env_values); g_cfg->env_values);
if (session_was_already_running) {
g_exit(0); if (x_server_running_check_remote_ports(remote_server, display))
}
if (x_server_running(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); auth_set_env(data);
if (s->directory != 0) if (s->directory != 0)
{ {
@ -619,6 +765,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
} }
else else
{ {
g_free(remote_server);
log_message(LOG_LEVEL_ERROR, "another Xserver might " log_message(LOG_LEVEL_ERROR, "another Xserver might "
"already be active on display %d - see log", display); "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 */ /* fire up Xorg */
pid_t serverpid; pid_t serverpid;
serverpid = raptor_sm_run_remote_server(s->username, pp1); 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 (serverpid >= 0) {
if (!session_was_already_running) { if (!session_was_already_running) {
@ -841,7 +989,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
} }
else 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); chansrv_pid = session_start_chansrv(s->username, display);
log_message(LOG_LEVEL_ALWAYS, "waiting for window manager " log_message(LOG_LEVEL_ALWAYS, "waiting for window manager "
"(pid %d) to exit", window_manager_pid); "(pid %d) to exit", window_manager_pid);

@ -21,6 +21,7 @@
#if defined(HAVE_CONFIG_H) #if defined(HAVE_CONFIG_H)
#include <config_ac.h> #include <config_ac.h>
#endif #endif
#include <string.h>
#include "xrdp.h" #include "xrdp.h"
#include "log.h" #include "log.h"
@ -494,6 +495,7 @@ static int
xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid) xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
{ {
char text[256]; char text[256];
char raptortext[256];
const char *name; const char *name;
const char *value; const char *value;
int i; 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 */ else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
{ {
char* rsmip = raptor_sm_get_ip_for_username(self->login_username, true); 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); int allocdisplay = raptor_sm_get_display_for_username(self->login_username);
if ((raptor_sm_sesslimit_reached(self->login_username)) && (allocdisplay < 0)) { if ((raptor_sm_sesslimit_reached(self->login_username)) && (allocdisplay < 0)) {
g_snprintf(text, 255, "[LICENSE] Maximum concurrent session"); g_snprintf(raptortext, 255, "[LICENSE] Maximum concurrent session");
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text); xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
g_snprintf(text, 255, "[LICENSE] limit exceeded for group."); g_snprintf(raptortext, 255, "[LICENSE] limit exceeded for group.");
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text); xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
g_snprintf(text, 255, "[LICENSE] Login for user %s denied.", self->login_username); g_snprintf(raptortext, 255, "[LICENSE] Login for user %s denied.", self->login_username);
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, text); xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING, raptortext);
g_free(rsmip);
raptor_sm_session_terminated(self->login_username); raptor_sm_session_terminated(self->login_username);
return 1; return 1;
} }
@ -542,10 +554,14 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
self->display = allocdisplay; self->display = allocdisplay;
} }
self->mod->mod_set_param(self->mod, "ip", rsmip); self->mod->mod_set_param(self->mod, "ip", rsmip);
#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
use_uds = 0;
#else
use_uds = 1; use_uds = 1;
if (g_strcmp(rsmip, "127.0.0.1") != 0) { if (g_strcmp(rsmip, "127.0.0.1") != 0) {
use_uds = 0; use_uds = 0;
} }
#endif
} }
g_free(rsmip); g_free(rsmip);
@ -1432,7 +1448,11 @@ xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port)
self->usechansrv = 1; self->usechansrv = 1;
/* connect channel redir */ /* connect channel redir */
#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
if (0)
#else
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
#endif
{ {
/* unix socket */ /* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); 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; self->wm->dragging = 0;
/* connect channel redir */ /* connect channel redir */
#ifdef DISABLE_UNIX_DOMAIN_SOCKETS
if (0)
#else
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
#endif
{ {
g_snprintf(port, 255, XRDP_CHANSRV_STR, display); g_snprintf(port, 255, XRDP_CHANSRV_STR, display);
} }

@ -32,6 +32,98 @@
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) 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 static int
lib_mod_process_message(struct mod *mod, struct stream *s); lib_mod_process_message(struct mod *mod, struct stream *s);
@ -164,6 +256,18 @@ lib_mod_connect(struct mod *mod)
return 1; 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) if (g_strcmp(mod->ip, "") == 0)
{ {
mod->server_msg(mod, "error - no ip set", 0); mod->server_msg(mod, "error - no ip set", 0);

Loading…
Cancel
Save