00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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 };