29const size_t DEFAULT_BUFFER_SIZE = 4096;
33using namespace isc::asiolink;
34using namespace isc::asiodns;
35using namespace isc::dns;
36using namespace isc::dns::rdata;
37using namespace isc::dns::rdata::generic;
38using namespace isc::log;
39using namespace isc::stats;
40using namespace isc::util;
47 return (
"response received and is ok");
49 return (
"no response, timeout");
51 return (
"IO was stopped");
53 return (
"response received but invalid");
55 return (
"response received but not signed");
57 return (
"bad client credentials");
59 return (
"other, unclassified error");
94 uint32_t timeout, OM_uint32 flags);
117 return (io_service_);
124 io_service_ = io_service;
143 void acquireCredentials();
165 void incrStats(
const string& stat);
209 uint32_t timeout, OM_uint32 flags)
210 : io_service_(io_service), state_(
NONE), in_buf_(), out_buf_(),
211 callback_(callback), server_(server), key_(key), flags_(flags), cred_(),
212 msg_(), timeout_(timeout) {
216 if (key->getSecCtx().get() != GSS_C_NO_CONTEXT) {
217 isc_throw(BadValue,
"wrong security context state");
232 intoken = readTKey(out_buf_);
233 if (!intoken || intoken->empty()) {
235 incrStats(
"tkey-error");
241 doExchangeInternal(intoken);
247 incrStats(
"tkey-timeout");
253 incrStats(
"tkey-error");
260 incrStats(
"tkey-error");
267TKeyExchangeImpl::acquireCredentials() {
268 const string& cred_princ = server_->getClientPrincipal();
269 if (cred_princ.empty()) {
273 OM_uint32 lifetime(0);
274 GssApiName cname(cred_princ);
275 cred_.reset(
new GssApiCred(cname, GSS_C_INITIATE, lifetime));
277 isc_throw(GssCredExpired,
"credentials expired for " << cred_princ);
282TKeyExchangeImpl::verifyTKey() {
284 const TSIGRecord* tsig = msg_->getTSIGRecord();
291 TSIGError
error = tkey_ctx->verify(tsig, out_buf_->getData(),
292 out_buf_->getLength());
313 msg_->addQuestion(Question(key_->getKeyName(),
RRClass::ANY(),
319 Name algorithm(
"gss-tsig.");
320 uint32_t inception = key_->getInception32();
321 uint32_t expire = key_->getExpire32();
324 size_t key_length = outtoken->getLength();
325 if (key_length > std::numeric_limits<uint16_t>::max()) {
326 isc_throw(BadValue,
"TKEY value too long: " << key_length);
328 uint16_t key_len =
static_cast<uint16_t
>(key_length);
329 ConstRdataPtr tkey_rdata(
new TKEY(algorithm, inception, expire, mode, error,
330 key_len, outtoken->getValue(), 0, 0));
331 tkey_rrset->addRdata(tkey_rdata);
335 MessageRenderer renderer;
336 in_buf_.reset(
new OutputBuffer(DEFAULT_BUFFER_SIZE));
339 msg_->toWire(renderer);
347 (*callback_)(status);
358 GssApiName named_gname(server_->getServerPrincipal());
361 OM_uint32 lifetime(0);
364 ret = key_->getSecCtx().init(cred_, named_gname, flags_, *intoken,
365 *outtoken, lifetime);
366 }
catch (
const isc::Exception& ex) {
369 incrStats(
"tkey-error");
375 if (!outtoken->empty()) {
382 lifetime = key_->getSecCtx().getLifetime();
383 if (lifetime < server_->getKeyLifetime()) {
385 msg <<
"too short credential lifetime: " << lifetime
386 <<
" < " << server_->getKeyLifetime();
389 incrStats(
"tkey-error");
394 .arg(key_->getSecCtx().getLifetime());
397 incrStats(
"tkey-success");
400 incrStats(
"tkey-error");
407 if (outtoken->empty()) {
409 incrStats(
"tkey-error");
414 createTKeyRequest(outtoken);
416 .arg(in_buf_->getLength());
417 incrStats(
"tkey-sent");
420 IOAddress io_addr = server_->getIpAddress();
421 out_buf_.reset(
new OutputBuffer(DEFAULT_BUFFER_SIZE));
424 io_fetch_.reset(
new IOFetch(server_->getKeyProto(), io_service_, in_buf_,
425 io_addr, server_->getPort(), out_buf_,
426 this,
static_cast<int>(timeout_)));
427 io_service_->post(*io_fetch_);
432 if (state_ !=
NONE) {
440 acquireCredentials();
444 incrStats(
"tkey-error");
450 doExchangeInternal(intoken);
464 size_t msg_len = outbuf->getLength();
469 const void* msg_buf = outbuf->getData();
480 msg_->fromWire(recv_buf);
488 .arg(msg_->getRcode().toText());
493 .arg(msg_->getOpcode());
509 .arg(rrset->getClass().toText());
513 .arg(rrset->getType().toText());
516 if (rrset->getTTL() != RRTTL(0)) {
518 .arg(rrset->getTTL().toText());
520 if (rrset->getRdataCount() != 1) {
522 .arg(rrset->getRdataCount());
523 if (rrset->getRdataCount() == 0) {
528 auto rdata_it = rrset->getRdataIterator();
529 const TKEY& tkey =
dynamic_cast<const TKEY&
>(rdata_it->getCurrent());
539TKeyExchangeImpl::incrStats(
const string& stat) {
541 mgr.addValue(stat,
static_cast<int64_t
>(1));
544 static_cast<int64_t
>(1));
553 Callback* callback, uint32_t timeout, OM_uint32 flags)
554 : impl_(new
TKeyExchangeImpl(io_service, server, key, callback, timeout, flags)) {
573 return (impl_->getIOService());
578 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.
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).
uint16_t getCode() const
Returns the Rcode code value.
@ NOERROR_CODE
0: No error (RFC1035)
@ 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.
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.
isc::asiolink::IOServicePtr getIOService()
Gets IO service.
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.
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 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).
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_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.