Desc.Owner = this;
Desc.ShortDesc = ShortDesc;
- if(available_patches.size() == 0)
+ if(available_patches.empty() == true)
{
// we are done (yeah!)
Finish(true);
string Final = _config->FindDir("Dir::State::lists");
Final += URItoFileName(RealURI);
- struct stat Buf;
- if (stat(Final.c_str(),&Buf) == 0)
+ if (RealFileExists(Final) == true)
{
// File was already in place. It needs to be re-downloaded/verified
// because Release might have changed, we do give it a differnt
}
QueueURI(Desc);
+}
+ /*}}}*/
+pkgAcqMetaSig::~pkgAcqMetaSig() /*{{{*/
+{
+ // if the file was never queued undo file-changes done in the constructor
+ if (QueueCounter == 1 && Status == StatIdle && FileSize == 0 && Complete == false &&
+ LastGoodSig.empty() == false)
+ {
+ string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
+ if (RealFileExists(Final) == false && RealFileExists(LastGoodSig) == true)
+ Rename(LastGoodSig, Final);
+ }
+
}
/*}}}*/
// pkgAcqMetaSig::Custom600Headers - Insert custom request headers /*{{{*/
string FinalFile = _config->FindDir("Dir::State::lists");
FinalFile += URItoFileName(RealURI);
if (SigFile == DestFile)
+ {
SigFile = FinalFile;
+ // 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);
+ }
DestFile = FinalFile;
}
Complete = true;
{
HashString ExpectedIndexHash;
const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
+ bool compressedAvailable = false;
if (Record == NULL)
{
- if (verify == true && (*Target)->IsOptional() == false)
+ if ((*Target)->IsOptional() == true)
+ {
+ std::vector<std::string> types = APT::Configuration::getCompressionTypes();
+ for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
+ if (MetaIndexParser->Exists(string((*Target)->MetaKey).append(".").append(*t)) == true)
+ {
+ compressedAvailable = true;
+ break;
+ }
+ }
+ else if (verify == true)
{
Status = StatAuthError;
strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str());
if ((*Target)->IsSubIndex() == true)
new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description,
(*Target)->ShortDesc, ExpectedIndexHash);
- else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true)
+ else if (transInRelease == false || Record != NULL || compressedAvailable == true)
{
- new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
+ if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
+ MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true)
+ new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
+ (*Target)->ShortDesc, ExpectedIndexHash);
+ else
+ new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
}
continue;
}
if (AuthPass == true)
{
// gpgv method failed, if we have a good signature
- string LastGoodSigFile = _config->FindDir("Dir::State::lists");
- if (DestFile == SigFile)
- LastGoodSigFile.append(URItoFileName(RealURI));
- else
- LastGoodSigFile.append("partial/").append(URItoFileName(RealURI)).append(".gpg.reverify");
+ string LastGoodSigFile = _config->FindDir("Dir::State::lists").append("partial/").append(URItoFileName(RealURI));
+ if (DestFile != SigFile)
+ LastGoodSigFile.append(".gpg");
+ LastGoodSigFile.append(".reverify");
if(FileExists(LastGoodSigFile))
{
+ string VerifiedSigFile = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
if (DestFile != SigFile)
- {
- string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
- URItoFileName(RealURI) + ".gpg";
- Rename(LastGoodSigFile,VerifiedSigFile);
- }
+ VerifiedSigFile.append(".gpg");
+ Rename(LastGoodSigFile, VerifiedSigFile);
Status = StatTransientNetworkError;
- _error->Warning(_("A error occurred during the signature "
+ _error->Warning(_("An error occurred during the signature "
"verification. The repository is not updated "
"and the previous index files will be used. "
"GPG error: %s: %s\n"),
MetaSigURI(MetaSigURI), MetaSigURIDesc(MetaSigURIDesc), MetaSigShortDesc(MetaSigShortDesc)
{
SigFile = DestFile;
+
+ // 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);
+ }
+}
+ /*}}}*/
+pkgAcqMetaClearSig::~pkgAcqMetaClearSig() /*{{{*/
+{
+ // 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);
+ }
}
/*}}}*/
// pkgAcqMetaClearSig::Custom600Headers - Insert custom request headers /*{{{*/
struct stat Buf;
if (stat(Final.c_str(),&Buf) != 0)
- return "\nIndex-File: true\nFail-Ignore: true\n";
+ {
+ Final = DestFile + ".reverify";
+ if (stat(Final.c_str(),&Buf) != 0)
+ return "\nIndex-File: true\nFail-Ignore: true\n";
+ }
return "\nIndex-File: true\nFail-Ignore: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
}
{
if (AuthPass == false)
{
+ // Remove the 'old' InRelease file if we try Release.gpg now as otherwise
+ // the file will stay around and gives a false-auth impression (CVE-2012-0214)
+ string FinalFile = _config->FindDir("Dir::State::lists");
+ FinalFile.append(URItoFileName(RealURI));
+ if (FileExists(FinalFile))
+ unlink(FinalFile.c_str());
+
new pkgAcqMetaSig(Owner,
MetaSigURI, MetaSigURIDesc, MetaSigShortDesc,
MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
assumption here that all the available sources for this version share
the same extension.. */
// Skip not source sources, they do not have file fields.
- for (; Vf.end() == false; Vf++)
+ for (; Vf.end() == false; ++Vf)
{
if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0)
continue;
{
if(stringcasecmp(ForceHash, "sha512") == 0)
ExpectedHash = HashString("SHA512", Parse.SHA512Hash());
- if(stringcasecmp(ForceHash, "sha256") == 0)
+ else if(stringcasecmp(ForceHash, "sha256") == 0)
ExpectedHash = HashString("SHA256", Parse.SHA256Hash());
else if (stringcasecmp(ForceHash, "sha1") == 0)
ExpectedHash = HashString("SHA1", Parse.SHA1Hash());
else
PartialSize = Buf.st_size;
}
-
+
+ // Disables download of archives - useful if no real installation follows,
+ // e.g. if we are just interested in proposed installation order
+ if (_config->FindB("Debug::pkgAcqArchive::NoQueue", false) == true)
+ {
+ Complete = true;
+ Local = true;
+ Status = StatDone;
+ StoreFilename = DestFile = FinalFile;
+ return true;
+ }
+
// Create the item
Local = false;
Desc.URI = Index->ArchiveURI(PkgFile);