From 37b6f9dd8efbd47b755fff2e94878d589382ad2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 25 Oct 2012 18:38:51 -0400 Subject: [PATCH] libfreerdp-core: improve options for connection cookie --- include/freerdp/settings.h | 3 ++- libfreerdp/core/connection.c | 40 ++++++++++++++++++++++++++++++++++-- libfreerdp/core/nego.c | 24 +++++++++++++++++++--- libfreerdp/core/nego.h | 11 +++++++--- libfreerdp/core/settings.c | 12 +++++++++++ 5 files changed, 81 insertions(+), 9 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 16d01b0ed..f9c45bdf6 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -301,7 +301,8 @@ struct rdp_settings ALIGN64 BOOL send_preconnection_pdu; /* 72 */ ALIGN64 UINT32 preconnection_id; /* 73 */ ALIGN64 char* preconnection_blob; /* 74 */ - UINT64 paddingC[80 - 75]; /* 75 */ + ALIGN64 char* computer_name; /* 75 */ + UINT64 paddingC[80 - 76]; /* 76 */ /* User Interface Parameters */ ALIGN64 BOOL sw_gdi; /* 80 */ diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index afe472ab3..071c494f6 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -62,7 +62,7 @@ */ /** - * Establish RDP Connection based on the settings given in the 'rdp' paremeter. + * Establish RDP Connection based on the settings given in the 'rdp' parameter. * @msdn{cc240452} * @param rdp RDP module * @return true if the connection succeeded. FALSE otherwise. @@ -74,7 +74,43 @@ BOOL rdp_client_connect(rdpRdp* rdp) nego_init(rdp->nego); nego_set_target(rdp->nego, settings->hostname, settings->port); - nego_set_cookie(rdp->nego, settings->username); + + if (settings->ts_gateway) + { + char* user; + char* domain; + char* cookie; + int user_length; + int domain_length; + int cookie_length; + + user = settings->username; + user_length = strlen(settings->username); + + if (settings->domain) + domain = settings->domain; + else + domain = settings->computer_name; + + domain_length = strlen(domain); + + cookie_length = domain_length + 1 + user_length; + cookie = (char*) malloc(cookie_length + 1); + + CopyMemory(cookie, domain, domain_length); + CharUpperBuffA(cookie, domain_length); + cookie[domain_length] = '\\'; + CopyMemory(&cookie[domain_length + 1], user, user_length); + cookie[cookie_length] = '\0'; + + nego_set_cookie(rdp->nego, cookie); + //nego_set_cookie_max_length(rdp->nego, MSTSC_COOKIE_MAX_LENGTH); + } + else + { + nego_set_cookie(rdp->nego, settings->username); + } + nego_set_send_preconnection_pdu(rdp->nego, settings->send_preconnection_pdu); nego_set_preconnection_id(rdp->nego, settings->preconnection_id); nego_set_preconnection_blob(rdp->nego, settings->preconnection_blob); diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index d5ef12106..80fd10409 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -149,7 +149,7 @@ BOOL nego_connect(rdpNego* nego) /* connect to selected security layer */ BOOL nego_security_connect(rdpNego* nego) { - if(!nego->tcp_connected) + if (!nego->tcp_connected) { nego->security_connected = FALSE; } @@ -160,7 +160,7 @@ BOOL nego_security_connect(rdpNego* nego) DEBUG_NEGO("nego_security_connect with PROTOCOL_NLA"); nego->security_connected = transport_connect_nla(nego->transport); } - else if (nego->selected_protocol == PROTOCOL_TLS ) + else if (nego->selected_protocol == PROTOCOL_TLS) { DEBUG_NEGO("nego_security_connect with PROTOCOL_TLS"); nego->security_connected = transport_connect_tls(nego->transport); @@ -175,6 +175,7 @@ BOOL nego_security_connect(rdpNego* nego) DEBUG_NEGO("cannot connect security layer because no protocol has been selected yet."); } } + return nego->security_connected; } @@ -562,6 +563,7 @@ BOOL nego_send_negotiation_request(rdpNego* nego) STREAM* s; int length; BYTE *bm, *em; + int cookie_length; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_REQUEST_LENGTH; @@ -575,7 +577,11 @@ BOOL nego_send_negotiation_request(rdpNego* nego) } else if (nego->cookie != NULL) { - int cookie_length = strlen(nego->cookie); + cookie_length = strlen(nego->cookie); + + if (cookie_length > nego->cookie_max_length) + cookie_length = nego->cookie_max_length; + stream_write(s, "Cookie: mstshash=", 17); stream_write(s, (BYTE*) nego->cookie, cookie_length); stream_write_BYTE(s, 0x0D); /* CR */ @@ -802,6 +808,7 @@ void nego_init(rdpNego* nego) nego->requested_protocols = PROTOCOL_RDP; nego->transport->recv_callback = nego_recv; nego->transport->recv_extra = (void*) nego; + nego->cookie_max_length = DEFAULT_COOKIE_MAX_LENGTH; nego->flags = 0; } @@ -919,6 +926,17 @@ void nego_set_cookie(rdpNego* nego, char* cookie) nego->cookie = cookie; } +/** + * Set cookie maximum length + * @param nego + * @param cookie_max_length + */ + +void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length) +{ + nego->cookie_max_length = cookie_max_length; +} + /** * Enable / disable preconnection PDU. * @param nego diff --git a/libfreerdp/core/nego.h b/libfreerdp/core/nego.h index a0b046270..7d8e6a96f 100644 --- a/libfreerdp/core/nego.h +++ b/libfreerdp/core/nego.h @@ -65,14 +65,17 @@ enum RDP_NEG_MSG TYPE_RDP_NEG_FAILURE = 0x3 }; -#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 +#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 -#define PRECONNECTION_PDU_V1_SIZE 16 -#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE+2) +#define PRECONNECTION_PDU_V1_SIZE 16 +#define PRECONNECTION_PDU_V2_MIN_SIZE (PRECONNECTION_PDU_V1_SIZE + 2) #define PRECONNECTION_PDU_V1 1 #define PRECONNECTION_PDU_V2 2 +#define MSTSC_COOKIE_MAX_LENGTH 9 +#define DEFAULT_COOKIE_MAX_LENGTH 0xFF + struct rdp_nego { int port; @@ -88,6 +91,7 @@ struct rdp_nego NEGO_STATE state; BOOL tcp_connected; BOOL security_connected; + UINT32 cookie_max_length; UINT32 selected_protocol; UINT32 requested_protocols; @@ -128,6 +132,7 @@ void nego_enable_nla(rdpNego* nego, BOOL enable_nla); void nego_enable_tls(rdpNego* nego, BOOL enable_tls); void nego_set_routing_token(rdpNego* nego, BYTE* RoutingToken, DWORD RoutingTokenLength); void nego_set_cookie(rdpNego* nego, char* cookie); +void nego_set_cookie_max_length(rdpNego* nego, UINT32 cookie_max_length); void nego_set_send_preconnection_pdu(rdpNego* nego, BOOL send_pcpdu); void nego_set_preconnection_id(rdpNego* nego, UINT32 id); void nego_set_preconnection_blob(rdpNego* nego, char* blob); diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 5568b47b9..11b386b54 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -31,6 +31,7 @@ #endif #include +#include #include #include @@ -184,6 +185,15 @@ void settings_load_hkey_local_machine(rdpSettings* settings) settings_client_load_hkey_local_machine(settings); } +void settings_get_computer_name(rdpSettings* settings) +{ + DWORD nSize = 0; + + GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize); + settings->computer_name = (char*) malloc(nSize); + GetComputerNameExA(ComputerNameNetBIOS, settings->computer_name, &nSize); +} + rdpSettings* settings_new(void* instance) { rdpSettings* settings; @@ -235,6 +245,8 @@ rdpSettings* settings_new(void* instance) settings->authentication_only = FALSE; settings->from_stdin = FALSE; + settings_get_computer_name(settings); + settings->received_caps = xzalloc(32); settings->order_support = xzalloc(32);