Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / info.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * RDP Client Info
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include "info.h"
21
22 #define INFO_TYPE_LOGON                 0x00000000
23 #define INFO_TYPE_LOGON_LONG            0x00000001
24 #define INFO_TYPE_LOGON_PLAIN_NOTIFY    0x00000002
25 #define INFO_TYPE_LOGON_EXTENDED_INF    0x00000003
26
27 /*
28 static const char* const INFO_TYPE_LOGON_STRINGS[] =
29 {
30         "Logon Info V1",
31         "Logon Info V2",
32         "Logon Plain Notify",
33         "Logon Extended Info"
34 };
35 */
36
37 /**
38  * Read SYSTEM_TIME structure (TS_SYSTEMTIME).\n
39  * @msdn{cc240478}
40  * @param s stream
41  * @param system_time system time structure
42  */
43
44 void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time)
45 {
46         stream_read_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
47         stream_read_uint16(s, system_time->wMonth); /* wMonth */
48         stream_read_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
49         stream_read_uint16(s, system_time->wDay); /* wDay */
50         stream_read_uint16(s, system_time->wHour); /* wHour */
51         stream_read_uint16(s, system_time->wMinute); /* wMinute */
52         stream_read_uint16(s, system_time->wSecond); /* wSecond */
53         stream_read_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
54 }
55
56 /**
57  * Write SYSTEM_TIME structure (TS_SYSTEMTIME).\n
58  * @msdn{cc240478}
59  * @param s stream
60  * @param system_time system time structure
61  */
62
63 void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time)
64 {
65         stream_write_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
66         stream_write_uint16(s, system_time->wMonth); /* wMonth */
67         stream_write_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
68         stream_write_uint16(s, system_time->wDay); /* wDay */
69         stream_write_uint16(s, system_time->wHour); /* wHour */
70         stream_write_uint16(s, system_time->wMinute); /* wMinute */
71         stream_write_uint16(s, system_time->wSecond); /* wSecond */
72         stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
73 }
74
75 /**
76  * Get client time zone information.\n
77  * @param s stream
78  * @param settings settings
79  */
80
81 void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings)
82 {
83         time_t t;
84         struct tm* local_time;
85         TIME_ZONE_INFO* clientTimeZone;
86
87         time(&t);
88         local_time = localtime(&t);
89         clientTimeZone = settings->client_time_zone;
90
91 #if defined(sun)
92         if(local_time->tm_isdst > 0)
93                 clientTimeZone->bias = (uint32) (altzone / 3600);
94         else
95                 clientTimeZone->bias = (uint32) (timezone / 3600);
96 #elif defined(HAVE_TM_GMTOFF)
97         if(local_time->tm_gmtoff >= 0)
98                 clientTimeZone->bias = (uint32) (local_time->tm_gmtoff / 60);
99         else
100                 clientTimeZone->bias = (uint32) ((-1 * local_time->tm_gmtoff) / 60 + 720);
101 #else
102         clientTimeZone->bias = 0;
103 #endif
104
105         if(local_time->tm_isdst > 0)
106         {
107                 clientTimeZone->standardBias = clientTimeZone->bias - 60;
108                 clientTimeZone->daylightBias = clientTimeZone->bias;
109         }
110         else
111         {
112                 clientTimeZone->standardBias = clientTimeZone->bias;
113                 clientTimeZone->daylightBias = clientTimeZone->bias + 60;
114         }
115
116         strftime(clientTimeZone->standardName, 32, "%Z, Standard Time", local_time);
117         clientTimeZone->standardName[31] = 0;
118         strftime(clientTimeZone->daylightName, 32, "%Z, Summer Time", local_time);
119         clientTimeZone->daylightName[31] = 0;
120 }
121
122 /**
123  * Read client time zone information (TS_TIME_ZONE_INFORMATION).\n
124  * @msdn{cc240477}
125  * @param s stream
126  * @param settings settings
127  */
128
129 boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings)
130 {
131         char* str;
132         TIME_ZONE_INFO* clientTimeZone;
133
134         if (stream_get_left(s) < 172)
135                 return false;
136
137         clientTimeZone = settings->client_time_zone;
138
139         stream_read_uint32(s, clientTimeZone->bias); /* Bias */
140
141         /* standardName (64 bytes) */
142         str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
143         stream_seek(s, 64);
144         strncpy(clientTimeZone->standardName, str, sizeof(clientTimeZone->standardName));
145         xfree(str);
146
147         rdp_read_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
148         stream_read_uint32(s, clientTimeZone->standardBias); /* StandardBias */
149
150         /* daylightName (64 bytes) */
151         str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64);
152         stream_seek(s, 64);
153         strncpy(clientTimeZone->daylightName, str, sizeof(clientTimeZone->daylightName));
154         xfree(str);
155
156         rdp_read_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
157         stream_read_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
158
159         return true;
160 }
161
162 /**
163  * Write client time zone information (TS_TIME_ZONE_INFORMATION).\n
164  * @msdn{cc240477}
165  * @param s stream
166  * @param settings settings
167  */
168
169 void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings)
170 {
171         size_t length;
172         uint8* standardName;
173         uint8* daylightName;
174         size_t standardNameLength;
175         size_t daylightNameLength;
176         TIME_ZONE_INFO* clientTimeZone;
177
178         rdp_get_client_time_zone(s, settings);
179         clientTimeZone = settings->client_time_zone;
180
181         standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length);
182         standardNameLength = length;
183
184         daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length);
185         daylightNameLength = length;
186
187         if (standardNameLength > 62)
188                 standardNameLength = 62;
189
190         if (daylightNameLength > 62)
191                 daylightNameLength = 62;
192
193         stream_write_uint32(s, clientTimeZone->bias); /* Bias */
194
195         /* standardName (64 bytes) */
196         stream_write(s, standardName, standardNameLength);
197         stream_write_zero(s, 64 - standardNameLength);
198
199         rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
200         stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */
201
202         /* daylightName (64 bytes) */
203         stream_write(s, daylightName, daylightNameLength);
204         stream_write_zero(s, 64 - daylightNameLength);
205
206         rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
207         stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
208
209         xfree(standardName);
210         xfree(daylightName);
211 }
212
213 /**
214  * Read Server Auto Reconnect Cookie (ARC_SC_PRIVATE_PACKET).\n
215  * @msdn{cc240540}
216  * @param s stream
217  * @param settings settings
218  */
219
220 void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
221 {
222         ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
223         autoReconnectCookie = settings->server_auto_reconnect_cookie;
224
225         stream_read_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
226         stream_read_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
227         stream_read_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
228         stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */
229 }
230
231 /**
232  * Read Client Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n
233  * @msdn{cc240541}
234  * @param s stream
235  * @param settings settings
236  */
237
238 boolean rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
239 {
240         ARC_CS_PRIVATE_PACKET* autoReconnectCookie;
241         autoReconnectCookie = settings->client_auto_reconnect_cookie;
242
243         if (stream_get_left(s) < 28)
244                 return false;
245
246         stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
247         stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
248         stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
249         stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
250
251         return true;
252 }
253
254 /**
255  * Write Client Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n
256  * @msdn{cc240541}
257  * @param s stream
258  * @param settings settings
259  */
260
261 void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
262 {
263         ARC_CS_PRIVATE_PACKET* autoReconnectCookie;
264         autoReconnectCookie = settings->client_auto_reconnect_cookie;
265
266         stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
267         stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
268         stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
269         stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
270 }
271
272 /**
273  * Read Extended Info Packet (TS_EXTENDED_INFO_PACKET).\n
274  * @msdn{cc240476}
275  * @param s stream
276  * @param settings settings
277  */
278
279 boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings)
280 {
281         uint16 clientAddressFamily;
282         uint16 cbClientAddress;
283         uint16 cbClientDir;
284         uint16 cbAutoReconnectLen;
285
286         stream_read_uint16(s, clientAddressFamily); /* clientAddressFamily */
287         stream_read_uint16(s, cbClientAddress); /* cbClientAddress */
288
289         settings->ipv6 = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? true : false);
290         if (stream_get_left(s) < cbClientAddress)
291                 return false;
292         settings->ip_address = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientAddress);
293         stream_seek(s, cbClientAddress);
294
295         stream_read_uint16(s, cbClientDir); /* cbClientDir */
296         if (stream_get_left(s) < cbClientDir)
297                 return false;
298         if (settings->client_dir)
299                 xfree(settings->client_dir);
300         settings->client_dir = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientDir);
301         stream_seek(s, cbClientDir);
302
303         if (!rdp_read_client_time_zone(s, settings))
304                 return false;
305
306         stream_seek_uint32(s); /* clientSessionId, should be set to 0 */
307         stream_read_uint32(s, settings->performance_flags); /* performanceFlags */
308
309         stream_read_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */
310
311         if (cbAutoReconnectLen > 0)
312                 return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
313
314         /* reserved1 (2 bytes) */
315         /* reserved2 (2 bytes) */
316
317         return true;
318 }
319
320 /**
321  * Write Extended Info Packet (TS_EXTENDED_INFO_PACKET).\n
322  * @msdn{cc240476}
323  * @param s stream
324  * @param settings settings
325  */
326
327 void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings)
328 {
329         size_t length;
330         uint16 clientAddressFamily;
331         uint8* clientAddress;
332         uint16 cbClientAddress;
333         uint8* clientDir;
334         uint16 cbClientDir;
335         uint16 cbAutoReconnectLen;
336
337         clientAddressFamily = settings->ipv6 ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET;
338
339         clientAddress = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->ip_address, &length);
340         cbClientAddress = length;
341
342         clientDir = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->client_dir, &length);
343         cbClientDir = length;
344
345         cbAutoReconnectLen = settings->client_auto_reconnect_cookie->cbLen;
346
347         stream_write_uint16(s, clientAddressFamily); /* clientAddressFamily */
348
349         stream_write_uint16(s, cbClientAddress + 2); /* cbClientAddress */
350
351         if (cbClientAddress > 0)
352                 stream_write(s, clientAddress, cbClientAddress); /* clientAddress */
353         stream_write_uint16(s, 0);
354
355         stream_write_uint16(s, cbClientDir + 2); /* cbClientDir */
356
357         if (cbClientDir > 0)
358                 stream_write(s, clientDir, cbClientDir); /* clientDir */
359         stream_write_uint16(s, 0);
360
361         rdp_write_client_time_zone(s, settings); /* clientTimeZone */
362
363         stream_write_uint32(s, 0); /* clientSessionId, should be set to 0 */
364         stream_write_uint32(s, settings->performance_flags); /* performanceFlags */
365
366         stream_write_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */
367
368         if (cbAutoReconnectLen > 0)
369                 rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
370
371         /* reserved1 (2 bytes) */
372         /* reserved2 (2 bytes) */
373
374         xfree(clientAddress);
375         xfree(clientDir);
376 }
377
378 /**
379  * Read Info Packet (TS_INFO_PACKET).\n
380  * @msdn{cc240475}
381  * @param s stream
382  * @param settings settings
383  */
384
385 boolean rdp_read_info_packet(STREAM* s, rdpSettings* settings)
386 {
387         uint32 flags;
388         uint16 cbDomain;
389         uint16 cbUserName;
390         uint16 cbPassword;
391         uint16 cbAlternateShell;
392         uint16 cbWorkingDir;
393
394         stream_seek_uint32(s); /* CodePage */
395         stream_read_uint32(s, flags); /* flags */
396
397         settings->autologon = ((flags & INFO_AUTOLOGON) ? true : false);
398         settings->remote_app = ((flags & INFO_RAIL) ? true : false);
399         settings->console_audio = ((flags & INFO_REMOTECONSOLEAUDIO) ? true : false);
400         settings->compression = ((flags & INFO_COMPRESSION) ? true : false);
401
402         stream_read_uint16(s, cbDomain); /* cbDomain */
403         stream_read_uint16(s, cbUserName); /* cbUserName */
404         stream_read_uint16(s, cbPassword); /* cbPassword */
405         stream_read_uint16(s, cbAlternateShell); /* cbAlternateShell */
406         stream_read_uint16(s, cbWorkingDir); /* cbWorkingDir */
407
408         if (stream_get_left(s) < cbDomain + 2)
409                 return false;
410         if (cbDomain > 0)
411         {
412                 settings->domain = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbDomain);
413                 stream_seek(s, cbDomain);
414         }
415         stream_seek(s, 2);
416
417         if (stream_get_left(s) < cbUserName + 2)
418                 return false;
419         if (cbUserName > 0)
420         {
421                 settings->username = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbUserName);
422                 stream_seek(s, cbUserName);
423         }
424         stream_seek(s, 2);
425
426         if (stream_get_left(s) < cbPassword + 2)
427                 return false;
428         if (cbPassword > 0)
429         {
430                 settings->password = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbPassword);
431                 stream_seek(s, cbPassword);
432         }
433         stream_seek(s, 2);
434
435         if (stream_get_left(s) < cbAlternateShell + 2)
436                 return false;
437         if (cbAlternateShell > 0)
438         {
439                 settings->shell = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbAlternateShell);
440                 stream_seek(s, cbAlternateShell);
441         }
442         stream_seek(s, 2);
443
444         if (stream_get_left(s) < cbWorkingDir + 2)
445                 return false;
446         if (cbWorkingDir > 0)
447         {
448                 settings->directory = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbWorkingDir);
449                 stream_seek(s, cbWorkingDir);
450         }
451         stream_seek(s, 2);
452
453         if (settings->rdp_version >= 5)
454                 return rdp_read_extended_info_packet(s, settings); /* extraInfo */
455
456         return true;
457 }
458
459 /**
460  * Write Info Packet (TS_INFO_PACKET).\n
461  * @msdn{cc240475}
462  * @param s stream
463  * @param settings settings
464  */
465
466 void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
467 {
468         size_t length;
469         uint32 flags;
470         uint8* domain;
471         uint16 cbDomain;
472         uint8* userName;
473         uint16 cbUserName;
474         uint8* password;
475         uint16 cbPassword;
476         size_t passwordLength;
477         uint8* alternateShell;
478         uint16 cbAlternateShell;
479         uint8* workingDir;
480         uint16 cbWorkingDir;
481         boolean usedPasswordCookie = false;
482
483         flags = INFO_MOUSE |
484                 INFO_UNICODE |
485                 INFO_LOGONERRORS |
486                 INFO_LOGONNOTIFY |
487                 INFO_MAXIMIZESHELL |
488                 INFO_ENABLEWINDOWSKEY |
489                 INFO_DISABLECTRLALTDEL |
490                 RNS_INFO_AUDIOCAPTURE;
491
492         if (settings->autologon)
493                 flags |= INFO_AUTOLOGON;
494
495         if (settings->remote_app)
496                 flags |= INFO_RAIL;
497
498         if (settings->console_audio)
499                 flags |= INFO_REMOTECONSOLEAUDIO;
500
501         if (settings->compression)
502                 flags |= INFO_COMPRESSION | INFO_PACKET_COMPR_TYPE_64K;
503
504         domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length);
505         cbDomain = length;
506
507         userName = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->username, &length);
508         cbUserName = length;
509
510         if (settings->password_cookie && settings->password_cookie->length > 0)
511         {
512                 usedPasswordCookie = true;
513                 password = (uint8*)settings->password_cookie->data;
514                 passwordLength = settings->password_cookie->length;
515                 cbPassword = passwordLength - 2;
516         }
517         else
518         {
519                 password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &passwordLength);
520                 cbPassword = passwordLength;
521         }
522
523         alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length);
524         cbAlternateShell = length;
525
526         workingDir = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->directory, &length);
527         cbWorkingDir = length;
528
529         stream_write_uint32(s, 0); /* CodePage */
530         stream_write_uint32(s, flags); /* flags */
531
532         stream_write_uint16(s, cbDomain); /* cbDomain */
533         stream_write_uint16(s, cbUserName); /* cbUserName */
534         stream_write_uint16(s, cbPassword); /* cbPassword */
535         stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */
536         stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */
537
538         if (cbDomain > 0)
539                 stream_write(s, domain, cbDomain);
540         stream_write_uint16(s, 0);
541
542         if (cbUserName > 0)
543                 stream_write(s, userName, cbUserName);
544         stream_write_uint16(s, 0);
545
546         if (cbPassword > 0)
547                 stream_write(s, password, passwordLength);
548         stream_write_uint16(s, 0);
549
550         if (cbAlternateShell > 0)
551                 stream_write(s, alternateShell, cbAlternateShell);
552         stream_write_uint16(s, 0);
553
554         if (cbWorkingDir > 0)
555                 stream_write(s, workingDir, cbWorkingDir);
556         stream_write_uint16(s, 0);
557
558         xfree(domain);
559         xfree(userName);
560         xfree(alternateShell);
561         xfree(workingDir);
562
563         if (!usedPasswordCookie)
564                 xfree(password);
565
566         if (settings->rdp_version >= 5)
567                 rdp_write_extended_info_packet(s, settings); /* extraInfo */
568 }
569
570 /**
571  * Read Client Info PDU (CLIENT_INFO_PDU).\n
572  * @msdn{cc240474}
573  * @param rdp RDP module
574  * @param s stream
575  */
576
577 boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s)
578 {
579         uint16 length;
580         uint16 channelId;
581         uint16 securityFlags;
582
583         if (!rdp_read_header(rdp, s, &length, &channelId))
584                 return false;
585
586         rdp_read_security_header(s, &securityFlags);
587         if ((securityFlags & SEC_INFO_PKT) == 0)
588                 return false;
589
590         if (rdp->settings->encryption)
591         {
592                 if (securityFlags & SEC_REDIRECTION_PKT)
593                 {
594                         printf("Error: SEC_REDIRECTION_PKT unsupported\n");
595                         return false;
596                 }
597                 if (securityFlags & SEC_ENCRYPT)
598                 {
599                         if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
600                         {
601                                 printf("rdp_decrypt failed\n");
602                                 return false;
603                         }
604                 }
605         }
606
607         return rdp_read_info_packet(s, rdp->settings);
608 }
609
610 /**
611  * Send Client Info PDU (CLIENT_INFO_PDU).\n
612  * @msdn{cc240474}
613  * @param rdp RDP module
614  */
615
616 boolean rdp_send_client_info(rdpRdp* rdp)
617 {
618         STREAM* s;
619
620         //rdp->settings->crypt_flags |= SEC_INFO_PKT;
621         rdp->sec_flags |= SEC_INFO_PKT;
622         s = rdp_send_stream_init(rdp);
623         rdp_write_info_packet(s, rdp->settings);
624         return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
625 }
626
627 void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s)
628 {
629         uint32 cbDomain;
630         uint32 cbUserName;
631
632         stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */
633         stream_seek(s, 52); /* domain (52 bytes) */
634         stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */
635         stream_seek(s, 512); /* userName (512 bytes) */
636         stream_seek_uint32(s); /* sessionId (4 bytes) */
637 }
638
639 void rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s)
640 {
641         uint32 cbDomain;
642         uint32 cbUserName;
643
644         stream_seek_uint16(s); /* version (2 bytes) */
645         stream_seek_uint32(s); /* size (4 bytes) */
646         stream_seek_uint32(s); /* sessionId (4 bytes) */
647         stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */
648         stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */
649         stream_seek(s, 558); /* pad */
650         stream_seek(s, cbDomain); /* domain */
651         stream_seek(s, cbUserName); /* userName */
652 }
653
654 void rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s)
655 {
656         stream_seek(s, 576); /* pad */
657 }
658
659 void rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s)
660 {
661         uint32 errorNotificationType;
662         uint32 errorNotificationData;
663
664         stream_read_uint32(s, errorNotificationType); /* errorNotificationType (4 bytes) */
665         stream_read_uint32(s, errorNotificationData); /* errorNotificationData (4 bytes) */
666 }
667
668 void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
669 {
670         uint32 cbFieldData;
671         uint32 fieldsPresent;
672         uint16 Length;
673
674         stream_read_uint16(s, Length); /* The total size in bytes of this structure */
675         stream_read_uint32(s, fieldsPresent); /* fieldsPresent (4 bytes) */
676
677         /* logonFields */
678
679         if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE)
680         {
681                 stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */
682                 rdp_read_server_auto_reconnect_cookie(s, rdp->settings);
683         }
684
685         if (fieldsPresent & LOGON_EX_LOGONERRORS)
686         {
687                 stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */
688                 rdp_recv_logon_error_info(rdp, s);
689         }
690
691         stream_seek(s, 570); /* pad */
692 }
693
694 boolean rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
695 {
696         uint32 infoType;
697
698         stream_read_uint32(s, infoType); /* infoType (4 bytes) */
699
700         //printf("%s\n", INFO_TYPE_LOGON_STRINGS[infoType]);
701
702         switch (infoType)
703         {
704                 case INFO_TYPE_LOGON:
705                         rdp_recv_logon_info_v1(rdp, s);
706                         break;
707
708                 case INFO_TYPE_LOGON_LONG:
709                         rdp_recv_logon_info_v2(rdp, s);
710                         break;
711
712                 case INFO_TYPE_LOGON_PLAIN_NOTIFY:
713                         rdp_recv_logon_plain_notify(rdp, s);
714                         break;
715
716                 case INFO_TYPE_LOGON_EXTENDED_INF:
717                         rdp_recv_logon_info_extended(rdp, s);
718                         break;
719
720                 default:
721                         break;
722         }
723
724         return true;
725 }
726