2008-06-30 22:41:06 +02:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
|
|
* of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, Novell, Inc.
|
|
|
|
*
|
|
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
|
|
* you may find current contact information at www.novell.com.
|
|
|
|
*
|
|
|
|
* Authors: Juan Carlos Luciani <jluciani@novell.com>
|
|
|
|
* Todd Throne <tthrone@novell.com>
|
|
|
|
*
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Include files ]=====================================================
|
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include <micasa.h>
|
|
|
|
|
|
|
|
//===[ Type definitions ]==================================================
|
|
|
|
|
|
|
|
//
|
|
|
|
// Auth Cache Entry Wrapper definition
|
|
|
|
//
|
|
|
|
typedef struct _WrapperAuthCacheEntry
|
|
|
|
{
|
|
|
|
int size;
|
|
|
|
AuthCacheEntry entry;
|
|
|
|
|
|
|
|
} WrapperAuthCacheEntry, *PWrapperAuthCacheEntry;
|
|
|
|
|
|
|
|
// Undocumented CASA Flags
|
|
|
|
#define CASA_SECRET_PERSIST_FLAG 0x10000000
|
|
|
|
#define CASA_SECRET_DO_NOT_PERSIST_FLAG 0x20000000
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
|
|
|
|
static
|
|
|
|
bool g_authCacheInitialized = false;
|
|
|
|
HANDLE g_hCASAContext;
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
AuthCacheEntry*
|
|
|
|
CreateAuthTokenCacheEntry(
|
|
|
|
IN const char *pCacheKey,
|
|
|
|
IN const char *pGroupOrHostName,
|
|
|
|
IN const ATSHostEntry *pATSHost,
|
|
|
|
IN CasaStatus status,
|
|
|
|
IN char *pToken,
|
|
|
|
IN int entryLifetime, // seconds (0 == Lives forever)
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
|
|
|
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
|
|
|
uint32_t entrySize, keySize;
|
|
|
|
size_t tokenSize, wrapperEntrySize, cacheKeyStrLen, groupOrHostNameStrLen, hostAndPortStrLen;
|
|
|
|
WrapperAuthCacheEntry *pWrapperEntry = NULL;
|
|
|
|
AuthCacheEntry *pEntry = NULL;
|
|
|
|
char *pKey;
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateAuthTokenCacheEntry- Start\n", 0);
|
|
|
|
|
|
|
|
if (status == CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
tokenSize = (uint32_t) strlen(pToken);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tokenSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapperEntrySize = tokenSize + sizeof(WrapperAuthCacheEntry);
|
|
|
|
|
|
|
|
// Verify that entrySize will not overflow
|
|
|
|
if ((tokenSize + sizeof(AuthCacheEntry)) <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
|
|
|
|
|
|
|
// Allocate space for the entry wrapper
|
|
|
|
//
|
|
|
|
// The WrapperAuthCacheEntry structure contains room for the tokens NULL terminator
|
|
|
|
pWrapperEntry = (WrapperAuthCacheEntry*) malloc(wrapperEntrySize);
|
|
|
|
if (pWrapperEntry)
|
|
|
|
{
|
|
|
|
// Save the entry size
|
|
|
|
pWrapperEntry->size = wrapperEntrySize;
|
|
|
|
|
|
|
|
// Set the AuthCacheEntry pointer
|
|
|
|
pEntry = &pWrapperEntry->entry;
|
|
|
|
|
|
|
|
// Set the status
|
|
|
|
pEntry->status = status;
|
|
|
|
|
|
|
|
if (pEntry->status == CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
memcpy(&pEntry->token[0], pToken, tokenSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
pEntry->token[tokenSize] = '\0';
|
|
|
|
|
|
|
|
// Set the time when the entry was added to the cache
|
|
|
|
pEntry->creationTime = GetTickCount();
|
|
|
|
|
|
|
|
// First determine the time when the entry is due to expire
|
|
|
|
if (entryLifetime != 0)
|
|
|
|
{
|
|
|
|
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
|
|
|
pEntry->doesNotExpire = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The entry does not expire
|
|
|
|
pEntry->expirationTime = 0;
|
|
|
|
pEntry->doesNotExpire = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cacheKeyStrLen = strlen(pCacheKey);
|
|
|
|
groupOrHostNameStrLen = strlen(pGroupOrHostName);
|
|
|
|
|
|
|
|
// Build the cache entry key based on the status
|
|
|
|
if (status == CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
// Successful cache entries have a key of the form
|
|
|
|
// cachekey@group_or_host_name.
|
|
|
|
//
|
|
|
|
// Verify that keySize will not overflow
|
|
|
|
if ((cacheKeyStrLen + groupOrHostNameStrLen + 2) <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + 2);
|
|
|
|
|
|
|
|
pKey = malloc(keySize);
|
|
|
|
if (pKey)
|
|
|
|
{
|
|
|
|
strncpy(pKey, pCacheKey, keySize);
|
|
|
|
strncat(pKey, "@", keySize);
|
|
|
|
strncat(pKey, pGroupOrHostName, keySize);
|
|
|
|
|
|
|
|
DbgTrace(3, "-CreateAuthTokenCacheEntry- Key = %s\n", pKey);
|
|
|
|
DbgTrace(3, "-CreateAuthTokenCacheEntry- Keysize = %d\n", keySize);
|
|
|
|
DbgTrace(3, "-CreateAuthTokenCacheEntry- CredStoreScope = %X\n", pCredStoreScope);
|
|
|
|
|
|
|
|
miCasaStatus = miCASAWriteBinaryKey(g_hCASAContext,
|
|
|
|
CASA_SECRET_DO_NOT_PERSIST_FLAG,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&entrySize,
|
|
|
|
NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- miCASAWriteBinaryKey failure, status = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pKey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- Memory allocation failure\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- keySize overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Unsuccessful cache entries have a key of the form
|
|
|
|
// cachekey@group_or_host_name@ATSHostAddress.
|
|
|
|
//
|
|
|
|
// Verify that keySize will not overflow
|
|
|
|
hostAndPortStrLen = strlen(pATSHost->pNameAndPort);
|
|
|
|
if ((cacheKeyStrLen + groupOrHostNameStrLen + hostAndPortStrLen + 3) <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + hostAndPortStrLen + 3);
|
|
|
|
|
|
|
|
pKey = malloc(keySize);
|
|
|
|
if (pKey)
|
|
|
|
{
|
|
|
|
strncpy(pKey, pCacheKey, keySize);
|
|
|
|
strncat(pKey, "@", keySize);
|
|
|
|
strncat(pKey, pGroupOrHostName, keySize);
|
|
|
|
strncat(pKey, "@", keySize);
|
|
|
|
strncat(pKey, pATSHost->pNameAndPort, keySize);
|
|
|
|
|
|
|
|
miCasaStatus = miCASAWriteBinaryKey(g_hCASAContext,
|
|
|
|
CASA_SECRET_DO_NOT_PERSIST_FLAG,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&entrySize,
|
|
|
|
NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- miCASAWriteBinaryKey failure, status = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pKey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- Memory allocation failure\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- keySize overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- Memory allocation failure\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateAuthTokenCacheEntry- entrySize overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateAuthTokenCacheEntry- End, pEntry = 0x%X\n", pEntry);
|
|
|
|
|
|
|
|
return pEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
AuthCacheEntry*
|
|
|
|
CreateSessionTokenCacheEntry(
|
|
|
|
IN const char *pCacheKey,
|
|
|
|
IN CasaStatus status,
|
|
|
|
IN char *pToken,
|
|
|
|
IN int entryLifetime, // seconds (0 == Lives forever)
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
|
|
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
|
|
|
uint32_t entrySize;
|
|
|
|
size_t tokenSize, wrapperEntrySize, cacheKeyStrLen;
|
|
|
|
WrapperAuthCacheEntry *pWrapperEntry = NULL;
|
|
|
|
AuthCacheEntry *pEntry = NULL;
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateSessionTokenCacheEntry- Start\n", 0);
|
|
|
|
|
|
|
|
if (status == CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
tokenSize = (uint32_t)strlen(pToken);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tokenSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
wrapperEntrySize = tokenSize + sizeof(WrapperAuthCacheEntry);
|
|
|
|
|
|
|
|
// Verify that entrySize will not overflow
|
|
|
|
if ((tokenSize + sizeof(AuthCacheEntry)) <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
entrySize = tokenSize + sizeof(AuthCacheEntry);
|
|
|
|
|
|
|
|
// Allocate space for the entry wrapper
|
|
|
|
//
|
|
|
|
// The WrapperAuthCacheEntry structure contains room for the tokens NULL terminator
|
|
|
|
pWrapperEntry = (WrapperAuthCacheEntry*) malloc(wrapperEntrySize);
|
|
|
|
if (pWrapperEntry)
|
|
|
|
{
|
|
|
|
// Save the entry size
|
|
|
|
pWrapperEntry->size = wrapperEntrySize;
|
|
|
|
|
|
|
|
// Set the AuthCacheEntry pointer
|
|
|
|
pEntry = &pWrapperEntry->entry;
|
|
|
|
|
|
|
|
// Set the status
|
|
|
|
pEntry->status = status;
|
|
|
|
|
|
|
|
if (pEntry->status == CASA_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
memcpy(&pEntry->token[0], pToken, tokenSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
pEntry->token[tokenSize] = '\0';
|
|
|
|
|
|
|
|
// Set the time when the entry was added to the cache
|
|
|
|
pEntry->creationTime = GetTickCount();
|
|
|
|
|
|
|
|
// First determine the time when the entry is due to expire
|
|
|
|
if (entryLifetime != 0)
|
|
|
|
{
|
|
|
|
pEntry->expirationTime = pEntry->creationTime + (entryLifetime * 1000);
|
|
|
|
pEntry->doesNotExpire = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The entry does not expire
|
|
|
|
pEntry->expirationTime = 0;
|
|
|
|
pEntry->doesNotExpire = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cacheKeyStrLen = strlen(pCacheKey) + 1;
|
|
|
|
|
|
|
|
// Verify that the cacheKeyStrLen can be casted to a uint32_t
|
|
|
|
if (cacheKeyStrLen <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
DbgTrace(3, "-CreateSessionTokenCacheEntry- Key = %s\n", pCacheKey);
|
|
|
|
DbgTrace(3, "-CreateSessionTokenCacheEntry- Keysize = %d\n", cacheKeyStrLen);
|
|
|
|
DbgTrace(3, "-CreateSessionTokenCacheEntry- CredStoreScope = %X\n", pCredStoreScope);
|
|
|
|
|
|
|
|
miCasaStatus = miCASAWriteBinaryKey(g_hCASAContext,
|
|
|
|
CASA_SECRET_DO_NOT_PERSIST_FLAG,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pCacheKey,
|
|
|
|
(uint32_t) cacheKeyStrLen,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&entrySize,
|
|
|
|
NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateSessionTokenCacheEntry- miCASAWriteBinaryKey failure, status = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateSessionTokenCacheEntry- cacheKeyStrLen overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateSessionTokenCacheEntry- Memory allocation failure\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-CreateSessionTokenCacheEntry- entrySize overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-CreateSessionTokenCacheEntry- End, pEntry = 0x%X\n", pEntry);
|
|
|
|
|
|
|
|
return pEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
FreeAuthCacheEntry(
|
|
|
|
IN AuthCacheEntry *pEntry
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
WrapperAuthCacheEntry *pWrapperEntry = CONTAINING_RECORD(pEntry, WrapperAuthCacheEntry, entry);
|
|
|
|
|
|
|
|
DbgTrace(1, "-FreeAuthCacheEntry- Start, pEntry = 0x%X\n", pEntry);
|
|
|
|
|
|
|
|
// Free the entry after clearing the memory holding it since it
|
|
|
|
// may contain security sensitive data.
|
|
|
|
memset(pWrapperEntry, 0, pWrapperEntry->size);
|
|
|
|
free(pWrapperEntry);
|
|
|
|
|
|
|
|
DbgTrace(1, "-FreeAuthCacheEntry- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
CacheEntryLifetimeExpired(
|
|
|
|
IN DWORD creationTime,
|
|
|
|
IN DWORD expirationTime
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DWORD currentTime = GetTickCount();
|
|
|
|
bool expired = false;
|
|
|
|
|
|
|
|
DbgTrace(2, "-CacheEntryLifetimeExpired- Start\n", 0);
|
|
|
|
|
|
|
|
// Check if the clock has wrapped
|
|
|
|
if (currentTime >= creationTime)
|
|
|
|
{
|
|
|
|
// The clock has not wrapped, check if the
|
|
|
|
// expiration time has wrapped.
|
|
|
|
if (expirationTime > creationTime)
|
|
|
|
{
|
|
|
|
// The expiration time also has not wrapped,
|
|
|
|
// do a straight compare against the current
|
|
|
|
// time.
|
|
|
|
if (currentTime >= expirationTime)
|
|
|
|
{
|
|
|
|
// It has expired
|
|
|
|
expired = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The clock has wrapped, check if the expiration
|
|
|
|
// time also wrapped.
|
|
|
|
if (expirationTime > creationTime)
|
|
|
|
{
|
|
|
|
// The expiration time did not wrap, therefore
|
|
|
|
// it has been exceeded since the clock wrapped.
|
|
|
|
expired = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The expiration time also wrapped, do a straight
|
|
|
|
// compare against the current time.
|
|
|
|
if (currentTime >= expirationTime)
|
|
|
|
{
|
|
|
|
// It has expired
|
|
|
|
expired = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(2, "-CacheEntryLifetimeExpired- End, result = %08X\n", expired);
|
|
|
|
|
|
|
|
return expired;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
AuthCacheEntry*
|
|
|
|
FindSessionTokenEntryInCache(
|
|
|
|
IN const char *pCacheKey,
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
|
|
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
|
|
|
uint32_t valueLength, bytesRequired;
|
|
|
|
size_t wrapperEntrySize, cacheKeyStrLen;
|
|
|
|
WrapperAuthCacheEntry *pWrapperEntry = NULL;
|
|
|
|
AuthCacheEntry *pEntry = NULL;
|
|
|
|
|
|
|
|
DbgTrace(1, "-FindSessionTokenEntryInCache- Start\n", 0);
|
|
|
|
|
|
|
|
valueLength = 0;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
cacheKeyStrLen = strlen(pCacheKey) + 1;
|
|
|
|
|
|
|
|
// Verify that the cacheKeyStrLen can be casted to a uint32_t
|
|
|
|
if (cacheKeyStrLen <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
DbgTrace(3, "-FindSessionTokenCacheEntry- Key = %s\n", pCacheKey);
|
|
|
|
DbgTrace(3, "-FindSessionTokenCacheEntry- Keysize = %d\n", cacheKeyStrLen);
|
|
|
|
DbgTrace(3, "-FindSessionTokenCacheEntry- CredStoreScope = %X\n", pCredStoreScope);
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pCacheKey,
|
|
|
|
cacheKeyStrLen,
|
|
|
|
NULL,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
|
|
|
|
if (miCasaStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
|
|
|
&& bytesRequired != 0)
|
|
|
|
{
|
|
|
|
wrapperEntrySize = bytesRequired + sizeof(WrapperAuthCacheEntry) - sizeof(AuthCacheEntry);
|
|
|
|
pWrapperEntry = (WrapperAuthCacheEntry*) malloc(wrapperEntrySize);
|
|
|
|
if (pWrapperEntry)
|
|
|
|
{
|
|
|
|
pWrapperEntry->size = wrapperEntrySize;
|
|
|
|
pEntry = &pWrapperEntry->entry;
|
|
|
|
valueLength = bytesRequired;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pCacheKey,
|
|
|
|
cacheKeyStrLen,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus == NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
if (pEntry->doesNotExpire == false
|
|
|
|
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
|
|
|
{
|
|
|
|
// Remove the entry from the cache
|
|
|
|
miCasaStatus = miCASARemoveKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pCacheKey,
|
|
|
|
cacheKeyStrLen,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindSessionTokenEntryInCache- miCASARemoveKey error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindSessionTokenEntryInCache- miCASAReadBinaryKey error = %0X\n", miCasaStatus);
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindSessionTokenEntryInCache- cacheKeyStrLen overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-FindSessionTokenEntryInCache- End, pEntry = 0x%X\n", pEntry);
|
|
|
|
|
|
|
|
return pEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
AuthCacheEntry*
|
|
|
|
FindAuthTokenEntryInCache(
|
|
|
|
IN const char *pCacheKey,
|
|
|
|
IN const char *pGroupOrHostName,
|
|
|
|
IN const ATSHostEntry *pATSHost,
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
|
|
|
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
|
|
|
uint32_t valueLength, bytesRequired, keySize;
|
|
|
|
size_t wrapperEntrySize, cacheKeyStrLen, groupOrHostNameStrLen, hostAndPortStrLen;
|
|
|
|
WrapperAuthCacheEntry *pWrapperEntry = NULL;
|
|
|
|
AuthCacheEntry *pEntry = NULL;
|
|
|
|
char *pKey;
|
|
|
|
|
|
|
|
|
|
|
|
DbgTrace(1, "-FindAuthTokenEntryInCache- Start\n", 0);
|
|
|
|
|
|
|
|
cacheKeyStrLen = strlen(pCacheKey);
|
|
|
|
groupOrHostNameStrLen = strlen(pGroupOrHostName);
|
|
|
|
hostAndPortStrLen = strlen(pATSHost->pNameAndPort);
|
|
|
|
|
|
|
|
// Verify that the worst case keySize will not overflow
|
|
|
|
if ((cacheKeyStrLen + groupOrHostNameStrLen + hostAndPortStrLen + 3) <= UINT32_MAX)
|
|
|
|
{
|
|
|
|
// Allocate space for the worst case key
|
|
|
|
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + hostAndPortStrLen + 3);
|
|
|
|
|
|
|
|
pKey = malloc(keySize);
|
|
|
|
if (pKey)
|
|
|
|
{
|
|
|
|
// First try to read entry using key for successful cache entries
|
|
|
|
strncpy(pKey, pCacheKey, keySize);
|
|
|
|
strncat(pKey, "@", keySize);
|
|
|
|
strncat(pKey, pGroupOrHostName, keySize);
|
|
|
|
|
|
|
|
valueLength = 0;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
DbgTrace(3, "-FindAuthTokenCacheEntry- Key = %s\n", pKey);
|
|
|
|
DbgTrace(3, "-FindAuthTokenCacheEntry- Keysize = %d\n", strlen(pKey) + 1);
|
|
|
|
DbgTrace(3, "-FindAuthTokenCacheEntry- CredStoreScope = %X\n", pCredStoreScope);
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
strlen(pKey) + 1,
|
|
|
|
NULL,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
|
|
|
&& bytesRequired != 0)
|
|
|
|
{
|
|
|
|
wrapperEntrySize = bytesRequired + sizeof(WrapperAuthCacheEntry) - sizeof(AuthCacheEntry);
|
|
|
|
pWrapperEntry = (WrapperAuthCacheEntry*) malloc(wrapperEntrySize);
|
|
|
|
if (pWrapperEntry)
|
|
|
|
{
|
|
|
|
pWrapperEntry->size = wrapperEntrySize;
|
|
|
|
pEntry = &pWrapperEntry->entry;
|
|
|
|
valueLength = bytesRequired;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
strlen(pKey) + 1,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus == NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
if (pEntry->doesNotExpire == false
|
|
|
|
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
|
|
|
{
|
|
|
|
// Remove the entry from the cache
|
|
|
|
miCasaStatus = miCASARemoveKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindAuthTokenEntryInCache- miCASARemoveKey error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindAuthTokenEntryInCache- miCASAReadBinaryKey error = %0X\n", miCasaStatus);
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// We failed to obtain a cache entry using key for successful cache entry, try for using key for
|
|
|
|
// unsuccessful cache entry.
|
|
|
|
strncat(pKey, "@", keySize);
|
|
|
|
strncat(pKey, pATSHost->pNameAndPort, keySize);
|
|
|
|
|
|
|
|
valueLength = 0;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
NULL,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT
|
|
|
|
&& bytesRequired != 0)
|
|
|
|
{
|
|
|
|
wrapperEntrySize = bytesRequired + sizeof(WrapperAuthCacheEntry) - sizeof(AuthCacheEntry);
|
|
|
|
pWrapperEntry = (WrapperAuthCacheEntry*) malloc(wrapperEntrySize);
|
|
|
|
if (pWrapperEntry)
|
|
|
|
{
|
|
|
|
pWrapperEntry->size = wrapperEntrySize;
|
|
|
|
pEntry = &pWrapperEntry->entry;
|
|
|
|
valueLength = bytesRequired;
|
|
|
|
bytesRequired = 0;
|
|
|
|
|
|
|
|
miCasaStatus = miCASAReadBinaryKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
(uint8_t *) pEntry,
|
|
|
|
&valueLength,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
&bytesRequired,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus == NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
if (pEntry->doesNotExpire == false
|
|
|
|
&& CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime))
|
|
|
|
{
|
|
|
|
// Remove the entry from the cache
|
|
|
|
miCasaStatus = miCASARemoveKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pKey,
|
|
|
|
keySize,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindAuthTokenEntryInCache- miCASARemoveKey error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindAuthTokenEntryInCache- miCASAReadBinaryKey error = %0X\n", miCasaStatus);
|
|
|
|
FreeAuthCacheEntry(pEntry);
|
|
|
|
pEntry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(pKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-FindAuthTokenEntryInCache- keySize overflow prevented\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-FindAuthTokenEntryInCache- End, pEntry = 0x%X\n", pEntry);
|
|
|
|
|
|
|
|
return pEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
RemoveSessionTokenEntryInCache(
|
|
|
|
IN const char *pCacheKey,
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"};
|
|
|
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
|
|
|
|
|
|
|
DbgTrace(1, "-RemoveSessionTokenEntryInCache- Start\n", 0);
|
|
|
|
|
|
|
|
// Remove the entry from the cache
|
|
|
|
miCasaStatus = miCASARemoveKey(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
&sessionKeyChain,
|
|
|
|
&sharedId,
|
|
|
|
(SS_UTF8_T*) pCacheKey,
|
|
|
|
(uint32_t) strlen(pCacheKey) + 1,
|
|
|
|
(SSCS_PASSWORD_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-RemoveSessionTokenEntryInCache- miCASARemoveKey error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-RemoveSessionTokenEntryInCache- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
DeleteAuthTokenEntriesInCache(
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"};
|
|
|
|
|
|
|
|
DbgTrace(1, "-DeleteAuthTokenEntriesInCache- Start\n", 0);
|
|
|
|
|
|
|
|
// Remove all of the auth tokens from the cache
|
|
|
|
miCasaStatus = miCASARemoveCredential(0,
|
|
|
|
&sharedId,
|
|
|
|
(SSCS_SECRET_ID_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-DeleteAuthTokenEntriesInCache- miCASADeleteCredential error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-DeleteAuthTokenEntriesInCache- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
DeleteSessionTokenEntriesInCache(
|
|
|
|
IN void *pCredStoreScope
|
|
|
|
)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t miCasaStatus;
|
|
|
|
SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"};
|
|
|
|
|
|
|
|
DbgTrace(1, "-DeleteSessionTokenEntriesInCache- Start\n", 0);
|
|
|
|
|
|
|
|
// Remove all of the auth tokens from the cache
|
|
|
|
miCasaStatus = miCASARemoveCredential(0,
|
|
|
|
&sharedId,
|
|
|
|
(SSCS_SECRET_ID_T*) NULL,
|
|
|
|
(SSCS_EXT_T*) pCredStoreScope);
|
|
|
|
if (miCasaStatus != NSSCS_SUCCESS)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "-DeleteSessionTokenEntriesInCache- miCASADeleteCredential error = %0X\n", miCasaStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-DeleteSessionTokenEntriesInCache- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
CasaStatus
|
|
|
|
InitializeAuthCache()
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
CasaStatus retStatus;
|
|
|
|
SSCS_SECRETSTORE_T ssId;
|
|
|
|
|
|
|
|
DbgTrace(1, "-InitializeAuthCache- Start\n", 0);
|
|
|
|
|
|
|
|
ssId.version = NSSCS_VERSION_NUMBER;
|
|
|
|
strcpy((char *)ssId.ssName, (char *)SSCS_DEFAULT_SECRETSTORE_ID);
|
|
|
|
|
|
|
|
g_hCASAContext = miCASAOpenSecretStoreCache(&ssId,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
if (!g_hCASAContext)
|
|
|
|
{
|
|
|
|
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
|
|
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
|
|
CASA_STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_authCacheInitialized = true;
|
|
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
UnInitializeAuthCache(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "-UnInitializeAuthCache- Start\n", 0);
|
|
|
|
|
|
|
|
// Proceed if initialized
|
|
|
|
if (g_authCacheInitialized)
|
|
|
|
{
|
|
|
|
// Close the secret store cache
|
|
|
|
miCASACloseSecretStoreCache(g_hCASAContext,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
// Forget about being initialized
|
|
|
|
g_hCASAContext = NULL;
|
|
|
|
g_authCacheInitialized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "-UnInitializeAuthCache- End\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
//++=======================================================================
|
|
|
|
|