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
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
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
00090
00091
00092 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && \
00093 OPENSSL_VERSION_NUMBER < 0x00908051L
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
00109 #endif
00110
00111
00112 #if OPENSSL_VERSION_NUMBER < 0x01000000L
00113 # warning "openssl < 1.0: no TLS extensions or server name support"
00114 #endif
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;
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
00139 #endif
00140
00141
00142
00143
00144
00145 #ifdef TLS_MALLOC_DBG
00146 #warning "tls module compiled with malloc debugging info (extra overhead)"
00147 #include <execinfo.h>
00148
00149
00150
00151
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
00181 for (i=3; i< bt_size; i++){
00182
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);
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=':';
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
00218
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
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
00255
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
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
00304
00305 int tls_h_init_si(struct socket_info *si)
00306 {
00307 int ret;
00308
00309
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
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
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
00368 # ifndef SSL_COMP_ZLIB_IDX
00369 # define SSL_COMP_ZLIB_IDX 1
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;
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
00382
00383
00384 if ((ssl_version >= 0x00908000L) && (ssl_version < 0x00908051L)){
00385
00386
00387
00388
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 ;
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
00415
00416
00417
00418
00419
00420
00421
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);
00429 goto end;
00430 }
00431
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
00445 return 0;
00446 }
00447
00448
00452 int tls_pre_init(void)
00453 {
00454
00455
00456
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
00477
00478 int init_tls_h(void)
00479 {
00480
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
00498
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;
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
00525
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;
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
00574
00575
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
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
00588 low_mem_threshold1=512*1024*get_max_procs();
00589 }else
00590 low_mem_threshold1*=1024;
00591 if (low_mem_threshold2<0){
00592
00593 low_mem_threshold2=256*1024*get_max_procs();
00594 }else
00595 low_mem_threshold2*=1024;
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
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 , &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 , &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
00649
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
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
00678 tls_destroy_cfg();
00679 tls_destroy_locks();
00680 tls_ct_wq_destroy();
00681 }