// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace boost; using namespace isc::util; using namespace isc::util::encode; // BEGIN_ISC_NAMESPACE // BEGIN_RDATA_NAMESPACE /// This is a straightforward representation of TSIG RDATA fields. struct TSIG::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_; }; namespace { string getToken(istringstream& iss, const string& full_input) { string token; iss >> token; if (iss.bad() || iss.fail()) { isc_throw(InvalidRdataText, "Invalid TSIG text: parse error " << full_input); } return (token); } // This helper function converts a string token to an *unsigned* integer. // NumType is a *signed* integral type (e.g. int32_t) that is sufficiently // wide to store resulting integers. // BitSize is the maximum number of bits that the resulting integer can take. // This function first checks whether the given token can be converted to // an integer of NumType type. It then confirms the conversion result is // within the valid range, i.e., [0, 2^NumType - 1]. The second check is // necessary because lexical_cast where T is an unsigned integer type // doesn't correctly reject negative numbers when compiled with SunStudio. template NumType tokenToNum(const string& num_token) { NumType num; try { num = lexical_cast(num_token); } catch (const boost::bad_lexical_cast& ex) { isc_throw(InvalidRdataText, "Invalid TSIG numeric parameter: " << num_token); } if (num < 0 || num >= (static_cast(1) << BitSize)) { isc_throw(InvalidRdataText, "Numeric TSIG parameter out of range: " << num); } return (num); } } /// \brief Constructor from string. /// /// \c tsig_str must be formatted as follows: /// \code