From: Francis Dupont Date: Tue, 3 Mar 2026 10:59:45 +0000 (+0100) Subject: [#4326] Checkpoint: code done, need UT & doc X-Git-Tag: Kea-3.1.9~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1786bbebbef337922b563592f21da99328936e2d;p=thirdparty%2Fkea.git [#4326] Checkpoint: code done, need UT & doc --- diff --git a/src/hooks/d2/gss_tsig/gss_tsig_api.cc b/src/hooks/d2/gss_tsig/gss_tsig_api.cc index c304da20bc..662289c852 100644 --- a/src/hooks/d2/gss_tsig/gss_tsig_api.cc +++ b/src/hooks/d2/gss_tsig/gss_tsig_api.cc @@ -266,6 +266,8 @@ GssApiCred::inquire(GssApiName& name, gss_cred_usage_t& cred_usage, } } +bool GssApiSecCtx::ignore_bad_direction_ = false; + GssApiSecCtx::GssApiSecCtx(gss_ctx_id_t sec_ctx) : GssApiLastError(), sec_ctx_(sec_ctx) { } @@ -357,9 +359,20 @@ GssApiSecCtx::verify(GssApiBuffer& gmessage, GssApiBuffer& gsig) { OM_uint32 major = gss_verify_mic(&minor, sec_ctx_, gmessage.getPtr(), gsig.getPtr(), 0); if (major != GSS_S_COMPLETE) { + string err_msg = gssApiErrMsg(major, minor); + // Should use minor == G_BAD_DIRECTION but the code point is + // in a generated include not provided by all packages. + if (ignore_bad_direction_ && (major == GSS_S_BAD_MIC) && +#ifdef G_BAD_DIRECTION + (minor == G_BAD_DIRECTION) +#else + (err_msg.find("wrong direction") != string::npos) +#endif + ) { + return; + } setLastError(major); - isc_throw(GssApiError, "gss_verify_mic failed with " - << gssApiErrMsg(major, minor)); + isc_throw(GssApiError, "gss_verify_mic failed with " << err_msg); } } diff --git a/src/hooks/d2/gss_tsig/gss_tsig_api.h b/src/hooks/d2/gss_tsig/gss_tsig_api.h index 259e4755d4..b730d8d005 100644 --- a/src/hooks/d2/gss_tsig/gss_tsig_api.h +++ b/src/hooks/d2/gss_tsig/gss_tsig_api.h @@ -289,6 +289,13 @@ typedef boost::shared_ptr GssApiCredPtr; /// @note: some methods should be const but this does not match the API. class GssApiSecCtx : public boost::noncopyable, public GssApiLastError { public: + /// @brief Ignore bad direction flag. + /// + /// @note: when true (default is false) verify accepts + /// messages sent in the wrong direction as Microsoft servers + /// sending DNS update responses when prerequisities fail. + static bool ignore_bad_direction_; + /// @brief Constructor. /// /// @param sec_ctx The GSS-API security context. diff --git a/src/hooks/d2/gss_tsig/gss_tsig_cfg.cc b/src/hooks/d2/gss_tsig/gss_tsig_cfg.cc index d3113a0a7e..4969b9885c 100644 --- a/src/hooks/d2/gss_tsig/gss_tsig_cfg.cc +++ b/src/hooks/d2/gss_tsig/gss_tsig_cfg.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -285,26 +286,27 @@ DnsServer::toElement() const { } const SimpleKeywords GssTsigCfg::GLOBAL_PARAMETERS = { - { "server-principal", Element::string }, - { "client-principal", Element::string }, - { "client-keytab", Element::string }, - { "credentials-cache", Element::string }, - { "gss-replay-flag", Element::boolean }, - { "gss-sequence-flag", Element::boolean }, - { "tkey-lifetime", Element::integer }, - { "rekey-interval", Element::integer }, - { "retry-interval", Element::integer }, - { "tkey-protocol", Element::string }, - { "fallback", Element::boolean }, - { "exchange-timeout", Element::integer }, - { "servers", Element::list }, - { "user-context", Element::map }, - { "comment", Element::string } + { "server-principal", Element::string }, + { "client-principal", Element::string }, + { "client-keytab", Element::string }, + { "credentials-cache", Element::string }, + { "gss-replay-flag", Element::boolean }, + { "gss-sequence-flag", Element::boolean }, + { "tkey-lifetime", Element::integer }, + { "rekey-interval", Element::integer }, + { "retry-interval", Element::integer }, + { "tkey-protocol", Element::string }, + { "fallback", Element::boolean }, + { "exchange-timeout", Element::integer }, + { "ignore-bad-direction", Element::boolean }, + { "servers", Element::list }, + { "user-context", Element::map }, + { "comment", Element::string } }; GssTsigCfg::GssTsigCfg() : servers_(), servers_rev_map_(), client_keytab_(""), creds_cache_(""), - max_tkey_lifetime_(0) { + max_tkey_lifetime_(0), ignore_bad_direction_(false) { } GssTsigCfg::~GssTsigCfg() { @@ -463,6 +465,13 @@ GssTsigCfg::configure(ConstElementPtr params) { } } + ConstElementPtr ignore_bad_direction = params->get("ignore-bad-direction"); + if (ignore_bad_direction) { + bool val = ignore_bad_direction->boolValue(); + ignore_bad_direction_ = val; + GssApiSecCtx::ignore_bad_direction_ = val; + } + ConstElementPtr servers = params->get("servers"); if (!servers) { return; diff --git a/src/hooks/d2/gss_tsig/gss_tsig_cfg.h b/src/hooks/d2/gss_tsig/gss_tsig_cfg.h index 220bb0a58a..965c864767 100644 --- a/src/hooks/d2/gss_tsig/gss_tsig_cfg.h +++ b/src/hooks/d2/gss_tsig/gss_tsig_cfg.h @@ -532,6 +532,20 @@ public: max_tkey_lifetime_ = max_tkey_lifetime; } + /// @brief Get the ignore bad direction flag. + /// + /// @return the ignore bad direction flag. + bool getIgnoreBadDirection() const { + return (ignore_bad_direction_); + } + + /// @brief Set the ignore bad direction flag. + /// + /// @param ignore_bad_direction A new ignore bad direction. + void setIgnoreBadDirection(bool ignore_bad_direction) { + ignore_bad_direction_ = ignore_bad_direction; + } + private: /// @brief The DNS server list. DnsServerList servers_; @@ -547,6 +561,9 @@ private: /// @brief The maximum TKEY lifetime. uint32_t max_tkey_lifetime_; + + /// @brief The ignore bad direction flag. + bool ignore_bad_direction_; }; } // end of namespace isc::gss_tsig diff --git a/src/hooks/d2/gss_tsig/gss_tsig_context.h b/src/hooks/d2/gss_tsig/gss_tsig_context.h index 6761a48b0c..9b50cc26e6 100644 --- a/src/hooks/d2/gss_tsig/gss_tsig_context.h +++ b/src/hooks/d2/gss_tsig/gss_tsig_context.h @@ -70,7 +70,7 @@ public: sign(const uint16_t qid, const void* const data, const size_t data_len) override; - /// @brief a DNS message. + /// @brief Verify a DNS message. /// /// See @c isc::dns::TSIGContext::verify(). ///