Browse Source

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.
tags/debian/1.6_alpha6
David Kalnischkies 4 years ago
parent
commit
04ab37feca
7 changed files with 107 additions and 57 deletions
  1. +3
    -0
      apt-pkg/acquire-method.cc
  2. +10
    -4
      apt-pkg/acquire-method.h
  3. +66
    -45
      apt-pkg/acquire-worker.cc
  4. +3
    -0
      apt-pkg/acquire-worker.h
  5. +18
    -5
      apt-pkg/acquire.cc
  6. +6
    -2
      apt-pkg/acquire.h
  7. +1
    -1
      methods/mirror.cc

+ 3
- 0
apt-pkg/acquire-method.cc View File

@@ -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);


+ 10
- 4
apt-pkg/acquire-method.h View File

@@ -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,...);


+ 66
- 45
apt-pkg/acquire-worker.cc View File

@@ -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;


+ 3
- 0
apt-pkg/acquire-worker.h View File

@@ -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);
};

/** @} */


+ 18
- 5
apt-pkg/acquire.cc View File

@@ -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 /*{{{*/


+ 6
- 2
apt-pkg/acquire.h View File

@@ -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();
};
/*}}}*/


+ 1
- 1
methods/mirror.cc View File

@@ -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;



Loading…
Cancel
Save