The introduction of isc_commandline_parse() has caused a compatibility problem with nsec3hash. Previously you were able to type (for example) $ dig +multiline +dnssec com txt | grep 'IN NSEC3' CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 864 IN NSEC3 1 1 0 - ( $ /opt/bind-9.12.0-dev+9+889cc53/bin/nsec3hash - 1 0 com CK0POJMG874LJREF7EFN8430QVIT8BSM (salt=-, hash=1, iterations=0) However the current version says: $ /opt/bind-9.12.0-dev+11+bc78a97/bin/nsec3hash - 1 0 com /opt/bind-9.12.0-dev+11+bc78a97/bin/nsec3hash: illegal option -- - Usage: nsec3hash salt algorithm iterations domain nsec3hash -r algorithm flags iterations salt domain The patch below restores the old behaviour for compatibility with existing scripts. It also now canonicalizes empty salts from '' to '-' to properly match presentation format. I've also revamped the test script to check various empty salt command line parsing edge cases. --- bin/tests/system/tools/tests.sh | 103 ++++++++++++++++++++++++++-------------- bin/tools/nsec3hash.c | 9 +++- 2 files changed, 75 insertions(+), 37 deletions(-) diff --git a/bin/tests/system/tools/tests.sh b/bin/tests/system/tools/tests.sh index de7222b..7e8fe14 100644 --- a/bin/tests/system/tools/tests.sh +++ b/bin/tests/system/tools/tests.sh @@ -11,16 +11,12 @@ SYSTEMTESTTOP=.. status=0 -checkhash() { - name=$1 - hash=$2 - echo "I:checking nsec3hash $name" - out=`$NSEC3HASH $salt $algo $iters $1` +checkout() { case $? in 0) : ok ;; - *) echo "I:failed $cmd" + *) echo "I:failed" status=`expr $status + 1` - continue ;; + return 1 ;; esac case $out in *$hash*) : ok ;; @@ -29,41 +25,76 @@ checkhash() { echo "I:failed" status=`expr $status + 1` ;; esac +} - echo "I:checking nsec3hash -r $name" +# test cases taken from RFC 5155 appendix A +algo=1 flags=0 iters=12 salt="aabbccdd" +while read name hash +do + echo "I:checking $NSEC3HASH $name" + out=`$NSEC3HASH $salt $algo $iters $name` + checkout + + echo "I:checking $NSEC3HASH -r $name" out=`$NSEC3HASH -r $algo $flags $iters $salt $name` + checkout + +done <&1` +checkfail +echo "I:checking $NSEC3HASH extra args" +out=`$NSEC3HASH 00 1 0 two names 2>&1` +checkfail +echo "I:checking $NSEC3HASH bad option" +out=`$NSEC3HASH -? 2>&1` +checkfail echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/bin/tools/nsec3hash.c b/bin/tools/nsec3hash.c index 3103c20..8928ed2 100644 --- a/bin/tools/nsec3hash.c +++ b/bin/tools/nsec3hash.c @@ -85,6 +85,7 @@ nsec3hash(nsec3printer *nsec3print, char *algostr, char *flagstr, unsigned int length; unsigned int iterations; unsigned int salt_length; + char dash[] = "-"; if (strcmp(saltstr, "-") == 0) { salt_length = 0; @@ -96,6 +97,8 @@ nsec3hash(nsec3printer *nsec3print, char *algostr, char *flagstr, salt_length = isc_buffer_usedlength(&buffer); if (salt_length > DNS_NSEC3_SALTSIZE) fatal("salt too long"); + if (salt_length == 0) + saltstr = dash; } hash_alg = atoi(algostr); if (hash_alg > 255U) @@ -157,17 +160,21 @@ main(int argc, char *argv[]) { rdata_format = ISC_TRUE; } - while ((ch = isc_commandline_parse(argc, argv, "r")) != -1) { + while ((ch = isc_commandline_parse(argc, argv, "-r")) != -1) { switch (ch) { case 'r': rdata_format = ISC_TRUE; break; + case '-': + isc_commandline_index -= 1; + goto skip; default: usage(); break; } } +skip: argc -= isc_commandline_index; argv += isc_commandline_index;