You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
609 lines
12 KiB
609 lines
12 KiB
#ifndef _SSPIPROVIDER_HXX_
|
|
#define _SSPIPROVIDER_HXX_
|
|
|
|
#define NTDIGEST_SP_NAME "wdigest"
|
|
|
|
class SSPI_CONTEXT_STATE : public W3_MAIN_CONTEXT_STATE
|
|
{
|
|
public:
|
|
|
|
SSPI_CONTEXT_STATE(
|
|
const CHAR * pszCredentials
|
|
)
|
|
{
|
|
DBG_ASSERT( pszCredentials != NULL );
|
|
_pszCredentials = pszCredentials;
|
|
}
|
|
|
|
HRESULT
|
|
SetPackage(
|
|
const CHAR * pszPackage
|
|
)
|
|
{
|
|
return _strPackage.Copy( pszPackage );
|
|
}
|
|
|
|
const CHAR *
|
|
QueryPackage(
|
|
VOID
|
|
)
|
|
{
|
|
return _strPackage.QueryStr();
|
|
}
|
|
|
|
const CHAR *
|
|
QueryCredentials(
|
|
VOID
|
|
) const
|
|
{
|
|
return _pszCredentials;
|
|
}
|
|
|
|
STRA *
|
|
QueryResponseHeader(
|
|
VOID
|
|
)
|
|
{
|
|
return &_strResponseHeader;
|
|
}
|
|
|
|
BOOL
|
|
Cleanup(
|
|
W3_MAIN_CONTEXT *
|
|
)
|
|
{
|
|
delete this;
|
|
return TRUE;
|
|
}
|
|
|
|
private:
|
|
|
|
STRA _strPackage;
|
|
const CHAR * _pszCredentials;
|
|
STRA _strResponseHeader;
|
|
};
|
|
|
|
class SSPI_AUTH_PROVIDER : public AUTH_PROVIDER
|
|
{
|
|
public:
|
|
|
|
SSPI_AUTH_PROVIDER( DWORD dwAuthType )
|
|
{
|
|
m_dwAuthType = dwAuthType;
|
|
}
|
|
|
|
virtual ~SSPI_AUTH_PROVIDER()
|
|
{
|
|
}
|
|
|
|
virtual
|
|
HRESULT
|
|
Initialize(
|
|
DWORD dwInternalId
|
|
);
|
|
|
|
virtual
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
virtual
|
|
HRESULT
|
|
DoesApply(
|
|
W3_MAIN_CONTEXT * pMainContext,
|
|
BOOL * pfApplies
|
|
);
|
|
|
|
virtual
|
|
HRESULT
|
|
DoAuthenticate(
|
|
W3_MAIN_CONTEXT * pMainContext,
|
|
BOOL * pfFilterFinished
|
|
);
|
|
|
|
virtual
|
|
HRESULT
|
|
OnAccessDenied(
|
|
W3_MAIN_CONTEXT * pMainContext
|
|
);
|
|
|
|
DWORD
|
|
QueryAuthType(
|
|
VOID
|
|
)
|
|
{
|
|
return m_dwAuthType;
|
|
}
|
|
|
|
private:
|
|
|
|
DWORD m_dwAuthType;
|
|
};
|
|
|
|
#define SSPI_CREDENTIAL_SIGNATURE CREATE_SIGNATURE( 'SCCS' )
|
|
#define SSPI_CREDENTIAL_FREE_SIGNATURE CREATE_SIGNATURE( 'fCCS' )
|
|
|
|
class SSPI_CREDENTIAL
|
|
{
|
|
public:
|
|
|
|
SSPI_CREDENTIAL()
|
|
: m_dwSignature ( SSPI_CREDENTIAL_SIGNATURE ),
|
|
m_strPackageName( m_rgPackageName, sizeof( m_rgPackageName ) ),
|
|
m_cbMaxTokenLen ( 0 ),
|
|
m_fSupportsEncoding( FALSE )
|
|
{
|
|
m_ListEntry.Flink = NULL;
|
|
SecInvalidateHandle( &m_hCredHandle );
|
|
}
|
|
|
|
~SSPI_CREDENTIAL()
|
|
{
|
|
DBG_ASSERT( CheckSignature() );
|
|
|
|
m_dwSignature = SSPI_CREDENTIAL_FREE_SIGNATURE;
|
|
|
|
if ( SecIsValidHandle( &m_hCredHandle ) )
|
|
{
|
|
FreeCredentialsHandle( &m_hCredHandle );
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CheckSignature(
|
|
VOID
|
|
) const
|
|
{
|
|
return m_dwSignature == SSPI_CREDENTIAL_SIGNATURE;
|
|
}
|
|
|
|
BOOL
|
|
QuerySupportsEncoding(
|
|
VOID
|
|
) const
|
|
{
|
|
return m_fSupportsEncoding;
|
|
}
|
|
|
|
STRA *
|
|
QueryPackageName(
|
|
VOID
|
|
)
|
|
{
|
|
return &m_strPackageName;
|
|
}
|
|
|
|
DWORD
|
|
QueryMaxTokenSize(
|
|
VOID
|
|
)
|
|
{
|
|
return m_cbMaxTokenLen;
|
|
}
|
|
|
|
CredHandle *
|
|
QueryCredHandle(
|
|
VOID
|
|
)
|
|
{
|
|
return &m_hCredHandle;
|
|
}
|
|
|
|
static
|
|
HRESULT
|
|
Initialize(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
GetCredential(
|
|
CHAR * pszPackage,
|
|
SSPI_CREDENTIAL ** ppCredential
|
|
);
|
|
|
|
static
|
|
VOID
|
|
RemoveCredentialFromCache(
|
|
SSPI_CREDENTIAL * pCredential
|
|
);
|
|
|
|
private:
|
|
|
|
DWORD m_dwSignature;
|
|
CHAR m_rgPackageName[ 64 ];
|
|
STRA m_strPackageName;
|
|
LIST_ENTRY m_ListEntry;
|
|
|
|
//
|
|
// Handle to the server's credentials
|
|
//
|
|
|
|
CredHandle m_hCredHandle;
|
|
|
|
//
|
|
// Used for SSPI, max message token size
|
|
//
|
|
|
|
ULONG m_cbMaxTokenLen;
|
|
|
|
//
|
|
// Do we need to uudecode/encode buffers when dealing with this package
|
|
//
|
|
|
|
BOOL m_fSupportsEncoding;
|
|
|
|
//
|
|
// Global lock
|
|
//
|
|
|
|
static CRITICAL_SECTION sm_csCredentials;
|
|
|
|
//
|
|
// Global credential list
|
|
//
|
|
|
|
static LIST_ENTRY sm_CredentialListHead;
|
|
};
|
|
|
|
#define SSPI_CONTEXT_SIGNATURE CREATE_SIGNATURE( 'SXCS' )
|
|
#define SSPI_CONTEXT_FREE_SIGNATURE CREATE_SIGNATURE( 'fXCS' )
|
|
|
|
class SSPI_SECURITY_CONTEXT : public CONNECTION_AUTH_CONTEXT
|
|
{
|
|
public:
|
|
|
|
SSPI_SECURITY_CONTEXT(
|
|
SSPI_CREDENTIAL * pCredential,
|
|
BOOL fDigestAuth = FALSE
|
|
)
|
|
{
|
|
DBG_ASSERT( pCredential != NULL );
|
|
_pCredential = pCredential;
|
|
SetSignature( SSPI_CONTEXT_SIGNATURE );
|
|
_fIsComplete = FALSE;
|
|
_fHaveAContext = FALSE;
|
|
_fDigestAuth = fDigestAuth;
|
|
SecInvalidateHandle( &_hCtxtHandle );
|
|
}
|
|
|
|
virtual ~SSPI_SECURITY_CONTEXT()
|
|
{
|
|
SetSignature( SSPI_CONTEXT_FREE_SIGNATURE );
|
|
|
|
if ( _fHaveAContext )
|
|
{
|
|
if( _fDigestAuth )
|
|
{
|
|
DBG_ASSERT( g_pW3Server->QueryDigestContextCache() );
|
|
|
|
//
|
|
// On connection close, we are adding this full formed
|
|
// security context handle to our Digest context handle
|
|
// cache, cause the security context can be used to
|
|
// process other requests from different connections
|
|
// (per Digest protocol)
|
|
//
|
|
|
|
if( FAILED( g_pW3Server->QueryDigestContextCache()->
|
|
AddContextCacheEntry( &_hCtxtHandle ) ) )
|
|
{
|
|
if ( SecIsValidHandle( &_hCtxtHandle ) )
|
|
{
|
|
if (g_pW3Server->QueryDigestContextCache()->QueryTraceLog() != NULL)
|
|
{
|
|
WriteRefTraceLogEx(g_pW3Server->QueryDigestContextCache()->QueryTraceLog(),
|
|
0,
|
|
(PVOID)_hCtxtHandle.dwLower,
|
|
(PVOID)_hCtxtHandle.dwUpper,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
DeleteSecurityContext( &_hCtxtHandle );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( SecIsValidHandle( &_hCtxtHandle ) )
|
|
{
|
|
DeleteSecurityContext( &_hCtxtHandle );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SSPI_CREDENTIAL *
|
|
QueryCredentials(
|
|
VOID
|
|
)
|
|
{
|
|
return _pCredential;
|
|
}
|
|
|
|
VOID
|
|
SetCredentials(
|
|
SSPI_CREDENTIAL * pCredential
|
|
)
|
|
{
|
|
_pCredential = pCredential;
|
|
}
|
|
|
|
CtxtHandle *
|
|
QueryContextHandle(
|
|
VOID
|
|
)
|
|
{
|
|
return &_hCtxtHandle;
|
|
}
|
|
|
|
VOID
|
|
SetContextHandle(
|
|
CtxtHandle ctxtHandle
|
|
)
|
|
{
|
|
_fHaveAContext = TRUE;
|
|
_hCtxtHandle = ctxtHandle;
|
|
}
|
|
|
|
BOOL
|
|
CheckSignature(
|
|
VOID
|
|
)
|
|
{
|
|
return QuerySignature() == SSPI_CONTEXT_SIGNATURE;
|
|
}
|
|
|
|
VOID *
|
|
operator new(
|
|
#if DBG
|
|
size_t size
|
|
#else
|
|
size_t
|
|
#endif
|
|
)
|
|
{
|
|
DBG_ASSERT( size == sizeof( SSPI_SECURITY_CONTEXT ) );
|
|
DBG_ASSERT( sm_pachSSPISecContext != NULL );
|
|
return sm_pachSSPISecContext->Alloc();
|
|
}
|
|
|
|
VOID
|
|
operator delete(
|
|
VOID * pSSPISecContext
|
|
)
|
|
{
|
|
DBG_ASSERT( pSSPISecContext != NULL );
|
|
DBG_ASSERT( sm_pachSSPISecContext != NULL );
|
|
|
|
DBG_REQUIRE( sm_pachSSPISecContext->Free( pSSPISecContext ) );
|
|
}
|
|
|
|
virtual
|
|
BOOL
|
|
Cleanup(
|
|
VOID
|
|
)
|
|
{
|
|
delete this;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
QueryIsComplete(
|
|
VOID
|
|
) const
|
|
{
|
|
return _fIsComplete;
|
|
}
|
|
|
|
VOID
|
|
SetIsComplete(
|
|
BOOL fIsComplete
|
|
)
|
|
{
|
|
_fIsComplete = fIsComplete;
|
|
}
|
|
|
|
VOID
|
|
SetContextAttributes(
|
|
ULONG ulContextAttributes
|
|
)
|
|
{
|
|
_ulContextAttributes = ulContextAttributes;
|
|
}
|
|
|
|
ULONG
|
|
QueryContextAttributes(
|
|
VOID
|
|
)
|
|
{
|
|
return _ulContextAttributes;
|
|
}
|
|
|
|
static
|
|
HRESULT
|
|
Initialize(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
private:
|
|
|
|
SSPI_CREDENTIAL * _pCredential;
|
|
|
|
//
|
|
// Do we have a context set? If so we should delete it on cleanup
|
|
//
|
|
|
|
BOOL _fHaveAContext;
|
|
|
|
//
|
|
// Is the handshake complete?
|
|
//
|
|
|
|
BOOL _fIsComplete;
|
|
|
|
//
|
|
// Handle to the partially formed context
|
|
//
|
|
|
|
CtxtHandle _hCtxtHandle;
|
|
|
|
//
|
|
// Attributes of the established context
|
|
//
|
|
|
|
ULONG _ulContextAttributes;
|
|
|
|
//
|
|
// Allocation cache for SSPI_SECURITY_CONTEXT
|
|
//
|
|
|
|
//
|
|
// Is this Digest authentication
|
|
//
|
|
|
|
BOOL _fDigestAuth;
|
|
|
|
static ALLOC_CACHE_HANDLER * sm_pachSSPISecContext;
|
|
};
|
|
|
|
class SSPI_USER_CONTEXT : public W3_USER_CONTEXT
|
|
{
|
|
public:
|
|
|
|
SSPI_USER_CONTEXT( AUTH_PROVIDER * pProvider )
|
|
: W3_USER_CONTEXT( pProvider )
|
|
{
|
|
_hImpersonationToken = NULL;
|
|
_hPrimaryToken = NULL;
|
|
_fSetAccountPwdExpiry = FALSE;
|
|
_pSecurityContext = NULL;
|
|
}
|
|
|
|
virtual ~SSPI_USER_CONTEXT()
|
|
{
|
|
if ( _hImpersonationToken != NULL )
|
|
{
|
|
CloseHandle( _hImpersonationToken );
|
|
_hImpersonationToken = NULL;
|
|
}
|
|
|
|
if ( _hPrimaryToken != NULL )
|
|
{
|
|
CloseHandle( _hPrimaryToken );
|
|
_hPrimaryToken = NULL;
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
Create(
|
|
SSPI_SECURITY_CONTEXT * pSecurityContext,
|
|
W3_MAIN_CONTEXT * pMainContext
|
|
);
|
|
|
|
|
|
WCHAR *
|
|
QueryUserName(
|
|
VOID
|
|
)
|
|
{
|
|
return _strUserName.QueryStr();
|
|
}
|
|
|
|
WCHAR *
|
|
QueryPassword(
|
|
VOID
|
|
)
|
|
{
|
|
return L"";
|
|
}
|
|
|
|
DWORD
|
|
QueryAuthType(
|
|
VOID
|
|
)
|
|
{
|
|
return QueryProvider()->QueryAuthType();
|
|
}
|
|
|
|
virtual
|
|
HRESULT
|
|
GetSspiInfo(
|
|
BYTE * pCredHandle,
|
|
DWORD cbCredHandle,
|
|
BYTE * pCtxtHandle,
|
|
DWORD cbCtxtHandle
|
|
)
|
|
{
|
|
if ( cbCredHandle < sizeof( CredHandle ) ||
|
|
cbCtxtHandle < sizeof( CtxtHandle ) )
|
|
{
|
|
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
|
|
}
|
|
|
|
memcpy( pCredHandle,
|
|
_pSecurityContext->QueryCredentials()->QueryCredHandle(),
|
|
sizeof( CredHandle ) );
|
|
|
|
memcpy( pCtxtHandle,
|
|
_pSecurityContext->QueryContextHandle(),
|
|
sizeof( CtxtHandle ) );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
HANDLE
|
|
QueryImpersonationToken(
|
|
VOID
|
|
)
|
|
{
|
|
DBG_ASSERT( _hImpersonationToken != NULL );
|
|
return _hImpersonationToken;
|
|
}
|
|
|
|
HANDLE
|
|
QueryPrimaryToken(
|
|
VOID
|
|
);
|
|
|
|
STRA *
|
|
QueryAuthToken(
|
|
VOID
|
|
)
|
|
{
|
|
return &_strAuthToken;
|
|
}
|
|
|
|
LARGE_INTEGER *
|
|
QueryExpiry(
|
|
VOID
|
|
) ;
|
|
|
|
private:
|
|
HANDLE _hImpersonationToken;
|
|
HANDLE _hPrimaryToken;
|
|
STRU _strUserName;
|
|
STRU _strPackageName;
|
|
DWORD _dwAuthType;
|
|
LARGE_INTEGER _AccountPwdExpiry;
|
|
BOOL _fSetAccountPwdExpiry;
|
|
SSPI_SECURITY_CONTEXT * _pSecurityContext;
|
|
STRA _strAuthToken;
|
|
};
|
|
|
|
#endif
|