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 (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
210 if (credentials->identity.User)
211 memset(credentials->identity.User, 0, userLength);
212 if (credentials->identity.Domain)
213 memset(credentials->identity.Domain, 0, domainLength);
214 if (credentials->identity.Password)
215 memset(credentials->identity.Password, 0, passwordLength);
216 free(credentials->identity.User);
217 free(credentials->identity.Domain);
218 free(credentials->identity.Password);
256 SecInvalidateHandle(handle);
260void* sspi_SecureHandleGetLowerPointer(
SecHandle* handle)
262 void* pointer =
nullptr;
264 if (!handle || !SecIsValidHandle(handle) || !handle->dwLower)
267 pointer = (
void*)~((
size_t)handle->dwLower);
271void sspi_SecureHandleInvalidate(
SecHandle* handle)
280void sspi_SecureHandleSetLowerPointer(
SecHandle* handle,
void* pointer)
285 handle->dwLower = (ULONG_PTR)(~((
size_t)pointer));
288void* sspi_SecureHandleGetUpperPointer(
SecHandle* handle)
290 void* pointer =
nullptr;
292 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
295 pointer = (
void*)~((
size_t)handle->dwUpper);
299void sspi_SecureHandleSetUpperPointer(
SecHandle* handle,
void* pointer)
304 handle->dwUpper = (ULONG_PTR)(~((
size_t)pointer));
307void sspi_SecureHandleFree(
SecHandle* handle)
312int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
const WCHAR* domain,
313 const WCHAR* password)
315 return sspi_SetAuthIdentityWithLengthW(identity, user, user ? _wcslen(user) : 0, domain,
316 domain ? _wcslen(domain) : 0, password,
317 password ? _wcslen(password) : 0);
320static BOOL copy(WCHAR** dst, ULONG* dstLen,
const WCHAR* what,
size_t len)
323 WINPR_ASSERT(dstLen);
328 if (len > UINT32_MAX)
332 if (!what && (len != 0))
334 if (!what && (len == 0))
337 *dst = calloc(
sizeof(WCHAR), len + 1);
341 memcpy(*dst, what, len *
sizeof(WCHAR));
342 *dstLen = WINPR_ASSERTING_INT_CAST(UINT32, len);
346int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
347 size_t userLen,
const WCHAR* domain,
size_t domainLen,
348 const WCHAR* password,
size_t passwordLen)
350 WINPR_ASSERT(identity);
351 sspi_FreeAuthIdentity(identity);
352 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
353 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
355 if (!copy(&identity->User, &identity->UserLength, user, userLen))
358 if (!copy(&identity->Domain, &identity->DomainLength, domain, domainLen))
361 if (!copy(&identity->Password, &identity->PasswordLength, password, passwordLen))
367static void zfree(WCHAR* str,
size_t len)
370 memset(str, 0, len *
sizeof(WCHAR));
374int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity,
const char* user,
const char* domain,
375 const char* password)
378 size_t unicodeUserLenW = 0;
379 size_t unicodeDomainLenW = 0;
380 size_t unicodePasswordLenW = 0;
381 LPWSTR unicodeUser =
nullptr;
382 LPWSTR unicodeDomain =
nullptr;
383 LPWSTR unicodePassword =
nullptr;
386 unicodeUser = ConvertUtf8ToWCharAlloc(user, &unicodeUserLenW);
389 unicodeDomain = ConvertUtf8ToWCharAlloc(domain, &unicodeDomainLenW);
392 unicodePassword = ConvertUtf8ToWCharAlloc(password, &unicodePasswordLenW);
394 rc = sspi_SetAuthIdentityWithLengthW(identity, unicodeUser, unicodeUserLenW, unicodeDomain,
395 unicodeDomainLenW, unicodePassword, unicodePasswordLenW);
397 zfree(unicodeUser, unicodeUserLenW);
398 zfree(unicodeDomain, unicodeDomainLenW);
399 zfree(unicodePassword, unicodePasswordLenW);
403UINT32 sspi_GetAuthIdentityVersion(
const void* identity)
410 version = *((
const UINT32*)identity);
412 if ((version == SEC_WINNT_AUTH_IDENTITY_VERSION) ||
413 (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2))
421UINT32 sspi_GetAuthIdentityFlags(
const void* identity)
429 version = sspi_GetAuthIdentityVersion(identity);
431 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
433 flags = ((
const SEC_WINNT_AUTH_IDENTITY_EX*)identity)->Flags;
435 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
441 flags = ((
const SEC_WINNT_AUTH_IDENTITY*)identity)->Flags;
447BOOL sspi_GetAuthIdentityUserDomainW(
const void* identity,
const WCHAR** pUser, UINT32* pUserLength,
448 const WCHAR** pDomain, UINT32* pDomainLength)
455 version = sspi_GetAuthIdentityVersion(identity);
457 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
460 *pUser = (
const WCHAR*)id->User;
461 *pUserLength =
id->UserLength;
462 *pDomain = (
const WCHAR*)id->Domain;
463 *pDomainLength =
id->DomainLength;
465 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
468 UINT32 UserOffset =
id->UserOffset;
469 UINT32 DomainOffset =
id->DomainOffset;
470 *pUser = (
const WCHAR*)&((
const uint8_t*)identity)[UserOffset];
471 *pUserLength =
id->UserLength / 2;
472 *pDomain = (
const WCHAR*)&((
const uint8_t*)identity)[DomainOffset];
473 *pDomainLength =
id->DomainLength / 2;
478 *pUser = (
const WCHAR*)id->User;
479 *pUserLength =
id->UserLength;
480 *pDomain = (
const WCHAR*)id->Domain;
481 *pDomainLength =
id->DomainLength;
487BOOL sspi_GetAuthIdentityUserDomainA(
const void* identity,
const char** pUser, UINT32* pUserLength,
488 const char** pDomain, UINT32* pDomainLength)
495 version = sspi_GetAuthIdentityVersion(identity);
497 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
500 *pUser = (
const char*)id->User;
501 *pUserLength =
id->UserLength;
502 *pDomain = (
const char*)id->Domain;
503 *pDomainLength =
id->DomainLength;
505 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
508 UINT32 UserOffset =
id->UserOffset;
509 UINT32 DomainOffset =
id->DomainOffset;
510 *pUser = (
const char*)&((
const uint8_t*)identity)[UserOffset];
511 *pUserLength =
id->UserLength;
512 *pDomain = (
const char*)&((
const uint8_t*)identity)[DomainOffset];
513 *pDomainLength =
id->DomainLength;
518 *pUser = (
const char*)id->User;
519 *pUserLength =
id->UserLength;
520 *pDomain = (
const char*)id->Domain;
521 *pDomainLength =
id->DomainLength;
527BOOL sspi_GetAuthIdentityPasswordW(
const void* identity,
const WCHAR** pPassword,
528 UINT32* pPasswordLength)
535 version = sspi_GetAuthIdentityVersion(identity);
537 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
540 *pPassword = (
const WCHAR*)id->Password;
541 *pPasswordLength =
id->PasswordLength;
543 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
550 *pPassword = (
const WCHAR*)id->Password;
551 *pPasswordLength =
id->PasswordLength;
557BOOL sspi_GetAuthIdentityPasswordA(
const void* identity,
const char** pPassword,
558 UINT32* pPasswordLength)
565 version = sspi_GetAuthIdentityVersion(identity);
567 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
570 *pPassword = (
const char*)id->Password;
571 *pPasswordLength =
id->PasswordLength;
573 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
580 *pPassword = (
const char*)id->Password;
581 *pPasswordLength =
id->PasswordLength;
588 char** pDomain,
char** pPassword)
590 BOOL success = FALSE;
591 const char* UserA =
nullptr;
592 const char* DomainA =
nullptr;
593 const char* PasswordA =
nullptr;
594 const WCHAR* UserW =
nullptr;
595 const WCHAR* DomainW =
nullptr;
596 const WCHAR* PasswordW =
nullptr;
597 UINT32 UserLength = 0;
598 UINT32 DomainLength = 0;
599 UINT32 PasswordLength = 0;
601 if (!identity || !pUser || !pDomain || !pPassword)
604 *pUser = *pDomain = *pPassword =
nullptr;
606 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
608 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
610 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
614 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
617 if (UserA && UserLength)
619 *pUser = _strdup(UserA);
625 if (DomainA && DomainLength)
627 *pDomain = _strdup(DomainA);
633 if (PasswordA && PasswordLength)
635 *pPassword = _strdup(PasswordA);
645 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
649 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
652 if (UserW && (UserLength > 0))
654 *pUser = ConvertWCharNToUtf8Alloc(UserW, UserLength,
nullptr);
659 if (DomainW && (DomainLength > 0))
661 *pDomain = ConvertWCharNToUtf8Alloc(DomainW, DomainLength,
nullptr);
666 if (PasswordW && (PasswordLength > 0))
668 *pPassword = ConvertWCharNToUtf8Alloc(PasswordW, PasswordLength,
nullptr);
681 WCHAR** pDomain, WCHAR** pPassword)
683 BOOL success = FALSE;
684 const char* UserA =
nullptr;
685 const char* DomainA =
nullptr;
686 const char* PasswordA =
nullptr;
687 const WCHAR* UserW =
nullptr;
688 const WCHAR* DomainW =
nullptr;
689 const WCHAR* PasswordW =
nullptr;
690 UINT32 UserLength = 0;
691 UINT32 DomainLength = 0;
692 UINT32 PasswordLength = 0;
694 if (!identity || !pUser || !pDomain || !pPassword)
697 *pUser = *pDomain = *pPassword =
nullptr;
699 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
701 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
703 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
707 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
710 if (UserA && (UserLength > 0))
712 WCHAR* ptr = ConvertUtf8NToWCharAlloc(UserA, UserLength,
nullptr);
719 if (DomainA && (DomainLength > 0))
721 WCHAR* ptr = ConvertUtf8NToWCharAlloc(DomainA, DomainLength,
nullptr);
727 if (PasswordA && (PasswordLength > 0))
729 WCHAR* ptr = ConvertUtf8NToWCharAlloc(PasswordA, PasswordLength,
nullptr);
740 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
744 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
747 if (UserW && UserLength)
749 *pUser = winpr_wcsndup(UserW, UserLength /
sizeof(WCHAR));
755 if (DomainW && DomainLength)
757 *pDomain = winpr_wcsndup(DomainW, DomainLength /
sizeof(WCHAR));
763 if (PasswordW && PasswordLength)
765 *pPassword = winpr_wcsndup(PasswordW, PasswordLength /
sizeof(WCHAR));
781 UINT32 identityFlags = 0;
782 char* PackageList =
nullptr;
783 const char* PackageListA =
nullptr;
784 const WCHAR* PackageListW =
nullptr;
785 UINT32 PackageListLength = 0;
786 UINT32 PackageListOffset = 0;
787 const void* pAuthData = (
const void*)identity;
792 version = sspi_GetAuthIdentityVersion(pAuthData);
793 identityFlags = sspi_GetAuthIdentityFlags(pAuthData);
795 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
797 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
800 PackageListA = (
const char*)ad->PackageList;
801 PackageListLength = ad->PackageListLength;
804 if (PackageListA && PackageListLength)
806 PackageList = _strdup(PackageListA);
811 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
814 PackageListW = (
const WCHAR*)ad->PackageList;
815 PackageListLength = ad->PackageListLength;
817 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
820 PackageListOffset = ad->PackageListOffset;
821 PackageListW = (
const WCHAR*)&((
const uint8_t*)pAuthData)[PackageListOffset];
822 PackageListLength = ad->PackageListLength / 2;
825 if (PackageListW && (PackageListLength > 0))
826 PackageList = ConvertWCharNToUtf8Alloc(PackageListW, PackageListLength,
nullptr);
831 *pPackageList = PackageList;
838int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity,
842 UINT32 identityFlags = 0;
843 const char* UserA =
nullptr;
844 const char* DomainA =
nullptr;
845 const char* PasswordA =
nullptr;
846 const WCHAR* UserW =
nullptr;
847 const WCHAR* DomainW =
nullptr;
848 const WCHAR* PasswordW =
nullptr;
849 UINT32 UserLength = 0;
850 UINT32 DomainLength = 0;
851 UINT32 PasswordLength = 0;
853 sspi_FreeAuthIdentity(identity);
855 identityFlags = sspi_GetAuthIdentityFlags(srcIdentity);
857 identity->Flags = identityFlags;
859 if (identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI)
861 if (!sspi_GetAuthIdentityUserDomainA(srcIdentity, &UserA, &UserLength, &DomainA,
867 if (!sspi_GetAuthIdentityPasswordA(srcIdentity, &PasswordA, &PasswordLength))
872 status = sspi_SetAuthIdentity(identity, UserA, DomainA, PasswordA);
877 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
878 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
882 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
884 if (!sspi_GetAuthIdentityUserDomainW(srcIdentity, &UserW, &UserLength, &DomainW, &DomainLength))
889 if (!sspi_GetAuthIdentityPasswordW(srcIdentity, &PasswordW, &PasswordLength))
895 identity->UserLength = UserLength;
897 if (identity->UserLength > 0)
899 identity->User = (UINT16*)calloc((identity->UserLength + 1),
sizeof(WCHAR));
904 CopyMemory(identity->User, UserW, identity->UserLength *
sizeof(WCHAR));
905 identity->User[identity->UserLength] = 0;
908 identity->DomainLength = DomainLength;
910 if (identity->DomainLength > 0)
912 identity->Domain = (UINT16*)calloc((identity->DomainLength + 1),
sizeof(WCHAR));
914 if (!identity->Domain)
917 CopyMemory(identity->Domain, DomainW, identity->DomainLength *
sizeof(WCHAR));
918 identity->Domain[identity->DomainLength] = 0;
921 identity->PasswordLength = PasswordLength;
925 identity->Password = (UINT16*)calloc((identity->PasswordLength + 1),
sizeof(WCHAR));
927 if (!identity->Password)
930 CopyMemory(identity->Password, PasswordW, identity->PasswordLength *
sizeof(WCHAR));
931 identity->Password[identity->PasswordLength] = 0;
942 for (UINT32 index = 0; index < pMessage->cBuffers; index++)
944 if (pMessage->pBuffers[index].BufferType == BufferType)
946 pSecBuffer = &pMessage->pBuffers[index];
954static BOOL WINPR_init(
void)
957 for (
size_t x = 0; x < ARRAYSIZE(SecurityFunctionTableA_NAME_LIST); x++)
959 const SecurityFunctionTableA_NAME* cur = &SecurityFunctionTableA_NAME_LIST[x];
960 InitializeConstWCharFromUtf8(cur->Name, BUFFER_NAME_LIST_W[x],
961 ARRAYSIZE(BUFFER_NAME_LIST_W[x]));
966static BOOL CALLBACK sspi_init(WINPR_ATTR_UNUSED
PINIT_ONCE InitOnce,
967 WINPR_ATTR_UNUSED PVOID Parameter, WINPR_ATTR_UNUSED PVOID* Context)
969 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
971 sspi_ContextBufferAllocTableNew();
972 if (!SCHANNEL_init())
974 if (!KERBEROS_init())
980 if (!NEGOTIATE_init())
985void sspi_GlobalInit(
void)
987 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
989 if (!InitOnceExecuteOnce(&once, sspi_init, &flags,
nullptr))
990 WLog_ERR(TAG,
"InitOnceExecuteOnce failed");
993void sspi_GlobalFinish(
void)
995 sspi_ContextBufferAllocTableFree();
1000 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1002 for (
size_t index = 0; index < cPackages; index++)
1004 if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
1006 return SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
1015 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1017 for (
size_t index = 0; index < cPackages; index++)
1019 if (_wcscmp(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
1021 return SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
1030 SEC_WCHAR* NameW =
nullptr;
1036 NameW = ConvertUtf8ToWCharAlloc(Name,
nullptr);
1041 table = sspi_GetSecurityFunctionTableWByNameW(NameW);
1046static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer);
1047static void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer);
1049void sspi_ContextBufferFree(
void* contextBuffer)
1051 UINT32 allocatorIndex = 0;
1053 for (
size_t index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
1055 if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
1057 contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
1058 allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
1059 ContextBufferAllocTable.cEntries--;
1060 ContextBufferAllocTable.entries[index].allocatorIndex = 0;
1061 ContextBufferAllocTable.entries[index].contextBuffer =
nullptr;
1063 switch (allocatorIndex)
1065 case EnumerateSecurityPackagesIndex:
1066 FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
1069 case QuerySecurityPackageInfoIndex:
1070 FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
1085static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages,
1088 const size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1089 const size_t size =
sizeof(
SecPkgInfoW) * cPackages;
1091 (
SecPkgInfoW*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1093 WINPR_ASSERT(cPackages <= UINT32_MAX);
1096 return SEC_E_INSUFFICIENT_MEMORY;
1098 for (
size_t index = 0; index < cPackages; index++)
1100 pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1101 pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
1102 pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1103 pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1104 pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1105 pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1108 *(pcPackages) = (UINT32)cPackages;
1109 *(ppPackageInfo) = pPackageInfo;
1113static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages,
1116 const size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1117 const size_t size =
sizeof(
SecPkgInfoA) * cPackages;
1119 (
SecPkgInfoA*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1121 WINPR_ASSERT(cPackages <= UINT32_MAX);
1124 return SEC_E_INSUFFICIENT_MEMORY;
1126 for (
size_t index = 0; index < cPackages; index++)
1128 pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1129 pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
1130 pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1131 pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1132 pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1133 pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1135 if (!pPackageInfo[index].Name || !pPackageInfo[index].Comment)
1137 sspi_ContextBufferFree(pPackageInfo);
1138 return SEC_E_INSUFFICIENT_MEMORY;
1142 *(pcPackages) = (UINT32)cPackages;
1143 *(ppPackageInfo) = pPackageInfo;
1147static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer)
1150 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1155 for (
size_t index = 0; index < cPackages; index++)
1157 free(pPackageInfo[index].Name);
1158 free(pPackageInfo[index].Comment);
1164static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
1167 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1169 for (
size_t index = 0; index < cPackages; index++)
1171 if (_wcscmp(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
1175 (
SecPkgInfoW*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1178 return SEC_E_INSUFFICIENT_MEMORY;
1180 pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1181 pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
1182 pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1183 pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1184 pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1185 pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1186 *(ppPackageInfo) = pPackageInfo;
1191 *(ppPackageInfo) =
nullptr;
1192 return SEC_E_SECPKG_NOT_FOUND;
1195static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
1198 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1200 for (
size_t index = 0; index < cPackages; index++)
1202 if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
1206 (
SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1209 return SEC_E_INSUFFICIENT_MEMORY;
1211 pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1212 pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
1213 pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1214 pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1215 pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1216 pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1218 if (!pPackageInfo->Name || !pPackageInfo->Comment)
1220 sspi_ContextBufferFree(pPackageInfo);
1221 return SEC_E_INSUFFICIENT_MEMORY;
1224 *(ppPackageInfo) = pPackageInfo;
1229 *(ppPackageInfo) =
nullptr;
1230 return SEC_E_SECPKG_NOT_FOUND;
1233void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer)
1235 SecPkgInfo* pPackageInfo = (SecPkgInfo*)contextBuffer;
1240 free(pPackageInfo->Name);
1241 free(pPackageInfo->Comment);
1245#define log_status(what, status) log_status_((what), (status), __FILE__, __func__, __LINE__)
1246static SECURITY_STATUS log_status_(
const char* what, SECURITY_STATUS status,
const char* file,
1247 const char* fkt,
size_t line)
1249 if (IsSecurityStatusError(status))
1251 const DWORD level = WLOG_WARN;
1252 static wLog* log =
nullptr;
1254 log = WLog_Get(TAG);
1256 if (WLog_IsLevelActive(log, level))
1258 WLog_PrintTextMessage(log, level, line, file, fkt,
"%s status %s [0x%08" PRIx32
"]",
1259 what, GetSecurityStatusString(status),
1260 WINPR_CXX_COMPAT_CAST(uint32_t, status));
1268static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(
1269 SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1270 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1273 SECURITY_STATUS status = 0;
1277 return SEC_E_SECPKG_NOT_FOUND;
1279 if (!table->AcquireCredentialsHandleW)
1281 WLog_WARN(TAG,
"Security module does not provide an implementation");
1282 return SEC_E_UNSUPPORTED_FUNCTION;
1285 status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
1286 pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
1288 return log_status(
"AcquireCredentialsHandleW", status);
1291static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(
1292 SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1293 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1296 SECURITY_STATUS status = 0;
1300 return SEC_E_SECPKG_NOT_FOUND;
1302 if (!table->AcquireCredentialsHandleA)
1304 WLog_WARN(TAG,
"Security module does not provide an implementation");
1305 return SEC_E_UNSUPPORTED_FUNCTION;
1308 status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
1309 pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
1311 return log_status(
"AcquireCredentialsHandleA", status);
1314static SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(
PCtxtHandle phContext, ULONG fFlags,
1318 SEC_CHAR* Name =
nullptr;
1319 SECURITY_STATUS status = 0;
1321 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1324 return SEC_E_SECPKG_NOT_FOUND;
1326 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1329 return SEC_E_SECPKG_NOT_FOUND;
1331 if (!table->ExportSecurityContext)
1333 WLog_WARN(TAG,
"Security module does not provide an implementation");
1334 return SEC_E_UNSUPPORTED_FUNCTION;
1337 status = table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
1338 return log_status(
"ExportSecurityContext", status);
1341static SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(
PCredHandle phCredential)
1343 char* Name =
nullptr;
1344 SECURITY_STATUS status = 0;
1346 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1349 return SEC_E_SECPKG_NOT_FOUND;
1351 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1354 return SEC_E_SECPKG_NOT_FOUND;
1356 if (!table->FreeCredentialsHandle)
1358 WLog_WARN(TAG,
"Security module does not provide an implementation");
1359 return SEC_E_UNSUPPORTED_FUNCTION;
1362 status = table->FreeCredentialsHandle(phCredential);
1363 return log_status(
"FreeCredentialsHandle", status);
1366static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage,
1370 SEC_CHAR* Name =
nullptr;
1371 SECURITY_STATUS status = 0;
1373 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1376 return SEC_E_SECPKG_NOT_FOUND;
1378 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1381 return SEC_E_SECPKG_NOT_FOUND;
1383 if (!table->ImportSecurityContextW)
1385 WLog_WARN(TAG,
"Security module does not provide an implementation");
1386 return SEC_E_UNSUPPORTED_FUNCTION;
1389 status = table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
1390 return log_status(
"ImportSecurityContextW", status);
1393static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage,
1397 char* Name =
nullptr;
1398 SECURITY_STATUS status = 0;
1400 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1403 return SEC_E_SECPKG_NOT_FOUND;
1405 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1408 return SEC_E_SECPKG_NOT_FOUND;
1410 if (!table->ImportSecurityContextA)
1412 WLog_WARN(TAG,
"Security module does not provide an implementation");
1413 return SEC_E_UNSUPPORTED_FUNCTION;
1416 status = table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
1417 return log_status(
"ImportSecurityContextA", status);
1420static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(
PCredHandle phCredential,
1421 ULONG ulAttribute,
void* pBuffer)
1423 SEC_WCHAR* Name =
nullptr;
1424 SECURITY_STATUS status = 0;
1426 Name = (SEC_WCHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1429 return SEC_E_SECPKG_NOT_FOUND;
1431 table = sspi_GetSecurityFunctionTableWByNameW(Name);
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 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)
1449 char* Name =
nullptr;
1450 SECURITY_STATUS status = 0;
1452 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1455 return SEC_E_SECPKG_NOT_FOUND;
1457 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1460 return SEC_E_SECPKG_NOT_FOUND;
1462 if (!table->QueryCredentialsAttributesA)
1464 WLog_WARN(TAG,
"Security module does not provide an implementation");
1465 return SEC_E_UNSUPPORTED_FUNCTION;
1468 status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
1469 return log_status(
"QueryCredentialsAttributesA", status);
1472static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesW(
PCredHandle phCredential,
1473 ULONG ulAttribute,
void* pBuffer,
1476 SEC_WCHAR* Name =
nullptr;
1477 SECURITY_STATUS status = 0;
1479 Name = (SEC_WCHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1482 return SEC_E_SECPKG_NOT_FOUND;
1484 table = sspi_GetSecurityFunctionTableWByNameW(Name);
1487 return SEC_E_SECPKG_NOT_FOUND;
1489 if (!table->SetCredentialsAttributesW)
1491 WLog_WARN(TAG,
"Security module does not provide an implementation");
1492 return SEC_E_UNSUPPORTED_FUNCTION;
1495 status = table->SetCredentialsAttributesW(phCredential, ulAttribute, pBuffer, cbBuffer);
1496 return log_status(
"SetCredentialsAttributesW", status);
1499static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesA(
PCredHandle phCredential,
1500 ULONG ulAttribute,
void* pBuffer,
1503 char* Name =
nullptr;
1504 SECURITY_STATUS status = 0;
1506 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1509 return SEC_E_SECPKG_NOT_FOUND;
1511 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1514 return SEC_E_SECPKG_NOT_FOUND;
1516 if (!table->SetCredentialsAttributesA)
1518 WLog_WARN(TAG,
"Security module does not provide an implementation");
1519 return SEC_E_UNSUPPORTED_FUNCTION;
1522 status = table->SetCredentialsAttributesA(phCredential, ulAttribute, pBuffer, cbBuffer);
1523 return log_status(
"SetCredentialsAttributesA", status);
1528static SECURITY_STATUS SEC_ENTRY
1530 ULONG fContextReq, ULONG TargetDataRep,
PCtxtHandle phNewContext,
1533 char* Name =
nullptr;
1534 SECURITY_STATUS status = 0;
1536 Name = (
char*)sspi_SecureHandleGetUpperPointer(phCredential);
1539 return SEC_E_SECPKG_NOT_FOUND;
1541 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1544 return SEC_E_SECPKG_NOT_FOUND;
1546 if (!table->AcceptSecurityContext)
1548 WLog_WARN(TAG,
"Security module does not provide an implementation");
1549 return SEC_E_UNSUPPORTED_FUNCTION;
1553 table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
1554 phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
1555 return log_status(
"AcceptSecurityContext", status);
1558static SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(
PCtxtHandle phContext,
1561 char* Name =
nullptr;
1562 SECURITY_STATUS status = 0;
1564 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1567 return SEC_E_SECPKG_NOT_FOUND;
1569 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1572 return SEC_E_SECPKG_NOT_FOUND;
1574 if (!table->ApplyControlToken)
1576 WLog_WARN(TAG,
"Security module does not provide an implementation");
1577 return SEC_E_UNSUPPORTED_FUNCTION;
1580 status = table->ApplyControlToken(phContext, pInput);
1581 return log_status(
"ApplyControlToken", status);
1584static SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(
PCtxtHandle phContext,
1587 char* Name =
nullptr;
1588 SECURITY_STATUS status = 0;
1590 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1593 return SEC_E_SECPKG_NOT_FOUND;
1595 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1598 return SEC_E_SECPKG_NOT_FOUND;
1600 if (!table->CompleteAuthToken)
1602 WLog_WARN(TAG,
"Security module does not provide an implementation");
1603 return SEC_E_UNSUPPORTED_FUNCTION;
1606 status = table->CompleteAuthToken(phContext, pToken);
1607 return log_status(
"CompleteAuthToken", status);
1610static SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(
PCtxtHandle phContext)
1612 const char* Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1615 return SEC_E_SECPKG_NOT_FOUND;
1620 return SEC_E_SECPKG_NOT_FOUND;
1622 if (!table->DeleteSecurityContext)
1624 WLog_WARN(TAG,
"Security module does not provide an implementation");
1625 return SEC_E_UNSUPPORTED_FUNCTION;
1628 const SECURITY_STATUS status = table->DeleteSecurityContext(phContext);
1629 return log_status(
"DeleteSecurityContext", status);
1632static SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(
void* pvContextBuffer)
1634 if (!pvContextBuffer)
1635 return SEC_E_INVALID_HANDLE;
1637 sspi_ContextBufferFree(pvContextBuffer);
1641static SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(
PCtxtHandle phContext)
1643 SEC_CHAR* Name =
nullptr;
1644 SECURITY_STATUS status = 0;
1646 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1649 return SEC_E_SECPKG_NOT_FOUND;
1651 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1654 return SEC_E_SECPKG_NOT_FOUND;
1656 if (!table->ImpersonateSecurityContext)
1658 WLog_WARN(TAG,
"Security module does not provide an implementation");
1659 return SEC_E_UNSUPPORTED_FUNCTION;
1662 status = table->ImpersonateSecurityContext(phContext);
1663 return log_status(
"ImpersonateSecurityContext", status);
1666static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(
1668 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1671 SEC_CHAR* Name =
nullptr;
1672 SECURITY_STATUS status = 0;
1674 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1677 return SEC_E_SECPKG_NOT_FOUND;
1679 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1682 return SEC_E_SECPKG_NOT_FOUND;
1684 if (!table->InitializeSecurityContextW)
1686 WLog_WARN(TAG,
"Security module does not provide an implementation");
1687 return SEC_E_UNSUPPORTED_FUNCTION;
1690 status = table->InitializeSecurityContextW(phCredential, phContext, pszTargetName, fContextReq,
1691 Reserved1, TargetDataRep, pInput, Reserved2,
1692 phNewContext, pOutput, pfContextAttr, ptsExpiry);
1693 return log_status(
"InitializeSecurityContextW", status);
1696static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(
1698 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1701 SEC_CHAR* Name =
nullptr;
1702 SECURITY_STATUS status = 0;
1704 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
1707 return SEC_E_SECPKG_NOT_FOUND;
1709 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1712 return SEC_E_SECPKG_NOT_FOUND;
1714 if (!table->InitializeSecurityContextA)
1716 WLog_WARN(TAG,
"Security module does not provide an implementation");
1717 return SEC_E_UNSUPPORTED_FUNCTION;
1720 status = table->InitializeSecurityContextA(phCredential, phContext, pszTargetName, fContextReq,
1721 Reserved1, TargetDataRep, pInput, Reserved2,
1722 phNewContext, pOutput, pfContextAttr, ptsExpiry);
1724 return log_status(
"InitializeSecurityContextA", status);
1727static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(
PCtxtHandle phContext,
1728 ULONG ulAttribute,
void* pBuffer)
1730 SEC_CHAR* Name =
nullptr;
1731 SECURITY_STATUS status = 0;
1733 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1736 return SEC_E_SECPKG_NOT_FOUND;
1738 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1741 return SEC_E_SECPKG_NOT_FOUND;
1743 if (!table->QueryContextAttributesW)
1745 WLog_WARN(TAG,
"Security module does not provide an implementation");
1746 return SEC_E_UNSUPPORTED_FUNCTION;
1749 status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
1750 return log_status(
"QueryContextAttributesW", status);
1753static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(
PCtxtHandle phContext,
1754 ULONG ulAttribute,
void* pBuffer)
1756 SEC_CHAR* Name =
nullptr;
1757 SECURITY_STATUS status = 0;
1759 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1762 return SEC_E_SECPKG_NOT_FOUND;
1764 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1767 return SEC_E_SECPKG_NOT_FOUND;
1769 if (!table->QueryContextAttributesA)
1771 WLog_WARN(TAG,
"Security module does not provide an implementation");
1772 return SEC_E_UNSUPPORTED_FUNCTION;
1775 status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
1776 return log_status(
"QueryContextAttributesA", status);
1779static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(
PCtxtHandle phContext,
1782 SEC_CHAR* Name =
nullptr;
1783 SECURITY_STATUS status = 0;
1785 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1788 return SEC_E_SECPKG_NOT_FOUND;
1790 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1793 return SEC_E_SECPKG_NOT_FOUND;
1795 if (!table->QuerySecurityContextToken)
1797 WLog_WARN(TAG,
"Security module does not provide an implementation");
1798 return SEC_E_UNSUPPORTED_FUNCTION;
1801 status = table->QuerySecurityContextToken(phContext, phToken);
1802 return log_status(
"QuerySecurityContextToken", status);
1805static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(
PCtxtHandle phContext,
1806 ULONG ulAttribute,
void* pBuffer,
1809 SEC_CHAR* Name =
nullptr;
1810 SECURITY_STATUS status = 0;
1812 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1815 return SEC_E_SECPKG_NOT_FOUND;
1817 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1820 return SEC_E_SECPKG_NOT_FOUND;
1822 if (!table->SetContextAttributesW)
1824 WLog_WARN(TAG,
"Security module does not provide an implementation");
1825 return SEC_E_UNSUPPORTED_FUNCTION;
1828 status = table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
1829 return log_status(
"SetContextAttributesW", status);
1832static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(
PCtxtHandle phContext,
1833 ULONG ulAttribute,
void* pBuffer,
1836 char* Name =
nullptr;
1837 SECURITY_STATUS status = 0;
1839 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1842 return SEC_E_SECPKG_NOT_FOUND;
1844 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1847 return SEC_E_SECPKG_NOT_FOUND;
1849 if (!table->SetContextAttributesA)
1851 WLog_WARN(TAG,
"Security module does not provide an implementation");
1852 return SEC_E_UNSUPPORTED_FUNCTION;
1855 status = table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
1856 return log_status(
"SetContextAttributesA", status);
1859static SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(
PCtxtHandle phContext)
1861 SEC_CHAR* Name =
nullptr;
1862 SECURITY_STATUS status = 0;
1864 Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
1867 return SEC_E_SECPKG_NOT_FOUND;
1869 table = sspi_GetSecurityFunctionTableWByNameA(Name);
1872 return SEC_E_SECPKG_NOT_FOUND;
1874 if (!table->RevertSecurityContext)
1876 WLog_WARN(TAG,
"Security module does not provide an implementation");
1877 return SEC_E_UNSUPPORTED_FUNCTION;
1880 status = table->RevertSecurityContext(phContext);
1882 return log_status(
"RevertSecurityContext", status);
1887static SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(
PCtxtHandle phContext,
1891 char* Name =
nullptr;
1892 SECURITY_STATUS status = 0;
1894 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1897 return SEC_E_SECPKG_NOT_FOUND;
1899 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1902 return SEC_E_SECPKG_NOT_FOUND;
1904 if (!table->DecryptMessage)
1906 WLog_WARN(TAG,
"Security module does not provide an implementation");
1907 return SEC_E_UNSUPPORTED_FUNCTION;
1910 status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
1912 return log_status(
"DecryptMessage", status);
1915static SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(
PCtxtHandle phContext, ULONG fQOP,
1918 char* Name =
nullptr;
1919 SECURITY_STATUS status = 0;
1921 Name = (
char*)sspi_SecureHandleGetUpperPointer(phContext);
1924 return SEC_E_SECPKG_NOT_FOUND;
1926 table = sspi_GetSecurityFunctionTableAByNameA(Name);
1929 return SEC_E_SECPKG_NOT_FOUND;
1931 if (!table->EncryptMessage)
1933 WLog_WARN(TAG,
"Security module does not provide an implementation");
1934 return SEC_E_UNSUPPORTED_FUNCTION;
1937 status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
1938 return log_status(
"EncryptMessage", status);
1941static SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(
PCtxtHandle phContext, ULONG fQOP,
1944 SECURITY_STATUS status = 0;
1945 const char* Name = (
const char*)sspi_SecureHandleGetUpperPointer(phContext);
1948 return SEC_E_SECPKG_NOT_FOUND;
1953 return SEC_E_SECPKG_NOT_FOUND;
1955 if (!table->MakeSignature)
1957 WLog_WARN(TAG,
"Security module does not provide an implementation");
1958 return SEC_E_UNSUPPORTED_FUNCTION;
1961 status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
1962 return log_status(
"MakeSignature", status);
1965static SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(
PCtxtHandle phContext,
1969 SECURITY_STATUS status = 0;
1971 const char* Name = (
const char*)sspi_SecureHandleGetUpperPointer(phContext);
1974 return SEC_E_SECPKG_NOT_FOUND;
1979 return SEC_E_SECPKG_NOT_FOUND;
1981 if (!table->VerifySignature)
1983 WLog_WARN(TAG,
"Security module does not provide an implementation");
1984 return SEC_E_UNSUPPORTED_FUNCTION;
1987 status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1989 return log_status(
"VerifySignature", status);
1994 winpr_EnumerateSecurityPackagesA,
1995 winpr_QueryCredentialsAttributesA,
1996 winpr_AcquireCredentialsHandleA,
1997 winpr_FreeCredentialsHandle,
1999 winpr_InitializeSecurityContextA,
2000 winpr_AcceptSecurityContext,
2001 winpr_CompleteAuthToken,
2002 winpr_DeleteSecurityContext,
2003 winpr_ApplyControlToken,
2004 winpr_QueryContextAttributesA,
2005 winpr_ImpersonateSecurityContext,
2006 winpr_RevertSecurityContext,
2007 winpr_MakeSignature,
2008 winpr_VerifySignature,
2009 winpr_FreeContextBuffer,
2010 winpr_QuerySecurityPackageInfoA,
2013 winpr_ExportSecurityContext,
2014 winpr_ImportSecurityContextA,
2017 winpr_QuerySecurityContextToken,
2018 winpr_EncryptMessage,
2019 winpr_DecryptMessage,
2020 winpr_SetContextAttributesA,
2021 winpr_SetCredentialsAttributesA,
2026 winpr_EnumerateSecurityPackagesW,
2027 winpr_QueryCredentialsAttributesW,
2028 winpr_AcquireCredentialsHandleW,
2029 winpr_FreeCredentialsHandle,
2031 winpr_InitializeSecurityContextW,
2032 winpr_AcceptSecurityContext,
2033 winpr_CompleteAuthToken,
2034 winpr_DeleteSecurityContext,
2035 winpr_ApplyControlToken,
2036 winpr_QueryContextAttributesW,
2037 winpr_ImpersonateSecurityContext,
2038 winpr_RevertSecurityContext,
2039 winpr_MakeSignature,
2040 winpr_VerifySignature,
2041 winpr_FreeContextBuffer,
2042 winpr_QuerySecurityPackageInfoW,
2045 winpr_ExportSecurityContext,
2046 winpr_ImportSecurityContextW,
2049 winpr_QuerySecurityContextToken,
2050 winpr_EncryptMessage,
2051 winpr_DecryptMessage,
2052 winpr_SetContextAttributesW,
2053 winpr_SetCredentialsAttributesW,
2058 return &winpr_SecurityFunctionTableW;
2063 return &winpr_SecurityFunctionTableA;