921 lines
19 KiB
C++
921 lines
19 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
|
//
|
|
// File: negsupp.cxx
|
|
//
|
|
// Contents: General (both win9x and nt) functions
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 02-09-00 RichardW Created - split from negotiat.cxx
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <lsapch.hxx>
|
|
|
|
#ifdef WIN32_CHICAGO
|
|
#include <kerb.hxx>
|
|
#endif // WIN32_CHICAGO
|
|
|
|
extern "C"
|
|
{
|
|
#include <align.h>
|
|
#include <lm.h>
|
|
#include <dsgetdc.h>
|
|
#include <cryptdll.h>
|
|
#ifndef WIN32_CHICAGO
|
|
#include <spmgr.h>
|
|
#endif
|
|
#include "sesmgr.h"
|
|
#include "spinit.h"
|
|
}
|
|
|
|
#include "negotiat.hxx"
|
|
#ifdef WIN32_CHICAGO
|
|
#include <debug.h>
|
|
#include <rpc.h> // fpr SEC_WINNT_AUTH_IDENTITY_ANSI
|
|
#define LsapChangeBuffer( o, n ) 0 ; CopyMemory( (n), (o),sizeof(SecBuffer) )
|
|
#endif // WIN32_CHICAGO
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
BOOL fSPNEGOModuleStarted = FALSE;
|
|
|
|
|
|
|
|
int
|
|
SpnegoInitAsn(
|
|
IN OUT ASN1encoding_t * pEnc,
|
|
IN OUT ASN1decoding_t * pDec
|
|
)
|
|
{
|
|
int Result = 0;
|
|
ASN1error_e Asn1Err;
|
|
|
|
if (!fSPNEGOModuleStarted)
|
|
{
|
|
fSPNEGOModuleStarted = TRUE;
|
|
SPNEGO_Module_Startup();
|
|
}
|
|
|
|
if (pEnc != NULL)
|
|
{
|
|
Asn1Err = ASN1_CreateEncoder(
|
|
SPNEGO_Module,
|
|
pEnc,
|
|
NULL, // pbBuf
|
|
0, // cbBufSize
|
|
NULL // pParent
|
|
);
|
|
}
|
|
else
|
|
{
|
|
Asn1Err = ASN1_CreateDecoder(
|
|
SPNEGO_Module,
|
|
pDec,
|
|
NULL, // pbBuf
|
|
0, // cbBufSize
|
|
NULL // pParent
|
|
);
|
|
}
|
|
|
|
if (ASN1_SUCCESS != Asn1Err)
|
|
{
|
|
DebugLog((DEB_ERROR, "Failed to init ASN1: 0x%x\n",Asn1Err));
|
|
Result = 1;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
VOID
|
|
SpnegoTermAsn(
|
|
IN ASN1encoding_t pEnc,
|
|
IN ASN1decoding_t pDec
|
|
)
|
|
{
|
|
if (pEnc != NULL)
|
|
{
|
|
ASN1_CloseEncoder(pEnc);
|
|
}
|
|
else if (pDec != NULL)
|
|
{
|
|
ASN1_CloseDecoder(pDec);
|
|
}
|
|
|
|
//SPNEGO_Module_Cleanup();
|
|
}
|
|
|
|
int NTAPI
|
|
SpnegoUnpackData(
|
|
IN PUCHAR Data,
|
|
IN ULONG DataSize,
|
|
IN ULONG PduValue,
|
|
OUT PVOID * DecodedData
|
|
)
|
|
{
|
|
int Result = 0;
|
|
ULONG OldPduValue;
|
|
ASN1decoding_t pDec = NULL;
|
|
ASN1error_e Asn1Err;
|
|
|
|
if ((DataSize == 0) || (Data == NULL))
|
|
{
|
|
DebugLog((DEB_ERROR,"Trying to unpack NULL data\n"));
|
|
return(1);
|
|
}
|
|
|
|
|
|
Result = SpnegoInitAsn(
|
|
NULL,
|
|
&pDec // we are decoding
|
|
);
|
|
if (Result != 0)
|
|
{
|
|
return(Result);
|
|
}
|
|
|
|
|
|
*DecodedData = NULL;
|
|
Asn1Err = ASN1_Decode(
|
|
pDec,
|
|
DecodedData,
|
|
PduValue,
|
|
ASN1DECODE_SETBUFFER,
|
|
(BYTE *) Data,
|
|
DataSize
|
|
);
|
|
|
|
if (!ASN1_SUCCEEDED(Asn1Err))
|
|
{
|
|
if ((ASN1_ERR_BADARGS == Asn1Err) ||
|
|
(ASN1_ERR_EOD == Asn1Err))
|
|
{
|
|
DebugLog((DEB_TRACE,"More input required to decode data %d.\n",PduValue));
|
|
Result = 1;
|
|
}
|
|
else
|
|
{
|
|
DebugLog((DEB_WARN,"Failed to decode data: %d\n", Asn1Err ));
|
|
Result = 1;
|
|
}
|
|
*DecodedData = NULL;
|
|
}
|
|
|
|
SpnegoTermAsn(NULL, pDec);
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
int NTAPI
|
|
SpnegoPackData(
|
|
IN PVOID Data,
|
|
IN ULONG PduValue,
|
|
OUT PULONG DataSize,
|
|
OUT PUCHAR * MarshalledData
|
|
)
|
|
{
|
|
int Result = 0;
|
|
PUCHAR Buffer = NULL;
|
|
ASN1encoding_t pEnc = NULL;
|
|
ASN1error_e Asn1Err;
|
|
|
|
Result = SpnegoInitAsn(
|
|
&pEnc, // we are encoding
|
|
NULL
|
|
);
|
|
if (Result != 0)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Encode the data type.
|
|
//
|
|
Asn1Err = ASN1_Encode(
|
|
pEnc,
|
|
Data,
|
|
PduValue,
|
|
ASN1ENCODE_ALLOCATEBUFFER,
|
|
NULL, // pbBuf
|
|
0 // cbBufSize
|
|
);
|
|
|
|
if (!ASN1_SUCCEEDED(Asn1Err))
|
|
{
|
|
DebugLog((DEB_ERROR,"Failed to encode data: %d\n",Asn1Err));
|
|
Result = 1;
|
|
goto Cleanup;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// when the oss compiler was used the allocation routines were configurable.
|
|
// therefore, the encoded data could just be free'd using our
|
|
// deallocator. in the new model we cannot configure the allocation routines
|
|
// for encoding.
|
|
|
|
// so we do not have to go and change every place where a free
|
|
// of an encoded buffer is done, use our allocator to allocate a new buffer,
|
|
// then copy the encoded data to it, and free the buffer that was allocated by
|
|
// the encoding engine.
|
|
//
|
|
|
|
*MarshalledData = (PUCHAR)LsapAllocateLsaHeap(pEnc->len);
|
|
if (*MarshalledData == NULL)
|
|
{
|
|
Result = 1;
|
|
*DataSize = 0;
|
|
}
|
|
else
|
|
{
|
|
RtlCopyMemory(*MarshalledData, pEnc->buf, pEnc->len);
|
|
*DataSize = pEnc->len;
|
|
|
|
//DebugLog((DEB_ERROR,"encoded pdu size: %d\n",pEnc->len));
|
|
//PrintBytes(pEnc->buf, pEnc->len);
|
|
}
|
|
|
|
ASN1_FreeEncoded(pEnc, pEnc->buf);
|
|
}
|
|
|
|
Cleanup:
|
|
SpnegoTermAsn(pEnc, NULL);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
VOID
|
|
SpnegoFreeData(
|
|
IN ULONG PduValue,
|
|
IN PVOID Data
|
|
)
|
|
{
|
|
ASN1decoding_t pDec = NULL;
|
|
|
|
if (ARGUMENT_PRESENT(Data))
|
|
{
|
|
int Result;
|
|
Result = SpnegoInitAsn(
|
|
NULL,
|
|
&pDec // this is a decoded structure
|
|
);
|
|
|
|
if (Result == 0)
|
|
{
|
|
ASN1_FreeDecoded(pDec, Data, PduValue);
|
|
|
|
SpnegoTermAsn(NULL, pDec);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpFreeObjectId
|
|
//
|
|
// Synopsis: Frees an object ID structure created by us
|
|
//
|
|
// Arguments: [Id] -- Id to free
|
|
//
|
|
// History: 8-09-96 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
NegpFreeObjectId(
|
|
ObjectID Id)
|
|
{
|
|
ObjectID Next;
|
|
|
|
while (Id) {
|
|
|
|
Next = Id->next;
|
|
|
|
LsapFreeLsaHeap( Id );
|
|
|
|
Id = Next ;
|
|
|
|
} ;
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpFreeMechList
|
|
//
|
|
// Synopsis: Frees a Mechlist created by NecpCopyMechList
|
|
//
|
|
// Arguments: [Id] -- Id to free
|
|
//
|
|
// History: 8-09-96 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
NegpFreeMechList(
|
|
struct MechTypeList *MechList)
|
|
{
|
|
struct MechTypeList *Next;
|
|
|
|
Next = MechList;
|
|
while (Next != NULL)
|
|
{
|
|
|
|
NegpFreeObjectId(Next->value);
|
|
|
|
Next = Next->next ;
|
|
|
|
} while ( Next );
|
|
|
|
LsapFreeLsaHeap(MechList);
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpDecodeObjectId
|
|
//
|
|
// Synopsis: Create an Object ID struct from a BER encoded Object ID
|
|
//
|
|
// Arguments: [Id] --
|
|
// [Len] --
|
|
//
|
|
// History: 8-09-96 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ObjectID
|
|
NegpDecodeObjectId(
|
|
PUCHAR Id,
|
|
DWORD Len)
|
|
{
|
|
ObjectID Root;
|
|
ObjectID Tail;
|
|
ObjectID Current;
|
|
DWORD i, j;
|
|
DWORD value;
|
|
|
|
if ( Len < 3 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
//
|
|
// Check for BER type OBJECT_ID
|
|
//
|
|
|
|
if ( Id[ 0 ] != 0x06 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
if ( Id[ 1 ] > 127 )
|
|
{
|
|
return( NULL );
|
|
}
|
|
|
|
Root = (struct ASN1objectidentifier_s *) LsapAllocateLsaHeap( sizeof( struct ASN1objectidentifier_s ) );
|
|
|
|
Tail = (struct ASN1objectidentifier_s *) LsapAllocateLsaHeap( sizeof( struct ASN1objectidentifier_s ) );
|
|
|
|
if ( !Root || !Tail )
|
|
{
|
|
if ( Root )
|
|
{
|
|
LsapFreeLsaHeap( Root );
|
|
}
|
|
|
|
if ( Tail )
|
|
{
|
|
LsapFreeLsaHeap( Tail );
|
|
}
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
Root->value = (WORD) Id[2] / 40 ;
|
|
|
|
Tail->value = (WORD) Id[2] % 40 ;
|
|
|
|
Root->next = Tail ;
|
|
|
|
i = 3 ;
|
|
|
|
while ( i < Len )
|
|
{
|
|
j = 0;
|
|
|
|
value = Id[ i ] & 0x7F ;
|
|
|
|
while ( Id[i] & 0x80 )
|
|
{
|
|
value <<= 7;
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
if ( (i >= Len) || ( j > sizeof( ULONG ) ) )
|
|
{
|
|
NegpFreeObjectId( Root );
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
value |= Id[ i ] & 0x7F ;
|
|
}
|
|
|
|
i++;
|
|
|
|
Current = (struct ASN1objectidentifier_s *) LsapAllocateLsaHeap( sizeof( struct ASN1objectidentifier_s ) );
|
|
|
|
if ( Current )
|
|
{
|
|
Current->value = value ;
|
|
Current->next = NULL ;
|
|
|
|
Tail->next = Current ;
|
|
|
|
Tail = Current ;
|
|
|
|
}
|
|
else
|
|
{
|
|
NegpFreeObjectId( Root );
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
}
|
|
|
|
return( Root );
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpCompareOid
|
|
//
|
|
// Synopsis: Standard compare function for OIDs:
|
|
//
|
|
// Arguments: [A] --
|
|
// [B] --
|
|
//
|
|
// Returns: < 0 if A is "less than" B
|
|
// > 0 if A is "greater than" B
|
|
// 0 if A equals B
|
|
//
|
|
// History: 8-22-96 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
NegpCompareOid(
|
|
ObjectID A,
|
|
ObjectID B)
|
|
{
|
|
while ( A )
|
|
{
|
|
if ( A->value < B->value )
|
|
{
|
|
return( -1 );
|
|
}
|
|
if ( A->value > B->value )
|
|
{
|
|
return( 1 );
|
|
}
|
|
|
|
A = A->next ;
|
|
|
|
B = B->next ;
|
|
|
|
if ( ( A == NULL ) && ( B == NULL ) )
|
|
{
|
|
return( 0 );
|
|
}
|
|
|
|
if ( !B )
|
|
{
|
|
return( 1 );
|
|
}
|
|
|
|
if ( !A )
|
|
{
|
|
return( -1 );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Never reached
|
|
//
|
|
return( 0 );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpDumpOid
|
|
//
|
|
// Synopsis: Debug-only dumper
|
|
//
|
|
// Arguments: [Banner] --
|
|
// [Id] --
|
|
//
|
|
// History: 9-17-96 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
VOID
|
|
NegpDumpOid(
|
|
PSTR Banner,
|
|
ObjectID Id
|
|
)
|
|
{
|
|
CHAR Oid[128];
|
|
PSTR Next;
|
|
int Count;
|
|
|
|
Next = Oid;
|
|
|
|
while ( Id )
|
|
{
|
|
Count = sprintf(Next, "%d.", Id->value );
|
|
|
|
Next += Count;
|
|
|
|
Id = Id->next;
|
|
}
|
|
|
|
DebugLog(( DEB_TRACE_NEG, "%s: %s\n", Banner, Oid ));
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpBuildMechListFromCreds
|
|
//
|
|
// Synopsis: Builds a MechList from a credential struct
|
|
//
|
|
// Arguments: [Creds] -- Creds
|
|
// [fPackageReq]
|
|
// [MechList] -- Constructed mechlist
|
|
//
|
|
// History: 9-27-96 RichardW Created
|
|
//
|
|
// Notes: Returned MechList should be freed in a single call to LsapFreeHeap
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
SECURITY_STATUS
|
|
NegpBuildMechListFromCreds(
|
|
PNEG_CREDS Creds,
|
|
ULONG fPackageReq,
|
|
ULONG MechAttributes,
|
|
struct MechTypeList ** MechList)
|
|
{
|
|
struct MechTypeList *pMechs = NULL;
|
|
ULONG iCred, iMech = 0 ;
|
|
SECURITY_STATUS Status = STATUS_SUCCESS;
|
|
PNEG_PACKAGE Package ;
|
|
|
|
NegReadLockCreds( Creds );
|
|
|
|
if ( Creds->Count != 0 )
|
|
{
|
|
|
|
pMechs = (struct MechTypeList *) LsapAllocateLsaHeap(
|
|
sizeof( struct MechTypeList ) * ( Creds->Count) );
|
|
|
|
if ( pMechs )
|
|
{
|
|
for ( iCred = 0 ; iCred < Creds->Count ; iCred++ )
|
|
{
|
|
Package = Creds->Creds[ iCred ].Package ;
|
|
|
|
if ( (Package->PackageFlags & fPackageReq) != fPackageReq)
|
|
{
|
|
continue;
|
|
}
|
|
pMechs[ iMech ].next = &pMechs[ iMech + 1 ];
|
|
|
|
pMechs[ iMech ].value = Package->ObjectId ;
|
|
|
|
iMech++ ;
|
|
|
|
}
|
|
|
|
if ( iMech != 0 )
|
|
{
|
|
pMechs[ iMech - 1 ].next = NULL ;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
Status = SEC_E_INSUFFICIENT_MEMORY;
|
|
}
|
|
}
|
|
|
|
NegUnlockCreds( Creds );
|
|
|
|
*MechList = pMechs;
|
|
return( Status );
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpCopyObjectId
|
|
//
|
|
// Synopsis: Duplicates an ObjectId
|
|
//
|
|
// Arguments: [ObjectId] = Object Id to copy
|
|
//
|
|
// History: 9-27-96 RichardW Created
|
|
//
|
|
// Notes: Returned ObjectId should be freed with NegpFreeObjectId
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
ObjectID
|
|
NegpCopyObjectId(
|
|
IN ObjectID Id
|
|
)
|
|
{
|
|
ObjectID RootId = NULL;
|
|
ObjectID NewId = NULL;
|
|
ObjectID LastId = NULL;
|
|
ObjectID NextId = NULL;
|
|
|
|
NextId = Id;
|
|
while (NextId != NULL)
|
|
{
|
|
NewId = (struct ASN1objectidentifier_s *) LsapAllocateLsaHeap(sizeof(struct ASN1objectidentifier_s));
|
|
if (NewId == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
NewId->next = NULL;
|
|
NewId->value = NextId->value;
|
|
|
|
if (RootId == NULL)
|
|
{
|
|
RootId = NewId;
|
|
}
|
|
|
|
if (LastId != NULL)
|
|
{
|
|
LastId->next = NewId;
|
|
}
|
|
LastId = NewId;
|
|
NextId= NextId->next;
|
|
}
|
|
return(RootId);
|
|
|
|
Cleanup:
|
|
if (RootId != NULL)
|
|
{
|
|
NegpFreeObjectId(RootId);
|
|
}
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpCopyMechList
|
|
//
|
|
// Synopsis: Duplicates a MechList
|
|
//
|
|
// Arguments: [Creds] -- Creds
|
|
//
|
|
// History: 9-27-96 RichardW Created
|
|
//
|
|
// Notes: Returned MechList should be freed with NegpFreeMechList
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
struct MechTypeList *
|
|
NegpCopyMechList(
|
|
struct MechTypeList *MechList)
|
|
{
|
|
struct MechTypeList *pMechs;
|
|
struct MechTypeList *NextMech;
|
|
ULONG i, Count;
|
|
|
|
Count = 0;
|
|
NextMech = MechList;
|
|
while (NextMech != NULL)
|
|
{
|
|
Count++;
|
|
NextMech = NextMech->next;
|
|
}
|
|
|
|
if (Count == 0)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
pMechs = (struct MechTypeList *) LsapAllocateLsaHeap(
|
|
sizeof( struct MechTypeList ) * Count );
|
|
|
|
if ( pMechs == NULL )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
pMechs,
|
|
sizeof(struct MechTypeList) * Count
|
|
);
|
|
|
|
i = 0;
|
|
|
|
NextMech = MechList;
|
|
while (NextMech != NULL)
|
|
{
|
|
pMechs[i].value = NegpCopyObjectId(NextMech->value);
|
|
if (pMechs[i].value == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
pMechs[i].next = NULL;
|
|
if (i != 0)
|
|
{
|
|
pMechs[i-1].next = &pMechs[i];
|
|
}
|
|
NextMech = NextMech->next;
|
|
i++;
|
|
}
|
|
|
|
return( pMechs );
|
|
Cleanup:
|
|
if (pMechs != NULL)
|
|
{
|
|
NegpFreeMechList (pMechs);
|
|
}
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpMapNegFlagsToContextFlags
|
|
//
|
|
// Synopsis: maps negotatie context flags to ASC_REQ_xxx flags
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
ULONG
|
|
NegoMapNegFlagsToPackageFlags(
|
|
IN int NegFlags
|
|
)
|
|
{
|
|
ULONG ContextFlags = 0;
|
|
if ((NegFlags & delegFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_DELEGATE;
|
|
}
|
|
if ((NegFlags & mutualFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_MUTUAL_AUTH;
|
|
}
|
|
if ((NegFlags & replayFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_REPLAY_DETECT;
|
|
}
|
|
if ((NegFlags & sequenceFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_SEQUENCE_DETECT;
|
|
}
|
|
if ((NegFlags & confFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_CONFIDENTIALITY;
|
|
}
|
|
if ((NegFlags & integFlag) != 0)
|
|
{
|
|
ContextFlags |= ASC_REQ_INTEGRITY;
|
|
}
|
|
return(ContextFlags);
|
|
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: NegpMapContextFlagsToNegFlags
|
|
//
|
|
// Synopsis: maps ISC_REQ_xxx flags to negotiate flags
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
int
|
|
NegoMapNegFlasgToContextFlags(
|
|
IN ULONG ContextFlags
|
|
)
|
|
{
|
|
int NegFlags = 0;
|
|
|
|
if ((ContextFlags & ISC_REQ_DELEGATE) != 0)
|
|
{
|
|
NegFlags |= delegFlag;
|
|
}
|
|
if ((ContextFlags & ISC_REQ_MUTUAL_AUTH) != 0)
|
|
{
|
|
NegFlags |= mutualFlag;
|
|
}
|
|
if ((ContextFlags & ISC_REQ_REPLAY_DETECT) != 0)
|
|
{
|
|
NegFlags |= replayFlag;
|
|
}
|
|
if ((ContextFlags & ISC_REQ_SEQUENCE_DETECT) != 0)
|
|
{
|
|
NegFlags |= sequenceFlag;
|
|
}
|
|
if ((ContextFlags & ISC_REQ_CONFIDENTIALITY) != 0)
|
|
{
|
|
NegFlags |= confFlag;
|
|
}
|
|
if ((ContextFlags & ISC_REQ_INTEGRITY) != 0)
|
|
{
|
|
NegFlags |= integFlag;
|
|
}
|
|
return(NegFlags);
|
|
|
|
}
|
|
|
|
|
|
int
|
|
Neg_der_read_length(
|
|
unsigned char **buf,
|
|
LONG *bufsize,
|
|
LONG * headersize
|
|
)
|
|
{
|
|
unsigned char sf;
|
|
LONG ret;
|
|
|
|
if (*bufsize < 1)
|
|
return(-1);
|
|
*headersize = 0;
|
|
sf = *(*buf)++;
|
|
(*bufsize)--;
|
|
(*headersize)++;
|
|
if (sf & 0x80) {
|
|
if ((sf &= 0x7f) > ((*bufsize)-1))
|
|
return(-1);
|
|
if (sf > sizeof(LONG))
|
|
return (-1);
|
|
ret = 0;
|
|
for (; sf; sf--) {
|
|
ret = (ret<<8) + (*(*buf)++);
|
|
(*bufsize)--;
|
|
(*headersize)++;
|
|
}
|
|
} else {
|
|
ret = sf;
|
|
}
|
|
|
|
return(ret);
|
|
}
|