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