protocol violation: rdp_read_extended_info_packet
authorNorbert Federa <norbert.federa@thincast.com>
Mon, 27 Jun 2016 08:56:40 +0000 (10:56 +0200)
committerNorbert Federa <norbert.federa@thincast.com>
Mon, 27 Jun 2016 08:56:40 +0000 (10:56 +0200)
The clientTimeZone and all subsequent fields in the Extended Info Packet
(MS RDPBCGR 2.2.1.11.1.1.1) are optional but were not handled as such.

libfreerdp/core/info.c

index 4f6c703..6e1433f 100644 (file)
@@ -293,23 +293,51 @@ BOOL rdp_read_extended_info_packet(rdpRdp* rdp, wStream* s)
                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;
 
-       if (Stream_GetRemainingLength(s) < 10)
+       /* 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);
 
-       Stream_Seek_UINT32(s); /* clientSessionId (4 bytes), should be set to 0 */
-       Stream_Read_UINT32(s, settings->PerformanceFlags); /* performanceFlags (4 bytes) */
+       /* 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);
 
-       Stream_Read_UINT16(s, cbAutoReconnectLen); /* cbAutoReconnectLen (2 bytes) */
+       /* 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); /* autoReconnectCookie */
+               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;
 }