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")
59#define NLA_AUTH_PKG NEGO_SSP_NAME
63 AUTHZ_SUCCESS = 0x00000000,
64 AUTHZ_ACCESS_DENIED = 0x00000005,
116 rdpContext* rdpcontext;
117 rdpTransport* transport;
132 SEC_WINNT_AUTH_IDENTITY* identity;
134 rdpCredsspAuth* auth;
141static BOOL nla_send(rdpNla* nla);
142static int nla_server_recv(rdpNla* nla);
143static BOOL nla_encrypt_public_key_echo(rdpNla* nla);
144static BOOL nla_encrypt_public_key_hash(rdpNla* nla);
145static BOOL nla_decrypt_public_key_echo(rdpNla* nla);
146static BOOL nla_decrypt_public_key_hash(rdpNla* nla);
147static BOOL nla_encrypt_ts_credentials(rdpNla* nla);
148static BOOL nla_decrypt_ts_credentials(rdpNla* nla);
150void nla_set_early_user_auth(rdpNla* nla, BOOL earlyUserAuth)
153 WLog_DBG(TAG,
"Early User Auth active: %s", earlyUserAuth ?
"true" :
"false");
154 nla->earlyUserAuth = earlyUserAuth;
157static void nla_buffer_free(rdpNla* nla)
160 sspi_SecBufferFree(&nla->pubKeyAuth);
161 sspi_SecBufferFree(&nla->authInfo);
162 sspi_SecBufferFree(&nla->negoToken);
163 sspi_SecBufferFree(&nla->ClientNonce);
164 sspi_SecBufferFree(&nla->PublicKey);
167static BOOL nla_Digest_Update_From_SecBuffer(WINPR_DIGEST_CTX* ctx,
const SecBuffer* buffer)
171 return winpr_Digest_Update(ctx, buffer->pvBuffer, buffer->cbBuffer);
174static BOOL nla_sec_buffer_alloc(
SecBuffer* buffer,
size_t size)
176 WINPR_ASSERT(buffer);
177 sspi_SecBufferFree(buffer);
178 if (size > UINT32_MAX)
180 if (!sspi_SecBufferAlloc(buffer, (ULONG)size))
183 WINPR_ASSERT(buffer);
184 buffer->BufferType = SECBUFFER_TOKEN;
188static BOOL nla_sec_buffer_alloc_from_data(
SecBuffer* buffer,
const BYTE* data,
size_t offset,
191 if (!nla_sec_buffer_alloc(buffer, offset + size))
194 WINPR_ASSERT(buffer);
195 BYTE* pb = buffer->pvBuffer;
196 memcpy(&pb[offset], data, size);
201static const BYTE ClientServerHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
202 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
203 0x6F, 0x2D, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
204 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
205 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
208static const BYTE ServerClientHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
209 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x54,
210 0x6F, 0x2D, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74,
211 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
212 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
214static const UINT32 NonceLength = 32;
216static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla)
221 WINPR_ASSERT(nla->rdpcontext);
223 rdpSettings* settings = nla->rdpcontext->settings;
224 WINPR_ASSERT(settings);
226 if (!settings->SmartcardLogon)
229 smartcardCertInfo_Free(nla->smartcardCert);
231 if (!smartcard_getCert(nla->rdpcontext, &nla->smartcardCert, FALSE))
233 WLog_ERR(TAG,
"unable to get smartcard certificate for logon");
237 if (!settings->CspName)
240 settings, FreeRDP_CspName, nla->smartcardCert->csp))
242 WLog_ERR(TAG,
"unable to set CSP name");
245 if (!settings->CspName &&
248 WLog_ERR(TAG,
"unable to set CSP name");
253 if (!settings->ReaderName && nla->smartcardCert->reader)
256 nla->smartcardCert->reader))
258 WLog_ERR(TAG,
"unable to copy reader name");
263 if (!settings->ContainerName && nla->smartcardCert->containerName)
266 nla->smartcardCert->containerName))
268 WLog_ERR(TAG,
"unable to copy container name");
273 memcpy(nla->certSha1, nla->smartcardCert->sha1Hash,
sizeof(nla->certSha1));
275 if (nla->smartcardCert->pkinitArgs)
277 nla->pkinitArgs = _strdup(nla->smartcardCert->pkinitArgs);
278 if (!nla->pkinitArgs)
280 WLog_ERR(TAG,
"unable to copy pkinitArgs");
290static BOOL nla_client_setup_identity(rdpNla* nla)
292 BOOL PromptPassword = FALSE;
295 WINPR_ASSERT(nla->rdpcontext);
297 rdpSettings* settings = nla->rdpcontext->settings;
298 WINPR_ASSERT(settings);
300 freerdp* instance = nla->rdpcontext->instance;
301 WINPR_ASSERT(instance);
304 if ((utils_str_is_empty(settings->Username) ||
305 (utils_str_is_empty(settings->Password) &&
306 utils_str_is_empty((
const char*)settings->RedirectionPassword))))
308 PromptPassword = TRUE;
311 if (PromptPassword && !utils_str_is_empty(settings->Username))
313 WINPR_SAM* sam = SamOpen(NULL, TRUE);
316 const UINT32 userLength = (UINT32)strnlen(settings->Username, INT32_MAX);
317 WINPR_SAM_ENTRY* entry = SamLookupUserA(
318 sam, settings->Username, userLength + 1 , NULL, 0);
325 PromptPassword = FALSE;
326 SamFreeEntry(sam, entry);
335 if (settings->RestrictedAdminModeRequired)
337 if ((settings->PasswordHash) && (strlen(settings->PasswordHash) > 0))
338 PromptPassword = FALSE;
341 if (settings->RemoteCredentialGuard)
342 PromptPassword = FALSE;
345 BOOL smartCardLogonWasDisabled = !settings->SmartcardLogon;
348 switch (utils_authenticate(instance, AUTH_NLA, TRUE))
354 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
356 case AUTH_NO_CREDENTIALS:
357 WLog_INFO(TAG,
"No credentials provided - using NULL identity");
364 if (!settings->Username)
366 sspi_FreeAuthIdentity(nla->identity);
368 nla->identity = NULL;
370 else if (settings->SmartcardLogon)
372 if (smartCardLogonWasDisabled)
374 if (!nla_adjust_settings_from_smartcard(nla))
378 if (!identity_set_from_smartcard_hash(nla->identity, settings, FreeRDP_Username,
379 FreeRDP_Domain, FreeRDP_Password, nla->certSha1,
380 sizeof(nla->certSha1)))
385 BOOL usePassword = TRUE;
387 if (settings->RedirectionPassword && (settings->RedirectionPasswordLength > 0))
389 const WCHAR* wstr = (
const WCHAR*)settings->RedirectionPassword;
390 const size_t len = _wcsnlen(wstr, settings->RedirectionPasswordLength /
sizeof(WCHAR));
392 if (!identity_set_from_settings_with_pwd(nla->identity, settings, FreeRDP_Username,
393 FreeRDP_Domain, wstr, len))
399 if (settings->RestrictedAdminModeRequired)
401 if (settings->PasswordHash && strlen(settings->PasswordHash) == 32)
403 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
404 FreeRDP_Domain, FreeRDP_PasswordHash))
412 nla->identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
419 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
420 FreeRDP_Domain, FreeRDP_Password))
428static int nla_client_init(rdpNla* nla)
431 WINPR_ASSERT(nla->rdpcontext);
433 rdpSettings* settings = nla->rdpcontext->settings;
434 WINPR_ASSERT(settings);
436 nla_set_state(nla, NLA_STATE_INITIAL);
438 if (!nla_adjust_settings_from_smartcard(nla))
441 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG, NULL))
444 if (!nla_client_setup_identity(nla))
449 if (!credssp_auth_setup_client(nla->auth,
"TERMSRV", hostname, nla->identity, nla->pkinitArgs))
452 const BYTE* data = NULL;
454 if (!transport_get_public_key(nla->transport, &data, &length))
456 WLog_ERR(TAG,
"Failed to get public key");
460 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
462 WLog_ERR(TAG,
"Failed to allocate sspi secBuffer");
469int nla_client_begin(rdpNla* nla)
473 if (nla_client_init(nla) < 1)
476 if (nla_get_state(nla) != NLA_STATE_INITIAL)
486 credssp_auth_set_flags(nla->auth, ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY);
488 const int rc = credssp_auth_authenticate(nla->auth);
495 nla_set_state(nla, NLA_STATE_NEGO_TOKEN);
498 if (credssp_auth_have_output_token(nla->auth))
503 nla_set_state(nla, NLA_STATE_FINAL);
506 switch (credssp_auth_sspi_error(nla->auth))
508 case SEC_E_LOGON_DENIED:
509 case SEC_E_NO_CREDENTIALS:
510 freerdp_set_last_error_log(nla->rdpcontext,
511 FREERDP_ERROR_CONNECT_LOGON_FAILURE);
522static int nla_client_recv_nego_token(rdpNla* nla)
524 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
525 const int rc = credssp_auth_authenticate(nla->auth);
536 if (nla->peerVersion < 5)
537 res = nla_encrypt_public_key_echo(nla);
539 res = nla_encrypt_public_key_hash(nla);
547 nla_set_state(nla, NLA_STATE_PUB_KEY_AUTH);
558static int nla_client_recv_pub_key_auth(rdpNla* nla)
565 if (nla->peerVersion < 5)
566 rc = nla_decrypt_public_key_echo(nla);
568 rc = nla_decrypt_public_key_hash(nla);
570 sspi_SecBufferFree(&nla->pubKeyAuth);
576 rc = nla_encrypt_ts_credentials(nla);
583 if (nla->earlyUserAuth)
585 transport_set_early_user_auth_mode(nla->transport, TRUE);
586 nla_set_state(nla, NLA_STATE_EARLY_USER_AUTH);
589 nla_set_state(nla, NLA_STATE_AUTH_INFO);
593static int nla_client_recv_early_user_auth(rdpNla* nla)
597 transport_set_early_user_auth_mode(nla->transport, FALSE);
598 nla_set_state(nla, NLA_STATE_AUTH_INFO);
602static int nla_client_recv(rdpNla* nla)
606 switch (nla_get_state(nla))
608 case NLA_STATE_NEGO_TOKEN:
609 return nla_client_recv_nego_token(nla);
611 case NLA_STATE_PUB_KEY_AUTH:
612 return nla_client_recv_pub_key_auth(nla);
614 case NLA_STATE_EARLY_USER_AUTH:
615 return nla_client_recv_early_user_auth(nla);
617 case NLA_STATE_FINAL:
619 WLog_ERR(TAG,
"NLA in invalid client receive state %s",
620 nla_get_state_str(nla_get_state(nla)));
625static int nla_client_authenticate(rdpNla* nla)
631 wStream* s = Stream_New(NULL, 4096);
635 WLog_ERR(TAG,
"Stream_New failed!");
639 if (nla_client_begin(nla) < 1)
642 while (nla_get_state(nla) < NLA_STATE_AUTH_INFO)
644 Stream_SetPosition(s, 0);
645 const int status = transport_read_pdu(nla->transport, s);
649 WLog_ERR(TAG,
"nla_client_authenticate failure");
653 const int status2 = nla_recv_pdu(nla, s);
661 Stream_Free(s, TRUE);
669static int nla_server_init(rdpNla* nla)
673 const BYTE* data = NULL;
675 if (!transport_get_public_key(nla->transport, &data, &length))
677 WLog_ERR(TAG,
"Failed to get public key");
681 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
683 WLog_ERR(TAG,
"Failed to allocate SecBuffer for public key");
687 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG, NULL))
690 if (!credssp_auth_setup_server(nla->auth))
693 nla_set_state(nla, NLA_STATE_INITIAL);
697static wStream* nla_server_recv_stream(rdpNla* nla)
704 s = Stream_New(NULL, 4096);
709 status = transport_read_pdu(nla->transport, s);
714 WLog_ERR(TAG,
"nla_recv() error: %d", status);
715 Stream_Free(s, TRUE);
722static BOOL nla_server_recv_credentials(rdpNla* nla)
726 if (nla_server_recv(nla) < 0)
729 if (!nla_decrypt_ts_credentials(nla))
732 if (!nla_impersonate(nla))
735 if (!nla_revert_to_self(nla))
748static int nla_server_authenticate(rdpNla* nla)
754 if (nla_server_init(nla) < 1)
763 credssp_auth_set_flags(nla->auth, ASC_REQ_MUTUAL_AUTH | ASC_REQ_CONFIDENTIALITY |
764 ASC_REQ_CONNECTION | ASC_REQ_USE_SESSION_KEY |
765 ASC_REQ_SEQUENCE_DETECT | ASC_REQ_EXTENDED_ERROR);
797 if (nla_server_recv(nla) < 0)
800 WLog_DBG(TAG,
"Receiving Authentication Token");
801 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
803 res = credssp_auth_authenticate(nla->auth);
810 switch (GetLastError())
812 case ERROR_PASSWORD_MUST_CHANGE:
813 nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
816 case ERROR_PASSWORD_EXPIRED:
817 nla->errorCode = STATUS_PASSWORD_EXPIRED;
820 case ERROR_ACCOUNT_DISABLED:
821 nla->errorCode = STATUS_ACCOUNT_DISABLED;
825 nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
837 if (credssp_auth_have_output_token(nla->auth))
842 if (nla_server_recv(nla) < 0)
845 WLog_DBG(TAG,
"Receiving pubkey Token");
848 if (nla->peerVersion < 5)
849 res = nla_decrypt_public_key_echo(nla);
851 res = nla_decrypt_public_key_hash(nla);
857 sspi_SecBufferFree(&nla->negoToken);
859 if (nla->peerVersion < 5)
860 res = nla_encrypt_public_key_echo(nla);
862 res = nla_encrypt_public_key_hash(nla);
869 WLog_DBG(TAG,
"Sending Authentication Token");
882 if (!nla_server_recv_credentials(nla))
886 nla_buffer_free(nla);
897int nla_authenticate(rdpNla* nla)
902 return nla_server_authenticate(nla);
904 return nla_client_authenticate(nla);
907static void ap_integer_increment_le(BYTE* number,
size_t size)
909 WINPR_ASSERT(number || (size == 0));
911 for (
size_t index = 0; index < size; index++)
913 if (number[index] < 0xFF)
926static void ap_integer_decrement_le(BYTE* number,
size_t size)
928 WINPR_ASSERT(number || (size == 0));
930 for (
size_t index = 0; index < size; index++)
932 if (number[index] > 0)
939 number[index] = 0xFF;
945BOOL nla_encrypt_public_key_echo(rdpNla* nla)
951 sspi_SecBufferFree(&nla->pubKeyAuth);
955 if (!sspi_SecBufferAlloc(&buf, nla->PublicKey.cbBuffer))
957 ap_integer_increment_le(buf.pvBuffer, buf.cbBuffer);
958 status = credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++);
959 sspi_SecBufferFree(&buf);
963 status = credssp_auth_encrypt(nla->auth, &nla->PublicKey, &nla->pubKeyAuth, NULL,
970BOOL nla_encrypt_public_key_hash(rdpNla* nla)
973 WINPR_DIGEST_CTX* sha256 = NULL;
978 const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
979 const size_t hashSize =
980 nla->server ?
sizeof(ServerClientHashMagic) : sizeof(ClientServerHashMagic);
982 if (!sspi_SecBufferAlloc(&buf, WINPR_SHA256_DIGEST_LENGTH))
986 if (!(sha256 = winpr_Digest_New()))
989 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
993 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
996 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1000 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1003 if (!winpr_Digest_Final(sha256, buf.pvBuffer, WINPR_SHA256_DIGEST_LENGTH))
1006 sspi_SecBufferFree(&nla->pubKeyAuth);
1007 if (!credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++))
1013 winpr_Digest_Free(sha256);
1014 sspi_SecBufferFree(&buf);
1018BOOL nla_decrypt_public_key_echo(rdpNla* nla)
1020 BOOL status = FALSE;
1026 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &public_key, nla->recvSeqNum++))
1032 ap_integer_decrement_le(public_key.pvBuffer, public_key.cbBuffer);
1035 if (public_key.cbBuffer != nla->PublicKey.cbBuffer ||
1036 memcmp(public_key.pvBuffer, nla->PublicKey.pvBuffer, public_key.cbBuffer) != 0)
1038 WLog_ERR(TAG,
"Could not verify server's public key echo");
1039#if defined(WITH_DEBUG_NLA)
1040 WLog_ERR(TAG,
"Expected (length = %" PRIu32
"):", nla->PublicKey.cbBuffer);
1041 winpr_HexDump(TAG, WLOG_ERROR, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer);
1042 WLog_ERR(TAG,
"Actual (length = %" PRIu32
"):", public_key.cbBuffer);
1043 winpr_HexDump(TAG, WLOG_ERROR, public_key.pvBuffer, public_key.cbBuffer);
1051 sspi_SecBufferFree(&public_key);
1055BOOL nla_decrypt_public_key_hash(rdpNla* nla)
1057 WINPR_DIGEST_CTX* sha256 = NULL;
1058 BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH] = { 0 };
1059 BOOL status = FALSE;
1063 const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
1064 const size_t hashSize =
1065 nla->server ?
sizeof(ClientServerHashMagic) : sizeof(ServerClientHashMagic);
1068 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &hash, nla->recvSeqNum++))
1072 if (!(sha256 = winpr_Digest_New()))
1075 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1079 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1082 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1086 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1089 if (!winpr_Digest_Final(sha256, serverClientHash,
sizeof(serverClientHash)))
1093 if (hash.cbBuffer != WINPR_SHA256_DIGEST_LENGTH ||
1094 memcmp(serverClientHash, hash.pvBuffer, WINPR_SHA256_DIGEST_LENGTH) != 0)
1096 WLog_ERR(TAG,
"Could not verify server's hash");
1103 winpr_Digest_Free(sha256);
1104 sspi_SecBufferFree(&hash);
1108static BOOL set_creds_octetstring_to_settings(
WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
1109 BOOL optional, FreeRDP_Settings_Keys_String settingId,
1110 rdpSettings* settings)
1114 WinPrAsn1_tagId itemTag = 0;
1115 if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != (ER_TAG_CONTEXTUAL | tagId)))
1124 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1128 value.len /
sizeof(WCHAR));
1131static BOOL nla_read_TSCspDataDetail(
WinPrAsn1Decoder* dec, rdpSettings* settings)
1136 WinPrAsn1_INTEGER keyspec = 0;
1137 if (!WinPrAsn1DecReadContextualInteger(dec, 0, &error, &keyspec))
1139 settings->KeySpec = (UINT32)keyspec;
1142 if (!set_creds_octetstring_to_settings(dec, 1, TRUE, FreeRDP_CardName, settings))
1146 if (!set_creds_octetstring_to_settings(dec, 2, TRUE, FreeRDP_ReaderName, settings))
1150 if (!set_creds_octetstring_to_settings(dec, 3, TRUE, FreeRDP_ContainerName, settings))
1154 return set_creds_octetstring_to_settings(dec, 4, TRUE, FreeRDP_CspName, settings);
1157static BOOL nla_messageTypeValid(UINT32 type)
1161 case KerbInvalidValue:
1162 case KerbInteractiveLogon:
1163 case KerbSmartCardLogon:
1164 case KerbWorkstationUnlockLogon:
1165 case KerbSmartCardUnlockLogon:
1166 case KerbProxyLogon:
1167 case KerbTicketLogon:
1168 case KerbTicketUnlockLogon:
1169#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0501)
1172#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
1173 case KerbCertificateLogon:
1174 case KerbCertificateS4ULogon:
1175 case KerbCertificateUnlockLogon:
1177#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0602)
1178 case KerbNoElevationLogon:
1183 WLog_ERR(TAG,
"Invalid message type %" PRIu32, type);
1188static BOOL nla_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1197 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1201 const UINT32 type = Stream_Get_UINT32(s);
1202 if (!nla_messageTypeValid(type))
1205 ticket->MessageType = (KERB_LOGON_SUBMIT_TYPE)type;
1207 Stream_Read_UINT32(s, ticket->Flags);
1208 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1209 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1211 if (ticket->MessageType != KerbTicketLogon)
1213 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1217 if (!Stream_CheckAndLogRequiredLength(
1218 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1226 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1227 Stream_Seek(s, ticket->ServiceTicketLength);
1232 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1236static BOOL nla_credentialTypeValid(UINT32 type)
1240 case InvalidCredKey:
1241 case DeprecatedIUMCredKey:
1242 case DomainUserCredKey:
1243 case LocalUserCredKey:
1244 case ExternallySuppliedCredKey:
1247 WLog_ERR(TAG,
"Invalid credential type %" PRIu32, type);
1252WINPR_ATTR_MALLOC(free, 1)
1260 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32 + 4))
1263 size_t pos = Stream_GetPosition(s);
1266 ULONG EncryptedCredsSize = Stream_Get_UINT32(s);
1267 if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize))
1270 Stream_SetPosition(s, pos);
1277 ret->Version = Stream_Get_UINT32(s);
1278 ret->Flags = Stream_Get_UINT32(s);
1279 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1281 const UINT32 val = Stream_Get_UINT32(s);
1282 if (!nla_credentialTypeValid(val))
1287 ret->CredentialKeyType = WINPR_ASSERTING_INT_CAST(MSV1_0_CREDENTIAL_KEY_TYPE, val);
1289 ret->EncryptedCredsSize = EncryptedCredsSize;
1290 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1301} RemoteGuardPackageCredType;
1303static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1304 RemoteGuardPackageCredType* credsType,
1310 char packageNameStr[100] = { 0 };
1314 WINPR_ASSERT(credsType);
1315 WINPR_ASSERT(payload);
1317 *credsType = RCG_TYPE_NONE;
1320 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1323 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1324 packageNameStr,
sizeof(packageNameStr));
1325 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1328 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1331 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1333 *credsType = RCG_TYPE_KERB;
1335 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1337 *credsType = RCG_TYPE_NTLM;
1341 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1345 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1352 TSCREDS_INVALID = 0,
1353 TSCREDS_USER_PASSWD = 1,
1354 TSCREDS_SMARTCARD = 2,
1355 TSCREDS_REMOTEGUARD = 6
1358static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1364 WinPrAsn1_INTEGER credType = -1;
1370 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1373 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1378 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1382 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1385 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1387 rdpSettings* settings = nla->rdpcontext->settings;
1388 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1389 credType != TSCREDS_REMOTEGUARD)
1391 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1397 case TSCREDS_USER_PASSWD:
1400 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1405 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1409 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1413 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1415 case TSCREDS_SMARTCARD:
1418 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1423 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1425 settings->PasswordIsSmartcardPin = TRUE;
1429 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1431 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1435 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1439 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1441 case TSCREDS_REMOTEGUARD:
1444 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1450 .ServiceTicketLength = 0,
1451 .TicketGrantingTicketLength = 0,
1452 .ServiceTicket = NULL,
1453 .TicketGrantingTicket = NULL };
1457 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1460 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1462 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1465 if (logonCredsType != RCG_TYPE_KERB)
1467 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1471 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1473 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1481 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1482 Stream_GetRemainingLength(&suppCredsSeq.source))
1485 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1488 RemoteGuardPackageCredType suppCredsType = RCG_TYPE_NONE;
1490 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1494 if (suppCredsType != RCG_TYPE_NTLM)
1496 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1500 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1503 WLog_ERR(TAG,
"invalid supplementalCreds");
1509 WLog_ERR(TAG,
"invalid supplementalCreds");
1513 freerdp_peer* peer = nla->rdpcontext->peer;
1514 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1519 WLog_DBG(TAG,
"TSCredentials type %d not supported for now", credType);
1529 WINPR_ASSERT(ticket);
1531 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1532 ticket->TicketGrantingTicketLength))
1535 Stream_Write_UINT32(s, KerbTicketLogon);
1536 Stream_Write_UINT32(s, ticket->Flags);
1537 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1538 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1540 Stream_Write_UINT64(s, 0x20);
1541 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1543 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1544 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1548static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1551 WINPR_ASSERT(logonTicket);
1553 SecurityFunctionTable* table = NULL;
1555 credssp_auth_tableAndContext(nla->auth, &table, &context);
1556 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1560static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1564 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1565 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1570 logonTicket.ServiceTicket = NULL;
1571 logonTicket.TicketGrantingTicket = NULL;
1574 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1578 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1581 s = Stream_New(NULL, 2000);
1585 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1588 credBuffer.len = Stream_GetPosition(s);
1589 credBuffer.data = Stream_Buffer(s);
1590 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1593 free(logonTicket.ServiceTicket);
1594 free(logonTicket.TicketGrantingTicket);
1595 Stream_Free(s, TRUE);
1599static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1604 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1608 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1612 wStream* s = Stream_New(NULL, 300);
1616 Stream_Write_UINT32(s, pntlm->Version);
1617 Stream_Write_UINT32(s, pntlm->Flags);
1619 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1620 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1621 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1622 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1623 Stream_Zero(s, 6 + 16 * 4 + 14);
1627 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1631 Stream_Free(s, TRUE);
1635static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1639 WinPrAsn1_tagId tag;
1640 FreeRDP_Settings_Keys_String setting_id;
1641 } cspData_fields[] = { { 1, FreeRDP_CardName },
1642 { 2, FreeRDP_ReaderName },
1643 { 3, FreeRDP_ContainerName },
1644 { 4, FreeRDP_CspName } };
1649 WINPR_ASSERT(nla->rdpcontext);
1651 const rdpSettings* settings = nla->rdpcontext->settings;
1652 WINPR_ASSERT(settings);
1655 if (!WinPrAsn1EncSeqContainer(enc))
1662 octet_string.len = ss *
sizeof(WCHAR);
1663 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1664 free(octet_string.data);
1669 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1673 if (!WinPrAsn1EncContextualInteger(
1675 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1679 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1684 settings, cspData_fields[i].setting_id, &len);
1685 octet_string.len = len *
sizeof(WCHAR);
1686 if (octet_string.len)
1689 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1690 free(octet_string.data);
1697 if (!WinPrAsn1EncEndContainer(enc))
1705 octet_string.len = ss *
sizeof(WCHAR);
1706 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1707 free(octet_string.data);
1717 octet_string.len = ss *
sizeof(WCHAR);
1718 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1719 free(octet_string.data);
1725 return WinPrAsn1EncEndContainer(enc) != 0;
1728static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1736 WINPR_ASSERT(nla->rdpcontext);
1738 const rdpSettings* settings = nla->rdpcontext->settings;
1739 WINPR_ASSERT(settings);
1742 if (!WinPrAsn1EncSeqContainer(enc))
1745 if (!settings->DisableCredentialsDelegation && nla->identity)
1747 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1748 username.data = (BYTE*)nla->identity->User;
1750 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1751 domain.data = (BYTE*)nla->identity->Domain;
1753 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1754 password.data = (BYTE*)nla->identity->Password;
1757 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1759 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1761 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1765 return WinPrAsn1EncEndContainer(enc) != 0;
1768static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1774 if (!WinPrAsn1EncSeqContainer(enc))
1778 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1781 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1789 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1792 if (!WinPrAsn1EncSeqContainer(enc))
1795 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1798 if (!WinPrAsn1EncEndContainer(enc))
1801 if (!WinPrAsn1EncEndContainer(enc))
1806 return WinPrAsn1EncEndContainer(enc) != 0;
1816static BOOL nla_encode_ts_credentials(rdpNla* nla)
1819 WinPrAsn1Encoder* enc = NULL;
1822 TsCredentialsType credType = TSCREDS_INVALID;
1825 WINPR_ASSERT(nla->rdpcontext);
1827 rdpSettings* settings = nla->rdpcontext->settings;
1828 WINPR_ASSERT(settings);
1830 if (settings->RemoteCredentialGuard)
1831 credType = TSCREDS_REMOTEGUARD;
1832 else if (settings->SmartcardLogon)
1833 credType = TSCREDS_SMARTCARD;
1835 credType = TSCREDS_USER_PASSWD;
1837 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1842 if (!WinPrAsn1EncSeqContainer(enc))
1846 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1850 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1855 case TSCREDS_SMARTCARD:
1856 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1860 case TSCREDS_USER_PASSWD:
1861 if (!nla_encode_ts_password_credentials(nla, enc))
1865 case TSCREDS_REMOTEGUARD:
1866 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1874 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1877 if (!WinPrAsn1EncStreamSize(enc, &length))
1880 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1882 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1886 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1888 ret = WinPrAsn1EncToStream(enc, &s);
1891 WinPrAsn1Encoder_Free(&enc);
1895static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1899 if (!nla_encode_ts_credentials(nla))
1902 sspi_SecBufferFree(&nla->authInfo);
1903 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1910static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1914 if (nla->authInfo.cbBuffer < 1)
1916 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1920 sspi_SecBufferFree(&nla->tsCredentials);
1921 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1924 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1930static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1931 WinPrAsn1_tagId tagId,
const char* msg)
1936 WINPR_ASSERT(buffer);
1939 if (buffer->cbBuffer > 0)
1944 WLog_DBG(TAG,
" ----->> %s", msg);
1945 octet_string.data = buffer->pvBuffer;
1946 octet_string.len = buffer->cbBuffer;
1947 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1955static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1956 WinPrAsn1_tagId tagId,
const char* msg)
1958 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1959 sspi_SecBufferFree(buffer);
1971BOOL nla_send(rdpNla* nla)
1976 WinPrAsn1Encoder* enc = NULL;
1980 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1985 WLog_DBG(TAG,
"----->> sending...");
1986 if (!WinPrAsn1EncSeqContainer(enc))
1990 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1991 if (!WinPrAsn1EncContextualInteger(enc, 0,
1992 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1996 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1998 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
2000 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
2004 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
2008 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
2013 if (nla->authInfo.cbBuffer > 0)
2015 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
2020 if (nla->pubKeyAuth.cbBuffer > 0)
2022 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
2027 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
2029 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2030 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2031 if (!WinPrAsn1EncContextualInteger(
2032 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
2037 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
2039 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
2044 if (!WinPrAsn1EncEndContainer(enc))
2047 if (!WinPrAsn1EncStreamSize(enc, &length))
2050 s = Stream_New(NULL, length);
2054 if (!WinPrAsn1EncToStream(enc, s))
2057 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
2058 if (transport_write(nla->transport, s) < 0)
2063 Stream_Free(s, TRUE);
2064 WinPrAsn1Encoder_Free(&enc);
2068static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
2073 WinPrAsn1_tagId tag = { 0 };
2074 WinPrAsn1_INTEGER val = { 0 };
2080 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
2082 WLog_DBG(TAG,
"<<----- receiving...");
2085 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
2091 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
2094 if (!Stream_SafeSeek(s, offset))
2097 version = (UINT)val;
2098 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
2100 if (nla->peerVersion == 0)
2101 nla->peerVersion = version;
2104 if (nla->peerVersion != version)
2106 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
2107 nla->peerVersion, version);
2111 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
2119 WLog_DBG(TAG,
" <<----- nego token");
2121 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
2122 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
2125 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
2129 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
2134 WLog_DBG(TAG,
" <<----- auth info");
2136 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2138 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
2143 WLog_DBG(TAG,
" <<----- public key auth");
2145 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2147 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
2153 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
2155 nla->errorCode = val;
2156 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2157 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2160 WLog_DBG(TAG,
" <<----- client nonce");
2162 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2164 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
2176int nla_recv_pdu(rdpNla* nla,
wStream* s)
2181 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
2184 Stream_Read_UINT32(s, code);
2185 if (code != AUTHZ_SUCCESS)
2187 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
2188 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2189 freerdp_set_last_error_log(nla->rdpcontext, code);
2193 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2197 if (nla_decode_ts_request(nla, s) < 1)
2204 switch (nla->errorCode)
2206 case STATUS_PASSWORD_MUST_CHANGE:
2207 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2210 case STATUS_PASSWORD_EXPIRED:
2211 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2214 case STATUS_ACCOUNT_DISABLED:
2215 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2218 case STATUS_LOGON_FAILURE:
2219 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2222 case STATUS_WRONG_PASSWORD:
2223 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2226 case STATUS_ACCESS_DENIED:
2227 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2230 case STATUS_ACCOUNT_RESTRICTION:
2231 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2234 case STATUS_ACCOUNT_LOCKED_OUT:
2235 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2238 case STATUS_ACCOUNT_EXPIRED:
2239 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2242 case STATUS_LOGON_TYPE_NOT_GRANTED:
2243 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2247 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIx32
"]",
2248 NtStatus2Tag(nla->errorCode),
2249 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2250 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2254 freerdp_set_last_error_log(nla->rdpcontext, code);
2259 return nla_client_recv(nla);
2262int nla_server_recv(rdpNla* nla)
2268 wStream* s = nla_server_recv_stream(nla);
2271 status = nla_decode_ts_request(nla, s);
2274 Stream_Free(s, TRUE);
2287rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2289 WINPR_ASSERT(transport);
2290 WINPR_ASSERT(context);
2292 rdpSettings* settings = context->settings;
2293 WINPR_ASSERT(settings);
2295 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2300 nla->rdpcontext = context;
2301 nla->server = settings->ServerMode;
2302 nla->transport = transport;
2303 nla->sendSeqNum = 0;
2304 nla->recvSeqNum = 0;
2306 nla->earlyUserAuth = FALSE;
2308 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2312 nla->auth = credssp_auth_new(context);
2317 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2321 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2326 WINPR_PRAGMA_DIAG_PUSH
2327 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2329 WINPR_PRAGMA_DIAG_POP
2338void nla_free(rdpNla* nla)
2343 smartcardCertInfo_Free(nla->smartcardCert);
2344 nla_buffer_free(nla);
2345 sspi_SecBufferFree(&nla->tsCredentials);
2346 credssp_auth_free(nla->auth);
2348 sspi_FreeAuthIdentity(nla->identity);
2349 free(nla->pkinitArgs);
2350 free(nla->identity);
2354SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2359 return nla->identity;
2362NLA_STATE nla_get_state(
const rdpNla* nla)
2365 return NLA_STATE_FINAL;
2370BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2375 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2380BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2382 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2387BOOL nla_impersonate(rdpNla* nla)
2389 return credssp_auth_impersonate(nla->auth);
2392BOOL nla_revert_to_self(rdpNla* nla)
2394 return credssp_auth_revert_to_self(nla->auth);
2397const char* nla_get_state_str(NLA_STATE state)
2401 case NLA_STATE_INITIAL:
2402 return "NLA_STATE_INITIAL";
2403 case NLA_STATE_NEGO_TOKEN:
2404 return "NLA_STATE_NEGO_TOKEN";
2405 case NLA_STATE_PUB_KEY_AUTH:
2406 return "NLA_STATE_PUB_KEY_AUTH";
2407 case NLA_STATE_AUTH_INFO:
2408 return "NLA_STATE_AUTH_INFO";
2409 case NLA_STATE_POST_NEGO:
2410 return "NLA_STATE_POST_NEGO";
2411 case NLA_STATE_EARLY_USER_AUTH:
2412 return "NLA_STATE_EARLY_USER_AUTH";
2413 case NLA_STATE_FINAL:
2414 return "NLA_STATE_FINAL";
2420DWORD nla_get_error(
const rdpNla* nla)
2423 return ERROR_INTERNAL_ERROR;
2424 return (UINT32)nla->errorCode;
2427INT32 nla_get_sspi_error(
const rdpNla* nla)
2430 return credssp_auth_sspi_error(nla->auth);
2436 WINPR_ASSERT(inBuffer);
2437 WINPR_ASSERT(outBuffer);
2438 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2444 WINPR_ASSERT(inBuffer);
2445 WINPR_ASSERT(outBuffer);
2446 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2449SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2453 SecurityFunctionTable* table = NULL;
2455 credssp_auth_tableAndContext(nla->auth, &table, &context);
2457 return table->QueryContextAttributes(&context, ulAttr, pBuffer);
2460SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer)
2464 SecurityFunctionTable* table = NULL;
2466 credssp_auth_tableAndContext(nla->auth, &table, &context);
2468 return table->FreeContextBuffer(pBuffer);
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
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.
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 UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD 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.
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.