Skip to content

[pull] devel from neutrinolabs:devel #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion common/ms-rdpbcgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
#define PROTOCOL_RDSTLS 0x00000004
#define PROTOCOL_HYBRID_EX 0x00000008

/* Negotiation packet flags (2.2.1.2.1) */
/* Negotiation request packet flags (2.2.1.1.1) */
#define RESTRICTED_ADMIN_MODE_REQUIRED 0x00000001
#define REDIRECTED_AUTHENTICATION_MODE_REQUIRED 0x00000002
#define CORRELATION_INFO_PRESENT 0x00000008

/* Negotiation response packet flags (2.2.1.2.1) */
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
#define NEGRSP_RESERVED 0x04
Expand Down
2 changes: 2 additions & 0 deletions common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ struct xrdp_client_info
int require_credentials; /* when true, credentials *must* be passed on cmd line */

int security_layer; /* SECURITY_LAYER_* */
int vmconnect; /* Used when used from inside Hyper-V */

int multimon; /* 0 = deny , 1 = allow */
struct display_size_description display_sizes;

Expand Down
19 changes: 19 additions & 0 deletions docs/man/xrdp.ini.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ All options and values (except for file names and paths) are case insensitive, a
.SH "GLOBALS"
The options to be specified in the \fB[Globals]\fR section are the following:

.TP
\fBport\fR=\fIport_specification [ port_specification ... ]\fR
Specify the port(s) that xrdp should listen on. More instructions and
examples can be found within xrdp.ini itself.

.TP
\fBvmconnect\fR=\fI[true|false]\fR
(Hyper-V VMs only). Enables a wider support of security protocols when a
virtual machine running xrdp is hosted on Hyper-V, and the user connects
to it via the vmms service on TCP port 2179. In this configuration,
RDP security is handled by the vmms service, and security features which
are not yet added to xrdp itself can be supported.

This parameter is required in environments which do not support 'classic'
RDP encryption.

The parameter is ignored for connections which are not made to the
virtual machine over the vsock transport.

.TP
\fBautorun\fP=\fIsession_name\fP
Section name for automatic login. If set and the client supplies valid
Expand Down
62 changes: 54 additions & 8 deletions libxrdp/xrdp_iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
self->trans = trans;

// See if we're running in vmconnect mode on this connection
struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);
if (client_info->vmconnect && trans->mode != TRANS_MODE_VSOCK)
{
char desc[MAX_PEER_DESCSTRLEN];
g_sck_get_peer_description(trans->sck, desc, sizeof(desc));
LOG(LOG_LEVEL_INFO, "Disabling vmconnect mode for connection from %s",
desc);
client_info->vmconnect = 0;
}
return self;
}

Expand Down Expand Up @@ -116,6 +127,11 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
{
security_type_mask = PROTOCOL_SSL;
}
/* But VMConnect mode supports everything. */
if (client_info->vmconnect)
{
security_type_mask |= PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
}

/* Logically 'and' this value with the mask requested by the client, and
* see what's left */
Expand All @@ -124,12 +140,25 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
protostr);
security_type_mask &= self->requestedProtocol;

/* Is there a match on SSL/TLS? */
if ((security_type_mask & PROTOCOL_SSL) != 0)
if (security_type_mask & PROTOCOL_HYBRID_EX)
{
/* Currently supported by VMConnect mode only */
LOG(LOG_LEVEL_INFO, "Selected HYBRID_EX security");
self->selectedProtocol = PROTOCOL_HYBRID_EX;
got_protocol = 1;
}
else if (security_type_mask & PROTOCOL_HYBRID)
{
/* Currently supported by VMConnect mode only */
LOG(LOG_LEVEL_INFO, "Selected HYBRID security");
self->selectedProtocol = PROTOCOL_HYBRID;
got_protocol = 1;
}
else if ((security_type_mask & PROTOCOL_SSL) != 0)
{
/* Can we do TLS? (basic check) */
if (g_file_readable(client_info->certificate) &&
g_file_readable(client_info->key_file))
/* Can we do TLS? (basic check). VMConnect is exempt. */
if ((g_file_readable(client_info->certificate) &&
g_file_readable(client_info->key_file)) || client_info->vmconnect)
{
LOG(LOG_LEVEL_INFO, "Selected TLS security");
self->selectedProtocol = PROTOCOL_SSL;
Expand Down Expand Up @@ -205,13 +234,20 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
/* The type field has already been read to determine that this function
should be called */
in_uint8(s, flags); /* flags */
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
if ((flags & 0x0000000b) != flags)
{
LOG(LOG_LEVEL_ERROR,
"Unsupported [MS-RDPBCGR] RDP_NEG_REQ flags: 0x%2.2x", flags);
return 1;
}

/* If both flags are set, it means 'OR', so fail only if only the one is set. */
if ((flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED) && !(flags & RESTRICTED_ADMIN_MODE_REQUIRED))
{
LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] RDP_NEG_REQ: RemoteGuard isn't supported !");
return 1;
}

in_uint16_le(s, len); /* length */
if (len != 8)
{
Expand Down Expand Up @@ -374,9 +410,12 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
char *holdp;
char *len_ptr;
char *len_indicator_ptr;
char flags;
int len;
int len_indicator;

struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);

make_stream(s);
init_stream(s, 8192);

Expand Down Expand Up @@ -410,10 +449,17 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
}
else
{
flags = EXTENDED_CLIENT_DATA_SUPPORTED;

if (client_info->vmconnect)
{
/* NLA is handled by the host and not us. */
flags |= RESTRICTED_ADMIN_MODE_SUPPORTED;
}

/* [MS-RDPBCGR] RDP_NEG_RSP */
out_uint8(s, RDP_NEG_RSP); /* type*/
//TODO: hardcoded flags
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
out_uint8(s, flags); /* flags */
out_uint16_le(s, 8); /* length (must be 8) */
out_uint32_le(s, self->selectedProtocol); /* selectedProtocol */
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_RSP "
Expand Down
4 changes: 4 additions & 0 deletions libxrdp/xrdp_rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
client_info->security_layer = SECURITY_LAYER_NEGOTIATE;
}
}
else if (g_strcasecmp(item, "vmconnect") == 0)
{
client_info->vmconnect = g_text2bool(value);
}
else if (g_strcasecmp(item, "certificate") == 0)
{
g_memset(client_info->certificate, 0, sizeof(char) * 1024);
Expand Down
6 changes: 5 additions & 1 deletion libxrdp/xrdp_sec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2252,7 +2252,11 @@ xrdp_sec_incoming(struct xrdp_sec *self)
}

/* initialize selected security layer */
if (iso->selectedProtocol > PROTOCOL_RDP)
if (self->rdp_layer->client_info.vmconnect && iso->selectedProtocol > PROTOCOL_RDP)
{
/* Security handled by host: do nothing. */
}
else if (iso->selectedProtocol > PROTOCOL_RDP)
{
/* init tls security */

Expand Down
3 changes: 3 additions & 0 deletions xrdp/xrdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ read_xrdp_ini_startup_params(struct xrdp_startup_params *startup_params)

else if (g_strcasecmp(name, "use_vsock") == 0)
{
LOG(LOG_LEVEL_WARNING,
"Config parameter 'use_vsock' is obsolete. "
"Use 'port=vsock://...' instead");
startup_params->use_vsock = g_text2bool(val);
}

Expand Down
7 changes: 3 additions & 4 deletions xrdp/xrdp.ini.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ fork=true
; port=vsock://<cid>:<port>
port=3389

; 'port' above should be connected to with vsock instead of tcp
; use this only with number alone in port above
; prefer use vsock://<cid>:<port> above
use_vsock=false
; if used inside a Hyper-V VM through vmconnect and bound on vsock,
; turn this on to enable wider security protocol support.
#vmconnect=true

; Unprivileged User name and group to run the xrdp daemon.
; It is HIGHLY RECOMMENDED you set these values. See the xrdp.ini(5)
Expand Down