From patchwork Tue Nov 3 08:13:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 5573 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:6022:4121:b0:118:2077:975e with SMTP id d33csp336524laa; Tue, 3 Nov 2026 00:14:08 -0800 (PST) X-Forwarded-Encrypted: i=2; AKwUvBwBRr+Lm+xCeB/MP5b663O1fmh6IxDZdyk1ce+KLjuSK4/VaGStbUjziRRcAOJMGD9PbgX1nmwBNQ8=@openvpn.net X-Received: by 2002:a05:693c:2802:b0:36a:1008:5815 with SMTP id 5a478bee46e88-36a4220407bmr17542155eec.5.1793693648218; Tue, 03 Nov 2026 00:14:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1793693648; cv=none; d=google.com; s=arc-20260327; b=IRSu4NhCVlnwaXm3GNOoseRVjAYEJj73OwSCInha/eSFJcY6xo7uJ+1bNytx0RO5V8 5xb3e4vaMAPHfj8GL7f6xlu+FLkBAxT7Lg+1Umm8BlYTnbv+m0v8C2Pnj8Cht80MwlUU VC6I1rFGWrgpQJsPEf1UySth6sioS3PcM7FFSQUzth570BBy8MifQKa9F4G4hiqNXFio 2BC36MMR2pSA9BEkOIlUeljM08P0rQJq2hosW1t+Yh1zSFORP3MHuf9quL98jU6S6Cz0 e0n6D+uyzrOgXeUVM/e5DSXDIeYZxJnglB80ckkzcyhrwHtcLsD6A8jSk0eWvDgXUI8K u6HA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature; bh=mGaqXL7u8Rf6DzEfDA43+M0ffrvn1N4J6MrfE129rDI=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=g4ZS8QDCwymsNq70TdSTO8GpN589cgCAS1tiocJy1Rv5GJH3RR4hOArTukK2nq9y2F O8D1AQFRXzokrw2qH2moytMOEsTkdbLdX3rWJM4ungpjoL0wrY9ntCzGdOWDd0nirbZa qD1FElPnte6u/SDf2Tw8MVjDu5yEtjaslgVlWJNI/SnaDGLI7esKQjVuRMAqwOGil27K qCzgf5PnK/rN5NE2ICBsn35tfTxgKUlxG0GwW8ebK5iznXYs20BE8dj6cewEMinJYsvS AyJkzfGr96JJEc/MJkICFjpKTQaj1WmYQJWRBsHFAphgClIrz8DzRwkLxcF2YoUJd+NB pLtA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=CTiNO1hg; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=HYUl3AlM; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=fOucoD35; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5a478bee46e88-36a42b13f7esi41562690eec.53.2026.11.03.00.14.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Nov 2026 00:14:08 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=CTiNO1hg; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=HYUl3AlM; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=fOucoD35; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Unsubscribe-Post: List-Owner; bh=mGaqXL7u8Rf6DzEfDA43+M0ffrvn1N4J6MrfE129rDI=; b=CTiNO1hgOn4Wug VpeRY+un0bwOcID7GBH6iiFx0btIwKoRR00BAFB+3vP6QVstr1VWYtxgXxFc48RKIlNYXUT/q6RHx sEzU/VtJaH/RMhg+v2JM0I8pytcbuMuWqetnfkud4nZjPd60v9ZvqWq2n27UT/aq3MyXVz5aY1StW XzM=; 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.100.1) (envelope-from ) id 1xO9eg-000000005n8-3aq7; Tue, 03 Nov 2026 08:14:06 +0000 Received: from [172.30.29.66] (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.100.1) (envelope-from ) id 1xO9eg-000000005my-04Jf for openvpn-devel@lists.sourceforge.net; Tue, 03 Nov 2026 08:14:06 +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-Unsubscribe-Post:List-Subscribe:List-Post:List-Owner:List-Archive; bh=6zUTbYO3/+4rchEd1q9c9MA019vkTVh8yj3iw5K+CyA=; b=HYUl3AlMy1ODTHKbcj+pQB3ANP 0Dh9mrlcxDvZy6yuXBF3X3i7qdTewAGXz1ANXNJRKALPqm92APRWYeHXRGvRyCOuTIsJD+1tKIvsR qulwR01adEsrYNXgQzsD8Q69Jpy0+OLzxJ0i7xRHSoLgWgRCDPReNHvpxGnuDWrDpKR8=; 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-Unsubscribe-Post: List-Subscribe:List-Post:List-Owner:List-Archive; bh=6zUTbYO3/+4rchEd1q9c9MA019vkTVh8yj3iw5K+CyA=; b=fOucoD35kFQ3mPqcuF/1W383OV knGQog2eQLOGBhJcrsJvne84havjVAuigHf66c1r0oQ6N9vP6FqoS8MERod8LP2ni80sVAvhP6Cms lNuWVTGKmpOj6y5U3wk7VOoDJnIlnAEH1SGmwfLFyBN6roecU5hFBk0eT+M7p9Lk8MXY=; Received: from [193.149.48.129] (helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.100.1) id 1xO9ee-000000003aE-2pmD for openvpn-devel@lists.sourceforge.net; Tue, 03 Nov 2026 08:14:05 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.18.1/8.18.1) with ESMTP id 6A38Dwrv008599 for ; Tue, 3 Nov 2026 09:13:58 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.2/8.18.1/Submit) id 6A38Dw4g008598 for openvpn-devel@lists.sourceforge.net; Tue, 3 Nov 2026 09:13:58 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Tue, 3 Nov 2026 09:13:52 +0100 Message-ID: <20261103081357.8587-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.55.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 1.3 (+) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", 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: From: Selva Nair Consume the complete username line before reading the password from an auth file or inline credentials. This also fixes an exactly full username buffer leaving its newline to be read as an empty passw [...] Content analysis details: (1.3 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS 0.0 T_FILL_THIS_FORM_SHORT Fill in a short form with personal information X-Headers-End: 1xO9ee-000000003aE-2pmD Subject: [Openvpn-devel] [PATCH v2] misc: Fix username overflow spilling into password 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 X-GMAIL-THRID: 1880824110553341272 X-GMAIL-MSGID: 1880824110553341272 From: Selva Nair Consume the complete username line before reading the password from an auth file or inline credentials. This also fixes an exactly full username buffer leaving its newline to be read as an empty password in auth files. Existing credential truncation behaviour is unchanged. Tests: Add regression coverage for long and boundary-length usernames with missing, blank, or supplied passwords in both inlined and external file inputs. Github: OpenVPN/openvpn#1140 Change-Id: I3c8c62c7d90c2b94dd1cd149b4c13b383a2303e9 Signed-off-by: Selva Nair Acked-by: Razvan Cojocaru Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2096 --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/2096 This mail reflects revision 2 of this Change. Acked-by according to Gerrit (reflected above): Razvan Cojocaru diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 304a87e..8c9ad08 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -250,6 +250,10 @@ if (!(flags & GET_USER_PASS_PASSWORD_ONLY)) { buf_parse(&buf, '\n', up->username, USER_PASS_LEN); + /* The password starts on the next line, even if the username was truncated. */ + const char *password = strchr(auth_file, '\n'); + password = password ? password + 1 : ""; + buf_set_read(&buf, (uint8_t *)password, strlen(password) + 1); } buf_parse(&buf, '\n', up->password, USER_PASS_LEN); @@ -283,6 +287,14 @@ msg(M_FATAL, "Error reading username from %s authfile: %s", prefix, auth_file); } + if (!strchr(up->username, '\n')) + { + /* Consume the rest of the username line before reading the password. */ + int c; + while ((c = fgetc(fp)) != '\n' && c != EOF) + { + } + } } chomp(up->username); diff --git a/tests/unit_tests/openvpn/test_user_pass.c b/tests/unit_tests/openvpn/test_user_pass.c index adcf74a..776a86a 100644 --- a/tests/unit_tests/openvpn/test_user_pass.c +++ b/tests/unit_tests/openvpn/test_user_pass.c @@ -366,6 +366,58 @@ assert_string_equal(up.password, "fuser"); } +static void +test_get_user_pass_long_username(void **state) +{ + struct gc_arena gc = gc_new(); + const char *authfile = platform_create_temp_file(platform_get_tmp_dir(), "user_pass", &gc); + assert_non_null(authfile); + const size_t lengths[] = { USER_PASS_LEN - 2, USER_PASS_LEN - 1, USER_PASS_LEN + 10 }; + const char *endings[] = { "", "\n", "\n\n", "\nfpassword\n", "\r\nfpassword\r\n" }; + + const bool inline_mode[] = { false, true }; + for (size_t mode = 0; mode < SIZE(inline_mode); mode++) + { + const bool use_inline_creds = inline_mode[mode]; + for (size_t i = 0; i < SIZE(lengths); i++) + { + for (size_t j = 0; j < SIZE(endings); j++) + { + struct user_pass up = { 0 }; + char creds[USER_PASS_LEN + 64]; + memset(creds, 'u', lengths[i]); + strcpy(creds + lengths[i], endings[j]); + if (!use_inline_creds) + { + FILE *fp = platform_fopen(authfile, "w"); + assert_non_null(fp); + assert_true(fputs(creds, fp) >= 0); + assert_int_equal(fclose(fp), 0); + } + + const bool missing_password = j < 3; + if (missing_password) + { + expect_string(query_user_exec_builtin, query_user[i].prompt, + "Enter UT Password:"); + will_return(query_user_exec_builtin, "cpassword"); + } + will_return(query_user_exec_builtin, true); + assert_true(get_user_pass_cr(&up, use_inline_creds ? creds : authfile, "UT", + use_inline_creds ? GET_USER_PASS_INLINE_CREDS : 0, NULL)); + /* Truncation must not change where the password line starts. */ + creds[lengths[i] < USER_PASS_LEN ? lengths[i] : USER_PASS_LEN - 1] = '\0'; + assert_true(up.defined); + assert_string_equal(up.username, creds); + assert_string_equal(up.password, + missing_password ? "cpassword" : "fpassword"); + } + } + } + assert_true(platform_unlink(authfile)); + gc_free(&gc); +} + #ifdef ENABLE_MANAGEMENT static void test_get_user_pass_dynamic_challenge(void **state) @@ -474,6 +526,7 @@ cmocka_unit_test(test_get_user_pass_inline_creds), cmocka_unit_test(test_get_user_pass_authfile_stdin), cmocka_unit_test(test_get_user_pass_authfile_file), + cmocka_unit_test(test_get_user_pass_long_username), #ifdef ENABLE_MANAGEMENT cmocka_unit_test(test_get_user_pass_dynamic_challenge), cmocka_unit_test(test_get_user_pass_static_challenge),