From f5fff7658a30b1ac229e3f46e5be80330d650fa0 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 20 Sep 2016 08:58:04 +0200 Subject: [PATCH] Made some functions static. --- libfreerdp/core/gcc.c | 427 ++++++++++++++++++++++++++------------------ libfreerdp/core/transport.c | 108 +++++------ libfreerdp/crypto/tls.c | 251 +++++++++++++------------- 3 files changed, 438 insertions(+), 348 deletions(-) diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 36c9f18..2d92e1d 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -154,6 +154,7 @@ BOOL gcc_read_conference_create_request(wStream* s, rdpMcs* mcs) /* ConnectData */ if (!per_read_choice(s, &choice)) return FALSE; + if (!per_read_object_identifier(s, t124_02_98_oid)) return FALSE; @@ -164,30 +165,38 @@ BOOL gcc_read_conference_create_request(wStream* s, rdpMcs* mcs) /* ConnectGCCPDU */ if (!per_read_choice(s, &choice)) return FALSE; + if (!per_read_selection(s, &selection)) return FALSE; /* ConferenceCreateRequest::conferenceName */ if (!per_read_numeric_string(s, 1)) /* ConferenceName::numeric */ return FALSE; + if (!per_read_padding(s, 1)) /* padding */ return FALSE; /* UserData (SET OF SEQUENCE) */ - if (!per_read_number_of_sets(s, &number) || number != 1) /* one set of UserData */ + if (!per_read_number_of_sets(s, &number) + || number != 1) /* one set of UserData */ return FALSE; - if (!per_read_choice(s, &choice) || choice != 0xC0) /* UserData::value present + select h221NonStandard (1) */ + + if (!per_read_choice(s, &choice) + || choice != 0xC0) /* UserData::value present + select h221NonStandard (1) */ return FALSE; /* h221NonStandard */ - if (!per_read_octet_string(s, h221_cs_key, 4, 4)) /* h221NonStandard, client-to-server H.221 key, "Duca" */ + if (!per_read_octet_string(s, h221_cs_key, 4, + 4)) /* h221NonStandard, client-to-server H.221 key, "Duca" */ return FALSE; /* userData::value (OCTET_STRING) */ if (!per_read_length(s, &length)) return FALSE; + if (Stream_GetRemainingLength(s) < length) return FALSE; + if (!gcc_read_client_data_blocks(s, mcs, length)) return FALSE; @@ -204,29 +213,30 @@ BOOL gcc_read_conference_create_request(wStream* s, rdpMcs* mcs) void gcc_write_conference_create_request(wStream* s, wStream* userData) { /* ConnectData */ - per_write_choice(s, 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */ - per_write_object_identifier(s, t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */ - + per_write_choice(s, + 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */ + per_write_object_identifier(s, + t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */ /* ConnectData::connectPDU (OCTET_STRING) */ per_write_length(s, Stream_GetPosition(userData) + 14); /* connectPDU length */ - /* ConnectGCCPDU */ - per_write_choice(s, 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */ - per_write_selection(s, 0x08); /* select optional userData from ConferenceCreateRequest */ - + per_write_choice(s, + 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */ + per_write_selection(s, + 0x08); /* select optional userData from ConferenceCreateRequest */ /* ConferenceCreateRequest::conferenceName */ per_write_numeric_string(s, (BYTE*)"1", 1, 1); /* ConferenceName::numeric */ per_write_padding(s, 1); /* padding */ - /* UserData (SET OF SEQUENCE) */ per_write_number_of_sets(s, 1); /* one set of UserData */ - per_write_choice(s, 0xC0); /* UserData::value present + select h221NonStandard (1) */ - + per_write_choice(s, + 0xC0); /* UserData::value present + select h221NonStandard (1) */ /* h221NonStandard */ - per_write_octet_string(s, h221_cs_key, 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */ - + per_write_octet_string(s, h221_cs_key, 4, + 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */ /* userData::value (OCTET_STRING) */ - per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData), 0); /* array of client data blocks */ + per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData), + 0); /* array of client data blocks */ } BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) @@ -240,7 +250,7 @@ BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) /* ConnectData */ if (!per_read_choice(s, &choice) || - !per_read_object_identifier(s, t124_02_98_oid)) + !per_read_object_identifier(s, t124_02_98_oid)) return FALSE; /* ConnectData::connectPDU (OCTET_STRING) */ @@ -272,7 +282,8 @@ BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) return FALSE; /* h221NonStandard */ - if (!per_read_octet_string(s, h221_sc_key, 4, 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */ + if (!per_read_octet_string(s, h221_sc_key, 4, + 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */ return FALSE; /* userData (OCTET_STRING) */ @@ -281,7 +292,8 @@ BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) if (!gcc_read_server_data_blocks(s, mcs, length)) { - WLog_ERR(TAG, "gcc_read_conference_create_response: gcc_read_server_data_blocks failed"); + WLog_ERR(TAG, + "gcc_read_conference_create_response: gcc_read_server_data_blocks failed"); return FALSE; } @@ -293,34 +305,27 @@ void gcc_write_conference_create_response(wStream* s, wStream* userData) /* ConnectData */ per_write_choice(s, 0); per_write_object_identifier(s, t124_02_98_oid); - /* ConnectData::connectPDU (OCTET_STRING) */ /* This length MUST be ignored by the client according to [MS-RDPBCGR] */ per_write_length(s, 0x2A); - /* ConnectGCCPDU */ per_write_choice(s, 0x14); - /* ConferenceCreateResponse::nodeID (UserID) */ per_write_integer16(s, 0x79F3, 1001); - /* ConferenceCreateResponse::tag (INTEGER) */ per_write_integer(s, 1); - /* ConferenceCreateResponse::result (ENUMERATED) */ per_write_enumerated(s, 0, MCS_Result_enum_length); - /* number of UserData sets */ per_write_number_of_sets(s, 1); - /* UserData::value present + select h221NonStandard (1) */ per_write_choice(s, 0xC0); - /* h221NonStandard */ - per_write_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */ - + per_write_octet_string(s, h221_sc_key, 4, + 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */ /* userData (OCTET_STRING) */ - per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData), 0); /* array of server data blocks */ + per_write_octet_string(s, Stream_Buffer(userData), Stream_GetPosition(userData), + 0); /* array of server data blocks */ } BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) @@ -336,7 +341,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) if (!gcc_read_user_data_header(s, &type, &blockLength)) return FALSE; - if (Stream_GetRemainingLength(s) < (size_t) (blockLength - 4)) + if (Stream_GetRemainingLength(s) < (size_t)(blockLength - 4)) return FALSE; switch (type) @@ -344,42 +349,50 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) case CS_CORE: if (!gcc_read_client_core_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_SECURITY: if (!gcc_read_client_security_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_NET: if (!gcc_read_client_network_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_CLUSTER: if (!gcc_read_client_cluster_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_MONITOR: if (!gcc_read_client_monitor_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_MCS_MSGCHANNEL: if (!gcc_read_client_message_channel_data(s, mcs, blockLength - 4)) return FALSE; + break; case CS_MONITOR_EX: if (!gcc_read_client_monitor_extended_data(s, mcs, blockLength - 4)) return FALSE; + break; case 0xC009: case CS_MULTITRANSPORT: if (!gcc_read_client_multitransport_channel_data(s, mcs, blockLength - 4)) return FALSE; + break; default: @@ -392,8 +405,9 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) if (endPos != (begPos + blockLength)) { - WLog_ERR(TAG, "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d", - type, endPos, begPos + blockLength); + WLog_ERR(TAG, + "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d", + type, endPos, begPos + blockLength); } length -= blockLength; @@ -406,7 +420,6 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs) { rdpSettings* settings = mcs->settings; - gcc_write_client_core_data(s, mcs); gcc_write_client_cluster_data(s, mcs); gcc_write_client_security_data(s, mcs); @@ -429,17 +442,20 @@ void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs) { if (settings->UseMultimon && !settings->SpanMonitors) { - WLog_ERR(TAG, "WARNING: true multi monitor support was not advertised by server!"); + WLog_ERR(TAG, + "WARNING: true multi monitor support was not advertised by server!"); if (settings->ForceMultimon) { - WLog_ERR(TAG, "Sending multi monitor information anyway (may break connectivity!)"); + WLog_ERR(TAG, + "Sending multi monitor information anyway (may break connectivity!)"); gcc_write_client_monitor_data(s, mcs); gcc_write_client_monitor_extended_data(s, mcs); } else { - WLog_ERR(TAG, "Use /multimon:force to force sending multi monitor information"); + WLog_ERR(TAG, + "Use /multimon:force to force sending multi monitor information"); } } } @@ -470,44 +486,54 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_core_data failed"); return FALSE; } + break; case SC_SECURITY: if (!gcc_read_server_security_data(s, mcs)) { - WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_security_data failed"); + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_security_data failed"); return FALSE; } + break; case SC_NET: if (!gcc_read_server_network_data(s, mcs)) { - WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_network_data failed"); + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_network_data failed"); return FALSE; } + break; case SC_MCS_MSGCHANNEL: if (!gcc_read_server_message_channel_data(s, mcs)) { - WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed"); + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed"); return FALSE; } + break; case SC_MULTITRANSPORT: if (!gcc_read_server_multitransport_channel_data(s, mcs)) { - WLog_ERR(TAG, "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed"); + WLog_ERR(TAG, + "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed"); return FALSE; } + break; default: WLog_ERR(TAG, "gcc_read_server_data_blocks: ignoring type=%hu", type); break; } + offset += blockLength; Stream_SetPointer(s, holdp + blockLength); } @@ -518,10 +544,9 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) BOOL gcc_write_server_data_blocks(wStream* s, rdpMcs* mcs) { return gcc_write_server_core_data(s, mcs) && /* serverCoreData */ - gcc_write_server_network_data(s, mcs) && /* serverNetworkData */ - gcc_write_server_security_data(s, mcs) && /* serverSecurityData */ - gcc_write_server_message_channel_data(s, mcs); /* serverMessageChannelData */ - + gcc_write_server_network_data(s, mcs) && /* serverNetworkData */ + gcc_write_server_security_data(s, mcs) && /* serverSecurityData */ + gcc_write_server_message_channel_data(s, mcs); /* serverMessageChannelData */ /* TODO: Send these GCC data blocks only when the client sent them */ //gcc_write_server_multitransport_channel_data(s, settings); /* serverMultitransportChannelData */ } @@ -534,7 +559,7 @@ BOOL gcc_read_user_data_header(wStream* s, UINT16* type, UINT16* length) Stream_Read_UINT16(s, *type); /* type */ Stream_Read_UINT16(s, *length); /* length */ - if (Stream_GetRemainingLength(s) < (size_t) (*length - 4)) + if (Stream_GetRemainingLength(s) < (size_t)(*length - 4)) return FALSE; return TRUE; @@ -581,7 +606,6 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) Stream_Read_UINT32(s, version); /* version (4 bytes) */ settings->RdpVersion = (version == RDP_VERSION_4 ? 4 : 7); - Stream_Read_UINT16(s, settings->DesktopWidth); /* DesktopWidth (2 bytes) */ Stream_Read_UINT16(s, settings->DesktopHeight); /* DesktopHeight (2 bytes) */ Stream_Read_UINT16(s, colorDepth); /* ColorDepth (2 bytes) */ @@ -591,22 +615,22 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 32 / 2, - &str, 0, NULL, NULL) < 1) + &str, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client host name"); return FALSE; } + Stream_Seek(s, 32); free(settings->ClientHostname); settings->ClientHostname = str; str = NULL; - Stream_Read_UINT32(s, settings->KeyboardType); /* KeyboardType (4 bytes) */ - Stream_Read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType (4 bytes) */ - Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey (4 bytes) */ - + Stream_Read_UINT32(s, + settings->KeyboardSubType); /* KeyboardSubType (4 bytes) */ + Stream_Read_UINT32(s, + settings->KeyboardFunctionKey); /* KeyboardFunctionKey (4 bytes) */ Stream_Seek(s, 64); /* imeFileName (64 bytes) */ - blockLength -= 128; /** @@ -620,32 +644,40 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) { if (blockLength < 2) break; + Stream_Read_UINT16(s, postBeta2ColorDepth); /* postBeta2ColorDepth (2 bytes) */ blockLength -= 2; if (blockLength < 2) break; + Stream_Seek_UINT16(s); /* clientProductID (2 bytes) */ blockLength -= 2; if (blockLength < 4) break; + Stream_Seek_UINT32(s); /* serialNumber (4 bytes) */ blockLength -= 4; if (blockLength < 2) break; + Stream_Read_UINT16(s, highColorDepth); /* highColorDepth (2 bytes) */ blockLength -= 2; if (blockLength < 2) break; - Stream_Read_UINT16(s, supportedColorDepths); /* supportedColorDepths (2 bytes) */ + + Stream_Read_UINT16(s, + supportedColorDepths); /* supportedColorDepths (2 bytes) */ blockLength -= 2; if (blockLength < 2) break; - Stream_Read_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags (2 bytes) */ + + Stream_Read_UINT16(s, + earlyCapabilityFlags); /* earlyCapabilityFlags (2 bytes) */ settings->EarlyCapabilityFlags = (UINT32) earlyCapabilityFlags; blockLength -= 2; @@ -655,11 +687,12 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) break; if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 64 / 2, - &str, 0, NULL, NULL) < 1) + &str, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert the client product identifier"); return FALSE; } + Stream_Seek(s, 64); /* clientDigProductId (64 bytes) */ free(settings->ClientProductId); settings->ClientProductId = str; @@ -667,47 +700,62 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 1) break; + Stream_Read_UINT8(s, connectionType); /* connectionType (1 byte) */ blockLength -= 1; if (blockLength < 1) break; + Stream_Seek_UINT8(s); /* pad1octet (1 byte) */ blockLength -= 1; if (blockLength < 4) break; - Stream_Read_UINT32(s, serverSelectedProtocol); /* serverSelectedProtocol (4 bytes) */ + + Stream_Read_UINT32(s, + serverSelectedProtocol); /* serverSelectedProtocol (4 bytes) */ blockLength -= 4; if (blockLength < 4) break; - Stream_Read_UINT32(s, settings->DesktopPhysicalWidth); /* desktopPhysicalWidth (4 bytes) */ + + Stream_Read_UINT32(s, + settings->DesktopPhysicalWidth); /* desktopPhysicalWidth (4 bytes) */ blockLength -= 4; if (blockLength < 4) break; - Stream_Read_UINT32(s, settings->DesktopPhysicalHeight); /* desktopPhysicalHeight (4 bytes) */ + + Stream_Read_UINT32(s, + settings->DesktopPhysicalHeight); /* desktopPhysicalHeight (4 bytes) */ blockLength -= 4; if (blockLength < 2) break; - Stream_Read_UINT16(s, settings->DesktopOrientation); /* desktopOrientation (2 bytes) */ + + Stream_Read_UINT16(s, + settings->DesktopOrientation); /* desktopOrientation (2 bytes) */ blockLength -= 2; if (blockLength < 4) break; - Stream_Read_UINT32(s, settings->DesktopScaleFactor); /* desktopScaleFactor (4 bytes) */ + + Stream_Read_UINT32(s, + settings->DesktopScaleFactor); /* desktopScaleFactor (4 bytes) */ blockLength -= 4; if (blockLength < 4) break; - Stream_Read_UINT32(s, settings->DeviceScaleFactor); /* deviceScaleFactor (4 bytes) */ + + Stream_Read_UINT32(s, + settings->DeviceScaleFactor); /* deviceScaleFactor (4 bytes) */ blockLength -= 4; if (settings->SelectedProtocol != serverSelectedProtocol) return FALSE; - } while (0); + } + while (0); if (highColorDepth > 0) { @@ -723,18 +771,23 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) case RNS_UD_COLOR_4BPP: clientColorDepth = 4; break; + case RNS_UD_COLOR_8BPP: clientColorDepth = 8; break; + case RNS_UD_COLOR_16BPP_555: clientColorDepth = 15; break; + case RNS_UD_COLOR_16BPP_565: clientColorDepth = 16; break; + case RNS_UD_COLOR_24BPP: clientColorDepth = 24; break; + default: return FALSE; } @@ -746,9 +799,11 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) case RNS_UD_COLOR_4BPP: clientColorDepth = 4; break; + case RNS_UD_COLOR_8BPP: clientColorDepth = 8; break; + default: return FALSE; } @@ -762,27 +817,31 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) settings->ColorDepth = clientColorDepth; if (settings->NetworkAutoDetect) - settings->NetworkAutoDetect = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT) ? TRUE : FALSE; + settings->NetworkAutoDetect = (earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT) ? TRUE : FALSE; if (settings->SupportHeartbeatPdu) - settings->SupportHeartbeatPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_HEARTBEAT_PDU) ? TRUE : FALSE; + settings->SupportHeartbeatPdu = (earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_HEARTBEAT_PDU) ? TRUE : FALSE; if (settings->SupportGraphicsPipeline) - settings->SupportGraphicsPipeline = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL) ? TRUE : FALSE; + settings->SupportGraphicsPipeline = (earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL) ? TRUE : FALSE; if (settings->SupportDynamicTimeZone) - settings->SupportDynamicTimeZone = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE; + settings->SupportDynamicTimeZone = (earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE; if (settings->SupportMonitorLayoutPdu) - settings->SupportMonitorLayoutPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE; + settings->SupportMonitorLayoutPdu = (earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE; if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE)) connectionType = 0; - settings->SupportErrorInfoPdu = earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU; - + settings->SupportErrorInfoPdu = earlyCapabilityFlags & + RNS_UD_CS_SUPPORT_ERRINFO_PDU; settings->ConnectionType = connectionType; - return TRUE; } @@ -805,19 +864,19 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) WCHAR* clientDigProductId = NULL; int clientDigProductIdLength; rdpSettings* settings = mcs->settings; - gcc_write_user_data_header(s, CS_CORE, 234); - version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; - - clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); - clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); - + clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, + &clientName, 0); + clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, + settings->ClientProductId, -1, &clientDigProductId, 0); Stream_Write_UINT32(s, version); /* Version */ Stream_Write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ Stream_Write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ - Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ - Stream_Write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ + Stream_Write_UINT16(s, + RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ + Stream_Write_UINT16(s, + RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ Stream_Write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ Stream_Write_UINT32(s, settings->ClientBuild); /* ClientBuild */ @@ -832,24 +891,18 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) Stream_Write(s, clientName, (clientNameLength * 2)); Stream_Zero(s, 32 - (clientNameLength * 2)); free(clientName); - Stream_Write_UINT32(s, settings->KeyboardType); /* KeyboardType */ Stream_Write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ - Stream_Zero(s, 64); /* imeFileName */ - Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ Stream_Write_UINT16(s, 1); /* clientProductID */ Stream_Write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ - highColorDepth = MIN(settings->ColorDepth, 24); - supportedColorDepths = - RNS_UD_24BPP_SUPPORT | - RNS_UD_16BPP_SUPPORT | - RNS_UD_15BPP_SUPPORT; - + RNS_UD_24BPP_SUPPORT | + RNS_UD_16BPP_SUPPORT | + RNS_UD_15BPP_SUPPORT; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->NetworkAutoDetect) @@ -886,7 +939,6 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */ Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ - Stream_Write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ @@ -895,17 +947,17 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength - 1] = 0; } - Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2) ); - Stream_Zero(s, 64 - (clientDigProductIdLength * 2) ); - free(clientDigProductId); + Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2)); + Stream_Zero(s, 64 - (clientDigProductIdLength * 2)); + free(clientDigProductId); Stream_Write_UINT8(s, connectionType); /* connectionType */ Stream_Write_UINT8(s, 0); /* pad1octet */ - Stream_Write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ - - Stream_Write_UINT32(s, settings->DesktopPhysicalWidth); /* desktopPhysicalWidth */ - Stream_Write_UINT32(s, settings->DesktopPhysicalHeight); /* desktopPhysicalHeight */ + Stream_Write_UINT32(s, + settings->DesktopPhysicalWidth); /* desktopPhysicalWidth */ + Stream_Write_UINT32(s, + settings->DesktopPhysicalHeight); /* desktopPhysicalHeight */ Stream_Write_UINT16(s, settings->DesktopOrientation); /* desktopOrientation */ Stream_Write_UINT32(s, settings->DesktopScaleFactor); /* desktopScaleFactor */ Stream_Write_UINT32(s, settings->DeviceScaleFactor); /* deviceScaleFactor */ @@ -951,15 +1003,16 @@ BOOL gcc_write_server_core_data(wStream* s, rdpMcs* mcs) return FALSE; gcc_write_user_data_header(s, SC_CORE, 16); - version = settings->RdpVersion == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS; if (settings->SupportDynamicTimeZone) earlyCapabilityFlags |= RNS_UD_SC_DYNAMIC_DST_SUPPORTED; Stream_Write_UINT32(s, version); /* version (4 bytes) */ - Stream_Write_UINT32(s, settings->RequestedProtocols); /* clientRequestedProtocols (4 bytes) */ - Stream_Write_UINT32(s, earlyCapabilityFlags); /* earlyCapabilityFlags (4 bytes) */ + Stream_Write_UINT32(s, + settings->RequestedProtocols); /* clientRequestedProtocols (4 bytes) */ + Stream_Write_UINT32(s, + earlyCapabilityFlags); /* earlyCapabilityFlags (4 bytes) */ return TRUE; } @@ -980,6 +1033,7 @@ BOOL gcc_read_client_security_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (settings->UseRdpSecurityLayer) { Stream_Read_UINT32(s, settings->EncryptionMethods); /* encryptionMethods */ + if (settings->EncryptionMethods == 0) Stream_Read_UINT32(s, settings->EncryptionMethods); /* extEncryptionMethods */ else @@ -989,6 +1043,7 @@ BOOL gcc_read_client_security_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) { Stream_Seek(s, 8); } + return TRUE; } @@ -1002,7 +1057,6 @@ BOOL gcc_read_client_security_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) void gcc_write_client_security_data(wStream* s, rdpMcs* mcs) { rdpSettings* settings = mcs->settings; - gcc_write_user_data_header(s, CS_SECURITY, 12); if (settings->UseRdpSecurityLayer) @@ -1038,26 +1092,34 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) case ENCRYPTION_METHOD_NONE: WLog_DBG(TAG, "Server rdp encryption method: NONE"); break; + case ENCRYPTION_METHOD_40BIT: WLog_DBG(TAG, "Server rdp encryption method: 40BIT"); break; + case ENCRYPTION_METHOD_56BIT: WLog_DBG(TAG, "Server rdp encryption method: 56BIT"); break; + case ENCRYPTION_METHOD_128BIT: WLog_DBG(TAG, "Server rdp encryption method: 128BIT"); break; + case ENCRYPTION_METHOD_FIPS: WLog_DBG(TAG, "Server rdp encryption method: FIPS"); break; + default: - WLog_ERR(TAG, "Received unknown encryption method %08X", serverEncryptionMethod); + WLog_ERR(TAG, "Received unknown encryption method %08X", + serverEncryptionMethod); return FALSE; } - if (settings->UseRdpSecurityLayer && !(settings->EncryptionMethods & serverEncryptionMethod)) + if (settings->UseRdpSecurityLayer + && !(settings->EncryptionMethods & serverEncryptionMethod)) { - WLog_WARN(TAG, "Server uses non-advertised encryption method 0x%08X", serverEncryptionMethod); + WLog_WARN(TAG, "Server uses non-advertised encryption method 0x%08X", + serverEncryptionMethod); /* FIXME: Should we return FALSE; in this case ?? */ } @@ -1071,13 +1133,17 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) { validCryptoConfig = TRUE; } + break; + case ENCRYPTION_LEVEL_FIPS: if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { validCryptoConfig = TRUE; } + break; + case ENCRYPTION_LEVEL_LOW: case ENCRYPTION_LEVEL_HIGH: case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: @@ -1088,15 +1154,19 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) { validCryptoConfig = TRUE; } + break; + default: - WLog_ERR(TAG, "Received unknown encryption level %08X", settings->EncryptionLevel); + WLog_ERR(TAG, "Received unknown encryption level %08X", + settings->EncryptionLevel); } if (!validCryptoConfig) { - WLog_ERR(TAG, "Received invalid cryptographic configuration (level=0x%08X method=0x%08X)", - settings->EncryptionLevel, settings->EncryptionMethods); + WLog_ERR(TAG, + "Received invalid cryptographic configuration (level=0x%08X method=0x%08X)", + settings->EncryptionLevel, settings->EncryptionMethods); return FALSE; } @@ -1113,34 +1183,38 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs) Stream_Read_UINT32(s, settings->ServerRandomLength); /* serverRandomLen */ Stream_Read_UINT32(s, settings->ServerCertificateLength); /* serverCertLen */ - if (Stream_GetRemainingLength(s) < settings->ServerRandomLength + settings->ServerCertificateLength) + if (Stream_GetRemainingLength(s) < settings->ServerRandomLength + + settings->ServerCertificateLength) return FALSE; - if ((settings->ServerRandomLength <= 0) || (settings->ServerCertificateLength <= 0)) + if ((settings->ServerRandomLength <= 0) + || (settings->ServerCertificateLength <= 0)) return FALSE; /* serverRandom */ settings->ServerRandom = (BYTE*) malloc(settings->ServerRandomLength); + if (!settings->ServerRandom) return FALSE; - Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength); - + Stream_Read(s, settings->ServerRandom, settings->ServerRandomLength); /* serverCertificate */ settings->ServerCertificate = (BYTE*) malloc(settings->ServerCertificateLength); + if (!settings->ServerCertificate) return FALSE; - Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength); + Stream_Read(s, settings->ServerCertificate, settings->ServerCertificateLength); certificate_free(settings->RdpServerCertificate); settings->RdpServerCertificate = certificate_new(); + if (!settings->RdpServerCertificate) return FALSE; data = settings->ServerCertificate; length = settings->ServerCertificateLength; - - return certificate_read_server_certificate(settings->RdpServerCertificate, data, length); + return certificate_read_server_certificate(settings->RdpServerCertificate, data, + length); } static const BYTE initial_signature[] = @@ -1221,20 +1295,26 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) case ENCRYPTION_LEVEL_NONE: WLog_INFO(TAG, "Active rdp encryption level: NONE"); break; + case ENCRYPTION_LEVEL_FIPS: WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant"); break; + case ENCRYPTION_LEVEL_HIGH: WLog_INFO(TAG, "Active rdp encryption level: HIGH"); break; + case ENCRYPTION_LEVEL_LOW: WLog_INFO(TAG, "Active rdp encryption level: LOW"); break; + case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE"); break; + default: - WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel); + WLog_ERR(TAG, "Invalid server encryption level 0x%08X", + settings->EncryptionLevel); WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE"); settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } @@ -1246,24 +1326,34 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) /* The only valid method is NONE in this case */ settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; break; + case ENCRYPTION_LEVEL_FIPS: + /* The only valid method is FIPS in this case */ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)) { - WLog_WARN(TAG, "client does not support FIPS as required by server configuration"); + WLog_WARN(TAG, + "client does not support FIPS as required by server configuration"); } + settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; break; + case ENCRYPTION_LEVEL_HIGH: + /* Maximum key strength supported by the server must be used (128 bit)*/ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)) { - WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration"); + WLog_WARN(TAG, + "client does not support 128 bit encryption method as required by server configuration"); } + settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; break; + case ENCRYPTION_LEVEL_LOW: case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: + /* Maximum key strength supported by the client must be used */ if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; @@ -1278,7 +1368,9 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) WLog_WARN(TAG, "client has not announced any supported encryption methods"); settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } + break; + default: WLog_ERR(TAG, "internal error: unknown encryption level"); return FALSE; @@ -1290,18 +1382,23 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) case ENCRYPTION_METHOD_NONE: WLog_INFO(TAG, "Selected rdp encryption method: NONE"); break; + case ENCRYPTION_METHOD_40BIT: WLog_INFO(TAG, "Selected rdp encryption method: 40BIT"); break; + case ENCRYPTION_METHOD_56BIT: WLog_INFO(TAG, "Selected rdp encryption method: 56BIT"); break; + case ENCRYPTION_METHOD_128BIT: WLog_INFO(TAG, "Selected rdp encryption method: 128BIT"); break; + case ENCRYPTION_METHOD_FIPS: WLog_INFO(TAG, "Selected rdp encryption method: FIPS"); break; + default: WLog_ERR(TAG, "internal error: unknown encryption method"); return FALSE; @@ -1316,7 +1413,6 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) { serverRandomLen = 32; - keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ @@ -1326,7 +1422,6 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ - serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ @@ -1337,7 +1432,6 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ - headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; @@ -1346,8 +1440,8 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) if (!Stream_EnsureRemainingCapacity(s, headerLen + 4)) return FALSE; - gcc_write_user_data_header(s, SC_SECURITY, headerLen); + gcc_write_user_data_header(s, SC_SECURITY, headerLen); Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ @@ -1358,46 +1452,39 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ - settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); winpr_RAND(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); - sigData = Stream_Pointer(s); - Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ - Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ Stream_Write(s, "RSA1", 4); /* magic */ Stream_Write_UINT32(s, keyLen + 8); /* keylen */ Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ Stream_Write_UINT32(s, keyLen - 1); /* datalen */ - Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); - sigDataLen = Stream_Pointer(s) - sigData; - Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */ - memcpy(signature, initial_signature, sizeof(initial_signature)); if (!winpr_MD5_Init(&md5)) return FALSE; + if (!winpr_MD5_Update(&md5, sigData, sigDataLen)) return FALSE; + if (!winpr_MD5_Final(&md5, signature, sizeof(signature))) return FALSE; crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, - tssk_modulus, tssk_privateExponent, encryptedSignature); - + tssk_modulus, tssk_privateExponent, encryptedSignature); Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); Stream_Zero(s, 8); return TRUE; @@ -1435,11 +1522,14 @@ BOOL gcc_read_client_network_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) * - options: a 32-bit, unsigned integer. Channel option flags */ Stream_Read(s, mcs->channels[i].Name, 8); /* name (8 bytes) */ + if (!memchr(mcs->channels[i].Name, 0, 8)) { - WLog_ERR(TAG, "protocol violation: received a static channel name with missing null-termination"); + WLog_ERR(TAG, + "protocol violation: received a static channel name with missing null-termination"); return FALSE; } + Stream_Read_UINT32(s, mcs->channels[i].options); /* options (4 bytes) */ mcs->channels[i].ChannelId = mcs->baseChannelId++; } @@ -1463,7 +1553,6 @@ void gcc_write_client_network_data(wStream* s, rdpMcs* mcs) { length = mcs->channelCount * 12 + 8; gcc_write_user_data_header(s, CS_NET, length); - Stream_Write_UINT32(s, mcs->channelCount); /* channelCount */ /* channelDefArray */ @@ -1489,13 +1578,12 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs) Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */ Stream_Read_UINT16(s, channelCount); /* channelCount */ - parsedChannelCount = channelCount; if (channelCount != mcs->channelCount) { WLog_ERR(TAG, "requested %d channels, got %d instead", - mcs->channelCount, channelCount); + mcs->channelCount, channelCount); /* we ensure that the response is not bigger than the request */ @@ -1521,13 +1609,13 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs) BOOL gcc_write_server_network_data(wStream* s, rdpMcs* mcs) { UINT32 i; - int payloadLen = 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : 0); + int payloadLen = 8 + mcs->channelCount * 2 + (mcs->channelCount % 2 == 1 ? 2 : + 0); if (!Stream_EnsureRemainingCapacity(s, payloadLen + 4)) return FALSE; gcc_write_user_data_header(s, SC_NET, payloadLen); - Stream_Write_UINT16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ Stream_Write_UINT16(s, mcs->channelCount); /* channelCount */ @@ -1538,6 +1626,7 @@ BOOL gcc_write_server_network_data(wStream* s, rdpMcs* mcs) if (mcs->channelCount % 2 == 1) Stream_Write_UINT16(s, 0); + return TRUE; } @@ -1586,9 +1675,7 @@ void gcc_write_client_cluster_data(wStream* s, rdpMcs* mcs) { UINT32 flags; rdpSettings* settings = mcs->settings; - gcc_write_user_data_header(s, CS_CLUSTER, 12); - flags = REDIRECTION_SUPPORTED | (REDIRECTION_VERSION4 << 2); if (settings->ConsoleSession || settings->RedirectedSessionId) @@ -1621,7 +1708,8 @@ BOOL gcc_read_client_monitor_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (monitorCount > settings->MonitorDefArraySize) { - WLog_ERR(TAG, "too many announced monitors(%d), clamping to %d", monitorCount, settings->MonitorDefArraySize); + WLog_ERR(TAG, "too many announced monitors(%d), clamping to %d", monitorCount, + settings->MonitorDefArraySize); monitorCount = settings->MonitorDefArraySize; } @@ -1637,7 +1725,6 @@ BOOL gcc_read_client_monitor_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) Stream_Read_UINT32(s, right); /* right */ Stream_Read_UINT32(s, bottom); /* bottom */ Stream_Read_UINT32(s, flags); /* flags */ - settings->MonitorDefArray[index].x = left; settings->MonitorDefArray[index].y = top; settings->MonitorDefArray[index].width = right - left + 1; @@ -1666,7 +1753,6 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) { length = (20 * settings->MonitorCount) + 12; gcc_write_user_data_header(s, CS_MONITOR, length); - Stream_Write_UINT32(s, 0); /* flags */ Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ @@ -1675,9 +1761,9 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) left = settings->MonitorDefArray[i].x; top = settings->MonitorDefArray[i].y; right = settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width - 1; - bottom = settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height - 1; + bottom = settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height - + 1; flags = settings->MonitorDefArray[i].is_primary ? MONITOR_PRIMARY : 0; - Stream_Write_UINT32(s, left); /* left */ Stream_Write_UINT32(s, top); /* top */ Stream_Write_UINT32(s, right); /* right */ @@ -1687,7 +1773,8 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) } } -BOOL gcc_read_client_monitor_extended_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) +BOOL gcc_read_client_monitor_extended_data(wStream* s, rdpMcs* mcs, + UINT16 blockLength) { UINT32 index; UINT32 flags; @@ -1715,11 +1802,16 @@ BOOL gcc_read_client_monitor_extended_data(wStream* s, rdpMcs* mcs, UINT16 block for (index = 0; index < monitorCount; index++) { - Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.physicalWidth); /* physicalWidth */ - Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.physicalHeight); /* physicalHeight */ - Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.orientation); /* orientation */ - Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.desktopScaleFactor); /* desktopScaleFactor */ - Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.deviceScaleFactor); /* deviceScaleFactor */ + Stream_Read_UINT32(s, + settings->MonitorDefArray[index].attributes.physicalWidth); /* physicalWidth */ + Stream_Read_UINT32(s, + settings->MonitorDefArray[index].attributes.physicalHeight); /* physicalHeight */ + Stream_Read_UINT32(s, + settings->MonitorDefArray[index].attributes.orientation); /* orientation */ + Stream_Read_UINT32(s, + settings->MonitorDefArray[index].attributes.desktopScaleFactor); /* desktopScaleFactor */ + Stream_Read_UINT32(s, + settings->MonitorDefArray[index].attributes.deviceScaleFactor); /* deviceScaleFactor */ } return TRUE; @@ -1735,18 +1827,22 @@ void gcc_write_client_monitor_extended_data(wStream* s, rdpMcs* mcs) { length = (20 * settings->MonitorCount) + 16; gcc_write_user_data_header(s, CS_MONITOR_EX, length); - Stream_Write_UINT32(s, 0); /* flags */ Stream_Write_UINT32(s, 20); /* monitorAttributeSize */ Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ for (i = 0; i < settings->MonitorCount; i++) { - Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.physicalWidth); /* physicalWidth */ - Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.physicalHeight); /* physicalHeight */ - Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.orientation); /* orientation */ - Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.desktopScaleFactor); /* desktopScaleFactor */ - Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.deviceScaleFactor); /* deviceScaleFactor */ + Stream_Write_UINT32(s, + settings->MonitorDefArray[i].attributes.physicalWidth); /* physicalWidth */ + Stream_Write_UINT32(s, + settings->MonitorDefArray[i].attributes.physicalHeight); /* physicalHeight */ + Stream_Write_UINT32(s, + settings->MonitorDefArray[i].attributes.orientation); /* orientation */ + Stream_Write_UINT32(s, + settings->MonitorDefArray[i].attributes.desktopScaleFactor); /* desktopScaleFactor */ + Stream_Write_UINT32(s, + settings->MonitorDefArray[i].attributes.deviceScaleFactor); /* deviceScaleFactor */ } } } @@ -1758,7 +1854,8 @@ void gcc_write_client_monitor_extended_data(wStream* s, rdpMcs* mcs) * @param settings rdp settings */ -BOOL gcc_read_client_message_channel_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) +BOOL gcc_read_client_message_channel_data(wStream* s, rdpMcs* mcs, + UINT16 blockLength) { UINT32 flags; @@ -1766,9 +1863,7 @@ BOOL gcc_read_client_message_channel_data(wStream* s, rdpMcs* mcs, UINT16 blockL return FALSE; Stream_Read_UINT32(s, flags); - mcs->messageChannelId = mcs->baseChannelId++; - return TRUE; } @@ -1784,11 +1879,10 @@ void gcc_write_client_message_channel_data(wStream* s, rdpMcs* mcs) rdpSettings* settings = mcs->settings; if (settings->NetworkAutoDetect || - settings->SupportHeartbeatPdu || - settings->SupportMultitransport) + settings->SupportHeartbeatPdu || + settings->SupportMultitransport) { gcc_write_user_data_header(s, CS_MCS_MSGCHANNEL, 8); - Stream_Write_UINT32(s, 0); /* flags */ } } @@ -1801,10 +1895,8 @@ BOOL gcc_read_server_message_channel_data(wStream* s, rdpMcs* mcs) return FALSE; Stream_Read_UINT16(s, MCSChannelId); /* MCSChannelId */ - /* Save the MCS message channel id */ mcs->messageChannelId = MCSChannelId; - return TRUE; } @@ -1817,7 +1909,6 @@ BOOL gcc_write_server_message_channel_data(wStream* s, rdpMcs* mcs) return FALSE; gcc_write_user_data_header(s, SC_MCS_MSGCHANNEL, 6); - Stream_Write_UINT16(s, mcs->messageChannelId); /* mcsChannelId (2 bytes) */ return TRUE; } @@ -1829,7 +1920,8 @@ BOOL gcc_write_server_message_channel_data(wStream* s, rdpMcs* mcs) * @param settings rdp settings */ -BOOL gcc_read_client_multitransport_channel_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) +BOOL gcc_read_client_multitransport_channel_data(wStream* s, rdpMcs* mcs, + UINT16 blockLength) { UINT32 flags; @@ -1837,7 +1929,6 @@ BOOL gcc_read_client_multitransport_channel_data(wStream* s, rdpMcs* mcs, UINT16 return FALSE; Stream_Read_UINT32(s, flags); - return TRUE; } @@ -1855,7 +1946,6 @@ void gcc_write_client_multitransport_channel_data(wStream* s, rdpMcs* mcs) if (settings->MultitransportFlags != 0) { gcc_write_user_data_header(s, CS_MULTITRANSPORT, 8); - Stream_Write_UINT32(s, settings->MultitransportFlags); /* flags */ } } @@ -1868,15 +1958,12 @@ BOOL gcc_read_server_multitransport_channel_data(wStream* s, rdpMcs* mcs) return FALSE; Stream_Read_UINT32(s, flags); /* flags */ - return TRUE; } void gcc_write_server_multitransport_channel_data(wStream* s, rdpMcs* mcs) { UINT32 flags = 0; - gcc_write_user_data_header(s, SC_MULTITRANSPORT, 8); - Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ } diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 2ae619a..09cd381 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -61,10 +61,12 @@ static void* transport_client_thread(void* arg); static void transport_ssl_cb(SSL* ssl, int where, int ret) { - rdpTransport *transport; + rdpTransport* transport; + if ((where | SSL_CB_ALERT) && (ret == 561)) { - transport = (rdpTransport *) SSL_get_app_data(ssl); + transport = (rdpTransport*) SSL_get_app_data(ssl); + if (!freerdp_get_last_error(transport->context)) freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED); } @@ -73,13 +75,16 @@ static void transport_ssl_cb(SSL* ssl, int where, int ret) wStream* transport_send_stream_init(rdpTransport* transport, int size) { wStream* s; + if (!(s = StreamPool_Take(transport->ReceivePool, size))) return NULL; + if (!Stream_EnsureCapacity(s, size)) { Stream_Release(s); return NULL; } + Stream_SetPosition(s, 0); return s; } @@ -88,23 +93,19 @@ BOOL transport_attach(rdpTransport* transport, int sockfd) { BIO* socketBio; BIO* bufferedBio; - socketBio = BIO_new(BIO_s_simple_socket()); if (!socketBio) return FALSE; BIO_set_fd(socketBio, sockfd, BIO_CLOSE); - bufferedBio = BIO_new(BIO_s_buffered_socket()); if (!bufferedBio) return FALSE; bufferedBio = BIO_push(bufferedBio, socketBio); - transport->frontBio = bufferedBio; - return TRUE; } @@ -157,8 +158,8 @@ BOOL transport_connect_tls(rdpTransport* transport) } transport->frontBio = tls->bio; - - BIO_callback_ctrl(tls->bio, BIO_CTRL_SET_CALLBACK, (bio_info_cb*) transport_ssl_cb); + BIO_callback_ctrl(tls->bio, BIO_CTRL_SET_CALLBACK, + (bio_info_cb*) transport_ssl_cb); SSL_set_app_data(tls->ssl, transport); if (!transport->frontBio) @@ -193,7 +194,7 @@ BOOL transport_connect_nla(rdpTransport* transport) if (settings->AuthenticationServiceClass) { rdp->nla->ServicePrincipalName = - nla_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname); + nla_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname); if (!rdp->nla->ServicePrincipalName) return FALSE; @@ -205,22 +206,20 @@ BOOL transport_connect_nla(rdpTransport* transport) freerdp_set_last_error(context, FREERDP_ERROR_AUTHENTICATION_FAILED); transport_set_nla_mode(transport, FALSE); - return FALSE; } rdp_client_transition_to_state(rdp, CONNECTION_STATE_NLA); - return TRUE; } -BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout) +BOOL transport_connect(rdpTransport* transport, const char* hostname, + UINT16 port, int timeout) { int sockfd; BOOL status = FALSE; rdpSettings* settings = transport->settings; rdpContext* context = transport->context; - transport->async = settings->AsyncTransport; if (transport->GatewayEnabled) @@ -294,7 +293,7 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por } if (!(transport->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL))) + (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL))) { WLog_ERR(TAG, "Failed to create transport client thread"); CloseHandle(transport->stopEvent); @@ -326,7 +325,6 @@ BOOL transport_accept_tls(rdpTransport* transport) return FALSE; transport->frontBio = transport->tls->bio; - return TRUE; } @@ -362,7 +360,8 @@ BOOL transport_accept_nla(rdpTransport* transport) transport_set_nla_mode(transport, FALSE); nla_free(transport->nla); transport->nla = NULL; - tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED); + tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL, + TLS_ALERT_DESCRIPTION_ACCESS_DENIED); tls_send_alert(transport->tls); return FALSE; } @@ -376,21 +375,21 @@ BOOL transport_accept_nla(rdpTransport* transport) transport_bio_error_log(tag, biofunc, bio, __FILE__, __FUNCTION__, __LINE__) static void transport_bio_error_log(LPCSTR tag, LPCSTR biofunc, BIO* bio, - LPCSTR file, LPCSTR func, DWORD line) + LPCSTR file, LPCSTR func, DWORD line) { unsigned long sslerr; - char *buf; + char* buf; wLog* log; wLogMessage log_message; int saveerrno; - saveerrno = errno; - log = WLog_Get(tag); + if (!log) return; log_message.Level = WLOG_ERROR; + if (log_message.Level < WLog_GetLogLevel(log)) return; @@ -407,14 +406,16 @@ static void transport_bio_error_log(LPCSTR tag, LPCSTR biofunc, BIO* bio, } buf = malloc(120); + if (buf) { - while((sslerr = ERR_get_error())) + while ((sslerr = ERR_get_error())) { ERR_error_string_n(sslerr, buf, 120); log_message.FormatString = "%s returned an error: %s"; WLog_PrintMessage(log, &log_message, biofunc, buf); } + free(buf); } } @@ -444,6 +445,7 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) WLog_ERR(TAG, "BIO_read: transport->frontBio null"); return -1; } + WLog_ERR_BIO(TAG, "BIO_read", transport->frontBio); transport->layer = TRANSPORT_LAYER_CLOSED; return -1; @@ -487,7 +489,8 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) * @param[in] toRead number of bytes to read * @return < 0 on error; 0 if not enough data is available (non blocking mode); 1 toRead bytes read */ -static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsigned int toRead) +static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, + unsigned int toRead) { int status; status = transport_read_layer(transport, Stream_Pointer(s), toRead); @@ -517,7 +520,6 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) int position; int pduLength; BYTE* header; - position = 0; pduLength = 0; @@ -528,12 +530,14 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) return -1; position = Stream_GetPosition(s); + /* Make sure there is enough space for the longest header within the stream */ if (!Stream_EnsureCapacity(s, 4)) return -1; /* Make sure at least two bytes are read for further processing */ - if (position < 2 && (status = transport_read_layer_bytes(transport, s, 2 - position)) != 1) + if (position < 2 + && (status = transport_read_layer_bytes(transport, s, 2 - position)) != 1) { /* No data available at the moment */ return status; @@ -560,7 +564,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) { /* check for header bytes already was readed in previous calls */ if (position < 3 - && (status = transport_read_layer_bytes(transport, s, 3 - position)) != 1) + && (status = transport_read_layer_bytes(transport, s, 3 - position)) != 1) return status; pduLength = header[2]; @@ -570,7 +574,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) { /* check for header bytes already was readed in previous calls */ if (position < 4 - && (status = transport_read_layer_bytes(transport, s, 4 - position)) != 1) + && (status = transport_read_layer_bytes(transport, s, 4 - position)) != 1) return status; pduLength = (header[2] << 8) | header[3]; @@ -596,7 +600,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) /* TPKT header */ /* check for header bytes already was readed in previous calls */ if (position < 4 - && (status = transport_read_layer_bytes(transport, s, 4 - position)) != 1) + && (status = transport_read_layer_bytes(transport, s, 4 - position)) != 1) return status; pduLength = (header[2] << 8) | header[3]; @@ -615,7 +619,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) { /* check for header bytes already was readed in previous calls */ if (position < 3 - && (status = transport_read_layer_bytes(transport, s, 3 - position)) != 1) + && (status = transport_read_layer_bytes(transport, s, 3 - position)) != 1) return status; pduLength = ((header[1] & 0x7F) << 8) | header[2]; @@ -638,13 +642,16 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) if (!Stream_EnsureCapacity(s, Stream_GetPosition(s) + pduLength)) return -1; - status = transport_read_layer_bytes(transport, s, pduLength - Stream_GetPosition(s)); + + status = transport_read_layer_bytes(transport, s, + pduLength - Stream_GetPosition(s)); if (status != 1) return status; if (Stream_GetPosition(s) >= pduLength) - WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), pduLength, WLOG_PACKET_INBOUND); + WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), pduLength, + WLOG_PACKET_INBOUND); Stream_SealLength(s); Stream_SetPosition(s, 0); @@ -667,14 +674,14 @@ int transport_write(rdpTransport* transport, wStream* s) } EnterCriticalSection(&(transport->WriteLock)); - length = Stream_GetPosition(s); writtenlength = length; Stream_SetPosition(s, 0); if (length > 0) { - WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND); + WLog_Packet(WLog_Get(TAG), WLOG_TRACE, Stream_Buffer(s), length, + WLOG_PACKET_OUTBOUND); } while (length > 0) @@ -733,8 +740,8 @@ int transport_write(rdpTransport* transport, wStream* s) length -= status; Stream_Seek(s, status); } - transport->written += writtenlength; + transport->written += writtenlength; out_cleanup: if (status < 0) @@ -744,12 +751,12 @@ out_cleanup: } Stream_Release(s); - LeaveCriticalSection(&(transport->WriteLock)); return status; } -DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD count) +DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, + DWORD count) { DWORD nCount = 0; DWORD tmp; @@ -760,6 +767,7 @@ DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD { if (BIO_get_event(transport->frontBio, &events[nCount]) != 1) return 0; + nCount++; } } @@ -793,9 +801,7 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) DWORD index; DWORD nCount; HANDLE events[64]; - nCount = transport_get_event_handles(transport, events, 64); - *rcount = nCount; for (index = 0; index < nCount; index++) @@ -833,7 +839,7 @@ int transport_check_fds(rdpTransport* transport) if (!transport) return -1; - while(!freerdp_shall_disconnect(transport->context->instance)) + while (!freerdp_shall_disconnect(transport->context->instance)) { /** * Note: transport_read_pdu tries to read one PDU from @@ -848,19 +854,23 @@ int transport_check_fds(rdpTransport* transport) { if (status < 0) WLog_DBG(TAG, "transport_check_fds: transport_read_pdu() - %i", status); + return status; } received = transport->ReceiveBuffer; + if (!(transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0))) return -1; + /** * status: * -1: error * 0: success * 1: redirection */ - recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); + recv_status = transport->ReceiveCallback(transport, received, + transport->ReceiveExtra); Stream_Release(received); /* session redirection or activation */ @@ -871,7 +881,8 @@ int transport_check_fds(rdpTransport* transport) if (recv_status < 0) { - WLog_ERR(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", recv_status); + WLog_ERR(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", + recv_status); return -1; } } @@ -948,9 +959,7 @@ BOOL transport_disconnect(rdpTransport* transport) } transport->frontBio = NULL; - transport->layer = TRANSPORT_LAYER_TCP; - return status; } @@ -964,13 +973,10 @@ static void* transport_client_thread(void* arg) rdpTransport* transport = (rdpTransport*) arg; rdpContext* context = transport->context; rdpRdp* rdp = context->rdp; - WLog_DBG(TAG, "Asynchronous transport thread started"); - nCount = 0; handles[nCount++] = transport->stopEvent; handles[nCount++] = transport->connectedEvent; - status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); switch (status) @@ -993,13 +999,14 @@ static void* transport_client_thread(void* arg) { nCount = 1; /* transport->stopEvent */ - if (!(nCountTmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount))) + if (!(nCountTmp = freerdp_get_event_handles(context, &handles[nCount], + 64 - nCount))) { WLog_ERR(TAG, "freerdp_get_event_handles failed"); break; } - nCount += nCountTmp; + nCount += nCountTmp; status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); if (transport->layer == TRANSPORT_LAYER_CLOSED) @@ -1029,6 +1036,7 @@ static void* transport_client_thread(void* arg) WLog_ERR(TAG, "WaitForMultipleObjects returned WAIT_TIMEOUT"); else WLog_ERR(TAG, "WaitForMultipleObjects returned 0x%08X", status); + dwExitCode = 1; break; } @@ -1043,7 +1051,6 @@ out: rdpTransport* transport_new(rdpContext* context) { rdpTransport* transport; - transport = (rdpTransport*) calloc(1, sizeof(rdpTransport)); if (!transport) @@ -1051,7 +1058,6 @@ rdpTransport* transport_new(rdpContext* context) transport->context = context; transport->settings = context->settings; - transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE); if (!transport->ReceivePool) @@ -1065,7 +1071,8 @@ rdpTransport* transport_new(rdpContext* context) transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!transport->connectedEvent || transport->connectedEvent == INVALID_HANDLE_VALUE) + if (!transport->connectedEvent + || transport->connectedEvent == INVALID_HANDLE_VALUE) goto out_free_receivebuffer; transport->blocking = TRUE; @@ -1106,6 +1113,5 @@ void transport_free(rdpTransport* transport) CloseHandle(transport->connectedEvent); DeleteCriticalSection(&(transport->ReadLock)); DeleteCriticalSection(&(transport->WriteLock)); - free(transport); } diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 1dfc7c4..381a1ff 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -52,7 +52,8 @@ struct _BIO_RDP_TLS }; typedef struct _BIO_RDP_TLS BIO_RDP_TLS; -long bio_rdp_tls_callback(BIO* bio, int mode, const char* argp, int argi, long argl, long ret) +long bio_rdp_tls_callback(BIO* bio, int mode, const char* argp, int argi, + long argl, long ret) { return 1; } @@ -67,12 +68,9 @@ static int bio_rdp_tls_write(BIO* bio, const char* buf, int size) return 0; BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL); - EnterCriticalSection(&tls->lock); - status = SSL_write(tls->ssl, buf, size); error = SSL_get_error(tls->ssl, status); - LeaveCriticalSection(&tls->lock); if (status <= 0) @@ -124,12 +122,9 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size) return 0; BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL); - EnterCriticalSection(&tls->lock); - status = SSL_read(tls->ssl, buf, size); error = SSL_get_error(tls->ssl, status); - LeaveCriticalSection(&tls->lock); if (status <= 0) @@ -178,12 +173,13 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size) } #ifdef HAVE_VALGRIND_MEMCHECK_H + if (status > 0) { VALGRIND_MAKE_MEM_DEFINED(buf, status); } -#endif +#endif return status; } @@ -197,7 +193,6 @@ static int bio_rdp_tls_puts(BIO* bio, const char* str) size = strlen(str); status = BIO_write(bio, str, size); - return status; } @@ -236,6 +231,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) status = BIO_ctrl(tls->ssl->rbio, cmd, num, ptr); else status = 1; + break; case BIO_C_GET_FD: @@ -260,6 +256,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) SSL_set_connect_state(tls->ssl); else SSL_set_accept_state(tls->ssl); + status = 1; break; @@ -278,8 +275,10 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) case BIO_CTRL_PENDING: status = SSL_pending(tls->ssl); + if (status == 0) status = BIO_pending(tls->ssl->rbio); + break; case BIO_CTRL_FLUSH: @@ -295,6 +294,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) SSL_set_bio(tls->ssl, bio->next_bio, bio->next_bio); CRYPTO_add(&(bio->next_bio->references), 1, CRYPTO_LOCK_BIO); } + status = 1; break; @@ -309,6 +309,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) tls->ssl->wbio = tls->ssl->rbio = NULL; } + status = 1; break; @@ -318,6 +319,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) *((SSL**) ptr) = tls->ssl; status = 1; } + break; case BIO_C_SET_SSL: @@ -344,7 +346,6 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) case BIO_C_DO_STATE_MACHINE: BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL); bio->retry_reason = 0; - status = SSL_do_handshake(tls->ssl); if (status <= 0) @@ -369,6 +370,7 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) break; } } + break; default: @@ -382,21 +384,17 @@ static long bio_rdp_tls_ctrl(BIO* bio, int cmd, long num, void* ptr) static int bio_rdp_tls_new(BIO* bio) { BIO_RDP_TLS* tls; - bio->init = 0; bio->num = 0; bio->flags = BIO_FLAGS_SHOULD_RETRY; bio->next_bio = NULL; - tls = calloc(1, sizeof(BIO_RDP_TLS)); if (!tls) return 0; bio->ptr = (void*) tls; - InitializeCriticalSectionAndSpinCount(&tls->lock, 4000); - return 1; } @@ -425,9 +423,7 @@ static int bio_rdp_tls_free(BIO* bio) } DeleteCriticalSection(&tls->lock); - free(tls); - return 1; } @@ -447,7 +443,7 @@ static long bio_rdp_tls_callback_ctrl(BIO* bio, int cmd, bio_info_cb* fp) switch (cmd) { case BIO_CTRL_SET_CALLBACK: - SSL_set_info_callback(tls->ssl, (void (*)(const SSL *, int, int)) fp); + SSL_set_info_callback(tls->ssl, (void (*)(const SSL*, int, int)) fp); status = 1; break; @@ -484,7 +480,6 @@ BIO* BIO_new_rdp_tls(SSL_CTX* ctx, int client) { BIO* bio; SSL* ssl; - bio = BIO_new(BIO_s_rdp_tls()); if (!bio) @@ -504,7 +499,6 @@ BIO* BIO_new_rdp_tls(SSL_CTX* ctx, int client) SSL_set_accept_state(ssl); BIO_set_ssl(bio, ssl, BIO_CLOSE); - return bio; } @@ -517,7 +511,7 @@ static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer) if (peer) remote_cert = SSL_get_peer_certificate(tls->ssl); else - remote_cert = X509_dup( SSL_get_certificate(tls->ssl) ); + remote_cert = X509_dup(SSL_get_certificate(tls->ssl)); if (!remote_cert) { @@ -526,6 +520,7 @@ static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer) } cert = malloc(sizeof(*cert)); + if (!cert) { X509_free(remote_cert); @@ -533,11 +528,9 @@ static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer) } cert->px509 = remote_cert; - /* Get the peer's chain. If it does not exist, we're setting NULL (clean data either way) */ chain = SSL_get_peer_cert_chain(tls->ssl); cert->px509chain = chain; - return cert; } @@ -558,45 +551,47 @@ SecPkgContext_Bindings* tls_get_channel_bindings(X509* cert) UINT32 ChannelBindingTokenLength; SEC_CHANNEL_BINDINGS* ChannelBindings; SecPkgContext_Bindings* ContextBindings; - ZeroMemory(CertificateHash, sizeof(CertificateHash)); X509_digest(cert, EVP_sha256(), CertificateHash, &CertificateHashLength); - PrefixLength = strlen(TLS_SERVER_END_POINT); ChannelBindingTokenLength = PrefixLength + CertificateHashLength; + ContextBindings = (SecPkgContext_Bindings*) calloc(1, + sizeof(SecPkgContext_Bindings)); - ContextBindings = (SecPkgContext_Bindings*) calloc(1, sizeof(SecPkgContext_Bindings)); if (!ContextBindings) return NULL; - ContextBindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + ChannelBindingTokenLength; - ChannelBindings = (SEC_CHANNEL_BINDINGS*) calloc(1, ContextBindings->BindingsLength); + ContextBindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + + ChannelBindingTokenLength; + ChannelBindings = (SEC_CHANNEL_BINDINGS*) calloc(1, + ContextBindings->BindingsLength); + if (!ChannelBindings) goto out_free; - ContextBindings->Bindings = ChannelBindings; + ContextBindings->Bindings = ChannelBindings; ChannelBindings->cbApplicationDataLength = ChannelBindingTokenLength; ChannelBindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS); - ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; - + ChannelBindingToken = &((BYTE*) + ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; strcpy((char*) ChannelBindingToken, TLS_SERVER_END_POINT); - CopyMemory(&ChannelBindingToken[PrefixLength], CertificateHash, CertificateHashLength); - + CopyMemory(&ChannelBindingToken[PrefixLength], CertificateHash, + CertificateHashLength); return ContextBindings; - out_free: free(ContextBindings); return NULL; } #if OPENSSL_VERSION_NUMBER >= 0x010000000L -static BOOL tls_prepare(rdpTls* tls, BIO* underlying, const SSL_METHOD* method, int options, BOOL clientMode) +static BOOL tls_prepare(rdpTls* tls, BIO* underlying, const SSL_METHOD* method, + int options, BOOL clientMode) #else -static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, int options, BOOL clientMode) +static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, + int options, BOOL clientMode) #endif { rdpSettings* settings = tls->settings; - tls->ctx = SSL_CTX_new(method); if (!tls->ctx) @@ -605,8 +600,8 @@ static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, int op return FALSE; } - SSL_CTX_set_mode(tls->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); - + SSL_CTX_set_mode(tls->ctx, + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_options(tls->ctx, options); SSL_CTX_set_read_ahead(tls->ctx, 1); @@ -629,7 +624,6 @@ static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, int op BIO_push(tls->bio, underlying); tls->underlying = underlying; - return TRUE; } @@ -653,7 +647,6 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) HANDLE event; DWORD status; #endif - status = BIO_do_handshake(tls->bio); if (status == 1) @@ -672,6 +665,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) WLog_ERR(TAG, "unable to retrieve BIO fd"); return -1; } + #else BIO_get_event(tls->bio, &event); @@ -680,8 +674,8 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) WLog_ERR(TAG, "unable to retrieve BIO event"); return -1; } -#endif +#endif #ifdef HAVE_POLL_H pollfds.fd = fd; pollfds.events = POLLIN; @@ -692,29 +686,32 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) status = poll(&pollfds, 1, 10 * 1000); } while ((status < 0) && (errno == EINTR)); + #elif !defined(_WIN32) FD_ZERO(&rset); FD_SET(fd, &rset); tv.tv_sec = 0; tv.tv_usec = 10 * 1000; /* 10ms */ - status = _select(fd + 1, &rset, NULL, NULL, &tv); #else status = WaitForSingleObject(event, 10); #endif - #ifndef _WIN32 + if (status < 0) { WLog_ERR(TAG, "error during select()"); return -1; } + #else + if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT)) { WLog_ERR(TAG, "error during WaitForSingleObject(): 0x%04X", status); return -1; } + #endif } while (TRUE); @@ -738,7 +735,8 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) { - WLog_ERR(TAG, "crypto_cert_get_public_key failed to return the server public key."); + WLog_ERR(TAG, + "crypto_cert_get_public_key failed to return the server public key."); verify_status = -1; goto out; } @@ -760,14 +758,12 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) out: tls_free_certificate(cert); - return verify_status; } int tls_connect(rdpTls* tls, BIO* underlying) { int options = 0; - /** * SSL_OP_NO_COMPRESSION: * @@ -780,7 +776,6 @@ int tls_connect(rdpTls* tls, BIO* underlying) #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif - /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * @@ -788,7 +783,6 @@ int tls_connect(rdpTls* tls, BIO* underlying) * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; - /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * @@ -796,7 +790,6 @@ int tls_connect(rdpTls* tls, BIO* underlying) * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; - /** * disable SSLv2 and SSLv3 */ @@ -809,30 +802,28 @@ int tls_connect(rdpTls* tls, BIO* underlying) #ifndef OPENSSL_NO_TLSEXT SSL_set_tlsext_host_name(tls->ssl, tls->hostname); #endif - return tls_do_handshake(tls, TRUE); } #ifndef OPENSSL_NO_TLSEXT -static void tls_openssl_tlsext_debug_callback(SSL *s, int client_server, - int type, unsigned char *data, int len, void *arg) +static void tls_openssl_tlsext_debug_callback(SSL* s, int client_server, + int type, unsigned char* data, int len, void* arg) { /* see code comment in tls_accept() below */ - - if (type == TLSEXT_TYPE_server_name) { + if (type == TLSEXT_TYPE_server_name) + { WLog_DBG(TAG, "Client uses SNI (extension disabled)"); s->servername_done = 2; } } #endif -BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) +BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; - BIO *bio; - RSA *rsa; - X509 *x509; - + BIO* bio; + RSA* rsa; + X509* x509; /** * SSL_OP_NO_SSLv2: * @@ -840,7 +831,6 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; - /** * SSL_OP_NO_COMPRESSION: * @@ -853,7 +843,6 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif - /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * @@ -861,7 +850,6 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; - /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * @@ -876,15 +864,19 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb+"); + if (!bio) { - WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); + WLog_ERR(TAG, "BIO_new_file failed for private key %s", + settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { - bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); + bio = BIO_new_mem_buf(settings->PrivateKeyContent, + strlen(settings->PrivateKeyContent)); + if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); @@ -913,19 +905,22 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) return FALSE; } - if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb+"); + if (!bio) { - WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); + WLog_ERR(TAG, "BIO_new_file failed for certificate %s", + settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { - bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); + bio = BIO_new_mem_buf(settings->CertificateContent, + strlen(settings->CertificateContent)); + if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); @@ -947,7 +942,6 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) return FALSE; } - if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); @@ -972,10 +966,8 @@ BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) * extension debug callback that sets the SSL context's servername_done * to 1 which effectively disables the parsing of that extension type. */ - SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif - return tls_do_handshake(tls, FALSE) > 0; } @@ -998,7 +990,6 @@ BOOL tls_send_alert(rdpTls* tls) * Manually sending a TLS alert is necessary in certain cases, * like when server-side NLA results in an authentication failure. */ - SSL_set_quiet_shutdown(tls->ssl, 1); if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (tls->ssl->session)) @@ -1015,14 +1006,15 @@ BOOL tls_send_alert(rdpTls* tls) return TRUE; } -BIO *findBufferedBio(BIO *front) +BIO* findBufferedBio(BIO* front) { - BIO *ret = front; + BIO* ret = front; while (ret) { if (BIO_method_type(ret) == BIO_TYPE_BUFFERED) return ret; + ret = ret->next_bio; } @@ -1070,19 +1062,20 @@ int tls_set_alert_code(rdpTls* tls, int level, int description) return 0; } -BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname) +BOOL tls_match_hostname(char* pattern, int pattern_length, char* hostname) { if (strlen(hostname) == pattern_length) { - if (_strnicmp( hostname, pattern, pattern_length) == 0) + if (_strnicmp(hostname, pattern, pattern_length) == 0) return TRUE; } - if ((pattern_length > 2) && (pattern[0] == '*') && (pattern[1] == '.') && (((int) strlen(hostname)) >= pattern_length)) + if ((pattern_length > 2) && (pattern[0] == '*') && (pattern[1] == '.') + && (((int) strlen(hostname)) >= pattern_length)) { char* check_hostname = &hostname[strlen(hostname) - pattern_length + 1]; - if (_strnicmp( check_hostname, &pattern[1], pattern_length - 1) == 0) + if (_strnicmp(check_hostname, &pattern[1], pattern_length - 1) == 0) { return TRUE; } @@ -1091,7 +1084,8 @@ BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname) return FALSE; } -int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int port) +int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, + int port) { int match; int index; @@ -1113,11 +1107,9 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por int offset; BYTE* pemCert; freerdp* instance = (freerdp*) tls->settings->instance; - /** * Don't manage certificates internally, leave it up entirely to the external client implementation */ - bio = BIO_new(BIO_s_mem()); if (!bio) @@ -1137,6 +1129,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por offset = 0; length = 2048; pemCert = (BYTE*) malloc(length + 1); + if (!pemCert) { WLog_ERR(TAG, "error allocating pemCert"); @@ -1156,15 +1149,15 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por while (offset >= length) { int new_len; - BYTE *new_cert; - + BYTE* new_cert; new_len = length * 2; new_cert = (BYTE*) realloc(pemCert, new_len + 1); + if (!new_cert) return -1; + length = new_len; pemCert = new_cert; - status = BIO_read(bio, &pemCert[offset], length); if (status < 0) @@ -1181,11 +1174,11 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por length = offset; pemCert[length] = '\0'; - status = -1; if (instance->VerifyX509Certificate) - status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); + status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, + port, tls->isGatewayTransport); else WLog_ERR(TAG, "No VerifyX509Certificate callback registered!"); @@ -1195,7 +1188,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (status < 0) { WLog_ERR(TAG, "VerifyX509Certificate failed: (length = %d) status: [%d] %s", - length, status, pemCert); + length, status, pemCert); return -1; } @@ -1211,15 +1204,14 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por hostname = tls->settings->CertificateName; /* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */ - certificate_status = x509_verify_certificate(cert, tls->certificate_store->path); - + certificate_status = x509_verify_certificate(cert, + tls->certificate_store->path); /* verify certificate name match */ certificate_data = crypto_get_certificate_data(cert->px509, hostname, port); - - /* extra common name and alternative names */ common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length); - alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count, &alt_names_lengths); + alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count, + &alt_names_lengths); /* compare against common name */ @@ -1255,11 +1247,9 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por char* fingerprint; freerdp* instance = (freerdp*) tls->settings->instance; DWORD accept_certificate = 0; - issuer = crypto_cert_issuer(cert->px509); subject = crypto_cert_subject(cert->px509); fingerprint = crypto_cert_fingerprint(cert->px509); - /* search for matching entry in known_hosts file */ match = certificate_data_match(tls->certificate_store, certificate_data); @@ -1268,9 +1258,9 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por /* no entry was found in known_hosts file, prompt user for manual verification */ if (!hostname_match) tls_print_certificate_name_mismatch_error( - hostname, port, - common_name, alt_names, - alt_names_count); + hostname, port, + common_name, alt_names, + alt_names_count); /* Automatically accept certificate on first use */ if (tls->settings->AutoAcceptCertificate) @@ -1281,21 +1271,24 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por else if (instance->VerifyCertificate) { accept_certificate = instance->VerifyCertificate( - instance, common_name, - subject, issuer, - fingerprint, !hostname_match); + instance, common_name, + subject, issuer, + fingerprint, !hostname_match); } - switch(accept_certificate) + switch (accept_certificate) { case 1: /* user accepted certificate, add entry in known_hosts file */ - verification_status = certificate_data_print(tls->certificate_store, certificate_data); + verification_status = certificate_data_print(tls->certificate_store, + certificate_data); break; + case 2: /* user did accept temporaty, do not add to known hosts file */ verification_status = TRUE; break; + default: /* user did not accept, abort and do not add entry in known_hosts file */ verification_status = FALSE; /* failure! */ @@ -1307,37 +1300,39 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por char* old_subject = NULL; char* old_issuer = NULL; char* old_fingerprint = NULL; - /* entry was found in known_hosts file, but fingerprint does not match. ask user to use it */ tls_print_certificate_error(hostname, port, fingerprint, - tls->certificate_store->file); + tls->certificate_store->file); if (!certificate_get_stored_data(tls->certificate_store, - certificate_data, &old_subject, - &old_issuer, &old_fingerprint)) + certificate_data, &old_subject, + &old_issuer, &old_fingerprint)) WLog_WARN(TAG, "Failed to get certificate entry for %s:hu", - hostname, port); + hostname, port); if (instance->VerifyChangedCertificate) { accept_certificate = instance->VerifyChangedCertificate( - instance, common_name, subject, issuer, - fingerprint, old_subject, old_issuer, - old_fingerprint); + instance, common_name, subject, issuer, + fingerprint, old_subject, old_issuer, + old_fingerprint); } free(old_fingerprint); - switch(accept_certificate) + switch (accept_certificate) { case 1: /* user accepted certificate, add entry in known_hosts file */ - verification_status = certificate_data_replace(tls->certificate_store, certificate_data); + verification_status = certificate_data_replace(tls->certificate_store, + certificate_data); break; + case 2: /* user did accept temporaty, do not add to known hosts file */ verification_status = TRUE; break; + default: /* user did not accept, abort and do not add entry in known_hosts file */ verification_status = FALSE; /* failure! */ @@ -1353,73 +1348,77 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por } certificate_data_free(certificate_data); - free(common_name); if (alt_names) crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths, - alt_names); + alt_names); return (verification_status == 0) ? 0 : 1; } void tls_print_certificate_error(char* hostname, UINT16 port, char* fingerprint, - char *hosts_file) + char* hosts_file) { WLog_ERR(TAG, "The host key for %s:%hu has changed", hostname, port); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - WLog_ERR(TAG, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + WLog_ERR(TAG, + "Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); WLog_ERR(TAG, "It is also possible that a host key has just been changed."); - WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is%s", fingerprint); + WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is%s", + fingerprint); WLog_ERR(TAG, "Please contact your system administrator."); - WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", hosts_file); - WLog_ERR(TAG, "Host key for %s has changed and you have requested strict checking.", hostname); + WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", + hosts_file); + WLog_ERR(TAG, + "Host key for %s has changed and you have requested strict checking.", + hostname); WLog_ERR(TAG, "Host key verification failed."); } void tls_print_certificate_name_mismatch_error(char* hostname, UINT16 port, - char* common_name, char** alt_names, - int alt_names_count) + char* common_name, char** alt_names, + int alt_names_count) { int index; - assert(NULL != hostname); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "@ WARNING: CERTIFICATE NAME MISMATCH! @"); WLog_ERR(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); WLog_ERR(TAG, "The hostname used for this connection (%s:%hu) ", - hostname, port); + hostname, port); WLog_ERR(TAG, "does not match %s given in the certificate:", - alt_names_count < 1 ? "the name" : "any of the names"); + alt_names_count < 1 ? "the name" : "any of the names"); WLog_ERR(TAG, "Common Name (CN):"); WLog_ERR(TAG, "\t%s", common_name ? common_name : "no CN found in certificate"); + if (alt_names_count > 0) { assert(NULL != alt_names); WLog_ERR(TAG, "Alternative names:"); + for (index = 0; index < alt_names_count; index++) { assert(alt_names[index]); WLog_ERR(TAG, "\t %s", alt_names[index]); } } + WLog_ERR(TAG, "A valid certificate for the wrong name should NOT be trusted!"); } rdpTls* tls_new(rdpSettings* settings) { rdpTls* tls; - tls = (rdpTls*) calloc(1, sizeof(rdpTls)); if (!tls) return NULL; winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); - tls->settings = settings; if (!settings->ServerMode) @@ -1432,9 +1431,7 @@ rdpTls* tls_new(rdpSettings* settings) tls->alertLevel = TLS_ALERT_LEVEL_WARNING; tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY; - return tls; - out_free: free(tls); return NULL; -- 2.7.4