Replace X11 display number with a display string

As far as possible, use of the X11 display number is kept to
X11-specific routines. This is to make it easier to restructure
the code to add non-X11 display support.
This commit is contained in:
matt335672
2026-02-03 15:36:20 +00:00
parent d56408a891
commit c4727ad8f3
40 changed files with 726 additions and 527 deletions
+66 -2
View File
@@ -162,8 +162,8 @@ g_text2bool(const char *s)
} }
/*****************************************************************************/ /*****************************************************************************/
int static int
g_get_display_num_from_display(const char *display_text) get_display_num_from_display(const char *display_text)
{ {
int rv = -1; int rv = -1;
const char *p; const char *p;
@@ -191,6 +191,70 @@ g_get_display_num_from_display(const char *display_text)
return rv; return rv;
} }
/*****************************************************************************/
int
g_get_display_string_from_x11_display(int display_num,
char buff[], unsigned int bufflen)
{
unsigned int res = g_snprintf(buff, bufflen, "X11-%d", display_num);
return (res >= bufflen) ? -1 : 0;
}
/*****************************************************************************/
int
g_get_x11_display_from_display_string(const char *display_str)
{
int result = -1;
if (display_str != NULL)
{
if (display_str[0] == 'X' && display_str[1] == '1' &&
display_str[2] == '1' && display_str[3] == '-' &&
isdigit(display_str[4]))
{
result = g_atoi(display_str + 4);
}
}
return result;
}
/*****************************************************************************/
int
g_get_display_string(char buff[], unsigned int bufflen)
{
const char *str;
const char *p = NULL;
int rv = 0;
if ((str = g_getenv("WAYLAND_DISPLAY")) != NULL)
{
// Return the unqualified part of the name
p = strrchr(str, '/');
p = (p != NULL) ? (p + 1) : str;
strlcpy(buff, p, bufflen);
}
else if ((str = g_getenv("DISPLAY")) != NULL)
{
int n = get_display_num_from_display(str);
if (n >= 0)
{
g_snprintf(buff, bufflen, "X11-%d", n);
}
else
{
rv = g_get_display_string_from_x11_display(n, buff, bufflen);
}
}
else
{
rv = -1;
}
return rv;
}
/*****************************************************************************/ /*****************************************************************************/
/* returns length of text */ /* returns length of text */
int int
+28 -5
View File
@@ -190,14 +190,37 @@ char *
g_bytes_to_hexdump(const char *src, int len); g_bytes_to_hexdump(const char *src, int len);
/** /**
* Extracts the display number from an X11 display string * Converts an X11 display number to a display string
* *
* @param display_text Display string (i.e. g_getenv("DISPLAY")) * @param display_num X11 display unmber
* * @param buff Buffer for result
* @result <0 if the string could not be parsed, or >=0 for a display number * @param bufflen size of above
* @return != 0 if the result doesn't fit
*/ */
int int
g_get_display_num_from_display(const char *display_text); g_get_display_string_from_x11_display(int display_num,
char buff[], unsigned int bufflen);
/**
* Converts a display string to an X11 display number
*
* @param display_str Display string
* @return X11 display number, or -1 if the display string isn't X11
*/
int
g_get_x11_display_from_display_string(const char *display_str);
/**
* Extracts the display string from either DISPLAY or WAYLAND_DISPLAY
*
* @param buff Buffer for result
* @param bufflen Length of above buffer
*
* Returned buffer will be (e.g.) "X11-10" for X11 or "wayland-1" for Wayland
*
* @result != 0 if the string could not be found or parsed
*/
int
g_get_display_string(char buff[], unsigned int bufflen);
/** /**
* Converts a bitmask into a string for output purposes * Converts a bitmask into a string for output purposes
+6
View File
@@ -49,6 +49,12 @@
**/ **/
#define MAX_XRDP_INSTANCE_NAMELEN 80 #define MAX_XRDP_INSTANCE_NAMELEN 80
/**
* Max length of buffer containing a Wayland or X11 display
* name
**/
#define MAX_DISPLAY_NAME_SIZE 32
/** /**
* Size of buffer including terminator for a socket description, as * Size of buffer including terminator for a socket description, as
* returned by g_sck_get_peer_description() * returned by g_sck_get_peer_description()
+7 -7
View File
@@ -45,13 +45,13 @@
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket" #define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
/* names of socket files within XRDP_SOCKET_PATH, qualified by /* names of socket files within XRDP_SOCKET_PATH, qualified by
* display number */ * display name */
#define XRDP_CHANSRV_BASE_STR "xrdp_chansrv_socket_%d" #define XRDP_CHANSRV_BASE_STR "xrdp_chansrv_socket_%s"
#define CHANSRV_PORT_OUT_BASE_STR "xrdp_chansrv_audio_out_socket_%d" #define CHANSRV_PORT_OUT_BASE_STR "xrdp_chansrv_audio_out_socket_%s"
#define CHANSRV_PORT_IN_BASE_STR "xrdp_chansrv_audio_in_socket_%d" #define CHANSRV_PORT_IN_BASE_STR "xrdp_chansrv_audio_in_socket_%s"
#define CHANSRV_API_BASE_STR "xrdpapi_%d" #define CHANSRV_API_BASE_STR "xrdpapi_%s"
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d" #define XRDP_X11RDP_BASE_STR "xrdp_display_%s"
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d" #define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%s"
/* fullpath declarations */ /* fullpath declarations */
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR #define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR
+1 -2
View File
@@ -420,8 +420,7 @@ If first character is not a '/', this is relative to $HOME.
The following substitutions are made in this string:- The following substitutions are made in this string:-
%U - Username %U - Username
%u - Numeric UID %u - Numeric UID
%d - Numeric display number (ex 10) %d - Display identifier (e.g. "X11-10" for X11, or "wayland-1" for Wayland)
%D - Display environment variable (ex :10.0)
%% - Percent character %% - Percent character
.HP 3 .HP 3
1) The directory path permissions MUST be configured correctly by 1) The directory path permissions MUST be configured correctly by
+17 -10
View File
@@ -273,7 +273,7 @@ eicp_send_logout_request(struct trans *trans)
int int
eicp_send_create_session_request(struct trans *trans, eicp_send_create_session_request(struct trans *trans,
unsigned int display, int x11_display,
enum scp_session_type type, enum scp_session_type type,
unsigned short width, unsigned short width,
unsigned short height, unsigned short height,
@@ -285,8 +285,8 @@ eicp_send_create_session_request(struct trans *trans,
return libipm_msg_out_simple_send( return libipm_msg_out_simple_send(
trans, trans,
(int)E_EICP_CREATE_SESSION_REQUEST, (int)E_EICP_CREATE_SESSION_REQUEST,
"uyqqysss", "iyqqysss",
display, x11_display,
type, type,
width, width,
height, height,
@@ -300,7 +300,7 @@ eicp_send_create_session_request(struct trans *trans,
int int
eicp_get_create_session_request(struct trans *trans, eicp_get_create_session_request(struct trans *trans,
unsigned int *display, int *x11_display,
enum scp_session_type *type, enum scp_session_type *type,
unsigned short *width, unsigned short *width,
unsigned short *height, unsigned short *height,
@@ -310,7 +310,7 @@ eicp_get_create_session_request(struct trans *trans,
const char **instance_name) const char **instance_name)
{ {
/* Intermediate values */ /* Intermediate values */
uint32_t i_display; int32_t i_x11_display;
uint8_t i_type; uint8_t i_type;
uint16_t i_width; uint16_t i_width;
uint16_t i_height; uint16_t i_height;
@@ -318,8 +318,8 @@ eicp_get_create_session_request(struct trans *trans,
int rv = libipm_msg_in_parse( int rv = libipm_msg_in_parse(
trans, trans,
"uyqqysss", "iyqqysss",
&i_display, &i_x11_display,
&i_type, &i_type,
&i_width, &i_width,
&i_height, &i_height,
@@ -330,7 +330,7 @@ eicp_get_create_session_request(struct trans *trans,
if (rv == 0) if (rv == 0)
{ {
*display = i_display; *x11_display = i_x11_display;
*type = (enum scp_session_type)i_type; *type = (enum scp_session_type)i_type;
*width = i_width; *width = i_width;
*height = i_height; *height = i_height;
@@ -345,12 +345,13 @@ eicp_get_create_session_request(struct trans *trans,
int int
eicp_send_create_session_response(struct trans *trans, eicp_send_create_session_response(struct trans *trans,
enum scp_screate_status status, enum scp_screate_status status,
const char *display,
const struct guid *guid) const struct guid *guid)
{ {
struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };
return libipm_msg_out_simple_send( return libipm_msg_out_simple_send(
trans, (int)E_EICP_CREATE_SESSION_RESPONSE, trans, (int)E_EICP_CREATE_SESSION_RESPONSE,
"iB", status, &guid_descriptor); "isB", status, display, &guid_descriptor);
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -358,6 +359,7 @@ eicp_send_create_session_response(struct trans *trans,
int int
eicp_get_create_session_response(struct trans *trans, eicp_get_create_session_response(struct trans *trans,
enum scp_screate_status *status, enum scp_screate_status *status,
const char **display,
struct guid *guid) struct guid *guid)
{ {
/* Intermediate values */ /* Intermediate values */
@@ -366,14 +368,19 @@ eicp_get_create_session_response(struct trans *trans,
const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };
int rv = libipm_msg_in_parse( int rv = libipm_msg_in_parse(
trans, trans,
"iB", "isB",
&i_status, &i_status,
display,
&guid_descriptor); &guid_descriptor);
if (rv == 0) if (rv == 0)
{ {
*status = (enum scp_screate_status)i_status; *status = (enum scp_screate_status)i_status;
} }
else
{
*display = "";
}
return rv; return rv;
} }
+10 -4
View File
@@ -272,7 +272,7 @@ eicp_send_logout_request(struct trans *trans);
* Send an E_EICP_CREATE_SESSION_REQUEST (sesman) * Send an E_EICP_CREATE_SESSION_REQUEST (sesman)
* *
* @param trans EICP transport * @param trans EICP transport
* @param display X display number to use * @param x11_display X display number to use, or -1 if not X11
* @param type Session type * @param type Session type
* @param width Initial session width * @param width Initial session width
* @param height Initial session height * @param height Initial session height
@@ -293,7 +293,7 @@ eicp_send_logout_request(struct trans *trans);
*/ */
int int
eicp_send_create_session_request(struct trans *trans, eicp_send_create_session_request(struct trans *trans,
unsigned int display, int x11_display,
enum scp_session_type type, enum scp_session_type type,
unsigned short width, unsigned short width,
unsigned short height, unsigned short height,
@@ -307,7 +307,7 @@ eicp_send_create_session_request(struct trans *trans,
* Parse an incoming E_EICP_CREATE_SESSION_REQUEST (sesexec) * Parse an incoming E_EICP_CREATE_SESSION_REQUEST (sesexec)
* *
* @param trans EICP transport * @param trans EICP transport
* @param[out] display X display number to use * @param[out] x11_display X display number to use
* @param[out] type Session type * @param[out] type Session type
* @param[out] width Initial session width * @param[out] width Initial session width
* @param[out] height Initial session height * @param[out] height Initial session height
@@ -322,7 +322,7 @@ eicp_send_create_session_request(struct trans *trans,
*/ */
int int
eicp_get_create_session_request(struct trans *trans, eicp_get_create_session_request(struct trans *trans,
unsigned int *display, int *x11_display,
enum scp_session_type *type, enum scp_session_type *type,
unsigned short *width, unsigned short *width,
unsigned short *height, unsigned short *height,
@@ -340,12 +340,15 @@ eicp_get_create_session_request(struct trans *trans,
* *
* @param trans EICP transport * @param trans EICP transport
* @param status Status of creation request * @param status Status of creation request
* @param display Display name, either (e.g.) "X11-n" (X11)
* or "wayland-n" (Wayland)
* @param guid GUID of session * @param guid GUID of session
* @return != 0 for error * @return != 0 for error
*/ */
int int
eicp_send_create_session_response(struct trans *trans, eicp_send_create_session_response(struct trans *trans,
enum scp_screate_status status, enum scp_screate_status status,
const char *display,
const struct guid *guid); const struct guid *guid);
@@ -358,12 +361,15 @@ eicp_send_create_session_response(struct trans *trans,
* *
* @param trans EICP transport * @param trans EICP transport
* @param[out] status Status of creation request * @param[out] status Status of creation request
* @param[out] display Display name, either (e.g.) "X11-n" (X11)
* or "wayland-n" (Wayland)
* @param[out] guid GUID of session * @param[out] guid GUID of session
* @return != 0 for error * @return != 0 for error
*/ */
int int
eicp_get_create_session_response(struct trans *trans, eicp_get_create_session_response(struct trans *trans,
enum scp_screate_status *status, enum scp_screate_status *status,
const char **display,
struct guid *guid); struct guid *guid);
#endif /* EICP_H */ #endif /* EICP_H */
+9 -7
View File
@@ -147,7 +147,7 @@ ercp_msg_in_reset(struct trans *trans)
int int
ercp_send_session_announce_event(struct trans *trans, ercp_send_session_announce_event(struct trans *trans,
unsigned int display, const char *display,
uid_t uid, uid_t uid,
enum scp_session_type type, enum scp_session_type type,
unsigned short start_width, unsigned short start_width,
@@ -163,7 +163,7 @@ ercp_send_session_announce_event(struct trans *trans,
return libipm_msg_out_simple_send( return libipm_msg_out_simple_send(
trans, trans,
(int)E_ERCP_SESSION_ANNOUNCE_EVENT, (int)E_ERCP_SESSION_ANNOUNCE_EVENT,
"uiyqqyBsxs", "siyqqyBsxs",
display, display,
uid, uid,
type, type,
@@ -180,7 +180,7 @@ ercp_send_session_announce_event(struct trans *trans,
int int
ercp_get_session_announce_event(struct trans *trans, ercp_get_session_announce_event(struct trans *trans,
unsigned int *display, const char **display,
uid_t *uid, uid_t *uid,
enum scp_session_type *type, enum scp_session_type *type,
unsigned short *start_width, unsigned short *start_width,
@@ -192,7 +192,6 @@ ercp_get_session_announce_event(struct trans *trans,
const char **instance_name) const char **instance_name)
{ {
/* Intermediate values */ /* Intermediate values */
uint32_t i_display;
int32_t i_uid; int32_t i_uid;
uint8_t i_type; uint8_t i_type;
uint16_t i_width; uint16_t i_width;
@@ -204,8 +203,8 @@ ercp_get_session_announce_event(struct trans *trans,
int rv = libipm_msg_in_parse( int rv = libipm_msg_in_parse(
trans, trans,
"uiyqqyBsxs", "siyqqyBsxs",
&i_display, display,
&i_uid, &i_uid,
&i_type, &i_type,
&i_width, &i_width,
@@ -218,7 +217,6 @@ ercp_get_session_announce_event(struct trans *trans,
if (rv == 0) if (rv == 0)
{ {
*display = i_display;
*uid = (uid_t)i_uid; *uid = (uid_t)i_uid;
*type = (enum scp_session_type)i_type; *type = (enum scp_session_type)i_type;
*start_width = i_width; *start_width = i_width;
@@ -226,6 +224,10 @@ ercp_get_session_announce_event(struct trans *trans,
*bpp = i_bpp; *bpp = i_bpp;
*start_time = (time_t)i_start_time; *start_time = (time_t)i_start_time;
} }
else
{
*display = "";
}
return rv; return rv;
} }
+2 -2
View File
@@ -177,7 +177,7 @@ ercp_msg_in_reset(struct trans *trans);
*/ */
int int
ercp_send_session_announce_event(struct trans *trans, ercp_send_session_announce_event(struct trans *trans,
unsigned int display, const char *display,
uid_t uid, uid_t uid,
enum scp_session_type type, enum scp_session_type type,
unsigned short start_width, unsigned short start_width,
@@ -209,7 +209,7 @@ ercp_send_session_announce_event(struct trans *trans,
*/ */
int int
ercp_get_session_announce_event(struct trans *trans, ercp_get_session_announce_event(struct trans *trans,
unsigned int *display, const char **display,
uid_t *uid, uid_t *uid,
enum scp_session_type *type, enum scp_session_type *type,
unsigned short *start_width, unsigned short *start_width,
+14 -11
View File
@@ -481,7 +481,7 @@ scp_get_create_session_request(struct trans *trans,
int int
scp_send_create_session_response(struct trans *trans, scp_send_create_session_response(struct trans *trans,
enum scp_screate_status status, enum scp_screate_status status,
int display, const char *display,
const struct guid *guid) const struct guid *guid)
{ {
struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };
@@ -489,7 +489,7 @@ scp_send_create_session_response(struct trans *trans,
return libipm_msg_out_simple_send( return libipm_msg_out_simple_send(
trans, trans,
(int)E_SCP_CREATE_SESSION_RESPONSE, (int)E_SCP_CREATE_SESSION_RESPONSE,
"iiB", "isB",
status, status,
display, display,
&guid_descriptor); &guid_descriptor);
@@ -500,25 +500,27 @@ scp_send_create_session_response(struct trans *trans,
int int
scp_get_create_session_response(struct trans *trans, scp_get_create_session_response(struct trans *trans,
enum scp_screate_status *status, enum scp_screate_status *status,
int *display, const char **display,
struct guid *guid) struct guid *guid)
{ {
/* Intermediate values */ /* Intermediate values */
int32_t i_status; int32_t i_status;
int32_t i_display;
const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) }; const struct libipm_fsb guid_descriptor = { (void *)guid, sizeof(*guid) };
int rv = libipm_msg_in_parse( int rv = libipm_msg_in_parse(
trans, trans,
"iiB", "isB",
&i_status, &i_status,
&i_display, display,
&guid_descriptor); &guid_descriptor);
if (rv == 0) if (rv == 0)
{ {
*status = (enum scp_screate_status)i_status; *status = (enum scp_screate_status)i_status;
*display = i_display; }
else
{
*display = "";
} }
return rv; return rv;
@@ -747,7 +749,7 @@ scp_send_list_sessions_response(
rv = libipm_msg_out_simple_send( rv = libipm_msg_out_simple_send(
trans, trans,
(int)E_SCP_LIST_SESSIONS_RESPONSE, (int)E_SCP_LIST_SESSIONS_RESPONSE,
"iiuyqqyxisssxs", "iisyqqyxisssxs",
status, status,
info->sid, info->sid,
info->display, info->display,
@@ -791,7 +793,7 @@ scp_get_list_sessions_response(
if (*status == E_SCP_LS_SESSION_INFO) if (*status == E_SCP_LS_SESSION_INFO)
{ {
int32_t i_sid; int32_t i_sid;
uint32_t i_display; char *i_display;
uint8_t i_type; uint8_t i_type;
uint16_t i_width; uint16_t i_width;
uint16_t i_height; uint16_t i_height;
@@ -806,7 +808,7 @@ scp_get_list_sessions_response(
rv = libipm_msg_in_parse( rv = libipm_msg_in_parse(
trans, trans,
"iuyqqyxisssxs", "isyqqyxisssxs",
&i_sid, &i_sid,
&i_display, &i_display,
&i_type, &i_type,
@@ -826,6 +828,7 @@ scp_get_list_sessions_response(
/* Allocate a block of memory large enough for the /* Allocate a block of memory large enough for the
* structure result, and the strings it contains */ * structure result, and the strings it contains */
unsigned int len = sizeof(struct scp_session_info) + unsigned int len = sizeof(struct scp_session_info) +
g_strlen(i_display) + 1 +
g_strlen(i_start_ip_addr) + 1 + g_strlen(i_start_ip_addr) + 1 +
g_strlen(i_client_ip) + 1 + g_strlen(i_client_ip) + 1 +
g_strlen(i_client_name) + 1 + g_strlen(i_client_name) + 1 +
@@ -848,7 +851,7 @@ scp_get_list_sessions_response(
} }
/* Copy the data over */ /* Copy the data over */
p->sid = i_sid; p->sid = i_sid;
p->display = i_display; COPY_STRING(p->display, i_display);
p->type = (enum scp_session_type)i_type; p->type = (enum scp_session_type)i_type;
p->width = i_width; p->width = i_width;
p->height = i_height; p->height = i_height;
+6 -4
View File
@@ -391,15 +391,17 @@ scp_get_create_session_request(struct trans *trans,
* *
* @param trans SCP transport * @param trans SCP transport
* @param status Status of creation request * @param status Status of creation request
* @param display Should be zero if create session failed. * @param display Will be "" if create session failed
* @param guid Guid for session. Should be all zeros if create session failed * @param guid Guid for session. Should be all zeros if create session failed
* *
* @return != 0 for error * @return != 0 for error
*
* The display will be either "X11-n" (X11) or (e.g) "wayland-0" (Wayland)
*/ */
int int
scp_send_create_session_response(struct trans *trans, scp_send_create_session_response(struct trans *trans,
enum scp_screate_status status, enum scp_screate_status status,
int display, const char *display,
const struct guid *guid); const struct guid *guid);
@@ -408,7 +410,7 @@ scp_send_create_session_response(struct trans *trans,
* *
* @param trans SCP transport * @param trans SCP transport
* @param[out] status Status of creation request * @param[out] status Status of creation request
* @param[out] display Should be zero if create session failed. * @param[out] display Will be "" if create session failed
* @param[out] guid Guid for session. Should be all zeros if create session * @param[out] guid Guid for session. Should be all zeros if create session
* failed * failed
* *
@@ -417,7 +419,7 @@ scp_send_create_session_response(struct trans *trans,
int int
scp_get_create_session_response(struct trans *trans, scp_get_create_session_response(struct trans *trans,
enum scp_screate_status *status, enum scp_screate_status *status,
int *display, const char **display,
struct guid *guid); struct guid *guid);
/** /**
+4 -1
View File
@@ -45,13 +45,16 @@ enum scp_session_type
"unknown" \ "unknown" \
) )
#define SCP_SESSION_TYPE_IS_X11(t) \
((t) >= SCP_SESSION_TYPE_XVNC && (t) <= SCP_SESSION_TYPE_XORG)
/** /**
* @brief Information to display about a particular sesman session * @brief Information to display about a particular sesman session
*/ */
struct scp_session_info struct scp_session_info
{ {
int sid; ///< Session ID int sid; ///< Session ID
unsigned int display; ///< Display number char *display; ///< Display name ("X11-n" or "wayland-n")
enum scp_session_type type; ///< Session type enum scp_session_type type; ///< Session type
unsigned short width; ///< Initial session width unsigned short width; ///< Initial session width
unsigned short height; ///< Initial session height unsigned short height; ///< Initial session height
+11 -18
View File
@@ -43,6 +43,7 @@
#include "chansrv_fuse.h" #include "chansrv_fuse.h"
#include "chansrv_config.h" #include "chansrv_config.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
#include "xrdp_constants.h"
#include "audin.h" #include "audin.h"
#include "channel_defs.h" #include "channel_defs.h"
@@ -68,7 +69,8 @@ static tbus g_thread_done_event = 0;
struct config_chansrv *g_cfg = NULL; struct config_chansrv *g_cfg = NULL;
int g_display_num = -1; char g_display_str[MAX_DISPLAY_NAME_SIZE];
int g_cliprdr_chan_id = -1; /* cliprdr */ int g_cliprdr_chan_id = -1; /* cliprdr */
int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpsnd_chan_id = -1; /* rdpsnd */
int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rdpdr_chan_id = -1; /* rdpdr */
@@ -1426,7 +1428,8 @@ setup_listen(void)
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
g_lis_trans->is_term = g_is_term; g_lis_trans->is_term = g_is_term;
g_snprintf(port, sizeof(port), XRDP_CHANSRV_STR, g_getuid(), g_display_num); g_snprintf(port, sizeof(port), XRDP_CHANSRV_STR,
g_getuid(), g_display_str);
g_lis_trans->trans_conn_in = my_trans_conn_in; g_lis_trans->trans_conn_in = my_trans_conn_in;
error = trans_listen(g_lis_trans, port); error = trans_listen(g_lis_trans, port);
@@ -1450,7 +1453,8 @@ setup_api_listen(void)
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4); g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
g_api_lis_trans->is_term = g_is_term; g_api_lis_trans->is_term = g_is_term;
g_snprintf(port, sizeof(port), CHANSRV_API_STR, g_getuid(), g_display_num); g_snprintf(port, sizeof(port), CHANSRV_API_STR,
g_getuid(), g_display_str);
g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
error = trans_listen(g_api_lis_trans, port); error = trans_listen(g_api_lis_trans, port);
@@ -1933,24 +1937,15 @@ main(int argc, char **argv)
char text[256]; char text[256];
const char *config_path; const char *config_path;
char log_path[256]; char log_path[256];
const char *display_text;
char log_file[256]; char log_file[256];
enum logReturns error; enum logReturns error;
struct log_config *logconfig; struct log_config *logconfig;
g_init("xrdp-chansrv"); /* os_calls */ g_init("xrdp-chansrv"); /* os_calls */
g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs)); g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs));
display_text = g_getenv("DISPLAY"); if (g_get_display_string(g_display_str, sizeof(g_display_str)) < 0)
if (display_text == NULL)
{ {
g_writeln("DISPLAY is not set"); g_writeln("Unable to get display string");
main_cleanup();
return 1;
}
g_display_num = g_get_display_num_from_display(display_text);
if (g_display_num < 0)
{
g_writeln("Unable to get display from DISPLAY='%s'", display_text);
main_cleanup(); main_cleanup();
return 1; return 1;
} }
@@ -1976,7 +1971,8 @@ main(int argc, char **argv)
pid = g_getpid(); pid = g_getpid();
/* starting logging subsystem */ /* starting logging subsystem */
g_snprintf(log_file, 255, "%s/xrdp-chansrv.%d.log", log_path, g_display_num); g_snprintf(log_file, sizeof(log_file),
"%s/xrdp-chansrv.%s.log", log_path, g_display_str);
g_writeln("chansrv::main: using log file [%s]", log_file); g_writeln("chansrv::main: using log file [%s]", log_file);
if (g_file_exist(log_file)) if (g_file_exist(log_file))
{ {
@@ -2038,9 +2034,6 @@ main(int argc, char **argv)
/* Cater for the X server exiting unexpectedly */ /* Cater for the X server exiting unexpectedly */
xcommon_set_x_server_fatal_handler(x_server_fatal_handler); xcommon_set_x_server_fatal_handler(x_server_fatal_handler);
LOG_DEVEL(LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text);
LOG_DEVEL(LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num);
/* Set up RAIL sync objects */ /* Set up RAIL sync objects */
g_snprintf(text, sizeof(text), "xrdp_chansrv_%8.8x_exec", pid); g_snprintf(text, sizeof(text), "xrdp_chansrv_%8.8x_exec", pid);
g_exec_event = g_create_wait_obj(text); g_exec_event = g_create_wait_obj(text);
+5 -13
View File
@@ -173,6 +173,7 @@ int xfuse_path_in_xfuse_fs(const char *path)
#include "devredir.h" #include "devredir.h"
#include "list.h" #include "list.h"
#include "file.h" #include "file.h"
#include "xrdp_constants.h"
/* Check for FUSE features we may wish to use /* Check for FUSE features we may wish to use
* *
@@ -2989,14 +2990,12 @@ static unsigned int format_user_info(char *dest, unsigned int len,
{ {
char uidstr[64]; char uidstr[64];
char username[64]; char username[64];
char display[64]; char display[MAX_DISPLAY_NAME_SIZE];
char displaynum[64];
const struct info_string_tag map[] = const struct info_string_tag map[] =
{ {
{'u', uidstr}, {'u', uidstr},
{'U', username}, {'U', username},
{'d', displaynum}, {'d', display},
{'D', display},
INFO_STRING_END_OF_LIST INFO_STRING_END_OF_LIST
}; };
@@ -3005,20 +3004,13 @@ static unsigned int format_user_info(char *dest, unsigned int len,
if (g_getlogin(username, sizeof(username)) != 0) if (g_getlogin(username, sizeof(username)) != 0)
{ {
/* Fall back to UID */ /* Fall back to UID */
g_strncpy(username, uidstr, sizeof(username) - 1); strlcpy(username, uidstr, sizeof(username));
} }
if (getenv("DISPLAY") == NULL) if (g_get_display_string(display, sizeof(display)) < 0)
{ {
/* if environment variable is not set, set it to empty string */ /* if environment variable is not set, set it to empty string */
display[0] = '\0'; display[0] = '\0';
displaynum[0] = '\0';
}
else
{
g_strncpy(display, getenv("DISPLAY"), sizeof(display) - 1);
g_snprintf(displaynum, sizeof(displaynum), "%d",
g_get_display_num_from_display(display));
} }
return g_format_info_string(dest, len, format, map); return g_format_info_string(dest, len, format, map);
+7 -14
View File
@@ -15,7 +15,9 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <poll.h> #include <poll.h>
#include "os_calls.h"
#include "string_calls.h" #include "string_calls.h"
#include "xrdp_constants.h"
#define PCSC_API #define PCSC_API
@@ -164,10 +166,9 @@ static int
connect_to_chansrv(void) connect_to_chansrv(void)
{ {
int bytes; int bytes;
int dis; char disstr[MAX_DISPLAY_NAME_SIZE];
int error; int error;
char *xrdp_session; char *xrdp_session;
char *xrdp_display;
char *home_str; char *home_str;
struct sockaddr_un saddr; struct sockaddr_un saddr;
struct sockaddr *psaddr; struct sockaddr *psaddr;
@@ -184,11 +185,10 @@ connect_to_chansrv(void)
LLOGLN(0, ("connect_to_chansrv: error, not xrdp session")); LLOGLN(0, ("connect_to_chansrv: error, not xrdp session"));
return 1; return 1;
} }
xrdp_display = getenv("DISPLAY");
if (xrdp_display == NULL) if (g_get_display_string(disstr, sizeof(disstr)) < 0)
{ {
/* DISPLAY must be set */ LLOGLN(0, ("connect_to_chansrv: error, don't understand DISPLAY"));
LLOGLN(0, ("connect_to_chansrv: error, display not set"));
return 1; return 1;
} }
home_str = getenv("HOME"); home_str = getenv("HOME");
@@ -198,13 +198,6 @@ connect_to_chansrv(void)
LLOGLN(0, ("connect_to_chansrv: error, home not set")); LLOGLN(0, ("connect_to_chansrv: error, home not set"));
return 1; return 1;
} }
dis = g_get_display_num_from_display(xrdp_display);
if (dis < 0)
{
LLOGLN(0, ("connect_to_chansrv: error, don't understand DISPLAY='%s'",
xrdp_display));
return 1;
}
g_sck = socket(PF_LOCAL, SOCK_STREAM, 0); g_sck = socket(PF_LOCAL, SOCK_STREAM, 0);
if (g_sck == -1) if (g_sck == -1)
{ {
@@ -214,7 +207,7 @@ connect_to_chansrv(void)
memset(&saddr, 0, sizeof(struct sockaddr_un)); memset(&saddr, 0, sizeof(struct sockaddr_un));
saddr.sun_family = AF_UNIX; saddr.sun_family = AF_UNIX;
bytes = sizeof(saddr.sun_path); bytes = sizeof(saddr.sun_path);
snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis); snprintf(saddr.sun_path, bytes, "%s/.pcsc%s/pcscd.comm", home_str, disstr);
saddr.sun_path[bytes - 1] = 0; saddr.sun_path[bytes - 1] = 0;
LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path)); LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
psaddr = (struct sockaddr *) &saddr; psaddr = (struct sockaddr *) &saddr;
+1 -1
View File
@@ -44,7 +44,7 @@
#include "list.h" #include "list.h"
extern int g_rail_chan_id; /* in chansrv.c */ extern int g_rail_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */ extern char g_display_str[]; /* in chansrv.c */
extern char *g_exec_name; /* in chansrv.c */ extern char *g_exec_name; /* in chansrv.c */
extern tbus g_exec_event; /* in chansrv.c */ extern tbus g_exec_event; /* in chansrv.c */
extern tbus g_exec_mutex; /* in chansrv.c */ extern tbus g_exec_mutex; /* in chansrv.c */
+6 -5
View File
@@ -52,11 +52,12 @@
#include "chansrv.h" #include "chansrv.h"
#include "list.h" #include "list.h"
#include "smartcard_pcsc.h" #include "smartcard_pcsc.h"
#include "xrdp_sockets.h"
#if PCSC_STANDIN #if PCSC_STANDIN
extern int g_display_num; /* in chansrv.c */ extern char g_display_str[]; /* in chansrv.c */
static int g_autoinc = 0; /* general purpose autoinc */ static int g_autoinc = 0; /* general purpose autoinc */
@@ -1982,7 +1983,6 @@ int
scard_pcsc_init(void) scard_pcsc_init(void)
{ {
char *home; char *home;
int disp;
int error; int error;
LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_init:"); LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_init:");
@@ -1992,8 +1992,8 @@ scard_pcsc_init(void)
// TODO: See #2501. Use needs a way to move PCSCLITE_CSOCK_NAME // TODO: See #2501. Use needs a way to move PCSCLITE_CSOCK_NAME
// to a location not under $HOME. // to a location not under $HOME.
home = g_getenv("HOME"); home = g_getenv("HOME");
disp = g_display_num; g_snprintf(g_pcsclite_ipc_dir, sizeof(g_pcsclite_ipc_dir),
g_snprintf(g_pcsclite_ipc_dir, 255, "%s/.pcsc%d", home, disp); "%s/.pcsc%s", home, g_display_str);
if (g_directory_exist(g_pcsclite_ipc_dir)) if (g_directory_exist(g_pcsclite_ipc_dir))
{ {
@@ -2015,7 +2015,8 @@ scard_pcsc_init(void)
/* Only the current user should be able to access the remote /* Only the current user should be able to access the remote
* smartcard */ * smartcard */
g_chmod_hex(g_pcsclite_ipc_dir, 0x700); g_chmod_hex(g_pcsclite_ipc_dir, 0x700);
g_snprintf(g_pcsclite_ipc_file, 255, "%s/pcscd.comm", g_pcsclite_ipc_dir); g_snprintf(g_pcsclite_ipc_file, sizeof(g_pcsclite_ipc_file),
"%s/pcscd.comm", g_pcsclite_ipc_dir);
g_lis->trans_conn_in = my_pcsc_trans_conn_in; g_lis->trans_conn_in = my_pcsc_trans_conn_in;
error = trans_listen(g_lis, g_pcsclite_ipc_file); error = trans_listen(g_lis, g_pcsclite_ipc_file);
if (error != 0) if (error != 0)
+5 -3
View File
@@ -63,7 +63,7 @@ static lame_global_flags *g_lame_encoder = 0;
#endif #endif
extern int g_rdpsnd_chan_id; /* in chansrv.c */ extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */ extern char g_display_str[]; /* in chansrv.c */
extern struct config_chansrv *g_cfg; /* in chansrv.c */ extern struct config_chansrv *g_cfg; /* in chansrv.c */
/* audio out: sound_server -> xrdp -> NeutrinoRDP */ /* audio out: sound_server -> xrdp -> NeutrinoRDP */
@@ -1903,7 +1903,8 @@ sound_start_source_listener(void)
g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192); g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
g_audio_l_trans_in->is_term = g_is_term; g_audio_l_trans_in->is_term = g_is_term;
g_snprintf(port, sizeof(port), CHANSRV_PORT_IN_STR, g_getuid(), g_display_num); g_snprintf(port, sizeof(port), CHANSRV_PORT_IN_STR, g_getuid(),
g_display_str);
g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in; g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
if (trans_listen(g_audio_l_trans_in, port) != 0) if (trans_listen(g_audio_l_trans_in, port) != 0)
{ {
@@ -1922,7 +1923,8 @@ sound_start_sink_listener(void)
g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192); g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
g_audio_l_trans_out->is_term = g_is_term; g_audio_l_trans_out->is_term = g_is_term;
g_snprintf(port, sizeof(port), CHANSRV_PORT_OUT_STR, g_getuid(), g_display_num); g_snprintf(port, sizeof(port), CHANSRV_PORT_OUT_STR, g_getuid(),
g_display_str);
g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in; g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
if (trans_listen(g_audio_l_trans_out, port) != 0) if (trans_listen(g_audio_l_trans_out, port) != 0)
{ {
+5 -6
View File
@@ -100,12 +100,12 @@ static int
process_create_session_response(struct scp_list_item *sli) process_create_session_response(struct scp_list_item *sli)
{ {
struct session_item *s_item; struct session_item *s_item;
int display; const char *display;
struct guid guid; struct guid guid;
enum scp_screate_status status; enum scp_screate_status status;
int rv = eicp_get_create_session_response(sli->sesexec_trans, int rv = eicp_get_create_session_response(sli->sesexec_trans,
&status, &guid); &status, &display, &guid);
if (rv == 0) if (rv == 0)
{ {
// Create an entry on the session list for the new session // Create an entry on the session list for the new session
@@ -130,8 +130,7 @@ process_create_session_response(struct scp_list_item *sli)
s_item->sesexec_pid = sli->sesexec_pid; s_item->sesexec_pid = sli->sesexec_pid;
s_item->guid = guid; s_item->guid = guid;
s_item->uid = sli->uid; s_item->uid = sli->uid;
s_item->display = sli->session_display; strlcpy(s_item->display, display, sizeof(s_item->display));
display = s_item->display;
// We don't use the sesexec process again // We don't use the sesexec process again
sli->sesexec_trans = NULL; sli->sesexec_trans = NULL;
@@ -140,12 +139,12 @@ process_create_session_response(struct scp_list_item *sli)
else else
{ {
guid_clear(&guid); guid_clear(&guid);
display = -1; display = "";
} }
rv = scp_send_create_session_response(sli->client_trans, status, rv = scp_send_create_session_response(sli->client_trans, status,
display, &guid); display, &guid);
sli->create_session_in_progress = 0; sli->create_session_in_progress = 0;
sli->session_display = -1; sli->session_x11_display = -1;
} }
return rv; return rv;
+6 -17
View File
@@ -44,7 +44,7 @@ process_session_announce_event(struct session_item *si)
int rv; int rv;
const char *start_ip_addr; const char *start_ip_addr;
const char *instance_name; const char *instance_name;
unsigned int display; const char *display;
rv = ercp_get_session_announce_event(si->sesexec_trans, rv = ercp_get_session_announce_event(si->sesexec_trans,
&display, &display,
@@ -57,30 +57,19 @@ process_session_announce_event(struct session_item *si)
&start_ip_addr, &start_ip_addr,
&si->start_time, &si->start_time,
&instance_name); &instance_name);
if (rv == 0)
{
// We may already know the display we sent sesexec. If we do,
// check sesexec sent the same value back.
if (si->display >= 0 && display != (unsigned int)si->display)
{
LOG(LOG_LEVEL_ERROR, "Bugcheck: sesman expected display %d, got %u",
si->display, display);
rv = 1;
}
}
if (rv == 0) if (rv == 0)
{ {
snprintf(si->start_ip_addr, sizeof(si->start_ip_addr), snprintf(si->start_ip_addr, sizeof(si->start_ip_addr),
"%s", start_ip_addr); "%s", start_ip_addr);
strlcpy(si->display, display, sizeof(si->display));
snprintf(si->xrdp_instance_name, sizeof(si->xrdp_instance_name), snprintf(si->xrdp_instance_name, sizeof(si->xrdp_instance_name),
"%s", instance_name); "%s", instance_name);
si->display = display;
si->state = E_SESSION_RUNNING; si->state = E_SESSION_RUNNING;
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"sesman: Session on display :%d is now running", si->display); "sesman: Session on display %s is now running", si->display);
} }
return rv; return rv;
@@ -90,7 +79,7 @@ process_session_announce_event(struct session_item *si)
static void static void
process_session_finished_event(struct session_item *si) process_session_finished_event(struct session_item *si)
{ {
LOG(LOG_LEVEL_INFO, "sesman: Session on display :%d has finished.", LOG(LOG_LEVEL_INFO, "sesman: Session on display %s has finished.",
si->display); si->display);
// Setting the transport down will remove this connection from the list // Setting the transport down will remove this connection from the list
si->sesexec_trans->status = TRANS_STATUS_DOWN; si->sesexec_trans->status = TRANS_STATUS_DOWN;
@@ -113,7 +102,7 @@ process_client_connect_event(struct session_item *si)
strlcpy(si->client_name, client_name, sizeof(si->client_name)); strlcpy(si->client_name, client_name, sizeof(si->client_name));
si->last_connect_disconnect = connect_time; si->last_connect_disconnect = connect_time;
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"sesman: Session on display :%d is connected from client '%s'", "sesman: Session on display %s is connected from client '%s'",
si->display, si->client_name); si->display, si->client_name);
} }
@@ -134,7 +123,7 @@ process_client_disconnect_event(struct session_item *si)
si->client_name[0] = '\0'; si->client_name[0] = '\0';
si->last_connect_disconnect = disconnect_time; si->last_connect_disconnect = disconnect_time;
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"sesman: Session on display :%d has no client connection", "sesman: Session on display %s has no client connection",
si->display); si->display);
} }
+6 -4
View File
@@ -126,7 +126,7 @@ scp_list_item_new(void)
{ {
g_snprintf(result->peername, sizeof(result->peername), "unknown"); g_snprintf(result->peername, sizeof(result->peername), "unknown");
result->uid = (uid_t) -1; result->uid = (uid_t) -1;
result->session_display = -1; result->session_x11_display = -1;
if (!list_add_item(g_scp_list, (tintptr)result)) if (!list_add_item(g_scp_list, (tintptr)result))
{ {
g_free(result); g_free(result);
@@ -263,7 +263,7 @@ scp_list_check_wait_objs(void)
/******************************************************************************/ /******************************************************************************/
void void
scp_list_get_create_session_displays(struct set_int *alloc_displays) scp_list_get_create_session_x11_displays(struct set_int *alloc_displays)
{ {
int i = 0; int i = 0;
for (i = 0; i < g_scp_list->count; ++i) for (i = 0; i < g_scp_list->count; ++i)
@@ -272,10 +272,12 @@ scp_list_get_create_session_displays(struct set_int *alloc_displays)
sli = (struct scp_list_item *)list_get_item(g_scp_list, i); sli = (struct scp_list_item *)list_get_item(g_scp_list, i);
// Only add X11 displays
if (SCP_LIST_ITEM_IN_USE(sli) && if (SCP_LIST_ITEM_IN_USE(sli) &&
sli->create_session_in_progress) sli->create_session_in_progress &&
sli->session_x11_display >= 0)
{ {
set_int_add(alloc_displays, sli->session_display); set_int_add(alloc_displays, sli->session_x11_display);
} }
} }
} }
+5 -5
View File
@@ -87,8 +87,8 @@ struct scp_list_item
char xrdp_instance_name[MAX_XRDP_INSTANCE_NAMELEN]; ///< Instance name associated with session char xrdp_instance_name[MAX_XRDP_INSTANCE_NAMELEN]; ///< Instance name associated with session
int is_admin; int is_admin;
int create_session_in_progress; ///< Already handling a create_session int create_session_in_progress; ///< Already handling a create_session
/// Display allocated for session. This is always valid (>= 0) /// X11 display allocated for session (-1 if N/A)
unsigned int session_display; int session_x11_display;
}; };
@@ -158,11 +158,11 @@ int
scp_list_check_wait_objs(void); scp_list_check_wait_objs(void);
/** /**
* @brief Get all create-session displays * @brief Get all create-session X11 displays
* *
* Adds displays allocated to create-session operations to a set * Adds X11 displays allocated to create-session operations to a set
*/ */
void void
scp_list_get_create_session_displays(struct set_int *alloc_displays); scp_list_get_create_session_x11_displays(struct set_int *alloc_displays);
#endif // SCP_LIST_H #endif // SCP_LIST_H
+11 -9
View File
@@ -414,8 +414,8 @@ get_free_display(void)
{ {
// Get all the displays either allocated to sessions, or // Get all the displays either allocated to sessions, or
// potentially assigned to sessions on the SCP list // potentially assigned to sessions on the SCP list
session_list_get_session_displays(alloc_displays); session_list_get_session_x11_displays(alloc_displays);
scp_list_get_create_session_displays(alloc_displays); scp_list_get_create_session_x11_displays(alloc_displays);
// Find a free display, taking the allocated ones into account // Find a free display, taking the allocated ones into account
result = display_utils_get_free_display(alloc_displays); result = display_utils_get_free_display(alloc_displays);
@@ -442,7 +442,8 @@ process_create_session_request(struct scp_list_item *sli)
const char *instance_name; const char *instance_name;
struct guid guid; struct guid guid;
int display = -1; const char *display;
int x11_display = -1;
struct session_item *s_item = NULL; struct session_item *s_item = NULL;
int start_sesexec = (sli->sesexec_trans == NULL); int start_sesexec = (sli->sesexec_trans == NULL);
int send_client_reply = 1; int send_client_reply = 1;
@@ -476,7 +477,7 @@ process_create_session_request(struct scp_list_item *sli)
{ {
// Found an existing session // Found an existing session
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"A suitable session on display :%d is already active", "A suitable session on display %s is already active",
s_item->display); s_item->display);
display = s_item->display; display = s_item->display;
guid = s_item->guid; guid = s_item->guid;
@@ -489,10 +490,11 @@ process_create_session_request(struct scp_list_item *sli)
"The maximum number of sessions has been reached"); "The maximum number of sessions has been reached");
status = E_SCP_SCREATE_MAX_REACHED; status = E_SCP_SCREATE_MAX_REACHED;
} }
else if ((display = get_free_display()) < 0) else if (SCP_SESSION_TYPE_IS_X11(type) &&
(x11_display = get_free_display()) < 0)
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"No free display can be found for a new session"); "No free X11 display can be found for a new session");
status = E_SCP_SCREATE_NO_DISPLAY; status = E_SCP_SCREATE_NO_DISPLAY;
} }
// Create a socket dir for this user // Create a socket dir for this user
@@ -532,7 +534,7 @@ process_create_session_request(struct scp_list_item *sli)
int eicp_stat; int eicp_stat;
eicp_stat = eicp_send_create_session_request( eicp_stat = eicp_send_create_session_request(
sli->sesexec_trans, sli->sesexec_trans,
display, x11_display,
type, width, height, type, width, height,
bpp, shell, directory, bpp, shell, directory,
instance_name); instance_name);
@@ -551,7 +553,7 @@ process_create_session_request(struct scp_list_item *sli)
// We're not sending a reply yet // We're not sending a reply yet
send_client_reply = 0; send_client_reply = 0;
sli->create_session_in_progress = 1; sli->create_session_in_progress = 1;
sli->session_display = display; // Reserve display sli->session_x11_display = x11_display; // Reserve display
} }
} }
} }
@@ -560,7 +562,7 @@ process_create_session_request(struct scp_list_item *sli)
{ {
if (status != E_SCP_SCREATE_OK) if (status != E_SCP_SCREATE_OK)
{ {
display = -1; display = "";
guid_clear(&guid); guid_clear(&guid);
} }
rv = scp_send_create_session_response(sli->client_trans, rv = scp_send_create_session_response(sli->client_trans,
+9 -3
View File
@@ -148,13 +148,14 @@ handle_create_session_request(struct trans *self)
int status; int status;
status = eicp_get_create_session_request( status = eicp_get_create_session_request(
self, &sp.display, self, &sp.x11_display,
&sp.type, &sp.width, &sp.height, &sp.type, &sp.width, &sp.height,
&sp.bpp, &sp.shell, &sp.directory, &sp.bpp, &sp.shell, &sp.directory,
&sp.instance_name); &sp.instance_name);
if (status == 0) if (status == 0)
{ {
enum scp_screate_status scp_status = E_SCP_SCREATE_OK; enum scp_screate_status scp_status = E_SCP_SCREATE_OK;
const char *display = "";
// Must be logged in to start a session // Must be logged in to start a session
if (g_login_info == NULL) if (g_login_info == NULL)
@@ -166,10 +167,15 @@ handle_create_session_request(struct trans *self)
// Try to create the session // Try to create the session
sp.guid = guid_new(); sp.guid = guid_new();
scp_status = session_start(g_login_info, &sp, &g_session_data); scp_status = session_start(g_login_info, &sp, &g_session_data);
if (scp_status == E_SCP_SCREATE_OK)
{
display = session_get_display(g_session_data);
}
} }
// Return the creation status to sesman. // Return the creation status to sesman.
status = eicp_send_create_session_response(self, scp_status, &sp.guid); status = eicp_send_create_session_response(self, scp_status, display,
&sp.guid);
if (status == 0 && scp_status == E_SCP_SCREATE_OK) if (status == 0 && scp_status == E_SCP_SCREATE_OK)
{ {
// Further comms to sesman is sent over the ERCP protocol // Further comms to sesman is sent over the ERCP protocol
@@ -178,7 +184,7 @@ handle_create_session_request(struct trans *self)
// Announce the session to sesman // Announce the session to sesman
if ((status = ercp_send_session_announce_event( if ((status = ercp_send_session_announce_event(
self, self,
sp.display, display,
g_login_info->uid, g_login_info->uid,
sp.type, sp.type,
sp.width, sp.width,
+43 -160
View File
@@ -36,95 +36,24 @@
#include "log.h" #include "log.h"
#include "os_calls.h" #include "os_calls.h"
#include "sesexec.h" #include "sesexec.h"
#include "ssl_calls.h"
#include "string_calls.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
/******************************************************************************/ /******************************************************************************/
int int
env_check_password_file(const char *filename, const char *passwd) env_set_user(int uid,
{
char encryptedPasswd[16];
char key[24];
char passwd_hash[20];
char passwd_hash_text[40];
int fd;
int passwd_bytes;
void *des;
void *sha1;
if (filename == NULL)
{
LOG(LOG_LEVEL_WARNING, "Cannot write VNC password hash to NULL file");
return 1;
}
/*
* If we're in FIPS mode, do not write the GUID to disk after it's
* been encrypted with an insecure algorithm.
*/
if (g_fips_mode_enabled())
{
LOG(LOG_LEVEL_ERROR, "Can't create VNC password file in FIPS mode");
return 1;
}
/* create password hash from password */
passwd_bytes = (passwd == NULL) ? 0 : strlen(passwd);
sha1 = ssl_sha1_info_create();
ssl_sha1_clear(sha1);
ssl_sha1_transform(sha1, "xrdp_vnc", 8);
ssl_sha1_transform(sha1, passwd, passwd_bytes);
ssl_sha1_transform(sha1, passwd, passwd_bytes);
ssl_sha1_complete(sha1, passwd_hash);
ssl_sha1_info_delete(sha1);
g_snprintf(passwd_hash_text, sizeof(passwd_hash_text),
"%2.2x%2.2x%2.2x%2.2x",
(tui8)passwd_hash[0], (tui8)passwd_hash[1],
(tui8)passwd_hash[2], (tui8)passwd_hash[3]);
passwd = passwd_hash_text;
/* create file from password */
g_memset(encryptedPasswd, 0, sizeof(encryptedPasswd));
g_strncpy(encryptedPasswd, passwd, 8);
g_memset(key, 0, sizeof(key));
g_mirror_memcpy(key, g_fixedkey, 8);
des = ssl_des3_encrypt_info_create(key, 0);
ssl_des3_encrypt(des, 8, encryptedPasswd, encryptedPasswd);
ssl_des3_info_delete(des);
fd = g_file_open_ex(filename, 0, 1, 1, 1);
if (fd == -1)
{
LOG(LOG_LEVEL_WARNING,
"Cannot write VNC password hash to file %s: %s",
filename, g_get_strerror());
return 1;
}
g_file_write(fd, encryptedPasswd, 8);
g_file_close(fd);
return 0;
}
/******************************************************************************/
/* its the responsibility of the caller to free passwd_file */
int
env_set_user(int uid, char **passwd_file, int display,
const struct list *env_names, const struct list *env_values) const struct list *env_names, const struct list *env_values)
{ {
int error; int error;
int pw_gid; int pw_gid;
int index; int index;
int len;
char *name; char *name;
char *value; char *value;
char *pw_username; char *pw_username = NULL;
char *pw_shell; char *pw_shell = NULL;
char *pw_dir; char *pw_dir = NULL;
char *display = NULL;
int is_x11 = 0;
char text[256]; char text[256];
char hostname[256];
pw_username = 0;
pw_shell = 0;
pw_dir = 0;
error = g_getuser_info_by_uid(uid, &pw_username, &pw_gid, &pw_shell, error = g_getuser_info_by_uid(uid, &pw_username, &pw_gid, &pw_shell,
&pw_dir, 0); &pw_dir, 0);
@@ -162,27 +91,15 @@ env_set_user(int uid, char **passwd_file, int display,
g_setenv_log("UID", text, 1); g_setenv_log("UID", text, 1);
g_setenv_log("HOME", pw_dir, 1); g_setenv_log("HOME", pw_dir, 1);
g_set_current_dir(pw_dir); g_set_current_dir(pw_dir);
g_snprintf(text, sizeof(text), ":%d.0", display);
g_setenv_log("DISPLAY", text, 1);
// Use our PID as the XRDP_SESSION value // Use our PID as the XRDP_SESSION value
g_snprintf(text, sizeof(text), "%d", g_pid); g_snprintf(text, sizeof(text), "%d", g_pid);
g_setenv_log("XRDP_SESSION", text, 1); g_setenv_log("XRDP_SESSION", text, 1);
/* XRDP_SOCKET_PATH should be set here. It's used by /* XRDP_SOCKET_PATH is used by
* xorgxrdp and the pulseaudio plugin */ * xorgxrdp and the pulseaudio plugin */
g_snprintf(text, sizeof(text), XRDP_SOCKET_PATH, uid); g_snprintf(text, sizeof(text), XRDP_SOCKET_PATH, uid);
g_setenv_log("XRDP_SOCKET_PATH", text, 1); g_setenv_log("XRDP_SOCKET_PATH", text, 1);
/* pulse sink socket */
g_snprintf(text, sizeof(text), CHANSRV_PORT_OUT_BASE_STR, display); // Set the passed-in variables. This may include a DISPLAY
g_setenv_log("XRDP_PULSE_SINK_SOCKET", text, 1);
/* pulse source socket */
g_snprintf(text, sizeof(text), CHANSRV_PORT_IN_BASE_STR, display);
g_setenv_log("XRDP_PULSE_SOURCE_SOCKET", text, 1);
if (g_cfg->sec.xauth_in_sysdir)
{
g_snprintf(text, sizeof(text), XRDP_SOCKET_PATH "/Xauthority",
uid);
g_setenv_log("XAUTHORITY", text, 1);
}
if ((env_names != 0) && (env_values != 0) && if ((env_names != 0) && (env_values != 0) &&
(env_names->count == env_values->count)) (env_names->count == env_values->count))
{ {
@@ -191,80 +108,42 @@ env_set_user(int uid, char **passwd_file, int display,
name = (char *) list_get_item(env_names, index), name = (char *) list_get_item(env_names, index),
value = (char *) list_get_item(env_values, index), value = (char *) list_get_item(env_values, index),
g_setenv_log(name, value, 1); g_setenv_log(name, value, 1);
// Look for a DISPLAY. WAYLAND_DISPLAY overrides
// DISPLAY
if (strcmp(name, "WAYLAND_DISPLAY") == 0)
{
display = value;
is_x11 = 0;
}
else if (display == NULL && strcmp(name, "DISPLAY") == 0)
{
display = value;
is_x11 = 1;
}
} }
} }
g_gethostname(hostname, 255);
hostname[255] = 0; // Set things dependent on the DISPLAY
if (passwd_file != 0) if (display != NULL)
{ {
if (0 == g_cfg->auth_file_path) /* pulse sink socket */
g_snprintf(text, sizeof(text), CHANSRV_PORT_OUT_BASE_STR,
display);
g_setenv_log("XRDP_PULSE_SINK_SOCKET", text, 1);
/* pulse source socket */
g_snprintf(text, sizeof(text), CHANSRV_PORT_IN_BASE_STR,
display);
g_setenv_log("XRDP_PULSE_SOURCE_SOCKET", text, 1);
// Only set Xauthority for X11
if (is_x11 && g_cfg->sec.xauth_in_sysdir)
{ {
/* if no auth_file_path is set, then we go for g_snprintf(text, sizeof(text),
$HOME/.vnc/sesman_passwd-USERNAME@HOSTNAME:DISPLAY */ XRDP_SOCKET_PATH "/Xauthority", uid);
if (!g_directory_exist(".vnc")) g_setenv_log("XAUTHORITY", text, 1);
{
if (g_mkdir(".vnc") < 0)
{
LOG(LOG_LEVEL_ERROR,
"Error creating .vnc directory: %s",
g_get_strerror());
}
}
len = g_snprintf(NULL, 0, "%s/.vnc/sesman_passwd-%s@%s:%d",
pw_dir, pw_username, hostname, display);
++len; // Allow for terminator
*passwd_file = (char *) g_malloc(len, 1);
if (*passwd_file != NULL)
{
/* Try legacy names first, remove if found */
g_snprintf(*passwd_file, len,
"%s/.vnc/sesman_%s_passwd:%d",
pw_dir, pw_username, display);
if (g_file_exist(*passwd_file))
{
LOG(LOG_LEVEL_WARNING, "Removing old "
"password file %s", *passwd_file);
g_file_delete(*passwd_file);
}
g_snprintf(*passwd_file, len,
"%s/.vnc/sesman_%s_passwd",
pw_dir, pw_username);
if (g_file_exist(*passwd_file))
{
LOG(LOG_LEVEL_WARNING, "Removing insecure "
"password file %s", *passwd_file);
g_file_delete(*passwd_file);
}
g_snprintf(*passwd_file, len,
"%s/.vnc/sesman_passwd-%s@%s:%d",
pw_dir, pw_username, hostname, display);
}
}
else
{
/* we use auth_file_path as requested */
len = g_snprintf(NULL, 0, g_cfg->auth_file_path, pw_username);
++len; // Allow for terminator
*passwd_file = (char *) g_malloc(len, 1);
if (*passwd_file != NULL)
{
g_snprintf(*passwd_file, len,
g_cfg->auth_file_path, pw_username);
}
}
if (*passwd_file != NULL)
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "pass file: %s", *passwd_file);
} }
} }
g_free(pw_username);
g_free(pw_dir);
g_free(pw_shell);
} }
} }
else else
@@ -273,5 +152,9 @@ env_set_user(int uid, char **passwd_file, int display,
"error getting user info for uid %d", uid); "error getting user info for uid %d", uid);
} }
g_free(pw_username);
g_free(pw_dir);
g_free(pw_shell);
return error; return error;
} }
+3 -3
View File
@@ -44,13 +44,13 @@ env_check_password_file(const char *filename, const char *password);
* *
* @brief Sets user environment ($PATH, $HOME, $UID, and others) * @brief Sets user environment ($PATH, $HOME, $UID, and others)
* @param uid user ID * @param uid user ID
* @param passwd_file VNC password file * @param env_names List of session environment variables to set
* @param display The session display * @param env_values List of session environment values to set
* @return 0 on success, g_getuser_info() error codes on error * @return 0 on success, g_getuser_info() error codes on error
* *
*/ */
int int
env_set_user(int uid, char **passwd_file, int display, env_set_user(int uid,
const struct list *env_names, const struct list *env_values); const struct list *env_names, const struct list *env_values);
#endif #endif
+3 -3
View File
@@ -92,7 +92,7 @@ discover_trans_conn_in(struct trans *trans, struct trans *new_trans)
{ {
(void)ercp_send_session_announce_event( (void)ercp_send_session_announce_event(
new_trans, new_trans,
sp->display, session_get_display(g_session_data),
g_login_info->uid, g_login_info->uid,
sp->type, sp->type,
sp->width, sp->width,
@@ -143,9 +143,9 @@ sesexec_discover_enable(void)
{ {
char discover_port[XRDP_SOCKETS_MAXPATH]; char discover_port[XRDP_SOCKETS_MAXPATH];
snprintf(discover_port, sizeof(discover_port), "%s.r/%u", snprintf(discover_port, sizeof(discover_port), "%s.r/%s",
g_cfg->listen_port, g_cfg->listen_port,
session_get_parameters(g_session_data)->display); session_get_display(g_session_data));
g_discover_trans->is_term = sesexec_is_term; g_discover_trans->is_term = sesexec_is_term;
g_discover_trans->trans_conn_in = discover_trans_conn_in; g_discover_trans->trans_conn_in = discover_trans_conn_in;
if ((rv = trans_listen(g_discover_trans, discover_port)) != 0) if ((rv = trans_listen(g_discover_trans, discover_port)) != 0)
+341 -148
View File
@@ -49,6 +49,7 @@
#include "os_calls.h" #include "os_calls.h"
#include "sesexec.h" #include "sesexec.h"
#include "sessionrecord.h" #include "sessionrecord.h"
#include "ssl_calls.h"
#include "string_calls.h" #include "string_calls.h"
#include "trans.h" #include "trans.h"
#include "xauth.h" #include "xauth.h"
@@ -62,6 +63,7 @@ struct session_data
pid_t chansrv; ///< PID of chansrv pid_t chansrv; ///< PID of chansrv
time_t start_time; time_t start_time;
unsigned int connect_count; unsigned int connect_count;
char display[MAX_DISPLAY_NAME_SIZE]; // Set by session_start()
struct session_parameters params; struct session_parameters params;
// Flexible array member used to store strings in params and ip_addr; // Flexible array member used to store strings in params and ip_addr;
#ifdef __cplusplus #ifdef __cplusplus
@@ -189,7 +191,7 @@ dumpItemsToString(struct list *self, char *outstr, int len)
/******************************************************************************/ /******************************************************************************/
static void static void
start_chansrv(const struct login_info *login_info, start_chansrv(const struct login_info *login_info,
const struct session_parameters *s, const struct session_data *sd,
void *closure /* unused */) void *closure /* unused */)
{ {
struct list *chansrv_params = list_create(); struct list *chansrv_params = list_create();
@@ -211,7 +213,7 @@ start_chansrv(const struct login_info *login_info,
} }
else else
{ {
env_set_user(login_info->uid, 0, s->display, env_set_user(login_info->uid,
g_cfg->env_names, g_cfg->env_names,
g_cfg->env_values); g_cfg->env_values);
@@ -228,36 +230,35 @@ start_chansrv(const struct login_info *login_info,
/******************************************************************************/ /******************************************************************************/
static void static void
start_window_manager(const struct login_info *login_info, start_window_manager(const struct login_info *login_info,
const struct session_parameters *s, const struct session_data *sd,
void *closure /* unused */) void *closure /* unused */)
{ {
char text[256]; char text[256];
const struct session_parameters *sp = &sd->params;
env_set_user(login_info->uid, env_set_user(login_info->uid,
0,
s->display,
g_cfg->env_names, g_cfg->env_names,
g_cfg->env_values); g_cfg->env_values);
auth_set_env(login_info->auth_info); auth_set_env(login_info->auth_info);
LOG_DEVEL_LEAKING_FDS("window manager", 3, -1); LOG_DEVEL_LEAKING_FDS("window manager", 3, -1);
if (s->directory[0] != '\0') if (sp->directory[0] != '\0')
{ {
if (g_cfg->sec.allow_alternate_shell) if (g_cfg->sec.allow_alternate_shell)
{ {
g_set_current_dir(s->directory); g_set_current_dir(sp->directory);
} }
else else
{ {
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"Directory change to %s requested, but not " "Directory change to %s requested, but not "
"allowed by AllowAlternateShell config value.", "allowed by AllowAlternateShell config value.",
s->directory); sp->directory);
} }
} }
if (s->shell[0] != '\0') if (sp->shell[0] != '\0')
{ {
if (g_cfg->sec.allow_alternate_shell) if (g_cfg->sec.allow_alternate_shell)
{ {
@@ -269,27 +270,28 @@ start_window_manager(const struct login_info *login_info,
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Setting variable '%s' to the specified shell of '%s'", "Setting variable '%s' to the specified shell of '%s'",
g_cfg->sec.pass_shell_as_env, g_cfg->sec.pass_shell_as_env,
s->shell); sp->shell);
g_setenv_log(g_cfg->sec.pass_shell_as_env, s->shell, 1); g_setenv_log(g_cfg->sec.pass_shell_as_env, sp->shell, 1);
} }
else else
{ {
// Try to execute the shell directly (if permitted) // Try to execute the shell directly (if permitted)
if (g_strchr(s->shell, ' ') != 0 || g_strchr(s->shell, '\t') != 0) if (g_strchr(sp->shell, ' ') != 0 ||
g_strchr(sp->shell, '\t') != 0)
{ {
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Using user requested window manager on " "Using user requested window manager on "
"display %u with embedded arguments using a shell: %s", "display %s with embedded arguments using a shell: %s",
s->display, s->shell); sd->display, sp->shell);
const char *argv[] = {"sh", "-c", s->shell, NULL}; const char *argv[] = {"sh", "-c", sp->shell, NULL};
g_execvp("/bin/sh", (char **)argv); g_execvp("/bin/sh", (char **)argv);
} }
else else
{ {
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Using user requested window manager on " "Using user requested window manager on "
"display %d: %s", s->display, s->shell); "display %s %s", sd->display, sp->shell);
g_execlp3(s->shell, s->shell, 0); g_execlp3(sp->shell, sp->shell, 0);
} }
} }
} }
@@ -298,13 +300,13 @@ start_window_manager(const struct login_info *login_info,
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"Shell %s requested by user, but not allowed by " "Shell %s requested by user, but not allowed by "
"AllowAlternateShell config value.", "AllowAlternateShell config value.",
s->shell); sp->shell);
} }
} }
else else
{ {
LOG(LOG_LEVEL_DEBUG, "The user session on display %u did " LOG(LOG_LEVEL_DEBUG, "The user session on display %s did "
"not request a specific window manager", s->display); "not request a specific window manager", sd->display);
} }
/* try to execute user window manager if enabled */ /* try to execute user window manager if enabled */
@@ -315,8 +317,8 @@ start_window_manager(const struct login_info *login_info,
if (g_file_exist(text)) if (g_file_exist(text))
{ {
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Using window manager on display %u" "Using window manager on display %s"
" from user home directory: %s", s->display, text); " from user home directory: %s", sd->display, text);
g_execlp3(text, g_cfg->user_wm, 0); g_execlp3(text, g_cfg->user_wm, 0);
} }
else else
@@ -329,26 +331,26 @@ start_window_manager(const struct login_info *login_info,
} }
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Using the default window manager on display %u: %s", "Using the default window manager on display %s: %s",
s->display, g_cfg->default_wm); sd->display, g_cfg->default_wm);
g_execlp3(g_cfg->default_wm, g_cfg->default_wm, 0); g_execlp3(g_cfg->default_wm, g_cfg->default_wm, 0);
/* still a problem starting window manager just start xterm */ /* still a problem starting window manager just start xterm */
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"No window manager on display %u started, " "No window manager on display %s started, "
"so falling back to starting xterm for user debugging", "so falling back to starting xterm for user debugging",
s->display); sd->display);
g_execlp3("xterm", "xterm", 0); g_execlp3("xterm", "xterm", 0);
/* should not get here */ /* should not get here */
LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting to start " LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting to start "
"the window manager on display %u, aborting connection", "the window manager on display %s, aborting connection",
s->display); sd->display);
} }
/******************************************************************************/ /******************************************************************************/
static struct list * static struct list *
prepare_xorg_xserver_params(const struct session_parameters *s, prepare_xorg_xserver_params(const struct session_data *sd,
const char *authfile) const char *authfile)
{ {
@@ -369,18 +371,18 @@ prepare_xorg_xserver_params(const struct session_parameters *s,
if (g_cfg->sec.xorg_no_new_privileges && g_no_new_privs() != 0) if (g_cfg->sec.xorg_no_new_privileges && g_no_new_privs() != 0)
{ {
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"[session start] (display %u): Failed to disable " "[session start] (display :%d): Failed to disable "
"setuid on X server: %s", "setuid on X server: %s",
s->display, g_get_strerror()); sd->params.x11_display, g_get_strerror());
} }
g_snprintf(screen, sizeof(screen), ":%u", s->display); g_snprintf(screen, sizeof(screen), ":%d", sd->params.x11_display);
/* some args are passed via env vars */ /* some args are passed via env vars */
g_snprintf(text, sizeof(text), "%d", s->width); g_snprintf(text, sizeof(text), "%d", sd->params.width);
g_setenv_log("XRDP_START_WIDTH", text, 1); g_setenv_log("XRDP_START_WIDTH", text, 1);
g_snprintf(text, sizeof(text), "%d", s->height); g_snprintf(text, sizeof(text), "%d", sd->params.height);
g_setenv_log("XRDP_START_HEIGHT", text, 1); g_setenv_log("XRDP_START_HEIGHT", text, 1);
g_snprintf(text, sizeof(text), "%d", g_cfg->sess.max_idle_time); g_snprintf(text, sizeof(text), "%d", g_cfg->sess.max_idle_time);
@@ -408,10 +410,180 @@ prepare_xorg_xserver_params(const struct session_parameters *s,
return params; return params;
} }
/******************************************************************************/
/**
* Create an Xvnc password file
*
* @param x11_display X11 display number
* @return Name of passwd file, or NULL if no memory.
*
* env_set_user() must be called before calling this function
*/
static char *
get_xvnc_passwd_file_name(int x11_display)
{
char *result = NULL;
int len;
char *pw_username = NULL;
char *pw_dir = NULL;
char hostname[256];
int error;
/* Get parameters needed for VNC filename */
hostname[sizeof(hostname) - 1] = '\0';
g_gethostname(hostname, sizeof(hostname));
error = g_getuser_info_by_uid(g_getuid(), &pw_username, 0, 0, &pw_dir, 0);
if (error != 0 || pw_username == NULL || pw_dir == NULL)
{
LOG(LOG_LEVEL_ERROR, "Can't get parameters for XVnc passwd file");
}
else
{
if (0 == g_cfg->auth_file_path)
{
/* if no auth_file_path is set, then we go for
$HOME/.vnc/sesman_passwd-USERNAME@HOSTNAME:DISPLAY */
if (!g_directory_exist(".vnc"))
{
if (g_mkdir(".vnc") < 0)
{
LOG(LOG_LEVEL_ERROR,
"Error creating .vnc directory: %s",
g_get_strerror());
}
}
len = g_snprintf(NULL, 0, "%s/.vnc/sesman_passwd-%s@%s:%d",
pw_dir, pw_username, hostname, x11_display);
++len; // Allow for terminator
result = (char *) g_malloc(len, 1);
if (result != NULL)
{
/* Try legacy names first, remove if found */
g_snprintf(result, len,
"%s/.vnc/sesman_%s_passwd:%d",
pw_dir, pw_username, x11_display);
if (g_file_exist(result))
{
LOG(LOG_LEVEL_WARNING, "Removing old "
"password file %s", result);
g_file_delete(result);
}
g_snprintf(result, len,
"%s/.vnc/sesman_%s_passwd",
pw_dir, pw_username);
if (g_file_exist(result))
{
LOG(LOG_LEVEL_WARNING, "Removing insecure "
"password file %s", result);
g_file_delete(result);
}
g_snprintf(result, len,
"%s/.vnc/sesman_passwd-%s@%s:%d",
pw_dir, pw_username, hostname, x11_display);
}
}
else
{
/* we use auth_file_path as requested */
len = g_snprintf(NULL, 0, g_cfg->auth_file_path, pw_username);
++len; // Allow for terminator
result = (char *) g_malloc(len, 1);
if (result != NULL)
{
g_snprintf(result, len,
g_cfg->auth_file_path, pw_username);
}
}
if (result == NULL)
{
LOG(LOG_LEVEL_ERROR,
"Can't allocate memory for Xvnc passwd file name");
}
else
{
LOG_DEVEL(LOG_LEVEL_DEBUG, "pass file: %s", result);
}
}
g_free(pw_username);
g_free(pw_dir);
return result;
}
/******************************************************************************/
static int
set_xvnc_passwd(const char *filename, const char *passwd)
{
char encryptedPasswd[16];
char key[24];
char passwd_hash[20];
char passwd_hash_text[40];
int fd;
int passwd_bytes;
void *des;
void *sha1;
if (filename == NULL)
{
LOG(LOG_LEVEL_WARNING, "Cannot write VNC password hash to NULL file");
return 1;
}
/*
* If we're in FIPS mode, do not write the GUID to disk after it's
* been encrypted with an insecure algorithm.
*/
if (g_fips_mode_enabled())
{
LOG(LOG_LEVEL_ERROR, "Can't create VNC password file in FIPS mode");
return 1;
}
/* create password hash from password */
passwd_bytes = (passwd == NULL) ? 0 : strlen(passwd);
sha1 = ssl_sha1_info_create();
ssl_sha1_clear(sha1);
ssl_sha1_transform(sha1, "xrdp_vnc", 8);
ssl_sha1_transform(sha1, passwd, passwd_bytes);
ssl_sha1_transform(sha1, passwd, passwd_bytes);
ssl_sha1_complete(sha1, passwd_hash);
ssl_sha1_info_delete(sha1);
g_snprintf(passwd_hash_text, sizeof(passwd_hash_text),
"%2.2x%2.2x%2.2x%2.2x",
(tui8)passwd_hash[0], (tui8)passwd_hash[1],
(tui8)passwd_hash[2], (tui8)passwd_hash[3]);
passwd = passwd_hash_text;
/* create file from password */
g_memset(encryptedPasswd, 0, sizeof(encryptedPasswd));
g_strncpy(encryptedPasswd, passwd, 8);
g_memset(key, 0, sizeof(key));
g_mirror_memcpy(key, g_fixedkey, 8);
des = ssl_des3_encrypt_info_create(key, 0);
ssl_des3_encrypt(des, 8, encryptedPasswd, encryptedPasswd);
ssl_des3_info_delete(des);
fd = g_file_open_ex(filename, 0, 1, 1, 1);
if (fd == -1)
{
LOG(LOG_LEVEL_WARNING,
"Cannot write VNC password hash to file %s: %s",
filename, g_get_strerror());
return 1;
}
g_file_write(fd, encryptedPasswd, 8);
g_file_close(fd);
return 0;
}
/******************************************************************************/ /******************************************************************************/
/** /**
* Prepare a list of parameters for the Xvnc X server * Prepare a list of parameters for the Xvnc X server
* @param s Session parameters * @param sd Session data
* @param authfile XAUTHORITY file * @param authfile XAUTHORITY file
* @param passwd_file VNC password file, or NULL * @param passwd_file VNC password file, or NULL
* @param port UDS port to connect to, or NULL * @param port UDS port to connect to, or NULL
@@ -420,7 +592,7 @@ prepare_xorg_xserver_params(const struct session_parameters *s,
* One of passwd_file and port must be set * One of passwd_file and port must be set
*/ */
static struct list * static struct list *
prepare_xvnc_xserver_params(const struct session_parameters *s, prepare_xvnc_xserver_params(const struct session_data *sd,
const char *authfile, const char *authfile,
const char *passwd_file, const char *passwd_file,
const char *port) const char *port)
@@ -428,19 +600,17 @@ prepare_xvnc_xserver_params(const struct session_parameters *s,
char screen[32] = {0}; /* display number */ char screen[32] = {0}; /* display number */
char geometry[32] = {0}; char geometry[32] = {0};
char depth[32] = {0}; char depth[32] = {0};
char guid_str[GUID_STR_SIZE];
const char *xserver; const char *xserver;
const struct session_parameters *sp = &sd->params;
struct list *params = list_create(); struct list *params = list_create();
if (params != NULL) if (params != NULL)
{ {
params->auto_free = 1; params->auto_free = 1;
g_snprintf(screen, sizeof(screen), ":%u", s->display); g_snprintf(screen, sizeof(screen), ":%d", sp->x11_display);
g_snprintf(geometry, sizeof(geometry), "%dx%d", s->width, s->height); g_snprintf(geometry, sizeof(geometry), "%dx%d", sp->width, sp->height);
g_snprintf(depth, sizeof(depth), "%d", s->bpp); g_snprintf(depth, sizeof(depth), "%d", sp->bpp);
guid_to_str(&s->guid, guid_str);
/* get path of Xvnc from config */ /* get path of Xvnc from config */
xserver = (const char *)list_get_item(g_cfg->vnc_params, 0); xserver = (const char *)list_get_item(g_cfg->vnc_params, 0);
@@ -456,7 +626,6 @@ prepare_xvnc_xserver_params(const struct session_parameters *s,
if (passwd_file != NULL) if (passwd_file != NULL)
{ {
/* RFB authorization */ /* RFB authorization */
env_check_password_file(passwd_file, guid_str);
list_add_strdup_multi(params, list_add_strdup_multi(params,
"-rfbauth", passwd_file, "-rfbauth", passwd_file,
LIST_ADD_STRDUP_TERM); LIST_ADD_STRDUP_TERM);
@@ -493,7 +662,7 @@ prepare_xvnc_xserver_params(const struct session_parameters *s,
/* Either execs the X server, or returns */ /* Either execs the X server, or returns */
static void static void
start_x_server(const struct login_info *login_info, start_x_server(const struct login_info *login_info,
const struct session_parameters *s, const struct session_data *sd,
void *closure /* unused */) void *closure /* unused */)
{ {
char authfile[256]; /* The filename for storing xauth information */ char authfile[256]; /* The filename for storing xauth information */
@@ -501,22 +670,19 @@ start_x_server(const struct login_info *login_info,
char *passwd_file = NULL; char *passwd_file = NULL;
struct list *xserver_params = NULL; struct list *xserver_params = NULL;
int unknown_session_type = 0; int unknown_session_type = 0;
const struct session_parameters *sp = &sd->params;
if (s->type == SCP_SESSION_TYPE_XVNC) env_set_user(login_info->uid,
g_cfg->env_names,
g_cfg->env_values);
if (sp->type == SCP_SESSION_TYPE_XVNC)
{ {
env_set_user(login_info->uid, char guid_str[GUID_STR_SIZE];
&passwd_file, passwd_file = get_xvnc_passwd_file_name(sp->x11_display);
s->display,
g_cfg->env_names, guid_to_str(&sp->guid, guid_str);
g_cfg->env_values); set_xvnc_passwd(passwd_file, guid_str);
}
else
{
env_set_user(login_info->uid,
0,
s->display,
g_cfg->env_names,
g_cfg->env_values);
} }
/* prepare the Xauthority stuff */ /* prepare the Xauthority stuff */
@@ -531,31 +697,32 @@ start_x_server(const struct login_info *login_info,
} }
/* Add the entry in XAUTHORITY file or exit if error */ /* Add the entry in XAUTHORITY file or exit if error */
if (add_xauth_cookie(s->display, authfile) != 0) if (sp->x11_display >= 0 &&
add_xauth_cookie(sp->x11_display, authfile) != 0)
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Error setting the xauth cookie for display %u in file %s", "Error setting the xauth cookie for display %s in file %s",
s->display, authfile); sd->display, authfile);
} }
else else
{ {
switch (s->type) switch (sp->type)
{ {
char port[256]; char port[256];
case SCP_SESSION_TYPE_XORG: case SCP_SESSION_TYPE_XORG:
xserver_params = prepare_xorg_xserver_params(s, authfile); xserver_params = prepare_xorg_xserver_params(sd, authfile);
break; break;
case SCP_SESSION_TYPE_XVNC: case SCP_SESSION_TYPE_XVNC:
xserver_params = prepare_xvnc_xserver_params(s, authfile, xserver_params = prepare_xvnc_xserver_params(sd, authfile,
passwd_file, NULL); passwd_file, NULL);
break; break;
case SCP_SESSION_TYPE_XVNC_UDS: case SCP_SESSION_TYPE_XVNC_UDS:
g_snprintf(port, sizeof(port), XRDP_X11RDP_STR, g_snprintf(port, sizeof(port), XRDP_X11RDP_STR,
login_info->uid, s->display); login_info->uid, sd->display);
xserver_params = prepare_xvnc_xserver_params(s, authfile, xserver_params = prepare_xvnc_xserver_params(sd, authfile,
NULL, port); NULL, port);
break; break;
@@ -570,13 +737,13 @@ start_x_server(const struct login_info *login_info,
else if (unknown_session_type) else if (unknown_session_type)
{ {
LOG(LOG_LEVEL_ERROR, "Unknown session type: %d", LOG(LOG_LEVEL_ERROR, "Unknown session type: %d",
s->type); sp->type);
} }
else else
{ {
/* fire up X server */ /* fire up X server */
LOG(LOG_LEVEL_INFO, "Starting X server on display %u: %s", LOG(LOG_LEVEL_INFO, "Starting X server on display %s: %s",
s->display, sd->display,
dumpItemsToString(xserver_params, execvpparams, 2048)); dumpItemsToString(xserver_params, execvpparams, 2048));
LOG_DEVEL_LEAKING_FDS("X server", 3, -1); LOG_DEVEL_LEAKING_FDS("X server", 3, -1);
g_execvp_list((const char *)xserver_params->items[0], g_execvp_list((const char *)xserver_params->items[0],
@@ -588,8 +755,8 @@ start_x_server(const struct login_info *login_info,
g_free(passwd_file); g_free(passwd_file);
list_delete(xserver_params); list_delete(xserver_params);
LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting " LOG(LOG_LEVEL_ERROR, "A fatal error has occurred attempting "
"to start the X server on display %u, aborting connection", "to start the X server on display %s, aborting connection",
s->display); sd->display);
} }
/******************************************************************************/ /******************************************************************************/
@@ -598,10 +765,10 @@ start_x_server(const struct login_info *login_info,
static int static int
fork_child( fork_child(
void (*runproc)(const struct login_info *, void (*runproc)(const struct login_info *,
const struct session_parameters *, const struct session_data *,
void *closure), void *closure),
const struct login_info *login_info, const struct login_info *login_info,
const struct session_parameters *s, const struct session_data *sd,
pid_t group_pid, pid_t group_pid,
void *closure) void *closure)
{ {
@@ -613,7 +780,7 @@ fork_child(
{ {
(void)g_setpgid(0, group_pid); (void)g_setpgid(0, group_pid);
} }
runproc(login_info, s, closure); runproc(login_info, sd, closure);
g_exit(0); g_exit(0);
} }
@@ -694,7 +861,6 @@ session_start_wrapped(struct login_info *login_info,
int display_pid; int display_pid;
int window_manager_pid; int window_manager_pid;
enum scp_screate_status status = E_SCP_SCREATE_GENERAL_ERROR; enum scp_screate_status status = E_SCP_SCREATE_GENERAL_ERROR;
char displaystr[32];
/* Set the secondary groups before starting the session to prevent /* Set the secondary groups before starting the session to prevent
* problems on PAM-based systems (see Linux pam_setcred(3)). * problems on PAM-based systems (see Linux pam_setcred(3)).
@@ -709,8 +875,7 @@ session_start_wrapped(struct login_info *login_info,
} }
#endif #endif
snprintf(displaystr, sizeof(displaystr), "%d", s->display); if (auth_start_session(login_info->auth_info, sd->display) != 0)
if (auth_start_session(login_info->auth_info, displaystr) != 0)
{ {
// Errors are logged by the auth module, as they are // Errors are logged by the auth module, as they are
// specific to that module // specific to that module
@@ -724,15 +889,15 @@ session_start_wrapped(struct login_info *login_info,
if (g_setsid() < 0) if (g_setsid() < 0)
{ {
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"[session start] (display %d): setsid failed - pid %d", "[session start] (display %s): setsid failed - pid %d",
s->display, g_getpid()); sd->display, g_getpid());
} }
if (g_setlogin(login_info->username) < 0) if (g_setlogin(login_info->username) < 0)
{ {
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"[session start] (display %d): setlogin failed for user %s - pid %d", "[session start] (display %s): setlogin failed for user %s - pid %d",
s->display, login_info->username, g_getpid()); sd->display, login_info->username, g_getpid());
} }
#endif #endif
@@ -743,14 +908,14 @@ session_start_wrapped(struct login_info *login_info,
* without affecting sesexec (and vice-versa). This is particularly * without affecting sesexec (and vice-versa). This is particularly
* important when debugging sesexec as we don't want a SIGINT in * important when debugging sesexec as we don't want a SIGINT in
* the debugger to be passed to the children */ * the debugger to be passed to the children */
display_pid = fork_child(start_x_server, login_info, s, 0, NULL); display_pid = fork_child(start_x_server, login_info, sd, 0, NULL);
if (display_pid > 0) if (display_pid > 0)
{ {
enum xwait_status xws; enum xwait_status xws;
xws = wait_for_xserver(login_info->uid, xws = wait_for_xserver(login_info->uid,
g_cfg->env_names, g_cfg->env_names,
g_cfg->env_values, g_cfg->env_values,
s->display); s->x11_display);
if (xws != XW_STATUS_OK) if (xws != XW_STATUS_OK)
{ {
@@ -774,12 +939,12 @@ session_start_wrapped(struct login_info *login_info,
} }
else else
{ {
LOG(LOG_LEVEL_INFO, "X server :%d is working", s->display); LOG(LOG_LEVEL_INFO, "Display %s is working", sd->display);
LOG(LOG_LEVEL_INFO, "Starting window manager for display :%d", LOG(LOG_LEVEL_INFO, "Starting window manager for display %s",
s->display); sd->display);
window_manager_pid = fork_child(start_window_manager, window_manager_pid = fork_child(start_window_manager,
login_info, s, display_pid, NULL); login_info, sd, display_pid, NULL);
if (window_manager_pid < 0) if (window_manager_pid < 0)
{ {
g_sigterm(display_pid); g_sigterm(display_pid);
@@ -787,15 +952,13 @@ session_start_wrapped(struct login_info *login_info,
} }
else else
{ {
char dstr[32]; utmp_login(window_manager_pid, sd->display, login_info);
g_snprintf(dstr, sizeof(dstr), "%u", s->display);
utmp_login(window_manager_pid, dstr, login_info);
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Starting the xrdp channel server for display :%d", "Starting the xrdp channel server for display %s",
s->display); sd->display);
chansrv_pid = fork_child(start_chansrv, login_info, chansrv_pid = fork_child(start_chansrv, login_info,
s, display_pid, NULL); sd, display_pid, NULL);
sd->win_mgr = window_manager_pid; sd->win_mgr = window_manager_pid;
sd->x_server = display_pid; sd->x_server = display_pid;
@@ -806,9 +969,9 @@ session_start_wrapped(struct login_info *login_info,
{ {
// Tell the caller we've started // Tell the caller we've started
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Session in progress on display :%d. Waiting until the " "Session in progress on display %s. Waiting until the "
"window manager (pid %d) exits to end the session", "window manager (pid %d) exits to end the session",
s->display, window_manager_pid); sd->display, window_manager_pid);
status = E_SCP_SCREATE_OK; status = E_SCP_SCREATE_OK;
} }
@@ -832,7 +995,8 @@ session_start(struct login_info *login_info,
const struct session_parameters *sp, const struct session_parameters *sp,
struct session_data **session_data) struct session_data **session_data)
{ {
enum scp_screate_status status = E_SCP_SCREATE_GENERAL_ERROR; enum scp_screate_status status = E_SCP_SCREATE_OK;
/* Create the session_data struct first */ /* Create the session_data struct first */
struct session_data *sd = session_data_new(sp); struct session_data *sd = session_data_new(sp);
if (sd == NULL) if (sd == NULL)
@@ -841,15 +1005,38 @@ session_start(struct login_info *login_info,
} }
else else
{ {
status = session_start_wrapped(login_info, sp, sd); if (sp->x11_display >= 0)
{
/* Initialise the display name for logging purposes */
g_get_display_string_from_x11_display(sp->x11_display,
sd->display,
MAX_DISPLAY_NAME_SIZE);
/* Add the DISPLAY to the list of environment variables we
* set for all the sub-processes */
char displayname[32];
snprintf(displayname, sizeof(displayname), ":%d",
sp->x11_display);
if (!list_add_strdup(g_cfg->env_names, "DISPLAY") ||
!list_add_strdup(g_cfg->env_values, displayname))
{
session_data_free(sd);
status = E_SCP_SCREATE_NO_MEMORY;
}
}
if (status == E_SCP_SCREATE_OK) if (status == E_SCP_SCREATE_OK)
{ {
*session_data = sd; status = session_start_wrapped(login_info, sp, sd);
} if (status == E_SCP_SCREATE_OK)
else {
{ *session_data = sd;
*session_data = NULL; }
session_data_free(sd); else
{
*session_data = NULL;
session_data_free(sd);
}
} }
} }
@@ -858,14 +1045,16 @@ session_start(struct login_info *login_info,
/******************************************************************************/ /******************************************************************************/
static int static int
cleanup_sockets(int uid, int display) cleanup_sockets(struct session_data *sd)
{ {
LOG_DEVEL(LOG_LEVEL_INFO, "cleanup_sockets:"); LOG_DEVEL(LOG_LEVEL_INFO, "cleanup_sockets:");
char file[XRDP_SOCKETS_MAXPATH]; char file[XRDP_SOCKETS_MAXPATH];
int error = 0; int error = 0;
g_snprintf(file, sizeof(file), CHANSRV_PORT_OUT_STR, uid, display); int uid = g_login_info->uid;
g_snprintf(file, sizeof(file), CHANSRV_PORT_OUT_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -878,7 +1067,7 @@ cleanup_sockets(int uid, int display)
} }
} }
g_snprintf(file, sizeof(file), CHANSRV_PORT_IN_STR, uid, display); g_snprintf(file, sizeof(file), CHANSRV_PORT_IN_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -891,7 +1080,7 @@ cleanup_sockets(int uid, int display)
} }
} }
g_snprintf(file, sizeof(file), XRDP_CHANSRV_STR, uid, display); g_snprintf(file, sizeof(file), XRDP_CHANSRV_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -904,7 +1093,7 @@ cleanup_sockets(int uid, int display)
} }
} }
g_snprintf(file, sizeof(file), CHANSRV_API_STR, uid, display); g_snprintf(file, sizeof(file), CHANSRV_API_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -920,7 +1109,7 @@ cleanup_sockets(int uid, int display)
/* the following files should be deleted by xorgxrdp /* the following files should be deleted by xorgxrdp
* but just in case the deletion failed */ * but just in case the deletion failed */
g_snprintf(file, sizeof(file), XRDP_X11RDP_STR, uid, display); g_snprintf(file, sizeof(file), XRDP_X11RDP_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -933,7 +1122,7 @@ cleanup_sockets(int uid, int display)
} }
} }
g_snprintf(file, sizeof(file), XRDP_DISCONNECT_STR, uid, display); g_snprintf(file, sizeof(file), XRDP_DISCONNECT_STR, uid, sd->display);
if (g_file_exist(file)) if (g_file_exist(file))
{ {
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
@@ -997,16 +1186,16 @@ process_child_exit(struct session_data *sd,
{ {
if (pid == sd->x_server) if (pid == sd->x_server)
{ {
LOG(LOG_LEVEL_INFO, "X server pid %d on display :%d finished", LOG(LOG_LEVEL_INFO, "X server pid %d on display %s finished",
sd->x_server, sd->params.display); sd->x_server, sd->display);
sd->x_server = -1; sd->x_server = -1;
// No other action - window manager should be going soon // No other action - window manager should be going soon
} }
else if (pid == sd->chansrv) else if (pid == sd->chansrv)
{ {
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"xrdp channel server pid %d on display :%d finished", "xrdp channel server pid %d on display %s finished",
sd->chansrv, sd->params.display); sd->chansrv, sd->display);
sd->chansrv = -1; sd->chansrv = -1;
} }
else if (pid == sd->win_mgr) else if (pid == sd->win_mgr)
@@ -1016,53 +1205,50 @@ process_child_exit(struct session_data *sd,
if (e->reason == E_PXR_STATUS_CODE && e->val == 0) if (e->reason == E_PXR_STATUS_CODE && e->val == 0)
{ {
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Window manager (pid %d, display %d) " "Window manager (pid %d, display %s) "
"finished normally in %d secs", "finished normally in %d secs",
sd->win_mgr, sd->params.display, wm_wait_time); sd->win_mgr, sd->display, wm_wait_time);
} }
else else
{ {
char reason[128]; char reason[128];
exit_status_to_str(e, reason, sizeof(reason)); exit_status_to_str(e, reason, sizeof(reason));
LOG(LOG_LEVEL_WARNING, "Window manager (pid %d, display %d) " LOG(LOG_LEVEL_WARNING, "Window manager (pid %d, display %s) "
"exited with %s. This " "exited with %s. This "
"could indicate a window manager config problem", "could indicate a window manager config problem",
sd->win_mgr, sd->params.display, reason); sd->win_mgr, sd->display, reason);
} }
if (wm_wait_time < 10) if (wm_wait_time < 10)
{ {
/* This could be a config issue. Log a significant error */ /* This could be a config issue. Log a significant error */
LOG(LOG_LEVEL_WARNING, "Window manager (pid %d, display %d) " LOG(LOG_LEVEL_WARNING, "Window manager (pid %d, display %s) "
"exited quickly (%d secs). This could indicate a window " "exited quickly (%d secs). This could indicate a window "
"manager config problem", "manager config problem",
sd->win_mgr, sd->params.display, wm_wait_time); sd->win_mgr, sd->display, wm_wait_time);
}
{
char dstr[32];
g_snprintf(dstr, sizeof(dstr), "%u", sd->params.display);
utmp_logout(sd->win_mgr, dstr, e);
} }
utmp_logout(sd->win_mgr, sd->display, e);
sd->win_mgr = -1; sd->win_mgr = -1;
if (sd->x_server > 0) if (sd->x_server > 0)
{ {
LOG(LOG_LEVEL_INFO, "Terminating X server (pid %d) on display :%d", LOG(LOG_LEVEL_INFO, "Terminating X server (pid %d) on display %s",
sd->x_server, sd->params.display); sd->x_server, sd->display);
g_sigterm(sd->x_server); g_sigterm(sd->x_server);
} }
if (sd->chansrv > 0) if (sd->chansrv > 0)
{ {
LOG(LOG_LEVEL_INFO, "Terminating the xrdp channel server (pid %d) " LOG(LOG_LEVEL_INFO, "Terminating the xrdp channel server (pid %d) "
"on display :%d", sd->chansrv, sd->params.display); "on display %s", sd->chansrv, sd->display);
g_sigterm(sd->chansrv); g_sigterm(sd->chansrv);
} }
} }
if (!session_active(sd)) if (!session_active(sd))
{ {
cleanup_sockets(g_login_info->uid, sd->params.display); cleanup_sockets(sd);
} }
} }
@@ -1104,6 +1290,13 @@ session_get_connect_count(const struct session_data *sd)
return (sd == NULL) ? 0 : sd->connect_count; return (sd == NULL) ? 0 : sd->connect_count;
} }
/******************************************************************************/
const char *
session_get_display(const struct session_data *sd)
{
return (sd == NULL) ? "" : sd->display;
}
/******************************************************************************/ /******************************************************************************/
unsigned int unsigned int
session_increment_connect_count(struct session_data *sd) session_increment_connect_count(struct session_data *sd)
@@ -1157,10 +1350,10 @@ session_send_term(struct session_data *sd, int wait_for_all)
/******************************************************************************/ /******************************************************************************/
static void static void
start_reconnect_script(const struct login_info *login_info, start_reconnect_script(const struct login_info *login_info,
const struct session_parameters *s, const struct session_data *sd,
void *closure) void *closure)
{ {
env_set_user(login_info->uid, 0, s->display, env_set_user(login_info->uid,
g_cfg->env_names, g_cfg->env_names,
g_cfg->env_values); g_cfg->env_values);
@@ -1182,14 +1375,14 @@ start_reconnect_script(const struct login_info *login_info,
LOG_DEVEL_LEAKING_FDS("reconnect script", 3, -1); LOG_DEVEL_LEAKING_FDS("reconnect script", 3, -1);
LOG(LOG_LEVEL_INFO, LOG(LOG_LEVEL_INFO,
"Starting session reconnection script on display %d: %s", "Starting session reconnection script on display %s: %s",
s->display, g_cfg->reconnect_sh); sd->display, g_cfg->reconnect_sh);
g_execlp3(g_cfg->reconnect_sh, g_cfg->reconnect_sh, 0); g_execlp3(g_cfg->reconnect_sh, g_cfg->reconnect_sh, 0);
/* should not get here */ /* should not get here */
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Error starting session reconnection script on display %d: %s", "Error starting session reconnection script on display %s: %s",
s->display, g_cfg->reconnect_sh); sd->display, g_cfg->reconnect_sh);
} }
else else
{ {
@@ -1206,7 +1399,7 @@ session_run_reconnect_script(const struct login_info *login_info,
const char *vars[]) const char *vars[])
{ {
if (fork_child(start_reconnect_script, if (fork_child(start_reconnect_script,
login_info, &sd->params, sd->x_server, (void *)vars) < 0) login_info, sd, sd->x_server, (void *)vars) < 0)
{ {
LOG(LOG_LEVEL_ERROR, "Failed to fork for session reconnection script"); LOG(LOG_LEVEL_ERROR, "Failed to fork for session reconnection script");
} }
@@ -1226,8 +1419,8 @@ session_get_display_server_fd(const struct login_info *login_info,
if (sd->x_server <= 0) if (sd->x_server <= 0)
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Request to connect to display server :%u" "Request to connect to display server %s"
" which has exited", sd->params.display); " which has exited", sd->display);
} }
else else
{ {
@@ -1235,15 +1428,15 @@ session_get_display_server_fd(const struct login_info *login_info,
{ {
case SCP_SESSION_TYPE_XVNC: case SCP_SESSION_TYPE_XVNC:
socket_mode = TRANS_MODE_TCP; socket_mode = TRANS_MODE_TCP;
snprintf(portname, sizeof(portname), "%u", snprintf(portname, sizeof(portname), "%d",
5900 + sd->params.display); 5900 + sd->params.x11_display);
break; break;
case SCP_SESSION_TYPE_XVNC_UDS: case SCP_SESSION_TYPE_XVNC_UDS:
case SCP_SESSION_TYPE_XORG: case SCP_SESSION_TYPE_XORG:
socket_mode = TRANS_MODE_UNIX; socket_mode = TRANS_MODE_UNIX;
snprintf(portname, sizeof(portname), XRDP_X11RDP_STR, snprintf(portname, sizeof(portname), XRDP_X11RDP_STR,
login_info->uid, (int)sd->params.display); login_info->uid, sd->display);
break; break;
@@ -1263,8 +1456,8 @@ session_get_display_server_fd(const struct login_info *login_info,
} }
else if (trans_connect(t, localhost, portname, 3000) != 0) else if (trans_connect(t, localhost, portname, 3000) != 0)
{ {
LOG(LOG_LEVEL_ERROR, "Can't connect to display server :%u [%s]", LOG(LOG_LEVEL_ERROR, "Can't connect to display server %s [%s]",
sd->params.display, sd->display,
g_get_strerror()); g_get_strerror());
} }
else else
@@ -1291,13 +1484,13 @@ session_get_chansrv_fd(const struct login_info *login_info,
if (sd->chansrv <= 0) if (sd->chansrv <= 0)
{ {
LOG(LOG_LEVEL_ERROR, LOG(LOG_LEVEL_ERROR,
"Request to connect to chansrv :%u" "Request to connect to chansrv %s"
" which has exited", sd->params.display); " which has exited", sd->display);
} }
else else
{ {
snprintf(portname, sizeof(portname), snprintf(portname, sizeof(portname),
XRDP_CHANSRV_STR, login_info->uid, (int)sd->params.display); XRDP_CHANSRV_STR, login_info->uid, sd->display);
// Use the transport library to get the fd // Use the transport library to get the fd
struct trans *t = trans_create(TRANS_MODE_UNIX, 8192, 8192); struct trans *t = trans_create(TRANS_MODE_UNIX, 8192, 8192);
@@ -1307,8 +1500,8 @@ session_get_chansrv_fd(const struct login_info *login_info,
} }
else if (trans_connect(t, NULL, portname, 10 * 1000) != 0) else if (trans_connect(t, NULL, portname, 10 * 1000) != 0)
{ {
LOG(LOG_LEVEL_ERROR, "Can't connect to chansrv :%u [%s]", LOG(LOG_LEVEL_ERROR, "Can't connect to chansrv %s [%s]",
sd->params.display, sd->display,
g_get_strerror()); g_get_strerror());
} }
else else
+12 -1
View File
@@ -41,7 +41,7 @@ struct proc_exit_status;
*/ */
struct session_parameters struct session_parameters
{ {
unsigned int display; int x11_display; // >= 0 for X11 only
enum scp_session_type type; enum scp_session_type type;
unsigned short width; unsigned short width;
unsigned short height; unsigned short height;
@@ -114,6 +114,17 @@ session_get_start_time(const struct session_data *sd);
unsigned int unsigned int
session_get_connect_count(const struct session_data *sd); session_get_connect_count(const struct session_data *sd);
/**
* Get a pointer to the session display name
*
* @param self session_data object
* @return session name ("X11-n" or "wayland-n")
*
* A session name is set by a successful call to session_start()
*/
const char *
session_get_display(const struct session_data *sd);
/** /**
* Increment the connect count for an active session * Increment the connect count for an active session
* @param sd session_data for this session * @param sd session_data for this session
-2
View File
@@ -117,8 +117,6 @@ wait_for_xserver(uid_t uid,
/* Move to the user context... */ /* Move to the user context... */
env_set_user(uid, env_set_user(uid,
0,
display,
env_names, env_names,
env_values); env_values);
+1 -1
View File
@@ -150,7 +150,7 @@ add_sesexec_fd_to_session_list(const char *filename)
// E_SESSION_STARTING state // E_SESSION_STARTING state
s_item->sesexec_trans = t; s_item->sesexec_trans = t;
s_item->sesexec_pid = sesexec_pid; s_item->sesexec_pid = sesexec_pid;
s_item->display = -1; s_item->display[0] = '\0';
// Tell the caller we've added one // Tell the caller we've added one
status = 1; status = 1;
+12 -6
View File
@@ -160,7 +160,7 @@ session_list_new(void)
/******************************************************************************/ /******************************************************************************/
void void
session_list_get_session_displays(struct set_int *alloc_displays) session_list_get_session_x11_displays(struct set_int *alloc_displays)
{ {
int count = (g_session_list == NULL) ? 0 : g_session_list->count; int count = (g_session_list == NULL) ? 0 : g_session_list->count;
@@ -170,9 +170,13 @@ session_list_get_session_displays(struct set_int *alloc_displays)
struct session_item *si; struct session_item *si;
si = (struct session_item *)list_get_item(g_session_list, i); si = (struct session_item *)list_get_item(g_session_list, i);
if (SESSION_IN_USE(si)) if (SESSION_IN_USE(si) && SCP_SESSION_TYPE_IS_X11(si->type))
{ {
set_int_add(alloc_displays, si->display); int display = g_get_x11_display_from_display_string(si->display);
if (display >= 0)
{
set_int_add(alloc_displays, display);
}
} }
} }
} }
@@ -289,7 +293,7 @@ session_list_get_bydata(uid_t uid,
} }
LOG(LOG_LEVEL_DEBUG, LOG(LOG_LEVEL_DEBUG,
"%s: Got match, display=%d", __func__, si->display); "%s: Got match, display=%s", __func__, si->display);
return si; return si;
} }
@@ -351,7 +355,7 @@ session_list_get_byuid(const uid_t *uid, unsigned int *cnt, unsigned int flags)
if (SESSION_IN_USE(si) && (uid == NULL || *uid == si->uid)) if (SESSION_IN_USE(si) && (uid == NULL || *uid == si->uid))
{ {
sess[index].sid = si->sesexec_pid; sess[index].sid = si->sesexec_pid;
sess[index].display = si->display; sess[index].display = g_strdup(si->display);
sess[index].type = si->type; sess[index].type = si->type;
sess[index].height = si->start_height; sess[index].height = si->start_height;
sess[index].width = si->start_width; sess[index].width = si->start_width;
@@ -365,7 +369,8 @@ session_list_get_byuid(const uid_t *uid, unsigned int *cnt, unsigned int flags)
sess[index].xrdp_instance_name = g_strdup(si->xrdp_instance_name); sess[index].xrdp_instance_name = g_strdup(si->xrdp_instance_name);
/* Check for string allocation failures */ /* Check for string allocation failures */
if (sess[index].start_ip_addr == NULL || if (sess[index].display == NULL ||
sess[index].start_ip_addr == NULL ||
sess[index].client_ip == NULL || sess[index].client_ip == NULL ||
sess[index].client_name == NULL || sess[index].client_name == NULL ||
sess[index].xrdp_instance_name == NULL) sess[index].xrdp_instance_name == NULL)
@@ -410,6 +415,7 @@ free_session_info_list(struct scp_session_info *sesslist, unsigned int cnt)
unsigned int i; unsigned int i;
for (i = 0 ; i < cnt ; ++i) for (i = 0 ; i < cnt ; ++i)
{ {
g_free(sesslist[i].display);
g_free(sesslist[i].start_ip_addr); g_free(sesslist[i].start_ip_addr);
g_free(sesslist[i].client_ip); g_free(sesslist[i].client_ip);
g_free(sesslist[i].client_name); g_free(sesslist[i].client_name);
+4 -4
View File
@@ -58,8 +58,8 @@ struct session_item
struct trans *sesexec_trans; // trans for sesexec process. Always valid. struct trans *sesexec_trans; // trans for sesexec process. Always valid.
pid_t sesexec_pid; // pid for sesexec process. Always valid pid_t sesexec_pid; // pid for sesexec process. Always valid
/** /**
* May be valid if known when the session is starting, otherwise -1 */ * May be valid if known when the session is starting, otherwise "" */
int display; char display[MAX_DISPLAY_NAME_SIZE];
uid_t uid; uid_t uid;
enum scp_session_type type; enum scp_session_type type;
unsigned short start_width; unsigned short start_width;
@@ -125,10 +125,10 @@ session_list_new(void);
/** /**
* @brief Get all session displays * @brief Get all session displays
* *
* Adds displays allocated to sessions to a set * Adds X11 displays allocated to sessions to a set
*/ */
void void
session_list_get_session_displays(struct set_int *alloc_displays); session_list_get_session_x11_displays(struct set_int *alloc_displays);
/** /**
* *
+5 -13
View File
@@ -28,6 +28,7 @@
#include <sys/un.h> #include <sys/un.h>
#include <errno.h> #include <errno.h>
#include "xrdp_constants.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
#include "os_calls.h" #include "os_calls.h"
#include "string_calls.h" #include "string_calls.h"
@@ -35,10 +36,9 @@
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int sck; int sck;
int dis; char disstr[MAX_DISPLAY_NAME_SIZE];
struct sockaddr_un sa; struct sockaddr_un sa;
size_t len; size_t len;
char *display;
if (argc != 1) if (argc != 1)
{ {
@@ -47,23 +47,15 @@ int main(int argc, char **argv)
return 0; return 0;
} }
display = getenv("DISPLAY"); if (g_get_display_string(disstr, sizeof(disstr)) < 0)
if (display == 0)
{ {
printf("display not set\n"); printf("Can't find teh display from the environment\n");
return 1; return 1;
} }
dis = g_get_display_num_from_display(display);
if (dis < 0)
{
printf("Can't parse DISPLAY='%s'\n", display);
return 1;
}
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.sun_family = AF_UNIX; sa.sun_family = AF_UNIX;
sprintf(sa.sun_path, XRDP_DISCONNECT_STR, g_getuid(), dis); g_sprintf(sa.sun_path, XRDP_DISCONNECT_STR, g_getuid(), disstr);
if (access(sa.sun_path, F_OK) != 0) if (access(sa.sun_path, F_OK) != 0)
{ {
+1 -1
View File
@@ -141,7 +141,7 @@ print_session(const struct scp_session_info *s)
uptr = (username == NULL) ? "<unknown>" : username; uptr = (username == NULL) ? "<unknown>" : username;
printf("Session ID: %d\n", s->sid); printf("Session ID: %d\n", s->sid);
printf("\tDisplay: :%u\n", s->display); printf("\tDisplay: %s\n", s->display);
printf("\tUser: %s\n", uptr); printf("\tUser: %s\n", uptr);
printf("\tSession type: %s\n", SCP_SESSION_TYPE_TO_STR(s->type)); printf("\tSession type: %s\n", SCP_SESSION_TYPE_TO_STR(s->type));
printf("\tScreen size: %dx%d, color depth %d\n", printf("\tScreen size: %dx%d, color depth %d\n",
+2 -2
View File
@@ -520,7 +520,7 @@ static int
handle_create_session_response(struct trans *t) handle_create_session_response(struct trans *t)
{ {
enum scp_screate_status status; enum scp_screate_status status;
int display; const char *display;
struct guid guid; struct guid guid;
int rv = scp_sync_wait_specific(t, E_SCP_CREATE_SESSION_RESPONSE); int rv = scp_sync_wait_specific(t, E_SCP_CREATE_SESSION_RESPONSE);
@@ -541,7 +541,7 @@ handle_create_session_response(struct trans *t)
else else
{ {
char guid_str[GUID_STR_SIZE]; char guid_str[GUID_STR_SIZE];
g_printf("ok display=:%d GUID=%s\n", g_printf("ok display=%s GUID=%s\n",
display, display,
guid_to_str(&guid, guid_str)); guid_to_str(&guid, guid_str));
} }
+5 -2
View File
@@ -311,10 +311,13 @@ password=ask
#pampassword=asksame #pampassword=asksame
#delay_ms=2000 #delay_ms=2000
; Use one of these to connect to a chansrv instance created outside of sesman ; Use one of these to connect to a chansrv instance created outside of sesman
; (e.g. as part of an x11vnc console session). Replace 'n' with the ; (e.g. as part of an x11vnc console session). Replace 's' with the
; display number of the session, and (if applicable) 'u' with the numeric ; display string of the session, and (if applicable) 'u' with the numeric
; UID of the session. ; UID of the session.
; ;
; For compatibility, a completely numeric display string is taken to be
; an X11 display number
;
; You will also need to change the value of SessionSockdirGroup in ; You will also need to change the value of SessionSockdirGroup in
; sesman.ini to allow xrdp to reach the chansrv instance ; sesman.ini to allow xrdp to reach the chansrv instance
; ;
+40 -21
View File
@@ -325,7 +325,7 @@ xrdp_mm_create_session(struct xrdp_mm *self)
type = SCP_SESSION_TYPE_XVNC_UDS; type = SCP_SESSION_TYPE_XVNC_UDS;
break; break;
case XORG_SESSION_CODE: case XORG_SESSION_CODE:
type = SCP_SESSION_TYPE_XORG; type = SCP_SESSION_TYPE_XORG;
break; break;
@@ -2770,7 +2770,7 @@ static int
xrdp_mm_process_create_session_response(struct xrdp_mm *self) xrdp_mm_process_create_session_response(struct xrdp_mm *self)
{ {
enum scp_screate_status status; enum scp_screate_status status;
int display; const char *display;
struct guid guid; struct guid guid;
int rv; int rv;
@@ -2792,11 +2792,11 @@ xrdp_mm_process_create_session_response(struct xrdp_mm *self)
if (status == E_SCP_SCREATE_OK) if (status == E_SCP_SCREATE_OK)
{ {
xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
"session is available on display %d for user %s", "session is available on display %s for user %s",
display, username); display, username);
/* Carry on with the connect state machine */ /* Carry on with the connect state machine */
self->display = display; strlcpy(self->display, display, sizeof(self->display));
self->guid = guid; self->guid = guid;
xrdp_mm_connect_sm(self); xrdp_mm_connect_sm(self);
} }
@@ -2937,7 +2937,7 @@ cleanup_states(struct xrdp_mm *self)
//self->sesman_trans = NULL; /* connection to sesman */ //self->sesman_trans = NULL; /* connection to sesman */
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->display = 0; /* 10 for :10.0, 11 for :11.0, etc */ memset(self->display, '\0', sizeof(self->display));
guid_clear(&self->guid); guid_clear(&self->guid);
self->code = 0; /* ???_SESSION_CODE value */ self->code = 0; /* ???_SESSION_CODE value */
close_sesman_file_descriptors(self); close_sesman_file_descriptors(self);
@@ -2966,7 +2966,7 @@ static int
parse_chansrvport(const char *value, char *dest, int dest_size, int uid) parse_chansrvport(const char *value, char *dest, int dest_size, int uid)
{ {
int rv = 0; int rv = 0;
int dnum; char dstr[MAX_DISPLAY_NAME_SIZE];
if (value == NULL) if (value == NULL)
{ {
@@ -2978,22 +2978,34 @@ parse_chansrvport(const char *value, char *dest, int dest_size, int uid)
{ {
const char *p = value + 8; const char *p = value + 8;
const char *end = p; const char *end = p;
int is_numeric = 1;
/* Check next chars are digits */ /* Look for a ',' or ')' or '\0' */
while (isdigit(*end)) while (*end != ',' && *end != ')' && *end != '\0')
{ {
if (!isdigit(*end))
{
is_numeric = 0;
}
++end; ++end;
} }
if (end == p) if (end == p || (unsigned int)(end - p) > (sizeof(dstr) - 1))
{ {
LOG(LOG_LEVEL_WARNING, LOG(LOG_LEVEL_WARNING,
"Ignoring chansrvport string with bad display number '%s'", "Ignoring chansrvport string with bad display string '%s'",
value); value);
return -1; return -1;
} }
dnum = g_atoi(p); memcpy(dstr, p, end - p);
dstr[end - p] = '\0';
if (is_numeric)
{
// X11 compatibility
int dnum = g_atoi(dstr);
(void)g_get_display_string_from_x11_display(
dnum, dstr, sizeof(dstr));
}
if (*end == ',') if (*end == ',')
{ {
@@ -3025,7 +3037,7 @@ parse_chansrvport(const char *value, char *dest, int dest_size, int uid)
return -1; return -1;
} }
g_snprintf(dest, dest_size, XRDP_CHANSRV_STR, uid, dnum); g_snprintf(dest, dest_size, XRDP_CHANSRV_STR, uid, dstr);
} }
else else
{ {
@@ -5464,17 +5476,24 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event)) if (!g_is_wait_obj_set(self->wm->pro_layer->self_term_event))
{ {
if (self->display < 0) if (self->code == XVNC_SESSION_CODE)
{
LOG(LOG_LEVEL_ERROR,
"Unexpected display value %d setting up module", self->display);
xrdp_mm_set_fatal(self, ERRINFO_SERVER_DWM_CRASH);
}
else if (self->code == XVNC_SESSION_CODE)
{ {
if (self->use_sesman) if (self->use_sesman)
{ {
g_snprintf(text, sizeof(text), "%d", 5900 + self->display); // We have to make assumptions about the display format for
// classic VNC
int dnum = g_get_x11_display_from_display_string(self->display);
if (dnum < 0)
{
LOG(LOG_LEVEL_ERROR,
"Unexpected display value %s setting up VNC module",
self->display);
xrdp_mm_set_fatal(self, ERRINFO_SERVER_DWM_CRASH);
}
else
{
g_snprintf(text, sizeof(text), "%d", 5900 + dnum);
}
} }
} }
else if (self->code == XORG_SESSION_CODE || else if (self->code == XORG_SESSION_CODE ||
+2 -3
View File
@@ -42,8 +42,7 @@
/* To check whether touch events has been implemented on session type 'mm' */ /* To check whether touch events has been implemented on session type 'mm' */
#define XRDP_MM_IMPLEMENTS_TOUCH(mm) \ #define XRDP_MM_IMPLEMENTS_TOUCH(mm) \
(((mm)->code != XVNC_SESSION_CODE) && \ ((mm)->code == XORG_SESSION_CODE)
((mm)->code != XVNC_UDS_SESSION_CODE))
struct source_info; struct source_info;
struct list16; struct list16;
@@ -440,7 +439,7 @@ struct xrdp_mm
struct xrdp_mod *(*mod_init)(void); struct xrdp_mod *(*mod_init)(void);
int (*mod_exit)(struct xrdp_mod *); int (*mod_exit)(struct xrdp_mod *);
struct xrdp_mod *mod; /* module interface */ struct xrdp_mod *mod; /* module interface */
int display; /* 10 for :10.0, 11 for :11.0, etc */ char display[MAX_DISPLAY_NAME_SIZE];
int uid; /* UID for a successful login, -1 otherwise */ int uid; /* UID for a successful login, -1 otherwise */
struct guid guid; /* GUID for the session, or all zeros */ struct guid guid; /* GUID for the session, or all zeros */
int code; /* 0=Xvnc session, 20=xorg driver mode */ int code; /* 0=Xvnc session, 20=xorg driver mode */
+5 -4
View File
@@ -35,6 +35,7 @@
#include <poll.h> #include <poll.h>
#include "log.h" #include "log.h"
#include "xrdp_constants.h"
#include "xrdp_sockets.h" #include "xrdp_sockets.h"
#include "string_calls.h" #include "string_calls.h"
#include "channel_defs.h" #include "channel_defs.h"
@@ -43,7 +44,7 @@
struct wts_obj struct wts_obj
{ {
int fd; int fd;
int display_num; char display_name[MAX_DISPLAY_NAME_SIZE];
}; };
/** /**
@@ -132,8 +133,7 @@ VirtualChannelOpen(unsigned int SessionId, const char *pVirtualName,
return 0; return 0;
} }
wts->fd = -1; wts->fd = -1;
wts->display_num = g_get_display_num_from_display(getenv("DISPLAY")); if (g_get_display_string(wts->display_name, sizeof(wts->display_name)) < 0)
if (wts->display_num < 0)
{ {
LOG(LOG_LEVEL_ERROR, "WTSVirtualChannelOpenEx: fatal error; invalid DISPLAY"); LOG(LOG_LEVEL_ERROR, "WTSVirtualChannelOpenEx: fatal error; invalid DISPLAY");
*errcode = WTS_E_RESOURCE_ERROR; *errcode = WTS_E_RESOURCE_ERROR;
@@ -162,7 +162,8 @@ VirtualChannelOpen(unsigned int SessionId, const char *pVirtualName,
memset(&s, 0, sizeof(struct sockaddr_un)); memset(&s, 0, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX; s.sun_family = AF_UNIX;
bytes = sizeof(s.sun_path); bytes = sizeof(s.sun_path);
snprintf(s.sun_path, bytes - 1, CHANSRV_API_STR, getuid(), wts->display_num); snprintf(s.sun_path, bytes - 1, CHANSRV_API_STR,
getuid(), wts->display_name);
s.sun_path[bytes - 1] = 0; s.sun_path[bytes - 1] = 0;
bytes = sizeof(struct sockaddr_un); bytes = sizeof(struct sockaddr_un);