summaryrefslogtreecommitdiff
path: root/usr/src/test/os-tests/tests/pf_key/acquire-compare.sh
blob: f9b0c03e4898604c9e284d7aab214786e7b29eec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/ksh

#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright 2019 Joyent, Inc.
#

# we can't presume /usr/bin/timeout is there
timeout_cmd() {
    $* &
    sleep 3
    kill $!
    # we want to pause a while to make sure the monitor log is
    # updated...
    sleep 2
}

if [[ `id -u` -ne 0 ]]; then
    echo "Error: need to be root or have effective UID of root." >&2
    exit 255
fi

if [[ ! -x "$(type -p curl)" ]]; then
    echo "Error: curl binary not found." >&2
    exit 255
fi

# NOTE: If multihomed, this may fail in interesting ways...
MY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1`
TEST_REMOTE_DST1=10.90.1.25
TEST_REMOTE_DST2=10.19.84.2
TEST_REMOTE_DST3=10.19.84.3
TEST_REMOTE_DST4=10.19.84.4

T1_SRC=10.21.12.4
T1_DST=10.21.12.5
T1_PREFIX=10.21.12.0/24
T2_SRC=10.51.50.4
T2_DST=10.51.50.5
T2_PREFIX=10.51.50.0/24

CURL_DST3_LPORT=10001
CURL_DST4_LPORT=10002
CURL_DST1_LPORT=10003
CURL_PORT=80

MONITOR_LOG=/tmp/ipseckey-monitor.$$

EACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler

$EACQ_PROG &
eapid=$!

echo "Warning, this trashes IPsec policy."
ipsecconf -Fq

# Setup the IPsec policy...
ipsecconf -qa - << EOF
# Global policy...
# Remote-port-based policy.  Use different algorithms...
{ raddr $TEST_REMOTE_DST3 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha512 }

# Unique policy...
{ raddr $TEST_REMOTE_DST4 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha256 sa unique }

# Simple IP address policy.  Use an AH + ESP for it.
{ raddr $TEST_REMOTE_DST1 } ipsec { auth_algs sha512 encr_algs aes(256) }
{ raddr $TEST_REMOTE_DST2 } ipsec { auth_algs sha384 encr_algs aes(256) }

# Tunnel policy...
{ tunnel rush0 raddr $T1_PREFIX negotiate tunnel } ipsec { encr_algs aes-gcm(256) }
# NULL-encryption...
{ tunnel vh0 raddr $T2_PREFIX negotiate tunnel } ipsec {encr_auth_algs hmac-sha384 }
EOF

# Plumb the tunnels
dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0
dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0
ipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4
ipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4
route add $T1_PREFIX $T1_DST
route add $T2_PREFIX $T2_DST

ipseckey flush
ipseckey -np monitor > $MONITOR_LOG &
IPSECKEY_PID=$!

# give the monitor some time to get set up
sleep 3

# Launch pings to various addresses (each requiring an ACQUIRE).

timeout_cmd ping -svn $TEST_REMOTE_DST1 1024 1
timeout_cmd ping -svn $TEST_REMOTE_DST2 1024 1
timeout_cmd ping -svn $T1_DST 1024 1
timeout_cmd ping -svn $T2_DST 1024 1

# Now try some curls to trigger local port and unique policy.

# port-only for DST3
timeout_cmd curl --local-port $CURL_DST3_LPORT \
    http://$TEST_REMOTE_DST3:$CURL_PORT
# unique for DST4
timeout_cmd curl --local-port $CURL_DST4_LPORT \
    http://$TEST_REMOTE_DST4:$CURL_PORT
# Nothing specced for DST1
timeout_cmd curl --local-port $CURL_DST1_LPORT \
    http://$TEST_REMOTE_DST1:$CURL_PORT

# Clean up.
kill $IPSECKEY_PID
kill $eapid
# Unplumb the tunnels
route delete $T2_PREFIX $T2_DST
route delete $T1_PREFIX $T1_DST
ipadm delete-addr vh0/v4
ipadm delete-addr rush0/v4
ipadm delete-if vh0
ipadm delete-if rush0
dladm delete-iptun vh0
dladm delete-iptun rush0
# Flush policy
ipsecconf -Fq
# Use SMF to restore anything that may have been there.  "restart" on
# a disabled service is a NOP, but an enabled one will get
# /etc/inet/ipsecinit.conf reloaded.
svcadm restart ipsec/policy

# give the monitor some time to finish up
sleep 5

# Process MONITOR_LOG's output...
echo "Checking for unique local port only in one ACQUIRE case."
egrep "$CURL_DST3_LPORT|$CURL_DST4_LPORT|$CURL_DST1_LPORT" \
    $MONITOR_LOG > /tmp/egrep.$$
grep $CURL_DST4_LPORT $MONITOR_LOG > /tmp/grep.$$ || {
    echo "unique port $CURL_DST4_LPORT missing from monitor log."
    exit 1
}
diff /tmp/grep.$$ /tmp/egrep.$$
if [[ $? != 0 ]]; then
    echo "More than just the one unique port $CURL_DST4_LPORT found."
    exit 1
fi

# Split out extended (file.0) and regular (file.1) ACQUIREs.
# NOTE: "+7" is dependent on "ipseckey monitor"'s first output where it gets
# the "PROMISC" reply.

mkdir /tmp/raw.$$
savedir=$PWD
cd /tmp/raw.$$
tail +7 $MONITOR_LOG | \
    awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }'
cd $savedir

# Pluck out the address extension from the two ACQUIRE types.
# NOTE: Add any new in-ACQUIRE address types here if more arrive.
egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$
egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$

# There should be NO differences between address fields from regular vs.
# extended ACQUIREs. If there are, it's a bug (or an older version of illumos).
diff /tmp/extended-addresses.$$ /tmp/regular-addresses.$$
if [[ $? != 0 ]]; then
    echo "Address fields in ACQUIRE differ."
    rc=1
else
    rc=0
fi

/bin/rm -rf /tmp/*-addresses.$$ /tmp/raw.$$
/bin/rm -f /tmp/grep.$$ /tmp/egrep.$$ /tmp/addrs.$$ $MONITOR_LOG

exit $rc