From patchwork Tue May 17 23:32:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arne Schwabe X-Patchwork-Id: 2472 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director15.mail.ord1d.rsapps.net ([172.31.255.6]) by backend41.mail.ord1d.rsapps.net with LMTP id mDrtF3y9hGKmbQAAqwncew (envelope-from ) for ; Wed, 18 May 2022 05:33:48 -0400 Received: from proxy16.mail.iad3b.rsapps.net ([172.31.255.6]) by director15.mail.ord1d.rsapps.net with LMTP id EL6sL3y9hGJtaQAAIcMcQg (envelope-from ) for ; Wed, 18 May 2022 05:33:48 -0400 Received: from smtp24.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy16.mail.iad3b.rsapps.net with LMTPS id mAoMKXy9hGLUTAAAPj+4aA (envelope-from ) for ; Wed, 18 May 2022 05:33:48 -0400 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: smtp24.gate.iad3b.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: 9e4c5522-d68d-11ec-9973-525400892b35-1-1 Received: from [216.105.38.7] ([216.105.38.7:51620] helo=lists.sourceforge.net) by smtp24.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 30/2B-25362-C7DB4826; Wed, 18 May 2022 05:33:48 -0400 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nrG2g-0002HC-LU; Wed, 18 May 2022 09:32:29 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nrG2e-0002H6-3Y for openvpn-devel@lists.sourceforge.net; Wed, 18 May 2022 09:32:27 +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:References: In-Reply-To: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:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=vC5VdRmkprPEqZc4w4eNVny6gQ6ZJAYAuGUiv19VAtE=; b=Jj8lndlaU0BkhyQp37cp+LJ2f+ j48SoZLL+Uf7CEijTwGSt/H6TQpkHe4T0F8tWR4ENcLX4in/bozAw5YnFY8bs7l6EM2ZDhZmasFF4 2uPdDZ/n42DBsppKPJNqkWdkmC7WB2jHVgXaaoHvz4a8MqAL3ZyALyWMwA+L1rslslaU=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: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:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=vC5VdRmkprPEqZc4w4eNVny6gQ6ZJAYAuGUiv19VAtE=; b=QCB7coIWDLHMs+q5WYm6YH/5Jg QSi/8SXq8TyF7HCE+KaLec8VNeyzJa+q21I8+GkMhfGuv9SGs0wPmMehWF2zlkrTLHPu3wEndNMRe jDehseQlN8KYahhER4VPE+Oh+57TkFcsNfu7ZBtaCCpei4E/i4CFgVYPbEK3NoB55zXQ=; 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.94.2) id 1nrG2a-0001Cf-TK for openvpn-devel@lists.sourceforge.net; Wed, 18 May 2022 09:32:26 +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 1nrG2O-000GUC-Sw for openvpn-devel@lists.sourceforge.net; Wed, 18 May 2022 11:32:12 +0200 Received: (nullmailer pid 2802546 invoked by uid 10006); Wed, 18 May 2022 09:32:12 -0000 From: Arne Schwabe To: openvpn-devel@lists.sourceforge.net Date: Wed, 18 May 2022 11:32:09 +0200 Message-Id: <20220518093212.2802495-2-arne@rfc2549.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220518093212.2802495-1-arne@rfc2549.org> References: <20220518093212.2802495-1-arne@rfc2549.org> 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: Current exit notification relies on data channel messages with specific prefix. Adding these to new data channel modules (DCO) adds uncessary complexity for the data for messages that from their idea [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 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 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1nrG2a-0001Cf-TK Subject: [Openvpn-devel] [PATCH 1/4] Implement exit notification via control channel 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 Current exit notification relies on data channel messages with specific prefix. Adding these to new data channel modules (DCO) adds uncessary complexity for the data for messages that from their idea belong to the control channel anyway. This patch adds announcing support for control channel and sending/receving it. We use the simple EXIT message for this. --- doc/man-sections/client-options.rst | 7 ++++++- src/openvpn/crypto.h | 5 +++++ src/openvpn/forward.c | 4 ++++ src/openvpn/multi.c | 5 +++++ src/openvpn/options.c | 14 ++++++++++++++ src/openvpn/push.c | 19 +++++++++++++++++++ src/openvpn/push.h | 2 ++ src/openvpn/sig.c | 27 +++++++++++++++++++++++++-- src/openvpn/ssl.c | 3 +++ src/openvpn/ssl.h | 3 +++ src/openvpn/ssl_ncp.c | 5 +++++ 11 files changed, 91 insertions(+), 3 deletions(-) diff --git a/doc/man-sections/client-options.rst b/doc/man-sections/client-options.rst index 8e0e4f18a..5a906895b 100644 --- a/doc/man-sections/client-options.rst +++ b/doc/man-sections/client-options.rst @@ -220,9 +220,14 @@ configuration. immediately close its client instance object rather than waiting for a timeout. + If both server and client support sending this message using the control + channel, the message will be sent as control-channel message. Otherwise + the message is sent as data-channel message, which will be ignored by + data-channel offloaded peers. + The **n** parameter (default :code:`1` if not present) controls the maximum number of attempts that the client will try to resend the exit - notification message. + notification message if messages are sent in data-channel mode. In UDP server mode, send :code:`RESTART` control channel command to connected clients. The ``n`` parameter (default :code:`1` if not present) diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 98e2c7664..8219d2b76 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -264,6 +264,11 @@ struct crypto_options /**< Bit-flag indicating that we do not allow clients that do * not support resending the wrapped client key (WKc) with the * third packet of the three-way handshake */ +#define CO_USE_CC_EXIT_NOTIFY (1<<6) + /**< Bit-flag indicating that explicit exit notifies should be + * send via the control channel instead of using an OCC message + */ + unsigned int flags; /**< Bit-flags determining behavior of * security operation functions. */ }; diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 6afe152b4..50d3fd2b2 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -241,6 +241,10 @@ check_incoming_control_channel(struct context *c) { receive_auth_pending(c, &buf); } + else if (buf_string_match_head_str(&buf, "EXIT")) + { + receive_exit_message(c, &buf); + } else { msg(D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR(&buf)); diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index ba2f6d581..e7c99f813 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -1777,6 +1777,11 @@ multi_client_set_protocol_options(struct context *c) } #endif + if (proto & IV_PROTO_CC_EXIT_NOTIFY) + { + o->data_channel_crypto_flags |= CO_USE_CC_EXIT_NOTIFY; + } + /* Select cipher if client supports Negotiable Crypto Parameters */ /* if we have already created our key, we cannot *change* our own diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 9ff384d09..7913661c7 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -8338,6 +8338,20 @@ add_option(struct options *options, msg(msglevel, "Unknown key-derivation method %s", p[1]); } } + else if (streq(p[0], "protocol-flags") && p[1]) + { + for (size_t j = 1; j < MAX_PARMS && p[j] != NULL; j++) + { + if (streq(p[j], "cc-exit")) + { + options->data_channel_crypto_flags |= CO_USE_CC_EXIT_NOTIFY; + } + else + { + msg(msglevel, "Unknown protocol-flags flag: %s", p[j]); + } + } + } else if (streq(p[0], "prng") && p[1] && !p[3]) { msg(M_WARN, "NOTICE: --prng option ignored (SSL library PRNG is used)"); diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 70fd1c3ce..51b8bd521 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -176,6 +176,21 @@ server_pushed_signal(struct context *c, const struct buffer *buffer, const bool } } +void +receive_exit_message(struct context *c, const struct buffer *buffer) +{ + dmsg(D_STREAM_ERRORS, "Exit message received by peer"); + c->sig->signal_received = SIGTERM; + c->sig->signal_text = "remote-exit"; +#ifdef ENABLE_MANAGEMENT + if (management) + { + management_notify(management, "info", c->sig->signal_text, "EXIT"); + } +#endif +} + + void server_pushed_info(struct context *c, const struct buffer *buffer, const int adv) @@ -604,6 +619,10 @@ prepare_push_reply(struct context *c, struct gc_arena *gc, { push_option_fmt(gc, push_list, M_USAGE, "key-derivation tls-ekm"); } + if (o->data_channel_crypto_flags & CO_USE_CC_EXIT_NOTIFY) + { + push_option_fmt(gc, push_list, M_USAGE, "protocol-flags cc-exit"); + } return true; } diff --git a/src/openvpn/push.h b/src/openvpn/push.h index 62fad4a14..33e62120c 100644 --- a/src/openvpn/push.h +++ b/src/openvpn/push.h @@ -48,6 +48,8 @@ void receive_auth_failed(struct context *c, const struct buffer *buffer); void server_pushed_signal(struct context *c, const struct buffer *buffer, const bool restart, const int adv); +void receive_exit_message(struct context *c, const struct buffer *buffer); + void server_pushed_info(struct context *c, const struct buffer *buffer, const int adv); diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c index e06edd216..1fc9c6dca 100644 --- a/src/openvpn/sig.c +++ b/src/openvpn/sig.c @@ -321,20 +321,43 @@ print_status(const struct context *c, struct status_output *so) gc_free(&gc); } + +/* Small helper function to determine if we should be sending exit notifcation + * via control channel */ +static inline bool +cc_exit_notify_enabled(struct context *c) +{ + /* Check if we have TLS active at all */ + if (!c->c2.tls_multi) + { + return false; + } + + const struct key_state *ks = get_primary_key(c->c2.tls_multi); + return (ks->crypto_options.flags & CO_USE_CC_EXIT_NOTIFY); +} + /* * Handle the triggering and time-wait of explicit * exit notification. */ - static void process_explicit_exit_notification_init(struct context *c) { msg(M_INFO, "SIGTERM received, sending exit notification to peer"); event_timeout_init(&c->c2.explicit_exit_notification_interval, 1, 0); reset_coarse_timers(c); + signal_reset(c->sig); halt_non_edge_triggered_signals(); c->c2.explicit_exit_notification_time_wait = now; + + /* Check if we are in TLS mode and should sent the notify via data + * channel */ + if (cc_exit_notify_enabled(c)) + { + send_control_channel_string(c, "EXIT", D_PUSH); + } } void @@ -351,7 +374,7 @@ process_explicit_exit_notification_timer_wakeup(struct context *c) c->sig->signal_received = SIGTERM; c->sig->signal_text = "exit-with-notification"; } - else + else if (!cc_exit_notify_enabled(c)) { c->c2.occ_op = OCC_EXIT; } diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 61dea996d..4506b7504 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1940,6 +1940,9 @@ push_peer_info(struct buffer *buf, struct tls_session *session) /* support for P_DATA_V2 */ int iv_proto = IV_PROTO_DATA_V2; + /* support for exit notify via control channel */ + iv_proto |= IV_PROTO_CC_EXIT_NOTIFY; + /* support for receiving push_reply before sending * push request, also signal that the client wants * to get push-reply messages without without requiring a round diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 0ba86d3e6..1b8b736b9 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -93,6 +93,9 @@ * result. */ #define IV_PROTO_NCP_P2P (1<<5) +/** Support for explicit exit notify via control channel */ +#define IV_PROTO_CC_EXIT_NOTIFY (1<<7) + /* Default field in X509 to be username */ #define X509_USERNAME_FIELD_DEFAULT "CN" diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c index 5d7e6dd38..4a083e247 100644 --- a/src/openvpn/ssl_ncp.c +++ b/src/openvpn/ssl_ncp.c @@ -419,6 +419,11 @@ p2p_ncp_set_options(struct tls_multi *multi, struct tls_session *session) multi->peer_id = 0x76706e; /* 'v' 'p' 'n' */ } + if (iv_proto_peer & IV_PROTO_CC_EXIT_NOTIFY) + { + session->opt->crypto_flags |= CO_USE_CC_EXIT_NOTIFY; + } + #if defined(HAVE_EXPORT_KEYING_MATERIAL) if (iv_proto_peer & IV_PROTO_TLS_KEY_EXPORT) {