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:
Juan Carlos Luciani
2006-11-30 18:21:42 +00:00
parent a522f9d982
commit 1974ee9875
28 changed files with 1196 additions and 548 deletions

View File

@@ -57,6 +57,7 @@ CFILES = ../authmech.c \
../util.c \
../invalidcert.c \
rpc.c \
osslsupp.c \
platform.c
CSFILES_CSC :=

View 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);
}
//++=======================================================================
//++=======================================================================
//++=======================================================================

View File

@@ -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

View File

@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <openssl/crypto.h>
//===[ Type definitions ]==================================================

View File

@@ -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;
}