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.
442 lines
9.0 KiB
442 lines
9.0 KiB
#ifndef _TOKENCACHE_HXX_
|
|
#define _TOKENCACHE_HXX_
|
|
|
|
#include <wincrypt.h>
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#include "usercache.hxx"
|
|
#include "stringa.hxx"
|
|
|
|
//
|
|
// Special logon types to indicate local system and passport
|
|
//
|
|
|
|
#define IIS_LOGON_METHOD_LOCAL_SYSTEM (-2)
|
|
#define IIS_LOGON_METHOD_PASSPORT (-3)
|
|
|
|
#define DEFAULT_MD5_HASH_SIZE 16
|
|
|
|
class TOKEN_CACHE_KEY : public CACHE_KEY
|
|
{
|
|
public:
|
|
|
|
TOKEN_CACHE_KEY()
|
|
: m_strHashKey( m_achHashKey, sizeof( m_achHashKey ) )
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
QueryIsEqual(
|
|
const CACHE_KEY * pCompareKey
|
|
) const
|
|
{
|
|
TOKEN_CACHE_KEY * pTokenKey = (TOKEN_CACHE_KEY*) pCompareKey;
|
|
|
|
DBG_ASSERT( pTokenKey != NULL );
|
|
|
|
//
|
|
// If lengths are not equal, this is easy
|
|
//
|
|
|
|
if ( m_strHashKey.QueryCB() != pTokenKey->m_strHashKey.QueryCB() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Do memcmp
|
|
//
|
|
|
|
return memcmp( m_strHashKey.QueryStr(),
|
|
pTokenKey->m_strHashKey.QueryStr(),
|
|
m_strHashKey.QueryCB() ) == 0;
|
|
}
|
|
|
|
DWORD
|
|
QueryKeyHash(
|
|
VOID
|
|
) const
|
|
{
|
|
return HashString( m_strHashKey.QueryStr() );
|
|
}
|
|
|
|
HRESULT
|
|
SetKey(
|
|
TOKEN_CACHE_KEY * pCacheKey
|
|
)
|
|
{
|
|
return m_strHashKey.Copy( pCacheKey->m_strHashKey.QueryStr() );
|
|
}
|
|
|
|
HRESULT
|
|
CreateCacheKey(
|
|
WCHAR * pszUserName,
|
|
WCHAR * pszDomainName,
|
|
DWORD dwLogonMethod
|
|
);
|
|
|
|
private:
|
|
|
|
WCHAR m_achHashKey[ 64 ];
|
|
|
|
STRU m_strHashKey;
|
|
};
|
|
|
|
//
|
|
// The check period for how long a token can be in the cache.
|
|
// Tokens can be in the cache for up to two times this value
|
|
// (in seconds)
|
|
//
|
|
|
|
#define DEFAULT_CACHED_TOKEN_TTL ( 15 * 60 )
|
|
|
|
#define SID_DEFAULT_SIZE 64
|
|
|
|
#define TOKEN_CACHE_ENTRY_SIGNATURE 'TC3W'
|
|
#define TOKEN_CACHE_ENTRY_FREE_SIGNATURE 'fC3W'
|
|
|
|
class TOKEN_CACHE_ENTRY : public CACHE_ENTRY
|
|
{
|
|
public:
|
|
TOKEN_CACHE_ENTRY( OBJECT_CACHE * pObjectCache )
|
|
: CACHE_ENTRY( pObjectCache ),
|
|
m_strMD5Password( m_achMD5Password, sizeof( m_achMD5Password ) ),
|
|
m_lOOPToken( 0 ),
|
|
m_lDisBackupPriToken( 0 ),
|
|
m_hImpersonationToken( NULL ),
|
|
m_hPrimaryToken( NULL ),
|
|
m_pSid( NULL )
|
|
{
|
|
m_liPwdExpiry.HighPart = 0x7fffffff;
|
|
m_liPwdExpiry.LowPart = 0xffffffff;
|
|
|
|
m_dwSignature = TOKEN_CACHE_ENTRY_SIGNATURE;
|
|
}
|
|
|
|
virtual ~TOKEN_CACHE_ENTRY()
|
|
{
|
|
DBG_ASSERT( CheckSignature() );
|
|
m_dwSignature = TOKEN_CACHE_ENTRY_FREE_SIGNATURE;
|
|
|
|
if ( m_hImpersonationToken != NULL )
|
|
{
|
|
CloseHandle( m_hImpersonationToken );
|
|
m_hImpersonationToken = NULL;
|
|
}
|
|
|
|
if ( m_hPrimaryToken != NULL )
|
|
{
|
|
CloseHandle( m_hPrimaryToken );
|
|
m_hPrimaryToken = NULL;
|
|
}
|
|
}
|
|
|
|
CACHE_KEY *
|
|
QueryCacheKey(
|
|
VOID
|
|
) const
|
|
{
|
|
return (CACHE_KEY*) &m_cacheKey;
|
|
}
|
|
|
|
HRESULT
|
|
SetCacheKey(
|
|
TOKEN_CACHE_KEY * pCacheKey
|
|
)
|
|
{
|
|
return m_cacheKey.SetKey( pCacheKey );
|
|
}
|
|
|
|
BOOL
|
|
CheckSignature(
|
|
VOID
|
|
) const
|
|
{
|
|
return m_dwSignature == TOKEN_CACHE_ENTRY_SIGNATURE;
|
|
}
|
|
|
|
VOID *
|
|
operator new(
|
|
#if DBG
|
|
size_t size
|
|
#else
|
|
size_t
|
|
#endif
|
|
)
|
|
{
|
|
DBG_ASSERT( size == sizeof( TOKEN_CACHE_ENTRY ) );
|
|
DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
|
|
return sm_pachTokenCacheEntry->Alloc();
|
|
}
|
|
|
|
VOID
|
|
operator delete(
|
|
VOID * pTokenCacheEntry
|
|
)
|
|
{
|
|
DBG_ASSERT( pTokenCacheEntry != NULL );
|
|
DBG_ASSERT( sm_pachTokenCacheEntry != NULL );
|
|
|
|
DBG_REQUIRE( sm_pachTokenCacheEntry->Free( pTokenCacheEntry ) );
|
|
}
|
|
|
|
HANDLE
|
|
QueryImpersonationToken(
|
|
VOID
|
|
);
|
|
|
|
HANDLE
|
|
QueryPrimaryToken(
|
|
VOID
|
|
);
|
|
|
|
|
|
PSID
|
|
QuerySid(
|
|
VOID
|
|
);
|
|
|
|
LARGE_INTEGER *
|
|
QueryExpiry(
|
|
VOID
|
|
)
|
|
{
|
|
return &m_liPwdExpiry;
|
|
}
|
|
|
|
LONG
|
|
QueryOOPToken(
|
|
VOID
|
|
)
|
|
{
|
|
if( m_lOOPToken )
|
|
{
|
|
return m_lOOPToken;
|
|
}
|
|
|
|
return InterlockedExchange( &m_lOOPToken, 1 );
|
|
}
|
|
|
|
LONG
|
|
QueryDisBackupPriToken(
|
|
VOID
|
|
)
|
|
{
|
|
if( m_lDisBackupPriToken )
|
|
{
|
|
return m_lDisBackupPriToken;
|
|
}
|
|
|
|
return InterlockedExchange( &m_lDisBackupPriToken, 1 );
|
|
}
|
|
|
|
HRESULT
|
|
GenMD5Password(
|
|
IN WCHAR * pszPassword,
|
|
OUT STRA * pstrMD5Password
|
|
);
|
|
|
|
HRESULT
|
|
EqualMD5Password(
|
|
IN WCHAR * pszPassword,
|
|
OUT BOOL * fEqual
|
|
);
|
|
|
|
HRESULT
|
|
Create(
|
|
IN HANDLE hToken,
|
|
IN WCHAR * pszPassword,
|
|
IN LARGE_INTEGER * pliPwdExpiry,
|
|
IN BOOL fImpersonation
|
|
);
|
|
|
|
static
|
|
HRESULT
|
|
Initialize(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
private:
|
|
|
|
TOKEN_CACHE_ENTRY(const TOKEN_CACHE_ENTRY &);
|
|
void operator=(const TOKEN_CACHE_ENTRY &);
|
|
|
|
DWORD m_dwSignature;
|
|
|
|
//
|
|
// Cache key
|
|
//
|
|
|
|
TOKEN_CACHE_KEY m_cacheKey;
|
|
|
|
//
|
|
// Hashed password. The hashed binary data will be converted to
|
|
// ASCII hex representation, so the size would be twice as big
|
|
// as the original one
|
|
//
|
|
|
|
CHAR m_achMD5Password[ 2 * DEFAULT_MD5_HASH_SIZE + 1 ];
|
|
|
|
STRA m_strMD5Password;
|
|
|
|
//
|
|
// The actual tokens
|
|
//
|
|
|
|
HANDLE m_hImpersonationToken;
|
|
HANDLE m_hPrimaryToken;
|
|
|
|
//
|
|
// Have we modified the token for OOP isapi
|
|
//
|
|
|
|
LONG m_lOOPToken;
|
|
|
|
//
|
|
// Have we disabled the backup privilege for the token
|
|
//
|
|
|
|
LONG m_lDisBackupPriToken;
|
|
|
|
//
|
|
// Time to expire for the token
|
|
//
|
|
|
|
LARGE_INTEGER m_liPwdExpiry;
|
|
|
|
//
|
|
// Keep the sid for file cache purposes
|
|
//
|
|
|
|
PSID m_pSid;
|
|
BYTE m_abSid[ SID_DEFAULT_SIZE ];
|
|
|
|
//
|
|
// Allocation cache for TOKEN_CACHE_ENTRY's
|
|
//
|
|
|
|
static ALLOC_CACHE_HANDLER * sm_pachTokenCacheEntry;
|
|
|
|
//
|
|
// Handle of a cryptographic service provider
|
|
//
|
|
|
|
static HCRYPTPROV sm_hCryptProv;
|
|
};
|
|
|
|
class TOKEN_CACHE : public OBJECT_CACHE
|
|
{
|
|
public:
|
|
|
|
TOKEN_CACHE()
|
|
: m_dwLastPriorityUPNLogon ( 0 ),
|
|
m_hKey ( NULL ),
|
|
m_hEvent ( NULL ),
|
|
m_hWaitObject ( NULL ),
|
|
m_fInitializedThreadPool ( FALSE )
|
|
{}
|
|
|
|
~TOKEN_CACHE()
|
|
{}
|
|
|
|
HRESULT
|
|
GetCachedToken(
|
|
IN LPWSTR pszUserName,
|
|
IN LPWSTR pszDomain,
|
|
IN LPWSTR pszPassword,
|
|
IN DWORD dwLogonMethod,
|
|
IN BOOL fUseSubAuth,
|
|
IN BOOL fPossibleUPNLogon,
|
|
IN PSOCKADDR pSockAddr,
|
|
OUT TOKEN_CACHE_ENTRY ** ppCachedToken,
|
|
OUT DWORD * pdwLogonError
|
|
);
|
|
|
|
WCHAR *
|
|
QueryName(
|
|
VOID
|
|
) const
|
|
{
|
|
return L"TOKEN_CACHE";
|
|
}
|
|
|
|
HKEY
|
|
QueryRegKey(
|
|
VOID
|
|
) const
|
|
{
|
|
return m_hKey;
|
|
}
|
|
|
|
HANDLE
|
|
QueryEventHandle(
|
|
VOID
|
|
) const
|
|
{
|
|
return m_hEvent;
|
|
}
|
|
|
|
HRESULT
|
|
Initialize(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
Terminate(
|
|
VOID
|
|
);
|
|
|
|
static
|
|
VOID
|
|
WINAPI
|
|
FlushTokenCacheWaitCallback(
|
|
PVOID pParam,
|
|
BOOL fWaitFired
|
|
);
|
|
|
|
private:
|
|
|
|
TOKEN_CACHE(const TOKEN_CACHE &);
|
|
void operator=(const TOKEN_CACHE &);
|
|
|
|
DWORD m_dwLastPriorityUPNLogon;
|
|
|
|
//
|
|
// Handle to the "UserTokenTTL" registry key
|
|
//
|
|
|
|
HKEY m_hKey;
|
|
|
|
//
|
|
// Handle to the event waiting for the notification
|
|
//
|
|
|
|
HANDLE m_hEvent;
|
|
|
|
//
|
|
// Wait handle
|
|
//
|
|
|
|
HANDLE m_hWaitObject;
|
|
|
|
//
|
|
// Has the threadpool been successfully initialized
|
|
//
|
|
|
|
BOOL m_fInitializedThreadPool;
|
|
|
|
};
|
|
|
|
HRESULT
|
|
ToHex(
|
|
IN BUFFER & buffSrc,
|
|
OUT STRA & strDst
|
|
);
|
|
|
|
#endif
|