]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
API regression test succeed now, mostly setting right headers
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 27 Nov 2024 15:50:24 +0000 (16:50 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 11 Feb 2025 15:28:22 +0000 (16:28 +0100)
pdns/credentials.cc
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-main.hh
pdns/recursordist/reczones.cc
pdns/recursordist/settings/rust/src/web.rs
pdns/recursordist/ws-recursor.cc

index 062155326fa1c31476e4f0f797fd7c60a5f46db0..ddc5add19bd253d7f29256a1f396b737cb2cd9bf 100644 (file)
@@ -388,9 +388,7 @@ CredentialsHolder::~CredentialsHolder()
 
 bool CredentialsHolder::matches(const std::string& password) const
 {
-  cerr << "matches " << d_isHashed << ' ' << password << ' ' << d_credentials.getString() << endl;
   if (d_isHashed) {
-     cerr << "Case 1" << endl;
     return verifyPassword(d_credentials.getString(), d_salt, d_workFactor, d_parallelFactor, d_blockSize, password);
   }
   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
index bd71181692d44e41f73e4cb41bb16603fb5731c0..f1758e7082de3abb36f30c5821086907a5b798c5 100644 (file)
@@ -112,9 +112,9 @@ boost::optional<ComboAddress> g_dns64Prefix{boost::none};
 DNSName g_dns64PrefixReverse;
 unsigned int g_maxChainLength;
 LockGuarded<std::shared_ptr<SyncRes::domainmap_t>> g_initialDomainMap; // new threads needs this to be setup
-std::shared_ptr<NetmaskGroup> g_initialAllowFrom; // new thread needs to be setup with this
-std::shared_ptr<NetmaskGroup> g_initialAllowNotifyFrom; // new threads need this to be setup
-std::shared_ptr<notifyset_t> g_initialAllowNotifyFor; // new threads need this to be setup
+LockGuarded<std::shared_ptr<NetmaskGroup>> g_initialAllowFrom; // new thread needs to be setup with this
+LockGuarded<std::shared_ptr<NetmaskGroup>> g_initialAllowNotifyFrom; // new threads need this to be setup
+LockGuarded<std::shared_ptr<notifyset_t>> g_initialAllowNotifyFor; // new threads need this to be setup
 bool g_logRPZChanges{false};
 static time_t s_statisticsInterval;
 static std::atomic<uint32_t> s_counter;
@@ -1472,13 +1472,13 @@ void parseACLs()
     allowFrom = nullptr;
   }
 
-  g_initialAllowFrom = allowFrom;
+  *g_initialAllowFrom.lock() = allowFrom;
   // coverity[copy_constructor_call] maybe this can be avoided, but be careful as pointers get passed to other threads
   broadcastFunction([=] { return pleaseSupplantAllowFrom(allowFrom); });
 
   auto allowNotifyFrom = parseACL("allow-notify-from-file", "allow-notify-from", log);
 
-  g_initialAllowNotifyFrom = allowNotifyFrom;
+  *g_initialAllowNotifyFrom.lock() = allowNotifyFrom;
   // coverity[copy_constructor_call] maybe this can be avoided, but be careful as pointers get passed to other threads
   broadcastFunction([=] { return pleaseSupplantAllowNotifyFrom(allowNotifyFrom); });
 
@@ -2233,7 +2233,7 @@ static int serviceMain(Logr::log_t log)
   }
   g_networkTimeoutMsec = ::arg().asNum("network-timeout");
 
-  std::tie(*g_initialDomainMap.lock(), g_initialAllowNotifyFor) = parseZoneConfiguration(g_yamlSettings);
+  std::tie(*g_initialDomainMap.lock(), *g_initialAllowNotifyFor.lock()) = parseZoneConfiguration(g_yamlSettings);
 
   g_latencyStatSize = ::arg().asNum("latency-statistic-size");
 
@@ -2834,9 +2834,9 @@ static void recursorThread()
     {
       SyncRes tmp(g_now); // make sure it allocates tsstorage before we do anything, like primeHints or so..
       SyncRes::setDomainMap(*g_initialDomainMap.lock());
-      t_allowFrom = g_initialAllowFrom;
-      t_allowNotifyFrom = g_initialAllowNotifyFrom;
-      t_allowNotifyFor = g_initialAllowNotifyFor;
+      t_allowFrom = *g_initialAllowFrom.lock();
+      t_allowNotifyFrom = *g_initialAllowNotifyFrom.lock();
+      t_allowNotifyFor = *g_initialAllowNotifyFor.lock();
       t_udpclientsocks = std::make_unique<UDPClientSocks>();
       t_tcpClientCounts = std::make_unique<tcpClientCounts_t>();
       if (g_proxyMapping) {
index 4effb058f28058157c94a9933a16fcbe1f7b6b1c..b1946b63e1a0f2f02bb87974209f5cdf21e71ca8 100644 (file)
@@ -229,9 +229,9 @@ extern uint32_t g_disthashseed;
 extern int g_argc;
 extern char** g_argv;
 extern LockGuarded<std::shared_ptr<SyncRes::domainmap_t>> g_initialDomainMap; // new threads needs this to be setup
-extern std::shared_ptr<NetmaskGroup> g_initialAllowFrom; // new thread needs to be setup with this
-extern std::shared_ptr<NetmaskGroup> g_initialAllowNotifyFrom; // new threads need this to be setup
-extern std::shared_ptr<notifyset_t> g_initialAllowNotifyFor; // new threads need this to be setup
+extern LockGuarded<std::shared_ptr<NetmaskGroup>> g_initialAllowFrom; // new thread needs to be setup with this
+extern LockGuarded<std::shared_ptr<NetmaskGroup>> g_initialAllowNotifyFrom; // new threads need this to be setup
+extern LockGuarded<std::shared_ptr<notifyset_t>> g_initialAllowNotifyFor; // new threads need this to be setup
 extern thread_local std::shared_ptr<Regex> t_traceRegex;
 extern thread_local FDWrapper t_tracefd;
 extern string g_programname;
index f892225d4e2f0689dd17158e72b4ffaae47bf6df..9410d7589f900ef267dc27c3f773afe02e5aa846 100644 (file)
@@ -219,6 +219,8 @@ string reloadZoneConfiguration(bool yaml)
     }
     extern LockGuarded<std::shared_ptr<SyncRes::domainmap_t>> g_initialDomainMap; // XXX
     *g_initialDomainMap.lock() = newDomainMap;
+    extern LockGuarded<std::shared_ptr<notifyset_t>> g_initialAllowNotifyFor; // XXX
+    *g_initialAllowNotifyFor.lock() = newNotifySet;
     return "ok\n";
   }
   catch (const std::exception& e) {
index 16b762b532cfc5bba8a467b6bd7cb04534d01ef4..6e0e51966f911137845e0edc300ee11311c7ff4c 100644 (file)
@@ -2,9 +2,7 @@
 TODO
 
 - Logging
-- Table based routing including OPTIONS request handling
 - ACLs of webserver
-- ACL handling; thread local does not work, see how domains are done
 - Authorization: metrics and plain files (and more?) are not subject to password auth
 - Allow multipe listen addreses in settings (singlevalued right now)
 - TLS?
@@ -55,22 +53,16 @@ fn compare_authorization(ctx: &Context, reqheaders: &header::HeaderMap) -> bool
             if lcase.starts_with(b"basic ") {
                 let cookie = &authorization.as_bytes()[6..];
                 if let Ok(plain) = BASE64_STANDARD.decode(cookie) {
-                    println!("plain {:?}", plain);
                     let mut split = plain.split(|i| *i == b':');
-                    println!("split {:?}", split);
                     if split.next().is_some() {
-                        println!("split {:?}", split);
                         if let Some(split) = split.next() {
-                            println!("split {:?}", split);
                             cxx::let_cxx_string!(s = &split);
                             auth_ok = ctx.password_ch.as_ref().unwrap().matches(&s);
-                            println!("OK4 {}", auth_ok);
                         }
                     }
                 }
             }
         }
-        println!("OK5 {}", auth_ok);
     } else {
         auth_ok = true;
     }
@@ -112,23 +104,20 @@ fn api_wrapper(
 
     // XXX AUDIT!
     let mut auth_ok = false;
-    println!("OK0 {}", auth_ok);
+
     if let Some(api) = reqheaders.get("x-api-key") {
         cxx::let_cxx_string!(s = &api.as_bytes());
         auth_ok = ctx.api_ch.as_ref().unwrap().matches(&s);
-        println!("OK1 {}", auth_ok);
     }
     if !auth_ok {
         for kv in &request.vars {
             cxx::let_cxx_string!(s = &kv.value);
             if kv.key == "x-api-key" && ctx.api_ch.as_ref().unwrap().matches(&s) {
                 auth_ok = true;
-                println!("OK2 {}", auth_ok);
                 break;
             }
         }
     }
-    println!("OK3 {}", auth_ok);
     if !auth_ok && allow_password {
         auth_ok = compare_authorization(ctx, reqheaders);
         if !auth_ok {
@@ -276,10 +265,8 @@ fn collect_options(path: &str, response: &mut rustweb::Response)
             vars: vec![],
             parameters: vec![],
         };
-        println!("MATCH? {}", path);
         matcher(&method, path, &mut apifunc, &mut rawfunc, &mut filefunc, &mut allow_password, &mut request);
         if apifunc.is_some() || rawfunc.is_some() /* || filefunc.is_some() */ {
-            println!("MATCH");
             methods.push(method.to_string());
         }
     }
@@ -415,7 +402,6 @@ async fn serveweb_async(listener: TcpListener, ctx: Arc<Context>) -> MyResult<()
                 eprintln!("Error serving connection: {:?}", err);
             }
         });
-        eprintln!("{}", ctx2.counter.lock().await);
     }
 }
 
index e5ac0e50dfb54e98dcf338f2f0b355047f80f161..d4449971fca7f0d75434fd62975543863cb026a3 100644 (file)
@@ -91,11 +91,13 @@ static void apiServerConfigACLGET(const std::string& aclType, HttpRequest* /* re
 {
   // Return currently configured ACLs
   vector<string> entries;
-  if (t_allowFrom && aclType == "allow-from") {
-    entries = t_allowFrom->toStringVector();
+  auto lock1 = g_initialAllowFrom.lock();
+  auto lock2 = g_initialAllowNotifyFrom.lock();
+  if (*lock1 && aclType == "allow-from") {
+      entries = (*lock1)->toStringVector();
   }
-  else if (t_allowNotifyFrom && aclType == "allow-notify-from") {
-    entries = t_allowNotifyFrom->toStringVector();
+  else if (*lock2 && aclType == "allow-notify-from") {
+    entries = (*lock2)->toStringVector();
   }
 
   resp->setJsonBody(Json::object{
@@ -183,6 +185,23 @@ static void apiServerConfigAllowNotifyFromPUT(HttpRequest* req, HttpResponse* re
   apiServerConfigACLPUT("allow-notify-from", req, resp);
 }
 
+static bool isAllowedNotify(DNSName qname)
+{
+  auto lock = g_initialAllowNotifyFor.lock();
+
+  if (*lock == nullptr || (*lock)->empty()) {
+    return false;
+  }
+
+  do {
+    auto ret = (*lock)->find(qname);
+    if (ret != (*lock)->end()) {
+      return true;
+    }
+  } while (qname.chopOff());
+  return false;
+}
+
 static void fillZone(const DNSName& zonename, HttpResponse* resp)
 {
   auto lock = g_initialDomainMap.lock();
@@ -216,7 +235,7 @@ static void fillZone(const DNSName& zonename, HttpResponse* resp)
     {"kind", zone.d_servers.empty() ? "Native" : "Forwarded"},
     {"servers", servers},
     {"recursion_desired", zone.d_servers.empty() ? false : zone.d_rdForward},
-    {"notify_allowed", isAllowNotifyForZone(zonename)},
+    {"notify_allowed", isAllowedNotify(zonename)},
     {"records", records}};
 
   resp->setJsonBody(doc);
@@ -444,8 +463,9 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp)
     throw ApiException("Query q can't be blank");
   }
 
+  auto lock = g_initialDomainMap.lock();
   Json::array doc;
-  for (const SyncRes::domainmap_t::value_type& val : *SyncRes::t_sstorage.domainmap) {
+  for (const SyncRes::domainmap_t::value_type& val : **lock) {
     string zoneId = apiZoneNameToId(val.first);
     string zoneName = val.first.toString();
     if (pdns_ci_find(zoneName, qVar) != string::npos) {