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 if (!identity_set_from_settings_with_pwd(
390 nla->identity, settings, FreeRDP_Username, FreeRDP_Domain,
391 (
const WCHAR*)settings->RedirectionPassword,
392 settings->RedirectionPasswordLength /
sizeof(WCHAR)))
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, NULL))
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 = NULL;
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(NULL, 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_SetPosition(s, 0);
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 = NULL;
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, NULL))
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(NULL, 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);
957 status = credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++);
958 sspi_SecBufferFree(&buf);
962 status = credssp_auth_encrypt(nla->auth, &nla->PublicKey, &nla->pubKeyAuth, NULL,
969BOOL nla_encrypt_public_key_hash(rdpNla* nla)
972 WINPR_DIGEST_CTX* sha256 = NULL;
977 const BYTE* hashMagic = nla->server ? ServerClientHashMagic : ClientServerHashMagic;
978 const size_t hashSize =
979 nla->server ?
sizeof(ServerClientHashMagic) : sizeof(ClientServerHashMagic);
981 if (!sspi_SecBufferAlloc(&buf, WINPR_SHA256_DIGEST_LENGTH))
985 if (!(sha256 = winpr_Digest_New()))
988 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
992 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
995 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
999 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1002 if (!winpr_Digest_Final(sha256, buf.pvBuffer, WINPR_SHA256_DIGEST_LENGTH))
1005 sspi_SecBufferFree(&nla->pubKeyAuth);
1006 if (!credssp_auth_encrypt(nla->auth, &buf, &nla->pubKeyAuth, NULL, nla->sendSeqNum++))
1012 winpr_Digest_Free(sha256);
1013 sspi_SecBufferFree(&buf);
1017BOOL nla_decrypt_public_key_echo(rdpNla* nla)
1019 BOOL status = FALSE;
1025 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &public_key, nla->recvSeqNum++))
1031 ap_integer_decrement_le(public_key.pvBuffer, public_key.cbBuffer);
1034 if (public_key.cbBuffer != nla->PublicKey.cbBuffer ||
1035 memcmp(public_key.pvBuffer, nla->PublicKey.pvBuffer, public_key.cbBuffer) != 0)
1037 WLog_ERR(TAG,
"Could not verify server's public key echo");
1038#if defined(WITH_DEBUG_NLA)
1039 WLog_ERR(TAG,
"Expected (length = %" PRIu32
"):", nla->PublicKey.cbBuffer);
1040 winpr_HexDump(TAG, WLOG_ERROR, nla->PublicKey.pvBuffer, nla->PublicKey.cbBuffer);
1041 WLog_ERR(TAG,
"Actual (length = %" PRIu32
"):", public_key.cbBuffer);
1042 winpr_HexDump(TAG, WLOG_ERROR, public_key.pvBuffer, public_key.cbBuffer);
1050 sspi_SecBufferFree(&public_key);
1054BOOL nla_decrypt_public_key_hash(rdpNla* nla)
1056 WINPR_DIGEST_CTX* sha256 = NULL;
1057 BYTE serverClientHash[WINPR_SHA256_DIGEST_LENGTH] = { 0 };
1058 BOOL status = FALSE;
1062 const BYTE* hashMagic = nla->server ? ClientServerHashMagic : ServerClientHashMagic;
1063 const size_t hashSize =
1064 nla->server ?
sizeof(ClientServerHashMagic) : sizeof(ServerClientHashMagic);
1067 if (!credssp_auth_decrypt(nla->auth, &nla->pubKeyAuth, &hash, nla->recvSeqNum++))
1071 if (!(sha256 = winpr_Digest_New()))
1074 if (!winpr_Digest_Init(sha256, WINPR_MD_SHA256))
1078 if (!winpr_Digest_Update(sha256, hashMagic, hashSize))
1081 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->ClientNonce))
1085 if (!nla_Digest_Update_From_SecBuffer(sha256, &nla->PublicKey))
1088 if (!winpr_Digest_Final(sha256, serverClientHash,
sizeof(serverClientHash)))
1092 if (hash.cbBuffer != WINPR_SHA256_DIGEST_LENGTH ||
1093 memcmp(serverClientHash, hash.pvBuffer, WINPR_SHA256_DIGEST_LENGTH) != 0)
1095 WLog_ERR(TAG,
"Could not verify server's hash");
1102 winpr_Digest_Free(sha256);
1103 sspi_SecBufferFree(&hash);
1107static BOOL set_creds_octetstring_to_settings(
WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
1108 BOOL optional, FreeRDP_Settings_Keys_String settingId,
1109 rdpSettings* settings)
1113 WinPrAsn1_tagId itemTag = 0;
1114 if (!WinPrAsn1DecPeekTag(dec, &itemTag) || (itemTag != tagId))
1123 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1127 value.len /
sizeof(WCHAR));
1130static BOOL nla_read_TSCspDataDetail(
WinPrAsn1Decoder* dec, rdpSettings* settings)
1135 WinPrAsn1_INTEGER keyspec = 0;
1136 if (!WinPrAsn1DecReadContextualInteger(dec, 0, &error, &keyspec))
1138 settings->KeySpec = (UINT32)keyspec;
1141 if (!set_creds_octetstring_to_settings(dec, 1, TRUE, FreeRDP_CardName, settings))
1145 if (!set_creds_octetstring_to_settings(dec, 2, TRUE, FreeRDP_ReaderName, settings))
1149 if (!set_creds_octetstring_to_settings(dec, 3, TRUE, FreeRDP_ContainerName, settings))
1153 return set_creds_octetstring_to_settings(dec, 4, TRUE, FreeRDP_CspName, settings);
1156static BOOL nla_read_KERB_TICKET_LOGON(WINPR_ATTR_UNUSED rdpNla* nla,
wStream* s,
1165 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1168 Stream_Read_UINT32(s, ticket->MessageType);
1169 Stream_Read_UINT32(s, ticket->Flags);
1170 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1171 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1173 if (ticket->MessageType != KerbTicketLogon)
1175 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1179 if (!Stream_CheckAndLogRequiredLength(
1180 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1188 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1189 Stream_Seek(s, ticket->ServiceTicketLength);
1194 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1204} RemoteGuardPackageCredType;
1206static BOOL nla_read_TSRemoteGuardPackageCred(WINPR_ATTR_UNUSED rdpNla* nla,
WinPrAsn1Decoder* dec,
1207 RemoteGuardPackageCredType* credsType,
1213 char packageNameStr[100] = { 0 };
1217 WINPR_ASSERT(credsType);
1218 WINPR_ASSERT(payload);
1220 *credsType = RCG_TYPE_NONE;
1223 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1226 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1227 packageNameStr,
sizeof(packageNameStr));
1228 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1231 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1234 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1236 *credsType = RCG_TYPE_KERB;
1238 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1240 *credsType = RCG_TYPE_NTLM;
1244 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1248 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1255 TSCREDS_INVALID = 0,
1256 TSCREDS_USER_PASSWD = 1,
1257 TSCREDS_SMARTCARD = 2,
1258 TSCREDS_REMOTEGUARD = 6
1261static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1267 WinPrAsn1_INTEGER credType = -1;
1273 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1276 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1281 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1285 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1288 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1290 rdpSettings* settings = nla->rdpcontext->settings;
1291 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1292 credType != TSCREDS_REMOTEGUARD)
1294 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1300 case TSCREDS_USER_PASSWD:
1303 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1308 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1312 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1316 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1318 case TSCREDS_SMARTCARD:
1321 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1326 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1328 settings->PasswordIsSmartcardPin = TRUE;
1332 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1334 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1338 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1342 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1344 case TSCREDS_REMOTEGUARD:
1347 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1353 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1356 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1358 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1361 if (logonCredsType != RCG_TYPE_KERB)
1363 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1367 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1369 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1377 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq))
1380 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1383 RemoteGuardPackageCredType suppCredsType = { 0 };
1385 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1389 if (suppCredsType != RCG_TYPE_NTLM)
1391 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1399 WLog_ERR(TAG,
"invalid supplementalCreds");
1403 freerdp_peer* peer = nla->rdpcontext->peer;
1404 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1408 WLog_DBG(TAG,
"TSCredentials type " PRIu32
" not supported for now", credType);
1418 WINPR_ASSERT(ticket);
1420 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1421 ticket->TicketGrantingTicketLength))
1424 Stream_Write_UINT32(s, KerbTicketLogon);
1425 Stream_Write_UINT32(s, ticket->Flags);
1426 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1427 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1429 Stream_Write_UINT64(s, 0x20);
1430 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1432 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1433 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1437static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1440 WINPR_ASSERT(logonTicket);
1442 SecurityFunctionTable* table = NULL;
1444 credssp_auth_tableAndContext(nla->auth, &table, &context);
1445 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1449static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1453 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1454 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1459 logonTicket.ServiceTicket = NULL;
1460 logonTicket.TicketGrantingTicket = NULL;
1463 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1467 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1470 s = Stream_New(NULL, 2000);
1474 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1477 credBuffer.len = Stream_GetPosition(s);
1478 credBuffer.data = Stream_Buffer(s);
1479 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1482 free(logonTicket.ServiceTicket);
1483 free(logonTicket.TicketGrantingTicket);
1484 Stream_Free(s, TRUE);
1495static BOOL nla_encode_ts_credentials(rdpNla* nla)
1498 WinPrAsn1Encoder* enc = NULL;
1501 TsCredentialsType credType = TSCREDS_INVALID;
1504 WINPR_ASSERT(nla->rdpcontext);
1506 rdpSettings* settings = nla->rdpcontext->settings;
1507 WINPR_ASSERT(settings);
1509 if (settings->RemoteCredentialGuard)
1510 credType = TSCREDS_REMOTEGUARD;
1511 else if (settings->SmartcardLogon)
1512 credType = TSCREDS_SMARTCARD;
1514 credType = TSCREDS_USER_PASSWD;
1516 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1521 if (!WinPrAsn1EncSeqContainer(enc))
1525 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1529 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1534 case TSCREDS_SMARTCARD:
1538 WinPrAsn1_tagId tag;
1539 FreeRDP_Settings_Keys_String setting_id;
1540 } cspData_fields[] = { { 1, FreeRDP_CardName },
1541 { 2, FreeRDP_ReaderName },
1542 { 3, FreeRDP_ContainerName },
1543 { 4, FreeRDP_CspName } };
1547 if (!WinPrAsn1EncSeqContainer(enc))
1554 octet_string.len = ss *
sizeof(WCHAR);
1555 BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1556 free(octet_string.data);
1561 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1565 if (!WinPrAsn1EncContextualInteger(
1567 WINPR_ASSERTING_INT_CAST(
1571 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1576 settings, cspData_fields[i].setting_id, &len);
1577 octet_string.len = len *
sizeof(WCHAR);
1578 if (octet_string.len)
1580 const BOOL res2 = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag,
1582 free(octet_string.data);
1589 if (!WinPrAsn1EncEndContainer(enc))
1597 octet_string.len = ss *
sizeof(WCHAR);
1598 res = WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) > 0;
1599 free(octet_string.data);
1609 octet_string.len = ss *
sizeof(WCHAR);
1610 res = WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) > 0;
1611 free(octet_string.data);
1617 if (!WinPrAsn1EncEndContainer(enc))
1621 case TSCREDS_USER_PASSWD:
1628 if (!WinPrAsn1EncSeqContainer(enc))
1631 if (!settings->DisableCredentialsDelegation && nla->identity)
1633 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1634 username.data = (BYTE*)nla->identity->User;
1636 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1637 domain.data = (BYTE*)nla->identity->Domain;
1639 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1640 password.data = (BYTE*)nla->identity->Password;
1643 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1645 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1647 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1651 if (!WinPrAsn1EncEndContainer(enc))
1655 case TSCREDS_REMOTEGUARD:
1657 if (!WinPrAsn1EncSeqContainer(enc))
1661 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1664 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1672 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncEndContainer(enc))
1676 if (!WinPrAsn1EncEndContainer(enc))
1684 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1687 if (!WinPrAsn1EncStreamSize(enc, &length))
1690 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1692 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1696 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1698 ret = WinPrAsn1EncToStream(enc, &s);
1701 WinPrAsn1Encoder_Free(&enc);
1705static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1709 if (!nla_encode_ts_credentials(nla))
1712 sspi_SecBufferFree(&nla->authInfo);
1713 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1720static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1724 if (nla->authInfo.cbBuffer < 1)
1726 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1730 sspi_SecBufferFree(&nla->tsCredentials);
1731 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1734 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1740static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1741 WinPrAsn1_tagId tagId,
const char* msg)
1746 WINPR_ASSERT(buffer);
1749 if (buffer->cbBuffer > 0)
1754 WLog_DBG(TAG,
" ----->> %s", msg);
1755 octet_string.data = buffer->pvBuffer;
1756 octet_string.len = buffer->cbBuffer;
1757 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1765static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1766 WinPrAsn1_tagId tagId,
const char* msg)
1768 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1769 sspi_SecBufferFree(buffer);
1781BOOL nla_send(rdpNla* nla)
1786 WinPrAsn1Encoder* enc = NULL;
1790 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1795 WLog_DBG(TAG,
"----->> sending...");
1796 if (!WinPrAsn1EncSeqContainer(enc))
1800 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1801 if (!WinPrAsn1EncContextualInteger(enc, 0,
1802 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1806 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1808 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1810 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
1814 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
1818 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1823 if (nla->authInfo.cbBuffer > 0)
1825 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
1830 if (nla->pubKeyAuth.cbBuffer > 0)
1832 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
1837 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
1839 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1841 if (!WinPrAsn1EncContextualInteger(
1842 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
1847 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
1849 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
1854 if (!WinPrAsn1EncEndContainer(enc))
1857 if (!WinPrAsn1EncStreamSize(enc, &length))
1860 s = Stream_New(NULL, length);
1864 if (!WinPrAsn1EncToStream(enc, s))
1867 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
1868 if (transport_write(nla->transport, s) < 0)
1873 Stream_Free(s, TRUE);
1874 WinPrAsn1Encoder_Free(&enc);
1878static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
1883 WinPrAsn1_tagId tag = { 0 };
1884 WinPrAsn1_INTEGER val = { 0 };
1890 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
1892 WLog_DBG(TAG,
"<<----- receiving...");
1895 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
1901 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
1904 if (!Stream_SafeSeek(s, offset))
1907 version = (UINT)val;
1908 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
1910 if (nla->peerVersion == 0)
1911 nla->peerVersion = version;
1914 if (nla->peerVersion != version)
1916 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
1917 nla->peerVersion, version);
1921 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
1929 WLog_DBG(TAG,
" <<----- nego token");
1931 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
1932 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
1935 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
1939 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
1944 WLog_DBG(TAG,
" <<----- auth info");
1946 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1948 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
1953 WLog_DBG(TAG,
" <<----- public key auth");
1955 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1957 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
1963 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
1965 nla->errorCode = val;
1966 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1970 WLog_DBG(TAG,
" <<----- client nonce");
1972 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1974 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
1986int nla_recv_pdu(rdpNla* nla,
wStream* s)
1991 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
1994 Stream_Read_UINT32(s, code);
1995 if (code != AUTHZ_SUCCESS)
1997 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
1998 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
1999 freerdp_set_last_error_log(nla->rdpcontext, code);
2003 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
2007 if (nla_decode_ts_request(nla, s) < 1)
2014 switch (nla->errorCode)
2016 case STATUS_PASSWORD_MUST_CHANGE:
2017 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
2020 case STATUS_PASSWORD_EXPIRED:
2021 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
2024 case STATUS_ACCOUNT_DISABLED:
2025 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2028 case STATUS_LOGON_FAILURE:
2029 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2032 case STATUS_WRONG_PASSWORD:
2033 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2036 case STATUS_ACCESS_DENIED:
2037 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2040 case STATUS_ACCOUNT_RESTRICTION:
2041 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2044 case STATUS_ACCOUNT_LOCKED_OUT:
2045 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2048 case STATUS_ACCOUNT_EXPIRED:
2049 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2052 case STATUS_LOGON_TYPE_NOT_GRANTED:
2053 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2057 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32
"]",
2058 NtStatus2Tag(nla->errorCode), nla->errorCode);
2059 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2063 freerdp_set_last_error_log(nla->rdpcontext, code);
2068 return nla_client_recv(nla);
2071int nla_server_recv(rdpNla* nla)
2077 wStream* s = nla_server_recv_stream(nla);
2080 status = nla_decode_ts_request(nla, s);
2083 Stream_Free(s, TRUE);
2096rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2098 WINPR_ASSERT(transport);
2099 WINPR_ASSERT(context);
2101 rdpSettings* settings = context->settings;
2102 WINPR_ASSERT(settings);
2104 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2109 nla->rdpcontext = context;
2110 nla->server = settings->ServerMode;
2111 nla->transport = transport;
2112 nla->sendSeqNum = 0;
2113 nla->recvSeqNum = 0;
2115 nla->earlyUserAuth = FALSE;
2117 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2121 nla->auth = credssp_auth_new(context);
2126 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2130 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2135 WINPR_PRAGMA_DIAG_PUSH
2136 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2138 WINPR_PRAGMA_DIAG_POP
2147void nla_free(rdpNla* nla)
2152 smartcardCertInfo_Free(nla->smartcardCert);
2153 nla_buffer_free(nla);
2154 sspi_SecBufferFree(&nla->tsCredentials);
2155 credssp_auth_free(nla->auth);
2157 sspi_FreeAuthIdentity(nla->identity);
2158 free(nla->pkinitArgs);
2159 free(nla->identity);
2163SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2168 return nla->identity;
2171NLA_STATE nla_get_state(rdpNla* nla)
2174 return NLA_STATE_FINAL;
2179BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2184 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2189BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2191 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2196BOOL nla_impersonate(rdpNla* nla)
2198 return credssp_auth_impersonate(nla->auth);
2201BOOL nla_revert_to_self(rdpNla* nla)
2203 return credssp_auth_revert_to_self(nla->auth);
2206const char* nla_get_state_str(NLA_STATE state)
2210 case NLA_STATE_INITIAL:
2211 return "NLA_STATE_INITIAL";
2212 case NLA_STATE_NEGO_TOKEN:
2213 return "NLA_STATE_NEGO_TOKEN";
2214 case NLA_STATE_PUB_KEY_AUTH:
2215 return "NLA_STATE_PUB_KEY_AUTH";
2216 case NLA_STATE_AUTH_INFO:
2217 return "NLA_STATE_AUTH_INFO";
2218 case NLA_STATE_POST_NEGO:
2219 return "NLA_STATE_POST_NEGO";
2220 case NLA_STATE_EARLY_USER_AUTH:
2221 return "NLA_STATE_EARLY_USER_AUTH";
2222 case NLA_STATE_FINAL:
2223 return "NLA_STATE_FINAL";
2229DWORD nla_get_error(rdpNla* nla)
2232 return ERROR_INTERNAL_ERROR;
2233 return (UINT32)nla->errorCode;
2236INT32 nla_get_sspi_error(rdpNla* nla)
2239 return credssp_auth_sspi_error(nla->auth);
2245 WINPR_ASSERT(inBuffer);
2246 WINPR_ASSERT(outBuffer);
2247 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2253 WINPR_ASSERT(inBuffer);
2254 WINPR_ASSERT(outBuffer);
2255 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2258SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2262 SecurityFunctionTable* table = NULL;
2264 credssp_auth_tableAndContext(nla->auth, &table, &context);
2266 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.