1# 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2025 Rubicon Communications, LLC (Netgate) 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26 27. $(atf_get_srcdir)/utils.subr 28 29atf_test_case "basic" "cleanup" 30basic_head() 31{ 32 atf_set descr 'Basic one shot rule test' 33 atf_set require.user root 34} 35 36basic_body() 37{ 38 pft_init 39 40 epair=$(vnet_mkepair) 41 42 vnet_mkjail alcatraz ${epair}a 43 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 44 45 ifconfig ${epair}b 192.0.2.2/24 up 46 47 # Sanity checks 48 atf_check -s exit:0 -o ignore \ 49 ping -c 1 192.0.2.1 50 51 jexec alcatraz pfctl -e 52 pft_set_rules alcatraz \ 53 "block" \ 54 "pass in from 192.0.2.2 once" 55 56 # First once succeeds 57 atf_check -s exit:0 -o ignore \ 58 ping -c 3 192.0.2.1 59 60 # Check for '# expired' 61 atf_check -s exit:0 -e ignore \ 62 -o match:'pass in inet from 192.0.2.2 to any flags S/SA keep state once # expired' \ 63 jexec alcatraz pfctl -sr -vv 64 65 # The second one does not 66 atf_check -s exit:2 -o ignore \ 67 ping -c 3 192.0.2.1 68 69 # Flush states, still shouldn't work 70 jexec alcatraz pfctl -Fs 71 atf_check -s exit:2 -o ignore \ 72 ping -c 3 192.0.2.1 73} 74 75basic_cleanup() 76{ 77 pft_cleanup 78} 79 80atf_test_case "anchor" "cleanup" 81anchor_head() 82{ 83 atf_set descr 'Test one shot rule in anchors' 84 atf_set require.user root 85} 86 87anchor_body() 88{ 89 pft_init 90 epair=$(vnet_mkepair) 91 92 vnet_mkjail alcatraz ${epair}a 93 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 94 95 ifconfig ${epair}b 192.0.2.2/24 up 96 97 # Sanity checks 98 atf_check -s exit:0 -o ignore \ 99 ping -c 1 192.0.2.1 100 101 jexec alcatraz pfctl -e 102 pft_set_rules alcatraz \ 103 "block" \ 104 "anchor \"once\" {\n 105 pass in from 192.0.2.2 once\n 106 }" 107 108 # First once succeeds 109 atf_check -s exit:0 -o ignore \ 110 ping -c 3 192.0.2.1 111 112 # Check for '# expired' 113 jexec alcatraz pfctl -sr -vv -a "*" 114 atf_check -s exit:0 -e ignore \ 115 -o match:'pass in inet from 192.0.2.2 to any flags S/SA keep state once # expired' \ 116 jexec alcatraz pfctl -sr -vv -a "*" 117 118 # The second one does not 119 atf_check -s exit:2 -o ignore \ 120 ping -c 3 192.0.2.1 121} 122 123anchor_cleanup() 124{ 125 pft_cleanup 126} 127 128atf_init_test_cases() 129{ 130 atf_add_test_case "basic" 131 atf_add_test_case "anchor" 132} 133