1#	$NetBSD: t_ipsec_tcp.sh,v 1.2 2017/08/03 03:16:27 ozaki-r Exp $
2#
3# Copyright (c) 2017 Internet Initiative Japan Inc.
4# All rights reserved.
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28SOCK_LOCAL=unix://ipsec_local
29SOCK_PEER=unix://ipsec_peer
30BUS=./bus_ipsec
31
32DEBUG=${DEBUG:-true}
33
34setup_sasp()
35{
36	local proto=$1
37	local algo_args="$2"
38	local ip_local=$3
39	local ip_peer=$4
40	local tmpfile=./tmp
41	local extra=
42
43	export RUMP_SERVER=$SOCK_LOCAL
44	cat > $tmpfile <<-EOF
45	add $ip_local $ip_peer $proto 10000 $algo_args;
46	add $ip_peer $ip_local $proto 10001 $algo_args;
47	spdadd $ip_local $ip_peer any -P out ipsec $proto/transport//require;
48	$extra
49	EOF
50	$DEBUG && cat $tmpfile
51	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
52	# XXX it can be expired if $lifetime is very short
53	#check_sa_entries $SOCK_LOCAL $ip_local $ip_peer
54
55	export RUMP_SERVER=$SOCK_PEER
56	cat > $tmpfile <<-EOF
57	add $ip_local $ip_peer $proto 10000 $algo_args;
58	add $ip_peer $ip_local $proto 10001 $algo_args;
59	spdadd $ip_peer $ip_local any -P out ipsec $proto/transport//require;
60	$extra
61	EOF
62	$DEBUG && cat $tmpfile
63	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
64	# XXX it can be expired if $lifetime is very short
65	#check_sa_entries $SOCK_PEER $ip_local $ip_peer
66}
67
68prepare_file()
69{
70	local file=$1
71	local data="0123456789"
72
73	touch $file
74	for i in `seq 1 512`
75	do
76		echo $data >> $file
77	done
78}
79
80test_tcp()
81{
82	local local_proto=$1
83	local ip_local=$2
84	local peer_proto=$3
85	local ip_peer=$4
86	local port=1234
87	local file_send=./file.send
88	local file_recv=./file.recv
89	local opts=
90
91	if [ $local_proto = ipv4 ]; then
92		opts="-N -w 3 -4"
93	else
94		opts="-N -w 3 -6"
95	fi
96
97	# Start nc server
98	start_nc_server $SOCK_PEER $port $file_recv $peer_proto
99
100	export RUMP_SERVER=$SOCK_LOCAL
101	# Send a file to the server
102	prepare_file $file_send
103	atf_check -s exit:0 $HIJACKING nc $opts $ip_peer $port < $file_send
104
105	# Check if the file is transferred correctly
106	atf_check -s exit:0 diff -q $file_send $file_recv
107
108	stop_nc_server
109	rm -f $file_send $file_recv
110}
111
112test_tcp_ipv4()
113{
114	local proto=$1
115	local algo=$2
116	local ip_local=10.0.0.1
117	local ip_peer=10.0.0.2
118	local algo_args="$(generate_algo_args $proto $algo)"
119	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
120	local outfile=./out
121
122	rump_server_crypto_start $SOCK_LOCAL netipsec
123	rump_server_crypto_start $SOCK_PEER netipsec
124	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
125	rump_server_add_iface $SOCK_PEER shmif0 $BUS
126
127	export RUMP_SERVER=$SOCK_LOCAL
128	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
129	atf_check -s exit:0 rump.ifconfig -w 10
130
131	export RUMP_SERVER=$SOCK_PEER
132	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
133	atf_check -s exit:0 rump.ifconfig -w 10
134
135	if [ $proto != none ]; then
136		setup_sasp $proto "$algo_args" $ip_local $ip_peer
137	fi
138
139	extract_new_packets $BUS > $outfile
140
141	test_tcp ipv4 $ip_local ipv4 $ip_peer
142
143	extract_new_packets $BUS > $outfile
144	$DEBUG && cat $outfile
145
146	if [ $proto != none ]; then
147		atf_check -s exit:0 \
148		    -o match:"$ip_local > $ip_peer: $proto_cap" \
149		    cat $outfile
150		atf_check -s exit:0 \
151		    -o match:"$ip_peer > $ip_local: $proto_cap" \
152		    cat $outfile
153	fi
154}
155
156test_tcp_ipv6()
157{
158	local proto=$1
159	local algo=$2
160	local ip_local=fd00::1
161	local ip_peer=fd00::2
162	local algo_args="$(generate_algo_args $proto $algo)"
163	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
164	local outfile=./out
165
166	rump_server_crypto_start $SOCK_LOCAL netinet6 netipsec
167	rump_server_crypto_start $SOCK_PEER netinet6 netipsec
168	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
169	rump_server_add_iface $SOCK_PEER shmif0 $BUS
170
171	export RUMP_SERVER=$SOCK_LOCAL
172	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local
173	atf_check -s exit:0 rump.ifconfig -w 10
174
175	export RUMP_SERVER=$SOCK_PEER
176	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_peer
177	atf_check -s exit:0 rump.ifconfig -w 10
178
179	if [ $proto != none ]; then
180		setup_sasp $proto "$algo_args" $ip_local $ip_peer
181	fi
182
183	extract_new_packets $BUS > $outfile
184
185	test_tcp ipv6 $ip_local ipv6 $ip_peer
186
187	extract_new_packets $BUS > $outfile
188	$DEBUG && cat $outfile
189
190	if [ $proto != none ]; then
191		atf_check -s exit:0 \
192		    -o match:"$ip_local > $ip_peer: $proto_cap" \
193		    cat $outfile
194		atf_check -s exit:0 \
195		    -o match:"$ip_peer > $ip_local: $proto_cap" \
196		    cat $outfile
197	fi
198}
199
200test_tcp_ipv4mappedipv6()
201{
202	local proto=$1
203	local algo=$2
204	local ip_local=10.0.0.1
205	local ip_peer=10.0.0.2
206	local ip6_peer=::ffff:10.0.0.2
207	local algo_args="$(generate_algo_args $proto $algo)"
208	local proto_cap=$(echo $proto | tr 'a-z' 'A-Z')
209	local outfile=./out
210
211	rump_server_crypto_start $SOCK_LOCAL netipsec
212	rump_server_crypto_start $SOCK_PEER netipsec netinet6
213	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
214	rump_server_add_iface $SOCK_PEER shmif0 $BUS
215
216	export RUMP_SERVER=$SOCK_LOCAL
217	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
218	atf_check -s exit:0 rump.ifconfig -w 10
219
220	export RUMP_SERVER=$SOCK_PEER
221	atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.v6only=0
222	atf_check -s exit:0 rump.ifconfig shmif0 $ip_peer/24
223	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip6_peer/96
224	atf_check -s exit:0 rump.ifconfig -w 10
225
226	if [ $proto != none ]; then
227		setup_sasp $proto "$algo_args" $ip_local $ip_peer 100
228	fi
229
230	extract_new_packets $BUS > $outfile
231
232	test_tcp ipv4 $ip_local ipv6 $ip_peer
233
234	extract_new_packets $BUS > $outfile
235	$DEBUG && cat $outfile
236
237	if [ $proto != none ]; then
238		atf_check -s exit:0 \
239		    -o match:"$ip_local > $ip_peer: $proto_cap" \
240		    cat $outfile
241		atf_check -s exit:0 \
242		    -o match:"$ip_peer > $ip_local: $proto_cap" \
243		    cat $outfile
244	fi
245}
246
247add_test_tcp()
248{
249	local ipproto=$1
250	local proto=$2
251	local algo=$3
252	local _algo=$(echo $algo | sed 's/-//g')
253	local name= desc=
254
255	if [ $proto = none ]; then
256		desc="Tests of TCP with IPsec enabled ($ipproto)"
257		name="ipsec_tcp_${ipproto}_${proto}"
258	else
259		desc="Tests of TCP with IPsec ($ipproto) $proto $algo"
260		name="ipsec_tcp_${ipproto}_${proto}_${_algo}"
261	fi
262
263	atf_test_case ${name} cleanup
264	eval "
265	    ${name}_head() {
266	        atf_set descr \"$desc\"
267	        atf_set require.progs rump_server setkey
268	    }
269	    ${name}_body() {
270	        test_tcp_${ipproto} $proto $algo
271	        rump_server_destroy_ifaces
272	    }
273	    ${name}_cleanup() {
274	        \$DEBUG && dump
275	        cleanup
276	    }
277	"
278	atf_add_test_case ${name}
279}
280
281atf_init_test_cases()
282{
283	local algo=
284
285	for algo in $ESP_ENCRYPTION_ALGORITHMS_MINIMUM; do
286		add_test_tcp ipv4 esp $algo
287		add_test_tcp ipv6 esp $algo
288		add_test_tcp ipv4mappedipv6 esp $algo
289	done
290	for algo in $AH_AUTHENTICATION_ALGORITHMS_MINIMUM; do
291		add_test_tcp ipv4 ah $algo
292		add_test_tcp ipv6 ah $algo
293		add_test_tcp ipv4mappedipv6 ah $algo
294	done
295
296	add_test_tcp ipv4 none
297	add_test_tcp ipv6 none
298	add_test_tcp ipv4mappedipv6 none
299}
300