25#include <freerdp/config.h>
32#include <freerdp/log.h>
33#include <freerdp/build-config.h>
36#include <winpr/assert.h>
38#include <winpr/sspi.h>
39#include <winpr/print.h>
40#include <winpr/tchar.h>
41#include <winpr/ncrypt.h>
42#include <winpr/cred.h>
43#include <winpr/debug.h>
44#include <winpr/asn1.h>
45#include <winpr/secapi.h>
47#include "../crypto/tls.h"
52#include "credssp_auth.h"
53#include <freerdp/utils/smartcardlogon.h>
55#define TAG FREERDP_TAG("core.nla")
57#define NLA_AUTH_PKG NEGO_SSP_NAME
61 AUTHZ_SUCCESS = 0x00000000,
62 AUTHZ_ACCESS_DENIED = 0x00000005,
114 rdpContext* rdpcontext;
115 rdpTransport* transport;
130 SEC_WINNT_AUTH_IDENTITY* identity;
132 rdpCredsspAuth* auth;
139static BOOL nla_send(rdpNla* nla);
140static int nla_server_recv(rdpNla* nla);
141static BOOL nla_encrypt_public_key_echo(rdpNla* nla);
142static BOOL nla_encrypt_public_key_hash(rdpNla* nla);
143static BOOL nla_decrypt_public_key_echo(rdpNla* nla);
144static BOOL nla_decrypt_public_key_hash(rdpNla* nla);
145static BOOL nla_encrypt_ts_credentials(rdpNla* nla);
146static BOOL nla_decrypt_ts_credentials(rdpNla* nla);
148void nla_set_early_user_auth(rdpNla* nla, BOOL earlyUserAuth)
151 WLog_DBG(TAG,
"Early User Auth active: %s", earlyUserAuth ?
"true" :
"false");
152 nla->earlyUserAuth = earlyUserAuth;
155static void nla_buffer_free(rdpNla* nla)
158 sspi_SecBufferFree(&nla->pubKeyAuth);
159 sspi_SecBufferFree(&nla->authInfo);
160 sspi_SecBufferFree(&nla->negoToken);
161 sspi_SecBufferFree(&nla->ClientNonce);
162 sspi_SecBufferFree(&nla->PublicKey);
165static BOOL nla_Digest_Update_From_SecBuffer(WINPR_DIGEST_CTX* ctx,
const SecBuffer* buffer)
169 return winpr_Digest_Update(ctx, buffer->pvBuffer, buffer->cbBuffer);
172static BOOL nla_sec_buffer_alloc(
SecBuffer* buffer,
size_t size)
174 WINPR_ASSERT(buffer);
175 sspi_SecBufferFree(buffer);
176 if (size > UINT32_MAX)
178 if (!sspi_SecBufferAlloc(buffer, (ULONG)size))
181 WINPR_ASSERT(buffer);
182 buffer->BufferType = SECBUFFER_TOKEN;
186static BOOL nla_sec_buffer_alloc_from_data(
SecBuffer* buffer,
const BYTE* data,
size_t offset,
189 if (!nla_sec_buffer_alloc(buffer, offset + size))
192 WINPR_ASSERT(buffer);
193 BYTE* pb = buffer->pvBuffer;
194 memcpy(&pb[offset], data, size);
199static const BYTE ClientServerHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
200 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
201 0x6F, 0x2D, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
202 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
203 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
206static const BYTE ServerClientHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
207 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x54,
208 0x6F, 0x2D, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74,
209 0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
210 0x20, 0x48, 0x61, 0x73, 0x68, 0x00 };
212static const UINT32 NonceLength = 32;
214static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla)
219 WINPR_ASSERT(nla->rdpcontext);
221 rdpSettings* settings = nla->rdpcontext->settings;
222 WINPR_ASSERT(settings);
224 if (!settings->SmartcardLogon)
227 smartcardCertInfo_Free(nla->smartcardCert);
229 if (!smartcard_getCert(nla->rdpcontext, &nla->smartcardCert, FALSE))
231 WLog_ERR(TAG,
"unable to get smartcard certificate for logon");
235 if (!settings->CspName)
238 settings, FreeRDP_CspName, nla->smartcardCert->csp))
240 WLog_ERR(TAG,
"unable to set CSP name");
243 if (!settings->CspName &&
246 WLog_ERR(TAG,
"unable to set CSP name");
251 if (!settings->ReaderName && nla->smartcardCert->reader)
254 nla->smartcardCert->reader))
256 WLog_ERR(TAG,
"unable to copy reader name");
261 if (!settings->ContainerName && nla->smartcardCert->containerName)
264 nla->smartcardCert->containerName))
266 WLog_ERR(TAG,
"unable to copy container name");
271 memcpy(nla->certSha1, nla->smartcardCert->sha1Hash,
sizeof(nla->certSha1));
273 if (nla->smartcardCert->pkinitArgs)
275 nla->pkinitArgs = _strdup(nla->smartcardCert->pkinitArgs);
276 if (!nla->pkinitArgs)
278 WLog_ERR(TAG,
"unable to copy pkinitArgs");
288static BOOL nla_client_setup_identity(rdpNla* nla)
290 BOOL PromptPassword = FALSE;
293 WINPR_ASSERT(nla->rdpcontext);
295 rdpSettings* settings = nla->rdpcontext->settings;
296 WINPR_ASSERT(settings);
298 freerdp* instance = nla->rdpcontext->instance;
299 WINPR_ASSERT(instance);
302 if ((utils_str_is_empty(settings->Username) ||
303 (utils_str_is_empty(settings->Password) &&
304 utils_str_is_empty((
const char*)settings->RedirectionPassword))))
306 PromptPassword = TRUE;
309 if (PromptPassword && !utils_str_is_empty(settings->Username))
311 WINPR_SAM* sam = SamOpen(
nullptr, TRUE);
314 const UINT32 userLength = (UINT32)strnlen(settings->Username, INT32_MAX);
315 WINPR_SAM_ENTRY* entry =
316 SamLookupUserA(sam, settings->Username,
317 userLength + 1 ,
nullptr, 0);
324 PromptPassword = FALSE;
325 SamFreeEntry(sam, entry);
334 if (settings->RestrictedAdminModeRequired)
336 if ((settings->PasswordHash) && (strlen(settings->PasswordHash) > 0))
337 PromptPassword = FALSE;
340 if (settings->RemoteCredentialGuard)
341 PromptPassword = FALSE;
344 BOOL smartCardLogonWasDisabled = !settings->SmartcardLogon;
347 switch (utils_authenticate(instance, AUTH_NLA, TRUE))
353 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
355 case AUTH_NO_CREDENTIALS:
356 WLog_INFO(TAG,
"No credentials provided - using nullptr identity");
363 if (!settings->Username)
365 sspi_FreeAuthIdentity(nla->identity);
367 nla->identity =
nullptr;
369 else if (settings->SmartcardLogon)
371 if (smartCardLogonWasDisabled)
373 if (!nla_adjust_settings_from_smartcard(nla))
377 if (!identity_set_from_smartcard_hash(nla->identity, settings, FreeRDP_Username,
378 FreeRDP_Domain, FreeRDP_Password, nla->certSha1,
379 sizeof(nla->certSha1)))
384 BOOL usePassword = TRUE;
386 if (settings->RedirectionPassword && (settings->RedirectionPasswordLength > 0))
388 const WCHAR* wstr = (
const WCHAR*)settings->RedirectionPassword;
389 const size_t len = _wcsnlen(wstr, settings->RedirectionPasswordLength /
sizeof(WCHAR));
391 if (!identity_set_from_settings_with_pwd(nla->identity, settings, FreeRDP_Username,
392 FreeRDP_Domain, wstr, len))
398 if (settings->RestrictedAdminModeRequired)
400 if (settings->PasswordHash && strlen(settings->PasswordHash) == 32)
402 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
403 FreeRDP_Domain, FreeRDP_PasswordHash))
411 nla->identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
418 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
419 FreeRDP_Domain, FreeRDP_Password))
427static int nla_client_init(rdpNla* nla)
430 WINPR_ASSERT(nla->rdpcontext);
432 rdpSettings* settings = nla->rdpcontext->settings;
433 WINPR_ASSERT(settings);
435 nla_set_state(nla, NLA_STATE_INITIAL);
437 if (!nla_adjust_settings_from_smartcard(nla))
440 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG,
nullptr))
443 if (!nla_client_setup_identity(nla))
448 if (!credssp_auth_setup_client(nla->auth,
"TERMSRV", hostname, nla->identity, nla->pkinitArgs))
451 const BYTE* data =
nullptr;
453 if (!transport_get_public_key(nla->transport, &data, &length))
455 WLog_ERR(TAG,
"Failed to get public key");
459 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
461 WLog_ERR(TAG,
"Failed to allocate sspi secBuffer");
468int nla_client_begin(rdpNla* nla)
472 if (nla_client_init(nla) < 1)
475 if (nla_get_state(nla) != NLA_STATE_INITIAL)
485 credssp_auth_set_flags(nla->auth, ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY);
487 const int rc = credssp_auth_authenticate(nla->auth);
494 nla_set_state(nla, NLA_STATE_NEGO_TOKEN);
497 if (credssp_auth_have_output_token(nla->auth))
502 nla_set_state(nla, NLA_STATE_FINAL);
505 switch (credssp_auth_sspi_error(nla->auth))
507 case SEC_E_LOGON_DENIED:
508 case SEC_E_NO_CREDENTIALS:
509 freerdp_set_last_error_log(nla->rdpcontext,
510 FREERDP_ERROR_CONNECT_LOGON_FAILURE);
521static int nla_client_recv_nego_token(rdpNla* nla)
523 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
524 const int rc = credssp_auth_authenticate(nla->auth);
535 if (nla->peerVersion < 5)
536 res = nla_encrypt_public_key_echo(nla);
538 res = nla_encrypt_public_key_hash(nla);
546 nla_set_state(nla, NLA_STATE_PUB_KEY_AUTH);
557static int nla_client_recv_pub_key_auth(rdpNla* nla)
564 if (nla->peerVersion < 5)
565 rc = nla_decrypt_public_key_echo(nla);
567 rc = nla_decrypt_public_key_hash(nla);
569 sspi_SecBufferFree(&nla->pubKeyAuth);
575 rc = nla_encrypt_ts_credentials(nla);
582 if (nla->earlyUserAuth)
584 transport_set_early_user_auth_mode(nla->transport, TRUE);
585 nla_set_state(nla, NLA_STATE_EARLY_USER_AUTH);
588 nla_set_state(nla, NLA_STATE_AUTH_INFO);
592static int nla_client_recv_early_user_auth(rdpNla* nla)
596 transport_set_early_user_auth_mode(nla->transport, FALSE);
597 nla_set_state(nla, NLA_STATE_AUTH_INFO);
601static int nla_client_recv(rdpNla* nla)
605 switch (nla_get_state(nla))
607 case NLA_STATE_NEGO_TOKEN:
608 return nla_client_recv_nego_token(nla);
610 case NLA_STATE_PUB_KEY_AUTH:
611 return nla_client_recv_pub_key_auth(nla);
613 case NLA_STATE_EARLY_USER_AUTH:
614 return nla_client_recv_early_user_auth(nla);
616 case NLA_STATE_FINAL:
618 WLog_ERR(TAG,
"NLA in invalid client receive state %s",
619 nla_get_state_str(nla_get_state(nla)));
624static int nla_client_authenticate(rdpNla* nla)
630 wStream* s = Stream_New(
nullptr, 4096);
634 WLog_ERR(TAG,
"Stream_New failed!");
638 if (nla_client_begin(nla) < 1)
641 while (nla_get_state(nla) < NLA_STATE_AUTH_INFO)
643 Stream_ResetPosition(s);
644 const int status = transport_read_pdu(nla->transport, s);
648 WLog_ERR(TAG,
"nla_client_authenticate failure");
652 const int status2 = nla_recv_pdu(nla, s);
660 Stream_Free(s, TRUE);
668static int nla_server_init(rdpNla* nla)
672 const BYTE* data =
nullptr;
674 if (!transport_get_public_key(nla->transport, &data, &length))
676 WLog_ERR(TAG,
"Failed to get public key");
680 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
682 WLog_ERR(TAG,
"Failed to allocate SecBuffer for public key");
686 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG,
nullptr))
689 if (!credssp_auth_setup_server(nla->auth))
692 nla_set_state(nla, NLA_STATE_INITIAL);
696static wStream* nla_server_recv_stream(rdpNla* nla)
703 s = Stream_New(
nullptr, 4096);
708 status = transport_read_pdu(nla->transport, s);
713 WLog_ERR(TAG,
"nla_recv() error: %d", status);
714 Stream_Free(s, TRUE);
721static BOOL nla_server_recv_credentials(rdpNla* nla)
725 if (nla_server_recv(nla) < 0)
728 if (!nla_decrypt_ts_credentials(nla))
731 if (!nla_impersonate(nla))
734 if (!nla_revert_to_self(nla))
747static int nla_server_authenticate(rdpNla* nla)
753 if (nla_server_init(nla) < 1)
762 credssp_auth_set_flags(nla->auth, ASC_REQ_MUTUAL_AUTH | ASC_REQ_CONFIDENTIALITY |
763 ASC_REQ_CONNECTION | ASC_REQ_USE_SESSION_KEY |
764 ASC_REQ_SEQUENCE_DETECT | ASC_REQ_EXTENDED_ERROR);
796 if (nla_server_recv(nla) < 0)
799 WLog_DBG(TAG,
"Receiving Authentication Token");
800 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
802 res = credssp_auth_authenticate(nla->auth);
809 switch (GetLastError())
811 case ERROR_PASSWORD_MUST_CHANGE:
812 nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
815 case ERROR_PASSWORD_EXPIRED:
816 nla->errorCode = STATUS_PASSWORD_EXPIRED;
819 case ERROR_ACCOUNT_DISABLED:
820 nla->errorCode = STATUS_ACCOUNT_DISABLED;
824 nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
836 if (credssp_auth_have_output_token(nla->auth))
841 if (nla_server_recv(nla) < 0)
844 WLog_DBG(TAG,
"Receiving pubkey Token");
847 if (nla->peerVersion < 5)
848 res = nla_decrypt_public_key_echo(nla);
850 res = nla_decrypt_public_key_hash(nla);
856 sspi_SecBufferFree(&nla->negoToken);
858 if (nla->peerVersion < 5)
859 res = nla_encrypt_public_key_echo(nla);
861 res = nla_encrypt_public_key_hash(nla);
868 WLog_DBG(TAG,
"Sending Authentication Token");
881 if (!nla_server_recv_credentials(nla))
885 nla_buffer_free(nla);
896int nla_authenticate(rdpNla* nla)
901 return nla_server_authenticate(nla);
903 return nla_client_authenticate(nla);
906static void ap_integer_increment_le(BYTE* number,
size_t size)
908 WINPR_ASSERT(number || (size == 0));
910 for (
size_t index = 0; index < size; index++)
912 if (number[index] < 0xFF)
925static void ap_integer_decrement_le(BYTE* number,
size_t size)
927 WINPR_ASSERT(number || (size == 0));
929 for (
size_t index = 0; index < size; index++)
931 if (number[index] > 0)
938 number[index] = 0xFF;
944BOOL nla_encrypt_public_key_echo(rdpNla* nla)
950 sspi_SecBufferFree(&nla->pubKeyAuth);
954 if (!sspi_SecBufferAlloc(&buf, nla->PublicKey.cbBuffer))
956 ap_integer_increment_le(buf.pvBuffer, buf.cbBuffer);
958 credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth,
nullptr, nla->sendSeqNum++);
959 sspi_SecBufferFree(&buf);
963 status = credssp_auth_encrypt(nla->auth, &nla->PublicKey, &nla->pubKeyAuth,
nullptr,
970BOOL nla_encrypt_public_key_hash(rdpNla* nla)
973 WINPR_DIGEST_CTX* sha256 =
nullptr;
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,
nullptr, nla->sendSeqNum++))
1013 winpr_Digest_Free(sha256);
1014 sspi_SecBufferFree(&buf);
1018BOOL nla_decrypt_public_key_echo(rdpNla* nla)
1020 BOOL status = FALSE;
1021 SecBuffer public_key = WINPR_C_ARRAY_INIT;
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 =
nullptr;
1058 BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH] = WINPR_C_ARRAY_INIT;
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 if (!Stream_SetPosition(s, pos))
1278 ret->Version = Stream_Get_UINT32(s);
1279 ret->Flags = Stream_Get_UINT32(s);
1280 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1282 const UINT32 val = Stream_Get_UINT32(s);
1283 if (!nla_credentialTypeValid(val))
1288 ret->CredentialKeyType = WINPR_ASSERTING_INT_CAST(MSV1_0_CREDENTIAL_KEY_TYPE, val);
1290 ret->EncryptedCredsSize = EncryptedCredsSize;
1291 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1302} RemoteGuardPackageCredType;
1304static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1305 RemoteGuardPackageCredType* credsType,
1311 char packageNameStr[100] = WINPR_C_ARRAY_INIT;
1315 WINPR_ASSERT(credsType);
1316 WINPR_ASSERT(payload);
1318 *credsType = RCG_TYPE_NONE;
1321 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1324 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1325 packageNameStr,
sizeof(packageNameStr));
1326 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1329 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1332 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1334 *credsType = RCG_TYPE_KERB;
1336 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1338 *credsType = RCG_TYPE_NTLM;
1342 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1346 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1353 TSCREDS_INVALID = 0,
1354 TSCREDS_USER_PASSWD = 1,
1355 TSCREDS_SMARTCARD = 2,
1356 TSCREDS_REMOTEGUARD = 6
1359static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1365 WinPrAsn1_INTEGER credType = -1;
1371 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1374 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1379 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1383 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1386 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1388 rdpSettings* settings = nla->rdpcontext->settings;
1389 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1390 credType != TSCREDS_REMOTEGUARD)
1392 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1398 case TSCREDS_USER_PASSWD:
1401 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1406 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1410 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1414 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1416 case TSCREDS_SMARTCARD:
1419 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1424 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1426 settings->PasswordIsSmartcardPin = TRUE;
1430 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1432 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1436 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1440 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1442 case TSCREDS_REMOTEGUARD:
1445 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1451 .ServiceTicketLength = 0,
1452 .TicketGrantingTicketLength = 0,
1453 .ServiceTicket =
nullptr,
1454 .TicketGrantingTicket =
nullptr };
1458 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1461 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1462 wStream logonPayload = WINPR_C_ARRAY_INIT;
1463 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1466 if (logonCredsType != RCG_TYPE_KERB)
1468 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1472 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1474 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1482 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1483 Stream_GetRemainingLength(&suppCredsSeq.source))
1486 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1489 RemoteGuardPackageCredType suppCredsType = RCG_TYPE_NONE;
1490 wStream ntlmPayload = WINPR_C_ARRAY_INIT;
1491 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1495 if (suppCredsType != RCG_TYPE_NTLM)
1497 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1501 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1504 WLog_ERR(TAG,
"invalid supplementalCreds");
1510 WLog_ERR(TAG,
"invalid supplementalCreds");
1514 freerdp_peer* peer = nla->rdpcontext->peer;
1515 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1520 WLog_DBG(TAG,
"TSCredentials type %d not supported for now", credType);
1530 WINPR_ASSERT(ticket);
1532 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1533 ticket->TicketGrantingTicketLength))
1536 Stream_Write_UINT32(s, KerbTicketLogon);
1537 Stream_Write_UINT32(s, ticket->Flags);
1538 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1539 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1541 Stream_Write_UINT64(s, 0x20);
1542 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1544 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1545 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1549static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1552 WINPR_ASSERT(logonTicket);
1554 SecurityFunctionTable* table =
nullptr;
1556 credssp_auth_tableAndContext(nla->auth, &table, &context);
1557 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1561static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1565 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1566 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1571 logonTicket.ServiceTicket =
nullptr;
1572 logonTicket.TicketGrantingTicket =
nullptr;
1575 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1579 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1582 s = Stream_New(
nullptr, 2000);
1586 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1589 credBuffer.len = Stream_GetPosition(s);
1590 credBuffer.data = Stream_Buffer(s);
1591 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1594 free(logonTicket.ServiceTicket);
1595 free(logonTicket.TicketGrantingTicket);
1596 Stream_Free(s, TRUE);
1600static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1605 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1609 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1613 wStream* s = Stream_New(
nullptr, 300);
1617 Stream_Write_UINT32(s, pntlm->Version);
1618 Stream_Write_UINT32(s, pntlm->Flags);
1620 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1621 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1622 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1623 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1624 Stream_Zero(s, 6 + 16 * 4 + 14);
1628 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1632 Stream_Free(s, TRUE);
1636static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1640 WinPrAsn1_tagId tag;
1641 FreeRDP_Settings_Keys_String setting_id;
1642 } cspData_fields[] = { { 1, FreeRDP_CardName },
1643 { 2, FreeRDP_ReaderName },
1644 { 3, FreeRDP_ContainerName },
1645 { 4, FreeRDP_CspName } };
1650 WINPR_ASSERT(nla->rdpcontext);
1652 const rdpSettings* settings = nla->rdpcontext->settings;
1653 WINPR_ASSERT(settings);
1656 if (!WinPrAsn1EncSeqContainer(enc))
1663 octet_string.len = ss *
sizeof(WCHAR);
1664 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1665 free(octet_string.data);
1670 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1674 if (!WinPrAsn1EncContextualInteger(
1676 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1680 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1685 settings, cspData_fields[i].setting_id, &len);
1686 octet_string.len = len *
sizeof(WCHAR);
1687 if (octet_string.len)
1690 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1691 free(octet_string.data);
1698 if (!WinPrAsn1EncEndContainer(enc))
1706 octet_string.len = ss *
sizeof(WCHAR);
1707 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1708 free(octet_string.data);
1718 octet_string.len = ss *
sizeof(WCHAR);
1719 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1720 free(octet_string.data);
1726 return WinPrAsn1EncEndContainer(enc) != 0;
1729static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1737 WINPR_ASSERT(nla->rdpcontext);
1739 const rdpSettings* settings = nla->rdpcontext->settings;
1740 WINPR_ASSERT(settings);
1743 if (!WinPrAsn1EncSeqContainer(enc))
1746 if (!settings->DisableCredentialsDelegation && nla->identity)
1748 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1749 username.data = (BYTE*)nla->identity->User;
1751 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1752 domain.data = (BYTE*)nla->identity->Domain;
1754 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1755 password.data = (BYTE*)nla->identity->Password;
1758 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1760 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1762 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1766 return WinPrAsn1EncEndContainer(enc) != 0;
1769static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1775 if (!WinPrAsn1EncSeqContainer(enc))
1779 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1782 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1790 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1793 if (!WinPrAsn1EncSeqContainer(enc))
1796 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1799 if (!WinPrAsn1EncEndContainer(enc))
1802 if (!WinPrAsn1EncEndContainer(enc))
1807 return WinPrAsn1EncEndContainer(enc) != 0;
1817static BOOL nla_encode_ts_credentials(rdpNla* nla)
1820 WinPrAsn1Encoder* enc =
nullptr;
1822 wStream s = WINPR_C_ARRAY_INIT;
1823 TsCredentialsType credType = TSCREDS_INVALID;
1826 WINPR_ASSERT(nla->rdpcontext);
1828 rdpSettings* settings = nla->rdpcontext->settings;
1829 WINPR_ASSERT(settings);
1831 if (settings->RemoteCredentialGuard)
1832 credType = TSCREDS_REMOTEGUARD;
1833 else if (settings->SmartcardLogon)
1834 credType = TSCREDS_SMARTCARD;
1836 credType = TSCREDS_USER_PASSWD;
1838 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1843 if (!WinPrAsn1EncSeqContainer(enc))
1847 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1851 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1856 case TSCREDS_SMARTCARD:
1857 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1861 case TSCREDS_USER_PASSWD:
1862 if (!nla_encode_ts_password_credentials(nla, enc))
1866 case TSCREDS_REMOTEGUARD:
1867 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1875 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1878 if (!WinPrAsn1EncStreamSize(enc, &length))
1881 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1883 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1887 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1889 ret = WinPrAsn1EncToStream(enc, &s);
1892 WinPrAsn1Encoder_Free(&enc);
1896static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1900 if (!nla_encode_ts_credentials(nla))
1903 sspi_SecBufferFree(&nla->authInfo);
1904 return (credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo,
nullptr,
1905 nla->sendSeqNum++));
1908static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1912 if (nla->authInfo.cbBuffer < 1)
1914 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1918 sspi_SecBufferFree(&nla->tsCredentials);
1919 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1922 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1928static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1929 WinPrAsn1_tagId tagId,
const char* msg)
1934 WINPR_ASSERT(buffer);
1937 if (buffer->cbBuffer > 0)
1942 WLog_DBG(TAG,
" ----->> %s", msg);
1943 octet_string.data = buffer->pvBuffer;
1944 octet_string.len = buffer->cbBuffer;
1945 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1953static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1954 WinPrAsn1_tagId tagId,
const char* msg)
1956 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1957 sspi_SecBufferFree(buffer);
1969BOOL nla_send(rdpNla* nla)
1974 WinPrAsn1Encoder* enc =
nullptr;
1978 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1983 WLog_DBG(TAG,
"----->> sending...");
1984 if (!WinPrAsn1EncSeqContainer(enc))
1988 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1989 if (!WinPrAsn1EncContextualInteger(enc, 0,
1990 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1994 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1996 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1998 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
2002 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
2006 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
2011 if (nla->authInfo.cbBuffer > 0)
2013 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
2018 if (nla->pubKeyAuth.cbBuffer > 0)
2020 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
2025 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
2027 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2028 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2029 if (!WinPrAsn1EncContextualInteger(
2030 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
2035 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
2037 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
2042 if (!WinPrAsn1EncEndContainer(enc))
2045 if (!WinPrAsn1EncStreamSize(enc, &length))
2048 s = Stream_New(
nullptr, length);
2052 if (!WinPrAsn1EncToStream(enc, s))
2055 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
2056 if (transport_write(nla->transport, s) < 0)
2061 Stream_Free(s, TRUE);
2062 WinPrAsn1Encoder_Free(&enc);
2066static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
2071 WinPrAsn1_tagId tag = WINPR_C_ARRAY_INIT;
2072 WinPrAsn1_INTEGER val = WINPR_C_ARRAY_INIT;
2078 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
2080 WLog_DBG(TAG,
"<<----- receiving...");
2083 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
2089 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
2092 if (!Stream_SafeSeek(s, offset))
2095 version = (UINT)val;
2096 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
2098 if (nla->peerVersion == 0)
2099 nla->peerVersion = version;
2102 if (nla->peerVersion != version)
2104 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
2105 nla->peerVersion, version);
2109 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
2117 WLog_DBG(TAG,
" <<----- nego token");
2119 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
2120 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
2123 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
2127 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
2132 WLog_DBG(TAG,
" <<----- auth info");
2134 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2136 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
2141 WLog_DBG(TAG,
" <<----- public key auth");
2143 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2145 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
2151 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
2153 nla->errorCode = val;
2154 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
2155 WINPR_CXX_COMPAT_CAST(uint32_t, nla->errorCode));
2158 WLog_DBG(TAG,
" <<----- client nonce");
2160 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
2162 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
2174int nla_recv_pdu(rdpNla* nla,
wStream* s)
2179 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
2182 Stream_Read_UINT32(s, code);
2183 if (code != AUTHZ_SUCCESS)
2185 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
2186 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2187 freerdp_set_last_error_log(nla->rdpcontext, code);
2191 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2195 if (nla_decode_ts_request(nla, s) < 1)
2202 switch (nla->errorCode)
2204 case STATUS_PASSWORD_MUST_CHANGE:
2205 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2208 case STATUS_PASSWORD_EXPIRED:
2209 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2212 case STATUS_ACCOUNT_DISABLED:
2213 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2216 case STATUS_LOGON_FAILURE:
2217 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2220 case STATUS_WRONG_PASSWORD:
2221 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2224 case STATUS_ACCESS_DENIED:
2225 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2228 case STATUS_ACCOUNT_RESTRICTION:
2229 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2232 case STATUS_ACCOUNT_LOCKED_OUT:
2233 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2236 case STATUS_ACCOUNT_EXPIRED:
2237 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2240 case STATUS_LOGON_TYPE_NOT_GRANTED:
2241 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2245 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIx32
"]",
2246 NtStatus2Tag(nla->errorCode),
2247 WINPR_CXX_COMPAT_CAST(uint32_t, 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 return (credssp_auth_set_spn(nla->auth, service, hostname));
2383BOOL nla_impersonate(rdpNla* nla)
2385 return credssp_auth_impersonate(nla->auth);
2388BOOL nla_revert_to_self(rdpNla* nla)
2390 return credssp_auth_revert_to_self(nla->auth);
2393const char* nla_get_state_str(NLA_STATE state)
2397 case NLA_STATE_INITIAL:
2398 return "NLA_STATE_INITIAL";
2399 case NLA_STATE_NEGO_TOKEN:
2400 return "NLA_STATE_NEGO_TOKEN";
2401 case NLA_STATE_PUB_KEY_AUTH:
2402 return "NLA_STATE_PUB_KEY_AUTH";
2403 case NLA_STATE_AUTH_INFO:
2404 return "NLA_STATE_AUTH_INFO";
2405 case NLA_STATE_POST_NEGO:
2406 return "NLA_STATE_POST_NEGO";
2407 case NLA_STATE_EARLY_USER_AUTH:
2408 return "NLA_STATE_EARLY_USER_AUTH";
2409 case NLA_STATE_FINAL:
2410 return "NLA_STATE_FINAL";
2416DWORD nla_get_error(
const rdpNla* nla)
2419 return ERROR_INTERNAL_ERROR;
2420 return (UINT32)nla->errorCode;
2423INT32 nla_get_sspi_error(
const rdpNla* nla)
2426 return credssp_auth_sspi_error(nla->auth);
2432 WINPR_ASSERT(inBuffer);
2433 WINPR_ASSERT(outBuffer);
2434 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer,
nullptr, nla->sendSeqNum++);
2440 WINPR_ASSERT(inBuffer);
2441 WINPR_ASSERT(outBuffer);
2442 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2445SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2449 SecurityFunctionTable* table =
nullptr;
2451 credssp_auth_tableAndContext(nla->auth, &table, &context);
2453 return table->QueryContextAttributes(&context, ulAttr, pBuffer);
2456SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer)
2460 SecurityFunctionTable* table =
nullptr;
2462 credssp_auth_tableAndContext(nla->auth, &table, &context);
2464 return table->FreeContextBuffer(pBuffer);
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.
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.