Home | History | Annotate | Line # | Download | only in tsiggss
      1 #!/bin/sh
      2 
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # SPDX-License-Identifier: MPL-2.0
      6 #
      7 # This Source Code Form is subject to the terms of the Mozilla Public
      8 # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10 #
     11 # See the COPYRIGHT file distributed with this work for additional
     12 # information regarding copyright ownership.
     13 
     14 # tests for TSIG-GSS updates
     15 
     16 set -e
     17 
     18 . ../conf.sh
     19 
     20 # Uncomment to regenerate credential caches after running krb5/setup.sh
     21 # KRB5_CONFIG=$(pwd)/krb/krb5.conf
     22 
     23 status=0
     24 n=1
     25 
     26 DIGOPTS="@10.53.0.1 -p ${PORT}"
     27 
     28 test_update() {
     29   num="$1"
     30   host="$2"
     31   type="$3"
     32   cmd="$4"
     33   digout="$5"
     34 
     35   cat <<EOF >ns1/update.txt
     36 server 10.53.0.1 ${PORT}
     37 update add $host $cmd
     38 send
     39 answer
     40 EOF
     41   echo_i "testing update for $host $type $cmd"
     42   $NSUPDATE -g -d ns1/update.txt >nsupdate.out${num} 2>&1 || {
     43     echo_i "update failed for $host $type $cmd"
     44     sed "s/^/I:/" nsupdate.out${num}
     45     return 1
     46   }
     47 
     48   # Verify that TKEY response is signed.
     49   tkeyout=$(awk '/recvmsg reply from GSS-TSIG query/,/Sending update to/' nsupdate.out${num})
     50   pattern="recvmsg reply from GSS-TSIG query .* opcode: QUERY, status: NOERROR, id: .* flags: qr; QUESTION: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: ;.* ANY TKEY ;; ANSWER SECTION: .* 0 ANY TKEY gss-tsig\. .* ;; TSIG PSEUDOSECTION: .* 0 ANY TSIG gss-tsig\. .* NOERROR 0"
     51   echo $tkeyout | grep "$pattern" >/dev/null || {
     52     echo_i "bad tkey response (not tsig signed)"
     53     return 1
     54   }
     55 
     56   # Weak verification that TKEY response is signed.
     57   grep -q "flags: qr; QUESTION: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1" nsupdate.out${num} || {
     58     echo_i "bad tkey response (not tsig signed)"
     59     return 1
     60   }
     61 
     62   out=$($DIG $DIGOPTS -t $type -q $host | grep -E "^${host}")
     63   lines=$(echo "$out" | grep "$digout" | wc -l)
     64   [ $lines -eq 1 ] || {
     65     echo_i "dig output incorrect for $host $type $cmd: $out"
     66     return 1
     67   }
     68   return 0
     69 }
     70 
     71 # Testing updates with good credentials.
     72 KRB5CCNAME="FILE:"$(pwd)/ns1/administrator.ccache
     73 export KRB5CCNAME
     74 
     75 echo_i "testing updates to testdc1 as administrator ($n)"
     76 ret=0
     77 test_update $n testdc1.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || ret=1
     78 n=$((n + 1))
     79 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
     80 status=$((status + ret))
     81 
     82 echo_i "testing updates to testdc2 as administrator ($n)"
     83 ret=0
     84 test_update $n testdc2.example.nil. A "86400 A 10.53.0.11" "10.53.0.11" || ret=1
     85 n=$((n + 1))
     86 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
     87 status=$((status + ret))
     88 
     89 echo_i "testing updates to denied as administrator ($n)"
     90 ret=0
     91 test_update $n denied.example.nil. TXT "86400 TXT helloworld" "helloworld" >/dev/null && ret=1
     92 n=$((n + 1))
     93 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
     94 status=$((status + ret))
     95 
     96 # Testing denied updates.
     97 KRB5CCNAME="FILE:"$(pwd)/ns1/testdenied.ccache
     98 export KRB5CCNAME
     99 
    100 echo_i "testing updates to denied (A) as a user ($n)"
    101 ret=0
    102 test_update $n testdenied.example.nil. A "86400 A 10.53.0.12" "10.53.0.12" >/dev/null && ret=1
    103 n=$((n + 1))
    104 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    105 status=$((status + ret))
    106 
    107 echo_i "testing updates to denied (TXT) as a user ($n)"
    108 ret=0
    109 test_update $n testdenied.example.nil. TXT "86400 TXT helloworld" "helloworld" || ret=1
    110 n=$((n + 1))
    111 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    112 status=$((status + ret))
    113 
    114 echo_i "testing external update policy (CNAME) ($n)"
    115 ret=0
    116 test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" >/dev/null && ret=1
    117 n=$((n + 1))
    118 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    119 status=$((status + ret))
    120 
    121 echo_i "testing external update policy (CNAME) with auth sock ($n)"
    122 ret=0
    123 $PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >/dev/null 2>&1 &
    124 sleep 1
    125 test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" || ret=1
    126 n=$((n + 1))
    127 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    128 status=$((status + ret))
    129 
    130 echo_i "testing external update policy (A) ($n)"
    131 ret=0
    132 test_update $n testcname.example.nil. A "86400 A 10.53.0.13" "10.53.0.13" >/dev/null && ret=1
    133 n=$((n + 1))
    134 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    135 status=$((status + ret))
    136 
    137 echo_i "testing external policy with SIG(0) key ($n)"
    138 ret=0
    139 $NSUPDATE -k ns1/Kkey.example.nil.*.private <<END >/dev/null 2>&1 || ret=1
    140 server 10.53.0.1 ${PORT}
    141 zone example.nil
    142 update add fred.example.nil 120 cname foo.bar.
    143 send
    144 END
    145 output=$($DIG $DIGOPTS +short cname fred.example.nil.)
    146 [ -n "$output" ] || ret=1
    147 [ $ret -eq 0 ] || echo_i "failed"
    148 n=$((n + 1))
    149 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    150 status=$((status + ret))
    151 
    152 echo_i "ensure too long realm name is fatal in non-interactive mode ($n)"
    153 ret=0
    154 $NSUPDATE <<END >nsupdate.out${n} 2>&1 && ret=1
    155     realm namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename
    156 END
    157 grep "realm is too long" nsupdate.out${n} >/dev/null || ret=1
    158 grep "syntax error" nsupdate.out${n} >/dev/null || ret=1
    159 n=$((n + 1))
    160 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    161 status=$((status + ret))
    162 
    163 echo_i "ensure too long realm name is not fatal in interactive mode ($n)"
    164 ret=0
    165 $NSUPDATE -i <<END >nsupdate.out${n} 2>&1 || ret=1
    166     realm namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename
    167 END
    168 grep "realm is too long" nsupdate.out${n} >/dev/null || ret=1
    169 [ $ret = 0 ] || {
    170   echo_i "failed"
    171   status=1
    172 }
    173 n=$((n + 1))
    174 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    175 status=$((status + ret))
    176 
    177 echo_i "stop and start server to check key restoration ($n)"
    178 ret=0
    179 gss_keys=$(grep 'tsig key.*generated' ns1/named.run | wc -l)
    180 stop_server --use-rndc --port "${CONTROLPORT}" ns1
    181 start_server --noclean --restart --port "${PORT}" ns1
    182 restored_keys=$(grep 'tsig key.*restored from file' ns1/named.run | wc -l)
    183 [ "$gss_keys" -ne 0 ] || ret=1
    184 [ "$restored_keys" -ne 0 ] || ret=1
    185 [ "$gss_keys" -eq "$restored_keys" ] || ret=1
    186 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    187 status=$((status + ret))
    188 
    189 [ $status -eq 0 ] && echo_i "tsiggss tests all OK"
    190 
    191 kill $(cat authsock.pid)
    192 
    193 echo_i "exit status: $status"
    194 [ $status -eq 0 ] || exit 1
    195