src/modules/tls/tls_init.c
a444035d
 /*
7771e9cd
  * TLS module
dd0647fb
  *
  * Copyright (C) 2005,2006 iptelorg GmbH
  *
7771e9cd
  * 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.
433e6896
  */
dd0647fb
 
0cfc2f26
 /*! \defgroup tls Kamailio TLS support
9accd256
  *
  * This modules implements SIP over TCP with TLS encryption.
  * Make sure you read the README file that describes configuration
  * of TLS for single servers and servers hosting multiple domains,
  * and thus using multiple SSL/TLS certificates.
  *
  *
  */
 /*!
  * \file
0cfc2f26
  * \brief Kamailio TLS support :: Initialization
9accd256
  * \ingroup tls
  * Module: \ref tls
  */
 
 
 
dd0647fb
 #include <stdio.h>
dd750880
 #include <sys/types.h>
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
dd0647fb
 #include <netinet/tcp.h>
 #include <netinet/ip.h>
 #include <unistd.h>
fc660aae
 #include <string.h>
dd0647fb
 #include <openssl/ssl.h>
a444035d
 
cf83221d
 #include "../../core/dprint.h"
 #include "../../core/mem/shm_mem.h"
 #include "../../core/tcp_init.h"
 #include "../../core/socket_info.h"
 #include "../../core/pt.h"
 #include "../../core/cfg/cfg.h"
 #include "../../core/cfg/cfg_ctx.h"
dd0647fb
 #include "tls_verify.h"
 #include "tls_domain.h"
 #include "tls_util.h"
 #include "tls_mod.h"
 #include "tls_init.h"
36cb8fa7
 #include "tls_locking.h"
93c495f3
 #include "tls_ct_wrq.h"
e40e993e
 #include "tls_cfg.h"
dd0647fb
 
517d38ed
 /* will be set to 1 when the TLS env is initialized to make destroy safe */
f7124341
 static int tls_mod_preinitialized = 0;
517d38ed
 static int tls_mod_initialized = 0;
 
dd0647fb
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
 #    warning ""
 #    warning "==============================================================="
 #    warning " Your version of OpenSSL is < 0.9.7."
 #    warning " Upgrade for better compatibility, features and security fixes!"
 #    warning "==============================================================="
 #    warning ""
 #endif
 
5decf8ec
 /* replace openssl zlib compression with our version if necessary
  * (the openssl zlib compression uses the wrong malloc, see
  *  openssl #1468): 0.9.8-dev < version  <0.9.8e-beta1 */
 #if OPENSSL_VERSION_NUMBER >= 0x00908000L  /* 0.9.8-dev */ && \
a8b30d34
 							  OPENSSL_VERSION_NUMBER <  0x00908051L  /* 0.9.8.e-beta1 */
dd0647fb
 #    ifndef OPENSSL_NO_COMP
433e6896
 #        warning "openssl zlib compression bug workaround enabled"
dd0647fb
 #    endif
fc660aae
 #    define TLS_FIX_ZLIB_COMPRESSION
 #    include "fixed_c_zlib.h"
dd0647fb
 #endif
 
fc660aae
 #ifdef TLS_KSSL_WORKARROUND
560a42b6
 #if OPENSSL_VERSION_NUMBER < 0x00908050L
c20ee398
 #	warning "openssl lib compiled with kerberos support which introduces a bug\
a8b30d34
 	(wrong malloc/free used in kssl.c) -- attempting workaround"
c20ee398
 #	warning "NOTE: if you don't link libssl staticaly don't try running the \
a8b30d34
 	compiled code on a system with a differently compiled openssl (it's safer \
 			to compile on the  _target_ system)"
560a42b6
 #endif /* OPENSSL_VERSION_NUMBER */
 #endif /* TLS_KSSL_WORKARROUND */
fc660aae
 
0705191b
 /* openssl < 1. 0 */
 #if OPENSSL_VERSION_NUMBER < 0x01000000L
 #	warning "openssl < 1.0: no TLS extensions or server name support"
 #endif /* OPENSSL_VERION < 1.0 */
 
fc660aae
 
 
 #ifndef OPENSSL_NO_COMP
 #define TLS_COMP_SUPPORT
 #else
 #undef TLS_COMP_SUPPORT
 #endif
 
 #ifndef OPENSSL_NO_KRB5
 #define TLS_KERBEROS_SUPPORT
 #else
 #undef TLS_KERBEROS_SUPPORT
 #endif
 
 
560a42b6
 #ifdef TLS_KSSL_WORKARROUND
 int openssl_kssl_malloc_bug=0; /* is openssl bug #1467 present ? */
 #endif
fc660aae
 
76efc9b7
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
ea32bf9d
 const SSL_METHOD* ssl_methods[TLS_METHOD_MAX];
76efc9b7
 #else
 sr_tls_methods_t sr_tls_methods[TLS_METHOD_MAX];
 #endif
dd0647fb
 
9bc19d49
 #ifdef NO_TLS_MALLOC_DBG
3d980a8e
 #undef TLS_MALLOC_DBG /* extra malloc debug info from openssl */
9bc19d49
 #endif /* NO_TLS_MALLOC_DBG */
 
dd0647fb
 /*
  * Wrappers around SER shared memory functions
  * (which can be macros)
  */
0e4d732d
 #ifdef TLS_MALLOC_DBG
9bc19d49
 #warning "tls module compiled with malloc debugging info (extra overhead)"
0e4d732d
 #include <execinfo.h>
 
433e6896
 /*
 #define RAND_NULL_MALLOC (1024)
0e4d732d
 #define NULL_GRACE_PERIOD 10U
433e6896
 */
0e4d732d
 
cfade98e
 
 
634efd6b
 #ifndef LIBRESSL_VERSION_NUMBER
0e4d732d
 inline static char* buf_append(char* buf, char* end, char* str, int str_len)
 {
 	if ( (buf+str_len)<end){
 		memcpy(buf, str, str_len);
 		return buf+str_len;
 	}
 	return 0;
 }
 
 
 inline static int backtrace2str(char* buf, int size)
 {
 	void* bt[32];
 	int bt_size, i;
 	char** bt_strs;
 	char* p;
 	char* end;
 	char* next;
 	char* s;
 	char* e;
a444035d
 
0e4d732d
 	p=buf; end=buf+size;
 	bt_size=backtrace(bt, sizeof(bt)/sizeof(bt[0]));
 	bt_strs=backtrace_symbols(bt, bt_size);
 	if (bt_strs){
 		p=buf; end=buf+size;
 		/*if (bt_size>16) bt_size=16;*/ /* go up only 12 entries */
 		for (i=3; i< bt_size; i++){
 			/* try to isolate only the function name*/
 			s=strchr(bt_strs[i], '(');
 			if (s && ((e=strchr(s, ')'))!=0)){
 				s++;
 			}else if ((s=strchr(bt_strs[i], '['))!=0){
 				e=s+strlen(s);
 			}else{
 				s=bt_strs[i]; e=s+strlen(s); /* add thw whole string */
 			}
 			next=buf_append(p, end, s, (int)(long)(e-s));
 			if (next==0) break;
 			else p=next;
 			if (p<end){
 				*p=':'; /* separator */
 				p++;
 			}else break;
 		}
 		if (p==buf){
 			*p=0;
 			p++;
 		}else
 			*(p-1)=0;
 		free(bt_strs);
 	}
 	return (int)(long)(p-buf);
 }
 
 static void* ser_malloc(size_t size, const char* file, int line)
 {
 	void  *p;
 	char bt_buf[1024];
 	int s;
3d980a8e
 #ifdef RAND_NULL_MALLOC
 	static ticks_t st=0;
0e4d732d
 
a444035d
 	/* start random null returns only after
0e4d732d
 	 * NULL_GRACE_PERIOD from first call */
 	if (st==0) st=get_ticks();
 	if (((get_ticks()-st)<NULL_GRACE_PERIOD) || (random()%RAND_NULL_MALLOC)){
3d980a8e
 #endif
0e4d732d
 		s=backtrace2str(bt_buf, sizeof(bt_buf));
 		/* ugly hack: keep the bt inside the alloc'ed fragment */
 		p=_shm_malloc(size+s, file, "via ser_malloc", line);
 		if (p==0){
a8b30d34
 			LM_CRIT("tls - ser_malloc(%d)[%s:%d]==null, bt: %s\n",
 					size, file, line, bt_buf);
0e4d732d
 		}else{
 			memcpy(p+size, bt_buf, s);
 			((struct qm_frag*)((char*)p-sizeof(struct qm_frag)))->func=
 				p+size;
 		}
3d980a8e
 #ifdef RAND_NULL_MALLOC
0e4d732d
 	}else{
 		p=0;
 		backtrace2str(bt_buf, sizeof(bt_buf));
a8b30d34
 		LM_CRIT("tls - random ser_malloc(%d)[%s:%d] returning null - bt: %s\n",
0e4d732d
 				size, file, line, bt_buf);
 	}
3d980a8e
 #endif
0e4d732d
 	return p;
 }
 
 
 static void* ser_realloc(void *ptr, size_t size, const char* file, int line)
 {
 	void  *p;
 	char bt_buf[1024];
 	int s;
3d980a8e
 #ifdef RAND_NULL_MALLOC
 	static ticks_t st=0;
0e4d732d
 
a444035d
 	/* start random null returns only after
0e4d732d
 	 * NULL_GRACE_PERIOD from first call */
 	if (st==0) st=get_ticks();
 	if (((get_ticks()-st)<NULL_GRACE_PERIOD) || (random()%RAND_NULL_MALLOC)){
3d980a8e
 #endif
0e4d732d
 		s=backtrace2str(bt_buf, sizeof(bt_buf));
 		p=_shm_realloc(ptr, size+s, file, "via ser_realloc", line);
 		if (p==0){
a8b30d34
 			LM_CRIT("tls - ser_realloc(%p, %d)[%s:%d]==null, bt: %s\n",
0e4d732d
 					ptr, size, file, line, bt_buf);
 		}else{
 			memcpy(p+size, bt_buf, s);
 			((struct qm_frag*)((char*)p-sizeof(struct qm_frag)))->func=
 				p+size;
 		}
3d980a8e
 #ifdef RAND_NULL_MALLOC
0e4d732d
 	}else{
 		p=0;
 		backtrace2str(bt_buf, sizeof(bt_buf));
a8b30d34
 		LM_CRIT("tls - random ser_realloc(%p, %d)[%s:%d]"
 				" returning null - bt: %s\n", ptr, size, file, line,
 				bt_buf);
0e4d732d
 	}
3d980a8e
 #endif
0e4d732d
 	return p;
 }
634efd6b
 #endif /* LIBRESSL_VERSION_NUMBER */
0e4d732d
 
3d980a8e
 #else /*TLS_MALLOC_DBG */
0e4d732d
 
634efd6b
 #ifndef LIBRESSL_VERSION_NUMBER
 
ef021552
 #if OPENSSL_VERSION_NUMBER < 0x010100000L
dd0647fb
 static void* ser_malloc(size_t size)
 {
 	return shm_malloc(size);
 }
 
 
3d980a8e
 static void* ser_realloc(void *ptr, size_t size)
dd0647fb
 {
a8b30d34
 	return shm_realloc(ptr, size);
dd0647fb
 }
ef021552
 #else
 static void* ser_malloc(size_t size, const char *fname, int fline)
 {
 	return shm_malloc(size);
 }
 
dd0647fb
 
ef021552
 static void* ser_realloc(void *ptr, size_t size, const char *fname, int fline)
 {
a8b30d34
 	return shm_realloc(ptr, size);
ef021552
 }
0e4d732d
 #endif
dd0647fb
 
ef021552
 #endif
 
 #if OPENSSL_VERSION_NUMBER < 0x010100000L
dd0647fb
 static void ser_free(void *ptr)
 {
7c37f8d4
 	/* The memory functions provided to openssl needs to behave like standard
 	 * memory functions, i.e. free(). Therefore, ser_free must accept NULL
a8b30d34
 	 * pointers, see:
 	 * http://openssl.6102.n7.nabble.com/Custom-free-routine-is-invoked-with-NULL-argument-in-openssl-1-0-1-td25937.html
7c37f8d4
 	 * As shm_free() aborts on null pointers, we have to check for null pointer
 	 * here in the wrapper function.
 	 */
 	if (ptr) {
 		shm_free(ptr);
 	}
dd0647fb
 }
ef021552
 #else
 static void ser_free(void *ptr, const char *fname, int fline)
 {
 	if (ptr) {
 		shm_free(ptr);
 	}
 }
 #endif
dd0647fb
 
634efd6b
 #endif /* LIBRESSL_VERSION_NUMBER */
dd0647fb
 
 /*
  * Initialize TLS socket
  */
c26f40bc
 int tls_h_init_si_f(struct socket_info *si)
dd0647fb
 {
 	int ret;
a444035d
 	/*
 	 * reuse tcp initialization
 	 */
dd0647fb
 	ret = tcp_init(si);
 	if (ret != 0) {
a8b30d34
 		LM_ERR("Error while initializing TCP part of TLS socket %.*s:%d\n",
 				si->address_str.len, si->address_str.s, si->port_no);
dd0647fb
 		goto error;
 	}
a444035d
 
dd0647fb
 	si->proto = PROTO_TLS;
 	return 0;
a444035d
 
 error:
dd0647fb
 	if (si->socket != -1) {
 		close(si->socket);
 		si->socket = -1;
 	}
 	return ret;
 }
 
 
 
 /*
a444035d
  * initialize ssl methods
dd0647fb
  */
 static void init_ssl_methods(void)
 {
76efc9b7
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
 	/* libssl < 1.1.0 */
16649609
 	memset(ssl_methods, 0, sizeof(ssl_methods));
 
711833b8
 	/* any SSL/TLS version */
 	ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
 	ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
 	ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
 
 	/* only specific SSL or TLS version */
634efd6b
 #if OPENSSL_VERSION_NUMBER < 0x010100000L || defined(LIBRESSL_VERSION_NUMBER)
7c7ed8ad
 #ifndef OPENSSL_NO_SSL2
dd0647fb
 	ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method();
 	ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method();
 	ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method();
7c7ed8ad
 #endif
ef021552
 #endif
7c7ed8ad
 
b1c6c2af
 #ifndef OPENSSL_NO_SSL3_METHOD
dd0647fb
 	ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method();
 	ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method();
 	ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method();
b1c6c2af
 #endif
ea32bf9d
 
dd0647fb
 	ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method();
 	ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();
 	ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method();
ea32bf9d
 
634efd6b
 #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(LIBRESSL_VERSION_NUMBER)
ea32bf9d
 	ssl_methods[TLS_USE_TLSv1_1_cli - 1] = TLSv1_1_client_method();
 	ssl_methods[TLS_USE_TLSv1_1_srv - 1] = TLSv1_1_server_method();
 	ssl_methods[TLS_USE_TLSv1_1 - 1] = TLSv1_1_method();
16649609
 #endif
ea32bf9d
 
634efd6b
 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(LIBRESSL_VERSION_NUMBER)
ea32bf9d
 	ssl_methods[TLS_USE_TLSv1_2_cli - 1] = TLSv1_2_client_method();
 	ssl_methods[TLS_USE_TLSv1_2_srv - 1] = TLSv1_2_server_method();
 	ssl_methods[TLS_USE_TLSv1_2 - 1] = TLSv1_2_method();
 #endif
711833b8
 
 	/* ranges of TLS versions (require a minimum TLS version) */
 	ssl_methods[TLS_USE_TLSv1_PLUS - 1] = (void*)TLS_OP_TLSv1_PLUS;
 
634efd6b
 #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(LIBRESSL_VERSION_NUMBER)
711833b8
 	ssl_methods[TLS_USE_TLSv1_1_PLUS - 1] = (void*)TLS_OP_TLSv1_1_PLUS;
 #endif
 
634efd6b
 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(LIBRESSL_VERSION_NUMBER)
711833b8
 	ssl_methods[TLS_USE_TLSv1_2_PLUS - 1] = (void*)TLS_OP_TLSv1_2_PLUS;
 #endif
76efc9b7
 
 #else
 	/* openssl 1.1.0+ */
 	memset(sr_tls_methods, 0, sizeof(sr_tls_methods));
 
 	/* any SSL/TLS version */
 	sr_tls_methods[TLS_USE_SSLv23_cli - 1].TLSMethod = TLS_client_method();
 	sr_tls_methods[TLS_USE_SSLv23_srv - 1].TLSMethod = TLS_server_method();
 	sr_tls_methods[TLS_USE_SSLv23 - 1].TLSMethod = TLS_method();
 
 #ifndef OPENSSL_NO_SSL3_METHOD
 	sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethod = TLS_client_method();
 	sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethodMin = SSL3_VERSION;
 	sr_tls_methods[TLS_USE_SSLv3_cli - 1].TLSMethodMax = SSL3_VERSION;
 	sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethod = TLS_server_method();
 	sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethodMin = SSL3_VERSION;
 	sr_tls_methods[TLS_USE_SSLv3_srv - 1].TLSMethodMax = SSL3_VERSION;
 	sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethodMin = SSL3_VERSION;
 	sr_tls_methods[TLS_USE_SSLv3 - 1].TLSMethodMax = SSL3_VERSION;
 #endif
 
 	sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethod = TLS_client_method();
 	sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethodMin = TLS1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_cli - 1].TLSMethodMax = TLS1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethod = TLS_server_method();
 	sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethodMin = TLS1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_srv - 1].TLSMethodMax = TLS1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethodMin = TLS1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1 - 1].TLSMethodMax = TLS1_VERSION;
 
 	sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethod = TLS_client_method();
 	sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethodMin = TLS1_1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_1_cli - 1].TLSMethodMax = TLS1_1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethod = TLS_server_method();
 	sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethodMin = TLS1_1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_1_srv - 1].TLSMethodMax = TLS1_1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethodMin = TLS1_1_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_1 - 1].TLSMethodMax = TLS1_1_VERSION;
 
 	sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethod = TLS_client_method();
 	sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethodMin = TLS1_2_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_2_cli - 1].TLSMethodMax = TLS1_2_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethod = TLS_server_method();
 	sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethodMin = TLS1_2_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_2_srv - 1].TLSMethodMax = TLS1_2_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethodMin = TLS1_2_VERSION;
 	sr_tls_methods[TLS_USE_TLSv1_2 - 1].TLSMethodMax = TLS1_2_VERSION;
 
 	/* ranges of TLS versions (require a minimum TLS version) */
 	sr_tls_methods[TLS_USE_TLSv1_PLUS - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1_PLUS - 1].TLSMethodMin = TLS1_VERSION;
 
 	sr_tls_methods[TLS_USE_TLSv1_1_PLUS - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1_1_PLUS - 1].TLSMethodMin = TLS1_1_VERSION;
 
 	sr_tls_methods[TLS_USE_TLSv1_2_PLUS - 1].TLSMethod = TLS_method();
 	sr_tls_methods[TLS_USE_TLSv1_2_PLUS - 1].TLSMethodMin = TLS1_2_VERSION;
 
 #endif
dd0647fb
 }
 
 
 /*
  * Fix openssl compression bugs if necessary
  */
 static int init_tls_compression(void)
 {
634efd6b
 #ifndef LIBRESSL_VERSION_NUMBER
ef021552
 #if OPENSSL_VERSION_NUMBER < 0x010100000L
fc660aae
 #if OPENSSL_VERSION_NUMBER >= 0x00908000L
dd0647fb
 	int n, r;
 	STACK_OF(SSL_COMP)* comp_methods;
 	SSL_COMP* zlib_comp;
fc660aae
 	long ssl_version;
a444035d
 
fc660aae
 	/* disabling compression */
 #	ifndef SSL_COMP_ZLIB_IDX
 #		define SSL_COMP_ZLIB_IDX 1 /* openssl/ssl/ssl_ciph.c:84 */
a444035d
 #	endif
dd0647fb
 	comp_methods = SSL_COMP_get_compression_methods();
 	if (comp_methods == 0) {
a8b30d34
 		LM_INFO("compression support disabled in the"
 				" openssl lib\n");
fc660aae
 		goto end; /* nothing to do, exit */
e40e993e
 	} else if (cfg_get(tls, tls_cfg, disable_compression)){
a8b30d34
 		LM_INFO("disabling compression...\n");
dd0647fb
 		sk_SSL_COMP_zero(comp_methods);
fc660aae
 	}else{
 		ssl_version=SSLeay();
433e6896
 		/* replace openssl zlib compression with our version if necessary
 		 * (the openssl zlib compression uses the wrong malloc, see
 		 *  openssl #1468): 0.9.8-dev < version  <0.9.8e-beta1 */
 		if ((ssl_version >= 0x00908000L) && (ssl_version < 0x00908051L)){
7f8edfa7
 			/* the above SSL_COMP_get_compression_methods() call has the side
 			 * effect of initializing the compression stack (if not already
 			 * initialized) => after it zlib is initialized and in the stack */
 			/* find zlib_comp (cannot use ssl3_comp_find, not exported) */
dd0647fb
 			n = sk_SSL_COMP_num(comp_methods);
 			zlib_comp = 0;
 			for (r = 0; r < n; r++) {
 				zlib_comp = sk_SSL_COMP_value(comp_methods, r);
a8b30d34
 				LM_DBG("found compression method %p id %d\n",
fc660aae
 						zlib_comp, zlib_comp->id);
dd0647fb
 				if (zlib_comp->id == SSL_COMP_ZLIB_IDX) {
a8b30d34
 					LM_DBG("found zlib compression (%d)\n",
fc660aae
 							SSL_COMP_ZLIB_IDX);
dd0647fb
 					break /* found */;
 				} else {
 					zlib_comp = 0;
 				}
 			}
 			if (zlib_comp == 0) {
a8b30d34
 				LM_INFO("no openssl zlib compression found\n");
7f8edfa7
 			}else{
a8b30d34
 				LM_WARN("detected openssl lib with "
 						"known zlib compression bug: \"%s\" (0x%08lx)\n",
 						SSLeay_version(SSLEAY_VERSION), ssl_version);
fc660aae
 #	ifdef TLS_FIX_ZLIB_COMPRESSION
a8b30d34
 				LM_WARN("enabling openssl zlib compression "
 						"bug workaround (replacing zlib COMP method with "
 						"our own version)\n");
fc660aae
 				/* hack: make sure that the CRYPTO_EX_INDEX_COMP class is empty
a444035d
 				 * and it does not contain any free_ex_data from the
fc660aae
 				 * built-in zlib. This can happen if the current openssl
 				 * zlib malloc fix patch is used (CRYPTO_get_ex_new_index() in
 				 * COMP_zlib()). Unfortunately the only way
 				 * to do this it to cleanup all the ex_data stuff.
 				 * It should be safe if this is executed before SSL_init()
 				 * (only the COMP class is initialized before).
 				 */
 				CRYPTO_cleanup_all_ex_data();
a444035d
 
fc660aae
 				if (fixed_c_zlib_init() != 0) {
a8b30d34
 					LM_CRIT("BUG: failed to initialize zlib"
fc660aae
 							" compression fix, disabling compression...\n");
 					sk_SSL_COMP_zero(comp_methods); /* delete compression */
 					goto end;
 				}
7f8edfa7
 				/* "fix" it */
 				zlib_comp->method = &zlib_method;
fc660aae
 #	else
a8b30d34
 				LM_WARN("disabling openssl zlib compression \n");
fc660aae
 				zlib_comp=sk_SSL_COMP_delete(comp_methods, r);
0e4d732d
 				if (zlib_comp)
 					OPENSSL_free(zlib_comp);
fc660aae
 #	endif
dd0647fb
 			}
 		}
 	}
fc660aae
 end:
 #endif /* OPENSSL_VERSION_NUMBER >= 0.9.8 */
ef021552
 #endif /* OPENSSL_VERSION_NUMBER < 1.1.0 */
634efd6b
 #endif /* LIBRESSL_VERSION_NUMBER */
dd0647fb
 	return 0;
 }
 
 
517d38ed
 /**
  * tls pre-init function
f7124341
  * - executed when module is loaded
517d38ed
  */
 int tls_pre_init(void)
 {
634efd6b
 #ifndef LIBRESSL_VERSION_NUMBER
ef021552
 #if OPENSSL_VERSION_NUMBER < 0x010100000L
966513b3
 	void *(*mf)(size_t) = NULL;
 	void *(*rf)(void *, size_t) = NULL;
 	void (*ff)(void *) = NULL;
ef021552
 #else
 	void *(*mf)(size_t, const char *, int) = NULL;
 	void *(*rf)(void *, size_t, const char *, int) = NULL;
 	void (*ff)(void *, const char *, int) = NULL;
 #endif
 
365e7e46
 #ifdef KSR_LIBSSL_STATIC
 	LM_INFO("libssl linked mode: static\n");
 #endif
 
a444035d
 	/*
 	 * this has to be called before any function calling CRYPTO_malloc,
 	 * CRYPTO_malloc will set allow_customize in openssl to 0
 	 */
81ace1c9
 	CRYPTO_get_mem_functions(&mf, &rf, &ff);
 	LM_DBG("initial memory functions - malloc: %p realloc: %p free: %p\n",
 			mf, rf, ff);
 	mf = NULL;
 	rf = NULL;
 	ff = NULL;
517d38ed
 #ifdef TLS_MALLOC_DBG
 	if (!CRYPTO_set_mem_ex_functions(ser_malloc, ser_realloc, ser_free)) {
 #else
 	if (!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) {
 #endif
a8b30d34
 		LM_ERR("Unable to set the memory allocation functions\n");
966513b3
 		CRYPTO_get_mem_functions(&mf, &rf, &ff);
a8b30d34
 		LM_ERR("libssl current mem functions - m: %p r: %p f: %p\n",
 					mf, rf, ff);
81ace1c9
 		LM_ERR("module mem functions - m: %p r: %p f: %p\n",
 					ser_malloc, ser_realloc, ser_free);
a8b30d34
 		LM_ERR("Be sure tls module is loaded before any other module using"
 				" libssl (can be loaded first to be safe)\n");
517d38ed
 		return -1;
 	}
81ace1c9
 	LM_DBG("updated memory functions - malloc: %p realloc: %p free: %p\n",
 			ser_malloc, ser_realloc, ser_free);
634efd6b
 #endif /* LIBRESSL_VERSION_NUMBER */
517d38ed
 
 	if (tls_init_locks()<0)
 		return -1;
 
 	init_tls_compression();
 
 	return 0;
 }
 
f7124341
 /**
  * tls mod pre-init function
  * - executed before any mod_init()
  */
c26f40bc
 int tls_h_mod_pre_init_f(void)
f7124341
 {
 	if(tls_mod_preinitialized==1) {
 		LM_DBG("already mod pre-initialized\n");
 		return 0;
 	}
a8b30d34
 	LM_DBG("preparing tls env for modules initialization\n");
6df13e61
 #if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
 	LM_DBG("preparing tls env for modules initialization (libssl >=1.1)\n");
 	OPENSSL_init_ssl(0, NULL);
 #else
5b81ee81
 	LM_DBG("preparing tls env for modules initialization (libssl <=1.0)\n");
f7124341
 	SSL_library_init();
4d14057a
 #endif
6df13e61
 	SSL_load_error_strings();
f7124341
 	tls_mod_preinitialized=1;
 	return 0;
 }
 
dd0647fb
 /*
  * First step of TLS initialization
  */
c26f40bc
 int tls_h_mod_init_f(void)
dd0647fb
 {
6a8994c4
 	/*struct socket_info* si;*/
fc660aae
 	long ssl_version;
6ee8085a
 	const char *ssl_version_txt;
634efd6b
 #if OPENSSL_VERSION_NUMBER < 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
fc660aae
 	int lib_kerberos;
 	int lib_zlib;
 	int kerberos_support;
 	int comp_support;
 	const char* lib_cflags;
e59fa823
 #endif
e40e993e
 	int low_mem_threshold1;
 	int low_mem_threshold2;
 	str tls_grp;
 	str s;
 	cfg_ctx_t* cfg_ctx;
dd0647fb
 
f7124341
 	if(tls_mod_initialized == 1) {
 		LM_DBG("already initialized\n");
 		return 0;
 	}
a8b30d34
 	LM_DBG("initializing tls system\n");
f7124341
 
dd0647fb
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
a8b30d34
 	LM_WARN("You are using an old version of OpenSSL (< 0.9.7). Upgrade!\n");
dd0647fb
 #endif
6ee8085a
 
 #if OPENSSL_VERSION_NUMBER < 0x010100000L
 	ssl_version=SSLeay();
 	ssl_version_txt=SSLeay_version(SSLEAY_VERSION);
 #else
4d14057a
 	ssl_version=OpenSSL_version_num();
6ee8085a
 	ssl_version_txt=OpenSSL_version(OPENSSL_VERSION);
 #endif
 
fc660aae
 	/* check if version have the same major minor and fix level
c38b4c73
 	 * (e.g. 0.9.8a & 0.9.8c are ok, but 0.9.8 and 0.9.9x are not)
 	 * - values is represented as 0xMMNNFFPPS: major minor fix patch status
 	 *   0x00090705f == 0.9.7e release */
 	if ((ssl_version>>12)!=(OPENSSL_VERSION_NUMBER>>12)){
a8b30d34
 		LM_CRIT("installed openssl library"
 				" version is too different from the library the " NAME " tls"
 				" module was compiled with: installed \"%s\" (0x%08lx),"
 				" compiled \"%s\" (0x%08lx).\n"
fc660aae
 				" Please make sure a compatible version is used"
49cbae4a
 				" (tls_force_run in kamailio.cfg will override this check)\n",
6ee8085a
 				ssl_version_txt, ssl_version,
fc660aae
 				OPENSSL_VERSION_TEXT, (long)OPENSSL_VERSION_NUMBER);
e40e993e
 		if (cfg_get(tls, tls_cfg, force_run))
a8b30d34
 			LM_WARN("tls_force_run turned on, ignoring "
 					" openssl version mismatch\n");
fc660aae
 		else
 			return -1; /* safer to exit */
 	}
e59fa823
 
a8b30d34
 	/* check kerberos support using compile flags only for version < 1.1.0 */
634efd6b
 #if OPENSSL_VERSION_NUMBER < 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
e59fa823
 
fc660aae
 #ifdef TLS_KERBEROS_SUPPORT
 	kerberos_support=1;
 #else
 	kerberos_support=0;
 #endif
 #ifdef TLS_COMP_SUPPORT
 	comp_support=1;
 #else
 	comp_support=0;
 #endif
 	/* attempt to guess if the library was compiled with kerberos or
 	 * compression support from the cflags */
 	lib_cflags=SSLeay_version(SSLEAY_CFLAGS);
 	lib_kerberos=0;
 	lib_zlib=0;
a444035d
 	if ((lib_cflags==0) || strstr(lib_cflags, "not available")){
fc660aae
 		lib_kerberos=-1;
 		lib_zlib=-1;
 	}else{
 		if (strstr(lib_cflags, "-DZLIB"))
 			lib_zlib=1;
 		if (strstr(lib_cflags, "-DKRB5_"))
 			lib_kerberos=1;
 	}
a8b30d34
 	LM_INFO("compiled  with  openssl  version "
 			"\"%s\" (0x%08lx), kerberos support: %s, compression: %s\n",
 			OPENSSL_VERSION_TEXT, (long)OPENSSL_VERSION_NUMBER,
 			kerberos_support?"on":"off", comp_support?"on":"off");
 	LM_INFO("installed openssl library version "
 			"\"%s\" (0x%08lx), kerberos support: %s, "
 			" zlib compression: %s"
 			"\n %s\n",
 			SSLeay_version(SSLEAY_VERSION), ssl_version,
 			(lib_kerberos==1)?"on":(lib_kerberos==0)?"off":"unknown",
 			(lib_zlib==1)?"on":(lib_zlib==0)?"off":"unknown",
 			SSLeay_version(SSLEAY_CFLAGS));
fc660aae
 	if (lib_kerberos!=kerberos_support){
 		if (lib_kerberos!=-1){
a8b30d34
 			LM_CRIT("openssl compile options"
 					" mismatch: library has kerberos support"
 					" %s and Kamailio tls %s (unstable configuration)\n"
 					" (tls_force_run in " NAME ".cfg will override this"
 					" check)\n",
 					lib_kerberos?"enabled":"disabled",
 					kerberos_support?"enabled":"disabled"
 			   );
e40e993e
 			if (cfg_get(tls, tls_cfg, force_run))
a8b30d34
 				LM_WARN("tls_force_run turned on, "
6a8994c4
 						"ignoring kerberos support mismatch\n");
fc660aae
 			else
 				return -1; /* exit, is safer */
 		}else{
a8b30d34
 			LM_WARN("openssl  compile options"
 					" missing -- cannot detect if kerberos support is"
 					" enabled. Possible unstable configuration\n");
fc660aae
 		}
 	}
517d38ed
 
a8b30d34
 #ifdef TLS_KSSL_WORKARROUND
560a42b6
 	/* if openssl compiled with kerberos support, and openssl < 0.9.8e-dev
433e6896
 	 * or openssl between 0.9.9-dev and 0.9.9-beta1 apply workaround for
560a42b6
 	 * openssl bug #1467 */
a444035d
 	if (ssl_version < 0x00908050L ||
560a42b6
 			(ssl_version >= 0x00909000L && ssl_version < 0x00909001L)){
 		openssl_kssl_malloc_bug=1;
a8b30d34
 		LM_WARN("openssl kerberos malloc bug detected, "
 				" kerberos support will be disabled...\n");
560a42b6
 	}
a8b30d34
 #endif
e59fa823
 
 #endif /* libssl version < 1.1.0 (OPENSSL_VERSION_NUMBER < 0x010100000L) */
 
e40e993e
 	/* set free memory threshold for openssl bug #1491 workaround */
 	low_mem_threshold1 = cfg_get(tls, tls_cfg, low_mem_threshold1);
 	low_mem_threshold2 = cfg_get(tls, tls_cfg, low_mem_threshold2);
 	if (low_mem_threshold1<0){
66fff017
 		/* default */
e40e993e
 		low_mem_threshold1=512*1024*get_max_procs();
66fff017
 	}else
e40e993e
 		low_mem_threshold1*=1024; /* KB */
 	if (low_mem_threshold2<0){
66fff017
 		/* default */
e40e993e
 		low_mem_threshold2=256*1024*get_max_procs();
66fff017
 	}else
e40e993e
 		low_mem_threshold2*=1024; /* KB */
 	if ((low_mem_threshold1==0) || (low_mem_threshold2==0))
a8b30d34
 	 LM_WARN("tls: openssl bug #1491 (crash/mem leaks on low memory)"
09f85198
 				" workaround disabled\n");
66fff017
 	else
a8b30d34
 		LM_WARN("openssl bug #1491 (crash/mem leaks on low memory)"
66fff017
 				" workaround enabled (on low memory tls operations will fail"
 				" preemptively) with free memory thresholds %d and %d bytes\n",
e40e993e
 				low_mem_threshold1, low_mem_threshold2);
a444035d
 
433e6896
 	if (shm_available()==(unsigned long)(-1)){
a8b30d34
 		LM_WARN(NAME " is compiled without MALLOC_STATS support:"
433e6896
 				" the workaround for low mem. openssl bugs will _not_ "
 				"work\n");
e40e993e
 		low_mem_threshold1=0;
 		low_mem_threshold2=0;
433e6896
 	}
a444035d
 	if ((low_mem_threshold1 != cfg_get(tls, tls_cfg, low_mem_threshold1))
 			|| (low_mem_threshold2
a8b30d34
 				!= cfg_get(tls, tls_cfg, low_mem_threshold2))) {
e40e993e
 		/* ugly hack to set the initial values for the mem tresholds */
 		if (cfg_register_ctx(&cfg_ctx, 0)) {
a8b30d34
 			LM_ERR("failed to register cfg context\n");
e40e993e
 			return -1;
dd0647fb
 		}
e40e993e
 		tls_grp.s = "tls";
 		tls_grp.len = strlen(tls_grp.s);
 		s.s = "low_mem_threshold1";
 		s.len = strlen(s.s);
 		if (low_mem_threshold1 != cfg_get(tls, tls_cfg, low_mem_threshold1) &&
a8b30d34
 				cfg_set_now_int(cfg_ctx, &tls_grp, NULL /* group id */, &s,
 					low_mem_threshold1)) {
 			LM_ERR("failed to set tls.low_mem_threshold1 to %d\n",
e40e993e
 					low_mem_threshold1);
 			return -1;
 		}
 		s.s = "low_mem_threshold2";
 		s.len = strlen(s.s);
 		if (low_mem_threshold2 != cfg_get(tls, tls_cfg, low_mem_threshold2) &&
a8b30d34
 				cfg_set_now_int(cfg_ctx, &tls_grp, NULL /* group id */, &s,
 					low_mem_threshold2)) {
 			LM_ERR("failed to set tls.low_mem_threshold1 to %d\n",
e40e993e
 					low_mem_threshold2);
 			return -1;
dd0647fb
 		}
 	}
a444035d
 
e40e993e
 	init_ssl_methods();
517d38ed
 	tls_mod_initialized = 1;
dd0647fb
 	return 0;
 }
 
 
 /*
38a66479
  * Make sure that all server domains in the configuration have corresponding
  * listening socket in SER
dd0647fb
  */
36ed3b92
 int tls_check_sockets(tls_domains_cfg_t* cfg)
dd0647fb
 {
 	tls_domain_t* d;
 
38a66479
 	if (!cfg) return 0;
dd0647fb
 
38a66479
 	d = cfg->srv_list;
 	while(d) {
 		if (d->ip.len && !find_si(&d->ip, d->port, PROTO_TLS)) {
a8b30d34
 			LM_ERR("%s: No listening socket found\n", tls_domain_str(d));
38a66479
 			return -1;
dd0647fb
 		}
38a66479
 		d = d->next;
dd0647fb
 	}
38a66479
 	return 0;
dd0647fb
 }
 
 
 /*
c26f40bc
  * TLS cleanup when application exits
dd0647fb
  */
c26f40bc
 void tls_h_mod_destroy_f(void)
dd0647fb
 {
a8b30d34
 	LM_DBG("tls module final tls destroy\n");
f7124341
 	if(tls_mod_preinitialized > 0)
517d38ed
 		ERR_free_strings();
a558c65e
 	/* TODO: free all the ctx'es */
6a8994c4
 	tls_destroy_cfg();
a558c65e
 	tls_destroy_locks();
93c495f3
 	tls_ct_wq_destroy();
9bdc1eba
 #if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER)
00eb71da
 	/* explicit execution of libssl cleanup to avoid being executed again
 	 * by atexit(), when shm is gone */
a8b30d34
 	LM_DBG("executing openssl v1.1+ cleanup\n");
00eb71da
 	OPENSSL_cleanup();
 #endif
dd0647fb
 }