1#!/usr/bin/ksh 2 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright 2019 Joyent, Inc. 16# 17 18# we can't presume /usr/bin/timeout is there 19timeout_cmd() { 20 $* & 21 sleep 3 22 kill $! 23 # we want to pause a while to make sure the monitor log is 24 # updated... 25 sleep 2 26} 27 28if [[ `id -u` -ne 0 ]]; then 29 echo "Error: need to be root or have effective UID of root." >&2 30 exit 255 31fi 32 33if [[ ! -x "$(type -p curl)" ]]; then 34 echo "Error: curl binary not found." >&2 35 exit 255 36fi 37 38# NOTE: If multihomed, this may fail in interesting ways... 39MY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1` 40TEST_REMOTE_DST1=10.90.1.25 41TEST_REMOTE_DST2=10.19.84.2 42TEST_REMOTE_DST3=10.19.84.3 43TEST_REMOTE_DST4=10.19.84.4 44 45T1_SRC=10.21.12.4 46T1_DST=10.21.12.5 47T1_PREFIX=10.21.12.0/24 48T2_SRC=10.51.50.4 49T2_DST=10.51.50.5 50T2_PREFIX=10.51.50.0/24 51 52CURL_DST3_LPORT=10001 53CURL_DST4_LPORT=10002 54CURL_DST1_LPORT=10003 55CURL_PORT=80 56 57MONITOR_LOG=/tmp/ipseckey-monitor.$$ 58 59EACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler 60 61$EACQ_PROG & 62eapid=$! 63 64echo "Warning, this trashes IPsec policy." 65ipsecconf -Fq 66 67# Setup the IPsec policy... 68ipsecconf -qa - << EOF 69# Global policy... 70# Remote-port-based policy. Use different algorithms... 71{ raddr $TEST_REMOTE_DST3 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha512 } 72 73# Unique policy... 74{ raddr $TEST_REMOTE_DST4 rport $CURL_PORT ulp tcp } ipsec { encr_algs aes encr_auth_algs sha256 sa unique } 75 76# Simple IP address policy. Use an AH + ESP for it. 77{ raddr $TEST_REMOTE_DST1 } ipsec { auth_algs sha512 encr_algs aes(256) } 78{ raddr $TEST_REMOTE_DST2 } ipsec { auth_algs sha384 encr_algs aes(256) } 79 80# Tunnel policy... 81{ tunnel rush0 raddr $T1_PREFIX negotiate tunnel } ipsec { encr_algs aes-gcm(256) } 82# NULL-encryption... 83{ tunnel vh0 raddr $T2_PREFIX negotiate tunnel } ipsec {encr_auth_algs hmac-sha384 } 84EOF 85 86# Plumb the tunnels 87dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0 88dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0 89ipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4 90ipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4 91route add $T1_PREFIX $T1_DST 92route add $T2_PREFIX $T2_DST 93 94ipseckey flush 95ipseckey -np monitor > $MONITOR_LOG & 96IPSECKEY_PID=$! 97 98# give the monitor some time to get set up 99sleep 3 100 101# Launch pings to various addresses (each requiring an ACQUIRE). 102 103timeout_cmd ping -svn $TEST_REMOTE_DST1 1024 1 104timeout_cmd ping -svn $TEST_REMOTE_DST2 1024 1 105timeout_cmd ping -svn $T1_DST 1024 1 106timeout_cmd ping -svn $T2_DST 1024 1 107 108# Now try some curls to trigger local port and unique policy. 109 110# port-only for DST3 111timeout_cmd curl --local-port $CURL_DST3_LPORT \ 112 http://$TEST_REMOTE_DST3:$CURL_PORT 113# unique for DST4 114timeout_cmd curl --local-port $CURL_DST4_LPORT \ 115 http://$TEST_REMOTE_DST4:$CURL_PORT 116# Nothing specced for DST1 117timeout_cmd curl --local-port $CURL_DST1_LPORT \ 118 http://$TEST_REMOTE_DST1:$CURL_PORT 119 120# Clean up. 121kill $IPSECKEY_PID 122kill $eapid 123# Unplumb the tunnels 124route delete $T2_PREFIX $T2_DST 125route delete $T1_PREFIX $T1_DST 126ipadm delete-addr vh0/v4 127ipadm delete-addr rush0/v4 128ipadm delete-if vh0 129ipadm delete-if rush0 130dladm delete-iptun vh0 131dladm delete-iptun rush0 132# Flush policy 133ipsecconf -Fq 134# Use SMF to restore anything that may have been there. "restart" on 135# a disabled service is a NOP, but an enabled one will get 136# /etc/inet/ipsecinit.conf reloaded. 137svcadm restart ipsec/policy 138 139# give the monitor some time to finish up 140sleep 5 141 142# Process MONITOR_LOG's output... 143echo "Checking for unique local port only in one ACQUIRE case." 144egrep "$CURL_DST3_LPORT|$CURL_DST4_LPORT|$CURL_DST1_LPORT" \ 145 $MONITOR_LOG > /tmp/egrep.$$ 146grep $CURL_DST4_LPORT $MONITOR_LOG > /tmp/grep.$$ || { 147 echo "unique port $CURL_DST4_LPORT missing from monitor log." 148 exit 1 149} 150diff /tmp/grep.$$ /tmp/egrep.$$ 151if [[ $? != 0 ]]; then 152 echo "More than just the one unique port $CURL_DST4_LPORT found." 153 exit 1 154fi 155 156# Split out extended (file.0) and regular (file.1) ACQUIREs. 157# NOTE: "+7" is dependent on "ipseckey monitor"'s first output where it gets 158# the "PROMISC" reply. 159 160mkdir /tmp/raw.$$ 161savedir=$PWD 162cd /tmp/raw.$$ 163tail +7 $MONITOR_LOG | \ 164 awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }' 165cd $savedir 166 167# Pluck out the address extension from the two ACQUIRE types. 168# NOTE: Add any new in-ACQUIRE address types here if more arrive. 169egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$ 170egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$ 171 172# There should be NO differences between address fields from regular vs. 173# extended ACQUIREs. If there are, it's a bug (or an older version of illumos). 174diff /tmp/extended-addresses.$$ /tmp/regular-addresses.$$ 175if [[ $? != 0 ]]; then 176 echo "Address fields in ACQUIRE differ." 177 rc=1 178else 179 rc=0 180fi 181 182/bin/rm -rf /tmp/*-addresses.$$ /tmp/raw.$$ 183/bin/rm -f /tmp/grep.$$ /tmp/egrep.$$ /tmp/addrs.$$ $MONITOR_LOG 184 185exit $rc 186