25 #include <freerdp/config.h>
32 #include <freerdp/log.h>
33 #include <freerdp/build-config.h>
35 #include <winpr/crt.h>
36 #include <winpr/assert.h>
37 #include <winpr/sam.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;
141 static BOOL nla_send(rdpNla* nla);
142 static int nla_server_recv(rdpNla* nla);
143 static BOOL nla_encrypt_public_key_echo(rdpNla* nla);
144 static BOOL nla_encrypt_public_key_hash(rdpNla* nla);
145 static BOOL nla_decrypt_public_key_echo(rdpNla* nla);
146 static BOOL nla_decrypt_public_key_hash(rdpNla* nla);
147 static BOOL nla_encrypt_ts_credentials(rdpNla* nla);
148 static BOOL nla_decrypt_ts_credentials(rdpNla* nla);
150 void 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;
157 static 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);
167 static BOOL nla_Digest_Update_From_SecBuffer(WINPR_DIGEST_CTX* ctx,
const SecBuffer* buffer)
171 return winpr_Digest_Update(ctx, buffer->pvBuffer, buffer->cbBuffer);
174 static 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;
188 static 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);
201 static 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 };
208 static 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 };
214 static const UINT32 NonceLength = 32;
216 static 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");
290 static 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);
367 nla->identity = NULL;
369 else if (settings->SmartcardLogon)
371 if (smartCardLogonWasDisabled)
373 if (!nla_adjust_settings_from_smartcard(nla))
377 if (!identity_set_from_smartcard_hash(nla->identity, settings, FreeRDP_Username,
378 FreeRDP_Domain, FreeRDP_Password, nla->certSha1,
379 sizeof(nla->certSha1)))
384 BOOL usePassword = TRUE;
386 if (settings->RedirectionPassword && (settings->RedirectionPasswordLength > 0))
388 if (!identity_set_from_settings_with_pwd(
389 nla->identity, settings, FreeRDP_Username, FreeRDP_Domain,
390 (
const WCHAR*)settings->RedirectionPassword,
391 settings->RedirectionPasswordLength /
sizeof(WCHAR)))
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))
426 static 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");
467 int 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);
520 static 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);
556 static 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);
591 static 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);
600 static 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)));
623 static 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);
667 static 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);
695 static 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);
720 static 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))
746 static 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);
895 int nla_authenticate(rdpNla* nla)
900 return nla_server_authenticate(nla);
902 return nla_client_authenticate(nla);
905 static 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)
924 static 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;
943 BOOL 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,
968 BOOL 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);
1016 BOOL 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);
1053 BOOL 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);
1106 static 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 != tagId))
1122 if (!WinPrAsn1DecReadContextualOctetString(dec, tagId, &error, &value, FALSE))
1126 value.len /
sizeof(WCHAR));
1129 static 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);
1163 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16 + 16))
1166 Stream_Read_UINT32(s, ticket->MessageType);
1167 Stream_Read_UINT32(s, ticket->Flags);
1168 Stream_Read_UINT32(s, ticket->ServiceTicketLength);
1169 Stream_Read_UINT32(s, ticket->TicketGrantingTicketLength);
1171 if (ticket->MessageType != KerbTicketLogon)
1173 WLog_ERR(TAG,
"Not a KerbTicketLogon");
1177 if (!Stream_CheckAndLogRequiredLength(
1178 TAG, s, 16ull + ticket->ServiceTicketLength + ticket->TicketGrantingTicketLength))
1186 ticket->ServiceTicket = Stream_PointerAs(s, UCHAR);
1187 Stream_Seek(s, ticket->ServiceTicketLength);
1192 ticket->TicketGrantingTicket = Stream_PointerAs(s, UCHAR);
1202 } RemoteGuardPackageCredType;
1204 static BOOL nla_read_TSRemoteGuardPackageCred(rdpNla* nla,
WinPrAsn1Decoder* dec,
1205 RemoteGuardPackageCredType* credsType,
1211 char packageNameStr[100] = { 0 };
1215 WINPR_ASSERT(credsType);
1216 WINPR_ASSERT(payload);
1218 *credsType = RCG_TYPE_NONE;
1221 if (!WinPrAsn1DecReadContextualOctetString(dec, 0, &error, &packageName, FALSE) || error)
1224 ConvertMszWCharNToUtf8((WCHAR*)packageName.data, packageName.len /
sizeof(WCHAR),
1225 packageNameStr,
sizeof(packageNameStr));
1226 WLog_DBG(TAG,
"TSRemoteGuardPackageCred(%s)", packageNameStr);
1229 if (!WinPrAsn1DecReadContextualOctetString(dec, 1, &error, &credBuffer, FALSE) || error)
1232 if (_stricmp(packageNameStr,
"Kerberos") == 0)
1234 *credsType = RCG_TYPE_KERB;
1236 else if (_stricmp(packageNameStr,
"NTLM") == 0)
1238 *credsType = RCG_TYPE_NTLM;
1242 WLog_INFO(TAG,
"TSRemoteGuardPackageCred package %s not handled", packageNameStr);
1246 Stream_StaticInit(payload, credBuffer.data, credBuffer.len);
1253 TSCREDS_INVALID = 0,
1254 TSCREDS_USER_PASSWD = 1,
1255 TSCREDS_SMARTCARD = 2,
1256 TSCREDS_REMOTEGUARD = 6
1257 } TsCredentialsType;
1259 static BOOL nla_read_ts_credentials(rdpNla* nla,
SecBuffer* data)
1265 WinPrAsn1_INTEGER credType = -1;
1271 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer, data->cbBuffer);
1274 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1279 if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
1283 if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
1286 WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
1288 rdpSettings* settings = nla->rdpcontext->settings;
1289 if (nego_get_remoteCredentialGuard(nla->rdpcontext->rdp->nego) &&
1290 credType != TSCREDS_REMOTEGUARD)
1292 WLog_ERR(TAG,
"connecting with RCG but it's not TSRemoteGuard credentials");
1298 case TSCREDS_USER_PASSWD:
1301 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1306 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Domain, settings))
1310 if (!set_creds_octetstring_to_settings(&dec, 1, FALSE, FreeRDP_Username, settings))
1314 return set_creds_octetstring_to_settings(&dec, 2, FALSE, FreeRDP_Password, settings);
1316 case TSCREDS_SMARTCARD:
1319 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1324 if (!set_creds_octetstring_to_settings(&dec, 0, FALSE, FreeRDP_Password, settings))
1326 settings->PasswordIsSmartcardPin = TRUE;
1330 if (!WinPrAsn1DecReadContextualSequence(&dec, 1, &error, &cspDetails) && error)
1332 if (!nla_read_TSCspDataDetail(&cspDetails, settings))
1336 if (!set_creds_octetstring_to_settings(&dec, 2, TRUE, FreeRDP_Username, settings))
1340 return set_creds_octetstring_to_settings(&dec, 3, TRUE, FreeRDP_Domain, settings);
1342 case TSCREDS_REMOTEGUARD:
1345 if (!WinPrAsn1DecReadSequence(&dec, &dec2))
1351 if (!WinPrAsn1DecReadContextualSequence(&dec2, 0, &error, &logonCredsSeq) || error)
1354 RemoteGuardPackageCredType logonCredsType = RCG_TYPE_NONE;
1356 if (!nla_read_TSRemoteGuardPackageCred(nla, &logonCredsSeq, &logonCredsType,
1359 if (logonCredsType != RCG_TYPE_KERB)
1361 WLog_ERR(TAG,
"logonCred must be some Kerberos creds");
1365 if (!nla_read_KERB_TICKET_LOGON(nla, &logonPayload, &kerbLogon))
1367 WLog_ERR(TAG,
"invalid KERB_TICKET_LOGON");
1375 if (WinPrAsn1DecReadContextualSequence(&dec2, 1, &error, &suppCredsSeq))
1378 if (!WinPrAsn1DecReadSequence(&suppCredsSeq, &ntlmCredsSeq))
1381 RemoteGuardPackageCredType suppCredsType = { 0 };
1383 if (!nla_read_TSRemoteGuardPackageCred(nla, &ntlmCredsSeq, &suppCredsType,
1387 if (suppCredsType != RCG_TYPE_NTLM)
1389 WLog_ERR(TAG,
"supplementalCreds must be some NTLM creds");
1397 WLog_ERR(TAG,
"invalid supplementalCreds");
1401 freerdp_peer* peer = nla->rdpcontext->peer;
1402 ret = IFCALLRESULT(TRUE, peer->RemoteCredentials, peer, &kerbLogon, suppCreds);
1406 WLog_DBG(TAG,
"TSCredentials type " PRIu32
" not supported for now", credType);
1416 WINPR_ASSERT(ticket);
1418 if (!Stream_EnsureRemainingCapacity(s, (4ULL * 4) + 16ULL + ticket->ServiceTicketLength +
1419 ticket->TicketGrantingTicketLength))
1422 Stream_Write_UINT32(s, KerbTicketLogon);
1423 Stream_Write_UINT32(s, ticket->Flags);
1424 Stream_Write_UINT32(s, ticket->ServiceTicketLength);
1425 Stream_Write_UINT32(s, ticket->TicketGrantingTicketLength);
1427 Stream_Write_UINT64(s, 0x20);
1428 Stream_Write_UINT64(s, 0x20 + ticket->ServiceTicketLength);
1430 Stream_Write(s, ticket->ServiceTicket, ticket->ServiceTicketLength);
1431 Stream_Write(s, ticket->TicketGrantingTicket, ticket->TicketGrantingTicketLength);
1435 static BOOL nla_get_KERB_TICKET_LOGON(rdpNla* nla,
KERB_TICKET_LOGON* logonTicket)
1438 WINPR_ASSERT(logonTicket);
1440 SecurityFunctionTable* table = NULL;
1442 credssp_auth_tableAndContext(nla->auth, &table, &context);
1443 return table->QueryContextAttributes(&context, SECPKG_CRED_ATTR_TICKET_LOGON, logonTicket) ==
1447 static BOOL nla_write_TSRemoteGuardKerbCred(rdpNla* nla, WinPrAsn1Encoder* enc)
1451 char kerberos[] = {
'K',
'\0',
'e',
'\0',
'r',
'\0',
'b',
'\0',
1452 'e',
'\0',
'r',
'\0',
'o',
'\0',
's',
'\0' };
1457 logonTicket.ServiceTicket = NULL;
1458 logonTicket.TicketGrantingTicket = NULL;
1461 if (!WinPrAsn1EncContextualOctetString(enc, 0, &packageName))
1465 if (!nla_get_KERB_TICKET_LOGON(nla, &logonTicket))
1468 s = Stream_New(NULL, 2000);
1472 if (!nla_write_KERB_TICKET_LOGON(s, &logonTicket))
1475 credBuffer.len = Stream_GetPosition(s);
1476 credBuffer.data = Stream_Buffer(s);
1477 ret = WinPrAsn1EncContextualOctetString(enc, 1, &credBuffer) != 0;
1480 free(logonTicket.ServiceTicket);
1481 free(logonTicket.TicketGrantingTicket);
1482 Stream_Free(s, TRUE);
1493 static BOOL nla_encode_ts_credentials(rdpNla* nla)
1496 WinPrAsn1Encoder* enc = NULL;
1499 TsCredentialsType credType = TSCREDS_INVALID;
1502 WINPR_ASSERT(nla->rdpcontext);
1504 rdpSettings* settings = nla->rdpcontext->settings;
1505 WINPR_ASSERT(settings);
1507 if (settings->RemoteCredentialGuard)
1508 credType = TSCREDS_REMOTEGUARD;
1509 else if (settings->SmartcardLogon)
1510 credType = TSCREDS_SMARTCARD;
1512 credType = TSCREDS_USER_PASSWD;
1514 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1519 if (!WinPrAsn1EncSeqContainer(enc))
1523 if (!WinPrAsn1EncContextualInteger(enc, 0, (WinPrAsn1_INTEGER)credType))
1527 if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
1532 case TSCREDS_SMARTCARD:
1536 WinPrAsn1_tagId tag;
1538 } cspData_fields[] = { { 1, FreeRDP_CardName },
1539 { 2, FreeRDP_ReaderName },
1540 { 3, FreeRDP_ContainerName },
1541 { 4, FreeRDP_CspName } };
1545 if (!WinPrAsn1EncSeqContainer(enc))
1552 octet_string.len = ss *
sizeof(WCHAR);
1553 const BOOL res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0;
1554 free(octet_string.data);
1559 if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
1563 if (!WinPrAsn1EncContextualInteger(
1565 WINPR_ASSERTING_INT_CAST(
1569 for (
size_t i = 0; i < ARRAYSIZE(cspData_fields); i++)
1574 settings, (FreeRDP_Settings_Keys_String)cspData_fields[i].setting_id, &len);
1575 octet_string.len = len *
sizeof(WCHAR);
1576 if (octet_string.len)
1578 const BOOL res2 = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag,
1580 free(octet_string.data);
1587 if (!WinPrAsn1EncEndContainer(enc))
1591 if (!WinPrAsn1EncEndContainer(enc))
1595 case TSCREDS_USER_PASSWD:
1602 if (!WinPrAsn1EncSeqContainer(enc))
1605 if (!settings->DisableCredentialsDelegation && nla->identity)
1607 username.len = nla->identity->UserLength *
sizeof(WCHAR);
1608 username.data = (BYTE*)nla->identity->User;
1610 domain.len = nla->identity->DomainLength *
sizeof(WCHAR);
1611 domain.data = (BYTE*)nla->identity->Domain;
1613 password.len = nla->identity->PasswordLength *
sizeof(WCHAR);
1614 password.data = (BYTE*)nla->identity->Password;
1617 if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0)
1619 if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0)
1621 if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0)
1625 if (!WinPrAsn1EncEndContainer(enc))
1629 case TSCREDS_REMOTEGUARD:
1631 if (!WinPrAsn1EncSeqContainer(enc))
1635 if (!WinPrAsn1EncContextualSeqContainer(enc, 0))
1638 if (!nla_write_TSRemoteGuardKerbCred(nla, enc) || !WinPrAsn1EncEndContainer(enc))
1646 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncEndContainer(enc))
1650 if (!WinPrAsn1EncEndContainer(enc))
1658 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1661 if (!WinPrAsn1EncStreamSize(enc, &length))
1664 if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
1666 WLog_ERR(TAG,
"sspi_SecBufferAlloc failed!");
1670 Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
1672 ret = WinPrAsn1EncToStream(enc, &s);
1675 WinPrAsn1Encoder_Free(&enc);
1679 static BOOL nla_encrypt_ts_credentials(rdpNla* nla)
1683 if (!nla_encode_ts_credentials(nla))
1686 sspi_SecBufferFree(&nla->authInfo);
1687 if (!credssp_auth_encrypt(nla->auth, &nla->tsCredentials, &nla->authInfo, NULL,
1694 static BOOL nla_decrypt_ts_credentials(rdpNla* nla)
1698 if (nla->authInfo.cbBuffer < 1)
1700 WLog_ERR(TAG,
"nla_decrypt_ts_credentials missing authInfo buffer");
1704 sspi_SecBufferFree(&nla->tsCredentials);
1705 if (!credssp_auth_decrypt(nla->auth, &nla->authInfo, &nla->tsCredentials, nla->recvSeqNum++))
1708 if (!nla_read_ts_credentials(nla, &nla->tsCredentials))
1714 static BOOL nla_write_octet_string(WinPrAsn1Encoder* enc,
const SecBuffer* buffer,
1715 WinPrAsn1_tagId tagId,
const char* msg)
1720 WINPR_ASSERT(buffer);
1723 if (buffer->cbBuffer > 0)
1728 WLog_DBG(TAG,
" ----->> %s", msg);
1729 octet_string.data = buffer->pvBuffer;
1730 octet_string.len = buffer->cbBuffer;
1731 rc = WinPrAsn1EncContextualOctetString(enc, tagId, &octet_string);
1739 static BOOL nla_write_octet_string_free(WinPrAsn1Encoder* enc,
SecBuffer* buffer,
1740 WinPrAsn1_tagId tagId,
const char* msg)
1742 const BOOL rc = nla_write_octet_string(enc, buffer, tagId, msg);
1743 sspi_SecBufferFree(buffer);
1755 BOOL nla_send(rdpNla* nla)
1760 WinPrAsn1Encoder* enc = NULL;
1764 enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
1769 WLog_DBG(TAG,
"----->> sending...");
1770 if (!WinPrAsn1EncSeqContainer(enc))
1774 WLog_DBG(TAG,
" ----->> protocol version %" PRIu32, nla->version);
1775 if (!WinPrAsn1EncContextualInteger(enc, 0,
1776 WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->version)))
1780 if (nla_get_state(nla) <= NLA_STATE_NEGO_TOKEN && credssp_auth_have_output_token(nla->auth))
1782 const SecBuffer* buffer = credssp_auth_get_output_buffer(nla->auth);
1784 if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
1788 if (!nla_write_octet_string(enc, buffer, 0,
"negoToken"))
1792 if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
1797 if (nla->authInfo.cbBuffer > 0)
1799 if (!nla_write_octet_string_free(enc, &nla->authInfo, 2,
"auth info"))
1804 if (nla->pubKeyAuth.cbBuffer > 0)
1806 if (!nla_write_octet_string_free(enc, &nla->pubKeyAuth, 3,
"public key auth"))
1811 if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
1813 WLog_DBG(TAG,
" ----->> error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1815 if (!WinPrAsn1EncContextualInteger(
1816 enc, 4, WINPR_ASSERTING_INT_CAST(WinPrAsn1_INTEGER, nla->errorCode)))
1821 if (!nla->server && nla->ClientNonce.cbBuffer > 0)
1823 if (!nla_write_octet_string(enc, &nla->ClientNonce, 5,
"client nonce"))
1828 if (!WinPrAsn1EncEndContainer(enc))
1831 if (!WinPrAsn1EncStreamSize(enc, &length))
1834 s = Stream_New(NULL, length);
1838 if (!WinPrAsn1EncToStream(enc, s))
1841 WLog_DBG(TAG,
"[%" PRIuz
" bytes]", length);
1842 if (transport_write(nla->transport, s) < 0)
1847 Stream_Free(s, TRUE);
1848 WinPrAsn1Encoder_Free(&enc);
1852 static int nla_decode_ts_request(rdpNla* nla,
wStream* s)
1857 WinPrAsn1_tagId tag = { 0 };
1858 WinPrAsn1_INTEGER val = { 0 };
1864 WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
1866 WLog_DBG(TAG,
"<<----- receiving...");
1869 const size_t offset = WinPrAsn1DecReadSequence(&dec, &dec2);
1875 if (WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val) == 0)
1878 if (!Stream_SafeSeek(s, offset))
1881 version = (UINT)val;
1882 WLog_DBG(TAG,
" <<----- protocol version %" PRIu32, version);
1884 if (nla->peerVersion == 0)
1885 nla->peerVersion = version;
1888 if (nla->peerVersion != version)
1890 WLog_ERR(TAG,
"CredSSP peer changed protocol version from %" PRIu32
" to %" PRIu32,
1891 nla->peerVersion, version);
1895 while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2) != 0)
1903 WLog_DBG(TAG,
" <<----- nego token");
1905 if ((WinPrAsn1DecReadSequence(&dec2, &dec3) == 0) ||
1906 (WinPrAsn1DecReadSequence(&dec3, &dec2) == 0))
1909 if ((WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
1913 if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
1918 WLog_DBG(TAG,
" <<----- auth info");
1920 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1922 if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
1927 WLog_DBG(TAG,
" <<----- public key auth");
1929 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1931 if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
1937 if (WinPrAsn1DecReadInteger(&dec2, &val) == 0)
1939 nla->errorCode = val;
1940 WLog_DBG(TAG,
" <<----- error code %s 0x%08" PRIx32, NtStatus2Tag(nla->errorCode),
1944 WLog_DBG(TAG,
" <<----- client nonce");
1946 if (WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE) == 0)
1948 if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
1960 int nla_recv_pdu(rdpNla* nla,
wStream* s)
1965 if (nla_get_state(nla) == NLA_STATE_EARLY_USER_AUTH)
1968 Stream_Read_UINT32(s, code);
1969 if (code != AUTHZ_SUCCESS)
1971 WLog_DBG(TAG,
"Early User Auth active: FAILURE code 0x%08" PRIX32
"", code);
1972 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
1973 freerdp_set_last_error_log(nla->rdpcontext, code);
1977 WLog_DBG(TAG,
"Early User Auth active: SUCCESS");
1981 if (nla_decode_ts_request(nla, s) < 1)
1988 switch (nla->errorCode)
1990 case STATUS_PASSWORD_MUST_CHANGE:
1991 code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
1994 case STATUS_PASSWORD_EXPIRED:
1995 code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
1998 case STATUS_ACCOUNT_DISABLED:
1999 code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
2002 case STATUS_LOGON_FAILURE:
2003 code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
2006 case STATUS_WRONG_PASSWORD:
2007 code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
2010 case STATUS_ACCESS_DENIED:
2011 code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
2014 case STATUS_ACCOUNT_RESTRICTION:
2015 code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
2018 case STATUS_ACCOUNT_LOCKED_OUT:
2019 code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
2022 case STATUS_ACCOUNT_EXPIRED:
2023 code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
2026 case STATUS_LOGON_TYPE_NOT_GRANTED:
2027 code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
2031 WLog_ERR(TAG,
"SPNEGO failed with NTSTATUS: %s [0x%08" PRIX32
"]",
2032 NtStatus2Tag(nla->errorCode), nla->errorCode);
2033 code = FREERDP_ERROR_AUTHENTICATION_FAILED;
2037 freerdp_set_last_error_log(nla->rdpcontext, code);
2042 return nla_client_recv(nla);
2045 int nla_server_recv(rdpNla* nla)
2051 wStream* s = nla_server_recv_stream(nla);
2054 status = nla_decode_ts_request(nla, s);
2057 Stream_Free(s, TRUE);
2070 rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
2072 WINPR_ASSERT(transport);
2073 WINPR_ASSERT(context);
2075 rdpSettings* settings = context->settings;
2076 WINPR_ASSERT(settings);
2078 rdpNla* nla = (rdpNla*)calloc(1,
sizeof(rdpNla));
2083 nla->rdpcontext = context;
2084 nla->server = settings->ServerMode;
2085 nla->transport = transport;
2086 nla->sendSeqNum = 0;
2087 nla->recvSeqNum = 0;
2089 nla->earlyUserAuth = FALSE;
2091 nla->identity = calloc(1,
sizeof(SEC_WINNT_AUTH_IDENTITY));
2095 nla->auth = credssp_auth_new(context);
2100 if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
2104 if (winpr_RAND(nla->ClientNonce.pvBuffer, NonceLength) < 0)
2109 WINPR_PRAGMA_DIAG_PUSH
2110 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2112 WINPR_PRAGMA_DIAG_POP
2121 void nla_free(rdpNla* nla)
2126 smartcardCertInfo_Free(nla->smartcardCert);
2127 nla_buffer_free(nla);
2128 sspi_SecBufferFree(&nla->tsCredentials);
2129 credssp_auth_free(nla->auth);
2131 sspi_FreeAuthIdentity(nla->identity);
2132 free(nla->pkinitArgs);
2133 free(nla->identity);
2137 SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla)
2142 return nla->identity;
2145 NLA_STATE nla_get_state(rdpNla* nla)
2148 return NLA_STATE_FINAL;
2153 BOOL nla_set_state(rdpNla* nla, NLA_STATE state)
2158 WLog_DBG(TAG,
"-- %s\t--> %s", nla_get_state_str(nla->state), nla_get_state_str(state));
2163 BOOL nla_set_service_principal(rdpNla* nla,
const char* service,
const char* hostname)
2165 if (!credssp_auth_set_spn(nla->auth, service, hostname))
2170 BOOL nla_impersonate(rdpNla* nla)
2172 return credssp_auth_impersonate(nla->auth);
2175 BOOL nla_revert_to_self(rdpNla* nla)
2177 return credssp_auth_revert_to_self(nla->auth);
2180 const char* nla_get_state_str(NLA_STATE state)
2184 case NLA_STATE_INITIAL:
2185 return "NLA_STATE_INITIAL";
2186 case NLA_STATE_NEGO_TOKEN:
2187 return "NLA_STATE_NEGO_TOKEN";
2188 case NLA_STATE_PUB_KEY_AUTH:
2189 return "NLA_STATE_PUB_KEY_AUTH";
2190 case NLA_STATE_AUTH_INFO:
2191 return "NLA_STATE_AUTH_INFO";
2192 case NLA_STATE_POST_NEGO:
2193 return "NLA_STATE_POST_NEGO";
2194 case NLA_STATE_EARLY_USER_AUTH:
2195 return "NLA_STATE_EARLY_USER_AUTH";
2196 case NLA_STATE_FINAL:
2197 return "NLA_STATE_FINAL";
2203 DWORD nla_get_error(rdpNla* nla)
2206 return ERROR_INTERNAL_ERROR;
2207 return (UINT32)nla->errorCode;
2210 INT32 nla_get_sspi_error(rdpNla* nla)
2213 return credssp_auth_sspi_error(nla->auth);
2219 WINPR_ASSERT(inBuffer);
2220 WINPR_ASSERT(outBuffer);
2221 return credssp_auth_encrypt(nla->auth, inBuffer, outBuffer, NULL, nla->sendSeqNum++);
2227 WINPR_ASSERT(inBuffer);
2228 WINPR_ASSERT(outBuffer);
2229 return credssp_auth_decrypt(nla->auth, inBuffer, outBuffer, nla->recvSeqNum++);
2232 SECURITY_STATUS nla_QueryContextAttributes(rdpNla* nla, DWORD ulAttr, PVOID pBuffer)
2236 SecurityFunctionTable* table = NULL;
2238 credssp_auth_tableAndContext(nla->auth, &table, &context);
2240 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 const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.
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.