mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-03 15:35:17 +00:00
[trac813] supported another form of TSIGRecord constructore, intending to
use it in "from wire" cases. also corrected RR_COMMON_LEN and related tests.
This commit is contained in:
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
#include <util/buffer.h>
|
#include <util/buffer.h>
|
||||||
|
|
||||||
|
#include <dns/exceptions.h>
|
||||||
#include <dns/messagerenderer.h>
|
#include <dns/messagerenderer.h>
|
||||||
#include <dns/name.h>
|
#include <dns/name.h>
|
||||||
|
#include <dns/rdata.h>
|
||||||
#include <dns/rdataclass.h>
|
#include <dns/rdataclass.h>
|
||||||
#include <dns/tsig.h>
|
#include <dns/tsig.h>
|
||||||
#include <dns/tsigkey.h>
|
#include <dns/tsigkey.h>
|
||||||
@@ -39,14 +41,16 @@ class TSIGRecordTest : public ::testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
TSIGRecordTest() :
|
TSIGRecordTest() :
|
||||||
test_name("www.example.com"), test_mac(16, 0xda),
|
test_name("www.example.com"), test_mac(16, 0xda),
|
||||||
test_record(test_name, any::TSIG(TSIGKey::HMACMD5_NAME(), 0x4da8877a,
|
test_rdata(any::TSIG(TSIGKey::HMACMD5_NAME(), 0x4da8877a,
|
||||||
TSIGContext::DEFAULT_FUDGE,
|
TSIGContext::DEFAULT_FUDGE,
|
||||||
test_mac.size(), &test_mac[0],
|
test_mac.size(), &test_mac[0],
|
||||||
0x2d65, 0, 0, NULL)),
|
0x2d65, 0, 0, NULL)),
|
||||||
|
test_record(test_name, test_rdata),
|
||||||
buffer(0), renderer(buffer)
|
buffer(0), renderer(buffer)
|
||||||
{}
|
{}
|
||||||
const Name test_name;
|
const Name test_name;
|
||||||
vector<unsigned char> test_mac;
|
vector<unsigned char> test_mac;
|
||||||
|
const any::TSIG test_rdata;
|
||||||
const TSIGRecord test_record;
|
const TSIGRecord test_record;
|
||||||
OutputBuffer buffer;
|
OutputBuffer buffer;
|
||||||
MessageRenderer renderer;
|
MessageRenderer renderer;
|
||||||
@@ -58,12 +62,48 @@ TEST_F(TSIGRecordTest, getName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TSIGRecordTest, getLength) {
|
TEST_F(TSIGRecordTest, getLength) {
|
||||||
// 83 = 17 + 26 + 16 + 24
|
// 85 = 17 + 26 + 16 + 24
|
||||||
// len(www.example.com) = 17
|
// len(www.example.com) = 17
|
||||||
// len(hmac-md5.sig-alg.reg.int) = 26
|
// len(hmac-md5.sig-alg.reg.int) = 26
|
||||||
// len(MAC) = 16
|
// len(MAC) = 16
|
||||||
// the rest are fixed length fields (24 in total)
|
// the rest are fixed length fields (26 in total)
|
||||||
EXPECT_EQ(83, test_record.getLength());
|
EXPECT_EQ(85, test_record.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TSIGRecordTest, fromParams) {
|
||||||
|
// Construct the same TSIG RR as test_record from parameters.
|
||||||
|
// See the getLength test for the magic number of 85 (although it
|
||||||
|
// actually doesn't matter)
|
||||||
|
const TSIGRecord record(test_name, TSIGRecord::getClass(),
|
||||||
|
TSIGRecord::getTTL(), test_rdata, 85);
|
||||||
|
// Perform straight sanity checks
|
||||||
|
EXPECT_EQ(test_name, record.getName());
|
||||||
|
EXPECT_EQ(85, record.getLength());
|
||||||
|
EXPECT_EQ(0, test_rdata.compare(record.getRdata()));
|
||||||
|
|
||||||
|
// The constructor doesn't check the length...
|
||||||
|
EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
|
||||||
|
TSIGRecord::getTTL(), test_rdata, 82));
|
||||||
|
// ...even for impossibly small values...
|
||||||
|
EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
|
||||||
|
TSIGRecord::getTTL(), test_rdata, 1));
|
||||||
|
// ...or too large values.
|
||||||
|
EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
|
||||||
|
TSIGRecord::getTTL(), test_rdata, 65536));
|
||||||
|
|
||||||
|
// RDATA must indeed be TSIG
|
||||||
|
EXPECT_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
|
||||||
|
TSIGRecord::getTTL(), in::A("192.0.2.1"), 85),
|
||||||
|
DNSMessageFORMERR);
|
||||||
|
|
||||||
|
// Unexpected class
|
||||||
|
EXPECT_THROW(TSIGRecord(test_name, RRClass::IN(), TSIGRecord::getTTL(),
|
||||||
|
test_rdata, 85),
|
||||||
|
DNSMessageFORMERR);
|
||||||
|
|
||||||
|
// Unexpected TTL (simply ignored)
|
||||||
|
EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
|
||||||
|
RRTTL(3600), test_rdata, 85));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TSIGRecordTest, recordToWire) {
|
TEST_F(TSIGRecordTest, recordToWire) {
|
||||||
@@ -82,10 +122,10 @@ TEST_F(TSIGRecordTest, recordToWire) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TSIGRecordTest, recordToOLongToWire) {
|
TEST_F(TSIGRecordTest, recordToOLongToWire) {
|
||||||
// Rendering the test record requires a room of 83 bytes (see the
|
// Rendering the test record requires a room of 85 bytes (see the
|
||||||
// getLength test). By setting the limit to 82, it will fail, and
|
// getLength test). By setting the limit to 84, it will fail, and
|
||||||
// the renderer will be marked as "truncated".
|
// the renderer will be marked as "truncated".
|
||||||
renderer.setLengthLimit(82);
|
renderer.setLengthLimit(84);
|
||||||
EXPECT_FALSE(renderer.isTruncated()); // not marked before render attempt
|
EXPECT_FALSE(renderer.isTruncated()); // not marked before render attempt
|
||||||
EXPECT_EQ(0, test_record.toWire(renderer));
|
EXPECT_EQ(0, test_record.toWire(renderer));
|
||||||
EXPECT_TRUE(renderer.isTruncated());
|
EXPECT_TRUE(renderer.isTruncated());
|
||||||
|
@@ -17,18 +17,20 @@
|
|||||||
|
|
||||||
#include <util/buffer.h>
|
#include <util/buffer.h>
|
||||||
|
|
||||||
|
#include <dns/exceptions.h>
|
||||||
#include <dns/messagerenderer.h>
|
#include <dns/messagerenderer.h>
|
||||||
#include <dns/rrclass.h>
|
#include <dns/rrclass.h>
|
||||||
#include <dns/rrttl.h>
|
#include <dns/rrttl.h>
|
||||||
#include <dns/tsigrecord.h>
|
#include <dns/tsigrecord.h>
|
||||||
|
|
||||||
using namespace isc::util;
|
using namespace isc::util;
|
||||||
|
using namespace isc::dns::rdata;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Internally used constants:
|
// Internally used constants:
|
||||||
|
|
||||||
// Size in octets for the RR type, class TTL fields.
|
// Size in octets for the RR type, class TTL, RDLEN fields.
|
||||||
const size_t RR_COMMON_LEN = 8;
|
const size_t RR_COMMON_LEN = 10;
|
||||||
|
|
||||||
// Size in octets for the fixed part of TSIG RDATAs.
|
// Size in octets for the fixed part of TSIG RDATAs.
|
||||||
// - Time Signed (6)
|
// - Time Signed (6)
|
||||||
@@ -50,11 +52,45 @@ TSIGRecord::TSIGRecord(const Name& key_name,
|
|||||||
rdata_.getMACSize() + rdata_.getOtherLen())
|
rdata_.getMACSize() + rdata_.getOtherLen())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// This is a straightforward wrapper of dynamic_cast<const any::TSIG&>.
|
||||||
|
// We use this so that we can throw the DNSMessageFORMERR exception when
|
||||||
|
// unexpected type of RDATA is detected in the member initialization list
|
||||||
|
// of the constructor below.
|
||||||
|
const any::TSIG&
|
||||||
|
castToTSIGRdata(const rdata::Rdata& rdata) {
|
||||||
|
try {
|
||||||
|
return (dynamic_cast<const any::TSIG&>(rdata));
|
||||||
|
} catch (std::bad_cast&) {
|
||||||
|
isc_throw(DNSMessageFORMERR,
|
||||||
|
"TSIG record is being constructed from "
|
||||||
|
"incompatible RDATA:" << rdata.toText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TSIGRecord::TSIGRecord(const Name& name, const RRClass& rrclass,
|
||||||
|
const RRTTL&, // we ignore TTL
|
||||||
|
const rdata::Rdata& rdata,
|
||||||
|
size_t length) :
|
||||||
|
key_name_(name), rdata_(castToTSIGRdata(rdata)), length_(length)
|
||||||
|
{
|
||||||
|
if (rrclass != getClass()) {
|
||||||
|
isc_throw(DNSMessageFORMERR, "Unexpected TSIG RR class: " << rrclass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const RRClass&
|
const RRClass&
|
||||||
TSIGRecord::getClass() {
|
TSIGRecord::getClass() {
|
||||||
return (RRClass::ANY());
|
return (RRClass::ANY());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RRTTL&
|
||||||
|
TSIGRecord::getTTL() {
|
||||||
|
static RRTTL ttl(TSIG_TTL);
|
||||||
|
return (ttl);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template <typename OUTPUT>
|
template <typename OUTPUT>
|
||||||
void
|
void
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include <util/buffer.h>
|
||||||
|
|
||||||
#include <dns/name.h>
|
#include <dns/name.h>
|
||||||
#include <dns/rdataclass.h>
|
#include <dns/rdataclass.h>
|
||||||
|
|
||||||
@@ -65,6 +67,12 @@ public:
|
|||||||
/// RDATA fails
|
/// RDATA fails
|
||||||
TSIGRecord(const Name& key_name, const rdata::any::TSIG& tsig_rdata);
|
TSIGRecord(const Name& key_name, const rdata::any::TSIG& tsig_rdata);
|
||||||
|
|
||||||
|
/// Constructor from resource record (RR) parameters.
|
||||||
|
///
|
||||||
|
/// \exception DNSMessageFORMERR
|
||||||
|
TSIGRecord(const Name& name, const RRClass& rrclass, const RRTTL& ttl,
|
||||||
|
const rdata::Rdata& rdata, size_t length);
|
||||||
|
|
||||||
/// Return the owner name of the TSIG RR, which is the TSIG key name
|
/// Return the owner name of the TSIG RR, which is the TSIG key name
|
||||||
///
|
///
|
||||||
/// \exception None
|
/// \exception None
|
||||||
@@ -87,6 +95,15 @@ public:
|
|||||||
/// \exception None
|
/// \exception None
|
||||||
static const RRClass& getClass();
|
static const RRClass& getClass();
|
||||||
|
|
||||||
|
/// Return the TTL value of TSIG
|
||||||
|
///
|
||||||
|
/// TSIG always uses 0 TTL. This static method returns it,
|
||||||
|
/// when, though unlikely, an application wants to know the TTL TSIG
|
||||||
|
/// is supposed to use.
|
||||||
|
///
|
||||||
|
/// \exception None
|
||||||
|
static const RRTTL& getTTL();
|
||||||
|
|
||||||
/// Return the length of the TSIG record
|
/// Return the length of the TSIG record
|
||||||
///
|
///
|
||||||
/// When constructed from the key name and RDATA, it is the length of
|
/// When constructed from the key name and RDATA, it is the length of
|
||||||
|
Reference in New Issue
Block a user