Move SCP to a Unix Domain Socket

The TCP socket implementation of sesman has a number of limitations,
namely that it is affected by firewalls, and also that determining the
user on the other end requires a full authentication process.

The advantage of the TCP socket is that sesman and xrdp can be run on
separate machines. This is however not supported by the xorgxrdp
backend (shared memory), and is insecure, in that passwords are sent
in-the-clear, and the connection is susceptible to MitM attacks. This
architecture has been deprecated in release notes since xrdp v0.9.17,
and although it will continue to be supported in any further releases
in the x0.9.x series, it will not be supported in the next major
version.
This commit is contained in:
matt335672 2022-03-19 11:29:28 +00:00
parent 9c30d4c2f8
commit 0db849fc5c
21 changed files with 335 additions and 286 deletions

View File

@ -28,6 +28,7 @@
#define CHANSRV_API_BASE_STR "xrdpapi_%d" #define CHANSRV_API_BASE_STR "xrdpapi_%d"
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d" #define XRDP_X11RDP_BASE_STR "xrdp_display_%d"
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d" #define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d"
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
/* fullpath of sockets */ /* fullpath of sockets */
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR #define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR

View File

@ -52,10 +52,16 @@ AC_CHECK_SIZEOF([void *])
AC_ARG_WITH([socketdir], AC_ARG_WITH([socketdir],
[AS_HELP_STRING([--with-socketdir=DIR], [AS_HELP_STRING([--with-socketdir=DIR],
[Use directory for UNIX sockets (default: /tmp/.xrdp)])], [Use directory for UNIX sockets for XRDP sessions (default: RUNSTATEDIR/xrdp)])],
[], [with_socketdir="/tmp/.xrdp"]) [], [with_socketdir="$runstatedir/xrdp"])
AC_SUBST([socketdir], [$with_socketdir]) AC_SUBST([socketdir], [$with_socketdir])
AC_ARG_WITH([sesmanruntimedir],
[AS_HELP_STRING([--with-sesmanruntimedir=DIR],
[Use directory for sesman runtime data (default: RUNSTATEDIR/xrdp-sesman))])],
[], [with_sesmanruntimedir="$runstatedir/xrdp-sesman"])
AC_SUBST([sesmanruntimedir], [$with_sesmanruntimedir])
AC_ARG_WITH([systemdsystemunitdir], AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files, no to disable]), AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files, no to disable]),
[], [ [], [
@ -547,6 +553,10 @@ echo " exec_prefix $exec_prefix"
echo " libdir $libdir" echo " libdir $libdir"
echo " bindir $bindir" echo " bindir $bindir"
echo " sysconfdir $sysconfdir" echo " sysconfdir $sysconfdir"
echo " localstatedir $localstatedir"
echo " runstatedir $runstatedir"
echo " socketdir $socketdir"
echo " sesmanruntimedir $sesmanruntimedir"
echo "" echo ""
echo " unit tests performable $perform_unit_tests" echo " unit tests performable $perform_unit_tests"
echo "" echo ""

View File

@ -19,6 +19,7 @@ SUBST_VARS = sed \
-e 's|@localstatedir[@]|$(localstatedir)|g' \ -e 's|@localstatedir[@]|$(localstatedir)|g' \
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-e 's|@socketdir[@]|$(socketdir)|g' \ -e 's|@socketdir[@]|$(socketdir)|g' \
-e 's|@sesmanruntimedir[@]|$(sesmanruntimedir)|g' \
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \ -e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \
-e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g' -e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g'

View File

@ -50,13 +50,19 @@ outside their proper section will be \fIignored\fR.
Following parameters can be used in the \fB[Globals]\fR section. Following parameters can be used in the \fB[Globals]\fR section.
.TP .TP
\fBListenAddress\fR=\fIip address\fR \fBListenPort\fR=\fIpath-to-socket\fR
xrdp-sesman listening address. If not specified, defaults to \fI0.0.0.0\fR UNIX domain socket for xrdp-sesman(8) to listen on.
(all interfaces). .PP
.RS
.TP The default value of this setting is 'sesman.socket'.
\fBListenPort\fR=\fIport number\fR .PP
xrdp-sesman listening port. If not specified, defaults to \fI3350\fR. An absoute path can be specified by starting this parameter with a '/'.
In this instance, the system administrator is responsible for ensuring
the socket can only be created by a suitably privileged process.
.PP
If the parameter does not start with a '/', a name within
@sesmanruntimedir@ is used.
.RE
.TP .TP
\fBEnableUserWindowManager\fR=\fI[true|false]\fR \fBEnableUserWindowManager\fR=\fI[true|false]\fR

View File

@ -26,15 +26,11 @@ Defaults to \fBroot\fP.
The \fIpassword\fP to authenticate with. The \fIpassword\fP to authenticate with.
The default is to ask for the password interactively. The default is to ask for the password interactively.
.TP
.BI \-s= server
The host address of the \fIserver\fP to connect to.
Defaults to \fBlocalhost\fP.
.TP .TP
.BI \-i= port .BI \-i= port
The TCP \fIport\fP number to connect to. The sesman \fIUNIX domain socket\fP to connect to.
Defaults to \fB3350\fP. Defaults to \fBsesman.socket\fP.
If no path is specified for the socket, a default of @sesmanruntimedir@ is used.
.TP .TP
.BI \-c= command .BI \-c= command

View File

@ -58,6 +58,8 @@ to read it.
@localstatedir@/log/xrdp\-sesman.log @localstatedir@/log/xrdp\-sesman.log
.br .br
@localstatedir@/run/xrdp\-sesman.pid @localstatedir@/run/xrdp\-sesman.pid
.br
@sesmanruntimedir@/sesman.socket
.SH "AUTHORS" .SH "AUTHORS"
Jay Sorg <jsorg71@users.sourceforge.net> Jay Sorg <jsorg71@users.sourceforge.net>

View File

@ -29,11 +29,6 @@ option may not do what you expect.
Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg) Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
will ignore this setting. will ignore this setting.
.TP .TP
.B -s <server>
Server on which sesman is running (probably 'localhost').
.br
Use of this option is discouraged as it will be removed in the future.
.TP
.B -t <session-type> .B -t <session-type>
Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
only, use the numeric session code. only, use the numeric session code.

View File

@ -1,5 +1,6 @@
AM_CPPFLAGS = \ AM_CPPFLAGS = \
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
-I$(top_srcdir)/common -I$(top_srcdir)/common
module_LTLIBRARIES = \ module_LTLIBRARIES = \

View File

@ -33,6 +33,7 @@
#include "trans.h" #include "trans.h"
#include "os_calls.h" #include "os_calls.h"
#include "string_calls.h" #include "string_calls.h"
#include "xrdp_sockets.h"
/*****************************************************************************/ /*****************************************************************************/
static const char * static const char *
@ -66,28 +67,97 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size)
return buff; return buff;
} }
/*****************************************************************************/
int
scp_port_to_unix_domain_path(const char *port, char *buff,
unsigned int bufflen)
{
/* GOTCHA: Changes to this logic should be mirrored in
* scp_port_to_display_string() */
int result;
/* Make sure we can safely de-reference 'port' */
if (port == NULL)
{
port = "";
}
if (port[0] == '/')
{
result = g_snprintf(buff, bufflen, "%s", port);
}
else
{
const char *sep;
if ((sep = g_strrchr(port, '/')) != NULL && sep != port)
{
/* We allow the user to specify an absolute path, but not
* a relative one with embedded '/' characters */
LOG(LOG_LEVEL_WARNING, "Ignoring path elements of '%s'", port);
port = sep + 1;
}
if (port[0] == '\0')
{
port = SCP_LISTEN_PORT_BASE_STR;
}
else if (g_strcmp(port, "3350") == 0)
{
/* Version v0.9.x and earlier of xrdp used a TCP port
* number. If we come across this, we'll ignore it for
* compatibility with old config files */
LOG(LOG_LEVEL_WARNING,
"Ignoring obsolete SCP port value '%s'", port);
port = SCP_LISTEN_PORT_BASE_STR;
}
result = g_snprintf(buff, bufflen, SESMAN_RUNTIME_PATH "/%s", port);
}
return result;
}
/*****************************************************************************/
int
scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen)
{
/* Make sure we can safely de-reference 'port' */
if (port == NULL)
{
port = "";
}
/* Ignore any directories for the display */
const char *sep;
if ((sep = g_strrchr(port, '/')) != NULL)
{
port = sep + 1;
}
/* Check for a default */
if (port[0] == '\0' || g_strcmp(port, "3350") == 0)
{
port = SCP_LISTEN_PORT_BASE_STR;
}
return g_snprintf(buff, bufflen, "%s", port);
}
/*****************************************************************************/ /*****************************************************************************/
struct trans * struct trans *
scp_connect(const char *host, const char *port, scp_connect(const char *port,
int (*term_func)(void)) int (*term_func)(void))
{ {
char sock_path[256];
struct trans *t; struct trans *t;
if ((t = trans_create(TRANS_MODE_TCP, 128, 128)) != NULL)
(void)scp_port_to_unix_domain_path(port, sock_path, sizeof(sock_path));
if ((t = trans_create(TRANS_MODE_UNIX, 128, 128)) != NULL)
{ {
if (host == NULL)
{
host = "localhost";
}
if (port == NULL)
{
port = "3350";
}
t->is_term = term_func; t->is_term = term_func;
trans_connect(t, host, port, 3000); if (trans_connect(t, NULL, sock_path, 3000) != 0)
if (t->status != TRANS_STATUS_UP)
{ {
trans_delete(t); trans_delete(t);
t = NULL; t = NULL;

View File

@ -65,11 +65,38 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size);
/* Connection management facilities */ /* Connection management facilities */
/**
* Maps a port definition to a UNIX domain socket path
* @param port Port definition (e.g. from sesman.ini). Can be "" or NULL
* @param buff Buffer for result
* @param bufflen Length of buff
*
* @return Number of chars needed for result, excluding the '\0'
*/
int
scp_port_to_unix_domain_path(const char *port, char *buff,
unsigned int bufflen);
/**
* Maps a port definition to a displayable string
* @param port Port definition (e.g. from sesman.ini). Can be "" or NULL
* @param buff Buffer for result
* @param bufflen Length of buff
*
* @return Number of chars needed for result, excluding the '\0'
*
* This differs from scp_port_to_unix_domain_path() in that the result is
* for displaying to the user (i.e. in a status message), rather than for
* connecting to. For log messages, use the result of
* scp_port_to_unix_domain_path()
*/
int
scp_port_to_display_string(const char *port, char *buff, unsigned int bufflen);
/** /**
* Connect to an SCP server * Connect to an SCP server
* *
* @param host Host providing SCP service * @param port Port definition (e.g. from sesman.ini)
* @param port TCP port for SCP service
* @param term_func Function to poll during connection for program * @param term_func Function to poll during connection for program
* termination, or NULL for none. * termination, or NULL for none.
* @return Initialised SCP transport * @return Initialised SCP transport
@ -77,7 +104,7 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size);
* The returned tranport has the is_term member set to term_func. * The returned tranport has the is_term member set to term_func.
*/ */
struct trans * struct trans *
scp_connect(const char *host, const char *port, scp_connect(const char *port,
int (*term_func)(void)); int (*term_func)(void));
/** /**

View File

@ -8,6 +8,7 @@ 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}\" \
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/libipm -I$(top_srcdir)/libipm

View File

@ -35,6 +35,7 @@
#include "log.h" #include "log.h"
#include "string_calls.h" #include "string_calls.h"
#include "chansrv/chansrv_common.h" #include "chansrv/chansrv_common.h"
#include "scp.h"
/***************************************************************************//** /***************************************************************************//**
* *
@ -51,14 +52,11 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
struct list *param_v) struct list *param_v)
{ {
int i; int i;
int length;
char *buf;
list_clear(param_v); list_clear(param_v);
list_clear(param_n); list_clear(param_n);
/* resetting the struct */ /* resetting the struct */
cf->listen_address[0] = '\0';
cf->listen_port[0] = '\0'; cf->listen_port[0] = '\0';
cf->enable_user_wm = 0; cf->enable_user_wm = 0;
cf->user_wm[0] = '\0'; cf->user_wm[0] = '\0';
@ -70,47 +68,50 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
for (i = 0; i < param_n->count; i++) for (i = 0; i < param_n->count; i++)
{ {
buf = (char *)list_get_item(param_n, i); const char *param = (const char *)list_get_item(param_n, i);
const char *val = (const char *)list_get_item(param_v, i);
if (0 == g_strcasecmp(buf, SESMAN_CFG_DEFWM)) if (0 == g_strcasecmp(param, SESMAN_CFG_DEFWM))
{ {
cf->default_wm = g_strdup((char *)list_get_item(param_v, i)); cf->default_wm = g_strdup(val);
} }
else if (0 == g_strcasecmp(buf, SESMAN_CFG_USERWM)) else if (0 == g_strcasecmp(param, SESMAN_CFG_USERWM))
{ {
g_strncpy(cf->user_wm, (char *)list_get_item(param_v, i), 31); g_strncpy(cf->user_wm, val, sizeof(cf->user_wm) - 1);
} }
else if (0 == g_strcasecmp(buf, SESMAN_CFG_ENABLE_USERWM)) else if (0 == g_strcasecmp(param, SESMAN_CFG_ENABLE_USERWM))
{ {
cf->enable_user_wm = g_text2bool((char *)list_get_item(param_v, i)); cf->enable_user_wm = g_text2bool(val);
} }
else if (0 == g_strcasecmp(buf, SESMAN_CFG_PORT)) else if (0 == g_strcasecmp(param, SESMAN_CFG_PORT))
{ {
g_strncpy(cf->listen_port, (char *)list_get_item(param_v, i), 15); scp_port_to_unix_domain_path(val, cf->listen_port,
sizeof(cf->listen_port));
} }
else if (0 == g_strcasecmp(buf, SESMAN_CFG_ADDRESS)) else if (0 == g_strcasecmp(param, SESMAN_CFG_AUTH_FILE_PATH))
{ {
g_strncpy(cf->listen_address, (char *)list_get_item(param_v, i), 31); cf->auth_file_path = g_strdup(val);
} }
else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH)) else if (g_strcasecmp(param, SESMAN_CFG_RECONNECT_SH) == 0)
{ {
cf->auth_file_path = g_strdup((char *)list_get_item(param_v, i)); cf->reconnect_sh = g_strdup(val);
} }
else if (g_strcasecmp(buf, SESMAN_CFG_RECONNECT_SH) == 0) else if (0 == g_strcasecmp(param, SESMAN_CFG_ADDRESS))
{ {
cf->reconnect_sh = g_strdup((char *)list_get_item(param_v, i)); /* Config must be updated for Unix Domain Sockets */
LOG(LOG_LEVEL_WARNING, "Obsolete setting' " SESMAN_CFG_ADDRESS
"' in [" SESMAN_CFG_GLOBALS "] should be removed.");
LOG(LOG_LEVEL_WARNING, "Review setting' " SESMAN_CFG_PORT "' in ["
SESMAN_CFG_GLOBALS "]");
} }
} }
/* checking for missing required parameters */ /* checking for missing required parameters */
if ('\0' == cf->listen_address[0])
{
g_strncpy(cf->listen_address, "0.0.0.0", 8);
}
if ('\0' == cf->listen_port[0]) if ('\0' == cf->listen_port[0])
{ {
g_strncpy(cf->listen_port, "3350", 5); /* Load the default value */
scp_port_to_unix_domain_path(NULL, cf->listen_port,
sizeof(cf->listen_port));
} }
if ('\0' == cf->user_wm[0]) if ('\0' == cf->user_wm[0])
@ -118,46 +119,40 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
cf->enable_user_wm = 0; cf->enable_user_wm = 0;
} }
if (cf->default_wm == 0) if (cf->default_wm == 0 || cf->default_wm[0] == '\0')
{
cf->default_wm = g_strdup("startwm.sh");
}
else if (g_strlen(cf->default_wm) == 0)
{ {
g_free(cf->default_wm); g_free(cf->default_wm);
cf->default_wm = g_strdup("startwm.sh"); cf->default_wm = g_strdup("startwm.sh");
} }
/* if default_wm doesn't begin with '/', it's a relative path to XRDP_CFG_PATH */ /* if default_wm doesn't begin with '/', it's a relative path to
* XRDP_CFG_PATH */
if (cf->default_wm[0] != '/') if (cf->default_wm[0] != '/')
{ {
/* sizeof operator returns string length including null terminator */ /* sizeof operator returns string length including null terminator */
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->default_wm) + 1; /* '/' */ int length = (sizeof(XRDP_CFG_PATH) +
buf = (char *)g_malloc(length, 0); g_strlen(cf->default_wm) + 1); /* '/' */
char *buf = (char *)g_malloc(length, 0);
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->default_wm); g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->default_wm);
g_free(cf->default_wm); g_free(cf->default_wm);
cf->default_wm = g_strdup(buf); cf->default_wm = buf;
g_free(buf);
} }
if (cf->reconnect_sh == 0) if (cf->reconnect_sh == 0 || cf->reconnect_sh[0] == '\0')
{
cf->reconnect_sh = g_strdup("reconnectwm.sh");
}
else if (g_strlen(cf->reconnect_sh) == 0)
{ {
g_free(cf->reconnect_sh); g_free(cf->reconnect_sh);
cf->reconnect_sh = g_strdup("reconnectwm.sh"); cf->reconnect_sh = g_strdup("reconnectwm.sh");
} }
/* if reconnect_sh doesn't begin with '/', it's a relative path to XRDP_CFG_PATH */ /* if reconnect_sh doesn't begin with '/', it's a relative path to
* XRDP_CFG_PATH */
if (cf->reconnect_sh[0] != '/') if (cf->reconnect_sh[0] != '/')
{ {
/* sizeof operator returns string length including null terminator */ /* sizeof operator returns string length including null terminator */
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->reconnect_sh) + 1; /* '/' */ int length = (sizeof(XRDP_CFG_PATH) +
buf = (char *)g_malloc(length, 0); g_strlen(cf->reconnect_sh) + 1); /* '/' */
char *buf = (char *)g_malloc(length, 0);
g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->reconnect_sh); g_sprintf(buf, "%s/%s", XRDP_CFG_PATH, cf->reconnect_sh);
g_free(cf->reconnect_sh); g_free(cf->reconnect_sh);
cf->reconnect_sh = g_strdup(buf); cf->reconnect_sh = buf;
g_free(buf);
} }
return 0; return 0;
@ -530,6 +525,7 @@ config_read(const char *sesman_ini)
param_n->auto_free = 1; param_n->auto_free = 1;
param_v = list_create(); param_v = list_create();
param_v->auto_free = 1; param_v->auto_free = 1;
all_ok = 1;
/* read global config */ /* read global config */
config_read_globals(fd, cfg, param_n, param_v); config_read_globals(fd, cfg, param_n, param_v);
@ -552,7 +548,6 @@ config_read(const char *sesman_ini)
list_delete(param_v); list_delete(param_v);
list_delete(param_n); list_delete(param_n);
g_file_close(fd); g_file_close(fd);
all_ok = 1;
} }
} }
} }
@ -579,14 +574,13 @@ config_dump(struct config_sesman *config)
/* Global sesman configuration */ /* Global sesman configuration */
g_writeln("Filename: %s", config->sesman_ini); g_writeln("Filename: %s", config->sesman_ini);
g_writeln("Global configuration:"); g_writeln("Global configuration:");
g_writeln(" ListenAddress: %s", config->listen_address);
g_writeln(" ListenPort: %s", config->listen_port); g_writeln(" ListenPort: %s", config->listen_port);
g_writeln(" EnableUserWindowManager: %d", config->enable_user_wm); g_writeln(" EnableUserWindowManager: %d", config->enable_user_wm);
g_writeln(" UserWindowManager: %s", config->user_wm); g_writeln(" UserWindowManager: %s", config->user_wm);
g_writeln(" DefaultWindowManager: %s", config->default_wm); g_writeln(" DefaultWindowManager: %s", config->default_wm);
g_writeln(" ReconnectScript: %s", config->reconnect_sh); g_writeln(" ReconnectScript: %s", config->reconnect_sh);
g_writeln(" AuthFilePath: %s", g_writeln(" AuthFilePath: %s",
((config->auth_file_path) ? (config->auth_file_path) : ("disabled"))); (config->auth_file_path ? config->auth_file_path : "disabled"));
/* Session configuration */ /* Session configuration */
g_writeln("Session configuration:"); g_writeln("Session configuration:");

View File

@ -201,16 +201,11 @@ struct config_sesman
*/ */
char *sesman_ini; char *sesman_ini;
/**
* @var listen_address
* @brief Listening address
*/
char listen_address[32];
/** /**
* @var listen_port * @var listen_port
* @brief Listening port * @brief Listening port
*/ */
char listen_port[16]; char listen_port[256];
/** /**
* @var enable_user_wm * @var enable_user_wm
* @brief Flag that enables user specific wm * @brief Flag that enables user specific wm

View File

@ -36,6 +36,7 @@
#include "trans.h" #include "trans.h"
#include "scp_process.h" #include "scp_process.h"
#include "lock_uds.h"
/** /**
* Maximum number of short-lived connections to sesman * Maximum number of short-lived connections to sesman
@ -70,6 +71,10 @@ struct sesman_con
}; };
static struct trans *g_list_trans; static struct trans *g_list_trans;
/* Variables used to lock g_list_trans */
static struct lock_uds *g_list_trans_lock;
static struct list *g_con_list = NULL; static struct list *g_con_list = NULL;
static int g_pid; static int g_pid;
@ -206,45 +211,52 @@ sesman_process_params(int argc, char **argv,
} }
/******************************************************************************/ /******************************************************************************/
static int sesman_listen_test(struct config_sesman *cfg) static int
create_sesman_runtime_dir(void)
{ {
int error; int rv = -1;
int sck; /* Make sure if we create the directory, there's no gap where it
int rv = 0; * may have the wrong permissions */
int entry_umask = g_umask_hex(0x755);
sck = g_tcp_socket(); if (!g_directory_exist(SESMAN_RUNTIME_PATH) &&
if (sck < 0) !g_create_dir(SESMAN_RUNTIME_PATH))
{ {
return 1; LOG(LOG_LEVEL_ERROR,
"Can't create runtime directory '"
SESMAN_RUNTIME_PATH "' [%s]", g_get_strerror());
} }
else if (g_chown(SESMAN_RUNTIME_PATH, g_getuid(), g_getuid()) != 0)
LOG(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.",
cfg->listen_address, cfg->listen_port);
g_tcp_set_non_blocking(sck);
error = g_tcp_bind_address(sck, cfg->listen_port, cfg->listen_address);
if (error == 0)
{ {
/* try to listen */ LOG(LOG_LEVEL_ERROR,
error = g_tcp_listen(sck); "Can't set ownership of sesman runtime directory [%s]",
g_get_strerror());
if (error == 0) }
{ else if (g_chmod_hex(SESMAN_RUNTIME_PATH, 0x755) != 0)
/* if listen succeeded, stop listen immediately */ {
g_sck_close(sck); /* This might seem redundant, but there's a chance the
} * directory already exists */
else LOG(LOG_LEVEL_ERROR,
{ "Can't set permissions of sesman runtime directory [%s]",
rv = 1; g_get_strerror());
}
} }
else else
{ {
rv = 1; rv = 0;
} }
g_umask_hex(entry_umask);
return rv; return rv;
} }
/******************************************************************************/
static int sesman_listen_test(struct config_sesman *cfg)
{
int status = sesman_create_listening_transport(cfg);
sesman_delete_listening_transport();
return status;
}
/******************************************************************************/ /******************************************************************************/
int int
sesman_close_all(void) sesman_close_all(void)
@ -357,8 +369,18 @@ set_reload_event(int sig)
void void
sesman_delete_listening_transport(void) sesman_delete_listening_transport(void)
{ {
trans_delete(g_list_trans); if (g_getpid() == g_pid)
{
trans_delete(g_list_trans);
}
else
{
trans_delete_from_child(g_list_trans);
}
g_list_trans = NULL; g_list_trans = NULL;
unlock_uds(g_list_trans_lock);
g_list_trans_lock = NULL;
} }
/******************************************************************************/ /******************************************************************************/
@ -366,26 +388,43 @@ int
sesman_create_listening_transport(const struct config_sesman *cfg) sesman_create_listening_transport(const struct config_sesman *cfg)
{ {
int rv = 1; int rv = 1;
g_list_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); g_list_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
if (g_list_trans == NULL) if (g_list_trans == NULL)
{ {
LOG(LOG_LEVEL_ERROR, "%s: trans_create failed", __func__); LOG(LOG_LEVEL_ERROR, "%s: trans_create failed", __func__);
} }
else else if ((g_list_trans_lock = lock_uds(cfg->listen_port)) != NULL)
{ {
LOG(LOG_LEVEL_DEBUG, "%s: address %s port %s", /* Make sure the file is always created with the correct
__func__, cfg->listen_address, cfg->listen_port); * permissions, if it's not there */
rv = trans_listen_address(g_list_trans, cfg->listen_port, int entry_umask = g_umask_hex(0x666);
cfg->listen_address); LOG_DEVEL(LOG_LEVEL_DEBUG, "%s: port %s", __func__, cfg->listen_port);
rv = trans_listen_address(g_list_trans, cfg->listen_port, NULL);
if (rv != 0) if (rv != 0)
{ {
LOG(LOG_LEVEL_ERROR, "%s: trans_listen_address failed", __func__); LOG(LOG_LEVEL_ERROR, "%s: trans_listen_address failed", __func__);
sesman_delete_listening_transport(); }
else if (g_chown(cfg->listen_port, g_getuid(), g_getuid()) != 0)
{
LOG(LOG_LEVEL_ERROR,
"Can't set ownership of '%s' [%s]",
cfg->listen_port, g_get_strerror());
}
else if ((rv = g_chmod_hex(cfg->listen_port, 0x666)) != 0)
{
LOG(LOG_LEVEL_ERROR, "%s: Can't set permissions on '%s' [%s]",
__func__, cfg->listen_port, g_get_strerror());
} }
else else
{ {
g_list_trans->trans_conn_in = sesman_listen_conn_in; g_list_trans->trans_conn_in = sesman_listen_conn_in;
} }
g_umask_hex(entry_umask);
}
if (rv != 0)
{
sesman_delete_listening_transport();
} }
return rv; return rv;
@ -422,6 +461,7 @@ sesman_main_loop(void)
list_delete(g_con_list); list_delete(g_con_list);
return 1; return 1;
} }
LOG(LOG_LEVEL_INFO, "Sesman now listening on %s", g_cfg->listen_port);
error = 0; error = 0;
while (!error) while (!error)
@ -722,7 +762,6 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__); LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__);
LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini); LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini);
LOG(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address);
LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port); LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port);
LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm); LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm);
LOG(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm); LOG(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm);
@ -751,6 +790,16 @@ main(int argc, char **argv)
} }
} }
/* Create the runtime directory before we try to listen (or
* test-listen), so there's somewhere for the default socket to live */
if (create_sesman_runtime_dir() != 0)
{
config_free(g_cfg);
log_end();
g_deinit();
g_exit(1);
}
if (daemon) if (daemon)
{ {
/* start of daemonizing code */ /* start of daemonizing code */
@ -759,6 +808,7 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, "
"possibly address already in use."); "possibly address already in use.");
config_free(g_cfg); config_free(g_cfg);
log_end();
g_deinit(); g_deinit();
g_exit(1); g_exit(1);
} }
@ -766,14 +816,17 @@ main(int argc, char **argv)
if (0 != g_fork()) if (0 != g_fork())
{ {
config_free(g_cfg); config_free(g_cfg);
log_end();
g_deinit(); g_deinit();
g_exit(0); g_exit(0);
} }
} }
/* signal handling */ /* Now we've forked (if necessary), we can get the prgram PID */
g_pid = g_getpid(); g_pid = g_getpid();
/* signal handling */
g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid); g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid);
g_term_event = g_create_wait_obj(text); g_term_event = g_create_wait_obj(text);
g_snprintf(text, 255, "xrdp_sesman_%8.8x_sigchld", g_pid); g_snprintf(text, 255, "xrdp_sesman_%8.8x_sigchld", g_pid);

View File

@ -1,8 +1,8 @@
;; See `man 5 sesman.ini` for details ;; See `man 5 sesman.ini` for details
[Globals] [Globals]
ListenAddress=127.0.0.1 ; listening port
ListenPort=3350 #ListenPort=sesman.socket
EnableUserWindowManager=true EnableUserWindowManager=true
; Give in relative path to user's home directory ; Give in relative path to user's home directory
UserWindowManager=startwm.sh UserWindowManager=startwm.sh

View File

@ -47,16 +47,19 @@ sig_sesman_reload_cfg(void)
} }
/* Deal with significant config changes */ /* Deal with significant config changes */
if (g_strcmp(g_cfg->listen_address, cfg->listen_address) != 0 || if (g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
{ {
LOG(LOG_LEVEL_INFO, "sesman listen address changed to %s:%s", LOG(LOG_LEVEL_INFO, "sesman listen port changed to %s",
cfg->listen_address, cfg->listen_port); cfg->listen_port);
/* We have to delete the old port before listening to the new one /* We have to delete the old port before listening to the new one
* in case they overlap in scope */ * in case they overlap in scope */
sesman_delete_listening_transport(); sesman_delete_listening_transport();
sesman_create_listening_transport(cfg); if (sesman_create_listening_transport(cfg) == 0)
{
LOG(LOG_LEVEL_INFO, "Sesman now listening on %s",
g_cfg->listen_port);
}
} }
/* free old config data */ /* free old config data */

View File

@ -34,7 +34,6 @@
char user[257]; char user[257];
char pass[257]; char pass[257];
char cmnd[257]; char cmnd[257];
char serv[257];
char port[257]; char port[257];
static int cmndList(struct trans *t); static int cmndList(struct trans *t);
@ -55,7 +54,6 @@ int main(int argc, char **argv)
user[0] = '\0'; user[0] = '\0';
pass[0] = '\0'; pass[0] = '\0';
cmnd[0] = '\0'; cmnd[0] = '\0';
serv[0] = '\0';
port[0] = '\0'; port[0] = '\0';
logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL); logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL);
@ -72,10 +70,6 @@ int main(int argc, char **argv)
{ {
g_strncpy(pass, (argv[idx]) + 3, 256); g_strncpy(pass, (argv[idx]) + 3, 256);
} }
else if (0 == g_strncmp(argv[idx], "-s=", 3))
{
g_strncpy(serv, (argv[idx]) + 3, 256);
}
else if (0 == g_strncmp(argv[idx], "-i=", 3)) else if (0 == g_strncmp(argv[idx], "-i=", 3))
{ {
g_strncpy(port, (argv[idx]) + 3, 256); g_strncpy(port, (argv[idx]) + 3, 256);
@ -86,11 +80,6 @@ int main(int argc, char **argv)
} }
} }
if (0 == g_strncmp(serv, "", 1))
{
g_strncpy(serv, "localhost", 256);
}
if (0 == g_strncmp(port, "", 1)) if (0 == g_strncmp(port, "", 1))
{ {
g_strncpy(port, "3350", 256); g_strncpy(port, "3350", 256);
@ -115,7 +104,7 @@ int main(int argc, char **argv)
} }
t = scp_connect(serv, port, NULL); t = scp_connect(port, NULL);
if (t == NULL) if (t == NULL)

View File

@ -63,10 +63,6 @@
# define DEFAULT_BPP 32 # define DEFAULT_BPP 32
#endif #endif
#ifndef DEFAULT_SERVER
# define DEFAULT_SERVER "localhost"
#endif
#ifndef DEFAULT_TYPE #ifndef DEFAULT_TYPE
# define DEFAULT_TYPE "Xorg" # define DEFAULT_TYPE "Xorg"
#endif #endif
@ -95,7 +91,6 @@ struct session_params
int height; int height;
int bpp; int bpp;
enum scp_session_type session_type; enum scp_session_type session_type;
const char *server;
const char *directory; const char *directory;
const char *shell; const char *shell;
@ -175,9 +170,6 @@ usage(void)
g_printf(" -g <geometry> Default:%dx%d\n", g_printf(" -g <geometry> Default:%dx%d\n",
DEFAULT_WIDTH, DEFAULT_HEIGHT); DEFAULT_WIDTH, DEFAULT_HEIGHT);
g_printf(" -b <bits-per-pixel> Default:%d\n", DEFAULT_BPP); g_printf(" -b <bits-per-pixel> Default:%d\n", DEFAULT_BPP);
/* Don't encourage use of this one - we need to move to local sockets */
g_printf(" -s <server> Default:%s (Deprecated)\n",
DEFAULT_SERVER);
g_printf(" -t <type> Default:%s\n", DEFAULT_TYPE); g_printf(" -t <type> Default:%s\n", DEFAULT_TYPE);
g_printf(" -D <directory> Default: $HOME\n" g_printf(" -D <directory> Default: $HOME\n"
" -S <shell> Default: Defined window manager\n" " -S <shell> Default: Defined window manager\n"
@ -291,7 +283,6 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
sp->height = DEFAULT_HEIGHT; sp->height = DEFAULT_HEIGHT;
sp->bpp = DEFAULT_BPP; sp->bpp = DEFAULT_BPP;
(void)string_to_session_type(DEFAULT_TYPE, &sp->session_type); (void)string_to_session_type(DEFAULT_TYPE, &sp->session_type);
sp->server = DEFAULT_SERVER;
sp->directory = ""; sp->directory = "";
sp->shell = ""; sp->shell = "";
@ -315,11 +306,6 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
sp->bpp = atoi(optarg); sp->bpp = atoi(optarg);
break; break;
case 's':
LOG(LOG_LEVEL_WARNING, "Using deprecated option '-s'");
sp->server = optarg;
break;
case 't': case 't':
if (string_to_session_type(optarg, &sp->session_type) != 0) if (string_to_session_type(optarg, &sp->session_type) != 0)
{ {
@ -419,10 +405,10 @@ send_create_session_request(struct trans *t, const struct session_params *sp)
{ {
LOG(LOG_LEVEL_DEBUG, LOG(LOG_LEVEL_DEBUG,
"width:%d height:%d bpp:%d code:%d\n" "width:%d height:%d bpp:%d code:%d\n"
"server:\"%s\" directory:\"%s\"\n" "directory:\"%s\"\n"
"shell:\"%s\" connection_description:\"%s\"", "shell:\"%s\" connection_description:\"%s\"",
sp->width, sp->height, sp->bpp, sp->session_type, sp->width, sp->height, sp->bpp, sp->session_type,
sp->server, sp->directory, sp->directory,
sp->shell, sp->connection_description); sp->shell, sp->connection_description);
/* Only log the password in development builds */ /* Only log the password in development builds */
LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password); LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
@ -498,7 +484,7 @@ main(int argc, char **argv)
LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s", LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s",
sesman_ini, g_get_strerror()); sesman_ini, g_get_strerror());
} }
else if (!(t = scp_connect(sp.server, cfg->listen_port, NULL))) else if (!(t = scp_connect(cfg->listen_port, NULL)))
{ {
LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror()); LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror());
} }

View File

@ -223,7 +223,6 @@ name=Xorg
lib=libxup.@lib_extension@ lib=libxup.@lib_extension@
username=ask username=ask
password=ask password=ask
ip=127.0.0.1
port=-1 port=-1
code=20 code=20
@ -232,7 +231,6 @@ name=Xvnc
lib=libvnc.@lib_extension@ lib=libvnc.@lib_extension@
username=ask username=ask
password=ask password=ask
ip=127.0.0.1
port=-1 port=-1
#xserverbpp=24 #xserverbpp=24
#delay_ms=2000 #delay_ms=2000
@ -256,7 +254,6 @@ username=na
password=ask password=ask
#pamusername=asksame #pamusername=asksame
#pampassword=asksame #pampassword=asksame
#pamsessionmng=127.0.0.1
#delay_ms=2000 #delay_ms=2000
; Generic RDP proxy using NeutrinoRDP ; Generic RDP proxy using NeutrinoRDP
@ -275,7 +272,6 @@ password=ask
; connections. ; connections.
#pamusername=ask #pamusername=ask
#pampassword=ask #pampassword=ask
#pamsessionmng=127.0.0.1
; Currently NeutrinoRDP doesn't support dynamic resizing. Uncomment ; Currently NeutrinoRDP doesn't support dynamic resizing. Uncomment
; this line if you're using a client which does. ; this line if you're using a client which does.
#enable_dynamic_resizing=false #enable_dynamic_resizing=false

View File

@ -51,7 +51,7 @@ getPAMError(const int pamError, char *text, int text_bytes);
static const char * static const char *
getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self); getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self);
static int static int
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port); xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port);
static void static void
xrdp_mm_connect_sm(struct xrdp_mm *self); xrdp_mm_connect_sm(struct xrdp_mm *self);
@ -159,8 +159,6 @@ xrdp_mm_delete(struct xrdp_mm *self)
trans_delete(self->sesman_trans); trans_delete(self->sesman_trans);
self->sesman_trans = 0; self->sesman_trans = 0;
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = 0;
list_delete(self->login_names); list_delete(self->login_names);
list_delete(self->login_values); list_delete(self->login_values);
g_free(self); g_free(self);
@ -229,7 +227,7 @@ xrdp_mm_send_gateway_login(struct xrdp_mm *self, const char *username,
"sending login info to session manager, please wait..."); "sending login info to session manager, please wait...");
return scp_send_gateway_request( return scp_send_gateway_request(
self->pam_auth_trans, username, password, self->sesman_trans, username, password,
self->wm->client_info->connection_description); self->wm->client_info->connection_description);
} }
@ -475,7 +473,6 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
int rv; int rv;
int key_flags; int key_flags;
int device_flags; int device_flags;
int use_uds;
rv = 1; /* failure */ rv = 1; /* failure */
g_memset(text, 0, sizeof(text)); g_memset(text, 0, sizeof(text));
@ -500,22 +497,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
} }
else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */ else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
{ {
use_uds = 1; g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
if ((value = xrdp_mm_get_value(self, "ip")) != NULL &&
g_strcmp(value, "127.0.0.1") != 0)
{
use_uds = 0;
}
if (use_uds)
{
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
}
else
{
g_snprintf(text, 255, "%d", 6200 + self->display);
}
} }
else else
{ {
@ -1691,10 +1673,9 @@ xrdp_mm_chan_data_in(struct trans *trans)
static void cleanup_sesman_connection(struct xrdp_mm *self) static void cleanup_sesman_connection(struct xrdp_mm *self)
{ {
/* Don't delete these transports here - we may be in /* Don't delete any transports here - we may be in
* an auth callback from one of them */ * an auth callback from one of them */
self->delete_sesman_trans = 1; self->delete_sesman_trans = 1;
self->delete_pam_auth_trans = 1;
if (self->wm->login_state != WMLS_CLEANUP) if (self->wm->login_state != WMLS_CLEANUP)
{ {
@ -1861,16 +1842,12 @@ xrdp_mm_process_gateway_response(struct xrdp_mm *self)
int auth_result; int auth_result;
int rv; int rv;
rv = scp_get_gateway_response(self->pam_auth_trans, &auth_result); rv = scp_get_gateway_response(self->sesman_trans, &auth_result);
if (rv == 0) if (rv == 0)
{ {
const char *additionalError; const char *additionalError;
char pam_error[128]; char pam_error[128];
/* We no longer need the pam_auth transport - it's only used
* for the one message */
self->delete_pam_auth_trans = 1;
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
"Reply from access control: %s", "Reply from access control: %s",
getPAMError(auth_result, getPAMError(auth_result,
@ -1987,11 +1964,8 @@ xrdp_mm_scp_data_in(struct trans *trans)
{ {
char buff[64]; char buff[64];
scp_msgno_to_str(msgno, buff, sizeof(buff)); scp_msgno_to_str(msgno, buff, sizeof(buff));
const char *src = (trans == self->pam_auth_trans) LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from sesman",
? "PAM authenticator" buff);
: "sesman";
LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from %s",
buff, src);
} }
} }
@ -2015,10 +1989,8 @@ cleanup_states(struct xrdp_mm *self)
self->use_chansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */ self->use_chansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
self->use_pam_auth = 0; /* true if we're to use the PAM authentication facility */ self->use_pam_auth = 0; /* true if we're to use the PAM authentication facility */
self->sesman_trans = NULL; /* connection to sesman */ self->sesman_trans = NULL; /* connection to sesman */
self->pam_auth_trans = NULL; /* connection to PAM authenticator */
self->chan_trans = NULL; /* connection to chansrv */ self->chan_trans = NULL; /* connection to chansrv */
self->delete_sesman_trans = 0; self->delete_sesman_trans = 0;
self->delete_pam_auth_trans = 0;
self->display = 0; /* 10 for :10.0, 11 for :11.0, etc */ self->display = 0; /* 10 for :10.0, 11 for :11.0, etc */
guid_clear(&self->guid); guid_clear(&self->guid);
self->code = 0; /* 0 Xvnc session, 10 X11rdp session, 20 Xorg session */ self->code = 0; /* 0 Xvnc session, 10 X11rdp session, 20 Xorg session */
@ -2304,28 +2276,31 @@ parse_chansrvport(const char *value, char *dest, int dest_size)
/*****************************************************************************/ /*****************************************************************************/
static struct trans * static struct trans *
xrdp_mm_scp_connect(struct xrdp_mm *self, const char *target, const char *ip) xrdp_mm_scp_connect(struct xrdp_mm *self)
{ {
char port[128]; char port[128];
char port_description[128];
struct trans *t; struct trans *t;
xrdp_mm_get_sesman_port(port, sizeof(port)); xrdp_mm_get_sesman_port(port, sizeof(port));
scp_port_to_display_string(port,
port_description, sizeof(port_description));
xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG, xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
"connecting to %s on %s:%s", target, ip, port); "connecting to sesman on %s", port_description);
t = scp_connect(ip, port, g_is_term); t = scp_connect(port, g_is_term);
if (t != NULL) if (t != NULL)
{ {
/* fully connected */ /* fully connected */
t->trans_data_in = xrdp_mm_scp_data_in; t->trans_data_in = xrdp_mm_scp_data_in;
t->callback_data = self; t->callback_data = self;
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s connect ok", target); xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "sesman connect ok");
} }
else else
{ {
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
"Error connecting to %s on %s:%s", "Error connecting to sesman on %s", port_description);
target, ip, port);
trans_delete(t); trans_delete(t);
t = NULL; t = NULL;
} }
@ -2334,27 +2309,17 @@ xrdp_mm_scp_connect(struct xrdp_mm *self, const char *target, const char *ip)
/*****************************************************************************/ /*****************************************************************************/
static int static int
xrdp_mm_pam_auth_connect(struct xrdp_mm *self, const char *ip) xrdp_mm_sesman_connect(struct xrdp_mm *self)
{
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = xrdp_mm_scp_connect(self, "PAM authenticator", ip);
return (self->pam_auth_trans == NULL); /* 0 for success */
}
/*****************************************************************************/
static int
xrdp_mm_sesman_connect(struct xrdp_mm *self, const char *ip)
{ {
trans_delete(self->sesman_trans); trans_delete(self->sesman_trans);
self->sesman_trans = xrdp_mm_scp_connect(self, "sesman", ip); self->sesman_trans = xrdp_mm_scp_connect(self);
return (self->sesman_trans == NULL); /* 0 for success */ return (self->sesman_trans == NULL); /* 0 for success */
} }
/*****************************************************************************/ /*****************************************************************************/
static int static int
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port) xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port)
{ {
if (self->wm->client_info->channels_allowed == 0) if (self->wm->client_info->channels_allowed == 0)
{ {
@ -2365,16 +2330,7 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
} }
/* connect channel redir */ /* connect channel redir */
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0)) self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
}
else
{
/* tcp */
self->chan_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
}
self->chan_trans->is_term = g_is_term; self->chan_trans->is_term = g_is_term;
self->chan_trans->si = &(self->wm->session->si); self->chan_trans->si = &(self->wm->session->si);
@ -2386,7 +2342,7 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
self->chan_trans->extra_flags = 0; self->chan_trans->extra_flags = 0;
/* try to connect for up to 10 seconds */ /* try to connect for up to 10 seconds */
trans_connect(self->chan_trans, ip, port, 10 * 1000); trans_connect(self->chan_trans, NULL, port, 10 * 1000);
if (self->chan_trans->status != TRANS_STATUS_UP) if (self->chan_trans->status != TRANS_STATUS_UP)
{ {
LOG(LOG_LEVEL_ERROR, "xrdp_mm_chansrv_connect: error in " LOG(LOG_LEVEL_ERROR, "xrdp_mm_chansrv_connect: error in "
@ -2454,10 +2410,26 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (port != NULL && g_strcmp(port, "-1") == 0) if (port != NULL && g_strcmp(port, "-1") == 0)
{ {
self->use_sesman = 1; self->use_sesman = 1;
/* Connecting to a remote sesman is no longer supported */
if (xrdp_mm_get_value(self, "ip") != NULL)
{
xrdp_wm_log_msg(self->wm,
LOG_LEVEL_WARNING,
"Parameter 'ip' is obsolete for sesman connections."
" Please remove from config");
}
} }
if (gateway_username != NULL) if (gateway_username != NULL)
{ {
/* Connecting to a remote sesman is no longer supported */
if (xrdp_mm_get_value(self, "pamsessionmng") != NULL)
{
xrdp_wm_log_msg(self->wm,
LOG_LEVEL_WARNING,
"Parameter 'pamsessionmng' is obsolete."
" Please remove from config");
}
#ifdef USE_PAM #ifdef USE_PAM
self->use_pam_auth = 1; self->use_pam_auth = 1;
#else #else
@ -2499,22 +2471,10 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
{ {
case MMCS_CONNECT_TO_SESMAN: case MMCS_CONNECT_TO_SESMAN:
{ {
if (self->use_sesman) if (self->use_sesman || self->use_pam_auth)
{ {
/* Synchronous call */ /* Synchronous call */
const char *ip = xrdp_mm_get_value(self, "ip"); status = xrdp_mm_sesman_connect(self);
status = xrdp_mm_sesman_connect(self, ip);
}
if (status == 0 && self->use_pam_auth)
{
/* Synchronous call */
const char *ip = xrdp_mm_get_value(self, "pamsessionmng");
if (ip == NULL)
{
ip = xrdp_mm_get_value(self, "ip");
}
status = xrdp_mm_pam_auth_connect(self, ip);
} }
} }
break; break;
@ -2589,25 +2549,12 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
{ {
if (self->use_chansrv) if (self->use_chansrv)
{ {
const char *ip = "";
char portbuff[256]; char portbuff[256];
if (self->use_sesman) if (self->use_sesman)
{ {
ip = xrdp_mm_get_value(self, "ip"); g_snprintf(portbuff, sizeof(portbuff),
XRDP_CHANSRV_STR, self->display);
/* connect channel redir */
if (ip == NULL || (ip[0] == '\0') ||
(g_strcmp(ip, "127.0.0.1") == 0))
{
g_snprintf(portbuff, sizeof(portbuff),
XRDP_CHANSRV_STR, self->display);
}
else
{
g_snprintf(portbuff, sizeof(portbuff),
"%d", 7200 + self->display);
}
} }
else else
{ {
@ -2617,7 +2564,7 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
} }
xrdp_mm_update_allowed_channels(self); xrdp_mm_update_allowed_channels(self);
xrdp_mm_chansrv_connect(self, ip, portbuff); xrdp_mm_chansrv_connect(self, portbuff);
} }
} }
break; break;
@ -2668,12 +2615,6 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
trans_get_wait_objs(self->sesman_trans, read_objs, rcount); trans_get_wait_objs(self->sesman_trans, read_objs, rcount);
} }
if (self->pam_auth_trans != 0 &&
self->pam_auth_trans->status == TRANS_STATUS_UP)
{
trans_get_wait_objs(self->pam_auth_trans, read_objs, rcount);
}
if ((self->chan_trans != 0) && self->chan_trans->status == TRANS_STATUS_UP) if ((self->chan_trans != 0) && self->chan_trans->status == TRANS_STATUS_UP)
{ {
trans_get_wait_objs_rw(self->chan_trans, read_objs, rcount, trans_get_wait_objs_rw(self->chan_trans, read_objs, rcount,
@ -2898,22 +2839,6 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->sesman_trans = NULL; self->sesman_trans = NULL;
} }
if (self->pam_auth_trans != NULL &&
!self->delete_pam_auth_trans &&
self->pam_auth_trans->status == TRANS_STATUS_UP)
{
if (trans_check_wait_objs(self->pam_auth_trans) != 0)
{
self->delete_pam_auth_trans = 1;
}
}
if (self->delete_pam_auth_trans)
{
trans_delete(self->pam_auth_trans);
self->pam_auth_trans = NULL;
}
if (self->chan_trans != NULL && if (self->chan_trans != NULL &&
self->chan_trans->status == TRANS_STATUS_UP) self->chan_trans->status == TRANS_STATUS_UP)
{ {

View File

@ -322,7 +322,6 @@ struct xrdp_mm
int use_pam_auth; /* True if we're to authenticate using PAM */ int use_pam_auth; /* True if we're to authenticate using PAM */
int use_chansrv; /* true if chansrvport is set in xrdp.ini or using sesman */ int use_chansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
struct trans *sesman_trans; /* connection to sesman */ struct trans *sesman_trans; /* connection to sesman */
struct trans *pam_auth_trans; /* connection to pam authenticator */
struct trans *chan_trans; /* connection to chansrv */ struct trans *chan_trans; /* connection to chansrv */
/* We can't delete transports while we're in a callback for that /* We can't delete transports while we're in a callback for that
@ -330,7 +329,6 @@ struct xrdp_mm
* These flags mark transports as needing to be deleted when * These flags mark transports as needing to be deleted when
* we are definitely not in a transport callback */ * we are definitely not in a transport callback */
int delete_sesman_trans; int delete_sesman_trans;
int delete_pam_auth_trans;
struct list *login_names; struct list *login_names;
struct list *login_values; struct list *login_values;