Browse Source

[2522] support multiline or space-separated fingerprint text in SSHFP

Paul Selkirk 12 years ago
parent
commit
87a710de67
2 changed files with 32 additions and 7 deletions
  1. 20 5
      src/lib/dns/rdata/generic/sshfp_44.cc
  2. 12 2
      src/lib/dns/tests/rdata_sshfp_unittest.cc

+ 20 - 5
src/lib/dns/rdata/generic/sshfp_44.cc

@@ -64,11 +64,25 @@ SSHFP::constructFromLexer(MasterLexer& lexer) {
         isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
     }
 
-    const MasterToken& token = lexer.getNextToken(MasterToken::STRING, true);
+    std::string fingerprint_str;
+    std::string fingerprint_substr;
+    while (true) {
+        const MasterToken& token =
+            lexer.getNextToken(MasterToken::STRING, true);
+        if ((token.getType() == MasterToken::END_OF_FILE) ||
+            (token.getType() == MasterToken::END_OF_LINE)) {
+            break;
+        }
+        token.getString(fingerprint_substr);
+        fingerprint_str.append(fingerprint_substr);
+    }
+    lexer.ungetToken();
+
     vector<uint8_t> fingerprint;
-    if ((token.getType() != MasterToken::END_OF_FILE) &&
-        (token.getType() != MasterToken::END_OF_LINE)) {
-        decodeHex(token.getString(), fingerprint);
+    // If fingerprint is missing, it's OK. See the API documentation of the
+    // constructor.
+    if (fingerprint_str.size() > 0) {
+        decodeHex(fingerprint_str, fingerprint);
     }
 
     return (new SSHFPImpl(algorithm, fingerprint_type, fingerprint));
@@ -85,7 +99,8 @@ SSHFP::constructFromLexer(MasterLexer& lexer) {
 /// ranges, but are not constrained to the values defined in RFC4255.
 ///
 /// The Fingerprint field may be absent, but if present it must contain a
-/// valid hex encoding of the fingerprint.
+/// valid hex encoding of the fingerprint. For compatibility with BIND 9,
+/// whitespace is allowed in the hex text (RFC4255 is silent on the matter).
 ///
 /// \throw InvalidRdataText if any fields are missing, out of their valid
 /// ranges, or incorrect.

+ 12 - 2
src/lib/dns/tests/rdata_sshfp_unittest.cc

@@ -95,7 +95,17 @@ TEST_F(Rdata_SSHFP_Test, createFromText) {
     checkFromText_None("2 1   123456789abcdef67890123456789abcdef67890");
 
     // Combination of lowercase and uppercase
-    checkFromText_None("2 1   123456789ABCDEF67890123456789abcdef67890");
+    checkFromText_None("2 1 123456789ABCDEF67890123456789abcdef67890");
+
+    // spacing in the fingerprint field
+    checkFromText_None("2 1 123456789abcdef67890 123456789abcdef67890");
+
+    // multi-line fingerprint field
+    checkFromText_None("2 1 ( 123456789abcdef67890\n 123456789abcdef67890 )");
+
+    // string constructor throws if there's extra text,
+    // but lexer constructor doesn't
+    checkFromText_BadString(sshfp_txt + "\n" + sshfp_txt);
 }
 
 TEST_F(Rdata_SSHFP_Test, algorithmTypes) {
@@ -129,7 +139,7 @@ TEST_F(Rdata_SSHFP_Test, badText) {
     checkFromText_LexerError("ONE 2 123456789abcdef67890123456789abcdef67890");
     checkFromText_LexerError("1 TWO 123456789abcdef67890123456789abcdef67890");
     checkFromText_BadValue("1 2 BUCKLEMYSHOE");
-    checkFromText_BadString(sshfp_txt + " extra text");
+    checkFromText_BadValue(sshfp_txt + " extra text");
 
     // yes, these are redundant to the last test cases in algorithmTypes
     checkFromText_InvalidText(