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_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1166 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1169 Stream_Read_UINT32(s, ticket->MessageType);
1170 Stream_Read_UINT32(s, ticket->Flags);
1171 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1172 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1174 if (ticket->MessageType != KerbTicketLogon)
1176 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1180 if (!Stream_CheckAndLogRequiredLength(
1181 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1189 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1190 Stream_Seek(s, ticket->ServiceTicketLength);
1195 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1199WINPR_ATTR_MALLOC(free, 1)
1206 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32 + 4))
1209 size_t pos = Stream_GetPosition(s);
1212 ULONG EncryptedCredsSize = Stream_Get_UINT32(s);
1213 if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize))
1216 Stream_SetPosition(s, pos);
1223 ret->Version = Stream_Get_UINT32(s);
1224 ret->Flags = Stream_Get_UINT32(s);
1225 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1226 ret->CredentialKeyType = Stream_Get_UINT32(s);
1227 ret->EncryptedCredsSize = EncryptedCredsSize;
1228 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1239} RemoteGuardPackageCredType;
1241static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1242 RemoteGuardPackageCredType* credsType,
1248 char packageNameStr[100] = { 0 };
1252 WINPR_ASSERT(credsType);
1253 WINPR_ASSERT(payload);
1255 *credsType = RCG_TYPE_NONE;
1258 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1261 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1262 packageNameStr,
sizeof(packageNameStr));
1263 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1266 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1269 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1271 *credsType = RCG_TYPE_KERB;
1273 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1275 *credsType = RCG_TYPE_NTLM;
1279 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1283 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1290 TSCREDS_INVALID = 0,
1291 TSCREDS_USER_PASSWD = 1,
1292 TSCREDS_SMARTCARD = 2,
1293 TSCREDS_REMOTEGUARD = 6
1296static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1302 WinPrAsn1_INTEGER credType = -1;
1308 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1311 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1316 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1320 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1323 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1325 rdpSettings* settings = nla->rdpcontext->settings;
1326 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1327 credType != TSCREDS_REMOTEGUARD)
1329 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1335 case TSCREDS_USER_PASSWD:
1338 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1343 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1347 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1351 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1353 case TSCREDS_SMARTCARD:
1356 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1361 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1363 settings->PasswordIsSmartcardPin = TRUE;
1367 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1369 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1373 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1377 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1379 case TSCREDS_REMOTEGUARD:
1382 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1388 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1391 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1393 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1396 if (logonCredsType != RCG_TYPE_KERB)
1398 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1402 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1404 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1412 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1413 Stream_GetRemainingLength(&suppCredsSeq.source))
1416 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1419 RemoteGuardPackageCredType suppCredsType = { 0 };
1421 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1425 if (suppCredsType != RCG_TYPE_NTLM)
1427 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1431 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1434 WLog_ERR(TAG,
"invalid supplementalCreds");
1440 WLog_ERR(TAG,
"invalid supplementalCreds");
1444 freerdp_peer* peer = nla->rdpcontext->peer;
1445 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1450 WLog_DBG(TAG,
"TSCredentials type " PRIu32
" not supported for now", credType);
1460 WINPR_ASSERT(ticket);
1462 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1463 ticket->TicketGrantingTicketLength))
1466 Stream_Write_UINT32(s, KerbTicketLogon);
1467 Stream_Write_UINT32(s, ticket->Flags);
1468 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1469 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1471 Stream_Write_UINT64(s, 0x20);
1472 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1474 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1475 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1479static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1482 WINPR_ASSERT(logonTicket);
1484 SecurityFunctionTable* table = NULL;
1486 credssp_auth_tableAndContext(nla->auth, &table, &context);
1487 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1491static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1495 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1496 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1501 logonTicket.ServiceTicket = NULL;
1502 logonTicket.TicketGrantingTicket = NULL;
1505 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1509 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1512 s = Stream_New(NULL, 2000);
1516 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1519 credBuffer.len = Stream_GetPosition(s);
1520 credBuffer.data = Stream_Buffer(s);
1521 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1524 free(logonTicket.ServiceTicket);
1525 free(logonTicket.TicketGrantingTicket);
1526 Stream_Free(s, TRUE);
1530static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1535 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1539 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1543 wStream* s = Stream_New(NULL, 300);
1547 Stream_Write_UINT32(s, pntlm->Version);
1548 Stream_Write_UINT32(s, pntlm->Flags);
1550 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1551 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1552 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1553 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1554 Stream_Zero(s, 6 + 16 * 4 + 14);
1557 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1560 Stream_Free(s, TRUE);
1564static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1568 WinPrAsn1_tagId tag;
1569 FreeRDP_Settings_Keys_String setting_id;
1570 } cspData_fields[] = { { 1, FreeRDP_CardName },
1571 { 2, FreeRDP_ReaderName },
1572 { 3, FreeRDP_ContainerName },
1573 { 4, FreeRDP_CspName } };
1578 WINPR_ASSERT(nla->rdpcontext);
1580 const rdpSettings* settings = nla->rdpcontext->settings;
1581 WINPR_ASSERT(settings);
1584 if (!WinPrAsn1EncSeqContainer(enc))
1591 octet_string.len = ss *
sizeof(WCHAR);
1592 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1593 free(octet_string.data);
1598 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1602 if (!WinPrAsn1EncContextualInteger(
1604 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1608 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1613 settings, cspData_fields[i].setting_id, &len);
1614 octet_string.len = len *
sizeof(WCHAR);
1615 if (octet_string.len)
1618 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1619 free(octet_string.data);
1626 if (!WinPrAsn1EncEndContainer(enc))
1634 octet_string.len = ss *
sizeof(WCHAR);
1635 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1636 free(octet_string.data);
1646 octet_string.len = ss *
sizeof(WCHAR);
1647 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1648 free(octet_string.data);
1654 return WinPrAsn1EncEndContainer(enc) != 0;
1657static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1665 WINPR_ASSERT(nla->rdpcontext);
1667 const rdpSettings* settings = nla->rdpcontext->settings;
1668 WINPR_ASSERT(settings);
1671 if (!WinPrAsn1EncSeqContainer(enc))
1674 if (!settings->DisableCredentialsDelegation && nla->identity)
1676 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1677 username.data = (BYTE*)nla->identity->User;
1679 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1680 domain.data = (BYTE*)nla->identity->Domain;
1682 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1683 password.data = (BYTE*)nla->identity->Password;
1686 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1688 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1690 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1694 return WinPrAsn1EncEndContainer(enc) != 0;
1697static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1703 if (!WinPrAsn1EncSeqContainer(enc))
1707 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1710 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1718 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1721 if (!WinPrAsn1EncSeqContainer(enc))
1724 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1727 if (!WinPrAsn1EncEndContainer(enc))
1730 if (!WinPrAsn1EncEndContainer(enc))
1735 return WinPrAsn1EncEndContainer(enc) != 0;
1745static BOOL nla_encode_ts_credentials(rdpNla* nla)
1748 WinPrAsn1Encoder* enc = NULL;
1751 TsCredentialsType credType = TSCREDS_INVALID;
1754 WINPR_ASSERT(nla->rdpcontext);
1756 rdpSettings* settings = nla->rdpcontext->settings;
1757 WINPR_ASSERT(settings);
1759 if (settings->RemoteCredentialGuard)
1760 credType = TSCREDS_REMOTEGUARD;
1761 else if (settings->SmartcardLogon)
1762 credType = TSCREDS_SMARTCARD;
1764 credType = TSCREDS_USER_PASSWD;
1766 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1771 if (!WinPrAsn1EncSeqContainer(enc))
1775 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1779 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1784 case TSCREDS_SMARTCARD:
1785 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1789 case TSCREDS_USER_PASSWD:
1790 if (!nla_encode_ts_password_credentials(nla, enc))
1794 case TSCREDS_REMOTEGUARD:
1795 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1803 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1806 if (!WinPrAsn1EncStreamSize(enc, &length))
1809 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1811 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1815 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1817 ret = WinPrAsn1EncToStream(enc, &s);
1820 WinPrAsn1Encoder_Free(&enc);
1824static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1828 if (!nla_encode_ts_credentials(nla))
1831 sspi_SecBufferFree(&nla->authInfo);
1832 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1839static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1843 if (nla->authInfo.cbBuffer < 1)
1845 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1849 sspi_SecBufferFree(&nla->tsCredentials);
1850 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1853 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1859static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1860 WinPrAsn1_tagId tagId,
const char* msg)
1865 WINPR_ASSERT(buffer);
1868 if (buffer->cbBuffer > 0)
1873 WLog_DBG(TAG,
" ----->> %s", msg);
1874 octet_string.data = buffer->pvBuffer;
1875 octet_string.len = buffer->cbBuffer;
1876 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1884static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1885 WinPrAsn1_tagId tagId,
const char* msg)
1887 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1888 sspi_SecBufferFree(buffer);
1900BOOL nla_send(rdpNla* nla)
1905 WinPrAsn1Encoder* enc = NULL;
1909 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1914 WLog_DBG(TAG,
"----->> sending...");
1915 if (!WinPrAsn1EncSeqContainer(enc))
1919 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1920 if (!WinPrAsn1EncContextualInteger(enc, 0,
1921 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1925 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1927 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1929 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
1933 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
1937 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1942 if (nla->authInfo.cbBuffer > 0)
1944 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
1949 if (nla->pubKeyAuth.cbBuffer > 0)
1951 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
1956 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
1958 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1960 if (!WinPrAsn1EncContextualInteger(
1961 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
1966 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
1968 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
1973 if (!WinPrAsn1EncEndContainer(enc))
1976 if (!WinPrAsn1EncStreamSize(enc, &length))
1979 s = Stream_New(NULL, length);
1983 if (!WinPrAsn1EncToStream(enc, s))
1986 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
1987 if (transport_write(nla->transport, s) < 0)
1992 Stream_Free(s, TRUE);
1993 WinPrAsn1Encoder_Free(&enc);
1997static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
2002 WinPrAsn1_tagId tag = { 0 };
2003 WinPrAsn1_INTEGER val = { 0 };
2009 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
2011 WLog_DBG(TAG,
"<<----- receiving...");
2014 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
2020 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
2023 if (!Stream_SafeSeek(s, offset))
2026 version = (UINT)val;
2027 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
2029 if (nla->peerVersion == 0)
2030 nla->peerVersion = version;
2033 if (nla->peerVersion != version)
2035 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
2036 nla->peerVersion, version);
2040 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
2048 WLog_DBG(TAG,
" <<----- nego token");
2050 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
2051 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
2054 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
2058 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
2063 WLog_DBG(TAG,
" <<----- auth info");
2065 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2067 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
2072 WLog_DBG(TAG,
" <<----- public key auth");
2074 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2076 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
2082 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
2084 nla->errorCode = val;
2085 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2089 WLog_DBG(TAG,
" <<----- client nonce");
2091 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2093 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
2105int nla_recv_pdu(rdpNla* nla,
wStream* s)
2110 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
2113 Stream_Read_UINT32(s, code);
2114 if (code != AUTHZ_SUCCESS)
2116 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
2117 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2118 freerdp_set_last_error_log(nla->rdpcontext, code);
2122 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2126 if (nla_decode_ts_request(nla, s) < 1)
2133 switch (nla->errorCode)
2135 case STATUS_PASSWORD_MUST_CHANGE:
2136 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2139 case STATUS_PASSWORD_EXPIRED:
2140 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2143 case STATUS_ACCOUNT_DISABLED:
2144 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2147 case STATUS_LOGON_FAILURE:
2148 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2151 case STATUS_WRONG_PASSWORD:
2152 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2155 case STATUS_ACCESS_DENIED:
2156 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2159 case STATUS_ACCOUNT_RESTRICTION:
2160 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2163 case STATUS_ACCOUNT_LOCKED_OUT:
2164 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2167 case STATUS_ACCOUNT_EXPIRED:
2168 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2171 case STATUS_LOGON_TYPE_NOT_GRANTED:
2172 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2176 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32
"]",
2177 NtStatus2Tag(nla->errorCode), nla->errorCode);
2178 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2182 freerdp_set_last_error_log(nla->rdpcontext, code);
2187 return nla_client_recv(nla);
2190int nla_server_recv(rdpNla* nla)
2196 wStream* s = nla_server_recv_stream(nla);
2199 status = nla_decode_ts_request(nla, s);
2202 Stream_Free(s, TRUE);
2215rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2217 WINPR_ASSERT(transport);
2218 WINPR_ASSERT(context);
2220 rdpSettings* settings = context->settings;
2221 WINPR_ASSERT(settings);
2223 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2228 nla->rdpcontext = context;
2229 nla->server = settings->ServerMode;
2230 nla->transport = transport;
2231 nla->sendSeqNum = 0;
2232 nla->recvSeqNum = 0;
2234 nla->earlyUserAuth = FALSE;
2236 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2240 nla->auth = credssp_auth_new(context);
2245 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2249 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2254 WINPR_PRAGMA_DIAG_PUSH
2255 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2257 WINPR_PRAGMA_DIAG_POP
2266void nla_free(rdpNla* nla)
2271 smartcardCertInfo_Free(nla->smartcardCert);
2272 nla_buffer_free(nla);
2273 sspi_SecBufferFree(&nla->tsCredentials);
2274 credssp_auth_free(nla->auth);
2276 sspi_FreeAuthIdentity(nla->identity);
2277 free(nla->pkinitArgs);
2278 free(nla->identity);
2282SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2287 return nla->identity;
2290NLA_STATE nla_get_state(
const rdpNla* nla)
2293 return NLA_STATE_FINAL;
2298BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2303 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2308BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2310 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2315BOOL nla_impersonate(rdpNla* nla)
2317 return credssp_auth_impersonate(nla->auth);
2320BOOL nla_revert_to_self(rdpNla* nla)
2322 return credssp_auth_revert_to_self(nla->auth);
2325const char* nla_get_state_str(NLA_STATE state)
2329 case NLA_STATE_INITIAL:
2330 return "NLA_STATE_INITIAL";
2331 case NLA_STATE_NEGO_TOKEN:
2332 return "NLA_STATE_NEGO_TOKEN";
2333 case NLA_STATE_PUB_KEY_AUTH:
2334 return "NLA_STATE_PUB_KEY_AUTH";
2335 case NLA_STATE_AUTH_INFO:
2336 return "NLA_STATE_AUTH_INFO";
2337 case NLA_STATE_POST_NEGO:
2338 return "NLA_STATE_POST_NEGO";
2339 case NLA_STATE_EARLY_USER_AUTH:
2340 return "NLA_STATE_EARLY_USER_AUTH";
2341 case NLA_STATE_FINAL:
2342 return "NLA_STATE_FINAL";
2348DWORD nla_get_error(
const rdpNla* nla)
2351 return ERROR_INTERNAL_ERROR;
2352 return (UINT32)nla->errorCode;
2355INT32 nla_get_sspi_error(
const rdpNla* nla)
2358 return credssp_auth_sspi_error(nla->auth);
2364 WINPR_ASSERT(inBuffer);
2365 WINPR_ASSERT(outBuffer);
2366 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2372 WINPR_ASSERT(inBuffer);
2373 WINPR_ASSERT(outBuffer);
2374 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2377SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2381 SecurityFunctionTable* table = NULL;
2383 credssp_auth_tableAndContext(nla->auth, &table, &context);
2385 return table->QueryContextAttributes(&context, ulAttr, pBuffer);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
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.
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.
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.
FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.