|
|
#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
|