123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * TLS module
- *
- * Copyright (C) 2007 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- /*!
- * \file
- * \brief Kamailio TLS support :: Locking
- * \ingroup tls
- * Module: \ref tls
- */
- #include <stdlib.h> /* abort() */
- #include <openssl/crypto.h>
- #include "../../dprint.h"
- #include "../../locking.h"
- static int n_static_locks=0;
- static gen_lock_set_t* static_locks=0;
- /* "dynamic" locks */
- struct CRYPTO_dynlock_value{
- gen_lock_t lock;
- };
- static struct CRYPTO_dynlock_value* dyn_create_f(const char* file, int line)
- {
- struct CRYPTO_dynlock_value* l;
-
- l=shm_malloc(sizeof(struct CRYPTO_dynlock_value));
- if (l==0){
- LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback out of shm."
- " memory (called from %s:%d)\n", file, line);
- goto error;
- }
- if (lock_init(&l->lock)==0){
- LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback: lock "
- "initialization failed (called from %s:%d)\n", file, line);
- shm_free(l);
- goto error;
- }
- return l;
- error:
- return 0;
- }
- static void dyn_lock_f(int mode, struct CRYPTO_dynlock_value* l,
- const char* file, int line)
- {
- if (l==0){
- LOG(L_CRIT, "BUG: tls: dyn_lock_f locking callback: null lock"
- " (called from %s:%d)\n", file, line);
- /* try to continue */
- return;
- }
- if (mode & CRYPTO_LOCK){
- lock_get(&l->lock);
- }else{
- lock_release(&l->lock);
- }
- }
- static void dyn_destroy_f(struct CRYPTO_dynlock_value *l,
- const char* file, int line)
- {
- if (l==0){
- LOG(L_CRIT, "BUG: tls: dyn_destroy_f locking callback: null lock"
- " (called from %s:%d)\n", file, line);
- return;
- }
- lock_destroy(&l->lock);
- shm_free(l);
- }
- /* normal locking callback */
- static void locking_f(int mode, int n, const char* file, int line)
- {
- if (n<0 || n>=n_static_locks){
- LOG(L_CRIT, "BUG: tls: locking_f (callback): invalid lock number: "
- " %d (range 0 - %d), called from %s:%d\n",
- n, n_static_locks, file, line);
- abort(); /* quick crash :-) */
- }
- if (mode & CRYPTO_LOCK){
- lock_set_get(static_locks, n);
- }else{
- lock_set_release(static_locks, n);
- }
-
- }
- void tls_destroy_locks()
- {
- if (static_locks){
- lock_set_destroy(static_locks);
- lock_set_dealloc(static_locks);
- static_locks=0;
- n_static_locks=0;
- }
- }
- unsigned long sr_ssl_id_f()
- {
- return my_pid();
- }
- /* returns -1 on error, 0 on success */
- int tls_init_locks()
- {
- /* init "static" tls locks */
- n_static_locks=CRYPTO_num_locks();
- if (n_static_locks<0){
- LOG(L_CRIT, "BUG: tls: tls_init_locking: bad CRYPTO_num_locks %d\n",
- n_static_locks);
- n_static_locks=0;
- }
- if (n_static_locks){
- static_locks=lock_set_alloc(n_static_locks);
- if (static_locks==0){
- LOG(L_CRIT, "ERROR: tls_init_locking: could not allocate lockset"
- " with %d locks\n", n_static_locks);
- goto error;
- }
- if (lock_set_init(static_locks)==0){
- LOG(L_CRIT, "ERROR: tls_init_locking: lock_set_init failed "
- "(%d locks)\n", n_static_locks);
- lock_set_dealloc(static_locks);
- static_locks=0;
- n_static_locks=0;
- goto error;
- }
- CRYPTO_set_locking_callback(locking_f);
- }
- /* set "dynamic" locks callbacks */
- CRYPTO_set_dynlock_create_callback(dyn_create_f);
- CRYPTO_set_dynlock_lock_callback(dyn_lock_f);
- CRYPTO_set_dynlock_destroy_callback(dyn_destroy_f);
-
- /* starting with v1.0.0 openssl does not use anymore getpid(), but address
- * of errno which can point to same virtual address in a multi-process
- * application
- * - for refrence http://www.openssl.org/docs/crypto/threads.html
- */
- CRYPTO_set_id_callback(sr_ssl_id_f);
- /* atomic add -- since for now we don't have atomic_add
- * (only atomic_inc), fallback to the default use-locks mode
- * CRYPTO_set_add_lock_callback(atomic_add_f);
- */
-
-
- return 0;
- error:
- tls_destroy_locks();
- return -1;
- }
|