summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/tsig.cc
diff options
context:
space:
mode:
authorJINMEI Tatuya <jinmei@isc.org>2011-04-27 08:17:42 +0200
committerJINMEI Tatuya <jinmei@isc.org>2011-04-27 08:17:42 +0200
commitf4ad75548592b2f3eeae22de5685cacbf5c82bae (patch)
treec191b4599b3b557071fedbca15fb81c60b6e3722 /src/lib/dns/tsig.cc
parent[trac812] reject NULL or len=0 data (diff)
downloadkea-f4ad75548592b2f3eeae22de5685cacbf5c82bae.tar.xz
kea-f4ad75548592b2f3eeae22de5685cacbf5c82bae.zip
[trac812] ensure TSIGContext::sign() provides strong exception guarantee
added new test for that. with some other cleanups.
Diffstat (limited to 'src/lib/dns/tsig.cc')
-rw-r--r--src/lib/dns/tsig.cc51
1 files changed, 13 insertions, 38 deletions
diff --git a/src/lib/dns/tsig.cc b/src/lib/dns/tsig.cc
index 3a51f03a7c..6e24eb67d6 100644
--- a/src/lib/dns/tsig.cc
+++ b/src/lib/dns/tsig.cc
@@ -19,7 +19,6 @@
#include <cassert> // for the tentative verifyTentative()
#include <vector>
-#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
@@ -67,6 +66,12 @@ gettimeofdayWrapper() {
namespace {
typedef boost::shared_ptr<HMAC> HMACPtr;
+}
+
+const RRClass&
+TSIGRecord::getClass() {
+ return (RRClass::ANY());
+}
struct TSIGContext::TSIGContextImpl {
TSIGContextImpl(const TSIGKey& key) :
@@ -79,12 +84,6 @@ struct TSIGContext::TSIGContextImpl {
TSIGError error_;
uint64_t previous_timesigned_; // only meaningful for response with BADTIME
};
-}
-
-const RRClass&
-TSIGRecord::getClass() {
- return (RRClass::ANY());
-}
TSIGContext::TSIGContext(const TSIGKey& key) : impl_(new TSIGContextImpl(key))
{
@@ -123,12 +122,12 @@ TSIGContext::sign(const uint16_t qid, const void* const data,
// For errors related to key or MAC, return an unsigned response as
// specified in Section 4.3 of RFC2845.
if (error == TSIGError::BAD_SIG() || error == TSIGError::BAD_KEY()) {
- impl_->previous_digest_.clear();
- impl_->state_ = SIGNED;
ConstTSIGRecordPtr tsig(new TSIGRecord(
any::TSIG(impl_->key_.getAlgorithmName(),
now, DEFAULT_FUDGE, NULL, 0,
qid, error.getCode(), 0, NULL)));
+ impl_->previous_digest_.clear();
+ impl_->state_ = SIGNED;
return (tsig);
}
@@ -191,16 +190,17 @@ TSIGContext::sign(const uint16_t qid, const void* const data,
const uint16_t otherlen = variables.getLength();
// Get the final digest, update internal state, then finish.
- impl_->previous_digest_ = hmac->sign();
- impl_->state_ = SIGNED;
+ vector<uint8_t> digest = hmac->sign();
ConstTSIGRecordPtr tsig(new TSIGRecord(
any::TSIG(impl_->key_.getAlgorithmName(),
time_signed, DEFAULT_FUDGE,
- impl_->previous_digest_.size(),
- &impl_->previous_digest_[0],
+ digest.size(), &digest[0],
qid, error.getCode(), otherlen,
otherlen == 0 ?
NULL : variables.getData())));
+ // Exception free from now on.
+ impl_->previous_digest_.swap(digest);
+ impl_->state_ = SIGNED;
return (tsig);
}
@@ -222,30 +222,5 @@ TSIGContext::verifyTentative(ConstTSIGRecordPtr tsig, TSIGError error) {
impl_->state_ = CHECKED;
}
-
-namespace {
-const char* const tsigerror_text[] = {
- "BADSIG",
- "BADKEY",
- "BADTIME"
-};
-}
-
-TSIGError::TSIGError(Rcode rcode) : code_(rcode.getCode()) {
- if (code_ > MAX_RCODE_FOR_TSIGERROR) {
- isc_throw(OutOfRange, "Invalid RCODE for TSIG Error: " << rcode);
- }
-}
-
-string
-TSIGError::toText() const {
- if (code_ <= MAX_RCODE_FOR_TSIGERROR) {
- return (Rcode(code_).toText());
- } else if (code_ <= BAD_TIME_CODE) {
- return (tsigerror_text[code_ - (MAX_RCODE_FOR_TSIGERROR + 1)]);
- } else {
- return (boost::lexical_cast<string>(code_));
- }
-}
} // namespace dns
} // namespace isc