summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs/smb/spnegoparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs/smb/spnegoparse.c')
-rw-r--r--usr/src/lib/libsmbfs/smb/spnegoparse.c94
1 files changed, 53 insertions, 41 deletions
diff --git a/usr/src/lib/libsmbfs/smb/spnegoparse.c b/usr/src/lib/libsmbfs/smb/spnegoparse.c
index e9f1e2781b..ea5fb03a70 100644
--- a/usr/src/lib/libsmbfs/smb/spnegoparse.c
+++ b/usr/src/lib/libsmbfs/smb/spnegoparse.c
@@ -1,3 +1,4 @@
+// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
// Copyright (C) 2002 Microsoft Corporation
// All rights reserved.
//
@@ -54,6 +55,7 @@ extern MECH_OID g_stcMechOIDList [];
// Parameters:
// [in] nMechTokenLength - Length of the MechToken Element
// [in] nMechListMICLength - Length of the MechListMIC Element
+// (or negHints, if no MechToken)
// [in] mechOID - OID for MechList
// [in] nReqFlagsAvailable - Is ContextFlags element available
// [out] pnTokenSize - Filled out with total size of token
@@ -75,7 +77,7 @@ extern MECH_OID g_stcMechOIDList [];
////////////////////////////////////////////////////////////////////////////
int CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
+ long nMechListMICLength, SPNEGO_MECH_OID *mechOidLst, int mechOidCnt,
int nReqFlagsAvailable, long* pnTokenSize,
long* pnInternalTokenLength )
{
@@ -87,7 +89,7 @@ int CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
// We will calculate this by walking the token backwards
- // Start with MIC Element
+ // Start with MIC Element (or negHints)
if ( nMechListMICLength > 0L )
{
nTempLength = ASNDerCalcElementLength( nMechListMICLength, NULL );
@@ -130,7 +132,7 @@ int CalculateMinSpnegoInitTokenSize( long nMechTokenLength,
}
// Next is the MechList - This is REQUIRED
- nTempLength += ASNDerCalcMechListLength( mechOid, NULL );
+ nTempLength += ASNDerCalcMechListLength( mechOidLst, mechOidCnt, NULL );
// Check for rollover error
if ( nTempLength < nTotalLength )
@@ -205,11 +207,12 @@ xEndTokenInitLength:
// CreateSpnegoInitToken
//
// Parameters:
-// [in] MechType - OID in MechList
+// [in] pMechTypeList - OID array
+// [in] MechTypeCnt - OID array length
// [in] ucContextFlags - ContextFlags value
// [in] pbMechToken - Mech Token Binary Data
// [in] ulMechTokenLen - Length of Mech Token
-// [in] pbMechListMIC - MechListMIC Binary Data
+// [in] pbMechListMIC - MechListMIC Binary Data (or negHints)
// [in] ulMechListMICn - Length of MechListMIC
// [out] pbTokenData - Buffer to write token into.
// [in] nTokenLength - Length of pbTokenData buffer
@@ -227,9 +230,18 @@ xEndTokenInitLength:
// backwards, so we always know how many bytes we will potentially be
// writing out.
//
+// This function is also used to create an SPNEGO "hint", as described in
+// [MS-SPNG] sec. 2.2.1 negTokenInit2. The "hint" looks almost identical
+// to a NegTokenInit, but has a "negHints" field inserted before the MIC.
+// A normal SPNEGO negTokenInit2 contains only the mech list and the
+// negHints. To avoid a giant copy/paste of this function, we pass the
+// negHints as the MIC arg, and pass NULL as the MechToken to indicate
+// that we're creating a Hint rather than an Init, and use the correct
+// type when writing out the MIC (or negHints) element.
+//
////////////////////////////////////////////////////////////////////////////
-int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
+int CreateSpnegoInitToken( SPNEGO_MECH_OID *pMechTypeList, long MechTypeCnt,
unsigned char ucContextFlags, unsigned char* pbMechToken,
unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
unsigned long ulMechListMICLen, unsigned char* pbTokenData,
@@ -251,17 +263,22 @@ int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
// We will write the token out backwards to properly handle the cases
// where the length bytes become adjustable
- // Start with MIC Element
+ // Start with MIC Element (or negHints)
if ( ulMechListMICLen > 0L )
{
+ unsigned char ucType;
nTempLength = ASNDerCalcElementLength( ulMechListMICLen, &nInternalLength );
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
+ // Decrease the pbWriteTokenData, now we know the length and write it out.
+ // Note: When MechTokenLen == 0, we're writing a negTokenInit2 and the
+ // MIC arg is really negHints, written as a constructed sequence.
+ // Otherwise we're writing a negTokenInit, and the MIC is an OCTETSTRING.
+ ucType = (ulMechTokenLen == 0) ?
+ SPNEGO_CONSTRUCTED_SEQUENCE : OCTETSTRING;
pbWriteTokenData -= nTempLength;
nTempLength = ASNDerWriteElement( pbWriteTokenData, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC,
- OCTETSTRING, pbMechListMIC, ulMechListMICLen );
+ ucType, pbMechListMIC, ulMechListMICLen );
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
@@ -325,12 +342,12 @@ int CreateSpnegoInitToken( SPNEGO_MECH_OID MechType,
} // IF ContextFlags
// Next is the MechList - This is REQUIRED
- nTempLength = ASNDerCalcMechListLength( MechType, &nInternalLength );
+ nTempLength = ASNDerCalcMechListLength( pMechTypeList, MechTypeCnt, &nInternalLength );
// Decrease the pbWriteTokenData, now we know the length and
// write it out.
pbWriteTokenData -= nTempLength;
- nTempLength = ASNDerWriteMechList( pbWriteTokenData, MechType );
+ nTempLength = ASNDerWriteMechList( pbWriteTokenData, pMechTypeList, MechTypeCnt );
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
@@ -1281,8 +1298,6 @@ int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD
long nElementLength = 0L;
long nActualTokenLength = 0L;
unsigned char* pbElements = NULL;
- unsigned char * ptok;
- long tlen, elen, len;
// Point to the correct array
switch( pSpnegoToken->ucTokenType )
@@ -1370,37 +1385,32 @@ int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD
nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
OCTETSTRING, spnego_init_mechToken,
&pSpnegoToken->aElementArray[nCtr] );
- }
+ }
break;
- case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC:
+ case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC: // xA3
{
//
- // This is an OCTETSTRING which contains a message integrity BLOB.
+ // Don't yet know if this is a negTokenInit, or negTokenInit2.
+ // Unfortunately, both have the same type: SPNEGO_TOKEN_INIT
+ // If it's negTokenInit, this element should be an OCTETSTRING
+ // containing the MIC. If it's a negTokenInit2, this element
+ // should be an SPNEGO_CONSTRUCTED_SEQUENCE containing the
+ // negHints (GENERALSTR, ignored)
//
nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_init_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
- /*
- * don't believe everything you read in RFCs (and MS
- * sample code)... win2k is sending not an octet string,
- * but a "general string", wrapped in a sequence.
- */
- if (nReturn != SPNEGO_E_UNEXPECTED_TYPE)
- break;
- ptok = pbTokenData;
- elen = nElementLength;
- if ((nReturn = ASNDerCheckToken(ptok, SPNEGO_CONSTRUCTED_SEQUENCE, elen, elen, &len, &tlen)) != SPNEGO_E_SUCCESS)
- break;
- elen -= tlen;
- ptok += tlen;
-
- if ((nReturn = ASNDerCheckToken(ptok, SEQ_ELM(0), elen, elen, &len, &tlen)) != SPNEGO_E_SUCCESS)
- break;
- elen -= tlen;
- ptok += tlen;
- nReturn = InitSpnegoTokenElementFromBasicType(ptok, elen, GENERALSTR, spnego_init_mechListMIC, &pSpnegoToken->aElementArray[nCtr]);
+ OCTETSTRING, spnego_init_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr] );
+
+ if (nReturn == SPNEGO_E_UNEXPECTED_TYPE) {
+ // This is really a negHints element. Check the type and length,
+ // but otherwise just ignore it.
+ long elen, tlen;
+ nReturn = ASNDerCheckToken( pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ nElementLength, nElementLength,
+ &elen, &tlen );
+ }
}
break;
@@ -1408,6 +1418,7 @@ int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD
}
else
{
+ /* pSpnegoToken->ucTokenType == SPNEGO_TOKEN_TARG */
switch( pbElements[nCtr] )
{
@@ -1453,12 +1464,13 @@ int InitSpnegoTokenElements( SPNEGO_TOKEN* pSpnegoToken, unsigned char* pbTokenD
case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC:
{
//
- // This is an OCTETSTRING which specifies a message integrity BLOB.
+ // This is an OCTETSTRING, typically 16 bytes,
+ // which contains a message integrity BLOB.
//
nReturn = InitSpnegoTokenElementFromBasicType( pbTokenData, nElementLength,
- OCTETSTRING, spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr] );
+ OCTETSTRING, spnego_targ_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr] );
}
break;