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(NULL, TRUE);
314 const UINT32 userLength = (UINT32)strnlen(settings->Username, INT32_MAX);
315 WINPR_SAM_ENTRY* entry = SamLookupUserA(
316 sam, settings->Username, userLength + 1 , NULL, 0);
323 PromptPassword = FALSE;
324 SamFreeEntry(sam, entry);
333 if (settings->RestrictedAdminModeRequired)
335 if ((settings->PasswordHash) && (strlen(settings->PasswordHash) > 0))
336 PromptPassword = FALSE;
339 if (settings->RemoteCredentialGuard)
340 PromptPassword = FALSE;
343 BOOL smartCardLogonWasDisabled = !settings->SmartcardLogon;
346 switch (utils_authenticate(instance, AUTH_NLA, TRUE))
352 freerdp_set_last_error_log(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
354 case AUTH_NO_CREDENTIALS:
355 WLog_INFO(TAG,
"No credentials provided - using NULL identity");
362 if (!settings->Username)
364 sspi_FreeAuthIdentity(nla->identity);
366 nla->identity = NULL;
368 else if (settings->SmartcardLogon)
370 if (smartCardLogonWasDisabled)
372 if (!nla_adjust_settings_from_smartcard(nla))
376 if (!identity_set_from_smartcard_hash(nla->identity, settings, FreeRDP_Username,
377 FreeRDP_Domain, FreeRDP_Password, nla->certSha1,
378 sizeof(nla->certSha1)))
383 BOOL usePassword = TRUE;
385 if (settings->RedirectionPassword && (settings->RedirectionPasswordLength > 0))
387 const WCHAR* wstr = (
const WCHAR*)settings->RedirectionPassword;
388 const size_t len = _wcsnlen(wstr, settings->RedirectionPasswordLength /
sizeof(WCHAR));
390 if (!identity_set_from_settings_with_pwd(nla->identity, settings, FreeRDP_Username,
391 FreeRDP_Domain, wstr, len))
397 if (settings->RestrictedAdminModeRequired)
399 if (settings->PasswordHash && strlen(settings->PasswordHash) == 32)
401 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
402 FreeRDP_Domain, FreeRDP_PasswordHash))
410 nla->identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
417 if (!identity_set_from_settings(nla->identity, settings, FreeRDP_Username,
418 FreeRDP_Domain, FreeRDP_Password))
426static int nla_client_init(rdpNla* nla)
429 WINPR_ASSERT(nla->rdpcontext);
431 rdpSettings* settings = nla->rdpcontext->settings;
432 WINPR_ASSERT(settings);
434 nla_set_state(nla, NLA_STATE_INITIAL);
436 if (!nla_adjust_settings_from_smartcard(nla))
439 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG, NULL))
442 if (!nla_client_setup_identity(nla))
447 if (!credssp_auth_setup_client(nla->auth,
"TERMSRV", hostname, nla->identity, nla->pkinitArgs))
450 const BYTE* data = NULL;
452 if (!transport_get_public_key(nla->transport, &data, &length))
454 WLog_ERR(TAG,
"Failed to get public key");
458 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
460 WLog_ERR(TAG,
"Failed to allocate sspi secBuffer");
467int nla_client_begin(rdpNla* nla)
471 if (nla_client_init(nla) < 1)
474 if (nla_get_state(nla) != NLA_STATE_INITIAL)
484 credssp_auth_set_flags(nla->auth, ISC_REQ_MUTUAL_AUTH | ISC_REQ_CONFIDENTIALITY);
486 const int rc = credssp_auth_authenticate(nla->auth);
493 nla_set_state(nla, NLA_STATE_NEGO_TOKEN);
496 if (credssp_auth_have_output_token(nla->auth))
501 nla_set_state(nla, NLA_STATE_FINAL);
504 switch (credssp_auth_sspi_error(nla->auth))
506 case SEC_E_LOGON_DENIED:
507 case SEC_E_NO_CREDENTIALS:
508 freerdp_set_last_error_log(nla->rdpcontext,
509 FREERDP_ERROR_CONNECT_LOGON_FAILURE);
520static int nla_client_recv_nego_token(rdpNla* nla)
522 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
523 const int rc = credssp_auth_authenticate(nla->auth);
534 if (nla->peerVersion < 5)
535 res = nla_encrypt_public_key_echo(nla);
537 res = nla_encrypt_public_key_hash(nla);
545 nla_set_state(nla, NLA_STATE_PUB_KEY_AUTH);
556static int nla_client_recv_pub_key_auth(rdpNla* nla)
563 if (nla->peerVersion < 5)
564 rc = nla_decrypt_public_key_echo(nla);
566 rc = nla_decrypt_public_key_hash(nla);
568 sspi_SecBufferFree(&nla->pubKeyAuth);
574 rc = nla_encrypt_ts_credentials(nla);
581 if (nla->earlyUserAuth)
583 transport_set_early_user_auth_mode(nla->transport, TRUE);
584 nla_set_state(nla, NLA_STATE_EARLY_USER_AUTH);
587 nla_set_state(nla, NLA_STATE_AUTH_INFO);
591static int nla_client_recv_early_user_auth(rdpNla* nla)
595 transport_set_early_user_auth_mode(nla->transport, FALSE);
596 nla_set_state(nla, NLA_STATE_AUTH_INFO);
600static int nla_client_recv(rdpNla* nla)
604 switch (nla_get_state(nla))
606 case NLA_STATE_NEGO_TOKEN:
607 return nla_client_recv_nego_token(nla);
609 case NLA_STATE_PUB_KEY_AUTH:
610 return nla_client_recv_pub_key_auth(nla);
612 case NLA_STATE_EARLY_USER_AUTH:
613 return nla_client_recv_early_user_auth(nla);
615 case NLA_STATE_FINAL:
617 WLog_ERR(TAG,
"NLA in invalid client receive state %s",
618 nla_get_state_str(nla_get_state(nla)));
623static int nla_client_authenticate(rdpNla* nla)
629 wStream* s = Stream_New(NULL, 4096);
633 WLog_ERR(TAG,
"Stream_New failed!");
637 if (nla_client_begin(nla) < 1)
640 while (nla_get_state(nla) < NLA_STATE_AUTH_INFO)
642 Stream_SetPosition(s, 0);
643 const int status = transport_read_pdu(nla->transport, s);
647 WLog_ERR(TAG,
"nla_client_authenticate failure");
651 const int status2 = nla_recv_pdu(nla, s);
659 Stream_Free(s, TRUE);
667static int nla_server_init(rdpNla* nla)
671 const BYTE* data = NULL;
673 if (!transport_get_public_key(nla->transport, &data, &length))
675 WLog_ERR(TAG,
"Failed to get public key");
679 if (!nla_sec_buffer_alloc_from_data(&nla->PublicKey, data, 0, length))
681 WLog_ERR(TAG,
"Failed to allocate SecBuffer for public key");
685 if (!credssp_auth_init(nla->auth, NLA_AUTH_PKG, NULL))
688 if (!credssp_auth_setup_server(nla->auth))
691 nla_set_state(nla, NLA_STATE_INITIAL);
695static wStream* nla_server_recv_stream(rdpNla* nla)
702 s = Stream_New(NULL, 4096);
707 status = transport_read_pdu(nla->transport, s);
712 WLog_ERR(TAG,
"nla_recv() error: %d", status);
713 Stream_Free(s, TRUE);
720static BOOL nla_server_recv_credentials(rdpNla* nla)
724 if (nla_server_recv(nla) < 0)
727 if (!nla_decrypt_ts_credentials(nla))
730 if (!nla_impersonate(nla))
733 if (!nla_revert_to_self(nla))
746static int nla_server_authenticate(rdpNla* nla)
752 if (nla_server_init(nla) < 1)
761 credssp_auth_set_flags(nla->auth, ASC_REQ_MUTUAL_AUTH | ASC_REQ_CONFIDENTIALITY |
762 ASC_REQ_CONNECTION | ASC_REQ_USE_SESSION_KEY |
763 ASC_REQ_SEQUENCE_DETECT | ASC_REQ_EXTENDED_ERROR);
795 if (nla_server_recv(nla) < 0)
798 WLog_DBG(TAG,
"Receiving Authentication Token");
799 credssp_auth_take_input_buffer(nla->auth, &nla->negoToken);
801 res = credssp_auth_authenticate(nla->auth);
808 switch (GetLastError())
810 case ERROR_PASSWORD_MUST_CHANGE:
811 nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
814 case ERROR_PASSWORD_EXPIRED:
815 nla->errorCode = STATUS_PASSWORD_EXPIRED;
818 case ERROR_ACCOUNT_DISABLED:
819 nla->errorCode = STATUS_ACCOUNT_DISABLED;
823 nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
835 if (credssp_auth_have_output_token(nla->auth))
840 if (nla_server_recv(nla) < 0)
843 WLog_DBG(TAG,
"Receiving pubkey Token");
846 if (nla->peerVersion < 5)
847 res = nla_decrypt_public_key_echo(nla);
849 res = nla_decrypt_public_key_hash(nla);
855 sspi_SecBufferFree(&nla->negoToken);
857 if (nla->peerVersion < 5)
858 res = nla_encrypt_public_key_echo(nla);
860 res = nla_encrypt_public_key_hash(nla);
867 WLog_DBG(TAG,
"Sending Authentication Token");
880 if (!nla_server_recv_credentials(nla))
884 nla_buffer_free(nla);
895int nla_authenticate(rdpNla* nla)
900 return nla_server_authenticate(nla);
902 return nla_client_authenticate(nla);
905static void ap_integer_increment_le(BYTE* number,
size_t size)
907 WINPR_ASSERT(number || (size == 0));
909 for (
size_t index = 0; index < size; index++)
911 if (number[index] < 0xFF)
924static void ap_integer_decrement_le(BYTE* number,
size_t size)
926 WINPR_ASSERT(number || (size == 0));
928 for (
size_t index = 0; index < size; index++)
930 if (number[index] > 0)
937 number[index] = 0xFF;
943BOOL nla_encrypt_public_key_echo(rdpNla* nla)
949 sspi_SecBufferFree(&nla->pubKeyAuth);
953 if (!sspi_SecBufferAlloc(&buf, nla->PublicKey.cbBuffer))
955 ap_integer_increment_le(buf.pvBuffer, buf.cbBuffer);
956 status = credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++);
957 sspi_SecBufferFree(&buf);
961 status = credssp_auth_encrypt(nla->auth, &nla->PublicKey, &nla->pubKeyAuth, NULL,
968BOOL nla_encrypt_public_key_hash(rdpNla* nla)
971 WINPR_DIGEST_CTX* sha256 = NULL;
976 const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
977 const size_t hashSize =
978 nla->server ?
sizeof(ServerClientHashMagic) : sizeof(ClientServerHashMagic);
980 if (!sspi_SecBufferAlloc(&buf, WINPR_SHA256_DIGEST_LENGTH))
984 if (!(sha256 = winpr_Digest_New()))
987 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
991 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
994 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
998 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1001 if (!winpr_Digest_Final(sha256, buf.pvBuffer, WINPR_SHA256_DIGEST_LENGTH))
1004 sspi_SecBufferFree(&nla->pubKeyAuth);
1005 if (!credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++))
1011 winpr_Digest_Free(sha256);
1012 sspi_SecBufferFree(&buf);
1016BOOL nla_decrypt_public_key_echo(rdpNla* nla)
1018 BOOL status = FALSE;
1024 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &public_key, nla->recvSeqNum++))
1030 ap_integer_decrement_le(public_key.pvBuffer, public_key.cbBuffer);
1033 if (public_key.cbBuffer != nla->PublicKey.cbBuffer ||
1034 memcmp(public_key.pvBuffer, nla->PublicKey.pvBuffer, public_key.cbBuffer) != 0)
1036 WLog_ERR(TAG,
"Could not verify server's public key echo");
1037#if defined(WITH_DEBUG_NLA)
1038 WLog_ERR(TAG,
"Expected (length = %" PRIu32
"):", nla->PublicKey.cbBuffer);
1039 winpr_HexDump(TAG, WLOG_ERROR, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer);
1040 WLog_ERR(TAG,
"Actual (length = %" PRIu32
"):", public_key.cbBuffer);
1041 winpr_HexDump(TAG, WLOG_ERROR, public_key.pvBuffer, public_key.cbBuffer);
1049 sspi_SecBufferFree(&public_key);
1053BOOL nla_decrypt_public_key_hash(rdpNla* nla)
1055 WINPR_DIGEST_CTX* sha256 = NULL;
1056 BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH] = { 0 };
1057 BOOL status = FALSE;
1061 const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
1062 const size_t hashSize =
1063 nla->server ?
sizeof(ClientServerHashMagic) : sizeof(ServerClientHashMagic);
1066 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &hash, nla->recvSeqNum++))
1070 if (!(sha256 = winpr_Digest_New()))
1073 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1077 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1080 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1084 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1087 if (!winpr_Digest_Final(sha256, serverClientHash,
sizeof(serverClientHash)))
1091 if (hash.cbBuffer != WINPR_SHA256_DIGEST_LENGTH ||
1092 memcmp(serverClientHash, hash.pvBuffer, WINPR_SHA256_DIGEST_LENGTH) != 0)
1094 WLog_ERR(TAG,
"Could not verify server's hash");
1101 winpr_Digest_Free(sha256);
1102 sspi_SecBufferFree(&hash);
1106static BOOL set_creds_octetstring_to_settings(
WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
1107 BOOL optional, FreeRDP_Settings_Keys_String settingId,
1108 rdpSettings* settings)
1112 WinPrAsn1_tagId itemTag = 0;
1113 if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != (ER_TAG_CONTEXTUAL | tagId)))
1122 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1126 value.len /
sizeof(WCHAR));
1129static BOOL nla_read_TSCspDataDetail(
WinPrAsn1Decoder* dec, rdpSettings* settings)
1134 WinPrAsn1_INTEGER keyspec = 0;
1135 if (!WinPrAsn1DecReadContextualInteger(dec, 0, &error, &keyspec))
1137 settings->KeySpec = (UINT32)keyspec;
1140 if (!set_creds_octetstring_to_settings(dec, 1, TRUE, FreeRDP_CardName, settings))
1144 if (!set_creds_octetstring_to_settings(dec, 2, TRUE, FreeRDP_ReaderName, settings))
1148 if (!set_creds_octetstring_to_settings(dec, 3, TRUE, FreeRDP_ContainerName, settings))
1152 return set_creds_octetstring_to_settings(dec, 4, TRUE, FreeRDP_CspName, settings);
1155static BOOL nla_messageTypeValid(UINT32 type)
1159 case KerbInvalidValue:
1160 case KerbInteractiveLogon:
1161 case KerbSmartCardLogon:
1162 case KerbWorkstationUnlockLogon:
1163 case KerbSmartCardUnlockLogon:
1164 case KerbProxyLogon:
1165 case KerbTicketLogon:
1166 case KerbTicketUnlockLogon:
1167#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0501)
1170#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0600)
1171 case KerbCertificateLogon:
1172 case KerbCertificateS4ULogon:
1173 case KerbCertificateUnlockLogon:
1175#if !defined(_WIN32_WINNT) || (_WIN32_WINNT >= 0x0602)
1176 case KerbNoElevationLogon:
1181 WLog_ERR(TAG,
"Invalid message type %" PRIu32, type);
1186static BOOL nla_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1195 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1199 const UINT32 type = Stream_Get_UINT32(s);
1200 if (!nla_messageTypeValid(type))
1203 ticket->MessageType = (KERB_LOGON_SUBMIT_TYPE)type;
1205 Stream_Read_UINT32(s, ticket->Flags);
1206 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1207 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1209 if (ticket->MessageType != KerbTicketLogon)
1211 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1215 if (!Stream_CheckAndLogRequiredLength(
1216 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1224 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1225 Stream_Seek(s, ticket->ServiceTicketLength);
1230 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1234static BOOL nla_credentialTypeValid(UINT32 type)
1238 case InvalidCredKey:
1239 case DeprecatedIUMCredKey:
1240 case DomainUserCredKey:
1241 case LocalUserCredKey:
1242 case ExternallySuppliedCredKey:
1245 WLog_ERR(TAG,
"Invalid credential type %" PRIu32, type);
1250WINPR_ATTR_MALLOC(free, 1)
1258 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32 + 4))
1261 size_t pos = Stream_GetPosition(s);
1264 ULONG EncryptedCredsSize = Stream_Get_UINT32(s);
1265 if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize))
1268 Stream_SetPosition(s, pos);
1275 ret->Version = Stream_Get_UINT32(s);
1276 ret->Flags = Stream_Get_UINT32(s);
1277 Stream_Read(s, ret->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1279 const UINT32 val = Stream_Get_UINT32(s);
1280 if (!nla_credentialTypeValid(val))
1285 ret->CredentialKeyType = WINPR_ASSERTING_INT_CAST(MSV1_0_CREDENTIAL_KEY_TYPE, val);
1287 ret->EncryptedCredsSize = EncryptedCredsSize;
1288 Stream_Read(s, ret->EncryptedCreds, EncryptedCredsSize);
1299} RemoteGuardPackageCredType;
1301static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1302 RemoteGuardPackageCredType* credsType,
1308 char packageNameStr[100] = { 0 };
1312 WINPR_ASSERT(credsType);
1313 WINPR_ASSERT(payload);
1315 *credsType = RCG_TYPE_NONE;
1318 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1321 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1322 packageNameStr,
sizeof(packageNameStr));
1323 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1326 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1329 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1331 *credsType = RCG_TYPE_KERB;
1333 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1335 *credsType = RCG_TYPE_NTLM;
1339 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1343 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1350 TSCREDS_INVALID = 0,
1351 TSCREDS_USER_PASSWD = 1,
1352 TSCREDS_SMARTCARD = 2,
1353 TSCREDS_REMOTEGUARD = 6
1356static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1362 WinPrAsn1_INTEGER credType = -1;
1368 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1371 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1376 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1380 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1383 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1385 rdpSettings* settings = nla->rdpcontext->settings;
1386 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1387 credType != TSCREDS_REMOTEGUARD)
1389 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1395 case TSCREDS_USER_PASSWD:
1398 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1403 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1407 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1411 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1413 case TSCREDS_SMARTCARD:
1416 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1421 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1423 settings->PasswordIsSmartcardPin = TRUE;
1427 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1429 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1433 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1437 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1439 case TSCREDS_REMOTEGUARD:
1442 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1448 .ServiceTicketLength = 0,
1449 .TicketGrantingTicketLength = 0,
1450 .ServiceTicket = NULL,
1451 .TicketGrantingTicket = NULL };
1455 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1458 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1460 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1463 if (logonCredsType != RCG_TYPE_KERB)
1465 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1469 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1471 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1479 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq) &&
1480 Stream_GetRemainingLength(&suppCredsSeq.source))
1483 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1486 RemoteGuardPackageCredType suppCredsType = RCG_TYPE_NONE;
1488 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1492 if (suppCredsType != RCG_TYPE_NTLM)
1494 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1498 suppCreds = nla_read_NtlmCreds(nla, &ntlmPayload);
1501 WLog_ERR(TAG,
"invalid supplementalCreds");
1507 WLog_ERR(TAG,
"invalid supplementalCreds");
1511 freerdp_peer* peer = nla->rdpcontext->peer;
1512 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1517 WLog_DBG(TAG,
"TSCredentials type %d not supported for now", credType);
1527 WINPR_ASSERT(ticket);
1529 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1530 ticket->TicketGrantingTicketLength))
1533 Stream_Write_UINT32(s, KerbTicketLogon);
1534 Stream_Write_UINT32(s, ticket->Flags);
1535 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1536 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1538 Stream_Write_UINT64(s, 0x20);
1539 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1541 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1542 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1546static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1549 WINPR_ASSERT(logonTicket);
1551 SecurityFunctionTable* table = NULL;
1553 credssp_auth_tableAndContext(nla->auth, &table, &context);
1554 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1558static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1562 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1563 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1568 logonTicket.ServiceTicket = NULL;
1569 logonTicket.TicketGrantingTicket = NULL;
1572 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1576 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1579 s = Stream_New(NULL, 2000);
1583 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1586 credBuffer.len = Stream_GetPosition(s);
1587 credBuffer.data = Stream_Buffer(s);
1588 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1591 free(logonTicket.ServiceTicket);
1592 free(logonTicket.TicketGrantingTicket);
1593 Stream_Free(s, TRUE);
1597static BOOL nla_write_TSRemoteGuardNtlmCred(rdpNla* nla, WinPrAsn1Encoder* enc,
1602 BYTE ntlm[] = {
'N',
'\0',
'T',
'\0',
'L',
'\0',
'M',
'\0' };
1606 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1610 wStream* s = Stream_New(NULL, 300);
1614 Stream_Write_UINT32(s, pntlm->Version);
1615 Stream_Write_UINT32(s, pntlm->Flags);
1617 Stream_Write(s, pntlm->CredentialKey.Data, MSV1_0_CREDENTIAL_KEY_LENGTH);
1618 Stream_Write_UINT32(s, pntlm->CredentialKeyType);
1619 Stream_Write_UINT32(s, pntlm->EncryptedCredsSize);
1620 Stream_Write(s, pntlm->EncryptedCreds, pntlm->EncryptedCredsSize);
1621 Stream_Zero(s, 6 + 16 * 4 + 14);
1625 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1629 Stream_Free(s, TRUE);
1633static BOOL nla_encode_ts_smartcard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1637 WinPrAsn1_tagId tag;
1638 FreeRDP_Settings_Keys_String setting_id;
1639 } cspData_fields[] = { { 1, FreeRDP_CardName },
1640 { 2, FreeRDP_ReaderName },
1641 { 3, FreeRDP_ContainerName },
1642 { 4, FreeRDP_CspName } };
1647 WINPR_ASSERT(nla->rdpcontext);
1649 const rdpSettings* settings = nla->rdpcontext->settings;
1650 WINPR_ASSERT(settings);
1653 if (!WinPrAsn1EncSeqContainer(enc))
1660 octet_string.len = ss *
sizeof(WCHAR);
1661 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1662 free(octet_string.data);
1667 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1671 if (!WinPrAsn1EncContextualInteger(
1673 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER,
1677 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1682 settings, cspData_fields[i].setting_id, &len);
1683 octet_string.len = len *
sizeof(WCHAR);
1684 if (octet_string.len)
1687 WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > 0;
1688 free(octet_string.data);
1695 if (!WinPrAsn1EncEndContainer(enc))
1703 octet_string.len = ss *
sizeof(WCHAR);
1704 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1705 free(octet_string.data);
1715 octet_string.len = ss *
sizeof(WCHAR);
1716 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1717 free(octet_string.data);
1723 return WinPrAsn1EncEndContainer(enc) != 0;
1726static BOOL nla_encode_ts_password_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1734 WINPR_ASSERT(nla->rdpcontext);
1736 const rdpSettings* settings = nla->rdpcontext->settings;
1737 WINPR_ASSERT(settings);
1740 if (!WinPrAsn1EncSeqContainer(enc))
1743 if (!settings->DisableCredentialsDelegation && nla->identity)
1745 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1746 username.data = (BYTE*)nla->identity->User;
1748 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1749 domain.data = (BYTE*)nla->identity->Domain;
1751 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1752 password.data = (BYTE*)nla->identity->Password;
1755 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1757 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1759 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1763 return WinPrAsn1EncEndContainer(enc) != 0;
1766static BOOL nla_encode_ts_remoteguard_credentials(rdpNla* nla, WinPrAsn1Encoder* enc)
1772 if (!WinPrAsn1EncSeqContainer(enc))
1776 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1779 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1787 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1790 if (!WinPrAsn1EncSeqContainer(enc))
1793 if (!nla_write_TSRemoteGuardNtlmCred(nla, enc, ntlm))
1796 if (!WinPrAsn1EncEndContainer(enc))
1799 if (!WinPrAsn1EncEndContainer(enc))
1804 return WinPrAsn1EncEndContainer(enc) != 0;
1814static BOOL nla_encode_ts_credentials(rdpNla* nla)
1817 WinPrAsn1Encoder* enc = NULL;
1820 TsCredentialsType credType = TSCREDS_INVALID;
1823 WINPR_ASSERT(nla->rdpcontext);
1825 rdpSettings* settings = nla->rdpcontext->settings;
1826 WINPR_ASSERT(settings);
1828 if (settings->RemoteCredentialGuard)
1829 credType = TSCREDS_REMOTEGUARD;
1830 else if (settings->SmartcardLogon)
1831 credType = TSCREDS_SMARTCARD;
1833 credType = TSCREDS_USER_PASSWD;
1835 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1840 if (!WinPrAsn1EncSeqContainer(enc))
1844 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1848 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1853 case TSCREDS_SMARTCARD:
1854 if (!nla_encode_ts_smartcard_credentials(nla, enc))
1858 case TSCREDS_USER_PASSWD:
1859 if (!nla_encode_ts_password_credentials(nla, enc))
1863 case TSCREDS_REMOTEGUARD:
1864 if (!nla_encode_ts_remoteguard_credentials(nla, enc))
1872 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1875 if (!WinPrAsn1EncStreamSize(enc, &length))
1878 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1880 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1884 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1886 ret = WinPrAsn1EncToStream(enc, &s);
1889 WinPrAsn1Encoder_Free(&enc);
1893static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1897 if (!nla_encode_ts_credentials(nla))
1900 sspi_SecBufferFree(&nla->authInfo);
1901 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
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 = NULL;
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(NULL, 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 = { 0 };
2072 WinPrAsn1_INTEGER val = { 0 };
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 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);
2458SECURITY_STATUS nla_FreeContextBuffer(rdpNla* nla, PVOID pBuffer)
2462 SecurityFunctionTable* table = NULL;
2464 credssp_auth_tableAndContext(nla->auth, &table, &context);
2466 return table->FreeContextBuffer(pBuffer);
FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *param)
Sets a string settings value. The param is copied.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_string_from_utf16N(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param, size_t length)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API WCHAR * freerdp_settings_get_string_as_utf16(const rdpSettings *settings, FreeRDP_Settings_Keys_String id, size_t *pCharLen)
Return an allocated UTF16 string.
FREERDP_API BOOL freerdp_settings_set_string_from_utf16(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const WCHAR *param)
Sets a string settings value. The param is converted to UTF-8 and the copy stored.