From 39223c8c182bd9ed750513c767d065125e754b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 25 Jul 2011 13:42:14 -0400 Subject: [PATCH] libfreerdp-core: parsing of server save session info PDU --- include/freerdp/settings.h | 16 ++++- libfreerdp-core/info.c | 137 +++++++++++++++++++++++++++++++++++-- libfreerdp-core/info.h | 19 +++++ libfreerdp-core/rdp.c | 1 + libfreerdp-core/settings.c | 5 ++ 5 files changed, 171 insertions(+), 7 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index cdd5389e1..fcff17a82 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -86,6 +86,15 @@ typedef struct uint8 securityVerifier[16]; } ARC_CS_PRIVATE_PACKET; +/* ARC_SC_PRIVATE_PACKET */ +typedef struct +{ + uint32 cbLen; + uint32 version; + uint32 logonId; + uint8 arcRandomBits[16]; +} ARC_SC_PRIVATE_PACKET; + struct rdp_chan { char name[8]; /* ui sets */ @@ -159,7 +168,10 @@ struct rdp_settings uint8* ip_address; uint8* client_dir; TIME_ZONE_INFORMATION client_time_zone; - ARC_CS_PRIVATE_PACKET auto_reconnect_cookie; + + boolean auto_reconnection; + ARC_CS_PRIVATE_PACKET client_auto_reconnect_cookie; + ARC_SC_PRIVATE_PACKET server_auto_reconnect_cookie; boolean encryption; boolean tls_security; @@ -183,12 +195,12 @@ struct rdp_settings boolean sound_beeps; boolean fast_path_input; - boolean auto_reconnection; boolean offscreen_bitmap_cache; uint16 offscreen_bitmap_cache_size; uint16 offscreen_bitmap_cache_entries; + boolean bitmap_cache; boolean persistent_bitmap_cache; uint32 vc_chunk_size; diff --git a/libfreerdp-core/info.c b/libfreerdp-core/info.c index 3330e90ef..dcded8115 100644 --- a/libfreerdp-core/info.c +++ b/libfreerdp-core/info.c @@ -19,6 +19,19 @@ #include "info.h" +#define INFO_TYPE_LOGON 0x00000000 +#define INFO_TYPE_LOGON_LONG 0x00000001 +#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002 +#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003 + +uint8 INFO_TYPE_LOGON_STRINGS[][32] = +{ + "Logon Info V1", + "Logon Info V2", + "Logon Plain Notify", + "Logon Extended Info" +}; + /** * Write SYSTEM_TIME structure (TS_SYSTEMTIME).\n * @msdn{cc240478} @@ -137,16 +150,34 @@ void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) } /** - * Write Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n + * Read Server Auto Reconnect Cookie (ARC_SC_PRIVATE_PACKET).\n + * @msdn{cc240540} + * @param s stream + * @param settings settings + */ + +void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) +{ + ARC_SC_PRIVATE_PACKET* autoReconnectCookie; + autoReconnectCookie = &settings->server_auto_reconnect_cookie; + + stream_read_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + stream_read_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */ + stream_read_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ +} + +/** + * Write Client Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n * @msdn{cc240541} * @param s stream * @param settings settings */ -void rdp_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) +void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) { ARC_CS_PRIVATE_PACKET* autoReconnectCookie; - autoReconnectCookie = &settings->auto_reconnect_cookie; + autoReconnectCookie = &settings->client_auto_reconnect_cookie; stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */ @@ -179,7 +210,7 @@ void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings) clientDir = freerdp_uniconv_out(settings->uniconv, settings->client_dir, &length); cbClientDir = length; - cbAutoReconnectLen = settings->auto_reconnect_cookie.cbLen; + cbAutoReconnectLen = settings->client_auto_reconnect_cookie.cbLen; stream_write_uint16(s, clientAddressFamily); /* clientAddressFamily */ @@ -203,7 +234,7 @@ void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings) stream_write_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) - rdp_write_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ + rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ @@ -324,3 +355,99 @@ void rdp_send_client_info(rdpRdp* rdp) rdp_send(rdp, s); } +void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s) +{ + uint32 cbDomain; + uint32 cbUserName; + + stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */ + stream_seek(s, 52); /* domain (52 bytes) */ + stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */ + stream_seek(s, 512); /* userName (512 bytes) */ + stream_seek_uint32(s); /* sessionId (4 bytes) */ +} + +void rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s) +{ + uint32 cbDomain; + uint32 cbUserName; + + stream_seek_uint16(s); /* version (2 bytes) */ + stream_seek_uint32(s); /* size (4 bytes) */ + stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */ + stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */ + stream_seek(s, 558); /* pad */ + stream_seek(s, cbDomain); /* domain */ + stream_seek(s, cbUserName); /* userName */ +} + +void rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s) +{ + stream_seek(s, 576); /* pad */ +} + +void rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s) +{ + uint32 errorNotificationType; + uint32 errorNotificationData; + + stream_read_uint32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ + stream_read_uint32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ +} + +void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s) +{ + uint8* m; + uint32 cbFieldData; + uint32 fieldsPresent; + + stream_read_uint32(s, fieldsPresent); /* fieldsPresent (4 bytes) */ + + /* logonFields */ + + if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE) + { + stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */ + rdp_read_server_auto_reconnect_cookie(s, rdp->settings); + } + + if (fieldsPresent & LOGON_EX_LOGONERRORS) + { + stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */ + rdp_recv_logon_error_info(rdp, s); + } + + stream_seek(s, 570); /* pad */ +} + +void rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s) +{ + uint32 infoType; + + stream_read_uint32(s, infoType); /* infoType (4 bytes) */ + + printf("%s\n", INFO_TYPE_LOGON_STRINGS[infoType]); + + switch (infoType) + { + case INFO_TYPE_LOGON: + rdp_recv_logon_info_v1(rdp, s); + break; + + case INFO_TYPE_LOGON_LONG: + rdp_recv_logon_info_v2(rdp, s); + break; + + case INFO_TYPE_LOGON_PLAIN_NOTIFY: + rdp_recv_logon_plain_notify(rdp, s); + break; + + case INFO_TYPE_LOGON_EXTENDED_INF: + rdp_recv_logon_info_extended(rdp, s); + break; + + default: + break; + } +} + diff --git a/libfreerdp-core/info.h b/libfreerdp-core/info.h index 8680a3c22..ecafa1359 100644 --- a/libfreerdp-core/info.h +++ b/libfreerdp-core/info.h @@ -54,12 +54,31 @@ #define INFO_PACKET_COMPR_TYPE_RDP6 0x00000300 #define INFO_PACKET_COMPR_TYPE_RDP61 0x00000400 +/* Logon Information Types */ +#define INFO_TYPE_LOGON 0x00000000 +#define INFO_TYPE_LOGON_LONG 0x00000001 +#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002 +#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003 + +/* Extended Logon Info */ +#define LOGON_EX_AUTORECONNECTCOOKIE 0x00000001 +#define LOGON_EX_LOGONERRORS 0x00000002 + +/* Logon Error Info */ +#define LOGON_FAILED_BAD_PASSWORD 0x00000000 +#define LOGON_FAILED_UPDATE_PASSWORD 0x00000001 +#define LOGON_FAILED_OTHER 0x00000002 +#define LOGON_WARNING 0x00000003 + void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time); void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings); void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings); +void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); +void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); void rdp_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings); void rdp_write_info_packet(STREAM* s, rdpSettings* settings); void rdp_send_client_info(rdpRdp* rdp); +void rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s); #endif /* __INFO_H */ diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index 864b078c6..094f34322 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -289,6 +289,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: + rdp_recv_save_session_info(rdp, s); break; case DATA_PDU_TYPE_FONT_LIST: diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c index 462cd7987..9e0d30e34 100644 --- a/libfreerdp-core/settings.c +++ b/libfreerdp-core/settings.c @@ -56,6 +56,8 @@ rdpSettings* settings_new() PERF_DISABLE_MENUANIMATIONS | PERF_DISABLE_WALLPAPER; + settings->auto_reconnection = True; + settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; @@ -89,6 +91,9 @@ rdpSettings* settings_new() settings->frame_marker = False; settings->bitmap_cache_v3 = False; + settings->bitmap_cache = True; + settings->persistent_bitmap_cache = False; + settings->offscreen_bitmap_cache = True; settings->offscreen_bitmap_cache_size = 7680; settings->offscreen_bitmap_cache_entries = 100;