792 lines
25 KiB
C
792 lines
25 KiB
C
// Copyright (C) 2002 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS"
|
|
// WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
// TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY
|
|
// AND/OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// Date - 10/08/2002
|
|
// Author - Sanj Surati
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
//
|
|
// SPNEGO.C
|
|
//
|
|
// SPNEGO Token Handler Source File
|
|
//
|
|
// Contains implementation of SPNEGO Token Handling API
|
|
// as defined in SPNEGO.H.
|
|
//
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
/*#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <memory.h>
|
|
#include "spnego.h"
|
|
#include "derparse.h"
|
|
#include "spnegoparse.h"*/
|
|
|
|
#include "..\pch.h"
|
|
|
|
//
|
|
// Defined in DERPARSE.C
|
|
//
|
|
|
|
extern MECH_OID g_stcMechOIDList[];
|
|
|
|
|
|
/**********************************************************************/
|
|
/** **/
|
|
/** **/
|
|
/** **/
|
|
/** **/
|
|
/** SPNEGO Token Handler API implementation **/
|
|
/** **/
|
|
/** **/
|
|
/** **/
|
|
/** **/
|
|
/**********************************************************************/
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoInitFromBinary
|
|
//
|
|
// Parameters:
|
|
// [in] pbTokenData - Binary Token Data
|
|
// [in] ulLength - Length of binary Token Data
|
|
// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// Initializes a SPNEGO_TOKEN_HANDLE from the supplied
|
|
// binary data. Data is copied locally. Returned data structure
|
|
// must be freed by calling spnegoFreeData().
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int spnegoInitFromBinary(unsigned char* pbTokenData, unsigned short ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**)phSpnegoToken;
|
|
|
|
// Pass off to a handler function that allows tighter control over how the token structure
|
|
// is handled. In this case, we want the token data copied and we want the associated buffer
|
|
// freed.
|
|
nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYDATA,
|
|
SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
|
|
ulLength, ppSpnegoToken);
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoCreateNegTokenInit
|
|
//
|
|
// Parameters:
|
|
// [in] MechType - MechType to specify in MechTypeList element
|
|
// [in] ucContextFlags - Context Flags element value
|
|
// [in] pbMechToken - Pointer to binary MechToken Data
|
|
// [in] ulMechTokenLen - Length of MechToken Data
|
|
// [in] pbMechListMIC - Pointer to binary MechListMIC Data
|
|
// [in] ulMechListMICLen - Length of MechListMIC Data
|
|
// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenInit type
|
|
// from the supplied parameters. ucContextFlags may be 0 or must be
|
|
// a valid flag combination. MechToken data can be NULL - if not, it
|
|
// must correspond to the MechType. MechListMIC can also be NULL.
|
|
// Returned data structure must be freed by calling spnegoFreeData().
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
|
|
unsigned char ucContextFlags, unsigned char* pbMechToken,
|
|
unsigned short ulMechTokenLen, unsigned char* pbMechListMIC,
|
|
unsigned short ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
unsigned short nTokenLength = 0L;
|
|
unsigned short nInternalTokenLength = 0L;
|
|
unsigned char* pbTokenData = NULL;
|
|
SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN * *)phSpnegoToken;
|
|
|
|
if (NULL != ppSpnegoToken &&
|
|
IsValidMechOid(MechType) &&
|
|
IsValidContextFlags(ucContextFlags))
|
|
{
|
|
// Get the actual token size
|
|
|
|
if ((nReturn = CalculateMinSpnegoInitTokenSize(ulMechTokenLen, ulMechListMICLen,
|
|
MechType, (ucContextFlags != 0L),
|
|
&nTokenLength, &nInternalTokenLength))
|
|
== SPNEGO_E_SUCCESS)
|
|
{
|
|
// Allocate a buffer to hold the data.
|
|
pbTokenData = calloc(1, nTokenLength);
|
|
|
|
if (NULL != pbTokenData)
|
|
{
|
|
|
|
// Now write the token
|
|
if ((nReturn = CreateSpnegoInitToken(MechType,
|
|
ucContextFlags, pbMechToken,
|
|
ulMechTokenLen, pbMechListMIC,
|
|
ulMechListMICLen, pbTokenData,
|
|
nTokenLength, nInternalTokenLength))
|
|
== SPNEGO_E_SUCCESS)
|
|
{
|
|
|
|
// This will copy our allocated pointer, and ensure that the sructure cleans
|
|
// up the data later
|
|
nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
|
|
SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
|
|
pbTokenData, nTokenLength, ppSpnegoToken);
|
|
|
|
}
|
|
|
|
// Cleanup on failure
|
|
if (SPNEGO_E_SUCCESS != nReturn)
|
|
{
|
|
free(pbTokenData);
|
|
}
|
|
|
|
} // IF alloc succeeded
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
} // If calculated token size
|
|
|
|
} // IF Valid Parameters
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoCreateNegTokenTarg
|
|
//
|
|
// Parameters:
|
|
// [in] MechType - MechType to specify in supported MechType element
|
|
// [in] spnegoNegResult - NegResult value
|
|
// [in] pbMechToken - Pointer to response MechToken Data
|
|
// [in] ulMechTokenLen - Length of MechToken Data
|
|
// [in] pbMechListMIC - Pointer to binary MechListMIC Data
|
|
// [in] ulMechListMICLen - Length of MechListMIC Data
|
|
// [out] phSpnegoToken - SPNEGO_TOKEN_HANDLE pointer
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// Initializes a SPNEGO_TOKEN_HANDLE for a NegTokenTarg type
|
|
// from the supplied parameters. MechToken data can be NULL - if not,
|
|
// it must correspond to the MechType. MechListMIC can also be NULL.
|
|
// Returned data structure must be freed by calling spnegoFreeData().
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
|
|
SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken,
|
|
unsigned short ulMechTokenLen, unsigned char* pbMechListMIC,
|
|
unsigned short ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
unsigned short nTokenLength = 0L;
|
|
unsigned short nInternalTokenLength = 0L;
|
|
unsigned char* pbTokenData = NULL;
|
|
SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**)phSpnegoToken;
|
|
|
|
//
|
|
// spnego_mech_oid_NotUsed and spnego_negresult_NotUsed
|
|
// are okay here, however a valid MechOid is required
|
|
// if spnego_negresult_success or spnego_negresult_incomplete
|
|
// is specified.
|
|
//
|
|
|
|
if (NULL != ppSpnegoToken &&
|
|
|
|
(IsValidMechOid(MechType) ||
|
|
spnego_mech_oid_NotUsed == MechType) &&
|
|
|
|
(IsValidNegResult(spnegoNegResult) ||
|
|
spnego_negresult_NotUsed == spnegoNegResult) &&
|
|
|
|
!(!IsValidMechOid(MechType) &&
|
|
(spnego_negresult_success == spnegoNegResult ||
|
|
spnego_negresult_incomplete == spnegoNegResult)))
|
|
{
|
|
// Get the actual token size
|
|
|
|
if ((nReturn = CalculateMinSpnegoTargTokenSize(MechType, spnegoNegResult, ulMechTokenLen, // CHange ici
|
|
ulMechListMICLen, &nTokenLength,
|
|
&nInternalTokenLength))
|
|
== SPNEGO_E_SUCCESS)
|
|
{
|
|
// Allocate a buffer to hold the data.
|
|
pbTokenData = calloc(1, nTokenLength);
|
|
|
|
if (NULL != pbTokenData)
|
|
{
|
|
// Now write the token
|
|
if ((nReturn = CreateSpnegoTargToken(MechType,
|
|
spnegoNegResult, pbMechToken,
|
|
ulMechTokenLen, pbMechListMIC,
|
|
ulMechListMICLen, pbTokenData,
|
|
nTokenLength, nInternalTokenLength))
|
|
== SPNEGO_E_SUCCESS)
|
|
{
|
|
// This will copy our allocated pointer, and ensure that the sructure cleans
|
|
// up the data later
|
|
nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
|
|
SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
|
|
pbTokenData, nTokenLength, ppSpnegoToken);
|
|
}
|
|
|
|
// Cleanup on failure
|
|
if (SPNEGO_E_SUCCESS != nReturn)
|
|
{
|
|
free(pbTokenData);
|
|
}
|
|
|
|
} // IF alloc succeeded
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
} // If calculated token size
|
|
|
|
} // IF Valid Parameters
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoTokenGetBinary
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pbTokenData - Buffer to copy token into
|
|
// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
|
|
// with actual size used upon function return.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// Copies binary SPNEGO token data from hSpnegoToken into the user
|
|
// supplied buffer. If pbTokenData is NULL, or the value in pulDataLen
|
|
// is too small, the function will return SPNEGO_E_BUFFER_TOO_SMALL and
|
|
// fill out pulDataLen with the minimum required buffer size.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData,
|
|
unsigned short* pulDataLen)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters - pbTokenData is optional
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pulDataLen)
|
|
{
|
|
|
|
// Check for Buffer too small conditions
|
|
if (NULL == pbTokenData ||
|
|
pSpnegoToken->ulBinaryDataLen > * pulDataLen)
|
|
{
|
|
*pulDataLen = pSpnegoToken->ulBinaryDataLen;
|
|
nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pbTokenData, pSpnegoToken->pbBinaryData, pSpnegoToken->ulBinaryDataLen);
|
|
*pulDataLen = pSpnegoToken->ulBinaryDataLen;
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoFreeData
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
//
|
|
// Returns:
|
|
// void
|
|
//
|
|
// Comments :
|
|
// Frees up resources consumed by hSpnegoToken. The supplied data
|
|
// pointer is invalidated by this function.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
void spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken)
|
|
{
|
|
FreeSpnegoToken((SPNEGO_TOKEN*)hSpnegoToken);
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoGetTokenType
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] piTokenType - Filled out with token type value.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// The function will analyze hSpnegoToken and return the appropriate
|
|
// type in piTokenType.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int* piTokenType)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != piTokenType &&
|
|
pSpnegoToken)
|
|
{
|
|
|
|
// Check that the type in the structure makes sense
|
|
if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
|
|
SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType)
|
|
{
|
|
*piTokenType = pSpnegoToken->ucTokenType;
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoIsMechTypeAvailable
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [in] MechOID - MechOID to search MechTypeList for
|
|
// [out] piMechTypeIndex - Filled out with index in MechTypeList
|
|
// element if MechOID is found.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken must reference a token of type NegTokenInit. The
|
|
// function will search the MechTypeList element for an OID corresponding
|
|
// to the specified MechOID. If one is found, the index (0 based) will
|
|
// be passed into the piMechTypeIndex parameter.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Returns the Initial Mech Type in the MechList element in the NegInitToken.
|
|
/*static int spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int* piMechTypeIndex)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != piMechTypeIndex &&
|
|
IsValidMechOid(MechOID) &&
|
|
SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType)
|
|
{
|
|
|
|
// Check if MechList is available
|
|
if (pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].iElementPresent
|
|
== SPNEGO_TOKEN_ELEMENT_AVAILABLE)
|
|
{
|
|
// Locate the MechOID in the list element
|
|
nReturn = FindMechOIDInMechList(
|
|
&pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT],
|
|
MechOID, piMechTypeIndex);
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoGetContextFlags
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pucContextFlags - Filled out with ContextFlags value.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken must reference a token of type NegTokenInit. The
|
|
// function will copy data from the ContextFlags element into the
|
|
// location pucContextFlags points to. Note that the function will
|
|
// fail if the actual ContextFlags data appears invalid.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pucContextFlags &&
|
|
SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType)
|
|
{
|
|
|
|
// Check if ContextFlags is available
|
|
if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].iElementPresent
|
|
== SPNEGO_TOKEN_ELEMENT_AVAILABLE)
|
|
{
|
|
// The length should be two, the value should show a 1 bit difference in the difference byte, and
|
|
// the value must be valid
|
|
if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS &&
|
|
pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF &&
|
|
IsValidContextFlags(pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1]))
|
|
{
|
|
*pucContextFlags = pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1];
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_INVALID_ELEMENT;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoGetNegotiationResult
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pnegResult - Filled out with NegResult value.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken must reference a token of type NegTokenTarg. The
|
|
// function will copy data from the NegResult element into the
|
|
// location pointed to by pnegResult. Note that the function will
|
|
// fail if the actual NegResult data appears invalid.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pnegResult &&
|
|
SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType)
|
|
{
|
|
|
|
// Check if NegResult is available
|
|
if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].iElementPresent
|
|
== SPNEGO_TOKEN_ELEMENT_AVAILABLE)
|
|
{
|
|
// Must be 1 byte long and a valid value
|
|
if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT &&
|
|
IsValidNegResult(*pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData))
|
|
{
|
|
*pnegResult = *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData;
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_INVALID_ELEMENT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoGetSupportedMechType
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pMechOID - Filled out with Supported MechType value.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken must reference a token of type NegTokenTarg. The
|
|
// function will check the Supported MechType element, and if it
|
|
// corresponds to a supported MechType ( spnego_mech_oid_Kerberos_V5_Legacy
|
|
// or spnego_mech_oid_Kerberos_V5 ), will set the location pointed
|
|
// to by pMechOID equal to the appropriate value.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
int nCtr = 0L;
|
|
unsigned short nLength = 0L;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pMechOID &&
|
|
SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType)
|
|
{
|
|
|
|
// Check if MechList is available
|
|
if (pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].iElementPresent
|
|
== SPNEGO_TOKEN_ELEMENT_AVAILABLE)
|
|
{
|
|
|
|
for (nCtr = 0;
|
|
nReturn != SPNEGO_E_SUCCESS &&
|
|
g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
|
|
nCtr++)
|
|
{
|
|
|
|
if ((nReturn = ASNDerCheckOID(
|
|
pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
|
|
nCtr,
|
|
pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].nDatalength,
|
|
&nLength)) == SPNEGO_E_SUCCESS)
|
|
{
|
|
*pMechOID = nCtr;
|
|
}
|
|
|
|
} // For enum MechOIDs
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoTokenGetMechToken
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pbTokenData - Buffer to copy MechToken into
|
|
// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
|
|
// with actual size used upon function return.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token.
|
|
// The function will copy the MechToken (the initial MechToken if
|
|
// NegTokenInit, the response MechToken if NegTokenTarg) from the
|
|
// underlying token into the buffer pointed to by pbTokenData. If
|
|
// pbTokenData is NULL, or the value in pulDataLen is too small, the
|
|
// function will return SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen
|
|
// with the minimum required buffer size. The token can then be passed
|
|
// to a GSS-API function for processing.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
int spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned short* pulDataLen)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
SPNEGO_ELEMENT* pSpnegoElement = NULL;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pulDataLen)
|
|
{
|
|
// Point at the proper Element
|
|
if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType)
|
|
{
|
|
pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
|
|
}
|
|
else
|
|
{
|
|
pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
|
|
}
|
|
|
|
// Check if MechType is available
|
|
if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent)
|
|
{
|
|
// Check for Buffer too small conditions
|
|
if (NULL == pbTokenData ||
|
|
pSpnegoElement->nDatalength > * pulDataLen)
|
|
{
|
|
*pulDataLen = pSpnegoElement->nDatalength;
|
|
nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
// Copy Memory
|
|
memcpy(pbTokenData, pSpnegoElement->pbData, pSpnegoElement->nDatalength);
|
|
*pulDataLen = pSpnegoElement->nDatalength;
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function:
|
|
// spnegoTokenGetMechListMIC
|
|
//
|
|
// Parameters:
|
|
// [in] hSpnegoToken - Initialized SPNEGO_TOKEN_HANDLE
|
|
// [out] pbTokenData - Buffer to copy MechListMIC data into
|
|
// [in/out] pulDataLen - Length of pbTokenData buffer, filled out
|
|
// with actual size used upon function return.
|
|
//
|
|
// Returns:
|
|
// int Success - SPNEGO_E_SUCCESS
|
|
// Failure - SPNEGO API Error code
|
|
//
|
|
// Comments :
|
|
// hSpnegoToken can point to either NegTokenInit or a NegTokenTarg token.
|
|
// The function will copy the MechListMIC data from the underlying token
|
|
// into the buffer pointed to by pbTokenData. If pbTokenData is NULL,
|
|
// or the value in pulDataLen is too small, the function will return
|
|
// SPNEGO_E_BUFFER_TOO_SMALL and fill out pulDataLen with the minimum
|
|
// required buffer size.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/*static int spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned short* pulDataLen)
|
|
{
|
|
int nReturn = SPNEGO_E_INVALID_PARAMETER;
|
|
SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*)hSpnegoToken;
|
|
SPNEGO_ELEMENT* pSpnegoElement = NULL;
|
|
|
|
// Check parameters
|
|
if (IsValidSpnegoToken(pSpnegoToken) &&
|
|
NULL != pulDataLen)
|
|
{
|
|
|
|
// Point at the proper Element
|
|
if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType)
|
|
{
|
|
pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
|
|
}
|
|
else
|
|
{
|
|
pSpnegoElement = &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
|
|
}
|
|
|
|
// Check if MechType is available
|
|
if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent)
|
|
{
|
|
// Check for Buffer too small conditions
|
|
if (NULL == pbMICData ||
|
|
pSpnegoElement->nDatalength > * pulDataLen)
|
|
{
|
|
*pulDataLen = pSpnegoElement->nDatalength;
|
|
nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
// Copy Memory
|
|
memcpy(pbMICData, pSpnegoElement->pbData, pSpnegoElement->nDatalength);
|
|
*pulDataLen = pSpnegoElement->nDatalength;
|
|
nReturn = SPNEGO_E_SUCCESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
|
|
}
|
|
|
|
} // IF parameters OK
|
|
|
|
return nReturn;
|
|
}*/
|