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)
1259 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32 + 4))
1262 size_t pos = Stream_GetPosition(s);
1265 ULONG EncryptedCredsSize = Stream_Get_UINT32(s);
1266 if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize))
1269 Stream_SetPosition(s, pos);
1276 ret->Version = Stream_Get_UINT32(s);
1277 ret->Flags = Stream_Get_UINT32(s);
1278 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1280 const UINT32 val = Stream_Get_UINT32(s);
1281 if (!nla_credentialTypeValid(val))
1286 ret->CredentialKeyType = WINPR_ASSERTING_INT_CAST(MSV1_0_CREDENTIAL_KEY_TYPE, val);
1288 ret->EncryptedCredsSize = EncryptedCredsSize;
1289 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1300} RemoteGuardPackageCredType;
1302static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1303 RemoteGuardPackageCredType* credsType,
1309 char packageNameStr[100] = { 0 };
1313 WINPR_ASSERT(credsType);
1314 WINPR_ASSERT(payload);
1316 *credsType = RCG_TYPE_NONE;
1319 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1322 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1323 packageNameStr,
sizeof(packageNameStr));
1324 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1327 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1330 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1332 *credsType = RCG_TYPE_KERB;
1334 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1336 *credsType = RCG_TYPE_NTLM;
1340 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1344 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1351 TSCREDS_INVALID = 0,
1352 TSCREDS_USER_PASSWD = 1,
1353 TSCREDS_SMARTCARD = 2,
1354 TSCREDS_REMOTEGUARD = 6
1357static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1363 WinPrAsn1_INTEGER credType = -1;
1369 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1372 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1377 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1381 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1384 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1386 rdpSettings* settings = nla->rdpcontext->settings;
1387 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1388 credType != TSCREDS_REMOTEGUARD)
1390 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1396 case TSCREDS_USER_PASSWD:
1399 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1404 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1408 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1412 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1414 case TSCREDS_SMARTCARD:
1417 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1422 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1424 settings->PasswordIsSmartcardPin = TRUE;
1428 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1430 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1434 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1438 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1440 case TSCREDS_REMOTEGUARD:
1443 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1449 .ServiceTicketLength = 0,
1450 .TicketGrantingTicketLength = 0,
1451 .ServiceTicket = NULL,
1452 .TicketGrantingTicket = NULL };
1456 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1459 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1461 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1464 if (logonCredsType != RCG_TYPE_KERB)
1466 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1470 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1472 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1480 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1481 Stream_GetRemainingLength(&suppCredsSeq.source))
1484 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1487 RemoteGuardPackageCredType suppCredsType = RCG_TYPE_NONE;
1489 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1493 if (suppCredsType != RCG_TYPE_NTLM)
1495 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1499 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1502 WLog_ERR(TAG,
"invalid supplementalCreds");
1508 WLog_ERR(TAG,
"invalid supplementalCreds");
1512 freerdp_peer* peer = nla->rdpcontext->peer;
1513 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1518 WLog_DBG(TAG,
"TSCredentials type " PRIu32
" not supported for now", credType);
1528 WINPR_ASSERT(ticket);
1530 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1531 ticket->TicketGrantingTicketLength))
1534 Stream_Write_UINT32(s, KerbTicketLogon);
1535 Stream_Write_UINT32(s, ticket->Flags);
1536 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1537 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1539 Stream_Write_UINT64(s, 0x20);
1540 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1542 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1543 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1547static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1550 WINPR_ASSERT(logonTicket);
1552 SecurityFunctionTable* table = NULL;
1554 credssp_auth_tableAndContext(nla->auth, &table, &context);
1555 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1559static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1563 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1564 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1569 logonTicket.ServiceTicket = NULL;
1570 logonTicket.TicketGrantingTicket = NULL;
1573 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1577 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1580 s = Stream_New(NULL, 2000);
1584 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1587 credBuffer.len = Stream_GetPosition(s);
1588 credBuffer.data = Stream_Buffer(s);
1589 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1592 free(logonTicket.ServiceTicket);
1593 free(logonTicket.TicketGrantingTicket);
1594 Stream_Free(s, TRUE);
1598static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1603 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1607 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1611 wStream* s = Stream_New(NULL, 300);
1615 Stream_Write_UINT32(s, pntlm->Version);
1616 Stream_Write_UINT32(s, pntlm->Flags);
1618 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1619 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1620 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1621 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1622 Stream_Zero(s, 6 + 16 * 4 + 14);
1626 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1630 Stream_Free(s, TRUE);
1634static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1638 WinPrAsn1_tagId tag;
1639 FreeRDP_Settings_Keys_String setting_id;
1640 } cspData_fields[] = { { 1, FreeRDP_CardName },
1641 { 2, FreeRDP_ReaderName },
1642 { 3, FreeRDP_ContainerName },
1643 { 4, FreeRDP_CspName } };
1648 WINPR_ASSERT(nla->rdpcontext);
1650 const rdpSettings* settings = nla->rdpcontext->settings;
1651 WINPR_ASSERT(settings);
1654 if (!WinPrAsn1EncSeqContainer(enc))
1661 octet_string.len = ss *
sizeof(WCHAR);
1662 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1663 free(octet_string.data);
1668 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1672 if (!WinPrAsn1EncContextualInteger(
1674 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1678 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1683 settings, cspData_fields[i].setting_id, &len);
1684 octet_string.len = len *
sizeof(WCHAR);
1685 if (octet_string.len)
1688 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1689 free(octet_string.data);
1696 if (!WinPrAsn1EncEndContainer(enc))
1704 octet_string.len = ss *
sizeof(WCHAR);
1705 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1706 free(octet_string.data);
1716 octet_string.len = ss *
sizeof(WCHAR);
1717 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1718 free(octet_string.data);
1724 return WinPrAsn1EncEndContainer(enc) != 0;
1727static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1735 WINPR_ASSERT(nla->rdpcontext);
1737 const rdpSettings* settings = nla->rdpcontext->settings;
1738 WINPR_ASSERT(settings);
1741 if (!WinPrAsn1EncSeqContainer(enc))
1744 if (!settings->DisableCredentialsDelegation && nla->identity)
1746 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1747 username.data = (BYTE*)nla->identity->User;
1749 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1750 domain.data = (BYTE*)nla->identity->Domain;
1752 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1753 password.data = (BYTE*)nla->identity->Password;
1756 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1758 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1760 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1764 return WinPrAsn1EncEndContainer(enc) != 0;
1767static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1773 if (!WinPrAsn1EncSeqContainer(enc))
1777 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1780 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1788 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1791 if (!WinPrAsn1EncSeqContainer(enc))
1794 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1797 if (!WinPrAsn1EncEndContainer(enc))
1800 if (!WinPrAsn1EncEndContainer(enc))
1805 return WinPrAsn1EncEndContainer(enc) != 0;
1815static BOOL nla_encode_ts_credentials(rdpNla* nla)
1818 WinPrAsn1Encoder* enc = NULL;
1821 TsCredentialsType credType = TSCREDS_INVALID;
1824 WINPR_ASSERT(nla->rdpcontext);
1826 rdpSettings* settings = nla->rdpcontext->settings;
1827 WINPR_ASSERT(settings);
1829 if (settings->RemoteCredentialGuard)
1830 credType = TSCREDS_REMOTEGUARD;
1831 else if (settings->SmartcardLogon)
1832 credType = TSCREDS_SMARTCARD;
1834 credType = TSCREDS_USER_PASSWD;
1836 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1841 if (!WinPrAsn1EncSeqContainer(enc))
1845 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1849 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1854 case TSCREDS_SMARTCARD:
1855 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1859 case TSCREDS_USER_PASSWD:
1860 if (!nla_encode_ts_password_credentials(nla, enc))
1864 case TSCREDS_REMOTEGUARD:
1865 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1873 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1876 if (!WinPrAsn1EncStreamSize(enc, &length))
1879 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1881 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1885 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1887 ret = WinPrAsn1EncToStream(enc, &s);
1890 WinPrAsn1Encoder_Free(&enc);
1894static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1898 if (!nla_encode_ts_credentials(nla))
1901 sspi_SecBufferFree(&nla->authInfo);
1902 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1909static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1913 if (nla->authInfo.cbBuffer < 1)
1915 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1919 sspi_SecBufferFree(&nla->tsCredentials);
1920 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1923 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1929static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1930 WinPrAsn1_tagId tagId,
const char* msg)
1935 WINPR_ASSERT(buffer);
1938 if (buffer->cbBuffer > 0)
1943 WLog_DBG(TAG,
" ----->> %s", msg);
1944 octet_string.data = buffer->pvBuffer;
1945 octet_string.len = buffer->cbBuffer;
1946 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1954static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1955 WinPrAsn1_tagId tagId,
const char* msg)
1957 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1958 sspi_SecBufferFree(buffer);
1970BOOL nla_send(rdpNla* nla)
1975 WinPrAsn1Encoder* enc = NULL;
1979 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1984 WLog_DBG(TAG,
"----->> sending...");
1985 if (!WinPrAsn1EncSeqContainer(enc))
1989 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1990 if (!WinPrAsn1EncContextualInteger(enc, 0,
1991 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1995 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1997 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1999 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
2003 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
2007 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
2012 if (nla->authInfo.cbBuffer > 0)
2014 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
2019 if (nla->pubKeyAuth.cbBuffer > 0)
2021 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
2026 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
2028 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2030 if (!WinPrAsn1EncContextualInteger(
2031 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
2036 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
2038 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
2043 if (!WinPrAsn1EncEndContainer(enc))
2046 if (!WinPrAsn1EncStreamSize(enc, &length))
2049 s = Stream_New(NULL, length);
2053 if (!WinPrAsn1EncToStream(enc, s))
2056 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
2057 if (transport_write(nla->transport, s) < 0)
2062 Stream_Free(s, TRUE);
2063 WinPrAsn1Encoder_Free(&enc);
2067static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
2072 WinPrAsn1_tagId tag = { 0 };
2073 WinPrAsn1_INTEGER val = { 0 };
2079 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
2081 WLog_DBG(TAG,
"<<----- receiving...");
2084 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
2090 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
2093 if (!Stream_SafeSeek(s, offset))
2096 version = (UINT)val;
2097 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
2099 if (nla->peerVersion == 0)
2100 nla->peerVersion = version;
2103 if (nla->peerVersion != version)
2105 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
2106 nla->peerVersion, version);
2110 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
2118 WLog_DBG(TAG,
" <<----- nego token");
2120 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
2121 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
2124 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
2128 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
2133 WLog_DBG(TAG,
" <<----- auth info");
2135 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2137 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
2142 WLog_DBG(TAG,
" <<----- public key auth");
2144 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2146 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
2152 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
2154 nla->errorCode = val;
2155 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2159 WLog_DBG(TAG,
" <<----- client nonce");
2161 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2163 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
2175int nla_recv_pdu(rdpNla* nla,
wStream* s)
2180 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
2183 Stream_Read_UINT32(s, code);
2184 if (code != AUTHZ_SUCCESS)
2186 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
2187 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2188 freerdp_set_last_error_log(nla->rdpcontext, code);
2192 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2196 if (nla_decode_ts_request(nla, s) < 1)
2203 switch (nla->errorCode)
2205 case STATUS_PASSWORD_MUST_CHANGE:
2206 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2209 case STATUS_PASSWORD_EXPIRED:
2210 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2213 case STATUS_ACCOUNT_DISABLED:
2214 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2217 case STATUS_LOGON_FAILURE:
2218 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2221 case STATUS_WRONG_PASSWORD:
2222 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2225 case STATUS_ACCESS_DENIED:
2226 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2229 case STATUS_ACCOUNT_RESTRICTION:
2230 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2233 case STATUS_ACCOUNT_LOCKED_OUT:
2234 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2237 case STATUS_ACCOUNT_EXPIRED:
2238 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2241 case STATUS_LOGON_TYPE_NOT_GRANTED:
2242 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2246 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32
"]",
2247 NtStatus2Tag(nla->errorCode), nla->errorCode);
2248 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2252 freerdp_set_last_error_log(nla->rdpcontext, code);
2257 return nla_client_recv(nla);
2260int nla_server_recv(rdpNla* nla)
2266 wStream* s = nla_server_recv_stream(nla);
2269 status = nla_decode_ts_request(nla, s);
2272 Stream_Free(s, TRUE);
2285rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2287 WINPR_ASSERT(transport);
2288 WINPR_ASSERT(context);
2290 rdpSettings* settings = context->settings;
2291 WINPR_ASSERT(settings);
2293 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2298 nla->rdpcontext = context;
2299 nla->server = settings->ServerMode;
2300 nla->transport = transport;
2301 nla->sendSeqNum = 0;
2302 nla->recvSeqNum = 0;
2304 nla->earlyUserAuth = FALSE;
2306 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2310 nla->auth = credssp_auth_new(context);
2315 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2319 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2324 WINPR_PRAGMA_DIAG_PUSH
2325 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2327 WINPR_PRAGMA_DIAG_POP
2336void nla_free(rdpNla* nla)
2341 smartcardCertInfo_Free(nla->smartcardCert);
2342 nla_buffer_free(nla);
2343 sspi_SecBufferFree(&nla->tsCredentials);
2344 credssp_auth_free(nla->auth);
2346 sspi_FreeAuthIdentity(nla->identity);
2347 free(nla->pkinitArgs);
2348 free(nla->identity);
2352SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2357 return nla->identity;
2360NLA_STATE nla_get_state(
const rdpNla* nla)
2363 return NLA_STATE_FINAL;
2368BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2373 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2378BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2380 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2385BOOL nla_impersonate(rdpNla* nla)
2387 return credssp_auth_impersonate(nla->auth);
2390BOOL nla_revert_to_self(rdpNla* nla)
2392 return credssp_auth_revert_to_self(nla->auth);
2395const char* nla_get_state_str(NLA_STATE state)
2399 case NLA_STATE_INITIAL:
2400 return "NLA_STATE_INITIAL";
2401 case NLA_STATE_NEGO_TOKEN:
2402 return "NLA_STATE_NEGO_TOKEN";
2403 case NLA_STATE_PUB_KEY_AUTH:
2404 return "NLA_STATE_PUB_KEY_AUTH";
2405 case NLA_STATE_AUTH_INFO:
2406 return "NLA_STATE_AUTH_INFO";
2407 case NLA_STATE_POST_NEGO:
2408 return "NLA_STATE_POST_NEGO";
2409 case NLA_STATE_EARLY_USER_AUTH:
2410 return "NLA_STATE_EARLY_USER_AUTH";
2411 case NLA_STATE_FINAL:
2412 return "NLA_STATE_FINAL";
2418DWORD nla_get_error(
const rdpNla* nla)
2421 return ERROR_INTERNAL_ERROR;
2422 return (UINT32)nla->errorCode;
2425INT32 nla_get_sspi_error(
const rdpNla* nla)
2428 return credssp_auth_sspi_error(nla->auth);
2434 WINPR_ASSERT(inBuffer);
2435 WINPR_ASSERT(outBuffer);
2436 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2442 WINPR_ASSERT(inBuffer);
2443 WINPR_ASSERT(outBuffer);
2444 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2447SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2451 SecurityFunctionTable* table = NULL;
2453 credssp_auth_tableAndContext(nla->auth, &table, &context);
2455 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.