From: Remi Gacogne Date: Mon, 17 Aug 2020 09:29:55 +0000 (+0200) Subject: auth: Remove GSS/TSIG support X-Git-Tag: rec-4.5.0-alpha0~2^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2a4ac94e7bbb5b72ff3907158c9dbd7ba48d606;p=thirdparty%2Fpdns.git auth: Remove GSS/TSIG support --- diff --git a/configure.ac b/configure.ac index 0776153069..88293d1ad0 100644 --- a/configure.ac +++ b/configure.ac @@ -144,7 +144,6 @@ AC_SUBST([LIBDL], [$lt_cv_dlopen_libs]) PDNS_ENABLE_VERBOSE_LOGGING PDNS_ENABLE_PKCS11 -PDNS_ENABLE_GSS_TSIG AC_SUBST([socketdir]) socketdir="/var/run" @@ -398,9 +397,6 @@ AS_IF([test "x$LUAPC" != "x"], AS_IF([test "x$enable_experimental_pkcs11" = "xyes"], [AC_MSG_NOTICE([PKCS-11: yes])] ) -AS_IF([test "x$enable_experimental_gss_tsig" = "xyes"], - [AC_MSG_NOTICE([GSS-TSIG: yes])] -) AS_IF([test "x$enable_lua_records" = "xyes"], [AC_MSG_NOTICE([LUA records: yes])] ) diff --git a/docs/domainmetadata.rst b/docs/domainmetadata.rst index 2e86567fcf..153118187b 100644 --- a/docs/domainmetadata.rst +++ b/docs/domainmetadata.rst @@ -118,6 +118,8 @@ Use this named TSIG key to retrieve this zone from its master, see :ref:`tsig-pr GSS-ALLOW-AXFR-PRINCIPAL ------------------------ + .. versionchanged:: 4.3.1 + GSS support was removed Allow this GSS principal to perform AXFR retrieval. Most commonly it is ``host/something@REALM``, ``DNS/something@REALM`` or ``user@REALM``. @@ -125,6 +127,8 @@ Allow this GSS principal to perform AXFR retrieval. Most commonly it is GSS-ACCEPTOR-PRINCIPAL ---------------------- + .. versionchanged:: 4.3.1 + GSS support was removed Use this principal for accepting GSS context. (See :ref:`tsig-gss-tsig`). diff --git a/docs/tsig.rst b/docs/tsig.rst index 1f7941c89f..b51deed3bb 100644 --- a/docs/tsig.rst +++ b/docs/tsig.rst @@ -119,6 +119,8 @@ the master, not just those about AXFR requests. GSS-TSIG support ---------------- + .. versionchanged:: 4.3.1 + GSS support was removed GSS-TSIG allows authentication and authorization of DNS updates or AXFR using Kerberos with TSIG signatures. diff --git a/m4/pdns_enable_gss_tsig.m4 b/m4/pdns_enable_gss_tsig.m4 deleted file mode 100644 index 9acd756976..0000000000 --- a/m4/pdns_enable_gss_tsig.m4 +++ /dev/null @@ -1,24 +0,0 @@ -AC_DEFUN([PDNS_ENABLE_GSS_TSIG],[ - AC_MSG_CHECKING([whether to enable experimental GSS-TSIG support]) - AC_ARG_ENABLE([experimental_gss_tsig], - AS_HELP_STRING([--enable-experimental-gss-tsig], - [enable experimental GSS-TSIG support @<:@default=no@:>@] - ), - [enable_experimental_gss_tsig=$enableval], - [enable_experimental_gss_tsig=no] - ) - - AC_MSG_RESULT([$enable_experimental_gss_tsig]) - - AM_CONDITIONAL([GSS_TSIG],[test "x$enable_experimental_gss_tsig" != "xno"]) - AC_SUBST(GSS_TSIG) - AS_IF([test "x$enable_experimental_gss_tsig" != "xno"], - [PKG_CHECK_MODULES([GSS], [krb5 krb5-gssapi gss], - [ - AC_DEFINE([ENABLE_GSS_TSIG], [1], [Define to 1 if you want to enable GSS-TSIG support]) - GSS_TSIG=yes - ], - [AC_MSG_ERROR([Required libraries for GSS-TSIG not found])] - )], - [GSS_TSIG=no]) -]) diff --git a/modules/remotebackend/Makefile.am b/modules/remotebackend/Makefile.am index 762df16080..fc120a423f 100644 --- a/modules/remotebackend/Makefile.am +++ b/modules/remotebackend/Makefile.am @@ -123,7 +123,6 @@ libtestremotebackend_la_SOURCES = \ ../../pdns/nameserver.cc \ ../../pdns/rcpgenerator.cc \ ../../pdns/unix_utility.cc \ - ../../pdns/gss_context.cc ../../pdns/gss_context.hh \ ../../pdns/json.hh ../../pdns/json.cc \ ../../pdns/shuffle.hh ../../pdns/shuffle.cc \ httpconnector.cc \ @@ -161,13 +160,6 @@ libtestremotebackend_la_CPPFLAGS += \ $(P11KIT1_CFLAGS) endif -if GSS_TSIG -libtestremotebackend_la_LIBADD += \ - $(GSS_LIBS) -libtestremotebackend_la_CPPFLAGS+= \ - $(GSS_CFLAGS) -endif - remotebackend_http_test_SOURCES = \ test-remotebackend.cc \ test-remotebackend-http.cc \ diff --git a/pdns/Makefile.am b/pdns/Makefile.am index ff2dc1058f..1ac133c636 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -32,10 +32,6 @@ if LUA AM_CPPFLAGS +=$(LUA_CFLAGS) endif -if GSS_TSIG -AM_CPPFLAGS +=$(GSS_CFLAGS) -endif - if LIBSODIUM AM_CPPFLAGS +=$(LIBSODIUM_CFLAGS) endif @@ -184,7 +180,6 @@ pdns_server_SOURCES = \ dynmessenger.hh \ ednsoptions.cc ednsoptions.hh \ ednssubnet.cc ednssubnet.hh \ - gss_context.cc gss_context.hh \ iputils.cc iputils.hh \ ixfr.cc ixfr.hh \ json.cc json.hh \ @@ -279,10 +274,6 @@ if LUA pdns_server_LDADD += $(LUA_LIBS) endif -if GSS_TSIG -pdns_server_LDADD += $(GSS_LIBS) -endif - pdnsutil_SOURCES = \ arguments.cc \ auth-caches.cc auth-caches.hh \ @@ -311,7 +302,6 @@ pdnsutil_SOURCES = \ dynlistener.cc \ ednsoptions.cc ednsoptions.hh \ ednssubnet.cc \ - gss_context.cc gss_context.hh \ ipcipher.cc ipcipher.hh \ iputils.cc iputils.hh \ json.cc \ @@ -378,10 +368,6 @@ if LUA pdnsutil_LDADD += $(LUA_LIBS) endif -if GSS_TSIG -pdnsutil_LDADD += $(GSS_LIBS) -endif - zone2sql_SOURCES = \ arguments.cc \ base32.cc \ @@ -587,7 +573,6 @@ saxfr_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ iputils.cc \ logger.cc \ misc.cc misc.hh \ @@ -608,10 +593,6 @@ saxfr_SOURCES += pkcs11signers.cc pkcs11signers.hh saxfr_LDADD += $(P11KIT1_LIBS) endif -if GSS_TSIG -saxfr_LDADD += $(GSS_LIBS) -endif - ixfrdist_SOURCES = \ arguments.cc \ base32.cc \ @@ -624,7 +605,6 @@ ixfrdist_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ iputils.hh iputils.cc \ ixfr.cc ixfr.hh \ ixfrdist.cc \ @@ -669,11 +649,6 @@ ixfrdist_SOURCES += pkcs11signers.cc pkcs11signers.hh ixfrdist_LDADD += $(P11KIT1_LIBS) endif -if GSS_TSIG -ixfrdist_LDADD += $(GSS_LIBS) -endif - - ixplore_SOURCES = \ arguments.cc \ base32.cc \ @@ -686,7 +661,6 @@ ixplore_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ iputils.cc \ logger.cc \ misc.cc misc.hh \ @@ -713,11 +687,6 @@ ixplore_SOURCES += pkcs11signers.cc pkcs11signers.hh ixplore_LDADD += $(P11KIT1_LIBS) endif -if GSS_TSIG -ixplore_LDADD += $(GSS_LIBS) -endif - - dnstcpbench_SOURCES = \ base32.cc \ base64.cc base64.hh \ @@ -757,7 +726,6 @@ nsec3dig_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ iputils.cc \ logger.cc \ misc.cc misc.hh \ @@ -778,10 +746,6 @@ nsec3dig_SOURCES += pkcs11signers.cc pkcs11signers.hh nsec3dig_LDADD += $(P11KIT1_LIBS) endif -if GSS_TSIG -nsec3dig_LDADD += $(GSS_LIBS) -endif - toysdig_SOURCES = \ base32.cc \ base64.cc base64.hh \ @@ -794,7 +758,6 @@ toysdig_SOURCES = \ dnswriter.cc dnswriter.hh \ ednssubnet.cc ednssubnet.hh \ filterpo.hh \ - gss_context.cc gss_context.hh \ iputils.cc \ logger.cc \ misc.cc misc.hh \ @@ -819,10 +782,6 @@ toysdig_LDFLAGS = $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) toysdig_LDADD = $(LIBCRYPTO_LIBS) -if GSS_TSIG -toysdig_LDADD += $(GSS_LIBS) -endif - if PKCS11 toysdig_SOURCES += pkcs11signers.cc pkcs11signers.hh toysdig_LDADD += $(P11KIT1_LIBS) @@ -842,7 +801,6 @@ tsig_tests_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ iputils.cc \ logger.cc \ misc.cc misc.hh \ @@ -866,10 +824,6 @@ tsig_tests_SOURCES += pkcs11signers.cc pkcs11signers.hh tsig_tests_LDADD += $(P11KIT1_LIBS) endif -if GSS_TSIG -tsig_tests_LDADD += $(GSS_LIBS) -endif - speedtest_SOURCES = \ base32.cc \ base64.cc base64.hh \ @@ -1292,7 +1246,6 @@ testrunner_SOURCES = \ ednscookies.cc ednscookies.hh \ ednssubnet.cc \ gettime.cc gettime.hh \ - gss_context.cc gss_context.hh \ ipcipher.cc ipcipher.hh \ iputils.cc \ ixfr.cc ixfr.hh \ diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index fa193d4834..0c7a63f260 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -48,7 +48,6 @@ #include "dnssecinfra.hh" #include "base64.hh" #include "ednssubnet.hh" -#include "gss_context.hh" #include "dns_random.hh" #include "shuffle.hh" @@ -634,14 +633,12 @@ bool DNSPacket::checkForCorrectTSIG(UeberBackend* B, DNSName* keyname, string* s tt.algo = DNSName("hmac-md5"); string secret64; - if (tt.algo != DNSName("gss-tsig")) { - if(!B->getTSIGKey(*keyname, &tt.algo, &secret64)) { - g_log<qdomain<<"' denied: can't find TSIG key with name '"<<*keyname<<"' and algorithm '"<getTSIGKey(*keyname, &tt.algo, &secret64)) { + g_log<qdomain<<"' denied: can't find TSIG key with name '"<<*keyname<<"' and algorithm '"<(pw.getContent().data()), pw.getContent().size(), tsigkeyname, trc, timersonly); if (algo == TSIG_GSS) { - if (!gss_add_signature(tsigkeyname, toSign, trc.d_mac)) { - throw PDNSException(string("Could not add TSIG signature with algorithm 'gss-tsig' and key name '")+tsigkeyname.toLogString()+string("'")); - } + throw PDNSException(string("Unsupported TSIG GSS algorithm ") + trc.d_algoName.toLogString()); } else { trc.d_mac = calculateHMAC(tsigsecret, toSign, algo); // trc.d_mac[0]++; // sabotage @@ -698,10 +695,7 @@ bool validateTSIG(const std::string& packet, size_t sigPos, const TSIGTriplet& t tsigMsg = makeTSIGMessageFromTSIGPacket(packet, sigPos, tt.name, trc, previousMAC, timersOnly, dnsHeaderOffset); if (algo == TSIG_GSS) { - GssContext gssctx(tt.name); - if (!gss_verify_signature(tt.name, tsigMsg, theirMAC)) { - throw std::runtime_error("Signature with TSIG key '"+tt.name.toLogString()+"' failed to validate"); - } + throw std::runtime_error("Unsupported TSIG GSS algorithm " + trc.d_algoName.toLogString()); } else { string ourMac = calculateHMAC(tt.secret, tsigMsg, algo); diff --git a/pdns/gss_context.cc b/pdns/gss_context.cc deleted file mode 100644 index 3c2ed292cd..0000000000 --- a/pdns/gss_context.cc +++ /dev/null @@ -1,490 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include -#include "namespaces.hh" -#include "dns.hh" -#include "dnsparser.hh" -#include "dnspacket.hh" -#include "dnsrecords.hh" -#include "logger.hh" -#include "lock.hh" -#include "arguments.hh" - -#include -#include -#include "gss_context.hh" - -#ifndef ENABLE_GSS_TSIG - -bool GssContext::supported() { return false; } -GssContext::GssContext() : d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {} -GssContext::GssContext(const DNSName& label) : d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {} -void GssContext::setLocalPrincipal(const std::string& name) {} -bool GssContext::getLocalPrincipal(std::string& name) { return false; } -void GssContext::setPeerPrincipal(const std::string& name) {} -bool GssContext::getPeerPrincipal(std::string& name) { return false; } -void GssContext::generateLabel(const std::string& suffix) {} -void GssContext::setLabel(const DNSName& label) {} -bool GssContext::init(const std::string &input, std::string& output) { return false; } -bool GssContext::accept(const std::string &input, std::string& output) { return false; } -bool GssContext::destroy() { return false; } -bool GssContext::expired() { return false; } -bool GssContext::valid() { return false; } -bool GssContext::sign(const std::string &input, std::string& output) { return false; } -bool GssContext::verify(const std::string &input, const std::string &signature) { return false; } -GssContextError GssContext::getError() { return GSS_CONTEXT_UNSUPPORTED; } - -#else - -class GssCredential : boost::noncopyable { -public: - GssCredential(const std::string& name, const gss_cred_usage_t usage) : - d_valid(false), d_nameS(name), d_name(GSS_C_NO_NAME), d_cred(GSS_C_NO_CREDENTIAL), d_usage(usage) { - gss_buffer_desc buffer; - - if (name.empty() == false) { - buffer.length = name.size(); - buffer.value = (void*)name.c_str(); - d_maj = gss_import_name(&d_min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &d_name); - if (d_maj != GSS_S_COMPLETE) { - d_valid = false; - return; - } - } - - renew(); - }; - - ~GssCredential() { - OM_uint32 tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - if (d_cred != GSS_C_NO_CREDENTIAL) - tmp_maj = gss_release_cred(&tmp_min, &d_cred); - if (d_name != GSS_C_NO_NAME) - tmp_maj = gss_release_name(&tmp_min, &d_name); - }; - - bool expired() const { - if (d_expires == -1) return false; - return time((time_t*)NULL)>d_expires; - } - - bool renew() { - OM_uint32 time_rec, tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - d_maj = gss_acquire_cred(&d_min, d_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, d_usage, &d_cred, NULL, &time_rec); - - if (d_maj != GSS_S_COMPLETE) { - d_valid = false; - tmp_maj = gss_release_name(&tmp_min, &d_name); - d_name = GSS_C_NO_NAME; - return false; - } - - d_valid = true; - - if (time_rec > GSS_C_INDEFINITE) { - d_expires = time((time_t*)NULL)+time_rec; - } else { - d_expires = -1; - } - - return true; - } - - bool valid() { - return d_valid && !expired(); - } - - OM_uint32 d_maj,d_min; - - bool d_valid; - int64_t d_expires; - std::string d_nameS; - gss_name_t d_name; - gss_cred_id_t d_cred; - gss_cred_usage_t d_usage; -}; - -std::map > s_gss_accept_creds; -std::map > s_gss_init_creds; - -class GssSecContext : boost::noncopyable { -public: - GssSecContext(boost::shared_ptr cred) { - if (cred->valid() == false) throw PDNSException("Invalid credential " + cred->d_nameS); - d_cred = cred; - d_state = GssStateInitial; - d_ctx = GSS_C_NO_CONTEXT; - d_expires = 0; - d_maj = d_min = 0; - d_peer_name = GSS_C_NO_NAME; - d_type = GSS_CONTEXT_NONE; - } - - ~GssSecContext() { - OM_uint32 tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - if (d_ctx != GSS_C_NO_CONTEXT) { - tmp_maj = gss_delete_sec_context(&tmp_min, &d_ctx, GSS_C_NO_BUFFER); - } - if (d_peer_name != GSS_C_NO_NAME) { - tmp_maj = gss_release_name(&tmp_min, &(d_peer_name)); - } - } - - GssContextType d_type; - gss_ctx_id_t d_ctx; - gss_name_t d_peer_name; - int64_t d_expires; - boost::shared_ptr d_cred; - OM_uint32 d_maj,d_min; - - enum { - GssStateInitial, - GssStateNegotiate, - GssStateComplete, - GssStateError - } d_state; - -}; - -std::map > s_gss_sec_context; - -bool GssContext::supported() { return true; } - -void GssContext::initialize() { - d_peerPrincipal = ""; - d_localPrincipal = ""; - d_error = GSS_CONTEXT_NO_ERROR; - d_type = GSS_CONTEXT_NONE; -} - -GssContext::GssContext() { - initialize(); - generateLabel("pdns.tsig."); -} - -GssContext::GssContext(const DNSName& label) { - initialize(); - setLabel(label); -} - -void GssContext::generateLabel(const std::string& suffix) { - std::ostringstream oss; - oss << std::hex << time((time_t*)NULL) << "." << suffix; - setLabel(DNSName(oss.str())); -} - -void GssContext::setLabel(const DNSName& label) { - d_label = label; - if (s_gss_sec_context.find(d_label) != s_gss_sec_context.end()) { - d_ctx = s_gss_sec_context[d_label]; - d_type = d_ctx->d_type; - } -} - -bool GssContext::expired() { - return (!d_ctx || (d_ctx->d_expires > -1 && d_ctx->d_expires < time((time_t*)NULL))); -} - -bool GssContext::valid() { - return (d_ctx && !expired() && d_ctx->d_state == GssSecContext::GssStateComplete); -} - -bool GssContext::init(const std::string &input, std::string& output) { - OM_uint32 tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - OM_uint32 maj,min; - gss_buffer_desc recv_tok, send_tok, buffer; - OM_uint32 flags; - OM_uint32 expires; - - boost::shared_ptr cred; - if (d_label.empty()) { - d_error = GSS_CONTEXT_INVALID; - return false; - } - - d_type = GSS_CONTEXT_INIT; - - if (s_gss_init_creds.find(d_localPrincipal) != s_gss_init_creds.end()) { - cred = s_gss_init_creds[d_localPrincipal]; - } else { - s_gss_init_creds[d_localPrincipal] = boost::make_shared(d_localPrincipal, GSS_C_INITIATE); - cred = s_gss_init_creds[d_localPrincipal]; - } - - // see if we can find a context in non-completed state - if (d_ctx) { - if (d_ctx->d_state != GssSecContext::GssStateNegotiate) { - d_error = GSS_CONTEXT_INVALID; - return false; - } - } else { - // make context - s_gss_sec_context[d_label] = boost::make_shared(cred); - s_gss_sec_context[d_label]->d_type = d_type; - d_ctx = s_gss_sec_context[d_label]; - d_ctx->d_state = GssSecContext::GssStateNegotiate; - } - - recv_tok.length = input.size(); - recv_tok.value = (void*)input.c_str(); - - if (d_peerPrincipal.empty() == false) { - buffer.value = (void*)d_peerPrincipal.c_str(); - buffer.length = d_peerPrincipal.size(); - maj = gss_import_name(&min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &(d_ctx->d_peer_name)); - if (maj != GSS_S_COMPLETE) { - processError("gss_import_name", maj, min); - return false; - } - } - - maj = gss_init_sec_context(&min, cred->d_cred, &(d_ctx->d_ctx), d_ctx->d_peer_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &recv_tok, NULL, &send_tok, &flags, &expires); - - if (send_tok.length>0) { - output.assign((const char*)send_tok.value, send_tok.length); - tmp_maj = gss_release_buffer(&tmp_min, &send_tok); - } - - if (maj == GSS_S_COMPLETE) { - if (expires > GSS_C_INDEFINITE) { - d_ctx->d_expires = time((time_t*)NULL) + expires; - } else { - d_ctx->d_expires = -1; - } - d_ctx->d_state = GssSecContext::GssStateComplete; - return true; - } else if (maj != GSS_S_CONTINUE_NEEDED) { - processError("gss_init_sec_context", maj,min); - } - - return (maj == GSS_S_CONTINUE_NEEDED); -} - -bool GssContext::accept(const std::string &input, std::string& output) { - OM_uint32 tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - OM_uint32 maj,min; - gss_buffer_desc recv_tok, send_tok; - OM_uint32 flags; - OM_uint32 expires; - - boost::shared_ptr cred; - if (d_label.empty()) { - d_error = GSS_CONTEXT_INVALID; - return false; - } - - d_type = GSS_CONTEXT_ACCEPT; - - if (s_gss_accept_creds.find(d_localPrincipal) != s_gss_accept_creds.end()) { - cred = s_gss_accept_creds[d_localPrincipal]; - } else { - s_gss_accept_creds[d_localPrincipal] = boost::make_shared(d_localPrincipal, GSS_C_ACCEPT); - cred = s_gss_accept_creds[d_localPrincipal]; - } - - // see if we can find a context in non-completed state - if (d_ctx) { - if (d_ctx->d_state != GssSecContext::GssStateNegotiate) { - d_error = GSS_CONTEXT_INVALID; - return false; - } - } else { - // make context - s_gss_sec_context[d_label] = boost::make_shared(cred); - s_gss_sec_context[d_label]->d_type = d_type; - d_ctx = s_gss_sec_context[d_label]; - d_ctx->d_state = GssSecContext::GssStateNegotiate; - } - - recv_tok.length = input.size(); - recv_tok.value = (void*)input.c_str(); - - maj = gss_accept_sec_context(&min, &(d_ctx->d_ctx), cred->d_cred, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &(d_ctx->d_peer_name), NULL, &send_tok, &flags, &expires, NULL); - - if (send_tok.length>0) { - output.assign((const char*)send_tok.value, send_tok.length); - tmp_maj = gss_release_buffer(&tmp_min, &send_tok); - } - - if (maj == GSS_S_COMPLETE) { - if (expires > GSS_C_INDEFINITE) { - d_ctx->d_expires = time((time_t*)NULL) + expires; - } else { - d_ctx->d_expires = -1; - } - d_ctx->d_state = GssSecContext::GssStateComplete; - return true; - } else if (maj != GSS_S_CONTINUE_NEEDED) { - processError("gss_accept_sec_context", maj,min); - } - return (maj == GSS_S_CONTINUE_NEEDED); -}; - -bool GssContext::sign(const std::string& input, std::string& output) { - OM_uint32 tmp_maj __attribute__((unused)), tmp_min __attribute__((unused)); - OM_uint32 maj,min; - - gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; - gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; - - recv_tok.length = input.size(); - recv_tok.value = (void*)input.c_str(); - - maj = gss_get_mic(&min, d_ctx->d_ctx, GSS_C_QOP_DEFAULT, &recv_tok, &send_tok); - - if (send_tok.length>0) { - output.assign((const char*)send_tok.value, send_tok.length); - tmp_maj = gss_release_buffer(&tmp_min, &send_tok); - } - - if (maj != GSS_S_COMPLETE) { - processError("gss_get_mic", maj,min); - } - - return (maj == GSS_S_COMPLETE); -} - -bool GssContext::verify(const std::string& input, const std::string& signature) { - OM_uint32 maj,min; - - gss_buffer_desc recv_tok = GSS_C_EMPTY_BUFFER; - gss_buffer_desc sign_tok = GSS_C_EMPTY_BUFFER; - - recv_tok.length = input.size(); - recv_tok.value = (void*)input.c_str(); - sign_tok.length = signature.size(); - sign_tok.value = (void*)signature.c_str(); - - maj = gss_verify_mic(&min, d_ctx->d_ctx, &recv_tok, &sign_tok, NULL); - - if (maj != GSS_S_COMPLETE) { - processError("gss_get_mic", maj,min); - } - - return (maj == GSS_S_COMPLETE); -} - -bool GssContext::destroy() { - return false; -} - -void GssContext::setLocalPrincipal(const std::string& name) { - d_localPrincipal = name; -} - -bool GssContext::getLocalPrincipal(std::string& name) { - name = d_localPrincipal; - return name.size()>0; -} - -void GssContext::setPeerPrincipal(const std::string& name) { - d_peerPrincipal = name; -} - -bool GssContext::getPeerPrincipal(std::string& name) { - gss_buffer_desc value; - OM_uint32 maj,min; - - if (d_ctx->d_peer_name != GSS_C_NO_NAME) { - maj = gss_display_name(&min, d_ctx->d_peer_name, &value, NULL); - if (maj == GSS_S_COMPLETE && value.length > 0) { - name.assign((const char*)value.value, value.length); - maj = gss_release_buffer(&min, &value); - return true; - } else { - return false; - } - } else { - return false; - } -} - -void GssContext::processError(const std::string& method, OM_uint32 maj, OM_uint32 min) { - OM_uint32 tmp_min; - gss_buffer_desc msg; - OM_uint32 msg_ctx; - - msg_ctx = 0; - while (1) { - ostringstream oss; - gss_display_status(&tmp_min, maj, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg); - oss << method << ": " << (char*)msg.value; - d_gss_errors.push_back(oss.str()); - if (!msg_ctx) break; - } - msg_ctx = 0; - while (1) { - ostringstream oss; - gss_display_status(&tmp_min, min, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg); - oss << method << ": " << (char*)msg.value; - d_gss_errors.push_back(oss.str()); - if (!msg_ctx) break; - } -} - -#endif - -bool gss_add_signature(const DNSName& context, const std::string& message, std::string& mac) { - string tmp_mac; - GssContext gssctx(context); - if (!gssctx.valid()) { - g_log< -#include -#include -#endif - -//! Generic errors -enum GssContextError { - GSS_CONTEXT_NO_ERROR, - GSS_CONTEXT_UNSUPPORTED, - GSS_CONTEXT_NOT_FOUND, - GSS_CONTEXT_NOT_INITIALIZED, - GSS_CONTEXT_INVALID, - GSS_CONTEXT_EXPIRED, - GSS_CONTEXT_ALREADY_INITIALIZED -}; - -//! GSS context types -enum GssContextType { - GSS_CONTEXT_NONE, - GSS_CONTEXT_INIT, - GSS_CONTEXT_ACCEPT -}; - -class GssSecContext; - -/*! Class for representing GSS names, such as host/host.domain.com@REALM. -*/ -class GssName { -public: - //! Initialize to empty name - GssName() { - setName(""); - }; - - //! Initialize using specific name - GssName(const std::string& name) { - setName(name); - }; - - //! Parse name into native representation - bool setName(const std::string& name) { -#ifdef ENABLE_GSS_TSIG - gss_buffer_desc buffer; - d_name = GSS_C_NO_NAME; - - if (!name.empty()) { - buffer.length = name.size(); - buffer.value = (void*)name.c_str(); - d_maj = gss_import_name(&d_min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &d_name); - return d_maj == GSS_S_COMPLETE; - } - - return true; -#endif - return false; - }; - - ~GssName() { -#ifdef ENABLE_GSS_TSIG - if (d_name != GSS_C_NO_NAME) - gss_release_name(&d_min, &d_name); -#endif - }; - - //! Compare two Gss Names, if no gss support is compiled in, returns false always - //! This is not necessarily same as string comparison between two non-parsed names - bool operator==(const GssName& rhs) { -#ifdef ENABLE_GSS_TSIG - OM_uint32 maj,min; - int result; - maj = gss_compare_name(&min, d_name, rhs.d_name, &result); - return (maj == GSS_S_COMPLETE && result != 0); -#endif - return false; - } - - //! Compare two Gss Names, if no gss support is compiled in, returns false always - //! This is not necessarily same as string comparison between two non-parsed names - bool match(const std::string& name) { -#ifdef ENABLE_GSS_TSIG - OM_uint32 maj,min; - int result; - gss_name_t comp; - gss_buffer_desc buffer; - buffer.length = name.size(); - buffer.value = (void*)name.c_str(); - maj = gss_import_name(&min, &buffer, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &comp); - if (maj != GSS_S_COMPLETE) - throw PDNSException("Could not import " + name + ": " + std::to_string(maj) + string(",") + std::to_string(min)); - // do comparison - maj = gss_compare_name(&min, d_name, comp, &result); - gss_release_name(&min, &comp); - return (maj == GSS_S_COMPLETE && result != 0); -#else - return false; -#endif - }; - - //! Check if GSS name was parsed successfully. - bool valid() { -#ifdef ENABLE_GSS_TSIG - return d_maj == GSS_S_COMPLETE; -#else - return false; -#endif - } -private: -#ifdef ENABLE_GSS_TSIG - OM_uint32 d_maj,d_min; - gss_name_t d_name; -#endif -}; - -class GssContext { -public: - static bool supported(); // getErrorStrings() { return d_gss_errors; } // d_gss_errors; // d_ctx; // #include "axfr-retriever.hh" #include diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 2eec1d1b62..ceb95b7599 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -1167,12 +1167,6 @@ std::unique_ptr PacketHandler::doQuestion(DNSPacket& p) return r; } else { getTSIGHashEnum(trc.d_algoName, p.d_tsig_algo); - if (p.d_tsig_algo == TSIG_GSS) { - GssContext gssctx(keyname); - if (!gssctx.getPeerPrincipal(p.d_peer_principal)) { - g_log< multiMetaWhitelist = {"ALLOW-AXFR-FROM", "ALLOW-DNSUPDATE-FROM", - "ALSO-NOTIFY", "TSIG-ALLOW-AXFR", "TSIG-ALLOW-DNSUPDATE", "GSS-ALLOW-AXFR-PRINCIPAL", + "ALSO-NOTIFY", "TSIG-ALLOW-AXFR", "TSIG-ALLOW-DNSUPDATE", "PUBLISH-CDS"}; bool clobber = true; if (cmds[0] == "add-meta") { diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 573047c75e..cf58ccacdc 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -120,7 +120,6 @@ pdns_recursor_SOURCES = \ filterpo.cc filterpo.hh \ fstrm_logger.cc fstrm_logger.hh \ gettime.cc gettime.hh \ - gss_context.cc gss_context.hh \ iputils.hh iputils.cc \ ixfr.cc ixfr.hh \ json.cc json.hh \ @@ -242,7 +241,6 @@ testrunner_SOURCES = \ ednssubnet.cc ednssubnet.hh \ filterpo.cc filterpo.hh \ gettime.cc gettime.hh \ - gss_context.cc gss_context.hh \ iputils.cc iputils.hh \ ixfr.cc ixfr.hh \ logger.cc logger.hh \ diff --git a/pdns/recursordist/gss_context.cc b/pdns/recursordist/gss_context.cc deleted file mode 120000 index 3ed3e719f9..0000000000 --- a/pdns/recursordist/gss_context.cc +++ /dev/null @@ -1 +0,0 @@ -../gss_context.cc \ No newline at end of file diff --git a/pdns/recursordist/gss_context.hh b/pdns/recursordist/gss_context.hh deleted file mode 120000 index 050b795024..0000000000 --- a/pdns/recursordist/gss_context.hh +++ /dev/null @@ -1 +0,0 @@ -../gss_context.hh \ No newline at end of file diff --git a/pdns/resolver.cc b/pdns/resolver.cc index 423e3f9022..a5bdec36be 100644 --- a/pdns/resolver.cc +++ b/pdns/resolver.cc @@ -48,7 +48,6 @@ #include "dns_random.hh" #include -#include "gss_context.hh" #include "namespaces.hh" using pdns::resolver::parseResult; diff --git a/pdns/rfc2136handler.cc b/pdns/rfc2136handler.cc index 15902766d4..e7ab1f6568 100644 --- a/pdns/rfc2136handler.cc +++ b/pdns/rfc2136handler.cc @@ -748,20 +748,10 @@ int PacketHandler::processUpdate(DNSPacket& p) { return RCode::Refused; } - if (p.d_tsig_algo == TSIG_GSS) { - GssName inputname(p.d_peer_principal); // match against principal since GSS - for(const auto& key: tsigKeys) { - if (inputname.match(key)) { - validKey = true; - break; - } - } - } else { - for(const auto& key: tsigKeys) { - if (inputkey == DNSName(key)) { // because checkForCorrectTSIG has already been performed earlier on, if the names of the ky match with the domain given. THis is valid. - validKey=true; - break; - } + for(const auto& key: tsigKeys) { + if (inputkey == DNSName(key)) { // because checkForCorrectTSIG has already been performed earlier on, if the names of the ky match with the domain given. THis is valid. + validKey=true; + break; } } diff --git a/pdns/saxfr.cc b/pdns/saxfr.cc index 1a48cfac7b..a7517804f0 100644 --- a/pdns/saxfr.cc +++ b/pdns/saxfr.cc @@ -12,7 +12,6 @@ #include "dnssecinfra.hh" #include "dns_random.hh" -#include "gss_context.hh" StatBag S; @@ -20,14 +19,13 @@ int main(int argc, char** argv) try { if(argc < 4) { - cerr<<"Syntax: saxfr IP-address port zone [showdetails] [showflags] [unhash] [gss:remote-principal] [tsig:keyname:algo:secret]"< parts; tsig=true; @@ -90,75 +78,6 @@ try Socket sock(dest.sin4.sin_family, SOCK_STREAM); sock.connect(dest); - if (gss) { -#ifndef ENABLE_GSS_TSIG - cerr<<"No GSS support compiled in"<id = dns_random_uint16(); - pwtkey.startRecord(gssctx.getLabel(), QType::TKEY, 3600, QClass::ANY, DNSResourceRecord::ADDITIONAL, false); - tkrc.toPacket(pwtkey); - pwtkey.commit(); - for(const string& msg : gssctx.getErrorStrings()) { - cerr< creply(new char[len]); - int n=0; - int numread; - while(nfirst.d_type != QType::TKEY) continue; - // recover TKEY record - tkrc = TKEYRecordContent(i->first.d_content->getZoneRepresentation()); - input = tkrc.d_key; - } - } - - if (gssctx.valid() == false) { - cerr<<"Could not create GSS context"<id = dns_random_uint16(); diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 6dea329261..6a56ce13b4 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -401,29 +401,9 @@ bool TCPNameserver::canDoAXFR(std::unique_ptr& q) return false; } else { getTSIGHashEnum(trc.d_algoName, q->d_tsig_algo); - if (q->d_tsig_algo == TSIG_GSS) { - GssContext gssctx(keyname); - if (!gssctx.getPeerPrincipal(q->d_peer_principal)) { - g_log<getBackend()); - - if (q->d_tsig_algo == TSIG_GSS) { - vector princs; - s_P->getBackend()->getDomainMetadata(q->qdomain, "GSS-ALLOW-AXFR-PRINCIPAL", princs); - for(const std::string& princ : princs) { - if (q->d_peer_principal == princ) { - g_log<qdomain<<"' allowed: TSIG signed request with authorized principal '"<d_peer_principal<<"' and algorithm 'gss-tsig'"<qdomain<<"' denied: TSIG signed request with principal '"<d_peer_principal<<"' and algorithm 'gss-tsig' is not permitted"<qdomain, keyname)) { g_log<qdomain<<"' denied: key with name '"<d_tsig_algo)<<"' does not grant access to zone"<& q, DNSName algorithm=trc.d_algoName; // FIXME400: check if (algorithm == DNSName("hmac-md5.sig-alg.reg.int")) algorithm = DNSName("hmac-md5"); - if (algorithm != DNSName("gss-tsig")) { - if(!db.getTSIGKey(tsigkeyname, &algorithm, &tsig64)) { - g_log<& TKEYRecordContent tkey_in; std::shared_ptr tkey_out(new TKEYRecordContent()); DNSName name; - bool sign = false; if (!p.getTKEYRecord(&tkey_in, &name)) { g_log<& tkey_out->d_inception = time((time_t*)NULL); tkey_out->d_expiration = tkey_out->d_inception+15; - GssContext ctx(name); - if (tkey_in.d_mode == 3) { // establish context if (tkey_in.d_algo == DNSName("gss-tsig.")) { - std::vector meta; - DNSName tmpName(name); - do { - if (B.getDomainMetadata(tmpName, "GSS-ACCEPTOR-PRINCIPAL", meta) && meta.size()>0) { - break; - } - } while(tmpName.chopOff()); - - if (meta.size()>0) { - ctx.setLocalPrincipal(meta[0]); - } - // try to get a context - if (!ctx.accept(tkey_in.d_key, tkey_out->d_key)) - tkey_out->d_error = 19; - else - sign = true; + tkey_out->d_error = 19; } else { tkey_out->d_error = 21; // BADALGO } @@ -53,10 +35,8 @@ void PacketHandler::tkeyHandler(const DNSPacket& p, std::unique_ptr& r->setRcode(RCode::NotAuth); return; } - if (ctx.valid()) - ctx.destroy(); - else - tkey_out->d_error = 20; // BADNAME (because we have no support for anything here) + + tkey_out->d_error = 20; // BADNAME (because we have no support for anything here) } else { if (p.d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated if (p.d.opcode == Opcode::Update) @@ -80,20 +60,5 @@ void PacketHandler::tkeyHandler(const DNSPacket& p, std::unique_ptr& zrr.dr.d_content = tkey_out; zrr.dr.d_place = DNSResourceRecord::ANSWER; r->addRecord(std::move(zrr)); - - if (sign) - { - TSIGRecordContent trc; - trc.d_algoName = DNSName("gss-tsig"); - trc.d_time = tkey_out->d_inception; - trc.d_fudge = 300; - trc.d_mac = ""; - trc.d_origID = p.d.id; - trc.d_eRcode = 0; - trc.d_otherData = ""; - // this should cause it to lookup name context - r->setTSIGDetails(trc, name, name.toStringNoDot(), "", false); - } - r->commitD(); } diff --git a/pdns/tsigverifier.cc b/pdns/tsigverifier.cc index de0471b73d..c379c841af 100644 --- a/pdns/tsigverifier.cc +++ b/pdns/tsigverifier.cc @@ -1,7 +1,6 @@ #include "tsigverifier.hh" #include "dnssecinfra.hh" -#include "gss_context.hh" bool TSIGTCPVerifier::check(const string& data, const MOADNSParser& mdp) { diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 4feb89b81f..32aa1a8f13 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -855,8 +855,6 @@ static bool isValidMetadataKind(const string& kind, bool readonly) { "NOTIFY-DNSUPDATE", "ALSO-NOTIFY", "AXFR-MASTER-TSIG", - "GSS-ALLOW-AXFR-PRINCIPAL", - "GSS-ACCEPTOR-PRINCIPAL", "IXFR", "LUA-AXFR-SCRIPT", "NSEC3NARROW",