BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings) { UINT16 clientAddressFamily; UINT16 cbClientAddress; UINT16 cbClientDir; UINT16 cbAutoReconnectLen; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily */ Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress */ settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL); Stream_Seek(s, cbClientAddress); if (Stream_GetRemainingLength(s) < 2) return FALSE; Stream_Read_UINT16(s, cbClientDir); /* cbClientDir */ if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) free(settings->ClientDir); ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbClientDir / 2, &settings->ClientDir, 0, NULL, NULL); Stream_Seek(s, cbClientDir); if (!rdp_read_client_time_zone(s, settings)) return FALSE; if (Stream_GetRemainingLength(s) < 10) return FALSE; Stream_Seek_UINT32(s); /* clientSessionId, should be set to 0 */ Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */ Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ return TRUE; }
boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings) { uint16 clientAddressFamily; uint16 cbClientAddress; uint16 cbClientDir; uint16 cbAutoReconnectLen; stream_read_uint16(s, clientAddressFamily); /* clientAddressFamily */ stream_read_uint16(s, cbClientAddress); /* cbClientAddress */ settings->ipv6 = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? true : false); if (stream_get_left(s) < cbClientAddress) return false; settings->ip_address = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientAddress); stream_seek(s, cbClientAddress); stream_read_uint16(s, cbClientDir); /* cbClientDir */ if (stream_get_left(s) < cbClientDir) return false; if (settings->client_dir) xfree(settings->client_dir); settings->client_dir = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientDir); stream_seek(s, cbClientDir); if (!rdp_read_client_time_zone(s, settings)) return false; stream_seek_uint32(s); /* clientSessionId, should be set to 0 */ stream_read_uint32(s, settings->performance_flags); /* performanceFlags */ stream_read_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ return true; }
BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) { UINT16 clientAddressFamily; UINT16 cbClientAddress; UINT16 cbClientDir; UINT16 cbAutoReconnectLen; rdpSettings* settings = rdp->settings; WCHAR* wstr; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */ Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */ /* cbClientAddress is the size in bytes of the character data in the clientAddress field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 80 bytes * Note: Although according to [MS-RDPBCGR 2.2.1.11.1.1.1] the null terminator * is mandatory, connections via Microsoft's TS Gateway set cbClientAddress to 0. */ if ((cbClientAddress % 2) || cbClientAddress > 80) { WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %u", cbClientAddress); return FALSE; } settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; if (settings->ClientAddress) { free(settings->ClientAddress); settings->ClientAddress = NULL; } if (cbClientAddress) { wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientAddress / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientAddress must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client address"); return FALSE; } Stream_Seek(s, cbClientAddress); WLog_DBG(TAG, "rdp client address: [%s]", settings->ClientAddress); } if (Stream_GetRemainingLength(s) < 2) return FALSE; Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */ /* cbClientDir is the size in bytes of the character data in the clientDir field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 512 bytes. * Note: Although according to [MS-RDPBCGR 2.2.1.11.1.1.1] the null terminator * is mandatory the Microsoft Android client (starting with version 8.1.31.44) * sets cbClientDir to 0. */ if ((cbClientDir % 2) || cbClientDir > 512) { WLog_ERR(TAG, "protocol error: invalid cbClientDir value: %u", cbClientDir); return FALSE; } if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) { free(settings->ClientDir); settings->ClientDir = NULL; } if (cbClientDir) { wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientDir / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientDir must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client directory"); return FALSE; } Stream_Seek(s, cbClientDir); WLog_DBG(TAG, "rdp client dir: [%s]", settings->ClientDir); } /** * down below all fields are optional but if one field is not present, * then all of the subsequent fields also MUST NOT be present. */ /* optional: clientTimeZone (172 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; if (!rdp_read_client_time_zone(s, settings)) return FALSE; /* optional: clientSessionId (4 bytes), should be set to 0 */ if (Stream_GetRemainingLength(s) == 0) return TRUE; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Seek_UINT32(s); /* optional: performanceFlags (4 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT32(s, settings->PerformanceFlags); freerdp_performance_flags_split(settings); /* optional: cbAutoReconnectLen (2 bytes) */ if (Stream_GetRemainingLength(s) == 0) return TRUE; if (Stream_GetRemainingLength(s) < 2) return FALSE; Stream_Read_UINT16(s, cbAutoReconnectLen); /* optional: autoReconnectCookie (28 bytes) */ /* must be present if cbAutoReconnectLen is > 0 */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(rdp, s); /* TODO */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ /* cbDynamicDSTTimeZoneKeyName (2 bytes) */ /* dynamicDSTTimeZoneKeyName (variable) */ /* dynamicDaylightTimeDisabled (2 bytes) */ return TRUE; }
BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s) { UINT16 clientAddressFamily; UINT16 cbClientAddress; UINT16 cbClientDir; UINT16 cbAutoReconnectLen; rdpSettings* settings = rdp->settings; WCHAR* wstr; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT16(s, clientAddressFamily); /* clientAddressFamily (2 bytes) */ Stream_Read_UINT16(s, cbClientAddress); /* cbClientAddress (2 bytes) */ /* cbClientAddress is the size in bytes of the character data in the clientAddress field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 80 bytes */ if ((cbClientAddress % 2) || cbClientAddress < 2 || cbClientAddress > 80) { WLog_ERR(TAG, "protocol error: invalid cbClientAddress value: %u", cbClientAddress); return FALSE; } settings->IPv6Enabled = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? TRUE : FALSE); if (Stream_GetRemainingLength(s) < cbClientAddress) return FALSE; if (settings->ClientAddress) { free(settings->ClientAddress); settings->ClientAddress = NULL; } wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientAddress / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientAddress must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &settings->ClientAddress, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client address"); return FALSE; } Stream_Seek(s, cbClientAddress); if (Stream_GetRemainingLength(s) < 2) return FALSE; Stream_Read_UINT16(s, cbClientDir); /* cbClientDir (2 bytes) */ /* cbClientDir is the size in bytes of the character data in the clientDir field. * This size includes the length of the mandatory null terminator. * The maximum allowed value is 512 bytes */ if ((cbClientDir % 2) || cbClientDir < 2 || cbClientDir > 512) { WLog_ERR(TAG, "protocol error: invalid cbClientDir value: %u", cbClientDir); return FALSE; } if (Stream_GetRemainingLength(s) < cbClientDir) return FALSE; if (settings->ClientDir) { free(settings->ClientDir); settings->ClientDir = NULL; } wstr = (WCHAR*) Stream_Pointer(s); if (wstr[cbClientDir / 2 - 1]) { WLog_ERR(TAG, "protocol error: clientDir must be null terminated"); return FALSE; } if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &settings->ClientDir, 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert client directory"); return FALSE; } Stream_Seek(s, cbClientDir); if (!rdp_read_client_time_zone(s, settings)) return FALSE; if (Stream_GetRemainingLength(s) < 10) return FALSE; Stream_Seek_UINT32(s); /* clientSessionId (4 bytes), should be set to 0 */ Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */ freerdp_performance_flags_split(settings); Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen (2 bytes) */ if (cbAutoReconnectLen > 0) return rdp_read_client_auto_reconnect_cookie(rdp, s); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ return TRUE; }