Modified client to try to authenticate a user against a list of

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.
This commit is contained in:
Juan Carlos Luciani 2007-05-29 22:59:50 +00:00
parent f445b6d9c2
commit 3cc4067ab1
4 changed files with 521 additions and 195 deletions

View File

@ -60,6 +60,7 @@ 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)
@ -81,7 +82,7 @@ CreateAuthTokenCacheEntry(
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;
size_t tokenSize, wrapperEntrySize, cacheKeyStrLen, groupOrHostNameStrLen, hostAndPortStrLen;
WrapperAuthCacheEntry *pWrapperEntry = NULL;
AuthCacheEntry *pEntry = NULL;
char *pKey;
@ -145,43 +146,97 @@ CreateAuthTokenCacheEntry(
cacheKeyStrLen = strlen(pCacheKey);
groupOrHostNameStrLen = strlen(pGroupOrHostName);
// Verify that keySize will not overflow
if ((cacheKeyStrLen + groupOrHostNameStrLen + 2) <= UINT32_MAX)
// Build the cache entry key based on the status
if (status == CASA_STATUS_SUCCESS)
{
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + 2);
pKey = malloc(keySize);
if (pKey)
// 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)
{
strncpy(pKey, pCacheKey, keySize);
strncat(pKey, "@", keySize);
strncat(pKey, pGroupOrHostName, keySize);
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + 2);
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)
pKey = malloc(keySize);
if (pKey)
{
DbgTrace(0, "-CreateAuthTokenCacheEntry- miCASAWriteBinaryKey failure, status = %0X\n", miCasaStatus);
}
strncpy(pKey, pCacheKey, keySize);
strncat(pKey, "@", keySize);
strncat(pKey, pGroupOrHostName, keySize);
free(pKey);
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- Memory allocation failure\n", 0);
DbgTrace(0, "-CreateAuthTokenCacheEntry- keySize overflow prevented\n", 0);
}
}
else
{
DbgTrace(0, "-CreateAuthTokenCacheEntry- keySize overflow prevented\n", 0);
// 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
@ -543,6 +598,7 @@ AuthCacheEntry*
FindAuthTokenEntryInCache(
IN const char *pCacheKey,
IN const char *pGroupOrHostName,
IN const ATSHostEntry *pATSHost,
IN void *pCredStoreScope
)
//
@ -561,7 +617,7 @@ FindAuthTokenEntryInCache(
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;
size_t wrapperEntrySize, cacheKeyStrLen, groupOrHostNameStrLen, hostAndPortStrLen;
WrapperAuthCacheEntry *pWrapperEntry = NULL;
AuthCacheEntry *pEntry = NULL;
char *pKey;
@ -571,15 +627,18 @@ FindAuthTokenEntryInCache(
cacheKeyStrLen = strlen(pCacheKey);
groupOrHostNameStrLen = strlen(pGroupOrHostName);
hostAndPortStrLen = strlen(pATSHost->pNameAndPort);
// Verify that keySize will not overflow
if ((cacheKeyStrLen + groupOrHostNameStrLen + 2) <= UINT32_MAX)
// Verify that the worst case keySize will not overflow
if ((cacheKeyStrLen + groupOrHostNameStrLen + hostAndPortStrLen + 3) <= UINT32_MAX)
{
keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + 2);
// 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);
@ -592,7 +651,7 @@ FindAuthTokenEntryInCache(
&sessionKeyChain,
&sharedId,
(SS_UTF8_T*) pKey,
keySize,
strlen(pKey) + 1,
NULL,
&valueLength,
(SSCS_PASSWORD_T*) NULL,
@ -615,7 +674,7 @@ FindAuthTokenEntryInCache(
&sessionKeyChain,
&sharedId,
(SS_UTF8_T*) pKey,
keySize,
strlen(pKey) + 1,
(uint8_t *) pEntry,
&valueLength,
(SSCS_PASSWORD_T*) NULL,
@ -652,6 +711,82 @@ FindAuthTokenEntryInCache(
}
}
}
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);
}

View File

@ -6,28 +6,23 @@
#######################################################
#
# ATS-hostname setting.
# ATSHostList setting.
#
# Description: Used to configure the address of the
# ATS that should be used for obtaining
# authentication tokens.
# Description: Used to configure the addresses of the
# ATSs that should be used for obtaining
# authentication tokens. Use semicolons
# and no spaces to separate the host
# entries. To also configure the ports
# utilized by a host specify the
# port number after the hostname using
# a colon to separate the fields.
#
# If this parameter is not set, the client
# assummes that the ATS resides in the same
# host as the authentication token consuming
# services.
# Note that the client will try all of the
# ATSs on this list in the specified order
# in addition to the host for which an
# Authentication Token has been requested.
#
#ATS-hostname hostname or IP address
#
# ATS-port setting.
#
# Description: Used to configure the port utilized by the
# ATS to listen for connections.
#
# If this parameter is not set ....
#
#ATS-port 2645
#ATSHostList hostname1:2645;ip_address:443;hosname2
#
# DisableSecureConnections setting.

View File

@ -29,7 +29,9 @@
//===[ Type definitions ]==================================================
#define DEFAULT_RETRY_LIFETIME 5 // seconds
#define DEFAULT_RETRY_LIFETIME 300 // seconds
#define DEFAULT_ATS_PORT 2645
#define LOG_FILE_NAME "\\casaauthtoken.log"
@ -51,8 +53,7 @@ char *g_pDebugLogFilePath = NULL;
//
bool g_bInitialized = false;
long g_rpcFlags = SECURE_RPC_FLAG | ALLOW_INVALID_CERTS_USER_APPROVAL_RPC_FLAG;
char *g_pATSHostName = NULL;
uint16_t g_ATSPort = 2645;
LIST_ENTRY g_ATSHostList;
//++=======================================================================
@ -298,6 +299,7 @@ ObtainAuthTokenFromServer(
IN const char *pServiceName,
IN const char *pHostName,
IN const char *pNormalizedHostName,
IN const ATSHostEntry *pATSHost,
IN const void *pCredStoreScope,
INOUT char **ppAuthToken,
INOUT int *pTokenLifetime,
@ -324,8 +326,8 @@ ObtainAuthTokenFromServer(
*pAdvisedToRetry = false;
// Open Rpc Session to the auth service at the specified host
pRpcSession = OpenRpcSession((g_pATSHostName != NULL) ? g_pATSHostName : pHostName,
g_ATSPort);
pRpcSession = OpenRpcSession(pATSHost->pName,
pATSHost->port);
if (pRpcSession)
{
char *pReqMsg = NULL;
@ -337,7 +339,15 @@ ObtainAuthTokenFromServer(
char *pSessionToken = NULL;
// Request the auth parameters associated with this service
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost"); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
if (strcmp(pHostName, pATSHost->pName) == 0
|| strcmp(pNormalizedHostName, pATSHost->pName) == 0)
{
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, "localhost");
}
else
{
pReqMsg = BuildGetAuthPolicyMsg(pServiceName, pNormalizedHostName);
}
if (pReqMsg)
{
// Issue rpc
@ -367,15 +377,24 @@ ObtainAuthTokenFromServer(
// Now try to obtain a session token
retStatus = ObtainSessionToken(pRpcSession,
pAuthPolicy,
(g_pATSHostName != NULL) ? g_pATSHostName : pHostName,
(const char*) pATSHost->pName,
pCredStoreScope,
&pSessionToken,
&pSessionTokenAuthContext);
if (CASA_SUCCESS(retStatus))
{
// Request auth token for the service
free(pReqMsg);
pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken); // tbd - This will be changed in the future so that we can support services residing in a different host than the ATS
// Request auth token for the service
if (strcmp(pHostName, pATSHost->pName) == 0
|| strcmp(pNormalizedHostName, pATSHost->pName) == 0)
{
pReqMsg = BuildGetAuthTokenMsg(pServiceName, "localhost", pSessionToken);
}
else
{
pReqMsg = BuildGetAuthTokenMsg(pServiceName, pNormalizedHostName, pSessionToken);
}
if (pReqMsg)
{
// Free the previous response msg buffer
@ -620,16 +639,16 @@ ObtainAuthTokenInt(
// Make sure we are fully initialized
if (g_bInitialized == false)
{
retStatus = InitializeLibrary();
retStatus = InitializeLibrary();
if (retStatus == CASA_STATUS_SUCCESS)
{
g_bInitialized = true;
}
else
{
goto exit;
}
if (retStatus == CASA_STATUS_SUCCESS)
{
g_bInitialized = true;
}
else
{
goto exit;
}
}
// Release our synchronization mutex
@ -639,116 +658,202 @@ ObtainAuthTokenInt(
pNormalizedHostName = NormalizeHostName(pHostName);
if (pNormalizedHostName)
{
bool setupHostEntries = true;
char *pHostNameAnd443 = NULL;
char *pHostNameAnd2645 = NULL;
ATSHostEntry serviceHostEntry443 = {};
ATSHostEntry serviceHostEntry2645 = {};
LIST_ENTRY *pListEntry;
ATSHostEntry *pHostEntryInUse;
// Start user process synchronization
AcquireUserMutex(hUserMutex);
// Try to find a cache entry for the service
pCacheEntry = FindAuthTokenEntryInCache(pServiceName,
pNormalizedHostName,
pCredStoreScope);
if (pCacheEntry == NULL)
// Determine if we should setup host entries for the
// host where the service resides.
pListEntry = g_ATSHostList.Flink;
while(pListEntry != &g_ATSHostList)
{
// Initialize to retry in case of failure
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
bool advisedToRetry;
// Cache entry created, now try to obtain auth token from the CASA Server
pToken = NULL;
retStatus = ObtainAuthTokenFromServer(pServiceName,
pHostName,
pNormalizedHostName,
pCredStoreScope,
&pToken,
&cacheEntryLifetime,
&advisedToRetry);
// Retry if not successful and if advised to do so
if (!CASA_SUCCESS(retStatus)
&& advisedToRetry)
pHostEntryInUse = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
if (strcmp(pHostEntryInUse->pName, pHostName) == 0
|| strcmp(pHostEntryInUse->pName, pNormalizedHostName) == 0)
{
// The service's host is already in our list
setupHostEntries = false;
break;
}
// Advance to the next entry
pListEntry = pListEntry->Flink;
}
// Setup host entries for the service's host if necessary
if (setupHostEntries)
{
// Allocate space for the host name and port strings
pHostNameAnd443 = malloc(strlen(pHostName) + 5);
pHostNameAnd2645 = malloc(strlen(pHostName) + 6);
if (pHostNameAnd443 != NULL
&& pHostNameAnd2645 != NULL)
{
sprintf(pHostNameAnd443, "%s:%d", pHostName, 443);
sprintf(pHostNameAnd2645, "%s:%d", pHostName, 2645);
serviceHostEntry2645.pNameAndPort = pHostNameAnd2645;
serviceHostEntry2645.pName = pHostName;
serviceHostEntry2645.port = 2645;
InsertHeadList(&g_ATSHostList, &serviceHostEntry2645.listEntry);
serviceHostEntry443.pNameAndPort = pHostNameAnd443;
serviceHostEntry443.pName = pHostName;
serviceHostEntry443.port = 443;
InsertHeadList(&g_ATSHostList, &serviceHostEntry443.listEntry);
}
else
{
DbgTrace(0, "-ObtainAuthTokenInt- Buffer allocation failure\n", 0);
setupHostEntries = false; // To keep us from de-linking the entries later
}
}
// Now try to obtain an authentication token using the
// host entries at our disposal.
pListEntry = g_ATSHostList.Flink;
while(pListEntry != &g_ATSHostList)
{
// Get pointer to the host entry
pHostEntryInUse = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
// Try to find a cache entry for the service
pCacheEntry = FindAuthTokenEntryInCache(pServiceName,
pNormalizedHostName,
pHostEntryInUse,
pCredStoreScope);
if (pCacheEntry == NULL)
{
// Initialize to retry in case of failure
int cacheEntryLifetime = DEFAULT_RETRY_LIFETIME;
bool advisedToRetry;
// Cache entry created, now try to obtain auth token from the CASA Server
pToken = NULL;
retStatus = ObtainAuthTokenFromServer(pServiceName,
pHostName,
pNormalizedHostName,
pHostEntryInUse,
pCredStoreScope,
&pToken,
&cacheEntryLifetime,
&advisedToRetry);
}
// 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,
pCredStoreScope);
if (pCacheEntry)
// Retry if not successful and if advised to do so
if (!CASA_SUCCESS(retStatus)
&& advisedToRetry)
{
// Release the cache entry if the resulting status is not successful
if (!CASA_SUCCESS(retStatus))
retStatus = ObtainAuthTokenFromServer(pServiceName,
pHostName,
pNormalizedHostName,
pHostEntryInUse,
pCredStoreScope,
&pToken,
&cacheEntryLifetime,
&advisedToRetry);
}
// Add the entry to the cache if we did not fail due to authentication
// failure.
if (CasaStatusCode(retStatus) != CASA_STATUS_AUTHENTICATION_FAILURE)
{
pCacheEntry = CreateAuthTokenCacheEntry(pServiceName,
pNormalizedHostName,
pHostEntryInUse,
retStatus,
pToken,
cacheEntryLifetime,
pCredStoreScope);
if (pCacheEntry)
{
FreeAuthCacheEntry(pCacheEntry);
// Release the cache entry if the resulting status is not successful
if (!CASA_SUCCESS(retStatus))
{
FreeAuthCacheEntry(pCacheEntry);
}
}
}
}
// Release authentication token if present
if (pToken)
{
// Clear the memory before releasing the buffer since it contains
// security sensitive data.
memset(pToken, 0, strlen(pToken));
free(pToken);
}
}
else
{
// Cache entry found, update the return status with the information saved in it
// and release it if its status is not successful.
if (!CASA_SUCCESS(retStatus = pCacheEntry->status))
{
FreeAuthCacheEntry(pCacheEntry);
}
}
// Try to return auth token if we have one to return
if (CASA_SUCCESS(retStatus))
{
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
DbgTrace(2, "-ObtainAuthTokenInt- Copying the token into the callers buffer\n", 0);
strcpy(pAuthTokenBuf, pCacheEntry->token);
// Release authentication token if present
if (pToken)
{
// Clear the memory before releasing the buffer since it contains
// security sensitive data.
memset(pToken, 0, strlen(pToken));
free(pToken);
}
}
else
{
if (*pAuthTokenBufLen != 0)
// Cache entry found, update the return status with the information saved in it
// and release it if its status is not successful.
if (!CASA_SUCCESS(retStatus = pCacheEntry->status))
{
DbgTrace(0, "-ObtainAuthTokenInt- The supplied buffer is not large enough", 0);
FreeAuthCacheEntry(pCacheEntry);
}
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
// Return the token length to the caller
*pAuthTokenBufLen = tokenLen;
// Try to return auth token if we have one to return
if (CASA_SUCCESS(retStatus))
{
int tokenLen = (int) strlen(pCacheEntry->token) + 1;
FreeAuthCacheEntry(pCacheEntry);
// 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
DbgTrace(2, "-ObtainAuthTokenInt- Copying the token into the callers buffer\n", 0);
strcpy(pAuthTokenBuf, pCacheEntry->token);
}
else
{
if (*pAuthTokenBufLen != 0)
{
DbgTrace(0, "-ObtainAuthTokenInt- The supplied buffer is not large enough", 0);
}
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
// Return the token length to the caller
*pAuthTokenBufLen = tokenLen;
FreeAuthCacheEntry(pCacheEntry);
// No need to loop any longer
break;
}
// Advance to the next host entry
pListEntry = pListEntry->Flink;
}
// Unlink the service host entries if necessary
if (setupHostEntries)
{
RemoveEntryList(&serviceHostEntry2645.listEntry);
RemoveEntryList(&serviceHostEntry443.listEntry);
}
// Stop user process synchronization
ReleaseUserMutex(hUserMutex);
// Free the space allocated for the normalized host name
// Free the space allocated during processing of the request
if (pHostNameAnd443)
free(pHostNameAnd443);
if (pHostNameAnd2645)
free(pHostNameAnd2645);
free(pNormalizedHostName);
}
else
@ -928,6 +1033,64 @@ CleanUpAuthTokenCache(void)
}
//++=======================================================================
void
CreateATSHostEntry(
IN const char *pHostName,
IN uint16_t port)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(1, "-CreateATSHostEntry- Start\n", 0);
// Create host entry
ATSHostEntry *pHostEntry = malloc(sizeof(ATSHostEntry));
if (pHostEntry != NULL)
{
// Allocate buffers to keep copies of the strings provided
pHostEntry->pNameAndPort = malloc(strlen(pHostName) + 7);
pHostEntry->pName = malloc(strlen(pHostName) + 1);
if (pHostEntry->pNameAndPort != NULL
&& pHostEntry->pName != NULL)
{
// Setup the strings into the corresponding buffers
sprintf(pHostEntry->pNameAndPort, "%s:%d", pHostName, port);
strcpy(pHostEntry->pName, pHostName);
// Save host port in entry
pHostEntry->port = port;
// Insert the entry at the tail of the list
InsertTailList(&g_ATSHostList, &pHostEntry->listEntry);
}
else
{
DbgTrace(0, "-CreateATSHostEntry- Failed to allocate buffer\n", 0);
if (pHostEntry->pNameAndPort)
free(pHostEntry->pNameAndPort);
if (pHostEntry->pName)
free(pHostEntry->pName);
free(pHostEntry);
}
}
else
{
DbgTrace(0, "-CreateATSHostEntry- Failed to allocate buffer for host entry\n", 0);
}
DbgTrace(1, "-CreateATSHostEntry- Exit\n", 0);
}
//++=======================================================================
int
InitializeLibrary(void)
@ -948,14 +1111,16 @@ InitializeLibrary(void)
ConfigIf *pClientConfigIf;
char *pDebugLevelSetting;
char *pDebugLogFolderPathSetting;
char *pATSPortSetting;
char *pATSHostNameSetting;
char *pATSHostListSetting;
char *pDisableSecureConnections;
char *pAllowInvalidCerts;
char *pUsersCannotAllowInvalidCerts;
DbgTrace(1, "-InitializeLibrary- Start\n", 0);
// Initialize the ATSHostList
InitializeListHead(&g_ATSHostList);
// Try to obtain client configuration settings
getConfigStatus = GetConfigInterface(clientConfigFolder,
"client",
@ -998,25 +1163,59 @@ InitializeLibrary(void)
pClientConfigIf->freeValueString(pClientConfigIf, pDebugLogFolderPathSetting);
}
// Check if an ATS hostname has been configured
pATSHostNameSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-hostname");
if (pATSHostNameSetting != NULL)
// Check if an ATS Host List has been configured
pATSHostListSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATSHostList");
if (pATSHostListSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- ATS hostname configured = %s\n", pATSHostNameSetting);
char *pSavePtr;
char *pHostAndPort;
// Remember the ATS host name
g_pATSHostName = malloc(strlen(pATSHostNameSetting) + 1);
if (g_pATSHostName)
DbgTrace(0, "-InitializeLibrary- ATSHostList configured = %s\n", pATSHostListSetting);
// Go through all configured host addresses
pHostAndPort = strtok_r(pATSHostListSetting, ";", &pSavePtr);
while (pHostAndPort != NULL)
{
strcpy(g_pATSHostName, pATSHostNameSetting);
}
else
{
DbgTrace(0, "-InitializeLibrary- Failed to allocate buffer for ATS host name\n", 0);
char *pSavePtr2;
char *pHostName;
// Check if the host address includes the listen port number.
pHostName = strtok_r(pHostAndPort, ":", &pSavePtr2);
if (pHostName != NULL)
{
uint16_t port = 0;
char *pHostPort = strtok_r(NULL, ":", &pSavePtr2);
if (pHostPort != NULL)
{
// Convert the number to hex
port = (uint16_t) dtoul(pHostPort, strlen(pHostPort));
}
// Now create the necessary ATS Host entries
if (port == 0)
{
// The port number was not configured, create an ATS Host entry
// for each possible listen port.
CreateATSHostEntry(pHostName, 443);
CreateATSHostEntry(pHostName, 2645);
}
else
{
// Create ATS Host entry for configured port
CreateATSHostEntry(pHostName, port);
}
}
else
{
DbgTrace(0, "-InitializeLibrary- Error parsing configured host address\n", 0);
}
// Advance to the next entry
pHostAndPort = strtok_r(NULL, ";", &pSavePtr);
}
// Free the buffer holding the ats host name setting
pClientConfigIf->freeValueString(pClientConfigIf, pATSHostNameSetting);
// Free the buffer holding the ats host list setting
pClientConfigIf->freeValueString(pClientConfigIf, pATSHostListSetting);
}
// Check if the DisableSecureConnections setting has been configured
@ -1087,19 +1286,6 @@ InitializeLibrary(void)
}
}
// Check if an ATS port number has been configured
pATSPortSetting = pClientConfigIf->getEntryValue(pClientConfigIf, "ATS-port");
if (pATSPortSetting != NULL)
{
DbgTrace(0, "-InitializeLibrary- ATS port number configured = %s\n", pATSPortSetting);
// Convert the number to hex
g_ATSPort = (int) dtoul(pATSPortSetting, strlen(pATSPortSetting));
// Free the buffer holding the port number
pClientConfigIf->freeValueString(pClientConfigIf, pATSPortSetting);
}
// Release config interface instance
pClientConfigIf->releaseReference(pClientConfigIf);
}
@ -1108,22 +1294,6 @@ InitializeLibrary(void)
retStatus = InitializeHostNameNormalization();
if (CASA_SUCCESS(retStatus))
{
// Normalize ATS host name if configured
if (g_pATSHostName)
{
char *pNormalizedHostName = NormalizeHostName(g_pATSHostName);
if (pNormalizedHostName)
{
// Use this name instead of the one that we already have
free(g_pATSHostName);
g_pATSHostName = pNormalizedHostName;
}
else
{
DbgTrace(0, "-InitializeLibrary- ATS Hostname normalization failed\n", 0);
}
}
// Initialize the auth cache
retStatus = InitializeAuthCache();
if (CASA_SUCCESS(retStatus))
@ -1161,6 +1331,9 @@ UnInitializeLibrary(void)
// L2
//=======================================================================--
{
LIST_ENTRY *pListEntry;
ATSHostEntry *pHostEntry;
DbgTrace(1, "-UnInitializeLibrary- Start\n", 0);
// Un-initialize the host name normalization
@ -1180,8 +1353,16 @@ UnInitializeLibrary(void)
free(pBuffer);
}
if (g_pATSHostName)
free(g_pATSHostName);
pListEntry = g_ATSHostList.Flink;
while (pListEntry != &g_ATSHostList)
{
pHostEntry = CONTAINING_RECORD(pListEntry, ATSHostEntry, listEntry);
RemoveEntryList(pListEntry);
free(pHostEntry->pNameAndPort);
free(pHostEntry->pName);
free(pHostEntry);
pListEntry = g_ATSHostList.Flink;
}
DbgTrace(1, "-UnInitializeLibrary- End\n", 0);
}

View File

@ -41,6 +41,19 @@
#define MAX_RPC_REPLY_SZ (256 * 1024)
//
// ATS Host Entry structure
//
typedef struct _ATSHostEntry
{
LIST_ENTRY listEntry;
char *pNameAndPort;
char *pName;
uint16_t port;
} ATSHostEntry, *PATSHostEntry;
//
// Authentication Context structure
//
@ -270,6 +283,7 @@ AuthCacheEntry*
CreateAuthTokenCacheEntry(
IN const char *pCacheKey,
IN const char *pHostName,
IN const ATSHostEntry *pATSHost,
IN CasaStatus status,
IN char *pToken,
IN int entryLifetime,
@ -291,6 +305,7 @@ AuthCacheEntry*
FindAuthTokenEntryInCache(
IN const char *pCacheKey,
IN const char *pGroupOrHostName,
IN const ATSHostEntry *pATSHost,
IN void *pCredStoreScope);
extern