break;
}
return false;
+}
+ /*}}}*/
+void pkgAcquire::Item::SetActiveSubprocess(const std::string &subprocess)/*{{{*/
+{
+ ActiveSubprocess = subprocess;
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+ Mode = ActiveSubprocess.c_str();
+#if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+#endif
}
/*}}}*/
// Acquire::Item::ReportMirrorFailure /*{{{*/
Item::Done(Message, Size, Hashes, Cnf);
// verify the index target
- if(Target && Target->MetaKey != "" && MetaIndexParser && Hashes.size() > 0)
+ if(Target && Target->MetaKey != "" && MetaIndexParser && Hashes.usable())
{
std::string IndexMetaKey = Target->MetaKey + ".diff/Index";
indexRecords::checkSum *Record = MetaIndexParser->Lookup(IndexMetaKey);
}
+ if(!ParseDiffIndex(DestFile))
+ return Failed("", NULL);
+
+ // queue for final move
string FinalFile;
FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI);
-
- // success in downloading the index
- // rename the index
FinalFile += string(".IndexDiff");
- if(Debug)
- std::clog << "Renaming: " << DestFile << " -> " << FinalFile
- << std::endl;
- Rename(DestFile,FinalFile);
- chmod(FinalFile.c_str(),0644);
- DestFile = FinalFile;
-
- if(!ParseDiffIndex(DestFile))
- return Failed("", NULL);
+ TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
Complete = true;
Status = StatDone;
Local = true;
Desc.URI = "rred:" + FinalFile;
QueueURI(Desc);
- ActiveSubprocess = "rred";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- Mode = "rred";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic pop
-#endif
+ SetActiveSubprocess("rred");
return;
}
Local = true;
Desc.URI = "rred:" + FinalFile;
QueueURI(Desc);
- ActiveSubprocess = "rred";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- Mode = "rred";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic pop
-#endif
+ SetActiveSubprocess("rred");
return;
}
// success in download/apply all diffs, clean up
}
}
/*}}}*/
-
// AcqBaseIndex::VerifyHashByMetaKey - verify hash for the given metakey /*{{{*/
bool pkgAcqBaseIndex::VerifyHashByMetaKey(HashStringList const &Hashes)
{
- if(MetaKey != "" && Hashes.size() > 0)
+ if(MetaKey != "" && Hashes.usable())
{
indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
if(Record && Record->Hashes.usable() && Hashes != Record->Hashes)
}
return true;
}
-
-
+ /*}}}*/
// AcqIndex::AcqIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
-/* The package file is added to the queue and a second class is
- instantiated to fetch the revision file */
+/* The package file is added to the queue and a second class is
+ instantiated to fetch the revision file */
pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
string URI,string URIDesc,string ShortDesc,
HashStringList const &ExpectedHash)
}
/*}}}*/
// AcqIndex::AcqIndex - Constructor /*{{{*/
-// ---------------------------------------------------------------------
pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
pkgAcqMetaBase *TransactionManager,
IndexTarget const *Target,
- HashStringList const &ExpectedHash,
+ HashStringList const &ExpectedHash,
indexRecords *MetaIndexParser)
- : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash,
+ : pkgAcqBaseIndex(Owner, TransactionManager, Target, ExpectedHash,
MetaIndexParser)
{
RealURI = Target->URI;
}
/*}}}*/
// AcqIndex::AutoSelectCompression - Select compression /*{{{*/
-// ---------------------------------------------------------------------
void pkgAcqIndex::AutoSelectCompression()
{
std::vector<std::string> types = APT::Configuration::getCompressionTypes();
t != types.end(); ++t)
{
std::string CompressedMetaKey = string(Target->MetaKey).append(".").append(*t);
- if (*t == "uncompressed" ||
+ if (*t == "uncompressed" ||
MetaIndexParser->Exists(CompressedMetaKey) == true)
CompressionExtensions.append(*t).append(" ");
}
if (CompressionExtensions.empty() == false)
CompressionExtensions.erase(CompressionExtensions.end()-1);
}
+ /*}}}*/
// AcqIndex::Init - defered Constructor /*{{{*/
-// ---------------------------------------------------------------------
-void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
+void pkgAcqIndex::Init(string const &URI, string const &URIDesc,
string const &ShortDesc)
{
Stage = STAGE_DOWNLOAD;
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
DestFile += URItoFileName(URI);
- ComprExt = CompressionExtensions.substr(0, CompressionExtensions.find(' '));
- if (ComprExt == "uncompressed")
+ CurrentCompressionExtension = CompressionExtensions.substr(0, CompressionExtensions.find(' '));
+ if (CurrentCompressionExtension == "uncompressed")
{
Desc.URI = URI;
if(Target)
}
else
{
- Desc.URI = URI + '.' + ComprExt;
- DestFile = DestFile + '.' + ComprExt;
+ Desc.URI = URI + '.' + CurrentCompressionExtension;
+ DestFile = DestFile + '.' + CurrentCompressionExtension;
if(Target)
- MetaKey = string(Target->MetaKey) + '.' + ComprExt;
+ MetaKey = string(Target->MetaKey) + '.' + CurrentCompressionExtension;
}
// load the filesize
indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
if(Record)
FileSize = Record->Size;
-
+
InitByHashIfNeeded(MetaKey);
}
}
/*}}}*/
// AcqIndex::AdjustForByHash - modify URI for by-hash support /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void pkgAcqIndex::InitByHashIfNeeded(const std::string MetaKey)
{
// TODO:
string pkgAcqIndex::Custom600Headers() const
{
string Final = GetFinalFilename();
-
+
string msg = "\nIndex-File: true";
struct stat Buf;
if (stat(Final.c_str(),&Buf) == 0)
return msg;
}
/*}}}*/
-// pkgAcqIndex::Failed - getting the indexfile failed /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
+// pkgAcqIndex::Failed - getting the indexfile failed /*{{{*/
+void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
{
size_t const nextExt = CompressionExtensions.find(' ');
if (nextExt != std::string::npos)
// on decompression failure, remove bad versions in partial/
if (Stage == STAGE_DECOMPRESS_AND_VERIFY)
{
- string s = _config->FindDir("Dir::State::lists") + "partial/";
- s += URItoFileName(RealURI) + '.' + ComprExt;
- unlink(s.c_str());
+ unlink(EraseFileName.c_str());
}
Item::Failed(Message,Cnf);
TransactionManager->AbortTransaction();
}
/*}}}*/
-// pkgAcqIndex::GetFinalFilename - Return the full final file path /*{{{*/
-// ---------------------------------------------------------------------
-/* */
+// pkgAcqIndex::GetFinalFilename - Return the full final file path /*{{{*/
std::string pkgAcqIndex::GetFinalFilename() const
{
std::string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
if (_config->FindB("Acquire::GzipIndexes",false) == true)
- FinalFile += '.' + ComprExt;
+ FinalFile += '.' + CurrentCompressionExtension;
return FinalFile;
}
- /*}}}*/
-// AcqIndex::ReverifyAfterIMS - Reverify index after an ims-hit /*{{{*/
-// ---------------------------------------------------------------------
-/* */
+ /*}}}*/
+// AcqIndex::ReverifyAfterIMS - Reverify index after an ims-hit /*{{{*/
void pkgAcqIndex::ReverifyAfterIMS()
{
// update destfile to *not* include the compression extension when doing
// adjust DestFile if its compressed on disk
if (_config->FindB("Acquire::GzipIndexes",false) == true)
- DestFile += '.' + ComprExt;
+ DestFile += '.' + CurrentCompressionExtension;
// copy FinalFile into partial/ so that we check the hash again
string FinalFile = GetFinalFilename();
Desc.URI = "copy:" + FinalFile;
QueueURI(Desc);
}
- /*}}}*/
-
-// AcqIndex::ValidateFile - Validate the content of the downloaded file /*{{{*/
-// --------------------------------------------------------------------------
+ /*}}}*/
+// AcqIndex::ValidateFile - Validate the content of the downloaded file /*{{{*/
bool pkgAcqIndex::ValidateFile(const std::string &FileName)
{
// FIXME: this can go away once we only ever download stuff that
}
return true;
}
- /*}}}*/
+ /*}}}*/
// AcqIndex::Done - Finished a fetch /*{{{*/
// ---------------------------------------------------------------------
/* This goes through a number of states.. On the initial fetch the
break;
}
}
-
-// AcqIndex::StageDownloadDone - Queue for decompress and verify /*{{{*/
+ /*}}}*/
+// AcqIndex::StageDownloadDone - Queue for decompress and verify /*{{{*/
void pkgAcqIndex::StageDownloadDone(string Message,
HashStringList const &Hashes,
pkgAcquire::MethodConfig *Cfg)
}
Complete = true;
-
+
// Handle the unzipd case
string FileName = LookupTag(Message,"Alt-Filename");
if (FileName.empty() == false)
DestFile += ".decomp";
Desc.URI = "copy:" + FileName;
QueueURI(Desc);
- ActiveSubprocess = "copy";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- Mode = "copy";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic pop
-#endif
+ SetActiveSubprocess("copy");
return;
}
// not the "DestFile" we set, in this case we uncompress from the local file
if (FileName != DestFile)
Local = true;
+ else
+ EraseFileName = FileName;
// we need to verify the file against the current Release file again
// on if-modfied-since hit to avoid a stale attack against us
return;
// The files timestamp matches, reverify by copy into partial/
+ EraseFileName = "";
ReverifyAfterIMS();
return;
}
if (_config->FindB("Acquire::GzipIndexes",false))
{
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
- DestFile += URItoFileName(RealURI) + '.' + ComprExt;
-
+ DestFile += URItoFileName(RealURI) + '.' + CurrentCompressionExtension;
+ EraseFileName = "";
Stage = STAGE_DECOMPRESS_AND_VERIFY;
Desc.URI = "copy:" + FileName;
QueueURI(Desc);
// get the binary name for your used compression type
string decompProg;
- if(ComprExt == "uncompressed")
+ if(CurrentCompressionExtension == "uncompressed")
decompProg = "copy";
else
- decompProg = _config->Find(string("Acquire::CompressionTypes::").append(ComprExt),"");
+ decompProg = _config->Find(string("Acquire::CompressionTypes::").append(CurrentCompressionExtension),"");
if(decompProg.empty() == true)
{
- _error->Error("Unsupported extension: %s", ComprExt.c_str());
+ _error->Error("Unsupported extension: %s", CurrentCompressionExtension.c_str());
return;
}
Desc.URI = decompProg + ":" + FileName;
QueueURI(Desc);
- ActiveSubprocess = decompProg;
-#if __GNUC__ >= 4
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- Mode = ActiveSubprocess.c_str();
-#if __GNUC__ >= 4
- #pragma GCC diagnostic pop
-#endif
+ SetActiveSubprocess(decompProg);
}
- /*}}}*/
-// pkgAcqIndex::StageDecompressDone - Final verification /*{{{*/
+ /*}}}*/
+// pkgAcqIndex::StageDecompressDone - Final verification /*{{{*/
void pkgAcqIndex::StageDecompressDone(string Message,
HashStringList const &Hashes,
pkgAcquire::MethodConfig *Cfg)
Failed(Message, Cfg);
return;
}
-
- // remove the compressed version of the file (if the file got uncompressed)
- URI Get = LookupTag(Message, "URI");
- if (Get.Access != "copy")
- {
- // To account for relative paths
- std::string CompressedFile = Get.Host + Get.Path;
- unlink(CompressedFile.c_str());
- }
-
+
+ // remove the compressed version of the file
+ unlink(EraseFileName.c_str());
+
// Done, queue for rename on transaction finished
TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
-
+
return;
}
- /*}}}*/
/*}}}*/
// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The Translation file is added to the queue */
pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
- string URI,string URIDesc,string ShortDesc)
+ string URI,string URIDesc,string ShortDesc)
: pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashStringList())
{
}
- /*}}}*/
-pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
- pkgAcqMetaBase *TransactionManager,
+pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
+ pkgAcqMetaBase *TransactionManager,
IndexTarget const * const Target,
- HashStringList const &ExpectedHashes,
+ HashStringList const &ExpectedHashes,
indexRecords *MetaIndexParser)
: pkgAcqIndex(Owner, TransactionManager, Target, ExpectedHashes, MetaIndexParser)
{
}
/*}}}*/
// AcqIndexTrans::Custom600Headers - Insert custom request headers /*{{{*/
-// ---------------------------------------------------------------------
string pkgAcqIndexTrans::Custom600Headers() const
{
string Final = GetFinalFilename();
}
/*}}}*/
// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
{
size_t const nextExt = CompressionExtensions.find(' ');
}
// FIXME: this is used often (e.g. in pkgAcqIndexTrans) so refactor
- if (Cnf->LocalOnly == true ||
+ if (Cnf->LocalOnly == true ||
StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
- {
+ {
// Ignore this
Status = StatDone;
Complete = false;
Item::Failed(Message,Cnf);
}
/*}}}*/
-
+// AcqMetaBase::Add - Add a item to the current Transaction /*{{{*/
void pkgAcqMetaBase::Add(Item *I)
{
Transaction.push_back(I);
}
-
+ /*}}}*/
+// AcqMetaBase::AbortTransaction - Abort the current Transaction /*{{{*/
void pkgAcqMetaBase::AbortTransaction()
{
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
}
}
/*}}}*/
+// AcqMetaBase::TransactionHasError - Check for errors in Transaction /*{{{*/
bool pkgAcqMetaBase::TransactionHasError()
{
for (pkgAcquire::ItemIterator I = Transaction.begin();
return false;
}
-// Acquire::CommitTransaction - Commit a transaction /*{{{*/
+ /*}}}*/
+// AcqMetaBase::CommitTransaction - Commit a transaction /*{{{*/
void pkgAcqMetaBase::CommitTransaction()
{
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
(*I)->TransactionManager = 0;
}
}
-
+ /*}}}*/
+// AcqMetaBase::TransactionStageCopy - Stage a file for copying /*{{{*/
void pkgAcqMetaBase::TransactionStageCopy(Item *I,
const std::string &From,
const std::string &To)
I->PartialFile = From;
I->DestFile = To;
}
-
+ /*}}}*/
+// AcqMetaBase::TransactionStageRemoval - Sage a file for removal /*{{{*/
void pkgAcqMetaBase::TransactionStageRemoval(Item *I,
const std::string &FinalFile)
{
I->PartialFile = "";
I->DestFile = FinalFile;
}
-
-
- /*{{{*/
-bool pkgAcqMetaBase::GenerateAuthWarning(const std::string &RealURI,
- const std::string &Message)
+ /*}}}*/
+// AcqMetaBase::GenerateAuthWarning - Check gpg authentication error /*{{{*/
+bool pkgAcqMetaBase::CheckStopAuthentication(const std::string &RealURI,
+ const std::string &Message)
{
+ // FIXME: this entire function can do now that we disallow going to
+ // a unauthenticated state and can cleanly rollback
+
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
-
+
if(FileExists(Final))
{
Status = StatTransientNetworkError;
Desc.Description.c_str(),
LookupTag(Message,"Message").c_str());
}
- // gpgv method failed
+ // gpgv method failed
ReportMirrorFailure("GPGFailure");
return false;
}
/*}}}*/
-
-
-pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
+// AcqMetaSig::AcqMetaSig - Constructor /*{{{*/
+pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
pkgAcqMetaBase *TransactionManager,
string URI,string URIDesc,string ShortDesc,
string MetaIndexFile,
const vector<IndexTarget*>* IndexTargets,
indexRecords* MetaIndexParser) :
- pkgAcqMetaBase(Owner, IndexTargets, MetaIndexParser,
+ pkgAcqMetaBase(Owner, IndexTargets, MetaIndexParser,
HashStringList(), TransactionManager),
RealURI(URI), MetaIndexFile(MetaIndexFile), URIDesc(URIDesc),
ShortDesc(ShortDesc)
{
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
- DestFile += URItoFileName(URI);
+ DestFile += URItoFileName(RealURI);
- // remove any partial downloaded sig-file in partial/.
- // it may confuse proxies and is too small to warrant a
+ // remove any partial downloaded sig-file in partial/.
+ // it may confuse proxies and is too small to warrant a
// partial download anyway
unlink(DestFile.c_str());
/*}}}*/
// pkgAcqMetaSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
-/* The only header we use is the last-modified header. */
string pkgAcqMetaSig::Custom600Headers() const
{
string FinalFile = _config->FindDir("Dir::State::lists");
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
-
-void pkgAcqMetaSig::Done(string Message,unsigned long long Size, HashStringList const &Hashes,
+ /*}}}*/
+// pkgAcqMetaSig::Done - The signature was downloaded/verified /*{{{*/
+// ---------------------------------------------------------------------
+/* The only header we use is the last-modified header. */
+void pkgAcqMetaSig::Done(string Message,unsigned long long Size,
+ HashStringList const &Hashes,
pkgAcquire::MethodConfig *Cfg)
{
Item::Done(Message, Size, Hashes, Cfg);
- string FileName = LookupTag(Message,"Filename");
- if (FileName.empty() == true)
- {
- Status = StatError;
- ErrorText = "Method gave a blank filename";
- return;
- }
-
- if (FileName != DestFile)
- {
- // We have to copy it into place
- Local = true;
- Desc.URI = "copy:" + FileName;
- QueueURI(Desc);
- return;
- }
-
- if(StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
- IMSHit = true;
-
- // adjust paths if its a ims-hit
- if(IMSHit)
- {
- string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(RealURI);
-
- TransactionManager->TransactionStageCopy(this, FinalFile, FinalFile);
- }
-
- // queue for verify
if(AuthPass == false)
{
- AuthPass = true;
- Desc.URI = "gpgv:" + DestFile;
- DestFile = MetaIndexFile;
- QueueURI(Desc);
+ if(CheckDownloadDone(Message, RealURI) == true)
+ {
+ // destfile will be modified to point to MetaIndexFile for the
+ // gpgv method, so we need to save it here
+ MetaIndexFileSignature = DestFile;
+ QueueForSignatureVerify(MetaIndexFile, MetaIndexFileSignature);
+ }
return;
}
-
- // queue to copy the file in place if it was not a ims hit, on ims
- // hit the file is already at the right place
- if(IMSHit == false)
- {
- PartialFile = _config->FindDir("Dir::State::lists") + "partial/";
- PartialFile += URItoFileName(RealURI);
-
- std::string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(RealURI);
-
- TransactionManager->TransactionStageCopy(this, PartialFile, FinalFile);
- }
-
- // we parse the MetaIndexFile here because at this point we can
- // trust the data
- if(AuthPass == true)
+ else
{
- // load indexes and queue further downloads
- MetaIndexParser->Load(MetaIndexFile);
- QueueIndexes(true);
+ if(CheckAuthDone(Message, RealURI) == true)
+ {
+ std::string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile += URItoFileName(RealURI);
+ TransactionManager->TransactionStageCopy(this, MetaIndexFileSignature, FinalFile);
+ }
}
-
- Complete = true;
}
/*}}}*/
void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
{
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- // FIXME: duplicated code from pkgAcqMetaIndex
- if (AuthPass == true)
- {
- bool Stop = GenerateAuthWarning(RealURI, Message);
- if(Stop)
+ // check if we need to fail at this point
+ if (AuthPass == true && CheckStopAuthentication(RealURI, Message))
return;
- }
// FIXME: meh, this is not really elegant
string InReleaseURI = RealURI.replace(RealURI.rfind("Release.gpg"), 12,
Init(URIDesc, ShortDesc);
}
/*}}}*/
-// pkgAcqMetaIndex::Init - Delayed constructor /*{{{*/
+// pkgAcqMetaIndex::Init - Delayed constructor /*{{{*/
void pkgAcqMetaIndex::Init(std::string URIDesc, std::string ShortDesc)
{
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
ExpectedAdditionalItems = IndexTargets->size();
QueueURI(Desc);
}
+ /*}}}*/
// pkgAcqMetaIndex::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
-/* The only header we use is the last-modified header. */
string pkgAcqMetaIndex::Custom600Headers() const
{
string Final = _config->FindDir("Dir::State::lists");
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
/*}}}*/
-void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,HashStringList const &Hashes, /*{{{*/
+void pkgAcqMetaIndex::Done(string Message,unsigned long long Size, /*{{{*/
+ HashStringList const &Hashes,
pkgAcquire::MethodConfig *Cfg)
{
Item::Done(Message,Size,Hashes,Cfg);
- // MetaIndexes are done in two passes: one to download the
- // metaindex with an appropriate method, and a second to verify it
- // with the gpgv method
-
- if (AuthPass == true)
+ if(CheckDownloadDone(Message, RealURI))
{
- AuthDone(Message);
+ // we have a Release file, now download the Signature, all further
+ // verify/queue for additional downloads will be done in the
+ // pkgAcqMetaSig::Done() code
+ std::string MetaIndexFile = DestFile;
+ new pkgAcqMetaSig(Owner, TransactionManager,
+ MetaIndexSigURI, MetaIndexSigURIDesc,
+ MetaIndexSigShortDesc, MetaIndexFile, IndexTargets,
+ MetaIndexParser);
- // all cool, move Release file into place
- Complete = true;
+ string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile += URItoFileName(RealURI);
+ TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
}
- else
- {
- RetrievalDone(Message);
- if (!Complete)
- // Still more retrieving to do
- return;
+}
+ /*}}}*/
+bool pkgAcqMetaBase::CheckAuthDone(string Message, const string &RealURI) /*{{{*/
+{
+ // At this point, the gpgv method has succeeded, so there is a
+ // valid signature from a key in the trusted keyring. We
+ // perform additional verification of its contents, and use them
+ // to verify the indexes we are about to download
- if (SigFile != "")
- {
- // There was a signature file, so pass it to gpgv for
- // verification
- if (_config->FindB("Debug::pkgAcquire::Auth", false))
- std::cerr << "Metaindex acquired, queueing gpg verification ("
- << SigFile << "," << DestFile << ")\n";
- AuthPass = true;
- Desc.URI = "gpgv:" + SigFile;
- QueueURI(Desc);
- ActiveSubprocess = "gpgv";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- Mode = "gpgv";
-#if __GNUC__ >= 4
- #pragma GCC diagnostic pop
-#endif
- return;
- }
+ if (!MetaIndexParser->Load(DestFile))
+ {
+ Status = StatAuthError;
+ ErrorText = MetaIndexParser->ErrorText;
+ return false;
}
- if (Complete == true)
+ if (!VerifyVendor(Message, RealURI))
{
- string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(RealURI);
- if (SigFile == DestFile)
- SigFile = FinalFile;
-
- // queue for copy in place
- TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
+ return false;
}
+
+ if (_config->FindB("Debug::pkgAcquire::Auth", false))
+ std::cerr << "Signature verification succeeded: "
+ << DestFile << std::endl;
+
+ // Download further indexes with verification
+ //
+ // it would be really nice if we could simply do
+ // if (IMSHit == false) QueueIndexes(true)
+ // and skip the download if the Release file has not changed
+ // - but right now the list cleaner will needs to be tricked
+ // to not delete all our packages/source indexes in this case
+ QueueIndexes(true);
+
+ return true;
+}
+ /*}}}*/
+ /*{{{*/
+void pkgAcqMetaBase::QueueForSignatureVerify(const std::string &MetaIndexFile,
+ const std::string &MetaIndexFileSignature)
+{
+ AuthPass = true;
+ Desc.URI = "gpgv:" + MetaIndexFileSignature;
+ DestFile = MetaIndexFile;
+ QueueURI(Desc);
+ SetActiveSubprocess("gpgv");
}
/*}}}*/
-void pkgAcqMetaIndex::RetrievalDone(string Message) /*{{{*/
+ /*{{{*/
+bool pkgAcqMetaBase::CheckDownloadDone(const std::string &Message,
+ const std::string &RealURI)
{
// We have just finished downloading a Release file (it is not
// verified yet)
{
Status = StatError;
ErrorText = "Method gave a blank filename";
- return;
+ return false;
}
if (FileName != DestFile)
Local = true;
Desc.URI = "copy:" + FileName;
QueueURI(Desc);
- return;
+ return false;
}
// make sure to verify against the right file on I-M-S hit
{
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
- if (SigFile == DestFile)
- {
- SigFile = FinalFile;
-#if 0
- // constructor of pkgAcqMetaClearSig moved it out of the way,
- // now move it back in on IMS hit for the 'old' file
- string const OldClearSig = DestFile + ".reverify";
- if (RealFileExists(OldClearSig) == true)
- Rename(OldClearSig, FinalFile);
-#endif
- }
DestFile = FinalFile;
}
- // queue a signature
- if(SigFile != DestFile)
- new pkgAcqMetaSig(Owner, TransactionManager,
- MetaIndexSigURI, MetaIndexSigURIDesc,
- MetaIndexSigShortDesc, DestFile, IndexTargets,
- MetaIndexParser);
-
+ // set Item to complete as the remaining work is all local (verify etc)
Complete = true;
-}
- /*}}}*/
-void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/
-{
- // At this point, the gpgv method has succeeded, so there is a
- // valid signature from a key in the trusted keyring. We
- // perform additional verification of its contents, and use them
- // to verify the indexes we are about to download
- if (!MetaIndexParser->Load(DestFile))
- {
- Status = StatAuthError;
- ErrorText = MetaIndexParser->ErrorText;
- return;
- }
-
- if (!VerifyVendor(Message))
- {
- return;
- }
-
- if (_config->FindB("Debug::pkgAcquire::Auth", false))
- std::cerr << "Signature verification succeeded: "
- << DestFile << std::endl;
-
-// we ensure this by other means
-#if 0
- // do not trust any previously unverified content that we may have
- string LastGoodSigFile = _config->FindDir("Dir::State::lists").append("partial/").append(URItoFileName(RealURI));
- if (DestFile != SigFile)
- LastGoodSigFile.append(".gpg");
- LastGoodSigFile.append(".reverify");
- if(IMSHit == false && RealFileExists(LastGoodSigFile) == false)
- {
- for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
- Target != IndexTargets->end();
- ++Target)
- {
- // remove old indexes
- std::string index = _config->FindDir("Dir::State::lists") +
- URItoFileName((*Target)->URI);
- unlink(index.c_str());
- // and also old gzipindexes
- std::vector<std::string> types = APT::Configuration::getCompressionTypes();
- for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
- {
- index += '.' + (*t);
- unlink(index.c_str());
- }
- }
- }
-#endif
-
- // Download further indexes with verification
- //
- // it would be really nice if we could simply do
- // if (IMSHit == false) QueueIndexes(true)
- // and skip the download if the Release file has not changed
- // - but right now the list cleaner will needs to be tricked
- // to not delete all our packages/source indexes in this case
- QueueIndexes(true);
-
-#if 0
- // is it a clearsigned MetaIndex file?
- if (DestFile == SigFile)
- return;
-
- // Done, move signature file into position
- string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(RealURI) + ".gpg";
- Rename(SigFile,VerifiedSigFile);
- chmod(VerifiedSigFile.c_str(),0644);
-#endif
+ return true;
}
/*}}}*/
void pkgAcqMetaBase::QueueIndexes(bool verify) /*{{{*/
}
}
/*}}}*/
-bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/
+bool pkgAcqMetaBase::VerifyVendor(string Message, const string &RealURI)/*{{{*/
{
string::size_type pos;
return true;
}
/*}}}*/
-// pkgAcqMetaIndex::Failed - no Release file present or no signature file present /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void pkgAcqMetaIndex::Failed(string Message,
+// pkgAcqMetaIndex::Failed - no Release file present /*{{{*/
+void pkgAcqMetaIndex::Failed(string /*Message*/,
pkgAcquire::MethodConfig * /*Cnf*/)
{
- string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ string FinalFile = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- if (AuthPass == true)
- {
- bool Stop = GenerateAuthWarning(RealURI, Message);
- if(Stop)
- return;
- }
+ _error->Warning(_("The repository '%s' does not have a Release file. "
+ "This is deprecated, please contact the owner of the "
+ "repository."), URIDesc.c_str());
- /* Always move the meta index, even if gpgv failed. This ensures
- * that PackageFile objects are correctly filled in */
- if (FileExists(DestFile))
- {
- string FinalFile = _config->FindDir("Dir::State::lists");
- FinalFile += URItoFileName(RealURI);
- /* InRelease files become Release files, otherwise
- * they would be considered as trusted later on */
- if (SigFile == DestFile) {
- RealURI = RealURI.replace(RealURI.rfind("InRelease"), 9,
- "Release");
- FinalFile = FinalFile.replace(FinalFile.rfind("InRelease"), 9,
- "Release");
- SigFile = FinalFile;
- }
-
- // Done, queue for rename on transaction finished
- TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
- }
-
- _error->Warning(_("The data from '%s' is not signed. Packages "
- "from that repository can not be authenticated."),
- URIDesc.c_str());
-
- // No Release file was present, or verification failed, so fall
+ // No Release file was present so fall
// back to queueing Packages files without verification
// only allow going further if the users explicitely wants it
if(_config->FindB("Acquire::AllowInsecureRepositories") == true)
{
+ // Done, queue for rename on transaction finished
+ if (FileExists(DestFile))
+ TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
+
+ // queue without any kind of hashsum support
QueueIndexes(false);
} else {
// warn if the repository is unsinged
_error->Warning("Use --allow-insecure-repositories to force the update");
- }
+ TransactionManager->AbortTransaction();
+ Status = StatError;
+ return;
+ }
}
/*}}}*/
-
-void pkgAcqMetaIndex::Finished()
+void pkgAcqMetaIndex::Finished() /*{{{*/
{
if(_config->FindB("Debug::Acquire::Transaction", false) == true)
std::clog << "Finished: " << DestFile <<std::endl;
TransactionManager->TransactionHasError() == false)
TransactionManager->CommitTransaction();
}
-
-
+ /*}}}*/
pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner, /*{{{*/
string const &URI, string const &URIDesc, string const &ShortDesc,
string const &MetaIndexURI, string const &MetaIndexURIDesc, string const &MetaIndexShortDesc,
MetaIndexURI(MetaIndexURI), MetaIndexURIDesc(MetaIndexURIDesc), MetaIndexShortDesc(MetaIndexShortDesc),
MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc)
{
- SigFile = DestFile;
-
// index targets + (worst case:) Release/Release.gpg
ExpectedAdditionalItems = IndexTargets->size() + 2;
-#if 0
- // keep the old InRelease around in case of transistent network errors
- string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- if (RealFileExists(Final) == true)
- {
- string const LastGoodSig = DestFile + ".reverify";
- Rename(Final,LastGoodSig);
- }
-#endif
}
/*}}}*/
pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/
{
-#if 0
- // if the file was never queued undo file-changes done in the constructor
- if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false)
- {
- string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
- string const LastGoodSig = DestFile + ".reverify";
- if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
- Rename(LastGoodSig, Final);
- }
-#endif
}
/*}}}*/
// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/
// ---------------------------------------------------------------------
-// FIXME: this can go away once the InRelease file is used widely
string pkgAcqMetaClearSig::Custom600Headers() const
{
string Final = _config->FindDir("Dir::State::lists");
/*}}}*/
// pkgAcqMetaClearSig::Done - We got a file /*{{{*/
// ---------------------------------------------------------------------
-void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long Size,
- HashStringList const &Hashes,
+void pkgAcqMetaClearSig::Done(std::string Message,unsigned long long /*Size*/,
+ HashStringList const &/*Hashes*/,
pkgAcquire::MethodConfig *Cnf)
{
// if we expect a ClearTextSignature (InRelase), ensure that
TransactionManager->AbortTransaction();
return;
}
- pkgAcqMetaIndex::Done(Message, Size, Hashes, Cnf);
+
+ if(AuthPass == false)
+ {
+ if(CheckDownloadDone(Message, RealURI) == true)
+ QueueForSignatureVerify(DestFile, DestFile);
+ return;
+ }
+ else
+ {
+ if(CheckAuthDone(Message, RealURI) == true)
+ {
+ string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile += URItoFileName(RealURI);
+
+ // queue for copy in place
+ TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
+ }
+ }
}
/*}}}*/
void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
Dequeue();
}
else
- pkgAcqMetaIndex::Failed(Message, Cnf);
+ {
+ if(CheckStopAuthentication(RealURI, Message))
+ return;
+
+ _error->Warning(_("The data from '%s' is not signed. Packages "
+ "from that repository can not be authenticated."),
+ URIDesc.c_str());
+
+ // No Release file was present, or verification failed, so fall
+ // back to queueing Packages files without verification
+ // only allow going further if the users explicitely wants it
+ if(_config->FindB("Acquire::AllowInsecureRepositories") == true)
+ {
+ /* Always move the meta index, even if gpgv failed. This ensures
+ * that PackageFile objects are correctly filled in */
+ if (FileExists(DestFile))
+ {
+ string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile += URItoFileName(RealURI);
+ /* InRelease files become Release files, otherwise
+ * they would be considered as trusted later on */
+ RealURI = RealURI.replace(RealURI.rfind("InRelease"), 9,
+ "Release");
+ FinalFile = FinalFile.replace(FinalFile.rfind("InRelease"), 9,
+ "Release");
+
+
+ // Done, queue for rename on transaction finished
+ TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
+ }
+ QueueIndexes(false);
+ } else {
+ // warn if the repository is unsinged
+ _error->Warning("Use --allow-insecure-repositories to force the update");
+ TransactionManager->AbortTransaction();
+ Status = StatError;
+ return;
+ }
+ }
}
/*}}}*/
// AcqArchive::AcqArchive - Constructor /*{{{*/