]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Reinstate AXFR code for GSS-TSIG, respecting global enable flag.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 7 Jan 2022 09:36:20 +0000 (10:36 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 2 Sep 2022 12:22:48 +0000 (14:22 +0200)
pdns/gss_context.cc
pdns/gss_context.hh
pdns/tcpreceiver.cc

index 3d5528016d7f8bc4b2213688668899d1700253c0..cbd3265ee547f1268779404971931b4948caab4c 100644 (file)
@@ -508,7 +508,8 @@ void GssContext::processError(const std::string& method, OM_uint32 maj, OM_uint3
     ostringstream oss;
     if (gss_display_status(&tmp_min, maj, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msg) == GSS_S_COMPLETE) {
       oss << method << ": " << msg.value;
-    } else {
+    }
+    else {
       oss << method << ": ?";
     }
     if (msg.length != 0) {
@@ -521,9 +522,10 @@ void GssContext::processError(const std::string& method, OM_uint32 maj, OM_uint3
   msg_ctx = 0;
   while (1) {
     ostringstream oss;
-    if (gss_display_status(&tmp_min, min, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg) ==  GSS_S_COMPLETE) {
+    if (gss_display_status(&tmp_min, min, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msg) == GSS_S_COMPLETE) {
       oss << method << ": " << msg.value;
-    } else {
+    }
+    else {
       oss << method << ": ?";
     }
     if (msg.length != 0) {
index 0be518cdd5bbff1fdbf1d9c3074e372a4c59376b..659df9d2f0766290b22179201d1ff2763187e941 100644 (file)
@@ -57,7 +57,7 @@ enum GssContextType
 class GssSecContext;
 
 /*! Class for representing GSS names, such as host/host.domain.com@REALM.
-*/
+ */
 class GssName
 {
 public:
index 88d1be86c0eb08eccb0139f779120b1b5c6da8a4..37fc3ffb8e09ef85077333e4a1229e9b169df661 100644 (file)
@@ -60,6 +60,7 @@
 #include "stubresolver.hh"
 #include "proxy-protocol.hh"
 #include "noinitvector.hh"
+#include "gss_context.hh"
 extern AuthPacketCache PC;
 extern StatBag S;
 
@@ -458,9 +459,27 @@ bool TCPNameserver::canDoAXFR(std::unique_ptr<DNSPacket>& q, bool isAXFR, std::u
       return false;
     } else {
       getTSIGHashEnum(trc.d_algoName, q->d_tsig_algo);
+      if (g_doGssTSIG && q->d_tsig_algo == TSIG_GSS) {
+        GssContext gssctx(keyname);
+        if (!gssctx.getPeerPrincipal(q->d_peer_principal)) {
+          g_log<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<keyname<<"'"<<endl;
+        }
+      }
     }
 
     DNSSECKeeper dk(packetHandler->getBackend());
+    if (g_doGssTSIG && q->d_tsig_algo == TSIG_GSS) {
+      vector<string> princs;
+      packetHandler->getBackend()->getDomainMetadata(q->qdomain, "GSS-ALLOW-AXFR-PRINCIPAL", princs);
+      for(const std::string& princ :  princs) {
+        if (q->d_peer_principal == princ) {
+          g_log<<Logger::Warning<<"AXFR of domain '"<<q->qdomain<<"' allowed: TSIG signed request with authorized principal '"<<q->d_peer_principal<<"' and algorithm 'gss-tsig'"<<endl;
+          return true;
+        }
+      }
+      g_log<<Logger::Warning<<"AXFR of domain '"<<q->qdomain<<"' denied: TSIG signed request with principal '"<<q->d_peer_principal<<"' and algorithm 'gss-tsig' is not permitted"<<endl;
+      return false;
+    }
     if(!dk.TSIGGrantsAccess(q->qdomain, keyname)) {
       g_log<<Logger::Warning<<logPrefix<<"denied: key with name '"<<keyname<<"' and algorithm '"<<getTSIGAlgoName(q->d_tsig_algo)<<"' does not grant access"<<endl;
       return false;
@@ -634,13 +653,15 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr<DNSPacket>& q,
     DNSName algorithm=trc.d_algoName; // FIXME400: check
     if (algorithm == DNSName("hmac-md5.sig-alg.reg.int"))
       algorithm = DNSName("hmac-md5");
-    if (!db.getTSIGKey(tsigkeyname, algorithm, tsig64)) {
-      g_log<<Logger::Warning<<logPrefix<<"TSIG key not found"<<endl;
-      return 0;
-    }
-    if (B64Decode(tsig64, tsigsecret) == -1) {
-      g_log<<Logger::Error<<logPrefix<<"unable to Base-64 decode TSIG key '"<<tsigkeyname<<"'"<<endl;
-      return 0;
+    if (algorithm != DNSName("gss-tsig")) {
+      if(!db.getTSIGKey(tsigkeyname, algorithm, tsig64)) {
+        g_log<<Logger::Warning<<logPrefix<<"TSIG key not found"<<endl;
+        return 0;
+      }
+      if (B64Decode(tsig64, tsigsecret) == -1) {
+        g_log<<Logger::Error<<logPrefix<<"unable to Base-64 decode TSIG key '"<<tsigkeyname<<"'"<<endl;
+        return 0;
+      }
     }
   }