From fc7f88c01d58397fe16fd423721c6f24136d5eee Mon Sep 17 00:00:00 2001 From: Todd Throne Date: Tue, 20 Jun 2006 20:33:11 +0000 Subject: [PATCH] Changed storage of tokens from registry to CASA wallet. Broke out storage of Session tokens and Authentication tokens. --- CASA-auth-token/client/cache.c | 615 ++++++++++++ CASA-auth-token/client/client.vcproj | 20 +- CASA-auth-token/client/engine.c | 331 ++++--- CASA-auth-token/client/internal.h | 28 +- CASA-auth-token/client/windows/cache.c | 1091 --------------------- CASA-auth-token/client/windows/dllsup.c | 2 +- CASA-auth-token/client/windows/platform.c | 2 +- CASA-auth-token/client/windows/platform.h | 12 +- 8 files changed, 840 insertions(+), 1261 deletions(-) create mode 100644 CASA-auth-token/client/cache.c delete mode 100644 CASA-auth-token/client/windows/cache.c diff --git a/CASA-auth-token/client/cache.c b/CASA-auth-token/client/cache.c new file mode 100644 index 00000000..81e8dab2 --- /dev/null +++ b/CASA-auth-token/client/cache.c @@ -0,0 +1,615 @@ +/*********************************************************************** + * + * 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. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + + +//===[ Include files ]===================================================== + +#include "internal.h" +#include + +//===[ Type definitions ]================================================== + +// +// Registry Key/Value defines used in the AuthCache +// +#define CASA_AUTH_CACHE_REG_KEY "CASA_Auth_Cache" +#define CREATION_TIME_REG_VALUE "CreationTime" +#define EXPIRATION_TIME_REG_VALUE "ExpirationTime" +#define DOES_NOT_EXPIRE_REG_VALUE "DoesNotExpire" +#define STATUS_REG_VALUE "Status" +#define TOKEN_REG_VALUE "Token" + + +//===[ Function prototypes ]=============================================== + +//===[ Global variables ]================================================== + +// Non-host specific key name +static +char g_allHosts[] = "AllHosts"; + +static +int g_cacheEntryCount = 0; + +HANDLE g_hCASAContext; + +//++======================================================================= +AuthCacheEntry* +CreateAuthTokenCacheEntry( + IN const char *pCacheKey, + IN const char *pGroupOrHostName, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime // seconds (0 == Lives forever) + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {27, "CASA_AUTHENTICATION_TOKENS"}; + uint32_t tokenSize, entrySize, keySize; + AuthCacheEntry *pEntry = NULL; + unsigned char *pKey; + + + DbgTrace(1, "-CreateAuthTokenCacheEntry- Start\n", 0); + + if (status == CASA_STATUS_SUCCESS) + { + tokenSize = (uint32_t)strlen(pToken); + } + else + { + tokenSize = 0; + } + + entrySize = tokenSize + sizeof(AuthCacheEntry); + + // Allocate space for the entry + // The AuthCacheEntry structure contains room for the tokens NULL terminator + pEntry = (AuthCacheEntry*) malloc(entrySize); + if (pEntry) + { + // 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; + } + + keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2; + + pKey = malloc(keySize); + + if (pKey) + { + strncpy(pKey, pCacheKey, keySize); + strncat(pKey, "@", keySize); + strncat(pKey, pGroupOrHostName, keySize); + + retStatus = miCASAWriteBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + pKey, + keySize, + (uint8_t *)pEntry, + &entrySize, + NULL, + NULL); + + + free(pKey); + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateAuthTokenCacheEntry- End, pEntry = %08X\n", pEntry); + + return pEntry; +} + + +//++======================================================================= +AuthCacheEntry* +CreateSessionTokenCacheEntry( + IN const char *pCacheKey, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime // seconds (0 == Lives forever) + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"}; + uint32_t tokenSize, entrySize; + AuthCacheEntry *pEntry = NULL; + + + DbgTrace(1, "-CreateSessionTokenCacheEntry- Start\n", 0); + + if (status == CASA_STATUS_SUCCESS) + { + tokenSize = (uint32_t)strlen(pToken); + } + else + { + tokenSize = 0; + } + + entrySize = tokenSize + sizeof(AuthCacheEntry); + + // Allocate space for the entry + // The AuthCacheEntry structure contains room for the tokens NULL terminator + pEntry = (AuthCacheEntry*) malloc(entrySize); + if (pEntry) + { + // 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; + } + + retStatus = miCASAWriteBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (char *)pCacheKey, + (uint32_t)strlen(pCacheKey) + 1, + (uint8_t *)pEntry, + &entrySize, + NULL, + NULL); + } + else + { + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } + + DbgTrace(1, "-CreateSessionTokenCacheEntry- End, pEntry = %08X\n", pEntry); + + return pEntry; +} + + +//++======================================================================= +void +FreeAuthCacheEntry( + IN AuthCacheEntry *pEntry + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + DbgTrace(1, "-FreeAuthCacheEntry- Start, pEntry = %08X\n", pEntry); + + // Free the entry + free(pEntry); + + 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 + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + SSCS_KEYCHAIN_ID_T sessionKeyChain = {26, "SSCS_SESSION_KEY_CHAIN_ID"}; + SSCS_SECRET_ID_T sharedId = {20, "CASA_SESSION_TOKENS"}; + uint32_t valueLength, bytesRequired; + AuthCacheEntry *pEntry = NULL; + + + DbgTrace(1, "-FindSessionTokenEntryInCache- Start\n", 0); + + valueLength = 0; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (char *)pCacheKey, + (uint32_t)strlen(pCacheKey) + 1, + NULL, + &valueLength, + NULL, + &bytesRequired, + NULL); + + if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT + && bytesRequired != 0) + { + pEntry = (AuthCacheEntry*) malloc(bytesRequired); + + if (pEntry) + { + valueLength = bytesRequired; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + (char *)pCacheKey, + (uint32_t)strlen(pCacheKey) + 1, + (uint8_t *)pEntry, + &valueLength, + NULL, + &bytesRequired, + NULL); + + if (CASA_SUCCESS(retStatus)) + { + if (pEntry->doesNotExpire == FALSE + && CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime)) + { + // Remove the entry ??? + //miCASARemoveBinaryKey(); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pEntry); + pEntry = NULL; + } + } + } + + DbgTrace(1, "-FindSessionTokenEntryInCache- End, pEntry = %08X\n", pEntry); + + return pEntry; +} + +//++======================================================================= +AuthCacheEntry* +FindAuthTokenEntryInCache( + IN const char *pCacheKey, + IN const char *pGroupOrHostName + ) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + CasaStatus retStatus; + 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; + AuthCacheEntry *pEntry = NULL; + unsigned char *pKey; + + + DbgTrace(1, "-FindAuthTokenEntryInCache- Start\n", 0); + + keySize = (uint32_t)strlen(pCacheKey) + (uint32_t)strlen(pGroupOrHostName) + 2; + + pKey = malloc(keySize); + + if (pKey) + { + strncpy(pKey, pCacheKey, keySize); + strncat(pKey, "@", keySize); + strncat(pKey, pGroupOrHostName, keySize); + + valueLength = 0; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + pKey, + keySize, + NULL, + &valueLength, + NULL, + &bytesRequired, + NULL); + + if (retStatus == NSSCS_E_ENUM_BUFF_TOO_SHORT + && bytesRequired != 0) + { + pEntry = (AuthCacheEntry*) malloc(bytesRequired); + + if (pEntry) + { + valueLength = bytesRequired; + bytesRequired = 0; + + retStatus = miCASAReadBinaryKey( + g_hCASAContext, + 0, + &sessionKeyChain, + &sharedId, + pKey, + keySize, + (uint8_t *)pEntry, + &valueLength, + NULL, + &bytesRequired, + NULL); + + if (CASA_SUCCESS(retStatus)) + { + if (pEntry->doesNotExpire == FALSE + && CacheEntryLifetimeExpired(pEntry->creationTime, pEntry->expirationTime)) + { + // Remove the entry ??? + //miCASARemoveBinaryKey(); + + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_UNSUCCESSFUL); + } + } + + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pEntry); + pEntry = NULL; + } + } + } + + free(pKey); + } + + DbgTrace(1, "-FindAuthTokenEntryInCache- End, pEntry = %08X\n", pEntry); + + return pEntry; +} + + +//++======================================================================= +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 + { + retStatus = CASA_STATUS_SUCCESS; + } + + DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + +//++======================================================================= +//++======================================================================= +//++======================================================================= + diff --git a/CASA-auth-token/client/client.vcproj b/CASA-auth-token/client/client.vcproj index 842d8e62..99eb9010 100644 --- a/CASA-auth-token/client/client.vcproj +++ b/CASA-auth-token/client/client.vcproj @@ -21,7 +21,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/D "XML_STATIC"" Optimization="0" - AdditionalIncludeDirectories=".;windows;..\include;..\..\include;..\..\..\Expat-2.0.0\source\lib" + AdditionalIncludeDirectories=".;.\windows;..\include;..\..\CASA\include;"..\..\Expat-2.0.0\source\lib"" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" @@ -36,10 +36,10 @@ Name="VCLinkerTool" IgnoreImportLibrary="FALSE" AdditionalOptions="/EXPORT:ObtainAuthToken" - AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib" + AdditionalDependencies="ws2_32.lib winhttp.lib libexpatml.lib micasa.lib" OutputFile="$(OutDir)/authtoken.dll" LinkIncremental="1" - AdditionalLibraryDirectories=""..\..\..\Expat-2.0.0\StaticLibs"" + AdditionalLibraryDirectories=""\Program Files\Novell\CASA\lib";"..\..\Expat-2.0.0\StaticLibs"" GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/client.pdb" SubSystem="0" @@ -151,7 +151,19 @@ copy $(SolutionDir)client\windows\authtoken.lib \"Program Files"\novel RelativePath=".\win32\authtoken.def"> + RelativePath=".\cache.c"> + + + + + + diff --git a/CASA-auth-token/client/engine.c b/CASA-auth-token/client/engine.c index 31c8f5ff..7306ddc7 100644 --- a/CASA-auth-token/client/engine.c +++ b/CASA-auth-token/client/engine.c @@ -38,14 +38,17 @@ // // Debug tracing level // -int DebugLevel = 0; +int DebugLevel = -1; // // Operating parameter // bool secureRpcSetting = false; -int retryLifetime = DEFAULT_RETRY_LIFETIME; +// Synchronization mutex for the dll initialization +static +HANDLE g_hInitializationMutex; +bool g_bInitialized = FALSE; //++======================================================================= static @@ -100,8 +103,8 @@ ObtainSessionToken( } else { - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); + // Free the entry + FreeAuthCacheEntry(pCacheEntry); } } @@ -125,6 +128,10 @@ ObtainSessionToken( pCacheEntry = FindSessionTokenEntryInCache(pAuthContext->pContext); if (pCacheEntry == NULL) { + char *pReqMsg = NULL; + char *pRespMsg = NULL; + int respLen; + // Get authentication mechanism token retStatus = GetAuthMechToken(pAuthContext, &pAuthMechToken); if (!CASA_SUCCESS(retStatus)) @@ -137,93 +144,82 @@ ObtainSessionToken( continue; } - // Create a cache entry for the auth context - pCacheEntry = CreateSessionTokenCacheEntry(pAuthContext->pContext); - if (pCacheEntry) - { - char *pReqMsg = NULL; - char *pRespMsg = NULL; - int respLen; - int cacheEntryLifetime = retryLifetime; // Initialize to retry in case of failure + // Authenticate to the ATS + pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken); + if (pReqMsg) + { + // Issue rpc + retStatus = Rpc(pRpcSession, + "Authenticate", + secureRpcSetting, + pReqMsg, + &pRespMsg, + &respLen); + if (CASA_SUCCESS(retStatus)) + { + AuthenticateResp *pAuthenticateResp; - // Authenticate to the ATS - pReqMsg = BuildAuthenticateMsg(pAuthContext, pAuthMechToken); - if (pReqMsg) - { - // Issue rpc - retStatus = Rpc(pRpcSession, - "Authenticate", - secureRpcSetting, - pReqMsg, - &pRespMsg, - &respLen); - if (CASA_SUCCESS(retStatus)) - { - AuthenticateResp *pAuthenticateResp; + // Create Authenticate response object + retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp); + if (CASA_SUCCESS(retStatus)) + { + // Return the auth token to the caller + pCacheEntry = CreateSessionTokenCacheEntry( + pAuthContext->pContext, + retStatus, + pAuthenticateResp->pToken, + pAuthenticateResp->tokenLifetime); - // Create Authenticate response object - retStatus = CreateAuthenticateResp(pRespMsg, respLen, &pAuthenticateResp); - if (CASA_SUCCESS(retStatus)) - { - // Return the auth token to the caller - pCacheEntry->pToken = pAuthenticateResp->pToken; - pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer - cacheEntryLifetime = pAuthenticateResp->tokenLifetime; + pAuthenticateResp->pToken = NULL; // To keep us from freeing the buffer - // Free the Authenticate response object - RelAuthenticateResp(pAuthenticateResp); - } - } - else - { - DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus); - } + // Free the Authenticate response object + RelAuthenticateResp(pAuthenticateResp); + } + } + else + { + DbgTrace(0, "-ObtainSessionToken- Authenticate Rpc failure, error = %08X\n", retStatus); + } - // Free resources that may be hanging around - if (pRespMsg) - free(pRespMsg); + // Free resources that may be hanging around + if (pRespMsg) + free(pRespMsg); - free(pReqMsg); - } - else - { - DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0); - retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, - CASA_FACILITY_AUTHTOKEN, - CASA_STATUS_INSUFFICIENT_RESOURCES); - } + free(pReqMsg); + } + else + { + DbgTrace(0, "-ObtainSessionToken- Error building Authenticate msg\n", 0); + retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, + CASA_FACILITY_AUTHTOKEN, + CASA_STATUS_INSUFFICIENT_RESOURCES); + } - // Add the entry to the cache if successful or if the reason that we failed - // was because the server was unavailable. - if (CASA_SUCCESS(retStatus) - || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) - { - pCacheEntry->status = retStatus; - AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime); - } + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was unavailable. + if (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateSessionTokenCacheEntry( + pAuthContext->pContext, + retStatus, + NULL, + DEFAULT_RETRY_LIFETIME); - // Release the cache entry if the resulting status is not successful - if (!CASA_SUCCESS(retStatus)) - { - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); - } - } - else - { - DbgTrace(0, "-ObtainSessionToken- Cache entry creation failure\n", 0); - retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, - CASA_FACILITY_AUTHTOKEN, - CASA_STATUS_INSUFFICIENT_RESOURCES); - } + } + + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } // Free up the buffer associated with the authentication mechanism token free(pAuthMechToken); } else { - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); + // Free the entry + FreeAuthCacheEntry(pCacheEntry); } // Advance to the next entry @@ -234,11 +230,11 @@ ObtainSessionToken( if (CASA_SUCCESS(retStatus)) { // Allocate a buffer for the return token - *ppSessionToken = (char*) malloc(strlen(pCacheEntry->pToken) + 1); + *ppSessionToken = (char*) malloc(strlen(pCacheEntry->token) + 1); if (*ppSessionToken) { // Copy the token onto the allocated buffer - strcpy(*ppSessionToken, pCacheEntry->pToken); + strcpy(*ppSessionToken, pCacheEntry->token); } else { @@ -248,8 +244,7 @@ ObtainSessionToken( CASA_STATUS_INSUFFICIENT_RESOURCES); } - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); + FreeAuthCacheEntry(pCacheEntry); } DbgTrace(1, "-ObtainSessionToken- End, retStatus = %08X\n", retStatus); @@ -482,6 +477,7 @@ ObtainAuthToken( CasaStatus retStatus = CASA_STATUS_SUCCESS; AuthCacheEntry *pCacheEntry; char *pNormalizedHostName; + unsigned char *pToken; DbgTrace(1, "-ObtainAuthToken- Start\n", 0); @@ -498,6 +494,39 @@ ObtainAuthToken( goto exit; } + // Make sure we are initialized + // Obtain our synchronization mutex + WaitForSingleObject(g_hInitializationMutex, INFINITE); + + // Create user synchronization mutex + retStatus = CreateUserMutex(); + + if (retStatus != CASA_STATUS_SUCCESS) + { + DbgTrace(0, "-ObtainAuthToken- Error creating mutex for the user\n", 0); + goto exit; + } + + if (g_bInitialized == FALSE) + { + retStatus = InitializeLibrary(); + + if (retStatus == CASA_STATUS_SUCCESS) + { + g_bInitialized = TRUE; + } + else + { + goto exit; + } + } + + // Release our synchronization mutex + if (ReleaseMutex(g_hInitializationMutex) == 0) + { + DbgTrace(0, "-ObtainAuthToken- ReleaseMutex failed, error\n", 0); + } + // Normalize the host name pNormalizedHostName = NormalizeHostName(pHostName); if (pNormalizedHostName) @@ -509,41 +538,37 @@ ObtainAuthToken( pCacheEntry = FindAuthTokenEntryInCache(pServiceName, pNormalizedHostName); if (pCacheEntry == NULL) { - // No entry found in the cache, create one. - pCacheEntry = CreateAuthTokenCacheEntry(pServiceName, pNormalizedHostName); - if (pCacheEntry) - { - int cacheEntryLifetime = retryLifetime; // Initialize to retry in case of failure + // Initialize to retry in case of failure + int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME; - // Cache entry created, now try to obtain auth token from the CASA Server - retStatus = ObtainAuthTokenFromServer(pServiceName, - pNormalizedHostName, - &pCacheEntry->pToken, - &cacheEntryLifetime); + // Cache entry created, now try to obtain auth token from the CASA Server + retStatus = ObtainAuthTokenFromServer(pServiceName, + pNormalizedHostName, + &pToken, + &cacheEntryLifetime); - // Add the entry to the cache if successful or if the reason that we failed - // was because the server was un-available. - if (CASA_SUCCESS(retStatus) - || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) - { - pCacheEntry->status = retStatus; - AddEntryToAuthCache(pCacheEntry, cacheEntryLifetime); - } + // Add the entry to the cache if successful or if the reason that we failed + // was because the server was un-available. + if (CASA_SUCCESS(retStatus) + || CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE) + { + pCacheEntry = CreateAuthTokenCacheEntry( + pServiceName, + pNormalizedHostName, + retStatus, + pToken, + cacheEntryLifetime); + + if (pCacheEntry) + { + // Release the cache entry if the resulting status is not successful + if (!CASA_SUCCESS(retStatus)) + { + FreeAuthCacheEntry(pCacheEntry); + } + } + } - // Release the cache entry if the resulting status is not successful - if (!CASA_SUCCESS(retStatus)) - { - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); - } - } - else - { - DbgTrace(0, "-ObtainAuthToken- Cache entry creation failure\n", 0); - retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, - CASA_FACILITY_AUTHTOKEN, - CASA_STATUS_INSUFFICIENT_RESOURCES); - } } else { @@ -551,22 +576,22 @@ ObtainAuthToken( // and release it if its status is not successful. if (!CASA_SUCCESS(retStatus = pCacheEntry->status)) { - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); + FreeAuthCacheEntry(pCacheEntry); } } + // Try to return auth token if we have one to return if (CASA_SUCCESS(retStatus)) { - int tokenLen = (int) strlen(pCacheEntry->pToken) + 1; + int tokenLen = (int) strlen(pCacheEntry->token) + 1; // We have an authentication token, try to return it to the caller // after verifying that the supplied buffer is big enough. if (*pAuthTokenBufLen >= tokenLen) { // Return the auth token to the caller - strcpy(pAuthTokenBuf, pCacheEntry->pToken); + strcpy(pAuthTokenBuf, pCacheEntry->token); } else { @@ -579,8 +604,7 @@ ObtainAuthToken( // Return the token length to the caller *pAuthTokenBufLen = tokenLen; - // Release auth cache entry reference - ReleaseAuthCacheEntry(pCacheEntry); + FreeAuthCacheEntry(pCacheEntry); } // Stop user process synchronization @@ -605,6 +629,41 @@ exit: } +//++======================================================================= +int +Initialize(void) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + int retStatus = -1; + + DbgTrace(1, "-InitializeLibrary- Start\n", 0); + + // Create a cache mutex only applicable to the current process + g_hInitializationMutex = CreateMutex(NULL, + FALSE, + NULL); + + if (g_hInitializationMutex != NULL) + { + retStatus = CASA_STATUS_SUCCESS; + } + + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); + + return retStatus; +} + + //++======================================================================= int InitializeLibrary(void) @@ -624,39 +683,21 @@ InitializeLibrary(void) DbgTrace(1, "-InitializeLibrary- Start\n", 0); - // Create user synchronization mutex - if (CreateUserMutex() == 0) + // Initialize the host name normalization + retStatus = InitializeHostNameNormalization(); + + + if (CASA_SUCCESS(retStatus)) { - // Initialize the auth cache - if (CASA_SUCCESS(InitializeAuthCache())) - { - // Initialize the host name normalization - if (CASA_SUCCESS(InitializeHostNameNormalization())) - { - // Success - retStatus = 0; - } - else - { - DbgTrace(0, "-InitializeLibrary- Error initializing host name normalization\n", 0); - } - } - else - { - DbgTrace(0, "-InitializeLibrary- Error initializing the auth cache\n", 0); - } - } - else - { - DbgTrace(0, "-InitializeLibrary- Error creating mutex for the user\n", 0); + retStatus = InitializeAuthCache(); } + DbgTrace(1, "-InitializeLibrary- End, retStatus = %08X\n", retStatus); return retStatus; } - //++======================================================================= //++======================================================================= //++======================================================================= diff --git a/CASA-auth-token/client/internal.h b/CASA-auth-token/client/internal.h index bd342a90..769b5a27 100644 --- a/CASA-auth-token/client/internal.h +++ b/CASA-auth-token/client/internal.h @@ -118,6 +118,10 @@ extern char pathCharString[]; // Functions exported by engine.c // +extern +int +Initialize(void); + extern int InitializeLibrary(void); @@ -222,21 +226,25 @@ RelGetAuthTokenResp( extern AuthCacheEntry* CreateSessionTokenCacheEntry( - IN const char *pCacheKey); + IN const char *pCacheKey, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime + ); extern AuthCacheEntry* CreateAuthTokenCacheEntry( IN const char *pCacheKey, - IN const char *pGroupOrHostName); + IN const char *pHostName, + IN CasaStatus status, + IN unsigned char *pToken, + IN int entryLifetime + ); extern void -ReleaseAuthCacheEntry( - IN AuthCacheEntry *pEntry); - -extern void -IncAuthCacheEntryRefCount( +FreeAuthCacheEntry( IN AuthCacheEntry *pEntry); extern @@ -250,12 +258,6 @@ FindAuthTokenEntryInCache( IN const char *pCacheKey, IN const char *pGroupOrHostName); -extern -void -AddEntryToAuthCache( - IN AuthCacheEntry *pEntry, - IN int entryLifetime); - extern CasaStatus InitializeAuthCache(void); diff --git a/CASA-auth-token/client/windows/cache.c b/CASA-auth-token/client/windows/cache.c deleted file mode 100644 index 8405550a..00000000 --- a/CASA-auth-token/client/windows/cache.c +++ /dev/null @@ -1,1091 +0,0 @@ -/*********************************************************************** - * - * 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. - * - * Author: Juan Carlos Luciani - * - ***********************************************************************/ - - -//===[ Include files ]===================================================== - -#include "internal.h" - -//===[ Type definitions ]================================================== - -// -// Registry Key/Value defines used in the AuthCache -// -#define CASA_AUTH_CACHE_REG_KEY "CASA_Auth_Cache" -#define CREATION_TIME_REG_VALUE "CreationTime" -#define EXPIRATION_TIME_REG_VALUE "ExpirationTime" -#define DOES_NOT_EXPIRE_REG_VALUE "DoesNotExpire" -#define STATUS_REG_VALUE "Status" -#define TOKEN_REG_VALUE "Token" - - -//===[ Function prototypes ]=============================================== - -//===[ Global variables ]================================================== - -// In memory auth cache list head -static -LIST_ENTRY g_authCacheListHead; - -// Non-host specific key name -static -char g_allHosts[] = "AllHosts"; - -static -int g_cacheEntryCount = 0; - -//++======================================================================= -static -AuthCacheEntry* -CreateAuthCacheEntry( - IN const char *pCacheKeyName, - IN const char *pHostName) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - AuthCacheEntry *pEntry; - - DbgTrace(1, "-CreateAuthCacheEntry- Start\n", 0); - - // Use allHosts if a host name was not specified - if (pHostName == NULL) - { - pHostName = g_allHosts; - } - - // Allocate space for the entry - pEntry = (AuthCacheEntry*) malloc(sizeof(*pEntry)); - if (pEntry) - { - // Zero the entry - memset(pEntry, 0, sizeof(*pEntry)); - - // Now allocate buffers to maintain copies of the CacheKeyName and host names - pEntry->pCacheKeyName = (char*) malloc(strlen(pCacheKeyName) + 1); - if (pEntry->pCacheKeyName) - { - pEntry->pHostName = (char*) malloc(strlen(pHostName) + 1); - if (pEntry->pHostName) - { - // Save the names within the entry - strcpy(pEntry->pCacheKeyName, pCacheKeyName); - strcpy(pEntry->pHostName, pHostName); - - // Initialize the entries refCount - pEntry->refCount = 1; - - // Increment the cache entry count - g_cacheEntryCount ++; - } - else - { - DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for host name\n", 0); - - // Free allocated resources - free(pEntry->pCacheKeyName); - free(pEntry); - - // Adjust return parameter - pEntry = NULL; - } - } - else - { - DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for the CacheKeyName\n", 0); - - // Free allocated resources - free(pEntry); - - // Adjust return parameter - pEntry = NULL; - } - } - else - { - DbgTrace(0, "-CreateAuthCacheEntry- Unable to allocate buffer for auth cache entry\n", 0); - } - - DbgTrace(1, "-CreateAuthCacheEntry- End, pEntry = %08X\n", pEntry); - - return pEntry; -} - - -//++======================================================================= -AuthCacheEntry* -CreateSessionTokenCacheEntry( - IN const char *pCacheKey) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - return CreateAuthCacheEntry(pCacheKey, NULL); -} - - -//++======================================================================= -AuthCacheEntry* -CreateAuthTokenCacheEntry( - IN const char *pCacheKey, - IN const char *pGroupOrHostName) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - return CreateAuthCacheEntry(pCacheKey, pGroupOrHostName); -} - - -//++======================================================================= -static -void -FreeAuthCacheEntry( - IN AuthCacheEntry *pEntry) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - DbgTrace(1, "-FreeAuthCacheEntry- Start, pEntry = %08X\n", pEntry); - - // Free resources associated with the entry - if (pEntry->pToken) - free(pEntry->pToken); - - if (pEntry->pHostName) - free(pEntry->pHostName); - - if (pEntry->pCacheKeyName) - free(pEntry->pCacheKeyName); - - // Free the entry - free(pEntry); - - // Decrement the cache entry count - g_cacheEntryCount --; - - DbgTrace(1, "-FreeAuthCacheEntry- End\n", 0); -} - - -//++======================================================================= -void -ReleaseAuthCacheEntry( - IN AuthCacheEntry *pEntry) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - DbgTrace(1, "-ReleaseAuthCacheEntry- Start, pEntry = %08X\n", pEntry); - - // Reduce the entries reference count and free it if it goes to zero - pEntry->refCount --; - if (pEntry->refCount == 0) - FreeAuthCacheEntry(pEntry); - - DbgTrace(1, "-ReleaseAuthCacheEntry- End\n", 0); -} - - -//++======================================================================= -void -IncAuthCacheEntryRefCount( - IN AuthCacheEntry *pEntry) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - DbgTrace(1, "-IncAuthCacheEntryRefCount- Start, pEntry = %08X\n", pEntry); - - // Increase the entries reference count - pEntry->refCount ++; - - DbgTrace(1, "-IncAuthCacheEntryRefCount- 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; -} - - -//++======================================================================= -static -AuthCacheEntry* -FindEntryInAuthCache( - IN const char *pCacheKeyName, - IN const char *pHostName) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - AuthCacheEntry *pEntry = NULL; - LIST_ENTRY *pListEntry; - - DbgTrace(1, "-FindEntryInAuthCache- Start\n", 0); - - // Examine the cache, if entry found then check if it has expired - // in which case we would want to remove it from the cache. - - // Use allHosts if a host name was not specified - if (pHostName == NULL) - { - pHostName = g_allHosts; - } - - // First look through the entries in our in-memory cache - pListEntry = g_authCacheListHead.Flink; - while (pListEntry != &g_authCacheListHead) - { - AuthCacheEntry *pWrkEntry; - - // get a pointer to the entry - pWrkEntry = CONTAINING_RECORD(pListEntry, AuthCacheEntry, listEntry); - - // Check if this is an entry for the appropriate host - if (strcmp(pHostName, pWrkEntry->pHostName) == 0) - { - // This is an entry for the appropriate host, now check if it is - // also for the appropriate CacheKeyName - if (strcmp(pCacheKeyName, pWrkEntry->pCacheKeyName) == 0) - { - // This entry is for the appropriate CacheKeyName, check if it - // has not expired. - if (pWrkEntry->doesNotExpire == FALSE - && CacheEntryLifetimeExpired(pWrkEntry->creationTime, pWrkEntry->expirationTime)) - { - // The lifetime of the entry has expired, remove it from the in-memory cache - // and release it. - RemoveEntryList(&pWrkEntry->listEntry); - ReleaseAuthCacheEntry(pWrkEntry); - } - else - { - // This cache entry is still good, use it. - pEntry = pWrkEntry; - } - - // No need to keep looking in the in-memory cache - break; - - } - } - - // Advance to the next entry - pListEntry = pListEntry->Flink; - } - - // Look in the persistent cache if an entry was not found in the in-memory cache - if (pEntry == NULL) - { - LONG status; - HKEY hCASARegKey; - - // Open CASA Auth Cache Key - status = RegOpenKeyExA(HKEY_CURRENT_USER, - CASA_AUTH_CACHE_REG_KEY, - 0, - KEY_ALL_ACCESS, - &hCASARegKey); - if (status == ERROR_SUCCESS) - { - HKEY hHostRegKey; - - // CASA Auth Cache key opened, now try to open - // key for the host. - status = RegOpenKeyExA(hCASARegKey, - pHostName, - 0, - KEY_ALL_ACCESS, - &hHostRegKey); - if (status == ERROR_SUCCESS) - { - HKEY hCacheKeyNameRegKey; - - // Host key opened, now try to open key - // for the CacheKeyName. - status = RegOpenKeyExA(hHostRegKey, - pCacheKeyName, - 0, - KEY_ALL_ACCESS, - &hCacheKeyNameRegKey); - if (status == ERROR_SUCCESS) - { - DWORD creationTime; - DWORD expirationTime; - BOOL doesNotExpire; - BOOL deleteCacheKeyNameKey = TRUE; - DWORD variableSz; - - // Key for the CacheKeyName key opened, now determine whether - // or not its lifetime has expired. - // - // Read the creation time value - variableSz = sizeof(creationTime); - status = RegQueryValueExA(hCacheKeyNameRegKey, - CREATION_TIME_REG_VALUE, - NULL, - NULL, - (LPBYTE) &creationTime, - &variableSz); - if (status == ERROR_SUCCESS) - { - // Read the expiration time - variableSz = sizeof(expirationTime); - status = RegQueryValueExA(hCacheKeyNameRegKey, - EXPIRATION_TIME_REG_VALUE, - NULL, - NULL, - (LPBYTE) &expirationTime, - &variableSz); - if (status == ERROR_SUCCESS) - { - // Read the does not expire - variableSz = sizeof(doesNotExpire); - status = RegQueryValueExA(hCacheKeyNameRegKey, - EXPIRATION_TIME_REG_VALUE, - NULL, - NULL, - (LPBYTE) &doesNotExpire, - &variableSz); - if (status == ERROR_SUCCESS) - { - // Check if the extry lifetime has been exceeded - if (doesNotExpire == TRUE - || CacheEntryLifetimeExpired(creationTime, expirationTime) == FALSE) - { - // Create a AuthCacheEntry - pEntry = CreateAuthCacheEntry(pCacheKeyName, pHostName); - if (pEntry) - { - BOOL entryInitialized = FALSE; - - // Start setting up the AuthCacheEntry - pEntry->creationTime = creationTime; - pEntry->expirationTime = expirationTime; - pEntry->doesNotExpire = doesNotExpire; - - // Read the status - variableSz = sizeof(pEntry->status); - status = RegQueryValueExA(hCacheKeyNameRegKey, - STATUS_REG_VALUE, - NULL, - NULL, - (LPBYTE) &pEntry->status, - &variableSz); - if (status == ERROR_SUCCESS) - { - // Check if there is also an auth token associated with - // this entry. - if (pEntry->status == CASA_STATUS_SUCCESS) - { - DWORD tokenSz = 0; - - // There should be an auth token associated with this CacheKeyName, - // first determine what size buffer to allocate for it. - status = RegQueryValueExA(hCacheKeyNameRegKey, - TOKEN_REG_VALUE, - NULL, - NULL, - (LPBYTE) pEntry->pToken, - &tokenSz); - if (status == ERROR_SUCCESS - || status == ERROR_MORE_DATA) - { - // Allocate buffer to hold the auth token - pEntry->pToken = (char*) malloc(tokenSz); - if (pEntry->pToken) - { - // Now read token into the allocated buffer - status = RegQueryValueExA(hCacheKeyNameRegKey, - TOKEN_REG_VALUE, - NULL, - NULL, - (LPBYTE) pEntry->pToken, - &tokenSz); - if (status == ERROR_SUCCESS) - { - // The cache entry has been properly initialized, - // add it to the in-memory cache. - entryInitialized = TRUE; - deleteCacheKeyNameKey = FALSE; - InsertHeadList(&g_authCacheListHead, &pEntry->listEntry); - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading token, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Unable to allocate buffer for token\n", 0); - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading token2, status = %d\n", status); - } - } - else - { - // There is no auth token associated with this entry - // - // The cache entry has been properly initialized, - // add it to the in-memory cache. - entryInitialized = TRUE; - deleteCacheKeyNameKey = FALSE; - InsertHeadList(&g_authCacheListHead, &pEntry->listEntry); - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading status, status = %d\n", status); - } - - // Free the auth cache entry if it was not successfully initialized - if (entryInitialized == FALSE) - { - FreeAuthCacheEntry(pEntry); - pEntry = NULL; - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error creating auth cache entry\n", 0); - } - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading does not expire, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading expiration time, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error reading creation time, status = %d\n", status); - } - - // Close CacheKeyName key - RegCloseKey(hCacheKeyNameRegKey); - - // Delete the CacheKeyName key if necessary - if (deleteCacheKeyNameKey) - { - RegDeleteKey(hHostRegKey, pCacheKeyName); - } - } - - // Close host key - RegCloseKey(hHostRegKey); - } - - // Close CASA_Auth_Cache key - RegCloseKey(hCASARegKey); - } - else - { - DbgTrace(0, "-FindEntryInAuthCache- Error opening CASA Auth Cache key, status = %d\n", status); - } - } - - // Increment the reference count of entry being returned - if (pEntry) - { - // Increment entries reference count since we are returning it to the caller - IncAuthCacheEntryRefCount(pEntry); - } - - DbgTrace(1, "-FindEntryInAuthCache- End, pEntry = %08X\n", pEntry); - - return pEntry; -} - - -//++======================================================================= -AuthCacheEntry* -FindSessionTokenEntryInCache( - IN const char *pCacheKey) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - return FindEntryInAuthCache(pCacheKey, NULL); -} - -//++======================================================================= -AuthCacheEntry* -FindAuthTokenEntryInCache( - IN const char *pCacheKey, - IN const char *pGroupOrHostName) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - return FindEntryInAuthCache(pCacheKey, pGroupOrHostName); -} - - -//++======================================================================= -void -AddEntryToAuthCache( - IN AuthCacheEntry *pEntry, - IN int entryLifetime) // seconds (0 == Lives forever) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - LONG status; - HKEY hCASARegKey; - - DbgTrace(1, "-AddEntryToAuthCache- Start, pEntry = %08X\n", pEntry); - - // 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; - } - - // Save the entry in our persistent cache (registry) - // - // Open CASA Auth Cache key - status = RegOpenKeyExA(HKEY_CURRENT_USER, - CASA_AUTH_CACHE_REG_KEY, - 0, - KEY_ALL_ACCESS, - &hCASARegKey); - if (status == ERROR_SUCCESS) - { - HKEY hHostRegKey; - - // CASA_Auth_Cache key created or opened, now open or create key for the host. - status = RegCreateKeyExA(hCASARegKey, - pEntry->pHostName, - 0, - NULL, - REG_OPTION_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hHostRegKey, - NULL); - if (status == ERROR_SUCCESS) - { - HKEY hCacheKeyNameRegKey; - - // Host key created or opened, now create key for the CacheKeyName. - status = RegCreateKeyExA(hHostRegKey, - pEntry->pCacheKeyName, - 0, - NULL, - REG_OPTION_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hCacheKeyNameRegKey, - NULL); - if (status == ERROR_SUCCESS) - { - // Write entry values - status = RegSetValueExA(hCacheKeyNameRegKey, - CREATION_TIME_REG_VALUE, - 0, - REG_DWORD, - (LPBYTE) &pEntry->creationTime, - sizeof(pEntry->creationTime)); - if (status == ERROR_SUCCESS) - { - status = RegSetValueExA(hCacheKeyNameRegKey, - EXPIRATION_TIME_REG_VALUE, - 0, - REG_DWORD, - (LPBYTE) &pEntry->expirationTime, - sizeof(pEntry->expirationTime)); - if (status == ERROR_SUCCESS) - { - status = RegSetValueExA(hCacheKeyNameRegKey, - DOES_NOT_EXPIRE_REG_VALUE, - 0, - REG_DWORD, - (LPBYTE) &pEntry->doesNotExpire, - sizeof(pEntry->doesNotExpire)); - if (status == ERROR_SUCCESS) - { - status = RegSetValueExA(hCacheKeyNameRegKey, - STATUS_REG_VALUE, - 0, - REG_DWORD, - (LPBYTE) &pEntry->status, - sizeof(pEntry->status)); - if (status == ERROR_SUCCESS) - { - // Check if there is also an auth token associated with this entry - // this entry. - if (pEntry->status == CASA_STATUS_SUCCESS) - { - status = RegSetValueExA(hCacheKeyNameRegKey, - TOKEN_REG_VALUE, - 0, - REG_SZ, - (LPBYTE) pEntry->pToken, - (DWORD) strlen(pEntry->pToken) + 1); - if (status != ERROR_SUCCESS) - { - DbgTrace(0, "-AddEntryToAuthCache- Error setting token, status = %d\n", status); - } - } - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error setting status, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error setting does not expire, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error setting expiration time, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error setting creation time, status = %d\n", status); - } - - // Close CacheKeyName key - RegCloseKey(hCacheKeyNameRegKey); - - // Delete the CacheKeyName key if not successful - if (status != ERROR_SUCCESS) - { - RegDeleteKey(hHostRegKey, pEntry->pCacheKeyName); - } - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error creating key for CacheKeyName, status = %d\n", status); - } - - // Close host key - RegCloseKey(hHostRegKey); - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error creating key for host, status = %d\n", status); - } - - // Close CASA_Auth_Cache key - RegCloseKey(hCASARegKey); - } - else - { - DbgTrace(0, "-AddEntryToAuthCache- Error opening CASA Auth Cache Key, status = %d\n", status); - } - - // Either place the cache entry in our in-memory cache or - // free it depending on the status of the operations performed. - if (status == ERROR_SUCCESS) - { - // The entry was added to the cache, save it in - // our in-memory cache. - InsertHeadList(&g_authCacheListHead, &pEntry->listEntry); - - // Increment its reference count since we are keeping a reference - IncAuthCacheEntryRefCount(pEntry); - } - - DbgTrace(1, "-AddEntryToAuthCache- End\n", 0); -} - - -//++======================================================================= -CasaStatus -InitializeAuthCache(void) -// -// Arguments: -// -// Returns: -// -// Abstract: -// -// Notes: -// -// L2 -//=======================================================================-- -{ - CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, - CASA_FACILITY_AUTHTOKEN, - CASA_STATUS_UNSUCCESSFUL); - PSID pEveryoneSID; - SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; - - DbgTrace(1, "-InitializeAuthCache- Start\n", 0); - - // Initialize the cache list head - InitializeListHead(&g_authCacheListHead); - - // Lets create the CASA Auth Cache registry key in the - // user's hive and limit access to it. - // - // Create a well-known SID for the Everyone group. - if (AllocateAndInitializeSid(&SIDAuthWorld, - 1, - SECURITY_WORLD_RID, - 0, 0, 0, 0, 0, 0, 0, - &pEveryoneSID)) - { - EXPLICIT_ACCESS ea[3] = {0}; - SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; - PSID pAdminSID; - - // Initialize an EXPLICIT_ACCESS structure for an ACE. - // The ACE will revoke Everyone access to the key. - ea[0].grfAccessPermissions = KEY_ALL_ACCESS; - ea[0].grfAccessMode = REVOKE_ACCESS; - ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; - ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; - ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; - ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID; - - // Create a SID for the BUILTIN\Administrators group. - if (AllocateAndInitializeSid(&SIDAuthNT, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &pAdminSID)) - { - DWORD status; - PACL pACL; - HANDLE hToken; - - // Initialize an EXPLICIT_ACCESS structure for an ACE. - // The ACE will revoke the Administrators group access to the key. - ea[1].grfAccessPermissions = KEY_ALL_ACCESS; - ea[1].grfAccessMode = REVOKE_ACCESS; - ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; - ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; - ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; - ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID; - - // Create a SID for the interactive user, first get the process token - if (OpenProcessToken(GetCurrentProcess(), - TOKEN_QUERY, - &hToken)) - { - char tokenInformation[1024]; - DWORD infoLength; - - if (GetTokenInformation(hToken, - TokenUser, - tokenInformation, - sizeof(tokenInformation), - &infoLength)) - { - TOKEN_USER *pTokenUser = (TOKEN_USER*) tokenInformation; - - // Initialize an EXPLICIT_ACCESS structure for an ACE. - // The ACE will grant the interactive user access to the key. - ea[2].grfAccessPermissions = KEY_ALL_ACCESS; - ea[2].grfAccessMode = SET_ACCESS; - ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT; - ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID; - ea[2].Trustee.TrusteeType = TRUSTEE_IS_USER; - ea[2].Trustee.ptstrName = (LPTSTR) pTokenUser->User.Sid; - - // Create a new ACL that contains the new ACEs. - status = SetEntriesInAcl(3, ea, NULL, &pACL); - if (status == ERROR_SUCCESS) - { - PSECURITY_DESCRIPTOR pSD; - - // Allocate space for a security descriptor - pSD = (SECURITY_DESCRIPTOR*) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); - if (pSD) - { - // Initialize a security descriptor - if (InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) - { - // Add the ACL to the security descriptor - if (SetSecurityDescriptorDacl(pSD, - TRUE, // bDaclPresent flag - pACL, - FALSE)) // not a default DACL - { - SECURITY_ATTRIBUTES sa; - HKEY hCASARegKey; - DWORD disposition; - - // Initialize a security attributes structure - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = pSD; - sa.bInheritHandle = FALSE; - - // Now create the CASA Auth Cache registry key for this user - // with the required access control restrictions. - status = RegCreateKeyExA(HKEY_CURRENT_USER, - CASA_AUTH_CACHE_REG_KEY, - 0, - NULL, - REG_OPTION_VOLATILE, - KEY_ALL_ACCESS, - &sa, - &hCASARegKey, - &disposition); - if (status == ERROR_SUCCESS) - { - // Success - retStatus = CASA_STATUS_SUCCESS; - - // Close CASA_Auth_Cache key - RegCloseKey(hCASARegKey); - } - else - { - DbgTrace(0, "-InitializeAuthCache- Error creating CASA Key, status = %d\n", status); - } - } - else - { - DbgTrace(0, "-InitializeAuthCache- SetSecurityDescriptorDacl Error = %d\n", GetLastError()); - } - } - else - { - DbgTrace(0, "-InitializeAuthCache- InitializeSecurityDescriptor Error %d\n", GetLastError()); - } - - // Free the space allocated for the security descriptor - LocalFree(pSD); - } - else - { - DbgTrace(0, "-InitializeAuthCache- Unable to allocate memory for SD\n", 0); - } - - // Free the ACL structure - LocalFree(pACL); - } - else - { - DbgTrace(0, "-InitializeAuthCache- SetEntriesInAcl Error %d\n", status); - } - } - else - { - DbgTrace(0, "-InitializeAuthCache- Error obtaining token information, error = %d\n", GetLastError()); - } - - // Release the process token handle - CloseHandle(hToken); - } - else - { - DbgTrace(0, "-InitializeAuthCache- Unable to obtain process token, error = %d\n", GetLastError()); - } - - // Free the SID for the administrator - FreeSid(pAdminSID); - } - else - { - DbgTrace(0, "-InitializeAuthCache- AllocateAndInitializeSid Error %d\n", GetLastError()); - } - - // Free the SID for everyone - FreeSid(pEveryoneSID); - } - else - { - DbgTrace(0, "-InitializeAuthCache- AllocateAndInitializeSid Error = %d\n", GetLastError()); - } - - DbgTrace(1, "-InitializeAuthCache- End, retStatus = %08X\n", retStatus); - - return retStatus; -} - - -//++======================================================================= -//++======================================================================= -//++======================================================================= - diff --git a/CASA-auth-token/client/windows/dllsup.c b/CASA-auth-token/client/windows/dllsup.c index f6d3da15..c30b3cb2 100644 --- a/CASA-auth-token/client/windows/dllsup.c +++ b/CASA-auth-token/client/windows/dllsup.c @@ -58,7 +58,7 @@ BOOL APIENTRY DllMain( g_hModule = hModule; // Initialize the library - if (InitializeLibrary() != 0) + if (Initialize() != 0) { // Failed to initialize the library OutputDebugString("CASAAUTH -DllMain- Library initialization failed\n"); diff --git a/CASA-auth-token/client/windows/platform.c b/CASA-auth-token/client/windows/platform.c index e359d8eb..be5d587d 100644 --- a/CASA-auth-token/client/windows/platform.c +++ b/CASA-auth-token/client/windows/platform.c @@ -146,7 +146,7 @@ CreateUserMutex(void) } else { - DbgTrace(0, "-CreateUserMutex- Un-expected GetUserName error, error = %d\n", GetLastError()); + DbgTrace(0, "-CreateUserMutex- Unexpected GetUserName error, error = %d\n", GetLastError()); retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, CASA_FACILITY_AUTHTOKEN, CASA_STATUS_UNSUCCESSFUL); diff --git a/CASA-auth-token/client/windows/platform.h b/CASA-auth-token/client/windows/platform.h index b1729a01..c40accce 100644 --- a/CASA-auth-token/client/windows/platform.h +++ b/CASA-auth-token/client/windows/platform.h @@ -74,15 +74,15 @@ char printBuff[256]; \ // typedef struct _AuthCacheEntry { - LIST_ENTRY listEntry; - int refCount; +// LIST_ENTRY listEntry; +// int refCount; + int status; DWORD creationTime; DWORD expirationTime; BOOL doesNotExpire; - char *pHostName; - char *pCacheKeyName; - char *pToken; - int status; +// char *pHostName; +// char *pCacheKeyName; + char token[1]; } AuthCacheEntry, *PAuthCacheEntry;