From 02567e3084d2faec92e8bf248e89fda6452e634b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 9 Aug 2017 23:26:19 +0200 Subject: refactor message generation for methods The format isn't too hard to get right, but it gets funny with multiline fields (which we don't really have yet) and its just easier to deal with it once and for all which can be reused for more messages later. --- apt-pkg/acquire-method.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg/acquire-method.h') diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index 2de9cf5c2..fa22085b9 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -26,6 +26,7 @@ #include #include +#include #include #ifndef APT_8_CLEANER_HEADERS @@ -99,6 +100,7 @@ class pkgAcqMethod virtual void Fail(std::string Why, bool Transient = false); virtual void URIStart(FetchResult &Res); virtual void URIDone(FetchResult &Res,FetchResult *Alt = 0); + void SendMessage(std::string const &header, std::unordered_map &&fields); bool MediaFail(std::string Required,std::string Drive); virtual void Exit() {}; -- cgit v1.2.3-70-g09d2 From 04ab37fecaf286f724bef2e0969d2b67ab5ac1b1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 28 Oct 2017 00:01:27 +0200 Subject: require methods to request AuxRequest capability at startup Allowing a method to request work from other methods is a powerful capability which could be misused or exploited, so to slightly limited the surface let method opt-in into this capability on startup. --- apt-pkg/acquire-method.cc | 3 ++ apt-pkg/acquire-method.h | 14 ++++-- apt-pkg/acquire-worker.cc | 111 +++++++++++++++++++++++++++------------------- apt-pkg/acquire-worker.h | 3 ++ apt-pkg/acquire.cc | 23 +++++++--- apt-pkg/acquire.h | 8 +++- methods/mirror.cc | 2 +- 7 files changed, 107 insertions(+), 57 deletions(-) (limited to 'apt-pkg/acquire-method.h') diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc index 4e034b402..8934d87a0 100644 --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@ -76,6 +76,9 @@ pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags) if ((Flags & Removable) == Removable) try_emplace(fields, "Removable", "true"); + if ((Flags & AuxRequests) == AuxRequests) + try_emplace(fields, "AuxRequests", "true"); + SendMessage("100 Capabilities", std::move(fields)); SetNonBlock(STDIN_FILENO,true); diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index fa22085b9..664b95c18 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -108,10 +108,16 @@ class pkgAcqMethod void PrintStatus(char const * const header, const char* Format, va_list &args) const; public: - enum CnfFlags {SingleInstance = (1<<0), - Pipeline = (1<<1), SendConfig = (1<<2), - LocalOnly = (1<<3), NeedsCleanup = (1<<4), - Removable = (1<<5)}; + enum CnfFlags + { + SingleInstance = (1 << 0), + Pipeline = (1 << 1), + SendConfig = (1 << 2), + LocalOnly = (1 << 3), + NeedsCleanup = (1 << 4), + Removable = (1 << 5), + AuxRequests = (1 << 6) + }; void Log(const char *Format,...); void Status(const char *Format,...); diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 016aebdcd..6cbf8b7aa 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -508,6 +508,26 @@ bool pkgAcquire::Worker::RunMessages() _error->Error("Method gave invalid Aux Request message"); break; } + else if (Config->GetAuxRequests() == false) + { + std::vector const ItmOwners = Itm->Owners; + Message.append("\nMessage: Method tried to make an Aux Request while not being allowed to do them"); + OwnerQ->ItemDone(Itm); + Itm = nullptr; + HandleFailure(ItmOwners, Config, Log, Message, false, false); + ItemDone(); + + std::string Msg = "600 URI Acquire\n"; + Msg.reserve(200); + Msg += "URI: " + LookupTag(Message, "Aux-URI", ""); + Msg += "\nFilename: /nonexistent/auxrequest.blocked"; + Msg += "\n\n"; + if (Debug == true) + clog << " -> " << Access << ':' << QuoteString(Msg, "\n") << endl; + OutQueue += Msg; + OutReady = true; + break; + } auto maxsizestr = LookupTag(Message, "MaximumSize", ""); unsigned long long const MaxSize = maxsizestr.empty() ? 0 : strtoull(maxsizestr.c_str(), nullptr, 10); @@ -554,44 +574,7 @@ bool pkgAcquire::Worker::RunMessages() errAuthErr = std::find(std::begin(reasons), std::end(reasons), failReason) != std::end(reasons); } } - - for (auto const Owner: ItmOwners) - { - std::string NewURI; - if (errTransient == true && Config->LocalOnly == false && Owner->ModifyRetries() != 0) - { - --Owner->ModifyRetries(); - Owner->FailMessage(Message); - auto SavedDesc = Owner->GetItemDesc(); - if (Log != nullptr) - Log->Fail(SavedDesc); - if (isDoomedItem(Owner) == false) - OwnerQ->Owner->Enqueue(SavedDesc); - } - else if (Owner->PopAlternativeURI(NewURI)) - { - Owner->FailMessage(Message); - auto &desc = Owner->GetItemDesc(); - if (Log != nullptr) - Log->Fail(desc); - ChangeSiteIsMirrorChange(NewURI, desc, Owner); - desc.URI = NewURI; - if (isDoomedItem(Owner) == false) - OwnerQ->Owner->Enqueue(desc); - } - else - { - if (errAuthErr && Owner->GetExpectedHashes().empty() == false) - Owner->Status = pkgAcquire::Item::StatAuthError; - else if (errTransient) - Owner->Status = pkgAcquire::Item::StatTransientNetworkError; - auto SavedDesc = Owner->GetItemDesc(); - if (isDoomedItem(Owner) == false) - Owner->Failed(Message, Config); - if (Log != nullptr) - Log->Fail(SavedDesc); - } - } + HandleFailure(ItmOwners, Config, Log, Message, errTransient, errAuthErr); ItemDone(); break; @@ -609,6 +592,49 @@ bool pkgAcquire::Worker::RunMessages() return true; } /*}}}*/ +void pkgAcquire::Worker::HandleFailure(std::vector const &ItmOwners, /*{{{*/ + pkgAcquire::MethodConfig *const Config, pkgAcquireStatus *const Log, + std::string const &Message, bool const errTransient, bool const errAuthErr) +{ + for (auto const Owner : ItmOwners) + { + std::string NewURI; + if (errTransient == true && Config->LocalOnly == false && Owner->ModifyRetries() != 0) + { + --Owner->ModifyRetries(); + Owner->FailMessage(Message); + auto SavedDesc = Owner->GetItemDesc(); + if (Log != nullptr) + Log->Fail(SavedDesc); + if (isDoomedItem(Owner) == false) + OwnerQ->Owner->Enqueue(SavedDesc); + } + else if (Owner->PopAlternativeURI(NewURI)) + { + Owner->FailMessage(Message); + auto &desc = Owner->GetItemDesc(); + if (Log != nullptr) + Log->Fail(desc); + ChangeSiteIsMirrorChange(NewURI, desc, Owner); + desc.URI = NewURI; + if (isDoomedItem(Owner) == false) + OwnerQ->Owner->Enqueue(desc); + } + else + { + if (errAuthErr && Owner->GetExpectedHashes().empty() == false) + Owner->Status = pkgAcquire::Item::StatAuthError; + else if (errTransient) + Owner->Status = pkgAcquire::Item::StatTransientNetworkError; + auto SavedDesc = Owner->GetItemDesc(); + if (isDoomedItem(Owner) == false) + Owner->Failed(Message, Config); + if (Log != nullptr) + Log->Fail(SavedDesc); + } + } +} + /*}}}*/ // Worker::Capabilities - 100 Capabilities handler /*{{{*/ // --------------------------------------------------------------------- /* This parses the capabilities message and dumps it into the configuration @@ -625,18 +651,13 @@ bool pkgAcquire::Worker::Capabilities(string Message) Config->LocalOnly = StringToBool(LookupTag(Message,"Local-Only"),false); Config->NeedsCleanup = StringToBool(LookupTag(Message,"Needs-Cleanup"),false); Config->Removable = StringToBool(LookupTag(Message,"Removable"),false); + Config->SetAuxRequests(StringToBool(LookupTag(Message, "AuxRequests"), false)); // Some debug text if (Debug == true) { clog << "Configured access method " << Config->Access << endl; - clog << "Version:" << Config->Version << - " SingleInstance:" << Config->SingleInstance << - " Pipeline:" << Config->Pipeline << - " SendConfig:" << Config->SendConfig << - " LocalOnly: " << Config->LocalOnly << - " NeedsCleanup: " << Config->NeedsCleanup << - " Removable: " << Config->Removable << endl; + clog << "Version:" << Config->Version << " SingleInstance:" << Config->SingleInstance << " Pipeline:" << Config->Pipeline << " SendConfig:" << Config->SendConfig << " LocalOnly: " << Config->LocalOnly << " NeedsCleanup: " << Config->NeedsCleanup << " Removable: " << Config->Removable << " AuxRequests: " << Config->GetAuxRequests() << endl; } return true; diff --git a/apt-pkg/acquire-worker.h b/apt-pkg/acquire-worker.h index 3c5c1cef6..f04db2b3c 100644 --- a/apt-pkg/acquire-worker.h +++ b/apt-pkg/acquire-worker.h @@ -329,6 +329,9 @@ class pkgAcquire::Worker : public WeakPointable private: APT_HIDDEN void PrepareFiles(char const * const caller, pkgAcquire::Queue::QItem const * const Itm); + APT_HIDDEN void HandleFailure(std::vector const &ItmOwners, + pkgAcquire::MethodConfig *const Config, pkgAcquireStatus *const Log, + std::string const &Message, bool const errTransient, bool const errAuthErr); }; /** @} */ diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 5fa456ce3..b25a4434a 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -855,12 +855,25 @@ pkgAcquire::UriIterator pkgAcquire::UriEnd() } /*}}}*/ // Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgAcquire::MethodConfig::MethodConfig() : d(NULL), Next(0), SingleInstance(false), - Pipeline(false), SendConfig(false), LocalOnly(false), NeedsCleanup(false), - Removable(false) +class pkgAcquire::MethodConfig::Private +{ + public: + bool AuxRequests = false; +}; +pkgAcquire::MethodConfig::MethodConfig() : d(new Private()), Next(0), SingleInstance(false), + Pipeline(false), SendConfig(false), LocalOnly(false), NeedsCleanup(false), + Removable(false) +{ +} + /*}}}*/ +bool pkgAcquire::MethodConfig::GetAuxRequests() const /*{{{*/ +{ + return d->AuxRequests; +} + /*}}}*/ +void pkgAcquire::MethodConfig::SetAuxRequests(bool const value) /*{{{*/ { + d->AuxRequests = value; } /*}}}*/ // Queue::Queue - Constructor /*{{{*/ diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index e58aeef65..1cf4da5bf 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -636,9 +636,10 @@ class pkgAcquire::UriIterator /** \brief Information about the properties of a single acquire method. {{{*/ struct pkgAcquire::MethodConfig { + class Private; /** \brief dpointer placeholder (for later in case we need it) */ - void * const d; - + Private *const d; + /** \brief The next link on the acquire method list. * * \todo Why not an STL container? @@ -688,6 +689,9 @@ struct pkgAcquire::MethodConfig */ MethodConfig(); + APT_HIDDEN bool GetAuxRequests() const; + APT_HIDDEN void SetAuxRequests(bool const value); + virtual ~MethodConfig(); }; /*}}}*/ diff --git a/methods/mirror.cc b/methods/mirror.cc index ad8867836..ee703aaae 100644 --- a/methods/mirror.cc +++ b/methods/mirror.cc @@ -64,7 +64,7 @@ class MirrorMethod : public aptMethod /*{{{*/ void DealWithPendingItems(std::vector const &baseuris, MirrorInfo const &info, FetchItem *const Itm, std::function handler); public: - MirrorMethod(std::string &&pProg) : aptMethod(std::move(pProg), "2.0", SingleInstance | Pipeline | SendConfig) + MirrorMethod(std::string &&pProg) : aptMethod(std::move(pProg), "2.0", SingleInstance | Pipeline | SendConfig | AuxRequests) { SeccompFlags = aptMethod::BASE | aptMethod::DIRECTORY; -- cgit v1.2.3-70-g09d2