]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: avoid metadata cache polution in the api code
authorKees Monshouwer <mind04@monshouwer.org>
Mon, 31 Aug 2020 16:41:53 +0000 (18:41 +0200)
committermind04 <mind04@monshouwer.org>
Thu, 24 Sep 2020 11:28:30 +0000 (13:28 +0200)
pdns/dbdnsseckeeper.cc
pdns/dnsseckeeper.hh
pdns/ws-auth.cc

index 47cee9baa536e3cedf67978898cedbbcaf1b2a34..14e1cd253f2d9cd88ec3c7e32f0ab7120b812850 100644 (file)
@@ -59,9 +59,9 @@ bool DNSSECKeeper::doesDNSSEC()
   return d_keymetadb->doesDNSSEC();
 }
 
-bool DNSSECKeeper::isSecuredZone(const DNSName& zone) 
+bool DNSSECKeeper::isSecuredZone(const DNSName& zone, bool useCache
 {
-  if(isPresigned(zone))
+  if(isPresigned(zone, useCache))
     return true;
 
   keyset_t keys = getKeys(zone); // does the cache
@@ -74,10 +74,15 @@ bool DNSSECKeeper::isSecuredZone(const DNSName& zone)
   return false;
 }
 
-bool DNSSECKeeper::isPresigned(const DNSName& name)
+bool DNSSECKeeper::isPresigned(const DNSName& name, bool useCache)
 {
   string meta;
-  getFromMeta(name, "PRESIGNED", meta);
+  if (useCache) {
+    getFromMeta(name, "PRESIGNED", meta);
+  }
+  else {
+    getFromMetaNoCache(name, "PRESIGNED", meta);
+  }
   return meta=="1";
 }
 
@@ -270,12 +275,24 @@ bool DNSSECKeeper::getFromMeta(const DNSName& zname, const std::string& key, std
   return ret;
 }
 
-void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value)
+bool DNSSECKeeper::getFromMetaNoCache(const DNSName& name, const std::string& kind, std::string& value)
+{
+  std::vector<std::string> meta;
+  if (d_keymetadb->getDomainMetadata(name, kind, meta)) {
+    if(!meta.empty()) {
+      value = *meta.begin();
+      return true;
+    }
+  }
+  return false;
+}
+
+void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value, bool useCache)
 {
   static const string soaEdit(::arg()["default-soa-edit"]);
   static const string soaEditSigned(::arg()["default-soa-edit-signed"]);
 
-  if (isPresigned(zname)) {
+  if (isPresigned(zname, useCache)) {
     // SOA editing on a presigned zone never makes sense
     return;
   }
@@ -283,7 +300,7 @@ void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value)
   getFromMeta(zname, "SOA-EDIT", value);
 
   if ((!soaEdit.empty() || !soaEditSigned.empty()) && value.empty()) {
-    if (!soaEditSigned.empty() && isSecuredZone(zname))
+    if (!soaEditSigned.empty() && isSecuredZone(zname, useCache))
       value=soaEditSigned;
     if (value.empty())
       value=soaEdit;
@@ -305,10 +322,15 @@ uint64_t DNSSECKeeper::dbdnssecCacheSizes(const std::string& str)
   return (uint64_t)-1;
 }
 
-bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
+bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow, bool useCache)
 {
   string value;
-  getFromMeta(zname, "NSEC3PARAM", value);
+  if(useCache) {
+    getFromMeta(zname, "NSEC3PARAM", value);
+  }
+  else {
+    getFromMetaNoCache(zname, "NSEC3PARAM", value);
+  }
   if(value.empty()) { // "no NSEC3"
     return false;
   }
@@ -326,7 +348,12 @@ bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent*
     }
   }
   if(narrow) {
-    getFromMeta(zname, "NSEC3NARROW", value);
+    if(useCache) {
+      getFromMeta(zname, "NSEC3NARROW", value);
+    }
+    else {
+      getFromMetaNoCache(zname, "NSEC3NARROW", value);
+    }
     *narrow = (value=="1");
   }
   return true;
@@ -658,7 +685,7 @@ bool DNSSECKeeper::unSecureZone(const DNSName& zone, string& error, string& info
  * \param doTransaction Whether or not to wrap the rectify in a transaction
  */
 bool DNSSECKeeper::rectifyZone(const DNSName& zone, string& error, string& info, bool doTransaction) {
-  if (isPresigned(zone)) {
+  if (isPresigned(zone, doTransaction)) {
     error =  "Rectify presigned zone '"+zone.toLogString()+"' is not allowed/necessary.";
     return false;
   }
@@ -708,11 +735,11 @@ bool DNSSECKeeper::rectifyZone(const DNSName& zone, string& error, string& info,
   }
 
   NSEC3PARAMRecordContent ns3pr;
-  bool securedZone = isSecuredZone(zone);
+  bool securedZone = isSecuredZone(zone, doTransaction);
   bool haveNSEC3 = false, isOptOut = false, narrow = false;
 
   if(securedZone) {
-    haveNSEC3 = getNSEC3PARAM(zone, &ns3pr, &narrow);
+    haveNSEC3 = getNSEC3PARAM(zone, &ns3pr, &narrow, doTransaction);
     isOptOut = (haveNSEC3 && ns3pr.d_flags);
 
     if(!haveNSEC3) {
index f323b3adb1c684e5cc7566bb747af47a411421e4..56ddc226d844c9d5e862ab898d610af59b89c674 100644 (file)
@@ -192,7 +192,7 @@ public:
   static void clearCaches(const DNSName& name);
 
   bool doesDNSSEC();
-  bool isSecuredZone(const DNSName& zone);
+  bool isSecuredZone(const DNSName& zone, bool useCache=true);
   keyset_t getEntryPoints(const DNSName& zname);
   keyset_t getKeys(const DNSName& zone, bool useCache = true);
   DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id);
@@ -205,12 +205,12 @@ public:
   bool unpublishKey(const DNSName& zname, unsigned int id);
   bool checkKeys(const DNSName& zname, vector<string>* errorMessages = nullptr);
 
-  bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
+  bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0, bool useCache=true);
   bool checkNSEC3PARAM(const NSEC3PARAMRecordContent& ns3p, string& msg);
   bool setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
   bool unsetNSEC3PARAM(const DNSName& zname);
   bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector<DNSZoneRecord>& rrsigs, uint32_t signTTL);
-  bool isPresigned(const DNSName& zname);
+  bool isPresigned(const DNSName& zname, bool useCache=true);
   bool setPresigned(const DNSName& zname);
   bool unsetPresigned(const DNSName& zname);
   bool setPublishCDNSKEY(const DNSName& zname);
@@ -235,7 +235,7 @@ public:
   
   void getFromMetaOrDefault(const DNSName& zname, const std::string& key, std::string& value, const std::string& defaultvalue);
   bool getFromMeta(const DNSName& zname, const std::string& key, std::string& value);
-  void getSoaEdit(const DNSName& zname, std::string& value);
+  void getSoaEdit(const DNSName& zname, std::string& value, bool useCache=true);
   bool unSecureZone(const DNSName& zone, std::string& error, std::string& info);
   bool rectifyZone(const DNSName& zone, std::string& error, std::string& info, bool doTransaction);
 
@@ -243,6 +243,8 @@ public:
 
   typedef std::map<std::string, std::vector<std::string> > METAValues;
 private:
+  bool getFromMetaNoCache(const DNSName& name, const std::string& kind, std::string& value);
+
   int64_t d_metaCacheCleanAction{0};
 
   struct KeyCacheEntry
index 32bb9ad27b477a1dcf9b4c0feb976270c96e8219..77d66a77e387aa1d47ecc24a49dfa73796985d97 100644 (file)
@@ -331,7 +331,9 @@ static Json::object getZoneInfo(const DomainInfo& di, DNSSECKeeper* dk) {
   };
   if (dk) {
     obj["dnssec"] = dk->isSecuredZone(di.zone);
-    obj["edited_serial"] = (double)calculateEditSOA(di.serial, *dk, di.zone);
+    string soa_edit;
+    dk->getSoaEdit(di.zone, soa_edit, false);
+    obj["edited_serial"] = (double)calculateEditSOA(di.serial, soa_edit, di.zone);
   }
   return obj;
 }
@@ -697,6 +699,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
 
 
   bool isDNSSECZone = dk.isSecuredZone(zonename);
+  bool isPresigned = dk.isPresigned(zonename);
 
   if (dnssecInJSON) {
     if (dnssecDocVal) {
@@ -737,7 +740,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
         if (!dk.unSecureZone(zonename, error, info)) {
           throw ApiException("Error while un-securing zone '"+ zonename.toString()+"': " + error);
         }
-        isDNSSECZone = dk.isSecuredZone(zonename);
+        isDNSSECZone = dk.isSecuredZone(zonename, false); 
         if (isDNSSECZone) {
           throw ApiException("Unable to un-secure zone '"+ zonename.toString()+"'");
         }
@@ -773,7 +776,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo&
     }
   }
 
-  if (shouldRectify && !dk.isPresigned(zonename)) {
+  if (shouldRectify && !isPresigned) {
     // Rectify
     string api_rectify;
     di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify);