From 33dfbdea568b11cd9183248d85e9385e39d4b8c4 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Fri, 10 Jan 2014 09:17:56 +0100 Subject: [PATCH] worker will send information on the negotiated TLS/DTLS ciphersuites to main. --- src/ipc.proto | 7 ++++ src/main-misc.c | 102 ++++++++++++++++++++++++++++------------------- src/main.h | 3 ++ src/vpn.h | 2 + src/worker-vpn.c | 22 +++++++++- 5 files changed, 94 insertions(+), 42 deletions(-) diff --git a/src/ipc.proto b/src/ipc.proto index fe3a169e..959a4780 100644 --- a/src/ipc.proto +++ b/src/ipc.proto @@ -87,3 +87,10 @@ message udp_fd_msg { } + +/* SESSION_INFO */ +message session_info_msg +{ + required string tls_ciphersuite = 1; + required string dtls_ciphersuite = 2; +} diff --git a/src/main-misc.c b/src/main-misc.c index 0e07de23..eb7c114a 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -70,7 +70,7 @@ const char* name; memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name); ifr.ifr_mtu = mtu; - + ret = ioctl(fd, SIOCSIFMTU, &ifr); if (ret != 0) { e = errno; @@ -78,7 +78,7 @@ const char* name; ret = -1; goto fail; } - + ret = 0; fail: close(fd); @@ -98,7 +98,7 @@ int ret; ret = ERR_BAD_COMMAND; goto fail; } - + apply_iroutes(s, proc); } else { mslog(s, proc, LOG_INFO, "failed authentication attempt for user '%s'", proc->username); @@ -111,7 +111,7 @@ int ret; } ret = 0; -fail: +fail: /* we close the lease tun fd both on success and failure. * The parent doesn't need to keep the tunfd. */ @@ -136,19 +136,19 @@ unsigned i; ret = parse_group_cfg_file(s, file, &cfg); if (ret < 0) return ERR_READ_CONFIG; - + if (cfg.routes_size > 0) { if (proc->config.routes == NULL) { proc->config.routes = cfg.routes; proc->config.routes_size = cfg.routes_size; - + cfg.routes = NULL; cfg.routes_size = 0; } else { proc->config.routes = safe_realloc(proc->config.routes, (proc->config.routes_size + cfg.routes_size) * sizeof(proc->config.routes[0])); if (proc->config.routes == NULL) return ERR_MEM; - + for (i=0;iconfig.routes[proc->config.routes_size] = cfg.routes[i]; cfg.routes[i] = NULL; @@ -160,7 +160,7 @@ unsigned i; if (proc->config.iroutes == NULL) { proc->config.iroutes = cfg.iroutes; proc->config.iroutes_size = cfg.iroutes_size; - + cfg.iroutes = NULL; cfg.iroutes_size = 0; } @@ -226,7 +226,7 @@ unsigned i; } else mslog(s, proc, LOG_DEBUG, "No %s configuration for '%s'", type, proc->username); - + return 0; } @@ -253,7 +253,7 @@ int ret; if (ret < 0) return ret; } - + if (proc->config.cgroup != NULL) { put_into_cgroup(s, proc->config.cgroup, proc->pid); } @@ -279,10 +279,10 @@ void remove_proc(main_server_st* s, struct proc_st *proc, unsigned k) close(proc->fd); proc->fd = -1; proc->pid = -1; - + remove_iroutes(s, proc); del_additional_config(&proc->config); - + if (proc->auth_ctx != NULL) proc_auth_deinit(s, proc); @@ -341,7 +341,7 @@ const char* group; if (ret < 0) { mslog(s, proc, LOG_INFO, "user '%s' disconnected due to script", proc->username); } - + return ret; } @@ -403,43 +403,63 @@ int handle_commands(main_server_st *s, struct proc_st* proc) switch(cmd) { case CMD_TUN_MTU: { TunMtuMsg *tmsg; - + tmsg = tun_mtu_msg__unpack(NULL, raw_len, raw); if (tmsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; goto cleanup; } - + set_tun_mtu(s, proc, tmsg->mtu); - + tun_mtu_msg__free_unpacked(tmsg, NULL); - + } - + + break; + case CMD_SESSION_INFO: { + SessionInfoMsg *tmsg; + + tmsg = session_info_msg__unpack(NULL, raw_len, raw); + if (tmsg == NULL) { + mslog(s, proc, LOG_ERR, "error unpacking data"); + ret = ERR_BAD_COMMAND; + goto cleanup; + } + + if (tmsg->tls_ciphersuite) + snprintf(proc->tls_ciphersuite, sizeof(proc->tls_ciphersuite), "%s", tmsg->tls_ciphersuite); + if (tmsg->dtls_ciphersuite) + snprintf(proc->dtls_ciphersuite, sizeof(proc->dtls_ciphersuite), "%s", tmsg->dtls_ciphersuite); + + session_info_msg__free_unpacked(tmsg, NULL); + + } + break; case RESUME_STORE_REQ: { SessionResumeStoreReqMsg* smsg; - + smsg = session_resume_store_req_msg__unpack(NULL, raw_len, raw); if (smsg == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); ret = ERR_BAD_COMMAND; goto cleanup; } - + ret = handle_resume_store_req(s, proc, smsg); - + session_resume_store_req_msg__free_unpacked(smsg, NULL); - + if (ret < 0) { mslog(s, proc, LOG_DEBUG, "could not store resumption data"); } - + } break; - + case RESUME_DELETE_REQ: { SessionResumeFetchMsg* fmsg; @@ -451,13 +471,13 @@ int handle_commands(main_server_st *s, struct proc_st* proc) } ret = handle_resume_delete_req(s, proc, fmsg); - + session_resume_fetch_msg__free_unpacked(fmsg, NULL); if (ret < 0) { mslog(s, proc, LOG_DEBUG, "could not delete resumption data."); } - + } break; @@ -482,29 +502,29 @@ int handle_commands(main_server_st *s, struct proc_st* proc) } else { msg.reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__OK; } - + ret = send_msg_to_worker(s, proc, RESUME_FETCH_REP, &msg, (pack_size_func)session_resume_reply_msg__get_packed_size, (pack_func)session_resume_reply_msg__pack); - + if (ret < 0) { mslog(s, proc, LOG_ERR, "could not send reply cmd %d.", (unsigned) cmd); ret = ERR_BAD_COMMAND; goto cleanup; } - + } - + break; case AUTH_INIT: - + if (proc->auth_status != PS_AUTH_INACTIVE) { mslog(s, proc, LOG_ERR, "received authentication init when complete."); ret = ERR_BAD_COMMAND; goto cleanup; } - + auth_init = auth_init_msg__unpack(NULL, raw_len, raw); if (auth_init == NULL) { mslog(s, proc, LOG_ERR, "error unpacking data"); @@ -513,7 +533,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) } ret = handle_auth_init(s, proc, auth_init); - + auth_init_msg__free_unpacked(auth_init, NULL); if (ret == ERR_AUTH_CONTINUE) { @@ -536,7 +556,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) add_to_ip_ban_list(s, &proc->remote_addr, proc->remote_addr_len); goto cleanup; } - + break; case AUTH_REQ: @@ -584,7 +604,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) goto cleanup_auth; case AUTH_COOKIE_REQ: - + if (proc->auth_status != PS_AUTH_INACTIVE) { mslog(s, proc, LOG_ERR, "received unexpected cookie authentication."); ret = ERR_BAD_COMMAND; @@ -599,7 +619,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc) } ret = handle_auth_cookie_req(s, proc, auth_cookie_req); - + auth_cookie_request_msg__free_unpacked(auth_cookie_req, NULL); if (ret < 0) { @@ -628,7 +648,7 @@ cleanup_auth: ret = ERR_BAD_COMMAND; goto cleanup; } - + ret = 0; cleanup: free(raw); @@ -658,7 +678,7 @@ struct banned_st *btmp, *bpos; } } } - + return 0; } @@ -692,11 +712,11 @@ struct banned_st *btmp; btmp = malloc(sizeof(*btmp)); if (btmp == NULL) return; - + btmp->failed_time = time(0); memcpy(&btmp->addr, addr, addr_len); btmp->addr_len = addr_len; - + list_add(&s->ban_list.head, &(btmp->list)); } @@ -761,7 +781,7 @@ FILE* fd; mslog(s, NULL, LOG_DEBUG, "putting process %u to cgroup '%s:%s'", (unsigned)pid, p, name); snprintf(file, sizeof(file), "/sys/fs/cgroup/%s/%s/tasks", p, name); - + fd = fopen(file, "w"); if (fd == NULL) { mslog(s, NULL, LOG_ERR, "cannot open: %s", file); diff --git a/src/main.h b/src/main.h index 6517f547..2fc83e50 100644 --- a/src/main.h +++ b/src/main.h @@ -100,6 +100,9 @@ struct proc_st { char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */ uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */ + char tls_ciphersuite[MAX_CIPHERSUITE_NAME]; + char dtls_ciphersuite[MAX_CIPHERSUITE_NAME]; + /* if the session is initiated by a cookie the following two are set * and are considered when generating an IP address. */ diff --git a/src/vpn.h b/src/vpn.h index fe1895d9..43534800 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -76,6 +76,7 @@ extern int syslog_open; #define LOG_HTTP_DEBUG 2048 +#define MAX_CIPHERSUITE_NAME 48 #define MAX_MSG_SIZE 256 typedef enum { @@ -91,6 +92,7 @@ typedef enum { CMD_UDP_FD = 10, CMD_TUN_MTU = 11, CMD_TERMINATE = 12, + CMD_SESSION_INFO = 13, } cmd_request_t; typedef struct diff --git a/src/worker-vpn.c b/src/worker-vpn.c index ff482025..32410916 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -684,6 +684,24 @@ void mtu_send(worker_st* ws, unsigned mtu) oclog(ws, LOG_INFO, "setting MTU to %u", msg.mtu); } +static +void session_info_send(worker_st* ws) +{ + SessionInfoMsg msg = SESSION_INFO_MSG__INIT; + + if (ws->session) { + msg.tls_ciphersuite = gnutls_session_get_desc(ws->session); + } + + if (ws->udp_state != UP_DISABLED) { + msg.dtls_ciphersuite = ws->req.selected_ciphersuite; + } + + send_msg_to_main(ws, CMD_TUN_MTU, &msg, + (pack_size_func)session_info_msg__get_packed_size, + (pack_func)session_info_msg__pack); +} + static void mtu_set(worker_st* ws, unsigned mtu) { @@ -1120,7 +1138,7 @@ bandwidth_st b_rx; set_net_priority(ws, ws->udp_fd, ws->config->net_priority); } else dtls_mtu = 0; - + if (ws->buffer_size <= ws->conn_mtu+mtu_overhead) { oclog(ws, LOG_WARNING, "buffer size is smaller than MTU (%u < %u); adjusting", ws->buffer_size, ws->conn_mtu); ws->buffer_size = ws->conn_mtu+mtu_overhead; @@ -1160,6 +1178,8 @@ bandwidth_st b_rx; bandwidth_init(&b_rx, ws->config->rx_per_sec); bandwidth_init(&b_tx, ws->config->tx_per_sec); + session_info_send(ws); + /* main loop */ for(;;) { FD_ZERO(&rfds);