diff options
Diffstat (limited to 'methods')
-rw-r--r-- | methods/basehttp.cc | 24 | ||||
-rw-r--r-- | methods/basehttp.h | 3 | ||||
-rw-r--r-- | methods/gpgv.cc | 59 |
3 files changed, 45 insertions, 41 deletions
diff --git a/methods/basehttp.cc b/methods/basehttp.cc index 3d95ba7df..f8dd7c020 100644 --- a/methods/basehttp.cc +++ b/methods/basehttp.cc @@ -39,6 +39,10 @@ string BaseHttpMethod::FailFile; int BaseHttpMethod::FailFd = -1; time_t BaseHttpMethod::FailTime = 0; +// Number of successful requests in a pipeline needed to continue +// pipelining after a connection reset. +constexpr int PIPELINE_MIN_SUCCESSFUL_ANSWERS_TO_CONTINUE = 3; + // ServerState::RunHeaders - Get the headers before the data /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 if things are OK, 1 if an IO error occurred and 2 if a header @@ -215,8 +219,11 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/ /* Some servers send error pages (as they are dynamically generated) for simplicity via a connection close instead of e.g. chunked, so assuming an always closing server only if we get a file + close */ - if (Result >= 200 && Result < 300) + if (Result >= 200 && Result < 300 && Server->PipelineAnswersReceived < PIPELINE_MIN_SUCCESSFUL_ANSWERS_TO_CONTINUE) + { Server->PipelineAllowed = false; + Server->PipelineAnswersReceived = 0; + } } else if (stringcasecmp(Val,"keep-alive") == 0) Server->Persistent = true; @@ -267,6 +274,7 @@ void ServerState::Reset() /*{{{*/ Pipeline = false; PipelineAllowed = true; RangesAllowed = true; + PipelineAnswersReceived = 0; } /*}}}*/ @@ -593,8 +601,10 @@ int BaseHttpMethod::Loop() Server->Close(); // Reset the pipeline - if (Server->IsOpen() == false) + if (Server->IsOpen() == false) { QueueBack = Queue; + Server->PipelineAnswersReceived = 0; + } // Connect to the host switch (Server->Open()) @@ -752,6 +762,10 @@ int BaseHttpMethod::Loop() BeforeI = I; } } + if (Server->Pipeline == true) + { + Server->PipelineAnswersReceived++; + } Res.TakeHashes(*resultHashes); URIDone(Res); } @@ -861,9 +875,9 @@ unsigned long long BaseHttpMethod::FindMaximumObjectSizeInQueue() const /*{{{*/ return MaxSizeInQueue; } /*}}}*/ -BaseHttpMethod::BaseHttpMethod(std::string &&Binary, char const * const Ver,unsigned long const Flags) :/*{{{*/ - aptAuthConfMethod(std::move(Binary), Ver, Flags), Server(nullptr), PipelineDepth(10), - AllowRedirect(false), Debug(false) +BaseHttpMethod::BaseHttpMethod(std::string &&Binary, char const *const Ver, unsigned long const Flags) /*{{{*/ + : aptAuthConfMethod(std::move(Binary), Ver, Flags), Server(nullptr), + AllowRedirect(false), Debug(false), PipelineDepth(10) { } /*}}}*/ diff --git a/methods/basehttp.h b/methods/basehttp.h index 8220c1b3c..5fdff69e0 100644 --- a/methods/basehttp.h +++ b/methods/basehttp.h @@ -67,6 +67,7 @@ struct ServerState bool Persistent; bool PipelineAllowed; bool RangesAllowed; + unsigned long PipelineAnswersReceived; bool Pipeline; URI ServerName; @@ -122,7 +123,6 @@ class BaseHttpMethod : public aptAuthConfMethod std::unique_ptr<ServerState> Server; std::string NextURI; - unsigned long PipelineDepth; bool AllowRedirect; // Find the biggest item in the fetch queue for the checking of the maximum @@ -131,6 +131,7 @@ class BaseHttpMethod : public aptAuthConfMethod public: bool Debug; + unsigned long PipelineDepth; /** \brief Result of the header parsing */ enum DealWithHeadersResult { diff --git a/methods/gpgv.cc b/methods/gpgv.cc index 8de15c48a..84b8c3e59 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -94,7 +94,10 @@ struct Signer { std::string note; }; static bool IsTheSameKey(std::string const &validsig, std::string const &goodsig) { - // VALIDSIG reports a keyid (40 = 24 + 16), GOODSIG is a longid (16) only + // VALIDSIG reports a fingerprint (40 = 24 + 16), GOODSIG can be longid (16) or + // fingerprint according to documentation in DETAILS.gz + if (goodsig.length() == 40 + strlen("GOODSIG ")) + return validsig.compare(0, 40, goodsig, strlen("GOODSIG "), 40) == 0; return validsig.compare(24, 16, goodsig, strlen("GOODSIG "), 16) == 0; } @@ -254,46 +257,32 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, if (keyIsID == true) { if (Debug == true) - std::clog << "GoodSigs needs to be limited to keyid " << key << std::endl; - bool foundGood = false; - for (auto const &k: VectorizeString(key, ',')) + std::clog << "GoodSigs needs to be limited to keyid(s) " << key << std::endl; + auto const limitedTo = VectorizeString(key, ','); + std::vector<std::string> filteredGood; + for (auto &&good: GoodSigners) { - if (std::find(ValidSigners.begin(), ValidSigners.end(), k) == ValidSigners.end()) - continue; - // we look for GOODSIG here as well as an expired sig is a valid sig as well (but not a good one) - std::string const goodfingerprint = "GOODSIG " + k; - std::string const goodlongkeyid = "GOODSIG " + k.substr(24, 16); - foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodfingerprint) != GoodSigners.end(); if (Debug == true) - std::clog << "Key " << k << " is valid sig, is " << goodfingerprint << " also a good one? " << (foundGood ? "yes" : "no") << std::endl; - std::string goodsig; - if (foundGood == false) + std::clog << "Key " << good << " is good sig, is it also a valid and allowed one? "; + bool found = false; + for (auto const &l : limitedTo) { - foundGood = std::find(GoodSigners.begin(), GoodSigners.end(), goodlongkeyid) != GoodSigners.end(); - if (Debug == true) - std::clog << "Key " << k << " is valid sig, is " << goodlongkeyid << " also a good one? " << (foundGood ? "yes" : "no") << std::endl; - goodsig = goodlongkeyid; + if (IsTheSameKey(l, good) == false) + continue; + // GOODSIG might be "just" a longid, so we check VALIDSIG which is always a fingerprint + if (std::find(ValidSigners.begin(), ValidSigners.end(), l) == ValidSigners.end()) + continue; + found = true; + break; } + if (Debug) + std::clog << (found ? "yes" : "no") << "\n"; + if (found) + filteredGood.emplace_back(std::move(good)); else - goodsig = goodfingerprint; - if (foundGood == false) - continue; - std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator<std::vector<std::string> >(NoPubKeySigners)); - GoodSigners.clear(); - GoodSigners.push_back(goodsig); - NoPubKeySigners.erase( - std::remove(NoPubKeySigners.begin(), - std::remove(NoPubKeySigners.begin(), NoPubKeySigners.end(), goodfingerprint), - goodlongkeyid), - NoPubKeySigners.end() - ); - break; - } - if (foundGood == false) - { - std::copy(GoodSigners.begin(), GoodSigners.end(), std::back_insert_iterator<std::vector<std::string> >(NoPubKeySigners)); - GoodSigners.clear(); + NoPubKeySigners.emplace_back(std::move(good)); } + GoodSigners = std::move(filteredGood); } int status; |