tls_init.c

Go to the documentation of this file.
00001 /*
00002  * $Id: tls_init.c 4680 2008-08-12 07:26:43Z klaus_darilion $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  * Copyright (C) 2004,2005 Free Software Foundation, Inc.
00006  * Copyright (C) 2006 enum.at
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  */
00024 
00025 /*! 
00026  * \file
00027  * \brief Kamailio TLS support :: Initialization
00028  * \ingroup tls
00029  * Module: \ref tls
00030  */
00031 
00032 /*! \defgroup tls Kamailio TLS support
00033  *
00034  * This modules implements SIP over TCP with TLS encryption.
00035  * Make sure you read the README file that describes configuration
00036  * of TLS for single servers and servers hosting multiple domains,
00037  * and thus using multiple SSL/TLS certificates.
00038  *
00039  * Also see: \ref tlsops
00040  *
00041  */
00042 
00043 #include <stdio.h>
00044  
00045 #include "tls_init.h"
00046 #include "tls_config.h"
00047 #include "../dprint.h"
00048 #include "../mem/shm_mem.h"
00049 #include "../tcp_init.h"
00050 #include "../ut.h"
00051 #include "tls_domain.h"
00052 
00053 #include <openssl/ui.h>
00054 #include <openssl/ssl.h>
00055 #include <openssl/opensslv.h>
00056 #include <openssl/err.h>
00057 #include <openssl/comp.h>
00058 
00059 #include <netinet/in_systm.h>
00060 #include <netinet/tcp.h>
00061 #include <netinet/ip.h>
00062 #include <unistd.h>
00063 
00064 #define SER_SSL_SESS_ID ((unsigned char*)"Kamailio-tls")
00065 #define SER_SSL_SESS_ID_LEN (sizeof(SER_SSL_SESS_ID)-1)
00066 
00067 
00068 #if OPENSSL_VERSION_NUMBER < 0x00907000L
00069    #warning ""
00070    #warning "=============================================================="
00071    #warning "Your version of OpenSSL is < 0.9.7."
00072    #warning " Upgrade for better compatibility, features and security fixes!"
00073    #warning "============================================================="
00074    #warning ""
00075 #endif
00076 
00077 SSL_METHOD     *ssl_methods[TLS_USE_SSLv23 + 1];
00078 
00079 #define VERIFY_DEPTH_S 3
00080 
00081 /*! \brief This callback is called during each verification process, 
00082    at each step during the chain of certificates (this function
00083    is not the certificate_verification one!). */
00084 int verify_callback(int pre_verify_ok, X509_STORE_CTX *ctx) {
00085    char buf[256];
00086    X509 *err_cert;
00087    int err, depth;
00088 
00089    depth = X509_STORE_CTX_get_error_depth(ctx);
00090    LM_NOTICE("depth = %d\n",depth);
00091    if ( depth > VERIFY_DEPTH_S ) {
00092       LM_NOTICE("cert chain too long ( depth > VERIFY_DEPTH_S)\n");
00093       pre_verify_ok=0;
00094    }
00095    
00096    if( pre_verify_ok ) {
00097       LM_NOTICE("preverify is good: verify return: %d\n", pre_verify_ok);
00098       return pre_verify_ok;
00099    }
00100    
00101    err_cert = X509_STORE_CTX_get_current_cert(ctx);
00102    err = X509_STORE_CTX_get_error(ctx);   
00103    X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
00104    
00105    LM_NOTICE("subject = %s\n", buf);
00106    LM_NOTICE("verify error:num=%d:%s\n",
00107       err, X509_verify_cert_error_string(err));
00108    LM_NOTICE("error code is %d\n", ctx->error);
00109    
00110    switch (ctx->error) {
00111       case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
00112          X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
00113             buf,sizeof buf);
00114          LM_NOTICE("issuer= %s\n",buf);
00115          break;
00116       case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
00117       case X509_V_ERR_CERT_NOT_YET_VALID:
00118          LM_NOTICE("notBefore\n");
00119          break;
00120       case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
00121       case X509_V_ERR_CERT_HAS_EXPIRED:
00122          LM_NOTICE("notAfter\n");
00123          break;
00124       case X509_V_ERR_CERT_SIGNATURE_FAILURE:
00125       case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
00126          LM_NOTICE("unable to decrypt cert "
00127             "signature\n");
00128          break;
00129       case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
00130          LM_NOTICE("unable to decode issuer "
00131             "public key\n");
00132          break;
00133       case X509_V_ERR_OUT_OF_MEM:
00134          LM_NOTICE("out of memory \n");
00135          break;
00136       case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
00137       case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
00138          LM_NOTICE("Self signed certificate "
00139             "issue\n");
00140          break;
00141       case X509_V_ERR_CERT_CHAIN_TOO_LONG:
00142          LM_NOTICE("certificate chain too long\n");
00143          break;
00144       case X509_V_ERR_INVALID_CA:
00145          LM_NOTICE("invalid CA\n");
00146          break;
00147       case X509_V_ERR_PATH_LENGTH_EXCEEDED:
00148          LM_NOTICE("path length exceeded\n");
00149          break;
00150       case X509_V_ERR_INVALID_PURPOSE:
00151          LM_NOTICE("invalid purpose\n");
00152          break;
00153       case X509_V_ERR_CERT_UNTRUSTED:
00154          LM_NOTICE("certificate untrusted\n");
00155          break;
00156       case X509_V_ERR_CERT_REJECTED:
00157          LM_NOTICE("certificate rejected\n");
00158          break;
00159       
00160       default:
00161          LM_NOTICE("something wrong with the cert"
00162             " ... error code is %d (check x509_vfy.h)\n", ctx->error);
00163          break;
00164    }
00165    
00166    LM_NOTICE("verify return:%d\n", pre_verify_ok);
00167    return(pre_verify_ok);
00168 }
00169 
00170 
00171 static int
00172 passwd_cb(char *buf, int size, int rwflag, void *filename)
00173 {
00174 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
00175    UI             *ui;
00176    const char     *prompt;
00177    
00178    ui = UI_new();
00179    if (ui == NULL)
00180       goto err;
00181 
00182    prompt = UI_construct_prompt(ui, "passphrase", filename);
00183    UI_add_input_string(ui, prompt, 0, buf, 0, size - 1);
00184    UI_process(ui);
00185    UI_free(ui);
00186    return strlen(buf);
00187 
00188 err:
00189    LM_ERR("passwd_cb failed\n");
00190    if (ui)
00191       UI_free(ui);
00192    return 0;
00193    
00194 #else
00195    if( des_read_pw_string(buf, size-1, "Enter Private Key password:", 0) ) {
00196       LM_ERR("passwd_cb failed\n");
00197       return 0;
00198    }
00199    return strlen( buf );
00200    
00201 #endif
00202 }
00203 
00204 #ifndef OPENSSL_NO_TLSEXT
00205 
00206 /* callback on server_name -> trigger context switch if a TLS domain for
00207    the server_name is found (checks socket too) */
00208 static int tls_server_name_cb(SSL *ssl, int *ad, void *private) {
00209     struct tls_domain *orig_domain, *new_domain;
00210    orig_domain = (struct tls_domain *) private;
00211    const char *server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
00212    if (server_name)  {
00213       LM_DBG("received server_name (TLS extension): '%s'\n",server_name);
00214    } else {
00215       LM_DBG("SSL_get_servername returned NULL: return SSL_TLSEXT_ERR_NOACK\n");
00216       return SSL_TLSEXT_ERR_NOACK;
00217    }
00218 
00219    new_domain = tls_find_server_domain_server_name(&orig_domain->addr,
00220       orig_domain->port, server_name);
00221    if (!new_domain) {
00222       LM_DBG("TLS domain for socket [%s:%d] and server_name='%s' "
00223          "not found\n", ip_addr2a(&orig_domain->addr), 
00224          orig_domain->port, server_name);
00225       /* we do not perform SSL_CTX switching, thus the default server domain
00226          for this socket (or the default server domain) will be used. */
00227       return SSL_TLSEXT_ERR_ALERT_WARNING;
00228    }
00229 
00230    LM_DBG("TLS domain for socket [%s:%d] and server_name='%s' found "
00231       "switching CTX context\n", ip_addr2a(&new_domain->addr), 
00232       new_domain->port, server_name);
00233    SSL_set_SSL_CTX(ssl, new_domain->ctx);
00234    /* SSL_set_SSL_CTX only sets the correct certificate parameters, but does 
00235       set the proper verify options. Thus this will be done manually! */
00236 
00237    SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx));
00238    if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
00239             (SSL_num_renegotiations(ssl) == 0)) {
00240       /*
00241        * Only initialize the verification settings from the ctx
00242        * if they are not yet set, or if we're called when a new
00243        * SSL connection is set up (num_renegotiations == 0).
00244        * Otherwise, we would possibly reset a per-directory
00245        * configuration which was put into effect by ssl_hook_Access.
00246        */
00247       SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx),
00248          SSL_CTX_get_verify_callback(ssl->ctx));
00249    }
00250 
00251    return SSL_TLSEXT_ERR_OK;
00252 }
00253 #endif
00254 
00255 /*
00256  * Wrappers around SER shared memory functions
00257  * (which can be macros)
00258  */
00259 
00260 static void    *
00261 ser_malloc(size_t size)
00262 {
00263    return shm_malloc(size);
00264 }
00265 
00266 static void    *
00267 ser_realloc(void *ptr, size_t size)
00268 {
00269    return shm_realloc(ptr, size);
00270 }
00271 
00272 static void
00273 ser_free(void *ptr)
00274 {
00275    shm_free(ptr);
00276 }
00277 
00278 
00279 int
00280 tls_init(struct socket_info *si)
00281 {
00282    LM_DBG("entered\n");
00283    
00284    /*
00285     * reuse tcp initialization 
00286     */
00287    if (tcp_init(si) < 0) {
00288       LM_ERR("failed to initialize TCP part\n");
00289       goto error;
00290    }
00291 
00292    si->proto = PROTO_TLS;
00293    return 0;
00294 
00295   error:
00296    if (si->socket != -1) {
00297       close(si->socket);
00298       si->socket = -1;
00299    }
00300    return -1;
00301 }
00302 
00303 /*! \brief
00304  * load a certificate from a file 
00305  * (certificate file can be a chain, starting by the user cert, 
00306  * and ending in the root CA; if not all needed certs are in this
00307  * file, they are looked up in the caFile or caPATH (see verify
00308  * function).
00309  */
00310 static int
00311 load_certificate(SSL_CTX * ctx, char *filename)
00312 {
00313    LM_DBG("entered\n");
00314    if (!SSL_CTX_use_certificate_chain_file(ctx, filename)) {
00315       LM_ERR("unable to load certificate file '%s'\n",
00316          filename);
00317       return -1;
00318    }
00319 
00320    LM_DBG("'%s' successfuly loaded\n", filename);
00321    return 0;
00322 }
00323 
00324 
00325 #define NUM_RETRIES 3
00326 /*! \brief
00327  * load a private key from a file 
00328  */
00329 static int
00330 load_private_key(SSL_CTX * ctx, char *filename)
00331 {
00332    int idx, ret_pwd;
00333    LM_DBG("entered\n");
00334    
00335    SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
00336    SSL_CTX_set_default_passwd_cb_userdata(ctx, filename);
00337 
00338    for(idx = 0, ret_pwd = 0; idx < NUM_RETRIES; idx++ ) {
00339       ret_pwd = SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM);
00340       if ( ret_pwd ) {
00341          break;
00342       } else {
00343          LM_ERR("unable to load private key file '%s'. \n"
00344             "Retry (%d left) (check password case)\n",
00345             filename, (NUM_RETRIES - idx -1) );
00346          continue;
00347       }
00348    }
00349    
00350    if( ! ret_pwd ) {
00351       LM_ERR("unable to load private key file '%s'\n",
00352          filename);
00353       return -1;
00354    }
00355    
00356    if (!SSL_CTX_check_private_key(ctx)) {
00357       LM_ERR("key '%s' does not match the public key of the certificate\n",
00358          filename);
00359       return -1;
00360    }
00361    
00362    LM_DBG("key '%s' successfuly loaded\n", filename);
00363    return 0;
00364 }
00365 
00366 /*! \brief
00367  * Load a caList, to be used to verify the client's certificate.
00368  * The list is to be stored in a single file, containing all
00369  * the acceptable root certificates.
00370  */
00371 static int
00372 load_ca(SSL_CTX * ctx, char *filename)
00373 {
00374    LM_DBG("Entered\n");
00375    if (!SSL_CTX_load_verify_locations(ctx, filename, 0)) {
00376       LM_ERR("unable to load ca '%s'\n", filename);
00377       return -1;
00378    }
00379    
00380    LM_DBG("CA '%s' successfuly loaded\n", filename);
00381    return 0;
00382 }
00383 
00384 
00385 /*! \brief
00386  * initialize ssl methods 
00387  */
00388 static void
00389 init_ssl_methods(void)
00390 {
00391    LM_DBG("entered\n");
00392    ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method();
00393    ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method();
00394    ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method();
00395    
00396    ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method();
00397    ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method();
00398    ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method();
00399    
00400    ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method();
00401    ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method();
00402    ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method();
00403    
00404    ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method();
00405    ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method();
00406    ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method();
00407 }
00408 
00409 
00410 /*! \brief
00411  * Setup default SSL_CTX (and SSL * ) behavior:
00412  *     verification, cipherlist, acceptable versions, ...
00413  */
00414 static int
00415 init_ssl_ctx_behavior( struct tls_domain *d ) {
00416    int verify_mode;
00417    if( d->ciphers_list != 0 ) {
00418       if( SSL_CTX_set_cipher_list(d->ctx, d->ciphers_list) == 0 ) {
00419          LM_ERR("failure to set SSL context "
00420             "cipher list '%s'\n", d->ciphers_list);
00421          return -1;
00422       } else {
00423          LM_NOTICE("cipher list set to %s\n", d->ciphers_list);
00424       }
00425    } else {
00426       LM_DBG( "cipher list null ... setting default\n");
00427    }
00428 
00429    /* Set a bunch of options: 
00430     *     do not accept SSLv2
00431     *     no session resumption
00432     *     choose cipher according to server's preference's*/
00433 
00434 #if OPENSSL_VERSION_NUMBER >= 0x000907000
00435    SSL_CTX_set_options(d->ctx, 
00436       SSL_OP_ALL | SSL_OP_NO_SSLv2 |
00437       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
00438       SSL_OP_CIPHER_SERVER_PREFERENCE);
00439 #else
00440    SSL_CTX_set_options(d->ctx,
00441       SSL_OP_ALL | SSL_OP_NO_SSLv2 );
00442 #endif
00443 
00444    /* Set verification procedure
00445     * The verification can be made null with SSL_VERIFY_NONE, or 
00446     * at least easier with SSL_VERIFY_CLIENT_ONCE instead of 
00447     * SSL_VERIFY_FAIL_IF_NO_PEER_CERT.
00448     * For extra control, instead of 0, we can specify a callback function:
00449     *           int (*verify_callback)(int, X509_STORE_CTX *)
00450     * Also, depth 2 may be not enough in some scenarios ... though no need
00451     * to increase it much further */
00452 
00453    if (d->type & TLS_DOMAIN_SRV) {
00454       /* Server mode:
00455        * SSL_VERIFY_NONE
00456        *   the server will not send a client certificate request to the 
00457        *   client, so the client  will not send a certificate.
00458        * SSL_VERIFY_PEER
00459        *   the server sends a client certificate request to the client. 
00460        *   The certificate returned (if any) is checked. If the verification 
00461        *   process fails, the TLS/SSL handshake is immediately terminated 
00462        *   with an alert message containing the reason for the verification 
00463        *   failure. The behaviour can be controlled by the additional 
00464        *   SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags.
00465        * SSL_VERIFY_FAIL_IF_NO_PEER_CERT
00466        *   if the client did not return a certificate, the TLS/SSL handshake 
00467        *   is immediately terminated with a ``handshake failure'' alert. 
00468        *   This flag must be used together with SSL_VERIFY_PEER.
00469        * SSL_VERIFY_CLIENT_ONCE
00470        *   only request a client certificate on the initial TLS/SSL 
00471        *   handshake. Do not ask for a client certificate again in case of 
00472        *   a renegotiation. This flag must be used together with 
00473        *   SSL_VERIFY_PEER.
00474        */
00475 
00476       if( d->verify_cert ) {
00477          verify_mode = SSL_VERIFY_PEER;
00478          if( d->require_client_cert ) {
00479             LM_WARN("client verification activated. Client "
00480                "certificates are mandatory.\n");
00481             verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00482          } else
00483             LM_WARN("client verification activated. Client "
00484                "certificates are NOT mandatory.\n");
00485       } else {
00486          verify_mode = SSL_VERIFY_NONE;
00487          LM_WARN("client verification NOT activated. Weaker security.\n");
00488       }
00489    } else {
00490       /* Client mode:
00491        * SSL_VERIFY_NONE
00492        *   if not using an anonymous cipher (by default disabled), the 
00493        *   server will send a certificate which will be checked. The result 
00494        *   of the certificate verification process can be checked after the 
00495        *   TLS/SSL handshake using the SSL_get_verify_result(3) function.
00496        *   The handshake will be continued regardless of the verification 
00497        *   result.
00498        * SSL_VERIFY_PEER
00499        *   the server certificate is verified. If the verification process 
00500        *   fails, the TLS/SSL handshake is immediately terminated with an 
00501        *   alert message containing the reason for the verification failure.
00502        *   If no server certificate is sent, because an anonymous cipher is 
00503        *   used, SSL_VERIFY_PEER is ignored.
00504        * SSL_VERIFY_FAIL_IF_NO_PEER_CERT
00505        *   ignored
00506        * SSL_VERIFY_CLIENT_ONCE
00507        *   ignored
00508        */
00509 
00510       if( d->verify_cert ) {
00511          verify_mode = SSL_VERIFY_PEER;
00512          LM_WARN("server verification activated.\n");
00513       } else {
00514          verify_mode = SSL_VERIFY_NONE;
00515          LM_WARN("server verification NOT activated. Weaker security.\n");
00516       }
00517    }
00518    
00519    SSL_CTX_set_verify( d->ctx, verify_mode, verify_callback);
00520    SSL_CTX_set_verify_depth( d->ctx, VERIFY_DEPTH_S);
00521 
00522    SSL_CTX_set_session_cache_mode( d->ctx, SSL_SESS_CACHE_SERVER );
00523    SSL_CTX_set_session_id_context( d->ctx, SER_SSL_SESS_ID, 
00524       SER_SSL_SESS_ID_LEN );
00525 
00526    return 0;
00527 }
00528 
00529 
00530 static int check_for_krb(void)
00531 {
00532    SSL_CTX *xx;
00533    int j;
00534 
00535    xx = SSL_CTX_new(ssl_methods[tls_method - 1]);
00536    if (xx==NULL)
00537       return -1;
00538 
00539    for( j=0 ; j<M_sk_num(xx->cipher_list) ; j++) {
00540       SSL_CIPHER *yy = (SSL_CIPHER*)M_sk_value(xx->cipher_list,j);
00541       if ( yy->id>=SSL3_CK_KRB5_DES_64_CBC_SHA &&
00542        yy->id<=SSL3_CK_KRB5_RC4_40_MD5 ) {
00543          LM_INFO("KRB5 cipher %s found\n", yy->name);
00544          SSL_CTX_free(xx);
00545          return 1;
00546       }
00547    }
00548 
00549    SSL_CTX_free(xx);
00550    return 0;
00551 }
00552 
00553 
00554 /*! \brief
00555  * called once from main.c (main process) 
00556  */
00557 int
00558 init_tls(void)
00559 {
00560    int i;
00561 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) && !defined(OPENSSL_NO_COMP)
00562    STACK_OF(SSL_COMP)* comp_methods;
00563 #endif
00564 
00565    LM_DBG("entered\n");
00566 
00567 #if OPENSSL_VERSION_NUMBER < 0x00907000L
00568    LM_WARN("using an old version of OpenSSL (< 0.9.7). Upgrade!\n");
00569 #endif
00570 
00571    /*
00572    * this has to be called before any function calling CRYPTO_malloc,
00573    * CRYPTO_malloc will set allow_customize in openssl to 0 
00574    */
00575    if (!CRYPTO_set_mem_functions(ser_malloc, ser_realloc, ser_free)) {
00576       LM_ERR("unable to set the memory allocation functions\n");
00577       return -1;
00578    }
00579 
00580 #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) && !defined(OPENSSL_NO_COMP)
00581    /* disabling compression */
00582    LM_WARN("disabling compression due ZLIB problems\n");
00583    comp_methods = SSL_COMP_get_compression_methods();
00584    if (comp_methods==0) {
00585       LM_INFO("openssl compression methods already disabled\n");
00586    } else {
00587       sk_SSL_COMP_zero(comp_methods);
00588    }
00589 #endif
00590 
00591 #ifndef OPENSSL_NO_TLSEXT
00592    LM_DBG("openssl support TLS extensions, thus openser will use the server_name extension\n");
00593 #else
00594    LM_DBG("openssl does not support TLS extensions, thus openser can not use the server_name extension\n");
00595 #endif
00596 
00597    SSL_library_init();
00598    SSL_load_error_strings();
00599    init_ssl_methods();
00600 
00601    i = check_for_krb();
00602    if (i==-1) {
00603       LM_ERR("kerberos check failed\n");
00604       return -1;
00605    }
00606 
00607    if ( ( i ^ 
00608 #ifndef OPENSSL_NO_KRB5
00609    1
00610 #else
00611    0
00612 #endif
00613    )!=0 ) {
00614       LM_ERR("compiled agaist an openssl with %s"
00615          "kerberos, but run with one with %skerberos\n",
00616          (i==1)?"":"no ",(i!=1)?"no ":"");
00617       return -1;
00618    }
00619 
00620    /*
00621     * now initialize tls default domains 
00622     */
00623    if ( (i=init_tls_domains(tls_default_server_domain)) ) {
00624       return i;
00625    }
00626    if ( (i=init_tls_domains(tls_default_client_domain)) ) {
00627       return i;
00628    }
00629    /*
00630     * now initialize tls virtual domains 
00631     */
00632    if ( (i=init_tls_domains(tls_server_domains)) ) {
00633       return i;
00634    }
00635    if ( (i=init_tls_domains(tls_client_domains)) ) {
00636       return i;
00637    }
00638    /*
00639     * we are all set 
00640     */
00641    return 0;
00642 }
00643 
00644 /*! \brief
00645  * initialize tls virtual domains
00646  */
00647 int
00648 init_tls_domains(struct tls_domain *d)
00649 {
00650    struct tls_domain *dom;
00651 
00652    dom = d;
00653    while (d) {
00654       if (d->name.len) {
00655          LM_INFO("Processing TLS domain '%.*s'\n",
00656             d->name.len, ZSW(d->name.s));
00657       } else {
00658          LM_INFO("Processing TLS domain [%s:%d]\n",
00659             ip_addr2a(&d->addr), d->port);
00660       }
00661 
00662       /*
00663       * set method 
00664       */
00665       if (d->method == TLS_METHOD_UNSPEC) {
00666          LM_DBG("no method for tls[%s:%d], using default\n",
00667             ip_addr2a(&d->addr), d->port);
00668          d->method = tls_method;
00669       }
00670    
00671       /*
00672       * create context 
00673       */
00674       d->ctx = SSL_CTX_new(ssl_methods[d->method - 1]);
00675       if (d->ctx == NULL) {
00676          LM_ERR("cannot create ssl context for "
00677             "tls[%s:%d]\n", ip_addr2a(&d->addr), d->port);
00678          return -1;
00679       }
00680       if (init_ssl_ctx_behavior( d ) < 0)
00681          return -1;
00682 
00683       /*
00684       * load certificate 
00685       */
00686       if (!d->cert_file) {
00687          LM_NOTICE("no certificate for tls[%s:%d] defined, using default"
00688                "'%s'\n", ip_addr2a(&d->addr), d->port,   tls_cert_file);
00689          d->cert_file = tls_cert_file;
00690       }
00691       if (load_certificate(d->ctx, d->cert_file) < 0)
00692          return -1;
00693    
00694       /*
00695       * load ca 
00696       */
00697       if (!d->ca_file) {
00698          LM_NOTICE("no CA for tls[%s:%d] defined, "
00699             "using default '%s'\n", ip_addr2a(&d->addr), d->port,
00700             tls_ca_file);
00701          d->ca_file = tls_ca_file;
00702       }
00703       if (d->ca_file && load_ca(d->ctx, d->ca_file) < 0)
00704          return -1;
00705 
00706 #ifndef OPENSSL_NO_TLSEXT
00707       /*
00708       * check server domains for server_name extension and register
00709       * callback function
00710       */
00711       if ((d->type & TLS_DOMAIN_SRV) && !(d->server_name)) {
00712          LM_NOTICE("register server_name callback handler for socket "
00713             "[%s:%d], server_name='%s' ...\n", ip_addr2a(&d->addr), d->port,
00714             d->server_name);
00715          if (!SSL_CTX_set_tlsext_servername_callback(d->ctx, tls_server_name_cb)) {
00716             LM_ERR("register server_name callback handler for socket "
00717                "[%s:%d], server_name='%s' failed\n", ip_addr2a(&d->addr), d->port,
00718                d->server_name);
00719             return -1;
00720          }
00721          if (!SSL_CTX_set_tlsext_servername_arg(d->ctx, d)) {
00722             LM_ERR("register server_name callback handler data for socket "
00723                "[%s:%d], server_name='%s' failed\n", ip_addr2a(&d->addr), d->port,
00724                d->server_name);
00725             return -1;
00726          }
00727       }
00728 #endif
00729 
00730       d = d->next;
00731    }
00732 
00733    /*
00734    * load all private keys as the last step (may prompt for password) 
00735    */
00736    d = dom;
00737    while (d) {
00738       if (!d->pkey_file) {
00739          LM_NOTICE("no private key for tls[%s:%d] defined, using default"
00740                "'%s'\n", ip_addr2a(&d->addr), d->port, tls_pkey_file);
00741          d->pkey_file = tls_pkey_file;
00742       }
00743       if (load_private_key(d->ctx, d->pkey_file) < 0)
00744          return -1;
00745       d = d->next;
00746    }
00747    return 0;
00748 }
00749 
00750 /*! \brief
00751  * called from main.c when kamailio exits (main process) 
00752  */
00753 void
00754 destroy_tls(void)
00755 {
00756    struct tls_domain *d;
00757    LM_DBG("entered\n");
00758    
00759    d = tls_server_domains;
00760    while (d) {
00761       if (d->ctx)
00762          SSL_CTX_free(d->ctx);
00763       d = d->next;
00764    }
00765    d = tls_client_domains;
00766    while (d) {
00767       if (d->ctx)
00768          SSL_CTX_free(d->ctx);
00769       d = d->next;
00770    }
00771    if (tls_default_server_domain && tls_default_server_domain->ctx) {
00772       SSL_CTX_free(tls_default_server_domain->ctx);
00773    }
00774    if (tls_default_client_domain && tls_default_client_domain->ctx) {
00775       SSL_CTX_free(tls_default_client_domain->ctx);
00776    }
00777    tls_free_domains();
00778 
00779    /* library destroy */
00780    ERR_free_strings();
00781    /*SSL_free_comp_methods(); - this function is not on std. openssl*/
00782    EVP_cleanup();
00783    CRYPTO_cleanup_all_ex_data();
00784 }
00785 
00786 /*! \brief
00787  * called once from main.c (main process) before
00788  * parsing the configuration
00789  */
00790 int pre_init_tls(void)
00791 {
00792    LM_DBG("entered\n");
00793 
00794    tls_default_client_domain = tls_new_domain(TLS_DOMAIN_DEF|TLS_DOMAIN_CLI);
00795    if (tls_default_client_domain==0) {
00796       LM_ERR("failed to initialize tls_default_client_domain\n");
00797       return -1;
00798    }
00799    tls_default_client_domain->addr.af = AF_INET;
00800 
00801    tls_default_server_domain = tls_new_domain(TLS_DOMAIN_DEF|TLS_DOMAIN_SRV);
00802    if (tls_default_server_domain==0) {
00803       LM_ERR("failed to initialize tls_default_server_domain\n");
00804       return -1;
00805    }
00806    tls_default_server_domain->addr.af = AF_INET;
00807 
00808    return 0;
00809 }
00810 

Generated on Thu May 24 20:00:33 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6