tls_mod.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * TLS module - module interface
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  * History:
00027  * -------
00028  * 2003-03-11: New module interface (janakj)
00029  * 2003-03-16: flags export parameter added (janakj)
00030  * 2003-04-05: default_uri #define used (jiri)
00031  * 2003-04-06: db connection closed in mod_init (janakj)
00032  * 2004-06-06  updated to the new DB api, cleanup: static dbf & handler,
00033  *              calls to domain_db_{bind,init,close,ver} (andrei)
00034  * 2007-02-09  updated to the new tls_hooks api and renamed tls hooks hanlder
00035  *              functions to avoid conflicts: s/tls_/tls_h_/   (andrei)
00036  * 2010-03-19  new parameters to control advanced openssl lib options
00037  *              (mostly work on 1.0.0+): ssl_release_buffers, ssl_read_ahead,
00038  *              ssl_freelist_max_len, ssl_max_send_fragment   (andrei)
00039  * 2010-05-27  migrated to the runtime cfg framework (andrei)
00040  */
00048 #include <sys/types.h>
00049 #include <sys/socket.h>
00050 #include <arpa/inet.h>
00051 #include "../../locking.h"
00052 #include "../../sr_module.h"
00053 #include "../../ip_addr.h"
00054 #include "../../trim.h"
00055 #include "../../globals.h"
00056 #include "../../timer_ticks.h"
00057 #include "../../timer.h" /* ticks_t */
00058 #include "../../tls_hooks.h"
00059 #include "../../ut.h"
00060 #include "../../shm_init.h"
00061 #include "../../rpc_lookup.h"
00062 #include "../../cfg/cfg.h"
00063 #include "tls_init.h"
00064 #include "tls_server.h"
00065 #include "tls_domain.h"
00066 #include "tls_select.h"
00067 #include "tls_config.h"
00068 #include "tls_rpc.h"
00069 #include "tls_util.h"
00070 #include "tls_mod.h"
00071 #include "tls_cfg.h"
00072 
00073 #ifndef TLS_HOOKS
00074         #error "TLS_HOOKS must be defined, or the tls module won't work"
00075 #endif
00076 #ifdef CORE_TLS
00077         #error "conflict: CORE_TLS must _not_ be defined"
00078 #endif
00079 
00080 
00081 
00082 /*
00083  * FIXME:
00084  * - How do we ask for secret key password ? Mod_init is called after
00085  *   daemonize and thus has no console access
00086  * - forward_tls and t_relay_to_tls should be here
00087  * add tls_log
00088  * - Currently it is not possible to reset certificate in a domain,
00089  *   for example if you specify client certificate in the default client
00090  *   domain then there is no way to define another client domain which would
00091  *   have no client certificate configured
00092  */
00093 
00094 
00095 /*
00096  * Module management function prototypes
00097  */
00098 static int mod_init(void);
00099 static int mod_child(int rank);
00100 static void destroy(void);
00101 
00102 static int is_peer_verified(struct sip_msg* msg, char* foo, char* foo2);
00103 
00104 MODULE_VERSION
00105 
00106 
00107 /*
00108  * Default settings when modparams are used 
00109  */
00110 static tls_domain_t mod_params = {
00111         TLS_DOMAIN_DEF | TLS_DOMAIN_SRV,   /* Domain Type */
00112         {},               /* IP address */
00113         0,                /* Port number */
00114         0,                /* SSL ctx */
00115         STR_STATIC_INIT(TLS_CERT_FILE),    /* Certificate file */
00116         STR_STATIC_INIT(TLS_PKEY_FILE),    /* Private key file */
00117         0,                /* Verify certificate */
00118         9,                /* Verify depth */
00119         STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
00120         0,                /* Require certificate */
00121         {0, },                /* Cipher list */
00122         TLS_USE_TLSv1,    /* TLS method */
00123         STR_STATIC_INIT(TLS_CRL_FILE), /* Certificate revocation list */
00124         0                 /* next */
00125 };
00126 
00127 
00128 /*
00129  * Default settings for server domains when using external config file
00130  */
00131 tls_domain_t srv_defaults = {
00132         TLS_DOMAIN_DEF | TLS_DOMAIN_SRV,   /* Domain Type */
00133         {},               /* IP address */
00134         0,                /* Port number */
00135         0,                /* SSL ctx */
00136         STR_STATIC_INIT(TLS_CERT_FILE),    /* Certificate file */
00137         STR_STATIC_INIT(TLS_PKEY_FILE),    /* Private key file */
00138         0,                /* Verify certificate */
00139         9,                /* Verify depth */
00140         STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
00141         0,                /* Require certificate */
00142         {0, 0},                /* Cipher list */
00143         TLS_USE_TLSv1,    /* TLS method */
00144         STR_STATIC_INIT(TLS_CRL_FILE), /* Certificate revocation list */
00145         0                 /* next */
00146 };
00147 
00148 
00149 /*
00150  * Default settings for client domains when using external config file
00151  */
00152 tls_domain_t cli_defaults = {
00153         TLS_DOMAIN_DEF | TLS_DOMAIN_CLI,   /* Domain Type */
00154         {},               /* IP address */
00155         0,                /* Port number */
00156         0,                /* SSL ctx */
00157         {0, 0},                /* Certificate file */
00158         {0, 0},                /* Private key file */
00159         0,                /* Verify certificate */
00160         9,                /* Verify depth */
00161         STR_STATIC_INIT(TLS_CA_FILE),      /* CA file */
00162         0,                /* Require certificate */
00163         {0, 0},                /* Cipher list */
00164         TLS_USE_TLSv1,    /* TLS method */
00165         {0, 0}, /* Certificate revocation list */
00166         0                 /* next */
00167 };
00168 
00169 
00170 
00171 /* Current TLS configuration */
00172 tls_domains_cfg_t** tls_domains_cfg = NULL;
00173 
00174 /* List lock, used by garbage collector */
00175 gen_lock_t* tls_domains_cfg_lock = NULL;
00176 
00177 
00178 int sr_tls_renegotiation = 0;
00179 
00180 /*
00181  * Exported functions
00182  */
00183 static cmd_export_t cmds[] = {
00184         {"is_peer_verified", (cmd_function)is_peer_verified,   0, 0, 0,
00185                         REQUEST_ROUTE},
00186         {0,0,0,0,0,0}
00187 };
00188 
00189 
00190 /*
00191  * Exported parameters
00192  */
00193 static param_export_t params[] = {
00194         {"tls_method",          PARAM_STR,    &default_tls_cfg.method       },
00195         {"verify_certificate",  PARAM_INT,    &default_tls_cfg.verify_cert  },
00196         {"verify_depth",        PARAM_INT,    &default_tls_cfg.verify_depth },
00197         {"require_certificate", PARAM_INT,    &default_tls_cfg.require_cert },
00198         {"private_key",         PARAM_STR,    &default_tls_cfg.private_key  },
00199         {"ca_list",             PARAM_STR,    &default_tls_cfg.ca_list      },
00200         {"certificate",         PARAM_STR,    &default_tls_cfg.certificate  },
00201         {"crl",                 PARAM_STR,    &default_tls_cfg.crl          },
00202         {"cipher_list",         PARAM_STR,    &default_tls_cfg.cipher_list  },
00203         {"connection_timeout",  PARAM_INT,    &default_tls_cfg.con_lifetime },
00204         {"tls_log",             PARAM_INT,    &default_tls_cfg.log          },
00205         {"tls_debug",           PARAM_INT,    &default_tls_cfg.debug        },
00206         {"session_cache",       PARAM_INT,    &default_tls_cfg.session_cache},
00207         {"session_id",          PARAM_STR,    &default_tls_cfg.session_id   },
00208         {"config",              PARAM_STR,    &default_tls_cfg.config_file  },
00209         {"tls_disable_compression", PARAM_INT,
00210                                                                                  &default_tls_cfg.disable_compression},
00211         {"ssl_release_buffers",   PARAM_INT, &default_tls_cfg.ssl_release_buffers},
00212         {"ssl_freelist_max_len",  PARAM_INT,  &default_tls_cfg.ssl_freelist_max},
00213         {"ssl_max_send_fragment", PARAM_INT,
00214                                                                            &default_tls_cfg.ssl_max_send_fragment},
00215         {"ssl_read_ahead",        PARAM_INT,    &default_tls_cfg.ssl_read_ahead},
00216         {"send_close_notify",   PARAM_INT,    &default_tls_cfg.send_close_notify},
00217         {"con_ct_wq_max",      PARAM_INT,    &default_tls_cfg.con_ct_wq_max},
00218         {"ct_wq_max",          PARAM_INT,    &default_tls_cfg.ct_wq_max},
00219         {"ct_wq_blk_size",     PARAM_INT,    &default_tls_cfg.ct_wq_blk_size},
00220         {"tls_force_run",       PARAM_INT,    &default_tls_cfg.force_run},
00221         {"low_mem_threshold1",  PARAM_INT,    &default_tls_cfg.low_mem_threshold1},
00222         {"low_mem_threshold2",  PARAM_INT,    &default_tls_cfg.low_mem_threshold2},
00223         {"renegotiation",       PARAM_INT,    &sr_tls_renegotiation},
00224         {0, 0, 0}
00225 };
00226 
00227 
00228 /*
00229  * Module interface
00230  */
00231 struct module_exports exports = {
00232         "tls",
00233         DEFAULT_DLFLAGS, /* dlopen flags */
00234         cmds,        /* Exported functions */
00235         params,      /* Exported parameters */
00236         0,           /* exported statistics */
00237         0,           /* exported MI functions */
00238         tls_pv,      /* exported pseudo-variables */
00239         0,           /* extra processes */
00240         mod_init,    /* module initialization function */
00241         0,           /* response function */
00242         destroy,     /* destroy function */
00243         mod_child    /* child initialization function */
00244 };
00245 
00246 
00247 
00248 static struct tls_hooks tls_h = {
00249         tls_read_f,
00250         tls_encode_f,
00251         tls_h_tcpconn_init,
00252         tls_h_tcpconn_clean,
00253         tls_h_close,
00254         tls_h_init_si,
00255         init_tls_h,
00256         destroy_tls_h
00257 };
00258 
00259 
00260 
00261 #if 0
00262 /*
00263  * Create TLS configuration from modparams
00264  */
00265 static tls_domains_cfg_t* tls_use_modparams(void)
00266 {
00267         tls_domains_cfg_t* ret;
00268         
00269         ret = tls_new_cfg();
00270         if (!ret) return;
00271 
00272         
00273 }
00274 #endif
00275 
00276 int mod_register(char *path, int *dlflags, void *p1, void *p2)
00277 {
00278         /* shm is used, be sure it is initialized */
00279         if(!shm_initialized() && init_shm()<0)
00280                 return -1;
00281 
00282         if(tls_pre_init()<0)
00283                 return -1;
00284         return 0;
00285 }
00286 
00287 static int mod_init(void)
00288 {
00289         int method;
00290 
00291         if (tls_disable){
00292                 LOG(L_WARN, "WARNING: tls: mod_init: tls support is disabled "
00293                                 "(set enable_tls=1 in the config to enable it)\n");
00294                 return 0;
00295         }
00296         if (fix_tls_cfg(&default_tls_cfg) < 0 ) {
00297                 ERR("initial tls configuration fixup failed\n");
00298                 return -1;
00299         }
00300         /* declare configuration */
00301         if (cfg_declare("tls", tls_cfg_def, &default_tls_cfg,
00302                                                         cfg_sizeof(tls), &tls_cfg)) {
00303                 ERR("failed to register the configuration\n");
00304                 return -1;
00305         }
00306         /* Convert tls_method parameter to integer */
00307         method = tls_parse_method(&cfg_get(tls, tls_cfg, method));
00308         if (method < 0) {
00309                 ERR("Invalid tls_method parameter value\n");
00310                 return -1;
00311         }
00312         /* fill mod_params */
00313         mod_params.method = method;
00314         mod_params.verify_cert = cfg_get(tls, tls_cfg, verify_cert);
00315         mod_params.verify_depth = cfg_get(tls, tls_cfg, verify_depth);
00316         mod_params.require_cert = cfg_get(tls, tls_cfg, require_cert);
00317         mod_params.pkey_file = cfg_get(tls, tls_cfg, private_key);
00318         mod_params.ca_file = cfg_get(tls, tls_cfg, ca_list);
00319         mod_params.crl_file = cfg_get(tls, tls_cfg, crl);
00320         mod_params.cert_file = cfg_get(tls, tls_cfg, certificate);
00321         mod_params.cipher_list = cfg_get(tls, tls_cfg, cipher_list);
00322 
00323         tls_domains_cfg =
00324                         (tls_domains_cfg_t**)shm_malloc(sizeof(tls_domains_cfg_t*));
00325         if (!tls_domains_cfg) {
00326                 ERR("Not enough shared memory left\n");
00327                 goto error;
00328         }
00329         *tls_domains_cfg = NULL;
00330 
00331         register_tls_hooks(&tls_h);
00332         register_select_table(tls_sel);
00333         /* register the rpc interface */
00334         if (rpc_register_array(tls_rpc)!=0) {
00335                 LOG(L_ERR, "failed to register RPC commands\n");
00336                 goto error;
00337         }
00338 
00339          /* if (init_tls() < 0) return -1; */
00340         
00341         tls_domains_cfg_lock = lock_alloc();
00342         if (tls_domains_cfg_lock == 0) {
00343                 ERR("Unable to create TLS configuration lock\n");
00344                 goto error;
00345         }
00346         if (lock_init(tls_domains_cfg_lock) == 0) {
00347                 lock_dealloc(tls_domains_cfg_lock);
00348                 ERR("Unable to initialize TLS configuration lock\n");
00349                 goto error;
00350         }
00351         if (tls_ct_wq_init() < 0) {
00352                 ERR("Unable to initialize TLS buffering\n");
00353                 goto error;
00354         }
00355         if (cfg_get(tls, tls_cfg, config_file).s) {
00356                 *tls_domains_cfg = 
00357                         tls_load_config(&cfg_get(tls, tls_cfg, config_file));
00358                 if (!(*tls_domains_cfg)) goto error;
00359         } else {
00360                 *tls_domains_cfg = tls_new_cfg();
00361                 if (!(*tls_domains_cfg)) goto error;
00362         }
00363 
00364         if (tls_check_sockets(*tls_domains_cfg) < 0)
00365                 goto error;
00366 
00367         return 0;
00368 error:
00369         destroy_tls_h();
00370         return -1;
00371 }
00372 
00373 
00374 static int mod_child(int rank)
00375 {
00376         if (tls_disable || (tls_domains_cfg==0))
00377                 return 0;
00378         /* fix tls config only from the main proc/PROC_INIT., when we know 
00379          * the exact process number and before any other process starts*/
00380         if (rank == PROC_INIT){
00381                 if (cfg_get(tls, tls_cfg, config_file).s){
00382                         if (tls_fix_domains_cfg(*tls_domains_cfg,
00383                                                                         &srv_defaults, &cli_defaults) < 0)
00384                                 return -1;
00385                 }else{
00386                         if (tls_fix_domains_cfg(*tls_domains_cfg,
00387                                                                         &mod_params, &mod_params) < 0)
00388                                 return -1;
00389                 }
00390         }
00391         return 0;
00392 }
00393 
00394 
00395 static void destroy(void)
00396 {
00397         /* tls is destroyed via the registered destroy_tls_h callback
00398            => nothing to do here */
00399 }
00400 
00401 
00402 static int is_peer_verified(struct sip_msg* msg, char* foo, char* foo2)
00403 {
00404         struct tcp_connection *c;
00405         SSL *ssl;
00406         long ssl_verify;
00407         X509 *x509_cert;
00408 
00409         DBG("started...\n");
00410         if (msg->rcv.proto != PROTO_TLS) {
00411                 ERR("proto != TLS --> peer can't be verified, return -1\n");
00412                 return -1;
00413         }
00414 
00415         DBG("trying to find TCP connection of received message...\n");
00416 
00417         c = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0,
00418                                         cfg_get(tls, tls_cfg, con_lifetime));
00419         if (c && c->type != PROTO_TLS) {
00420                 ERR("Connection found but is not TLS\n");
00421                 tcpconn_put(c);
00422                 return -1;
00423         }
00424 
00425         if (!c->extra_data) {
00426                 LM_ERR("no extra_data specified in TLS/TCP connection found."
00427                                 " This should not happen... return -1\n");
00428                 tcpconn_put(c);
00429                 return -1;
00430         }
00431 
00432         ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
00433 
00434         ssl_verify = SSL_get_verify_result(ssl);
00435         if ( ssl_verify != X509_V_OK ) {
00436                 LM_WARN("verification of presented certificate failed... return -1\n");
00437                 tcpconn_put(c);
00438                 return -1;
00439         }
00440 
00441         /* now, we have only valid peer certificates or peers without certificates.
00442          * Thus we have to check for the existence of a peer certificate
00443          */
00444         x509_cert = SSL_get_peer_certificate(ssl);
00445         if ( x509_cert == NULL ) {
00446                 LM_WARN("tlsops:is_peer_verified: WARNING: peer did not presented "
00447                         "a certificate. Thus it could not be verified... return -1\n");
00448                 tcpconn_put(c);
00449                 return -1;
00450         }
00451 
00452         X509_free(x509_cert);
00453 
00454         tcpconn_put(c);
00455 
00456         LM_DBG("tlsops:is_peer_verified: peer is successfuly verified"
00457                 "...done\n");
00458         return 1;
00459 }