2012-02-21 01:17:57 +04:00
|
|
|
/**
|
|
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
|
|
* Security Support Provider Interface (SSPI)
|
|
|
|
*
|
|
|
|
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <freerdp/utils/memory.h>
|
|
|
|
|
2012-03-06 02:23:22 +04:00
|
|
|
#include <freerdp/sspi/sspi.h>
|
2012-02-21 01:17:57 +04:00
|
|
|
|
2012-02-24 00:56:50 +04:00
|
|
|
#include "sspi.h"
|
|
|
|
|
2012-02-21 02:33:21 +04:00
|
|
|
/* Authentication Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374731/ */
|
2012-02-21 02:04:45 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
extern const SecPkgInfo NTLM_SecPkgInfo;
|
|
|
|
extern const SecPkgInfo CREDSSP_SecPkgInfo;
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
const SecurityFunctionTable SSPI_SecurityFunctionTable;
|
|
|
|
extern const SecurityFunctionTable NTLM_SecurityFunctionTable;
|
|
|
|
extern const SecurityFunctionTable CREDSSP_SecurityFunctionTable;
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
const SecPkgInfo* SecPkgInfo_LIST[] =
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
&NTLM_SecPkgInfo,
|
|
|
|
&CREDSSP_SecPkgInfo
|
2012-02-23 08:41:22 +04:00
|
|
|
};
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
struct _SecurityFunctionTable_NAME
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
|
|
|
char* Name;
|
2012-03-16 04:37:38 +04:00
|
|
|
const SecurityFunctionTable* SecurityFunctionTable;
|
2012-02-23 08:41:22 +04:00
|
|
|
};
|
2012-03-16 04:37:38 +04:00
|
|
|
typedef struct _SecurityFunctionTable_NAME SecurityFunctionTable_NAME;
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
const SecurityFunctionTable_NAME SecurityFunctionTable_NAME_LIST[] =
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
{ "NTLM", &NTLM_SecurityFunctionTable },
|
|
|
|
{ "CREDSSP", &CREDSSP_SecurityFunctionTable }
|
2012-02-23 08:41:22 +04:00
|
|
|
};
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
#define SecHandle_LOWER_MAX 0xFFFFFFFF
|
|
|
|
#define SecHandle_UPPER_MAX 0xFFFFFFFE
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
struct _CONTEXT_BUFFER_ALLOC_ENTRY
|
|
|
|
{
|
|
|
|
void* contextBuffer;
|
|
|
|
uint32 allocatorIndex;
|
|
|
|
};
|
|
|
|
typedef struct _CONTEXT_BUFFER_ALLOC_ENTRY CONTEXT_BUFFER_ALLOC_ENTRY;
|
|
|
|
|
|
|
|
struct _CONTEXT_BUFFER_ALLOC_TABLE
|
|
|
|
{
|
|
|
|
uint32 cEntries;
|
|
|
|
uint32 cMaxEntries;
|
|
|
|
CONTEXT_BUFFER_ALLOC_ENTRY* entries;
|
|
|
|
};
|
|
|
|
typedef struct _CONTEXT_BUFFER_ALLOC_TABLE CONTEXT_BUFFER_ALLOC_TABLE;
|
|
|
|
|
|
|
|
CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable;
|
|
|
|
|
|
|
|
void sspi_ContextBufferAllocTableNew()
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
ContextBufferAllocTable.cEntries = 0;
|
2012-02-25 00:35:48 +04:00
|
|
|
ContextBufferAllocTable.cMaxEntries = 4;
|
2012-02-25 00:00:49 +04:00
|
|
|
|
|
|
|
size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
|
|
|
|
|
|
|
|
ContextBufferAllocTable.entries = xzalloc(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sspi_ContextBufferAllocTableGrow()
|
|
|
|
{
|
|
|
|
size_t size;
|
|
|
|
ContextBufferAllocTable.cEntries = 0;
|
|
|
|
ContextBufferAllocTable.cMaxEntries *= 2;
|
|
|
|
|
|
|
|
size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
|
|
|
|
|
|
|
|
ContextBufferAllocTable.entries = xrealloc(ContextBufferAllocTable.entries, size);
|
|
|
|
memset((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], 0, size / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sspi_ContextBufferAllocTableFree()
|
|
|
|
{
|
|
|
|
ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
|
|
|
|
xfree(ContextBufferAllocTable.entries);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* sspi_ContextBufferAlloc(uint32 allocatorIndex, size_t size)
|
|
|
|
{
|
|
|
|
int index;
|
2012-02-25 00:35:48 +04:00
|
|
|
void* contextBuffer;
|
2012-02-25 00:00:49 +04:00
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
|
2012-02-25 00:00:49 +04:00
|
|
|
{
|
|
|
|
if (ContextBufferAllocTable.entries[index].contextBuffer == NULL)
|
|
|
|
{
|
2012-02-25 00:35:48 +04:00
|
|
|
contextBuffer = xzalloc(size);
|
2012-02-25 00:00:49 +04:00
|
|
|
ContextBufferAllocTable.cEntries++;
|
2012-02-25 00:35:48 +04:00
|
|
|
|
|
|
|
ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
|
2012-02-25 00:00:49 +04:00
|
|
|
ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
|
2012-02-25 00:35:48 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
return ContextBufferAllocTable.entries[index].contextBuffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* no available entry was found, the table needs to be grown */
|
|
|
|
|
|
|
|
sspi_ContextBufferAllocTableGrow();
|
|
|
|
|
|
|
|
/* the next call to sspi_ContextBufferAlloc() should now succeed */
|
|
|
|
|
|
|
|
return sspi_ContextBufferAlloc(allocatorIndex, size);
|
|
|
|
}
|
|
|
|
|
2012-02-25 00:35:48 +04:00
|
|
|
void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer);
|
|
|
|
void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer);
|
2012-02-25 00:00:49 +04:00
|
|
|
|
|
|
|
void sspi_ContextBufferFree(void* contextBuffer)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
uint32 allocatorIndex;
|
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
|
2012-02-25 00:00:49 +04:00
|
|
|
{
|
|
|
|
if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
|
|
|
|
{
|
2012-02-25 00:35:48 +04:00
|
|
|
contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
|
2012-02-25 00:00:49 +04:00
|
|
|
allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
|
|
|
|
|
|
|
|
ContextBufferAllocTable.cEntries--;
|
2012-02-25 00:35:48 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
ContextBufferAllocTable.entries[index].allocatorIndex = 0;
|
|
|
|
ContextBufferAllocTable.entries[index].contextBuffer = NULL;
|
|
|
|
|
|
|
|
switch (allocatorIndex)
|
|
|
|
{
|
|
|
|
case EnumerateSecurityPackagesIndex:
|
2012-02-25 00:35:48 +04:00
|
|
|
FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
|
2012-02-25 00:00:49 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QuerySecurityPackageInfoIndex:
|
2012-02-25 00:35:48 +04:00
|
|
|
FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
|
2012-02-25 00:00:49 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-24 00:56:50 +04:00
|
|
|
CREDENTIALS* sspi_CredentialsNew()
|
|
|
|
{
|
|
|
|
CREDENTIALS* credentials;
|
|
|
|
|
|
|
|
credentials = xnew(CREDENTIALS);
|
|
|
|
|
|
|
|
if (credentials != NULL)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return credentials;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sspi_CredentialsFree(CREDENTIALS* credentials)
|
|
|
|
{
|
|
|
|
if (!credentials)
|
|
|
|
return;
|
|
|
|
|
|
|
|
xfree(credentials);
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecBufferAlloc(SecBuffer* SecBuffer, size_t size)
|
2012-02-25 02:17:38 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
SecBuffer->cbBuffer = size;
|
|
|
|
SecBuffer->pvBuffer = xzalloc(size);
|
2012-02-25 02:17:38 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecBufferFree(SecBuffer* SecBuffer)
|
2012-02-25 02:17:38 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
SecBuffer->cbBuffer = 0;
|
|
|
|
xfree(SecBuffer->pvBuffer);
|
|
|
|
SecBuffer->pvBuffer = NULL;
|
2012-02-25 02:17:38 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SecHandle* sspi_SecureHandleAlloc()
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
SecHandle* handle = xmalloc(sizeof(SecHandle));
|
2012-02-24 06:26:00 +04:00
|
|
|
sspi_SecureHandleInit(handle);
|
2012-02-24 00:56:50 +04:00
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecureHandleInit(SecHandle* handle)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return;
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
memset(handle, 0xFF, sizeof(SecHandle));
|
2012-02-24 00:56:50 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecureHandleInvalidate(SecHandle* handle)
|
2012-02-24 06:26:00 +04:00
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sspi_SecureHandleInit(handle);
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void* sspi_SecureHandleGetLowerPointer(SecHandle* handle)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
void* pointer;
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pointer = (void*) ~((size_t) handle->dwLower);
|
|
|
|
|
|
|
|
return pointer;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecureHandleSetLowerPointer(SecHandle* handle, void* pointer)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return;
|
|
|
|
|
|
|
|
handle->dwLower = (uint32*) (~((size_t) pointer));
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void* sspi_SecureHandleGetUpperPointer(SecHandle* handle)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
void* pointer;
|
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pointer = (void*) ~((size_t) handle->dwUpper);
|
|
|
|
|
|
|
|
return pointer;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecureHandleSetUpperPointer(SecHandle* handle, void* pointer)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return;
|
|
|
|
|
|
|
|
handle->dwUpper = (uint32*) (~((size_t) pointer));
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
void sspi_SecureHandleFree(SecHandle* handle)
|
2012-02-24 00:56:50 +04:00
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return;
|
|
|
|
|
|
|
|
xfree(handle);
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* sspi_GetSecurityFunctionTableByName(const char* Name)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
|
|
|
int index;
|
|
|
|
uint32 cPackages;
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
cPackages = ARRAY_SIZE(SecPkgInfo_LIST);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) cPackages; index++)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
if (strcmp(Name, SecurityFunctionTable_NAME_LIST[index].Name) == 0)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
return (SecurityFunctionTable*) SecurityFunctionTable_NAME_LIST[index].SecurityFunctionTable;
|
2012-02-23 08:41:22 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
void sspi_GlobalInit()
|
|
|
|
{
|
|
|
|
sspi_ContextBufferAllocTableNew();
|
|
|
|
}
|
|
|
|
|
|
|
|
void sspi_GlobalFinish()
|
|
|
|
{
|
|
|
|
sspi_ContextBufferAllocTableFree();
|
|
|
|
}
|
|
|
|
|
2012-02-21 02:33:21 +04:00
|
|
|
/* Package Management */
|
2012-02-21 01:17:57 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS EnumerateSecurityPackages(uint32* pcPackages, SecPkgInfo** ppPackageInfo)
|
2012-02-21 01:17:57 +04:00
|
|
|
{
|
2012-02-23 08:41:22 +04:00
|
|
|
int index;
|
2012-02-25 00:00:49 +04:00
|
|
|
size_t size;
|
2012-02-23 08:41:22 +04:00
|
|
|
uint32 cPackages;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecPkgInfo* pPackageInfo;
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
cPackages = ARRAY_SIZE(SecPkgInfo_LIST);
|
|
|
|
size = sizeof(SecPkgInfo) * cPackages;
|
2012-02-25 00:00:49 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
pPackageInfo = (SecPkgInfo*) sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) cPackages; index++)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
pPackageInfo[index].fCapabilities = SecPkgInfo_LIST[index]->fCapabilities;
|
|
|
|
pPackageInfo[index].wVersion = SecPkgInfo_LIST[index]->wVersion;
|
|
|
|
pPackageInfo[index].wRPCID = SecPkgInfo_LIST[index]->wRPCID;
|
|
|
|
pPackageInfo[index].cbMaxToken = SecPkgInfo_LIST[index]->cbMaxToken;
|
|
|
|
pPackageInfo[index].Name = xstrdup(SecPkgInfo_LIST[index]->Name);
|
|
|
|
pPackageInfo[index].Comment = xstrdup(SecPkgInfo_LIST[index]->Comment);
|
2012-02-23 08:41:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
*(pcPackages) = cPackages;
|
|
|
|
*(ppPackageInfo) = pPackageInfo;
|
|
|
|
|
2012-02-21 01:17:57 +04:00
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-02-25 00:35:48 +04:00
|
|
|
void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer)
|
2012-02-25 00:00:49 +04:00
|
|
|
{
|
|
|
|
int index;
|
|
|
|
uint32 cPackages;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecPkgInfo* pPackageInfo = (SecPkgInfo*) contextBuffer;
|
2012-02-25 00:00:49 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
cPackages = ARRAY_SIZE(SecPkgInfo_LIST);
|
2012-02-25 00:00:49 +04:00
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) cPackages; index++)
|
2012-02-25 00:00:49 +04:00
|
|
|
{
|
|
|
|
if (pPackageInfo[index].Name)
|
|
|
|
xfree(pPackageInfo[index].Name);
|
|
|
|
|
|
|
|
if (pPackageInfo[index].Comment)
|
|
|
|
xfree(pPackageInfo[index].Comment);
|
|
|
|
}
|
|
|
|
|
|
|
|
xfree(pPackageInfo);
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* InitSecurityInterface(void)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
|
|
|
table = xnew(SecurityFunctionTable);
|
|
|
|
memcpy((void*) table, (void*) &SSPI_SecurityFunctionTable, sizeof(SecurityFunctionTable));
|
|
|
|
return table;
|
2012-02-21 02:33:21 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS QuerySecurityPackageInfo(char* pszPackageName, SecPkgInfo** ppPackageInfo)
|
2012-02-21 01:17:57 +04:00
|
|
|
{
|
2012-02-23 08:41:22 +04:00
|
|
|
int index;
|
2012-02-25 00:00:49 +04:00
|
|
|
size_t size;
|
2012-02-23 08:41:22 +04:00
|
|
|
uint32 cPackages;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecPkgInfo* pPackageInfo;
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
cPackages = ARRAY_SIZE(SecPkgInfo_LIST);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-02-28 19:01:47 +04:00
|
|
|
for (index = 0; index < (int) cPackages; index++)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
if (strcmp(pszPackageName, SecPkgInfo_LIST[index]->Name) == 0)
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
size = sizeof(SecPkgInfo);
|
|
|
|
pPackageInfo = (SecPkgInfo*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
pPackageInfo->fCapabilities = SecPkgInfo_LIST[index]->fCapabilities;
|
|
|
|
pPackageInfo->wVersion = SecPkgInfo_LIST[index]->wVersion;
|
|
|
|
pPackageInfo->wRPCID = SecPkgInfo_LIST[index]->wRPCID;
|
|
|
|
pPackageInfo->cbMaxToken = SecPkgInfo_LIST[index]->cbMaxToken;
|
|
|
|
pPackageInfo->Name = xstrdup(SecPkgInfo_LIST[index]->Name);
|
|
|
|
pPackageInfo->Comment = xstrdup(SecPkgInfo_LIST[index]->Comment);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
|
|
|
*(ppPackageInfo) = pPackageInfo;
|
|
|
|
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*(ppPackageInfo) = NULL;
|
|
|
|
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
2012-02-21 01:17:57 +04:00
|
|
|
}
|
|
|
|
|
2012-02-25 00:35:48 +04:00
|
|
|
void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer)
|
2012-02-25 00:00:49 +04:00
|
|
|
{
|
2012-03-16 04:37:38 +04:00
|
|
|
SecPkgInfo* pPackageInfo = (SecPkgInfo*) contextBuffer;
|
2012-02-25 00:35:48 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
if (pPackageInfo->Name)
|
|
|
|
xfree(pPackageInfo->Name);
|
|
|
|
|
|
|
|
if (pPackageInfo->Comment)
|
|
|
|
xfree(pPackageInfo->Comment);
|
|
|
|
|
|
|
|
xfree(pPackageInfo);
|
|
|
|
}
|
|
|
|
|
2012-02-21 02:04:45 +04:00
|
|
|
/* Credential Management */
|
|
|
|
|
|
|
|
SECURITY_STATUS AcquireCredentialsHandle(char* pszPrincipal, char* pszPackage,
|
|
|
|
uint32 fCredentialUse, void* pvLogonID, void* pAuthData, void* pGetKeyFn,
|
2012-03-16 04:37:38 +04:00
|
|
|
void* pvGetKeyArgument, CredHandle* phCredential, SEC_TIMESTAMP* ptsExpiry)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-23 08:41:22 +04:00
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table = sspi_GetSecurityFunctionTableByName(pszPackage);
|
2012-02-23 08:41:22 +04:00
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->AcquireCredentialsHandle == NULL)
|
2012-02-23 08:41:22 +04:00
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse,
|
|
|
|
pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS ExportSecurityContext(CtxtHandle* phContext, uint32 fFlags, SecBuffer* pPackedContext, void* pToken)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS FreeCredentialsHandle(CredHandle* phCredential)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-25 00:00:49 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-24 00:56:50 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
|
2012-02-24 00:56:50 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
2012-02-24 00:56:50 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
2012-02-24 00:56:50 +04:00
|
|
|
|
2012-02-25 00:00:49 +04:00
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
2012-02-24 00:56:50 +04:00
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->FreeCredentialsHandle == NULL)
|
2012-02-25 00:00:49 +04:00
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->FreeCredentialsHandle(phCredential);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS ImportSecurityContext(char* pszPackage, SecBuffer* pPackedContext, void* pToken, CtxtHandle* phContext)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS QueryCredentialsAttributes(CredHandle* phCredential, uint32 ulAttribute, void* pBuffer)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
2012-02-24 00:56:50 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-24 00:56:50 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->QueryCredentialsAttributes == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
2012-02-24 00:56:50 +04:00
|
|
|
status = table->QueryCredentialsAttributes(phCredential, ulAttribute, pBuffer);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:33:21 +04:00
|
|
|
}
|
|
|
|
|
2012-02-21 02:04:45 +04:00
|
|
|
/* Context Management */
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS AcceptSecurityContext(CredHandle* phCredential, CtxtHandle* phContext,
|
|
|
|
SecBufferDesc* pInput, uint32 fContextReq, uint32 TargetDataRep, CtxtHandle* phNewContext,
|
|
|
|
SecBufferDesc* pOutput, uint32* pfContextAttr, SEC_TIMESTAMP* ptsTimeStamp)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-03-05 06:56:41 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-03-05 06:56:41 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
if (table->AcceptSecurityContext == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq,
|
|
|
|
TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS ApplyControlToken(CtxtHandle* phContext, SecBufferDesc* pInput)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS CompleteAuthToken(CtxtHandle* phContext, SecBufferDesc* pToken)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS DeleteSecurityContext(CtxtHandle* phContext)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
2012-03-16 21:12:49 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
|
|
|
SecurityFunctionTable* table;
|
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
if (table->DeleteSecurityContext == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->DeleteSecurityContext(phContext);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:33:21 +04:00
|
|
|
}
|
|
|
|
|
2012-02-21 01:17:57 +04:00
|
|
|
SECURITY_STATUS FreeContextBuffer(void* pvContextBuffer)
|
|
|
|
{
|
2012-02-25 00:00:49 +04:00
|
|
|
if (!pvContextBuffer)
|
|
|
|
return SEC_E_INVALID_HANDLE;
|
|
|
|
|
|
|
|
sspi_ContextBufferFree(pvContextBuffer);
|
2012-02-21 01:17:57 +04:00
|
|
|
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
2012-02-21 02:04:45 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS ImpersonateSecurityContext(CtxtHandle* phContext)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS InitializeSecurityContext(CredHandle* phCredential, CtxtHandle* phContext,
|
2012-02-21 02:04:45 +04:00
|
|
|
char* pszTargetName, uint32 fContextReq, uint32 Reserved1, uint32 TargetDataRep,
|
2012-03-16 04:37:38 +04:00
|
|
|
SecBufferDesc* pInput, uint32 Reserved2, CtxtHandle* phNewContext,
|
|
|
|
SecBufferDesc* pOutput, uint32* pfContextAttr, SEC_TIMESTAMP* ptsExpiry)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-24 00:56:50 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-24 00:56:50 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->InitializeSecurityContext == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
2012-02-24 00:56:50 +04:00
|
|
|
status = table->InitializeSecurityContext(phCredential, phContext,
|
|
|
|
pszTargetName, fContextReq, Reserved1, TargetDataRep,
|
|
|
|
pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS QueryContextAttributes(CtxtHandle* phContext, uint32 ulAttribute, void* pBuffer)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-27 08:41:59 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-27 08:41:59 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
if (table->QueryContextAttributes == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->QueryContextAttributes(phContext, ulAttribute, pBuffer);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS QuerySecurityContextToken(CtxtHandle* phContext, void* phToken)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS SetContextAttributes(CtxtHandle* phContext, uint32 ulAttribute, void* pBuffer, uint32 cbBuffer)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS RevertSecurityContext(CtxtHandle* phContext)
|
2012-02-21 02:33:21 +04:00
|
|
|
{
|
|
|
|
return SEC_E_OK;
|
|
|
|
}
|
|
|
|
|
2012-02-21 02:04:45 +04:00
|
|
|
/* Message Support */
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS DecryptMessage(CtxtHandle* phContext, SecBufferDesc* pMessage, uint32 MessageSeqNo, uint32* pfQOP)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-27 07:08:43 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-27 07:08:43 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->DecryptMessage == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
2012-02-27 07:08:43 +04:00
|
|
|
status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS EncryptMessage(CtxtHandle* phContext, uint32 fQOP, SecBufferDesc* pMessage, uint32 MessageSeqNo)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-27 05:07:42 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-27 05:07:42 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
2012-02-27 08:41:59 +04:00
|
|
|
if (table->EncryptMessage == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
2012-02-27 05:07:42 +04:00
|
|
|
status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS MakeSignature(CtxtHandle* phContext, uint32 fQOP, SecBufferDesc* pMessage, uint32 MessageSeqNo)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-27 08:41:59 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-27 08:41:59 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
if (table->MakeSignature == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
SECURITY_STATUS VerifySignature(CtxtHandle* phContext, SecBufferDesc* pMessage, uint32 MessageSeqNo, uint32* pfQOP)
|
2012-02-21 02:04:45 +04:00
|
|
|
{
|
2012-02-27 08:41:59 +04:00
|
|
|
char* Name;
|
|
|
|
SECURITY_STATUS status;
|
2012-03-16 04:37:38 +04:00
|
|
|
SecurityFunctionTable* table;
|
2012-02-27 08:41:59 +04:00
|
|
|
|
|
|
|
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
|
|
|
|
|
|
|
|
if (!Name)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
table = sspi_GetSecurityFunctionTableByName(Name);
|
|
|
|
|
|
|
|
if (!table)
|
|
|
|
return SEC_E_SECPKG_NOT_FOUND;
|
|
|
|
|
|
|
|
if (table->VerifySignature == NULL)
|
|
|
|
return SEC_E_UNSUPPORTED_FUNCTION;
|
|
|
|
|
|
|
|
status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
|
|
|
|
|
|
|
|
return status;
|
2012-02-21 02:04:45 +04:00
|
|
|
}
|
2012-02-23 08:41:22 +04:00
|
|
|
|
2012-03-16 04:37:38 +04:00
|
|
|
const SecurityFunctionTable SSPI_SecurityFunctionTable =
|
2012-02-23 08:41:22 +04:00
|
|
|
{
|
|
|
|
1, /* dwVersion */
|
|
|
|
EnumerateSecurityPackages, /* EnumerateSecurityPackages */
|
|
|
|
NULL, /* Reserved1 */
|
|
|
|
QueryCredentialsAttributes, /* QueryCredentialsAttributes */
|
|
|
|
AcquireCredentialsHandle, /* AcquireCredentialsHandle */
|
|
|
|
FreeCredentialsHandle, /* FreeCredentialsHandle */
|
|
|
|
NULL, /* Reserved2 */
|
|
|
|
InitializeSecurityContext, /* InitializeSecurityContext */
|
|
|
|
AcceptSecurityContext, /* AcceptSecurityContext */
|
|
|
|
CompleteAuthToken, /* CompleteAuthToken */
|
|
|
|
DeleteSecurityContext, /* DeleteSecurityContext */
|
|
|
|
ApplyControlToken, /* ApplyControlToken */
|
|
|
|
QueryContextAttributes, /* QueryContextAttributes */
|
|
|
|
ImpersonateSecurityContext, /* ImpersonateSecurityContext */
|
|
|
|
RevertSecurityContext, /* RevertSecurityContext */
|
|
|
|
MakeSignature, /* MakeSignature */
|
|
|
|
VerifySignature, /* VerifySignature */
|
|
|
|
FreeContextBuffer, /* FreeContextBuffer */
|
|
|
|
QuerySecurityPackageInfo, /* QuerySecurityPackageInfo */
|
|
|
|
NULL, /* Reserved3 */
|
|
|
|
NULL, /* Reserved4 */
|
|
|
|
ExportSecurityContext, /* ExportSecurityContext */
|
|
|
|
ImportSecurityContext, /* ImportSecurityContext */
|
|
|
|
NULL, /* AddCredentials */
|
|
|
|
NULL, /* Reserved8 */
|
|
|
|
QuerySecurityContextToken, /* QuerySecurityContextToken */
|
|
|
|
EncryptMessage, /* EncryptMessage */
|
|
|
|
DecryptMessage, /* DecryptMessage */
|
|
|
|
SetContextAttributes, /* SetContextAttributes */
|
|
|
|
};
|