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);
189 size_t userLength = 0;
190 size_t domainLength = 0;
191 size_t passwordLength = 0;
196 if (credentials->ntlmSettings.
samFile)
197 free(credentials->ntlmSettings.
samFile);
199 userLength = credentials->identity.UserLength;
200 domainLength = credentials->identity.DomainLength;
201 passwordLength = credentials->identity.PasswordLength;
203 if (passwordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
204 passwordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
206 if (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
213 if (credentials->identity.User)
214 memset(credentials->identity.User, 0, userLength);
215 if (credentials->identity.Domain)
216 memset(credentials->identity.Domain, 0, domainLength);
217 if (credentials->identity.Password)
218 memset(credentials->identity.Password, 0, passwordLength);
219 free(credentials->identity.User);
220 free(credentials->identity.Domain);
221 free(credentials->identity.Password);
259 SecInvalidateHandle(handle);
263void* sspi_SecureHandleGetLowerPointer(
SecHandle* handle)
265 void* pointer =
nullptr;
267 if (!handle || !SecIsValidHandle(handle) || !handle->dwLower)
270 pointer = (
void*)~((
size_t)handle->dwLower);
274void sspi_SecureHandleInvalidate(
SecHandle* handle)
283void sspi_SecureHandleSetLowerPointer(
SecHandle* handle,
void* pointer)
288 handle->dwLower = (ULONG_PTR)(~((
size_t)pointer));
291void* sspi_SecureHandleGetUpperPointer(
SecHandle* handle)
293 void* pointer =
nullptr;
295 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
298 pointer = (
void*)~((
size_t)handle->dwUpper);
302void sspi_SecureHandleSetUpperPointer(
SecHandle* handle,
void* pointer)
307 handle->dwUpper = (ULONG_PTR)(~((
size_t)pointer));
310void sspi_SecureHandleFree(
SecHandle* handle)
315int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
const WCHAR* domain,
316 const WCHAR* password)
318 return sspi_SetAuthIdentityWithLengthW(identity, user, user ? _wcslen(user) : 0, domain,
319 domain ? _wcslen(domain) : 0, password,
320 password ? _wcslen(password) : 0);
323static BOOL copy(WCHAR** dst, ULONG* dstLen,
const WCHAR* what,
size_t len)
326 WINPR_ASSERT(dstLen);
331 if (len > UINT32_MAX)
335 if (!what && (len != 0))
337 if (!what && (len == 0))
340 *dst = calloc(
sizeof(WCHAR), len + 1);
344 memcpy(*dst, what, len *
sizeof(WCHAR));
345 *dstLen = WINPR_ASSERTING_INT_CAST(UINT32, len);
349int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
350 size_t userLen,
const WCHAR* domain,
size_t domainLen,
351 const WCHAR* password,
size_t passwordLen)
353 WINPR_ASSERT(identity);
354 sspi_FreeAuthIdentity(identity);
355 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
356 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
358 if (!copy(&identity->User, &identity->UserLength, user, userLen))
361 if (!copy(&identity->Domain, &identity->DomainLength, domain, domainLen))
364 if (!copy(&identity->Password, &identity->PasswordLength, password, passwordLen))
370static void zfree(WCHAR* str,
size_t len)
373 memset(str, 0, len *
sizeof(WCHAR));
377int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity,
const char* user,
const char* domain,
378 const char* password)
381 size_t unicodeUserLenW = 0;
382 size_t unicodeDomainLenW = 0;
383 size_t unicodePasswordLenW = 0;
384 LPWSTR unicodeUser =
nullptr;
385 LPWSTR unicodeDomain =
nullptr;
386 LPWSTR unicodePassword =
nullptr;
389 unicodeUser = ConvertUtf8ToWCharAlloc(user, &unicodeUserLenW);
392 unicodeDomain = ConvertUtf8ToWCharAlloc(domain, &unicodeDomainLenW);
395 unicodePassword = ConvertUtf8ToWCharAlloc(password, &unicodePasswordLenW);
397 rc = sspi_SetAuthIdentityWithLengthW(identity, unicodeUser, unicodeUserLenW, unicodeDomain,
398 unicodeDomainLenW, unicodePassword, unicodePasswordLenW);
400 zfree(unicodeUser, unicodeUserLenW);
401 zfree(unicodeDomain, unicodeDomainLenW);
402 zfree(unicodePassword, unicodePasswordLenW);
406UINT32 sspi_GetAuthIdentityVersion(
const void* identity)
413 version = *((
const UINT32*)identity);
415 if ((version == SEC_WINNT_AUTH_IDENTITY_VERSION) ||
416 (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2))
424UINT32 sspi_GetAuthIdentityFlags(
const void* identity)
432 version = sspi_GetAuthIdentityVersion(identity);
434 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
436 flags = ((
const SEC_WINNT_AUTH_IDENTITY_EX*)identity)->Flags;
438 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
444 flags = ((
const SEC_WINNT_AUTH_IDENTITY*)identity)->Flags;
450BOOL sspi_GetAuthIdentityUserDomainW(
const void* identity,
const WCHAR** pUser, UINT32* pUserLength,
451 const WCHAR** pDomain, UINT32* pDomainLength)
458 version = sspi_GetAuthIdentityVersion(identity);
460 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
463 *pUser = (
const WCHAR*)id->User;
464 *pUserLength =
id->UserLength;
465 *pDomain = (
const WCHAR*)id->Domain;
466 *pDomainLength =
id->DomainLength;
468 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
471 UINT32 UserOffset =
id->UserOffset;
472 UINT32 DomainOffset =
id->DomainOffset;
473 *pUser = (
const WCHAR*)&((
const uint8_t*)identity)[UserOffset];
474 *pUserLength =
id->UserLength / 2;
475 *pDomain = (
const WCHAR*)&((
const uint8_t*)identity)[DomainOffset];
476 *pDomainLength =
id->DomainLength / 2;
481 *pUser = (
const WCHAR*)id->User;
482 *pUserLength =
id->UserLength;
483 *pDomain = (
const WCHAR*)id->Domain;
484 *pDomainLength =
id->DomainLength;
490BOOL sspi_GetAuthIdentityUserDomainA(
const void* identity,
const char** pUser, UINT32* pUserLength,
491 const char** pDomain, UINT32* pDomainLength)
498 version = sspi_GetAuthIdentityVersion(identity);
500 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
503 *pUser = (
const char*)id->User;
504 *pUserLength =
id->UserLength;
505 *pDomain = (
const char*)id->Domain;
506 *pDomainLength =
id->DomainLength;
508 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
511 UINT32 UserOffset =
id->UserOffset;
512 UINT32 DomainOffset =
id->DomainOffset;
513 *pUser = (
const char*)&((
const uint8_t*)identity)[UserOffset];
514 *pUserLength =
id->UserLength;
515 *pDomain = (
const char*)&((
const uint8_t*)identity)[DomainOffset];
516 *pDomainLength =
id->DomainLength;
521 *pUser = (
const char*)id->User;
522 *pUserLength =
id->UserLength;
523 *pDomain = (
const char*)id->Domain;
524 *pDomainLength =
id->DomainLength;
530BOOL sspi_GetAuthIdentityPasswordW(
const void* identity,
const WCHAR** pPassword,
531 UINT32* pPasswordLength)
538 version = sspi_GetAuthIdentityVersion(identity);
540 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
543 *pPassword = (
const WCHAR*)id->Password;
544 *pPasswordLength =
id->PasswordLength;
546 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
553 *pPassword = (
const WCHAR*)id->Password;
554 *pPasswordLength =
id->PasswordLength;
560BOOL sspi_GetAuthIdentityPasswordA(
const void* identity,
const char** pPassword,
561 UINT32* pPasswordLength)
568 version = sspi_GetAuthIdentityVersion(identity);
570 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
573 *pPassword = (
const char*)id->Password;
574 *pPasswordLength =
id->PasswordLength;
576 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
583 *pPassword = (
const char*)id->Password;
584 *pPasswordLength =
id->PasswordLength;
591 char** pDomain,
char** pPassword)
593 BOOL success = FALSE;
594 const char* UserA =
nullptr;
595 const char* DomainA =
nullptr;
596 const char* PasswordA =
nullptr;
597 const WCHAR* UserW =
nullptr;
598 const WCHAR* DomainW =
nullptr;
599 const WCHAR* PasswordW =
nullptr;
600 UINT32 UserLength = 0;
601 UINT32 DomainLength = 0;
602 UINT32 PasswordLength = 0;
604 if (!identity || !pUser || !pDomain || !pPassword)
607 *pUser = *pDomain = *pPassword =
nullptr;
609 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
611 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
613 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
617 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
620 if (UserA && UserLength)
622 *pUser = _strdup(UserA);
628 if (DomainA && DomainLength)
630 *pDomain = _strdup(DomainA);
636 if (PasswordA && PasswordLength)
638 *pPassword = _strdup(PasswordA);
648 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
652 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
655 if (UserW && (UserLength > 0))
657 *pUser = ConvertWCharNToUtf8Alloc(UserW, UserLength,
nullptr);
662 if (DomainW && (DomainLength > 0))
664 *pDomain = ConvertWCharNToUtf8Alloc(DomainW, DomainLength,
nullptr);
669 if (PasswordW && (PasswordLength > 0))
671 *pPassword = ConvertWCharNToUtf8Alloc(PasswordW, PasswordLength,
nullptr);
684 WCHAR** pDomain, WCHAR** pPassword)
686 BOOL success = FALSE;
687 const char* UserA =
nullptr;
688 const char* DomainA =
nullptr;
689 const char* PasswordA =
nullptr;
690 const WCHAR* UserW =
nullptr;
691 const WCHAR* DomainW =
nullptr;
692 const WCHAR* PasswordW =
nullptr;
693 UINT32 UserLength = 0;
694 UINT32 DomainLength = 0;
695 UINT32 PasswordLength = 0;
697 if (!identity || !pUser || !pDomain || !pPassword)
700 *pUser = *pDomain = *pPassword =
nullptr;
702 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
704 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
706 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
710 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
713 if (UserA && (UserLength > 0))
715 WCHAR* ptr = ConvertUtf8NToWCharAlloc(UserA, UserLength,
nullptr);
722 if (DomainA && (DomainLength > 0))
724 WCHAR* ptr = ConvertUtf8NToWCharAlloc(DomainA, DomainLength,
nullptr);
730 if (PasswordA && (PasswordLength > 0))
732 WCHAR* ptr = ConvertUtf8NToWCharAlloc(PasswordA, PasswordLength,
nullptr);
743 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
747 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
750 if (UserW && UserLength)
752 *pUser = winpr_wcsndup(UserW, UserLength /
sizeof(WCHAR));
758 if (DomainW && DomainLength)
760 *pDomain = winpr_wcsndup(DomainW, DomainLength /
sizeof(WCHAR));
766 if (PasswordW && PasswordLength)
768 *pPassword = winpr_wcsndup(PasswordW, PasswordLength /
sizeof(WCHAR));
784 UINT32 identityFlags = 0;
785 char* PackageList =
nullptr;
786 const char* PackageListA =
nullptr;
787 const WCHAR* PackageListW =
nullptr;
788 UINT32 PackageListLength = 0;
789 UINT32 PackageListOffset = 0;
790 const void* pAuthData = (
const void*)identity;
795 version = sspi_GetAuthIdentityVersion(pAuthData);
796 identityFlags = sspi_GetAuthIdentityFlags(pAuthData);
798 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
800 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
803 PackageListA = (
const char*)ad->PackageList;
804 PackageListLength = ad->PackageListLength;
807 if (PackageListA && PackageListLength)
809 PackageList = _strdup(PackageListA);
814 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
817 PackageListW = (
const WCHAR*)ad->PackageList;
818 PackageListLength = ad->PackageListLength;
820 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
823 PackageListOffset = ad->PackageListOffset;
824 PackageListW = (
const WCHAR*)&((
const uint8_t*)pAuthData)[PackageListOffset];
825 PackageListLength = ad->PackageListLength / 2;
828 if (PackageListW && (PackageListLength > 0))
829 PackageList = ConvertWCharNToUtf8Alloc(PackageListW, PackageListLength,
nullptr);
834 *pPackageList = PackageList;
841int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity,
845 UINT32 identityFlags = 0;
846 const char* UserA =
nullptr;
847 const char* DomainA =
nullptr;
848 const char* PasswordA =
nullptr;
849 const WCHAR* UserW =
nullptr;
850 const WCHAR* DomainW =
nullptr;
851 const WCHAR* PasswordW =
nullptr;
852 UINT32 UserLength = 0;
853 UINT32 DomainLength = 0;
854 UINT32 PasswordLength = 0;
856 sspi_FreeAuthIdentity(identity);
858 identityFlags = sspi_GetAuthIdentityFlags(srcIdentity);
860 identity->Flags = identityFlags;
862 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
864 if (!sspi_GetAuthIdentityUserDomainA(srcIdentity, &UserA, &UserLength, &DomainA,
870 if (!sspi_GetAuthIdentityPasswordA(srcIdentity, &PasswordA, &PasswordLength))
875 status = sspi_SetAuthIdentity(identity, UserA, DomainA, PasswordA);
880 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
881 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
885 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
887 if (!sspi_GetAuthIdentityUserDomainW(srcIdentity, &UserW, &UserLength, &DomainW, &DomainLength))
892 if (!sspi_GetAuthIdentityPasswordW(srcIdentity, &PasswordW, &PasswordLength))
898 identity->UserLength = UserLength;
900 if (identity->UserLength > 0)
902 identity->User = (UINT16*)calloc((identity->UserLength + 1),
sizeof(WCHAR));
907 CopyMemory(identity->User, UserW, identity->UserLength *
sizeof(WCHAR));
908 identity->User[identity->UserLength] = 0;
911 identity->DomainLength = DomainLength;
913 if (identity->DomainLength > 0)
915 identity->Domain = (UINT16*)calloc((identity->DomainLength + 1),
sizeof(WCHAR));
917 if (!identity->Domain)
920 CopyMemory(identity->Domain, DomainW, identity->DomainLength *
sizeof(WCHAR));
921 identity->Domain[identity->DomainLength] = 0;
924 identity->PasswordLength = PasswordLength;
926 if (identity->PasswordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
927 identity->PasswordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
931 identity->Password = (UINT16*)calloc((identity->PasswordLength + 1),
sizeof(WCHAR));
933 if (!identity->Password)
936 CopyMemory(identity->Password, PasswordW, identity->PasswordLength *
sizeof(WCHAR));
937 identity->Password[identity->PasswordLength] = 0;
940 identity->PasswordLength = PasswordLength;
949 for (UINT32 index = 0; index < pMessage->cBuffers; index++)
951 if (pMessage->pBuffers[index].BufferType == BufferType)
953 pSecBuffer = &pMessage->pBuffers[index];
961static BOOL WINPR_init(
void)
964 for (
size_t x = 0; x < ARRAYSIZE(SecurityFunctionTableA_NAME_LIST); x++)
966 const SecurityFunctionTableA_NAME* cur = &SecurityFunctionTableA_NAME_LIST[x];
967 InitializeConstWCharFromUtf8(cur->Name, BUFFER_NAME_LIST_W[x],
968 ARRAYSIZE(BUFFER_NAME_LIST_W[x]));
973static BOOL CALLBACK sspi_init(WINPR_ATTR_UNUSED
PINIT_ONCE InitOnce,
974 WINPR_ATTR_UNUSED PVOID Parameter, WINPR_ATTR_UNUSED PVOID* Context)
976 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
978 sspi_ContextBufferAllocTableNew();
979 if (!SCHANNEL_init())
981 if (!KERBEROS_init())
987 if (!NEGOTIATE_init())
992void sspi_GlobalInit(
void)
994 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
996 if (!InitOnceExecuteOnce(&once, sspi_init, &flags,
nullptr))
997 WLog_ERR(TAG,
"InitOnceExecuteOnce failed");
1000void sspi_GlobalFinish(
void)
1002 sspi_ContextBufferAllocTableFree();
1007 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1009 for (
size_t index = 0; index < cPackages; index++)
1011 if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
1013 return SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
1022 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1024 for (
size_t index = 0; index < cPackages; index++)
1026 if (_wcscmp(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
1028 return SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
1037 SEC_WCHAR* NameW =
nullptr;
1043 NameW = ConvertUtf8ToWCharAlloc(Name,
nullptr);
1048 table = sspi_GetSecurityFunctionTableWByNameW(NameW);
1053static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer);
1054static void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer);
1056void sspi_ContextBufferFree(
void* contextBuffer)
1058 UINT32 allocatorIndex = 0;
1060 for (
size_t index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
1062 if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
1064 contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
1065 allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
1066 ContextBufferAllocTable.cEntries--;
1067 ContextBufferAllocTable.entries[index].allocatorIndex = 0;
1068 ContextBufferAllocTable.entries[index].contextBuffer =
nullptr;
1070 switch (allocatorIndex)
1072 case EnumerateSecurityPackagesIndex:
1073 FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
1076 case QuerySecurityPackageInfoIndex:
1077 FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
1092static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages,
1095 const size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1096 const size_t size =
sizeof(
SecPkgInfoW) * cPackages;
1098 (
SecPkgInfoW*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1100 WINPR_ASSERT(cPackages <= UINT32_MAX);
1103 return SEC_E_INSUFFICIENT_MEMORY;
1105 for (
size_t index = 0; index < cPackages; index++)
1107 pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1108 pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
1109 pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1110 pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1111 pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1112 pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1115 *(pcPackages) = (UINT32)cPackages;
1116 *(ppPackageInfo) = pPackageInfo;
1120static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages,
1123 const size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1124 const size_t size =
sizeof(
SecPkgInfoA) * cPackages;
1126 (
SecPkgInfoA*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1128 WINPR_ASSERT(cPackages <= UINT32_MAX);
1131 return SEC_E_INSUFFICIENT_MEMORY;
1133 for (
size_t index = 0; index < cPackages; index++)
1135 pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1136 pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
1137 pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1138 pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1139 pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1140 pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1142 if (!pPackageInfo[index].Name || !pPackageInfo[index].Comment)
1144 sspi_ContextBufferFree(pPackageInfo);
1145 return SEC_E_INSUFFICIENT_MEMORY;
1149 *(pcPackages) = (UINT32)cPackages;
1150 *(ppPackageInfo) = pPackageInfo;
1154static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer)
1157 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1162 for (
size_t index = 0; index < cPackages; index++)
1164 free(pPackageInfo[index].Name);
1165 free(pPackageInfo[index].Comment);
1171static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
1174 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1176 for (
size_t index = 0; index < cPackages; index++)
1178 if (_wcscmp(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
1182 (
SecPkgInfoW*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1185 return SEC_E_INSUFFICIENT_MEMORY;
1187 pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1188 pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
1189 pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1190 pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1191 pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1192 pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1193 *(ppPackageInfo) = pPackageInfo;
1198 *(ppPackageInfo) =
nullptr;
1199 return SEC_E_SECPKG_NOT_FOUND;
1202static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
1205 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1207 for (
size_t index = 0; index < cPackages; index++)
1209 if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
1213 (
SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1216 return SEC_E_INSUFFICIENT_MEMORY;
1218 pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1219 pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
1220 pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1221 pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1222 pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1223 pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1225 if (!pPackageInfo->Name || !pPackageInfo->Comment)
1227 sspi_ContextBufferFree(pPackageInfo);
1228 return SEC_E_INSUFFICIENT_MEMORY;
1231 *(ppPackageInfo) = pPackageInfo;
1236 *(ppPackageInfo) =
nullptr;
1237 return SEC_E_SECPKG_NOT_FOUND;
1240void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer)
1242 SecPkgInfo* pPackageInfo = (SecPkgInfo*)contextBuffer;
1247 free(pPackageInfo->Name);
1248 free(pPackageInfo->Comment);
1252#define log_status(what, status) log_status_((what), (status), __FILE__, __func__, __LINE__)
1253static SECURITY_STATUS log_status_(
const char* what, SECURITY_STATUS status,
const char* file,
1254 const char* fkt,
size_t line)
1256 if (IsSecurityStatusError(status))
1258 const DWORD level = WLOG_WARN;
1259 static wLog* log =
nullptr;
1261 log = WLog_Get(TAG);
1263 if (WLog_IsLevelActive(log, level))
1265 WLog_PrintTextMessage(log, level, line, file, fkt,
"%s status %s [0x%08" PRIx32
"]",
1266 what, GetSecurityStatusString(status),
1267 WINPR_CXX_COMPAT_CAST(uint32_t, status));
1275static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(
1276 SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1277 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1280 SECURITY_STATUS status = 0;
1284 return SEC_E_SECPKG_NOT_FOUND;
1286 if (!table->AcquireCredentialsHandleW)
1288 WLog_WARN(TAG,
"Security module does not provide an implementation");
1289 return SEC_E_UNSUPPORTED_FUNCTION;
1292 status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
1293 pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
1295 return log_status(
"AcquireCredentialsHandleW", status);
1298static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(
1299 SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1300 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1303 SECURITY_STATUS status = 0;
1307 return SEC_E_SECPKG_NOT_FOUND;
1309 if (!table->AcquireCredentialsHandleA)
1311 WLog_WARN(TAG,
"Security module does not provide an implementation");
1312 return SEC_E_UNSUPPORTED_FUNCTION;
1315 status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
1316 pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
1318 return log_status(
"AcquireCredentialsHandleA", status);
1321static SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(
PCtxtHandle phContext, ULONG fFlags,
1325 SEC_CHAR* Name =
nullptr;
1326 SECURITY_STATUS status = 0;
1328 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1331 return SEC_E_SECPKG_NOT_FOUND;
1333 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1336 return SEC_E_SECPKG_NOT_FOUND;
1338 if (!table->ExportSecurityContext)
1340 WLog_WARN(TAG,
"Security module does not provide an implementation");
1341 return SEC_E_UNSUPPORTED_FUNCTION;
1344 status = table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
1345 return log_status(
"ExportSecurityContext", status);
1348static SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(
PCredHandle phCredential)
1350 char* Name =
nullptr;
1351 SECURITY_STATUS status = 0;
1353 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1356 return SEC_E_SECPKG_NOT_FOUND;
1358 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1361 return SEC_E_SECPKG_NOT_FOUND;
1363 if (!table->FreeCredentialsHandle)
1365 WLog_WARN(TAG,
"Security module does not provide an implementation");
1366 return SEC_E_UNSUPPORTED_FUNCTION;
1369 status = table->FreeCredentialsHandle(phCredential);
1370 return log_status(
"FreeCredentialsHandle", status);
1373static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage,
1377 SEC_CHAR* Name =
nullptr;
1378 SECURITY_STATUS status = 0;
1380 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1383 return SEC_E_SECPKG_NOT_FOUND;
1385 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1388 return SEC_E_SECPKG_NOT_FOUND;
1390 if (!table->ImportSecurityContextW)
1392 WLog_WARN(TAG,
"Security module does not provide an implementation");
1393 return SEC_E_UNSUPPORTED_FUNCTION;
1396 status = table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
1397 return log_status(
"ImportSecurityContextW", status);
1400static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage,
1404 char* Name =
nullptr;
1405 SECURITY_STATUS status = 0;
1407 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1410 return SEC_E_SECPKG_NOT_FOUND;
1412 table = sspi_GetSecurityFunctionTableAByNameA(Name);
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 status = table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
1424 return log_status(
"ImportSecurityContextA", status);
1427static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(
PCredHandle phCredential,
1428 ULONG ulAttribute,
void* pBuffer)
1430 SEC_WCHAR* Name =
nullptr;
1431 SECURITY_STATUS status = 0;
1433 Name = (SEC_WCHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1436 return SEC_E_SECPKG_NOT_FOUND;
1438 table = sspi_GetSecurityFunctionTableWByNameW(Name);
1441 return SEC_E_SECPKG_NOT_FOUND;
1443 if (!table->QueryCredentialsAttributesW)
1445 WLog_WARN(TAG,
"Security module does not provide an implementation");
1446 return SEC_E_UNSUPPORTED_FUNCTION;
1449 status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
1450 return log_status(
"QueryCredentialsAttributesW", status);
1453static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(
PCredHandle phCredential,
1454 ULONG ulAttribute,
void* pBuffer)
1456 char* Name =
nullptr;
1457 SECURITY_STATUS status = 0;
1459 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1462 return SEC_E_SECPKG_NOT_FOUND;
1464 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1467 return SEC_E_SECPKG_NOT_FOUND;
1469 if (!table->QueryCredentialsAttributesA)
1471 WLog_WARN(TAG,
"Security module does not provide an implementation");
1472 return SEC_E_UNSUPPORTED_FUNCTION;
1475 status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
1476 return log_status(
"QueryCredentialsAttributesA", status);
1479static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesW(
PCredHandle phCredential,
1480 ULONG ulAttribute,
void* pBuffer,
1483 SEC_WCHAR* Name =
nullptr;
1484 SECURITY_STATUS status = 0;
1486 Name = (SEC_WCHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1489 return SEC_E_SECPKG_NOT_FOUND;
1491 table = sspi_GetSecurityFunctionTableWByNameW(Name);
1494 return SEC_E_SECPKG_NOT_FOUND;
1496 if (!table->SetCredentialsAttributesW)
1498 WLog_WARN(TAG,
"Security module does not provide an implementation");
1499 return SEC_E_UNSUPPORTED_FUNCTION;
1502 status = table->SetCredentialsAttributesW(phCredential, ulAttribute, pBuffer, cbBuffer);
1503 return log_status(
"SetCredentialsAttributesW", status);
1506static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesA(
PCredHandle phCredential,
1507 ULONG ulAttribute,
void* pBuffer,
1510 char* Name =
nullptr;
1511 SECURITY_STATUS status = 0;
1513 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1516 return SEC_E_SECPKG_NOT_FOUND;
1518 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1521 return SEC_E_SECPKG_NOT_FOUND;
1523 if (!table->SetCredentialsAttributesA)
1525 WLog_WARN(TAG,
"Security module does not provide an implementation");
1526 return SEC_E_UNSUPPORTED_FUNCTION;
1529 status = table->SetCredentialsAttributesA(phCredential, ulAttribute, pBuffer, cbBuffer);
1530 return log_status(
"SetCredentialsAttributesA", status);
1535static SECURITY_STATUS SEC_ENTRY
1537 ULONG fContextReq, ULONG TargetDataRep,
PCtxtHandle phNewContext,
1540 char* Name =
nullptr;
1541 SECURITY_STATUS status = 0;
1543 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1546 return SEC_E_SECPKG_NOT_FOUND;
1548 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1551 return SEC_E_SECPKG_NOT_FOUND;
1553 if (!table->AcceptSecurityContext)
1555 WLog_WARN(TAG,
"Security module does not provide an implementation");
1556 return SEC_E_UNSUPPORTED_FUNCTION;
1560 table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
1561 phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
1562 return log_status(
"AcceptSecurityContext", status);
1565static SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(
PCtxtHandle phContext,
1568 char* Name =
nullptr;
1569 SECURITY_STATUS status = 0;
1571 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1574 return SEC_E_SECPKG_NOT_FOUND;
1576 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1579 return SEC_E_SECPKG_NOT_FOUND;
1581 if (!table->ApplyControlToken)
1583 WLog_WARN(TAG,
"Security module does not provide an implementation");
1584 return SEC_E_UNSUPPORTED_FUNCTION;
1587 status = table->ApplyControlToken(phContext, pInput);
1588 return log_status(
"ApplyControlToken", status);
1591static SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(
PCtxtHandle phContext,
1594 char* Name =
nullptr;
1595 SECURITY_STATUS status = 0;
1597 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1600 return SEC_E_SECPKG_NOT_FOUND;
1602 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1605 return SEC_E_SECPKG_NOT_FOUND;
1607 if (!table->CompleteAuthToken)
1609 WLog_WARN(TAG,
"Security module does not provide an implementation");
1610 return SEC_E_UNSUPPORTED_FUNCTION;
1613 status = table->CompleteAuthToken(phContext, pToken);
1614 return log_status(
"CompleteAuthToken", status);
1617static SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(
PCtxtHandle phContext)
1619 const char* Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1622 return SEC_E_SECPKG_NOT_FOUND;
1627 return SEC_E_SECPKG_NOT_FOUND;
1629 if (!table->DeleteSecurityContext)
1631 WLog_WARN(TAG,
"Security module does not provide an implementation");
1632 return SEC_E_UNSUPPORTED_FUNCTION;
1635 const SECURITY_STATUS status = table->DeleteSecurityContext(phContext);
1636 return log_status(
"DeleteSecurityContext", status);
1639static SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(
void* pvContextBuffer)
1641 if (!pvContextBuffer)
1642 return SEC_E_INVALID_HANDLE;
1644 sspi_ContextBufferFree(pvContextBuffer);
1648static SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(
PCtxtHandle phContext)
1650 SEC_CHAR* Name =
nullptr;
1651 SECURITY_STATUS status = 0;
1653 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1656 return SEC_E_SECPKG_NOT_FOUND;
1658 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1661 return SEC_E_SECPKG_NOT_FOUND;
1663 if (!table->ImpersonateSecurityContext)
1665 WLog_WARN(TAG,
"Security module does not provide an implementation");
1666 return SEC_E_UNSUPPORTED_FUNCTION;
1669 status = table->ImpersonateSecurityContext(phContext);
1670 return log_status(
"ImpersonateSecurityContext", status);
1673static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(
1675 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1678 SEC_CHAR* Name =
nullptr;
1679 SECURITY_STATUS status = 0;
1681 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1684 return SEC_E_SECPKG_NOT_FOUND;
1686 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1689 return SEC_E_SECPKG_NOT_FOUND;
1691 if (!table->InitializeSecurityContextW)
1693 WLog_WARN(TAG,
"Security module does not provide an implementation");
1694 return SEC_E_UNSUPPORTED_FUNCTION;
1697 status = table->InitializeSecurityContextW(phCredential, phContext, pszTargetName, fContextReq,
1698 Reserved1, TargetDataRep, pInput, Reserved2,
1699 phNewContext, pOutput, pfContextAttr, ptsExpiry);
1700 return log_status(
"InitializeSecurityContextW", status);
1703static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(
1705 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1708 SEC_CHAR* Name =
nullptr;
1709 SECURITY_STATUS status = 0;
1711 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1714 return SEC_E_SECPKG_NOT_FOUND;
1716 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1719 return SEC_E_SECPKG_NOT_FOUND;
1721 if (!table->InitializeSecurityContextA)
1723 WLog_WARN(TAG,
"Security module does not provide an implementation");
1724 return SEC_E_UNSUPPORTED_FUNCTION;
1727 status = table->InitializeSecurityContextA(phCredential, phContext, pszTargetName, fContextReq,
1728 Reserved1, TargetDataRep, pInput, Reserved2,
1729 phNewContext, pOutput, pfContextAttr, ptsExpiry);
1731 return log_status(
"InitializeSecurityContextA", status);
1734static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(
PCtxtHandle phContext,
1735 ULONG ulAttribute,
void* pBuffer)
1737 SEC_CHAR* Name =
nullptr;
1738 SECURITY_STATUS status = 0;
1740 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1743 return SEC_E_SECPKG_NOT_FOUND;
1745 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1748 return SEC_E_SECPKG_NOT_FOUND;
1750 if (!table->QueryContextAttributesW)
1752 WLog_WARN(TAG,
"Security module does not provide an implementation");
1753 return SEC_E_UNSUPPORTED_FUNCTION;
1756 status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
1757 return log_status(
"QueryContextAttributesW", status);
1760static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(
PCtxtHandle phContext,
1761 ULONG ulAttribute,
void* pBuffer)
1763 SEC_CHAR* Name =
nullptr;
1764 SECURITY_STATUS status = 0;
1766 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1769 return SEC_E_SECPKG_NOT_FOUND;
1771 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1774 return SEC_E_SECPKG_NOT_FOUND;
1776 if (!table->QueryContextAttributesA)
1778 WLog_WARN(TAG,
"Security module does not provide an implementation");
1779 return SEC_E_UNSUPPORTED_FUNCTION;
1782 status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
1783 return log_status(
"QueryContextAttributesA", status);
1786static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(
PCtxtHandle phContext,
1789 SEC_CHAR* Name =
nullptr;
1790 SECURITY_STATUS status = 0;
1792 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1795 return SEC_E_SECPKG_NOT_FOUND;
1797 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1800 return SEC_E_SECPKG_NOT_FOUND;
1802 if (!table->QuerySecurityContextToken)
1804 WLog_WARN(TAG,
"Security module does not provide an implementation");
1805 return SEC_E_UNSUPPORTED_FUNCTION;
1808 status = table->QuerySecurityContextToken(phContext, phToken);
1809 return log_status(
"QuerySecurityContextToken", status);
1812static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(
PCtxtHandle phContext,
1813 ULONG ulAttribute,
void* pBuffer,
1816 SEC_CHAR* Name =
nullptr;
1817 SECURITY_STATUS status = 0;
1819 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1822 return SEC_E_SECPKG_NOT_FOUND;
1824 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1827 return SEC_E_SECPKG_NOT_FOUND;
1829 if (!table->SetContextAttributesW)
1831 WLog_WARN(TAG,
"Security module does not provide an implementation");
1832 return SEC_E_UNSUPPORTED_FUNCTION;
1835 status = table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
1836 return log_status(
"SetContextAttributesW", status);
1839static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(
PCtxtHandle phContext,
1840 ULONG ulAttribute,
void* pBuffer,
1843 char* Name =
nullptr;
1844 SECURITY_STATUS status = 0;
1846 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1849 return SEC_E_SECPKG_NOT_FOUND;
1851 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1854 return SEC_E_SECPKG_NOT_FOUND;
1856 if (!table->SetContextAttributesA)
1858 WLog_WARN(TAG,
"Security module does not provide an implementation");
1859 return SEC_E_UNSUPPORTED_FUNCTION;
1862 status = table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
1863 return log_status(
"SetContextAttributesA", status);
1866static SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(
PCtxtHandle phContext)
1868 SEC_CHAR* Name =
nullptr;
1869 SECURITY_STATUS status = 0;
1871 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1874 return SEC_E_SECPKG_NOT_FOUND;
1876 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1879 return SEC_E_SECPKG_NOT_FOUND;
1881 if (!table->RevertSecurityContext)
1883 WLog_WARN(TAG,
"Security module does not provide an implementation");
1884 return SEC_E_UNSUPPORTED_FUNCTION;
1887 status = table->RevertSecurityContext(phContext);
1889 return log_status(
"RevertSecurityContext", status);
1894static SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(
PCtxtHandle phContext,
1898 char* Name =
nullptr;
1899 SECURITY_STATUS status = 0;
1901 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1904 return SEC_E_SECPKG_NOT_FOUND;
1906 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1909 return SEC_E_SECPKG_NOT_FOUND;
1911 if (!table->DecryptMessage)
1913 WLog_WARN(TAG,
"Security module does not provide an implementation");
1914 return SEC_E_UNSUPPORTED_FUNCTION;
1917 status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
1919 return log_status(
"DecryptMessage", status);
1922static SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(
PCtxtHandle phContext, ULONG fQOP,
1925 char* Name =
nullptr;
1926 SECURITY_STATUS status = 0;
1928 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1931 return SEC_E_SECPKG_NOT_FOUND;
1933 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1936 return SEC_E_SECPKG_NOT_FOUND;
1938 if (!table->EncryptMessage)
1940 WLog_WARN(TAG,
"Security module does not provide an implementation");
1941 return SEC_E_UNSUPPORTED_FUNCTION;
1944 status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
1945 return log_status(
"EncryptMessage", status);
1948static SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(
PCtxtHandle phContext, ULONG fQOP,
1951 SECURITY_STATUS status = 0;
1952 const char* Name = (
const char*)sspi_SecureHandleGetUpperPointer(phContext);
1955 return SEC_E_SECPKG_NOT_FOUND;
1960 return SEC_E_SECPKG_NOT_FOUND;
1962 if (!table->MakeSignature)
1964 WLog_WARN(TAG,
"Security module does not provide an implementation");
1965 return SEC_E_UNSUPPORTED_FUNCTION;
1968 status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
1969 return log_status(
"MakeSignature", status);
1972static SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(
PCtxtHandle phContext,
1976 SECURITY_STATUS status = 0;
1978 const char* Name = (
const char*)sspi_SecureHandleGetUpperPointer(phContext);
1981 return SEC_E_SECPKG_NOT_FOUND;
1986 return SEC_E_SECPKG_NOT_FOUND;
1988 if (!table->VerifySignature)
1990 WLog_WARN(TAG,
"Security module does not provide an implementation");
1991 return SEC_E_UNSUPPORTED_FUNCTION;
1994 status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1996 return log_status(
"VerifySignature", status);
2001 winpr_EnumerateSecurityPackagesA,
2002 winpr_QueryCredentialsAttributesA,
2003 winpr_AcquireCredentialsHandleA,
2004 winpr_FreeCredentialsHandle,
2006 winpr_InitializeSecurityContextA,
2007 winpr_AcceptSecurityContext,
2008 winpr_CompleteAuthToken,
2009 winpr_DeleteSecurityContext,
2010 winpr_ApplyControlToken,
2011 winpr_QueryContextAttributesA,
2012 winpr_ImpersonateSecurityContext,
2013 winpr_RevertSecurityContext,
2014 winpr_MakeSignature,
2015 winpr_VerifySignature,
2016 winpr_FreeContextBuffer,
2017 winpr_QuerySecurityPackageInfoA,
2020 winpr_ExportSecurityContext,
2021 winpr_ImportSecurityContextA,
2024 winpr_QuerySecurityContextToken,
2025 winpr_EncryptMessage,
2026 winpr_DecryptMessage,
2027 winpr_SetContextAttributesA,
2028 winpr_SetCredentialsAttributesA,
2033 winpr_EnumerateSecurityPackagesW,
2034 winpr_QueryCredentialsAttributesW,
2035 winpr_AcquireCredentialsHandleW,
2036 winpr_FreeCredentialsHandle,
2038 winpr_InitializeSecurityContextW,
2039 winpr_AcceptSecurityContext,
2040 winpr_CompleteAuthToken,
2041 winpr_DeleteSecurityContext,
2042 winpr_ApplyControlToken,
2043 winpr_QueryContextAttributesW,
2044 winpr_ImpersonateSecurityContext,
2045 winpr_RevertSecurityContext,
2046 winpr_MakeSignature,
2047 winpr_VerifySignature,
2048 winpr_FreeContextBuffer,
2049 winpr_QuerySecurityPackageInfoW,
2052 winpr_ExportSecurityContext,
2053 winpr_ImportSecurityContextW,
2056 winpr_QuerySecurityContextToken,
2057 winpr_EncryptMessage,
2058 winpr_DecryptMessage,
2059 winpr_SetContextAttributesW,
2060 winpr_SetCredentialsAttributesW,
2065 return &winpr_SecurityFunctionTableW;
2070 return &winpr_SecurityFunctionTableA;