summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2017-10-28 00:01:27 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2018-01-03 19:42:45 +0100
commit04ab37fecaf286f724bef2e0969d2b67ab5ac1b1 (patch)
tree99b25e7a854dc79b8f5398a7c34ea95109ca333e
parent57fa854e4cdb060e87ca265abd5a83364f9fa681 (diff)
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.
-rw-r--r--apt-pkg/acquire-method.cc3
-rw-r--r--apt-pkg/acquire-method.h14
-rw-r--r--apt-pkg/acquire-worker.cc111
-rw-r--r--apt-pkg/acquire-worker.h3
-rw-r--r--apt-pkg/acquire.cc23
-rw-r--r--apt-pkg/acquire.h8
-rw-r--r--methods/mirror.cc2
7 files changed, 107 insertions, 57 deletions
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<Item *> 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<pkgAcquire::Item *> 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<pkgAcquire::Item *> 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<std::string> const &baseuris, MirrorInfo const &info, FetchItem *const Itm, std::function<void()> 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;