21#include <winpr/config.h>
22#include <winpr/assert.h>
23#include <winpr/windows.h>
26#include <winpr/synch.h>
27#include <winpr/sspi.h>
29#include <winpr/print.h>
33#include "sspi_winpr.h"
37#define TAG WINPR_TAG("sspi")
42#include "NTLM/ntlm_export.h"
43#include "CredSSP/credssp.h"
44#include "Kerberos/kerberos.h"
45#include "Negotiate/negotiate.h"
46#include "Schannel/schannel.h"
48static const SecPkgInfoA* SecPkgInfoA_LIST[] = { &NTLM_SecPkgInfoA, &KERBEROS_SecPkgInfoA,
49 &NEGOTIATE_SecPkgInfoA, &CREDSSP_SecPkgInfoA,
50 &SCHANNEL_SecPkgInfoA };
52static const SecPkgInfoW* SecPkgInfoW_LIST[] = { &NTLM_SecPkgInfoW, &KERBEROS_SecPkgInfoW,
53 &NEGOTIATE_SecPkgInfoW, &CREDSSP_SecPkgInfoW,
54 &SCHANNEL_SecPkgInfoW };
60} SecurityFunctionTableA_NAME;
64 const SEC_WCHAR* Name;
66} SecurityFunctionTableW_NAME;
68static const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] = {
69 {
"NTLM", &NTLM_SecurityFunctionTableA },
70 {
"Kerberos", &KERBEROS_SecurityFunctionTableA },
71 {
"Negotiate", &NEGOTIATE_SecurityFunctionTableA },
72 {
"CREDSSP", &CREDSSP_SecurityFunctionTableA },
73 {
"Schannel", &SCHANNEL_SecurityFunctionTableA }
76static WCHAR BUFFER_NAME_LIST_W[5][32] = WINPR_C_ARRAY_INIT;
78static const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] = {
79 { BUFFER_NAME_LIST_W[0], &NTLM_SecurityFunctionTableW },
80 { BUFFER_NAME_LIST_W[1], &KERBEROS_SecurityFunctionTableW },
81 { BUFFER_NAME_LIST_W[2], &NEGOTIATE_SecurityFunctionTableW },
82 { BUFFER_NAME_LIST_W[3], &CREDSSP_SecurityFunctionTableW },
83 { BUFFER_NAME_LIST_W[4], &SCHANNEL_SecurityFunctionTableW }
89 UINT32 allocatorIndex;
90} CONTEXT_BUFFER_ALLOC_ENTRY;
96 CONTEXT_BUFFER_ALLOC_ENTRY* entries;
97} CONTEXT_BUFFER_ALLOC_TABLE;
99static CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable = WINPR_C_ARRAY_INIT;
104static int sspi_ContextBufferAllocTableNew(
void)
108 if (!InitializeCriticalSectionEx(&ContextBufferAllocTableLock, 0, 0))
111 ContextBufferAllocTable.entries =
nullptr;
112 ContextBufferAllocTable.cEntries = 0;
113 ContextBufferAllocTable.cMaxEntries = 4;
114 size =
sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
115 ContextBufferAllocTable.entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)calloc(1, size);
117 if (!ContextBufferAllocTable.entries)
119 DeleteCriticalSection(&ContextBufferAllocTableLock);
127static int sspi_ContextBufferAllocTableGrow(
void)
130 CONTEXT_BUFFER_ALLOC_ENTRY* entries =
nullptr;
131 const UINT32 cMaxEntries = ContextBufferAllocTable.cMaxEntries + 128ull;
132 size =
sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * cMaxEntries;
137 entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)realloc(ContextBufferAllocTable.entries, size);
143 ContextBufferAllocTable.cMaxEntries = cMaxEntries;
144 ContextBufferAllocTable.entries = entries;
145 ZeroMemory((
void*)&ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2],
150static void sspi_ContextBufferAllocTableFree(
void)
152 if (ContextBufferAllocTable.cEntries != 0)
153 WLog_ERR(TAG,
"ContextBufferAllocTable.entries == %" PRIu32,
154 ContextBufferAllocTable.cEntries);
156 ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
157 free(ContextBufferAllocTable.entries);
158 ContextBufferAllocTable.entries =
nullptr;
159 DeleteCriticalSection(&ContextBufferAllocTableLock);
163static void* sspi_ContextBufferAllocLocked(UINT32 allocatorIndex,
size_t size)
165 void* contextBuffer =
nullptr;
167 for (UINT32 index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
169 if (!ContextBufferAllocTable.entries[index].contextBuffer)
171 contextBuffer = calloc(1, size);
176 ContextBufferAllocTable.cEntries++;
177 ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
178 ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
179 return ContextBufferAllocTable.entries[index].contextBuffer;
185 if (sspi_ContextBufferAllocTableGrow() < 0)
189 return sspi_ContextBufferAllocLocked(allocatorIndex, size);
192void* sspi_ContextBufferAlloc(UINT32 allocatorIndex,
size_t size)
194 EnterCriticalSection(&ContextBufferAllocTableLock);
195 void* contextBuffer = sspi_ContextBufferAllocLocked(allocatorIndex, size);
196 LeaveCriticalSection(&ContextBufferAllocTableLock);
197 return contextBuffer;
206 credentials->ntlmSettingsV2 = sspi_AllocSecNtlmSettings();
207 if (!credentials->ntlmSettingsV2)
209 sspi_CredentialsFree(credentials);
221 size_t userLength = credentials->identity.UserLength;
222 size_t domainLength = credentials->identity.DomainLength;
223 size_t passwordLength = credentials->identity.PasswordLength;
225 if (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
232 if (credentials->identity.User)
233 memset(credentials->identity.User, 0, userLength);
234 if (credentials->identity.Domain)
235 memset(credentials->identity.Domain, 0, domainLength);
236 if (credentials->identity.Password)
237 memset(credentials->identity.Password, 0, passwordLength);
238 free(credentials->identity.User);
239 free(credentials->identity.Domain);
240 free(credentials->identity.Password);
241 sspi_FreeSecNtlmSettings(credentials->ntlmSettingsV2);
280 SecInvalidateHandle(handle);
284void* sspi_SecureHandleGetLowerPointer(
SecHandle* handle)
286 void* pointer =
nullptr;
288 if (!handle || !SecIsValidHandle(handle) || !handle->dwLower)
291 pointer = (
void*)~((
size_t)handle->dwLower);
295void sspi_SecureHandleInvalidate(
SecHandle* handle)
304void sspi_SecureHandleSetLowerPointer(
SecHandle* handle,
void* pointer)
309 handle->dwLower = (ULONG_PTR)(~((
size_t)pointer));
312void* sspi_SecureHandleGetUpperPointer(
SecHandle* handle)
314 void* pointer =
nullptr;
316 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
319 pointer = (
void*)~((
size_t)handle->dwUpper);
323void sspi_SecureHandleSetUpperPointer(
SecHandle* handle,
void* pointer)
328 handle->dwUpper = (ULONG_PTR)(~((
size_t)pointer));
331SSPI_PACKAGE_ID sspi_SecureHandleGetPackageId(
SecHandle* handle)
333 if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
334 return SSPI_PACKAGE_NONE;
336 return (SSPI_PACKAGE_ID)(~((size_t)handle->dwUpper));
339void sspi_SecureHandleSetPackageId(
SecHandle* handle, SSPI_PACKAGE_ID
id)
344 handle->dwUpper = (ULONG_PTR)(~((
size_t)
id));
347void sspi_SecureHandleFree(
SecHandle* handle)
352int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
const WCHAR* domain,
353 const WCHAR* password)
355 return sspi_SetAuthIdentityWithLengthW(identity, user, user ? _wcslen(user) : 0, domain,
356 domain ? _wcslen(domain) : 0, password,
357 password ? _wcslen(password) : 0);
360static BOOL copy(WCHAR** dst, ULONG* dstLen,
const WCHAR* what,
size_t len)
363 WINPR_ASSERT(dstLen);
368 if (len > UINT32_MAX)
372 if (!what && (len != 0))
374 if (!what && (len == 0))
377 *dst = calloc(
sizeof(WCHAR), len + 1);
381 memcpy(*dst, what, len *
sizeof(WCHAR));
382 *dstLen = WINPR_ASSERTING_INT_CAST(UINT32, len);
386int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity,
const WCHAR* user,
387 size_t userLen,
const WCHAR* domain,
size_t domainLen,
388 const WCHAR* password,
size_t passwordLen)
390 WINPR_ASSERT(identity);
391 sspi_FreeAuthIdentity(identity);
392 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
393 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
395 if (!copy(&identity->User, &identity->UserLength, user, userLen))
398 if (!copy(&identity->Domain, &identity->DomainLength, domain, domainLen))
401 if (!copy(&identity->Password, &identity->PasswordLength, password, passwordLen))
407int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity,
const char* user,
const char* domain,
408 const char* password)
411 size_t unicodeUserLenW = 0;
412 size_t unicodeDomainLenW = 0;
413 size_t unicodePasswordLenW = 0;
414 LPWSTR unicodeUser =
nullptr;
415 LPWSTR unicodeDomain =
nullptr;
416 LPWSTR unicodePassword =
nullptr;
419 unicodeUser = ConvertUtf8ToWCharAlloc(user, &unicodeUserLenW);
422 unicodeDomain = ConvertUtf8ToWCharAlloc(domain, &unicodeDomainLenW);
425 unicodePassword = ConvertUtf8ToWCharAlloc(password, &unicodePasswordLenW);
427 rc = sspi_SetAuthIdentityWithLengthW(identity, unicodeUser, unicodeUserLenW, unicodeDomain,
428 unicodeDomainLenW, unicodePassword, unicodePasswordLenW);
430 winpr_znfree(unicodeUser, unicodeUserLenW *
sizeof(WCHAR));
431 winpr_znfree(unicodeDomain, unicodeDomainLenW *
sizeof(WCHAR));
432 winpr_znfree(unicodePassword, unicodePasswordLenW *
sizeof(WCHAR));
436UINT32 sspi_GetAuthIdentityVersion(
const void* identity)
443 version = *((
const UINT32*)identity);
445 if ((version == SEC_WINNT_AUTH_IDENTITY_VERSION) ||
446 (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2))
454UINT32 sspi_GetAuthIdentityFlags(
const void* identity)
462 version = sspi_GetAuthIdentityVersion(identity);
464 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
466 flags = ((
const SEC_WINNT_AUTH_IDENTITY_EX*)identity)->Flags;
468 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
474 flags = ((
const SEC_WINNT_AUTH_IDENTITY*)identity)->Flags;
480BOOL sspi_GetAuthIdentityUserDomainW(
const void* identity,
const WCHAR** pUser, UINT32* pUserLength,
481 const WCHAR** pDomain, UINT32* pDomainLength)
488 version = sspi_GetAuthIdentityVersion(identity);
490 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
493 *pUser = (
const WCHAR*)id->User;
494 *pUserLength =
id->UserLength;
495 *pDomain = (
const WCHAR*)id->Domain;
496 *pDomainLength =
id->DomainLength;
498 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
501 UINT32 UserOffset =
id->UserOffset;
502 UINT32 DomainOffset =
id->DomainOffset;
503 *pUser = WINPR_PACKED_ALIGN_CAST(
const WCHAR*, &((
const uint8_t*)identity)[UserOffset]);
504 *pUserLength =
id->UserLength / 2;
505 *pDomain = WINPR_PACKED_ALIGN_CAST(
const WCHAR*, &((
const uint8_t*)identity)[DomainOffset]);
506 *pDomainLength =
id->DomainLength / 2;
511 *pUser = (
const WCHAR*)id->User;
512 *pUserLength =
id->UserLength;
513 *pDomain = (
const WCHAR*)id->Domain;
514 *pDomainLength =
id->DomainLength;
520BOOL sspi_GetAuthIdentityUserDomainA(
const void* identity,
const char** pUser, UINT32* pUserLength,
521 const char** pDomain, UINT32* pDomainLength)
528 version = sspi_GetAuthIdentityVersion(identity);
530 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
533 *pUser = (
const char*)id->User;
534 *pUserLength =
id->UserLength;
535 *pDomain = (
const char*)id->Domain;
536 *pDomainLength =
id->DomainLength;
538 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
541 UINT32 UserOffset =
id->UserOffset;
542 UINT32 DomainOffset =
id->DomainOffset;
543 *pUser = (
const char*)&((
const uint8_t*)identity)[UserOffset];
544 *pUserLength =
id->UserLength;
545 *pDomain = (
const char*)&((
const uint8_t*)identity)[DomainOffset];
546 *pDomainLength =
id->DomainLength;
551 *pUser = (
const char*)id->User;
552 *pUserLength =
id->UserLength;
553 *pDomain = (
const char*)id->Domain;
554 *pDomainLength =
id->DomainLength;
560BOOL sspi_GetAuthIdentityPasswordW(
const void* identity,
const WCHAR** pPassword,
561 UINT32* pPasswordLength)
568 version = sspi_GetAuthIdentityVersion(identity);
570 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
573 *pPassword = (
const WCHAR*)id->Password;
574 *pPasswordLength =
id->PasswordLength;
576 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
583 *pPassword = (
const WCHAR*)id->Password;
584 *pPasswordLength =
id->PasswordLength;
590BOOL sspi_GetAuthIdentityPasswordA(
const void* identity,
const char** pPassword,
591 UINT32* pPasswordLength)
598 version = sspi_GetAuthIdentityVersion(identity);
600 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
603 *pPassword = (
const char*)id->Password;
604 *pPasswordLength =
id->PasswordLength;
606 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
613 *pPassword = (
const char*)id->Password;
614 *pPasswordLength =
id->PasswordLength;
621 char** pDomain,
char** pPassword)
623 BOOL success = FALSE;
624 const char* UserA =
nullptr;
625 const char* DomainA =
nullptr;
626 const char* PasswordA =
nullptr;
627 const WCHAR* UserW =
nullptr;
628 const WCHAR* DomainW =
nullptr;
629 const WCHAR* PasswordW =
nullptr;
630 UINT32 UserLength = 0;
631 UINT32 DomainLength = 0;
632 UINT32 PasswordLength = 0;
634 if (!identity || !pUser || !pDomain || !pPassword)
637 *pUser = *pDomain = *pPassword =
nullptr;
639 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
641 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
643 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
647 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
650 if (UserA && UserLength)
652 *pUser = _strdup(UserA);
658 if (DomainA && DomainLength)
660 *pDomain = _strdup(DomainA);
666 if (PasswordA && PasswordLength)
668 *pPassword = _strdup(PasswordA);
676 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
678 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
682 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
685 if (UserW && (UserLength > 0))
687 *pUser = ConvertWCharNToUtf8Alloc(UserW, UserLength,
nullptr);
692 if (DomainW && (DomainLength > 0))
694 *pDomain = ConvertWCharNToUtf8Alloc(DomainW, DomainLength,
nullptr);
699 if (PasswordW && (PasswordLength > 0))
701 *pPassword = ConvertWCharNToUtf8Alloc(PasswordW, PasswordLength,
nullptr);
714 WCHAR** pDomain, WCHAR** pPassword)
716 BOOL success = FALSE;
717 const char* UserA =
nullptr;
718 const char* DomainA =
nullptr;
719 const char* PasswordA =
nullptr;
720 const WCHAR* UserW =
nullptr;
721 const WCHAR* DomainW =
nullptr;
722 const WCHAR* PasswordW =
nullptr;
723 UINT32 UserLength = 0;
724 UINT32 DomainLength = 0;
725 UINT32 PasswordLength = 0;
727 if (!identity || !pUser || !pDomain || !pPassword)
730 *pUser = *pDomain = *pPassword =
nullptr;
732 UINT32 identityFlags = sspi_GetAuthIdentityFlags(identity);
734 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
736 if (!sspi_GetAuthIdentityUserDomainA(identity, &UserA, &UserLength, &DomainA,
740 if (!sspi_GetAuthIdentityPasswordA(identity, &PasswordA, &PasswordLength))
743 if (UserA && (UserLength > 0))
745 WCHAR* ptr = ConvertUtf8NToWCharAlloc(UserA, UserLength,
nullptr);
752 if (DomainA && (DomainLength > 0))
754 WCHAR* ptr = ConvertUtf8NToWCharAlloc(DomainA, DomainLength,
nullptr);
760 if (PasswordA && (PasswordLength > 0))
762 WCHAR* ptr = ConvertUtf8NToWCharAlloc(PasswordA, PasswordLength,
nullptr);
771 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
773 if (!sspi_GetAuthIdentityUserDomainW(identity, &UserW, &UserLength, &DomainW,
777 if (!sspi_GetAuthIdentityPasswordW(identity, &PasswordW, &PasswordLength))
780 if (UserW && UserLength)
782 *pUser = winpr_wcsndup(UserW, UserLength /
sizeof(WCHAR));
788 if (DomainW && DomainLength)
790 *pDomain = winpr_wcsndup(DomainW, DomainLength /
sizeof(WCHAR));
796 if (PasswordW && PasswordLength)
798 *pPassword = winpr_wcsndup(PasswordW, PasswordLength /
sizeof(WCHAR));
814 UINT32 identityFlags = 0;
815 char* PackageList =
nullptr;
816 const char* PackageListA =
nullptr;
817 const WCHAR* PackageListW =
nullptr;
818 UINT32 PackageListLength = 0;
819 UINT32 PackageListOffset = 0;
820 const void* pAuthData = (
const void*)identity;
825 version = sspi_GetAuthIdentityVersion(pAuthData);
826 identityFlags = sspi_GetAuthIdentityFlags(pAuthData);
828 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
830 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
833 PackageListA = (
const char*)ad->PackageList;
834 PackageListLength = ad->PackageListLength;
837 if (PackageListA && PackageListLength)
839 PackageList = _strdup(PackageListA);
842 else if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0)
844 if (version == SEC_WINNT_AUTH_IDENTITY_VERSION)
847 PackageListW = (
const WCHAR*)ad->PackageList;
848 PackageListLength = ad->PackageListLength;
850 else if (version == SEC_WINNT_AUTH_IDENTITY_VERSION_2)
853 PackageListOffset = ad->PackageListOffset;
854 PackageListW = WINPR_PACKED_ALIGN_CAST(
const WCHAR*,
855 &((
const uint8_t*)pAuthData)[PackageListOffset]);
856 PackageListLength = ad->PackageListLength / 2;
859 if (PackageListW && (PackageListLength > 0))
860 PackageList = ConvertWCharNToUtf8Alloc(PackageListW, PackageListLength,
nullptr);
865 *pPackageList = PackageList;
872int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity,
876 UINT32 identityFlags = 0;
877 const char* UserA =
nullptr;
878 const char* DomainA =
nullptr;
879 const char* PasswordA =
nullptr;
880 const WCHAR* UserW =
nullptr;
881 const WCHAR* DomainW =
nullptr;
882 const WCHAR* PasswordW =
nullptr;
883 UINT32 UserLength = 0;
884 UINT32 DomainLength = 0;
885 UINT32 PasswordLength = 0;
887 sspi_FreeAuthIdentity(identity);
889 identityFlags = sspi_GetAuthIdentityFlags(srcIdentity);
891 identity->Flags = identityFlags;
893 if ((identityFlags & SEC_WINNT_AUTH_IDENTITY_ANSI) != 0)
895 if (!sspi_GetAuthIdentityUserDomainA(srcIdentity, &UserA, &UserLength, &DomainA,
901 if (!sspi_GetAuthIdentityPasswordA(srcIdentity, &PasswordA, &PasswordLength))
906 status = sspi_SetAuthIdentity(identity, UserA, DomainA, PasswordA);
911 identity->Flags &= (uint32_t)~SEC_WINNT_AUTH_IDENTITY_ANSI;
912 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
916 identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
918 if (!sspi_GetAuthIdentityUserDomainW(srcIdentity, &UserW, &UserLength, &DomainW, &DomainLength))
923 if (!sspi_GetAuthIdentityPasswordW(srcIdentity, &PasswordW, &PasswordLength))
929 identity->UserLength = UserLength;
931 if (identity->UserLength > 0)
933 identity->User = (UINT16*)calloc((identity->UserLength + 1),
sizeof(WCHAR));
938 CopyMemory(identity->User, UserW, identity->UserLength *
sizeof(WCHAR));
939 identity->User[identity->UserLength] = 0;
942 identity->DomainLength = DomainLength;
944 if (identity->DomainLength > 0)
946 identity->Domain = (UINT16*)calloc((identity->DomainLength + 1),
sizeof(WCHAR));
948 if (!identity->Domain)
951 CopyMemory(identity->Domain, DomainW, identity->DomainLength *
sizeof(WCHAR));
952 identity->Domain[identity->DomainLength] = 0;
955 identity->PasswordLength = PasswordLength;
959 identity->Password = (UINT16*)calloc((identity->PasswordLength + 1),
sizeof(WCHAR));
961 if (!identity->Password)
964 CopyMemory(identity->Password, PasswordW, identity->PasswordLength *
sizeof(WCHAR));
965 identity->Password[identity->PasswordLength] = 0;
976 for (UINT32 index = 0; index < pMessage->cBuffers; index++)
978 if (pMessage->pBuffers[index].BufferType == BufferType)
980 pSecBuffer = &pMessage->pBuffers[index];
988static BOOL WINPR_init(
void)
991 for (
size_t x = 0; x < ARRAYSIZE(SecurityFunctionTableA_NAME_LIST); x++)
993 const SecurityFunctionTableA_NAME* cur = &SecurityFunctionTableA_NAME_LIST[x];
994 InitializeConstWCharFromUtf8(cur->Name, BUFFER_NAME_LIST_W[x],
995 ARRAYSIZE(BUFFER_NAME_LIST_W[x]));
1000static BOOL CALLBACK sspi_init(WINPR_ATTR_UNUSED
PINIT_ONCE InitOnce,
1001 WINPR_ATTR_UNUSED PVOID Parameter, WINPR_ATTR_UNUSED PVOID* Context)
1003 if (!winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT))
1005 if (sspi_ContextBufferAllocTableNew() < 0)
1007 if (!SCHANNEL_init())
1009 if (!KERBEROS_init())
1013 if (!CREDSSP_init())
1015 if (!NEGOTIATE_init())
1017 return WINPR_init();
1020void sspi_GlobalInit(
void)
1022 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
1029 WINPR_STATIC_ASSERT(ARRAYSIZE(SecPkgInfoA_LIST) == SSPI_PACKAGE_COUNT - 1);
1030 WINPR_STATIC_ASSERT(ARRAYSIZE(SecPkgInfoW_LIST) == SSPI_PACKAGE_COUNT - 1);
1031 WINPR_STATIC_ASSERT(ARRAYSIZE(SecurityFunctionTableA_NAME_LIST) == SSPI_PACKAGE_COUNT - 1);
1032 WINPR_STATIC_ASSERT(ARRAYSIZE(SecurityFunctionTableW_NAME_LIST) == SSPI_PACKAGE_COUNT - 1);
1033 WINPR_STATIC_ASSERT(ARRAYSIZE(BUFFER_NAME_LIST_W) == SSPI_PACKAGE_COUNT - 1);
1035 if (!InitOnceExecuteOnce(&once, sspi_init, &flags,
nullptr))
1036 WLog_ERR(TAG,
"InitOnceExecuteOnce failed");
1039void sspi_GlobalFinish(
void)
1041 sspi_ContextBufferAllocTableFree();
1046 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1048 for (
size_t index = 0; index < cPackages; index++)
1050 if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
1052 return SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
1061 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1063 for (
size_t index = 0; index < cPackages; index++)
1065 if (_wcscmp(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
1067 return SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
1078sspi_GetSecurityFunctionTableAByHandle(
SecHandle* handle)
1080 const SSPI_PACKAGE_ID
id = sspi_SecureHandleGetPackageId(handle);
1082 if ((
id < SSPI_PACKAGE_NTLM) || (
id > ARRAYSIZE(SecurityFunctionTableA_NAME_LIST)))
1085 return SecurityFunctionTableA_NAME_LIST[
id - 1].SecurityFunctionTable;
1089sspi_GetSecurityFunctionTableWByHandle(
SecHandle* handle)
1091 const SSPI_PACKAGE_ID
id = sspi_SecureHandleGetPackageId(handle);
1093 if ((
id < SSPI_PACKAGE_NTLM) || (
id > ARRAYSIZE(SecurityFunctionTableW_NAME_LIST)))
1096 return SecurityFunctionTableW_NAME_LIST[
id - 1].SecurityFunctionTable;
1099static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer);
1100static void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer);
1102void sspi_ContextBufferFree(
void* contextBuffer)
1104 UINT32 allocatorIndex = 0;
1106 EnterCriticalSection(&ContextBufferAllocTableLock);
1108 for (
size_t index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
1110 if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
1112 contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
1113 allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
1114 ContextBufferAllocTable.cEntries--;
1115 ContextBufferAllocTable.entries[index].allocatorIndex = 0;
1116 ContextBufferAllocTable.entries[index].contextBuffer =
nullptr;
1118 switch (allocatorIndex)
1120 case EnumerateSecurityPackagesIndex:
1121 FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
1124 case QuerySecurityPackageInfoIndex:
1125 FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
1133 LeaveCriticalSection(&ContextBufferAllocTableLock);
1142static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages,
1145 const size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1146 const size_t size =
sizeof(
SecPkgInfoW) * cPackages;
1148 (
SecPkgInfoW*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1150 WINPR_ASSERT(cPackages <= UINT32_MAX);
1153 return SEC_E_INSUFFICIENT_MEMORY;
1155 for (
size_t index = 0; index < cPackages; index++)
1157 pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1158 pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
1159 pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1160 pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1161 pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1162 pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1165 *(pcPackages) = (UINT32)cPackages;
1166 *(ppPackageInfo) = pPackageInfo;
1170static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages,
1173 const size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1174 const size_t size =
sizeof(
SecPkgInfoA) * cPackages;
1176 (
SecPkgInfoA*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
1178 WINPR_ASSERT(cPackages <= UINT32_MAX);
1181 return SEC_E_INSUFFICIENT_MEMORY;
1183 for (
size_t index = 0; index < cPackages; index++)
1185 pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1186 pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
1187 pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1188 pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1189 pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1190 pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1192 if (!pPackageInfo[index].Name || !pPackageInfo[index].Comment)
1194 sspi_ContextBufferFree(pPackageInfo);
1195 return SEC_E_INSUFFICIENT_MEMORY;
1199 *(pcPackages) = (UINT32)cPackages;
1200 *(ppPackageInfo) = pPackageInfo;
1204static void FreeContextBuffer_EnumerateSecurityPackages(
void* contextBuffer)
1207 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1212 for (
size_t index = 0; index < cPackages; index++)
1214 free(pPackageInfo[index].Name);
1215 free(pPackageInfo[index].Comment);
1221static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
1224 size_t cPackages = ARRAYSIZE(SecPkgInfoW_LIST);
1226 for (
size_t index = 0; index < cPackages; index++)
1228 if (_wcscmp(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
1232 (
SecPkgInfoW*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1235 return SEC_E_INSUFFICIENT_MEMORY;
1237 pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
1238 pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
1239 pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
1240 pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
1241 pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
1242 pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
1243 *(ppPackageInfo) = pPackageInfo;
1248 *(ppPackageInfo) =
nullptr;
1249 return SEC_E_SECPKG_NOT_FOUND;
1252static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
1255 size_t cPackages = ARRAYSIZE(SecPkgInfoA_LIST);
1257 for (
size_t index = 0; index < cPackages; index++)
1259 if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
1263 (
SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
1266 return SEC_E_INSUFFICIENT_MEMORY;
1268 pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
1269 pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
1270 pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
1271 pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
1272 pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
1273 pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
1275 if (!pPackageInfo->Name || !pPackageInfo->Comment)
1277 sspi_ContextBufferFree(pPackageInfo);
1278 return SEC_E_INSUFFICIENT_MEMORY;
1281 *(ppPackageInfo) = pPackageInfo;
1286 *(ppPackageInfo) =
nullptr;
1287 return SEC_E_SECPKG_NOT_FOUND;
1290void FreeContextBuffer_QuerySecurityPackageInfo(
void* contextBuffer)
1292 SecPkgInfo* pPackageInfo = (SecPkgInfo*)contextBuffer;
1297 free(pPackageInfo->Name);
1298 free(pPackageInfo->Comment);
1302#define log_status(what, status) log_status_((what), (status), __FILE__, __func__, __LINE__)
1303static SECURITY_STATUS log_status_(
const char* what, SECURITY_STATUS status,
const char* file,
1304 const char* fkt,
size_t line)
1306 if (IsSecurityStatusError(status))
1308 const DWORD level = WLOG_WARN;
1309 static wLog* log =
nullptr;
1311 log = WLog_Get(TAG);
1313 if (WLog_IsLevelActive(log, level))
1315 WLog_PrintTextMessage(log, level, line, file, fkt,
"%s status %s [0x%08" PRIx32
"]",
1316 what, GetSecurityStatusString(status),
1317 WINPR_CXX_COMPAT_CAST(uint32_t, status));
1325static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(
1326 SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1327 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1333 return SEC_E_SECPKG_NOT_FOUND;
1335 if (!table->AcquireCredentialsHandleW)
1337 WLog_WARN(TAG,
"Security module does not provide an implementation");
1338 return SEC_E_UNSUPPORTED_FUNCTION;
1341 SECURITY_STATUS status = table->AcquireCredentialsHandleW(
1342 pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
1343 phCredential, ptsExpiry);
1344 return log_status(
"AcquireCredentialsHandleW", status);
1347static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(
1348 SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse,
void* pvLogonID,
1349 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument,
PCredHandle phCredential,
1355 return SEC_E_SECPKG_NOT_FOUND;
1357 if (!table->AcquireCredentialsHandleA)
1359 WLog_WARN(TAG,
"Security module does not provide an implementation");
1360 return SEC_E_UNSUPPORTED_FUNCTION;
1363 SECURITY_STATUS status = table->AcquireCredentialsHandleA(
1364 pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
1365 phCredential, ptsExpiry);
1366 return log_status(
"AcquireCredentialsHandleA", status);
1369static SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(
PCtxtHandle phContext, ULONG fFlags,
1376 return SEC_E_SECPKG_NOT_FOUND;
1378 if (!table->ExportSecurityContext)
1380 WLog_WARN(TAG,
"Security module does not provide an implementation");
1381 return SEC_E_UNSUPPORTED_FUNCTION;
1384 SECURITY_STATUS status =
1385 table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
1386 return log_status(
"ExportSecurityContext", status);
1389static SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(
PCredHandle phCredential)
1394 return SEC_E_SECPKG_NOT_FOUND;
1396 if (!table->FreeCredentialsHandle)
1398 WLog_WARN(TAG,
"Security module does not provide an implementation");
1399 return SEC_E_UNSUPPORTED_FUNCTION;
1402 SECURITY_STATUS status = table->FreeCredentialsHandle(phCredential);
1403 return log_status(
"FreeCredentialsHandle", status);
1406static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage,
1413 return SEC_E_SECPKG_NOT_FOUND;
1415 if (!table->ImportSecurityContextW)
1417 WLog_WARN(TAG,
"Security module does not provide an implementation");
1418 return SEC_E_UNSUPPORTED_FUNCTION;
1421 SECURITY_STATUS status =
1422 table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
1423 return log_status(
"ImportSecurityContextW", status);
1426static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage,
1433 return SEC_E_SECPKG_NOT_FOUND;
1435 if (!table->ImportSecurityContextA)
1437 WLog_WARN(TAG,
"Security module does not provide an implementation");
1438 return SEC_E_UNSUPPORTED_FUNCTION;
1441 SECURITY_STATUS status =
1442 table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
1443 return log_status(
"ImportSecurityContextA", status);
1446static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(
PCredHandle phCredential,
1447 ULONG ulAttribute,
void* pBuffer)
1452 return SEC_E_SECPKG_NOT_FOUND;
1454 if (!table->QueryCredentialsAttributesW)
1456 WLog_WARN(TAG,
"Security module does not provide an implementation");
1457 return SEC_E_UNSUPPORTED_FUNCTION;
1460 SECURITY_STATUS status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
1461 return log_status(
"QueryCredentialsAttributesW", status);
1464static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(
PCredHandle phCredential,
1465 ULONG ulAttribute,
void* pBuffer)
1470 return SEC_E_SECPKG_NOT_FOUND;
1472 if (!table->QueryCredentialsAttributesA)
1474 WLog_WARN(TAG,
"Security module does not provide an implementation");
1475 return SEC_E_UNSUPPORTED_FUNCTION;
1478 SECURITY_STATUS status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
1479 return log_status(
"QueryCredentialsAttributesA", status);
1482static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesW(
PCredHandle phCredential,
1483 ULONG ulAttribute,
void* pBuffer,
1489 return SEC_E_SECPKG_NOT_FOUND;
1491 if (!table->SetCredentialsAttributesW)
1493 WLog_WARN(TAG,
"Security module does not provide an implementation");
1494 return SEC_E_UNSUPPORTED_FUNCTION;
1497 SECURITY_STATUS status =
1498 table->SetCredentialsAttributesW(phCredential, ulAttribute, pBuffer, cbBuffer);
1499 return log_status(
"SetCredentialsAttributesW", status);
1502static SECURITY_STATUS SEC_ENTRY winpr_SetCredentialsAttributesA(
PCredHandle phCredential,
1503 ULONG ulAttribute,
void* pBuffer,
1509 return SEC_E_SECPKG_NOT_FOUND;
1511 if (!table->SetCredentialsAttributesA)
1513 WLog_WARN(TAG,
"Security module does not provide an implementation");
1514 return SEC_E_UNSUPPORTED_FUNCTION;
1517 SECURITY_STATUS status =
1518 table->SetCredentialsAttributesA(phCredential, ulAttribute, pBuffer, cbBuffer);
1519 return log_status(
"SetCredentialsAttributesA", status);
1524static SECURITY_STATUS SEC_ENTRY
1526 ULONG fContextReq, ULONG TargetDataRep,
PCtxtHandle phNewContext,
1532 return SEC_E_SECPKG_NOT_FOUND;
1534 if (!table->AcceptSecurityContext)
1536 WLog_WARN(TAG,
"Security module does not provide an implementation");
1537 return SEC_E_UNSUPPORTED_FUNCTION;
1540 SECURITY_STATUS status =
1541 table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
1542 phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
1543 return log_status(
"AcceptSecurityContext", status);
1546static SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(
PCtxtHandle phContext,
1552 return SEC_E_SECPKG_NOT_FOUND;
1554 if (!table->ApplyControlToken)
1556 WLog_WARN(TAG,
"Security module does not provide an implementation");
1557 return SEC_E_UNSUPPORTED_FUNCTION;
1560 SECURITY_STATUS status = table->ApplyControlToken(phContext, pInput);
1561 return log_status(
"ApplyControlToken", status);
1564static SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(
PCtxtHandle phContext,
1570 return SEC_E_SECPKG_NOT_FOUND;
1572 if (!table->CompleteAuthToken)
1574 WLog_WARN(TAG,
"Security module does not provide an implementation");
1575 return SEC_E_UNSUPPORTED_FUNCTION;
1578 SECURITY_STATUS status = table->CompleteAuthToken(phContext, pToken);
1579 return log_status(
"CompleteAuthToken", status);
1582static SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(
PCtxtHandle phContext)
1587 return SEC_E_SECPKG_NOT_FOUND;
1589 if (!table->DeleteSecurityContext)
1591 WLog_WARN(TAG,
"Security module does not provide an implementation");
1592 return SEC_E_UNSUPPORTED_FUNCTION;
1595 const SECURITY_STATUS status = table->DeleteSecurityContext(phContext);
1596 return log_status(
"DeleteSecurityContext", status);
1599static SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(
void* pvContextBuffer)
1601 if (!pvContextBuffer)
1602 return SEC_E_INVALID_HANDLE;
1604 sspi_ContextBufferFree(pvContextBuffer);
1608static SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(
PCtxtHandle phContext)
1613 return SEC_E_SECPKG_NOT_FOUND;
1615 if (!table->ImpersonateSecurityContext)
1617 WLog_WARN(TAG,
"Security module does not provide an implementation");
1618 return SEC_E_UNSUPPORTED_FUNCTION;
1621 SECURITY_STATUS status = table->ImpersonateSecurityContext(phContext);
1622 return log_status(
"ImpersonateSecurityContext", status);
1625static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(
1627 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1633 return SEC_E_SECPKG_NOT_FOUND;
1635 if (!table->InitializeSecurityContextW)
1637 WLog_WARN(TAG,
"Security module does not provide an implementation");
1638 return SEC_E_UNSUPPORTED_FUNCTION;
1641 const SECURITY_STATUS status = table->InitializeSecurityContextW(
1642 phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
1643 Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
1644 return log_status(
"InitializeSecurityContextW", status);
1647static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(
1649 ULONG Reserved1, ULONG TargetDataRep,
PSecBufferDesc pInput, ULONG Reserved2,
1655 return SEC_E_SECPKG_NOT_FOUND;
1657 if (!table->InitializeSecurityContextA)
1659 WLog_WARN(TAG,
"Security module does not provide an implementation");
1660 return SEC_E_UNSUPPORTED_FUNCTION;
1663 SECURITY_STATUS status = table->InitializeSecurityContextA(
1664 phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
1665 Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
1667 return log_status(
"InitializeSecurityContextA", status);
1670static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(
PCtxtHandle phContext,
1671 ULONG ulAttribute,
void* pBuffer)
1676 return SEC_E_SECPKG_NOT_FOUND;
1678 if (!table->QueryContextAttributesW)
1680 WLog_WARN(TAG,
"Security module does not provide an implementation");
1681 return SEC_E_UNSUPPORTED_FUNCTION;
1684 SECURITY_STATUS status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
1685 return log_status(
"QueryContextAttributesW", status);
1688static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(
PCtxtHandle phContext,
1689 ULONG ulAttribute,
void* pBuffer)
1694 return SEC_E_SECPKG_NOT_FOUND;
1696 if (!table->QueryContextAttributesA)
1698 WLog_WARN(TAG,
"Security module does not provide an implementation");
1699 return SEC_E_UNSUPPORTED_FUNCTION;
1702 SECURITY_STATUS status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
1703 return log_status(
"QueryContextAttributesA", status);
1706static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(
PCtxtHandle phContext,
1712 return SEC_E_SECPKG_NOT_FOUND;
1714 if (!table->QuerySecurityContextToken)
1716 WLog_WARN(TAG,
"Security module does not provide an implementation");
1717 return SEC_E_UNSUPPORTED_FUNCTION;
1720 SECURITY_STATUS status = table->QuerySecurityContextToken(phContext, phToken);
1721 return log_status(
"QuerySecurityContextToken", status);
1724static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(
PCtxtHandle phContext,
1725 ULONG ulAttribute,
void* pBuffer,
1731 return SEC_E_SECPKG_NOT_FOUND;
1733 if (!table->SetContextAttributesW)
1735 WLog_WARN(TAG,
"Security module does not provide an implementation");
1736 return SEC_E_UNSUPPORTED_FUNCTION;
1739 SECURITY_STATUS status =
1740 table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
1741 return log_status(
"SetContextAttributesW", status);
1744static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(
PCtxtHandle phContext,
1745 ULONG ulAttribute,
void* pBuffer,
1751 return SEC_E_SECPKG_NOT_FOUND;
1753 if (!table->SetContextAttributesA)
1755 WLog_WARN(TAG,
"Security module does not provide an implementation");
1756 return SEC_E_UNSUPPORTED_FUNCTION;
1759 SECURITY_STATUS status =
1760 table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
1761 return log_status(
"SetContextAttributesA", status);
1764static SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(
PCtxtHandle phContext)
1769 return SEC_E_SECPKG_NOT_FOUND;
1771 if (!table->RevertSecurityContext)
1773 WLog_WARN(TAG,
"Security module does not provide an implementation");
1774 return SEC_E_UNSUPPORTED_FUNCTION;
1777 SECURITY_STATUS status = table->RevertSecurityContext(phContext);
1779 return log_status(
"RevertSecurityContext", status);
1784static SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(
PCtxtHandle phContext,
1791 return SEC_E_SECPKG_NOT_FOUND;
1793 if (!table->DecryptMessage)
1795 WLog_WARN(TAG,
"Security module does not provide an implementation");
1796 return SEC_E_UNSUPPORTED_FUNCTION;
1799 const SECURITY_STATUS status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
1801 return log_status(
"DecryptMessage", status);
1804static SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(
PCtxtHandle phContext, ULONG fQOP,
1810 return SEC_E_SECPKG_NOT_FOUND;
1812 if (!table->EncryptMessage)
1814 WLog_WARN(TAG,
"Security module does not provide an implementation");
1815 return SEC_E_UNSUPPORTED_FUNCTION;
1818 const SECURITY_STATUS status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
1819 return log_status(
"EncryptMessage", status);
1822static SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(
PCtxtHandle phContext, ULONG fQOP,
1828 return SEC_E_SECPKG_NOT_FOUND;
1830 if (!table->MakeSignature)
1832 WLog_WARN(TAG,
"Security module does not provide an implementation");
1833 return SEC_E_UNSUPPORTED_FUNCTION;
1836 const SECURITY_STATUS status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
1837 return log_status(
"MakeSignature", status);
1840static SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(
PCtxtHandle phContext,
1847 return SEC_E_SECPKG_NOT_FOUND;
1849 if (!table->VerifySignature)
1851 WLog_WARN(TAG,
"Security module does not provide an implementation");
1852 return SEC_E_UNSUPPORTED_FUNCTION;
1855 SECURITY_STATUS status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1857 return log_status(
"VerifySignature", status);
1862 winpr_EnumerateSecurityPackagesA,
1863 winpr_QueryCredentialsAttributesA,
1864 winpr_AcquireCredentialsHandleA,
1865 winpr_FreeCredentialsHandle,
1867 winpr_InitializeSecurityContextA,
1868 winpr_AcceptSecurityContext,
1869 winpr_CompleteAuthToken,
1870 winpr_DeleteSecurityContext,
1871 winpr_ApplyControlToken,
1872 winpr_QueryContextAttributesA,
1873 winpr_ImpersonateSecurityContext,
1874 winpr_RevertSecurityContext,
1875 winpr_MakeSignature,
1876 winpr_VerifySignature,
1877 winpr_FreeContextBuffer,
1878 winpr_QuerySecurityPackageInfoA,
1881 winpr_ExportSecurityContext,
1882 winpr_ImportSecurityContextA,
1885 winpr_QuerySecurityContextToken,
1886 winpr_EncryptMessage,
1887 winpr_DecryptMessage,
1888 winpr_SetContextAttributesA,
1889 winpr_SetCredentialsAttributesA,
1894 winpr_EnumerateSecurityPackagesW,
1895 winpr_QueryCredentialsAttributesW,
1896 winpr_AcquireCredentialsHandleW,
1897 winpr_FreeCredentialsHandle,
1899 winpr_InitializeSecurityContextW,
1900 winpr_AcceptSecurityContext,
1901 winpr_CompleteAuthToken,
1902 winpr_DeleteSecurityContext,
1903 winpr_ApplyControlToken,
1904 winpr_QueryContextAttributesW,
1905 winpr_ImpersonateSecurityContext,
1906 winpr_RevertSecurityContext,
1907 winpr_MakeSignature,
1908 winpr_VerifySignature,
1909 winpr_FreeContextBuffer,
1910 winpr_QuerySecurityPackageInfoW,
1913 winpr_ExportSecurityContext,
1914 winpr_ImportSecurityContextW,
1917 winpr_QuerySecurityContextToken,
1918 winpr_EncryptMessage,
1919 winpr_DecryptMessage,
1920 winpr_SetContextAttributesW,
1921 winpr_SetCredentialsAttributesW,
1926 return &winpr_SecurityFunctionTableW;
1931 return &winpr_SecurityFunctionTableA;
1934SEC_WINPR_NTLM_SETTINGS_V2* sspi_CloneSecNtlmSettings(
const SEC_WINPR_NTLM_SETTINGS_V2* other)
1939 const size_t size =
sizeof(SEC_WINPR_NTLM_SETTINGS_V2);
1940 if (other->size < size)
1943 "Invalid SEC_WINPR_NTLM_SETTINGS_V2 parameter passed, must be of size >= "
1949 SEC_WINPR_NTLM_SETTINGS_V2* clone = sspi_AllocSecNtlmSettings();
1955 if (!sspi_CloneSecSettingsString(&clone->samFile, other->samFile))
1958 clone->hashCallback = other->hashCallback;
1959 clone->hashCallbackArg = other->hashCallbackArg;
1960 if (other->targetName)
1962 if (!sspi_CloneSecSettingsString(&clone->targetName, other->targetName))
1965 if (other->netBiosComputerName)
1967 if (!sspi_CloneSecSettingsString(&clone->netBiosComputerName, other->netBiosComputerName))
1970 if (other->netBiosDomainName)
1972 if (!sspi_CloneSecSettingsString(&clone->netBiosDomainName, other->netBiosDomainName))
1975 if (other->dnsComputerName)
1977 if (!sspi_CloneSecSettingsString(&clone->dnsComputerName, other->dnsComputerName))
1980 if (other->dnsDomainName)
1982 if (!sspi_CloneSecSettingsString(&clone->dnsDomainName, other->dnsDomainName))
1989 sspi_FreeSecNtlmSettings(clone);