tls_rpc.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * TLS module - management interface
00005  *
00006  * Copyright (C) 2001-2003 FhG FOKUS
00007  * Copyright (C) 2005 iptelorg GmbH
00008  *
00009  * This file is part of sip-router, a free SIP server.
00010  *
00011  * Permission to use, copy, modify, and distribute this software for any
00012  * purpose with or without fee is hereby granted, provided that the above
00013  * copyright notice and this permission notice appear in all copies.
00014  *
00015  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00016  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00017  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00018  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00019  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00020  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00021  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00022  */
00030 #include "../../rpc.h"
00031 #include "../../tcp_conn.h"
00032 #include "../../tcp_info.h"
00033 #include "../../timer.h"
00034 #include "../../cfg/cfg.h"
00035 #include "tls_init.h"
00036 #include "tls_mod.h"
00037 #include "tls_domain.h"
00038 #include "tls_config.h"
00039 #include "tls_util.h"
00040 #include "tls_server.h"
00041 #include "tls_ct_wrq.h"
00042 #include "tls_rpc.h"
00043 #include "tls_cfg.h"
00044 
00045 static const char* tls_reload_doc[2] = {
00046         "Reload TLS configuration file",
00047         0
00048 };
00049 
00050 static void tls_reload(rpc_t* rpc, void* ctx)
00051 {
00052         tls_domains_cfg_t* cfg;
00053         str tls_domains_cfg_file;
00054 
00055         tls_domains_cfg_file = cfg_get(tls, tls_cfg, config_file);
00056         if (!tls_domains_cfg_file.s) {
00057                 rpc->fault(ctx, 500, "No TLS configuration file configured");
00058                 return;
00059         }
00060 
00061              /* Try to delete old configurations first */
00062         collect_garbage();
00063 
00064         cfg = tls_load_config(&tls_domains_cfg_file);
00065         if (!cfg) {
00066                 rpc->fault(ctx, 500, "Error while loading TLS configuration file"
00067                                                         " (consult server log)");
00068                 return;
00069         }
00070 
00071         if (tls_fix_domains_cfg(cfg, &srv_defaults, &cli_defaults) < 0) {
00072                 rpc->fault(ctx, 500, "Error while fixing TLS configuration"
00073                                                                 " (consult server log)");
00074                 goto error;
00075         }
00076         if (tls_check_sockets(cfg) < 0) {
00077                 rpc->fault(ctx, 500, "No server listening socket found for one of"
00078                                                         " TLS domains (consult server log)");
00079                 goto error;
00080         }
00081 
00082         DBG("TLS configuration successfuly loaded");
00083         cfg->next = (*tls_domains_cfg);
00084         *tls_domains_cfg = cfg;
00085         return;
00086 
00087  error:
00088         tls_free_cfg(cfg);
00089         
00090 }
00091 
00092 
00093 static const char* tls_list_doc[2] = {
00094         "List currently open TLS connections",
00095         0
00096 };
00097 
00098 extern gen_lock_t* tcpconn_lock;
00099 extern struct tcp_connection** tcpconn_id_hash;
00100 
00101 static void tls_list(rpc_t* rpc, void* c)
00102 {
00103         char buf[128];
00104         char src_ip[IP_ADDR_MAX_STR_SIZE];
00105         char dst_ip[IP_ADDR_MAX_STR_SIZE];
00106         void* handle;
00107         char* tls_info;
00108         char* state;
00109         struct tls_extra_data* tls_d;
00110         struct tcp_connection* con;
00111         int i, len, timeout;
00112 
00113         TCPCONN_LOCK;
00114         for(i = 0; i < TCP_ID_HASH_SIZE; i++) {
00115                 for (con = tcpconn_id_hash[i]; con; con = con->id_next) {
00116                         if (con->rcv.proto != PROTO_TLS) continue;
00117                         tls_d = con->extra_data;
00118                         rpc->add(c, "{", &handle);
00119                         /* tcp data */
00120                         if ((len = ip_addr2sbuf(&con->rcv.src_ip, src_ip, sizeof(src_ip)))
00121                                         == 0)
00122                                 BUG("failed to convert source ip");
00123                         src_ip[len] = 0;
00124                         if ((len = ip_addr2sbuf(&con->rcv.dst_ip, dst_ip, sizeof(dst_ip)))
00125                                         == 0)
00126                                 BUG("failed to convert destination ip");
00127                         dst_ip[len] = 0;
00128                         timeout = TICKS_TO_S(con->timeout - get_ticks_raw());
00129                         rpc->struct_add(handle, "ddsdsd",
00130                                         "id", con->id,
00131                                         "timeout", timeout,
00132                                         "src_ip", src_ip,
00133                                         "src_port", con->rcv.src_port,
00134                                         "dst_ip", dst_ip,
00135                                         "dst_port", con->rcv.dst_port);
00136                         if (tls_d) {
00137                                 if(SSL_get_current_cipher(tls_d->ssl)) {
00138                                         tls_info = SSL_CIPHER_description(
00139                                                                         SSL_get_current_cipher(tls_d->ssl),
00140                                                                         buf, sizeof(buf));
00141                                         len = strlen(buf);
00142                                         if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
00143                                 } else {
00144                                         tls_info = "unknown";
00145                                 }
00146                                 /* tls data */
00147                                 state = "unknown/error";
00148                                 lock_get(&con->write_lock);
00149                                         switch(tls_d->state) {
00150                                                 case S_TLS_NONE:
00151                                                         state = "none/init";
00152                                                         break;
00153                                                 case S_TLS_ACCEPTING:
00154                                                         state = "tls_accept";
00155                                                         break;
00156                                                 case S_TLS_CONNECTING:
00157                                                         state = "tls_connect";
00158                                                         break;
00159                                                 case S_TLS_ESTABLISHED:
00160                                                         state = "established";
00161                                                         break;
00162                                         }
00163                                         rpc->struct_add(handle, "sddds",
00164                                                         "cipher", tls_info,
00165                                                         "ct_wq_size", tls_d->ct_wq?
00166                                                                                         tls_d->ct_wq->queued:0,
00167                                                         "enc_rd_buf", tls_d->enc_rd_buf?
00168                                                                                         tls_d->enc_rd_buf->size:0,
00169                                                         "flags", tls_d->flags,
00170                                                         "state", state
00171                                                         );
00172                                 lock_release(&con->write_lock);
00173                         } else {
00174                                 rpc->struct_add(handle, "sddds",
00175                                                 "cipher", "unknown",
00176                                                 "ct_wq_size", 0,
00177                                                 "enc_rd_buf", 0,
00178                                                 "flags", 0,
00179                                                 "state", "pre-init"
00180                                                 );
00181                         }
00182                 }
00183         }
00184         TCPCONN_UNLOCK;
00185 }
00186 
00187 
00188 
00189 static const char* tls_info_doc[2] = {
00190         "Returns internal tls related info.",
00191         0 };
00192 
00193 static void tls_info(rpc_t* rpc, void* c)
00194 {
00195         struct tcp_gen_info ti;
00196         void* handle;
00197 
00198         tcp_get_info(&ti);
00199         rpc->add(c, "{", &handle);
00200         rpc->struct_add(handle, "ddd",
00201                         "max_connections", ti.tls_max_connections,
00202                         "opened_connections", ti.tls_connections_no,
00203                         "clear_text_write_queued_bytes", tls_ct_wq_total_bytes());
00204 }
00205 
00206 
00207 
00208 static const char* tls_options_doc[2] = {
00209         "Dumps all the tls config options.",
00210         0 };
00211 
00212 static void tls_options(rpc_t* rpc, void* c)
00213 {
00214         void* handle;
00215         rpc->add(c, "{", &handle);
00216         rpc->struct_add(handle, "dSdddSSSSdSSdddddddddddddd",
00217                 "force_run",    cfg_get(tls, tls_cfg, force_run),
00218                 "method",               &cfg_get(tls, tls_cfg, method),
00219                 "verify_certificate", cfg_get(tls, tls_cfg, verify_cert),
00220 
00221                 "verify_depth",         cfg_get(tls, tls_cfg, verify_depth),
00222                 "require_certificate",  cfg_get(tls, tls_cfg, require_cert),
00223                 "private_key",          &cfg_get(tls, tls_cfg, private_key),
00224                 "ca_list",                      &cfg_get(tls, tls_cfg, ca_list),
00225                 "certificate",          &cfg_get(tls, tls_cfg, certificate),
00226                 "cipher_list",          &cfg_get(tls, tls_cfg, cipher_list),
00227                 "session_cache",        cfg_get(tls, tls_cfg, session_cache),
00228                 "session_id",           &cfg_get(tls, tls_cfg, session_id),
00229                 "config",                       &cfg_get(tls, tls_cfg, config_file),
00230                 "log",                          cfg_get(tls, tls_cfg, log),
00231                 "debug",                        cfg_get(tls, tls_cfg, debug),
00232                 "connection_timeout", TICKS_TO_S(cfg_get(tls, tls_cfg, con_lifetime)),
00233                 "disable_compression",  cfg_get(tls, tls_cfg, disable_compression),
00234                 "ssl_release_buffers",  cfg_get(tls, tls_cfg, ssl_release_buffers),
00235                 "ssl_freelist_max",             cfg_get(tls, tls_cfg, ssl_freelist_max),
00236                 "ssl_max_send_fragment", cfg_get(tls, tls_cfg, ssl_max_send_fragment),
00237                 "ssl_read_ahead",               cfg_get(tls, tls_cfg, ssl_read_ahead),
00238                 "send_close_notify",    cfg_get(tls, tls_cfg, send_close_notify),
00239                 "low_mem_threshold1",   cfg_get(tls, tls_cfg, low_mem_threshold1),
00240                 "low_mem_threshold2",   cfg_get(tls, tls_cfg, low_mem_threshold2),
00241                 "ct_wq_max",                    cfg_get(tls, tls_cfg, ct_wq_max),
00242                 "con_ct_wq_max",                cfg_get(tls, tls_cfg, con_ct_wq_max),
00243                 "ct_wq_blk_size",               cfg_get(tls, tls_cfg, ct_wq_blk_size)
00244                 );
00245 }
00246 
00247 
00248 
00249 
00250 rpc_export_t tls_rpc[] = {
00251         {"tls.reload", tls_reload, tls_reload_doc, 0},
00252         {"tls.list",   tls_list,   tls_list_doc,   RET_ARRAY},
00253         {"tls.info",   tls_info,   tls_info_doc, 0},
00254         {"tls.options",tls_options, tls_options_doc, 0},
00255         {0, 0, 0, 0}
00256 };