3cc4067ab1
configured ATSs instead of only utilizing a single configured ATS. The client also tries to contact the ATS using port 443 as well as port 2645 if the port number is not hard configured.
1001 lines
34 KiB
C
1001 lines
34 KiB
C
/***********************************************************************
|
|
*
|
|
* 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);
|
|
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
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;
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|