From e4714f34222983f8cfc35dc00d693e1292fec11b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 11 May 2016 15:52:36 -0400 Subject: [PATCH] freerdp: fix Hyper-V connectivity, fix issues #2421 and #3325 --- client/common/cmdline.c | 1 + include/freerdp/settings.h | 4 +++- libfreerdp/common/settings.c | 7 +++++++ libfreerdp/core/nego.c | 25 ++++++++++++++++--------- libfreerdp/core/nla.h | 1 + libfreerdp/core/rdp.c | 36 +++++++++++++++++++++++++++++++++--- 6 files changed, 61 insertions(+), 13 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index bf6639d..197d9e0 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1536,6 +1536,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "vmconnect") { + settings->VmConnectMode = TRUE; settings->ServerPort = 2179; settings->NegotiateSecurityLayer = FALSE; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 06e0841..8fb335a 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -601,6 +601,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_DisableCredentialsDelegation 1099 #define FreeRDP_AuthenticationLevel 1100 #define FreeRDP_AllowedTlsCiphers 1101 +#define FreeRDP_VmConnectMode 1102 #define FreeRDP_MstscCookieMode 1152 #define FreeRDP_CookieMaxLength 1153 #define FreeRDP_PreconnectionId 1154 @@ -1003,7 +1004,8 @@ struct rdp_settings ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */ ALIGN64 BOOL AuthenticationLevel; /* 1100 */ ALIGN64 char* AllowedTlsCiphers; /* 1101 */ - UINT64 padding1152[1152 - 1102]; /* 1102 */ + ALIGN64 BOOL VmConnectMode; /* 1102 */ + UINT64 padding1152[1152 - 1103]; /* 1103 */ /* Connection Cookie */ ALIGN64 BOOL MstscCookieMode; /* 1152 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 228c04c..b8a4a20 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -903,6 +903,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) case FreeRDP_AuthenticationLevel: return settings->AuthenticationLevel; + case FreeRDP_VmConnectMode: + return settings->VmConnectMode; + case FreeRDP_MstscCookieMode: return settings->MstscCookieMode; @@ -1354,6 +1357,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->AuthenticationLevel = param; break; + case FreeRDP_VmConnectMode: + settings->VmConnectMode = param; + break; + case FreeRDP_MstscCookieMode: settings->MstscCookieMode = param; break; diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 7cb6209..136b305 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -143,20 +143,27 @@ BOOL nego_connect(rdpNego* nego) } } - do + if (!nego->NegotiateSecurityLayer) { - WLog_DBG(TAG, "state: %s", NEGO_STATE_STRINGS[nego->state]); + nego->state = NEGO_STATE_FINAL; + } + else + { + do + { + WLog_DBG(TAG, "state: %s", NEGO_STATE_STRINGS[nego->state]); - nego_send(nego); + nego_send(nego); - if (nego->state == NEGO_STATE_FAIL) - { - WLog_ERR(TAG, "Protocol Security Negotiation Failure"); - nego->state = NEGO_STATE_FINAL; - return FALSE; + if (nego->state == NEGO_STATE_FAIL) + { + WLog_ERR(TAG, "Protocol Security Negotiation Failure"); + nego->state = NEGO_STATE_FINAL; + return FALSE; + } } + while (nego->state != NEGO_STATE_FINAL); } - while (nego->state != NEGO_STATE_FINAL); WLog_DBG(TAG, "Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->SelectedProtocol]); diff --git a/libfreerdp/core/nla.h b/libfreerdp/core/nla.h index 7489fc7..f6f173e 100644 --- a/libfreerdp/core/nla.h +++ b/libfreerdp/core/nla.h @@ -42,6 +42,7 @@ enum _NLA_STATE NLA_STATE_NEGO_TOKEN, NLA_STATE_PUB_KEY_AUTH, NLA_STATE_AUTH_INFO, + NLA_STATE_POST_NEGO, NLA_STATE_FINAL }; typedef enum _NLA_STATE NLA_STATE; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 43115fa..e7c5bd2 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1293,16 +1293,46 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) switch (rdp->state) { case CONNECTION_STATE_NLA: - if (nla_recv_pdu(rdp->nla, s) < 1) + if (rdp->nla->state < NLA_STATE_AUTH_INFO) { - WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - nla_recv_pdu() fail"); - return -1; + if (nla_recv_pdu(rdp->nla, s) < 1) + { + WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - nla_recv_pdu() fail"); + return -1; + } + } + else if (rdp->nla->state == NLA_STATE_POST_NEGO) + { + nego_recv(rdp->transport, s, (void*) rdp->nego); + + if (rdp->nego->state != NEGO_STATE_FINAL) + { + WLog_ERR(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - nego_recv() fail"); + return -1; + } + + rdp->nla->state = NLA_STATE_FINAL; } if (rdp->nla->state == NLA_STATE_AUTH_INFO) { transport_set_nla_mode(rdp->transport, FALSE); + if (rdp->settings->VmConnectMode) + { + rdp->nego->state = NEGO_STATE_NLA; + rdp->nego->RequestedProtocols = PROTOCOL_NLA | PROTOCOL_TLS; + nego_send_negotiation_request(rdp->nego); + rdp->nla->state = NLA_STATE_POST_NEGO; + } + else + { + rdp->nla->state = NLA_STATE_FINAL; + } + } + + if (rdp->nla->state == NLA_STATE_FINAL) + { nla_free(rdp->nla); rdp->nla = NULL; -- 2.7.4