summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/rdata/any_255
diff options
context:
space:
mode:
authorJINMEI Tatuya <jinmei@isc.org>2010-10-15 04:47:55 +0200
committerJINMEI Tatuya <jinmei@isc.org>2010-10-15 04:47:55 +0200
commitfc1213ec31971a146c266a4a2f618981f0e5d78e (patch)
treee6a84290b2cc912333dc9c3bc94ce39cb2d9cfe5 /src/lib/dns/rdata/any_255
parentworking branch for trac #372. (diff)
downloadkea-fc1213ec31971a146c266a4a2f618981f0e5d78e.tar.xz
kea-fc1213ec31971a146c266a4a2f618981f0e5d78e.zip
initial implementation of TSIG RDATA.
mostly complete. need some more doc. git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac372@3210 e5f2f494-b856-4b98-b285-d166d9295462
Diffstat (limited to 'src/lib/dns/rdata/any_255')
-rw-r--r--src/lib/dns/rdata/any_255/tsig_250.cc386
-rw-r--r--src/lib/dns/rdata/any_255/tsig_250.h69
2 files changed, 455 insertions, 0 deletions
diff --git a/src/lib/dns/rdata/any_255/tsig_250.cc b/src/lib/dns/rdata/any_255/tsig_250.cc
new file mode 100644
index 0000000000..53548cc3c8
--- /dev/null
+++ b/src/lib/dns/rdata/any_255/tsig_250.cc
@@ -0,0 +1,386 @@
+// 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.
+
+// $Id$
+
+#include <config.h>
+
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <boost/lexical_cast.hpp>
+
+#include <dns/buffer.h>
+#include <dns/messagerenderer.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+
+#include <dns/util/base64.h>
+
+using namespace std;
+using namespace boost;
+
+// 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<uint8_t>& mac, uint16_t original_id, uint16_t error,
+ vector<uint8_t>& 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<const uint8_t*>(mac),
+ static_cast<const uint8_t*>(mac) + macsize),
+ original_id_(original_id), error_(error),
+ other_data_(static_cast<const uint8_t*>(other_data),
+ static_cast<const uint8_t*>(other_data) + other_len)
+ {}
+
+ const Name algorithm_;
+ const uint64_t time_signed_;
+ const uint16_t fudge_;
+ const vector<uint8_t> mac_;
+ const uint16_t original_id_;
+ const uint16_t error_;
+ const vector<uint8_t> 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<T> where T is an unsigned integer type
+// doesn't correctly reject negative numbers when compiled with SunStudio.
+template <typename NumType, int BitSize>
+NumType
+tokenToNum(const string& num_token) {
+ NumType num;
+ try {
+ num = lexical_cast<NumType>(num_token);
+ } catch (const boost::bad_lexical_cast& ex) {
+ isc_throw(InvalidRdataText, "Invalid TSIG numeric parameter: " <<
+ num_token);
+ }
+ if (num < 0 || num >= (static_cast<NumType>(1) << BitSize)) {
+ isc_throw(InvalidRdataText, "Numeric TSIG parameter out of range: " <<
+ num);
+ }
+ return (num);
+}
+}
+
+/// \brief Constructor from string
+TSIG::TSIG(const std::string& tsig_str) : impl_(NULL) {
+ istringstream iss(tsig_str);
+
+ const Name algorithm(getToken(iss, tsig_str));
+ const int64_t time_signed = tokenToNum<int64_t, 48>(getToken(iss,
+ tsig_str));
+ const int32_t fudge = tokenToNum<int32_t, 16>(getToken(iss, tsig_str));
+ const int32_t macsize = tokenToNum<int32_t, 16>(getToken(iss, tsig_str));
+
+ const string mac_txt = (macsize > 0) ? getToken(iss, tsig_str) : "";
+ vector<uint8_t> mac;
+ decodeBase64(mac_txt, mac);
+ if (mac.size() != macsize) {
+ isc_throw(InvalidRdataText, "TSIG MAC size and data are inconsistent");
+ }
+
+ const int32_t orig_id = tokenToNum<int32_t, 16>(getToken(iss, tsig_str));
+
+ const string error_txt = getToken(iss, tsig_str);
+ int32_t error = 0;
+ if (error_txt == "BADSIG") {
+ error = 16; // FIXIT: hardcode
+ } else if (error_txt == "BADKEY") {
+ error = 17;
+ } else if (error_txt == "BADTIME") {
+ error = 18;
+ } else {
+ error = tokenToNum<int32_t, 16>(error_txt);
+ }
+
+ const int32_t otherlen = tokenToNum<int32_t, 16>(getToken(iss, tsig_str));
+ const string otherdata_txt = (otherlen > 0) ? getToken(iss, tsig_str) : "";
+ vector<uint8_t> other_data;
+ decodeBase64(otherdata_txt, other_data);
+
+ if (!iss.eof()) {
+ isc_throw(InvalidRdataText, "Unexpected input for TSIG RDATA: " <<
+ tsig_str);
+ }
+
+ impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac, orig_id,
+ error, other_data);
+}
+
+TSIG::TSIG(InputBuffer& buffer, size_t rdata_len UNUSED_PARAM) : impl_(NULL) {
+ // we don't need rdata_len for parsing. if necessary, the caller will
+ // check consistency.
+
+ Name algorithm(buffer);
+
+ uint8_t time_signed_buf[6];
+ buffer.readData(time_signed_buf, sizeof(time_signed_buf));
+ const uint64_t time_signed =
+ (static_cast<uint64_t>(time_signed_buf[0]) << 40 |
+ static_cast<uint64_t>(time_signed_buf[1]) << 32 |
+ static_cast<uint64_t>(time_signed_buf[2]) << 24 |
+ static_cast<uint64_t>(time_signed_buf[3]) << 16 |
+ static_cast<uint64_t>(time_signed_buf[4]) << 8 |
+ static_cast<uint64_t>(time_signed_buf[5]));
+
+ const uint16_t fudge = buffer.readUint16();
+
+ const uint16_t mac_size = buffer.readUint16();
+ vector<uint8_t> mac(mac_size);
+ if (mac_size > 0) {
+ buffer.readData(&mac[0], mac_size);
+ }
+
+ const uint16_t original_id = buffer.readUint16();
+ const uint16_t error = buffer.readUint16();
+
+ const uint16_t other_len = buffer.readUint16();
+ vector<uint8_t> other_data(other_len);
+ if (other_len > 0) {
+ buffer.readData(&other_data[0], other_len);
+ }
+
+ impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac, original_id,
+ error, other_data);
+}
+
+TSIG::TSIG(const Name& algorithm, uint64_t time_signed, uint16_t fudge,
+ size_t mac_size, const void* mac, uint16_t original_id,
+ uint16_t error, size_t other_len, const void* other_data) :
+ impl_(NULL)
+{
+ if (time_signed > 0xffffffffffff) {
+ isc_throw(OutOfRange, "TSIG Time Signed is too large: " <<
+ time_signed);
+ }
+ if ((mac_size == 0 && mac != NULL) || (mac_size > 0 && mac == NULL)) {
+ isc_throw(InvalidParameter, "TSIG MAC size and data inconsistent");
+ }
+ if ((other_len == 0 && other_data != NULL) ||
+ (other_len > 0 && other_data == NULL)) {
+ isc_throw(InvalidParameter,
+ "TSIG Other data length and data inconsistent");
+ }
+ impl_ = new TSIGImpl(algorithm, time_signed, fudge, mac_size, mac,
+ original_id, error, other_len, other_data);
+}
+
+TSIG::TSIG(const TSIG& source) : Rdata(), impl_(new TSIGImpl(*source.impl_))
+{}
+
+TSIG&
+TSIG::operator=(const TSIG& source) {
+ if (impl_ == source.impl_) {
+ return (*this);
+ }
+
+ TSIGImpl* newimpl = new TSIGImpl(*source.impl_);
+ delete impl_;
+ impl_ = newimpl;
+
+ return (*this);
+}
+
+TSIG::~TSIG() {
+ delete impl_;
+}
+
+std::string
+TSIG::toText() const {
+ string result;
+
+ result += impl_->algorithm_.toText() + " " +
+ lexical_cast<string>(impl_->time_signed_) + " " +
+ lexical_cast<string>(impl_->fudge_) + " " +
+ lexical_cast<string>(impl_->mac_.size()) + " ";
+ if (impl_->mac_.size() > 0) {
+ result += encodeBase64(impl_->mac_) + " ";
+ }
+ result += lexical_cast<string>(impl_->original_id_) + " ";
+ if (impl_->error_ == 16) { // XXX: we'll soon introduce generic converter.
+ result += "BADSIG ";
+ } else if (impl_->error_ == 17) {
+ result += "BADKEY ";
+ } else if (impl_->error_ == 18) {
+ result += "BADTIME ";
+ } else {
+ result += lexical_cast<string>(impl_->error_) + " ";
+ }
+ result += lexical_cast<string>(impl_->other_data_.size());
+ if (impl_->other_data_.size() > 0) {
+ result += " " + encodeBase64(impl_->other_data_);
+ }
+
+ return (result);
+}
+
+template <typename Output>
+void
+toWireCommon(const TSIG::TSIGImpl& impl, Output& output) {
+ output.writeUint16(impl.time_signed_ >> 32);
+ output.writeUint32(impl.time_signed_ & 0xffffffff);
+ output.writeUint16(impl.fudge_);
+ const uint16_t mac_size = impl.mac_.size();
+ output.writeUint16(mac_size);
+ if (mac_size > 0) {
+ output.writeData(&impl.mac_[0], mac_size);
+ }
+ output.writeUint16(impl.original_id_);
+ output.writeUint16(impl.error_);
+ const uint16_t other_len = impl.other_data_.size();
+ output.writeUint16(other_len);
+ if (other_len > 0) {
+ output.writeData(&impl.other_data_[0], other_len);
+ }
+}
+
+void
+TSIG::toWire(OutputBuffer& buffer) const {
+ impl_->algorithm_.toWire(buffer);
+ toWireCommon<OutputBuffer>(*impl_, buffer);
+}
+
+void
+TSIG::toWire(MessageRenderer& renderer) const {
+ renderer.writeName(impl_->algorithm_, false);
+ toWireCommon<MessageRenderer>(*impl_, renderer);
+}
+
+int
+vectorComp(const vector<uint8_t>& v1, const vector<uint8_t>& v2) {
+ const size_t this_size = v1.size();
+ const size_t other_size = v2.size();
+ if (this_size != other_size) {
+ return (this_size < other_size ? -1 : 1);
+ }
+ if (this_size > 0) {
+ return (memcmp(&v1[0], &v2[0], this_size));
+ }
+ return (0);
+}
+
+int
+TSIG::compare(const Rdata& other) const {
+ const TSIG& other_tsig = dynamic_cast<const TSIG&>(other);
+
+ const int ncmp = compareNames(impl_->algorithm_,
+ other_tsig.impl_->algorithm_);
+ if (ncmp != 0) {
+ return (ncmp);
+ }
+
+ if (impl_->time_signed_ != other_tsig.impl_->time_signed_) {
+ return (impl_->time_signed_ < other_tsig.impl_->time_signed_ ? -1 : 1);
+ }
+ if (impl_->fudge_ != other_tsig.impl_->fudge_) {
+ return (impl_->fudge_ < other_tsig.impl_->fudge_ ? -1 : 1);
+ }
+ const int vcmp = vectorComp(impl_->mac_, other_tsig.impl_->mac_);
+ if (vcmp != 0) {
+ return (vcmp);
+ }
+ if (impl_->original_id_ != other_tsig.impl_->original_id_) {
+ return (impl_->original_id_ < other_tsig.impl_->original_id_ ? -1 : 1);
+ }
+ if (impl_->error_ != other_tsig.impl_->error_) {
+ return (impl_->error_ < other_tsig.impl_->error_ ? -1 : 1);
+ }
+ return (vectorComp(impl_->other_data_, other_tsig.impl_->other_data_));
+}
+
+const Name&
+TSIG::getAlgorithm() const {
+ return (impl_->algorithm_);
+}
+
+uint64_t
+TSIG::getTimeSigned() const {
+ return (impl_->time_signed_);
+}
+
+uint16_t
+TSIG::getFudge() const {
+ return (impl_->fudge_);
+}
+
+uint16_t
+TSIG::getMACSize() const {
+ return (impl_->mac_.size());
+}
+
+const void*
+TSIG::getMAC() const {
+ if (impl_->mac_.size() > 0) {
+ return (&impl_->mac_[0]);
+ } else {
+ return (NULL);
+ }
+}
+
+uint16_t
+TSIG::getOriginalID() const {
+ return (impl_->original_id_);
+}
+
+uint16_t
+TSIG::getError() const {
+ return (impl_->error_);
+}
+
+uint16_t
+TSIG::getOtherLen() const {
+ return (impl_->other_data_.size());
+}
+
+const void*
+TSIG::getOtherData() const {
+ if (impl_->other_data_.size() > 0) {
+ return (&impl_->other_data_[0]);
+ } else {
+ return (NULL);
+ }
+}
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
diff --git a/src/lib/dns/rdata/any_255/tsig_250.h b/src/lib/dns/rdata/any_255/tsig_250.h
new file mode 100644
index 0000000000..52aaeefb64
--- /dev/null
+++ b/src/lib/dns/rdata/any_255/tsig_250.h
@@ -0,0 +1,69 @@
+// 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.
+
+// $Id$
+
+// BEGIN_HEADER_GUARD
+
+#include <stdint.h>
+
+#include <string>
+
+#include <dns/rdata.h>
+
+namespace isc {
+namespace dns {
+class Name;
+}
+}
+
+// BEGIN_ISC_NAMESPACE
+
+// BEGIN_COMMON_DECLARATIONS
+// END_COMMON_DECLARATIONS
+
+// BEGIN_RDATA_NAMESPACE
+
+/// \brief TSIG RDATA class.
+class TSIG : public Rdata {
+public:
+ // BEGIN_COMMON_MEMBERS
+ // END_COMMON_MEMBERS
+ TSIG(const Name& algorithm, uint64_t time_signed, uint16_t fudge,
+ size_t mac_size, const void* mac, uint16_t original_id,
+ uint16_t error, size_t other_len, const void* other_data);
+ TSIG& operator=(const TSIG& source);
+ ~TSIG();
+
+ const Name& getAlgorithm() const;
+ uint64_t getTimeSigned() const;
+ uint16_t getFudge() const;
+ uint16_t getMACSize() const;
+ const void* getMAC() const;
+ uint16_t getOriginalID() const;
+ uint16_t getError() const;
+ uint16_t getOtherLen() const;
+ const void* getOtherData() const;
+private:
+ struct TSIGImpl;
+ TSIGImpl* impl_;
+};
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
+// END_HEADER_GUARD
+
+// Local Variables:
+// mode: c++
+// End: