/////////////// /////////////// /////////////// THIS FILE IS AUTOMATICALLY GENERATED BY gen-rdatacode.py. /////////////// DO NOT EDIT! /////////////// /////////////// // Copyright (C) 2010-2021 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using boost::lexical_cast; using namespace isc::util; using namespace isc::util::encode; using namespace isc::dns; using isc::dns::rdata::generic::detail::createNameFromLexer; namespace isc { namespace dns { namespace rdata { namespace any { // straightforward representation of TSIG RDATA fields struct TSIGImpl { TSIGImpl(const Name& algorithm, uint64_t time_signed, uint16_t fudge, vector& mac, uint16_t original_id, uint16_t error, vector& other_data) : algorithm_(algorithm), time_signed_(time_signed), fudge_(fudge), mac_(mac), original_id_(original_id), error_(error), other_data_(other_data) {} TSIGImpl(const Name& algorithm, uint64_t time_signed, uint16_t fudge, size_t macsize, const void* mac, uint16_t original_id, uint16_t error, size_t other_len, const void* other_data) : algorithm_(algorithm), time_signed_(time_signed), fudge_(fudge), mac_(static_cast(mac), static_cast(mac) + macsize), original_id_(original_id), error_(error), other_data_(static_cast(other_data), static_cast(other_data) + other_len) {} template void toWireCommon(Output& output) const; const Name algorithm_; const uint64_t time_signed_; const uint16_t fudge_; const vector mac_; const uint16_t original_id_; const uint16_t error_; const vector other_data_; }; // helper function for string and lexer constructors TSIGImpl* TSIG::constructFromLexer(MasterLexer& lexer, const Name* origin) { const Name& algorithm = createNameFromLexer(lexer, origin ? origin : &Name::ROOT_NAME()); const Name& canonical_algorithm_name = (algorithm == TSIGKey::HMACMD5_SHORT_NAME()) ? TSIGKey::HMACMD5_NAME() : algorithm; const string& time_txt = lexer.getNextToken(MasterToken::STRING).getString(); uint64_t time_signed; try { time_signed = boost::lexical_cast(time_txt); } catch (const boost::bad_lexical_cast&) { isc_throw(InvalidRdataText, "Invalid TSIG Time"); } if ((time_signed >> 48) != 0) { isc_throw(InvalidRdataText, "TSIG Time out of range"); } const uint32_t fudge = lexer.getNextToken(MasterToken::NUMBER).getNumber(); if (fudge > 0xffff) { isc_throw(InvalidRdataText, "TSIG Fudge out of range"); } const uint32_t macsize = lexer.getNextToken(MasterToken::NUMBER).getNumber(); if (macsize > 0xffff) { isc_throw(InvalidRdataText, "TSIG MAC Size out of range"); } const string& mac_txt = (macsize > 0) ? lexer.getNextToken(MasterToken::STRING).getString() : ""; vector mac; decodeBase64(mac_txt, mac); if (mac.size() != macsize) { isc_throw(InvalidRdataText, "TSIG MAC Size and data are inconsistent"); } const uint32_t orig_id = lexer.getNextToken(MasterToken::NUMBER).getNumber(); if (orig_id > 0xffff) { isc_throw(InvalidRdataText, "TSIG Original ID out of range"); } const string& error_txt = lexer.getNextToken(MasterToken::STRING).getString(); uint32_t error = 0; // XXX: In the initial implementation we hardcode the mnemonics. // We'll soon generalize this. if (error_txt == "NOERROR") { error = Rcode::NOERROR_CODE; } else if (error_txt == "BADSIG") { error = TSIGError::BAD_SIG_CODE; } else if (error_txt == "BADKEY") { error = TSIGError::BAD_KEY_CODE; } else if (error_txt == "BADTIME") { error = TSIGError::BAD_TIME_CODE; } else if (error_txt == "BADMODE") { error = TSIGError::BAD_MODE_CODE; } else if (error_txt == "BADNAME") { error = TSIGError::BAD_NAME_CODE; } else if (error_txt == "BADALG") { error = TSIGError::BAD_ALG_CODE; } else if (error_txt == "BADTRUNC") { error = TSIGError::BAD_TRUNC_CODE; } else { /// we cast to uint32_t and range-check, because casting directly to /// uint16_t will convert negative numbers to large positive numbers try { error = boost::lexical_cast(error_txt); } catch (const boost::bad_lexical_cast&) { isc_throw(InvalidRdataText, "Invalid TSIG Error"); } if (error > 0xffff) { isc_throw(InvalidRdataText, "TSIG Error out of range"); } } const uint32_t otherlen = lexer.getNextToken(MasterToken::NUMBER).getNumber(); if (otherlen > 0xffff) { isc_throw(InvalidRdataText, "TSIG Other Len out of range"); } const string otherdata_txt = (otherlen > 0) ? lexer.getNextToken(MasterToken::STRING).getString() : ""; vector other_data; decodeBase64(otherdata_txt, other_data); if (other_data.size() != otherlen) { isc_throw(InvalidRdataText, "TSIG Other Data length does not match Other Len"); } // RFC2845 says Other Data is "empty unless Error == BADTIME". // However, we don't enforce that. return (new TSIGImpl(canonical_algorithm_name, time_signed, fudge, mac, orig_id, error, other_data)); } /// \brief Constructor from string. /// /// The given string must represent a valid TSIG 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. /// /// \c tsig_str must be formatted as follows: /// \code