Print this page
11837 tests/pf_key/acquire-compare is racy
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
   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 
  18 if [ `id -u` -ne 0 ]; then
  19         echo "Need to be root or have effective UID of root."










  20         exit 255
  21 fi
  22 





  23 # NOTE: If multihomed, this may fail in interesting ways...
  24 MY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1`
  25 TEST_REMOTE_DST1=10.90.1.25
  26 TEST_REMOTE_DST2=10.19.84.2
  27 TEST_REMOTE_DST3=10.19.84.3
  28 TEST_REMOTE_DST4=10.19.84.4
  29 
  30 T1_SRC=10.21.12.4
  31 T1_DST=10.21.12.5
  32 T1_PREFIX=10.21.12.0/24
  33 T2_SRC=10.51.50.4
  34 T2_DST=10.51.50.5
  35 T2_PREFIX=10.51.50.0/24
  36 





  37 MONITOR_LOG=/tmp/ipseckey-monitor.$$
  38 
  39 EACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler
  40 
  41 $EACQ_PROG &
  42 eapid=$!
  43 
  44 echo "Warning, this trashes IPsec policy."
  45 ipsecconf -Fq
  46 
  47 # Setup the IPsec policy...
  48 ipsecconf -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 }
  64 EOF
  65 
  66 # Plumb the tunnels
  67 dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0
  68 dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0
  69 ipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4
  70 ipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4
  71 route add $T1_PREFIX $T1_DST
  72 route add $T2_PREFIX $T2_DST
  73 
  74 ipseckey flush
  75 ipseckey -np monitor > $MONITOR_LOG &
  76 IPSECKEY_PID=$!
  77 
  78 # Launch pings and telnets to different addresses (each requiring an ACQUIRE).
  79 ping -svn $TEST_REMOTE_DST1 1024 1 2>&1 > /dev/null &
  80 p1=$!
  81 ping -svn $TEST_REMOTE_DST2 1024 1 2>&1 > /dev/null &
  82 p2=$!
  83 ping -svn $T1_DST 1024 1 2>&1 > /dev/null &
  84 p3=$!
  85 ping -svn $T2_DST 1024 1 2>&1 > /dev/null &
  86 p4=$!
  87 
  88 echo "Waiting for pings..."
  89 pwait $p1 $p2 $p3 $p4
  90 
  91 # Now try some telnets to trigger port and unique policy.






  92 # port-only for DST3
  93 telnet $TEST_REMOTE_DST3 &
  94 tpid=$!
  95 t1port=`pfiles $tpid | grep sockname | awk '{print $5}'`
  96 echo "First local port == $t1port"
  97 sleep 10 ; kill $tpid
  98 # unique for DST4
  99 telnet $TEST_REMOTE_DST4 &
 100 tpid=$!
 101 t2port=`pfiles $tpid | grep sockname | awk '{print $5}'`
 102 echo "Second local port == $t2port"
 103 sleep 10 ; kill $tpid
 104 # Nothing specced for DST1
 105 telnet $TEST_REMOTE_DST1 &
 106 tpid=$!
 107 t3port=`pfiles $tpid | grep sockname | awk '{print $5}'`
 108 echo "Third local port == $t3port"
 109 sleep 10 ; kill $tpid
 110 
 111 # Clean up.
 112 kill $IPSECKEY_PID
 113 kill $eapid
 114 # Unplumb the tunnels
 115 route delete $T2_PREFIX $T2_DST
 116 route delete $T1_PREFIX $T1_DST
 117 ipadm delete-addr vh0/v4
 118 ipadm delete-addr rush0/v4
 119 ipadm delete-if vh0
 120 ipadm delete-if rush0
 121 dladm delete-iptun vh0
 122 dladm delete-iptun rush0
 123 # Flush policy
 124 ipsecconf -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.
 128 svcadm restart ipsec/policy
 129 



 130 # Process MONITOR_LOG's output...
 131 echo "Checking for unique local port only in one ACQUIRE case."
 132 egrep "$t1port|$t2port|$t3port" $MONITOR_LOG > /tmp/egrep.$$
 133 grep $t2port $MONITOR_LOG > /tmp/grep.$$




 134 diff /tmp/grep.$$ /tmp/egrep.$$
 135 if [[ $? != 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
 139 fi
 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 
 145 mkdir /tmp/raw.$$
 146 savedir=$PWD
 147 cd /tmp/raw.$$
 148 tail +7 $MONITOR_LOG | \
 149     awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }'
 150 cd $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.
 154 egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$
 155 egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$
 156 
 157 # There should be NO differences between address fields from regular vs.
   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
  19 timeout_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 
  28 if [[ `id -u` -ne 0 ]]; then
  29     echo "Error: need to be root or have effective UID of root." >&2
  30     exit 255
  31 fi
  32 
  33 if [[ ! -x "$(type -p curl)" ]]; then
  34     echo "Error: curl binary not found." >&2
  35     exit 255
  36 fi
  37 
  38 # NOTE: If multihomed, this may fail in interesting ways...
  39 MY_IP=`netstat -in -f inet | egrep -v "Name|lo0" | awk '{print $4}' | head -1`
  40 TEST_REMOTE_DST1=10.90.1.25
  41 TEST_REMOTE_DST2=10.19.84.2
  42 TEST_REMOTE_DST3=10.19.84.3
  43 TEST_REMOTE_DST4=10.19.84.4
  44 
  45 T1_SRC=10.21.12.4
  46 T1_DST=10.21.12.5
  47 T1_PREFIX=10.21.12.0/24
  48 T2_SRC=10.51.50.4
  49 T2_DST=10.51.50.5
  50 T2_PREFIX=10.51.50.0/24
  51 
  52 CURL_DST3_LPORT=10001
  53 CURL_DST4_LPORT=10002
  54 CURL_DST1_LPORT=10003
  55 CURL_PORT=80
  56 
  57 MONITOR_LOG=/tmp/ipseckey-monitor.$$
  58 
  59 EACQ_PROG=/opt/os-tests/tests/pf_key/eacq-enabler
  60 
  61 $EACQ_PROG &
  62 eapid=$!
  63 
  64 echo "Warning, this trashes IPsec policy."
  65 ipsecconf -Fq
  66 
  67 # Setup the IPsec policy...
  68 ipsecconf -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 }
  84 EOF
  85 
  86 # Plumb the tunnels
  87 dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST1 rush0
  88 dladm create-iptun -t -T ipv4 -a local=$MY_IP -a remote=$TEST_REMOTE_DST2 vh0
  89 ipadm create-addr -t -T static -a local=$T1_SRC,remote=$T1_DST rush0/v4
  90 ipadm create-addr -t -T static -a local=$T2_SRC,remote=$T2_DST vh0/v4
  91 route add $T1_PREFIX $T1_DST
  92 route add $T2_PREFIX $T2_DST
  93 
  94 ipseckey flush
  95 ipseckey -np monitor > $MONITOR_LOG &
  96 IPSECKEY_PID=$!
  97 
  98 # give the monitor some time to get set up
  99 sleep 3







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

 102 
 103 timeout_cmd ping -svn $TEST_REMOTE_DST1 1024 1
 104 timeout_cmd ping -svn $TEST_REMOTE_DST2 1024 1
 105 timeout_cmd ping -svn $T1_DST 1024 1
 106 timeout_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
 111 timeout_cmd curl --local-port $CURL_DST3_LPORT \
 112     http://$TEST_REMOTE_DST3:$CURL_PORT



 113 # unique for DST4
 114 timeout_cmd curl --local-port $CURL_DST4_LPORT \
 115     http://$TEST_REMOTE_DST4:$CURL_PORT



 116 # Nothing specced for DST1
 117 timeout_cmd curl --local-port $CURL_DST1_LPORT \
 118     http://$TEST_REMOTE_DST1:$CURL_PORT



 119 
 120 # Clean up.
 121 kill $IPSECKEY_PID
 122 kill $eapid
 123 # Unplumb the tunnels
 124 route delete $T2_PREFIX $T2_DST
 125 route delete $T1_PREFIX $T1_DST
 126 ipadm delete-addr vh0/v4
 127 ipadm delete-addr rush0/v4
 128 ipadm delete-if vh0
 129 ipadm delete-if rush0
 130 dladm delete-iptun vh0
 131 dladm delete-iptun rush0
 132 # Flush policy
 133 ipsecconf -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.
 137 svcadm restart ipsec/policy
 138 
 139 # give the monitor some time to finish up
 140 sleep 5
 141 
 142 # Process MONITOR_LOG's output...
 143 echo "Checking for unique local port only in one ACQUIRE case."
 144 egrep "$CURL_DST3_LPORT|$CURL_DST4_LPORT|$CURL_DST1_LPORT" \
 145     $MONITOR_LOG > /tmp/egrep.$$
 146 grep $CURL_DST4_LPORT $MONITOR_LOG > /tmp/grep.$$ || {
 147     echo "unique port $CURL_DST4_LPORT missing from monitor log."
 148     exit 1
 149 }
 150 diff /tmp/grep.$$ /tmp/egrep.$$
 151 if [[ $? != 0 ]]; then
 152     echo "More than just the one unique port $CURL_DST4_LPORT found."

 153     exit 1
 154 fi
 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 
 160 mkdir /tmp/raw.$$
 161 savedir=$PWD
 162 cd /tmp/raw.$$
 163 tail +7 $MONITOR_LOG | \
 164     awk 'BEGIN { out=0; } /Read/ {out++;} { print >> (out % 2) }'
 165 cd $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.
 169 egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/0 > /tmp/extended-addresses.$$
 170 egrep "DST:|SRC:|INS:|IND:" /tmp/raw.$$/1 > /tmp/regular-addresses.$$
 171 
 172 # There should be NO differences between address fields from regular vs.