1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (C) 2011-2024 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 <config.h>

#include <vector><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <sstream><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <gtest/gtest.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <util/buffer.h>

#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/tsig.h>
#include <dns/tsigkey.h>
#include <dns/tsigrecord.h>

#include <dns/tests/unittest_util.h>
#include <util/unittests/wiredata.h>

using namespace std;
using namespace isc::util;
using namespace isc::dns;
using namespace isc::dns::rdata;
using namespace isc::dns::rdata::any;
using isc::UnitTestUtil;
using isc::util::unittests::matchWireData;

namespace {
class TSIGRecordTest : public ::testing::Test {
protected:
    TSIGRecordTest() :
        test_name("www.example.com"), test_mac(16, 0xda),
        test_rdata(TSIG(TSIGKey::HMACMD5_NAME(), 0x4da8877a, TSIGContext::DEFAULT_FUDGE,
                        test_mac.size(), &test_mac[0], 0x2d65, 0, 0, 0)),
        test_record(test_name, test_rdata),
        buffer(0) {
    }

    const Name test_name;

    vector<unsigned char> test_mac;

    const TSIG test_rdata;

    const TSIGRecord test_record;

    OutputBuffer buffer;

    MessageRenderer renderer;

    vector<unsigned char> data;
};

TEST_F(TSIGRecordTest, getName) {<--- syntax error
    EXPECT_EQ(test_name, test_record.getName());
}

TEST_F(TSIGRecordTest, getLength) {
    // 85 = 17 + 26 + 16 + 26
    // len(www.example.com) = 17
    // len(hmac-md5.sig-alg.reg.int) = 26
    // len(MAC) = 16
    // the rest are fixed length fields (26 in total)
    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
    EXPECT_THROW(TSIGRecord(test_name, TSIGRecord::getClass(),
                            RRTTL(3600), test_rdata, 85), DNSMessageFORMERR);
}

TEST_F(TSIGRecordTest, recordToWire) {
    UnitTestUtil::readWireData("tsigrecord_toWire1.wire", data);
    EXPECT_EQ(1, test_record.toWire(renderer));
    matchWireData(&data[0], data.size(),
                  renderer.getData(), renderer.getLength());

    // Same test for a dumb buffer
    buffer.clear();
    EXPECT_EQ(1, test_record.toWire(buffer));
    matchWireData(&data[0], data.size(),
                  buffer.getData(), buffer.getLength());
}

TEST_F(TSIGRecordTest, recordToOLongToWire) {
    // By setting the limit to "record length - 1", it will fail, and the
    // renderer will be marked as "truncated".
    renderer.setLengthLimit(test_record.getLength() - 1);
    EXPECT_FALSE(renderer.isTruncated()); // not marked before render attempt
    EXPECT_EQ(0, test_record.toWire(renderer));
    EXPECT_TRUE(renderer.isTruncated());
}

TEST_F(TSIGRecordTest, recordToWireAfterNames) {
    // A similar test but the TSIG RR follows some domain names that could
    // cause name compression inside TSIG.  Our implementation shouldn't
    // compress either owner (key) name or the algorithm name.  This test
    // confirms that.

    UnitTestUtil::readWireData("tsigrecord_toWire2.wire", data);
    renderer.writeName(TSIGKey::HMACMD5_NAME());
    renderer.writeName(Name("foo.example.com"));
    EXPECT_EQ(1, test_record.toWire(renderer));
    matchWireData(&data[0], data.size(),
                  renderer.getData(), renderer.getLength());
}

TEST_F(TSIGRecordTest, toText) {
    EXPECT_EQ("www.example.com. 0 ANY TSIG hmac-md5.sig-alg.reg.int. "
              "1302890362 300 16 2tra2tra2tra2tra2tra2g== 11621 NOERROR 0\n",
              test_record.toText());
}

// test operator<<.  We simply confirm it appends the result of toText().
TEST_F(TSIGRecordTest, LeftShiftOperator) {
    ostringstream oss;
    oss << test_record;
    EXPECT_EQ(test_record.toText(), oss.str());
}
} // end namespace