mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
7.2 KiB
263 lines
7.2 KiB
/*
|
|
* TLS module - management interface
|
|
*
|
|
* Copyright (C) 2005 iptelorg GmbH
|
|
* Copyright (C) 2013 Motorola Solutions, Inc.
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* 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.
|
|
*/
|
|
/** tls module management interface (rpc).
|
|
* @file tls_rpc.c
|
|
* @ingroup tls
|
|
* Module: @ref tls
|
|
*/
|
|
|
|
|
|
#include "../../rpc.h"
|
|
#include "../../tcp_conn.h"
|
|
#include "../../tcp_info.h"
|
|
#include "../../timer.h"
|
|
#include "../../cfg/cfg.h"
|
|
#include "../../dprint.h"
|
|
#include "tls_init.h"
|
|
#include "tls_mod.h"
|
|
#include "tls_domain.h"
|
|
#include "tls_config.h"
|
|
#include "tls_util.h"
|
|
#include "tls_server.h"
|
|
#include "tls_ct_wrq.h"
|
|
#include "tls_rpc.h"
|
|
#include "tls_cfg.h"
|
|
|
|
static const char* tls_reload_doc[2] = {
|
|
"Reload TLS configuration file",
|
|
0
|
|
};
|
|
|
|
static void tls_reload(rpc_t* rpc, void* ctx)
|
|
{
|
|
tls_domains_cfg_t* cfg;
|
|
str tls_domains_cfg_file;
|
|
|
|
tls_domains_cfg_file = cfg_get(tls, tls_cfg, config_file);
|
|
if (!tls_domains_cfg_file.s) {
|
|
rpc->fault(ctx, 500, "No TLS configuration file configured");
|
|
return;
|
|
}
|
|
|
|
/* Try to delete old configurations first */
|
|
collect_garbage();
|
|
|
|
cfg = tls_load_config(&tls_domains_cfg_file);
|
|
|
|
if (!cfg) {
|
|
rpc->fault(ctx, 500, "Error while loading TLS configuration file"
|
|
" (consult server log)");
|
|
return;
|
|
}
|
|
|
|
if (tls_fix_domains_cfg(cfg, &srv_defaults, &cli_defaults) < 0) {
|
|
rpc->fault(ctx, 500, "Error while fixing TLS configuration"
|
|
" (consult server log)");
|
|
goto error;
|
|
}
|
|
if (tls_check_sockets(cfg) < 0) {
|
|
rpc->fault(ctx, 500, "No server listening socket found for one of"
|
|
" TLS domains (consult server log)");
|
|
goto error;
|
|
}
|
|
|
|
DBG("TLS configuration successfuly loaded");
|
|
|
|
lock_get(tls_domains_cfg_lock);
|
|
|
|
cfg->next = (*tls_domains_cfg);
|
|
*tls_domains_cfg = cfg;
|
|
|
|
lock_release(tls_domains_cfg_lock);
|
|
|
|
return;
|
|
|
|
error:
|
|
tls_free_cfg(cfg);
|
|
|
|
}
|
|
|
|
|
|
static const char* tls_list_doc[2] = {
|
|
"List currently open TLS connections",
|
|
0
|
|
};
|
|
|
|
extern gen_lock_t* tcpconn_lock;
|
|
extern struct tcp_connection** tcpconn_id_hash;
|
|
|
|
static void tls_list(rpc_t* rpc, void* c)
|
|
{
|
|
char buf[128];
|
|
char src_ip[IP_ADDR_MAX_STR_SIZE];
|
|
char dst_ip[IP_ADDR_MAX_STR_SIZE];
|
|
void* handle;
|
|
char* tls_info;
|
|
char* state;
|
|
struct tls_extra_data* tls_d;
|
|
struct tcp_connection* con;
|
|
int i, len, timeout;
|
|
|
|
TCPCONN_LOCK;
|
|
for(i = 0; i < TCP_ID_HASH_SIZE; i++) {
|
|
for (con = tcpconn_id_hash[i]; con; con = con->id_next) {
|
|
if (con->rcv.proto != PROTO_TLS) continue;
|
|
tls_d = con->extra_data;
|
|
rpc->add(c, "{", &handle);
|
|
/* tcp data */
|
|
if ((len = ip_addr2sbuf(&con->rcv.src_ip, src_ip, sizeof(src_ip)))
|
|
== 0)
|
|
BUG("failed to convert source ip");
|
|
src_ip[len] = 0;
|
|
if ((len = ip_addr2sbuf(&con->rcv.dst_ip, dst_ip, sizeof(dst_ip)))
|
|
== 0)
|
|
BUG("failed to convert destination ip");
|
|
dst_ip[len] = 0;
|
|
timeout = TICKS_TO_S(con->timeout - get_ticks_raw());
|
|
rpc->struct_add(handle, "ddsdsd",
|
|
"id", con->id,
|
|
"timeout", timeout,
|
|
"src_ip", src_ip,
|
|
"src_port", con->rcv.src_port,
|
|
"dst_ip", dst_ip,
|
|
"dst_port", con->rcv.dst_port);
|
|
if (tls_d) {
|
|
if(SSL_get_current_cipher(tls_d->ssl)) {
|
|
tls_info = SSL_CIPHER_description(
|
|
SSL_get_current_cipher(tls_d->ssl),
|
|
buf, sizeof(buf));
|
|
len = strlen(buf);
|
|
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
|
|
} else {
|
|
tls_info = "unknown";
|
|
}
|
|
/* tls data */
|
|
state = "unknown/error";
|
|
lock_get(&con->write_lock);
|
|
switch(tls_d->state) {
|
|
case S_TLS_NONE:
|
|
state = "none/init";
|
|
break;
|
|
case S_TLS_ACCEPTING:
|
|
state = "tls_accept";
|
|
break;
|
|
case S_TLS_CONNECTING:
|
|
state = "tls_connect";
|
|
break;
|
|
case S_TLS_ESTABLISHED:
|
|
state = "established";
|
|
break;
|
|
}
|
|
rpc->struct_add(handle, "sddds",
|
|
"cipher", tls_info,
|
|
"ct_wq_size", tls_d->ct_wq?
|
|
tls_d->ct_wq->queued:0,
|
|
"enc_rd_buf", tls_d->enc_rd_buf?
|
|
tls_d->enc_rd_buf->size:0,
|
|
"flags", tls_d->flags,
|
|
"state", state
|
|
);
|
|
lock_release(&con->write_lock);
|
|
} else {
|
|
rpc->struct_add(handle, "sddds",
|
|
"cipher", "unknown",
|
|
"ct_wq_size", 0,
|
|
"enc_rd_buf", 0,
|
|
"flags", 0,
|
|
"state", "pre-init"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
TCPCONN_UNLOCK;
|
|
}
|
|
|
|
|
|
|
|
static const char* tls_info_doc[2] = {
|
|
"Returns internal tls related info.",
|
|
0 };
|
|
|
|
static void tls_info(rpc_t* rpc, void* c)
|
|
{
|
|
struct tcp_gen_info ti;
|
|
void* handle;
|
|
|
|
tcp_get_info(&ti);
|
|
rpc->add(c, "{", &handle);
|
|
rpc->struct_add(handle, "ddd",
|
|
"max_connections", ti.tls_max_connections,
|
|
"opened_connections", ti.tls_connections_no,
|
|
"clear_text_write_queued_bytes", tls_ct_wq_total_bytes());
|
|
}
|
|
|
|
|
|
|
|
static const char* tls_options_doc[2] = {
|
|
"Dumps all the tls config options.",
|
|
0 };
|
|
|
|
static void tls_options(rpc_t* rpc, void* c)
|
|
{
|
|
void* handle;
|
|
rpc->add(c, "{", &handle);
|
|
rpc->struct_add(handle, "dSdddSSSSdSSdddddddddddddd",
|
|
"force_run", cfg_get(tls, tls_cfg, force_run),
|
|
"method", &cfg_get(tls, tls_cfg, method),
|
|
"verify_certificate", cfg_get(tls, tls_cfg, verify_cert),
|
|
|
|
"verify_depth", cfg_get(tls, tls_cfg, verify_depth),
|
|
"require_certificate", cfg_get(tls, tls_cfg, require_cert),
|
|
"private_key", &cfg_get(tls, tls_cfg, private_key),
|
|
"ca_list", &cfg_get(tls, tls_cfg, ca_list),
|
|
"certificate", &cfg_get(tls, tls_cfg, certificate),
|
|
"cipher_list", &cfg_get(tls, tls_cfg, cipher_list),
|
|
"session_cache", cfg_get(tls, tls_cfg, session_cache),
|
|
"session_id", &cfg_get(tls, tls_cfg, session_id),
|
|
"config", &cfg_get(tls, tls_cfg, config_file),
|
|
"log", cfg_get(tls, tls_cfg, log),
|
|
"debug", cfg_get(tls, tls_cfg, debug),
|
|
"connection_timeout", TICKS_TO_S(cfg_get(tls, tls_cfg, con_lifetime)),
|
|
"disable_compression", cfg_get(tls, tls_cfg, disable_compression),
|
|
"ssl_release_buffers", cfg_get(tls, tls_cfg, ssl_release_buffers),
|
|
"ssl_freelist_max", cfg_get(tls, tls_cfg, ssl_freelist_max),
|
|
"ssl_max_send_fragment", cfg_get(tls, tls_cfg, ssl_max_send_fragment),
|
|
"ssl_read_ahead", cfg_get(tls, tls_cfg, ssl_read_ahead),
|
|
"send_close_notify", cfg_get(tls, tls_cfg, send_close_notify),
|
|
"low_mem_threshold1", cfg_get(tls, tls_cfg, low_mem_threshold1),
|
|
"low_mem_threshold2", cfg_get(tls, tls_cfg, low_mem_threshold2),
|
|
"ct_wq_max", cfg_get(tls, tls_cfg, ct_wq_max),
|
|
"con_ct_wq_max", cfg_get(tls, tls_cfg, con_ct_wq_max),
|
|
"ct_wq_blk_size", cfg_get(tls, tls_cfg, ct_wq_blk_size)
|
|
);
|
|
}
|
|
|
|
|
|
|
|
|
|
rpc_export_t tls_rpc[] = {
|
|
{"tls.reload", tls_reload, tls_reload_doc, 0},
|
|
{"tls.list", tls_list, tls_list_doc, RET_ARRAY},
|
|
{"tls.info", tls_info, tls_info_doc, 0},
|
|
{"tls.options",tls_options, tls_options_doc, 0},
|
|
{0, 0, 0, 0}
|
|
};
|