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 != tagId))
1124 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1128 value.len /
sizeof(WCHAR));
1131static BOOL nla_read_TSCspDataDetail(
WinPrAsn1Decoder* dec, rdpSettings* settings)
1136 WinPrAsn1_INTEGER keyspec = 0;
1137 if (!WinPrAsn1DecReadContextualInteger(dec, 0, &error, &keyspec))
1139 settings->KeySpec = (UINT32)keyspec;
1142 if (!set_creds_octetstring_to_settings(dec, 1, TRUE, FreeRDP_CardName, settings))
1146 if (!set_creds_octetstring_to_settings(dec, 2, TRUE, FreeRDP_ReaderName, settings))
1150 if (!set_creds_octetstring_to_settings(dec, 3, TRUE, FreeRDP_ContainerName, settings))
1154 return set_creds_octetstring_to_settings(dec, 4, TRUE, FreeRDP_CspName, settings);
1157static BOOL nla_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1166 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1169 Stream_Read_UINT32(s, ticket->MessageType);
1170 Stream_Read_UINT32(s, ticket->Flags);
1171 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1172 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1174 if (ticket->MessageType != KerbTicketLogon)
1176 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1180 if (!Stream_CheckAndLogRequiredLength(
1181 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1189 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1190 Stream_Seek(s, ticket->ServiceTicketLength);
1195 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1205} RemoteGuardPackageCredType;
1207static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1208 RemoteGuardPackageCredType* credsType,
1214 char packageNameStr[100] = { 0 };
1218 WINPR_ASSERT(credsType);
1219 WINPR_ASSERT(payload);
1221 *credsType = RCG_TYPE_NONE;
1224 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1227 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1228 packageNameStr,
sizeof(packageNameStr));
1229 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1232 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1235 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1237 *credsType = RCG_TYPE_KERB;
1239 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1241 *credsType = RCG_TYPE_NTLM;
1245 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1249 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1256 TSCREDS_INVALID = 0,
1257 TSCREDS_USER_PASSWD = 1,
1258 TSCREDS_SMARTCARD = 2,
1259 TSCREDS_REMOTEGUARD = 6
1262static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1268 WinPrAsn1_INTEGER credType = -1;
1274 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1277 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1282 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1286 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1289 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1291 rdpSettings* settings = nla->rdpcontext->settings;
1292 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1293 credType != TSCREDS_REMOTEGUARD)
1295 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1301 case TSCREDS_USER_PASSWD:
1304 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1309 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1313 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1317 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1319 case TSCREDS_SMARTCARD:
1322 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1327 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1329 settings->PasswordIsSmartcardPin = TRUE;
1333 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1335 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1339 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1343 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1345 case TSCREDS_REMOTEGUARD:
1348 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1354 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1357 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1359 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1362 if (logonCredsType != RCG_TYPE_KERB)
1364 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1368 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1370 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1378 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq))
1381 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1384 RemoteGuardPackageCredType suppCredsType = { 0 };
1386 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1390 if (suppCredsType != RCG_TYPE_NTLM)
1392 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1400 WLog_ERR(TAG,
"invalid supplementalCreds");
1404 freerdp_peer* peer = nla->rdpcontext->peer;
1405 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1409 WLog_DBG(TAG,
"TSCredentials type " PRIu32
" not supported for now", credType);
1419 WINPR_ASSERT(ticket);
1421 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1422 ticket->TicketGrantingTicketLength))
1425 Stream_Write_UINT32(s, KerbTicketLogon);
1426 Stream_Write_UINT32(s, ticket->Flags);
1427 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1428 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1430 Stream_Write_UINT64(s, 0x20);
1431 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1433 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1434 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1438static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1441 WINPR_ASSERT(logonTicket);
1443 SecurityFunctionTable* table = NULL;
1445 credssp_auth_tableAndContext(nla->auth, &table, &context);
1446 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1450static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1454 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1455 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1460 logonTicket.ServiceTicket = NULL;
1461 logonTicket.TicketGrantingTicket = NULL;
1464 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1468 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1471 s = Stream_New(NULL, 2000);
1475 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1478 credBuffer.len = Stream_GetPosition(s);
1479 credBuffer.data = Stream_Buffer(s);
1480 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1483 free(logonTicket.ServiceTicket);
1484 free(logonTicket.TicketGrantingTicket);
1485 Stream_Free(s, TRUE);
1496static BOOL nla_encode_ts_credentials(rdpNla* nla)
1499 WinPrAsn1Encoder* enc = NULL;
1502 TsCredentialsType credType = TSCREDS_INVALID;
1505 WINPR_ASSERT(nla->rdpcontext);
1507 rdpSettings* settings = nla->rdpcontext->settings;
1508 WINPR_ASSERT(settings);
1510 if (settings->RemoteCredentialGuard)
1511 credType = TSCREDS_REMOTEGUARD;
1512 else if (settings->SmartcardLogon)
1513 credType = TSCREDS_SMARTCARD;
1515 credType = TSCREDS_USER_PASSWD;
1517 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1522 if (!WinPrAsn1EncSeqContainer(enc))
1526 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1530 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1535 case TSCREDS_SMARTCARD:
1539 WinPrAsn1_tagId tag;
1540 FreeRDP_Settings_Keys_String setting_id;
1541 } cspData_fields[] = { { 1, FreeRDP_CardName },
1542 { 2, FreeRDP_ReaderName },
1543 { 3, FreeRDP_ContainerName },
1544 { 4, FreeRDP_CspName } };
1548 if (!WinPrAsn1EncSeqContainer(enc))
1555 octet_string.len = ss *
sizeof(WCHAR);
1556 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1557 free(octet_string.data);
1562 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1566 if (!WinPrAsn1EncContextualInteger(
1568 WINPR_ASSERTING_INT_CAST(
1572 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1577 settings, cspData_fields[i].setting_id, &len);
1578 octet_string.len = len *
sizeof(WCHAR);
1579 if (octet_string.len)
1581 const BOOL res2 = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag,
1583 free(octet_string.data);
1590 if (!WinPrAsn1EncEndContainer(enc))
1598 octet_string.len = ss *
sizeof(WCHAR);
1599 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1600 free(octet_string.data);
1610 octet_string.len = ss *
sizeof(WCHAR);
1611 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1612 free(octet_string.data);
1618 if (!WinPrAsn1EncEndContainer(enc))
1622 case TSCREDS_USER_PASSWD:
1629 if (!WinPrAsn1EncSeqContainer(enc))
1632 if (!settings->DisableCredentialsDelegation && nla->identity)
1634 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1635 username.data = (BYTE*)nla->identity->User;
1637 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1638 domain.data = (BYTE*)nla->identity->Domain;
1640 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1641 password.data = (BYTE*)nla->identity->Password;
1644 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1646 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1648 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1652 if (!WinPrAsn1EncEndContainer(enc))
1656 case TSCREDS_REMOTEGUARD:
1658 if (!WinPrAsn1EncSeqContainer(enc))
1662 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1665 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1673 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncEndContainer(enc))
1677 if (!WinPrAsn1EncEndContainer(enc))
1685 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1688 if (!WinPrAsn1EncStreamSize(enc, &length))
1691 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1693 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1697 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1699 ret = WinPrAsn1EncToStream(enc, &s);
1702 WinPrAsn1Encoder_Free(&enc);
1706static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1710 if (!nla_encode_ts_credentials(nla))
1713 sspi_SecBufferFree(&nla->authInfo);
1714 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1721static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1725 if (nla->authInfo.cbBuffer < 1)
1727 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1731 sspi_SecBufferFree(&nla->tsCredentials);
1732 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1735 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1741static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1742 WinPrAsn1_tagId tagId,
const char* msg)
1747 WINPR_ASSERT(buffer);
1750 if (buffer->cbBuffer > 0)
1755 WLog_DBG(TAG,
" ----->> %s", msg);
1756 octet_string.data = buffer->pvBuffer;
1757 octet_string.len = buffer->cbBuffer;
1758 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1766static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1767 WinPrAsn1_tagId tagId,
const char* msg)
1769 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1770 sspi_SecBufferFree(buffer);
1782BOOL nla_send(rdpNla* nla)
1787 WinPrAsn1Encoder* enc = NULL;
1791 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1796 WLog_DBG(TAG,
"----->> sending...");
1797 if (!WinPrAsn1EncSeqContainer(enc))
1801 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1802 if (!WinPrAsn1EncContextualInteger(enc, 0,
1803 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1807 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1809 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1811 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
1815 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
1819 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1824 if (nla->authInfo.cbBuffer > 0)
1826 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
1831 if (nla->pubKeyAuth.cbBuffer > 0)
1833 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
1838 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
1840 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1842 if (!WinPrAsn1EncContextualInteger(
1843 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
1848 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
1850 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
1855 if (!WinPrAsn1EncEndContainer(enc))
1858 if (!WinPrAsn1EncStreamSize(enc, &length))
1861 s = Stream_New(NULL, length);
1865 if (!WinPrAsn1EncToStream(enc, s))
1868 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
1869 if (transport_write(nla->transport, s) < 0)
1874 Stream_Free(s, TRUE);
1875 WinPrAsn1Encoder_Free(&enc);
1879static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
1884 WinPrAsn1_tagId tag = { 0 };
1885 WinPrAsn1_INTEGER val = { 0 };
1891 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
1893 WLog_DBG(TAG,
"<<----- receiving...");
1896 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
1902 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
1905 if (!Stream_SafeSeek(s, offset))
1908 version = (UINT)val;
1909 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
1911 if (nla->peerVersion == 0)
1912 nla->peerVersion = version;
1915 if (nla->peerVersion != version)
1917 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
1918 nla->peerVersion, version);
1922 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
1930 WLog_DBG(TAG,
" <<----- nego token");
1932 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
1933 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
1936 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
1940 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
1945 WLog_DBG(TAG,
" <<----- auth info");
1947 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1949 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
1954 WLog_DBG(TAG,
" <<----- public key auth");
1956 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1958 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
1964 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
1966 nla->errorCode = val;
1967 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1971 WLog_DBG(TAG,
" <<----- client nonce");
1973 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1975 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
1987int nla_recv_pdu(rdpNla* nla,
wStream* s)
1992 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
1995 Stream_Read_UINT32(s, code);
1996 if (code != AUTHZ_SUCCESS)
1998 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
1999 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2000 freerdp_set_last_error_log(nla->rdpcontext, code);
2004 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2008 if (nla_decode_ts_request(nla, s) < 1)
2015 switch (nla->errorCode)
2017 case STATUS_PASSWORD_MUST_CHANGE:
2018 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2021 case STATUS_PASSWORD_EXPIRED:
2022 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2025 case STATUS_ACCOUNT_DISABLED:
2026 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2029 case STATUS_LOGON_FAILURE:
2030 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2033 case STATUS_WRONG_PASSWORD:
2034 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2037 case STATUS_ACCESS_DENIED:
2038 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2041 case STATUS_ACCOUNT_RESTRICTION:
2042 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2045 case STATUS_ACCOUNT_LOCKED_OUT:
2046 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2049 case STATUS_ACCOUNT_EXPIRED:
2050 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2053 case STATUS_LOGON_TYPE_NOT_GRANTED:
2054 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2058 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32
"]",
2059 NtStatus2Tag(nla->errorCode), nla->errorCode);
2060 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2064 freerdp_set_last_error_log(nla->rdpcontext, code);
2069 return nla_client_recv(nla);
2072int nla_server_recv(rdpNla* nla)
2078 wStream* s = nla_server_recv_stream(nla);
2081 status = nla_decode_ts_request(nla, s);
2084 Stream_Free(s, TRUE);
2097rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2099 WINPR_ASSERT(transport);
2100 WINPR_ASSERT(context);
2102 rdpSettings* settings = context->settings;
2103 WINPR_ASSERT(settings);
2105 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2110 nla->rdpcontext = context;
2111 nla->server = settings->ServerMode;
2112 nla->transport = transport;
2113 nla->sendSeqNum = 0;
2114 nla->recvSeqNum = 0;
2116 nla->earlyUserAuth = FALSE;
2118 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2122 nla->auth = credssp_auth_new(context);
2127 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2131 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2136 WINPR_PRAGMA_DIAG_PUSH
2137 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2139 WINPR_PRAGMA_DIAG_POP
2148void nla_free(rdpNla* nla)
2153 smartcardCertInfo_Free(nla->smartcardCert);
2154 nla_buffer_free(nla);
2155 sspi_SecBufferFree(&nla->tsCredentials);
2156 credssp_auth_free(nla->auth);
2158 sspi_FreeAuthIdentity(nla->identity);
2159 free(nla->pkinitArgs);
2160 free(nla->identity);
2164SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2169 return nla->identity;
2172NLA_STATE nla_get_state(rdpNla* nla)
2175 return NLA_STATE_FINAL;
2180BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2185 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2190BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2192 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2197BOOL nla_impersonate(rdpNla* nla)
2199 return credssp_auth_impersonate(nla->auth);
2202BOOL nla_revert_to_self(rdpNla* nla)
2204 return credssp_auth_revert_to_self(nla->auth);
2207const char* nla_get_state_str(NLA_STATE state)
2211 case NLA_STATE_INITIAL:
2212 return "NLA_STATE_INITIAL";
2213 case NLA_STATE_NEGO_TOKEN:
2214 return "NLA_STATE_NEGO_TOKEN";
2215 case NLA_STATE_PUB_KEY_AUTH:
2216 return "NLA_STATE_PUB_KEY_AUTH";
2217 case NLA_STATE_AUTH_INFO:
2218 return "NLA_STATE_AUTH_INFO";
2219 case NLA_STATE_POST_NEGO:
2220 return "NLA_STATE_POST_NEGO";
2221 case NLA_STATE_EARLY_USER_AUTH:
2222 return "NLA_STATE_EARLY_USER_AUTH";
2223 case NLA_STATE_FINAL:
2224 return "NLA_STATE_FINAL";
2230DWORD nla_get_error(rdpNla* nla)
2233 return ERROR_INTERNAL_ERROR;
2234 return (UINT32)nla->errorCode;
2237INT32 nla_get_sspi_error(rdpNla* nla)
2240 return credssp_auth_sspi_error(nla->auth);
2246 WINPR_ASSERT(inBuffer);
2247 WINPR_ASSERT(outBuffer);
2248 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2254 WINPR_ASSERT(inBuffer);
2255 WINPR_ASSERT(outBuffer);
2256 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2259SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2263 SecurityFunctionTable* table = NULL;
2265 credssp_auth_tableAndContext(nla->auth, &table, &context);
2267 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.