From patchwork Wed Nov 30 16:57:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2878 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director11.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id SCb7NpCLh2PNbAAAIUCqbw (envelope-from ) for ; Wed, 30 Nov 2022 11:57:52 -0500 Received: from proxy7.mail.ord1d.rsapps.net ([172.30.191.6]) by director11.mail.ord1d.rsapps.net with LMTP id WMvmNpCLh2ONbgAAvGGmqA (envelope-from ) for ; Wed, 30 Nov 2022 11:57:52 -0500 Received: from smtp15.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy7.mail.ord1d.rsapps.net with LMTPS id uAGINpCLh2N2JAAAMe1Fpw (envelope-from ) for ; Wed, 30 Nov 2022 11:57:52 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp15.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=none (p=nil; dis=none) header.from=rfc2549.org X-Suspicious-Flag: YES X-Classification-ID: 1fe6a880-70d0-11ed-8167-5254007ab6c8-1-1 Received: from [216.105.38.7] ([216.105.38.7:49698] helo=lists.sourceforge.net) by smtp15.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 09/3C-13225-F8B87836; Wed, 30 Nov 2022 11:57:51 -0500 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1p0QOj-0002u1-FP; Wed, 30 Nov 2022 16:57:25 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1p0QOf-0002tv-Oh for openvpn-devel@lists.sourceforge.net; Wed, 30 Nov 2022 16:57:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=cwuOyj+SuUKnol05qabNTyXELtWkR8CwrpocbAqkFD8=; b=NU0jsPPCOwIfO7sQgBbuDZMkIs mB169EnxjkLK3KYAhV2biVkbSGH8cCuiZJwnQIFW4DvSE76W4WMDq1JoruSyVKqGTY6DDOUhtYixO ehib1+q2PILHJuqfwKeplbVOpOkAnkv5ex743L0V6OhcqzUAuQieZC6ywtiiZZlnA7xI=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:To:From: Sender:Reply-To:Cc:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=cwuOyj+SuUKnol05qabNTyXELtWkR8CwrpocbAqkFD8=; b=D gn6bsUrEGoRaXidNDK08CY3E91LLRAuA/R67yOpvUmapvTRkVJ2ugWR8oQfpUD0ltxCfFBvhJ0UmP Z7dBFNLJFvOiQTXJ8YrTQzcrfiBRVSJ7B1H9zlCVtRHAf2ZTEDE8A9AfErMTTsEQRLLcR3Ibf25SW ndOPyCFysfJjUiI4=; Received: from mail.blinkt.de ([192.26.174.232]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1p0QOb-0002L4-Ax for openvpn-devel@lists.sourceforge.net; Wed, 30 Nov 2022 16:57:21 +0000 Received: from kamera.blinkt.de ([2001:638:502:390:20c:29ff:fec8:535c]) by mail.blinkt.de with smtp (Exim 4.95 (FreeBSD)) (envelope-from ) id 1p0QOP-0007Bd-Vv for openvpn-devel@lists.sourceforge.net; Wed, 30 Nov 2022 17:57:05 +0100 Received: (nullmailer pid 159656 invoked by uid 10006); Wed, 30 Nov 2022 16:57:05 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 30 Nov 2022 17:57:05 +0100 Message-Id: <20221130165705.159610-1-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: We introduce this state to make the reconnecting of a client more obvious and what is called again instead of making it implicit. The new state CAS_RECONNECT_PENDING is between CAS_WAITING_OPTIONS_IMP [...] Content analysis details: (0.3 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different X-Headers-End: 1p0QOb-0002L4-Ax Subject: [Openvpn-devel] [PATCH] Introduce connection state for reconnecting peer in p2p X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox We introduce this state to make the reconnecting of a client more obvious and what is called again instead of making it implicit. The new state CAS_RECONNECT_PENDING is between CAS_WAITING_OPTIONS_IMPORT and CAS_CONNECT_DONE as we need to redo some of the steps of the connection setup, so this new state is going a "half step" back in the state machine. We also do no longer generate data channel keys for untrusted session. This is done for clarity but also to allow them being generated after the session has become actually active. These changes allow a reconnect in p2p mode with DCO to work as the initial reconnect working. Signed-off-by: Arne Schwabe Acked-by: Gert Doering --- src/openvpn/forward.c | 19 +++++++++++++---- src/openvpn/init.c | 6 ++++++ src/openvpn/ssl.c | 46 +++++++++++++++++++++++----------------- src/openvpn/ssl.h | 1 + src/openvpn/ssl_common.h | 5 +++++ 5 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 3b5b04074..37340aef5 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -174,7 +174,14 @@ check_tls(struct context *c) const int tmp_status = tls_multi_process (c->c2.tls_multi, &c->c2.to_link, &c->c2.to_link_addr, get_link_socket_info(c), &wakeup); - if (tmp_status == TLSMP_ACTIVE) + + if (tmp_status == TLSMP_RECONNECT) + { + event_timeout_init(&c->c2.wait_for_connect, 1, now); + reset_coarse_timers(c); + } + + if (tmp_status == TLSMP_ACTIVE || tmp_status == TLSMP_RECONNECT) { update_time(); interval_action(&c->c2.tmp_int); @@ -196,9 +203,15 @@ check_tls(struct context *c) interval_schedule_wakeup(&c->c2.tmp_int, &wakeup); - /* Our current code has no good hooks in the TLS machinery to update + /* + * Our current code has no good hooks in the TLS machinery to update * DCO keys. So we check the key status after the whole TLS machinery * has been completed and potentially update them + * + * We have a hidden state transition from secondary to primary key based + * on ks->auth_deferred_expire that DCO needs to check that the normal + * TLS state engine does not check. So we call the \c check_dco_key_status + * function even if tmp_status does not indicate that something has changed. */ check_dco_key_status(c); @@ -302,7 +315,6 @@ check_push_request(struct context *c) static void check_connection_established(struct context *c) { - if (connection_established(c)) { /* if --pull was specified, send a push request to server */ @@ -337,7 +349,6 @@ check_connection_established(struct context *c) event_timeout_clear(&c->c2.wait_for_connect); } - } bool diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 0e4769775..5f4b0543c 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2219,7 +2219,13 @@ do_up(struct context *c, bool pulled_options, unsigned int option_types_found) } } } + } + /* This pats needs to be run in p2p mode (wihout pull) when the client + * reconnects to setup various things (like DCO and NCP cipher) that + * might have changed from the previous client. */ + if (!c->c2.do_up_ran || (c->c2.tls_multi && c->c2.tls_multi->multi_state == CAS_RECONNECT_PENDING)) + { if (c->mode == MODE_POINT_TO_POINT) { /* ovpn-dco requires adding the peer now, before any option can be set, diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 818100c23..9e5480528 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -3249,29 +3249,29 @@ tls_multi_process(struct tls_multi *multi, if (multi->multi_state >= CAS_CONNECT_DONE) { - for (int i = 0; i < TM_SIZE; ++i) - { - struct tls_session *session = &multi->session[i]; - struct key_state *ks = &session->key[KS_PRIMARY]; + /* Only generate keys for the TM_ACTIVE session. We defer generating + * keys for TM_UNTRUSTED until we actually trust it. + * For TM_LAME_DUCK it makes no sense to generate new keys. */ + struct tls_session *session = &multi->session[TM_ACTIVE]; + struct key_state *ks = &session->key[KS_PRIMARY]; - if (ks->state == S_ACTIVE && ks->authenticated == KS_AUTH_TRUE) + if (ks->state == S_ACTIVE && ks->authenticated == KS_AUTH_TRUE) + { + /* Session is now fully authenticated. + * tls_session_generate_data_channel_keys will move ks->state + * from S_ACTIVE to S_GENERATED_KEYS */ + if (!tls_session_generate_data_channel_keys(multi, session)) { - /* Session is now fully authenticated. - * tls_session_generate_data_channel_keys will move ks->state - * from S_ACTIVE to S_GENERATED_KEYS */ - if (!tls_session_generate_data_channel_keys(multi, session)) - { - msg(D_TLS_ERRORS, "TLS Error: generate_key_expansion failed"); - ks->authenticated = KS_AUTH_FALSE; - ks->state = S_ERROR; - } + msg(D_TLS_ERRORS, "TLS Error: generate_key_expansion failed"); + ks->authenticated = KS_AUTH_FALSE; + ks->state = S_ERROR; + } - /* Update auth token on the client if needed on renegotiation - * (key id !=0) */ - if (session->key[KS_PRIMARY].key_id != 0) - { - resend_auth_token_renegotiation(multi, session); - } + /* Update auth token on the client if needed on renegotiation + * (key id !=0) */ + if (session->key[KS_PRIMARY].key_id != 0) + { + resend_auth_token_renegotiation(multi, session); } } } @@ -3304,6 +3304,12 @@ tls_multi_process(struct tls_multi *multi, move_session(multi, TM_ACTIVE, TM_UNTRUSTED, true); msg(D_TLS_DEBUG_LOW, "TLS: tls_multi_process: untrusted session promoted to %strusted", tas == TLS_AUTHENTICATION_SUCCEEDED ? "" : "semi-"); + + if (multi->multi_state == CAS_CONNECT_DONE) + { + multi->multi_state = CAS_RECONNECT_PENDING; + active = TLSMP_RECONNECT; + } } /* diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 646ec581a..55c672d44 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -212,6 +212,7 @@ void tls_multi_free(struct tls_multi *multi, bool clear); #define TLSMP_INACTIVE 0 #define TLSMP_ACTIVE 1 #define TLSMP_KILL 2 +#define TLSMP_RECONNECT 3 /* * Called by the top-level event loop. diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index e967970dd..0b5ad4c5f 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -551,7 +551,12 @@ enum multi_status { CAS_PENDING_DEFERRED_PARTIAL, /**< at least handler succeeded but another is still pending */ CAS_FAILED, /**< Option import failed or explicitly denied the client */ CAS_WAITING_OPTIONS_IMPORT, /**< client with pull or p2p waiting for first time options import */ + CAS_RECONNECT_PENDING, /**< session has already successful established (CAS_CONNECT_DONE) + * but has a reconnect and needs to redo some initialisation, this state is + * similar CAS_WAITING_OPTIONS_IMPORT but skips a few things. The normal connection + * skips this step. */ CAS_CONNECT_DONE, + };