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 16set -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 23status=0 24n=1 25 26DIGOPTS="@10.53.0.1 -p ${PORT}" 27 28test_update() { 29 num="$1" 30 host="$2" 31 type="$3" 32 cmd="$4" 33 digout="$5" 34 35 cat <<EOF >ns1/update.txt 36server 10.53.0.1 ${PORT} 37update add $host $cmd 38send 39answer 40EOF 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. 72KRB5CCNAME="FILE:"$(pwd)/ns1/administrator.ccache 73export KRB5CCNAME 74 75echo_i "testing updates to testdc1 as administrator ($n)" 76ret=0 77test_update $n testdc1.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || ret=1 78n=$((n + 1)) 79if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 80status=$((status + ret)) 81 82echo_i "testing updates to testdc2 as administrator ($n)" 83ret=0 84test_update $n testdc2.example.nil. A "86400 A 10.53.0.11" "10.53.0.11" || ret=1 85n=$((n + 1)) 86if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 87status=$((status + ret)) 88 89echo_i "testing updates to denied as administrator ($n)" 90ret=0 91test_update $n denied.example.nil. TXT "86400 TXT helloworld" "helloworld" >/dev/null && ret=1 92n=$((n + 1)) 93if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 94status=$((status + ret)) 95 96# Testing denied updates. 97KRB5CCNAME="FILE:"$(pwd)/ns1/testdenied.ccache 98export KRB5CCNAME 99 100echo_i "testing updates to denied (A) as a user ($n)" 101ret=0 102test_update $n testdenied.example.nil. A "86400 A 10.53.0.12" "10.53.0.12" >/dev/null && ret=1 103n=$((n + 1)) 104if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 105status=$((status + ret)) 106 107echo_i "testing updates to denied (TXT) as a user ($n)" 108ret=0 109test_update $n testdenied.example.nil. TXT "86400 TXT helloworld" "helloworld" || ret=1 110n=$((n + 1)) 111if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 112status=$((status + ret)) 113 114echo_i "testing external update policy (CNAME) ($n)" 115ret=0 116test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" >/dev/null && ret=1 117n=$((n + 1)) 118if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 119status=$((status + ret)) 120 121echo_i "testing external update policy (CNAME) with auth sock ($n)" 122ret=0 123$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >/dev/null 2>&1 & 124sleep 1 125test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" || ret=1 126n=$((n + 1)) 127if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 128status=$((status + ret)) 129 130echo_i "testing external update policy (A) ($n)" 131ret=0 132test_update $n testcname.example.nil. A "86400 A 10.53.0.13" "10.53.0.13" >/dev/null && ret=1 133n=$((n + 1)) 134if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 135status=$((status + ret)) 136 137echo_i "testing external policy with SIG(0) key ($n)" 138ret=0 139$NSUPDATE -k ns1/Kkey.example.nil.*.private <<END >/dev/null 2>&1 || ret=1 140server 10.53.0.1 ${PORT} 141zone example.nil 142update add fred.example.nil 120 cname foo.bar. 143send 144END 145output=$($DIG $DIGOPTS +short cname fred.example.nil.) 146[ -n "$output" ] || ret=1 147[ $ret -eq 0 ] || echo_i "failed" 148n=$((n + 1)) 149if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 150status=$((status + ret)) 151 152echo_i "ensure too long realm name is fatal in non-interactive mode ($n)" 153ret=0 154$NSUPDATE <<END >nsupdate.out${n} 2>&1 && ret=1 155 realm namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename 156END 157grep "realm is too long" nsupdate.out${n} >/dev/null || ret=1 158grep "syntax error" nsupdate.out${n} >/dev/null || ret=1 159n=$((n + 1)) 160if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 161status=$((status + ret)) 162 163echo_i "ensure too long realm name is not fatal in interactive mode ($n)" 164ret=0 165$NSUPDATE -i <<END >nsupdate.out${n} 2>&1 || ret=1 166 realm namenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamenamename 167END 168grep "realm is too long" nsupdate.out${n} >/dev/null || ret=1 169[ $ret = 0 ] || { 170 echo_i "failed" 171 status=1 172} 173n=$((n + 1)) 174if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 175status=$((status + ret)) 176 177echo_i "stop and start server to check key restoration ($n)" 178ret=0 179gss_keys=$(grep 'tsig key.*generated' ns1/named.run | wc -l) 180stop_server --use-rndc --port "${CONTROLPORT}" ns1 181start_server --noclean --restart --port "${PORT}" ns1 182restored_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 186if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 187status=$((status + ret)) 188 189[ $status -eq 0 ] && echo_i "tsiggss tests all OK" 190 191kill $(cat authsock.pid) 192 193echo_i "exit status: $status" 194[ $status -eq 0 ] || exit 1 195