From: Arne Schwabe Date: Tue, 13 Dec 2022 22:54:29 +0000 (+0100) Subject: Trigger a USR1 if dco_update_keys fails X-Git-Tag: v2.6_beta2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=238ac1785f08e4cde4c095629c94f2b9bcc977fa;p=thirdparty%2Fopenvpn.git Trigger a USR1 if dco_update_keys fails When dco_update_keys fails, we are in some weird state that we are unlikely to recover since what userspace and kernel space think of the keys is very likely to not in sync anymore. So abandon the connection if this happens. Signed-off-by: Arne Schwabe Acked-by: Antonio Quartulli Message-Id: <20221213225430.1892940-2-arne@rfc2549.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25679.html Signed-off-by: Gert Doering (cherry picked from commit 419051c96e9fb1f3202fd67733aa3b6a4bbc3181) --- diff --git a/src/openvpn/dco.c b/src/openvpn/dco.c index c250826ca..5804ce73e 100644 --- a/src/openvpn/dco.c +++ b/src/openvpn/dco.c @@ -130,7 +130,7 @@ dco_get_secondary_key(struct tls_multi *multi, const struct key_state *primary) return NULL; } -void +bool dco_update_keys(dco_context_t *dco, struct tls_multi *multi) { msg(D_DCO_DEBUG, "%s: peer_id=%d", __func__, multi->dco_peer_id); @@ -140,7 +140,7 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi) */ if (multi->dco_keys_installed == 0) { - return; + return true; } struct key_state *primary = tls_select_encryption_key(multi); @@ -155,18 +155,18 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi) if (ret < 0) { msg(D_DCO, "Cannot delete primary key during wipe: %s (%d)", strerror(-ret), ret); - return; + return false; } ret = dco_del_key(dco, multi->dco_peer_id, OVPN_KEY_SLOT_SECONDARY); if (ret < 0) { msg(D_DCO, "Cannot delete secondary key during wipe: %s (%d)", strerror(-ret), ret); - return; + return false; } multi->dco_keys_installed = 0; - return; + return true; } /* if we have a primary key, it must have been installed already (keys @@ -198,7 +198,7 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi) if (ret < 0) { msg(D_DCO, "Cannot swap keys: %s (%d)", strerror(-ret), ret); - return; + return false; } primary->dco_status = DCO_INSTALLED_PRIMARY; @@ -216,7 +216,7 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi) if (ret < 0) { msg(D_DCO, "Cannot delete secondary key: %s (%d)", strerror(-ret), ret); - return; + return false; } multi->dco_keys_installed = 1; } @@ -230,6 +230,7 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi) ks->dco_status = DCO_NOT_INSTALLED; } } + return true; } static bool diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h index 941060e04..701bbea12 100644 --- a/src/openvpn/dco.h +++ b/src/openvpn/dco.h @@ -164,9 +164,11 @@ int init_key_dco_bi(struct tls_multi *multi, struct key_state *ks, * * @param dco DCO device context * @param multi TLS multi instance + * + * @return returns false if an error occurred that is not + * recoverable and should reset the connection */ -void dco_update_keys(dco_context_t *dco, struct tls_multi *multi); - +bool dco_update_keys(dco_context_t *dco, struct tls_multi *multi); /** * Install a new peer in DCO - to be called by a CLIENT (or P2P) instance * @@ -312,10 +314,11 @@ init_key_dco_bi(struct tls_multi *multi, struct key_state *ks, return 0; } -static inline void +static inline bool dco_update_keys(dco_context_t *dco, struct tls_multi *multi) { ASSERT(false); + return false; } static inline int diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 5cd7eaa6e..8c1e49a34 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -151,7 +151,12 @@ check_dco_key_status(struct context *c) return; } - dco_update_keys(&c->c1.tuntap->dco, c->c2.tls_multi); + if (!dco_update_keys(&c->c1.tuntap->dco, c->c2.tls_multi)) + { + /* Something bad happened. Kill the connection to + * be able to recover. */ + register_signal(c, SIGUSR1, "dco update keys error"); + } } /*