25#include <freerdp/config.h>
32#include <freerdp/log.h>
33#include <freerdp/build-config.h>
36#include <winpr/assert.h>
38#include <winpr/sspi.h>
39#include <winpr/print.h>
40#include <winpr/tchar.h>
41#include <winpr/ncrypt.h>
42#include <winpr/cred.h>
43#include <winpr/debug.h>
44#include <winpr/asn1.h>
45#include <winpr/secapi.h>
47#include "../crypto/tls.h"
52#include "credssp_auth.h"
53#include <freerdp/utils/smartcardlogon.h>
55#define TAG FREERDP_TAG("core.nla")
57#define NLA_AUTH_PKG NEGO_SSP_NAME
61 AUTHZ_SUCCESS = 0x00000000,
62 AUTHZ_ACCESS_DENIED = 0x00000005,
114 rdpContext* rdpcontext;
115 rdpTransport* transport;
130 SEC_WINNT_AUTH_IDENTITY* identity;
132 rdpCredsspAuth* auth;
139static BOOL nla_send(rdpNla* nla);
140static int nla_server_recv(rdpNla* nla);
141static BOOL nla_encrypt_public_key_echo(rdpNla* nla);
142static BOOL nla_encrypt_public_key_hash(rdpNla* nla);
143static BOOL nla_decrypt_public_key_echo(rdpNla* nla);
144static BOOL nla_decrypt_public_key_hash(rdpNla* nla);
145static BOOL nla_encrypt_ts_credentials(rdpNla* nla);
146static BOOL nla_decrypt_ts_credentials(rdpNla* nla);
148void nla_set_early_user_auth(rdpNla* nla, BOOL earlyUserAuth)
151 WLog_DBG(TAG,
"Early User Auth active: %s", earlyUserAuth ?
"true" :
"false");
152 nla->earlyUserAuth = earlyUserAuth;
155static void nla_buffer_free(rdpNla* nla)
158 sspi_SecBufferFree(&nla->pubKeyAuth);
159 sspi_SecBufferFree(&nla->authInfo);
160 sspi_SecBufferFree(&nla->negoToken);
161 sspi_SecBufferFree(&nla->ClientNonce);
162 sspi_SecBufferFree(&nla->PublicKey);
165static BOOL nla_Digest_Update_From_SecBuffer(WINPR_DIGEST_CTX* ctx,
const SecBuffer* buffer)
169 return winpr_Digest_Update(ctx, buffer->pvBuffer, buffer->cbBuffer);
172static BOOL nla_sec_buffer_alloc(
SecBuffer* buffer,
size_t size)
174 WINPR_ASSERT(buffer);
175 sspi_SecBufferFree(buffer);
176 if (size > UINT32_MAX)
178 if (!sspi_SecBufferAlloc(buffer, (ULONG)size))
181 WINPR_ASSERT(buffer);
182 buffer->BufferType = SECBUFFER_TOKEN;
186static BOOL nla_sec_buffer_alloc_from_data(
SecBuffer* buffer,
const BYTE* data,
size_t offset,
189 if (!nla_sec_buffer_alloc(buffer, offset + size))
192 WINPR_ASSERT(buffer);
193 BYTE* pb = buffer->pvBuffer;
194 memcpy(&pb[offset], data, size);
199static const BYTE ClientServerHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
200 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
201 0x6F, 0x2D, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
202 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
203 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
206static const BYTE ServerClientHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
207 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x54,
208 0x6F, 0x2D, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74,
209 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
210 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
212static const UINT32 NonceLength = 32;
214static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla)
219 WINPR_ASSERT(nla->rdpcontext);
221 rdpSettings* settings = nla->rdpcontext->settings;
222 WINPR_ASSERT(settings);
224 if (!settings->SmartcardLogon)
227 smartcardCertInfo_Free(nla->smartcardCert);
229 if (!smartcard_getCert(nla->rdpcontext, &nla->smartcardCert, FALSE))
231 WLog_ERR(TAG,
"unable to get smartcard certificate for logon");
235 if (!settings->CspName)
240 MS_SMART_CARD_KEY_STORAGE_PROVIDER))
242 WLog_ERR(TAG,
"unable to set CSP name");
247 if (!settings->ReaderName && nla->smartcardCert->reader)
250 nla->smartcardCert->reader))
252 WLog_ERR(TAG,
"unable to copy reader name");
257 if (!settings->ContainerName && nla->smartcardCert->containerName)
260 nla->smartcardCert->containerName))
262 WLog_ERR(TAG,
"unable to copy container name");
270 WLog_ERR(TAG,
"unable to set KeySpec");
274 WLog_DBG(TAG,
"Smartcard logon: Provider='%s' Reader='%s' Container='%s' KeySpec=%" PRIu32,
280 memcpy(nla->certSha1, nla->smartcardCert->sha1Hash,
sizeof(nla->certSha1));
282 if (nla->smartcardCert->pkinitArgs)
284 nla->pkinitArgs = _strdup(nla->smartcardCert->pkinitArgs);
285 if (!nla->pkinitArgs)
287 WLog_ERR(TAG,
"unable to copy pkinitArgs");
297static BOOL nla_client_setup_identity(rdpNla* nla)
299 BOOL PromptPassword = FALSE;
302 WINPR_ASSERT(nla->rdpcontext);
304 rdpSettings* settings = nla->rdpcontext->settings;
305 WINPR_ASSERT(settings);
307 freerdp* instance = nla->rdpcontext->instance;
308 WINPR_ASSERT(instance);
311 if ((utils_str_is_empty(settings->Username) ||
312 (utils_str_is_empty(settings->Password) &&
313 utils_str_is_empty((
const char*)settings->RedirectionPassword))))
315 PromptPassword = TRUE;
318 if (PromptPassword && !utils_str_is_empty(settings->Username))
320 WINPR_SAM* sam = SamOpen(
nullptr, TRUE);
323 const UINT32 userLength = (UINT32)strnlen(settings->Username, INT32_MAX);
324 WINPR_SAM_ENTRY* entry =
325 SamLookupUserA(sam, settings->Username,
326 userLength + 1 ,
nullptr, 0);
333 PromptPassword = FALSE;
334 SamFreeEntry(sam, entry);
343 if (settings->RestrictedAdminModeRequired)
345 if ((settings->PasswordHash) && (strlen(settings->PasswordHash) > 0))
346 PromptPassword = FALSE;
349 if (settings->RemoteCredentialGuard)
350 PromptPassword = FALSE;
353 BOOL smartCardLogonWasDisabled = !settings->SmartcardLogon;
356 switch (utils_authenticate(instance, AUTH_NLA, TRUE))
362 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
364 case AUTH_NO_CREDENTIALS:
365 WLog_INFO(TAG,
"No credentials provided - using nullptr identity");
372 if (!settings->Username)
374 sspi_FreeAuthIdentity(nla->identity);
376 nla->identity =
nullptr;
378 else if (settings->SmartcardLogon)
380 if (smartCardLogonWasDisabled)
382 if (!nla_adjust_settings_from_smartcard(nla))
386 if (!identity_set_from_smartcard_hash(nla->identity, settings, FreeRDP_Username,
387 FreeRDP_Domain, FreeRDP_Password, nla->certSha1,
388 sizeof(nla->certSha1)))
393 BOOL usePassword = TRUE;
395 if (settings->RedirectionPassword && (settings->RedirectionPasswordLength > 0))
397 const WCHAR* wstr = (
const WCHAR*)settings->RedirectionPassword;
398 const size_t len = _wcsnlen(wstr, settings->RedirectionPasswordLength /
sizeof(WCHAR));
400 if (!identity_set_from_settings_with_pwd(nla->identity, settings, FreeRDP_Username,
401 FreeRDP_Domain, wstr, len))
407 if (settings->RestrictedAdminModeRequired)
409 if (settings->PasswordHash && strlen(settings->PasswordHash) == 32)
411 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
412 FreeRDP_Domain, FreeRDP_PasswordHash))
420 nla->identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
427 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
428 FreeRDP_Domain, FreeRDP_Password))
436static int nla_client_init(rdpNla* nla)
439 WINPR_ASSERT(nla->rdpcontext);
441 rdpSettings* settings = nla->rdpcontext->settings;
442 WINPR_ASSERT(settings);
444 nla_set_state(nla, NLA_STATE_INITIAL);
446 if (!nla_adjust_settings_from_smartcard(nla))
449 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG,
nullptr))
452 if (!nla_client_setup_identity(nla))
457 if (!credssp_auth_setup_client(nla->auth,
"TERMSRV", hostname, nla->identity, nla->pkinitArgs))
460 const BYTE* data =
nullptr;
462 if (!transport_get_public_key(nla->transport, &data, &length))
464 WLog_ERR(TAG,
"Failed to get public key");
468 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
470 WLog_ERR(TAG,
"Failed to allocate sspi secBuffer");
477int nla_client_begin(rdpNla* nla)
481 if (nla_client_init(nla) < 1)
484 if (nla_get_state(nla) != NLA_STATE_INITIAL)
494 credssp_auth_set_flags(nla->auth, ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY);
496 const int rc = credssp_auth_authenticate(nla->auth);
503 nla_set_state(nla, NLA_STATE_NEGO_TOKEN);
506 if (credssp_auth_have_output_token(nla->auth))
511 nla_set_state(nla, NLA_STATE_FINAL);
514 switch (credssp_auth_sspi_error(nla->auth))
516 case SEC_E_LOGON_DENIED:
517 case SEC_E_NO_CREDENTIALS:
518 freerdp_set_last_error_log(nla->rdpcontext,
519 FREERDP_ERROR_CONNECT_LOGON_FAILURE);
530static int nla_client_recv_nego_token(rdpNla* nla)
532 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
533 const int rc = credssp_auth_authenticate(nla->auth);
544 if (nla->peerVersion < 5)
545 res = nla_encrypt_public_key_echo(nla);
547 res = nla_encrypt_public_key_hash(nla);
555 nla_set_state(nla, NLA_STATE_PUB_KEY_AUTH);
566static int nla_client_recv_pub_key_auth(rdpNla* nla)
573 if (nla->peerVersion < 5)
574 rc = nla_decrypt_public_key_echo(nla);
576 rc = nla_decrypt_public_key_hash(nla);
578 sspi_SecBufferFree(&nla->pubKeyAuth);
584 rc = nla_encrypt_ts_credentials(nla);
591 if (nla->earlyUserAuth)
593 transport_set_early_user_auth_mode(nla->transport, TRUE);
594 nla_set_state(nla, NLA_STATE_EARLY_USER_AUTH);
597 nla_set_state(nla, NLA_STATE_AUTH_INFO);
601static int nla_client_recv_early_user_auth(rdpNla* nla)
605 transport_set_early_user_auth_mode(nla->transport, FALSE);
606 nla_set_state(nla, NLA_STATE_AUTH_INFO);
610static int nla_client_recv(rdpNla* nla)
614 switch (nla_get_state(nla))
616 case NLA_STATE_NEGO_TOKEN:
617 return nla_client_recv_nego_token(nla);
619 case NLA_STATE_PUB_KEY_AUTH:
620 return nla_client_recv_pub_key_auth(nla);
622 case NLA_STATE_EARLY_USER_AUTH:
623 return nla_client_recv_early_user_auth(nla);
625 case NLA_STATE_FINAL:
627 WLog_ERR(TAG,
"NLA in invalid client receive state %s",
628 nla_get_state_str(nla_get_state(nla)));
633static int nla_client_authenticate(rdpNla* nla)
639 wStream* s = Stream_New(
nullptr, 4096);
643 WLog_ERR(TAG,
"Stream_New failed!");
647 if (nla_client_begin(nla) < 1)
650 while (nla_get_state(nla) < NLA_STATE_AUTH_INFO)
652 Stream_ResetPosition(s);
653 const int status = transport_read_pdu(nla->transport, s);
657 WLog_ERR(TAG,
"nla_client_authenticate failure");
661 const int status2 = nla_recv_pdu(nla, s);
669 Stream_Free(s, TRUE);
677static int nla_server_init(rdpNla* nla)
681 const BYTE* data =
nullptr;
683 if (!transport_get_public_key(nla->transport, &data, &length))
685 WLog_ERR(TAG,
"Failed to get public key");
689 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
691 WLog_ERR(TAG,
"Failed to allocate SecBuffer for public key");
695 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG,
nullptr))
698 if (!credssp_auth_setup_server(nla->auth))
701 nla_set_state(nla, NLA_STATE_INITIAL);
705static wStream* nla_server_recv_stream(rdpNla* nla)
712 s = Stream_New(
nullptr, 4096);
717 status = transport_read_pdu(nla->transport, s);
722 WLog_ERR(TAG,
"nla_recv() error: %d", status);
723 Stream_Free(s, TRUE);
730static BOOL nla_server_recv_credentials(rdpNla* nla)
734 if (nla_server_recv(nla) < 0)
737 if (!nla_decrypt_ts_credentials(nla))
740 if (!nla_impersonate(nla))
743 if (!nla_revert_to_self(nla))
756static int nla_server_authenticate(rdpNla* nla)
762 if (nla_server_init(nla) < 1)
771 credssp_auth_set_flags(nla->auth, ASC_REQ_MUTUAL_AUTH | ASC_REQ_CONFIDENTIALITY |
772 ASC_REQ_CONNECTION | ASC_REQ_USE_SESSION_KEY |
773 ASC_REQ_SEQUENCE_DETECT | ASC_REQ_EXTENDED_ERROR);
805 if (nla_server_recv(nla) < 0)
808 WLog_DBG(TAG,
"Receiving Authentication Token");
809 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
811 res = credssp_auth_authenticate(nla->auth);
818 switch (GetLastError())
820 case ERROR_PASSWORD_MUST_CHANGE:
821 nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
824 case ERROR_PASSWORD_EXPIRED:
825 nla->errorCode = STATUS_PASSWORD_EXPIRED;
828 case ERROR_ACCOUNT_DISABLED:
829 nla->errorCode = STATUS_ACCOUNT_DISABLED;
834 nla->errorCode = STATUS_LOGON_FAILURE;
835 const INT32 sspi = credssp_auth_sspi_error(nla->auth);
836 if (sspi != SEC_E_OK)
837 WLog_DBG(TAG,
"[sspi][%s] failed with %s", credssp_auth_pkg_name(nla->auth),
838 GetSecurityStatusString(sspi));
851 if (credssp_auth_have_output_token(nla->auth))
856 if (nla_server_recv(nla) < 0)
859 WLog_DBG(TAG,
"Receiving pubkey Token");
862 if (nla->peerVersion < 5)
863 res = nla_decrypt_public_key_echo(nla);
865 res = nla_decrypt_public_key_hash(nla);
871 sspi_SecBufferFree(&nla->negoToken);
873 if (nla->peerVersion < 5)
874 res = nla_encrypt_public_key_echo(nla);
876 res = nla_encrypt_public_key_hash(nla);
883 WLog_DBG(TAG,
"Sending Authentication Token");
896 if (!nla_server_recv_credentials(nla))
900 nla_buffer_free(nla);
911int nla_authenticate(rdpNla* nla)
916 return nla_server_authenticate(nla);
918 return nla_client_authenticate(nla);
921static void ap_integer_increment_le(BYTE* number,
size_t size)
923 WINPR_ASSERT(number || (size == 0));
925 for (
size_t index = 0; index < size; index++)
927 if (number[index] < 0xFF)
940static void ap_integer_decrement_le(BYTE* number,
size_t size)
942 WINPR_ASSERT(number || (size == 0));
944 for (
size_t index = 0; index < size; index++)
946 if (number[index] > 0)
953 number[index] = 0xFF;
959BOOL nla_encrypt_public_key_echo(rdpNla* nla)
965 sspi_SecBufferFree(&nla->pubKeyAuth);
969 if (!sspi_SecBufferAlloc(&buf, nla->PublicKey.cbBuffer))
971 ap_integer_increment_le(buf.pvBuffer, buf.cbBuffer);
973 credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth,
nullptr, nla->sendSeqNum++);
974 sspi_SecBufferFree(&buf);
978 status = credssp_auth_encrypt(nla->auth, &nla->PublicKey, &nla->pubKeyAuth,
nullptr,
985BOOL nla_encrypt_public_key_hash(rdpNla* nla)
988 WINPR_DIGEST_CTX* sha256 =
nullptr;
993 const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
994 const size_t hashSize =
995 nla->server ?
sizeof(ServerClientHashMagic) : sizeof(ClientServerHashMagic);
997 if (!sspi_SecBufferAlloc(&buf, WINPR_SHA256_DIGEST_LENGTH))
1001 if (!(sha256 = winpr_Digest_New()))
1004 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1008 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1011 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1015 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1018 if (!winpr_Digest_Final(sha256, buf.pvBuffer, WINPR_SHA256_DIGEST_LENGTH))
1021 sspi_SecBufferFree(&nla->pubKeyAuth);
1022 if (!credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth,
nullptr, nla->sendSeqNum++))
1028 winpr_Digest_Free(sha256);
1029 sspi_SecBufferFree(&buf);
1033BOOL nla_decrypt_public_key_echo(rdpNla* nla)
1035 BOOL status = FALSE;
1036 SecBuffer public_key = WINPR_C_ARRAY_INIT;
1041 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &public_key, nla->recvSeqNum++))
1047 ap_integer_decrement_le(public_key.pvBuffer, public_key.cbBuffer);
1050 if (public_key.cbBuffer != nla->PublicKey.cbBuffer ||
1051 memcmp(public_key.pvBuffer, nla->PublicKey.pvBuffer, public_key.cbBuffer) != 0)
1053 WLog_ERR(TAG,
"Could not verify server's public key echo");
1054#if defined(WITH_DEBUG_NLA)
1055 WLog_ERR(TAG,
"Expected (length = %" PRIu32
"):", nla->PublicKey.cbBuffer);
1056 winpr_HexDump(TAG, WLOG_ERROR, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer);
1057 WLog_ERR(TAG,
"Actual (length = %" PRIu32
"):", public_key.cbBuffer);
1058 winpr_HexDump(TAG, WLOG_ERROR, public_key.pvBuffer, public_key.cbBuffer);
1066 sspi_SecBufferFree(&public_key);
1070BOOL nla_decrypt_public_key_hash(rdpNla* nla)
1072 WINPR_DIGEST_CTX* sha256 =
nullptr;
1073 BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH] = WINPR_C_ARRAY_INIT;
1074 BOOL status = FALSE;
1078 const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
1079 const size_t hashSize =
1080 nla->server ?
sizeof(ClientServerHashMagic) : sizeof(ServerClientHashMagic);
1083 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &hash, nla->recvSeqNum++))
1087 if (!(sha256 = winpr_Digest_New()))
1090 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1094 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1097 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1101 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1104 if (!winpr_Digest_Final(sha256, serverClientHash,
sizeof(serverClientHash)))
1108 if (hash.cbBuffer != WINPR_SHA256_DIGEST_LENGTH ||
1109 memcmp(serverClientHash, hash.pvBuffer, WINPR_SHA256_DIGEST_LENGTH) != 0)
1111 WLog_ERR(TAG,
"Could not verify server's hash");
1118 winpr_Digest_Free(sha256);
1119 sspi_SecBufferFree(&hash);
1123static BOOL set_creds_octetstring_to_settings(
WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
1124 BOOL optional, FreeRDP_Settings_Keys_String settingId,
1125 rdpSettings* settings)
1129 WinPrAsn1_tagId itemTag = 0;
1130 if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != (ER_TAG_CONTEXTUAL | tagId)))
1139 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1143 value.len /
sizeof(WCHAR));
1146static BOOL nla_read_TSCspDataDetail(
WinPrAsn1Decoder* dec, rdpSettings* settings)
1151 WinPrAsn1_INTEGER keyspec = 0;
1152 if (!WinPrAsn1DecReadContextualInteger(dec, 0, &error, &keyspec))
1154 settings->KeySpec = (UINT32)keyspec;
1157 if (!set_creds_octetstring_to_settings(dec, 1, TRUE, FreeRDP_CardName, settings))
1161 if (!set_creds_octetstring_to_settings(dec, 2, TRUE, FreeRDP_ReaderName, settings))
1165 if (!set_creds_octetstring_to_settings(dec, 3, TRUE, FreeRDP_ContainerName, settings))
1169 return set_creds_octetstring_to_settings(dec, 4, TRUE, FreeRDP_CspName, settings);
1172static BOOL nla_messageTypeValid(UINT32 type)
1176 case KerbInvalidValue:
1177 case KerbInteractiveLogon:
1178 case KerbSmartCardLogon:
1179 case KerbWorkstationUnlockLogon:
1180 case KerbSmartCardUnlockLogon:
1181 case KerbProxyLogon:
1182 case KerbTicketLogon:
1183 case KerbTicketUnlockLogon:
1184#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0501)
1187#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
1188 case KerbCertificateLogon:
1189 case KerbCertificateS4ULogon:
1190 case KerbCertificateUnlockLogon:
1192#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0602)
1193 case KerbNoElevationLogon:
1198 WLog_ERR(TAG,
"Invalid message type %" PRIu32, type);
1203static BOOL nla_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1212 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1216 const UINT32 type = Stream_Get_UINT32(s);
1217 if (!nla_messageTypeValid(type))
1220 ticket->MessageType = (KERB_LOGON_SUBMIT_TYPE)type;
1222 Stream_Read_UINT32(s, ticket->Flags);
1223 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1224 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1226 if (ticket->MessageType != KerbTicketLogon)
1228 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1232 if (!Stream_CheckAndLogRequiredLength(
1233 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1241 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1242 Stream_Seek(s, ticket->ServiceTicketLength);
1247 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1251static BOOL nla_credentialTypeValid(UINT32 type)
1255 case InvalidCredKey:
1256 case DeprecatedIUMCredKey:
1257 case DomainUserCredKey:
1258 case LocalUserCredKey:
1259 case ExternallySuppliedCredKey:
1262 WLog_ERR(TAG,
"Invalid credential type %" PRIu32, type);
1267WINPR_ATTR_MALLOC(free, 1)
1275 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32 + 4))
1278 size_t pos = Stream_GetPosition(s);
1281 ULONG EncryptedCredsSize = Stream_Get_UINT32(s);
1282 if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize))
1285 if (!Stream_SetPosition(s, pos))
1293 ret->Version = Stream_Get_UINT32(s);
1294 ret->Flags = Stream_Get_UINT32(s);
1295 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1297 const UINT32 val = Stream_Get_UINT32(s);
1298 if (!nla_credentialTypeValid(val))
1303 ret->CredentialKeyType = WINPR_ASSERTING_INT_CAST(MSV1_0_CREDENTIAL_KEY_TYPE, val);
1305 ret->EncryptedCredsSize = EncryptedCredsSize;
1306 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1317} RemoteGuardPackageCredType;
1319static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1320 RemoteGuardPackageCredType* credsType,
1326 char packageNameStr[100] = WINPR_C_ARRAY_INIT;
1330 WINPR_ASSERT(credsType);
1331 WINPR_ASSERT(payload);
1333 *credsType = RCG_TYPE_NONE;
1336 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1339 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1340 packageNameStr,
sizeof(packageNameStr));
1341 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1344 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1347 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1349 *credsType = RCG_TYPE_KERB;
1351 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1353 *credsType = RCG_TYPE_NTLM;
1357 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1361 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1368 TSCREDS_INVALID = 0,
1369 TSCREDS_USER_PASSWD = 1,
1370 TSCREDS_SMARTCARD = 2,
1371 TSCREDS_REMOTEGUARD = 6
1374static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1380 WinPrAsn1_INTEGER credType = -1;
1386 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1389 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1394 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1398 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1401 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1403 rdpSettings* settings = nla->rdpcontext->settings;
1404 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1405 credType != TSCREDS_REMOTEGUARD)
1407 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1413 case TSCREDS_USER_PASSWD:
1416 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1421 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1425 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1429 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1431 case TSCREDS_SMARTCARD:
1434 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1439 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1441 settings->PasswordIsSmartcardPin = TRUE;
1445 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1447 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1451 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1455 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1457 case TSCREDS_REMOTEGUARD:
1460 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1466 .ServiceTicketLength = 0,
1467 .TicketGrantingTicketLength = 0,
1468 .ServiceTicket =
nullptr,
1469 .TicketGrantingTicket =
nullptr };
1473 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1476 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1477 wStream logonPayload = WINPR_C_ARRAY_INIT;
1478 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1481 if (logonCredsType != RCG_TYPE_KERB)
1483 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1487 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1489 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1497 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1498 Stream_GetRemainingLength(&suppCredsSeq.source))
1501 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1504 RemoteGuardPackageCredType suppCredsType = RCG_TYPE_NONE;
1505 wStream ntlmPayload = WINPR_C_ARRAY_INIT;
1506 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1510 if (suppCredsType != RCG_TYPE_NTLM)
1512 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1516 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1519 WLog_ERR(TAG,
"invalid supplementalCreds");
1525 WLog_ERR(TAG,
"invalid supplementalCreds");
1529 freerdp_peer* peer = nla->rdpcontext->peer;
1530 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1535 WLog_DBG(TAG,
"TSCredentials type %d not supported for now", credType);
1545 WINPR_ASSERT(ticket);
1547 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1548 ticket->TicketGrantingTicketLength))
1551 Stream_Write_UINT32(s, KerbTicketLogon);
1552 Stream_Write_UINT32(s, ticket->Flags);
1553 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1554 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1556 Stream_Write_UINT64(s, 0x20);
1557 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1559 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1560 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1564static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1567 WINPR_ASSERT(logonTicket);
1569 SecurityFunctionTable* table =
nullptr;
1571 credssp_auth_tableAndContext(nla->auth, &table, &context);
1572 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1576static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1580 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1581 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1586 logonTicket.ServiceTicket =
nullptr;
1587 logonTicket.TicketGrantingTicket =
nullptr;
1590 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1594 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1597 s = Stream_New(
nullptr, 2000);
1601 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1604 credBuffer.len = Stream_GetPosition(s);
1605 credBuffer.data = Stream_Buffer(s);
1606 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1609 free(logonTicket.ServiceTicket);
1610 free(logonTicket.TicketGrantingTicket);
1611 Stream_Free(s, TRUE);
1615static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1620 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1624 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1628 wStream* s = Stream_New(
nullptr, 300);
1632 Stream_Write_UINT32(s, pntlm->Version);
1633 Stream_Write_UINT32(s, pntlm->Flags);
1635 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1636 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1637 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1638 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1639 Stream_Zero(s, 6 + 16 * 4 + 14);
1643 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1647 Stream_Free(s, TRUE);
1651static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1655 WinPrAsn1_tagId tag;
1656 FreeRDP_Settings_Keys_String setting_id;
1657 } cspData_fields[] = { { 1, FreeRDP_CardName },
1658 { 2, FreeRDP_ReaderName },
1659 { 3, FreeRDP_ContainerName },
1660 { 4, FreeRDP_CspName } };
1665 WINPR_ASSERT(nla->rdpcontext);
1667 const rdpSettings* settings = nla->rdpcontext->settings;
1668 WINPR_ASSERT(settings);
1671 if (!WinPrAsn1EncSeqContainer(enc))
1678 octet_string.len = ss *
sizeof(WCHAR);
1679 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1680 WinPrAsn1FreeOctetString(&octet_string);
1685 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1689 if (!WinPrAsn1EncContextualInteger(
1691 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1695 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1700 settings, cspData_fields[i].setting_id, &len);
1701 octet_string.len = len *
sizeof(WCHAR);
1702 if (octet_string.len)
1705 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1706 WinPrAsn1FreeOctetString(&octet_string);
1713 if (!WinPrAsn1EncEndContainer(enc))
1721 octet_string.len = ss *
sizeof(WCHAR);
1722 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1723 WinPrAsn1FreeOctetString(&octet_string);
1733 octet_string.len = ss *
sizeof(WCHAR);
1734 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1735 WinPrAsn1FreeOctetString(&octet_string);
1741 return WinPrAsn1EncEndContainer(enc) != 0;
1744static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1752 WINPR_ASSERT(nla->rdpcontext);
1754 const rdpSettings* settings = nla->rdpcontext->settings;
1755 WINPR_ASSERT(settings);
1758 if (!WinPrAsn1EncSeqContainer(enc))
1761 if (!settings->DisableCredentialsDelegation && nla->identity)
1763 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1764 username.data = (BYTE*)nla->identity->User;
1766 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1767 domain.data = (BYTE*)nla->identity->Domain;
1769 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1770 password.data = (BYTE*)nla->identity->Password;
1773 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1775 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1777 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1781 return WinPrAsn1EncEndContainer(enc) != 0;
1784static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1790 if (!WinPrAsn1EncSeqContainer(enc))
1794 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1797 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1805 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1808 if (!WinPrAsn1EncSeqContainer(enc))
1811 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1814 if (!WinPrAsn1EncEndContainer(enc))
1817 if (!WinPrAsn1EncEndContainer(enc))
1822 return WinPrAsn1EncEndContainer(enc) != 0;
1832static BOOL nla_encode_ts_credentials(rdpNla* nla)
1835 WinPrAsn1Encoder* enc =
nullptr;
1837 wStream s = WINPR_C_ARRAY_INIT;
1838 TsCredentialsType credType = TSCREDS_INVALID;
1841 WINPR_ASSERT(nla->rdpcontext);
1843 rdpSettings* settings = nla->rdpcontext->settings;
1844 WINPR_ASSERT(settings);
1846 if (settings->RemoteCredentialGuard)
1847 credType = TSCREDS_REMOTEGUARD;
1848 else if (settings->SmartcardLogon)
1849 credType = TSCREDS_SMARTCARD;
1851 credType = TSCREDS_USER_PASSWD;
1853 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1858 if (!WinPrAsn1EncSeqContainer(enc))
1862 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1866 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1871 case TSCREDS_SMARTCARD:
1872 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1876 case TSCREDS_USER_PASSWD:
1877 if (!nla_encode_ts_password_credentials(nla, enc))
1881 case TSCREDS_REMOTEGUARD:
1882 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1890 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1893 if (!WinPrAsn1EncStreamSize(enc, &length))
1896 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1898 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1902 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1904 ret = WinPrAsn1EncToStream(enc, &s);
1907 WinPrAsn1Encoder_Free(&enc);
1911static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1915 if (!nla_encode_ts_credentials(nla))
1918 sspi_SecBufferFree(&nla->authInfo);
1919 return (credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo,
nullptr,
1920 nla->sendSeqNum++));
1923static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1927 if (nla->authInfo.cbBuffer < 1)
1929 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1933 sspi_SecBufferFree(&nla->tsCredentials);
1934 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1937 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1943static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1944 WinPrAsn1_tagId tagId,
const char* msg)
1949 WINPR_ASSERT(buffer);
1952 if (buffer->cbBuffer > 0)
1957 WLog_DBG(TAG,
" ----->> %s", msg);
1958 octet_string.data = buffer->pvBuffer;
1959 octet_string.len = buffer->cbBuffer;
1960 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1968static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1969 WinPrAsn1_tagId tagId,
const char* msg)
1971 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1972 sspi_SecBufferFree(buffer);
1984BOOL nla_send(rdpNla* nla)
1989 WinPrAsn1Encoder* enc =
nullptr;
1993 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1998 WLog_DBG(TAG,
"----->> sending...");
1999 if (!WinPrAsn1EncSeqContainer(enc))
2003 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
2004 if (!WinPrAsn1EncContextualInteger(enc, 0,
2005 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
2009 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
2011 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
2013 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
2017 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
2021 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
2026 if (nla->authInfo.cbBuffer > 0)
2028 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
2033 if (nla->pubKeyAuth.cbBuffer > 0)
2035 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
2040 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
2042 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2043 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2044 if (!WinPrAsn1EncContextualInteger(
2045 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
2050 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
2052 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
2057 if (!WinPrAsn1EncEndContainer(enc))
2060 if (!WinPrAsn1EncStreamSize(enc, &length))
2063 s = Stream_New(
nullptr, length);
2067 if (!WinPrAsn1EncToStream(enc, s))
2070 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
2071 if (transport_write(nla->transport, s) < 0)
2076 Stream_Free(s, TRUE);
2077 WinPrAsn1Encoder_Free(&enc);
2081static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
2086 WinPrAsn1_tagId tag = WINPR_C_ARRAY_INIT;
2087 WinPrAsn1_INTEGER val = WINPR_C_ARRAY_INIT;
2093 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
2095 WLog_DBG(TAG,
"<<----- receiving...");
2098 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
2104 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
2107 if (!Stream_SafeSeek(s, offset))
2110 version = (UINT)val;
2111 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
2113 if (nla->peerVersion == 0)
2114 nla->peerVersion = version;
2117 if (nla->peerVersion != version)
2119 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
2120 nla->peerVersion, version);
2124 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
2132 WLog_DBG(TAG,
" <<----- nego token");
2134 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
2135 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
2138 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
2142 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
2147 WLog_DBG(TAG,
" <<----- auth info");
2149 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2151 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
2156 WLog_DBG(TAG,
" <<----- public key auth");
2158 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2160 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
2166 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
2168 nla->errorCode = val;
2169 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2170 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2173 WLog_DBG(TAG,
" <<----- client nonce");
2175 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2177 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
2189int nla_recv_pdu(rdpNla* nla,
wStream* s)
2194 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
2197 Stream_Read_UINT32(s, code);
2198 if (code != AUTHZ_SUCCESS)
2200 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
2201 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2202 freerdp_set_last_error_log(nla->rdpcontext, code);
2206 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2210 if (nla_decode_ts_request(nla, s) < 1)
2217 switch (nla->errorCode)
2219 case STATUS_PASSWORD_MUST_CHANGE:
2220 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2223 case STATUS_PASSWORD_EXPIRED:
2224 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2227 case STATUS_ACCOUNT_DISABLED:
2228 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2231 case STATUS_LOGON_FAILURE:
2232 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2235 case STATUS_WRONG_PASSWORD:
2236 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2239 case STATUS_ACCESS_DENIED:
2240 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2243 case STATUS_ACCOUNT_RESTRICTION:
2244 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2247 case STATUS_ACCOUNT_LOCKED_OUT:
2248 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2251 case STATUS_ACCOUNT_EXPIRED:
2252 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2255 case STATUS_LOGON_TYPE_NOT_GRANTED:
2256 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2260 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIx32
"]",
2261 NtStatus2Tag(nla->errorCode),
2262 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2263 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2267 freerdp_set_last_error_log(nla->rdpcontext, code);
2272 return nla_client_recv(nla);
2275int nla_server_recv(rdpNla* nla)
2281 wStream* s = nla_server_recv_stream(nla);
2284 status = nla_decode_ts_request(nla, s);
2287 Stream_Free(s, TRUE);
2300rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2302 WINPR_ASSERT(transport);
2303 WINPR_ASSERT(context);
2305 rdpSettings* settings = context->settings;
2306 WINPR_ASSERT(settings);
2308 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2313 nla->rdpcontext = context;
2314 nla->server = settings->ServerMode;
2315 nla->transport = transport;
2316 nla->sendSeqNum = 0;
2317 nla->recvSeqNum = 0;
2319 nla->earlyUserAuth = FALSE;
2321 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2325 nla->auth = credssp_auth_new(context);
2330 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2334 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2339 WINPR_PRAGMA_DIAG_PUSH
2340 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2342 WINPR_PRAGMA_DIAG_POP
2351void nla_free(rdpNla* nla)
2356 smartcardCertInfo_Free(nla->smartcardCert);
2357 nla_buffer_free(nla);
2358 sspi_SecBufferFree(&nla->tsCredentials);
2359 credssp_auth_free(nla->auth);
2361 sspi_FreeAuthIdentity(nla->identity);
2362 free(nla->pkinitArgs);
2363 free(nla->identity);
2367SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2372 return nla->identity;
2375NLA_STATE nla_get_state(
const rdpNla* nla)
2378 return NLA_STATE_FINAL;
2383BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2388 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2393BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2395 return (credssp_auth_set_spn(nla->auth, service, hostname));
2398BOOL nla_impersonate(rdpNla* nla)
2400 return credssp_auth_impersonate(nla->auth);
2403BOOL nla_revert_to_self(rdpNla* nla)
2405 return credssp_auth_revert_to_self(nla->auth);
2408const char* nla_get_state_str(NLA_STATE state)
2412 case NLA_STATE_INITIAL:
2413 return "NLA_STATE_INITIAL";
2414 case NLA_STATE_NEGO_TOKEN:
2415 return "NLA_STATE_NEGO_TOKEN";
2416 case NLA_STATE_PUB_KEY_AUTH:
2417 return "NLA_STATE_PUB_KEY_AUTH";
2418 case NLA_STATE_AUTH_INFO:
2419 return "NLA_STATE_AUTH_INFO";
2420 case NLA_STATE_POST_NEGO:
2421 return "NLA_STATE_POST_NEGO";
2422 case NLA_STATE_EARLY_USER_AUTH:
2423 return "NLA_STATE_EARLY_USER_AUTH";
2424 case NLA_STATE_FINAL:
2425 return "NLA_STATE_FINAL";
2431DWORD nla_get_error(
const rdpNla* nla)
2434 return ERROR_INTERNAL_ERROR;
2435 return (UINT32)nla->errorCode;
2438INT32 nla_get_sspi_error(
const rdpNla* nla)
2441 return credssp_auth_sspi_error(nla->auth);
2447 WINPR_ASSERT(inBuffer);
2448 WINPR_ASSERT(outBuffer);
2449 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer,
nullptr, nla->sendSeqNum++);
2455 WINPR_ASSERT(inBuffer);
2456 WINPR_ASSERT(outBuffer);
2457 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2460SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2464 SecurityFunctionTable* table =
nullptr;
2466 credssp_auth_tableAndContext(nla->auth, &table, &context);
2468 return table->QueryContextAttributes(&context, ulAttr, pBuffer);
2471SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer)
2475 SecurityFunctionTable* table =
nullptr;
2477 credssp_auth_tableAndContext(nla->auth, &table, &context);
2479 return table->FreeContextBuffer(pBuffer);
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string_from_utf16N(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param, size_t length)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string_from_utf16(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API WCHAR * freerdp_settings_get_string_as_utf16(const rdpSettings *settings, FreeRDP_Settings_Keys_String id, size_t *pCharLen)
Return an allocated UTF16 string.