Browse Source

[2521] add MasterLexer constructor for RRSIG

Paul Selkirk 12 years ago
parent
commit
fdb992f0a2

+ 2 - 1
src/lib/dns/gen-rdatacode.py.in

@@ -1,6 +1,6 @@
 #!@PYTHON@
 #!@PYTHON@
 
 
-# Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 #
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
 # purpose with or without fee is hereby granted, provided that the above
@@ -46,6 +46,7 @@ new_rdata_factory_users = [('a', 'in'),
                            ('nsec', 'generic'),
                            ('nsec', 'generic'),
                            ('opt', 'generic'),
                            ('opt', 'generic'),
                            ('ptr', 'generic'),
                            ('ptr', 'generic'),
+                           ('rrsig', 'generic'),
                            ('soa', 'generic'),
                            ('soa', 'generic'),
                            ('spf', 'generic'),
                            ('spf', 'generic'),
                            ('srv', 'in'),
                            ('srv', 'in'),

+ 88 - 18
src/lib/dns/rdata/generic/rrsig_46.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -29,6 +29,7 @@
 #include <dns/rrttl.h>
 #include <dns/rrttl.h>
 #include <dns/rdata.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
 #include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/lexer_util.h>
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <time.h>
 #include <time.h>
@@ -36,6 +37,7 @@
 using namespace std;
 using namespace std;
 using namespace isc::util;
 using namespace isc::util;
 using namespace isc::util::encode;
 using namespace isc::util::encode;
+using isc::dns::rdata::generic::detail::createNameFromLexer;
 
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
@@ -72,38 +74,106 @@ struct RRSIGImpl {
     const vector<uint8_t> signature_;
     const vector<uint8_t> signature_;
 };
 };
 
 
-RRSIG::RRSIG(const std::string& rrsig_str) :
-    impl_(NULL)
+namespace {
+// helper function for string and lexer constructors
+RRSIGImpl* createFromLexer(MasterLexer& lexer, const Name* origin)
 {
 {
-    istringstream iss(rrsig_str);
-    string covered_txt, signer_txt, expire_txt, inception_txt;
-    unsigned int algorithm, labels;
+    string covered_txt, expire_txt, inception_txt, signature_txt;
+    unsigned int algorithm, labels, tag;
     uint32_t originalttl;
     uint32_t originalttl;
-    uint16_t tag;
-    stringbuf signaturebuf;
 
 
-    iss >> covered_txt >> algorithm >> labels >> originalttl
-        >> expire_txt >> inception_txt >> tag >> signer_txt
-        >> &signaturebuf;
-    if (iss.bad() || iss.fail()) {
-        isc_throw(InvalidRdataText, "Invalid RRSIG text");
-    }
+    covered_txt = lexer.getNextToken(MasterToken::STRING).getString();
+    algorithm = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    labels = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    originalttl = RRTTL(lexer.getNextToken(MasterToken::STRING).getString()).getValue();
+    expire_txt = lexer.getNextToken(MasterToken::STRING).getString();
+    inception_txt = lexer.getNextToken(MasterToken::STRING).getString();
+    tag = lexer.getNextToken(MasterToken::NUMBER).getNumber();
+    Name signer = createNameFromLexer(lexer, origin);
+    signature_txt = lexer.getNextToken(MasterToken::STRING).getString();
+
     if (algorithm > 0xff) {
     if (algorithm > 0xff) {
         isc_throw(InvalidRdataText, "RRSIG algorithm out of range");
         isc_throw(InvalidRdataText, "RRSIG algorithm out of range");
     }
     }
     if (labels > 0xff) {
     if (labels > 0xff) {
         isc_throw(InvalidRdataText, "RRSIG labels out of range");
         isc_throw(InvalidRdataText, "RRSIG labels out of range");
     }
     }
+    if (tag > 0xffff) {
+        isc_throw(InvalidRdataText, "RRSIG key tag out of range");
+    }
 
 
     const uint32_t timeexpire = timeFromText32(expire_txt);
     const uint32_t timeexpire = timeFromText32(expire_txt);
     const uint32_t timeinception = timeFromText32(inception_txt);
     const uint32_t timeinception = timeFromText32(inception_txt);
 
 
     vector<uint8_t> signature;
     vector<uint8_t> signature;
-    decodeBase64(signaturebuf.str(), signature);
+    decodeBase64(signature_txt, signature);
 
 
-    impl_ = new RRSIGImpl(RRType(covered_txt), algorithm, labels,
-                          originalttl, timeexpire, timeinception, tag,
-                          Name(signer_txt), signature);
+    return new RRSIGImpl(RRType(covered_txt), algorithm, labels,
+                         originalttl, timeexpire, timeinception,
+			 static_cast<uint16_t>(tag), signer, signature);
+}
+}
+
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid RRSIG RDATA.  There can be extra
+/// space characters at the beginning or end of the text (which are simply
+/// ignored), but other extra text, including a new line, will make the
+/// construction fail with an exception.
+///
+/// The Signer's Name must be absolute since there's no parameter that
+/// specifies the origin name; if this is not absolute, \c MissingNameOrigin
+/// exception will be thrown.  This must not be represented as a quoted
+/// string.
+///
+/// See the construction that takes \c MasterLexer for other fields.
+///
+/// \throw Others Exception from the Name and RRTTL constructors.
+/// \throw InvalidRdataText Other general syntax errors.
+RRSIG::RRSIG(const std::string& rrsig_str) :
+    impl_(NULL)
+{
+    try {
+        istringstream iss(rrsig_str);
+        MasterLexer lexer;
+        lexer.pushSource(iss);
+
+        impl_ = createFromLexer(lexer, NULL);
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for RRSIG: "
+                      << rrsig_str);
+        }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct RRSIG from '" <<
+                  rrsig_str << "': " << ex.what());
+    }
+}
+
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an RRSIG RDATA.  The Signer's Name fields can be non absolute if \c
+/// origin is non NULL, in which case \c origin is used to make it absolute.
+/// This must not be represented as a quoted string.
+///
+/// The Original TTL field can be either a valid decimal representation of an
+/// unsigned 32-bit integer or other valid textual representation of \c RRTTL
+/// such as "1H" (which means 3600).
+///
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+/// \throw Other Exceptions from the Name and RRTTL constructors if
+/// construction of textual fields as these objects fail.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+/// \param origin If non NULL, specifies the origin of Signer's Name when
+/// it is non absolute.
+RRSIG::RRSIG(MasterLexer& lexer, const Name* origin,
+             MasterLoader::Options, MasterLoaderCallbacks&) :
+    impl_(NULL)
+{
+    impl_ = createFromLexer(lexer, origin);
 }
 }
 
 
 RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {
 RRSIG::RRSIG(InputBuffer& buffer, size_t rdata_len) {

+ 2 - 2
src/lib/dns/tests/message_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -98,7 +98,7 @@ protected:
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
                                         RRType::RRSIG(), RRTTL(3600)));
                                         RRType::RRSIG(), RRTTL(3600)));
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
-                                             "20100220084538 1 example.com "
+                                             "20100220084538 1 example.com. "
                                              "FAKEFAKEFAKEFAKE"));
                                              "FAKEFAKEFAKEFAKE"));
         rrset_aaaa->addRRsig(rrset_rrsig);
         rrset_aaaa->addRRsig(rrset_rrsig);
     }
     }

+ 10 - 3
src/lib/dns/tests/rdata_rrsig_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -56,42 +56,49 @@ TEST_F(Rdata_RRSIG_Test, fromText) {
 }
 }
 
 
 TEST_F(Rdata_RRSIG_Test, badText) {
 TEST_F(Rdata_RRSIG_Test, badText) {
+    // missing fields
     EXPECT_THROW(const generic::RRSIG sig("SPORK"), InvalidRdataText);
     EXPECT_THROW(const generic::RRSIG sig("SPORK"), InvalidRdataText);
+    // bad algorithm
     EXPECT_THROW(const generic::RRSIG sig("A 555 4 43200 "
     EXPECT_THROW(const generic::RRSIG sig("A 555 4 43200 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
+    // bad labels
     EXPECT_THROW(const generic::RRSIG sig("A 5 4444 43200 "
     EXPECT_THROW(const generic::RRSIG sig("A 5 4444 43200 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
+    // bad original ttl
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 999999999999 "
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 999999999999 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
-                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
+                     "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRRTTL);
+    // bad signature expiration, inception
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
                      "20100223 20100227 8496 isc.org. "
                      "20100223 20100227 8496 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidTime);
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidTime);
+    // bad key tag
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
     EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
                      "20100223214617 20100222214617 999999 isc.org. "
                      "20100223214617 20100222214617 999999 isc.org. "
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
                      "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidRdataText);
+    // bad signature
     EXPECT_THROW(const generic::RRSIG sig(
     EXPECT_THROW(const generic::RRSIG sig(
                      "A 5 4 43200 "
                      "A 5 4 43200 "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "20100223214617 20100222214617 8496 isc.org. "
                      "EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!="),
                      "EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!="),
-                 BadValue);     // bad base64 input
+                 BadValue);
 }
 }
 
 
 TEST_F(Rdata_RRSIG_Test, DISABLED_badText) {
 TEST_F(Rdata_RRSIG_Test, DISABLED_badText) {

+ 3 - 3
src/lib/dns/tests/rrcollator_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -59,10 +59,10 @@ protected:
         txt_rdata_(createRdata(RRType::TXT(), rrclass_, "test")),
         txt_rdata_(createRdata(RRType::TXT(), rrclass_, "test")),
         sig_rdata1_(createRdata(RRType::RRSIG(), rrclass_,
         sig_rdata1_(createRdata(RRType::RRSIG(), rrclass_,
                                 "A 5 3 3600 20000101000000 20000201000000 "
                                 "A 5 3 3600 20000101000000 20000201000000 "
-                                "12345 example.com. FAKE\n")),
+                                "12345 example.com. FAKE ")),
         sig_rdata2_(createRdata(RRType::RRSIG(), rrclass_,
         sig_rdata2_(createRdata(RRType::RRSIG(), rrclass_,
                                 "NS 5 3 3600 20000101000000 20000201000000 "
                                 "NS 5 3 3600 20000101000000 20000201000000 "
-                                "12345 example.com. FAKE\n"))
+                                "12345 example.com. FAKE "))
     {}
     {}
 
 
     void checkRRset(const Name& expected_name, const RRClass& expected_class,
     void checkRRset(const Name& expected_name, const RRClass& expected_class,

+ 2 - 2
src/lib/dns/tests/rrset_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -289,7 +289,7 @@ protected:
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
         rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(),
                                          RRType::RRSIG(), RRTTL(3600)));
                                          RRType::RRSIG(), RRTTL(3600)));
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
         rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 "
-                                             "20100220084538 1 example.com "
+                                             "20100220084538 1 example.com. "
                                              "FAKEFAKEFAKEFAKE"));
                                              "FAKEFAKEFAKEFAKE"));
         rrset_aaaa->addRRsig(rrset_rrsig);
         rrset_aaaa->addRRsig(rrset_rrsig);
     }
     }