summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/acquire-item.cc95
-rw-r--r--apt-pkg/acquire-item.h2
-rw-r--r--apt-pkg/acquire-method.cc14
-rw-r--r--apt-pkg/acquire-method.h5
-rw-r--r--methods/rred.cc62
-rwxr-xr-xtest/integration/test-pdiff-usage2
6 files changed, 121 insertions, 59 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index ec6ec6e84..7b69ee993 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -95,6 +95,19 @@ static std::string GetCompressedFileName(std::string const &URI, std::string con
return Name;
}
/*}}}*/
+static std::string GetMergeDiffsPatchFileName(std::string const &Final, std::string const &Patch)/*{{{*/
+{
+ // rred expects the patch as $FinalFile.ed.$patchname.gz
+ return Final + ".ed." + Patch + ".gz";
+}
+ /*}}}*/
+static std::string GetDiffsPatchFileName(std::string const &Final) /*{{{*/
+{
+ // rred expects the patch as $FinalFile.ed
+ return Final + ".ed";
+}
+ /*}}}*/
+
static bool AllowInsecureRepositories(indexRecords const * const MetaIndexParser, pkgAcqMetaBase * const TransactionManager, pkgAcquire::Item * const I) /*{{{*/
{
if(MetaIndexParser->IsAlwaysTrusted() || _config->FindB("Acquire::AllowInsecureRepositories") == true)
@@ -1860,6 +1873,9 @@ void pkgAcqIndexDiffs::Failed(string const &Message,pkgAcquire::MethodConfig con
<< "Falling back to normal index file acquire" << std::endl;
DestFile = GetPartialFileNameFromURI(Target->URI);
RenameOnError(PDiffError);
+ std::string const patchname = GetDiffsPatchFileName(DestFile);
+ if (RealFileExists(patchname))
+ rename(patchname.c_str(), std::string(patchname + ".FAILED").c_str());
new pkgAcqIndex(Owner, TransactionManager, Target);
Finish();
}
@@ -1968,28 +1984,13 @@ void pkgAcqIndexDiffs::Done(string const &Message, HashStringList const &Hashes,
Item::Done(Message, Hashes, Cnf);
- // FIXME: verify this download too before feeding it to rred
std::string const FinalFile = GetPartialFileNameFromURI(Target->URI);
+ std::string const PatchFile = GetDiffsPatchFileName(FinalFile);
// success in downloading a diff, enter ApplyDiff state
if(State == StateFetchDiff)
{
- FileFd fd(DestFile, FileFd::ReadOnly, FileFd::Gzip);
- class Hashes LocalHashesCalc;
- LocalHashesCalc.AddFD(fd);
- HashStringList const LocalHashes = LocalHashesCalc.GetHashStringList();
-
- if (fd.Size() != available_patches[0].patch_size ||
- available_patches[0].patch_hashes != LocalHashes)
- {
- // patchfiles are dated, so bad indicates a bad download, so kill it
- unlink(DestFile.c_str());
- Failed("Patch has Size/Hashsum mismatch", NULL);
- return;
- }
-
- // rred excepts the patch as $FinalFile.ed
- Rename(DestFile,FinalFile+".ed");
+ Rename(DestFile, PatchFile);
if(Debug)
std::clog << "Sending to rred method: " << FinalFile << std::endl;
@@ -2000,18 +2001,17 @@ void pkgAcqIndexDiffs::Done(string const &Message, HashStringList const &Hashes,
QueueURI(Desc);
SetActiveSubprocess("rred");
return;
- }
-
+ }
// success in download/apply a diff, queue next (if needed)
if(State == StateApplyDiff)
{
// remove the just applied patch
available_patches.erase(available_patches.begin());
- unlink((FinalFile + ".ed").c_str());
+ unlink(PatchFile.c_str());
// move into place
- if(Debug)
+ if(Debug)
{
std::clog << "Moving patched file in place: " << std::endl
<< DestFile << " -> " << FinalFile << std::endl;
@@ -2031,6 +2031,18 @@ void pkgAcqIndexDiffs::Done(string const &Message, HashStringList const &Hashes,
}
}
/*}}}*/
+std::string pkgAcqIndexDiffs::Custom600Headers() const /*{{{*/
+{
+ if(State != StateApplyDiff)
+ return pkgAcqBaseIndex::Custom600Headers();
+ std::ostringstream patchhashes;
+ HashStringList const ExpectedHashes = available_patches[0].patch_hashes;
+ for (HashStringList::const_iterator hs = ExpectedHashes.begin(); hs != ExpectedHashes.end(); ++hs)
+ patchhashes << "\nPatch-0-" << hs->HashType() << "-Hash: " << hs->HashValue();
+ patchhashes << pkgAcqBaseIndex::Custom600Headers();
+ return patchhashes.str();
+}
+ /*}}}*/
// AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor /*{{{*/
pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire * const Owner,
@@ -2079,6 +2091,9 @@ void pkgAcqIndexMergeDiffs::Failed(string const &Message,pkgAcquire::MethodConfi
std::clog << "Falling back to normal index file acquire" << std::endl;
DestFile = GetPartialFileNameFromURI(Target->URI);
RenameOnError(PDiffError);
+ std::string const patchname = GetMergeDiffsPatchFileName(DestFile, patch.file);
+ if (RealFileExists(patchname))
+ rename(patchname.c_str(), std::string(patchname + ".FAILED").c_str());
new pkgAcqIndex(Owner, TransactionManager, Target);
}
/*}}}*/
@@ -2090,26 +2105,10 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha
Item::Done(Message, Hashes, Cnf);
- // FIXME: verify download before feeding it to rred
string const FinalFile = GetPartialFileNameFromURI(Target->URI);
-
if (State == StateFetchDiff)
{
- FileFd fd(DestFile, FileFd::ReadOnly, FileFd::Gzip);
- class Hashes LocalHashesCalc;
- LocalHashesCalc.AddFD(fd);
- HashStringList const LocalHashes = LocalHashesCalc.GetHashStringList();
-
- if (fd.Size() != patch.patch_size || patch.patch_hashes != LocalHashes)
- {
- // patchfiles are dated, so bad indicates a bad download, so kill it
- unlink(DestFile.c_str());
- Failed("Patch has Size/Hashsum mismatch", NULL);
- return;
- }
-
- // rred expects the patch as $FinalFile.ed.$patchname.gz
- Rename(DestFile, FinalFile + ".ed." + patch.file + ".gz");
+ Rename(DestFile, GetMergeDiffsPatchFileName(FinalFile, patch.file));
// check if this is the last completed diff
State = StateDoneDiff;
@@ -2158,7 +2157,7 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha
I != allPatches->end(); ++I)
{
std::string const PartialFile = GetPartialFileNameFromURI(Target->URI);
- std::string patch = PartialFile + ".ed." + (*I)->patch.file + ".gz";
+ std::string const patch = GetMergeDiffsPatchFileName(PartialFile, (*I)->patch.file);
unlink(patch.c_str());
}
unlink(FinalFile.c_str());
@@ -2170,6 +2169,24 @@ void pkgAcqIndexMergeDiffs::Done(string const &Message, HashStringList const &Ha
}
}
/*}}}*/
+std::string pkgAcqIndexMergeDiffs::Custom600Headers() const /*{{{*/
+{
+ if(State != StateApplyDiff)
+ return pkgAcqBaseIndex::Custom600Headers();
+ std::ostringstream patchhashes;
+ unsigned int seen_patches = 0;
+ for (std::vector<pkgAcqIndexMergeDiffs *>::const_iterator I = allPatches->begin();
+ I != allPatches->end(); ++I)
+ {
+ HashStringList const ExpectedHashes = (*I)->patch.patch_hashes;
+ for (HashStringList::const_iterator hs = ExpectedHashes.begin(); hs != ExpectedHashes.end(); ++hs)
+ patchhashes << "\nPatch-" << seen_patches << "-" << hs->HashType() << "-Hash: " << hs->HashValue();
+ ++seen_patches;
+ }
+ patchhashes << pkgAcqBaseIndex::Custom600Headers();
+ return patchhashes.str();
+}
+ /*}}}*/
// AcqIndex::AcqIndex - Constructor /*{{{*/
pkgAcqIndex::pkgAcqIndex(pkgAcquire * const Owner,
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index 97d5ea1dd..f24af1aec 100644
--- a/apt-pkg/acquire-item.h
+++ b/apt-pkg/acquire-item.h
@@ -774,6 +774,7 @@ class APT_HIDDEN pkgAcqIndexMergeDiffs : public pkgAcqBaseIndex
virtual void Failed(std::string const &Message,pkgAcquire::MethodConfig const * const Cnf);
virtual void Done(std::string const &Message, HashStringList const &Hashes,
pkgAcquire::MethodConfig const * const Cnf);
+ virtual std::string Custom600Headers() const;
virtual std::string DescURI() const {return Target->URI + "Index";};
virtual HashStringList GetExpectedHashes() const;
virtual bool HashesRequired() const;
@@ -886,6 +887,7 @@ class APT_HIDDEN pkgAcqIndexDiffs : public pkgAcqBaseIndex
virtual void Done(std::string const &Message, HashStringList const &Hashes,
pkgAcquire::MethodConfig const * const Cnf);
+ virtual std::string Custom600Headers() const;
virtual std::string DescURI() const {return Target->URI + "IndexDiffs";};
virtual HashStringList GetExpectedHashes() const;
virtual bool HashesRequired() const;
diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc
index b77096efd..a8fc75f8e 100644
--- a/apt-pkg/acquire-method.cc
+++ b/apt-pkg/acquire-method.cc
@@ -388,14 +388,14 @@ int pkgAcqMethod::Run(bool Single)
*I = Tmp;
if (QueueBack == 0)
QueueBack = Tmp;
-
+
// Notify that this item is to be fetched.
- if (Fetch(Tmp) == false)
+ if (URIAcquire(Message, Tmp) == false)
Fail();
-
- break;
- }
- }
+
+ break;
+ }
+ }
}
Exit();
@@ -403,8 +403,6 @@ int pkgAcqMethod::Run(bool Single)
}
/*}}}*/
// AcqMethod::PrintStatus - privately really send a log/status message /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void pkgAcqMethod::PrintStatus(char const * const header, const char* Format,
va_list &args) const
{
diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h
index 399454892..6480eb4b5 100644
--- a/apt-pkg/acquire-method.h
+++ b/apt-pkg/acquire-method.h
@@ -76,11 +76,12 @@ class pkgAcqMethod
std::string FailReason;
std::string UsedMirror;
std::string IP;
-
+
// Handlers for messages
virtual bool Configuration(std::string Message);
virtual bool Fetch(FetchItem * /*Item*/) {return true;};
-
+ virtual bool URIAcquire(std::string const &/*Message*/, FetchItem *Itm) { return Fetch(Itm); };
+
// Outgoing messages
void Fail(bool Transient = false);
inline void Fail(const char *Why, bool Transient = false) {Fail(std::string(Why),Transient);};
diff --git a/methods/rred.cc b/methods/rred.cc
index 554ac99b4..3da33c126 100644
--- a/methods/rred.cc
+++ b/methods/rred.cc
@@ -388,7 +388,7 @@ class Patch {
public:
- void read_diff(FileFd &f)
+ void read_diff(FileFd &f, Hashes * const h)
{
char buffer[BLOCK_SIZE];
bool cmdwanted = true;
@@ -396,6 +396,8 @@ class Patch {
Change ch(0);
while(f.ReadLine(buffer, sizeof(buffer)))
{
+ if (h != NULL)
+ h->Add(buffer);
if (cmdwanted) {
char *m, *c;
size_t s, e;
@@ -519,8 +521,29 @@ class RredMethod : public pkgAcqMethod {
private:
bool Debug;
+ struct PDiffFile {
+ std::string FileName;
+ HashStringList ExpectedHashes;
+ PDiffFile(std::string const &FileName, HashStringList const &ExpectedHashes) :
+ FileName(FileName), ExpectedHashes(ExpectedHashes) {}
+ };
+
+ HashStringList ReadExpectedHashesForPatch(unsigned int const patch, std::string const &Message)
+ {
+ HashStringList ExpectedHashes;
+ for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
+ {
+ std::string tagname;
+ strprintf(tagname, "Patch-%d-%s-Hash", patch, *type);
+ std::string const hashsum = LookupTag(Message, tagname.c_str());
+ if (hashsum.empty() == false)
+ ExpectedHashes.push_back(HashString(*type, hashsum));
+ }
+ return ExpectedHashes;
+ }
+
protected:
- virtual bool Fetch(FetchItem *Itm) {
+ virtual bool URIAcquire(std::string const &Message, FetchItem *Itm) {
Debug = _config->FindB("Debug::pkgAcquire::RRed", false);
URI Get = Itm->Uri;
std::string Path = Get.Host + Get.Path; // rred:/path - no host
@@ -534,11 +557,17 @@ class RredMethod : public pkgAcqMethod {
} else
URIStart(Res);
- std::vector<std::string> patchpaths;
+ std::vector<PDiffFile> patchfiles;
Patch patch;
if (FileExists(Path + ".ed") == true)
- patchpaths.push_back(Path + ".ed");
+ {
+ HashStringList const ExpectedHashes = ReadExpectedHashesForPatch(0, Message);
+ std::string const FileName = Path + ".ed";
+ if (ExpectedHashes.usable() == false)
+ return _error->Error("No hashes found for uncompressed patch: %s", FileName.c_str());
+ patchfiles.push_back(PDiffFile(FileName, ExpectedHashes));
+ }
else
{
_error->PushToStack();
@@ -546,18 +575,27 @@ class RredMethod : public pkgAcqMethod {
_error->RevertToStack();
std::string const baseName = Path + ".ed.";
+ unsigned int seen_patches = 0;
for (std::vector<std::string>::const_iterator p = patches.begin();
p != patches.end(); ++p)
+ {
if (p->compare(0, baseName.length(), baseName) == 0)
- patchpaths.push_back(*p);
+ {
+ HashStringList const ExpectedHashes = ReadExpectedHashesForPatch(seen_patches, Message);
+ if (ExpectedHashes.usable() == false)
+ return _error->Error("No hashes found for uncompressed patch %d: %s", seen_patches, p->c_str());
+ patchfiles.push_back(PDiffFile(*p, ExpectedHashes));
+ ++seen_patches;
+ }
+ }
}
std::string patch_name;
- for (std::vector<std::string>::iterator I = patchpaths.begin();
- I != patchpaths.end();
+ for (std::vector<PDiffFile>::iterator I = patchfiles.begin();
+ I != patchfiles.end();
++I)
{
- patch_name = *I;
+ patch_name = I->FileName;
if (Debug == true)
std::clog << "Patching " << Path << " with " << patch_name
<< std::endl;
@@ -569,8 +607,12 @@ class RredMethod : public pkgAcqMethod {
_error->DumpErrors(std::cerr);
abort();
}
- patch.read_diff(p);
+ Hashes patch_hash(I->ExpectedHashes);
+ patch.read_diff(p, &patch_hash);
p.Close();
+ HashStringList const hsl = patch_hash.GetHashStringList();
+ if (hsl != I->ExpectedHashes)
+ return _error->Error("Patch %s doesn't have the expected hashsum", patch_name.c_str());
}
if (Debug == true)
@@ -643,7 +685,7 @@ int main(int argc, char **argv)
_error->DumpErrors(std::cerr);
exit(1);
}
- patch.read_diff(p);
+ patch.read_diff(p, NULL);
}
if (just_diff) {
diff --git a/test/integration/test-pdiff-usage b/test/integration/test-pdiff-usage
index 7d72a6944..73df61895 100755
--- a/test/integration/test-pdiff-usage
+++ b/test/integration/test-pdiff-usage
@@ -170,6 +170,8 @@ SHA256-Patches:
generatereleasefiles '+1hour'
signreleasefiles
testsuccess aptget update "$@"
+ cp -f rootdir/tmp/testsuccess.output rootdir/tmp/aptgetupdate.output
+ testsuccess grep 'have the expected hashsum' rootdir/tmp/aptgetupdate.output
testnopackage oldstuff
testsuccessequal "$(cat ${PKGFILE}-new)
" aptcache show apt newstuff