tls_cfg.c

Go to the documentation of this file.
00001 /* 
00002  * Copyright (C) 2010 iptelorg GmbH
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00024 /*
00025  * History:
00026  * --------
00027  *  2010-05-27  initial version (andrei)
00028 */
00029 
00030 #include "tls_cfg.h"
00031 #include "../../config.h"
00032 #include "../../str.h"
00033 #include "../../ut.h"
00034 #include "../../pt.h"
00035 #include "../../mem/shm_mem.h"
00036 
00037 struct cfg_group_tls default_tls_cfg = {
00038         0, /* tls_force_run */
00039         STR_STATIC_INIT("TLSv1"), /* method */
00040         0, /* verify_certificate */
00041         9, /* verify_depth */
00042         0, /* require_certificate */
00043         STR_NULL, /* private_key (default value set in fix_tls_cfg) */
00044         STR_NULL, /* ca_list (default value set in fix_tls_cfg) */
00045         STR_NULL, /* crl (default value set in fix_tls_cfg) */
00046         STR_NULL, /* certificate (default value set in fix_tls_cfg) */
00047         STR_NULL, /* cipher_list (default value set in fix_tls_cfg) */
00048         0, /* session_cache */
00049         STR_STATIC_INIT("sip-router-tls-3.1"), /* session_id */
00050         STR_NULL, /* config_file */
00051         3, /* log  (L_DBG)*/
00052         3, /* debug (L_DBG) */
00053         600, /* con_lifetime (s)*/
00054         1, /* disable_compression */
00055 #if OPENSSL_VERSION_NUMBER >= 0x01000000L
00056         1, /* ssl_release_buffers (on, avoid extra buffering) */
00057 #else
00058         -1, /* ssl_release_buffers: old openssl, leave it untouched */
00059 #endif /* openssl >= 1.0.0 */
00060 #if OPENSSL_VERSION_NUMBER >= 0x01000000L && ! defined OPENSSL_NO_BUF_FREELISTS
00061         0, /* ssl_freelist_max  (immediately free) */
00062 #else
00063         -1, /* ssl_freelist_max: old openssl, leave it untouched */
00064 #endif /* openssl >= 1.0.0 */
00065         -1, /* ssl_max_send_fragment (use the default: 16k), requires openssl
00066                    > 0.9.9 */
00067         0, /* ssl_read_ahead (off, not needed, we have our own buffering BIO)*/
00068         -1, /* low_mem_threshold1 */
00069         -1, /* low_mem_threshold2 */
00070         10*1024*1024, /* ct_wq_max: 10 Mb by default */
00071         64*1024, /* con_ct_wq_max: 64Kb by default */
00072         4096, /* ct_wq_blk_size */
00073         0 /* send_close_notify (off by default)*/
00074 };
00075 
00076 void* tls_cfg = &default_tls_cfg;
00077 
00078 
00079 /* if *to<0 to=default_val, else if to>max_val to=max_val */
00080 static void fix_timeout(char* name, int* to, int default_val, unsigned max_val)
00081 {
00082         if (*to < 0) *to=default_val;
00083         else if ((unsigned)*to > max_val){
00084                 WARN("%s: timeout too big (%u), the maximum value is %u\n",
00085                                 name, *to, max_val);
00086                 *to=max_val;
00087         }
00088 }
00089 
00090 
00091 static int fix_con_lt(void* cfg_h, str* gname, str* name, void** val)
00092 {
00093         int v;
00094         v=S_TO_TICKS((int)(long)*val);
00095         fix_timeout("tls.connection_timeout", &v,
00096                                         MAX_TLS_CON_LIFETIME, MAX_TLS_CON_LIFETIME);
00097         *val=(void*)(long)v;
00098         return 0;
00099 }
00100 
00101 
00102 
00104 static int fix_rel_pathname(void* cfg_h, str* gname, str* name, void** val)
00105 {
00106         str* f;
00107         str new_f;
00108         /* the cfg framework will immediately "clone" the value so
00109            we can pass a pointer to a temporary static buffer to it
00110            (using a dyn. alloc'd buffer would introduce the additional
00111             problem of having to free it somehow) */
00112         static char path_buf[MAX_PATH_SIZE];
00113 
00114         f = *val;
00115         /* use absolute paths, except when the path starts with
00116            '.' (in this case leave it as it is) */
00117         if (f && f->s && f->len && *f->s != '.' && *f->s != '/') {
00118                 new_f.s = get_abs_pathname(0, f);
00119                 if (new_f.s == 0)
00120                         return -1;
00121                 new_f.len = strlen(new_f.s);
00122                 if (new_f.len >= MAX_PATH_SIZE) {
00123                         ERR("%.*s.%.*s path too long (%d bytes): \"%.*s\"\n",
00124                                         gname->len, gname->s, name->len, name->s,
00125                                         new_f.len, new_f.len, new_f.s);
00126                         pkg_free(new_f.s);
00127                         return -1;
00128                 }
00129                 memcpy(path_buf, new_f.s, new_f.len);
00130                 pkg_free(new_f.s);
00131                 new_f.s = path_buf;
00132                 *f = new_f;
00133         }
00134         return 0;
00135 }
00136 
00137 
00138 
00139 cfg_def_t       tls_cfg_def[] = {
00140         {"force_run", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0,
00141                 "force loading the tls module even when initial sanity checks fail"},
00142         {"method",   CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00143                 "TLS method used (TLSv1, SSLv3, SSLv2, SSLv23)"},
00144         {"verify_certificate", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0,
00145                 "if enabled the certificates will be verified" },
00146         {"verify_depth", CFG_VAR_INT | CFG_READONLY, 0, 100, 0, 0,
00147                 "sets how far up the certificate chain will the certificate"
00148                 " verification go in the search for a trusted CA" },
00149         {"require_certificate", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0,
00150                 "if enabled a certificate will be required from clients" },
00151         {"private_key", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00152                 "name of the file containing the private key (pem format), if not"
00153                 " contained in the certificate file" },
00154         {"ca_list", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00155                 "name of the file containing the trusted CA list (pem format)" },
00156         {"crl", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00157                 "name of the file containing the CRL  (certificare revocation list"
00158                         " in pem format)" },
00159         {"certificate", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00160                 "name of the file containing the certificate (pem format)" },
00161         {"cipher_list", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00162                 "list of the accepted ciphers (strings separated by colons)" },
00163         {"session_cache", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0,
00164                 "enables or disables the session cache" },
00165         {"session_id", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0,
00166                 "string used for the session id" },
00167         {"config", CFG_VAR_STR, 0, 0, fix_rel_pathname, 0,
00168                 "tls config file name (used for the per domain options)" },
00169         {"log", CFG_VAR_INT | CFG_ATOMIC, 0, 1000, 0, 0,
00170                 "tls info messages log level" },
00171         {"debug", CFG_VAR_INT | CFG_ATOMIC, 0, 1000, 0, 0,
00172                 "tls debug messages log level" },
00173         {"connection_timeout", CFG_VAR_INT | CFG_ATOMIC,
00174                                                         -1, MAX_TLS_CON_LIFETIME, fix_con_lt, 0,
00175                 "initial connection lifetime (in s) (obsolete)" },
00176         {"disable_compression", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0,
00177                 "if set disable the built-in OpenSSL compression" },
00178         {"ssl_release_buffers", CFG_VAR_INT | CFG_READONLY, -1, 1, 0, 0,
00179                 "quickly release internal OpenSSL read or write buffers."
00180             " Works only for OpenSSL >= 1.0."},
00181         {"ssl_free_list_max", CFG_VAR_INT | CFG_READONLY, -1, 1<<30, 0, 0,
00182                 "maximum number of free/cached memory chunks that OpenSSL"
00183                 " will keep per connection. Works only for OpenSSL >= 1.0."},
00184         {"ssl_max_send_fragment", CFG_VAR_INT | CFG_READONLY, -1, 65536, 0, 0,
00185                 "sets the maximum number of bytes (clear text) send into one TLS"
00186                 " record. Valid values are between 512 and 16384."
00187                 " Works only for OpenSSL >= 0.9.9"},
00188         {"ssl_read_ahead", CFG_VAR_INT | CFG_READONLY, -1, 1, 0, 0,
00189                 "Enables read ahead, reducing the number of BIO read calls done"
00190                 " internally by the OpenSSL library. Note that in newer tls"
00191             " module versions it is better to have read ahead disabled, since"
00192                 " everything it is buffered in memory anyway"},
00193         {"low_mem_threshold1", CFG_VAR_INT | CFG_ATOMIC, -1, 1<<30, 0, 0,
00194                 "sets the minimum amount of free memory for accepting new TLS"
00195                 " connections (KB)"},
00196         {"low_mem_threshold2", CFG_VAR_INT | CFG_ATOMIC, -1, 1<<30, 0, 0,
00197                 "sets the minimum amount of free memory after which no more TLS"
00198                 " operations will be attempted (even on existing connections)" },
00199         {"ct_wq_max", CFG_VAR_INT | CFG_ATOMIC, 0, 1<<30, 0, 0,
00200                 "maximum bytes queued globally for write when write has to wait due"
00201                 " to TLS-level renegotiation (SSL_ERROR_WANT_READ) or initial TLS"
00202                 " connection establishment (it is different from tcp.wq_max,"
00203                 " which works at the TCP connection level)"},
00204         {"con_ct_wq_max", CFG_VAR_INT | CFG_ATOMIC, 0, 4*1024*1024, 0, 0,
00205                 "maximum bytes queued for write per connection when write has to wait"
00206                 " due to TLS-level renegotiation (SSL_ERROR_WANT_READ) or initial TLS"
00207                 " connection establishment (it is different from tcp.conn_wq_max,"
00208                 " which works at the TCP connection level)"},
00209         {"ct_wq_blk_size", CFG_VAR_INT | CFG_ATOMIC, 1, 65536, 0, 0,
00210                 "internal TLS pre-write (clear-text) queue minimum block size"
00211                 " (advanced tunning or debugging for now)"},
00212         {"send_close_notify", CFG_VAR_INT | CFG_ATOMIC, 0, 1, 0, 0,
00213                 "enable/disable sending a close notify TLS shutdown alert"
00214                         " before closing the corresponding TCP connection."
00215                         "Note that having it enabled has a performance impact."},
00216         {0, 0, 0, 0, 0, 0}
00217 };
00218 
00219 
00220 
00230 static int fix_initial_pathname(str* path, char* def)
00231 {
00232         str new_path;
00233         if (path->s && path->len && *path->s != '.' && *path->s != '/') {
00234                 new_path.s = get_abs_pathname(0, path);
00235                 if (new_path.s == 0) return -1;
00236                 new_path.len = strlen(new_path.s);
00237                 pkg_free(path->s);
00238                 *path = new_path;
00239         } else if (path->s == 0 && def) {
00240                 /* use defaults */
00241                 new_path.len = strlen(def);
00242                 new_path.s = def;
00243                 new_path.s = get_abs_pathname(0, &new_path);
00244                 if (new_path.s == 0) return -1;
00245                 new_path.len = strlen(new_path.s);
00246                 *path = new_path;
00247         }
00248         return 0;
00249 }
00250 
00251 
00252 
00256 int fix_tls_cfg(struct cfg_group_tls* cfg)
00257 {
00258         cfg->con_lifetime = S_TO_TICKS(cfg->con_lifetime);
00259         fix_timeout("tls_connection_timeout", &cfg->con_lifetime, 
00260                                                 MAX_TLS_CON_LIFETIME, MAX_TLS_CON_LIFETIME);
00261         /* Update relative paths of files configured through modparams, relative
00262          * pathnames will be converted to absolute and the directory of the main
00263          * SER configuration file will be used as reference.
00264          */
00265         if (fix_initial_pathname(&cfg->config_file, 0) < 0)
00266                 return -1;
00267         if (fix_initial_pathname(&cfg->private_key, TLS_PKEY_FILE) < 0)
00268                 return -1;
00269         if (fix_initial_pathname(&cfg->ca_list, TLS_CA_FILE) < 0 )
00270                 return -1;
00271         if (fix_initial_pathname(&cfg->crl, TLS_CRL_FILE) < 0 )
00272                 return -1;
00273         if (fix_initial_pathname(&cfg->certificate, TLS_CERT_FILE) < 0)
00274                 return -1;
00275         
00276         return 0;
00277 }
00278 
00279 
00280 
00281 
00282 /* vi: set ts=4 sw=4 tw=79:ai:cindent: */