From d2ff5164e68e5101b1da2d2d818e23eb7851dc9f Mon Sep 17 00:00:00 2001 From: Lev Stipakov Date: Thu, 20 Sep 2018 16:12:34 +0300 Subject: [PATCH] Refactor NCP-negotiable options handling NCP negotiation can alter options. On reconnect client sends possibly altered options while server expects original values. This leads to warnings in log and, if server uses --opt-verify, breaks reconnect. Fix by decouple setting/unsetting NCP options from the state of TLS context. At startup (and once per sighup) we load original values to c->c1, which persists over sigusr1 (restart). When tearing tunnel down we restore (possibly altered) options back to original values. Trac: #1105 Signed-off-by: Lev Stipakov Acked-by: Steffan Karger Message-Id: <1537449154-26879-1-git-send-email-lstipakov@gmail.com> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17477.html Signed-off-by: Gert Doering (cherry picked from commit 5fa25eeb7fefdbb17ad639d72fe46f393989159f) --- src/openvpn/init.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 87d42874a..0950f07e9 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -613,6 +613,33 @@ uninit_proxy(struct context *c) uninit_proxy_dowork(c); } +/* + * Assign NCP-negotiable options to context->c1 + * from context->options (initially config values). + * They persist over sigusr1 restart. + */ +static void +do_set_ncp_options(struct context *c) +{ + c->c1.ciphername = c->options.ciphername; + c->c1.authname = c->options.authname; + c->c1.keysize = c->options.keysize; +} + +/* + * Restore NCP-negotiable options from c->c1 to + * c->options. The latter ones can be altered by + * pushed options and therefore need to be restored + * to original values on sigusr1 restart. + */ +static void +do_unset_ncp_options(struct context *c) +{ + c->options.ciphername = c->c1.ciphername; + c->options.authname = c->c1.authname; + c->options.keysize = c->c1.keysize; +} + void context_init_1(struct context *c) { @@ -622,6 +649,8 @@ context_init_1(struct context *c) init_connection_list(c); + do_set_ncp_options(c); + #if defined(ENABLE_PKCS11) if (c->first_time) { @@ -2610,10 +2639,6 @@ do_init_crypto_tls_c1(struct context *c) options->tls_crypt_inline, options->tls_server); } - c->c1.ciphername = options->ciphername; - c->c1.authname = options->authname; - c->c1.keysize = options->keysize; - #if 0 /* was: #if ENABLE_INLINE_FILES -- Note that enabling this code will break restarts */ if (options->priv_key_file_inline) { @@ -2625,11 +2650,6 @@ do_init_crypto_tls_c1(struct context *c) else { msg(D_INIT_MEDIUM, "Re-using SSL/TLS context"); - - /* Restore pre-NCP cipher options */ - c->options.ciphername = c->c1.ciphername; - c->options.authname = c->c1.authname; - c->options.keysize = c->c1.keysize; } } @@ -4320,6 +4340,8 @@ close_instance(struct context *c) /* free key schedules */ do_close_free_key_schedule(c, (c->mode == CM_P2P || c->mode == CM_TOP)); + do_unset_ncp_options(c); + /* close TCP/UDP connection */ do_close_link_socket(c); -- 2.47.2