20 #include <freerdp/config.h>
24 #include <freerdp/log.h>
25 #include <freerdp/error.h>
26 #include <freerdp/settings.h>
28 #include <winpr/assert.h>
29 #include <winpr/stream.h>
30 #include <winpr/wlog.h>
33 #include "transport.h"
36 #define RDSTLS_VERSION_1 0x01
38 #define RDSTLS_TYPE_CAPABILITIES 0x01
39 #define RDSTLS_TYPE_AUTHREQ 0x02
40 #define RDSTLS_TYPE_AUTHRSP 0x04
42 #define RDSTLS_DATA_CAPABILITIES 0x01
43 #define RDSTLS_DATA_PASSWORD_CREDS 0x01
44 #define RDSTLS_DATA_AUTORECONNECT_COOKIE 0x02
45 #define RDSTLS_DATA_RESULT_CODE 0x01
50 RDSTLS_STATE_CAPABILITIES,
51 RDSTLS_STATE_AUTH_REQ,
52 RDSTLS_STATE_AUTH_RSP,
59 RDSTLS_RESULT_SUCCESS = 0x00000000,
60 RDSTLS_RESULT_ACCESS_DENIED = 0x00000005,
61 RDSTLS_RESULT_LOGON_FAILURE = 0x0000052e,
62 RDSTLS_RESULT_INVALID_LOGON_HOURS = 0x00000530,
63 RDSTLS_RESULT_PASSWORD_EXPIRED = 0x00000532,
64 RDSTLS_RESULT_ACCOUNT_DISABLED = 0x00000533,
65 RDSTLS_RESULT_PASSWORD_MUST_CHANGE = 0x00000773,
66 RDSTLS_RESULT_ACCOUNT_LOCKED_OUT = 0x00000775
74 rdpTransport* transport;
76 RDSTLS_RESULT_CODE resultCode;
80 static const char* rdstls_result_code_str(UINT32 resultCode)
84 case RDSTLS_RESULT_SUCCESS:
85 return "RDSTLS_RESULT_SUCCESS";
86 case RDSTLS_RESULT_ACCESS_DENIED:
87 return "RDSTLS_RESULT_ACCESS_DENIED";
88 case RDSTLS_RESULT_LOGON_FAILURE:
89 return "RDSTLS_RESULT_LOGON_FAILURE";
90 case RDSTLS_RESULT_INVALID_LOGON_HOURS:
91 return "RDSTLS_RESULT_INVALID_LOGON_HOURS";
92 case RDSTLS_RESULT_PASSWORD_EXPIRED:
93 return "RDSTLS_RESULT_PASSWORD_EXPIRED";
94 case RDSTLS_RESULT_ACCOUNT_DISABLED:
95 return "RDSTLS_RESULT_ACCOUNT_DISABLED";
96 case RDSTLS_RESULT_PASSWORD_MUST_CHANGE:
97 return "RDSTLS_RESULT_PASSWORD_MUST_CHANGE";
98 case RDSTLS_RESULT_ACCOUNT_LOCKED_OUT:
99 return "RDSTLS_RESULT_ACCOUNT_LOCKED_OUT";
101 return "RDSTLS_RESULT_UNKNOWN";
112 rdpRdstls* rdstls_new(rdpContext* context, rdpTransport* transport)
114 WINPR_ASSERT(context);
115 WINPR_ASSERT(transport);
117 rdpSettings* settings = context->settings;
118 WINPR_ASSERT(settings);
120 rdpRdstls* rdstls = (rdpRdstls*)calloc(1,
sizeof(rdpRdstls));
124 rdstls->log = WLog_Get(FREERDP_TAG(
"core.rdstls"));
125 rdstls->context = context;
126 rdstls->transport = transport;
127 rdstls->server = settings->ServerMode;
129 rdstls->state = RDSTLS_STATE_INITIAL;
139 void rdstls_free(rdpRdstls* rdstls)
144 static const char* rdstls_get_state_str(RDSTLS_STATE state)
148 case RDSTLS_STATE_INITIAL:
149 return "RDSTLS_STATE_INITIAL";
150 case RDSTLS_STATE_CAPABILITIES:
151 return "RDSTLS_STATE_CAPABILITIES";
152 case RDSTLS_STATE_AUTH_REQ:
153 return "RDSTLS_STATE_AUTH_REQ";
154 case RDSTLS_STATE_AUTH_RSP:
155 return "RDSTLS_STATE_AUTH_RSP";
156 case RDSTLS_STATE_FINAL:
157 return "RDSTLS_STATE_FINAL";
163 static RDSTLS_STATE rdstls_get_state(rdpRdstls* rdstls)
165 WINPR_ASSERT(rdstls);
166 return rdstls->state;
169 static BOOL check_transition(wLog* log, RDSTLS_STATE current, RDSTLS_STATE expected,
170 RDSTLS_STATE requested)
172 if (requested != expected)
174 WLog_Print(log, WLOG_ERROR,
175 "Unexpected rdstls state transition from %s [%d] to %s [%d], expected %s [%d]",
176 rdstls_get_state_str(current), current, rdstls_get_state_str(requested),
177 requested, rdstls_get_state_str(expected), expected);
183 static BOOL rdstls_set_state(rdpRdstls* rdstls, RDSTLS_STATE state)
186 WINPR_ASSERT(rdstls);
188 WLog_Print(rdstls->log, WLOG_DEBUG,
"-- %s\t--> %s", rdstls_get_state_str(rdstls->state),
189 rdstls_get_state_str(state));
191 switch (rdstls->state)
193 case RDSTLS_STATE_INITIAL:
194 rc = check_transition(rdstls->log, rdstls->state, RDSTLS_STATE_CAPABILITIES, state);
196 case RDSTLS_STATE_CAPABILITIES:
197 rc = check_transition(rdstls->log, rdstls->state, RDSTLS_STATE_AUTH_REQ, state);
199 case RDSTLS_STATE_AUTH_REQ:
200 rc = check_transition(rdstls->log, rdstls->state, RDSTLS_STATE_AUTH_RSP, state);
202 case RDSTLS_STATE_AUTH_RSP:
203 rc = check_transition(rdstls->log, rdstls->state, RDSTLS_STATE_FINAL, state);
205 case RDSTLS_STATE_FINAL:
206 rc = check_transition(rdstls->log, rdstls->state, RDSTLS_STATE_CAPABILITIES, state);
209 WLog_Print(rdstls->log, WLOG_ERROR,
210 "Invalid rdstls state %s [%d], requested transition to %s [%d]",
211 rdstls_get_state_str(rdstls->state), rdstls->state,
212 rdstls_get_state_str(state), state);
216 rdstls->state = state;
221 static BOOL rdstls_write_capabilities(rdpRdstls* rdstls,
wStream* s)
223 if (!Stream_EnsureRemainingCapacity(s, 6))
226 Stream_Write_UINT16(s, RDSTLS_TYPE_CAPABILITIES);
227 Stream_Write_UINT16(s, RDSTLS_DATA_CAPABILITIES);
228 Stream_Write_UINT16(s, RDSTLS_VERSION_1);
233 static SSIZE_T rdstls_write_string(
wStream* s,
const char* str)
235 const size_t pos = Stream_GetPosition(s);
237 if (!Stream_EnsureRemainingCapacity(s, 2))
243 Stream_Write_UINT16(s, 2);
244 if (!Stream_EnsureRemainingCapacity(s, 2))
247 Stream_Write_UINT16(s, 0);
248 return (SSIZE_T)(Stream_GetPosition(s) - pos);
251 const size_t length = (strlen(str) + 1);
253 Stream_Write_UINT16(s, (UINT16)length *
sizeof(WCHAR));
255 if (!Stream_EnsureRemainingCapacity(s, length *
sizeof(WCHAR)))
258 if (Stream_Write_UTF16_String_From_UTF8(s, length, str, length, TRUE) < 0)
261 return (SSIZE_T)(Stream_GetPosition(s) - pos);
264 static BOOL rdstls_write_data(
wStream* s, UINT32 length,
const BYTE* data)
266 WINPR_ASSERT(data || (length == 0));
268 if (!Stream_EnsureRemainingCapacity(s, 2) || (length > UINT16_MAX))
271 Stream_Write_UINT16(s, (UINT16)length);
273 if (!Stream_EnsureRemainingCapacity(s, length))
276 Stream_Write(s, data, length);
281 static BOOL rdstls_write_authentication_request_with_password(rdpRdstls* rdstls,
wStream* s)
283 rdpSettings* settings = rdstls->context->settings;
284 WINPR_ASSERT(settings);
286 if (!Stream_EnsureRemainingCapacity(s, 4))
289 Stream_Write_UINT16(s, RDSTLS_TYPE_AUTHREQ);
290 Stream_Write_UINT16(s, RDSTLS_DATA_PASSWORD_CREDS);
292 if (!rdstls_write_data(s, settings->RedirectionGuidLength, settings->RedirectionGuid))
295 if (rdstls_write_string(s, settings->Username) < 0)
298 if (rdstls_write_string(s, settings->Domain) < 0)
301 if (!rdstls_write_data(s, settings->RedirectionPasswordLength, settings->RedirectionPassword))
307 static BOOL rdstls_write_authentication_request_with_cookie(rdpRdstls* rdstls,
wStream* s)
313 static BOOL rdstls_write_authentication_response(rdpRdstls* rdstls,
wStream* s)
315 if (!Stream_EnsureRemainingCapacity(s, 8))
318 Stream_Write_UINT16(s, RDSTLS_TYPE_AUTHRSP);
319 Stream_Write_UINT16(s, RDSTLS_DATA_RESULT_CODE);
320 Stream_Write_UINT32(s, rdstls->resultCode);
325 static BOOL rdstls_process_capabilities(rdpRdstls* rdstls,
wStream* s)
328 UINT16 supportedVersions = 0;
330 if (Stream_GetRemainingLength(s) < 4)
333 Stream_Read_UINT16(s, dataType);
334 if (dataType != RDSTLS_DATA_CAPABILITIES)
336 WLog_Print(rdstls->log, WLOG_ERROR,
337 "received invalid DataType=0x%04" PRIX16
", expected 0x%04" PRIX16, dataType,
338 RDSTLS_DATA_CAPABILITIES);
342 Stream_Read_UINT16(s, supportedVersions);
343 if ((supportedVersions & RDSTLS_VERSION_1) == 0)
345 WLog_Print(rdstls->log, WLOG_ERROR,
346 "received invalid supportedVersions=0x%04" PRIX16
", expected 0x%04" PRIX16,
347 supportedVersions, RDSTLS_VERSION_1);
354 static BOOL rdstls_read_unicode_string(wLog* log,
wStream* s,
char** str)
360 if (Stream_GetRemainingLength(s) < 2)
363 Stream_Read_UINT16(s, length);
365 if (Stream_GetRemainingLength(s) < length)
370 Stream_Seek(s, length);
374 *str = Stream_Read_UTF16_String_As_UTF8(s, length /
sizeof(WCHAR), NULL);
381 static BOOL rdstls_read_data(wLog* log,
wStream* s, UINT16* pLength,
const BYTE** pData)
385 WINPR_ASSERT(pLength);
390 if (Stream_GetRemainingLength(s) < 2)
393 Stream_Read_UINT16(s, length);
395 if (Stream_GetRemainingLength(s) < length)
400 Stream_Seek(s, length);
404 *pData = Stream_ConstPointer(s);
406 Stream_Seek(s, length);
410 static BOOL rdstls_cmp_data(wLog* log,
const char* field,
const BYTE* serverData,
411 const UINT32 serverDataLength,
const BYTE* clientData,
412 const UINT16 clientDataLength)
414 if (serverDataLength > 0)
416 if (clientDataLength == 0)
418 WLog_Print(log, WLOG_ERROR,
"expected %s", field);
422 if (serverDataLength > UINT16_MAX || serverDataLength != clientDataLength ||
423 memcmp(serverData, clientData, serverDataLength) != 0)
425 WLog_Print(log, WLOG_ERROR,
"%s verification failed", field);
433 static BOOL rdstls_cmp_str(wLog* log,
const char* field,
const char* serverStr,
434 const char* clientStr)
436 if (!utils_str_is_empty(serverStr))
438 if (utils_str_is_empty(clientStr))
440 WLog_Print(log, WLOG_ERROR,
"expected %s", field);
444 WINPR_ASSERT(serverStr);
445 WINPR_ASSERT(clientStr);
446 if (strcmp(serverStr, clientStr) != 0)
448 WLog_Print(log, WLOG_ERROR,
"%s verification failed", field);
456 static BOOL rdstls_process_authentication_request_with_password(rdpRdstls* rdstls,
wStream* s)
460 const BYTE* clientRedirectionGuid = NULL;
461 UINT16 clientRedirectionGuidLength = 0;
462 char* clientPassword = NULL;
463 char* clientUsername = NULL;
464 char* clientDomain = NULL;
466 const BYTE* serverRedirectionGuid = NULL;
467 const char* serverPassword = NULL;
468 const char* serverUsername = NULL;
469 const char* serverDomain = NULL;
471 rdpSettings* settings = rdstls->context->settings;
472 WINPR_ASSERT(settings);
474 if (!rdstls_read_data(rdstls->log, s, &clientRedirectionGuidLength, &clientRedirectionGuid))
477 if (!rdstls_read_unicode_string(rdstls->log, s, &clientUsername))
480 if (!rdstls_read_unicode_string(rdstls->log, s, &clientDomain))
483 if (!rdstls_read_unicode_string(rdstls->log, s, &clientPassword))
487 const UINT32 serverRedirectionGuidLength =
493 rdstls->resultCode = RDSTLS_RESULT_SUCCESS;
495 if (!rdstls_cmp_data(rdstls->log,
"RedirectionGuid", serverRedirectionGuid,
496 serverRedirectionGuidLength, clientRedirectionGuid,
497 clientRedirectionGuidLength))
498 rdstls->resultCode = RDSTLS_RESULT_ACCESS_DENIED;
500 if (!rdstls_cmp_str(rdstls->log,
"UserName", serverUsername, clientUsername))
501 rdstls->resultCode = RDSTLS_RESULT_LOGON_FAILURE;
503 if (!rdstls_cmp_str(rdstls->log,
"Domain", serverDomain, clientDomain))
504 rdstls->resultCode = RDSTLS_RESULT_LOGON_FAILURE;
506 if (!rdstls_cmp_str(rdstls->log,
"Password", serverPassword, clientPassword))
507 rdstls->resultCode = RDSTLS_RESULT_LOGON_FAILURE;
514 static BOOL rdstls_process_authentication_request_with_cookie(rdpRdstls* rdstls,
wStream* s)
520 static BOOL rdstls_process_authentication_request(rdpRdstls* rdstls,
wStream* s)
524 if (Stream_GetRemainingLength(s) < 2)
527 Stream_Read_UINT16(s, dataType);
530 case RDSTLS_DATA_PASSWORD_CREDS:
531 if (!rdstls_process_authentication_request_with_password(rdstls, s))
534 case RDSTLS_DATA_AUTORECONNECT_COOKIE:
535 if (!rdstls_process_authentication_request_with_cookie(rdstls, s))
539 WLog_Print(rdstls->log, WLOG_ERROR,
540 "received invalid DataType=0x%04" PRIX16
", expected 0x%04" PRIX16
542 dataType, RDSTLS_DATA_PASSWORD_CREDS, RDSTLS_DATA_AUTORECONNECT_COOKIE);
549 static BOOL rdstls_process_authentication_response(rdpRdstls* rdstls,
wStream* s)
552 UINT32 resultCode = 0;
554 if (Stream_GetRemainingLength(s) < 6)
557 Stream_Read_UINT16(s, dataType);
558 if (dataType != RDSTLS_DATA_RESULT_CODE)
560 WLog_Print(rdstls->log, WLOG_ERROR,
561 "received invalid DataType=0x%04" PRIX16
", expected 0x%04" PRIX16, dataType,
562 RDSTLS_DATA_RESULT_CODE);
566 Stream_Read_UINT32(s, resultCode);
567 if (resultCode != RDSTLS_RESULT_SUCCESS)
569 WLog_Print(rdstls->log, WLOG_ERROR,
"resultCode: %s [0x%08" PRIX32
"]",
570 rdstls_result_code_str(resultCode), resultCode);
572 UINT32 error = ERROR_INTERNAL_ERROR;
575 case RDSTLS_RESULT_ACCESS_DENIED:
576 error = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
578 case RDSTLS_RESULT_ACCOUNT_DISABLED:
579 error = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
581 case RDSTLS_RESULT_ACCOUNT_LOCKED_OUT:
582 error = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
584 case RDSTLS_RESULT_LOGON_FAILURE:
585 error = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
587 case RDSTLS_RESULT_INVALID_LOGON_HOURS:
588 error = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
590 case RDSTLS_RESULT_PASSWORD_EXPIRED:
591 error = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
593 case RDSTLS_RESULT_PASSWORD_MUST_CHANGE:
594 error = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
597 error = ERROR_INVALID_PARAMETER;
601 freerdp_set_last_error_if_not(rdstls->context, error);
608 static BOOL rdstls_send(rdpTransport* transport,
wStream* s,
void* extra)
610 rdpRdstls* rdstls = (rdpRdstls*)extra;
611 rdpSettings* settings = NULL;
613 WINPR_ASSERT(transport);
615 WINPR_ASSERT(rdstls);
617 settings = rdstls->context->settings;
618 WINPR_ASSERT(settings);
620 if (!Stream_EnsureRemainingCapacity(s, 2))
623 Stream_Write_UINT16(s, RDSTLS_VERSION_1);
625 const RDSTLS_STATE state = rdstls_get_state(rdstls);
628 case RDSTLS_STATE_CAPABILITIES:
629 if (!rdstls_write_capabilities(rdstls, s))
632 case RDSTLS_STATE_AUTH_REQ:
633 if (settings->RedirectionFlags & LB_PASSWORD_IS_PK_ENCRYPTED)
635 if (!rdstls_write_authentication_request_with_password(rdstls, s))
638 else if (settings->ServerAutoReconnectCookie != NULL)
640 if (!rdstls_write_authentication_request_with_cookie(rdstls, s))
645 WLog_Print(rdstls->log, WLOG_ERROR,
646 "cannot authenticate with password or auto-reconnect cookie");
650 case RDSTLS_STATE_AUTH_RSP:
651 if (!rdstls_write_authentication_response(rdstls, s))
655 WLog_Print(rdstls->log, WLOG_ERROR,
"Invalid rdstls state %s [%d]",
656 rdstls_get_state_str(state), state);
660 if (transport_write(rdstls->transport, s) < 0)
666 static int rdstls_recv(rdpTransport* transport,
wStream* s,
void* extra)
670 rdpRdstls* rdstls = (rdpRdstls*)extra;
672 WINPR_ASSERT(transport);
674 WINPR_ASSERT(rdstls);
676 if (Stream_GetRemainingLength(s) < 4)
679 Stream_Read_UINT16(s, version);
680 if (version != RDSTLS_VERSION_1)
682 WLog_Print(rdstls->log, WLOG_ERROR,
683 "received invalid RDSTLS Version=0x%04" PRIX16
", expected 0x%04" PRIX16,
684 version, RDSTLS_VERSION_1);
688 Stream_Read_UINT16(s, pduType);
691 case RDSTLS_TYPE_CAPABILITIES:
692 if (!rdstls_process_capabilities(rdstls, s))
695 case RDSTLS_TYPE_AUTHREQ:
696 if (!rdstls_process_authentication_request(rdstls, s))
699 case RDSTLS_TYPE_AUTHRSP:
700 if (!rdstls_process_authentication_response(rdstls, s))
704 WLog_Print(rdstls->log, WLOG_ERROR,
"unknown RDSTLS PDU type [0x%04" PRIx16
"]",
712 #define rdstls_check_state_requirements(rdstls, expected) \
713 rdstls_check_state_requirements_((rdstls), (expected), __FILE__, __func__, __LINE__)
714 static BOOL rdstls_check_state_requirements_(rdpRdstls* rdstls, RDSTLS_STATE expected,
715 const char* file,
const char* fkt,
size_t line)
717 const RDSTLS_STATE current = rdstls_get_state(rdstls);
718 if (current == expected)
721 const DWORD log_level = WLOG_ERROR;
722 if (WLog_IsLevelActive(rdstls->log, log_level))
723 WLog_PrintMessage(rdstls->log, WLOG_MESSAGE_TEXT, log_level, line, file, fkt,
724 "Unexpected rdstls state %s [%d], expected %s [%d]",
725 rdstls_get_state_str(current), current, rdstls_get_state_str(expected),
731 static BOOL rdstls_send_capabilities(rdpRdstls* rdstls)
736 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_CAPABILITIES))
739 s = Stream_New(NULL, 512);
743 if (!rdstls_send(rdstls->transport, s, rdstls))
746 rc = rdstls_set_state(rdstls, RDSTLS_STATE_AUTH_REQ);
748 Stream_Free(s, TRUE);
752 static BOOL rdstls_recv_authentication_request(rdpRdstls* rdstls)
758 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_AUTH_REQ))
761 s = Stream_New(NULL, 4096);
765 status = transport_read_pdu(rdstls->transport, s);
770 status = rdstls_recv(rdstls->transport, s, rdstls);
775 rc = rdstls_set_state(rdstls, RDSTLS_STATE_AUTH_RSP);
777 Stream_Free(s, TRUE);
781 static BOOL rdstls_send_authentication_response(rdpRdstls* rdstls)
786 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_AUTH_RSP))
789 s = Stream_New(NULL, 512);
793 if (!rdstls_send(rdstls->transport, s, rdstls))
796 rc = rdstls_set_state(rdstls, RDSTLS_STATE_FINAL);
798 Stream_Free(s, TRUE);
802 static BOOL rdstls_recv_capabilities(rdpRdstls* rdstls)
808 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_CAPABILITIES))
811 s = Stream_New(NULL, 512);
815 status = transport_read_pdu(rdstls->transport, s);
820 status = rdstls_recv(rdstls->transport, s, rdstls);
825 rc = rdstls_set_state(rdstls, RDSTLS_STATE_AUTH_REQ);
827 Stream_Free(s, TRUE);
831 static BOOL rdstls_send_authentication_request(rdpRdstls* rdstls)
836 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_AUTH_REQ))
839 s = Stream_New(NULL, 4096);
843 if (!rdstls_send(rdstls->transport, s, rdstls))
846 rc = rdstls_set_state(rdstls, RDSTLS_STATE_AUTH_RSP);
848 Stream_Free(s, TRUE);
852 static BOOL rdstls_recv_authentication_response(rdpRdstls* rdstls)
858 WINPR_ASSERT(rdstls);
860 if (!rdstls_check_state_requirements(rdstls, RDSTLS_STATE_AUTH_RSP))
863 s = Stream_New(NULL, 512);
867 status = transport_read_pdu(rdstls->transport, s);
872 status = rdstls_recv(rdstls->transport, s, rdstls);
877 rc = rdstls_set_state(rdstls, RDSTLS_STATE_FINAL);
879 Stream_Free(s, TRUE);
883 static int rdstls_server_authenticate(rdpRdstls* rdstls)
885 if (!rdstls_set_state(rdstls, RDSTLS_STATE_CAPABILITIES))
888 if (!rdstls_send_capabilities(rdstls))
891 if (!rdstls_recv_authentication_request(rdstls))
894 if (!rdstls_send_authentication_response(rdstls))
897 if (rdstls->resultCode != RDSTLS_RESULT_SUCCESS)
903 static int rdstls_client_authenticate(rdpRdstls* rdstls)
905 if (!rdstls_set_state(rdstls, RDSTLS_STATE_CAPABILITIES))
908 if (!rdstls_recv_capabilities(rdstls))
911 if (!rdstls_send_authentication_request(rdstls))
914 if (!rdstls_recv_authentication_response(rdstls))
927 int rdstls_authenticate(rdpRdstls* rdstls)
929 WINPR_ASSERT(rdstls);
932 return rdstls_server_authenticate(rdstls);
934 return rdstls_client_authenticate(rdstls);
937 static SSIZE_T rdstls_parse_pdu_data_type(wLog* log, UINT16 dataType,
wStream* s)
941 case RDSTLS_DATA_PASSWORD_CREDS:
943 UINT16 redirGuidLength = 0;
944 if (Stream_GetRemainingLength(s) < 2)
946 Stream_Read_UINT16(s, redirGuidLength);
948 if (Stream_GetRemainingLength(s) < redirGuidLength)
950 Stream_Seek(s, redirGuidLength);
952 UINT16 usernameLength = 0;
953 if (Stream_GetRemainingLength(s) < 2)
955 Stream_Read_UINT16(s, usernameLength);
957 if (Stream_GetRemainingLength(s) < usernameLength)
959 Stream_Seek(s, usernameLength);
961 UINT16 domainLength = 0;
962 if (Stream_GetRemainingLength(s) < 2)
964 Stream_Read_UINT16(s, domainLength);
966 if (Stream_GetRemainingLength(s) < domainLength)
968 Stream_Seek(s, domainLength);
970 UINT16 passwordLength = 0;
971 if (Stream_GetRemainingLength(s) < 2)
973 Stream_Read_UINT16(s, passwordLength);
975 if (Stream_GetRemainingLength(s) < passwordLength)
977 Stream_Seek(s, passwordLength);
980 case RDSTLS_DATA_AUTORECONNECT_COOKIE:
982 if (Stream_GetRemainingLength(s) < 4)
986 UINT16 cookieLength = 0;
987 if (Stream_GetRemainingLength(s) < 2)
989 Stream_Read_UINT16(s, cookieLength);
990 if (!Stream_SafeSeek(s, cookieLength))
995 WLog_Print(log, WLOG_ERROR,
"invalid RDSLTS dataType");
999 const size_t len = Stream_GetPosition(s);
1000 if (len > SSIZE_MAX)
1002 return (SSIZE_T)len;
1005 SSIZE_T rdstls_parse_pdu(wLog* log,
wStream* stream)
1007 SSIZE_T pduLength = -1;
1009 wStream* s = Stream_StaticConstInit(&sbuffer, Stream_Buffer(stream), Stream_Length(stream));
1012 if (Stream_GetRemainingLength(s) < 2)
1014 Stream_Read_UINT16(s, version);
1015 if (version != RDSTLS_VERSION_1)
1017 WLog_Print(log, WLOG_ERROR,
"invalid RDSTLS version");
1022 if (Stream_GetRemainingLength(s) < 2)
1024 Stream_Read_UINT16(s, pduType);
1027 case RDSTLS_TYPE_CAPABILITIES:
1030 case RDSTLS_TYPE_AUTHREQ:
1031 if (Stream_GetRemainingLength(s) < 2)
1033 UINT16 dataType = 0;
1034 Stream_Read_UINT16(s, dataType);
1035 pduLength = rdstls_parse_pdu_data_type(log, dataType, s);
1038 case RDSTLS_TYPE_AUTHRSP:
1042 WLog_Print(log, WLOG_ERROR,
"invalid RDSTLS PDU type");
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.