Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "asterisk.h"
00031
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 373079 $")
00033
00034 #ifdef HAVE_OPENSSL
00035 #include <openssl/ssl.h>
00036 #include <openssl/err.h>
00037 #endif
00038
00039 #include <dlfcn.h>
00040
00041 #include "asterisk/_private.h"
00042
00043 #include "asterisk/utils.h"
00044 #include "asterisk/lock.h"
00045
00046 #ifdef HAVE_OPENSSL
00047
00048 #define get_OpenSSL_function(func) do { real_##func = dlsym(RTLD_NEXT, __stringify(func)); } while(0)
00049
00050 static int startup_complete;
00051
00052 static ast_mutex_t *ssl_locks;
00053
00054 static int ssl_num_locks;
00055
00056 static unsigned long ssl_threadid(void)
00057 {
00058 return (unsigned long) pthread_self();
00059 }
00060
00061 static void ssl_lock(int mode, int n, const char *file, int line)
00062 {
00063 if (n < 0 || n >= ssl_num_locks) {
00064 ast_log(LOG_ERROR, "OpenSSL is full of LIES!!! - "
00065 "ssl_num_locks '%d' - n '%d'\n",
00066 ssl_num_locks, n);
00067 return;
00068 }
00069
00070 if (mode & CRYPTO_LOCK) {
00071 ast_mutex_lock(&ssl_locks[n]);
00072 } else {
00073 ast_mutex_unlock(&ssl_locks[n]);
00074 }
00075 }
00076
00077 int SSL_library_init(void)
00078 {
00079 #if defined(AST_DEVMODE)
00080 if (startup_complete) {
00081 ast_debug(1, "Called after startup... ignoring!\n");
00082 }
00083 #endif
00084 return 1;
00085 }
00086
00087 void SSL_load_error_strings(void)
00088 {
00089 #if defined(AST_DEVMODE)
00090 if (startup_complete) {
00091 ast_debug(1, "Called after startup... ignoring!\n");
00092 }
00093 #endif
00094 }
00095
00096 void ERR_load_SSL_strings(void)
00097 {
00098 #if defined(AST_DEVMODE)
00099 if (startup_complete) {
00100 ast_debug(1, "Called after startup... ignoring!\n");
00101 }
00102 #endif
00103 }
00104
00105 void ERR_load_crypto_strings(void)
00106 {
00107 #if defined(AST_DEVMODE)
00108 if (startup_complete) {
00109 ast_debug(1, "Called after startup... ignoring!\n");
00110 }
00111 #endif
00112 }
00113
00114 void ERR_load_BIO_strings(void)
00115 {
00116 #if defined(AST_DEVMODE)
00117 if (startup_complete) {
00118 ast_debug(1, "Called after startup... ignoring!\n");
00119 }
00120 #endif
00121 }
00122
00123 void CRYPTO_set_id_callback(unsigned long (*func)(void))
00124 {
00125 #if defined(AST_DEVMODE)
00126 if (startup_complete) {
00127 ast_debug(1, "Called after startup... ignoring!\n");
00128 }
00129 #endif
00130 }
00131
00132 void CRYPTO_set_locking_callback(void (*func)(int mode,int type, const char *file, int line))
00133 {
00134 #if defined(AST_DEVMODE)
00135 if (startup_complete) {
00136 ast_debug(1, "Called after startup... ignoring!\n");
00137 }
00138 #endif
00139 }
00140
00141 void ERR_free_strings(void)
00142 {
00143
00144 }
00145
00146 #endif
00147
00148
00149
00150
00151
00152 int ast_ssl_init(void)
00153 {
00154 #ifdef HAVE_OPENSSL
00155 unsigned int i;
00156 int (*real_SSL_library_init)(void);
00157 void (*real_CRYPTO_set_id_callback)(unsigned long (*)(void));
00158 void (*real_CRYPTO_set_locking_callback)(void (*)(int, int, const char *, int));
00159 void (*real_SSL_load_error_strings)(void);
00160 void (*real_ERR_load_SSL_strings)(void);
00161 void (*real_ERR_load_BIO_strings)(void);
00162 const char *errstr;
00163
00164
00165 dlerror();
00166 get_OpenSSL_function(SSL_library_init);
00167 if ((errstr = dlerror()) != NULL) {
00168 ast_debug(1, "unable to get real address of SSL_library_init: %s\n", errstr);
00169
00170
00171
00172 return -1;
00173 } else {
00174 real_SSL_library_init();
00175 }
00176
00177
00178
00179 dlerror();
00180 get_OpenSSL_function(CRYPTO_set_id_callback);
00181 if ((errstr = dlerror()) != NULL) {
00182 ast_debug(1, "unable to get real address of CRYPTO_set_id_callback: %s\n", errstr);
00183
00184
00185
00186 return -1;
00187 } else {
00188 real_CRYPTO_set_id_callback(ssl_threadid);
00189 }
00190
00191 dlerror();
00192 get_OpenSSL_function(CRYPTO_set_locking_callback);
00193 if ((errstr = dlerror()) != NULL) {
00194 ast_debug(1, "unable to get real address of CRYPTO_set_locking_callback: %s\n", errstr);
00195
00196
00197
00198 return -1;
00199 } else {
00200 ssl_num_locks = CRYPTO_num_locks();
00201 if (!(ssl_locks = ast_calloc(ssl_num_locks, sizeof(ssl_locks[0])))) {
00202 return -1;
00203 }
00204 for (i = 0; i < ssl_num_locks; i++) {
00205 ast_mutex_init(&ssl_locks[i]);
00206 }
00207 real_CRYPTO_set_locking_callback(ssl_lock);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216 get_OpenSSL_function(SSL_load_error_strings);
00217 real_SSL_load_error_strings();
00218
00219 get_OpenSSL_function(ERR_load_SSL_strings);
00220 real_ERR_load_SSL_strings();
00221
00222 get_OpenSSL_function(ERR_load_BIO_strings);
00223 real_ERR_load_BIO_strings();
00224
00225 startup_complete = 1;
00226
00227 #endif
00228 return 0;
00229 }
00230