Back to index

opendkim  2.6.6
Functions | Variables
opendkim-crypto.c File Reference
#include "build-config.h"
#include <sys/types.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>
#include "opendkim-crypto.h"
#include "opendkim.h"

Go to the source code of this file.

Functions

static void dkimf_crypto_lock_callback (int mode, int idx, const char *file, int line)
static unsigned long dkimf_crypto_get_id (void)
static void dkimf_crypto_free_id (void *ptr)
static struct
CRYPTO_dynlock_value * 
dkimf_crypto_dyn_create (const char *file, int line)
static void dkimf_crypto_dyn_destroy (struct CRYPTO_dynlock_value *lock, const char *file, int line)
static void dkimf_crypto_dyn_lock (int mode, struct CRYPTO_dynlock_value *lock, const char *file, int line)
int dkimf_crypto_init (void)
void dkimf_crypto_free (void)

Variables

static char opendkim_crypto_c_id [] = "@(#)$Id: opendkim-crypto.c,v 1.9.22.1 2010/10/27 21:43:09 cm-msk Exp $"
static _Bool crypto_init_done = FALSE
static pthread_mutex_t id_lock
static pthread_key_t id_key
static unsigned int nmutexes = 0
static unsigned long threadid = 0L
static pthread_mutex_t * mutexes = NULL

Function Documentation

static struct CRYPTO_dynlock_value* dkimf_crypto_dyn_create ( const char *  file,
int  line 
) [static, read]

Definition at line 247 of file opendkim-crypto.c.

{
       int err;
       pthread_mutex_t *new;

       new = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
       if (new == NULL)
              return NULL;

       err = pthread_mutex_init(new, NULL);
       if (err != 0)
       {
              free(new);
              return NULL;
       }

       return (void *) new;
}

Here is the caller graph for this function:

static void dkimf_crypto_dyn_destroy ( struct CRYPTO_dynlock_value *  lock,
const char *  file,
int  line 
) [static]

Definition at line 280 of file opendkim-crypto.c.

{
       assert(lock != NULL);

       pthread_mutex_destroy((pthread_mutex_t *) lock);

       free(lock);
}

Here is the caller graph for this function:

static void dkimf_crypto_dyn_lock ( int  mode,
struct CRYPTO_dynlock_value *  lock,
const char *  file,
int  line 
) [static]

Definition at line 305 of file opendkim-crypto.c.

{
       int status;

       assert(lock != NULL);

       if ((mode & CRYPTO_LOCK) != 0)
              status = pthread_mutex_lock((pthread_mutex_t *) lock);
       else
              status = pthread_mutex_unlock((pthread_mutex_t *) lock);

       assert(status == 0);
}

Here is the caller graph for this function:

void dkimf_crypto_free ( void  )

Definition at line 392 of file opendkim-crypto.c.

{
       if (crypto_init_done)
       {
              CRYPTO_cleanup_all_ex_data();
              CONF_modules_free();
              EVP_cleanup();
              ERR_free_strings();
              ERR_remove_state(0);

              if (nmutexes > 0)
              {
                     unsigned int c;

                     for (c = 0; c < nmutexes; c++)
                            pthread_mutex_destroy(&mutexes[c]);

                     free(mutexes);
                     mutexes = NULL;
                     nmutexes = 0;
              }

              crypto_init_done = FALSE;
       }
}

Here is the caller graph for this function:

static void dkimf_crypto_free_id ( void *  ptr) [static]

Definition at line 210 of file opendkim-crypto.c.

{
       /*
       **  Trick dkimf_crypto_get_id(); the thread-specific pointer has
       **  already been cleared at this point, but dkimf_crypto_get_id()
       **  may be called by ERR_remove_state() which will then allocate a
       **  new thread pointer if the thread-specific pointer is NULL.  This
       **  means a memory leak of thread IDs and, on Solaris, an infinite loop
       **  because the destructor (indirectly) re-sets the thread-specific
       **  pointer to something not NULL.  See pthread_key_create(3).
       */

       if (ptr != NULL)
       {
              assert(pthread_setspecific(id_key, ptr) == 0);

              ERR_remove_state(0);

              free(ptr);

              /* now we can actually clear it for real */
              assert(pthread_setspecific(id_key, NULL) == 0);
       }
}

Here is the caller graph for this function:

static unsigned long dkimf_crypto_get_id ( void  ) [static]

Definition at line 181 of file opendkim-crypto.c.

{
       unsigned long *id;

       id = pthread_getspecific(id_key);
       if (id == NULL)
       {
              id = (unsigned long *) malloc(sizeof *id);
              assert(pthread_mutex_lock(&id_lock) == 0);
              threadid++;
              *id = threadid;
              assert(pthread_mutex_unlock(&id_lock) == 0);
              assert(pthread_setspecific(id_key, id) == 0);
       }

       return *id;
}

Here is the caller graph for this function:

int dkimf_crypto_init ( void  )

Definition at line 333 of file opendkim-crypto.c.

{
       int c;
       int n;
       int status;

       n = CRYPTO_num_locks();
       mutexes = (pthread_mutex_t *) malloc(n * sizeof(pthread_mutex_t));
       if (mutexes == NULL)
              return errno;

       for (c = 0; c < n; c++)
       {
              status = pthread_mutex_init(&mutexes[c], NULL);
              if (status != 0)
                     return status;
       }

       status = pthread_mutex_init(&id_lock, NULL);
       if (status != 0)
              return status;

       nmutexes = n;

       status = pthread_key_create(&id_key, &dkimf_crypto_free_id);
       if (status != 0)
              return status;

       SSL_load_error_strings();
       SSL_library_init();
       ERR_load_crypto_strings();

       CRYPTO_set_id_callback(&dkimf_crypto_get_id);
       CRYPTO_set_locking_callback(&dkimf_crypto_lock_callback);
       CRYPTO_set_dynlock_create_callback(&dkimf_crypto_dyn_create);
       CRYPTO_set_dynlock_lock_callback(&dkimf_crypto_dyn_lock);
       CRYPTO_set_dynlock_destroy_callback(&dkimf_crypto_dyn_destroy);

#ifdef USE_OPENSSL_ENGINE
       if (!SSL_set_engine(NULL))
              return EINVAL;
#endif /* USE_OPENSSL_ENGINE */

       crypto_init_done = TRUE;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dkimf_crypto_lock_callback ( int  mode,
int  idx,
const char *  file,
int  line 
) [static]

Definition at line 157 of file opendkim-crypto.c.

{
       int status;

       if ((mode & CRYPTO_LOCK) != 0)
              status = pthread_mutex_lock(&mutexes[idx]);
       else
              status = pthread_mutex_unlock(&mutexes[idx]);

       assert(status == 0);
}

Here is the caller graph for this function:


Variable Documentation

_Bool crypto_init_done = FALSE [static]

Definition at line 44 of file opendkim-crypto.c.

pthread_key_t id_key [static]

Definition at line 138 of file opendkim-crypto.c.

pthread_mutex_t id_lock [static]

Definition at line 137 of file opendkim-crypto.c.

pthread_mutex_t* mutexes = NULL [static]

Definition at line 141 of file opendkim-crypto.c.

unsigned int nmutexes = 0 [static]

Definition at line 139 of file opendkim-crypto.c.

char opendkim_crypto_c_id[] = "@(#)$Id: opendkim-crypto.c,v 1.9.22.1 2010/10/27 21:43:09 cm-msk Exp $" [static]

Definition at line 11 of file opendkim-crypto.c.

unsigned long threadid = 0L [static]

Definition at line 140 of file opendkim-crypto.c.