Add new session type SCP_SESSION_TYPE_XVNC_UDS

This PR adds a new session type, which is a VNC session using a
Unix Domain Socket connection rather than a TCP connection.

This is necessary for FIPS_based deployments using VNC, as the classic
VNC password algorithm is not supported by FIPS
This commit is contained in:
matt335672
2025-03-06 14:57:55 +00:00
parent e8a0699bb4
commit 6979df55ee
8 changed files with 106 additions and 15 deletions
+2 -1
View File
@@ -377,7 +377,8 @@ values supported for a particular release of \fBxrdp\fR(8) are documented in
.TP
\fBcode\fR=\fI<number>\fR|\fI0\fR
Specifies the session type. The default, \fI0\fR, is Xvnc,
Specifies the session type. The default, \fI0\fR, is Xvnc over TCP,
\fI1\fR, is Xvnc over a UNIX domain socket,
and \fI20\fR is Xorg with xorgxrdp modules.
.TP
+2
View File
@@ -34,11 +34,13 @@
enum scp_session_type
{
SCP_SESSION_TYPE_XVNC = 0, ///< Session used Xvnc
SCP_SESSION_TYPE_XVNC_UDS, ///< Session used Xvnc with UDS connection
SCP_SESSION_TYPE_XORG ///< Session used Xorg + xorgxrdp
};
#define SCP_SESSION_TYPE_TO_STR(t) \
((t) == SCP_SESSION_TYPE_XVNC ? "Xvnc" : \
(t) == SCP_SESSION_TYPE_XVNC_UDS ? "Xvnc-UDS" : \
(t) == SCP_SESSION_TYPE_XORG ? "Xorg" : \
"unknown" \
)
+49 -3
View File
@@ -388,10 +388,21 @@ prepare_xorg_xserver_params(const struct session_parameters *s,
}
/******************************************************************************/
/**
* Prepare a list of parameters for the Xvnc X server
* @param s Session parameters
* @params authfile XAUTHORITY file
* @params passwd_file VNC password file, or NULL
* @params port UDS port to connect to, or NULL
* @return parameters list
*
* One of passwd_file and port must be set
*/
static struct list *
prepare_xvnc_xserver_params(const struct session_parameters *s,
const char *authfile,
const char *passwd_file)
const char *passwd_file,
const char *port)
{
char screen[32] = {0}; /* display number */
char geometry[32] = {0};
@@ -420,9 +431,35 @@ prepare_xvnc_xserver_params(const struct session_parameters *s,
"-auth", authfile,
"-geometry", geometry,
"-depth", depth,
"-rfbauth", passwd_file,
NULL);
if (passwd_file != NULL)
{
/* RFB authorization */
list_add_strdup_multi(params,
"-rfbauth", passwd_file,
NULL);
}
else if (port != NULL)
{
/* UDS connection. Authorization is handled by standard socket
* permissions, so we do not need to authorize within the
* VNC protocol exchange as well */
char sock_mode[16];
/* Convert a standard permissions mask into decimal
* for the -rfbunixmode switch argument
*/
g_snprintf(sock_mode, sizeof(sock_mode),
"%d", 0660); /* rw-rw---- */
list_add_strdup_multi(params,
"-rfbunixpath", port,
"-rfbunixmode", sock_mode,
"-SecurityTypes", "None",
NULL);
}
/* additional parameters from sesman.ini file */
//config_read_xserver_params(SCP_SESSION_TYPE_XVNC,
// xserver_params);
@@ -482,13 +519,22 @@ start_x_server(struct login_info *login_info,
{
switch (s->type)
{
char port[256];
case SCP_SESSION_TYPE_XORG:
xserver_params = prepare_xorg_xserver_params(s, authfile);
break;
case SCP_SESSION_TYPE_XVNC:
xserver_params = prepare_xvnc_xserver_params(s, authfile,
passwd_file);
passwd_file, NULL);
break;
case SCP_SESSION_TYPE_XVNC_UDS:
g_snprintf(port, sizeof(port), XRDP_X11RDP_STR,
login_info->uid, s->display);
xserver_params = prepare_xvnc_xserver_params(s, authfile,
NULL, port);
break;
default:
+1
View File
@@ -83,6 +83,7 @@ static struct
} type_map[] =
{
{ "Xvnc", SCP_SESSION_TYPE_XVNC},
{ "Xvnc-UDS", SCP_SESSION_TYPE_XVNC_UDS},
{ "Xorg", SCP_SESSION_TYPE_XORG},
{ NULL, (enum scp_session_type) - 1}
};
+25 -6
View File
@@ -1659,6 +1659,9 @@ lib_mod_connect(struct vnc *v)
int error;
int i;
int check_sec_result;
int socket_mode;
g_snprintf(con_port, sizeof(con_port), "%s", v->port);
v->server_msg(v, "VNC started connecting", 0);
check_sec_result = 1;
@@ -1678,17 +1681,26 @@ lib_mod_connect(struct vnc *v)
return 1;
}
if (g_strcmp(v->ip, "") == 0)
/* Assume a TCP-port based connection (i.e. not a UDS connection)
* if the port is not an absolute path */
if (con_port[0] == '/')
{
v->server_msg(v, "VNC error - no ip set", 0);
return 1;
socket_mode = TRANS_MODE_UNIX;
}
else
{
socket_mode = TRANS_MODE_TCP;
if (g_strcmp(v->ip, "") == 0)
{
v->server_msg(v, "VNC error - no IP set for TCP connection", 0);
return 1;
}
}
make_stream(s);
g_sprintf(con_port, "%s", v->port);
make_stream(pixel_format);
v->trans = trans_create(TRANS_MODE_TCP, 8 * 8192, 8192);
v->trans = trans_create(socket_mode, 8 * 8192, 8192);
if (v->trans == 0)
{
v->server_msg(v, "VNC error: trans_create() failed", 0);
@@ -1705,7 +1717,14 @@ lib_mod_connect(struct vnc *v)
g_sleep(v->delay_ms);
}
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
if (socket_mode == TRANS_MODE_TCP)
{
g_sprintf(text, "VNC connecting to TCP %s %s", v->ip, con_port);
}
else
{
g_sprintf(text, "VNC connecting to local socket %s", con_port);
}
v->server_msg(v, text, 0);
v->trans->si = v->si;
+14
View File
@@ -261,6 +261,20 @@ username=ask
password=ask
ip=127.0.0.1
port=-1
; For Xvnc, the 'code' parameter can be used to switch the connection
; protocol:-
; 0 - Use a TCP connection (default)
; 1 - Use a Unix Domain Sockets (UDS) connection.
; UDS connections are not supported by older VNC servers, but are
; supported by TigerVNC. If you select this option, comment out
; (or remove) the 'ip=' setting.
;
; UDS connections are recommended, if your X server supports them. They are
; more secure, and untroubled by firewalls.
;
; On FIPS-based systems, UDS MUST be used, as the classic algorithm used for
; VNC password files is no longer considered secure by FIPS
#code=0
#xserverbpp=24
#delay_ms=2000
; Disable requested encodings to support buggy VNC servers
+9 -4
View File
@@ -283,6 +283,10 @@ xrdp_mm_create_session(struct xrdp_mm *self)
type = SCP_SESSION_TYPE_XVNC;
break;
case XVNC_UDS_SESSION_CODE:
type = SCP_SESSION_TYPE_XVNC_UDS;
break;
case XORG_SESSION_CODE:
type = SCP_SESSION_TYPE_XORG;
break;
@@ -509,7 +513,8 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
{
g_snprintf(text, sizeof(text), "%d", 5900 + self->display);
}
else if (self->code == XORG_SESSION_CODE)
else if (self->code == XORG_SESSION_CODE ||
self->code == XVNC_UDS_SESSION_CODE)
{
g_snprintf(text, sizeof(text), XRDP_X11RDP_STR,
self->uid, self->display);
@@ -3250,11 +3255,11 @@ xrdp_mm_connect(struct xrdp_mm *self)
self->use_sesman = 1;
/* Connecting to a remote sesman is no longer supported. For purely
* local session types, this setting could be removed.
* The 'ip' value is still used for Xvnc sessions, to find the TCP
* address that the X server is listening on */
* The 'ip' value is still used for non-UDS Xvnc sessions, to find
* the TCP address that the X server is listening on */
if (xrdp_mm_get_value(self, "ip") != NULL)
{
if (self->code == XORG_SESSION_CODE)
if (self->code != XVNC_SESSION_CODE)
{
xrdp_wm_log_msg(self->wm,
LOG_LEVEL_WARNING,
+4 -1
View File
@@ -37,10 +37,13 @@
/* Code values used in 'xrdp_mm->code=' settings */
#define XVNC_SESSION_CODE 0
#define XVNC_UDS_SESSION_CODE 1
#define XORG_SESSION_CODE 20
/* To check whether touch events has been implemented on session type 'mm' */
#define XRDP_MM_IMPLEMENTS_TOUCH(mm) ((mm)->code != XVNC_SESSION_CODE)
#define XRDP_MM_IMPLEMENTS_TOUCH(mm) \
(((mm)->code != XVNC_SESSION_CODE) && \
((mm)->code != XVNC_UDS_SESSION_CODE))
struct source_info;
struct list16;