summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs')
-rw-r--r--usr/src/lib/libsmbfs/Makefile5
-rw-r--r--usr/src/lib/libsmbfs/Makefile.com4
-rw-r--r--usr/src/lib/libsmbfs/netsmb/ntlmssp.h (renamed from usr/src/lib/libsmbfs/smb/ntlmssp.h)29
-rw-r--r--usr/src/lib/libsmbfs/netsmb/spnego.h260
-rw-r--r--usr/src/lib/libsmbfs/smb/derparse.c92
-rw-r--r--usr/src/lib/libsmbfs/smb/derparse.h8
-rw-r--r--usr/src/lib/libsmbfs/smb/llib-lsmbfs3
-rw-r--r--usr/src/lib/libsmbfs/smb/mapfile-vers16
-rw-r--r--usr/src/lib/libsmbfs/smb/spnego.c119
-rw-r--r--usr/src/lib/libsmbfs/smb/spnego.h244
-rw-r--r--usr/src/lib/libsmbfs/smb/spnegoparse.c94
-rw-r--r--usr/src/lib/libsmbfs/smb/spnegoparse.h7
12 files changed, 539 insertions, 342 deletions
diff --git a/usr/src/lib/libsmbfs/Makefile b/usr/src/lib/libsmbfs/Makefile
index 47c14c6bfa..b708bd0571 100644
--- a/usr/src/lib/libsmbfs/Makefile
+++ b/usr/src/lib/libsmbfs/Makefile
@@ -19,10 +19,11 @@
# CDDL HEADER END
#
#
-# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
#
# lib/libsmbfs/Makefile
@@ -30,7 +31,7 @@
include $(SRC)/lib/Makefile.lib
-HDRS= smbfs_acl.h smbfs_api.h smb_keychain.h
+HDRS= ntlmssp.h smbfs_acl.h smbfs_api.h smb_keychain.h spnego.h
HDRDIR= netsmb
ROOTHDRDIR= $(ROOT)/usr/include/netsmb
diff --git a/usr/src/lib/libsmbfs/Makefile.com b/usr/src/lib/libsmbfs/Makefile.com
index a3ec0fb397..f5801a18db 100644
--- a/usr/src/lib/libsmbfs/Makefile.com
+++ b/usr/src/lib/libsmbfs/Makefile.com
@@ -23,6 +23,8 @@
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
#
# lib/libsmbfs/Makefile.com
@@ -101,7 +103,7 @@ CERRWARN += -_gcc=-Wno-uninitialized
CERRWARN += -_gcc=-Wno-unused-variable
CPPFLAGS += -D__EXTENSIONS__ -D_REENTRANT -DMIA \
- -I$(SRCDIR) -I.. \
+ -I$(SRCDIR) -I.. -I../netsmb \
-I$(SRC)/uts/common \
-I$(SRC)/common/smbclnt
diff --git a/usr/src/lib/libsmbfs/smb/ntlmssp.h b/usr/src/lib/libsmbfs/netsmb/ntlmssp.h
index 5f3e09ac0d..f4cfc34783 100644
--- a/usr/src/lib/libsmbfs/smb/ntlmssp.h
+++ b/usr/src/lib/libsmbfs/netsmb/ntlmssp.h
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
@@ -37,6 +38,10 @@
* http://msdn.microsoft.com/en-us/library/cc236621(PROT.10).aspx
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*
* NTLMSSP Message Types
* [MS-NLMP] sec. 2.2.1
@@ -82,4 +87,28 @@
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
#define NTLMSSP_NEGOTIATE_56 0x80000000
+/*
+ * NTLMSSP AV_PAIR types
+ * [MS-NLMP] sec. 2.2.2.1
+ *
+ * The names are all LE-Unicode.
+ */
+typedef enum ntlmssp_AvId {
+ MsvAvEOL = 0, /* End Of List */
+ MsvAvNbComputerName, /* server's NetBIOS name */
+ MsvAvNbDomainName, /* server's NetBIOS domain */
+ MsvAvDnsComputerName, /* server's DNS name */
+ MsvAvDnsDomainName, /* server's DNS domain */
+ MsvAvDnsTreeName, /* server's Forest name */
+ MsvAvFlags, /* 32-bit (LE) flags */
+ MsvAvTimestamp, /* 64-bit time, [MS-DTYP] sec. 2.3.1 */
+ MsvAvRestrictions, /* struct, [MS-NLMP] sec. 2.2.2.2 */
+ MsvAvTargetName, /* SPN of the server */
+ MsvChannelBindings, /* MD5 hash of GSS challen bindings */
+} ntlmssp_AvId_t;
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _NTLMSSP_H */
diff --git a/usr/src/lib/libsmbfs/netsmb/spnego.h b/usr/src/lib/libsmbfs/netsmb/spnego.h
new file mode 100644
index 0000000000..1a60436740
--- /dev/null
+++ b/usr/src/lib/libsmbfs/netsmb/spnego.h
@@ -0,0 +1,260 @@
+/*
+ * 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
+ */
+
+/*
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * 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
+
+#ifdef __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 */
+ spnego_mech_oid_Kerberos_V5,
+ spnego_mech_oid_Spnego,
+ spnego_mech_oid_NTLMSSP,
+ 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
+
+/*
+ * 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 */
+int spnegoCreateNegTokenHint(SPNEGO_MECH_OID *pMechTypeList, int MechTypeCnt,
+ unsigned char *pbPrincipal, SPNEGO_TOKEN_HANDLE* phSpnegoToken);
+
+/* Initializes SPNEGO_TOKEN structure for a NegTokenInit type */
+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 */
+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 */
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SPNEGO_H */
diff --git a/usr/src/lib/libsmbfs/smb/derparse.c b/usr/src/lib/libsmbfs/smb/derparse.c
index f92da913c2..f21a277d5a 100644
--- a/usr/src/lib/libsmbfs/smb/derparse.c
+++ b/usr/src/lib/libsmbfs/smb/derparse.c
@@ -1,3 +1,4 @@
+// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
// Copyright (C) 2002 Microsoft Corporation
// All rights reserved.
//
@@ -451,29 +452,37 @@ long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength )
// 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.
+// and finally a list of OIDs.
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength )
+long ASNDerCalcMechListLength( SPNEGO_MECH_OID *mechOidLst, int mechOidCnt,
+ 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;
+ // First the OID
+ SPNEGO_MECH_OID oid_idx;
+ long nTotalLength;
+ int i;
+
+ nTotalLength = 0;
+ for (i = 0; i < mechOidCnt; i++) {
+ oid_idx = mechOidLst[i];
+ nTotalLength += g_stcMechOIDList[oid_idx].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;
}
@@ -646,9 +655,12 @@ int ASNDerWriteToken( unsigned char* pbData, unsigned char ucType,
int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID )
{
- memcpy( pbData, g_stcMechOIDList[eMechOID].ucOid, g_stcMechOIDList[eMechOID].iLen );
+ if (pbData != NULL) {
+ memcpy( pbData, g_stcMechOIDList[eMechOID].ucOid,
+ g_stcMechOIDList[eMechOID].iLen );
+ }
- return g_stcMechOIDList[eMechOID].iLen;
+ return g_stcMechOIDList[eMechOID].iLen;
}
@@ -671,27 +683,35 @@ int ASNDerWriteOID( unsigned char* pbData, SPNEGO_MECH_OID eMechOID )
//
////////////////////////////////////////////////////////////////////////////
-long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID mechoid )
+long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID *mechOidLst, int mechOidCnt )
{
- // First get the length
- long nInternalLength = 0L;
- long nMechListLength = ASNDerCalcMechListLength( mechoid, &nInternalLength );
- long nTempLength = 0L;
-
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
+ // First get the length
+ long nInternalLength = 0L;
+ long nMechListLength;
+ long nTempLength = 0L;
+ int i;
+
+ nMechListLength = ASNDerCalcMechListLength(mechOidLst, mechOidCnt, &nInternalLength);
+ nTempLength = ASNDerWriteToken( pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
NULL, nInternalLength );
- // Adjust the data pointer
- pbData += nTempLength;
+ // Adjust the data pointer
+ pbData += nTempLength;
+ nInternalLength -= nTempLength;
+
+ // Now write the Sequence token and the OID (the OID is a BLOB in the global
+ // structure.
- // Now write the Sequence token and the OID (the OID is a BLOB in the global
- // structure.
+ nTempLength = ASNDerWriteToken( pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ NULL, nInternalLength);
+ pbData += nTempLength;
- nTempLength = ASNDerWriteToken( pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
- g_stcMechOIDList[mechoid].ucOid,
- g_stcMechOIDList[mechoid].iLen );
+ for (i = 0; i < mechOidCnt; i++) {
+ nTempLength = ASNDerWriteOID( pbData, mechOidLst[i] );
+ pbData += nTempLength;
+ }
- return nMechListLength;
+ return nMechListLength;
}
diff --git a/usr/src/lib/libsmbfs/smb/derparse.h b/usr/src/lib/libsmbfs/smb/derparse.h
index dcdf5828dc..b1801c8e1c 100644
--- a/usr/src/lib/libsmbfs/smb/derparse.h
+++ b/usr/src/lib/libsmbfs/smb/derparse.h
@@ -1,3 +1,4 @@
+// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
// Copyright (C) 2002 Microsoft Corporation
// All rights reserved.
//
@@ -21,8 +22,6 @@
//
/////////////////////////////////////////////////////////////
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef __DERPARSE_H__
#define __DERPARSE_H__
@@ -178,12 +177,13 @@ int ASNDerCheckOID( unsigned char* pbTokenData, SPNEGO_MECH_OID nMechOID, long n
int ASNDerCalcNumLengthBytes( long nLength );
long ASNDerCalcTokenLength( long nLength, long nDataLength );
long ASNDerCalcElementLength( long nDataLength, long* pnInternalLength );
-long ASNDerCalcMechListLength( SPNEGO_MECH_OID mechoid, long* pnInternalLength );
+long ASNDerCalcMechListLength( SPNEGO_MECH_OID *mechOidLst, int mechOidCnt,
+ 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 );
+long ASNDerWriteMechList( unsigned char* pbData, SPNEGO_MECH_OID *mechOidLst, int mechOidCnt );
int ASNDerWriteElement( unsigned char* pbData, unsigned char ucElementSequence,
unsigned char ucType, unsigned char* pbTokenValue, long nLength );
diff --git a/usr/src/lib/libsmbfs/smb/llib-lsmbfs b/usr/src/lib/libsmbfs/smb/llib-lsmbfs
index e8e05e4272..1096482541 100644
--- a/usr/src/lib/libsmbfs/smb/llib-lsmbfs
+++ b/usr/src/lib/libsmbfs/smb/llib-lsmbfs
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*LINTLIBRARY*/
@@ -34,4 +36,5 @@
#include <netsmb/smb_keychain.h>
#include <netsmb/smb_netshareenum.h>
#include <netsmb/smb_rap.h>
+#include <netsmb/spnego.h>
diff --git a/usr/src/lib/libsmbfs/smb/mapfile-vers b/usr/src/lib/libsmbfs/smb/mapfile-vers
index 1c2a5d6fa9..24bffec63d 100644
--- a/usr/src/lib/libsmbfs/smb/mapfile-vers
+++ b/usr/src/lib/libsmbfs/smb/mapfile-vers
@@ -18,8 +18,8 @@
# CDDL HEADER END
#
#
-# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -151,6 +151,20 @@ SYMBOL_VERSION SUNWprivate {
smbfs_set_default_user;
smbutil_std_opts;
+
+ spnegoCreateNegTokenHint;
+ spnegoCreateNegTokenInit;
+ spnegoCreateNegTokenTarg;
+ spnegoFreeData;
+ spnegoGetContextFlags;
+ spnegoGetMechListMIC;
+ spnegoGetMechToken;
+ spnegoGetNegotiationResult;
+ spnegoGetSupportedMechType;
+ spnegoGetTokenType;
+ spnegoInitFromBinary;
+ spnegoIsMechTypeAvailable;
+ spnegoTokenGetBinary;
local:
*;
};
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
diff --git a/usr/src/lib/libsmbfs/smb/spnego.h b/usr/src/lib/libsmbfs/smb/spnego.h
deleted file mode 100644
index 9865fbd85d..0000000000
--- a/usr/src/lib/libsmbfs/smb/spnego.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// 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.
-//
-/////////////////////////////////////////////////////////////
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#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_NTLMSSP,
- 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
-
-#endif
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;
diff --git a/usr/src/lib/libsmbfs/smb/spnegoparse.h b/usr/src/lib/libsmbfs/smb/spnegoparse.h
index b874dc453d..1f7fde7486 100644
--- a/usr/src/lib/libsmbfs/smb/spnegoparse.h
+++ b/usr/src/lib/libsmbfs/smb/spnegoparse.h
@@ -1,3 +1,4 @@
+// Copyright 2012 Nexenta Systems, Inc. All rights reserved.
// Copyright (C) 2002 Microsoft Corporation
// All rights reserved.
//
@@ -21,8 +22,6 @@
//
/////////////////////////////////////////////////////////////
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef __SPNEGOPARSE_H__
#define __SPNEGOPARSE_H__
@@ -136,13 +135,13 @@ int FindMechOIDInMechList( SPNEGO_ELEMENT* pSpnegoElement, SPNEGO_MECH_OID MechO
int * piMechTypeIndex );
int ValidateMechList( unsigned char* pbMechListData, long nBoundaryLength );
int CalculateMinSpnegoInitTokenSize( long nMechTokenLength, long nMechListMICLength,
- SPNEGO_MECH_OID mechOid, int nReqFlagsAvailable,
+ SPNEGO_MECH_OID *mechOid, int mechOidCnt, 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,
+int CreateSpnegoInitToken( SPNEGO_MECH_OID *MechTypeList, long nMechTypes,
unsigned char ucContextFlags, unsigned char* pbMechToken,
unsigned long ulMechTokenLen, unsigned char* pbMechListMIC,
unsigned long ulMechListMICLen, unsigned char* pbTokenData,