Leaked source code of windows server 2003
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

#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