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