Skip to content

Commit f0bae00

Browse files
committed
vmconnect mode: support all security modes when used in Hyper-V environment
1 parent b2d4077 commit f0bae00

File tree

6 files changed

+75
-6
lines changed

6 files changed

+75
-6
lines changed

common/ms-rdpbcgr.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
#define PROTOCOL_RDSTLS 0x00000004
3636
#define PROTOCOL_HYBRID_EX 0x00000008
3737

38-
/* Negotiation packet flags (2.2.1.2.1) */
38+
/* Negotiation request packet flags (2.2.1.1.1) */
39+
#define RESTRICTED_ADMIN_MODE_REQUIRED 0x00000001
40+
#define REDIRECTED_AUTHENTICATION_MODE_REQUIRED 0x00000002
41+
#define CORRELATION_INFO_PRESENT 0x00000008
42+
43+
/* Negotiation response packet flags (2.2.1.2.1) */
3944
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
4045
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
4146
#define NEGRSP_RESERVED 0x04

common/xrdp_client_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ struct xrdp_client_info
181181
int require_credentials; /* when true, credentials *must* be passed on cmd line */
182182

183183
int security_layer; /* SECURITY_LAYER_* */
184+
int vmconnect; /* Used when used from inside Hyper-V */
185+
184186
int multimon; /* 0 = deny , 1 = allow */
185187
struct display_size_description display_sizes;
186188

libxrdp/xrdp_iso.c

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
116116
{
117117
security_type_mask = PROTOCOL_SSL;
118118
}
119+
/* But VMConnect mode supports everything. */
120+
if (client_info->vmconnect)
121+
{
122+
security_type_mask |= PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
123+
}
119124

120125
/* Logically 'and' this value with the mask requested by the client, and
121126
* see what's left */
@@ -124,8 +129,36 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
124129
protostr);
125130
security_type_mask &= self->requestedProtocol;
126131

132+
/* In VMConnect mode, we support everything. */
133+
if (client_info->vmconnect && (self->requestedProtocol > PROTOCOL_RDP))
134+
{
135+
if (security_type_mask & PROTOCOL_HYBRID_EX)
136+
{
137+
LOG(LOG_LEVEL_INFO, "Selected HYBRID_EX security");
138+
self->selectedProtocol = PROTOCOL_HYBRID_EX;
139+
got_protocol = 1;
140+
}
141+
else if (security_type_mask & PROTOCOL_HYBRID)
142+
{
143+
LOG(LOG_LEVEL_INFO, "Selected HYBRID security");
144+
self->selectedProtocol = PROTOCOL_HYBRID;
145+
got_protocol = 1;
146+
}
147+
else if (security_type_mask & PROTOCOL_SSL)
148+
{
149+
LOG(LOG_LEVEL_INFO, "Selected TLS security");
150+
self->selectedProtocol = PROTOCOL_SSL;
151+
got_protocol = 1;
152+
}
153+
else
154+
{
155+
/* Impossible */
156+
LOG(LOG_LEVEL_ERROR, "Impossible case.");
157+
rv = 1;
158+
}
159+
}
127160
/* Is there a match on SSL/TLS? */
128-
if ((security_type_mask & PROTOCOL_SSL) != 0)
161+
else if ((security_type_mask & PROTOCOL_SSL) != 0)
129162
{
130163
/* Can we do TLS? (basic check) */
131164
if (g_file_readable(client_info->certificate) &&
@@ -205,13 +238,20 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
205238
/* The type field has already been read to determine that this function
206239
should be called */
207240
in_uint8(s, flags); /* flags */
208-
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
241+
if ((flags & 0x0000000b) != flags)
209242
{
210243
LOG(LOG_LEVEL_ERROR,
211244
"Unsupported [MS-RDPBCGR] RDP_NEG_REQ flags: 0x%2.2x", flags);
212245
return 1;
213246
}
214247

248+
/* If both flags are set, it means 'OR', so fail only if only the one is set. */
249+
if ((flags & REDIRECTED_AUTHENTICATION_MODE_REQUIRED) && !(flags & RESTRICTED_ADMIN_MODE_REQUIRED))
250+
{
251+
LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] RDP_NEG_REQ: RemoteGuard isn't supported !");
252+
return 1;
253+
}
254+
215255
in_uint16_le(s, len); /* length */
216256
if (len != 8)
217257
{
@@ -374,9 +414,12 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
374414
char *holdp;
375415
char *len_ptr;
376416
char *len_indicator_ptr;
417+
char flags;
377418
int len;
378419
int len_indicator;
379420

421+
struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);
422+
380423
make_stream(s);
381424
init_stream(s, 8192);
382425

@@ -410,10 +453,17 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
410453
}
411454
else
412455
{
456+
flags = EXTENDED_CLIENT_DATA_SUPPORTED;
457+
458+
if (client_info->vmconnect)
459+
{
460+
/* NLA is handled by the host and not us. */
461+
flags |= RESTRICTED_ADMIN_MODE_SUPPORTED;
462+
}
463+
413464
/* [MS-RDPBCGR] RDP_NEG_RSP */
414465
out_uint8(s, RDP_NEG_RSP); /* type*/
415-
//TODO: hardcoded flags
416-
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
466+
out_uint8(s, flags); /* flags */
417467
out_uint16_le(s, 8); /* length (must be 8) */
418468
out_uint32_le(s, self->selectedProtocol); /* selectedProtocol */
419469
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_RSP "

libxrdp/xrdp_rdp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
211211
client_info->security_layer = SECURITY_LAYER_NEGOTIATE;
212212
}
213213
}
214+
else if (g_strcasecmp(item, "vmconnect") == 0)
215+
{
216+
client_info->vmconnect = g_text2bool(value);
217+
}
214218
else if (g_strcasecmp(item, "certificate") == 0)
215219
{
216220
g_memset(client_info->certificate, 0, sizeof(char) * 1024);

libxrdp/xrdp_sec.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2252,7 +2252,11 @@ xrdp_sec_incoming(struct xrdp_sec *self)
22522252
}
22532253

22542254
/* initialize selected security layer */
2255-
if (iso->selectedProtocol > PROTOCOL_RDP)
2255+
if (self->rdp_layer->client_info.vmconnect && iso->selectedProtocol > PROTOCOL_RDP)
2256+
{
2257+
/* Security handled by host: do nothing. */
2258+
}
2259+
else if (iso->selectedProtocol > PROTOCOL_RDP)
22562260
{
22572261
/* init tls security */
22582262

xrdp/xrdp.ini.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ port=3389
2727
; prefer use vsock://<cid>:<port> above
2828
use_vsock=false
2929

30+
; if used inside a Hyper-V VM with vmconnect, turn this on to enable
31+
; wider protocol support.
32+
#vmconnect=true
33+
3034
; Unprivileged User name and group to run the xrdp daemon.
3135
; It is HIGHLY RECOMMENDED you set these values. See the xrdp.ini(5)
3236
; manpage for more information on setting and checking these.

0 commit comments

Comments
 (0)