Made changes to deal with issues found during self-code review.
Added lock callback functionality for interfacing with OpenSSL in a multi-threaded environment.
This commit is contained in:
		| @@ -57,6 +57,7 @@ CFILES = ../authmech.c \ | ||||
| 	 ../util.c \ | ||||
| 	 ../invalidcert.c \ | ||||
| 	 rpc.c \ | ||||
| 	 osslsupp.c \ | ||||
| 	 platform.c | ||||
|  | ||||
| CSFILES_CSC := | ||||
|   | ||||
							
								
								
									
										323
									
								
								CASA-auth-token/client/lib/linux/osslsupp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								CASA-auth-token/client/lib/linux/osslsupp.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,323 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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 <jluciani@novell.com> | ||||
|  * | ||||
|  ***********************************************************************/ | ||||
|  | ||||
|  | ||||
| //===[ Include files ]===================================================== | ||||
|  | ||||
| #include "internal.h" | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
| // Number of static locks required by OpenSSL | ||||
| static | ||||
| int   g_numStaticLocks = 0; | ||||
|  | ||||
| // Mutex array for OpenSSL static locks | ||||
| static | ||||
| pthread_mutex_t   *g_staticLocks = NULL; | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static void | ||||
| StaticLockFunction( | ||||
|    IN    int mode, | ||||
|    IN    int n, | ||||
|    IN    const char *file, | ||||
|    IN    int line) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(2, "-StaticLockFunction- Start\n", 0); | ||||
|  | ||||
|    // Verify that the lock number is within range | ||||
|    if (n < g_numStaticLocks | ||||
|        && n >= 0) | ||||
|    { | ||||
|       // Either set or release the nth lock | ||||
|       if (mode & CRYPTO_LOCK) | ||||
|       { | ||||
|          // Set the lock | ||||
|          pthread_mutex_lock(&g_staticLocks[n]); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // Release the lock | ||||
|          pthread_mutex_unlock(&g_staticLocks[n]); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(2, "-StaticLockFunction- n out of range\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-StaticLockFunction- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static void | ||||
| DynLockFunction( | ||||
|    IN    int mode, | ||||
|    IN    struct CRYPTO_dynlock_value *l, | ||||
|    IN    const char *file, | ||||
|    IN    int line) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(2, "-DynLockFunction- Start\n", 0); | ||||
|  | ||||
|    if (l) | ||||
|    { | ||||
|       // Either set or release the lock | ||||
|       if (mode & CRYPTO_LOCK) | ||||
|       { | ||||
|          // Set the lock | ||||
|          pthread_mutex_lock((pthread_mutex_t*) l); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // Release the lock | ||||
|          pthread_mutex_unlock((pthread_mutex_t*) l); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(2, "-DynLockFunction- Invalid parameter\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(2, "-DynLockFunction- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static struct CRYPTO_dynlock_value* | ||||
| CreateDynLockFunction( | ||||
|    IN    const char *file, | ||||
|    IN    int line) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    struct CRYPTO_dynlock_value   *l; | ||||
|  | ||||
|    DbgTrace(1, "-CreateDynLockFunction- Start\n", 0); | ||||
|  | ||||
|    // Allocate space for the lock | ||||
|    l = (struct CRYPTO_dynlock_value*) malloc(sizeof(pthread_mutex_t)); | ||||
|    if (l) | ||||
|    { | ||||
|       pthread_mutex_init((pthread_mutex_t*) l, NULL); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-CreateDynLockFunction- Buffer allocation failure\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-CreateDynLockFunction- End, l = %0lX\n", (long) l); | ||||
|  | ||||
|    return l; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static void | ||||
| DestroyDynLockFunction( | ||||
|    IN    struct CRYPTO_dynlock_value *l, | ||||
|    IN    const char *file, | ||||
|    IN    int line) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    DbgTrace(1, "-DestroyDynLockFunction- Start, l = %0lX\n", (long) l); | ||||
|  | ||||
|    if (l) | ||||
|    { | ||||
|       pthread_mutex_destroy((pthread_mutex_t*) l); | ||||
|       free(l); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-DestroyDynLockFunction- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| static unsigned long | ||||
| ThreadIdFunction(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    unsigned long  threadId; | ||||
|  | ||||
|    DbgTrace(2, "-ThreadIdFunction- Start\n", 0); | ||||
|  | ||||
|    threadId = (unsigned long) pthread_self(); | ||||
|  | ||||
|    DbgTrace(2, "-ThreadIdFunction- End, id = %0lX\n", threadId); | ||||
|  | ||||
|    return threadId; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| int | ||||
| SetupOSSLSupport(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int   retStatus = -1; | ||||
|    int   i; | ||||
|  | ||||
|    DbgTrace(1, "-SetupOSSLSupport- Start\n", 0); | ||||
|  | ||||
|    // Determine how many static locks are needed | ||||
|    g_numStaticLocks = CRYPTO_num_locks(); | ||||
|  | ||||
|    // Allocate space to hold the needed mutexes | ||||
|    g_staticLocks = malloc(sizeof(pthread_mutex_t) * g_numStaticLocks); | ||||
|    if (g_staticLocks) | ||||
|    { | ||||
|       for (i = 0; i < g_numStaticLocks; i++) | ||||
|          pthread_mutex_init(&g_staticLocks[i], NULL); | ||||
|  | ||||
|       // Set callback functions | ||||
|       CRYPTO_set_id_callback(ThreadIdFunction); | ||||
|       CRYPTO_set_locking_callback(StaticLockFunction); | ||||
|       CRYPTO_set_dynlock_create_callback(CreateDynLockFunction); | ||||
|       CRYPTO_set_dynlock_destroy_callback(DestroyDynLockFunction); | ||||
|       CRYPTO_set_dynlock_lock_callback(DynLockFunction); | ||||
|  | ||||
|       // Success | ||||
|       retStatus = 0; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       DbgTrace(0, "-SetupOSSLSupport- Buffer allocation failure\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-SetupOSSLSupport- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| void | ||||
| CleanupOSSLSupport(void) | ||||
| // | ||||
| //  Arguments:  | ||||
| // | ||||
| //  Returns:    | ||||
| // | ||||
| //  Abstract:   | ||||
| // | ||||
| //  Notes: | ||||
| // | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    int   i; | ||||
|  | ||||
|    DbgTrace(1, "-CleanupOSSLSupport- Start\n", 0); | ||||
|  | ||||
|    // Clear our callback functions | ||||
|    CRYPTO_set_id_callback(NULL); | ||||
|    CRYPTO_set_locking_callback(NULL); | ||||
|    CRYPTO_set_dynlock_create_callback(NULL); | ||||
|    CRYPTO_set_dynlock_destroy_callback(NULL); | ||||
|    CRYPTO_set_dynlock_lock_callback(NULL); | ||||
|  | ||||
|    // Now, cleanup the resources allocated for static locks | ||||
|    if (g_staticLocks) | ||||
|    { | ||||
|       for (i = 0; i < g_numStaticLocks; i++) | ||||
|          pthread_mutex_destroy(&g_staticLocks[i]); | ||||
|  | ||||
|       free(g_staticLocks); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-CleanupOSSLSupport- End\n", 0); | ||||
| } | ||||
|  | ||||
|  | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
| //++======================================================================= | ||||
|  | ||||
| @@ -42,6 +42,7 @@ typedef struct _NormalizedHostNameCacheEntry | ||||
|  | ||||
|  | ||||
| //===[ Type definitions for Local_sem ]==================================== | ||||
|  | ||||
| //  | ||||
| //  Notes: Most of the code for this definitions and the Local_sem_xxxx | ||||
| //         functions was copied with minor modifications from W. Richard | ||||
| @@ -694,53 +695,65 @@ NormalizeHostName( | ||||
|  | ||||
|             // Now try to resolve the normalized name | ||||
|             pLookupResult = gethostbyname(pHostName); | ||||
|             if (pLookupResult && pLookupResult->h_addrtype == AF_INET) | ||||
|             if (pLookupResult | ||||
|                 && pLookupResult->h_addrtype == AF_INET | ||||
|                 && pLookupResult->h_length > 0 | ||||
|                 && pLookupResult->h_addr_list[0] != NULL) | ||||
|             { | ||||
|                char  dnsHostName[NI_MAXHOST]; | ||||
|  | ||||
|                // Set up a sockaddr structure | ||||
|                sockAddr.sin_family = AF_INET; | ||||
|                sockAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); | ||||
|  | ||||
|                // Now try to resolve the name using DNS | ||||
|                if (getnameinfo((const struct sockaddr*) &sockAddr, | ||||
|                                sizeof(sockAddr), | ||||
|                                dnsHostName, | ||||
|                                sizeof(dnsHostName), | ||||
|                                NULL, | ||||
|                                0, | ||||
|                                NI_NAMEREQD) == 0) | ||||
|                char *pDnsHostName = (char*) malloc(NI_MAXHOST + 1); | ||||
|                if (pDnsHostName) | ||||
|                { | ||||
|                   // We resolved the address to a DNS name, use it as the normalized name. | ||||
|                   pEntry->buffLengthRequired = (int) strlen(dnsHostName) + 1; | ||||
|                   pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                   if (pEntry->pNormalizedHostName) | ||||
|                   // Set up a sockaddr structure | ||||
|                   sockAddr.sin_family = AF_INET; | ||||
|                   sockAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); | ||||
|  | ||||
|                   // Now try to resolve the name using DNS | ||||
|                   if (getnameinfo((const struct sockaddr*) &sockAddr, | ||||
|                                   sizeof(sockAddr), | ||||
|                                   pDnsHostName, | ||||
|                                   NI_MAXHOST, | ||||
|                                   NULL, | ||||
|                                   0, | ||||
|                                   NI_NAMEREQD) == 0) | ||||
|                   { | ||||
|                      // Copy the dns name | ||||
|                      strcpy(pEntry->pNormalizedHostName, dnsHostName); | ||||
|                      // We resolved the address to a DNS name, use it as the normalized name. | ||||
|                      pEntry->buffLengthRequired = (int) strlen(pDnsHostName) + 1; | ||||
|                      pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                      if (pEntry->pNormalizedHostName) | ||||
|                      { | ||||
|                         // Copy the dns name | ||||
|                         strcpy(pEntry->pNormalizedHostName, pDnsHostName); | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                      } | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                      DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", errno); | ||||
|  | ||||
|                      // Not able to resolve the name in DNS, just use the host name as | ||||
|                      // the normalized name. | ||||
|                      pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; | ||||
|                      pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                      if (pEntry->pNormalizedHostName) | ||||
|                      { | ||||
|                         // Copy the host name | ||||
|                         strcpy(pEntry->pNormalizedHostName, pHostName); | ||||
|                      } | ||||
|                      else | ||||
|                      { | ||||
|                         DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                      } | ||||
|                   } | ||||
|  | ||||
|                   // Free the buffer allocated to hold the DNS name | ||||
|                   free(pDnsHostName); | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   DbgTrace(0, "-NormalizeHostName- getnameInfo failed, error %d\n", errno); | ||||
|  | ||||
|                   // Not able to resolve the name in DNS, just use the host name as | ||||
|                   // the normalized name. | ||||
|                   pEntry->buffLengthRequired = (int) strlen(pHostName) + 1; | ||||
|                   pEntry->pNormalizedHostName = (char*) malloc(pEntry->buffLengthRequired); | ||||
|                   if (pEntry->pNormalizedHostName) | ||||
|                   { | ||||
|                      // Copy the host name | ||||
|                      strcpy(pEntry->pNormalizedHostName, pHostName); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      DbgTrace(0, "-NormalizeHostName- Buffer allocation error\n", 0); | ||||
|                   } | ||||
|                   DbgTrace(0, "-NormalizeHostName- Buffer allocation failure\n", 0); | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|   | ||||
| @@ -45,6 +45,7 @@ | ||||
| #include <sys/types.h> | ||||
| #include <sys/ipc.h> | ||||
| #include <sys/sem.h> | ||||
| #include <openssl/crypto.h> | ||||
|  | ||||
| //===[ Type definitions ]================================================== | ||||
|  | ||||
|   | ||||
| @@ -31,8 +31,19 @@ | ||||
|  | ||||
| #define MAX_RPC_RETRIES 3 | ||||
|  | ||||
| //===[ External prototypes ]=============================================== | ||||
|  | ||||
| extern | ||||
| int | ||||
| SetupOSSLSupport(void); | ||||
|  | ||||
| extern | ||||
| void | ||||
| CleanupOSSLSupport(void); | ||||
|  | ||||
| //===[ Function prototypes ]=============================================== | ||||
|  | ||||
|  | ||||
| //===[ Global variables ]================================================== | ||||
|  | ||||
|  | ||||
| @@ -307,7 +318,9 @@ InternalRpc( | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
| #ifndef CASA_STATUS_INVALID_SERVER_CERTIFICATE | ||||
| #define CASA_STATUS_INVALID_SERVER_CERTIFICATE CASA_STATUS_UNSUCCESSFUL // temporary until casa_status.h is updated | ||||
| #endif | ||||
|  | ||||
|    CasaStatus  retStatus; | ||||
|    char        *pPartialUrl; | ||||
| @@ -361,7 +374,6 @@ InternalRpc( | ||||
|    } | ||||
|  | ||||
|    pUrl = (char*) malloc(partialUrlLen + strlen(pMethod) + 1); | ||||
|  | ||||
|    if (pUrl) | ||||
|    { | ||||
|       strcpy(pUrl, pPartialUrl); | ||||
| @@ -465,7 +477,7 @@ InternalRpc( | ||||
|                                   CASA_STATUS_INSUFFICIENT_RESOURCES); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-InternalRpc- End, retStatus = %d\n", retStatus); | ||||
|    DbgTrace(1, "-InternalRpc- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
| @@ -514,7 +526,7 @@ Rpc( | ||||
|    } while (CasaStatusCode(retStatus) == CASA_STATUS_AUTH_SERVER_UNAVAILABLE | ||||
|             && retries < MAX_RPC_RETRIES); | ||||
|  | ||||
|    DbgTrace(1, "-Rpc- End, retStatus = %d\n", retStatus); | ||||
|    DbgTrace(1, "-Rpc- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
| @@ -535,26 +547,34 @@ InitializeRpc(void) | ||||
| // L2 | ||||
| //=======================================================================-- | ||||
| { | ||||
|    CasaStatus  retStatus; | ||||
|    CasaStatus  retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                            CASA_FACILITY_AUTHTOKEN, | ||||
|                                            CASA_STATUS_UNSUCCESSFUL); | ||||
|  | ||||
|    DbgTrace(1, "-InitializeRpc- Start\n", 0); | ||||
|  | ||||
|    // Perform libcurl initializatoin | ||||
|    CURLcode curlStatus = curl_global_init(CURL_GLOBAL_SSL); | ||||
|    if (curlStatus != 0) | ||||
|    // Initialize OpenSSL support | ||||
|    if (SetupOSSLSupport() == 0) | ||||
|    { | ||||
|       DbgTrace(0, "-InitializeRpc- Error initializing libcurl, curlStatus = %08X\n", curlStatus); | ||||
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR, | ||||
|                                   CASA_FACILITY_AUTHTOKEN, | ||||
|                                   CASA_STATUS_UNSUCCESSFUL); | ||||
|       // Perform libcurl initializatoin | ||||
|       CURLcode curlStatus = curl_global_init(CURL_GLOBAL_SSL); | ||||
|       if (curlStatus != 0) | ||||
|       { | ||||
|          DbgTrace(0, "-InitializeRpc- Error initializing libcurl, curlStatus = %0X\n", curlStatus); | ||||
|          CleanupOSSLSupport(); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // Success | ||||
|          retStatus = CASA_STATUS_SUCCESS; | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Success | ||||
|       retStatus = CASA_STATUS_SUCCESS; | ||||
|       DbgTrace(0, "-InitializeRpc- OpenSSL support setup failure\n", 0); | ||||
|    } | ||||
|  | ||||
|    DbgTrace(1, "-InitializeRpc- End, retStatus = %08X\n", retStatus); | ||||
|    DbgTrace(1, "-InitializeRpc- End, retStatus = %0X\n", retStatus); | ||||
|  | ||||
|    return retStatus; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user