21#include <winpr/config.h>
22#include <winpr/assert.h>
23#include <winpr/windows.h>
26#include <winpr/sspi.h>
28#include <winpr/print.h>
32#include "sspi_winpr.h"
36#define TAG WINPR_TAG("sspi")
41#include "NTLM/ntlm_export.h"
42#include "CredSSP/credssp.h"
43#include "Kerberos/kerberos.h"
44#include "Negotiate/negotiate.h"
45#include "Schannel/schannel.h"
47static const SecPkgInfoA* SecPkgInfoA_LIST[] = { &NTLM_SecPkgInfoA, &KERBEROS_SecPkgInfoA,
48 &NEGOTIATE_SecPkgInfoA, &CREDSSP_SecPkgInfoA,
49 &SCHANNEL_SecPkgInfoA };
51static const SecPkgInfoW* SecPkgInfoW_LIST[] = { &NTLM_SecPkgInfoW, &KERBEROS_SecPkgInfoW,
52 &NEGOTIATE_SecPkgInfoW, &CREDSSP_SecPkgInfoW,
53 &SCHANNEL_SecPkgInfoW };
59} SecurityFunctionTableA_NAME;
63 const SEC_WCHAR* Name;
65} SecurityFunctionTableW_NAME;
67static const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] = {
68 {
"NTLM", &NTLM_SecurityFunctionTableA },
69 {
"Kerberos", &KERBEROS_SecurityFunctionTableA },
70 {
"Negotiate", &NEGOTIATE_SecurityFunctionTableA },
71 {
"CREDSSP", &CREDSSP_SecurityFunctionTableA },
72 {
"Schannel", &SCHANNEL_SecurityFunctionTableA }
75static WCHAR BUFFER_NAME_LIST_W[5][32] = WINPR_C_ARRAY_INIT;
77static const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] = {
78 { BUFFER_NAME_LIST_W[0], &NTLM_SecurityFunctionTableW },
79 { BUFFER_NAME_LIST_W[1], &KERBEROS_SecurityFunctionTableW },
80 { BUFFER_NAME_LIST_W[2], &NEGOTIATE_SecurityFunctionTableW },
81 { BUFFER_NAME_LIST_W[3], &CREDSSP_SecurityFunctionTableW },
82 { BUFFER_NAME_LIST_W[4], &SCHANNEL_SecurityFunctionTableW }
88 UINT32 allocatorIndex;
89} CONTEXT_BUFFER_ALLOC_ENTRY;
95 CONTEXT_BUFFER_ALLOC_ENTRY* entries;
96} CONTEXT_BUFFER_ALLOC_TABLE;
98static CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable = WINPR_C_ARRAY_INIT;
100static int sspi_ContextBufferAllocTableNew(
void)
103 ContextBufferAllocTable.entries =
nullptr;
104 ContextBufferAllocTable.cEntries = 0;
105 ContextBufferAllocTable.cMaxEntries = 4;
106 size =
sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
107 ContextBufferAllocTable.entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)calloc(1, size);
109 if (!ContextBufferAllocTable.entries)
115static int sspi_ContextBufferAllocTableGrow(
void)
118 CONTEXT_BUFFER_ALLOC_ENTRY* entries =
nullptr;
119 ContextBufferAllocTable.cEntries = 0;
120 ContextBufferAllocTable.cMaxEntries *= 2;
121 size =
sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
126 entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)realloc(ContextBufferAllocTable.entries, size);
130 free(ContextBufferAllocTable.entries);
134 ContextBufferAllocTable.entries = entries;
135 ZeroMemory((
void*)&ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2],
140static void sspi_ContextBufferAllocTableFree(
void)
142 if (ContextBufferAllocTable.cEntries != 0)
143 WLog_ERR(TAG,
"ContextBufferAllocTable.entries == %" PRIu32,
144 ContextBufferAllocTable.cEntries);
146 ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
147 free(ContextBufferAllocTable.entries);
148 ContextBufferAllocTable.entries =
nullptr;
151void* sspi_ContextBufferAlloc(UINT32 allocatorIndex,
size_t size)
153 void* contextBuffer =
nullptr;
155 for (UINT32 index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
157 if (!ContextBufferAllocTable.entries[index].contextBuffer)
159 contextBuffer = calloc(1, size);
164 ContextBufferAllocTable.cEntries++;
165 ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
166 ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
167 return ContextBufferAllocTable.entries[index].contextBuffer;
173 if (sspi_ContextBufferAllocTableGrow() < 0)
177 return sspi_ContextBufferAlloc(allocatorIndex, size);
186 credentials->ntlmSettingsV2 = sspi_AllocSecNtlmSettings();
187 if (!credentials->ntlmSettingsV2)
189 sspi_CredentialsFree(credentials);
201 size_t userLength = credentials->identity.UserLength;
202 size_t domainLength = credentials->identity.DomainLength;
203 size_t passwordLength = credentials->identity.PasswordLength;
205 if (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
212 if (credentials->identity.User)
213 memset(credentials->identity.User, 0, userLength);
214 if (credentials->identity.Domain)
215 memset(credentials->identity.Domain, 0, domainLength);
216 if (credentials->identity.Password)
217 memset(credentials->identity.Password, 0, passwordLength);
218 free(credentials->identity.User);
219 free(credentials->identity.Domain);
220 free(credentials->identity.Password);
221 sspi_FreeSecNtlmSettings(credentials->ntlmSettingsV2);
260 SecInvalidateHandle(handle);
264void* sspi_SecureHandleGetLowerPointer(
SecHandle* handle)
266 void* pointer =
nullptr;
268 if (!handle || !SecIsValidHandle(handle) || !handle->dwLower)
271 pointer = (
void*)~((
size_t)handle->dwLower);
275void sspi_SecureHandleInvalidate(
SecHandle* handle)
284void sspi_SecureHandleSetLowerPointer(
SecHandle* handle,
void* pointer)
289 handle->dwLower = (ULONG_PTR)(~((
size_t)pointer));
292void* sspi_SecureHandleGetUpperPointer(
SecHandle* handle)
294 void* pointer =
nullptr;
296 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
299 pointer = (
void*)~((
size_t)handle->dwUpper);
303void sspi_SecureHandleSetUpperPointer(
SecHandle* handle,
void* pointer)
308 handle->dwUpper = (ULONG_PTR)(~((
size_t)pointer));
311SSPI_PACKAGE_ID sspi_SecureHandleGetPackageId(
SecHandle* handle)
313 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
314 return SSPI_PACKAGE_NONE;
316 return (SSPI_PACKAGE_ID)(~((size_t)handle->dwUpper));
319void sspi_SecureHandleSetPackageId(
SecHandle* handle, SSPI_PACKAGE_ID
id)
324 handle->dwUpper = (ULONG_PTR)(~((
size_t)
id));
327void sspi_SecureHandleFree(
SecHandle* handle)
332int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
const WCHAR* domain,
333 const WCHAR* password)
335 return sspi_SetAuthIdentityWithLengthW(identity, user, user ? _wcslen(user) : 0, domain,
336 domain ? _wcslen(domain) : 0, password,
337 password ? _wcslen(password) : 0);
340static BOOL copy(WCHAR** dst, ULONG* dstLen,
const WCHAR* what,
size_t len)
343 WINPR_ASSERT(dstLen);
348 if (len > UINT32_MAX)
352 if (!what && (len != 0))
354 if (!what && (len == 0))
357 *dst = calloc(
sizeof(WCHAR), len + 1);
361 memcpy(*dst, what, len *
sizeof(WCHAR));
362 *dstLen = WINPR_ASSERTING_INT_CAST(UINT32, len);
366int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
367 size_t userLen,
const WCHAR* domain,
size_t domainLen,
368 const WCHAR* password,
size_t passwordLen)
370 WINPR_ASSERT(identity);
371 sspi_FreeAuthIdentity(identity);
372 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
373 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
375 if (!copy(&identity->User, &identity->UserLength, user, userLen))
378 if (!copy(&identity->Domain, &identity->DomainLength, domain, domainLen))
381 if (!copy(&identity->Password, &identity->PasswordLength, password, passwordLen))
387static void zfree(WCHAR* str,
size_t len)
390 memset(str, 0, len *
sizeof(WCHAR));
394int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity,
const char* user,
const char* domain,
395 const char* password)
398 size_t unicodeUserLenW = 0;
399 size_t unicodeDomainLenW = 0;
400 size_t unicodePasswordLenW = 0;
401 LPWSTR unicodeUser =
nullptr;
402 LPWSTR unicodeDomain =
nullptr;
403 LPWSTR unicodePassword =
nullptr;
406 unicodeUser = ConvertUtf8ToWCharAlloc(user, &unicodeUserLenW);
409 unicodeDomain = ConvertUtf8ToWCharAlloc(domain, &unicodeDomainLenW);
412 unicodePassword = ConvertUtf8ToWCharAlloc(password, &unicodePasswordLenW);
414 rc = sspi_SetAuthIdentityWithLengthW(identity, unicodeUser, unicodeUserLenW, unicodeDomain,
415 unicodeDomainLenW, unicodePassword, unicodePasswordLenW);
417 zfree(unicodeUser, unicodeUserLenW);
418 zfree(unicodeDomain, unicodeDomainLenW);
419 zfree(unicodePassword, unicodePasswordLenW);
423UINT32 sspi_GetAuthIdentityVersion(
const void* identity)
430 version = *((
const UINT32*)identity);
432 if ((version == SEC_WINNT_AUTH_IDENTITY_VERSION) ||
433 (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2))
441UINT32 sspi_GetAuthIdentityFlags(
const void* identity)
449 version = sspi_GetAuthIdentityVersion(identity);
451 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
453 flags = ((
const SEC_WINNT_AUTH_IDENTITY_EX*)identity)->Flags;
455 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
461 flags = ((
const SEC_WINNT_AUTH_IDENTITY*)identity)->Flags;
467BOOL sspi_GetAuthIdentityUserDomainW(
const void* identity,
const WCHAR** pUser, UINT32* pUserLength,
468 const WCHAR** pDomain, UINT32* pDomainLength)
475 version = sspi_GetAuthIdentityVersion(identity);
477 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
480 *pUser = (
const WCHAR*)id->User;
481 *pUserLength =
id->UserLength;
482 *pDomain = (
const WCHAR*)id->Domain;
483 *pDomainLength =
id->DomainLength;
485 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
488 UINT32 UserOffset =
id->UserOffset;
489 UINT32 DomainOffset =
id->DomainOffset;
490 *pUser = WINPR_PACKED_ALIGN_CAST(
const WCHAR*, &((
const uint8_t*)identity)[UserOffset]);
491 *pUserLength =
id->UserLength / 2;
492 *pDomain = WINPR_PACKED_ALIGN_CAST(
const WCHAR*, &((
const uint8_t*)identity)[DomainOffset]);
493 *pDomainLength =
id->DomainLength / 2;
498 *pUser = (
const WCHAR*)id->User;
499 *pUserLength =
id->UserLength;
500 *pDomain = (
const WCHAR*)id->Domain;
501 *pDomainLength =
id->DomainLength;
507BOOL sspi_GetAuthIdentityUserDomainA(
const void* identity,
const char** pUser, UINT32* pUserLength,
508 const char** pDomain, UINT32* pDomainLength)
515 version = sspi_GetAuthIdentityVersion(identity);
517 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
520 *pUser = (
const char*)id->User;
521 *pUserLength =
id->UserLength;
522 *pDomain = (
const char*)id->Domain;
523 *pDomainLength =
id->DomainLength;
525 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
528 UINT32 UserOffset =
id->UserOffset;
529 UINT32 DomainOffset =
id->DomainOffset;
530 *pUser = (
const char*)&((
const uint8_t*)identity)[UserOffset];
531 *pUserLength =
id->UserLength;
532 *pDomain = (
const char*)&((
const uint8_t*)identity)[DomainOffset];
533 *pDomainLength =
id->DomainLength;
538 *pUser = (
const char*)id->User;
539 *pUserLength =
id->UserLength;
540 *pDomain = (
const char*)id->Domain;
541 *pDomainLength =
id->DomainLength;
547BOOL sspi_GetAuthIdentityPasswordW(
const void* identity,
const WCHAR** pPassword,
548 UINT32* pPasswordLength)
555 version = sspi_GetAuthIdentityVersion(identity);
557 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
560 *pPassword = (
const WCHAR*)id->Password;
561 *pPasswordLength =
id->PasswordLength;
563 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
570 *pPassword = (
const WCHAR*)id->Password;
571 *pPasswordLength =
id->PasswordLength;
577BOOL sspi_GetAuthIdentityPasswordA(
const void* identity,
const char** pPassword,
578 UINT32* pPasswordLength)
585 version = sspi_GetAuthIdentityVersion(identity);
587 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
590 *pPassword = (
const char*)id->Password;
591 *pPasswordLength =
id->PasswordLength;
593 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
600 *pPassword = (
const char*)id->Password;
601 *pPasswordLength =
id->PasswordLength;
608 char** pDomain,
char** pPassword)
610 BOOL success = FALSE;
611 const char* UserA =
nullptr;
612 const char* DomainA =
nullptr;
613 const char* PasswordA =
nullptr;
614 const WCHAR* UserW =
nullptr;
615 const WCHAR* DomainW =
nullptr;
616 const WCHAR* PasswordW =
nullptr;
617 UINT32 UserLength = 0;
618 UINT32 DomainLength = 0;
619 UINT32 PasswordLength = 0;
621 if (!identity || !pUser || !pDomain || !pPassword)
624 *pUser = *pDomain = *pPassword =
nullptr;
626 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
628 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
630 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
634 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
637 if (UserA && UserLength)
639 *pUser = _strdup(UserA);
645 if (DomainA && DomainLength)
647 *pDomain = _strdup(DomainA);
653 if (PasswordA && PasswordLength)
655 *pPassword = _strdup(PasswordA);
663 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
665 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
669 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
672 if (UserW && (UserLength > 0))
674 *pUser = ConvertWCharNToUtf8Alloc(UserW, UserLength,
nullptr);
679 if (DomainW && (DomainLength > 0))
681 *pDomain = ConvertWCharNToUtf8Alloc(DomainW, DomainLength,
nullptr);
686 if (PasswordW && (PasswordLength > 0))
688 *pPassword = ConvertWCharNToUtf8Alloc(PasswordW, PasswordLength,
nullptr);
701 WCHAR** pDomain, WCHAR** pPassword)
703 BOOL success = FALSE;
704 const char* UserA =
nullptr;
705 const char* DomainA =
nullptr;
706 const char* PasswordA =
nullptr;
707 const WCHAR* UserW =
nullptr;
708 const WCHAR* DomainW =
nullptr;
709 const WCHAR* PasswordW =
nullptr;
710 UINT32 UserLength = 0;
711 UINT32 DomainLength = 0;
712 UINT32 PasswordLength = 0;
714 if (!identity || !pUser || !pDomain || !pPassword)
717 *pUser = *pDomain = *pPassword =
nullptr;
719 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
721 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
723 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
727 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
730 if (UserA && (UserLength > 0))
732 WCHAR* ptr = ConvertUtf8NToWCharAlloc(UserA, UserLength,
nullptr);
739 if (DomainA && (DomainLength > 0))
741 WCHAR* ptr = ConvertUtf8NToWCharAlloc(DomainA, DomainLength,
nullptr);
747 if (PasswordA && (PasswordLength > 0))
749 WCHAR* ptr = ConvertUtf8NToWCharAlloc(PasswordA, PasswordLength,
nullptr);
758 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
760 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
764 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
767 if (UserW && UserLength)
769 *pUser = winpr_wcsndup(UserW, UserLength /
sizeof(WCHAR));
775 if (DomainW && DomainLength)
777 *pDomain = winpr_wcsndup(DomainW, DomainLength /
sizeof(WCHAR));
783 if (PasswordW && PasswordLength)
785 *pPassword = winpr_wcsndup(PasswordW, PasswordLength /
sizeof(WCHAR));
801 UINT32 identityFlags = 0;
802 char* PackageList =
nullptr;
803 const char* PackageListA =
nullptr;
804 const WCHAR* PackageListW =
nullptr;
805 UINT32 PackageListLength = 0;
806 UINT32 PackageListOffset = 0;
807 const void* pAuthData = (
const void*)identity;
812 version = sspi_GetAuthIdentityVersion(pAuthData);
813 identityFlags = sspi_GetAuthIdentityFlags(pAuthData);
815 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
817 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
820 PackageListA = (
const char*)ad->PackageList;
821 PackageListLength = ad->PackageListLength;
824 if (PackageListA && PackageListLength)
826 PackageList = _strdup(PackageListA);
829 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
831 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
834 PackageListW = (
const WCHAR*)ad->PackageList;
835 PackageListLength = ad->PackageListLength;
837 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
840 PackageListOffset = ad->PackageListOffset;
841 PackageListW = WINPR_PACKED_ALIGN_CAST(
const WCHAR*,
842 &((
const uint8_t*)pAuthData)[PackageListOffset]);
843 PackageListLength = ad->PackageListLength / 2;
846 if (PackageListW && (PackageListLength > 0))
847 PackageList = ConvertWCharNToUtf8Alloc(PackageListW, PackageListLength,
nullptr);
852 *pPackageList = PackageList;
859int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity,
863 UINT32 identityFlags = 0;
864 const char* UserA =
nullptr;
865 const char* DomainA =
nullptr;
866 const char* PasswordA =
nullptr;
867 const WCHAR* UserW =
nullptr;
868 const WCHAR* DomainW =
nullptr;
869 const WCHAR* PasswordW =
nullptr;
870 UINT32 UserLength = 0;
871 UINT32 DomainLength = 0;
872 UINT32 PasswordLength = 0;
874 sspi_FreeAuthIdentity(identity);
876 identityFlags = sspi_GetAuthIdentityFlags(srcIdentity);
878 identity->Flags = identityFlags;
880 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
882 if (!sspi_GetAuthIdentityUserDomainA(srcIdentity, &UserA, &UserLength, &DomainA,
888 if (!sspi_GetAuthIdentityPasswordA(srcIdentity, &PasswordA, &PasswordLength))
893 status = sspi_SetAuthIdentity(identity, UserA, DomainA, PasswordA);
898 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
899 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
903 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
905 if (!sspi_GetAuthIdentityUserDomainW(srcIdentity, &UserW, &UserLength, &DomainW, &DomainLength))
910 if (!sspi_GetAuthIdentityPasswordW(srcIdentity, &PasswordW, &PasswordLength))
916 identity->UserLength = UserLength;
918 if (identity->UserLength > 0)
920 identity->User = (UINT16*)calloc((identity->UserLength + 1),
sizeof(WCHAR));
925 CopyMemory(identity->User, UserW, identity->UserLength *
sizeof(WCHAR));
926 identity->User[identity->UserLength] = 0;
929 identity->DomainLength = DomainLength;
931 if (identity->DomainLength > 0)
933 identity->Domain = (UINT16*)calloc((identity->DomainLength + 1),
sizeof(WCHAR));
935 if (!identity->Domain)
938 CopyMemory(identity->Domain, DomainW, identity->DomainLength *
sizeof(WCHAR));
939 identity->Domain[identity->DomainLength] = 0;
942 identity->PasswordLength = PasswordLength;
946 identity->Password = (UINT16*)calloc((identity->PasswordLength + 1),
sizeof(WCHAR));
948 if (!identity->Password)
951 CopyMemory(identity->Password, PasswordW, identity->PasswordLength *
sizeof(WCHAR));
952 identity->Password[identity->PasswordLength] = 0;
963 for (UINT32 index = 0; index < pMessage->cBuffers; index++)
965 if (pMessage->pBuffers[index].BufferType == BufferType)
967 pSecBuffer = &pMessage->pBuffers[index];
975static BOOL WINPR_init(
void)
978 for (
size_t x = 0; x < ARRAYSIZE(SecurityFunctionTableA_NAME_LIST); x++)
980 const SecurityFunctionTableA_NAME* cur = &SecurityFunctionTableA_NAME_LIST[x];
981 InitializeConstWCharFromUtf8(cur->Name, BUFFER_NAME_LIST_W[x],
982 ARRAYSIZE(BUFFER_NAME_LIST_W[x]));
987static BOOL CALLBACK sspi_init(WINPR_ATTR_UNUSED
PINIT_ONCE InitOnce,
988 WINPR_ATTR_UNUSED PVOID Parameter, WINPR_ATTR_UNUSED PVOID* Context)
990 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
992 sspi_ContextBufferAllocTableNew();
993 if (!SCHANNEL_init())
995 if (!KERBEROS_init())
1001 if (!NEGOTIATE_init())
1003 return WINPR_init();
1006void sspi_GlobalInit(
void)
1008 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
1015 WINPR_STATIC_ASSERT(ARRAYSIZE(SecPkgInfoA_LIST) == SSPI_PACKAGE_COUNT - 1);
1016 WINPR_STATIC_ASSERT(ARRAYSIZE(SecPkgInfoW_LIST) == SSPI_PACKAGE_COUNT - 1);
1017 WINPR_STATIC_ASSERT(ARRAYSIZE(SecurityFunctionTableA_NAME_LIST) == SSPI_PACKAGE_COUNT - 1);
1018 WINPR_STATIC_ASSERT(ARRAYSIZE(SecurityFunctionTableW_NAME_LIST) == SSPI_PACKAGE_COUNT - 1);
1019 WINPR_STATIC_ASSERT(ARRAYSIZE(BUFFER_NAME_LIST_W) == SSPI_PACKAGE_COUNT - 1);
1021 if (!InitOnceExecuteOnce(&once, sspi_init, &flags,
nullptr))
1022 WLog_ERR(TAG,
"InitOnceExecuteOnce failed");
1025void sspi_GlobalFinish(
void)
1027 sspi_ContextBufferAllocTableFree();
1032 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1034 for (
size_t index = 0; index < cPackages; index++)
1036 if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
1038 return SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
1047 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1049 for (
size_t index = 0; index < cPackages; index++)
1051 if (_wcscmp(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
1053 return SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
1064sspi_GetSecurityFunctionTableAByHandle(
SecHandle* handle)
1066 const SSPI_PACKAGE_ID
id = sspi_SecureHandleGetPackageId(handle);
1068 if ((
id < SSPI_PACKAGE_NTLM) || (
id > ARRAYSIZE(SecurityFunctionTableA_NAME_LIST)))
1071 return SecurityFunctionTableA_NAME_LIST[
id - 1].SecurityFunctionTable;
1075sspi_GetSecurityFunctionTableWByHandle(
SecHandle* handle)
1077 const SSPI_PACKAGE_ID
id = sspi_SecureHandleGetPackageId(handle);
1079 if ((
id < SSPI_PACKAGE_NTLM) || (
id > ARRAYSIZE(SecurityFunctionTableW_NAME_LIST)))
1082 return SecurityFunctionTableW_NAME_LIST[
id - 1].SecurityFunctionTable;
1085static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer);
1086static void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer);
1088void sspi_ContextBufferFree(
void* contextBuffer)
1090 UINT32 allocatorIndex = 0;
1092 for (
size_t index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
1094 if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
1096 contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
1097 allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
1098 ContextBufferAllocTable.cEntries--;
1099 ContextBufferAllocTable.entries[index].allocatorIndex = 0;
1100 ContextBufferAllocTable.entries[index].contextBuffer =
nullptr;
1102 switch (allocatorIndex)
1104 case EnumerateSecurityPackagesIndex:
1105 FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
1108 case QuerySecurityPackageInfoIndex:
1109 FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
1124static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages,
1127 const size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1128 const size_t size =
sizeof(
SecPkgInfoW) * cPackages;
1130 (
SecPkgInfoW*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1132 WINPR_ASSERT(cPackages <= UINT32_MAX);
1135 return SEC_E_INSUFFICIENT_MEMORY;
1137 for (
size_t index = 0; index < cPackages; index++)
1139 pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1140 pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
1141 pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1142 pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1143 pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1144 pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1147 *(pcPackages) = (UINT32)cPackages;
1148 *(ppPackageInfo) = pPackageInfo;
1152static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages,
1155 const size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1156 const size_t size =
sizeof(
SecPkgInfoA) * cPackages;
1158 (
SecPkgInfoA*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1160 WINPR_ASSERT(cPackages <= UINT32_MAX);
1163 return SEC_E_INSUFFICIENT_MEMORY;
1165 for (
size_t index = 0; index < cPackages; index++)
1167 pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1168 pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
1169 pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1170 pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1171 pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1172 pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1174 if (!pPackageInfo[index].Name || !pPackageInfo[index].Comment)
1176 sspi_ContextBufferFree(pPackageInfo);
1177 return SEC_E_INSUFFICIENT_MEMORY;
1181 *(pcPackages) = (UINT32)cPackages;
1182 *(ppPackageInfo) = pPackageInfo;
1186static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer)
1189 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1194 for (
size_t index = 0; index < cPackages; index++)
1196 free(pPackageInfo[index].Name);
1197 free(pPackageInfo[index].Comment);
1203static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
1206 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1208 for (
size_t index = 0; index < cPackages; index++)
1210 if (_wcscmp(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
1214 (
SecPkgInfoW*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1217 return SEC_E_INSUFFICIENT_MEMORY;
1219 pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1220 pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
1221 pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1222 pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1223 pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1224 pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1225 *(ppPackageInfo) = pPackageInfo;
1230 *(ppPackageInfo) =
nullptr;
1231 return SEC_E_SECPKG_NOT_FOUND;
1234static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
1237 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1239 for (
size_t index = 0; index < cPackages; index++)
1241 if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
1245 (
SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1248 return SEC_E_INSUFFICIENT_MEMORY;
1250 pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1251 pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
1252 pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1253 pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1254 pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1255 pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1257 if (!pPackageInfo->Name || !pPackageInfo->Comment)
1259 sspi_ContextBufferFree(pPackageInfo);
1260 return SEC_E_INSUFFICIENT_MEMORY;
1263 *(ppPackageInfo) = pPackageInfo;
1268 *(ppPackageInfo) =
nullptr;
1269 return SEC_E_SECPKG_NOT_FOUND;
1272void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer)
1274 SecPkgInfo* pPackageInfo = (SecPkgInfo*)contextBuffer;
1279 free(pPackageInfo->Name);
1280 free(pPackageInfo->Comment);
1284#define log_status(what, status) log_status_((what), (status), __FILE__, __func__, __LINE__)
1285static SECURITY_STATUS log_status_(
const char* what, SECURITY_STATUS status,
const char* file,
1286 const char* fkt,
size_t line)
1288 if (IsSecurityStatusError(status))
1290 const DWORD level = WLOG_WARN;
1291 static wLog* log =
nullptr;
1293 log = WLog_Get(TAG);
1295 if (WLog_IsLevelActive(log, level))
1297 WLog_PrintTextMessage(log, level, line, file, fkt,
"%s status %s [0x%08" PRIx32
"]",
1298 what, GetSecurityStatusString(status),
1299 WINPR_CXX_COMPAT_CAST(uint32_t, status));
1307static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(
1308 SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1309 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1315 return SEC_E_SECPKG_NOT_FOUND;
1317 if (!table->AcquireCredentialsHandleW)
1319 WLog_WARN(TAG,
"Security module does not provide an implementation");
1320 return SEC_E_UNSUPPORTED_FUNCTION;
1323 SECURITY_STATUS status = table->AcquireCredentialsHandleW(
1324 pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
1325 phCredential, ptsExpiry);
1326 return log_status(
"AcquireCredentialsHandleW", status);
1329static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(
1330 SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1331 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1337 return SEC_E_SECPKG_NOT_FOUND;
1339 if (!table->AcquireCredentialsHandleA)
1341 WLog_WARN(TAG,
"Security module does not provide an implementation");
1342 return SEC_E_UNSUPPORTED_FUNCTION;
1345 SECURITY_STATUS status = table->AcquireCredentialsHandleA(
1346 pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
1347 phCredential, ptsExpiry);
1348 return log_status(
"AcquireCredentialsHandleA", status);
1351static SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(
PCtxtHandle phContext, ULONG fFlags,
1358 return SEC_E_SECPKG_NOT_FOUND;
1360 if (!table->ExportSecurityContext)
1362 WLog_WARN(TAG,
"Security module does not provide an implementation");
1363 return SEC_E_UNSUPPORTED_FUNCTION;
1366 SECURITY_STATUS status =
1367 table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
1368 return log_status(
"ExportSecurityContext", status);
1371static SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(
PCredHandle phCredential)
1376 return SEC_E_SECPKG_NOT_FOUND;
1378 if (!table->FreeCredentialsHandle)
1380 WLog_WARN(TAG,
"Security module does not provide an implementation");
1381 return SEC_E_UNSUPPORTED_FUNCTION;
1384 SECURITY_STATUS status = table->FreeCredentialsHandle(phCredential);
1385 return log_status(
"FreeCredentialsHandle", status);
1388static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage,
1395 return SEC_E_SECPKG_NOT_FOUND;
1397 if (!table->ImportSecurityContextW)
1399 WLog_WARN(TAG,
"Security module does not provide an implementation");
1400 return SEC_E_UNSUPPORTED_FUNCTION;
1403 SECURITY_STATUS status =
1404 table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
1405 return log_status(
"ImportSecurityContextW", status);
1408static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage,
1415 return SEC_E_SECPKG_NOT_FOUND;
1417 if (!table->ImportSecurityContextA)
1419 WLog_WARN(TAG,
"Security module does not provide an implementation");
1420 return SEC_E_UNSUPPORTED_FUNCTION;
1423 SECURITY_STATUS status =
1424 table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
1425 return log_status(
"ImportSecurityContextA", status);
1428static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(
PCredHandle phCredential,
1429 ULONG ulAttribute,
void* pBuffer)
1434 return SEC_E_SECPKG_NOT_FOUND;
1436 if (!table->QueryCredentialsAttributesW)
1438 WLog_WARN(TAG,
"Security module does not provide an implementation");
1439 return SEC_E_UNSUPPORTED_FUNCTION;
1442 SECURITY_STATUS status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
1443 return log_status(
"QueryCredentialsAttributesW", status);
1446static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(
PCredHandle phCredential,
1447 ULONG ulAttribute,
void* pBuffer)
1452 return SEC_E_SECPKG_NOT_FOUND;
1454 if (!table->QueryCredentialsAttributesA)
1456 WLog_WARN(TAG,
"Security module does not provide an implementation");
1457 return SEC_E_UNSUPPORTED_FUNCTION;
1460 SECURITY_STATUS status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
1461 return log_status(
"QueryCredentialsAttributesA", status);
1464static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesW(
PCredHandle phCredential,
1465 ULONG ulAttribute,
void* pBuffer,
1471 return SEC_E_SECPKG_NOT_FOUND;
1473 if (!table->SetCredentialsAttributesW)
1475 WLog_WARN(TAG,
"Security module does not provide an implementation");
1476 return SEC_E_UNSUPPORTED_FUNCTION;
1479 SECURITY_STATUS status =
1480 table->SetCredentialsAttributesW(phCredential, ulAttribute, pBuffer, cbBuffer);
1481 return log_status(
"SetCredentialsAttributesW", status);
1484static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesA(
PCredHandle phCredential,
1485 ULONG ulAttribute,
void* pBuffer,
1491 return SEC_E_SECPKG_NOT_FOUND;
1493 if (!table->SetCredentialsAttributesA)
1495 WLog_WARN(TAG,
"Security module does not provide an implementation");
1496 return SEC_E_UNSUPPORTED_FUNCTION;
1499 SECURITY_STATUS status =
1500 table->SetCredentialsAttributesA(phCredential, ulAttribute, pBuffer, cbBuffer);
1501 return log_status(
"SetCredentialsAttributesA", status);
1506static SECURITY_STATUS SEC_ENTRY
1508 ULONG fContextReq, ULONG TargetDataRep,
PCtxtHandle phNewContext,
1514 return SEC_E_SECPKG_NOT_FOUND;
1516 if (!table->AcceptSecurityContext)
1518 WLog_WARN(TAG,
"Security module does not provide an implementation");
1519 return SEC_E_UNSUPPORTED_FUNCTION;
1522 SECURITY_STATUS status =
1523 table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
1524 phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
1525 return log_status(
"AcceptSecurityContext", status);
1528static SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(
PCtxtHandle phContext,
1534 return SEC_E_SECPKG_NOT_FOUND;
1536 if (!table->ApplyControlToken)
1538 WLog_WARN(TAG,
"Security module does not provide an implementation");
1539 return SEC_E_UNSUPPORTED_FUNCTION;
1542 SECURITY_STATUS status = table->ApplyControlToken(phContext, pInput);
1543 return log_status(
"ApplyControlToken", status);
1546static SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(
PCtxtHandle phContext,
1552 return SEC_E_SECPKG_NOT_FOUND;
1554 if (!table->CompleteAuthToken)
1556 WLog_WARN(TAG,
"Security module does not provide an implementation");
1557 return SEC_E_UNSUPPORTED_FUNCTION;
1560 SECURITY_STATUS status = table->CompleteAuthToken(phContext, pToken);
1561 return log_status(
"CompleteAuthToken", status);
1564static SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(
PCtxtHandle phContext)
1569 return SEC_E_SECPKG_NOT_FOUND;
1571 if (!table->DeleteSecurityContext)
1573 WLog_WARN(TAG,
"Security module does not provide an implementation");
1574 return SEC_E_UNSUPPORTED_FUNCTION;
1577 const SECURITY_STATUS status = table->DeleteSecurityContext(phContext);
1578 return log_status(
"DeleteSecurityContext", status);
1581static SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(
void* pvContextBuffer)
1583 if (!pvContextBuffer)
1584 return SEC_E_INVALID_HANDLE;
1586 sspi_ContextBufferFree(pvContextBuffer);
1590static SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(
PCtxtHandle phContext)
1595 return SEC_E_SECPKG_NOT_FOUND;
1597 if (!table->ImpersonateSecurityContext)
1599 WLog_WARN(TAG,
"Security module does not provide an implementation");
1600 return SEC_E_UNSUPPORTED_FUNCTION;
1603 SECURITY_STATUS status = table->ImpersonateSecurityContext(phContext);
1604 return log_status(
"ImpersonateSecurityContext", status);
1607static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(
1609 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1615 return SEC_E_SECPKG_NOT_FOUND;
1617 if (!table->InitializeSecurityContextW)
1619 WLog_WARN(TAG,
"Security module does not provide an implementation");
1620 return SEC_E_UNSUPPORTED_FUNCTION;
1623 const SECURITY_STATUS status = table->InitializeSecurityContextW(
1624 phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
1625 Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
1626 return log_status(
"InitializeSecurityContextW", status);
1629static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(
1631 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1637 return SEC_E_SECPKG_NOT_FOUND;
1639 if (!table->InitializeSecurityContextA)
1641 WLog_WARN(TAG,
"Security module does not provide an implementation");
1642 return SEC_E_UNSUPPORTED_FUNCTION;
1645 SECURITY_STATUS status = table->InitializeSecurityContextA(
1646 phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
1647 Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
1649 return log_status(
"InitializeSecurityContextA", status);
1652static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(
PCtxtHandle phContext,
1653 ULONG ulAttribute,
void* pBuffer)
1658 return SEC_E_SECPKG_NOT_FOUND;
1660 if (!table->QueryContextAttributesW)
1662 WLog_WARN(TAG,
"Security module does not provide an implementation");
1663 return SEC_E_UNSUPPORTED_FUNCTION;
1666 SECURITY_STATUS status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
1667 return log_status(
"QueryContextAttributesW", status);
1670static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(
PCtxtHandle phContext,
1671 ULONG ulAttribute,
void* pBuffer)
1676 return SEC_E_SECPKG_NOT_FOUND;
1678 if (!table->QueryContextAttributesA)
1680 WLog_WARN(TAG,
"Security module does not provide an implementation");
1681 return SEC_E_UNSUPPORTED_FUNCTION;
1684 SECURITY_STATUS status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
1685 return log_status(
"QueryContextAttributesA", status);
1688static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(
PCtxtHandle phContext,
1694 return SEC_E_SECPKG_NOT_FOUND;
1696 if (!table->QuerySecurityContextToken)
1698 WLog_WARN(TAG,
"Security module does not provide an implementation");
1699 return SEC_E_UNSUPPORTED_FUNCTION;
1702 SECURITY_STATUS status = table->QuerySecurityContextToken(phContext, phToken);
1703 return log_status(
"QuerySecurityContextToken", status);
1706static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(
PCtxtHandle phContext,
1707 ULONG ulAttribute,
void* pBuffer,
1713 return SEC_E_SECPKG_NOT_FOUND;
1715 if (!table->SetContextAttributesW)
1717 WLog_WARN(TAG,
"Security module does not provide an implementation");
1718 return SEC_E_UNSUPPORTED_FUNCTION;
1721 SECURITY_STATUS status =
1722 table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
1723 return log_status(
"SetContextAttributesW", status);
1726static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(
PCtxtHandle phContext,
1727 ULONG ulAttribute,
void* pBuffer,
1733 return SEC_E_SECPKG_NOT_FOUND;
1735 if (!table->SetContextAttributesA)
1737 WLog_WARN(TAG,
"Security module does not provide an implementation");
1738 return SEC_E_UNSUPPORTED_FUNCTION;
1741 SECURITY_STATUS status =
1742 table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
1743 return log_status(
"SetContextAttributesA", status);
1746static SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(
PCtxtHandle phContext)
1751 return SEC_E_SECPKG_NOT_FOUND;
1753 if (!table->RevertSecurityContext)
1755 WLog_WARN(TAG,
"Security module does not provide an implementation");
1756 return SEC_E_UNSUPPORTED_FUNCTION;
1759 SECURITY_STATUS status = table->RevertSecurityContext(phContext);
1761 return log_status(
"RevertSecurityContext", status);
1766static SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(
PCtxtHandle phContext,
1773 return SEC_E_SECPKG_NOT_FOUND;
1775 if (!table->DecryptMessage)
1777 WLog_WARN(TAG,
"Security module does not provide an implementation");
1778 return SEC_E_UNSUPPORTED_FUNCTION;
1781 const SECURITY_STATUS status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
1783 return log_status(
"DecryptMessage", status);
1786static SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(
PCtxtHandle phContext, ULONG fQOP,
1792 return SEC_E_SECPKG_NOT_FOUND;
1794 if (!table->EncryptMessage)
1796 WLog_WARN(TAG,
"Security module does not provide an implementation");
1797 return SEC_E_UNSUPPORTED_FUNCTION;
1800 const SECURITY_STATUS status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
1801 return log_status(
"EncryptMessage", status);
1804static SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(
PCtxtHandle phContext, ULONG fQOP,
1810 return SEC_E_SECPKG_NOT_FOUND;
1812 if (!table->MakeSignature)
1814 WLog_WARN(TAG,
"Security module does not provide an implementation");
1815 return SEC_E_UNSUPPORTED_FUNCTION;
1818 const SECURITY_STATUS status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
1819 return log_status(
"MakeSignature", status);
1822static SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(
PCtxtHandle phContext,
1829 return SEC_E_SECPKG_NOT_FOUND;
1831 if (!table->VerifySignature)
1833 WLog_WARN(TAG,
"Security module does not provide an implementation");
1834 return SEC_E_UNSUPPORTED_FUNCTION;
1837 SECURITY_STATUS status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1839 return log_status(
"VerifySignature", status);
1844 winpr_EnumerateSecurityPackagesA,
1845 winpr_QueryCredentialsAttributesA,
1846 winpr_AcquireCredentialsHandleA,
1847 winpr_FreeCredentialsHandle,
1849 winpr_InitializeSecurityContextA,
1850 winpr_AcceptSecurityContext,
1851 winpr_CompleteAuthToken,
1852 winpr_DeleteSecurityContext,
1853 winpr_ApplyControlToken,
1854 winpr_QueryContextAttributesA,
1855 winpr_ImpersonateSecurityContext,
1856 winpr_RevertSecurityContext,
1857 winpr_MakeSignature,
1858 winpr_VerifySignature,
1859 winpr_FreeContextBuffer,
1860 winpr_QuerySecurityPackageInfoA,
1863 winpr_ExportSecurityContext,
1864 winpr_ImportSecurityContextA,
1867 winpr_QuerySecurityContextToken,
1868 winpr_EncryptMessage,
1869 winpr_DecryptMessage,
1870 winpr_SetContextAttributesA,
1871 winpr_SetCredentialsAttributesA,
1876 winpr_EnumerateSecurityPackagesW,
1877 winpr_QueryCredentialsAttributesW,
1878 winpr_AcquireCredentialsHandleW,
1879 winpr_FreeCredentialsHandle,
1881 winpr_InitializeSecurityContextW,
1882 winpr_AcceptSecurityContext,
1883 winpr_CompleteAuthToken,
1884 winpr_DeleteSecurityContext,
1885 winpr_ApplyControlToken,
1886 winpr_QueryContextAttributesW,
1887 winpr_ImpersonateSecurityContext,
1888 winpr_RevertSecurityContext,
1889 winpr_MakeSignature,
1890 winpr_VerifySignature,
1891 winpr_FreeContextBuffer,
1892 winpr_QuerySecurityPackageInfoW,
1895 winpr_ExportSecurityContext,
1896 winpr_ImportSecurityContextW,
1899 winpr_QuerySecurityContextToken,
1900 winpr_EncryptMessage,
1901 winpr_DecryptMessage,
1902 winpr_SetContextAttributesW,
1903 winpr_SetCredentialsAttributesW,
1908 return &winpr_SecurityFunctionTableW;
1913 return &winpr_SecurityFunctionTableA;
1916SEC_WINPR_NTLM_SETTINGS_V2* sspi_CloneSecNtlmSettings(
const SEC_WINPR_NTLM_SETTINGS_V2* other)
1921 const size_t size =
sizeof(SEC_WINPR_NTLM_SETTINGS_V2);
1922 if (other->size < size)
1925 "Invalid SEC_WINPR_NTLM_SETTINGS_V2 parameter passed, must be of size >= "
1931 SEC_WINPR_NTLM_SETTINGS_V2* clone = sspi_AllocSecNtlmSettings();
1937 if (!sspi_CloneSecSettingsString(&clone->samFile, other->samFile))
1940 clone->hashCallback = other->hashCallback;
1941 clone->hashCallbackArg = other->hashCallbackArg;
1942 if (other->targetName)
1944 if (!sspi_CloneSecSettingsString(&clone->targetName, other->targetName))
1947 if (other->netBiosComputerName)
1949 if (!sspi_CloneSecSettingsString(&clone->netBiosComputerName, other->netBiosComputerName))
1952 if (other->netBiosDomainName)
1954 if (!sspi_CloneSecSettingsString(&clone->netBiosDomainName, other->netBiosDomainName))
1957 if (other->dnsComputerName)
1959 if (!sspi_CloneSecSettingsString(&clone->dnsComputerName, other->dnsComputerName))
1962 if (other->dnsDomainName)
1964 if (!sspi_CloneSecSettingsString(&clone->dnsDomainName, other->dnsDomainName))
1971 sspi_FreeSecNtlmSettings(clone);