From patchwork Wed Jun 5 10:27:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "ralf_lici (Code Review)" X-Patchwork-Id: 3719 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:2b18:b0:57d:b2cb:6cf with SMTP id cr24csp155789mab; Wed, 5 Jun 2024 03:27:51 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVhxlru+5T8QtiJAFup0p3CQJeZ2Fmzr6sP/ZFKFSRxDbveHs+8xuANnYuUHmAjpadluLnwf0wQvLgZezo7Y1TFfVlDT1g= X-Google-Smtp-Source: AGHT+IF8YgtjpVJ91gXxrG8iDi6hUyqtOxMuHVH2SYF7jSnuBuNZ97OcK9P2xlYUpMHN/HyGmXIG X-Received: by 2002:a05:6a00:3d47:b0:6ec:ee44:17bb with SMTP id d2e1a72fcca58-703e59ef15emr2226100b3a.2.1717583271450; Wed, 05 Jun 2024 03:27:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1717583271; cv=none; d=google.com; s=arc-20160816; b=hONaclFp5+1XJ7z14XCTW6LS+OkHdlK4PBUp8IjXZnq+kZMIvJIb72ToPNySh7rY6T N+csCgLIZYUxDctLGmcLfyhmtqtM8Mu2G/XvSUXVmzDIlZd07RY2/hF/RgUJ+ngec7/i obKPV4Q+wp/D0ilJyF/wDqkMorZWtkO7V+rvBRzZPBcn4UABw689K5zFXRUqudZKnRSW gXOj4ciNvd/gEoTP5O54bgJx+SJj8WZwRBTXPt2meA14SM75s4QgKx+ppwZLqCXwtI6e YJS4YC1lCMenLgh4+cgyrwd4HUNQ1+L5+YGnjBk2YJ47lWhM7yGd726mrk9ESJC+hAIM 4Ztg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=gnSQyeVW4P9qcAs9IhTCMN1GLpbhPblqmVeka8L375I=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=UOMoFgGsx5KNp4N0ulzcWCT+87V0tZJ4QS1WfE+AVc+CDmr9rST6/+CEiuZfSzYmm+ 9tNhrcZBYmJzLKIeGi/gdjRMW34TQeCx3QDEVKP0n/q0uWALeNMrxqS9uTckdXqGbSSU EeV3RO1DRlckVr04fiE6aAGaffigsOcANZtcw5DZClH4AOHvgyzALRaqQHPzqMCrqUZU 9n9ODMz+jQYUvKlXTM8zDIfprGjqg8AuuBAmuSEa99PwfhuWANXFEWfatxFEH8bcgdv4 ykfFC70xjcL8hk6O5GsOQ19Vs/OeyW4aXzmU/dthe8TgNlMK+8sUnLzqjW4YosoHuysD NHnA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=k4dm2rT7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Bsz2hQLI; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=hDZ1KgFX; 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=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 41be03b00d2f7-6c35b223047si9553641a12.525.2024.06.05.03.27.51 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Jun 2024 03:27:51 -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=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=k4dm2rT7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Bsz2hQLI; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=hDZ1KgFX; 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=openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1sEnrZ-0005tA-S5; Wed, 05 Jun 2024 10:27:25 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1sEnrX-0005t2-Pd for openvpn-devel@lists.sourceforge.net; Wed, 05 Jun 2024 10:27:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=LIYZ5n/52tciggCUajOSMKkmkOGG5YXembGY2lSN/9c=; b=k4dm2rT7p35hTUigGgF0TwJjL7 Ed0dbVC1yC0U+T/4zXRoMxYQneOsGwIJKotZYDMgoK59eBcbRwlxiYmHk6tqLysU3eOh4tChoUgi4 jWVXtczNQj1YwbZ4bOhYgneR4ctDCH0WY6CosMDXf2wWUJBPIUjOVCf7yr65Pf/6AoSY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=LIYZ5n/52tciggCUajOSMKkmkOGG5YXembGY2lSN/9c=; b=B sz2hQLI9vCehpV/djtH3btwGMOEbIW0KYZuCAmpTRneAqO0o/2mcUuTBiig5hTm4fvttTTbIn8oiD NWH6ShQAM9M4bPzH2X0duxxHirGQSmjCq9tMzGF80/QdOYGnbdbYyGWnmR86Zo/FhEwcLFRufMPs0 FeE/zpmjczVGNK6k=; Received: from mail-wm1-f42.google.com ([209.85.128.42]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1sEnrU-000345-NJ for openvpn-devel@lists.sourceforge.net; Wed, 05 Jun 2024 10:27:23 +0000 Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-42138eadf64so33345685e9.3 for ; Wed, 05 Jun 2024 03:27:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1717583233; x=1718188033; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=LIYZ5n/52tciggCUajOSMKkmkOGG5YXembGY2lSN/9c=; b=hDZ1KgFXT5EL2pN7slgsRyqNdlx8yIJy3U7mycvoyi8rPLtIkPZP1gTiQ+5UIg3+IZ eBooPlMB+CN8W3tvhfHufTTO+b8givDgtNtkQVNXy31d2kXlPSJdrFaOuW+mkADqHozT aPL8MvXlCmBQEOFKYAYN9/MWgO4cQpnElPNjHeAqQYIqPiSLbASYC/+QY4OtQDCk99Yr QqoAdWsctT8xLEHvXWUzf2Tuph1a7KHkiY00CS/GD5n9ZH6eFQyRtwKQ35ivLflQQbhC GTpBnuzEShpvHXIblmSW3X0wKOabogpsgWzc/tPTiT0O339ZEwmk2QdyCI8yu5wUQT45 +S7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717583233; x=1718188033; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LIYZ5n/52tciggCUajOSMKkmkOGG5YXembGY2lSN/9c=; b=FOSxkkpGG3AKK9CpvB+FJtfFYz/5a8tJGs2dzEPdS2wMZDexWrJlT7KRKM/smrreh2 xmOw4JAF+nlvzIPyGNHsTqXMgaZjUtPgKafF25a5/Ivc8aHuZaUyD9cCkAtMOgFWzkI2 2hHsdqa+KgYrMKLJ2dfEIcblMlG/pftr+aoP+8Fg3QiVdzQXcL2z/6IbL1/n+HgRv2kQ B03cVZy6jxbljK8Te7/7Z9NcUPz6PPoLxedP3DemckwNn9WVAu3p8nfUmm/gIdCYl2Ly Ez+/zO3PSMcMiiRKQYOLoioU3gWg4lHURgVELDYEgbLzPMQXlPNJdLjU5V+h8MwzN4yt F/Dw== X-Gm-Message-State: AOJu0YzEQCw+ZSu2DqwI6/WmMx17Xz5AwaWe9XL/GwXq3kjRqby+E279 zcGYZ/dmSFh0/h97d2VlvlruDHe1AibLBKPBgM9Wg9OsB6c5ZsNp3qXKrbZypHo= X-Received: by 2002:a05:600c:3550:b0:41f:fca0:8c04 with SMTP id 5b1f17b1804b1-421562dd279mr17684865e9.11.1717583232822; Wed, 05 Jun 2024 03:27:12 -0700 (PDT) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42158110cb7sm16550845e9.15.2024.06.05.03.27.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Jun 2024 03:27:12 -0700 (PDT) From: "mattock (Code Review)" X-Google-Original-From: "mattock (Code Review)" X-Gerrit-PatchSet: 1 Date: Wed, 5 Jun 2024 10:27:11 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I1b54da258c7d15551b6c3de7522a0d19afdb66de X-Gerrit-Change-Number: 643 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 471e045b9c6b8ff32c291ad43249e07fd19268ab References: Message-ID: <527602e3daf46cfa68b51a92020d905af86089d4-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.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: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] 0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [209.85.128.42 listed in sa-accredit.habeas.com] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [209.85.128.42 listed in bl.score.senderscore.com] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.42 listed in wl.mailspike.net] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -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 -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1sEnrU-000345-NJ Subject: [Openvpn-devel] [L] Change in openvpn[master]: Add t_server_null test suite 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: , Reply-To: samuli.seppanen@gmail.com, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1801016596550256406?= X-GMAIL-MSGID: =?utf-8?q?1801016596550256406?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/643?usp=email to review the following change. Change subject: Add t_server_null test suite ...................................................................... Add t_server_null test suite Change-Id: I1b54da258c7d15551b6c3de7522a0d19afdb66de Signed-off-by: Samuli Seppänen --- M .gitignore A doc/t_server_null.rst M tests/Makefile.am A tests/null_client_up.sh A tests/t_server_null.rc-sample A tests/t_server_null.sh A tests/t_server_null_client.sh A tests/t_server_null_default.rc A tests/t_server_null_server.sh A tests/t_server_null_stress.sh 10 files changed, 566 insertions(+), 2 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/43/643/1 diff --git a/.gitignore b/.gitignore index 92d65bf..db8bb73 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ tests/t_client.sh tests/t_client-*-20??????-??????/ +tests/t_server_null.rc t_client.rc t_client_ips.rc tests/unit_tests/**/*_testdriver diff --git a/doc/t_server_null.rst b/doc/t_server_null.rst new file mode 100644 index 0000000..233e659 --- /dev/null +++ b/doc/t_server_null.rst @@ -0,0 +1,146 @@ +Notes for the --dev null test suite +=================================== + +Introduction +------------ + +The *--dev null test suite* is primary targeted at testing client connections +to the "just compiled" version of OpenVPN. The name is derived from "null" +device type in OpenVPN. In particular, when *--dev null --ifconfig-noexec* is +used in OpenVPN client configuration one does not need to run OpenVPN with root +privileges because interface, routing, etc. configuration is not done at all. +This is still enough to ensure that the OpenVPN client can connect to a server +instance. + +The main features of the test suite: + +* Parallelized for fairly high performance +* Mostly operating-system agnostic +* Tested on Fedora Linux 38 and FreeBSD 14 +* Should be POSIX shell compliant but uses Bash now +* Uses the sample certificates and keys +* Supports running multiple servers and clients +* Supports running servers directly as root and with sudo +* Supports using different OpenVPN client versions + + * The "current" (just compiled) version + * Any other OpenVPN versions that is present on the filesystem + +* Support testing for success as well as failure +* Test cases (client configurations) and server setups (server configurations) are stored in a configuration file, i.e. data and code have been separated +* Configuration file format is nearly identical to t_client.rc configuration +* Supports a set of default tests, overriding default test settings and adding local tests + +Prerequisites +------------- + +Running the test suite requires the following: + +* *bash* for running the tests +* root-level privileges for launching the servers + + * run as root + * a privilege escalation tool (sudo, doas, su) and the permission to become root + +Technical implementation +------------------------ + +The test suite is completely parallelized to allow running a large number of +server and client combinations quickly. + +A normal test run looks like this: + +#. Server instances start +#. Brief wait +#. Client instances start +#. Tests run +#. Client instances stop +#. Brief wait +#. Server instances stop + +The tests suite is launched via "make check": + +* make check + + * t_server_null.sh + + * t_server_null_server.sh + + * Launches the compiled OpenVPN server instances as root (if necessary with sudo or su) in the background. The servers are killed using their management interface once all clients have exited. + + * t_server_null_client.sh + + * Waits until servers have launched. Then launch all clients, wait for them to exit and then check test results by parsing the client log files. Each client kills itself after some delay using an "--up" script. + +Note that "make check" moves on once *t_server_null_client.sh* has exited. At +that point *t_server_null_server.sh* is still running, because it exists only +after waiting a few seconds for more client connections to potentially appear. +This is a feature and not a bug, but means that launching "make check" runs too +quickly might cause test failures or unexpected behavior such as leftover +OpenVPN server processes. + +Configuration +------------- + +The test suite reads its configuration from two files: + +* *tests/t_server_null_defaults.rc:* default test configuration that should work on any system +* *tests/t_server_null.rc:* a local configuration file; can be used to add additional tests or override settings from the default test configuration. Must be present or tests will be skipped, but can be an empty file. + +The configuration syntax is very similar to *t_client.rc*. New server instances can be +defined like this:: + + SERVER_NAME_5="t_server_null_server-11195_udp" + SERVER_MGMT_PORT_5="11195" + SERVER_EXEC_5="${SERVER_EXEC}" + SERVER_CONF_5="${SERVER_CONF_BASE} --lport 11195 --proto udp --management 127.0.0.1 ${SERVER_MGMT_PORT_5}" + +In this case the server instance identifier is **5**. Variables such as +*SERVER_EXEC* and *SERVER_CONF_BASE* are defined in +*t_server_null_defaults.rc*. To enable this server instance add it to the +server list:: + + TEST_SERVER_LIST="1 2 5" + +The client instances are added similarly:: + + TEST_NAME_9="t_server_null_client.sh-openvpn_current_udp_custom" + SHOULD_PASS_9="yes" + CLIENT_EXEC_9="${CLIENT_EXEC}" + CLIENT_CONF_9="${CLIENT_CONF_BASE} --remote 127.0.0.1 1194 udp --proto udp" + +In this case the test identifier is **9**. *CLIENT_EXEC* and *CLIENT_CONF_BASE* +are defined in *t_server_null_defaults.rc*. The variable *SHOULD_PASS* +determines that this particular test is supposed to succeed and not fail. To +enable this client instance add it to the test list:: + + TEST_RUN_LIST="1 2 5 9" + +Stress-testing the --dev null test suite +---------------------------------------- + +It is very easy to introduce subtle, difficult to debug issues to the --dev +null tests when you make changes to it. These issues can be difficult to spot: +based on practical experience a bad change can make the test failure rate go +from 0% (normal) to anywhere between 1% and 20%. You can spot these issues with +the provided stress-test script, *t_server_null_stress.sh*. It calls *make check* +over and over again in a loop and when failures occur it saves the output under +*tests/make-check*. + +To follow the test flow on Linux you can run this while stress-testing:: + + watch -n 0.5 "ps aux|grep -E '(openvpn|t_server_null_server.sh)'|grep -vE '(suppress|grep|tail)'" + +Regarding privilege escalation +------------------------------ + +The --dev null test servers need to be launched as root. Either run the tests +as root directly, or configure a privilege escalation tool of your choice in +*t_server_null.rc*. For example, to use sudo:: + + SUDO_EXEC=`which sudo` + RUN_SUDO="${SUDO_EXEC} -E" + +If you do stress-testing with *t_server_null_stress.sh* make sure your +privilege escalation authorization does not time out: if it does, then a +reauthorization prompt will interrupt your tests. diff --git a/tests/Makefile.am b/tests/Makefile.am index 5e9ad0a..f26b3b8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,10 +15,10 @@ SUBDIRS = unit_tests AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING) System Tests' -LOG_DRIVER = $(SHELL) $(top_srcdir)/forked-test-driver +SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/forked-test-driver if !WIN32 -test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh +test_scripts = t_client.sh t_lpback.sh t_cltsrv.sh t_server_null.sh check_PROGRAMS = ntlm_support if HAVE_SITNL @@ -27,6 +27,7 @@ endif TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)" +TEST_EXTENSIONS = .sh TESTS = $(test_scripts) dist_noinst_SCRIPTS = \ @@ -34,8 +35,14 @@ t_cltsrv-down.sh \ t_lpback.sh \ t_net.sh \ + t_server_null.sh \ + t_server_null_client.sh \ + t_server_null_server.sh \ + t_server_null_default.rc \ update_t_client_ips.sh +t_client.log: t_server_null.log + dist_noinst_DATA = \ t_client.rc-sample diff --git a/tests/null_client_up.sh b/tests/null_client_up.sh new file mode 100755 index 0000000..d4df0c6 --- /dev/null +++ b/tests/null_client_up.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Stop the parent process (openvpn) gracefully after a small delay + +# Determine the OpenVPN PID from its pid file. This works reliably even when +# the OpenVPN process is backgrounded for parallel tests. +MY_PPID=`cat $pid` + +# Allow OpenVPN to finish initializing while waiting in the background and then +# killing the process gracefully. +(sleep 5 ; kill -15 $MY_PPID) & diff --git a/tests/t_server_null.rc-sample b/tests/t_server_null.rc-sample new file mode 100644 index 0000000..28c3773 --- /dev/null +++ b/tests/t_server_null.rc-sample @@ -0,0 +1,15 @@ +# Uncomment to run tests with sudo +#SUDO_EXEC=`which sudo` +#RUN_SUDO="${SUDO_EXEC} -E" + +TEST_RUN_LIST="1 2 3 10 11" + +TEST_NAME_10="t_server_null_client.sh-openvpn_2_6_8_udp" +SHOULD_PASS_10="yes" +CLIENT_EXEC_10="/usr/sbin/openvpn" +CLIENT_CONF_10="${CLIENT_CONF_BASE} --remote 127.0.0.1 1194 udp --proto udp" + +TEST_NAME_11="t_server_null_client.sh-openvpn_2_6_8_tcp" +SHOULD_PASS_11="yes" +CLIENT_EXEC_11="/usr/sbin/openvpn" +CLIENT_CONF_11="${CLIENT_CONF_BASE} --remote 127.0.0.1 1195 tcp --proto tcp" diff --git a/tests/t_server_null.sh b/tests/t_server_null.sh new file mode 100755 index 0000000..7ad843a --- /dev/null +++ b/tests/t_server_null.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# +TSERVER_NULL_SKIP_RC="${TSERVER_NULL_SKIP_RC:-77}" + +if ! [ -r "./t_server_null.rc" ] ; then + echo "$0: cannot find './t_server_null.rc. SKIPPING TEST.'" >&2 + exit "${TSERVER_NULL_SKIP_RC}" +fi + +. ./t_server_null.rc + +export KILL_EXEC=`which kill` +if [ $? -ne 0 ]; then + echo "$0: kill not found in \$PATH" >&2 + exit "${TSERVER_NULL_SKIP_RC}" +fi + +# Ensure PREFER_KSU is in a known state +PREFER_KSU="${PREFER_KSU:-0}" + +# make sure we have permissions to run ifconfig/route from OpenVPN +# can't use "id -u" here - doesn't work on Solaris +ID=`id` +if expr "$ID" : "uid=0" >/dev/null +then : +else + if [ "${PREFER_KSU}" -eq 1 ]; + then + # Check if we have a valid kerberos ticket + klist -l 1>/dev/null 2>/dev/null + if [ $? -ne 0 ]; + then + # No kerberos ticket found, skip ksu and fallback to RUN_SUDO + PREFER_KSU=0 + echo "$0: No Kerberos ticket available. Will not use ksu." + else + RUN_SUDO="ksu -q -e" + fi + fi + + if [ -z "$RUN_SUDO" ] + then + echo "$0: this test must run be as root, or RUN_SUDO=... " >&2 + echo " must be set correctly in 't_server_null.rc'. SKIP." >&2 + exit "${TSERVER_NULL_SKIP_RC}" + else + # Run a no-op command with privilege escalation (e.g. sudo) so that + # we (hopefully) do not have to ask the users password during the test. + if $RUN_SUDO $KILL_EXEC -0 $$ + then + echo "$0: $RUN_SUDO $KILL_EXEC -0 succeeded, good." + else + echo "$0: $RUN_SUDO $KILL_EXEC -0 failed, cannot go on. SKIP." >&2 + exit "${TSERVER_NULL_SKIP_RC}" + fi + fi +fi + +srcdir="${srcdir:-.}" + + +if [ -z "${RUN_SUDO}" ]; then + "${srcdir}/t_server_null_server.sh" & +else + $RUN_SUDO "${srcdir}/t_server_null_server.sh" & +fi + +"${srcdir}/t_server_null_client.sh" + +# When running make jobs in parallel ("make -j check") we need to ensure +# that this script does not exit before all --dev null servers are dead and +# their network interfaces are gone. Otherwise t_client.sh will fail because +# pre and post ifconfig output does not match. +wait diff --git a/tests/t_server_null_client.sh b/tests/t_server_null_client.sh new file mode 100755 index 0000000..aa71f08 --- /dev/null +++ b/tests/t_server_null_client.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash + +launch_client() { + local test_name=$1 + local log="${test_name}.log" + local pid="${test_name}.pid" + local client_exec=$2 + local client_conf=$3 + + # Ensure that old log and pid files are gone + rm -f "${log}" "${pid}" + + "${client_exec}" \ + $client_conf \ + --writepid "${pid}" \ + --setenv pid $pid \ + --log "${log}" & +} + +wait_for_results() { + tests_running="yes" + + # Wait a bit to allow an OpenVPN client process to create a pidfile to + # prevent exiting too early + sleep 1 + + while [ "${tests_running}" == "yes" ]; do + tests_running="no" + for t in $test_names; do + if [ -f "${t}.pid" ]; then + tests_running="yes" + fi + done + + if [ "${tests_running}" == "yes" ]; then + echo "Clients still running" + sleep 1 + fi + done +} + +get_client_test_result() { + local test_name=$1 + local should_pass=$2 + local log="${test_name}.log" + + grep "Initialization Sequence Completed" "${log}" > /dev/null + local exit_code=$? + + if [ $exit_code -eq 0 ] && [ "${should_pass}" = "yes" ]; then + echo "PASS ${test_name}" + elif [ $exit_code -eq 1 ] && [ "${should_pass}" = "no" ]; then + echo "PASS ${test_name} (test failure)" + elif [ $exit_code -eq 0 ] && [ "${should_pass}" = "no" ]; then + echo "FAIL ${test_name} (test failure)" + cat "${log}" + retval=1 + elif [ $exit_code -eq 1 ] && [ "${should_pass}" = "yes" ]; then + echo "FAIL ${test_name}" + cat "${log}" + retval=1 + fi +} + +# Load basic/default tests +. ${srcdir}/t_server_null_default.rc || exit 1 + +# Load additional local tests, if any +test -r ./t_server_null.rc && . ./t_server_null.rc + +# Return value for the entire test suite. Gets set to 1 if any test fails. +export retval=0 + +# Wait until servers are up. This check is based on the presence of processes +# matching the PIDs in each servers PID files +count=0 +server_max_wait=15 +while [ $count -lt $server_max_wait ]; do + server_pids="" + for i in `(set -o posix; set)|grep 'SERVER_NAME_'|cut -d "=" -f 2`; do + server_pid=`cat "${i}.pid"` + server_pids="${server_pids} ${server_pid}" + done + + server_count=`echo ${server_pids}|wc -w` + servers_up=`ps -p $server_pids|sed '1d'|wc -l` + + echo "OpenVPN test servers up: ${servers_up}/${server_count}" + + if [ $servers_up -ge $server_count ]; then + retval=0 + break + else + ((count++)) + sleep 1 + fi + + if [ $count -eq $server_max_wait ]; then + retval=1 + fi +done + +# Wait a while to let server processes to settle down +sleep 1 + +# Launch OpenVPN clients. While at it, construct a list of test names. The list +# is used later to determine when all OpenVPN clients have exited and it is +# safe to check the test results. +test_names="" +for SUF in $TEST_RUN_LIST +do + eval test_name=\"\$TEST_NAME_$SUF\" + eval client_exec=\"\$CLIENT_EXEC_$SUF\" + eval client_conf=\"\$CLIENT_CONF_$SUF\" + + test_names="${test_names} ${test_name}" + launch_client "${test_name}" "${client_exec}" "${client_conf}" +done + +# Wait until all OpenVPN clients have exited +wait_for_results + +# Check test results +for SUF in $TEST_RUN_LIST +do + eval test_name=\"\$TEST_NAME_$SUF\" + eval should_pass=\"\$SHOULD_PASS_$SUF\" + + get_client_test_result "${test_name}" $should_pass +done + +exit $retval diff --git a/tests/t_server_null_default.rc b/tests/t_server_null_default.rc new file mode 100755 index 0000000..63b6bcd --- /dev/null +++ b/tests/t_server_null_default.rc @@ -0,0 +1,66 @@ +# Notes regarding --dev null server and client configurations: +# +# The t_server_null_server.sh exits when all client pid files have gone +# missing. That is the most reliable and fastest way to detect client +# disconnections in the "everything runs on localhost" context. Checking server +# status files for client connections works, but introduces long delays as +# --explicit-exit-notify does not seem to work on all client configurations. +# This means that, by default, there is about 1 minute delay before the server +# purges clients that have already exited and have not reported back. +# +srcdir="${srcdir:-.}" +top_builddir="${top_builddir:-..}" +sample_keys="${srcdir}/../sample/sample-keys" + +DH="${sample_keys}/dh2048.pem" +CA="${sample_keys}/ca.crt" +CLIENT_CERT="${sample_keys}/client.crt" +CLIENT_KEY="${sample_keys}/client.key" +SERVER_CERT="${sample_keys}/server.crt" +SERVER_KEY="${sample_keys}/server.key" +TA="${sample_keys}/ta.key" + +# Test server configurations +MAX_CLIENTS="10" +CLIENT_MATCH="Test-Client" +SERVER_EXEC="${top_builddir}/src/openvpn/openvpn" +SERVER_BASE_OPTS="--daemon --local 127.0.0.1 --dev tun --topology subnet --server 10.29.41.0 255.255.255.0 --max-clients $MAX_CLIENTS --persist-tun --verb 3" +SERVER_CIPHER_OPTS="" +SERVER_CERT_OPTS="--ca ${CA} --dh ${DH} --cert ${SERVER_CERT} --key ${SERVER_KEY} --tls-auth ${TA} 0" +SERVER_CONF_BASE="${SERVER_BASE_OPTS} ${SERVER_CIPHER_OPTS} ${SERVER_CERT_OPTS}" + +TEST_SERVER_LIST="1 2" + +SERVER_NAME_1="t_server_null_server-1194_udp" +SERVER_MGMT_PORT_1="11194" +SERVER_EXEC_1="${SERVER_EXEC}" +SERVER_CONF_1="${SERVER_CONF_BASE} --lport 1194 --proto udp --management 127.0.0.1 ${SERVER_MGMT_PORT_1}" + +SERVER_NAME_2="t_server_null_server-1195_tcp" +SERVER_MGMT_PORT_2="11195" +SERVER_EXEC_2="${SERVER_EXEC}" +SERVER_CONF_2="${SERVER_CONF_BASE} --lport 1195 --proto tcp --management 127.0.0.1 ${SERVER_MGMT_PORT_2}" + +# Test client configurations +CLIENT_EXEC="${top_builddir}/src/openvpn/openvpn" +CLIENT_BASE_OPTS="--client --dev null --ifconfig-noexec --nobind --remote-cert-tls server --persist-tun --verb 3 --resolv-retry infinite --connect-retry-max 3 --server-poll-timeout 5 --explicit-exit-notify 3 --script-security 2 --up ${srcdir}/null_client_up.sh" +CLIENT_CIPHER_OPTS="" +CLIENT_CERT_OPTS="--ca ${CA} --cert ${CLIENT_CERT} --key ${CLIENT_KEY} --tls-auth ${TA} 1" + +TEST_RUN_LIST="1 2 3" +CLIENT_CONF_BASE="${CLIENT_BASE_OPTS} ${CLIENT_CIPHER_OPTS} ${CLIENT_CERT_OPTS}" + +TEST_NAME_1="t_server_null_client.sh-openvpn_current_udp" +SHOULD_PASS_1="yes" +CLIENT_EXEC_1="${CLIENT_EXEC}" +CLIENT_CONF_1="${CLIENT_CONF_BASE} --remote 127.0.0.1 1194 udp --proto udp" + +TEST_NAME_2="t_server_null_client.sh-openvpn_current_tcp" +SHOULD_PASS_2="yes" +CLIENT_EXEC_2="${CLIENT_EXEC}" +CLIENT_CONF_2="${CLIENT_CONF_BASE} --remote 127.0.0.1 1195 tcp --proto tcp" + +TEST_NAME_3="t_server_null_client.sh-openvpn_current_udp_fail" +SHOULD_PASS_3="no" +CLIENT_EXEC_3="${CLIENT_EXEC}" +CLIENT_CONF_3="${CLIENT_CONF_BASE} --remote 127.0.0.1 11194 udp --proto udp" diff --git a/tests/t_server_null_server.sh b/tests/t_server_null_server.sh new file mode 100755 index 0000000..02ff728 --- /dev/null +++ b/tests/t_server_null_server.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +launch_server() { + local server_name=$1 + local server_exec=$2 + local server_conf=$3 + local log="${server_name}.log" + local status="${server_name}.status" + local pid="${server_name}.pid" + + + # Ensure that old status, log and pid files are gone + rm -f "${status}" "${log}" "${pid}" + + "${server_exec}" \ + $server_conf \ + --status "${status}" 1 \ + --log "${log}" \ + --writepid "${pid}" \ + --explicit-exit-notify 3 + +} + +# Load base/default configuration +. "${srcdir}/t_server_null_default.rc" || exit 1 + +# Load local configuration, if any +test -r ./t_server_null.rc && . ./t_server_null.rc + +# Launch test servers +for SUF in $TEST_SERVER_LIST +do + eval server_name=\"\$SERVER_NAME_$SUF\" + eval server_exec=\"\$SERVER_EXEC_$SUF\" + eval server_conf=\"\$SERVER_CONF_$SUF\" + + launch_server "${server_name}" "${server_exec}" "${server_conf}" +done + +# Create a list of server pid files so that servers can be killed at the end of +# the test run. +# +export server_pid_files="" +for SUF in $TEST_SERVER_LIST +do + eval server_name=\"\$SERVER_NAME_$SUF\" + server_pid_files="${server_pid_files} ./${server_name}.pid" +done + +# Wait until clients are no more, based on the presence of their pid files. +# Based on practical testing we have to wait at least four seconds to avoid +# accidentally exiting too early. +count=0 +maxcount=4 +while [ $count -le $maxcount ]; do + ls t_server_null_client.sh*.pid > /dev/null 2>&1 + + if [ $? -eq 0 ]; then + count=0 + sleep 1 + else + ((count++)) + sleep 1 + fi +done + +echo "All clients have disconnected from all servers" + +for PID_FILE in $server_pid_files +do + SERVER_PID=`cat $PID_FILE` + $KILL_EXEC $SERVER_PID + + # Make sure that the server processes are truly dead before exiting + while : + do + ps -p $SERVER_PID > /dev/null || break + sleep 0.2 + done +done diff --git a/tests/t_server_null_stress.sh b/tests/t_server_null_stress.sh new file mode 100755 index 0000000..3dc17d9 --- /dev/null +++ b/tests/t_server_null_stress.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# Run this stress test as root to avoid sudo authorization from timing out. + +count=0 + +. ./t_server_null_default.rc + +export pid_files="" +for SUF in $TEST_SERVER_LIST +do + eval server_name=\"\$SERVER_NAME_$SUF\" + pid_files="${pid_files} ./${server_name}.pid" +done + +LOG_BASEDIR="make-check" +mkdir -p "${LOG_BASEDIR}" + +while [ $count -lt 100 ]; do + count=$(( count + 1 )) + make check TESTS=t_server_null.sh SUBDIRS= > /dev/null 2>&1 + retval=$? + + echo "Iteration ${count}: return value ${retval}" >> "${LOG_BASEDIR}/make-check.log" + if [ $retval -ne 0 ]; then + DIR="${LOG_BASEDIR}/make-check-${count}" + mkdir -p "${DIR}" + cp t_server_null*.log "${DIR}/" + cp test-suite.log "${DIR}/" + ps aux|grep openvpn|grep -vE '(suppress|grep)' > "${DIR}/psaux" + fi +done