1b7daf799SDan McDonald#!/usr/bin/ksh
2b7daf799SDan McDonald
3b7daf799SDan McDonald#
4b7daf799SDan McDonald# This file and its contents are supplied under the terms of the
5b7daf799SDan McDonald# Common Development and Distribution License ("CDDL"), version 1.0.
6b7daf799SDan McDonald# You may only use this file in accordance with the terms of version
7b7daf799SDan McDonald# 1.0 of the CDDL.
8b7daf799SDan McDonald#
9b7daf799SDan McDonald# A full copy of the text of the CDDL should have accompanied this
10b7daf799SDan McDonald# source.  A copy of the CDDL is also available via the Internet at
11b7daf799SDan McDonald# http://www.illumos.org/license/CDDL.
12b7daf799SDan McDonald#
13b7daf799SDan McDonald
14b7daf799SDan McDonald#
153dae5456SJohn Levon# Copyright 2019 Joyent, Inc.
16b7daf799SDan McDonald#
17b7daf799SDan McDonald
183dae5456SJohn Levon# we can't presume /usr/bin/timeout is there
193dae5456SJohn Levontimeout_cmd() {
203dae5456SJohn Levon    $* &
213dae5456SJohn Levon    sleep 3
223dae5456SJohn Levon    kill $!
233dae5456SJohn Levon    # we want to pause a while to make sure the monitor log is
243dae5456SJohn Levon    # updated...
253dae5456SJohn Levon    sleep 2
263dae5456SJohn Levon}
273dae5456SJohn Levon
28*3580e26cSDan McDonaldif [[ `id -u` != 0 ]]; then
293dae5456SJohn Levon    echo "Error: need to be root or have effective UID of root." >&2
303dae5456SJohn Levon    exit 255
313dae5456SJohn Levonfi
323dae5456SJohn Levon
333dae5456SJohn Levonif [[ ! -x "$(type -p curl)" ]]; then
343dae5456SJohn Levon    echo "Error: curl binary not found." >&2
353dae5456SJohn Levon    exit 255
36b7daf799SDan McDonaldfi
37b7daf799SDan McDonald
38b7daf799SDan McDonald# NOTE: If multihomed, this may fail in interesting ways...
39b7daf799SDan McDonaldMY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1`
40b7daf799SDan McDonaldTEST_REMOTE_DST1=10.90.1.25
41b7daf799SDan McDonaldTEST_REMOTE_DST2=10.19.84.2
42b7daf799SDan McDonaldTEST_REMOTE_DST3=10.19.84.3
43b7daf799SDan McDonaldTEST_REMOTE_DST4=10.19.84.4
44b7daf799SDan McDonald
45b7daf799SDan McDonaldT1_SRC=10.21.12.4
46b7daf799SDan McDonaldT1_DST=10.21.12.5
47b7daf799SDan McDonaldT1_PREFIX=10.21.12.0/24
48b7daf799SDan McDonaldT2_SRC=10.51.50.4
49b7daf799SDan McDonaldT2_DST=10.51.50.5
50b7daf799SDan McDonaldT2_PREFIX=10.51.50.0/24
51b7daf799SDan McDonald
523dae5456SJohn LevonCURL_DST3_LPORT=10001
533dae5456SJohn LevonCURL_DST4_LPORT=10002
543dae5456SJohn LevonCURL_DST1_LPORT=10003
553dae5456SJohn LevonCURL_PORT=80
563dae5456SJohn Levon
57b7daf799SDan McDonaldMONITOR_LOG=/tmp/ipseckey-monitor.$$
58b7daf799SDan McDonald
59b7daf799SDan McDonaldEACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler
60b7daf799SDan McDonald
61b7daf799SDan McDonald$EACQ_PROG &
62b7daf799SDan McDonaldeapid=$!
63b7daf799SDan McDonald
64b7daf799SDan McDonaldecho "Warning, this trashes IPsec policy."
65b7daf799SDan McDonaldipsecconf -Fq
66b7daf799SDan McDonald
67b7daf799SDan McDonald# Setup the IPsec policy...
68b7daf799SDan McDonaldipsecconf -qa - << EOF
69b7daf799SDan McDonald# Global policy...
70b7daf799SDan McDonald# Remote-port-based policy.  Use different algorithms...
713dae5456SJohn Levon{ raddr $TEST_REMOTE_DST3 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha512 }
72b7daf799SDan McDonald
73b7daf799SDan McDonald# Unique policy...
743dae5456SJohn Levon{ raddr $TEST_REMOTE_DST4 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha256 sa unique }
75b7daf799SDan McDonald
76b7daf799SDan McDonald# Simple IP address policy.  Use an AH + ESP for it.
77b7daf799SDan McDonald{ raddr $TEST_REMOTE_DST1 } ipsec { auth_algs sha512 encr_algs aes(256) }
78b7daf799SDan McDonald{ raddr $TEST_REMOTE_DST2 } ipsec { auth_algs sha384 encr_algs aes(256) }
79b7daf799SDan McDonald
80b7daf799SDan McDonald# Tunnel policy...
81b7daf799SDan McDonald{ tunnel rush0 raddr $T1_PREFIX negotiate tunnel } ipsec { encr_algs aes-gcm(256) }
82b7daf799SDan McDonald# NULL-encryption...
83b7daf799SDan McDonald{ tunnel vh0 raddr $T2_PREFIX negotiate tunnel } ipsec {encr_auth_algs hmac-sha384 }
84b7daf799SDan McDonaldEOF
85b7daf799SDan McDonald
86b7daf799SDan McDonald# Plumb the tunnels
87b7daf799SDan McDonalddladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0
88b7daf799SDan McDonalddladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0
89b7daf799SDan McDonaldipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4
90b7daf799SDan McDonaldipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4
91b7daf799SDan McDonaldroute add $T1_PREFIX $T1_DST
92b7daf799SDan McDonaldroute add $T2_PREFIX $T2_DST
93b7daf799SDan McDonald
94b7daf799SDan McDonaldipseckey flush
95b7daf799SDan McDonaldipseckey -np monitor > $MONITOR_LOG &
96b7daf799SDan McDonaldIPSECKEY_PID=$!
97b7daf799SDan McDonald
983dae5456SJohn Levon# give the monitor some time to get set up
993dae5456SJohn Levonsleep 3
1003dae5456SJohn Levon
1013dae5456SJohn Levon# Launch pings to various addresses (each requiring an ACQUIRE).
102b7daf799SDan McDonald
1033dae5456SJohn Levontimeout_cmd ping -svn $TEST_REMOTE_DST1 1024 1
1043dae5456SJohn Levontimeout_cmd ping -svn $TEST_REMOTE_DST2 1024 1
1053dae5456SJohn Levontimeout_cmd ping -svn $T1_DST 1024 1
1063dae5456SJohn Levontimeout_cmd ping -svn $T2_DST 1024 1
1073dae5456SJohn Levon
1083dae5456SJohn Levon# Now try some curls to trigger local port and unique policy.
109b7daf799SDan McDonald
110b7daf799SDan McDonald# port-only for DST3
1113dae5456SJohn Levontimeout_cmd curl --local-port $CURL_DST3_LPORT \
1123dae5456SJohn Levon    http://$TEST_REMOTE_DST3:$CURL_PORT
113b7daf799SDan McDonald# unique for DST4
1143dae5456SJohn Levontimeout_cmd curl --local-port $CURL_DST4_LPORT \
1153dae5456SJohn Levon    http://$TEST_REMOTE_DST4:$CURL_PORT
116b7daf799SDan McDonald# Nothing specced for DST1
1173dae5456SJohn Levontimeout_cmd curl --local-port $CURL_DST1_LPORT \
1183dae5456SJohn Levon    http://$TEST_REMOTE_DST1:$CURL_PORT
119b7daf799SDan McDonald
120b7daf799SDan McDonald# Clean up.
121b7daf799SDan McDonaldkill $IPSECKEY_PID
122b7daf799SDan McDonaldkill $eapid
123b7daf799SDan McDonald# Unplumb the tunnels
124b7daf799SDan McDonaldroute delete $T2_PREFIX $T2_DST
125b7daf799SDan McDonaldroute delete $T1_PREFIX $T1_DST
126b7daf799SDan McDonaldipadm delete-addr vh0/v4
127b7daf799SDan McDonaldipadm delete-addr rush0/v4
128b7daf799SDan McDonaldipadm delete-if vh0
129b7daf799SDan McDonaldipadm delete-if rush0
130b7daf799SDan McDonalddladm delete-iptun vh0
131b7daf799SDan McDonalddladm delete-iptun rush0
132b7daf799SDan McDonald# Flush policy
133b7daf799SDan McDonaldipsecconf -Fq
134b7daf799SDan McDonald# Use SMF to restore anything that may have been there.  "restart" on
135b7daf799SDan McDonald# a disabled service is a NOP, but an enabled one will get
136b7daf799SDan McDonald# /etc/inet/ipsecinit.conf reloaded.
137b7daf799SDan McDonaldsvcadm restart ipsec/policy
138b7daf799SDan McDonald
1393dae5456SJohn Levon# give the monitor some time to finish up
1403dae5456SJohn Levonsleep 5
1413dae5456SJohn Levon
142b7daf799SDan McDonald# Process MONITOR_LOG's output...
143b7daf799SDan McDonaldecho "Checking for unique local port only in one ACQUIRE case."
1443dae5456SJohn Levonegrep "$CURL_DST3_LPORT|$CURL_DST4_LPORT|$CURL_DST1_LPORT" \
1453dae5456SJohn Levon    $MONITOR_LOG > /tmp/egrep.$$
1463dae5456SJohn Levongrep $CURL_DST4_LPORT $MONITOR_LOG > /tmp/grep.$$ || {
1473dae5456SJohn Levon    echo "unique port $CURL_DST4_LPORT missing from monitor log."
1483dae5456SJohn Levon    exit 1
1493dae5456SJohn Levon}
150b7daf799SDan McDonalddiff /tmp/grep.$$ /tmp/egrep.$$
151b7daf799SDan McDonaldif [[ $? != 0 ]]; then
1523dae5456SJohn Levon    echo "More than just the one unique port $CURL_DST4_LPORT found."
153b7daf799SDan McDonald    exit 1
154b7daf799SDan McDonaldfi
155b7daf799SDan McDonald
156b7daf799SDan McDonald# Split out extended (file.0) and regular (file.1) ACQUIREs.
157b7daf799SDan McDonald# NOTE: "+7" is dependent on "ipseckey monitor"'s first output where it gets
158b7daf799SDan McDonald# the "PROMISC" reply.
159b7daf799SDan McDonald
160b7daf799SDan McDonaldmkdir /tmp/raw.$$
161b7daf799SDan McDonaldsavedir=$PWD
162b7daf799SDan McDonaldcd /tmp/raw.$$
163b7daf799SDan McDonaldtail +7 $MONITOR_LOG | \
164b7daf799SDan McDonald    awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }'
165b7daf799SDan McDonaldcd $savedir
166b7daf799SDan McDonald
167b7daf799SDan McDonald# Pluck out the address extension from the two ACQUIRE types.
168b7daf799SDan McDonald# NOTE: Add any new in-ACQUIRE address types here if more arrive.
169b7daf799SDan McDonaldegrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$
170b7daf799SDan McDonaldegrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$
171b7daf799SDan McDonald
172b7daf799SDan McDonald# There should be NO differences between address fields from regular vs.
173b7daf799SDan McDonald# extended ACQUIREs. If there are, it's a bug (or an older version of illumos).
174b7daf799SDan McDonalddiff /tmp/extended-addresses.$$ /tmp/regular-addresses.$$
175b7daf799SDan McDonaldif [[ $? != 0 ]]; then
176b7daf799SDan McDonald    echo "Address fields in ACQUIRE differ."
177b7daf799SDan McDonald    rc=1
178b7daf799SDan McDonaldelse
179b7daf799SDan McDonald    rc=0
180b7daf799SDan McDonaldfi
181b7daf799SDan McDonald
182b7daf799SDan McDonald/bin/rm -rf /tmp/*-addresses.$$ /tmp/raw.$$
183b7daf799SDan McDonald/bin/rm -f /tmp/grep.$$ /tmp/egrep.$$ /tmp/addrs.$$ $MONITOR_LOG
184b7daf799SDan McDonald
185b7daf799SDan McDonaldexit $rc
186