From patchwork Fri Oct 10 21:11:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4497 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:7d42:b0:72f:f16c:e055 with SMTP id fr2csp601270mab; Fri, 10 Oct 2025 14:12:08 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX3bkJ1mN9Jl4c9wNGRiXmF+wySTrgkC0fMTDV1/mgbfxf/mVyQ3zkMPd8MKz99g3tqgGjTeGKeTIg=@openvpn.net X-Google-Smtp-Source: AGHT+IERPvaGPyxeXAQP6lE99RrsNB//92O9/7tXN83ZON/qyqYx6nzn6Q+Pj55mLdNeCgnX9Bw6 X-Received: by 2002:a05:6808:85f9:b0:441:8f74:fd6 with SMTP id 5614622812f47-4418f741d09mr3279473b6e.67.1760130727856; Fri, 10 Oct 2025 14:12:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1760130727; cv=none; d=google.com; s=arc-20240605; b=Hyn0ghn55dWgx6SRrIqBfKDNiwueStLVUUMzTp4HGMKz0TVd/IaX4SYcrKHWJibrm1 /37wmb20QTr2FdKI1+bkaMDsiFM05hZ+fHQVDwOdEwXdLbBPRJQoHydLX8585hk0wZ7U IkwuQ0VTEFoDrZS8A1JBihCmpY770areXaBO5Zr2As2VnwEa7JBhNQub1nn636yKYErP 3fmnHK6gMAgsiipPyI+d/Mq+twcyTUdMiHqZGnzd+Gb+Dw5SvGJwaRxTOXZP70rb/y9f GyO2YTiK6bun+SOdQJZbyczz11MHx/ew+Xx3eU07pFeIImwS0BAmiIl6gCffExG7/Qva 60hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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=wNz02gGakW6AOZMMgTuqOo7T32ch0ln7GUm+SWT74n8=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=G+5udRNPBYPMcGMtBYB2i7Zu/l0s1HTNh+FMkfB1Ngb2kEPHSVdd4KzUg56FVUWlwt KxSA097Ps5ESE+ajooixcEvOl65IyDAX56TruG1JYKM72vilH+OAOsvWMGtlnOX4diyZ 4iNONW4e1m2o7MhoYjr7xjyy39Qy4I9my2VFKb36SubcLXuxpzaXuuvoFTTc5p2Bb9Fg XEZyJRrqdL932CtXurGCdkViqdMg1IcxxhS0juX7imGhn51z84IMSwA1w+Z8TzfMJnYm yZCO8QySSIlqOXTemcweEQNCHee8ZF8+R9I5EkSEW0IfZyPUpX/hDIDgVtxaC0LWTPlD 7OyA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=QkB0WevE; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=MEkiHJ25; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Scy8sav4; 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 46e09a7af769-7c0f8fcaac3si842594a34.52.2025.10.10.14.12.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 10 Oct 2025 14:12:07 -0700 (PDT) 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=QkB0WevE; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=MEkiHJ25; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Scy8sav4; 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-Owner; bh=wNz02gGakW6AOZMMgTuqOo7T32ch0ln7GUm+SWT74n8=; b=QkB0WevE80GNzvpPYkGE7fckXD JYf90Nnp6VsvQyXGFCF3+y7mogt1ju5MdhIuzD1nKuyeB5dg0XnfBWNes09t5mT2Brzvf7VmDDat/ wEA/hrf42+LWqZUGGPm7WN3EW9XS599Ol5FGEYOa6JP8qcuidNy9crR0tFgQGbXjWxNY=; 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 1v7KPE-00047q-T7; Fri, 10 Oct 2025 21:12:04 +0000 Received: from [172.30.29.66] (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 1v7KPD-00047j-7j for openvpn-devel@lists.sourceforge.net; Fri, 10 Oct 2025 21:12:03 +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=aM92BFRBm6Grl4G0SZmWIPkXr0WcHdK01pFXNLG88K0=; b=MEkiHJ259Dvf36PrfExhn1h2uz 2ahe04c+4cUPXexyTyWQK8avLeXdCgLkp1JsVmKtd4OnA4j3LIcGcc5AM6rjlEFWOAotyq02W3K1P GmTi4+ipVDSNnUyTcfkiu53k/yY+ZfuCrJZWWZQ7JmPlRk5ppALQN34pMmwSKySLVNOE=; 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=aM92BFRBm6Grl4G0SZmWIPkXr0WcHdK01pFXNLG88K0=; b=Scy8sav4M9PcEeO3GaSeNZ0t2r gzxablSkhZMiGs5quqsyQP5CkXwJgwFPqH6MyNJ6nih2RW1pyRbv8S0z1z+bRQCX6CHbxWknecz7K xBKsOc0Twm7RmQQ77/B8WydMV2e3//2K09ZwFrDqEDkMGf2Ig61Xxn5+Z4pMONnjLGWo=; Received: from [193.149.48.134] (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.95) id 1v7KPB-0007Nb-Su for openvpn-devel@lists.sourceforge.net; Fri, 10 Oct 2025 21:12:03 +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 59ALBs37002797 for ; Fri, 10 Oct 2025 23:11:54 +0200 Received: (from gert@localhost) by blue.greenie.muc.de (8.18.1/8.18.1/Submit) id 59ALBshe002796 for openvpn-devel@lists.sourceforge.net; Fri, 10 Oct 2025 23:11:54 +0200 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Fri, 10 Oct 2025 23:11:47 +0200 Message-ID: <20251010211154.2780-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.49.1 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: Frank Lichtenheld Required a fix to mock_msg to make tests of M_FATAL possible at all. This also tests some cases which arguably should throw a fatal error but do not. v2: - Suppress LeakSanitizer errors for fatal error tests. Due to aborting the function, the memory will not be cleaned up, but that is expected. v3: - Disable assert tests with MSVC. Does not seem to [...] 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 X-Headers-End: 1v7KPB-0007Nb-Su Subject: [Openvpn-devel] [PATCH v13] test_user_pass: Check fatal errors for empty username/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: =?utf-8?q?1845630837725829438?= X-GMAIL-MSGID: =?utf-8?q?1845630837725829438?= From: Frank Lichtenheld Required a fix to mock_msg to make tests of M_FATAL possible at all. This also tests some cases which arguably should throw a fatal error but do not. v2: - Suppress LeakSanitizer errors for fatal error tests. Due to aborting the function, the memory will not be cleaned up, but that is expected. v3: - Disable assert tests with MSVC. Does not seem to catch the error correctly. - Rebase on top of parallel-tests series to get AM_TESTS_ENVIRONMENT. v8: - Update srcdir handling according to master. v10: - Update mock_msg.c fatal handling to be compatible with NO_CMOCKA. Change-Id: Icabc8acf75638c86c8c395e9ffecba7a7226cd97 Signed-off-by: Frank Lichtenheld Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/474 --- 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/+/474 This mail reflects revision 13 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/CMakeLists.txt b/CMakeLists.txt index 9511bda..9e0b46e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -729,7 +729,7 @@ add_test(${test_name} ${test_name}) # for compat with autotools make check set_tests_properties(${test_name} PROPERTIES - ENVIRONMENT "srcdir=${_UT_SOURCE_DIR}") + ENVIRONMENT "srcdir=${_UT_SOURCE_DIR};LSAN_OPTIONS=suppressions=${_UT_SOURCE_DIR}/input/leak_suppr.txt") endif () add_executable(${test_name} tests/unit_tests/openvpn/${test_name}.c diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 05c0ea5..50f4a11 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -4,6 +4,8 @@ AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING) Unit-Tests' +AM_TESTS_ENVIRONMENT = export LSAN_OPTIONS=suppressions=$(srcdir)/input/leak_suppr.txt; + test_binaries = argv_testdriver buffer_testdriver crypto_testdriver packet_id_testdriver auth_token_testdriver \ ncp_testdriver misc_testdriver options_parse_testdriver pkt_testdriver ssl_testdriver \ user_pass_testdriver push_update_msg_testdriver provider_testdriver socket_testdriver diff --git a/tests/unit_tests/openvpn/input/appears_empty.txt b/tests/unit_tests/openvpn/input/appears_empty.txt new file mode 100644 index 0000000..ffb749a --- /dev/null +++ b/tests/unit_tests/openvpn/input/appears_empty.txt @@ -0,0 +1,3 @@ + + +(contains \t\n\t\n) diff --git a/tests/unit_tests/openvpn/input/empty.txt b/tests/unit_tests/openvpn/input/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit_tests/openvpn/input/empty.txt diff --git a/tests/unit_tests/openvpn/input/leak_suppr.txt b/tests/unit_tests/openvpn/input/leak_suppr.txt new file mode 100644 index 0000000..72ebfe0 --- /dev/null +++ b/tests/unit_tests/openvpn/input/leak_suppr.txt @@ -0,0 +1 @@ +leak:_assertions$ diff --git a/tests/unit_tests/openvpn/mock_msg.c b/tests/unit_tests/openvpn/mock_msg.c index a2aa3f9..2cd1336 100644 --- a/tests/unit_tests/openvpn/mock_msg.c +++ b/tests/unit_tests/openvpn/mock_msg.c @@ -41,7 +41,6 @@ msglvl_t x_debug_level = 0; /* Default to (almost) no debugging output */ msglvl_t print_x_debug_level = 0; -bool fatal_error_triggered = false; char mock_msg_buf[MOCK_MSG_BUF]; @@ -75,7 +74,6 @@ { if (flags & M_FATAL) { - fatal_error_triggered = true; printf("FATAL ERROR:"); } CLEAR(mock_msg_buf); @@ -86,6 +84,12 @@ printf("%s", mock_msg_buf); printf("\n"); } +#ifndef NO_CMOCKA + if (flags & M_FATAL) + { + mock_assert(false, "FATAL ERROR", __FILE__, __LINE__); + } +#endif } void diff --git a/tests/unit_tests/openvpn/test_user_pass.c b/tests/unit_tests/openvpn/test_user_pass.c index 32ec59f..f5dddd6 100644 --- a/tests/unit_tests/openvpn/test_user_pass.c +++ b/tests/unit_tests/openvpn/test_user_pass.c @@ -180,6 +180,16 @@ reset_user_pass(&up); + /*FIXME: query_user_exec() called even though nothing queued */ + will_return(query_user_exec_builtin, true); + /*FIXME: silently removes control characters but does not error out */ + assert_true(get_user_pass_cr(&up, "\t\n\t", "UT", flags, NULL)); + assert_true(up.defined); + assert_string_equal(up.username, ""); + assert_string_equal(up.password, ""); + + reset_user_pass(&up); + 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); @@ -212,6 +222,25 @@ assert_string_equal(up.password, "cpassword"); } +/* NOTE: expect_assert_failure does not seem to work with MSVC */ +#ifndef _MSC_VER +/* NOTE: leaks gc memory */ +static void +test_get_user_pass_inline_creds_assertions(void **state) +{ + struct user_pass up = { 0 }; + reset_user_pass(&up); + unsigned int flags = GET_USER_PASS_INLINE_CREDS; + + reset_user_pass(&up); + + /*FIXME: query_user_exec() called even though nothing queued */ + /*FIXME? username error thrown very late in stdin handling */ + will_return(query_user_exec_builtin, true); + expect_assert_failure(get_user_pass_cr(&up, "\nipassword\n", "UT", flags, NULL)); +} +#endif + static void test_get_user_pass_authfile_stdin(void **state) { @@ -239,8 +268,39 @@ assert_true(up.defined); assert_string_equal(up.username, "user"); assert_string_equal(up.password, "cpassword"); + + reset_user_pass(&up); + + flags |= GET_USER_PASS_PASSWORD_ONLY; + expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:"); + will_return(query_user_exec_builtin, ""); + will_return(query_user_exec_builtin, true); + /*FIXME? does not error out on empty password */ + assert_true(get_user_pass_cr(&up, "stdin", "UT", flags, NULL)); + assert_true(up.defined); + assert_string_equal(up.username, "user"); + assert_string_equal(up.password, ""); } +/* NOTE: expect_assert_failure does not seem to work with MSVC */ +#ifndef _MSC_VER +/* NOTE: leaks gc memory */ +static void +test_get_user_pass_authfile_stdin_assertions(void **state) +{ + struct user_pass up = { 0 }; + reset_user_pass(&up); + unsigned int flags = 0; + + expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Username:"); + expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:"); + will_return(query_user_exec_builtin, ""); + will_return(query_user_exec_builtin, "cpassword"); + will_return(query_user_exec_builtin, true); + expect_assert_failure(get_user_pass_cr(&up, "stdin", "UT", flags, NULL)); +} +#endif + static void test_get_user_pass_authfile_file(void **state) { @@ -260,6 +320,17 @@ reset_user_pass(&up); + openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/appears_empty.txt"); + /*FIXME: query_user_exec() called even though nothing queued */ + will_return(query_user_exec_builtin, true); + /*FIXME? does not error out */ + assert_true(get_user_pass_cr(&up, authfile, "UT", flags, NULL)); + assert_true(up.defined); + assert_string_equal(up.username, ""); + assert_string_equal(up.password, ""); + + reset_user_pass(&up); + openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/user_only.txt"); expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:"); will_return(query_user_exec_builtin, "cpassword"); @@ -361,6 +432,29 @@ } #endif /* ENABLE_MANAGEMENT */ +/* NOTE: expect_assert_failure does not seem to work with MSVC */ +#ifndef _MSC_VER +/* NOTE: leaks gc memory */ +static void +test_get_user_pass_authfile_file_assertions(void **state) +{ + struct user_pass up = { 0 }; + reset_user_pass(&up); + unsigned int flags = 0; + + char authfile[PATH_MAX] = { 0 }; + + openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/empty.txt"); + expect_assert_failure(get_user_pass_cr(&up, authfile, "UT", flags, NULL)); + + reset_user_pass(&up); + + flags |= GET_USER_PASS_PASSWORD_ONLY; + openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/empty.txt"); + expect_assert_failure(get_user_pass_cr(&up, authfile, "UT", flags, NULL)); +} +#endif /* ifndef _MSC_VER */ + const struct CMUnitTest user_pass_tests[] = { cmocka_unit_test(test_get_user_pass_defined), cmocka_unit_test(test_get_user_pass_needok), @@ -371,6 +465,11 @@ cmocka_unit_test(test_get_user_pass_dynamic_challenge), cmocka_unit_test(test_get_user_pass_static_challenge), #endif /* ENABLE_MANAGEMENT */ +#ifndef _MSC_VER + cmocka_unit_test(test_get_user_pass_inline_creds_assertions), + cmocka_unit_test(test_get_user_pass_authfile_stdin_assertions), + cmocka_unit_test(test_get_user_pass_authfile_file_assertions), +#endif }; int