From 4c85fa97f00173eb3c19a6d8a38fb6f1a945e01b Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 22 Sep 2016 15:16:34 +0200 Subject: [PATCH] Added configuration option 'dtls-psk' When this option is set to false, the DTLS-PSK protocol will not be negotiated by worker processes. The process will fallback to the legacy protocol in that case. --- doc/sample.config | 6 ++++++ src/config.c | 2 ++ src/main.c | 7 +++++-- src/ocserv-args.def | 6 ++++++ src/vpn.h | 1 + src/worker-http.c | 8 +++++--- src/worker-vpn.c | 1 - 7 files changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/sample.config b/doc/sample.config index 0999097f..2f872419 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -588,6 +588,12 @@ no-route = 192.168.5.0/255.255.255.0 # and openconnect clients < 7.08. cisco-client-compat = true +# This option will disable the DTLS-PSK negotiation (enabled by default). +# The DTLS-PSK negotiation was introduced in ocserv 0.11.5 to deprecate +# the pre-draft-DTLS negotiation inherited from AnyConnect. It allows the +# DTLS channel to negotiate its ciphers and the DTLS protocol version. +#dtls-psk = false + # Client profile xml. A sample file exists in doc/profile.xml. # It is required by some of the CISCO clients. # This file must be accessible from inside the worker's chroot. diff --git a/src/config.c b/src/config.c index 45c43a40..1f112ecb 100644 --- a/src/config.c +++ b/src/config.c @@ -82,6 +82,7 @@ static struct cfg_options available_options[] = { { .name = "acct", .type = OPTION_STRING, .mandatory = 0 }, { .name = "listen-host", .type = OPTION_STRING, .mandatory = 0 }, { .name = "listen-host-is-dyndns", .type = OPTION_BOOLEAN, .mandatory = 0 }, + { .name = "dtls-psk", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "listen-proxy-proto", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "compression", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "no-compress-limit", .type = OPTION_NUMERIC, .mandatory = 0 }, @@ -824,6 +825,7 @@ size_t urlfw_size = 0; config->cisco_client_compat = 1; } + READ_TF("dtls-psk", config->dtls_psk, 1); READ_TF("match-tls-and-dtls-ciphers", config->match_dtls_and_tls, 0); if (config->match_dtls_and_tls) { if (config->cisco_client_compat) { diff --git a/src/main.c b/src/main.c index 1c8a0739..fa612e7e 100644 --- a/src/main.c +++ b/src/main.c @@ -684,7 +684,7 @@ void clear_lists(main_server_st *s) * } ServerHello; */ static -unsigned get_session_id(uint8_t *buffer, size_t buffer_size, uint8_t **id, int *id_size) +unsigned get_session_id(main_server_st* s, uint8_t *buffer, size_t buffer_size, uint8_t **id, int *id_size) { size_t pos; @@ -694,6 +694,9 @@ unsigned get_session_id(uint8_t *buffer, size_t buffer_size, uint8_t **id, int * return 0; } + if (!s->config->dtls_psk) + goto fallback; + /* try to read the extension data */ pos = RECORD_PAYLOAD_POS+HANDSHAKE_SESSION_ID_POS; SKIP8(pos, buffer_size); @@ -821,7 +824,7 @@ int sfd = -1; if (s->perm_config->unix_conn_file) goto fail; } else { - if (!get_session_id(s->msg_buffer, buffer_size, &session_id, &session_id_size)) { + if (!get_session_id(s, s->msg_buffer, buffer_size, &session_id, &session_id_size)) { mslog(s, NULL, LOG_INFO, "%s: too short handshake packet", human_addr((struct sockaddr*)&cli_addr, cli_addr_size, tbuf, sizeof(tbuf))); goto fail; diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 72180a9b..0b4ec32f 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -710,6 +710,12 @@ no-route = 192.168.5.0/255.255.255.0 # and openconnect clients < 7.08. cisco-client-compat = true +# This option will disable the DTLS-PSK negotiation (enabled by default). +# The DTLS-PSK negotiation was introduced in ocserv 0.11.5 to deprecate +# the pre-draft-DTLS negotiation inherited from AnyConnect. It allows the +# DTLS channel to negotiate its ciphers and the DTLS protocol version. +#dtls-psk = false + # Client profile xml. A sample file exists in doc/profile.xml. # It is required by some of the CISCO clients. # This file must be accessible from inside the worker's chroot. diff --git a/src/vpn.h b/src/vpn.h index 3c63581a..b646fda1 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -270,6 +270,7 @@ struct cfg_st { /* when using the new PSK DTLS negotiation make sure that * the negotiated DTLS cipher/mac matches the TLS cipher/mac. */ unsigned match_dtls_and_tls; + unsigned dtls_psk; /* whether to enable DTLS-PSK */ unsigned isolate; /* whether seccomp should be enabled or not */ diff --git a/src/worker-http.c b/src/worker-http.c index 3ae5a203..dbe69c26 100644 --- a/src/worker-http.c +++ b/src/worker-http.c @@ -272,9 +272,11 @@ void header_value_check(struct worker_st *ws, struct http_req_st *req) p = strstr(str, DTLS_PROTO_INDICATOR); if (p != NULL && (p[sizeof(DTLS_PROTO_INDICATOR)-1] == 0 || p[sizeof(DTLS_PROTO_INDICATOR)-1] == ':')) { /* OpenConnect DTLS setup was detected. */ - req->use_psk = 1; - req->master_secret_set = 1; /* we don't need it */ - break; + if (ws->config->dtls_psk) { + req->use_psk = 1; + req->master_secret_set = 1; /* we don't need it */ + break; + } } if (ws->session != NULL) { diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 465f71eb..3e8211cb 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -1926,7 +1926,6 @@ static int connect_handler(worker_st * ws) if (ws->udp_state != UP_DISABLED) { - if (ws->user_config->dpd > 0) { ret = cstp_printf(ws, "X-DTLS-DPD: %u\r\n",