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:
parent
9c30d4c2f8
commit
0db849fc5c
@ -28,6 +28,7 @@
|
||||
#define CHANSRV_API_BASE_STR "xrdpapi_%d"
|
||||
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d"
|
||||
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d"
|
||||
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
|
||||
|
||||
/* fullpath of sockets */
|
||||
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR
|
||||
|
14
configure.ac
14
configure.ac
@ -52,10 +52,16 @@ AC_CHECK_SIZEOF([void *])
|
||||
|
||||
AC_ARG_WITH([socketdir],
|
||||
[AS_HELP_STRING([--with-socketdir=DIR],
|
||||
[Use directory for UNIX sockets (default: /tmp/.xrdp)])],
|
||||
[], [with_socketdir="/tmp/.xrdp"])
|
||||
[Use directory for UNIX sockets for XRDP sessions (default: RUNSTATEDIR/xrdp)])],
|
||||
[], [with_socketdir="$runstatedir/xrdp"])
|
||||
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],
|
||||
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 " bindir $bindir"
|
||||
echo " sysconfdir $sysconfdir"
|
||||
echo " localstatedir $localstatedir"
|
||||
echo " runstatedir $runstatedir"
|
||||
echo " socketdir $socketdir"
|
||||
echo " sesmanruntimedir $sesmanruntimedir"
|
||||
echo ""
|
||||
echo " unit tests performable $perform_unit_tests"
|
||||
echo ""
|
||||
|
@ -19,6 +19,7 @@ SUBST_VARS = sed \
|
||||
-e 's|@localstatedir[@]|$(localstatedir)|g' \
|
||||
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
|
||||
-e 's|@socketdir[@]|$(socketdir)|g' \
|
||||
-e 's|@sesmanruntimedir[@]|$(sesmanruntimedir)|g' \
|
||||
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \
|
||||
-e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g'
|
||||
|
||||
|
@ -50,13 +50,19 @@ outside their proper section will be \fIignored\fR.
|
||||
Following parameters can be used in the \fB[Globals]\fR section.
|
||||
|
||||
.TP
|
||||
\fBListenAddress\fR=\fIip address\fR
|
||||
xrdp-sesman listening address. If not specified, defaults to \fI0.0.0.0\fR
|
||||
(all interfaces).
|
||||
|
||||
.TP
|
||||
\fBListenPort\fR=\fIport number\fR
|
||||
xrdp-sesman listening port. If not specified, defaults to \fI3350\fR.
|
||||
\fBListenPort\fR=\fIpath-to-socket\fR
|
||||
UNIX domain socket for xrdp-sesman(8) to listen on.
|
||||
.PP
|
||||
.RS
|
||||
The default value of this setting is 'sesman.socket'.
|
||||
.PP
|
||||
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
|
||||
\fBEnableUserWindowManager\fR=\fI[true|false]\fR
|
||||
|
@ -26,15 +26,11 @@ Defaults to \fBroot\fP.
|
||||
The \fIpassword\fP to authenticate with.
|
||||
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
|
||||
.BI \-i= port
|
||||
The TCP \fIport\fP number to connect to.
|
||||
Defaults to \fB3350\fP.
|
||||
The sesman \fIUNIX domain socket\fP to connect to.
|
||||
Defaults to \fBsesman.socket\fP.
|
||||
If no path is specified for the socket, a default of @sesmanruntimedir@ is used.
|
||||
|
||||
.TP
|
||||
.BI \-c= command
|
||||
|
@ -58,6 +58,8 @@ to read it.
|
||||
@localstatedir@/log/xrdp\-sesman.log
|
||||
.br
|
||||
@localstatedir@/run/xrdp\-sesman.pid
|
||||
.br
|
||||
@sesmanruntimedir@/sesman.socket
|
||||
|
||||
.SH "AUTHORS"
|
||||
Jay Sorg <jsorg71@users.sourceforge.net>
|
||||
|
@ -29,11 +29,6 @@ option may not do what you expect.
|
||||
Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
|
||||
will ignore this setting.
|
||||
.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>
|
||||
Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
|
||||
only, use the numeric session code.
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||
-I$(top_srcdir)/common
|
||||
|
||||
module_LTLIBRARIES = \
|
||||
|
96
libipm/scp.c
96
libipm/scp.c
@ -33,6 +33,7 @@
|
||||
#include "trans.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "xrdp_sockets.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
static const char *
|
||||
@ -67,27 +68,96 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
struct trans *
|
||||
scp_connect(const char *host, const char *port,
|
||||
int (*term_func)(void))
|
||||
int
|
||||
scp_port_to_unix_domain_path(const char *port, char *buff,
|
||||
unsigned int bufflen)
|
||||
{
|
||||
struct trans *t;
|
||||
if ((t = trans_create(TRANS_MODE_TCP, 128, 128)) != NULL)
|
||||
{
|
||||
if (host == NULL)
|
||||
{
|
||||
host = "localhost";
|
||||
}
|
||||
/* 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 = "3350";
|
||||
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 *
|
||||
scp_connect(const char *port,
|
||||
int (*term_func)(void))
|
||||
{
|
||||
char sock_path[256];
|
||||
struct trans *t;
|
||||
|
||||
(void)scp_port_to_unix_domain_path(port, sock_path, sizeof(sock_path));
|
||||
if ((t = trans_create(TRANS_MODE_UNIX, 128, 128)) != NULL)
|
||||
{
|
||||
t->is_term = term_func;
|
||||
|
||||
trans_connect(t, host, port, 3000);
|
||||
if (t->status != TRANS_STATUS_UP)
|
||||
if (trans_connect(t, NULL, sock_path, 3000) != 0)
|
||||
{
|
||||
trans_delete(t);
|
||||
t = NULL;
|
||||
|
33
libipm/scp.h
33
libipm/scp.h
@ -65,11 +65,38 @@ scp_msgno_to_str(enum scp_msg_code n, char *buff, unsigned int buff_size);
|
||||
|
||||
/* 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
|
||||
*
|
||||
* @param host Host providing SCP service
|
||||
* @param port TCP port for SCP service
|
||||
* @param port Port definition (e.g. from sesman.ini)
|
||||
* @param term_func Function to poll during connection for program
|
||||
* termination, or NULL for none.
|
||||
* @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.
|
||||
*/
|
||||
struct trans *
|
||||
scp_connect(const char *host, const char *port,
|
||||
scp_connect(const char *port,
|
||||
int (*term_func)(void));
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\" \
|
||||
-DSESMAN_RUNTIME_PATH=\"${sesmanruntimedir}\" \
|
||||
-I$(top_srcdir)/common \
|
||||
-I$(top_srcdir)/libipm
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "log.h"
|
||||
#include "string_calls.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)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
char *buf;
|
||||
|
||||
list_clear(param_v);
|
||||
list_clear(param_n);
|
||||
|
||||
/* resetting the struct */
|
||||
cf->listen_address[0] = '\0';
|
||||
cf->listen_port[0] = '\0';
|
||||
cf->enable_user_wm = 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++)
|
||||
{
|
||||
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 */
|
||||
if ('\0' == cf->listen_address[0])
|
||||
{
|
||||
g_strncpy(cf->listen_address, "0.0.0.0", 8);
|
||||
}
|
||||
|
||||
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])
|
||||
@ -118,46 +119,40 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
|
||||
cf->enable_user_wm = 0;
|
||||
}
|
||||
|
||||
if (cf->default_wm == 0)
|
||||
{
|
||||
cf->default_wm = g_strdup("startwm.sh");
|
||||
}
|
||||
else if (g_strlen(cf->default_wm) == 0)
|
||||
if (cf->default_wm == 0 || cf->default_wm[0] == '\0')
|
||||
{
|
||||
g_free(cf->default_wm);
|
||||
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] != '/')
|
||||
{
|
||||
/* sizeof operator returns string length including null terminator */
|
||||
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->default_wm) + 1; /* '/' */
|
||||
buf = (char *)g_malloc(length, 0);
|
||||
int length = (sizeof(XRDP_CFG_PATH) +
|
||||
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_free(cf->default_wm);
|
||||
cf->default_wm = g_strdup(buf);
|
||||
g_free(buf);
|
||||
cf->default_wm = buf;
|
||||
}
|
||||
|
||||
if (cf->reconnect_sh == 0)
|
||||
{
|
||||
cf->reconnect_sh = g_strdup("reconnectwm.sh");
|
||||
}
|
||||
else if (g_strlen(cf->reconnect_sh) == 0)
|
||||
if (cf->reconnect_sh == 0 || cf->reconnect_sh[0] == '\0')
|
||||
{
|
||||
g_free(cf->reconnect_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] != '/')
|
||||
{
|
||||
/* sizeof operator returns string length including null terminator */
|
||||
length = sizeof(XRDP_CFG_PATH) + g_strlen(cf->reconnect_sh) + 1; /* '/' */
|
||||
buf = (char *)g_malloc(length, 0);
|
||||
int length = (sizeof(XRDP_CFG_PATH) +
|
||||
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_free(cf->reconnect_sh);
|
||||
cf->reconnect_sh = g_strdup(buf);
|
||||
g_free(buf);
|
||||
cf->reconnect_sh = buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -530,6 +525,7 @@ config_read(const char *sesman_ini)
|
||||
param_n->auto_free = 1;
|
||||
param_v = list_create();
|
||||
param_v->auto_free = 1;
|
||||
all_ok = 1;
|
||||
|
||||
/* read global config */
|
||||
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_n);
|
||||
g_file_close(fd);
|
||||
all_ok = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,14 +574,13 @@ config_dump(struct config_sesman *config)
|
||||
/* Global sesman configuration */
|
||||
g_writeln("Filename: %s", config->sesman_ini);
|
||||
g_writeln("Global configuration:");
|
||||
g_writeln(" ListenAddress: %s", config->listen_address);
|
||||
g_writeln(" ListenPort: %s", config->listen_port);
|
||||
g_writeln(" EnableUserWindowManager: %d", config->enable_user_wm);
|
||||
g_writeln(" UserWindowManager: %s", config->user_wm);
|
||||
g_writeln(" DefaultWindowManager: %s", config->default_wm);
|
||||
g_writeln(" ReconnectScript: %s", config->reconnect_sh);
|
||||
g_writeln(" AuthFilePath: %s",
|
||||
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
|
||||
(config->auth_file_path ? config->auth_file_path : "disabled"));
|
||||
|
||||
/* Session configuration */
|
||||
g_writeln("Session configuration:");
|
||||
|
@ -201,16 +201,11 @@ struct config_sesman
|
||||
*/
|
||||
char *sesman_ini;
|
||||
|
||||
/**
|
||||
* @var listen_address
|
||||
* @brief Listening address
|
||||
*/
|
||||
char listen_address[32];
|
||||
/**
|
||||
* @var listen_port
|
||||
* @brief Listening port
|
||||
*/
|
||||
char listen_port[16];
|
||||
char listen_port[256];
|
||||
/**
|
||||
* @var enable_user_wm
|
||||
* @brief Flag that enables user specific wm
|
||||
|
121
sesman/sesman.c
121
sesman/sesman.c
@ -36,6 +36,7 @@
|
||||
#include "trans.h"
|
||||
|
||||
#include "scp_process.h"
|
||||
#include "lock_uds.h"
|
||||
|
||||
/**
|
||||
* Maximum number of short-lived connections to sesman
|
||||
@ -70,6 +71,10 @@ struct sesman_con
|
||||
};
|
||||
|
||||
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 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 sck;
|
||||
int rv = 0;
|
||||
int rv = -1;
|
||||
/* Make sure if we create the directory, there's no gap where it
|
||||
* may have the wrong permissions */
|
||||
int entry_umask = g_umask_hex(0x755);
|
||||
|
||||
sck = g_tcp_socket();
|
||||
if (sck < 0)
|
||||
if (!g_directory_exist(SESMAN_RUNTIME_PATH) &&
|
||||
!g_create_dir(SESMAN_RUNTIME_PATH))
|
||||
{
|
||||
return 1;
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Can't create runtime directory '"
|
||||
SESMAN_RUNTIME_PATH "' [%s]", g_get_strerror());
|
||||
}
|
||||
|
||||
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)
|
||||
else if (g_chown(SESMAN_RUNTIME_PATH, g_getuid(), g_getuid()) != 0)
|
||||
{
|
||||
/* try to listen */
|
||||
error = g_tcp_listen(sck);
|
||||
|
||||
if (error == 0)
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Can't set ownership of sesman runtime directory [%s]",
|
||||
g_get_strerror());
|
||||
}
|
||||
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 */
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Can't set permissions of sesman runtime directory [%s]",
|
||||
g_get_strerror());
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = 1;
|
||||
rv = 0;
|
||||
}
|
||||
g_umask_hex(entry_umask);
|
||||
|
||||
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
|
||||
sesman_close_all(void)
|
||||
@ -356,9 +368,19 @@ set_reload_event(int sig)
|
||||
/******************************************************************************/
|
||||
void
|
||||
sesman_delete_listening_transport(void)
|
||||
{
|
||||
if (g_getpid() == g_pid)
|
||||
{
|
||||
trans_delete(g_list_trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans_delete_from_child(g_list_trans);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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",
|
||||
__func__, cfg->listen_address, cfg->listen_port);
|
||||
rv = trans_listen_address(g_list_trans, cfg->listen_port,
|
||||
cfg->listen_address);
|
||||
/* Make sure the file is always created with the correct
|
||||
* permissions, if it's not there */
|
||||
int entry_umask = g_umask_hex(0x666);
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
g_list_trans->trans_conn_in = sesman_listen_conn_in;
|
||||
}
|
||||
g_umask_hex(entry_umask);
|
||||
}
|
||||
|
||||
if (rv != 0)
|
||||
{
|
||||
sesman_delete_listening_transport();
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -422,6 +461,7 @@ sesman_main_loop(void)
|
||||
list_delete(g_con_list);
|
||||
return 1;
|
||||
}
|
||||
LOG(LOG_LEVEL_INFO, "Sesman now listening on %s", g_cfg->listen_port);
|
||||
|
||||
error = 0;
|
||||
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, " 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, " enable_user_wm = %d", g_cfg->enable_user_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)
|
||||
{
|
||||
/* start of daemonizing code */
|
||||
@ -759,6 +808,7 @@ main(int argc, char **argv)
|
||||
LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, "
|
||||
"possibly address already in use.");
|
||||
config_free(g_cfg);
|
||||
log_end();
|
||||
g_deinit();
|
||||
g_exit(1);
|
||||
}
|
||||
@ -766,14 +816,17 @@ main(int argc, char **argv)
|
||||
if (0 != g_fork())
|
||||
{
|
||||
config_free(g_cfg);
|
||||
log_end();
|
||||
g_deinit();
|
||||
g_exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* signal handling */
|
||||
/* Now we've forked (if necessary), we can get the prgram PID */
|
||||
g_pid = g_getpid();
|
||||
|
||||
/* signal handling */
|
||||
g_snprintf(text, 255, "xrdp_sesman_%8.8x_main_term", g_pid);
|
||||
g_term_event = g_create_wait_obj(text);
|
||||
g_snprintf(text, 255, "xrdp_sesman_%8.8x_sigchld", g_pid);
|
||||
|
@ -1,8 +1,8 @@
|
||||
;; See `man 5 sesman.ini` for details
|
||||
|
||||
[Globals]
|
||||
ListenAddress=127.0.0.1
|
||||
ListenPort=3350
|
||||
; listening port
|
||||
#ListenPort=sesman.socket
|
||||
EnableUserWindowManager=true
|
||||
; Give in relative path to user's home directory
|
||||
UserWindowManager=startwm.sh
|
||||
|
13
sesman/sig.c
13
sesman/sig.c
@ -47,16 +47,19 @@ sig_sesman_reload_cfg(void)
|
||||
}
|
||||
|
||||
/* Deal with significant config changes */
|
||||
if (g_strcmp(g_cfg->listen_address, cfg->listen_address) != 0 ||
|
||||
g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
|
||||
if (g_strcmp(g_cfg->listen_port, cfg->listen_port) != 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "sesman listen address changed to %s:%s",
|
||||
cfg->listen_address, cfg->listen_port);
|
||||
LOG(LOG_LEVEL_INFO, "sesman listen port changed to %s",
|
||||
cfg->listen_port);
|
||||
|
||||
/* We have to delete the old port before listening to the new one
|
||||
* in case they overlap in scope */
|
||||
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 */
|
||||
|
@ -34,7 +34,6 @@
|
||||
char user[257];
|
||||
char pass[257];
|
||||
char cmnd[257];
|
||||
char serv[257];
|
||||
char port[257];
|
||||
|
||||
static int cmndList(struct trans *t);
|
||||
@ -55,7 +54,6 @@ int main(int argc, char **argv)
|
||||
user[0] = '\0';
|
||||
pass[0] = '\0';
|
||||
cmnd[0] = '\0';
|
||||
serv[0] = '\0';
|
||||
port[0] = '\0';
|
||||
|
||||
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);
|
||||
}
|
||||
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))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
|
@ -63,10 +63,6 @@
|
||||
# define DEFAULT_BPP 32
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_SERVER
|
||||
# define DEFAULT_SERVER "localhost"
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_TYPE
|
||||
# define DEFAULT_TYPE "Xorg"
|
||||
#endif
|
||||
@ -95,7 +91,6 @@ struct session_params
|
||||
int height;
|
||||
int bpp;
|
||||
enum scp_session_type session_type;
|
||||
const char *server;
|
||||
|
||||
const char *directory;
|
||||
const char *shell;
|
||||
@ -175,9 +170,6 @@ usage(void)
|
||||
g_printf(" -g <geometry> Default:%dx%d\n",
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
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(" -D <directory> Default: $HOME\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->bpp = DEFAULT_BPP;
|
||||
(void)string_to_session_type(DEFAULT_TYPE, &sp->session_type);
|
||||
sp->server = DEFAULT_SERVER;
|
||||
|
||||
sp->directory = "";
|
||||
sp->shell = "";
|
||||
@ -315,11 +306,6 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
|
||||
sp->bpp = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
LOG(LOG_LEVEL_WARNING, "Using deprecated option '-s'");
|
||||
sp->server = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
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,
|
||||
"width:%d height:%d bpp:%d code:%d\n"
|
||||
"server:\"%s\" directory:\"%s\"\n"
|
||||
"directory:\"%s\"\n"
|
||||
"shell:\"%s\" connection_description:\"%s\"",
|
||||
sp->width, sp->height, sp->bpp, sp->session_type,
|
||||
sp->server, sp->directory,
|
||||
sp->directory,
|
||||
sp->shell, sp->connection_description);
|
||||
/* Only log the password in development builds */
|
||||
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",
|
||||
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());
|
||||
}
|
||||
|
@ -223,7 +223,6 @@ name=Xorg
|
||||
lib=libxup.@lib_extension@
|
||||
username=ask
|
||||
password=ask
|
||||
ip=127.0.0.1
|
||||
port=-1
|
||||
code=20
|
||||
|
||||
@ -232,7 +231,6 @@ name=Xvnc
|
||||
lib=libvnc.@lib_extension@
|
||||
username=ask
|
||||
password=ask
|
||||
ip=127.0.0.1
|
||||
port=-1
|
||||
#xserverbpp=24
|
||||
#delay_ms=2000
|
||||
@ -256,7 +254,6 @@ username=na
|
||||
password=ask
|
||||
#pamusername=asksame
|
||||
#pampassword=asksame
|
||||
#pamsessionmng=127.0.0.1
|
||||
#delay_ms=2000
|
||||
|
||||
; Generic RDP proxy using NeutrinoRDP
|
||||
@ -275,7 +272,6 @@ password=ask
|
||||
; connections.
|
||||
#pamusername=ask
|
||||
#pampassword=ask
|
||||
#pamsessionmng=127.0.0.1
|
||||
; Currently NeutrinoRDP doesn't support dynamic resizing. Uncomment
|
||||
; this line if you're using a client which does.
|
||||
#enable_dynamic_resizing=false
|
||||
|
151
xrdp/xrdp_mm.c
151
xrdp/xrdp_mm.c
@ -51,7 +51,7 @@ getPAMError(const int pamError, char *text, int text_bytes);
|
||||
static const char *
|
||||
getPAMAdditionalErrorInfo(const int pamError, struct xrdp_mm *self);
|
||||
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
|
||||
xrdp_mm_connect_sm(struct xrdp_mm *self);
|
||||
|
||||
@ -159,8 +159,6 @@ xrdp_mm_delete(struct xrdp_mm *self)
|
||||
|
||||
trans_delete(self->sesman_trans);
|
||||
self->sesman_trans = 0;
|
||||
trans_delete(self->pam_auth_trans);
|
||||
self->pam_auth_trans = 0;
|
||||
list_delete(self->login_names);
|
||||
list_delete(self->login_values);
|
||||
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...");
|
||||
|
||||
return scp_send_gateway_request(
|
||||
self->pam_auth_trans, username, password,
|
||||
self->sesman_trans, username, password,
|
||||
self->wm->client_info->connection_description);
|
||||
}
|
||||
|
||||
@ -475,7 +473,6 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
|
||||
int rv;
|
||||
int key_flags;
|
||||
int device_flags;
|
||||
int use_uds;
|
||||
|
||||
rv = 1; /* failure */
|
||||
g_memset(text, 0, sizeof(text));
|
||||
@ -499,25 +496,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
|
||||
g_snprintf(text, 255, "%d", 5900 + self->display);
|
||||
}
|
||||
else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
|
||||
{
|
||||
use_uds = 1;
|
||||
|
||||
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
|
||||
{
|
||||
g_set_wait_obj(self->wm->pro_layer->self_term_event); /* kill session */
|
||||
}
|
||||
@ -1691,10 +1673,9 @@ xrdp_mm_chan_data_in(struct trans *trans)
|
||||
|
||||
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 */
|
||||
self->delete_sesman_trans = 1;
|
||||
self->delete_pam_auth_trans = 1;
|
||||
|
||||
if (self->wm->login_state != WMLS_CLEANUP)
|
||||
{
|
||||
@ -1861,16 +1842,12 @@ xrdp_mm_process_gateway_response(struct xrdp_mm *self)
|
||||
int auth_result;
|
||||
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)
|
||||
{
|
||||
const char *additionalError;
|
||||
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,
|
||||
"Reply from access control: %s",
|
||||
getPAMError(auth_result,
|
||||
@ -1987,11 +1964,8 @@ xrdp_mm_scp_data_in(struct trans *trans)
|
||||
{
|
||||
char buff[64];
|
||||
scp_msgno_to_str(msgno, buff, sizeof(buff));
|
||||
const char *src = (trans == self->pam_auth_trans)
|
||||
? "PAM authenticator"
|
||||
: "sesman";
|
||||
LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from %s",
|
||||
buff, src);
|
||||
LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s from sesman",
|
||||
buff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_pam_auth = 0; /* true if we're to use the PAM authentication facility */
|
||||
self->sesman_trans = NULL; /* connection to sesman */
|
||||
self->pam_auth_trans = NULL; /* connection to PAM authenticator */
|
||||
self->chan_trans = NULL; /* connection to chansrv */
|
||||
self->delete_sesman_trans = 0;
|
||||
self->delete_pam_auth_trans = 0;
|
||||
self->display = 0; /* 10 for :10.0, 11 for :11.0, etc */
|
||||
guid_clear(&self->guid);
|
||||
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 *
|
||||
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_description[128];
|
||||
struct trans *t;
|
||||
|
||||
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,
|
||||
"connecting to %s on %s:%s", target, ip, port);
|
||||
t = scp_connect(ip, port, g_is_term);
|
||||
"connecting to sesman on %s", port_description);
|
||||
t = scp_connect(port, g_is_term);
|
||||
if (t != NULL)
|
||||
{
|
||||
/* fully connected */
|
||||
t->trans_data_in = xrdp_mm_scp_data_in;
|
||||
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
|
||||
{
|
||||
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
|
||||
"Error connecting to %s on %s:%s",
|
||||
target, ip, port);
|
||||
"Error connecting to sesman on %s", port_description);
|
||||
trans_delete(t);
|
||||
t = NULL;
|
||||
}
|
||||
@ -2334,27 +2309,17 @@ xrdp_mm_scp_connect(struct xrdp_mm *self, const char *target, const char *ip)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_mm_pam_auth_connect(struct xrdp_mm *self, const char *ip)
|
||||
{
|
||||
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)
|
||||
xrdp_mm_sesman_connect(struct xrdp_mm *self)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
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)
|
||||
{
|
||||
@ -2365,16 +2330,7 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *ip, const char *port)
|
||||
}
|
||||
|
||||
/* connect channel redir */
|
||||
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
|
||||
{
|
||||
/* 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->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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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
|
||||
self->use_pam_auth = 1;
|
||||
#else
|
||||
@ -2499,22 +2471,10 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
||||
{
|
||||
case MMCS_CONNECT_TO_SESMAN:
|
||||
{
|
||||
if (self->use_sesman)
|
||||
if (self->use_sesman || self->use_pam_auth)
|
||||
{
|
||||
/* Synchronous call */
|
||||
const char *ip = xrdp_mm_get_value(self, "ip");
|
||||
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);
|
||||
status = xrdp_mm_sesman_connect(self);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2589,27 +2549,14 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
||||
{
|
||||
if (self->use_chansrv)
|
||||
{
|
||||
const char *ip = "";
|
||||
char portbuff[256];
|
||||
|
||||
if (self->use_sesman)
|
||||
{
|
||||
ip = xrdp_mm_get_value(self, "ip");
|
||||
|
||||
/* 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
|
||||
{
|
||||
const char *cp = xrdp_mm_get_value(self, "chansrvport");
|
||||
portbuff[0] = '\0';
|
||||
@ -2617,7 +2564,7 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
||||
|
||||
}
|
||||
xrdp_mm_update_allowed_channels(self);
|
||||
xrdp_mm_chansrv_connect(self, ip, portbuff);
|
||||
xrdp_mm_chansrv_connect(self, portbuff);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2668,12 +2615,6 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 &&
|
||||
self->chan_trans->status == TRANS_STATUS_UP)
|
||||
{
|
||||
|
@ -322,7 +322,6 @@ struct xrdp_mm
|
||||
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 */
|
||||
struct trans *sesman_trans; /* connection to sesman */
|
||||
struct trans *pam_auth_trans; /* connection to pam authenticator */
|
||||
struct trans *chan_trans; /* connection to chansrv */
|
||||
|
||||
/* 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
|
||||
* we are definitely not in a transport callback */
|
||||
int delete_sesman_trans;
|
||||
int delete_pam_auth_trans;
|
||||
|
||||
struct list *login_names;
|
||||
struct list *login_values;
|
||||
|
Loading…
Reference in New Issue
Block a user