Add preliminary Raptor session management

Raptorsmiface pulled from latest old master, changelog merged down to single commit
Due to the latest raptorsmiface code being used, this will not compile (yet)
master
Timothy Pearson 6 years ago
parent 4ff3578d7a
commit 58e06a0aa7

@ -49,6 +49,7 @@ endif
SUBDIRS = \ SUBDIRS = \
common \ common \
raptorsmiface \
vnc \ vnc \
xup \ xup \
mc \ mc \

@ -342,6 +342,7 @@ AC_CHECK_HEADERS([sys/prctl.h])
AC_CONFIG_FILES([ AC_CONFIG_FILES([
common/Makefile common/Makefile
raptorsmiface/Makefile
docs/Makefile docs/Makefile
docs/man/Makefile docs/man/Makefile
genkeymap/Makefile genkeymap/Makefile

@ -0,0 +1,32 @@
EXTRA_DIST = libraptorsmiface.h
EXTRA_DEFINES =
EXTRA_INCLUDES =
EXTRA_LIBS =
EXTRA_FLAGS =
EXTRA_INCLUDES += -I$(prefix)/include
EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
$(EXTRA_DEFINES)
AM_CPPFLAGS = \
-I$(top_srcdir)/common \
$(EXTRA_INCLUDES)
lib_LTLIBRARIES = \
libraptorsmiface.la
libraptorsmiface_la_SOURCES = \
libraptorsmiface.c
libraptorsmiface_la_LDFLAGS = \
$(EXTRA_FLAGS) -lmysqlclient
libraptorsmiface_la_LIBADD = \
$(EXTRA_LIBS)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,66 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
(c) 2012 Timothy Pearson
(c) 2012 Raptor Engineering
*/
#include <unistd.h>
#include <sys/types.h>
typedef unsigned char bool;
#define true 1
#define false 0
// SM_STATUS_ALLOCATED: Server is not yet started
// SM_STATUS_RUNNING: Server is up, but client is not connected
// SM_STATUS_CONNECTED: Server is up and client is connected
enum raptor_sm_status {
SM_STATUS_ALLOCATED,
SM_STATUS_RUNNING,
SM_STATUS_CONNECTED,
SM_STATUS_FORCEKILL
};
#define RAPTOR_SM_SERVER_PID_FIELD "server_pid"
#define RAPTOR_SM_WM_PID_FIELD "wm_pid"
#define RAPTOR_SM_BASE_PULSEAUDIO_PORT 2000
#define RAPTOR_SM_MANAGEMENT_SERVER_IP_NETRANGE "10.0.0.0/8"
char* raptor_sm_get_local_machine_fqdn();
char* raptor_sm_get_ip_for_hostname(char* hostname, char* err);
char* raptor_sm_get_hostname_for_username(char* username, bool create);
char* raptor_sm_get_ip_for_username(char* username, bool create);
pid_t raptor_sm_run_remote_server(char* username, char *const argv[], char* dbfield, int display);
pid_t raptor_sm_get_pid_for_username(char* username, char* dbfield);
int raptor_sm_server_started(char* username, pid_t pid, int display, char* dbfield);
int raptor_sm_wm_started(char* username, pid_t pid, char* dbfield);
int raptor_sm_get_display_for_username(char* username);
void raptor_sm_wait_for_pid_exit(char* username, pid_t pid);
char* raptor_sm_get_username_for_display_and_hostname(int display, char* hostname);
void raptor_sm_session_terminated(char* username);
int raptor_sm_wm_terminated(char* username);
int raptor_sm_get_new_unique_display(int mindisplay, int maxdisplay);
bool raptor_sm_sesslimit_reached(char* username);
char raptor_sm_set_session_state(int display, int state);
void raptor_sm_run_remote_desktop(char* username, int display, char* executable);
void raptor_sm_terminate_server(char* username);
char* raptor_sm_get_hostname_for_display(int display);
int raptor_sm_stats_report_server_start(char* hostname);
int raptor_sm_stats_report_server_stop(char* hostname);

@ -9,7 +9,8 @@ AM_CPPFLAGS = \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-DXRDP_SOCKET_PATH=\"${socketdir}\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/sesman/libscp -I$(top_srcdir)/sesman/libscp \
-I$(top_srcdir)/raptorsmiface
if XRDP_DEBUG if XRDP_DEBUG
AM_CPPFLAGS += -DXRDP_DEBUG AM_CPPFLAGS += -DXRDP_DEBUG
@ -70,6 +71,7 @@ xrdp_sesman_SOURCES = \
xrdp_sesman_LDADD = \ xrdp_sesman_LDADD = \
$(top_builddir)/common/libcommon.la \ $(top_builddir)/common/libcommon.la \
$(top_builddir)/sesman/libscp/libscp.la \ $(top_builddir)/sesman/libscp/libscp.la \
$(top_builddir)/raptorsmiface/libraptorsmiface.la \
$(AUTH_LIB) \ $(AUTH_LIB) \
-lpthread -lpthread

@ -9,7 +9,8 @@ AM_CPPFLAGS = \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \ -DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
-DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
-DXRDP_SOCKET_PATH=\"${socketdir}\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \
-I$(top_srcdir)/common -I$(top_srcdir)/common \
-I$(top_srcdir)/raptorsmiface
if XRDP_DEBUG if XRDP_DEBUG
AM_CPPFLAGS += -DXRDP_DEBUG AM_CPPFLAGS += -DXRDP_DEBUG
@ -77,5 +78,6 @@ xrdp_chansrv_LDFLAGS = \
xrdp_chansrv_LDADD = \ xrdp_chansrv_LDADD = \
$(top_builddir)/common/libcommon.la \ $(top_builddir)/common/libcommon.la \
$(top_builddir)/raptorsmiface/libraptorsmiface.la \
$(X_PRE_LIBS) -lXfixes -lXrandr -lX11 $(X_EXTRA_LIBS) \ $(X_PRE_LIBS) -lXfixes -lXrandr -lX11 $(X_EXTRA_LIBS) \
$(CHANSRV_EXTRA_LIBS) $(CHANSRV_EXTRA_LIBS)

@ -1,6 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Timothy Pearson 2012-2019
* Copyright (C) Jay Sorg 2009-2013 * Copyright (C) Jay Sorg 2009-2013
* Copyright (C) Laxmikant Rashinkar 2009-2012 * Copyright (C) Laxmikant Rashinkar 2009-2012
* *
@ -38,6 +39,8 @@
#include "chansrv_fuse.h" #include "chansrv_fuse.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
#include "libraptorsmiface.h"
static struct trans *g_lis_trans = 0; static struct trans *g_lis_trans = 0;
static struct trans *g_con_trans = 0; static struct trans *g_con_trans = 0;
static struct trans *g_api_lis_trans = 0; static struct trans *g_api_lis_trans = 0;
@ -60,6 +63,32 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */
int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rdpdr_chan_id = -1; /* rdpdr */
int g_rail_chan_id = -1; /* rail */ int g_rail_chan_id = -1; /* rail */
#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
char *g_exec_name; char *g_exec_name;
tbus g_exec_event; tbus g_exec_event;
tbus g_exec_mutex; tbus g_exec_mutex;
@ -414,6 +443,8 @@ process_message_channel_setup(struct stream *s)
rail_init(); 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; return rv;
} }
@ -1435,6 +1466,9 @@ channel_thread_loop(void *in_val)
/* delete g_con_trans */ /* delete g_con_trans */
trans_delete(g_con_trans); trans_delete(g_con_trans);
g_con_trans = 0; 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 */ /* create new listener */
error = setup_listen(); error = setup_listen();
@ -1904,6 +1938,8 @@ main(int argc, char **argv)
} }
} }
/* 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 */ /* cleanup */
main_cleanup(); main_cleanup();
LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));

@ -29,7 +29,7 @@ X11DisplayOffset=10
;; MaxSessions - maximum number of connections to an xrdp server ;; MaxSessions - maximum number of connections to an xrdp server
; Type: integer ; Type: integer
; Default: 0 ; Default: 0
MaxSessions=50 MaxSessions=1000000
;; KillDisconnected - kill disconnected sessions ;; KillDisconnected - kill disconnected sessions
; Type: boolean ; Type: boolean

@ -42,6 +42,8 @@
#include "xauth.h" #include "xauth.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
#include "libraptorsmiface.h"
#ifndef PR_SET_NO_NEW_PRIVS #ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38 #define PR_SET_NO_NEW_PRIVS 38
#endif #endif
@ -448,7 +450,21 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
return 0; return 0;
} }
display = session_get_avail_display_from_chain(); char session_was_already_running = 0;
int allocdisplay = raptor_sm_get_display_for_username(s->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) if (display == 0)
{ {
@ -533,6 +549,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
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(display)) if (x_server_running(display))
{ {
auth_set_env(data); auth_set_env(data);
@ -705,7 +724,29 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
g_setenv("XRDP_START_HEIGHT", geometry, 1); g_setenv("XRDP_START_HEIGHT", geometry, 1);
/* fire up Xorg */ /* fire up Xorg */
g_execvp(xserver, pp1); pid_t serverpid;
serverpid = raptor_sm_run_remote_server(s->username, pp1);
if (serverpid >= 0) {
if (!session_was_already_running) {
char *friendlyscreen = g_strdup(screen);
friendlyscreen[0] = ' ';
raptor_sm_server_started(s->username, serverpid, atoi(friendlyscreen));
g_free(friendlyscreen);
// Wait for PID exit and remove information from the session database
raptor_sm_wait_for_pid_exit(s->username, serverpid);
raptor_sm_session_terminated(s->username);
}
}
else {
raptor_sm_session_terminated(s->username);
log_message(LOG_LEVEL_WARNING, "max concurrent session limit "
"exceeded in group. login for user %s denied", s->username);
g_exit(1);
}
g_exit(0);
} }
else if (type == SESMAN_SESSION_TYPE_XVNC) else if (type == SESMAN_SESSION_TYPE_XVNC)
{ {

@ -12,7 +12,8 @@ AM_CPPFLAGS = \
-DXRDP_SOCKET_PATH=\"${socketdir}\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \
-I$(top_builddir) \ -I$(top_builddir) \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/libxrdp -I$(top_srcdir)/libxrdp \
-I$(top_srcdir)/raptorsmiface
XRDP_EXTRA_LIBS = XRDP_EXTRA_LIBS =
@ -63,6 +64,7 @@ xrdp_SOURCES = \
xrdp_LDADD = \ xrdp_LDADD = \
$(top_builddir)/common/libcommon.la \ $(top_builddir)/common/libcommon.la \
$(top_builddir)/libxrdp/libxrdp.la \ $(top_builddir)/libxrdp/libxrdp.la \
$(top_builddir)/raptorsmiface/libraptorsmiface.la \
$(XRDP_EXTRA_LIBS) $(XRDP_EXTRA_LIBS)
xrdpsysconfdir=$(sysconfdir)/xrdp xrdpsysconfdir=$(sysconfdir)/xrdp

@ -24,6 +24,8 @@
#include "xrdp.h" #include "xrdp.h"
#include "log.h" #include "log.h"
#include "libraptorsmiface.h"
#ifndef USE_NOPAM #ifndef USE_NOPAM
#if defined(HAVE__PAM_TYPES_H) #if defined(HAVE__PAM_TYPES_H)
#define LINUXPAM 1 #define LINUXPAM 1
@ -59,6 +61,7 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->wm = owner; self->wm = owner;
self->login_names = list_create(); self->login_names = list_create();
self->login_names->auto_free = 1; self->login_names->auto_free = 1;
self->login_username = 0;
self->login_values = list_create(); self->login_values = list_create();
self->login_values->auto_free = 1; self->login_values->auto_free = 1;
@ -190,6 +193,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
if (g_strcasecmp(name, "username") == 0) if (g_strcasecmp(name, "username") == 0)
{ {
username = value; username = value;
self->login_username = g_strdup(username);
} }
else if (g_strcasecmp(name, "password") == 0) else if (g_strcasecmp(name, "password") == 0)
{ {
@ -521,16 +525,30 @@ 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);
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);
raptor_sm_session_terminated(self->login_username);
return 1;
}
else {
if (allocdisplay >= 0) {
self->display = allocdisplay;
}
self->mod->mod_set_param(self->mod, "ip", rsmip);
use_uds = 1; use_uds = 1;
if (g_strcmp(rsmip, "127.0.0.1") != 0) {
if (xrdp_mm_get_value(self, "ip", text, 255) == 0)
{
if (g_strcmp(text, "127.0.0.1") != 0)
{
use_uds = 0; use_uds = 0;
} }
} }
g_free(rsmip);
if (use_uds) if (use_uds)
{ {
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display); g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
@ -576,8 +594,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid)
{ {
name = (const char *) list_get_item(self->login_names, i); name = (const char *) list_get_item(self->login_names, i);
value = (const char *) list_get_item(self->login_values, i); value = (const char *) list_get_item(self->login_values, i);
if (strcmp(name, "ip") != 0) {
self->mod->mod_set_param(self->mod, name, value); self->mod->mod_set_param(self->mod, name, value);
} }
}
/* connect */ /* connect */
if (self->mod->mod_connect(self->mod) == 0) if (self->mod->mod_connect(self->mod) == 0)
@ -1546,8 +1566,7 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
if (ok) if (ok)
{ {
self->display = display; self->display = display;
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "login successful on display %d", display);
"login successful for display %d", display);
if (xrdp_mm_setup_mod1(self) == 0) if (xrdp_mm_setup_mod1(self) == 0)
{ {

@ -294,6 +294,7 @@ struct xrdp_mm
int chan_trans_up; /* true once connected to chansrv */ int chan_trans_up; /* true once connected to chansrv */
int delete_chan_trans; /* boolean set when done with channel connection */ int delete_chan_trans; /* boolean set when done with channel connection */
int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */ int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
char* login_username; /* RAPTOR */
struct xrdp_encoder *encoder; struct xrdp_encoder *encoder;
int cs2xr_cid_map[256]; int cs2xr_cid_map[256];
int xr2cr_cid_map[256]; int xr2cr_cid_map[256];

Loading…
Cancel
Save