From: Otto Moerbeek Date: Wed, 27 Nov 2024 15:50:24 +0000 (+0100) Subject: API regression test succeed now, mostly setting right headers X-Git-Tag: dnsdist-2.0.0-alpha1~95^2~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6846c009dc873f0cf7e20eeab2dc3fd717e15d90;p=thirdparty%2Fpdns.git API regression test succeed now, mostly setting right headers --- diff --git a/pdns/credentials.cc b/pdns/credentials.cc index 062155326f..ddc5add19b 100644 --- a/pdns/credentials.cc +++ b/pdns/credentials.cc @@ -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) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index bd71181692..f1758e7082 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -112,9 +112,9 @@ boost::optional g_dns64Prefix{boost::none}; DNSName g_dns64PrefixReverse; unsigned int g_maxChainLength; LockGuarded> g_initialDomainMap; // new threads needs this to be setup -std::shared_ptr g_initialAllowFrom; // new thread needs to be setup with this -std::shared_ptr g_initialAllowNotifyFrom; // new threads need this to be setup -std::shared_ptr g_initialAllowNotifyFor; // new threads need this to be setup +LockGuarded> g_initialAllowFrom; // new thread needs to be setup with this +LockGuarded> g_initialAllowNotifyFrom; // new threads need this to be setup +LockGuarded> g_initialAllowNotifyFor; // new threads need this to be setup bool g_logRPZChanges{false}; static time_t s_statisticsInterval; static std::atomic 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(); t_tcpClientCounts = std::make_unique(); if (g_proxyMapping) { diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 4effb058f2..b1946b63e1 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -229,9 +229,9 @@ extern uint32_t g_disthashseed; extern int g_argc; extern char** g_argv; extern LockGuarded> g_initialDomainMap; // new threads needs this to be setup -extern std::shared_ptr g_initialAllowFrom; // new thread needs to be setup with this -extern std::shared_ptr g_initialAllowNotifyFrom; // new threads need this to be setup -extern std::shared_ptr g_initialAllowNotifyFor; // new threads need this to be setup +extern LockGuarded> g_initialAllowFrom; // new thread needs to be setup with this +extern LockGuarded> g_initialAllowNotifyFrom; // new threads need this to be setup +extern LockGuarded> g_initialAllowNotifyFor; // new threads need this to be setup extern thread_local std::shared_ptr t_traceRegex; extern thread_local FDWrapper t_tracefd; extern string g_programname; diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index f892225d4e..9410d7589f 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -219,6 +219,8 @@ string reloadZoneConfiguration(bool yaml) } extern LockGuarded> g_initialDomainMap; // XXX *g_initialDomainMap.lock() = newDomainMap; + extern LockGuarded> g_initialAllowNotifyFor; // XXX + *g_initialAllowNotifyFor.lock() = newNotifySet; return "ok\n"; } catch (const std::exception& e) { diff --git a/pdns/recursordist/settings/rust/src/web.rs b/pdns/recursordist/settings/rust/src/web.rs index 16b762b532..6e0e51966f 100644 --- a/pdns/recursordist/settings/rust/src/web.rs +++ b/pdns/recursordist/settings/rust/src/web.rs @@ -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) -> MyResult<() eprintln!("Error serving connection: {:?}", err); } }); - eprintln!("{}", ctx2.counter.lock().await); } } diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index e5ac0e50df..d4449971fc 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -91,11 +91,13 @@ static void apiServerConfigACLGET(const std::string& aclType, HttpRequest* /* re { // Return currently configured ACLs vector 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) {