31const size_t DEFAULT_BUFFER_SIZE = 8192;
35using namespace isc::asiolink;
36using namespace isc::asiodns;
37using namespace isc::dns;
38using namespace isc::dns::rdata;
39using namespace isc::dns::rdata::generic;
40using namespace isc::log;
41using namespace isc::stats;
42using namespace isc::util;
49 return (
"response received and is ok");
51 return (
"no response, timeout");
53 return (
"IO was stopped");
55 return (
"response received but invalid");
57 return (
"response received but not signed");
59 return (
"bad client credentials");
61 return (
"other, unclassified error");
96 uint32_t timeout, OM_uint32 flags);
119 return (io_service_);
126 io_service_ = io_service;
145 void acquireCredentials();
167 void incrStats(
const string& stat);
211 uint32_t timeout, OM_uint32 flags)
212 : io_service_(io_service), state_(
NONE), in_buf_(), out_buf_(),
213 callback_(callback), server_(server), key_(key), flags_(flags), cred_(),
214 msg_(), timeout_(timeout) {
218 if (key->getSecCtx().get() != GSS_C_NO_CONTEXT) {
219 isc_throw(BadValue,
"wrong security context state");
236 intoken = readTKey(out_buf_);
237 if (!intoken || intoken->empty()) {
239 incrStats(
"tkey-error");
245 doExchangeInternal(intoken);
251 incrStats(
"tkey-timeout");
257 incrStats(
"tkey-error");
264 incrStats(
"tkey-error");
271TKeyExchangeImpl::acquireCredentials() {
272 const string& cred_princ = server_->getClientPrincipal();
273 if (cred_princ.empty()) {
277 OM_uint32 lifetime(0);
278 GssApiName cname(cred_princ);
279 cred_.reset(
new GssApiCred(cname, GSS_C_INITIATE, lifetime));
281 isc_throw(GssCredExpired,
"credentials expired for " << cred_princ);
286TKeyExchangeImpl::verifyTKey() {
288 const TSIGRecord* tsig = msg_->getTSIGRecord();
295 TSIGError
error = tkey_ctx->verify(tsig, out_buf_->getData(),
296 out_buf_->getLength());
317 msg_->addQuestion(Question(key_->getKeyName(),
RRClass::ANY(),
323 Name algorithm(
"gss-tsig.");
324 uint32_t inception = key_->getInception32();
325 uint32_t expire = key_->getExpire32();
328 size_t key_length = outtoken->getLength();
329 if (key_length > std::numeric_limits<uint16_t>::max()) {
330 isc_throw(BadValue,
"TKEY value too long: " << key_length);
332 uint16_t key_len =
static_cast<uint16_t
>(key_length);
333 ConstRdataPtr tkey_rdata(
new TKEY(algorithm, inception, expire, mode, error,
334 key_len, outtoken->getValue(), 0, 0));
335 tkey_rrset->addRdata(tkey_rdata);
339 MessageRenderer renderer;
340 in_buf_.reset(
new OutputBuffer(DEFAULT_BUFFER_SIZE));
343 msg_->toWire(renderer);
351 (*callback_)(status);
362 GssApiName named_gname(server_->getServerPrincipal());
365 OM_uint32 lifetime(0);
368 ret = key_->getSecCtx().init(cred_, named_gname, flags_, *intoken,
369 *outtoken, lifetime);
370 }
catch (
const isc::Exception& ex) {
373 incrStats(
"tkey-error");
379 if (!outtoken->empty()) {
386 lifetime = key_->getSecCtx().getLifetime();
387 if (lifetime < server_->getKeyLifetime()) {
389 msg <<
"too short credential lifetime: " << lifetime
390 <<
" < " << server_->getKeyLifetime();
393 incrStats(
"tkey-error");
398 .arg(key_->getSecCtx().getLifetime());
401 incrStats(
"tkey-success");
404 incrStats(
"tkey-error");
411 if (outtoken->empty()) {
413 incrStats(
"tkey-error");
418 createTKeyRequest(outtoken);
420 .arg(in_buf_->getLength());
421 incrStats(
"tkey-sent");
424 IOAddress io_addr = server_->getIpAddress();
425 out_buf_.reset(
new OutputBuffer(DEFAULT_BUFFER_SIZE));
428 io_fetch_.reset(
new IOFetch(server_->getKeyProto(), io_service_, in_buf_,
429 io_addr, server_->getPort(), out_buf_,
430 this,
static_cast<int>(timeout_)));
431 io_service_->post(*io_fetch_);
436 if (state_ !=
NONE) {
444 acquireCredentials();
448 incrStats(
"tkey-error");
454 doExchangeInternal(intoken);
468 size_t msg_len = outbuf->getLength();
473 const void* msg_buf = outbuf->getData();
484 msg_->fromWire(recv_buf);
492 .arg(msg_->getRcode().toText());
497 .arg(msg_->getOpcode());
513 .arg(rrset->getClass().toText());
517 .arg(rrset->getType().toText());
520 if (rrset->getTTL() != RRTTL(0)) {
522 .arg(rrset->getTTL().toText());
524 if (rrset->getRdataCount() != 1) {
526 .arg(rrset->getRdataCount());
527 if (rrset->getRdataCount() == 0) {
532 auto rdata_it = rrset->getRdataIterator();
533 const TKEY& tkey =
dynamic_cast<const TKEY&
>(rdata_it->getCurrent());
543TKeyExchangeImpl::incrStats(
const string& stat) {
545 mgr.addValue(stat,
static_cast<int64_t
>(1));
548 static_cast<int64_t
>(1));
557 Callback* callback, uint32_t timeout, OM_uint32 flags)
558 : impl_(new
TKeyExchangeImpl(io_service, server, key, callback, timeout, flags)) {
577 return (impl_->getIOService());
582 impl_->setIOService(io_service);
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
static std::string const & resultToText(Result const &result)
Convert enum to string.
Result
Result of Upstream Fetch.
void setBuffer(isc::util::OutputBuffer *buffer)
Set or reset a temporary output buffer.
virtual void setLengthLimit(size_t len)
Set the maximum length of rendered data that can fit in the corresponding DNS message without truncat...
The Message class encapsulates a standard DNS message.
static const Opcode & QUERY()
A constant object for the QUERY Opcode.
static const RRClass & ANY()
static const RRType & TKEY()
static const Rcode & NOERROR()
A constant object for the NOERROR Rcode (see Rcode::NOERROR_CODE).
@ NOERROR_CODE
0: No error (RFC1035)
uint16_t getCode() const
Returns the Rcode code value.
@ SENT_REQUEST
Client sent a signed request, waiting response.
static const TSIGError & NOERROR()
A constant TSIG error object derived from Rcode::NOERROR().
static const uint16_t GSS_API_MODE
The GSS_API constant for the Mode field.
const void * getKey() const
Return the value of the Key field.
uint16_t getError() const
Return the value of the Error field.
uint16_t getKeyLen() const
Return the value of the Key Len field.
TKeyExchangeImpl(const IOServicePtr &io_service, const DnsServerPtr &server, const GssTsigKeyPtr &key, TKeyExchange::Callback *callback, uint32_t timeout, OM_uint32 flags)
Constructor.
void setIOService(const isc::asiolink::IOServicePtr &io_service)
Sets IO service.
isc::asiolink::IOServicePtr getIOService()
Gets IO service.
State
The TKEY exchange state.
@ FAILURE
The TKEY exchange has failed.
@ STARTED
The TKEY exchange has been started.
@ SUCCESS
The TKEY exchange has succeeded.
@ STOPPED
The TKEY exchange has been canceled.
@ NONE
Initial state: no action has been initiated.
void cancel()
This function cancels the started TKEY exchange.
virtual void operator()(IOFetch::Result result)
This internal callback is called when the DNS update message exchange is complete.
void doExchange()
This function handles the repeated communication with the DNS server trying to complete the TKEY exch...
virtual ~TKeyExchangeImpl()
Destructor.
Callback for the TKeyExchange class.
void cancel()
This function cancels the in-flight TKEY exchange.
static std::string statusToText(Status status)
Convert a status to its textual form.
TKeyExchange(const isc::asiolink::IOServicePtr &io_service, const DnsServerPtr &server, const GssTsigKeyPtr &key, Callback *callback, uint32_t timeout=TKEY_EXCHANGE_IO_TIMEOUT, OM_uint32 flags=TKEY_EXCHANGE_FLAGS)
Constructor.
isc::asiolink::IOServicePtr getIOService()
Gets IO service.
void doExchange()
This function handles the repeated communication with the DNS server trying to complete the TKEY exch...
void setIOService(const isc::asiolink::IOServicePtr io_service)
Sets IO service.
static const uint32_t TKEY_EXCHANGE_IO_TIMEOUT
The default IO timeout used for IO operations (in milliseconds) set to 3000 (3 seconds).
Status
A status code of the TKeyExchange.
@ SUCCESS
Response received and is ok.
@ BAD_CREDENTIALS
Bad client credentials.
@ IO_STOPPED
IO was stopped.
@ UNSIGNED_RESPONSE
Response received but not signed.
@ INVALID_RESPONSE
Response received but invalid.
@ TIMEOUT
No response, timeout.
@ OTHER
Other, unclassified error.
static const OM_uint32 TKEY_EXCHANGE_FLAGS
The default TKEY exchange flags.
virtual ~TKeyExchange()
Virtual destructor, does nothing.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
Defines a State within the State Model.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Implements a TSIGContext derived class which can be used as the value of TSIGContext pointers so with...
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< IOFetch > IOFetchPtr
Defines a pointer to an IOFetch.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
boost::shared_ptr< const Rdata > ConstRdataPtr
boost::shared_ptr< AbstractRRset > RRsetPtr
A pointer-like type pointing to an RRset object.
boost::shared_ptr< Message > MessagePtr
Pointer-like type pointing to a Message.
const isc::log::MessageID TKEY_EXCHANGE_FAIL_NO_RDATA
const isc::log::MessageID TKEY_EXCHANGE_IO_FETCH_RESULT
const isc::log::MessageID TKEY_EXCHANGE_FAIL_NOT_SIGNED
const isc::log::MessageID TKEY_EXCHANGE_FAIL_NO_RESPONSE_ANSWER
const isc::log::MessageID TKEY_EXCHANGE_RECEIVE_MESSAGE
const isc::log::MessageID TKEY_EXCHANGE_RDATA_COUNT
const isc::log::MessageID TKEY_EXCHANGE_FAIL_RESPONSE_ERROR
const isc::log::MessageID TKEY_EXCHANGE_FAIL_EMPTY_RESPONSE
boost::shared_ptr< DnsServer > DnsServerPtr
A pointer to a DNS server.
const isc::log::MessageID TKEY_EXCHANGE_FAILED_TO_VERIFY
const isc::log::MessageID TKEY_EXCHANGE_RESPONSE_TTL
const isc::log::MessageID TKEY_EXCHANGE_VERIFIED
const isc::log::MessageID TKEY_EXCHANGE_NOT_A_RESPONSE
const isc::log::MessageID TKEY_EXCHANGE_FAIL_WRONG_RESPONSE_OPCODE
const isc::log::MessageID TKEY_EXCHANGE_FAIL_IO_ERROR
const isc::log::MessageID TKEY_EXCHANGE_FAIL_EMPTY_IN_TOKEN
boost::shared_ptr< GssApiBuffer > GssApiBufferPtr
Shared pointer to GSS-API buffer.
const isc::log::MessageID TKEY_EXCHANGE_FAIL_EMPTY_OUT_TOKEN
const isc::log::MessageID TKEY_EXCHANGE_FAIL_NULL_RESPONSE
const isc::log::MessageID TKEY_EXCHANGE_OUT_TOKEN_NOT_EMPTY
const isc::log::MessageID TKEY_EXCHANGE_FAIL_IO_STOPPED
boost::shared_ptr< GssTsigContext > GssTsigContextPtr
Type of pointer to a GSS-TSIG context.
const isc::log::MessageID TKEY_EXCHANGE_SEND_MESSAGE
const isc::log::MessageID TKEY_EXCHANGE_FAIL_WRONG_RESPONSE_ANSWER_COUNT
const isc::log::MessageID TKEY_EXCHANGE_FAIL_TKEY_ERROR
const isc::log::MessageID TKEY_EXCHANGE_FAIL_TO_INIT
const isc::log::MessageID TKEY_EXCHANGE_ANSWER_CLASS
const isc::log::MessageID TKEY_EXCHANGE_FAIL_WRONG_RESPONSE_ANSWER_TYPE
isc::log::Logger gss_tsig_logger("gss-tsig-hooks")
const isc::log::MessageID TKEY_EXCHANGE_VALID
const isc::log::MessageID BAD_CLIENT_CREDENTIALS
boost::shared_ptr< GssApiCred > GssApiCredPtr
Shared pointer to GSS-API credential.
boost::shared_ptr< GssTsigKey > GssTsigKeyPtr
Type of pointer to a GSS-TSIG key.
const isc::log::MessageID TKEY_EXCHANGE_FAIL_IO_TIMEOUT
const int DBGLVL_TRACE_BASIC
Trace basic operations.
PerfMonMgrPtr mgr
PerfMonMgr singleton.
boost::shared_ptr< OutputBuffer > OutputBufferPtr
Type of pointers to output buffers.
Defines the logger used by the top-level component of kea-lfc.