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 set -e 15 16 . ../conf.sh 17 18 # replace_data dname RR old_data new_data 19 replace_data() { 20 if [ $# -ne 4 ]; then 21 echo_i "unexpected input for replace_data" 22 return 1 23 fi 24 25 _dname=$1 26 _rr=$2 27 _olddata=$3 28 _newdata=$4 29 30 _ret=0 31 $NSUPDATE -d <<END >>nsupdate.out.test 2>&1 || _ret=1 32 server 10.53.0.2 ${PORT} 33 update delete ${_dname} 30 ${_rr} ${_olddata} 34 update add ${_dname} 30 ${_rr} ${_newdata} 35 send 36 END 37 38 if [ $_ret != 0 ]; then 39 echo_i "failed to update the test data" 40 return 1 41 fi 42 43 return 0 44 } 45 46 status=0 47 n=0 48 49 DIGOPTS="+short +tcp -p ${PORT}" 50 DIGOPTS_CD="$DIGOPTS +cd" 51 52 echo_i "Priming cache." 53 ret=0 54 expect="10 mail.example." 55 ans=$($DIG $DIGOPTS_CD @10.53.0.4 hostile MX) || ret=1 56 test "$ans" = "$expect" || ret=1 57 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 58 status=$((status + ret)) 59 60 echo_i "Checking that bogus additional is not returned with +CD." 61 ret=0 62 expect="10.0.0.2" 63 ans=$($DIG $DIGOPTS_CD @10.53.0.4 mail.example A) || ret=1 64 test "$ans" = "$expect" || ret=1 65 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 66 status=$((status + ret)) 67 68 # 69 # Prime cache with pending additional records. These should not be promoted 70 # to answer. 71 # 72 echo_i "Priming cache (pending additional A and AAAA)" 73 ret=0 74 expect="10 mail.example.com." 75 ans=$($DIG $DIGOPTS @10.53.0.4 example.com MX) || ret=1 76 test "$ans" = "$expect" || ret=1 77 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 78 status=$((status + ret)) 79 80 echo_i "Replacing pending A" 81 ret=0 82 replace_data mail.example.com. A 192.0.2.2 192.0.2.3 || ret=1 83 status=$((status + ret)) 84 85 echo_i "Replacing pending AAAA" 86 ret=0 87 replace_data mail.example.com. AAAA 2001:db8::2 2001:db8::3 || ret=1 88 status=$((status + ret)) 89 90 echo_i "Checking updated data to be returned (without CD)" 91 ret=0 92 expect="192.0.2.3" 93 ans=$($DIG $DIGOPTS @10.53.0.4 mail.example.com A) || ret=1 94 test "$ans" = "$expect" || ret=1 95 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 96 status=$((status + ret)) 97 98 echo_i "Checking updated data to be returned (with CD)" 99 ret=0 100 expect="2001:db8::3" 101 ans=$($DIG $DIGOPTS_CD @10.53.0.4 mail.example.com AAAA) || ret=1 102 test "$ans" = "$expect" || ret=1 103 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 104 status=$((status + ret)) 105 106 # 107 # Prime cache with a pending answer record. It can be returned (without 108 # validation) with +CD. 109 # 110 echo_i "Priming cache (pending answer)" 111 ret=0 112 expect="192.0.2.2" 113 ans=$($DIG $DIGOPTS_CD @10.53.0.4 pending-ok.example.com A) || ret=1 114 test "$ans" = "$expect" || ret=1 115 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 116 status=$((status + ret)) 117 118 echo_i "Replacing pending data" 119 ret=0 120 replace_data pending-ok.example.com. A 192.0.2.2 192.0.2.3 || ret=1 121 status=$((status + ret)) 122 123 echo_i "Confirming cached pending data to be returned with CD" 124 ret=0 125 expect="192.0.2.2" 126 ans=$($DIG $DIGOPTS_CD @10.53.0.4 pending-ok.example.com A) || ret=1 127 test "$ans" = "$expect" || ret=1 128 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 129 status=$((status + ret)) 130 131 # 132 # Prime cache with a pending answer record. It should not be returned 133 # to no-DNSSEC clients. 134 # 135 echo_i "Priming cache (pending answer)" 136 ret=0 137 expect="192.0.2.102" 138 ans=$($DIG $DIGOPTS_CD @10.53.0.4 pending-ng.example.com A) || ret=1 139 test "$ans" = "$expect" || ret=1 140 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 141 status=$((status + ret)) 142 143 echo_i "Replacing pending data" 144 ret=0 145 replace_data pending-ng.example.com. A 192.0.2.102 192.0.2.103 || ret=1 146 status=$((status + ret)) 147 148 echo_i "Confirming updated data returned, not the cached one, without CD" 149 ret=0 150 expect="192.0.2.103" 151 ans=$($DIG $DIGOPTS @10.53.0.4 pending-ng.example.com A) || ret=1 152 test "$ans" = "$expect" || ret=1 153 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 154 status=$((status + ret)) 155 156 # 157 # Try to fool the resolver with an out-of-bailiwick CNAME 158 # 159 echo_i "Trying to Prime out-of-bailiwick pending answer with CD" 160 ret=0 161 expect="10.10.10.10" 162 ans=$($DIG $DIGOPTS_CD @10.53.0.4 bad.example. A) || ret=1 163 ans=$(echo $ans | awk '{print $NF}') 164 test "$ans" = "$expect" || ret=1 165 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 166 status=$((status + ret)) 167 168 echo_i "Confirming the out-of-bailiwick answer is not cached or reused with CD" 169 ret=0 170 expect="10.10.10.10" 171 ans=$($DIG $DIGOPTS_CD @10.53.0.4 nice.good. A) || ret=1 172 ans=$(echo $ans | awk '{print $NF}') 173 test "$ans" = "$expect" || ret=1 174 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 175 status=$((status + ret)) 176 177 # 178 # Make sure the resolver doesn't cache bogus NXDOMAIN 179 # 180 echo_i "Trying to Prime bogus NXDOMAIN" 181 ret=0 182 expect="SERVFAIL" 183 ans=$($DIG +tcp -p ${PORT} @10.53.0.4 removed.example.com. A) || ret=1 184 ans=$(echo $ans | sed 's/^.*status: \([A-Z][A-Z]*\).*$/\1/') 185 test "$ans" = "$expect" || ret=1 186 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 187 status=$((status + ret)) 188 189 echo_i "Confirming the bogus NXDOMAIN was not cached" 190 ret=0 191 expect="SERVFAIL" 192 ans=$($DIG +tcp -p ${PORT} @10.53.0.4 removed.example.com. A) || ret=1 193 ans=$(echo $ans | sed 's/^.*status: \([A-Z][A-Z]*\).*$/\1/') 194 test "$ans" = "$expect" || ret=1 195 test $ret = 0 || echo_i "failed, got '$ans', expected '$expect'" 196 status=$((status + ret)) 197 198 echo_i "exit status: $status" 199 [ $status -eq 0 ] || exit 1 200