921 lines
24 KiB
C
921 lines
24 KiB
C
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
||
|
//
|
||
|
// File: certmap.c
|
||
|
//
|
||
|
// Contents: Routines to call appropriate mapper, be it the system
|
||
|
// default one (in the LSA process) or an application one (in
|
||
|
// the application process).
|
||
|
//
|
||
|
// Classes:
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// History: 12-23-96 jbanes Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <spbase.h>
|
||
|
|
||
|
DWORD
|
||
|
WINAPI
|
||
|
SslReferenceMapper(HMAPPER *phMapper)
|
||
|
{
|
||
|
DWORD dwResult;
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
SECURITY_STATUS scRet;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(-1);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
return phMapper->m_vtable->ReferenceMapper(phMapper);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = 0;
|
||
|
Input.pvBuffer = NULL;
|
||
|
|
||
|
scRet = PerformApplicationCallback( SCH_REFERENCE_MAPPER_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
TRUE,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
TRUE);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x referencing mapper\n", scRet));
|
||
|
return SP_LOG_RESULT(scRet);
|
||
|
}
|
||
|
|
||
|
SP_ASSERT(Output.cbBuffer == sizeof(DWORD));
|
||
|
|
||
|
dwResult = *(PDWORD)(Output.pvBuffer);
|
||
|
|
||
|
SPExternalFree(Output.pvBuffer);
|
||
|
|
||
|
return dwResult;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
WINAPI
|
||
|
SslDereferenceMapper(HMAPPER *phMapper)
|
||
|
{
|
||
|
DWORD dwResult;
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
SECURITY_STATUS scRet;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(0);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
return phMapper->m_vtable->DeReferenceMapper(phMapper);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = 0;
|
||
|
Input.pvBuffer = NULL;
|
||
|
|
||
|
scRet = PerformApplicationCallback( SCH_REFERENCE_MAPPER_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
FALSE,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
TRUE);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x dereferencing mapper\n", scRet));
|
||
|
return SP_LOG_RESULT(scRet);
|
||
|
}
|
||
|
|
||
|
SP_ASSERT(Output.cbBuffer == sizeof(DWORD));
|
||
|
|
||
|
dwResult = *(PDWORD)(Output.pvBuffer);
|
||
|
|
||
|
SPExternalFree(Output.pvBuffer);
|
||
|
|
||
|
return dwResult;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ReferenceMapperCallback
|
||
|
//
|
||
|
// Synopsis: Reference (or dereference) the application mapper.
|
||
|
//
|
||
|
// Arguments: [fReference] -- Whether to reference or dereference.
|
||
|
// [dwArg2] -- Not used.
|
||
|
// [pInput] -- HMAPPER structure.
|
||
|
// [pOutput] -- DWORD reference count.
|
||
|
//
|
||
|
// History: 10-17-97 jbanes Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SECURITY_STATUS
|
||
|
ReferenceMapperCallback(
|
||
|
ULONG_PTR Mapper,
|
||
|
ULONG_PTR fReference,
|
||
|
SecBuffer *pInput,
|
||
|
SecBuffer *pOutput)
|
||
|
{
|
||
|
DWORD dwResult;
|
||
|
HMAPPER *phMapper;
|
||
|
|
||
|
if(!SchannelInit(TRUE))
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
DebugLog((DEB_TRACE, "ReferenceMapperCallback\n"));
|
||
|
|
||
|
phMapper = (HMAPPER *)Mapper;
|
||
|
|
||
|
// Perform reference counting.
|
||
|
try
|
||
|
{
|
||
|
if(fReference)
|
||
|
{
|
||
|
dwResult = phMapper->m_vtable->ReferenceMapper(phMapper);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwResult = phMapper->m_vtable->DeReferenceMapper(phMapper);
|
||
|
}
|
||
|
}
|
||
|
except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
}
|
||
|
|
||
|
// Build output buffer
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = sizeof(DWORD);
|
||
|
pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
|
||
|
if(pOutput->pvBuffer == NULL)
|
||
|
{
|
||
|
return SEC_E_INSUFFICIENT_MEMORY;
|
||
|
}
|
||
|
|
||
|
*(DWORD *)(pOutput->pvBuffer) = dwResult;
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
SECURITY_STATUS
|
||
|
WINAPI
|
||
|
SslGetMapperIssuerList(
|
||
|
HMAPPER * phMapper, // in
|
||
|
BYTE ** ppIssuerList, // out
|
||
|
DWORD * pcbIssuerList) // out
|
||
|
{
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
SECURITY_STATUS Status;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
|
||
|
Status = phMapper->m_vtable->GetIssuerList(phMapper,
|
||
|
0,
|
||
|
NULL,
|
||
|
pcbIssuerList);
|
||
|
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
{
|
||
|
return SP_LOG_RESULT(Status);
|
||
|
}
|
||
|
|
||
|
*ppIssuerList = SPExternalAlloc(*pcbIssuerList);
|
||
|
if(*ppIssuerList == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
|
||
|
}
|
||
|
|
||
|
Status = phMapper->m_vtable->GetIssuerList(phMapper,
|
||
|
0,
|
||
|
*ppIssuerList,
|
||
|
pcbIssuerList);
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
{
|
||
|
SPExternalFree(*ppIssuerList);
|
||
|
return SP_LOG_RESULT(Status);
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = 0;
|
||
|
Input.pvBuffer = NULL;
|
||
|
|
||
|
Status = PerformApplicationCallback( SCH_GET_MAPPER_ISSUER_LIST_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
0,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
TRUE);
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x getting mapper issuer list\n", Status));
|
||
|
|
||
|
*ppIssuerList = NULL;
|
||
|
*pcbIssuerList = 0;
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
*ppIssuerList = Output.pvBuffer;
|
||
|
*pcbIssuerList = Output.cbBuffer;
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetMapperIssuerListCallback
|
||
|
//
|
||
|
// Synopsis: Query the application mapper for the list of trusted CAs.
|
||
|
//
|
||
|
// Arguments: [pIssuerList] -- Pointer to LSA buffer.
|
||
|
// [cbIssuerList] -- Size of LSA buffer.
|
||
|
// [pInput] -- HMAPPER structure.
|
||
|
// [pOutput] -- Issuer list.
|
||
|
//
|
||
|
// History: 10-17-97 jbanes Created
|
||
|
//
|
||
|
// Notes: The format of the output buffer is as follows:
|
||
|
//
|
||
|
// BYTE rgbIssuerList;
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SECURITY_STATUS
|
||
|
GetMapperIssuerListCallback(
|
||
|
ULONG_PTR Mapper,
|
||
|
ULONG_PTR dwArg2,
|
||
|
SecBuffer *pInput,
|
||
|
SecBuffer *pOutput)
|
||
|
{
|
||
|
HMAPPER * phMapper;
|
||
|
DWORD cbIssuerList;
|
||
|
DWORD Status;
|
||
|
|
||
|
if(!SchannelInit(TRUE))
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
DebugLog((DEB_TRACE, "GetMapperIssuerListCallback\n"));
|
||
|
|
||
|
phMapper = (HMAPPER *)Mapper;
|
||
|
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = 0;
|
||
|
pOutput->pvBuffer = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
Status = phMapper->m_vtable->GetIssuerList(phMapper,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&cbIssuerList);
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
{
|
||
|
SP_LOG_RESULT(Status);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
pOutput->cbBuffer = cbIssuerList;
|
||
|
pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
|
||
|
if(pOutput->pvBuffer == NULL)
|
||
|
{
|
||
|
Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
Status = phMapper->m_vtable->GetIssuerList(phMapper,
|
||
|
NULL,
|
||
|
pOutput->pvBuffer,
|
||
|
&cbIssuerList);
|
||
|
if(!NT_SUCCESS(Status))
|
||
|
{
|
||
|
SP_LOG_RESULT(Status);
|
||
|
goto error;
|
||
|
}
|
||
|
}
|
||
|
except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
Status = SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
|
||
|
error:
|
||
|
|
||
|
if(pOutput->pvBuffer)
|
||
|
{
|
||
|
FreeExtVirtualAlloc(pOutput->pvBuffer, pOutput->cbBuffer);
|
||
|
pOutput->pvBuffer = NULL;
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
SECURITY_STATUS
|
||
|
WINAPI
|
||
|
SslGetMapperChallenge(
|
||
|
HMAPPER * phMapper, // in
|
||
|
BYTE * pAuthenticatorId, // in
|
||
|
DWORD cbAuthenticatorId, // in
|
||
|
BYTE * pChallenge, // out
|
||
|
DWORD * pcbChallenge) // out
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
|
||
|
}
|
||
|
|
||
|
|
||
|
SECURITY_STATUS
|
||
|
WINAPI
|
||
|
SslMapCredential(
|
||
|
HMAPPER * phMapper, // in
|
||
|
DWORD dwCredentialType, // in
|
||
|
PCCERT_CONTEXT pCredential, // in
|
||
|
PCCERT_CONTEXT pAuthority, // in
|
||
|
HLOCATOR * phLocator) // out
|
||
|
{
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
PBYTE pbBuffer;
|
||
|
DWORD cbCredential;
|
||
|
DWORD cbAuthority;
|
||
|
SECURITY_STATUS scRet;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
scRet = phMapper->m_vtable->MapCredential(phMapper,
|
||
|
dwCredentialType,
|
||
|
pCredential,
|
||
|
pAuthority,
|
||
|
phLocator);
|
||
|
return MapWinTrustError(scRet, SEC_E_NO_IMPERSONATION, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
// Determine the size of the serialized cert contexts.
|
||
|
scRet = SerializeCertContext(pCredential,
|
||
|
NULL,
|
||
|
&cbCredential);
|
||
|
if(FAILED(scRet))
|
||
|
{
|
||
|
return SP_LOG_RESULT(scRet);
|
||
|
}
|
||
|
if(pAuthority)
|
||
|
{
|
||
|
if(!CertSerializeCertificateStoreElement(
|
||
|
pAuthority,
|
||
|
0, NULL,
|
||
|
&cbAuthority))
|
||
|
{
|
||
|
return SP_LOG_RESULT(GetLastError());
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cbAuthority = 0;
|
||
|
}
|
||
|
|
||
|
// Allocate memory for the input buffer.
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = sizeof(DWORD) + cbCredential +
|
||
|
sizeof(DWORD) + cbAuthority;
|
||
|
Input.pvBuffer = LocalAlloc(LMEM_FIXED, Input.cbBuffer);
|
||
|
if(Input.pvBuffer == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
|
||
|
}
|
||
|
|
||
|
// Build the input buffer.
|
||
|
pbBuffer = Input.pvBuffer;
|
||
|
|
||
|
*(PDWORD)pbBuffer = cbCredential;
|
||
|
pbBuffer += sizeof(DWORD);
|
||
|
|
||
|
*(PDWORD)pbBuffer = cbAuthority;
|
||
|
pbBuffer += sizeof(DWORD);
|
||
|
|
||
|
scRet = SerializeCertContext(pCredential,
|
||
|
pbBuffer,
|
||
|
&cbCredential);
|
||
|
if(FAILED(scRet))
|
||
|
{
|
||
|
LocalFree(Input.pvBuffer);
|
||
|
return SP_LOG_RESULT(scRet);
|
||
|
}
|
||
|
pbBuffer += cbCredential;
|
||
|
|
||
|
if(pAuthority)
|
||
|
{
|
||
|
if(!CertSerializeCertificateStoreElement(
|
||
|
pAuthority,
|
||
|
0,
|
||
|
pbBuffer,
|
||
|
&cbAuthority))
|
||
|
{
|
||
|
scRet = SP_LOG_RESULT(GetLastError());
|
||
|
LocalFree(Input.pvBuffer);
|
||
|
return scRet;
|
||
|
}
|
||
|
pbBuffer += cbAuthority;
|
||
|
}
|
||
|
|
||
|
SP_ASSERT(pbBuffer - (PBYTE)Input.pvBuffer == (INT)Input.cbBuffer);
|
||
|
|
||
|
|
||
|
scRet = PerformApplicationCallback( SCH_MAP_CREDENTIAL_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
dwCredentialType,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
TRUE);
|
||
|
LocalFree(Input.pvBuffer);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x mapping credential\n", scRet));
|
||
|
return scRet;
|
||
|
}
|
||
|
|
||
|
SP_ASSERT(Output.cbBuffer == sizeof(HLOCATOR));
|
||
|
CopyMemory(phLocator, Output.pvBuffer, sizeof(HLOCATOR));
|
||
|
|
||
|
SPExternalFree(Output.pvBuffer);
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: MapCredentialCallback
|
||
|
//
|
||
|
// Synopsis: Maps the specified certificate to an NT user account, via
|
||
|
// an application-installed certificate mapper.
|
||
|
//
|
||
|
// Arguments: [dwCredentialType] -- Credential type.
|
||
|
// [dwArg2] -- Not used.
|
||
|
// [pInput] -- See notes.
|
||
|
// [pOutput] -- Returned locator.
|
||
|
//
|
||
|
// History: 12-29-97 jbanes Created
|
||
|
//
|
||
|
// Notes: The format of the input buffer is:
|
||
|
//
|
||
|
// DWORD cbCredential;
|
||
|
// DWORD cbAuthority;
|
||
|
// BYTE rgbCredential[cbCredential];
|
||
|
// BYTE rgbAuthority[cbAuthority];
|
||
|
//
|
||
|
// The credential and authority fields consist of serialized
|
||
|
// CERT_CONTEXT structures.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SECURITY_STATUS
|
||
|
MapCredentialCallback(
|
||
|
ULONG_PTR Mapper,
|
||
|
ULONG_PTR dwCredentialType,
|
||
|
SecBuffer *pInput,
|
||
|
SecBuffer *pOutput)
|
||
|
{
|
||
|
HMAPPER * phMapper;
|
||
|
PCCERT_CONTEXT pCredential = NULL;
|
||
|
PCCERT_CONTEXT pAuthority = NULL;
|
||
|
SECURITY_STATUS scRet;
|
||
|
DWORD cbCredential;
|
||
|
DWORD cbAuthority;
|
||
|
PBYTE pbBuffer;
|
||
|
HLOCATOR hLocator;
|
||
|
|
||
|
|
||
|
if(!SchannelInit(TRUE))
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
DebugLog((DEB_TRACE, "MapCredentialCallback\n"));
|
||
|
|
||
|
phMapper = (HMAPPER *)Mapper;
|
||
|
|
||
|
|
||
|
// Initialize output buffer.
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = 0;
|
||
|
pOutput->pvBuffer = NULL;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Parse input buffer
|
||
|
//
|
||
|
|
||
|
pbBuffer = pInput->pvBuffer;
|
||
|
|
||
|
if(pInput->cbBuffer < sizeof(DWORD) * 2)
|
||
|
{
|
||
|
scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
cbCredential = *(PDWORD)pbBuffer;
|
||
|
pbBuffer += sizeof(DWORD);
|
||
|
|
||
|
cbAuthority = *(PDWORD)pbBuffer;
|
||
|
pbBuffer += sizeof(DWORD);
|
||
|
|
||
|
if(pInput->cbBuffer < sizeof(DWORD) * 2 + cbCredential + cbAuthority)
|
||
|
{
|
||
|
scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
// Deserialize "credential" certificate context.
|
||
|
scRet = DeserializeCertContext(&pCredential,
|
||
|
pbBuffer,
|
||
|
cbCredential);
|
||
|
if(FAILED(scRet))
|
||
|
{
|
||
|
scRet = SP_LOG_RESULT(scRet);
|
||
|
goto done;
|
||
|
}
|
||
|
pbBuffer += cbCredential;
|
||
|
|
||
|
// Deserialize "authority" certificate context.
|
||
|
if(cbAuthority && pCredential->hCertStore)
|
||
|
{
|
||
|
if(!CertAddSerializedElementToStore(pCredential->hCertStore,
|
||
|
pbBuffer + sizeof(DWORD),
|
||
|
*(DWORD *)pbBuffer,
|
||
|
CERT_STORE_ADD_USE_EXISTING,
|
||
|
0,
|
||
|
CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
|
||
|
NULL,
|
||
|
&pAuthority))
|
||
|
{
|
||
|
scRet = SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Call application mapper.
|
||
|
//
|
||
|
|
||
|
try
|
||
|
{
|
||
|
scRet = phMapper->m_vtable->MapCredential(phMapper,
|
||
|
(DWORD)dwCredentialType,
|
||
|
pCredential,
|
||
|
pAuthority,
|
||
|
&hLocator);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
// Mapping was unsuccessful.
|
||
|
scRet = MapWinTrustError(scRet, SEC_E_NO_IMPERSONATION, 0);
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Build output buffer
|
||
|
//
|
||
|
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = sizeof(HLOCATOR);
|
||
|
pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
|
||
|
if(pOutput->pvBuffer == NULL)
|
||
|
{
|
||
|
scRet = SEC_E_INSUFFICIENT_MEMORY;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
*(HLOCATOR *)(pOutput->pvBuffer) = hLocator;
|
||
|
|
||
|
scRet = SEC_E_OK;
|
||
|
|
||
|
|
||
|
done:
|
||
|
|
||
|
if(pCredential)
|
||
|
{
|
||
|
CertFreeCertificateContext(pCredential);
|
||
|
}
|
||
|
if(pAuthority)
|
||
|
{
|
||
|
CertFreeCertificateContext(pAuthority);
|
||
|
}
|
||
|
|
||
|
return scRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
SECURITY_STATUS
|
||
|
WINAPI
|
||
|
SslCloseLocator(
|
||
|
HMAPPER * phMapper, // in
|
||
|
HLOCATOR hLocator) // in
|
||
|
{
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
SECURITY_STATUS scRet;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
return phMapper->m_vtable->CloseLocator(phMapper,
|
||
|
hLocator);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = 0;
|
||
|
Input.pvBuffer = NULL;
|
||
|
|
||
|
scRet = PerformApplicationCallback( SCH_CLOSE_LOCATOR_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
(ULONG_PTR)hLocator,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
FALSE);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x closing locator\n", scRet));
|
||
|
return scRet;
|
||
|
}
|
||
|
|
||
|
SP_ASSERT(Output.cbBuffer == 0);
|
||
|
|
||
|
return scRet;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CloseLocatorCallback
|
||
|
//
|
||
|
// Synopsis: Reference (or dereference) the application mapper.
|
||
|
//
|
||
|
// Arguments: [hLocator] -- Handle to locator.
|
||
|
// [dwArg2] -- Not used.
|
||
|
// [pInput] -- HMAPPER structure.
|
||
|
// [pOutput] -- Not used.
|
||
|
//
|
||
|
// History: 12-28-97 jbanes Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SECURITY_STATUS
|
||
|
CloseLocatorCallback(
|
||
|
ULONG_PTR Mapper,
|
||
|
ULONG_PTR hLocator,
|
||
|
SecBuffer *pInput,
|
||
|
SecBuffer *pOutput)
|
||
|
{
|
||
|
HMAPPER *phMapper;
|
||
|
SECURITY_STATUS Status;
|
||
|
|
||
|
if(!SchannelInit(TRUE))
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
DebugLog((DEB_TRACE, "CloseLocatorCallback\n"));
|
||
|
|
||
|
phMapper = (HMAPPER *)Mapper;
|
||
|
|
||
|
// Close the locator.
|
||
|
try
|
||
|
{
|
||
|
Status = phMapper->m_vtable->CloseLocator(phMapper, hLocator);
|
||
|
}
|
||
|
except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
}
|
||
|
|
||
|
// Build output buffer
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = 0;
|
||
|
pOutput->pvBuffer = NULL;
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
SECURITY_STATUS
|
||
|
WINAPI
|
||
|
SslQueryMappedCredentialAttributes(
|
||
|
HMAPPER * phMapper, // in
|
||
|
HLOCATOR hLocator, // in
|
||
|
DWORD dwAttribute, // in
|
||
|
PVOID * ppBuffer) // out
|
||
|
{
|
||
|
SecBuffer Input;
|
||
|
SecBuffer Output;
|
||
|
SECURITY_STATUS scRet;
|
||
|
|
||
|
if(phMapper == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
}
|
||
|
|
||
|
if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
|
||
|
{
|
||
|
// System mapper.
|
||
|
return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Application mapper.
|
||
|
|
||
|
Input.BufferType = SECBUFFER_DATA;
|
||
|
Input.cbBuffer = sizeof(DWORD);
|
||
|
Input.pvBuffer = &dwAttribute;
|
||
|
|
||
|
scRet = PerformApplicationCallback( SCH_GET_MAPPER_ATTRIBUTES_CALLBACK,
|
||
|
(ULONG_PTR)phMapper->m_Reserved1,
|
||
|
hLocator,
|
||
|
&Input,
|
||
|
&Output,
|
||
|
TRUE);
|
||
|
if(!NT_SUCCESS(scRet))
|
||
|
{
|
||
|
DebugLog((DEB_ERROR, "Error 0x%x querying mapped attribute.\n", scRet));
|
||
|
return scRet;
|
||
|
}
|
||
|
|
||
|
if(Output.cbBuffer != sizeof(PVOID))
|
||
|
{
|
||
|
SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
*ppBuffer = *(PVOID *)Output.pvBuffer;
|
||
|
|
||
|
SPExternalFree(Output.pvBuffer); //this is allocated by SPExternalAlloc()
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: QueryMappedCredAttributesCallback
|
||
|
//
|
||
|
// Synopsis: Queries the application mapper for the specified property.
|
||
|
//
|
||
|
// Arguments: [hLocator] -- Handle to locator.
|
||
|
// [dwAttribute] -- Attribute to query.
|
||
|
// [pInput] -- HMAPPER structure.
|
||
|
// [pOutput] -- Pointer to attribute data (in the
|
||
|
// application's address space).
|
||
|
//
|
||
|
// History: 03-16-98 jbanes Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
SECURITY_STATUS
|
||
|
QueryMappedCredAttributesCallback(
|
||
|
ULONG_PTR Mapper,
|
||
|
ULONG_PTR hLocator,
|
||
|
SecBuffer *pInput,
|
||
|
SecBuffer *pOutput)
|
||
|
{
|
||
|
HMAPPER * phMapper;
|
||
|
DWORD dwAttribute;
|
||
|
PVOID pvBuffer;
|
||
|
DWORD cbBuffer;
|
||
|
DWORD Status;
|
||
|
|
||
|
if(!SchannelInit(TRUE))
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
|
||
|
}
|
||
|
|
||
|
DebugLog((DEB_TRACE, "QueryMappedCredAttributesCallback\n"));
|
||
|
|
||
|
phMapper = (HMAPPER *)Mapper;
|
||
|
|
||
|
// Parse input buffer
|
||
|
SP_ASSERT(pInput->cbBuffer == sizeof(DWORD));
|
||
|
dwAttribute = *(DWORD *)pInput->pvBuffer;
|
||
|
|
||
|
// Query propery.
|
||
|
try
|
||
|
{
|
||
|
// Determine buffer size.
|
||
|
Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
|
||
|
phMapper,
|
||
|
hLocator,
|
||
|
dwAttribute,
|
||
|
NULL,
|
||
|
&cbBuffer);
|
||
|
if(FAILED(Status))
|
||
|
{
|
||
|
return SP_LOG_RESULT(Status);
|
||
|
}
|
||
|
|
||
|
// Allocate memory. This gets freed by the APPLICATION with FreeSecurityBuffer() call
|
||
|
// SPExternalAlloc() for the above reason!!!!
|
||
|
|
||
|
pvBuffer = SPExternalAlloc(cbBuffer);
|
||
|
if(pvBuffer == NULL)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
|
||
|
}
|
||
|
|
||
|
// Read propery.
|
||
|
Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
|
||
|
phMapper,
|
||
|
hLocator,
|
||
|
dwAttribute,
|
||
|
pvBuffer,
|
||
|
&cbBuffer);
|
||
|
if(FAILED(Status))
|
||
|
{
|
||
|
SPExternalFree(pvBuffer);
|
||
|
return SP_LOG_RESULT(Status);
|
||
|
}
|
||
|
}
|
||
|
except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
|
||
|
}
|
||
|
|
||
|
// Build output buffer
|
||
|
pOutput->BufferType = SECBUFFER_DATA;
|
||
|
pOutput->cbBuffer = sizeof(PVOID);
|
||
|
pOutput->pvBuffer = PvExtVirtualAlloc(pOutput->cbBuffer);
|
||
|
if(pOutput->pvBuffer == NULL)
|
||
|
{
|
||
|
SPExternalFree(pvBuffer);
|
||
|
return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
|
||
|
}
|
||
|
|
||
|
*(PVOID *)(pOutput->pvBuffer) = pvBuffer;
|
||
|
|
||
|
return SEC_E_OK;
|
||
|
}
|
||
|
|