Hello community, here is the log from the commit of package CASA_auth_token_client checked in at Sun Jul 1 17:31:59 CEST 2007. -------- --- CASA_auth_token_client/CASA_auth_token_client.changes 2007-04-30 16:48:12.000000000 +0200 +++ /mounts/work_src_done/STABLE/CASA_auth_token_client/CASA_auth_token_client.changes 2007-06-29 19:45:10.000000000 +0200 @@ -1,0 +2,26 @@ +Thu Jun 28 11:34:46 MDT 2007 - jluciani@novell.com + +- Fixed libcasa_c_authtoken crash that would occur when the + was unloaded before previously been initialized. This addresses + BUG288073. + +------------------------------------------------------------------- +Mon Jun 4 10:57:41 MDT 2007 - jluciani@novell.com + +- Commented out the line in the client.conf file which was allowing + clients to trust ATSs with Certificates that could not be validated. + This completes the changes necessary for the resolution of + BUG 242891. + +- Changed the client to allow a list of ATSs to be configured in + the client.conf file for the purposes of Fault-tolerance and also + the client now tries to contact an ATS at the same location as + the AuthToken consuming service in addition to the configured + ATSs. These changes were necessary to resolve BUG 242891. + +- The client now also attempts to access ATSs over port 443 in + addition to trying port 2645 if the ATS port number is not + configured. This will make it possible to access the ATSs + when connected to a Web Server. This addresses part of BUG287279. + +------------------------------------------------------------------- Old: ---- CASA_auth_token_client-1.7.1326.tar.bz2 New: ---- CASA_auth_token_client-1.7.1414.tar.bz2 check-build.sh ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ CASA_auth_token_client.spec ++++++ --- /var/tmp/diff_new_pack.Dx3575/_old 2007-07-01 17:31:45.000000000 +0200 +++ /var/tmp/diff_new_pack.Dx3575/_new 2007-07-01 17:31:45.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package CASA_auth_token_client (Version 1.7.1326 ) +# spec file for package CASA_auth_token_client (Version 1.7.1414 ) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -15,14 +15,17 @@ %define debug_opt "" URL: http://www.novell.com/products -BuildRequires: CASA-devel curl-devel expat gcc-c++ glade-sharp2 glib2-devel krb5-devel libexpat-devel libgcc libgssapi libstdc++ libstdc++-devel mono-devel pkgconfig sysvinit update-alternatives +BuildRequires: CASA-devel curl-devel expat gcc-c++ glade-sharp2 glib2-devel krb5-devel libgcc libgssapi libstdc++ libstdc++-devel mono-devel pkgconfig sysvinit update-alternatives +%if %suse_version > 1020 +BuildRequires: libexpat-devel +%endif %define prefix /usr License: GNU Library General Public License v. 2.0 and 2.1 (LGPL) Group: Development/Libraries/C and C++ Autoreqprov: on -%define bldno 1.7.1326 -Version: 1.7.1326 -Release: 2 +%define bldno 1.7.1414 +Version: 1.7.1414 +Release: 1 Summary: Novell CASA Authentication Token Libraries for Client Applications Source: %{name}-%{version}.tar.bz2 Group: Development/Libraries/C and C++ @@ -186,6 +189,24 @@ %{prefix}/include/casa_c_authtoken.h %changelog +* Thu Jun 28 2007 - jluciani@novell.com +- Fixed libcasa_c_authtoken crash that would occur when the + was unloaded before previously been initialized. This addresses + BUG288073. +* Mon Jun 04 2007 - jluciani@novell.com +- Commented out the line in the client.conf file which was allowing + clients to trust ATSs with Certificates that could not be validated. + This completes the changes necessary for the resolution of + BUG 242891. +- Changed the client to allow a list of ATSs to be configured in + the client.conf file for the purposes of Fault-tolerance and also + the client now tries to contact an ATS at the same location as + the AuthToken consuming service in addition to the configured + ATSs. These changes were necessary to resolve BUG 242891. +- The client now also attempts to access ATSs over port 443 in + addition to trying port 2645 if the ATS port number is not + configured. This will make it possible to access the ATSs + when connected to a Web Server. This addresses part of BUG287279. * Mon Apr 30 2007 - ro@suse.de - added libexpat-devel to buildrequires * Tue Apr 17 2007 - jluciani@novell.com ++++++ CASA_auth_token_client-1.7.1326.tar.bz2 -> CASA_auth_token_client-1.7.1414.tar.bz2 ++++++ diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/configure.in new/CASA_auth_token_client-1.7.1414/configure.in --- old/CASA_auth_token_client-1.7.1326/configure.in 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/configure.in 2007-06-29 19:37:55.000000000 +0200 @@ -22,7 +22,7 @@ AC_INIT(CASA_auth_token_client, 1.7.795,,CASA_auth_token_client) AC_CONFIG_SRCDIR(autogen.sh) AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(CASA_auth_token_client, 1.7.1326) +AM_INIT_AUTOMAKE(CASA_auth_token_client, 1.7.1414) RELEASE=`date +%Y%m%d_%H%M` AC_SUBST(RELEASE) AM_MAINTAINER_MODE diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/cache.c new/CASA_auth_token_client-1.7.1414/library/cache.c --- old/CASA_auth_token_client-1.7.1326/library/cache.c 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/cache.c 2007-06-29 19:37:55.000000000 +0200 @@ -60,6 +60,7 @@ 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 @@ 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 @@ 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); - - 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) + keySize = (uint32_t) (cacheKeyStrLen + groupOrHostNameStrLen + 2); + + 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); + + 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); + 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 @@ FindAuthTokenEntryInCache( IN const char *pCacheKey, IN const char *pGroupOrHostName, + IN const ATSHostEntry *pATSHost, IN void *pCredStoreScope ) // @@ -561,7 +617,7 @@ 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 @@ 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 @@ &sessionKeyChain, &sharedId, (SS_UTF8_T*) pKey, - keySize, + strlen(pKey) + 1, NULL, &valueLength, (SSCS_PASSWORD_T*) NULL, @@ -615,7 +674,7 @@ &sessionKeyChain, &sharedId, (SS_UTF8_T*) pKey, - keySize, + strlen(pKey) + 1, (uint8_t *) pEntry, &valueLength, (SSCS_PASSWORD_T*) NULL, @@ -652,6 +711,82 @@ } } } + 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); } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/client.conf new/CASA_auth_token_client-1.7.1414/library/client.conf --- old/CASA_auth_token_client-1.7.1326/library/client.conf 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/client.conf 2007-06-29 19:37:55.000000000 +0200 @@ -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. +# +# 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. # -# If this parameter is not set, the client -# assummes that the ATS resides in the same -# host as the authentication token consuming -# services. -# -#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;hostname2 # # DisableSecureConnections setting. @@ -63,7 +58,7 @@ # process to impersonate an ATS and obtain information that # is confidential such as username and passwords. # -AllowUntrustedCerts true +#AllowUntrustedCerts true # # UsersCannotAllowInvalidCerts setting. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/engine.c new/CASA_auth_token_client-1.7.1414/library/engine.c --- old/CASA_auth_token_client-1.7.1326/library/engine.c 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/engine.c 2007-06-29 19:37:55.000000000 +0200 @@ -29,7 +29,11 @@ //===[ Type definitions ]================================================== -#define DEFAULT_RETRY_LIFETIME 5 // seconds +#define DEFAULT_RETRY_LIFETIME 300 // seconds + +#define BAD_CACHE_TRIGER_TIME 30 // seconds + +#define DEFAULT_ATS_PORT 2645 #define LOG_FILE_NAME "\\casaauthtoken.log" @@ -51,8 +55,7 @@ // 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 +301,7 @@ 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 +328,8 @@ *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 +341,15 @@ 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 +379,24 @@ // 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 +641,16 @@ // 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 +660,211 @@ pNormalizedHostName = NormalizeHostName(pHostName); if (pNormalizedHostName) { + bool setupHostEntries = true; + char *pHostNameAnd443 = NULL; + char *pHostNameAnd2645 = NULL; + ATSHostEntry serviceHostEntry443 = {{NULL, NULL}, NULL, NULL, 0}; + ATSHostEntry serviceHostEntry2645 = {{NULL, NULL}, NULL, NULL, 0}; + 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; + DWORD opStartTime = GetTickCount(); + + // 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); + } + + // Try to add the entry to the cache if we did not fail due + // to authentication failure. + if (CasaStatusCode(retStatus) != CASA_STATUS_AUTHENTICATION_FAILURE) + { + DWORD opEndTime = GetTickCount(); + + // We only want to cache bad results if the operation took a + // considerable amount of time. + if (CASA_SUCCESS(retStatus) + || opEndTime >= (opStartTime + (BAD_CACHE_TRIGER_TIME * 1000))) { - FreeAuthCacheEntry(pCacheEntry); + pCacheEntry = CreateAuthTokenCacheEntry(pServiceName, + pNormalizedHostName, + pHostEntryInUse, + retStatus, + pToken, + cacheEntryLifetime, + pCredStoreScope); + if (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); + // 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)) + else { - FreeAuthCacheEntry(pCacheEntry); + // 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); - } - else + // Try to return auth token if we have one to return + if (CASA_SUCCESS(retStatus)) { - if (*pAuthTokenBufLen != 0) + 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) { - DbgTrace(0, "-ObtainAuthTokenInt- The supplied buffer is not large enough", 0); + // Return the auth token to the caller + DbgTrace(2, "-ObtainAuthTokenInt- Copying the token into the callers buffer\n", 0); + strcpy(pAuthTokenBuf, pCacheEntry->token); } - retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, - CASA_FACILITY_AUTHTOKEN, - CASA_STATUS_BUFFER_OVERFLOW); + 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; } - // Return the token length to the caller - *pAuthTokenBufLen = tokenLen; + // Advance to the next host entry + pListEntry = pListEntry->Flink; + } - FreeAuthCacheEntry(pCacheEntry); + // 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 @@ -929,6 +1045,66 @@ //++======================================================================= +void +CreateATSHostEntry( + IN const char *pHostName, + IN uint16_t port) +// +// Arguments: +// +// Returns: +// +// Abstract: +// +// Notes: +// +// L2 +//=======================================================================-- +{ + ATSHostEntry *pHostEntry; + + DbgTrace(1, "-CreateATSHostEntry- Start\n", 0); + + // Create host entry + 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 +1124,16 @@ 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 +1176,59 @@ 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) - { - strcpy(g_pATSHostName, pATSHostNameSetting); - } - else + DbgTrace(0, "-InitializeLibrary- ATSHostList configured = %s\n", pATSHostListSetting); + + // Go through all configured host addresses + pHostAndPort = strtok_r(pATSHostListSetting, ";", &pSavePtr); + while (pHostAndPort != NULL) { - 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 @@ -1026,11 +1238,11 @@ DbgTrace(0, "-InitializeLibrary- DisableSecureConnections setting configured = %s\n", pDisableSecureConnections); // Adjust the g_rpcFlags variable based on the setting - if (_stricmp(pDisableSecureConnections, "true") == 0) + if (stricmp(pDisableSecureConnections, "true") == 0) { g_rpcFlags &= ~SECURE_RPC_FLAG; } - else if (_stricmp(pDisableSecureConnections, "false") == 0) + else if (stricmp(pDisableSecureConnections, "false") == 0) { g_rpcFlags |= SECURE_RPC_FLAG; } @@ -1087,19 +1299,6 @@ } } - // 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 +1307,6 @@ 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 +1344,9 @@ // L2 //=======================================================================-- { + LIST_ENTRY *pListEntry; + ATSHostEntry *pHostEntry; + DbgTrace(1, "-UnInitializeLibrary- Start\n", 0); // Un-initialize the host name normalization @@ -1180,8 +1366,19 @@ free(pBuffer); } - if (g_pATSHostName) - free(g_pATSHostName); + pListEntry = g_ATSHostList.Flink; + if (pListEntry) + { + 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); } diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/internal.h new/CASA_auth_token_client-1.7.1414/library/internal.h --- old/CASA_auth_token_client-1.7.1326/library/internal.h 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/internal.h 2007-06-29 19:37:55.000000000 +0200 @@ -42,6 +42,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 // typedef struct _AuthContext @@ -270,6 +283,7 @@ 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 @@ FindAuthTokenEntryInCache( IN const char *pCacheKey, IN const char *pGroupOrHostName, + IN const ATSHostEntry *pATSHost, IN void *pCredStoreScope); extern diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/linux/rpc.c new/CASA_auth_token_client-1.7.1414/library/linux/rpc.c --- old/CASA_auth_token_client-1.7.1326/library/linux/rpc.c 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/linux/rpc.c 2007-06-29 19:37:55.000000000 +0200 @@ -208,6 +208,12 @@ setOptError = true; } + if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_CAPATH, "/etc/ssl/certs")) != CURLE_OK) + { + DbgTrace(0, "-OpenRpcSession- Error setting CURLOPT_CAPATH, code = %d\n", result); + setOptError = true; + } + pSession->headers = curl_slist_append(pSession->headers, "Content-Type: text/html"); pSession->headers = curl_slist_append(pSession->headers, "Expect:"); if ((result = curl_easy_setopt(pSession->hCurl, CURLOPT_HTTPHEADER, pSession->headers)) != CURLE_OK) diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/TODO new/CASA_auth_token_client-1.7.1414/library/TODO --- old/CASA_auth_token_client-1.7.1326/library/TODO 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/TODO 2007-06-29 19:37:54.000000000 +0200 @@ -10,14 +10,9 @@ OUTSTANDING ITEMS -- Add mechanism to try communicating with ATS over port 443 if communications - over port 2645 fail. - - Enhance the AuthMechanism interface to support authentication schemes that require several token exchanges between the client and the server. This will also require the enhancement of the client/server protocol utilized for authentication. -- Add mechanism to allow a user to either accept or reject server certificates - considered invalid. - +- Enhance to dynamically learn about the location of ATSs. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/library/windows/platform.h new/CASA_auth_token_client-1.7.1414/library/windows/platform.h --- old/CASA_auth_token_client-1.7.1326/library/windows/platform.h 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/library/windows/platform.h 2007-06-29 19:37:55.000000000 +0200 @@ -100,6 +100,8 @@ #define AcquireModuleMutex WaitForSingleObjectEx(g_hModuleMutex, INFINITE, FALSE) #define ReleaseModuleMutex ReleaseMutex(g_hModuleMutex) +#define strtok_r strtok_s + //===[ Inlines functions ]=============================================== //===[ Function prototypes ]=============================================== diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/package/linux/CASA_auth_token_client.changes new/CASA_auth_token_client-1.7.1414/package/linux/CASA_auth_token_client.changes --- old/CASA_auth_token_client-1.7.1326/package/linux/CASA_auth_token_client.changes 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/package/linux/CASA_auth_token_client.changes 2007-06-29 19:37:55.000000000 +0200 @@ -1,4 +1,35 @@ ------------------------------------------------------------------- +Thu Jun 28 11:34:46 MDT 2007 - jluciani@novell.com + +- Fixed libcasa_c_authtoken crash that would occur when the + was unloaded before previously been initialized. This addresses + BUG288073. + +------------------------------------------------------------------- +Mon Jun 4 10:57:41 MDT 2007 - jluciani@novell.com + +- Commented out the line in the client.conf file which was allowing + clients to trust ATSs with Certificates that could not be validated. + This completes the changes necessary for the resolution of + BUG 242891. + +- Changed the client to allow a list of ATSs to be configured in + the client.conf file for the purposes of Fault-tolerance and also + the client now tries to contact an ATS at the same location as + the AuthToken consuming service in addition to the configured + ATSs. These changes were necessary to resolve BUG 242891. + +- The client now also attempts to access ATSs over port 443 in + addition to trying port 2645 if the ATS port number is not + configured. This will make it possible to access the ATSs + when connected to a Web Server. This addresses part of BUG287279. + +------------------------------------------------------------------- +Mon Apr 30 16:48:07 CEST 2007 - ro@suse.de + +- added libexpat-devel to buildrequires + +------------------------------------------------------------------- Tue Apr 17 09:07:57 MDT 2007 - jluciani@novell.com - Added CleanUpAuthTokenCache() API to solve BUG260619. diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/CASA_auth_token_client-1.7.1326/package/linux/CASA_auth_token_client.spec.in new/CASA_auth_token_client-1.7.1414/package/linux/CASA_auth_token_client.spec.in --- old/CASA_auth_token_client-1.7.1326/package/linux/CASA_auth_token_client.spec.in 2007-04-26 00:24:05.000000000 +0200 +++ new/CASA_auth_token_client-1.7.1414/package/linux/CASA_auth_token_client.spec.in 2007-06-29 19:37:55.000000000 +0200 @@ -16,6 +16,9 @@ URL: http://www.novell.com/products BuildRequires: CASA-devel curl-devel expat gcc-c++ glade-sharp2 glib2-devel krb5-devel libgcc libgssapi libstdc++ libstdc++-devel mono-devel pkgconfig sysvinit update-alternatives +%if %suse_version > 1020 +BuildRequires: libexpat-devel +%endif %define prefix /usr License: LGPL Group: System/Libraries ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org