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 (c) 2017 Joyent, Inc. 16# 17 18if [ `id -u` -ne 0 ]; then 19 echo "Need to be root or have effective UID of root." 20 exit 255 21fi 22 23# NOTE: If multihomed, this may fail in interesting ways... 24MY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1` 25TEST_REMOTE_DST1=10.90.1.25 26TEST_REMOTE_DST2=10.19.84.2 27TEST_REMOTE_DST3=10.19.84.3 28TEST_REMOTE_DST4=10.19.84.4 29 30T1_SRC=10.21.12.4 31T1_DST=10.21.12.5 32T1_PREFIX=10.21.12.0/24 33T2_SRC=10.51.50.4 34T2_DST=10.51.50.5 35T2_PREFIX=10.51.50.0/24 36 37MONITOR_LOG=/tmp/ipseckey-monitor.$$ 38 39EACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler 40 41$EACQ_PROG & 42eapid=$! 43 44echo "Warning, this trashes IPsec policy." 45ipsecconf -Fq 46 47# Setup the IPsec policy... 48ipsecconf -qa - << EOF 49# Global policy... 50# Remote-port-based policy. Use different algorithms... 51{ raddr $TEST_REMOTE_DST3 rport 23 ulp tcp } ipsec { encr_algs aes encr_auth_algs sha512 } 52 53# Unique policy... 54{ raddr $TEST_REMOTE_DST4 rport 23 ulp tcp } ipsec { encr_algs aes encr_auth_algs sha256 sa unique } 55 56# Simple IP address policy. Use an AH + ESP for it. 57{ raddr $TEST_REMOTE_DST1 } ipsec { auth_algs sha512 encr_algs aes(256) } 58{ raddr $TEST_REMOTE_DST2 } ipsec { auth_algs sha384 encr_algs aes(256) } 59 60# Tunnel policy... 61{ tunnel rush0 raddr $T1_PREFIX negotiate tunnel } ipsec { encr_algs aes-gcm(256) } 62# NULL-encryption... 63{ tunnel vh0 raddr $T2_PREFIX negotiate tunnel } ipsec {encr_auth_algs hmac-sha384 } 64EOF 65 66# Plumb the tunnels 67dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0 68dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0 69ipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4 70ipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4 71route add $T1_PREFIX $T1_DST 72route add $T2_PREFIX $T2_DST 73 74ipseckey flush 75ipseckey -np monitor > $MONITOR_LOG & 76IPSECKEY_PID=$! 77 78# Launch pings and telnets to different addresses (each requiring an ACQUIRE). 79ping -svn $TEST_REMOTE_DST1 1024 1 2>&1 > /dev/null & 80p1=$! 81ping -svn $TEST_REMOTE_DST2 1024 1 2>&1 > /dev/null & 82p2=$! 83ping -svn $T1_DST 1024 1 2>&1 > /dev/null & 84p3=$! 85ping -svn $T2_DST 1024 1 2>&1 > /dev/null & 86p4=$! 87 88echo "Waiting for pings..." 89pwait $p1 $p2 $p3 $p4 90 91# Now try some telnets to trigger port and unique policy. 92# port-only for DST3 93telnet $TEST_REMOTE_DST3 & 94tpid=$! 95t1port=`pfiles $tpid | grep sockname | awk '{print $5}'` 96echo "First local port == $t1port" 97sleep 10 ; kill $tpid 98# unique for DST4 99telnet $TEST_REMOTE_DST4 & 100tpid=$! 101t2port=`pfiles $tpid | grep sockname | awk '{print $5}'` 102echo "Second local port == $t2port" 103sleep 10 ; kill $tpid 104# Nothing specced for DST1 105telnet $TEST_REMOTE_DST1 & 106tpid=$! 107t3port=`pfiles $tpid | grep sockname | awk '{print $5}'` 108echo "Third local port == $t3port" 109sleep 10 ; kill $tpid 110 111# Clean up. 112kill $IPSECKEY_PID 113kill $eapid 114# Unplumb the tunnels 115route delete $T2_PREFIX $T2_DST 116route delete $T1_PREFIX $T1_DST 117ipadm delete-addr vh0/v4 118ipadm delete-addr rush0/v4 119ipadm delete-if vh0 120ipadm delete-if rush0 121dladm delete-iptun vh0 122dladm delete-iptun rush0 123# Flush policy 124ipsecconf -Fq 125# Use SMF to restore anything that may have been there. "restart" on 126# a disabled service is a NOP, but an enabled one will get 127# /etc/inet/ipsecinit.conf reloaded. 128svcadm restart ipsec/policy 129 130# Process MONITOR_LOG's output... 131echo "Checking for unique local port only in one ACQUIRE case." 132egrep "$t1port|$t2port|$t3port" $MONITOR_LOG > /tmp/egrep.$$ 133grep $t2port $MONITOR_LOG > /tmp/grep.$$ 134diff /tmp/grep.$$ /tmp/egrep.$$ 135if [[ $? != 0 ]]; then 136 echo "More than just the one unique port, $tport2, found in monitor output." 137 /bin/rm -f /tmp/grep.$$ /tmp/egrep.$$ $MONITOR_LOG 138 exit 1 139fi 140 141# Split out extended (file.0) and regular (file.1) ACQUIREs. 142# NOTE: "+7" is dependent on "ipseckey monitor"'s first output where it gets 143# the "PROMISC" reply. 144 145mkdir /tmp/raw.$$ 146savedir=$PWD 147cd /tmp/raw.$$ 148tail +7 $MONITOR_LOG | \ 149 awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }' 150cd $savedir 151 152# Pluck out the address extension from the two ACQUIRE types. 153# NOTE: Add any new in-ACQUIRE address types here if more arrive. 154egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$ 155egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$ 156 157# There should be NO differences between address fields from regular vs. 158# extended ACQUIREs. If there are, it's a bug (or an older version of illumos). 159diff /tmp/extended-addresses.$$ /tmp/regular-addresses.$$ 160if [[ $? != 0 ]]; then 161 echo "Address fields in ACQUIRE differ." 162 rc=1 163else 164 rc=0 165fi 166 167/bin/rm -rf /tmp/*-addresses.$$ /tmp/raw.$$ 168/bin/rm -f /tmp/grep.$$ /tmp/egrep.$$ /tmp/addrs.$$ $MONITOR_LOG 169 170exit $rc 171