tls_init.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * TLS module - OpenSSL initialization funtions
00005  *
00006  * Copyright (C) 2001-2003 FhG FOKUS
00007  * Copyright (C) 2004,2005 Free Software Foundation, Inc.
00008  * Copyright (C) 2005,2006 iptelorg GmbH
00009  *
00010  * This file is part of SIP-router, a free SIP server.
00011  *
00012  * SIP-router is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version
00016  *
00017  * SIP-router is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License 
00023  * along with this program; if not, write to the Free Software 
00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  */
00026 /*
00027  * History:
00028  * --------
00029  *  2007-01-26  openssl kerberos malloc bug detection/workaround (andrei)
00030  *  2007-02-23  openssl low memory bugs workaround (andrei)
00031  */
00032 
00051 #include <stdio.h>
00052 #include <sys/types.h>
00053 #include <netinet/in_systm.h>
00054 #include <netinet/in.h>
00055 #include <netinet/tcp.h>
00056 #include <netinet/ip.h>
00057 #include <unistd.h>
00058 #include <string.h>
00059 #include <openssl/ssl.h>
00060  
00061 #include "../../dprint.h"
00062 #include "../../mem/shm_mem.h"
00063 #include "../../tcp_init.h"
00064 #include "../../socket_info.h"
00065 #include "../../pt.h"
00066 #include "../../cfg/cfg.h"
00067 #include "../../cfg/cfg_ctx.h"
00068 #include "tls_verify.h"
00069 #include "tls_domain.h"
00070 #include "tls_util.h"
00071 #include "tls_mod.h"
00072 #include "tls_init.h"
00073 #include "tls_locking.h"
00074 #include "tls_ct_wrq.h"
00075 #include "tls_cfg.h"
00076 
00077 /* will be set to 1 when the TLS env is initialized to make destroy safe */
00078 static int tls_mod_initialized = 0;
00079 
00080 #if OPENSSL_VERSION_NUMBER < 0x00907000L
00081 #    warning ""
00082 #    warning "==============================================================="
00083 #    warning " Your version of OpenSSL is < 0.9.7."
00084 #    warning " Upgrade for better compatibility, features and security fixes!"
00085 #    warning "==============================================================="
00086 #    warning ""
00087 #endif
00088 
00089 /* replace openssl zlib compression with our version if necessary
00090  * (the openssl zlib compression uses the wrong malloc, see
00091  *  openssl #1468): 0.9.8-dev < version  <0.9.8e-beta1 */
00092 #if OPENSSL_VERSION_NUMBER >= 0x00908000L  /* 0.9.8-dev */ && \
00093                 OPENSSL_VERSION_NUMBER <  0x00908051L  /* 0.9.8.e-beta1 */
00094 #    ifndef OPENSSL_NO_COMP
00095 #        warning "openssl zlib compression bug workaround enabled"
00096 #    endif
00097 #    define TLS_FIX_ZLIB_COMPRESSION
00098 #    include "fixed_c_zlib.h"
00099 #endif
00100 
00101 #ifdef TLS_KSSL_WORKARROUND
00102 #if OPENSSL_VERSION_NUMBER < 0x00908050L
00103 #       warning "openssl lib compiled with kerberos support which introduces a bug\
00104  (wrong malloc/free used in kssl.c) -- attempting workaround"
00105 #       warning "NOTE: if you don't link libssl staticaly don't try running the \
00106 compiled code on a system with a differently compiled openssl (it's safer \
00107 to compile on the  _target_ system)"
00108 #endif /* OPENSSL_VERSION_NUMBER */
00109 #endif /* TLS_KSSL_WORKARROUND */
00110 
00111 /* openssl < 1. 0 */
00112 #if OPENSSL_VERSION_NUMBER < 0x01000000L
00113 #       warning "openssl < 1.0: no TLS extensions or server name support"
00114 #endif /* OPENSSL_VERION < 1.0 */
00115 
00116 
00117 
00118 #ifndef OPENSSL_NO_COMP
00119 #define TLS_COMP_SUPPORT
00120 #else
00121 #undef TLS_COMP_SUPPORT
00122 #endif
00123 
00124 #ifndef OPENSSL_NO_KRB5
00125 #define TLS_KERBEROS_SUPPORT
00126 #else
00127 #undef TLS_KERBEROS_SUPPORT
00128 #endif
00129 
00130 
00131 #ifdef TLS_KSSL_WORKARROUND
00132 int openssl_kssl_malloc_bug=0; /* is openssl bug #1467 present ? */
00133 #endif
00134 
00135 const SSL_METHOD* ssl_methods[TLS_USE_SSLv23 + 1];
00136 
00137 #ifdef NO_TLS_MALLOC_DBG
00138 #undef TLS_MALLOC_DBG /* extra malloc debug info from openssl */
00139 #endif /* NO_TLS_MALLOC_DBG */
00140 
00141 /*
00142  * Wrappers around SER shared memory functions
00143  * (which can be macros)
00144  */
00145 #ifdef TLS_MALLOC_DBG
00146 #warning "tls module compiled with malloc debugging info (extra overhead)"
00147 #include <execinfo.h>
00148 
00149 /*
00150 #define RAND_NULL_MALLOC (1024)
00151 #define NULL_GRACE_PERIOD 10U
00152 */
00153 
00154 inline static char* buf_append(char* buf, char* end, char* str, int str_len)
00155 {
00156         if ( (buf+str_len)<end){
00157                 memcpy(buf, str, str_len);
00158                 return buf+str_len;
00159         }
00160         return 0;
00161 }
00162 
00163 
00164 inline static int backtrace2str(char* buf, int size)
00165 {
00166         void* bt[32];
00167         int bt_size, i;
00168         char** bt_strs;
00169         char* p;
00170         char* end;
00171         char* next;
00172         char* s;
00173         char* e;
00174         
00175         p=buf; end=buf+size;
00176         bt_size=backtrace(bt, sizeof(bt)/sizeof(bt[0]));
00177         bt_strs=backtrace_symbols(bt, bt_size);
00178         if (bt_strs){
00179                 p=buf; end=buf+size;
00180                 /*if (bt_size>16) bt_size=16;*/ /* go up only 12 entries */
00181                 for (i=3; i< bt_size; i++){
00182                         /* try to isolate only the function name*/
00183                         s=strchr(bt_strs[i], '(');
00184                         if (s && ((e=strchr(s, ')'))!=0)){
00185                                 s++;
00186                         }else if ((s=strchr(bt_strs[i], '['))!=0){
00187                                 e=s+strlen(s);
00188                         }else{
00189                                 s=bt_strs[i]; e=s+strlen(s); /* add thw whole string */
00190                         }
00191                         next=buf_append(p, end, s, (int)(long)(e-s));
00192                         if (next==0) break;
00193                         else p=next;
00194                         if (p<end){
00195                                 *p=':'; /* separator */
00196                                 p++;
00197                         }else break;
00198                 }
00199                 if (p==buf){
00200                         *p=0;
00201                         p++;
00202                 }else
00203                         *(p-1)=0;
00204                 free(bt_strs);
00205         }
00206         return (int)(long)(p-buf);
00207 }
00208 
00209 static void* ser_malloc(size_t size, const char* file, int line)
00210 {
00211         void  *p;
00212         char bt_buf[1024];
00213         int s;
00214 #ifdef RAND_NULL_MALLOC
00215         static ticks_t st=0;
00216 
00217         /* start random null returns only after 
00218          * NULL_GRACE_PERIOD from first call */
00219         if (st==0) st=get_ticks();
00220         if (((get_ticks()-st)<NULL_GRACE_PERIOD) || (random()%RAND_NULL_MALLOC)){
00221 #endif
00222                 s=backtrace2str(bt_buf, sizeof(bt_buf));
00223                 /* ugly hack: keep the bt inside the alloc'ed fragment */
00224                 p=_shm_malloc(size+s, file, "via ser_malloc", line);
00225                 if (p==0){
00226                         LOG(L_CRIT, "tsl: ser_malloc(%d)[%s:%d]==null, bt: %s\n", 
00227                                                 size, file, line, bt_buf);
00228                 }else{
00229                         memcpy(p+size, bt_buf, s);
00230                         ((struct qm_frag*)((char*)p-sizeof(struct qm_frag)))->func=
00231                                 p+size;
00232                 }
00233 #ifdef RAND_NULL_MALLOC
00234         }else{
00235                 p=0;
00236                 backtrace2str(bt_buf, sizeof(bt_buf));
00237                 LOG(L_CRIT, "tsl: random ser_malloc(%d)[%s:%d]"
00238                                 " returning null - bt: %s\n",
00239                                 size, file, line, bt_buf);
00240         }
00241 #endif
00242         return p;
00243 }
00244 
00245 
00246 static void* ser_realloc(void *ptr, size_t size, const char* file, int line)
00247 {
00248         void  *p;
00249         char bt_buf[1024];
00250         int s;
00251 #ifdef RAND_NULL_MALLOC
00252         static ticks_t st=0;
00253 
00254         /* start random null returns only after 
00255          * NULL_GRACE_PERIOD from first call */
00256         if (st==0) st=get_ticks();
00257         if (((get_ticks()-st)<NULL_GRACE_PERIOD) || (random()%RAND_NULL_MALLOC)){
00258 #endif
00259                 s=backtrace2str(bt_buf, sizeof(bt_buf));
00260                 p=_shm_realloc(ptr, size+s, file, "via ser_realloc", line);
00261                 if (p==0){
00262                         LOG(L_CRIT, "tsl: ser_realloc(%p, %d)[%s:%d]==null, bt: %s\n",
00263                                         ptr, size, file, line, bt_buf);
00264                 }else{
00265                         memcpy(p+size, bt_buf, s);
00266                         ((struct qm_frag*)((char*)p-sizeof(struct qm_frag)))->func=
00267                                 p+size;
00268                 }
00269 #ifdef RAND_NULL_MALLOC
00270         }else{
00271                 p=0;
00272                 backtrace2str(bt_buf, sizeof(bt_buf));
00273                 LOG(L_CRIT, "tsl: random ser_realloc(%p, %d)[%s:%d]"
00274                                         " returning null - bt: %s\n", ptr, size, file, line,
00275                                         bt_buf);
00276         }
00277 #endif
00278         return p;
00279 }
00280 
00281 #else /*TLS_MALLOC_DBG */
00282 
00283 static void* ser_malloc(size_t size)
00284 {
00285         return shm_malloc(size);
00286 }
00287 
00288 
00289 static void* ser_realloc(void *ptr, size_t size)
00290 {
00291                 return shm_realloc(ptr, size);
00292 }
00293 
00294 #endif
00295 
00296 static void ser_free(void *ptr)
00297 {
00298         shm_free(ptr);
00299 }
00300 
00301 
00302 /*
00303  * Initialize TLS socket
00304  */
00305 int tls_h_init_si(struct socket_info *si)
00306 {
00307         int ret;
00308              /*
00309               * reuse tcp initialization 
00310               */
00311         ret = tcp_init(si);
00312         if (ret != 0) {
00313                 ERR("Error while initializing TCP part of TLS socket %.*s:%d\n",
00314                     si->address_str.len, si->address_str.s, si->port_no);
00315                 goto error;
00316         }
00317         
00318         si->proto = PROTO_TLS;
00319         return 0;
00320         
00321  error:
00322         if (si->socket != -1) {
00323                 close(si->socket);
00324                 si->socket = -1;
00325         }
00326         return ret;
00327 }
00328 
00329 
00330 
00331 /*
00332  * initialize ssl methods 
00333  */
00334 static void init_ssl_methods(void)
00335 {
00336 #ifndef OPENSSL_NO_SSL2
00337         ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method();
00338         ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method();
00339         ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method();
00340 #endif
00341 
00342         ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method();
00343         ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method();
00344         ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method();
00345         
00346         ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method();
00347         ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();
00348         ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method();
00349         
00350         ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
00351         ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
00352         ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
00353 }
00354 
00355 
00356 /*
00357  * Fix openssl compression bugs if necessary
00358  */
00359 static int init_tls_compression(void)
00360 {
00361 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
00362         int n, r;
00363         STACK_OF(SSL_COMP)* comp_methods;
00364         SSL_COMP* zlib_comp;
00365         long ssl_version;
00366         
00367         /* disabling compression */
00368 #       ifndef SSL_COMP_ZLIB_IDX
00369 #               define SSL_COMP_ZLIB_IDX 1 /* openssl/ssl/ssl_ciph.c:84 */
00370 #       endif 
00371         comp_methods = SSL_COMP_get_compression_methods();
00372         if (comp_methods == 0) {
00373                 LOG(L_INFO, "tls: init_tls: compression support disabled in the"
00374                                         " openssl lib\n");
00375                 goto end; /* nothing to do, exit */
00376         } else if (cfg_get(tls, tls_cfg, disable_compression)){
00377                 LOG(L_INFO, "tls: init_tls: disabling compression...\n");
00378                 sk_SSL_COMP_zero(comp_methods);
00379         }else{
00380                 ssl_version=SSLeay();
00381                 /* replace openssl zlib compression with our version if necessary
00382                  * (the openssl zlib compression uses the wrong malloc, see
00383                  *  openssl #1468): 0.9.8-dev < version  <0.9.8e-beta1 */
00384                 if ((ssl_version >= 0x00908000L) && (ssl_version < 0x00908051L)){
00385                         /* the above SSL_COMP_get_compression_methods() call has the side
00386                          * effect of initializing the compression stack (if not already
00387                          * initialized) => after it zlib is initialized and in the stack */
00388                         /* find zlib_comp (cannot use ssl3_comp_find, not exported) */
00389                         n = sk_SSL_COMP_num(comp_methods);
00390                         zlib_comp = 0;
00391                         for (r = 0; r < n; r++) {
00392                                 zlib_comp = sk_SSL_COMP_value(comp_methods, r);
00393                                 DBG("tls: init_tls: found compression method %p id %d\n",
00394                                                 zlib_comp, zlib_comp->id);
00395                                 if (zlib_comp->id == SSL_COMP_ZLIB_IDX) {
00396                                         DBG("tls: init_tls: found zlib compression (%d)\n", 
00397                                                         SSL_COMP_ZLIB_IDX);
00398                                         break /* found */;
00399                                 } else {
00400                                         zlib_comp = 0;
00401                                 }
00402                         }
00403                         if (zlib_comp == 0) {
00404                                 LOG(L_INFO, "tls: init_tls: no openssl zlib compression "
00405                                                         "found\n");
00406                         }else{
00407                                 LOG(L_WARN, "tls: init_tls: detected openssl lib with "
00408                                                         "known zlib compression bug: \"%s\" (0x%08lx)\n",
00409                                                         SSLeay_version(SSLEAY_VERSION), ssl_version);
00410 #       ifdef TLS_FIX_ZLIB_COMPRESSION
00411                                 LOG(L_WARN, "tls: init_tls: enabling openssl zlib compression "
00412                                                         "bug workaround (replacing zlib COMP method with "
00413                                                         "our own version)\n");
00414                                 /* hack: make sure that the CRYPTO_EX_INDEX_COMP class is empty
00415                                  * and it does not contain any free_ex_data from the 
00416                                  * built-in zlib. This can happen if the current openssl
00417                                  * zlib malloc fix patch is used (CRYPTO_get_ex_new_index() in
00418                                  * COMP_zlib()). Unfortunately the only way
00419                                  * to do this it to cleanup all the ex_data stuff.
00420                                  * It should be safe if this is executed before SSL_init()
00421                                  * (only the COMP class is initialized before).
00422                                  */
00423                                 CRYPTO_cleanup_all_ex_data();
00424                                 
00425                                 if (fixed_c_zlib_init() != 0) {
00426                                         LOG(L_CRIT, "tls: init_tls: BUG: failed to initialize zlib"
00427                                                         " compression fix, disabling compression...\n");
00428                                         sk_SSL_COMP_zero(comp_methods); /* delete compression */
00429                                         goto end;
00430                                 }
00431                                 /* "fix" it */
00432                                 zlib_comp->method = &zlib_method;
00433 #       else
00434                                 LOG(L_WARN, "tls: init_tls: disabling openssl zlib "
00435                                                         "compression \n");
00436                                 zlib_comp=sk_SSL_COMP_delete(comp_methods, r);
00437                                 if (zlib_comp)
00438                                         OPENSSL_free(zlib_comp);
00439 #       endif
00440                         }
00441                 }
00442         }
00443 end:
00444 #endif /* OPENSSL_VERSION_NUMBER >= 0.9.8 */
00445         return 0;
00446 }
00447 
00448 
00452 int tls_pre_init(void)
00453 {
00454              /*
00455               * this has to be called before any function calling CRYPTO_malloc,
00456               * CRYPTO_malloc will set allow_customize in openssl to 0
00457               */
00458 #ifdef TLS_MALLOC_DBG
00459         if (!CRYPTO_set_mem_ex_functions(ser_malloc, ser_realloc, ser_free)) {
00460 #else
00461         if (!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) {
00462 #endif
00463                 ERR("Unable to set the memory allocation functions\n");
00464                 return -1;
00465         }
00466 
00467         if (tls_init_locks()<0)
00468                 return -1;
00469 
00470         init_tls_compression();
00471 
00472         return 0;
00473 }
00474 
00475 /*
00476  * First step of TLS initialization
00477  */
00478 int init_tls_h(void)
00479 {
00480         /*struct socket_info* si;*/
00481         long ssl_version;
00482         int lib_kerberos;
00483         int lib_zlib;
00484         int kerberos_support;
00485         int comp_support;
00486         const char* lib_cflags;
00487         int low_mem_threshold1;
00488         int low_mem_threshold2;
00489         str tls_grp;
00490         str s;
00491         cfg_ctx_t* cfg_ctx;
00492 
00493 #if OPENSSL_VERSION_NUMBER < 0x00907000L
00494         WARN("You are using an old version of OpenSSL (< 0.9.7). Upgrade!\n");
00495 #endif
00496         ssl_version=SSLeay();
00497         /* check if version have the same major minor and fix level
00498          * (e.g. 0.9.8a & 0.9.8c are ok, but 0.9.8 and 0.9.9x are not) */
00499         if ((ssl_version>>8)!=(OPENSSL_VERSION_NUMBER>>8)){
00500                 LOG(L_CRIT, "ERROR: tls: init_tls_h: installed openssl library "
00501                                 "version is too different from the library the ser tls module "
00502                                 "was compiled with: installed \"%s\" (0x%08lx), compiled "
00503                                 "\"%s\" (0x%08lx).\n"
00504                                 " Please make sure a compatible version is used"
00505                                 " (tls_force_run in ser.cfg will override this check)\n",
00506                                 SSLeay_version(SSLEAY_VERSION), ssl_version,
00507                                 OPENSSL_VERSION_TEXT, (long)OPENSSL_VERSION_NUMBER);
00508                 if (cfg_get(tls, tls_cfg, force_run))
00509                         LOG(L_WARN, "tls: init_tls_h: tls_force_run turned on, ignoring "
00510                                                 " openssl version mismatch\n");
00511                 else
00512                         return -1; /* safer to exit */
00513         }
00514 #ifdef TLS_KERBEROS_SUPPORT
00515         kerberos_support=1;
00516 #else
00517         kerberos_support=0;
00518 #endif
00519 #ifdef TLS_COMP_SUPPORT
00520         comp_support=1;
00521 #else
00522         comp_support=0;
00523 #endif
00524         /* attempt to guess if the library was compiled with kerberos or
00525          * compression support from the cflags */
00526         lib_cflags=SSLeay_version(SSLEAY_CFLAGS);
00527         lib_kerberos=0;
00528         lib_zlib=0;
00529         if ((lib_cflags==0) || strstr(lib_cflags, "not available")){ 
00530                 lib_kerberos=-1;
00531                 lib_zlib=-1;
00532         }else{
00533                 if (strstr(lib_cflags, "-DZLIB"))
00534                         lib_zlib=1;
00535                 if (strstr(lib_cflags, "-DKRB5_"))
00536                         lib_kerberos=1;
00537         }
00538         LOG(L_INFO, "tls: _init_tls_h:  compiled  with  openssl  version " 
00539                                 "\"%s\" (0x%08lx), kerberos support: %s, compression: %s\n",
00540                                 OPENSSL_VERSION_TEXT, (long)OPENSSL_VERSION_NUMBER,
00541                                 kerberos_support?"on":"off", comp_support?"on":"off");
00542         LOG(L_INFO, "tls: init_tls_h: installed openssl library version "
00543                                 "\"%s\" (0x%08lx), kerberos support: %s, "
00544                                 " zlib compression: %s"
00545                                 "\n %s\n",
00546                                 SSLeay_version(SSLEAY_VERSION), ssl_version,
00547                                 (lib_kerberos==1)?"on":(lib_kerberos==0)?"off":"unknown",
00548                                 (lib_zlib==1)?"on":(lib_zlib==0)?"off":"unknown",
00549                                 SSLeay_version(SSLEAY_CFLAGS));
00550         if (lib_kerberos!=kerberos_support){
00551                 if (lib_kerberos!=-1){
00552                         LOG(L_CRIT, "ERROR: tls: init_tls_h: openssl compile options"
00553                                                 " mismatch: library has kerberos support"
00554                                                 " %s and ser tls %s (unstable configuration)\n"
00555                                                 " (tls_force_run in ser.cfg will override this"
00556                                                 " check)\n",
00557                                                 lib_kerberos?"enabled":"disabled",
00558                                                 kerberos_support?"enabled":"disabled"
00559                                 );
00560                         if (cfg_get(tls, tls_cfg, force_run))
00561                                 LOG(L_WARN, "tls: init_tls_h: tls_force_run turned on, "
00562                                                 "ignoring kerberos support mismatch\n");
00563                         else
00564                                 return -1; /* exit, is safer */
00565                 }else{
00566                         LOG(L_WARN, "WARNING: tls: init_tls_h: openssl  compile options"
00567                                                 " missing -- cannot detect if kerberos support is"
00568                                                 " enabled. Possible unstable configuration\n");
00569                 }
00570         }
00571 
00572         #ifdef TLS_KSSL_WORKARROUND
00573         /* if openssl compiled with kerberos support, and openssl < 0.9.8e-dev
00574          * or openssl between 0.9.9-dev and 0.9.9-beta1 apply workaround for
00575          * openssl bug #1467 */
00576         if (ssl_version < 0x00908050L || 
00577                         (ssl_version >= 0x00909000L && ssl_version < 0x00909001L)){
00578                 openssl_kssl_malloc_bug=1;
00579                 LOG(L_WARN, "tls: init_tls_h: openssl kerberos malloc bug detected, "
00580                         " kerberos support will be disabled...\n");
00581         }
00582         #endif
00583         /* set free memory threshold for openssl bug #1491 workaround */
00584         low_mem_threshold1 = cfg_get(tls, tls_cfg, low_mem_threshold1);
00585         low_mem_threshold2 = cfg_get(tls, tls_cfg, low_mem_threshold2);
00586         if (low_mem_threshold1<0){
00587                 /* default */
00588                 low_mem_threshold1=512*1024*get_max_procs();
00589         }else
00590                 low_mem_threshold1*=1024; /* KB */
00591         if (low_mem_threshold2<0){
00592                 /* default */
00593                 low_mem_threshold2=256*1024*get_max_procs();
00594         }else
00595                 low_mem_threshold2*=1024; /* KB */
00596         if ((low_mem_threshold1==0) || (low_mem_threshold2==0))
00597                 LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
00598                                         " workarround disabled\n");
00599         else
00600                 LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
00601                                 " workaround enabled (on low memory tls operations will fail"
00602                                 " preemptively) with free memory thresholds %d and %d bytes\n",
00603                                 low_mem_threshold1, low_mem_threshold2);
00604         
00605         if (shm_available()==(unsigned long)(-1)){
00606                 LOG(L_WARN, "tls: ser compiled without MALLOC_STATS support:"
00607                                 " the workaround for low mem. openssl bugs will _not_ "
00608                                 "work\n");
00609                 low_mem_threshold1=0;
00610                 low_mem_threshold2=0;
00611         }
00612         if ((low_mem_threshold1 != cfg_get(tls, tls_cfg, low_mem_threshold1)) ||
00613             (low_mem_threshold2 != cfg_get(tls, tls_cfg, low_mem_threshold2))) {
00614                 /* ugly hack to set the initial values for the mem tresholds */
00615                 if (cfg_register_ctx(&cfg_ctx, 0)) {
00616                         ERR("failed to register cfg context\n");
00617                         return -1;
00618                 }
00619                 tls_grp.s = "tls";
00620                 tls_grp.len = strlen(tls_grp.s);
00621                 s.s = "low_mem_threshold1";
00622                 s.len = strlen(s.s);
00623                 if (low_mem_threshold1 != cfg_get(tls, tls_cfg, low_mem_threshold1) &&
00624                                 cfg_set_now_int(cfg_ctx, &tls_grp, NULL /* group id */, &s, low_mem_threshold1)) {
00625                         ERR("failed to set tls.low_mem_threshold1 to %d\n",
00626                                         low_mem_threshold1);
00627                         return -1;
00628                 }
00629                 s.s = "low_mem_threshold2";
00630                 s.len = strlen(s.s);
00631                 if (low_mem_threshold2 != cfg_get(tls, tls_cfg, low_mem_threshold2) &&
00632                                 cfg_set_now_int(cfg_ctx, &tls_grp, NULL /* group id */, &s, low_mem_threshold2)) {
00633                         ERR("failed to set tls.low_mem_threshold1 to %d\n",
00634                                         low_mem_threshold2);
00635                         return -1;
00636                 }
00637         }
00638         
00639         SSL_library_init();
00640         SSL_load_error_strings();
00641         init_ssl_methods();
00642         tls_mod_initialized = 1;
00643         return 0;
00644 }
00645 
00646 
00647 /*
00648  * Make sure that all server domains in the configuration have corresponding
00649  * listening socket in SER
00650  */
00651 int tls_check_sockets(tls_domains_cfg_t* cfg)
00652 {
00653         tls_domain_t* d;
00654 
00655         if (!cfg) return 0;
00656 
00657         d = cfg->srv_list;
00658         while(d) {
00659                 if (d->ip.len && !find_si(&d->ip, d->port, PROTO_TLS)) {
00660                         ERR("%s: No listening socket found\n", tls_domain_str(d));
00661                         return -1;
00662                 }
00663                 d = d->next;
00664         }
00665         return 0;
00666 }
00667 
00668 
00669 /*
00670  * TLS cleanup when SER exits
00671  */
00672 void destroy_tls_h(void)
00673 {
00674         DBG("tls module final tls destroy\n");
00675         if(tls_mod_initialized > 0)
00676                 ERR_free_strings();
00677         /* TODO: free all the ctx'es */
00678         tls_destroy_cfg();
00679         tls_destroy_locks();
00680         tls_ct_wq_destroy();
00681 }