summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs/smb/spnego.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs/smb/spnego.c')
-rw-r--r--usr/src/lib/libsmbfs/smb/spnego.c119
1 files changed, 110 insertions, 9 deletions
diff --git a/usr/src/lib/libsmbfs/smb/spnego.c b/usr/src/lib/libsmbfs/smb/spnego.c
index 3e300cd606..a15303da30 100644
--- a/usr/src/lib/libsmbfs/smb/spnego.c
+++ b/usr/src/lib/libsmbfs/smb/spnego.c
@@ -1,3 +1,4 @@
+// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
// Copyright (C) 2002 Microsoft Corporation
// All rights reserved.
//
@@ -21,10 +22,9 @@
//
/////////////////////////////////////////////////////////////
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <memory.h>
#include "spnego.h"
#include "derparse.h"
@@ -89,6 +89,111 @@ int spnegoInitFromBinary( unsigned char* pbTokenData, unsigned long ulLength, SP
/////////////////////////////////////////////////////////////////////////////
//
// Function:
+// spnegoCreateNegTokenHint
+//
+// Parameters:
+// [in] pMechTypeList - List of MechTypes (OIDs) to include
+// [in] MechTypeCnt - Length of MechTypes array
+// [in] pbPrincipal - Principal name for MechListMIC
+// [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 token
+// from the supplied parameters. The token created is the "hint"
+// used (for example) in the response to an SMB negotiate protocol.
+// Returned data structure must be freed by calling spnegoFreeData().
+//
+// The "hint" tells the client what authentication methods this
+// server supports (the ones in the MechTypeList). The Principal
+// name historically was the server's own SPN, but recent versions
+// of windows only supply: "not_defined_in_RFC4178@please_ignore"
+// So if you want to be nice to your clients, provide the host SPN,
+// otherwise provide the bogus SPN string like recent windows.
+//
+////////////////////////////////////////////////////////////////////////////
+
+int spnegoCreateNegTokenHint( SPNEGO_MECH_OID *pMechTypeList, int MechTypeCnt,
+ unsigned char *pbPrincipal, SPNEGO_TOKEN_HANDLE* phSpnegoToken )
+{
+ int nReturn;
+ long nTokenLength = 0L;
+ long nInternalTokenLength = 0L;
+ unsigned long ulPrincipalLen;
+ unsigned char* pbMechListMIC;
+ unsigned long ulMechListMICLen;
+ unsigned char* pbTokenData = NULL;
+ SPNEGO_TOKEN** ppSpnegoToken = (SPNEGO_TOKEN**) phSpnegoToken;
+
+ if ( NULL == ppSpnegoToken || NULL == pbPrincipal )
+ return (SPNEGO_E_INVALID_PARAMETER);
+
+ /*
+ * Get the actual token size
+ */
+ ulPrincipalLen = strlen((char *)pbPrincipal);
+ ulMechListMICLen = ASNDerCalcElementLength( ulPrincipalLen, NULL );
+ nReturn = CalculateMinSpnegoInitTokenSize(
+ 0, /* ulMechTokenLen */
+ ulMechListMICLen,
+ pMechTypeList,
+ MechTypeCnt,
+ 0, /* nReqFlagsAvailable */
+ &nTokenLength,
+ &nInternalTokenLength );
+ if ( nReturn != SPNEGO_E_SUCCESS )
+ return (nReturn);
+
+ // Allocate a buffer to hold the data.
+ pbTokenData = calloc( 1, nTokenLength );
+
+ if ( NULL == pbTokenData )
+ return ( SPNEGO_E_OUT_OF_MEMORY );
+
+ /*
+ * Construct the MechListMIC
+ */
+ pbMechListMIC = pbTokenData + (nTokenLength - ulMechListMICLen);
+ (void) ASNDerWriteElement( pbMechListMIC, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
+ GENERALSTR, pbPrincipal, ulPrincipalLen );
+
+ // Now write the token
+ nReturn = CreateSpnegoInitToken(
+ pMechTypeList,
+ MechTypeCnt,
+ 0, /* ContextFlags */
+ NULL, 0, /* MechToken, len */
+ pbMechListMIC,
+ ulMechListMICLen,
+ pbTokenData,
+ nTokenLength,
+ nInternalTokenLength );
+ if ( nReturn != SPNEGO_E_SUCCESS ) {
+ free( pbTokenData );
+ return (nReturn);
+ }
+
+ // 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 ( nReturn != SPNEGO_E_SUCCESS ) {
+ free( pbTokenData );
+ return (nReturn);
+ }
+
+ return (SPNEGO_E_SUCCESS);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Function:
// spnegoCreateNegTokenInit
//
// Parameters:
@@ -131,7 +236,7 @@ int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
// Get the actual token size
if ( ( nReturn = CalculateMinSpnegoInitTokenSize( ulMechTokenLen, ulMechListMICLen,
- MechType, ( ucContextFlags != 0L ),
+ &MechType, 1, ( ucContextFlags != 0L ),
&nTokenLength, &nInternalTokenLength ) )
== SPNEGO_E_SUCCESS )
{
@@ -142,7 +247,7 @@ int spnegoCreateNegTokenInit( SPNEGO_MECH_OID MechType,
{
// Now write the token
- if ( ( nReturn = CreateSpnegoInitToken( MechType,
+ if ( ( nReturn = CreateSpnegoInitToken( &MechType, 1,
ucContextFlags, pbMechToken,
ulMechTokenLen, pbMechListMIC,
ulMechListMICLen, pbTokenData,
@@ -227,11 +332,7 @@ int spnegoCreateNegTokenTarg( SPNEGO_MECH_OID MechType,
spnego_mech_oid_NotUsed == MechType ) &&
( IsValidNegResult( spnegoNegResult ) ||
- spnego_negresult_NotUsed == spnegoNegResult ) &&
-
- !( !IsValidMechOid( MechType ) &&
- ( spnego_negresult_success == spnegoNegResult ||
- spnego_negresult_incomplete == spnegoNegResult ) ) )
+ spnego_negresult_NotUsed == spnegoNegResult ) )
{
// Get the actual token size