Merge pull request #3514 from gpotter2/hyperv-modes
vmconnect mode: support all security modes when used in a Hyper-V environment
This commit is contained in:
+6
-1
@@ -35,7 +35,12 @@
|
|||||||
#define PROTOCOL_RDSTLS 0x00000004
|
#define PROTOCOL_RDSTLS 0x00000004
|
||||||
#define PROTOCOL_HYBRID_EX 0x00000008
|
#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 EXTENDED_CLIENT_DATA_SUPPORTED 0x01
|
||||||
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
|
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
|
||||||
#define NEGRSP_RESERVED 0x04
|
#define NEGRSP_RESERVED 0x04
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ struct xrdp_client_info
|
|||||||
int require_credentials; /* when true, credentials *must* be passed on cmd line */
|
int require_credentials; /* when true, credentials *must* be passed on cmd line */
|
||||||
|
|
||||||
int security_layer; /* SECURITY_LAYER_* */
|
int security_layer; /* SECURITY_LAYER_* */
|
||||||
|
int vmconnect; /* Used when used from inside Hyper-V */
|
||||||
|
|
||||||
int multimon; /* 0 = deny , 1 = allow */
|
int multimon; /* 0 = deny , 1 = allow */
|
||||||
struct display_size_description display_sizes;
|
struct display_size_description display_sizes;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,25 @@ All options and values (except for file names and paths) are case insensitive, a
|
|||||||
.SH "GLOBALS"
|
.SH "GLOBALS"
|
||||||
The options to be specified in the \fB[Globals]\fR section are the following:
|
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
|
.TP
|
||||||
\fBautorun\fP=\fIsession_name\fP
|
\fBautorun\fP=\fIsession_name\fP
|
||||||
Section name for automatic login. If set and the client supplies valid
|
Section name for automatic login. If set and the client supplies valid
|
||||||
|
|||||||
+54
-8
@@ -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 = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
|
||||||
self->mcs_layer = owner;
|
self->mcs_layer = owner;
|
||||||
self->trans = trans;
|
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;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +127,11 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
|
|||||||
{
|
{
|
||||||
security_type_mask = PROTOCOL_SSL;
|
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
|
/* Logically 'and' this value with the mask requested by the client, and
|
||||||
* see what's left */
|
* see what's left */
|
||||||
@@ -124,12 +140,25 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
|
|||||||
protostr);
|
protostr);
|
||||||
security_type_mask &= self->requestedProtocol;
|
security_type_mask &= self->requestedProtocol;
|
||||||
|
|
||||||
/* Is there a match on SSL/TLS? */
|
if (security_type_mask & PROTOCOL_HYBRID_EX)
|
||||||
if ((security_type_mask & PROTOCOL_SSL) != 0)
|
|
||||||
{
|
{
|
||||||
/* Can we do TLS? (basic check) */
|
/* Currently supported by VMConnect mode only */
|
||||||
if (g_file_readable(client_info->certificate) &&
|
LOG(LOG_LEVEL_INFO, "Selected HYBRID_EX security");
|
||||||
g_file_readable(client_info->key_file))
|
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). 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");
|
LOG(LOG_LEVEL_INFO, "Selected TLS security");
|
||||||
self->selectedProtocol = PROTOCOL_SSL;
|
self->selectedProtocol = PROTOCOL_SSL;
|
||||||
@@ -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
|
/* The type field has already been read to determine that this function
|
||||||
should be called */
|
should be called */
|
||||||
in_uint8(s, flags); /* flags */
|
in_uint8(s, flags); /* flags */
|
||||||
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
|
if ((flags & 0x0000000b) != flags)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR,
|
LOG(LOG_LEVEL_ERROR,
|
||||||
"Unsupported [MS-RDPBCGR] RDP_NEG_REQ flags: 0x%2.2x", flags);
|
"Unsupported [MS-RDPBCGR] RDP_NEG_REQ flags: 0x%2.2x", flags);
|
||||||
return 1;
|
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 */
|
in_uint16_le(s, len); /* length */
|
||||||
if (len != 8)
|
if (len != 8)
|
||||||
{
|
{
|
||||||
@@ -374,9 +410,12 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
|
|||||||
char *holdp;
|
char *holdp;
|
||||||
char *len_ptr;
|
char *len_ptr;
|
||||||
char *len_indicator_ptr;
|
char *len_indicator_ptr;
|
||||||
|
char flags;
|
||||||
int len;
|
int len;
|
||||||
int len_indicator;
|
int len_indicator;
|
||||||
|
|
||||||
|
struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);
|
||||||
|
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 8192);
|
init_stream(s, 8192);
|
||||||
|
|
||||||
@@ -410,10 +449,17 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
|
|||||||
}
|
}
|
||||||
else
|
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 */
|
/* [MS-RDPBCGR] RDP_NEG_RSP */
|
||||||
out_uint8(s, RDP_NEG_RSP); /* type*/
|
out_uint8(s, RDP_NEG_RSP); /* type*/
|
||||||
//TODO: hardcoded flags
|
out_uint8(s, flags); /* flags */
|
||||||
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
|
|
||||||
out_uint16_le(s, 8); /* length (must be 8) */
|
out_uint16_le(s, 8); /* length (must be 8) */
|
||||||
out_uint32_le(s, self->selectedProtocol); /* selectedProtocol */
|
out_uint32_le(s, self->selectedProtocol); /* selectedProtocol */
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_RSP "
|
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding structure [MS-RDPBCGR] RDP_NEG_RSP "
|
||||||
|
|||||||
@@ -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;
|
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)
|
else if (g_strcasecmp(item, "certificate") == 0)
|
||||||
{
|
{
|
||||||
g_memset(client_info->certificate, 0, sizeof(char) * 1024);
|
g_memset(client_info->certificate, 0, sizeof(char) * 1024);
|
||||||
|
|||||||
+5
-1
@@ -2252,7 +2252,11 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* initialize selected security layer */
|
/* 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 */
|
/* init tls security */
|
||||||
|
|
||||||
|
|||||||
@@ -332,6 +332,9 @@ read_xrdp_ini_startup_params(struct xrdp_startup_params *startup_params)
|
|||||||
|
|
||||||
else if (g_strcasecmp(name, "use_vsock") == 0)
|
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);
|
startup_params->use_vsock = g_text2bool(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -22,10 +22,9 @@ fork=true
|
|||||||
; port=vsock://<cid>:<port>
|
; port=vsock://<cid>:<port>
|
||||||
port=3389
|
port=3389
|
||||||
|
|
||||||
; 'port' above should be connected to with vsock instead of tcp
|
; if used inside a Hyper-V VM through vmconnect and bound on vsock,
|
||||||
; use this only with number alone in port above
|
; turn this on to enable wider security protocol support.
|
||||||
; prefer use vsock://<cid>:<port> above
|
#vmconnect=true
|
||||||
use_vsock=false
|
|
||||||
|
|
||||||
; Unprivileged User name and group to run the xrdp daemon.
|
; Unprivileged User name and group to run the xrdp daemon.
|
||||||
; It is HIGHLY RECOMMENDED you set these values. See the xrdp.ini(5)
|
; It is HIGHLY RECOMMENDED you set these values. See the xrdp.ini(5)
|
||||||
|
|||||||
Reference in New Issue
Block a user