From patchwork Mon Jan 21 09:04:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lev Stipakov X-Patchwork-Id: 666 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.27.255.58]) by backend30.mail.ord1d.rsapps.net with LMTP id QA+nMTwmRlxDewAAIUCqbw for ; Mon, 21 Jan 2019 15:06:20 -0500 Received: from proxy6.mail.iad3a.rsapps.net ([172.27.255.58]) by director12.mail.ord1d.rsapps.net with LMTP id ELZaLzwmRlyvUAAAIasKDg ; Mon, 21 Jan 2019 15:06:20 -0500 Received: from smtp35.gate.iad3a ([172.27.255.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy6.mail.iad3a.rsapps.net with LMTP id CDFCKjwmRlwNfgAA8udqhg ; Mon, 21 Jan 2019 15:06:20 -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: smtp35.gate.iad3a.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; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 046d62ca-1db8-11e9-8aa2-52540083445f-1-1 Received: from [216.105.38.7] ([216.105.38.7:64008] helo=lists.sourceforge.net) by smtp35.gate.iad3a.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 12/06-32731-C36264C5; Mon, 21 Jan 2019 15:06:20 -0500 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1glfop-0000fW-9g; Mon, 21 Jan 2019 20:05:15 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1glfon-0000fG-OJ for openvpn-devel@lists.sourceforge.net; Mon, 21 Jan 2019 20:05:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: 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=m1IT01JLWGSaSVjNo2BMicxlJFtg/cZzvx/xeOlowa0=; b=JJJv8n8FfqcE9avW53C+7LwonJ /AYV/yCED6rngWNpzjvza5f63bn1cSQMqAv66b6KGTXdmX7jUnuUMaN3h7aJNGO7OJAECPadTicHy fdZ4+ovji3QkBmV3lzT+yT20cqPFHw3oIOtBZd8ri40n0Pf3OaK1DWucyl2XFDyYiBB4=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding: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=m1IT01JLWGSaSVjNo2BMicxlJFtg/cZzvx/xeOlowa0=; b=m+YdpJ/R4BqdhcMaeLaYWKCLgz LDc+/TFR93dhB7kTaOPWTiGKDDqvz69dSuWB/oG+bcEJUx4cq1HSMBi3ofQ/Yo2CYZlmQBu/vkUAi +xCx65w2dIESpQm1zWQ0/Q5F/ebHGXs92vvFyzvT87hm2F7Ukos4ss7NA0kW87dz6vCM=; Received: from mail-ed1-f65.google.com ([209.85.208.65]) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.90_1) id 1glfol-00386I-7E for openvpn-devel@lists.sourceforge.net; Mon, 21 Jan 2019 20:05:13 +0000 Received: by mail-ed1-f65.google.com with SMTP id b3so17614731ede.1 for ; Mon, 21 Jan 2019 12:05:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=m1IT01JLWGSaSVjNo2BMicxlJFtg/cZzvx/xeOlowa0=; b=I92GGMOXoU4tUxtuqeFkY3sAzwyC7ojjN+RI0Pil8tkPECDSqr9/YSbd97gm/mDv5L Fqf4UfXvrpADKdsvR+BnA/hC6fXDO2/FsZ20cOQtyBI/tX42RA9s9FKAzhM38xeqwvVH zypt9FBaHkgaatVzIvN7V9KiX1ZKhEGDVzsSA56+7AMliihA1JeAZJhUsXLO5Erwjum2 o8l0tv+hbickiwm1qkzWxYmHaMhQROoiMA4vA5+8qKN7EAOEVr52zbjN+z3XjUTzPJMU ez3DTpJYWkJH8buMwy1mL4e/70TK3Vb15ageHMJl6sYO9ffrLFD9yX6e006Ni5xgY+zD +hzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=m1IT01JLWGSaSVjNo2BMicxlJFtg/cZzvx/xeOlowa0=; b=Pfk9okZ/Gnp6sS7GN1Sb75v/FQXSdMsJxJL7ir/mT6IqJ+fZQFMAngv7cPGxmRHT4F aV5VmjJ3KYs1odBzWCUqPmCkKZjfUx9P2CiaGojg1jaCa01OjAWg6XWsqE2s8+fnQsRf /k+Qae9p3I+HjaK+zsW7e30gEq6/prxeiCnbaS2s+ro+IWpZ/4iwUBqmt4lUhGFPCqGy RZk63gCGVUnAqcX4+lb/zL42TL/WlcfPveyL2v96aq3D9yynNjesCwxkKB5xdOvria4T PLEfAigBXRkwkoObD/SXEm0XQdkwNznsy57c4jYP5Pi6e7jQIBOPiv0a6G0c0plu2+2X UtGg== X-Gm-Message-State: AJcUukccqCgsPtEKRTzqSSTq0e53Y/8avn9R0JbjF3+BRbn48I1t+ygr 4xCL0mEeUwdVDmpJcgmPDieh1R6b X-Google-Smtp-Source: ALg8bN56MVXU+U2fp4qK7E9nnBiVSrIvT/Gn5eeNNk4wfqp0HtPzT/wulU5EJFX3olnvdNW+KLFnIw== X-Received: by 2002:a50:b2e1:: with SMTP id p88mr27582895edd.254.1548101104128; Mon, 21 Jan 2019 12:05:04 -0800 (PST) Received: from stipakov.fi (stipakov.fi. [128.199.52.117]) by smtp.gmail.com with ESMTPSA id 97sm9229107edq.45.2019.01.21.12.05.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 21 Jan 2019 12:05:03 -0800 (PST) From: Lev Stipakov To: openvpn-devel@lists.sourceforge.net Date: Mon, 21 Jan 2019 22:04:54 +0200 Message-Id: <1548101094-4449-1-git-send-email-lstipakov@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.208.65 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (lstipakov[at]gmail.com) -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.208.65 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1glfol-00386I-7E Subject: [Openvpn-devel] [PATCH v2] Fix broken fragment/mssfix with NCP 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Lev Stipakov NCP negotiation replaces worst cast crypto overhead with actual one in data channel frame. That frame params are used by mssfix. Fragment frame still contains worst case overhead. Because of that TCP packets are fragmented, since MSS value exceeds max fragment size. Fix by replacing worst case crypto overhead with actual one for fragment frame, as it is done for data channel frame. Trac #1140 Signed-off-by: Lev Stipakov Acked-By: Arne Schwabe Acked-by: Steffan Karger --- v2: fix --disable-fragment build src/openvpn/forward.c | 3 +++ src/openvpn/init.c | 12 +++++++++++- src/openvpn/openvpn.h | 1 + src/openvpn/push.c | 9 ++++++++- src/openvpn/ssl.c | 19 ++++++++++++++++++- src/openvpn/ssl.h | 13 ++++++++----- 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 4076f64..0dd599a 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1093,6 +1093,9 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo if (is_hard_reset(opcode, c->options.key_method)) { c->c2.frame = c->c2.frame_initial; +#ifdef ENABLE_FRAGMENT + c->c2.frame_fragment = c->c2.frame_fragment_initial; +#endif } interval_action(&c->c2.tmp_int); diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 560d87d..b1a91af 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2298,9 +2298,18 @@ do_deferred_options(struct context *c, const unsigned int found) { tls_poor_mans_ncp(&c->options, c->c2.tls_multi->remote_ciphername); } + struct frame *frame_fragment = NULL; +#ifdef ENABLE_FRAGMENT + if (c->options.ce.fragment) + { + frame_fragment = &c->c2.frame_fragment; + } +#endif + /* Do not regenerate keys if server sends an extra push reply */ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized - && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame)) + && !tls_session_update_crypto_params(session, &c->options, &c->c2.frame, + frame_fragment)) { msg(D_TLS_ERRORS, "OPTIONS ERROR: failed to import crypto options"); return false; @@ -3082,6 +3091,7 @@ do_init_frame(struct context *c) */ c->c2.frame_fragment = c->c2.frame; frame_subtract_extra(&c->c2.frame_fragment, &c->c2.frame_fragment_omit); + c->c2.frame_fragment_initial = c->c2.frame_fragment; #endif #if defined(ENABLE_FRAGMENT) && defined(ENABLE_OCC) diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index d11f61d..a5d250f 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -265,6 +265,7 @@ struct context_2 /* Object to handle advanced MTU negotiation and datagram fragmentation */ struct fragment_master *fragment; struct frame frame_fragment; + struct frame frame_fragment_initial; struct frame frame_fragment_omit; #endif diff --git a/src/openvpn/push.c b/src/openvpn/push.c index 8befc6f..248c2e4 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -287,11 +287,18 @@ incoming_push_message(struct context *c, const struct buffer *buffer) { if (c->options.mode == MODE_SERVER) { + struct frame *frame_fragment = NULL; +#ifdef ENABLE_FRAGMENT + if (c->options.ce.fragment) + { + frame_fragment = &c->c2.frame_fragment; + } +#endif struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE]; /* Do not regenerate keys if client send a second push request */ if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized && !tls_session_update_crypto_params(session, &c->options, - &c->c2.frame)) + &c->c2.frame, frame_fragment)) { msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed"); goto error; diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index e9927eb..ea9fd5f 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1990,7 +1990,8 @@ cleanup: bool tls_session_update_crypto_params(struct tls_session *session, - struct options *options, struct frame *frame) + struct options *options, struct frame *frame, + struct frame *frame_fragment) { if (!session->opt->server && 0 != strcmp(options->ciphername, session->opt->config_ciphername) @@ -2034,6 +2035,22 @@ tls_session_update_crypto_params(struct tls_session *session, frame_init_mssfix(frame, options); frame_print(frame, D_MTU_INFO, "Data Channel MTU parms"); + /* + * mssfix uses data channel framing, which at this point contains + * actual overhead. Fragmentation logic uses frame_fragment, which + * still contains worst case overhead. Replace it with actual overhead + * to prevent unneeded fragmentation. + */ + + if (frame_fragment) + { + frame_remove_from_extra_frame(frame_fragment, crypto_max_overhead()); + crypto_adjust_frame_parameters(frame_fragment, &session->opt->key_type, + options->replay, packet_id_long_form); + frame_set_mtu_dynamic(frame_fragment, options->ce.fragment, SET_MTU_UPPER_BOUND); + frame_print(frame_fragment, D_MTU_INFO, "Fragmentation MTU parms"); + } + return tls_session_generate_data_channel_keys(session); } diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index eafb235..a6b18d0 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -476,15 +476,18 @@ void tls_update_remote_addr(struct tls_multi *multi, * Update TLS session crypto parameters (cipher and auth) and derive data * channel keys based on the supplied options. * - * @param session The TLS session to update. - * @param options The options to use when updating session. - * @param frame The frame options for this session (frame overhead is - * adjusted based on the selected cipher/auth). + * @param session The TLS session to update. + * @param options The options to use when updating session. + * @param frame The frame options for this session (frame overhead is + * adjusted based on the selected cipher/auth). + * @param frame_fragment The fragment frame options. * * @return true if updating succeeded, false otherwise. */ bool tls_session_update_crypto_params(struct tls_session *session, - struct options *options, struct frame *frame); + struct options *options, + struct frame *frame, + struct frame *frame_fragment); /** * "Poor man's NCP": Use peer cipher if it is an allowed (NCP) cipher.