Blame winpr/libwinpr/sspi/sspi_winpr.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Security Support Provider Interface (SSPI)
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/windows.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/sspi.h>
Packit 1fb8d4
#include <winpr/ssl.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
Packit 1fb8d4
#include "sspi.h"
Packit 1fb8d4
Packit 1fb8d4
#include "sspi_winpr.h"
Packit 1fb8d4
Packit 1fb8d4
#include "../log.h"
Packit 1fb8d4
#define TAG WINPR_TAG("sspi")
Packit 1fb8d4
Packit 1fb8d4
/* Authentication Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374731/ */
Packit 1fb8d4
Packit 1fb8d4
extern const SecPkgInfoA NTLM_SecPkgInfoA;
Packit 1fb8d4
extern const SecPkgInfoW NTLM_SecPkgInfoW;
Packit 1fb8d4
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
Packit 1fb8d4
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
Packit 1fb8d4
Packit 1fb8d4
extern const SecPkgInfoA KERBEROS_SecPkgInfoA;
Packit 1fb8d4
extern const SecPkgInfoW KERBEROS_SecPkgInfoW;
Packit 1fb8d4
extern const SecurityFunctionTableA KERBEROS_SecurityFunctionTableA;
Packit 1fb8d4
extern const SecurityFunctionTableW KERBEROS_SecurityFunctionTableW;
Packit 1fb8d4
Packit 1fb8d4
extern const SecPkgInfoA NEGOTIATE_SecPkgInfoA;
Packit 1fb8d4
extern const SecPkgInfoW NEGOTIATE_SecPkgInfoW;
Packit 1fb8d4
extern const SecurityFunctionTableA NEGOTIATE_SecurityFunctionTableA;
Packit 1fb8d4
extern const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW;
Packit 1fb8d4
Packit 1fb8d4
extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
Packit 1fb8d4
extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
Packit 1fb8d4
extern const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA;
Packit 1fb8d4
extern const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW;
Packit 1fb8d4
Packit 1fb8d4
extern const SecPkgInfoA SCHANNEL_SecPkgInfoA;
Packit 1fb8d4
extern const SecPkgInfoW SCHANNEL_SecPkgInfoW;
Packit 1fb8d4
extern const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA;
Packit 1fb8d4
extern const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW;
Packit 1fb8d4
Packit Service 5a9772
static const SecPkgInfoA* SecPkgInfoA_LIST[] = { &NTLM_SecPkgInfoA, &KERBEROS_SecPkgInfoA,
Packit Service 5a9772
	                                             &NEGOTIATE_SecPkgInfoA, &CREDSSP_SecPkgInfoA,
Packit Service 5a9772
	                                             &SCHANNEL_SecPkgInfoA };
Packit 1fb8d4
Packit Service 5a9772
static const SecPkgInfoW* SecPkgInfoW_LIST[] = { &NTLM_SecPkgInfoW, &KERBEROS_SecPkgInfoW,
Packit Service 5a9772
	                                             &NEGOTIATE_SecPkgInfoW, &CREDSSP_SecPkgInfoW,
Packit Service 5a9772
	                                             &SCHANNEL_SecPkgInfoW };
Packit 1fb8d4
Packit 1fb8d4
static SecurityFunctionTableA winpr_SecurityFunctionTableA;
Packit 1fb8d4
static SecurityFunctionTableW winpr_SecurityFunctionTableW;
Packit 1fb8d4
Packit 1fb8d4
struct _SecurityFunctionTableA_NAME
Packit 1fb8d4
{
Packit 1fb8d4
	const SEC_CHAR* Name;
Packit 1fb8d4
	const SecurityFunctionTableA* SecurityFunctionTable;
Packit 1fb8d4
};
Packit 1fb8d4
typedef struct _SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME;
Packit 1fb8d4
Packit 1fb8d4
struct _SecurityFunctionTableW_NAME
Packit 1fb8d4
{
Packit 1fb8d4
	const SEC_WCHAR* Name;
Packit 1fb8d4
	const SecurityFunctionTableW* SecurityFunctionTable;
Packit 1fb8d4
};
Packit 1fb8d4
typedef struct _SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME;
Packit 1fb8d4
Packit Service 5a9772
static const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] = {
Packit 1fb8d4
	{ "NTLM", &NTLM_SecurityFunctionTableA },
Packit 1fb8d4
	{ "Kerberos", &KERBEROS_SecurityFunctionTableA },
Packit 1fb8d4
	{ "Negotiate", &NEGOTIATE_SecurityFunctionTableA },
Packit 1fb8d4
	{ "CREDSSP", &CREDSSP_SecurityFunctionTableA },
Packit 1fb8d4
	{ "Schannel", &SCHANNEL_SecurityFunctionTableA }
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static const WCHAR NTLM_NAME_W[] = { 'N', 'T', 'L', 'M', '\0' };
Packit 1fb8d4
static const WCHAR KERBEROS_NAME_W[] = { 'K', 'e', 'r', 'b', 'e', 'r', 'o', 's', '\0' };
Packit 1fb8d4
static const WCHAR NEGOTIATE_NAME_W[] = { 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', '\0' };
Packit 1fb8d4
static const WCHAR CREDSSP_NAME_W[] = { 'C', 'r', 'e', 'd', 'S', 'S', 'P', '\0' };
Packit 1fb8d4
static const WCHAR SCHANNEL_NAME_W[] = { 'S', 'c', 'h', 'a', 'n', 'n', 'e', 'l', '\0' };
Packit 1fb8d4
Packit Service 5a9772
static const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] = {
Packit 1fb8d4
	{ NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
Packit 1fb8d4
	{ KERBEROS_NAME_W, &KERBEROS_SecurityFunctionTableW },
Packit 1fb8d4
	{ NEGOTIATE_NAME_W, &NEGOTIATE_SecurityFunctionTableW },
Packit 1fb8d4
	{ CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW },
Packit 1fb8d4
	{ SCHANNEL_NAME_W, &SCHANNEL_SecurityFunctionTableW }
Packit 1fb8d4
};
Packit 1fb8d4
Packit Service 5a9772
#define SecHandle_LOWER_MAX 0xFFFFFFFF
Packit Service 5a9772
#define SecHandle_UPPER_MAX 0xFFFFFFFE
Packit 1fb8d4
Packit 1fb8d4
struct _CONTEXT_BUFFER_ALLOC_ENTRY
Packit 1fb8d4
{
Packit 1fb8d4
	void* contextBuffer;
Packit 1fb8d4
	UINT32 allocatorIndex;
Packit 1fb8d4
};
Packit 1fb8d4
typedef struct _CONTEXT_BUFFER_ALLOC_ENTRY CONTEXT_BUFFER_ALLOC_ENTRY;
Packit 1fb8d4
Packit 1fb8d4
struct _CONTEXT_BUFFER_ALLOC_TABLE
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 cEntries;
Packit 1fb8d4
	UINT32 cMaxEntries;
Packit 1fb8d4
	CONTEXT_BUFFER_ALLOC_ENTRY* entries;
Packit 1fb8d4
};
Packit 1fb8d4
typedef struct _CONTEXT_BUFFER_ALLOC_TABLE CONTEXT_BUFFER_ALLOC_TABLE;
Packit 1fb8d4
Packit 1fb8d4
static CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable = { 0 };
Packit 1fb8d4
Packit 1fb8d4
static int sspi_ContextBufferAllocTableNew(void)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	ContextBufferAllocTable.entries = NULL;
Packit 1fb8d4
	ContextBufferAllocTable.cEntries = 0;
Packit 1fb8d4
	ContextBufferAllocTable.cMaxEntries = 4;
Packit 1fb8d4
	size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
Packit Service 5a9772
	ContextBufferAllocTable.entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)calloc(1, size);
Packit 1fb8d4
Packit 1fb8d4
	if (!ContextBufferAllocTable.entries)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static int sspi_ContextBufferAllocTableGrow(void)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	CONTEXT_BUFFER_ALLOC_ENTRY* entries;
Packit 1fb8d4
	ContextBufferAllocTable.cEntries = 0;
Packit 1fb8d4
	ContextBufferAllocTable.cMaxEntries *= 2;
Packit 1fb8d4
	size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
Packit 1fb8d4
Packit 1fb8d4
	if (!size)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit Service 5a9772
	entries = (CONTEXT_BUFFER_ALLOC_ENTRY*)realloc(ContextBufferAllocTable.entries, size);
Packit 1fb8d4
Packit 1fb8d4
	if (!entries)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(ContextBufferAllocTable.entries);
Packit 1fb8d4
		return -1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ContextBufferAllocTable.entries = entries;
Packit Service 5a9772
	ZeroMemory((void*)&ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2],
Packit 1fb8d4
	           size / 2);
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void sspi_ContextBufferAllocTableFree(void)
Packit 1fb8d4
{
Packit 1fb8d4
	if (ContextBufferAllocTable.cEntries != 0)
Packit Service 5a9772
		WLog_ERR(TAG, "ContextBufferAllocTable.entries == %" PRIu32,
Packit Service 5a9772
		         ContextBufferAllocTable.cEntries);
Packit 1fb8d4
Packit 1fb8d4
	ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
Packit 1fb8d4
	free(ContextBufferAllocTable.entries);
Packit 1fb8d4
	ContextBufferAllocTable.entries = NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	void* contextBuffer;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!ContextBufferAllocTable.entries[index].contextBuffer)
Packit 1fb8d4
		{
Packit 1fb8d4
			contextBuffer = calloc(1, size);
Packit 1fb8d4
Packit 1fb8d4
			if (!contextBuffer)
Packit 1fb8d4
				return NULL;
Packit 1fb8d4
Packit 1fb8d4
			ContextBufferAllocTable.cEntries++;
Packit 1fb8d4
			ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
Packit 1fb8d4
			ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
Packit 1fb8d4
			return ContextBufferAllocTable.entries[index].contextBuffer;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	/* no available entry was found, the table needs to be grown */
Packit 1fb8d4
Packit 1fb8d4
	if (sspi_ContextBufferAllocTableGrow() < 0)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	/* the next call to sspi_ContextBufferAlloc() should now succeed */
Packit 1fb8d4
	return sspi_ContextBufferAlloc(allocatorIndex, size);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
SSPI_CREDENTIALS* sspi_CredentialsNew(void)
Packit 1fb8d4
{
Packit 1fb8d4
	SSPI_CREDENTIALS* credentials;
Packit Service 5a9772
	credentials = (SSPI_CREDENTIALS*)calloc(1, sizeof(SSPI_CREDENTIALS));
Packit 1fb8d4
	return credentials;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_CredentialsFree(SSPI_CREDENTIALS* credentials)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t userLength = 0;
Packit 1fb8d4
	size_t domainLength = 0;
Packit 1fb8d4
	size_t passwordLength = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (!credentials)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	userLength = credentials->identity.UserLength;
Packit 1fb8d4
	domainLength = credentials->identity.DomainLength;
Packit 1fb8d4
	passwordLength = credentials->identity.PasswordLength;
Packit 1fb8d4
Packit 1fb8d4
	if (passwordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET) /* [pth] */
Packit 1fb8d4
		passwordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
Packit 1fb8d4
Packit 1fb8d4
	if (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
Packit 1fb8d4
	{
Packit 1fb8d4
		userLength *= 2;
Packit 1fb8d4
		domainLength *= 2;
Packit 1fb8d4
		passwordLength *= 2;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	if (credentials->identity.User)
Packit Service 5a9772
		memset(credentials->identity.User, 0, userLength);
Packit Service 5a9772
	if (credentials->identity.Domain)
Packit Service 5a9772
		memset(credentials->identity.Domain, 0, domainLength);
Packit Service 5a9772
	if (credentials->identity.Password)
Packit Service 5a9772
		memset(credentials->identity.Password, 0, passwordLength);
Packit 1fb8d4
	free(credentials->identity.User);
Packit 1fb8d4
	free(credentials->identity.Domain);
Packit 1fb8d4
	free(credentials->identity.Password);
Packit 1fb8d4
	free(credentials);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void* sspi_SecBufferAlloc(PSecBuffer SecBuffer, ULONG size)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!SecBuffer)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	SecBuffer->pvBuffer = calloc(1, size);
Packit 1fb8d4
Packit 1fb8d4
	if (!SecBuffer->pvBuffer)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	SecBuffer->cbBuffer = size;
Packit 1fb8d4
	return SecBuffer->pvBuffer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_SecBufferFree(PSecBuffer SecBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!SecBuffer)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	if (SecBuffer->pvBuffer)
Packit 1fb8d4
		memset(SecBuffer->pvBuffer, 0, SecBuffer->cbBuffer);
Packit 1fb8d4
Packit 1fb8d4
	free(SecBuffer->pvBuffer);
Packit 1fb8d4
	SecBuffer->pvBuffer = NULL;
Packit 1fb8d4
	SecBuffer->cbBuffer = 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
SecHandle* sspi_SecureHandleAlloc(void)
Packit 1fb8d4
{
Packit Service 5a9772
	SecHandle* handle = (SecHandle*)calloc(1, sizeof(SecHandle));
Packit 1fb8d4
Packit 1fb8d4
	if (!handle)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	SecInvalidateHandle(handle);
Packit 1fb8d4
	return handle;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void* sspi_SecureHandleGetLowerPointer(SecHandle* handle)
Packit 1fb8d4
{
Packit 1fb8d4
	void* pointer;
Packit 1fb8d4
Packit 1fb8d4
	if (!handle || !SecIsValidHandle(handle) || !handle->dwLower)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit Service 5a9772
	pointer = (void*)~((size_t)handle->dwLower);
Packit 1fb8d4
	return pointer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_SecureHandleInvalidate(SecHandle* handle)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!handle)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	handle->dwLower = 0;
Packit 1fb8d4
	handle->dwUpper = 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_SecureHandleSetLowerPointer(SecHandle* handle, void* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!handle)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit Service 5a9772
	handle->dwLower = (ULONG_PTR)(~((size_t)pointer));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void* sspi_SecureHandleGetUpperPointer(SecHandle* handle)
Packit 1fb8d4
{
Packit 1fb8d4
	void* pointer;
Packit 1fb8d4
Packit 1fb8d4
	if (!handle || !SecIsValidHandle(handle) || !handle->dwUpper)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit Service 5a9772
	pointer = (void*)~((size_t)handle->dwUpper);
Packit 1fb8d4
	return pointer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_SecureHandleSetUpperPointer(SecHandle* handle, void* pointer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!handle)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit Service 5a9772
	handle->dwUpper = (ULONG_PTR)(~((size_t)pointer));
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_SecureHandleFree(SecHandle* handle)
Packit 1fb8d4
{
Packit 1fb8d4
	free(handle);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, const char* domain,
Packit 1fb8d4
                         const char* password)
Packit 1fb8d4
{
Packit 1fb8d4
	int rc;
Packit 1fb8d4
	int unicodePasswordLenW;
Packit 1fb8d4
	LPWSTR unicodePassword = NULL;
Packit 1fb8d4
	unicodePasswordLenW = ConvertToUnicode(CP_UTF8, 0, password, -1, &unicodePassword, 0);
Packit 1fb8d4
Packit 1fb8d4
	if (unicodePasswordLenW <= 0)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	rc = sspi_SetAuthIdentityWithUnicodePassword(identity, user, domain, unicodePassword,
Packit Service 5a9772
	                                             (ULONG)(unicodePasswordLenW - 1));
Packit 1fb8d4
	free(unicodePassword);
Packit 1fb8d4
	return rc;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int sspi_SetAuthIdentityWithUnicodePassword(SEC_WINNT_AUTH_IDENTITY* identity, const char* user,
Packit Service 5a9772
                                            const char* domain, LPWSTR password,
Packit Service 5a9772
                                            ULONG passwordLength)
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit 1fb8d4
	identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
Packit 1fb8d4
	free(identity->User);
Packit Service 5a9772
	identity->User = (UINT16*)NULL;
Packit 1fb8d4
	identity->UserLength = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (user)
Packit 1fb8d4
	{
Packit Service 5a9772
		status = ConvertToUnicode(CP_UTF8, 0, user, -1, (LPWSTR*)&(identity->User), 0);
Packit 1fb8d4
Packit 1fb8d4
		if (status <= 0)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		identity->UserLength = (ULONG)(status - 1);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	free(identity->Domain);
Packit Service 5a9772
	identity->Domain = (UINT16*)NULL;
Packit 1fb8d4
	identity->DomainLength = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (domain)
Packit 1fb8d4
	{
Packit Service 5a9772
		status = ConvertToUnicode(CP_UTF8, 0, domain, -1, (LPWSTR*)&(identity->Domain), 0);
Packit 1fb8d4
Packit 1fb8d4
		if (status <= 0)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		identity->DomainLength = (ULONG)(status - 1);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	free(identity->Password);
Packit Service 5a9772
	identity->Password = (UINT16*)calloc(1, (passwordLength + 1) * sizeof(WCHAR));
Packit 1fb8d4
Packit 1fb8d4
	if (!identity->Password)
Packit 1fb8d4
		return -1;
Packit 1fb8d4
Packit 1fb8d4
	CopyMemory(identity->Password, password, passwordLength * sizeof(WCHAR));
Packit 1fb8d4
	identity->PasswordLength = passwordLength;
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity)
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit 1fb8d4
Packit 1fb8d4
	if (srcIdentity->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
Packit 1fb8d4
	{
Packit Service 5a9772
		status = sspi_SetAuthIdentity(identity, (char*)srcIdentity->User,
Packit Service 5a9772
		                              (char*)srcIdentity->Domain, (char*)srcIdentity->Password);
Packit 1fb8d4
Packit 1fb8d4
		if (status <= 0)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		identity->Flags &= ~SEC_WINNT_AUTH_IDENTITY_ANSI;
Packit 1fb8d4
		identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
Packit 1fb8d4
		return 1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
Packit 1fb8d4
	/* login/password authentication */
Packit 1fb8d4
	identity->User = identity->Domain = identity->Password = NULL;
Packit 1fb8d4
	identity->UserLength = srcIdentity->UserLength;
Packit 1fb8d4
Packit 1fb8d4
	if (identity->UserLength > 0)
Packit 1fb8d4
	{
Packit Service 5a9772
		identity->User = (UINT16*)calloc((identity->UserLength + 1), sizeof(WCHAR));
Packit 1fb8d4
Packit 1fb8d4
		if (!identity->User)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR));
Packit 1fb8d4
		identity->User[identity->UserLength] = 0;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	identity->DomainLength = srcIdentity->DomainLength;
Packit 1fb8d4
Packit 1fb8d4
	if (identity->DomainLength > 0)
Packit 1fb8d4
	{
Packit Service 5a9772
		identity->Domain = (UINT16*)calloc((identity->DomainLength + 1), sizeof(WCHAR));
Packit 1fb8d4
Packit 1fb8d4
		if (!identity->Domain)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit 1fb8d4
		CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR));
Packit 1fb8d4
		identity->Domain[identity->DomainLength] = 0;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	identity->PasswordLength = srcIdentity->PasswordLength;
Packit 1fb8d4
Packit 1fb8d4
	if (identity->PasswordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
Packit 1fb8d4
		identity->PasswordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
Packit 1fb8d4
Packit 1fb8d4
	if (srcIdentity->Password)
Packit 1fb8d4
	{
Packit Service 5a9772
		identity->Password = (UINT16*)calloc((identity->PasswordLength + 1), sizeof(WCHAR));
Packit 1fb8d4
Packit 1fb8d4
		if (!identity->Password)
Packit 1fb8d4
			return -1;
Packit 1fb8d4
Packit Service 5a9772
		CopyMemory(identity->Password, srcIdentity->Password,
Packit Service 5a9772
		           identity->PasswordLength * sizeof(WCHAR));
Packit 1fb8d4
		identity->Password[identity->PasswordLength] = 0;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	identity->PasswordLength = srcIdentity->PasswordLength;
Packit 1fb8d4
	/* End of login/password authentication */
Packit 1fb8d4
	return 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
PSecBuffer sspi_FindSecBuffer(PSecBufferDesc pMessage, ULONG BufferType)
Packit 1fb8d4
{
Packit 1fb8d4
	ULONG index;
Packit 1fb8d4
	PSecBuffer pSecBuffer = NULL;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < pMessage->cBuffers; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (pMessage->pBuffers[index].BufferType == BufferType)
Packit 1fb8d4
		{
Packit 1fb8d4
			pSecBuffer = &pMessage->pBuffers[index];
Packit 1fb8d4
			break;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return pSecBuffer;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL CALLBACK sspi_init(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
Packit 1fb8d4
{
Packit 1fb8d4
	winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
Packit 1fb8d4
	sspi_ContextBufferAllocTableNew();
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_GlobalInit(void)
Packit 1fb8d4
{
Packit 1fb8d4
	static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
Packit 1fb8d4
	DWORD flags = 0;
Packit 1fb8d4
	InitOnceExecuteOnce(&once, sspi_init, &flags, NULL);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void sspi_GlobalFinish(void)
Packit 1fb8d4
{
Packit 1fb8d4
	sspi_ContextBufferAllocTableFree();
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameA(const SEC_CHAR* Name)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
Packit 1fb8d4
		{
Packit Service 5a9772
			return (SecurityFunctionTableA*)SecurityFunctionTableA_NAME_LIST[index]
Packit Service 5a9772
			    .SecurityFunctionTable;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameW(const SEC_WCHAR* Name)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (lstrcmpW(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
Packit 1fb8d4
		{
Packit Service 5a9772
			return (SecurityFunctionTableW*)SecurityFunctionTableW_NAME_LIST[index]
Packit Service 5a9772
			    .SecurityFunctionTable;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const SEC_CHAR* Name)
Packit 1fb8d4
{
Packit 1fb8d4
	int status;
Packit 1fb8d4
	SEC_WCHAR* NameW = NULL;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit 1fb8d4
	status = ConvertToUnicode(CP_UTF8, 0, Name, -1, &NameW, 0);
Packit 1fb8d4
Packit 1fb8d4
	if (status <= 0)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameW(NameW);
Packit 1fb8d4
	free(NameW);
Packit 1fb8d4
	return table;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer);
Packit 1fb8d4
static void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer);
Packit 1fb8d4
Packit 1fb8d4
static void sspi_ContextBufferFree(void* contextBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 index;
Packit 1fb8d4
	UINT32 allocatorIndex;
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < ContextBufferAllocTable.cMaxEntries; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
Packit 1fb8d4
		{
Packit 1fb8d4
			contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
Packit 1fb8d4
			allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
Packit 1fb8d4
			ContextBufferAllocTable.cEntries--;
Packit 1fb8d4
			ContextBufferAllocTable.entries[index].allocatorIndex = 0;
Packit 1fb8d4
			ContextBufferAllocTable.entries[index].contextBuffer = NULL;
Packit 1fb8d4
Packit 1fb8d4
			switch (allocatorIndex)
Packit 1fb8d4
			{
Packit 1fb8d4
				case EnumerateSecurityPackagesIndex:
Packit 1fb8d4
					FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
Packit 1fb8d4
					break;
Packit 1fb8d4
Packit 1fb8d4
				case QuerySecurityPackageInfoIndex:
Packit 1fb8d4
					FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
Packit 1fb8d4
					break;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Standard SSPI API
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
/* Package Management */
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages,
Packit Service 5a9772
                                                                  PSecPkgInfoW* ppPackageInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	SecPkgInfoW* pPackageInfo;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
Packit 1fb8d4
	size = sizeof(SecPkgInfoW) * cPackages;
Packit Service 5a9772
	pPackageInfo = (SecPkgInfoW*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
Packit 1fb8d4
Packit 1fb8d4
	if (!pPackageInfo)
Packit 1fb8d4
		return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
Packit 1fb8d4
		pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
Packit 1fb8d4
		pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
Packit 1fb8d4
		pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
Packit 1fb8d4
		pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
Packit 1fb8d4
		pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*(pcPackages) = cPackages;
Packit 1fb8d4
	*(ppPackageInfo) = pPackageInfo;
Packit 1fb8d4
	return SEC_E_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages,
Packit Service 5a9772
                                                                  PSecPkgInfoA* ppPackageInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	SecPkgInfoA* pPackageInfo;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
Packit 1fb8d4
	size = sizeof(SecPkgInfoA) * cPackages;
Packit Service 5a9772
	pPackageInfo = (SecPkgInfoA*)sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
Packit 1fb8d4
Packit 1fb8d4
	if (!pPackageInfo)
Packit 1fb8d4
		return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
Packit 1fb8d4
		pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
Packit 1fb8d4
		pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
Packit 1fb8d4
		pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
Packit 1fb8d4
		pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
Packit 1fb8d4
		pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
Packit 1fb8d4
Packit 1fb8d4
		if (!pPackageInfo[index].Name || !pPackageInfo[index].Comment)
Packit 1fb8d4
		{
Packit 1fb8d4
			sspi_ContextBufferFree(pPackageInfo);
Packit 1fb8d4
			return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*(pcPackages) = cPackages;
Packit 1fb8d4
	*(ppPackageInfo) = pPackageInfo;
Packit 1fb8d4
	return SEC_E_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	UINT32 cPackages;
Packit Service 5a9772
	SecPkgInfoA* pPackageInfo = (SecPkgInfoA*)contextBuffer;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
Packit 1fb8d4
Packit Service 5a9772
	if (!pPackageInfo)
Packit Service 5a9772
		return;
Packit Service 5a9772
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(pPackageInfo[index].Name);
Packit 1fb8d4
		free(pPackageInfo[index].Comment);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	free(pPackageInfo);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
SecurityFunctionTableW* SEC_ENTRY winpr_InitSecurityInterfaceW(void)
Packit 1fb8d4
{
Packit 1fb8d4
	return &winpr_SecurityFunctionTableW;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
SecurityFunctionTableA* SEC_ENTRY winpr_InitSecurityInterfaceA(void)
Packit 1fb8d4
{
Packit 1fb8d4
	return &winpr_SecurityFunctionTableA;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
Packit Service 5a9772
                                                                 PSecPkgInfoW* ppPackageInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	SecPkgInfoW* pPackageInfo;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (lstrcmpW(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			size = sizeof(SecPkgInfoW);
Packit Service 5a9772
			pPackageInfo =
Packit Service 5a9772
			    (SecPkgInfoW*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
Packit 1fb8d4
Packit 1fb8d4
			if (!pPackageInfo)
Packit 1fb8d4
				return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
Packit 1fb8d4
			pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
Packit 1fb8d4
			pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
Packit 1fb8d4
			pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
Packit 1fb8d4
			pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
Packit 1fb8d4
			pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
Packit 1fb8d4
			pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
Packit 1fb8d4
			*(ppPackageInfo) = pPackageInfo;
Packit 1fb8d4
			return SEC_E_OK;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*(ppPackageInfo) = NULL;
Packit 1fb8d4
	return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
Packit Service 5a9772
                                                                 PSecPkgInfoA* ppPackageInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	size_t size;
Packit 1fb8d4
	UINT32 cPackages;
Packit 1fb8d4
	SecPkgInfoA* pPackageInfo;
Packit 1fb8d4
	cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
Packit 1fb8d4
Packit Service 5a9772
	for (index = 0; index < (int)cPackages; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			size = sizeof(SecPkgInfoA);
Packit Service 5a9772
			pPackageInfo =
Packit Service 5a9772
			    (SecPkgInfoA*)sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
Packit 1fb8d4
Packit 1fb8d4
			if (!pPackageInfo)
Packit 1fb8d4
				return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
Packit 1fb8d4
			pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
Packit 1fb8d4
			pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
Packit 1fb8d4
			pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
Packit 1fb8d4
			pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
Packit 1fb8d4
			pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
Packit 1fb8d4
			pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
Packit 1fb8d4
Packit 1fb8d4
			if (!pPackageInfo->Name || !pPackageInfo->Comment)
Packit 1fb8d4
			{
Packit 1fb8d4
				sspi_ContextBufferFree(pPackageInfo);
Packit 1fb8d4
				return SEC_E_INSUFFICIENT_MEMORY;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			*(ppPackageInfo) = pPackageInfo;
Packit 1fb8d4
			return SEC_E_OK;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*(ppPackageInfo) = NULL;
Packit 1fb8d4
	return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer)
Packit 1fb8d4
{
Packit Service 5a9772
	SecPkgInfo* pPackageInfo = (SecPkgInfo*)contextBuffer;
Packit 1fb8d4
Packit 1fb8d4
	if (!pPackageInfo)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	free(pPackageInfo->Name);
Packit 1fb8d4
	free(pPackageInfo->Comment);
Packit 1fb8d4
	free(pPackageInfo);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* Credential Management */
Packit 1fb8d4
Packit Service 5a9772
static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(
Packit Service 5a9772
    SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
Packit Service 5a9772
    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
Packit Service 5a9772
    PTimeStamp ptsExpiry)
Packit 1fb8d4
{
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table = sspi_GetSecurityFunctionTableWByNameW(pszPackage);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->AcquireCredentialsHandleW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit Service 5a9772
	status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
Packit Service 5a9772
	                                          pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
Packit Service 5a9772
	                                          ptsExpiry);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "AcquireCredentialsHandleW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(
Packit Service 5a9772
    SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
Packit Service 5a9772
    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
Packit Service 5a9772
    PTimeStamp ptsExpiry)
Packit 1fb8d4
{
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table = sspi_GetSecurityFunctionTableAByNameA(pszPackage);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->AcquireCredentialsHandleA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit Service 5a9772
	status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
Packit Service 5a9772
	                                          pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
Packit Service 5a9772
	                                          ptsExpiry);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "AcquireCredentialsHandleA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags,
Packit Service 5a9772
                                                             PSecBuffer pPackedContext,
Packit Service 5a9772
                                                             HANDLE* pToken)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->ExportSecurityContext)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "ExportSecurityContext status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(PCredHandle phCredential)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->FreeCredentialsHandle)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->FreeCredentialsHandle(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "FreeCredentialsHandle status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage,
Packit Service 5a9772
                                                              PSecBuffer pPackedContext,
Packit Service 5a9772
                                                              HANDLE pToken, PCtxtHandle phContext)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->ImportSecurityContextW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "ImportSecurityContextW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage,
Packit Service 5a9772
                                                              PSecBuffer pPackedContext,
Packit Service 5a9772
                                                              HANDLE pToken, PCtxtHandle phContext)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name = NULL;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->ImportSecurityContextA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "ImportSecurityContextA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(PCredHandle phCredential,
Packit Service 5a9772
                                                                   ULONG ulAttribute, void* pBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_WCHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_WCHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameW(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->QueryCredentialsAttributesW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "QueryCredentialsAttributesW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(PCredHandle phCredential,
Packit Service 5a9772
                                                                   ULONG ulAttribute, void* pBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->QueryCredentialsAttributesA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "QueryCredentialsAttributesA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* Context Management */
Packit 1fb8d4
Packit Service 5a9772
static SECURITY_STATUS SEC_ENTRY
Packit Service 5a9772
winpr_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
Packit Service 5a9772
                            ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
Packit Service 5a9772
                            PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->AcceptSecurityContext)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit Service 5a9772
	status =
Packit Service 5a9772
	    table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
Packit Service 5a9772
	                                 phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "AcceptSecurityContext status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(PCtxtHandle phContext,
Packit Service 5a9772
                                                         PSecBufferDesc pInput)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name = NULL;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->ApplyControlToken)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->ApplyControlToken(phContext, pInput);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "ApplyControlToken status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(PCtxtHandle phContext,
Packit Service 5a9772
                                                         PSecBufferDesc pToken)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name = NULL;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->CompleteAuthToken)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->CompleteAuthToken(phContext, pToken);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "CompleteAuthToken status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(PCtxtHandle phContext)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name = NULL;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->DeleteSecurityContext)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->DeleteSecurityContext(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "DeleteSecurityContext status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(void* pvContextBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!pvContextBuffer)
Packit 1fb8d4
		return SEC_E_INVALID_HANDLE;
Packit 1fb8d4
Packit 1fb8d4
	sspi_ContextBufferFree(pvContextBuffer);
Packit 1fb8d4
	return SEC_E_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(PCtxtHandle phContext)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->ImpersonateSecurityContext)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->ImpersonateSecurityContext(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "ImpersonateSecurityContext status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(
Packit Service 5a9772
    PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq,
Packit Service 5a9772
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
Packit Service 5a9772
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->InitializeSecurityContextW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit Service 5a9772
	status = table->InitializeSecurityContextW(phCredential, phContext, pszTargetName, fContextReq,
Packit Service 5a9772
	                                           Reserved1, TargetDataRep, pInput, Reserved2,
Packit Service 5a9772
	                                           phNewContext, pOutput, pfContextAttr, ptsExpiry);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "InitializeSecurityContextW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(
Packit Service 5a9772
    PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq,
Packit Service 5a9772
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
Packit Service 5a9772
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phCredential);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->InitializeSecurityContextA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit Service 5a9772
	status = table->InitializeSecurityContextA(phCredential, phContext, pszTargetName, fContextReq,
Packit Service 5a9772
	                                           Reserved1, TargetDataRep, pInput, Reserved2,
Packit Service 5a9772
	                                           phNewContext, pOutput, pfContextAttr, ptsExpiry);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "InitializeSecurityContextA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(PCtxtHandle phContext,
Packit Service 5a9772
                                                               ULONG ulAttribute, void* pBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->QueryContextAttributesW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "QueryContextAttributesW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(PCtxtHandle phContext,
Packit Service 5a9772
                                                               ULONG ulAttribute, void* pBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->QueryContextAttributesA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "QueryContextAttributesA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(PCtxtHandle phContext,
Packit Service 5a9772
                                                                 HANDLE* phToken)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->QuerySecurityContextToken)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->QuerySecurityContextToken(phContext, phToken);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "QuerySecurityContextToken status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(PCtxtHandle phContext,
Packit Service 5a9772
                                                             ULONG ulAttribute, void* pBuffer,
Packit Service 5a9772
                                                             ULONG cbBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->SetContextAttributesW)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "SetContextAttributesW status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(PCtxtHandle phContext,
Packit Service 5a9772
                                                             ULONG ulAttribute, void* pBuffer,
Packit Service 5a9772
                                                             ULONG cbBuffer)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->SetContextAttributesA)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "SetContextAttributesA status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(PCtxtHandle phContext)
Packit 1fb8d4
{
Packit 1fb8d4
	SEC_CHAR* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableW* table;
Packit Service 5a9772
	Name = (SEC_CHAR*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableWByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->RevertSecurityContext)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->RevertSecurityContext(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "RevertSecurityContext status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* Message Support */
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(PCtxtHandle phContext,
Packit Service 5a9772
                                                      PSecBufferDesc pMessage, ULONG MessageSeqNo,
Packit Service 5a9772
                                                      PULONG pfQOP)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->DecryptMessage)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "DecryptMessage status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
Packit Service 5a9772
                                                      PSecBufferDesc pMessage, ULONG MessageSeqNo)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->EncryptMessage)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
Packit 1fb8d4
Packit 1fb8d4
	if (status != SEC_E_OK)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "EncryptMessage status %s [0x%08" PRIX32 "]", GetSecurityStatusString(status),
Packit Service 5a9772
		         status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
Packit Service 5a9772
                                                     PSecBufferDesc pMessage, ULONG MessageSeqNo)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->MakeSignature)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "MakeSignature status %s [0x%08" PRIX32 "]", GetSecurityStatusString(status),
Packit Service 5a9772
		          status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(PCtxtHandle phContext,
Packit Service 5a9772
                                                       PSecBufferDesc pMessage, ULONG MessageSeqNo,
Packit Service 5a9772
                                                       PULONG pfQOP)
Packit 1fb8d4
{
Packit 1fb8d4
	char* Name;
Packit 1fb8d4
	SECURITY_STATUS status;
Packit 1fb8d4
	SecurityFunctionTableA* table;
Packit Service 5a9772
	Name = (char*)sspi_SecureHandleGetUpperPointer(phContext);
Packit 1fb8d4
Packit 1fb8d4
	if (!Name)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	table = sspi_GetSecurityFunctionTableAByNameA(Name);
Packit 1fb8d4
Packit 1fb8d4
	if (!table)
Packit 1fb8d4
		return SEC_E_SECPKG_NOT_FOUND;
Packit 1fb8d4
Packit 1fb8d4
	if (!table->VerifySignature)
Packit 1fb8d4
		return SEC_E_UNSUPPORTED_FUNCTION;
Packit 1fb8d4
Packit 1fb8d4
	status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
Packit 1fb8d4
Packit 1fb8d4
	if (IsSecurityStatusError(status))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_WARN(TAG, "VerifySignature status %s [0x%08" PRIX32 "]",
Packit 1fb8d4
		          GetSecurityStatusString(status), status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static SecurityFunctionTableA winpr_SecurityFunctionTableA = {
Packit Service 5a9772
	1,                                 /* dwVersion */
Packit Service 5a9772
	winpr_EnumerateSecurityPackagesA,  /* EnumerateSecurityPackages */
Packit 1fb8d4
	winpr_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
Packit Service 5a9772
	winpr_AcquireCredentialsHandleA,   /* AcquireCredentialsHandle */
Packit Service 5a9772
	winpr_FreeCredentialsHandle,       /* FreeCredentialsHandle */
Packit Service 5a9772
	NULL,                              /* Reserved2 */
Packit Service 5a9772
	winpr_InitializeSecurityContextA,  /* InitializeSecurityContext */
Packit Service 5a9772
	winpr_AcceptSecurityContext,       /* AcceptSecurityContext */
Packit Service 5a9772
	winpr_CompleteAuthToken,           /* CompleteAuthToken */
Packit Service 5a9772
	winpr_DeleteSecurityContext,       /* DeleteSecurityContext */
Packit Service 5a9772
	winpr_ApplyControlToken,           /* ApplyControlToken */
Packit Service 5a9772
	winpr_QueryContextAttributesA,     /* QueryContextAttributes */
Packit Service 5a9772
	winpr_ImpersonateSecurityContext,  /* ImpersonateSecurityContext */
Packit Service 5a9772
	winpr_RevertSecurityContext,       /* RevertSecurityContext */
Packit Service 5a9772
	winpr_MakeSignature,               /* MakeSignature */
Packit Service 5a9772
	winpr_VerifySignature,             /* VerifySignature */
Packit Service 5a9772
	winpr_FreeContextBuffer,           /* FreeContextBuffer */
Packit Service 5a9772
	winpr_QuerySecurityPackageInfoA,   /* QuerySecurityPackageInfo */
Packit Service 5a9772
	NULL,                              /* Reserved3 */
Packit Service 5a9772
	NULL,                              /* Reserved4 */
Packit Service 5a9772
	winpr_ExportSecurityContext,       /* ExportSecurityContext */
Packit Service 5a9772
	winpr_ImportSecurityContextA,      /* ImportSecurityContext */
Packit Service 5a9772
	NULL,                              /* AddCredentials */
Packit Service 5a9772
	NULL,                              /* Reserved8 */
Packit Service 5a9772
	winpr_QuerySecurityContextToken,   /* QuerySecurityContextToken */
Packit Service 5a9772
	winpr_EncryptMessage,              /* EncryptMessage */
Packit Service 5a9772
	winpr_DecryptMessage,              /* DecryptMessage */
Packit Service 5a9772
	winpr_SetContextAttributesA,       /* SetContextAttributes */
Packit 1fb8d4
};
Packit 1fb8d4
Packit Service 5a9772
static SecurityFunctionTableW winpr_SecurityFunctionTableW = {
Packit Service 5a9772
	1,                                 /* dwVersion */
Packit Service 5a9772
	winpr_EnumerateSecurityPackagesW,  /* EnumerateSecurityPackages */
Packit 1fb8d4
	winpr_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
Packit Service 5a9772
	winpr_AcquireCredentialsHandleW,   /* AcquireCredentialsHandle */
Packit Service 5a9772
	winpr_FreeCredentialsHandle,       /* FreeCredentialsHandle */
Packit Service 5a9772
	NULL,                              /* Reserved2 */
Packit Service 5a9772
	winpr_InitializeSecurityContextW,  /* InitializeSecurityContext */
Packit Service 5a9772
	winpr_AcceptSecurityContext,       /* AcceptSecurityContext */
Packit Service 5a9772
	winpr_CompleteAuthToken,           /* CompleteAuthToken */
Packit Service 5a9772
	winpr_DeleteSecurityContext,       /* DeleteSecurityContext */
Packit Service 5a9772
	winpr_ApplyControlToken,           /* ApplyControlToken */
Packit Service 5a9772
	winpr_QueryContextAttributesW,     /* QueryContextAttributes */
Packit Service 5a9772
	winpr_ImpersonateSecurityContext,  /* ImpersonateSecurityContext */
Packit Service 5a9772
	winpr_RevertSecurityContext,       /* RevertSecurityContext */
Packit Service 5a9772
	winpr_MakeSignature,               /* MakeSignature */
Packit Service 5a9772
	winpr_VerifySignature,             /* VerifySignature */
Packit Service 5a9772
	winpr_FreeContextBuffer,           /* FreeContextBuffer */
Packit Service 5a9772
	winpr_QuerySecurityPackageInfoW,   /* QuerySecurityPackageInfo */
Packit Service 5a9772
	NULL,                              /* Reserved3 */
Packit Service 5a9772
	NULL,                              /* Reserved4 */
Packit Service 5a9772
	winpr_ExportSecurityContext,       /* ExportSecurityContext */
Packit Service 5a9772
	winpr_ImportSecurityContextW,      /* ImportSecurityContext */
Packit Service 5a9772
	NULL,                              /* AddCredentials */
Packit Service 5a9772
	NULL,                              /* Reserved8 */
Packit Service 5a9772
	winpr_QuerySecurityContextToken,   /* QuerySecurityContextToken */
Packit Service 5a9772
	winpr_EncryptMessage,              /* EncryptMessage */
Packit Service 5a9772
	winpr_DecryptMessage,              /* DecryptMessage */
Packit Service 5a9772
	winpr_SetContextAttributesW,       /* SetContextAttributes */
Packit 1fb8d4
};