fi
AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h gssapi/gssapi_krb5.h gssapi/gssapi_generic.h)
fi
- old_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="$CPPFLAGS $KRB5INCS"
- old_LIBS=$LIBS
- LIBS="$LIBS $KRB5LIBS"
- AC_CACHE_CHECK([for SPNEGO support],ac_cv_have_spnego,[
- AC_TRY_RUN([
-#ifdef HAVE_HEIMDAL_KERBEROS
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#else
-#ifdef HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif defined(HAVE_GSSAPI_H)
-#include <gssapi.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#endif
-#include <string.h>
-int main(int argc, char *argv[]) {
- OM_uint32 major_status,minor_status;
- gss_OID_set gss_mech_set;
- int i;
-
-static gss_OID_desc _gss_mech_spnego = {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
-gss_OID gss_mech_spnego = &_gss_mech_spnego;
-
- major_status = gss_indicate_mechs( &minor_status, &gss_mech_set);
-
- for (i=0;i<gss_mech_set->count;i++) {
- if (!memcmp(gss_mech_set->elements[i].elements,gss_mech_spnego->elements,gss_mech_set->elements[i].length)) {
- return 0;
- }
- }
-
- return 1;
-}],
- ac_cv_have_spnego=yes,
- ac_cv_have_spnego=no)])
- LIBS=$old_LIBS
- CPPFLAGS=$old_CPPFLAGS
- if test x"$ac_cv_have_spnego" = x"yes"; then
- AC_DEFINE(HAVE_SPNEGO,1, [Define to 1 if you have SPNEGO support])
- fi
AC_SUBST(KRB5INCS)
AC_SUBST(KRB5LIBS)
fi
-AM_CONDITIONAL(HAVE_SPNEGO, test x"$ac_cv_have_spnego" = x"yes" )
dnl Enable "NTLM fail open"
AC_ARG_ENABLE(ntlm-fail-open,
libexec_PROGRAMS = squid_kerb_auth
-SPNEGO = spnegohelp/derparse.c spnegohelp/derparse.h spnegohelp/Makefile spnegohelp/spnego.c spnegohelp/spnego.h spnegohelp/spnegohelp.c spnegohelp/spnegohelp.h spnegohelp/spnegoparse.c spnegohelp/spnegoparse.h
SOURCE = squid_kerb_auth.c base64.c base64.h
EXTRA_DIST = readme.txt do.sh
-if HAVE_SPNEGO
squid_kerb_auth_SOURCES = $(SOURCE)
-else
-squid_kerb_auth_SOURCES = $(SOURCE) $(SPNEGO)
-endif
-INCLUDES = -I$(top_srcdir)/include $(KERBINCS) -I$(srcdir)/spnegohelp -I.
+INCLUDES = -I$(top_srcdir)/include $(KERBINCS) -I.
#-I$(top_srcdir)/include -I$(top_srcdir)/src
LDADD = $(KERBLIBS)
#-L$(top_builddir)/lib -lmiscutil $(XTRA_LIBS)
+++ /dev/null
-#
-# Linux:
-# -D__LITTLE_ENDIAN__
-# Solaris:
-# -D__BIG_ENDIAN__
-#
-
-CFLAGS = -fpic
-
-LIB = libspnegohelp.a
-SLIB = libspnegohelp.so
-
-OBJS = derparse.o spnego.o spnegohelp.o spnegoparse.o
-
-all:
- make `uname`
-
-debug:
- make CFLAGS="$(CFLAGS) -DDEBUG" `uname`
-
-SunOS:
- make CFLAGS="$(CFLAGS) -D__BIG_ENDIAN__" libs
-
-AIX:
- make CFLAGS="$(CFLAGS) -D__BIG_ENDIAN__" libs
-
-Linux:
- make CFLAGS="$(CFLAGS) -D__LITTLE_ENDIAN__" libs
-
-libs: $(LIB) $(SLIB)
-
-$(LIB): $(OBJS)
- ar -r $(LIB) $(OBJS)
-
-$(SLIB): $(OBJS)
- gcc --shared -o $(SLIB) $(OBJS)
-
-derparse.o: derparse.c derparse.h spnego.h Makefile
- gcc -c $(CFLAGS) derparse.c -o $@
-
-spnego.o: spnego.c derparse.h spnego.h spnegoparse.h Makefile
- gcc -c $(CFLAGS) spnego.c -o $@
-
-spnegoparse.o: spnegoparse.c derparse.h spnego.h spnegoparse.h Makefile
- gcc -c $(CFLAGS) spnegoparse.c -o $@
-
-spnegohelp.o: spnegohelp.c spnego.h spnegohelp.h Makefile
- gcc -c $(CFLAGS) spnegohelp.c -o $@
-
-clean:
- rm $(OBJS) $(LIB) $(SLIB)
+++ /dev/null
-// 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
-
-
-/////////////////////////////////////////////////////////////
-//
-// DERPARSE.C
-//
-// SPNEGO Token Handler Source File
-//
-// Contains implementation of ASN.1 DER read/write functions
-// as defined in DERPARSE.H.
-//
-/////////////////////////////////////////////////////////////
-
-#include "config.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include "spnego.h"
-#include "derparse.h"
-
-//
-// The GSS Mechanism OID enumeration values (SPNEGO_MECH_OID) control which offset in
-// the array below, that a mechanism can be found.
-//
-MECH_OID g_stcMechOIDList [] =
-{
- { (unsigned char*) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy }, // 1.2.840.48018.1.2.2
- { (unsigned char*) "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5 }, // 1.2.840.113554.1.2.2
- { (unsigned char*) "\x06\x06\x2b\x06\x01\x05\x05\x02", 8, 6, spnego_mech_oid_Spnego }, // 1.3.6.1.1.5.5.2
- { (unsigned char*) "", 0, 0, spnego_mech_oid_NotUsed } // Placeholder
-};
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerGetLength
-//
-// Parameters:
-// [in] pbLengthData - DER Length Data
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnLength - Filled out with length value
-// [out] pnNumLengthBytes - Filled out with number of bytes
-// consumed by DER length.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Interprets the data at pbLengthData as a DER length. The length must
-// fit within the bounds of nBoundary length. We do not currently
-// process lengths that take more than 4 bytes.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pnLength,
- long* pnNumLengthBytes )
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- int nNumLengthBytes = 0;
-
- // First check if the extended length bit is set
-
- if ( *pbLengthData & LEN_XTND )
- {
- // Lower 7 bits contain the number of trailing bytes that describe the length
- nNumLengthBytes = *pbLengthData & LEN_MASK;
-
- // Check that the number of bytes we are about to read is within our boundary
- // constraints
-
- if ( nNumLengthBytes <= nBoundaryLength - 1 )
- {
-
- // For now, our handler won't deal with lengths greater than 4 bytes
- if ( nNumLengthBytes >= 1 && nNumLengthBytes <= 4 )
- {
- // 0 out the initial length
- *pnLength = 0L;
-
- // Bump by 1 byte
- pbLengthData++;
-
- #if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
-
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch ( nNumLengthBytes )
- {
- case 1:
- {
- *( ( (unsigned char*) pnLength ) ) = *pbLengthData;
- break;
- }
-
- case 2:
- {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData);
-
- break;
- }
-
- case 3:
- {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 2);
- *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
- break;
- }
-
- case 4:
- {
- *( ( (unsigned char*) pnLength ) ) = *(pbLengthData + 3);
- *( ( (unsigned char*) pnLength ) + 1 ) = *(pbLengthData + 2);
- *( ( (unsigned char*) pnLength ) + 2 ) = *(pbLengthData + 1);
- *( ( (unsigned char*) pnLength ) + 3 ) = *(pbLengthData);
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
-
- #else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
-
- memcpy( ( (unsigned char *) pnLength ) + ( 4 - nNumLengthBytes ),
- pbLengthData, nNumLengthBytes );
- #endif
-
- // Account for the initial length byte
- *pnNumLengthBytes = nNumLengthBytes + 1;
- nReturn = SPNEGO_E_SUCCESS;
-
- } // IF Valid Length
-
- } // IF num bytes to read is within the boundary length
-
- } // IF xtended length
- else
- {
-
- // Extended bit is not set, so the length is in the value and the one
- // byte describes the length
- *pnLength = *pbLengthData & LEN_MASK;
- *pnNumLengthBytes = 1;
- nReturn = SPNEGO_E_SUCCESS;
-
- }
- LOG(("ASNDerGetLength returned %d\n",nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCheckToken
-//
-// Parameters:
-// [in] pbTokenData - Token Data
-// [in] nToken - Token identifier to check for
-// [in] nLengthWithToken - Expected token length (with data)
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnLength - Filled out with data length
-// [out] pnTokenLength - Filled out with number of bytes
-// consumed by token identifier and length.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data pointed to by pbTokenData for the specified token
-// identifier and the length that immediately follows. If
-// nLengthWithToken is > 0, the calculated length must match. The
-// length must also not exceed the specified boundary length .
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken,
- long nLengthWithToken, long nBoundaryLength,
- long* pnLength, long* pnTokenLength )
-{
-
- int nReturn = SPNEGO_E_INVALID_LENGTH;
- long nNumLengthBytes = 0L;
-
- // Make sure that we've at least got 2 bytes of room to work with
-
- if ( nBoundaryLength >= 2 )
- {
- // The first byte of the token data MUST match the specified token
- if ( *pbTokenData == nToken )
- {
- // Next byte indicates the length
- pbTokenData++;
-
- // Get the length described by the token
- if ( ( nReturn = ASNDerGetLength( pbTokenData, nBoundaryLength, pnLength,
- &nNumLengthBytes ) ) == SPNEGO_E_SUCCESS )
- {
- // Verify that the length is LESS THAN the boundary length
- // (this should prevent us walking out of our buffer)
- if ( ( nBoundaryLength - ( nNumLengthBytes + 1 ) < *pnLength ) )
- {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
-
- // If we were passed a length to check, do so now
- if ( nLengthWithToken > 0L )
- {
-
- // Check that the expected length matches
- if ( ( nLengthWithToken - ( nNumLengthBytes + 1 ) ) != *pnLength )
- {
-
- nReturn = SPNEGO_E_INVALID_LENGTH;
-
- }
-
- } // IF need to validate length
-
- if ( SPNEGO_E_SUCCESS == nReturn )
- {
- *pnTokenLength = nNumLengthBytes + 1;
- }
-
- } // IF ASNDerGetLength
-
- } // IF token matches
- else
- {
- nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
- }
-
- } // IF Boundary Length is at least 2 bytes
-
- LOG(("ASNDerCheckToken returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCheckOID
-//
-// Parameters:
-// [in] pbTokenData - Token Data
-// [in] nMechOID - OID we are looking for
-// [in] nBoundaryLength - Length that value must not exceed.
-// [out] pnTokenLength - Filled out with number of bytes
-// consumed by token and data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data pointed to by pbTokenData for the specified OID.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long nBoundaryLength,
- long* pnTokenLength )
-{
- int nReturn = 0L;
- long nLength = 0L;
-
- // Verify that we have an OID token
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID, 0L, nBoundaryLength,
- &nLength, pnTokenLength ) ) == SPNEGO_E_SUCCESS )
- {
- // Add the data length to the Token Length
- *pnTokenLength += nLength;
-
- // Token Lengths plus the actual length must match the length in our OID list element.
- // If it doesn't, we're done
- if ( *pnTokenLength == g_stcMechOIDList[nMechOID].iLen )
- {
- // Memcompare the token and the expected field
- if ( memcmp( pbTokenData, g_stcMechOIDList[nMechOID].ucOid, *pnTokenLength ) != 0 )
- {
- LOG(("ASNDerCheckOID memcmp failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
- }
- else
- {
- LOG(("ASNDerCheckOID token length failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
-
- } // IF OID Token CHecks
-
- LOG(("ASNDerCheckOID returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcNumLengthBytes
-//
-// Parameters:
-// [in] nLength - Length to calculate length bytes for.
-//
-// Returns:
-// int Number of bytes necessary to represent length
-//
-// Comments :
-// Helper function to calculate the number of length bytes necessary to
-// represent a length value. For our purposes, a 32-bit value should be
-// enough to describea length.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerCalcNumLengthBytes( long nLength )
-{
- if ( nLength <= 0x7F )
- {
- // A single byte will be sufficient for describing this length.
- // The byte will simply contain the length
- return 1;
- }
- else if ( nLength <= 0xFF )
- {
- // Two bytes are necessary, one to say how many following bytes
- // describe the length, and one to give the length
- return 2;
- }
- else if ( nLength <= 0xFFFF )
- {
- // Three bytes are necessary, one to say how many following bytes
- // describe the length, and two to give the length
- return 3;
- }
- else if ( nLength <= 0xFFFFFF )
- {
- // Four bytes are necessary, one to say how many following bytes
- // describe the length, and three to give the length
- return 4;
- }
- else
- {
- // Five bytes are necessary, one to say how many following bytes
- // describe the length, and four to give the length
- return 5;
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcTokenLength
-//
-// Parameters:
-// [in] nLength - Length to calculate length bytes for.
-// [in] nDataLength - Actual Data length value.
-//
-// Returns:
-// long Number of bytes necessary to represent a token, length and data
-//
-// Comments :
-// Helper function to calculate a token and value size, based on a
-// supplied length value, and any binary data that will need to be
-// written out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long ASNDerCalcTokenLength( long nLength, long nDataLength )
-{
- // Add a byte to the length size to account for a single byte to
- // hold the token type.
- long nTotalLength = ASNDerCalcNumLengthBytes( nLength ) + 1;
-
- return nTotalLength + nDataLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcElementLength
-//
-// Parameters:
-// [in] nDataLength - Length of data.
-// [out] pnInternalLength - Filled out with length of element
-// without sequence info.
-//
-// Returns:
-// long Number of bytes necessary to represent an element
-//
-// Comments :
-// Helper function to calculate an element length. An element consists
-// of a sequence token, a type token and then the data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength )
-{
- // First the type token and the actual data
- long nTotalLength = ASNDerCalcTokenLength( nDataLength, nDataLength );
-
- // Internal length is the length without the element sequence token
- if ( NULL != pnInternalLength )
- {
- *pnInternalLength = nTotalLength;
- }
-
- // Next add in the element's sequence token (remember that its
- // length is the total length of the type token and data)
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- return nTotalLength;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerCalcMechListLength
-//
-// Parameters:
-// [in] mechoid - Mech OID to put in list.
-// [out] pnInternalLength - Filled out with length of element
-// without the primary sequence token.
-//
-// Returns:
-// long Number of bytes necessary to represent a mechList
-//
-// Comments :
-// Helper function to calculate a MechList length. A mechlist consists
-// of a NegTokenInit sequence token, a sequence token for the MechList
-// and finally a list of OIDs. In our case, we only really have one
-// OID.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength )
-{
- // First the OID
- long nTotalLength = g_stcMechOIDList[mechoid].iLen;
-
- // Next add in a sequence token
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Internal length is the length without the element sequence token
- if ( NULL != pnInternalLength )
- {
- *pnInternalLength = nTotalLength;
- }
-
- // Finally add in the element's sequence token
- nTotalLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- return nTotalLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteLength
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] nLength - Length to write out.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a length value following DER rules .
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerWriteLength( unsigned char* pbData, long nLength )
-{
- int nNumBytesRequired = ASNDerCalcNumLengthBytes( nLength );
- int nNumLengthBytes = nNumBytesRequired - 1;
-
-
- if ( nNumBytesRequired > 1 )
- {
-
- // Write out the number of bytes following which will be used
- *pbData = (unsigned char ) ( LEN_XTND | nNumLengthBytes );
-
- // Point to where we'll actually write the length
- pbData++;
-
-#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
-
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch ( nNumLengthBytes )
- {
- case 1:
- {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- break;
- }
-
- case 2:
- {
- *pbData = *( ( (unsigned char*) &nLength ) + 1 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- case 3:
- {
- *pbData = *( ( (unsigned char*) &nLength ) + 3 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
- *( pbData + 2) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- case 4:
- {
- *pbData = *( ( (unsigned char*) &nLength ) + 3 );
- *( pbData + 1) = *( ( (unsigned char*) &nLength ) + 2 );
- *( pbData + 2) = *( ( (unsigned char*) &nLength ) + 1 );
- *( pbData + 3) = *( ( (unsigned char*) &nLength ) );
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
-
-#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
-
- memcpy( pbData,
- ( (unsigned char *) &nLength ) + ( 4 - nNumLengthBytes ), nNumLengthBytes );
-#endif
-
- } // IF > 1 byte for length
- else
- {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- }
-
- return nNumBytesRequired;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteToken
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] ucType - Token Type
-// [in] pbTokenValue - Actual Value
-// [in] nLength - Length of Data.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a token and any associated data. If
-// pbTokenValue is non-NULL, then it is written out in addition to the
-// token identifier and the length bytes.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
- unsigned char* pbTokenValue, long nLength )
-{
- int nTotalBytesWrittenOut = 0L;
- int nNumLengthBytesWritten = 0L;
-
- // Write out the type
- *pbData = ucType;
-
- // Wrote 1 byte, and move data pointer
- nTotalBytesWrittenOut++;
- pbData++;
-
- // Now write out the length and adjust the number of bytes written out
- nNumLengthBytesWritten = ASNDerWriteLength( pbData, nLength );
-
- nTotalBytesWrittenOut += nNumLengthBytesWritten;
- pbData += nNumLengthBytesWritten;
-
- // Write out the token value if we got one. The assumption is that the
- // nLength value indicates how many bytes are in pbTokenValue.
-
- if ( NULL != pbTokenValue )
- {
- memcpy( pbData, pbTokenValue, nLength );
- nTotalBytesWrittenOut += nLength;
- }
-
- return nTotalBytesWrittenOut;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteOID
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] eMechOID - OID to write out.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out an OID. For these we have the raw bytes
-// listed in a global structure. The caller simply indicates which OID
-// should be written and we will splat out the data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID )
-{
-
- memcpy( pbData, g_stcMechOIDList[eMechOID].ucOid, g_stcMechOIDList[eMechOID].iLen );
-
- return g_stcMechOIDList[eMechOID].iLen;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteMechList
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] eMechOID - OID to put in MechList.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a MechList. A MechList consists of the
-// Init Token Sequence, a sequence token and then the list of OIDs. In
-// our case the OID is from a global array of known OIDs.
-//
-////////////////////////////////////////////////////////////////////////////
-
-long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid )
-{
- // First get the length
- long nInternalLength = 0L;
- long nMechListLength = ASNDerCalcMechListLength( mechoid, &nInternalLength );
- long nTempLength = 0L;
-
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
- NULL, nInternalLength );
-
- // Adjust the data pointer
- pbData += nTempLength;
-
- // Now write the Sequence token and the OID (the OID is a BLOB in the global
- // structure.
-
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
- g_stcMechOIDList[mechoid].ucOid,
- g_stcMechOIDList[mechoid].iLen );
-
- return nMechListLength;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ASNDerWriteElement
-//
-// Parameters:
-// [out] pbData - Buffer to write into.
-// [in] ucElementSequence - Sequence Token
-// [in] ucType - Token Type
-// [in] pbTokenValue - Actual Value
-// [in] nLength - Length of Data.
-//
-// Returns:
-// int Number of bytes written out
-//
-// Comments :
-// Helper function to write out a SPNEGO Token element. An element
-// consists of a sequence token, a type token and the associated data.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char* pbTokenValue, long nLength )
-{
- // First get the length
- long nInternalLength = 0L;
- long nElementLength = ASNDerCalcElementLength( nLength, &nInternalLength );
- long nTempLength = 0L;
-
- // Write out the sequence byte and the length of the type and data
- nTempLength = ASNDerWriteToken( pbData, ucElementSequence, NULL, nInternalLength );
-
- // Adjust the data pointer
- pbData += nTempLength;
-
- // Now write the type and the data.
- nTempLength = ASNDerWriteToken( pbData, ucType, pbTokenValue, nLength );
-
- return nElementLength;
-}
-
+++ /dev/null
-// 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
-
-/////////////////////////////////////////////////////////////
-//
-// DERPARSE.H
-//
-// SPNEGO Token Handler Header File
-//
-// Contains the definitions required to properly parse the
-// SPNEGO DER encoding.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __DERPARSE_H__
-#define __DERPARSE_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Identifier Types */
-#define IDENTIFIER_MASK 0xC0 // Bits 7 and 8
-#define IDENTIFIER_UNIVERSAL 0x00 // 00 = universal
-#define IDENTIFIER_APPLICATION 0x40 // 01 = application
-#define IDENTIFIER_CONTEXT_SPECIFIC 0x80 // 10 = context specific
-#define IDENTIFIER_PRIVATE 0xC0 // 11 = Private
-
-/* Encoding type */
-
-#define FORM_MASK 0x20 /* Bit 6 */
-#define PRIMITIVE 0x00 /* 0 = primitive */
-#define CONSTRUCTED 0x20 /* 1 = constructed */
-
-/* Universal tags */
-
-#define TAG_MASK 0x1F /* Bits 5 - 1 */
-#define BOOLEAN 0x01 /* 1: TRUE or FALSE */
-#define INTEGER 0x02 /* 2: Arbitrary precision integer */
-#define BITSTRING 0x03 /* 2: Sequence of bits */
-#define OCTETSTRING 0x04 /* 4: Sequence of bytes */
-#define NULLTAG 0x05 /* 5: NULL */
-#define OID 0x06 /* 6: Object Identifier (numeric sequence) */
-#define OBJDESCRIPTOR 0x07 /* 7: Object Descriptor (human readable) */
-#define EXTERNAL 0x08 /* 8: External / Instance Of */
-#define REAL 0x09 /* 9: Real (Mantissa * Base^Exponent) */
-#define ENUMERATED 0x0A /* 10: Enumerated */
-#define EMBEDDED_PDV 0x0B /* 11: Embedded Presentation Data Value */
-#define SEQUENCE 0x10 /* 16: Constructed Sequence / Sequence Of */
-#define SET 0x11 /* 17: Constructed Set / Set Of */
-#define NUMERICSTR 0x12 /* 18: Numeric String (digits only) */
-#define PRINTABLESTR 0x13 /* 19: Printable String */
-#define T61STR 0x14 /* 20: T61 String (Teletex) */
-#define VIDEOTEXSTR 0x15 /* 21: Videotex String */
-#define IA5STR 0x16 /* 22: IA5 String */
-#define UTCTIME 0x17 /* 23: UTC Time */
-#define GENERALIZEDTIME 0x18 /* 24: Generalized Time */
-#define GRAPHICSTR 0x19 /* 25: Graphic String */
-#define VISIBLESTR 0x1A /* 26: Visible String (ISO 646) */
-#define GENERALSTR 0x1B /* 27: General String */
-#define UNIVERSALSTR 0x1C /* 28: Universal String */
-#define BMPSTR 0x1E /* 30: Basic Multilingual Plane String */
-
-/* Length encoding */
-
-#define LEN_XTND 0x80 /* Indefinite or long form */
-#define LEN_MASK 0x7f /* Bits 7 - 1 */
-
-//
-// SPNEGO Token Parsing Constants
-//
-
-
-// Fixed Length of NegTokenInit ReqFlags field
-#define SPNEGO_NEGINIT_MAXLEN_REQFLAGS 2
-
-// Difference in bits for ReqFlags token
-#define SPNEGO_NEGINIT_REQFLAGS_BITDIFF 1
-
-// Fixed Length of NegTokenTarg NegResult field
-#define SPNEGO_NEGTARG_MAXLEN_NEGRESULT 1
-
-// Application Specific Construct - Always at the start of a NegTokenInit
-#define SPNEGO_NEGINIT_APP_CONSTRUCT ( IDENTIFIER_APPLICATION | CONSTRUCTED ) // 0x60
-
-// Constructed Sequence token - after the actual token identifier token
-#define SPNEGO_CONSTRUCTED_SEQUENCE ( SEQUENCE | CONSTRUCTED )
-
-// MechList Type Identifier
-#define SPNEGO_MECHLIST_TYPE ( SEQUENCE | CONSTRUCTED | OID )
-
-//
-// NegTokenInit - Token Identifier and Elements
-//
-
-// NegTokenInit - 0xa0
-#define SPNEGO_NEGINIT_TOKEN_IDENTIFIER ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_TOKEN_INIT )
-
-// Structure elements for NegTokenInit
-#define SPNEGO_NEGINIT_MECHTYPES 0x0 // MechTypes is element 0
-#define SPNEGO_NEGINIT_REQFLAGS 0x1 // ReqFlags is element 1
-#define SPNEGO_NEGINIT_MECHTOKEN 0x2 // MechToken is element 2
-#define SPNEGO_NEGINIT_MECHLISTMIC 0x3 // MechListMIC is element 3
-
-// MechTypes element is 0xa0
-#define SPNEGO_NEGINIT_ELEMENT_MECHTYPES ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHTYPES )
-
-// ReqFlags element is 0xa1
-#define SPNEGO_NEGINIT_ELEMENT_REQFLAGS ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_REQFLAGS )
-
-// MechToken element is 0xa2
-#define SPNEGO_NEGINIT_ELEMENT_MECHTOKEN ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHTOKEN )
-
-// MechListMIC element is 0xa3
-#define SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGINIT_MECHLISTMIC )
-
-//
-// NegTokenTarg - Token Identifier and Elements
-//
-
-// NegTokenTarg - 0xa1
-#define SPNEGO_NEGTARG_TOKEN_IDENTIFIER ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_TOKEN_TARG )
-
-// Structure elements for NegTokenTarg
-#define SPNEGO_NEGTARG_NEGRESULT 0x0 // NegResult is element 0
-#define SPNEGO_NEGTARG_SUPPORTEDMECH 0x1 // SupportedMech is element 1
-#define SPNEGO_NEGTARG_RESPONSETOKEN 0x2 // ResponseToken is element 2
-#define SPNEGO_NEGTARG_MECHLISTMIC 0x3 // MechListMIC is element 3
-
-// NegResult element is 0xa0
-#define SPNEGO_NEGTARG_ELEMENT_NEGRESULT ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_NEGRESULT )
-
-// SupportedMech element is 0xa1
-#define SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_SUPPORTEDMECH )
-
-// ResponseToken element is 0xa2
-#define SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_RESPONSETOKEN )
-
-// MechListMIC element is 0xa3
-#define SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC ( IDENTIFIER_CONTEXT_SPECIFIC | CONSTRUCTED | \
- SPNEGO_NEGTARG_MECHLISTMIC )
-
-//
-// Defines a GSS Mechanism OID. We keep a single static array
-// of these which we'll use for validation/searches/parsing.
-//
-
-typedef struct _mechOID
-{
- unsigned char* ucOid; // Byte representation of OID
- int iLen; // Length of the OID, length and identifier
- int iActualDataLen; // Length of the actual OID
- SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
-} MECH_OID;
-
-
-//
-// ASN Der functions
-//
-
-int ASNDerGetLength( unsigned char* pbLengthData, long nBoundaryLength, long* pnLength,
- long* pnNumLengthBytes );
-int ASNDerCheckToken( unsigned char* pbTokenData, unsigned char nToken,
- long nCheckLength, long nBoundaryLength, long* pnLength,
- long* pnTokenLength );
-int ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long nBoundaryLength,
- long* pnTokenLength );
-int ASNDerCalcNumLengthBytes( long nLength );
-long ASNDerCalcTokenLength( long nLength, long nDataLength );
-long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength );
-long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength );
-int ASNDerWriteLength( unsigned char* pbData, long nLength );
-int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
- unsigned char* pbTokenValue, long nLength );
-int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID );
-long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid );
-int ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char* pbTokenValue, long nLength );
-
-
- // C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
-
+++ /dev/null
-// 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"
-
-//
-// 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 long 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 );
-
- LOG(("spnegoInitFromBinary returned %d\n",nReturn));
- 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().
-//
-////////////////////////////////////////////////////////////////////////////
-
-int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long 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
-
- LOG(("spnegoCreateNegTokenInit returned %d\n",nReturn));
- 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 long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- long nTokenLength = 0L;
- long 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,
- 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
-
- LOG(("spnegoCreateNegTokenTarg returned %d\n",nReturn));
- 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 long * 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
-
- LOG(("spnegoTokenGetBinary returned %d\n",nReturn));
- 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.
-//
-////////////////////////////////////////////////////////////////////////////
-
-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
-
- LOG(("spnegoGetTokenType returned %d\n",nReturn));
- 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.
-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
-
- LOG(("spnegoIsMechTypeAvailable returned %d\n",nReturn));
- 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.
-//
-////////////////////////////////////////////////////////////////////////////
-
-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
-
- LOG(("spnegoGetContextFlags returned %d\n",nReturn));
- 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.
-//
-////////////////////////////////////////////////////////////////////////////
-
-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
-
- LOG(("spnegoGetNegotiationResult returned %d\n",nReturn));
- 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.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID )
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- int nCtr = 0L;
- long 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
-
- LOG(("spnegoGetSupportedMechType returned %d\n",nReturn));
- 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 long* 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
-
- LOG(("spnegoGetMechToken returned %d\n",nReturn));
- 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.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* 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
-
- LOG(("spnegoGetMechListMIC returned %d\n",nReturn));
- return nReturn;;
-}
-
+++ /dev/null
-// 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.H
-//
-// SPNEGO Token Handler Header File
-//
-// Contains the definitions required to interpret and create
-// SPNEGO tokens so that Kerberos GSS tokens can be
-// Unpackaged/packaged.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __SPNEGO_H__
-#define __SPNEGO_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-// Type Definitions
-
-//
-// Users of SPNEGO Token Handler API will request
-// these as well as free them,
-//
-typedef void* SPNEGO_TOKEN_HANDLE;
-
-//
-// Defines the element types that are found
-// in each of the tokens.
-//
-
-typedef enum spnego_element_type
-{
- spnego_element_min, // Lower bound
-
- // Init token elements
- spnego_init_mechtypes,
- spnego_init_reqFlags,
- spnego_init_mechToken,
- spnego_init_mechListMIC,
-
- // Targ token elements
- spnego_targ_negResult,
- spnego_targ_supportedMech,
- spnego_targ_responseToken,
- spnego_targ_mechListMIC,
-
- spnego_element_max // Upper bound
-
-} SPNEGO_ELEMENT_TYPE;
-
-//
-// Token Element Availability. Elements in both
-// token types are optional. Since there are only
-// 4 elements in each Token, we will allocate space
-// to hold the information, but we need a way to
-// indicate whether or not an element is available
-//
-
-#define SPNEGO_TOKEN_ELEMENT_UNAVAILABLE 0
-#define SPNEGO_TOKEN_ELEMENT_AVAILABLE 1
-
-//
-// Token type values. SPNEGO has 2 token types:
-// NegTokenInit and NegTokenTarg
-//
-
-#define SPNEGO_TOKEN_INIT 0
-#define SPNEGO_TOKEN_TARG 1
-
-//
-// GSS Mechanism OID enumeration. We only really handle
-// 3 different OIDs. These are stored in an array structure
-// defined in the parsing code.
-//
-
-typedef enum spnego_mech_oid
-{
- // Init token elements
- spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
- spnego_mech_oid_Kerberos_V5,
- spnego_mech_oid_Spnego,
- spnego_mech_oid_NotUsed = -1
-
-} SPNEGO_MECH_OID;
-
-//
-// Defines the negResult values.
-//
-
-typedef enum spnego_negResult
-{
- spnego_negresult_success,
- spnego_negresult_incomplete,
- spnego_negresult_rejected,
- spnego_negresult_NotUsed = -1
-} SPNEGO_NEGRESULT;
-
-//
-// Context Flags in NegTokenInit
-//
-
-//
-// ContextFlags values MUST be zero or a combination
-// of the below
-//
-
-#define SPNEGO_NEGINIT_CONTEXT_DELEG_FLAG 0x80
-#define SPNEGO_NEGINIT_CONTEXT_MUTUAL_FLAG 0x40
-#define SPNEGO_NEGINIT_CONTEXT_REPLAY_FLAG 0x20
-#define SPNEGO_NEGINIT_CONTEXT_SEQUENCE_FLAG 0x10
-#define SPNEGO_NEGINIT_CONTEXT_ANON_FLAG 0x8
-#define SPNEGO_NEGINIT_CONTEXT_CONF_FLAG 0x4
-#define SPNEGO_NEGINIT_CONTEXT_INTEG_FLAG 0x2
-
-//
-// Mask to retrieve valid values.
-//
-
-#define SPNEGO_NEGINIT_CONTEXT_MASK 0xFE // Logical combination of above flags
-
-//
-// SPNEGO API return codes.
-//
-
-// API function was successful
-#define SPNEGO_E_SUCCESS 0
-
-// The supplied Token was invalid
-#define SPNEGO_E_INVALID_TOKEN -1
-
-// An invalid length was encountered
-#define SPNEGO_E_INVALID_LENGTH -2
-
-// The Token Parse failed
-#define SPNEGO_E_PARSE_FAILED -3
-
-// The requested value was not found
-#define SPNEGO_E_NOT_FOUND -4
-
-// The requested element is not available
-#define SPNEGO_E_ELEMENT_UNAVAILABLE -5
-
-// Out of Memory
-#define SPNEGO_E_OUT_OF_MEMORY -6
-
-// Not Implemented
-#define SPNEGO_E_NOT_IMPLEMENTED -7
-
-// Invalid Parameter
-#define SPNEGO_E_INVALID_PARAMETER -8
-
-// Token Handler encountered an unexpected OID
-#define SPNEGO_E_UNEXPECTED_OID -9
-
-// The requested token was not found
-#define SPNEGO_E_TOKEN_NOT_FOUND -10
-
-// An unexpected type was encountered in the encoding
-#define SPNEGO_E_UNEXPECTED_TYPE -11
-
-// The buffer was too small
-#define SPNEGO_E_BUFFER_TOO_SMALL -12
-
-// A Token Element was invalid (e.g. improper length or value)
-#define SPNEGO_E_INVALID_ELEMENT -13
-
-/* Miscelaneous API Functions */
-
-// Frees opaque data
-void spnegoFreeData( SPNEGO_TOKEN_HANDLE hSpnegoToken );
-
-// Initializes SPNEGO_TOKEN structure from DER encoded binary data
-int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
-
-// Initializes SPNEGO_TOKEN structure for a NegTokenInit type using the
-// supplied parameters
-int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechTokenMIC,
- unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
-
-// Initializes SPNEGO_TOKEN structure for a NegTokenTarg type using the
-// supplied parameters
-int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE* phSpnegoToken );
-
-// Copies binary representation of SPNEGO Data into user supplied buffer
-int spnegoTokenGetBinary( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData,
- unsigned long * pulDataLen );
-
-// Returns SPNEGO Token Type
-int spnegoGetTokenType( SPNEGO_TOKEN_HANDLE hSpnegoToken, int * piTokenType );
-
-/* Reading an Init Token */
-
-// Returns the Initial Mech Type in the MechList element in the NegInitToken.
-int spnegoIsMechTypeAvailable( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID MechOID, int * piMechTypeIndex );
-
-// Returns the value from the context flags element in the NegInitToken as an unsigned long
-int spnegoGetContextFlags( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pucContextFlags );
-
-/* Reading a Response Token */
-
-// Returns the value from the negResult element (Status code of GSS call - 0,1,2)
-int spnegoGetNegotiationResult( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_NEGRESULT* pnegResult );
-
-// Returns the Supported Mech Type from the NegTokenTarg.
-int spnegoGetSupportedMechType( SPNEGO_TOKEN_HANDLE hSpnegoToken, SPNEGO_MECH_OID* pMechOID );
-
-/* Reading either Token Type */
-
-// Returns the actual Mechanism data from the token (this is what is passed into GSS-API functions
-int spnegoGetMechToken( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbTokenData, unsigned long* pulDataLen );
-
-// Returns the Message Integrity BLOB in the token
-int spnegoGetMechListMIC( SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char* pbMICData, unsigned long* pulDataLen );
-
-// C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-#ifdef DEBUG
-#include <stdio.h>
- #define PRERR(...) fprintf(stderr, __VA_ARGS__)
- #define LOG(x) PRERR x
-#else
- #define LOG(x)
-#endif
-#endif
+++ /dev/null
-/* -----------------------------------------------------------------------------
- * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003 All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * -----------------------------------------------------------------------------
- */
-
-#include "spnegohelp.h"
-#include "spnego.h"
-
-#include <stdlib.h>
-
-int makeNegTokenTarg (const unsigned char * kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char ** negTokenTarg,
- size_t * negTokenTargLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
-
- /* Check arguments. */
-
- if (!kerberosToken ||
- !negTokenTarg ||
- !negTokenTargLength)
- return 10;
-
- /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
-
- /* Does IIS always reply with accept_completed? */
-
- /* IIS does not include a MIC. */
-
- rc2 = spnegoCreateNegTokenTarg (spnego_mech_oid_Kerberos_V5_Legacy,
- spnego_negresult_success,
- (unsigned char *) kerberosToken,
- kerberosTokenLength,
- NULL,
- 0,
- &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+100;
- goto cleanup;
- }
-
- /* Get NegTokenTarg length. */
-
- rc2 = spnegoTokenGetBinary (hSpnegoToken,
- NULL,
- (unsigned long*) negTokenTargLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
- {
- rc1 = abs(rc2)+200;
- goto cleanup;
- }
-
- *negTokenTarg = malloc (*negTokenTargLength);
-
- if (!*negTokenTarg)
- {
- rc1 = abs(rc2)+300;
- goto cleanup;
- }
-
- /* Get NegTokenTarg data. */
-
- rc2 = spnegoTokenGetBinary (hSpnegoToken,
- (unsigned char *) *negTokenTarg,
- (unsigned long*) negTokenTargLength);
-
-
- if (rc2 != SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+400;
- goto error;
- }
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*negTokenTarg)
- {
- free ((unsigned char *) *negTokenTarg);
- *negTokenTarg = NULL;
- *negTokenTargLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData (hSpnegoToken);
-
- LOG(("makeNegTokenTarg returned %d\n",rc1));
- return rc1;
-}
-
-int parseNegTokenInit (const unsigned char * negTokenInit,
- size_t negTokenInitLength,
- const unsigned char ** kerberosToken,
- size_t * kerberosTokenLength)
-{
- SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
- int pindex = -1;
- int rc1 = 1;
- int rc2 = SPNEGO_E_SUCCESS;
- unsigned char reqFlags = 0;
- int tokenType = 0;
-
- /* Check arguments. */
-
- if (!negTokenInit ||
- !kerberosToken ||
- !kerberosTokenLength)
- return 10;
-
- /* Decode SPNEGO token. */
-
- rc2 = spnegoInitFromBinary ((unsigned char *) negTokenInit,
- negTokenInitLength,
- &hSpnegoToken);
-
- if (rc2 != SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+100;
- goto cleanup;
- }
-
- /* Check for negTokenInit choice. */
-
- rc2 = spnegoGetTokenType (hSpnegoToken,
- &tokenType);
-
- if (rc2 != SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+200;
- goto cleanup;
- }
-
- if (tokenType != SPNEGO_TOKEN_INIT)
- {
- rc1 = abs(rc2)+300;
- goto cleanup;
- }
-
- /*
- Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
- */
-
- /*
- IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
- */
-
- rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
- spnego_mech_oid_Kerberos_V5_Legacy,
- &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS ||
- pindex != 0)
- {
- rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
- spnego_mech_oid_Kerberos_V5,
- &pindex);
-
- if (rc2 != SPNEGO_E_SUCCESS ||
- pindex != 0)
- {
- rc1 = abs(rc2)+400;
- goto cleanup;
- }
- }
-
- /* Check for no reqFlags. */
-
- /* Does IE ever send reqFlags? */
-
- rc2 = spnegoGetContextFlags (hSpnegoToken,
- &reqFlags);
-
- if (rc2 == SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+500;
- goto cleanup;
- }
-
- /* Get mechanism token length. */
-
- rc2 = spnegoGetMechToken (hSpnegoToken,
- NULL,
- (unsigned long*) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
- {
- rc1 = abs(rc2)+600;
- goto cleanup;
- }
-
- *kerberosToken = malloc (*kerberosTokenLength);
-
- if (!*kerberosToken)
- {
- rc1 = abs(rc2)+700;
- goto cleanup;
- }
-
- /* Get mechanism token data. */
-
- rc2 = spnegoGetMechToken (hSpnegoToken,
- (unsigned char *) *kerberosToken,
- (unsigned long*) kerberosTokenLength);
-
- if (rc2 != SPNEGO_E_SUCCESS)
- {
- rc1 = abs(rc2)+800;
- goto error;
- }
-
- /* According to Microsoft, IE does not send a MIC. */
-
- rc1 = 0;
-
- goto cleanup;
-
-error:
-
- if (*kerberosToken)
- {
- free ((unsigned char *) *kerberosToken);
- *kerberosToken = NULL;
- *kerberosTokenLength = 0;
- }
-
-cleanup:
-
- if (hSpnegoToken)
- spnegoFreeData (hSpnegoToken);
-
- LOG(("parseNegTokenInit returned %d\n",rc1));
- return rc1;
-}
+++ /dev/null
-/* -----------------------------------------------------------------------------
- * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003. All rights reserved.
- * -----------------------------------------------------------------------------
- */
-
-#ifndef SPNEGOHELP_H
-#define SPNEGOHELP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-/* -----------------------------------------------------------------------------
- * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
- * RFC 1964 Kerberos GSS-API token.
- *
- * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
- * memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
-int makeNegTokenTarg (const unsigned char * kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char ** negTokenTarg,
- size_t * negTokenTargLength);
-
-/* -----------------------------------------------------------------------------
- * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
- * an RFC 1964 Kerberos GSS-API token.
- *
- * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
- * returns an error.
- *
- * If parseNegTokenInit is successful, call free (*kerberosToken) to
- * free the memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
-int parseNegTokenInit (const unsigned char * negTokenInit,
- size_t negTokenInitLength,
- const unsigned char ** kerberosToken,
- size_t * kerberosTokenLength);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SPNEGOHELP_H */
+++ /dev/null
-// 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
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGOPARSE.C
-//
-// SPNEGO Token Handler Source File
-//
-// Contains implementation of SPNEGO Token parsing functions.
-//
-/////////////////////////////////////////////////////////////
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-#include "spnego.h"
-#include "derparse.h"
-#include "spnegoparse.h"
-
-//
-// Defined in DERPARSE.C
-//
-
-extern MECH_OID g_stcMechOIDList [];
-
-/**********************************************************************/
-/** **/
-/** **/
-/** **/
-/** **/
-/** Local SPNEGO Helper definitions **/
-/** **/
-/** **/
-/** **/
-/** **/
-/**********************************************************************/
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateMinSpnegoInitTokenSize
-//
-// Parameters:
-// [in] nMechTokenLength - Length of the MechToken Element
-// [in] nMechListMICLength - Length of the MechListMIC Element
-// [in] mechOID - OID for MechList
-// [in] nReqFlagsAvailable - Is ContextFlags element available
-// [out] pnTokenSize - Filled out with total size of token
-// [out] pnInternalTokenLength - Filled out with length minus length
-// for initial token.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Calculates the required length for a SPNEGO NegTokenInit token based
-// on the supplied variable length values and which elements are present.
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long* pnTokenSize,
- long* pnInternalTokenLength )
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTotalLength = 0;
- long nTempLength= 0L;
-
- // We will calculate this by walking the token backwards
-
- // Start with MIC Element
- if ( nMechListMICLength > 0L )
- {
- nTempLength = ASNDerCalcElementLength( nMechListMICLength, NULL );
-
- // Check for rollover error
- if ( nTempLength < nMechListMICLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength += nTempLength;
- }
-
- // Next is the MechToken
- if ( nMechTokenLength > 0L )
- {
- nTempLength += ASNDerCalcElementLength( nMechTokenLength, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
- }
-
- // Next is the ReqFlags
- if ( nReqFlagsAvailable )
- {
- nTempLength += ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
- }
-
- // Next is the MechList - This is REQUIRED
- nTempLength += ASNDerCalcMechListLength( mechOid, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // Following four fields are the basic header tokens
-
- // Sequence Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // SPNEGO OID Token
- nTempLength += g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- nTotalLength = nTempLength;
-
- // App Constructed Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenInitLength;
- }
-
- // The internal length doesn't include the number of bytes
- // for the initial token
- *pnInternalTokenLength = nTotalLength;
- nTotalLength = nTempLength;
-
- // We're done
- *pnTokenSize = nTotalLength;
- nReturn = SPNEGO_E_SUCCESS;
-
-xEndTokenInitLength:
-
- LOG(("CalculateMinSpnegoInitTokenSize returned %d\n",nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CreateSpnegoInitToken
-//
-// Parameters:
-// [in] MechType - OID in MechList
-// [in] ucContextFlags - ContextFlags value
-// [in] pbMechToken - Mech Token Binary Data
-// [in] ulMechTokenLen - Length of Mech Token
-// [in] pbMechListMIC - MechListMIC Binary Data
-// [in] ulMechListMICn - Length of MechListMIC
-// [out] pbTokenData - Buffer to write token into.
-// [in] nTokenLength - Length of pbTokenData buffer
-// [in] nInternalTokenLength - Length of full token without leading
-// token bytes.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Uses DER to fill out pbTokenData with a SPNEGO NegTokenInit Token
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength )
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTempLength= 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
-
- unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
-
- // Temporary buffer to hold the REQ Flags as BIT String Data
- unsigned char abTempReqFlags[SPNEGO_NEGINIT_MAXLEN_REQFLAGS];
-
-
- // We will write the token out backwards to properly handle the cases
- // where the length bytes become adjustable
-
- // Start with MIC Element
- if ( ulMechListMICLen > 0L )
- {
- nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC,
- OCTETSTRING, pbMechListMIC, ulMechListMICLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechListMIC is present
-
- // Next is the MechToken
- if ( ulMechTokenLen > 0L )
- {
- nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHTOKEN,
- OCTETSTRING, pbMechToken, ulMechTokenLen );
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF MechToken Length is present
-
- // Next is the ReqFlags
- if ( ucContextFlags > 0L )
- {
-
- nTempLength = ASNDerCalcElementLength( SPNEGO_NEGINIT_MAXLEN_REQFLAGS, &nInternalLength );
-
- // We need a byte that indicates how many bits difference between the number
- // of bits used in final octet (we only have one) and the max (8)
-
- abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
- abTempReqFlags[1] = ucContextFlags;
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- BITSTRING, abTempReqFlags, SPNEGO_NEGINIT_MAXLEN_REQFLAGS );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- } // IF ContextFlags
-
- // Next is the MechList - This is REQUIRED
- nTempLength = ASNDerCalcMechListLength( MechType, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteMechList( pbWriteTokenData, MechType );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- // The next tokens we're writing out reflect the total number of bytes
- // we have actually written out.
-
- // Sequence Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- NULL, nTotalBytesWritten );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- // Neg Init Token Identifier Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- // SPNEGO OID Token
- nTempLength = g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteOID( pbWriteTokenData, spnego_mech_oid_Spnego );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenInit;
- }
-
- // App Constructed Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT,
- NULL, nTotalBytesWritten );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
-
- // Don't adjust the internal token length here, it doesn't account
- // the initial bytes written out (we really don't need to keep
- // a running count here, but for debugging, it helps to be able
- // to see the total number of bytes written out as well as the
- // number of bytes left to write).
-
- if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData )
- {
- nReturn = SPNEGO_E_SUCCESS;
- }
-
-xEndWriteNegTokenInit:
-
- LOG(("CreateSpnegoInitToken returned %d\n",nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateMinSpnegoTargTokenSize
-//
-// Parameters:
-// [in] MechType - Supported MechType
-// [in] spnegoNegResult - Neg Result
-// [in] nMechTokenLength - Length of the MechToken Element
-// [in] nMechListMICLength - Length of the MechListMIC Element
-// [out] pnTokenSize - Filled out with total size of token
-// [out] pnInternalTokenLength - Filled out with length minus length
-// for initial token.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Calculates the required length for a SPNEGO NegTokenTarg token based
-// on the supplied variable length values and which elements are present.
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechListMICLen, long* pnTokenSize,
- long* pnInternalTokenLength )
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTotalLength = 0;
- long nTempLength= 0L;
-
- // We will calculate this by walking the token backwards
-
- // Start with MIC Element
- if ( nMechListMICLen > 0L )
- {
- nTempLength = ASNDerCalcElementLength( nMechListMICLen, NULL );
-
- // Check for rollover error
- if ( nTempLength < nMechListMICLen )
- {
- goto xEndTokenTargLength;
- }
-
- nTotalLength += nTempLength;
- }
-
- // Next is the MechToken
- if ( nMechTokenLen > 0L )
- {
- nTempLength += ASNDerCalcElementLength( nMechTokenLen, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
- }
-
- // Supported MechType
- if ( spnego_mech_oid_NotUsed != MechType )
- {
- // Supported MechOID element - we use the token function since
- // we already know the size of the OID token and value
- nTempLength += ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
- NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF MechType is available
-
- // NegResult Element
- if ( spnego_negresult_NotUsed != spnegoNegResult )
- {
- nTempLength += ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- } // IF negResult is available
-
- // Following two fields are the basic header tokens
-
- // Sequence Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenTargLength;
- }
-
- nTotalLength = nTempLength;
-
- // Neg Token Identifier Token
- nTempLength += ASNDerCalcTokenLength( nTotalLength, 0L );
-
- // Check for rollover error
- if ( nTempLength < nTotalLength )
- {
- goto xEndTokenTargLength;
- }
-
- // The internal length doesn't include the number of bytes
- // for the initial token
- *pnInternalTokenLength = nTotalLength;
- nTotalLength = nTempLength;
-
- // We're done
- *pnTokenSize = nTotalLength;
- nReturn = SPNEGO_E_SUCCESS;
-
-xEndTokenTargLength:
-
- LOG(("CalculateMinSpnegoTargTokenSize returned %d\n",nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CreateSpnegoTargToken
-//
-// Parameters:
-// [in] MechType - Supported MechType
-// [in] eNegResult - NegResult value
-// [in] pbMechToken - Mech Token Binary Data
-// [in] ulMechTokenLen - Length of Mech Token
-// [in] pbMechListMIC - MechListMIC Binary Data
-// [in] ulMechListMICn - Length of MechListMIC
-// [out] pbTokenData - Buffer to write token into.
-// [in] nTokenLength - Length of pbTokenData buffer
-// [in] nInternalTokenLength - Length of full token without leading
-// token bytes.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Uses DER to fill out pbTokenData with a SPNEGO NegTokenTarg Token
-// Note that because the lengths can be represented by an arbitrary
-// number of bytes in DER encodings, we actually calculate the lengths
-// backwards, so we always know how many bytes we will potentially be
-// writing out.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength )
-{
- int nReturn = SPNEGO_E_INVALID_LENGTH;
-
- // Start at 0.
- long nTempLength= 0L;
- long nTotalBytesWritten = 0L;
- long nInternalLength = 0L;
-
- unsigned char ucTemp = 0;
-
- // We will write the token out backwards to properly handle the cases
- // where the length bytes become adjustable, so the write location
- // is initialized to point *just* past the end of the buffer.
-
- unsigned char* pbWriteTokenData = pbTokenData + nTokenLength;
-
-
- // Start with MIC Element
- if ( ulMechListMICLen > 0L )
- {
- nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
-
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC,
- OCTETSTRING, pbMechListMIC, ulMechListMICLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechListMIC is present
-
- // Next is the MechToken
- if ( ulMechTokenLen > 0L )
- {
- nTempLength = ASNDerCalcElementLength( ulMechTokenLen, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN,
- OCTETSTRING, pbMechToken, ulMechTokenLen );
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechToken Length is present
-
- // Supported Mech Type
- if ( spnego_mech_oid_NotUsed != MechType )
- {
-
- nTempLength = ASNDerCalcElementLength( g_stcMechOIDList[MechType].iActualDataLen,
- &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- g_stcMechOIDList[MechType].ucOid,
- g_stcMechOIDList[MechType].iLen );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenTarg;
- }
-
- } // IF MechType is present
-
- // Neg Result
- // NegResult Element
- if ( spnego_negresult_NotUsed != eNegResult )
- {
- ucTemp = (unsigned char) eNegResult;
-
- nTempLength = ASNDerCalcElementLength( SPNEGO_NEGTARG_MAXLEN_NEGRESULT, &nInternalLength );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
- ENUMERATED, &ucTemp, SPNEGO_NEGTARG_MAXLEN_NEGRESULT );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenTarg;
- }
-
- } // If eNegResult is available
-
- // The next tokens we're writing out reflect the total number of bytes
- // we have actually written out.
-
- // Sequence Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- NULL, nTotalBytesWritten );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if ( nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0 )
- {
- goto xEndWriteNegTokenTarg;
- }
-
- // Neg Targ Token Identifier Token
- nTempLength = ASNDerCalcTokenLength( nTotalBytesWritten, 0L );
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteToken( pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten );
-
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
-
- // Don't adjust the internal token length here, it doesn't account
- // the initial bytes written out (we really don't need to keep
- // a running count here, but for debugging, it helps to be able
- // to see the total number of bytes written out as well as the
- // number of bytes left to write).
-
- if ( nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData )
- {
- nReturn = SPNEGO_E_SUCCESS;
- }
-
-
-xEndWriteNegTokenTarg:
-
- LOG(("CreateSpnegoTargToken returned %d\n",nReturn));
- return nReturn;
-
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// AllocEmptySpnegoToken
-//
-// Parameters:
-// [in] ucCopyData - Flag to copy data or pointer.
-// [in] ulFlags - Flags for SPNEGO_TOKEN data member.
-// [in] pbTokenData - Binary token data.
-// [in] ulTokenSize - Size of pbTokenData.
-//
-// Returns:
-// SPNEGO_TOKEN* Success - Pointer to initialized SPNEGO_TOKEN struct
-// Failure - NULL
-//
-// Comments :
-// Allocates a SPNEGO_TOKEN data structure and initializes it. Based on
-// the value of ucCopyData, if non-zero, we copy the data into a buffer
-// we allocate in this function, otherwise, we copy the data pointer
-// direcly.
-//
-////////////////////////////////////////////////////////////////////////////
-
-SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char * pbTokenData, unsigned long ulTokenSize )
-{
- SPNEGO_TOKEN* pSpnegoToken = (SPNEGO_TOKEN*) calloc( 1, sizeof(SPNEGO_TOKEN) );
-
- if ( NULL != pSpnegoToken )
- {
- // Set the token size
- pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
-
- // Initialize the element array
- InitSpnegoTokenElementArray( pSpnegoToken );
-
- // Assign the flags value
- pSpnegoToken->ulFlags = ulFlags;
-
- //
- // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
- // Otherwise, we will just copy the pointer and the length. This is so we
- // can cut out additional allocations for performance reasons
- //
-
- if ( SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData )
- {
- // Alloc the internal buffer. Cleanup on failure.
- pSpnegoToken->pbBinaryData = (unsigned char*) calloc( ulTokenSize, sizeof(unsigned char) );
-
- if ( NULL != pSpnegoToken->pbBinaryData )
- {
- // We must ALWAYS free this buffer
- pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
-
- // Copy the data locally
- memcpy( pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize );
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- }
- else
- {
- free( pSpnegoToken );
- pSpnegoToken = NULL;
- }
-
- } // IF ucCopyData
- else
- {
- // Copy the pointer and the length directly - ulFlags will control whether or not
- // we are allowed to free the value
-
- pSpnegoToken->pbBinaryData = pbTokenData;
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- }
-
- }
-
- return pSpnegoToken;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// FreeSpnegoToken
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN to free.
-//
-// Returns:
-// void
-//
-// Comments :
-// If non-NULL, interprets pSpnegoToken, freeing any internal allocations
-// and finally the actual structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
-{
- if ( NULL != pSpnegoToken )
- {
-
- // Cleanup internal allocation per the flags
- if ( pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
- NULL != pSpnegoToken->pbBinaryData )
- {
- free( pSpnegoToken->pbBinaryData );
- pSpnegoToken->pbBinaryData = NULL;
- }
-
- free ( pSpnegoToken );
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementArray
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
-//
-// Returns:
-// void
-//
-// Comments :
-// Initializes the element array data member of a SPNEGO_TOKEN data
-// structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken )
-{
- int nCtr;
-
- // Set the number of elemnts
- pSpnegoToken->nNumElements = MAX_NUM_TOKEN_ELEMENTS;
-
- //
- // Initially, all elements are unavailable
- //
-
- for ( nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++ )
- {
- // Set the element size as well
- pSpnegoToken->aElementArray[ nCtr ].nStructSize = SPNEGO_ELEMENT_SIZE;
- pSpnegoToken->aElementArray[ nCtr ].iElementPresent = SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
- }
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenType
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN structure.
-// [out] pnTokenLength - Filled out with total token length
-// [out] pnRemainingTokenLength - Filled out with remaining length
-// after header is parsed
-// [out] ppbFirstElement - Filled out with pointer to first
-// element after header info.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Walks the underlying binary data for a SPNEGO_TOKEN data structure
-// and determines the type of the underlying token based on token header
-// information.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
- long* pnRemainingTokenLength, unsigned char** ppbFirstElement )
-{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nActualTokenLength = 0L;
- long nBoundaryLength = pSpnegoToken->ulBinaryDataLen;
- unsigned char* pbTokenData = pSpnegoToken->pbBinaryData;
-
- //
- // First byte MUST be either an APP_CONSTRUCT or the NEGTARG_TOKEN_TARG
- //
-
- if ( SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData )
- {
- // Validate the above token - this will tell us the actual length of the token
- // per the encoding (minus the actual token bytes)
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L, nBoundaryLength,
- pnTokenLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should be an OID
- if ( ( nReturn = ASNDerCheckOID( pbTokenData, spnego_mech_oid_Spnego, nBoundaryLength,
- &nActualTokenLength ) ) == SPNEGO_E_SUCCESS )
- {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the NegTokenInit
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
-
- } // IF Check for SPNEGO OID
-
-
- } // IF check app construct token
-
- }
- else if ( SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData )
- {
-
- // The next token should specify the NegTokenInit
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
- } // ELSE IF it's a NegTokenTarg
-
- LOG(("InitSpnegoTokenType returned %d\n",nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// GetSpnegoInitTokenMechList
-//
-// Parameters:
-// [in] pbTokenData - Points to binary MechList element
-// in NegTokenInit.
-// [in] nMechListLength - Length of the MechList
-// [out] pSpnegoElement - Filled out with MechList Element
-// data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks that pbTokenData is pointing at something that at least
-// *looks* like a MechList and then fills out the supplied
-// SPNEGO_ELEMENT structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT* pSpnegoElement )
-{
- int nReturn = SPNEGO_E_INVALID_TOKEN;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // Actual MechList is prepended by a Constructed Sequence Token
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- nMechListLength, nMechListLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Adjust for this token
- nMechListLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Perform simple validation of the actual MechList (i.e. ensure that
- // the OIDs in the MechList are reasonable).
-
- if ( ( nReturn = ValidateMechList( pbTokenData, nLength ) ) == SPNEGO_E_SUCCESS )
- {
- // Initialize the element now
- pSpnegoElement->eElementType = spnego_init_mechtypes;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF Check Token
-
- LOG(("GetSpnegoInitTokenMechList returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementFromBasicType
-//
-// Parameters:
-// [in] pbTokenData - Points to binary element data in
-// a SPNEGO token.
-// [in] nElementLength - Length of the element
-// [in] ucExpectedType - Expected DER type.
-// [in] spnegoElementType - Which element is this?
-// [out] pSpnegoElement - Filled out with element data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks that pbTokenData is pointing at the specified DER type. If so,
-// then we verify that lengths are proper and then fill out the
-// SPNEGO_ELEMENT data structure.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
- unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement )
-{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // The type BYTE must match our token data or something is badly wrong
- if ( *pbTokenData == ucExpectedType )
- {
-
- // Check that we are pointing at the specified type
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, ucExpectedType,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Adjust for this token
- nElementLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = ucExpectedType;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n",nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElementFromOID
-//
-// Parameters:
-// [in] pbTokenData - Points to binary element data in
-// a SPNEGO token.
-// [in] nElementLength - Length of the element
-// [in] spnegoElementType - Which element is this?
-// [out] pSpnegoElement - Filled out with element data.
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Initializes a SpnegoElement from an OID - normally, this would have
-// used the Basic Type function above, but since we do binary compares
-// on the OIDs against the DER information as well as the OID, we need
-// to account for that.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement )
-{
- int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
- long nLength = 0L;
- long nActualTokenLength = 0L;
-
- // The type BYTE must match our token data or something is badly wrong
- if ( *pbTokenData == OID )
- {
-
- // Check that we are pointing at an OID type
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, OID,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- // Don't adjust any values for this function
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = OID;
- pSpnegoElement->nDatalength = nElementLength;
- pSpnegoElement->pbData = pbTokenData;
- }
-
- } // IF type makes sense
-
- LOG(("InitSpnegoTokenElementFromBasicType returned %d\n",nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitSpnegoTokenElements
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN struct
-// [in] pbTokenData - Points to initial binary element
-// data in a SPNEGO token.
-// [in] nRemainingTokenLength - Length remaining past header
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Interprets the data at pbTokenData based on the TokenType in
-// pSpnegoToken. Since some elements are optional (technically all are
-// but the token becomes quite useless if this is so), we check if
-// an element exists before filling out the element in the array.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
- long nRemainingTokenLength )
-{
- //
- // The following arrays contain the token identifiers for the elements
- // comprising the actual token. All values are optional, and there are
- // no defaults.
- //
-
- static unsigned char abNegTokenInitElements[] =
- { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC };
-
- static unsigned char abNegTokenTargElements[] =
- { SPNEGO_NEGTARG_ELEMENT_NEGRESULT, SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC };
-
- int nReturn = SPNEGO_E_SUCCESS;
- int nCtr = 0L;
- long nElementLength = 0L;
- long nActualTokenLength = 0L;
- unsigned char* pbElements = NULL;
-
- // Point to the correct array
- switch( pSpnegoToken->ucTokenType )
- {
- case SPNEGO_TOKEN_INIT:
- {
- pbElements = abNegTokenInitElements;
- }
- break;
-
- case SPNEGO_TOKEN_TARG:
- {
- pbElements = abNegTokenTargElements;
- }
- break;
-
- } // SWITCH tokentype
-
- //
- // Enumerate the element arrays and look for the tokens at our current location
- //
-
- for ( nCtr = 0L;
- SPNEGO_E_SUCCESS == nReturn &&
- nCtr < MAX_NUM_TOKEN_ELEMENTS &&
- nRemainingTokenLength > 0L;
- nCtr++ )
- {
-
- // Check if the token exists
- if ( ( nReturn = ASNDerCheckToken( pbTokenData, pbElements[nCtr],
- 0L, nRemainingTokenLength,
- &nElementLength, &nActualTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
-
- // Token data should skip over the sequence token and then
- // call the appropriate function to initialize the element
- pbTokenData += nActualTokenLength;
-
- // Lengths in the elements should NOT go beyond the element
- // length
-
- // Different tokens mean different elements
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
- {
-
- // Handle each element as appropriate
- switch( pbElements[nCtr] )
- {
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTYPES:
- {
- //
- // This is a Mech List that specifies which OIDs the
- // originator of the Init Token supports.
- //
-
- nReturn = GetSpnegoInitTokenMechList( pbTokenData, nElementLength,
- &pSpnegoToken->aElementArray[nCtr] );
-
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_REQFLAGS:
- {
- //
- // This is a BITSTRING which specifies the flags that the receiver
- // pass to the gss_accept_sec_context() function.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- BITSTRING, spnego_init_reqFlags,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN:
- {
- //
- // This is an OCTETSTRING which contains a GSSAPI token corresponding
- // to the first OID in the MechList.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_init_mechToken,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC:
- {
- //
- // This is an OCTETSTRING which contains a message integrity BLOB.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_init_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- } // SWITCH Element
- }
- else
- {
-
- switch( pbElements[nCtr] )
- {
-
- case SPNEGO_NEGTARG_ELEMENT_NEGRESULT:
- {
- //
- // This is an ENUMERATION which specifies result of the last GSS
- // token negotiation call.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- ENUMERATED, spnego_targ_negResult,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH:
- {
- //
- // This is an OID which specifies a supported mechanism.
- //
-
- nReturn = InitSpnegoTokenElementFromOID( pbTokenData, nElementLength,
- spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN:
- {
- //
- // This is an OCTETSTRING which specifies results of the last GSS
- // token negotiation call.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_targ_responseToken,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC:
- {
- //
- // This is an OCTETSTRING which specifies a message integrity BLOB.
- //
-
- nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- }
- break;
-
- } // SWITCH Element
-
- } // ELSE !NegTokenInit
-
- // Account for the entire token and following data
- nRemainingTokenLength -= ( nActualTokenLength + nElementLength );
-
- // Token data should skip past the element length now
- pbTokenData += nElementLength;
-
- } // IF Token found
- else if ( SPNEGO_E_TOKEN_NOT_FOUND == nReturn )
- {
- // For now, this is a benign error (remember, all elements are optional, so
- // if we don't find one, it's okay).
-
- nReturn = SPNEGO_E_SUCCESS;
- }
-
- } // FOR enum elements
-
- //
- // We should always run down to 0 remaining bytes in the token. If not, we've got
- // a bad token.
- //
-
- if ( SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L )
- {
- nReturn = SPNEGO_E_INVALID_TOKEN;
- }
-
- LOG(("InitSpnegoTokenElements returned %d\n",nReturn));
- return nReturn;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// FindMechOIDInMechList
-//
-// Parameters:
-// [in] pSpnegoElement - SPNEGO_ELEMENT for MechList
-// [in] MechOID - OID we're looking for.
-// [out] piMechTypeIndex - Index in the list where OID was
-// found
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Walks the MechList for MechOID. When it is found, the index in the
-// list is written to piMechTypeIndex.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int * piMechTypeIndex )
-{
- int nReturn = SPNEGO_E_NOT_FOUND;
- int nCtr = 0;
- long nLength = 0L;
- long nBoundaryLength = pSpnegoElement->nDatalength;
- unsigned char* pbMechListData = pSpnegoElement->pbData;
-
- while( SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L )
- {
-
- // Use the helper function to check the OID
- if ( ( nReturn = ASNDerCheckOID( pbMechListData, MechOID, nBoundaryLength, &nLength ) )
- == SPNEGO_E_SUCCESS )
- {
- *piMechTypeIndex = nCtr;
- }
-
- // Adjust for the current OID
- pbMechListData += nLength;
- nBoundaryLength -= nLength;
- nCtr++;
-
- } // WHILE enuming OIDs
-
- LOG(("FindMechOIDInMechList returned %d\n",nReturn));
- return nReturn;
-
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// ValidateMechList
-//
-// Parameters:
-// [in] pbMechListData - Pointer to binary MechList data
-// [in] nBoundaryLength - Length we must not exceed
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Checks the data at pbMechListData to see if it looks like a MechList.
-// As part of this, we walk the list and ensure that none of the OIDs
-// have a length that takes us outside of nBoundaryLength.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength )
-{
- int nReturn = SPNEGO_E_SUCCESS;
- long nLength = 0L;
- long nTokenLength = 0L;
-
- while( SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L )
- {
- // Verify that we have something that at least *looks* like an OID - in other
- // words it has an OID identifier and specifies a length that doesn't go beyond
- // the size of the list.
- nReturn = ASNDerCheckToken( pbMechListData, OID, 0L, nBoundaryLength,
- &nLength, &nTokenLength );
-
- // Adjust for the current OID
- pbMechListData += ( nLength + nTokenLength );
- nBoundaryLength -= ( nLength + nTokenLength );
-
- } // WHILE enuming OIDs
-
- LOG(("ValidateMechList returned %d\n",nReturn));
- return nReturn;
-
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidMechOid
-//
-// Parameters:
-// [in] mechOid - mechOID id enumeration
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid mechOid value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int IsValidMechOid( SPNEGO_MECH_OID mechOid )
-{
- LOG(("IsValidMechOid returned %d\n",mechOid >= spnego_mech_oid_Kerberos_V5_Legacy &&
- mechOid <= spnego_mech_oid_Spnego));
- return ( mechOid >= spnego_mech_oid_Kerberos_V5_Legacy &&
- mechOid <= spnego_mech_oid_Spnego );
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidContextFlags
-//
-// Parameters:
-// [in] ucContextFlags - ContextFlags value
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid ContextFlags value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int IsValidContextFlags( unsigned char ucContextFlags )
-{
- // Mask out our valid bits. If there is anything leftover, this
- // is not a valid value for Context Flags
- LOG(("IsValidContextFlags returned %d\n",(( ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK ) == 0)));
- return ( ( ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK ) == 0 );
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidNegResult
-//
-// Parameters:
-// [in] negResult - NegResult value
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks for a valid NegResult value.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int IsValidNegResult( SPNEGO_NEGRESULT negResult )
-{
- LOG(("IsValidNegResult returned %d\n",negResult >= spnego_negresult_success &&
- negResult <= spnego_negresult_rejected ));
- return ( negResult >= spnego_negresult_success &&
- negResult <= spnego_negresult_rejected );
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidSpnegoToken
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Performs simple heuristic on location pointed to by pSpnegoToken.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken )
-{
- int nReturn = 0;
-
- // Parameter should be non-NULL
- if ( NULL != pSpnegoToken )
- {
- // Length should be at least the size defined in the header
- if ( pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE )
- {
- // Number of elements should be >= our maximum - if it's greater, that's
- // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
- if ( pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS )
- {
- // Check for proper token type
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType )
- {
- nReturn = 1;
- }
- }
-
- } // IF struct size makes sense
-
- } // IF non-NULL spnego Token
-
- LOG(("IsValidSpnegoToken returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// IsValidSpnegoElement
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-// [in] spnegoElement - spnegoElement Type from enumeration
-//
-// Returns:
-// int Success - 1
-// Failure - 0
-//
-// Comments :
-// Checks that spnegoElement has a valid value and is appropriate for
-// the SPNEGO token encapsulated by pSpnegoToken.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
-{
- int nReturn = 0;
-
- // Check boundaries
- if ( spnegoElement > spnego_element_min &&
- spnegoElement < spnego_element_max )
- {
-
- // Check for appropriateness to token type
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
- {
- nReturn = ( spnegoElement >= spnego_init_mechtypes &&
- spnegoElement <= spnego_init_mechListMIC );
- }
- else
- {
- nReturn = ( spnegoElement >= spnego_targ_negResult &&
- spnegoElement <= spnego_targ_mechListMIC );
- }
-
- } // IF boundary conditions are met
-
- LOG(("IsValidSpnegoElement returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// CalculateElementArrayIndex
-//
-// Parameters:
-// [in] pSpnegoToken - Points to SPNEGO_TOKEN data structure
-// [in] spnegoElement - spnegoElement Type from enumeration
-//
-// Returns:
-// int index in the SPNEGO_TOKEN element array that the element can
-// can be found
-//
-// Comments :
-// Based on the Token Type, calculates the index in the element array
-// at which the specified element can be found.
-//
-////////////////////////////////////////////////////////////////////////////
-
-int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement )
-{
- int nReturn = 0;
-
- // Offset is difference between value and initial element identifier
- // (these differ based on ucTokenType)
-
- if ( SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType )
- {
- nReturn = spnegoElement - spnego_init_mechtypes;
- }
- else
- {
- nReturn = spnegoElement - spnego_targ_negResult;
- }
-
- LOG(("CalculateElementArrayIndex returned %d\n",nReturn));
- return nReturn;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Function:
-// InitTokenFromBinary
-//
-// Parameters:
-// [in] ucCopyData - Flag indicating if data should be copied
-// [in] ulFlags - Flags value for structure
-// [in] pnTokenData - Binary Token Data
-// [in] ulLength - Length of the data
-// [out] ppSpnegoToken - Pointer to call allocated SPNEGO Token
-// data structure
-//
-// Returns:
-// int Success - SPNEGO_E_SUCCESS
-// Failure - SPNEGO API Error code
-//
-// Comments :
-// Allocates a SPNEGO_TOKEN data structure and fills it out as
-// appropriate based in the flags passed into the function.
-//
-////////////////////////////////////////////////////////////////////////////
-
-
-// Initializes SPNEGO_TOKEN structure from DER encoded binary data
-int InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char* pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN** ppSpnegoToken )
-{
- int nReturn = SPNEGO_E_INVALID_PARAMETER;
- SPNEGO_TOKEN* pSpnegoToken = NULL;
- unsigned char* pbFirstElement = NULL;
- long nTokenLength = 0L;
- long nRemainingTokenLength = 0L;
-
- // Basic Parameter Validation
-
- if ( NULL != pbTokenData &&
- NULL != ppSpnegoToken &&
- 0L != ulLength )
- {
-
- //
- // Allocate the empty token, then initialize the data structure.
- //
-
- pSpnegoToken = AllocEmptySpnegoToken( ucCopyData, ulFlags, pbTokenData, ulLength );
-
- if ( NULL != pSpnegoToken )
- {
-
- // Copy the binary data locally
-
-
- // Initialize the token type
- if ( ( nReturn = InitSpnegoTokenType( pSpnegoToken, &nTokenLength,
- &nRemainingTokenLength, &pbFirstElement ) )
- == SPNEGO_E_SUCCESS )
- {
-
- // Initialize the element array
- if ( ( nReturn = InitSpnegoTokenElements( pSpnegoToken, pbFirstElement,
- nRemainingTokenLength ) )
- == SPNEGO_E_SUCCESS )
- {
- *ppSpnegoToken = pSpnegoToken;
- }
-
- } // IF Init Token Type
-
- // Cleanup on error condition
- if ( SPNEGO_E_SUCCESS != nReturn )
- {
- spnegoFreeData( pSpnegoToken );
- }
-
- }
- else
- {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // IF Valid parameters
-
-
- LOG(("InitTokenFromBinary returned %d\n",nReturn));
- return nReturn;
-}
+++ /dev/null
-// 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
-
-/////////////////////////////////////////////////////////////
-//
-// SPNEGOPARSE.H
-//
-// SPNEGO Token Parser Header File
-//
-// Contains the definitions required to properly parse a
-// SPNEGO token using ASN.1 DER helpers.
-//
-/////////////////////////////////////////////////////////////
-
-#ifndef __SPNEGOPARSE_H__
-#define __SPNEGOPARSE_H__
-
-// C++ Specific
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-// Indicates if we copy data when creating a SPNEGO_TOKEN structure or not
-#define SPNEGO_TOKEN_INTERNAL_COPYPTR 0
-#define SPNEGO_TOKEN_INTERNAL_COPYDATA 0x1
-
-// Internal flag dictates whether or not we will free the binary data when
-// the SPNEG_TOKEN structure is destroyed
-#define SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA 0x1
-
- //
-// Each SPNEGO Token Type can be broken down into a
-// maximum of 4 separate elements.
-//
-
-#define MAX_NUM_TOKEN_ELEMENTS 4
-
-//
-// Element offsets in the array
-//
-
-// INIT elements
-#define SPNEGO_INIT_MECHTYPES_ELEMENT 0
-#define SPNEGO_INIT_REQFLAGS_ELEMENT 1
-#define SPNEGO_INIT_MECHTOKEN_ELEMENT 2
-#define SPNEGO_INIT_MECHLISTMIC_ELEMENT 3
-
-// Response elements
-#define SPNEGO_TARG_NEGRESULT_ELEMENT 0
-#define SPNEGO_TARG_SUPPMECH_ELEMENT 1
-#define SPNEGO_TARG_RESPTOKEN_ELEMENT 2
-#define SPNEGO_TARG_MECHLISTMIC_ELEMENT 3
-
-//
-// Defines an individual SPNEGO Token Element.
-//
-
-typedef struct SpnegoElement
-{
- size_t nStructSize; // Size of the element structure
- int iElementPresent; // Is the field present? Must be either
- // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
- // SPNEGO_TOKEN_ELEMENT_AVAILABLE
-
- SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
-
- unsigned char type; // Data Type
-
- unsigned char* pbData; // Points to actual Data
-
- unsigned long nDatalength; // Actual Data Length
-
-} SPNEGO_ELEMENT;
-
-// Structure size in case we later choose to extend the structure
-#define SPNEGO_ELEMENT_SIZE sizeof(SPNEGO_ELEMENT)
-
-//
-// Packages a SPNEGO Token Encoding. There are two types of
-// encodings: NegTokenInit and NegTokenTarg. Each encoding can
-// contain up to four distinct, optional elements.
-//
-
-typedef struct SpnegoToken
-{
- size_t nStructSize; // Size of the Token structure
- unsigned long ulFlags; // Internal Structure Flags - Reserved!
- int ucTokenType; // Token Type - Must be
- // SPNEGO_TOKEN_INIT or
- // SPNEGO_TOKEN_TARG
-
- unsigned char* pbBinaryData; // Points to binary token data
-
- unsigned long ulBinaryDataLen; // Length of the actual binary data
- int nNumElements; // Number of elements
- SPNEGO_ELEMENT aElementArray [MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
-} SPNEGO_TOKEN;
-
-// Structure size in case we later choose to extend the structure
-#define SPNEGO_TOKEN_SIZE sizeof(SPNEGO_TOKEN)
-
-//
-// Function definitions
-//
-
-SPNEGO_TOKEN* AllocEmptySpnegoToken( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char * pbTokenData, unsigned long ulTokenSize );
-void FreeSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
-void InitSpnegoTokenElementArray( SPNEGO_TOKEN* pSpnegoToken );
-int InitSpnegoTokenType( SPNEGO_TOKEN* pSpnegoToken, long* pnTokenLength,
- long* pnRemainingTokenLength, unsigned char** ppbFirstElement );
-int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenData,
- long nRemainingTokenLength );
-int GetSpnegoInitTokenMechList( unsigned char* pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT* pSpnegoElement );
-int InitSpnegoTokenElementFromBasicType( unsigned char* pbTokenData, int nElementLength,
- unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement );
-int InitSpnegoTokenElementFromOID( unsigned char* pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT* pSpnegoElement );
-int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int * piMechTypeIndex );
-int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength );
-int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, long nMechListMICLength,
- SPNEGO_MECH_OID mechOid, int nReqFlagsAvailable,
- long* plTokenSize, long* plInternalLength );
-int CalculateMinSpnegoTargTokenSize( SPNEGO_MECH_OID MechType, SPNEGO_NEGRESULT spnegoNegResult,
- long nMechTokenLen,
- long nMechTokenMIC, long* pnTokenSize,
- long* pnInternalTokenLength );
-int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength );
-int CreateSpnegoTargToken( SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char* pbMechToken,
- unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char* pbTokenData,
- long nTokenLength, long nInternalTokenLength );
-int IsValidMechOid( SPNEGO_MECH_OID mechOid );
-int IsValidContextFlags( unsigned char ucContextFlags );
-int IsValidNegResult( SPNEGO_NEGRESULT negResult );
-int IsValidSpnegoToken( SPNEGO_TOKEN* pSpnegoToken );
-int IsValidSpnegoElement( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
-int CalculateElementArrayIndex( SPNEGO_TOKEN* pSpnegoToken,SPNEGO_ELEMENT_TYPE spnegoElement );
-int InitTokenFromBinary( unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char* pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN** ppSpnegoToken );
-
- // C++ Specific
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
-
#include <sys/time.h>
#include "base64.h"
-#ifndef HAVE_SPNEGO
-#include "spnegohelp.h"
-#endif
// AYJ: must match the definition in src/auth/negotiate/auth_negotiate.cc
#define MAX_AUTHTOKEN_LEN 32768
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
const unsigned char *kerberosToken = NULL;
-#ifndef HAVE_SPNEGO
- int rc;
- size_t kerberosTokenLength = 0;
-#endif
const unsigned char *spnegoToken = NULL ;
size_t spnegoTokenLength = 0;
base64_decode(input_token.value,buf+3,input_token.length);
-#ifndef HAVE_SPNEGO
- if (( rc=parseNegTokenInit (input_token.value,
- input_token.length,
- &kerberosToken,
- &kerberosTokenLength))!=0 ){
- if (debug)
- fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n", LogTime(), PROGRAM, rc);
-
- /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
- if ( rc < 100 || rc > 199 ) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n", LogTime(), PROGRAM, buf);
- fprintf(stdout, "NA Invalid GSS-SPNEGO query\n");
- goto cleanup;
- }
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp (input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n", LogTime(), PROGRAM, (int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- fprintf(stdout, "NA received type %d NTLM token\n",(int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
- goto cleanup;
- }
- spnego_flag=0;
- } else {
- gss_release_buffer(&minor_status, &input_token);
- input_token.length=kerberosTokenLength;
- input_token.value=(void *)kerberosToken;
- spnego_flag=1;
- }
-#else
if ((input_token.length >= sizeof ntlmProtocol + 1) &&
(!memcmp (input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
if (debug)
fprintf(stdout, "NA received type %d NTLM token\n",(int) *((unsigned char *)input_token.value + sizeof ntlmProtocol));
goto cleanup;
}
-#endif
if ( service_principal ) {
if ( strcasecmp(service_principal,"GSS_C_NO_NAME") ){