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.