summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2017-04-12 17:39:06 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2017-06-28 19:18:47 +0200
commit081fbea14d12f79c8d91ce4fe1f1004c7bc08656 (patch)
treedbb551e6a7878f482ccd7790dfe512927df672c5 /apt-pkg
parentcbaf353ead58aa9eefe51542b6ad91e69b6289ce (diff)
error in update on Release information changes
The value of Origin, Label, Codename and co can be used in user configuration from apts own pinning to unattended upgrades. A repository changing this values can therefore have serious effects on the behaviour of apt and other tools using these values. In a first step we will generate error messages for these changes now explaining the need for explicit confirmation and provide config options and commandline flags to accept them.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc60
-rw-r--r--apt-pkg/deb/debmetaindex.cc19
-rw-r--r--apt-pkg/metaindex.cc32
-rw-r--r--apt-pkg/metaindex.h13
4 files changed, 115 insertions, 9 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 574ef4939..f5ff8288b 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -1605,13 +1605,63 @@ bool pkgAcqMetaBase::VerifyVendor(string const &) /*{{{*/
if (TransactionManager->MetaIndexParser->CheckDist(ExpectedDist) == false)
_error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
Desc.Description.c_str(), ExpectedDist.c_str(), NowCodename.c_str());
- // might be okay, might be not
+
+ // changed info potentially breaks user config like pinning
if (TransactionManager->LastMetaIndexParser != nullptr)
{
- auto const LastCodename = TransactionManager->LastMetaIndexParser->GetCodename();
- if (LastCodename.empty() == false && NowCodename.empty() == false && LastCodename != NowCodename)
- _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
- Desc.Description.c_str(), LastCodename.c_str(), NowCodename.c_str());
+ auto const AllowInfoChange = _config->FindB("Acquire::AllowReleaseInfoChange", false);
+ auto const quietInfoChange = _config->FindB("quiet::ReleaseInfoChange", false);
+ struct {
+ char const * const Type;
+ bool const Allowed;
+ decltype(&metaIndex::GetOrigin) const Getter;
+ } checkers[] = {
+ { "Origin", AllowInfoChange, &metaIndex::GetOrigin },
+ { "Label", AllowInfoChange, &metaIndex::GetLabel },
+ { "Version", true, &metaIndex::GetVersion }, // numbers change all the time, that is okay
+ { "Suite", AllowInfoChange, &metaIndex::GetSuite },
+ { "Codename", AllowInfoChange, &metaIndex::GetCodename },
+ { nullptr, false, nullptr }
+ };
+ auto const CheckReleaseInfo = [&](char const * const Type, bool const AllowChange, decltype(checkers[0].Getter) const Getter) {
+ std::string const Last = (TransactionManager->LastMetaIndexParser->*Getter)();
+ std::string const Now = (TransactionManager->MetaIndexParser->*Getter)();
+ if (Last == Now)
+ return true;
+ auto const Allow = _config->FindB(std::string("Acquire::AllowReleaseInfoChange::").append(Type), AllowChange);
+ auto const msg = _("Repository '%s' changed its '%s' value from '%s' to '%s'");
+ if (Allow == false)
+ _error->Error(msg, Desc.Description.c_str(), Type, Last.c_str(), Now.c_str());
+ else if (_config->FindB(std::string("quiet::ReleaseInfoChange::").append(Type), quietInfoChange) == false)
+ _error->Notice(msg, Desc.Description.c_str(), Type, Last.c_str(), Now.c_str());
+ return Allow;
+ };
+ bool CRI = true;
+ for (short i = 0; checkers[i].Type != nullptr; ++i)
+ if (CheckReleaseInfo(checkers[i].Type, checkers[i].Allowed, checkers[i].Getter) == false)
+ CRI = false;
+
+ {
+ auto const Last = TransactionManager->LastMetaIndexParser->GetDefaultPin();
+ auto const Now = TransactionManager->MetaIndexParser->GetDefaultPin();
+ if (Last != Now)
+ {
+ auto const Allow = _config->FindB("Acquire::AllowReleaseInfoChange::DefaultPin", AllowInfoChange);
+ auto const msg = _("Repository '%s' changed its default priority for %s from %hi to %hi.");
+ if (Allow == false)
+ _error->Error(msg, Desc.Description.c_str(), "apt_preferences(5)", Last, Now);
+ else if (_config->FindB("quiet::ReleaseInfoChange::DefaultPin", quietInfoChange) == false)
+ _error->Notice(msg, Desc.Description.c_str(), "apt_preferences(5)", Last, Now);
+ CRI &= Allow;
+ }
+ }
+ if (CRI == false)
+ {
+ // TRANSLATOR: %s is the name of the manpage in question, e.g. apt-secure(8)
+ _error->Notice(_("This must be accepted explicitly before updates for "
+ "this repository can be applied. See %s manpage for details."), "apt-secure(8)");
+ return false;
+ }
}
return true;
}
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 8c82414cb..424ef08f6 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -393,6 +393,9 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
// FIXME: find better tag name
SupportsAcquireByHash = Section.FindB("Acquire-By-Hash", false);
+ SetOrigin(Section.FindS("Origin"));
+ SetLabel(Section.FindS("Label"));
+ SetVersion(Section.FindS("Version"));
Suite = Section.FindS("Suite");
Codename = Section.FindS("Codename");
{
@@ -415,6 +418,20 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
else // e.g. security.debian.org uses this style
d->SupportedComponents.push_back(comp.substr(pos + 1));
}
+ {
+ decltype(pkgCache::ReleaseFile::Flags) flags = 0;
+ Section.FindFlag("NotAutomatic", flags, pkgCache::Flag::NotAutomatic);
+ signed short defaultpin = 500;
+ if ((flags & pkgCache::Flag::NotAutomatic) == pkgCache::Flag::NotAutomatic)
+ {
+ Section.FindFlag("ButAutomaticUpgrades", flags, pkgCache::Flag::ButAutomaticUpgrades);
+ if ((flags & pkgCache::Flag::ButAutomaticUpgrades) == pkgCache::Flag::ButAutomaticUpgrades)
+ defaultpin = 100;
+ else
+ defaultpin = 1;
+ }
+ SetDefaultPin(defaultpin);
+ }
bool FoundHashSum = false;
bool FoundStrongHashSum = false;
@@ -472,7 +489,6 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
if (CheckValidUntil == true)
{
- std::string const Label = Section.FindS("Label");
std::string const StrValidUntil = Section.FindS("Valid-Until");
// if we have a Valid-Until header in the Release file, use it as default
@@ -485,6 +501,7 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
return false;
}
}
+ auto const Label = GetLabel();
// get the user settings for this archive and use what expires earlier
time_t MaxAge = d->ValidUntilMax;
if (MaxAge == 0)
diff --git a/apt-pkg/metaindex.cc b/apt-pkg/metaindex.cc
index 624c7c9c7..8765851d6 100644
--- a/apt-pkg/metaindex.cc
+++ b/apt-pkg/metaindex.cc
@@ -9,6 +9,16 @@
#include <vector>
/*}}}*/
+class metaIndexPrivate /*{{{*/
+{
+ public:
+ std::string Origin;
+ std::string Label;
+ std::string Version;
+ signed short DefaultPin;
+};
+ /*}}}*/
+
std::string metaIndex::Describe() const
{
return "Release";
@@ -26,7 +36,7 @@ bool metaIndex::Merge(pkgCacheGenerator &Gen,OpProgress *) const
metaIndex::metaIndex(std::string const &URI, std::string const &Dist,
char const * const Type)
-: d(NULL), Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(TRI_UNSET),
+: d(new metaIndexPrivate()), Indexes(NULL), Type(Type), URI(URI), Dist(Dist), Trusted(TRI_UNSET),
Date(0), ValidUntil(0), SupportsAcquireByHash(false), LoadedSuccessfully(TRI_UNSET)
{
/* nothing */
@@ -43,6 +53,7 @@ metaIndex::~metaIndex()
}
for (auto const &E: Entries)
delete E.second;
+ delete d;
}
// one line Getters for public fields /*{{{*/
@@ -51,8 +62,12 @@ APT_PURE std::string metaIndex::GetDist() const { return Dist; }
APT_PURE const char* metaIndex::GetType() const { return Type; }
APT_PURE metaIndex::TriState metaIndex::GetTrusted() const { return Trusted; }
APT_PURE std::string metaIndex::GetSignedBy() const { return SignedBy; }
+APT_PURE std::string metaIndex::GetOrigin() const { return d->Origin; }
+APT_PURE std::string metaIndex::GetLabel() const { return d->Label; }
+APT_PURE std::string metaIndex::GetVersion() const { return d->Version; }
APT_PURE std::string metaIndex::GetCodename() const { return Codename; }
APT_PURE std::string metaIndex::GetSuite() const { return Suite; }
+APT_PURE signed short metaIndex::GetDefaultPin() const { return d->DefaultPin; }
APT_PURE bool metaIndex::GetSupportsAcquireByHash() const { return SupportsAcquireByHash; }
APT_PURE time_t metaIndex::GetValidUntil() const { return ValidUntil; }
APT_PURE time_t metaIndex::GetDate() const { return this->Date; }
@@ -104,11 +119,19 @@ std::vector<std::string> metaIndex::MetaKeys() const /*{{{*/
/*}}}*/
void metaIndex::swapLoad(metaIndex * const OldMetaIndex) /*{{{*/
{
- std::swap(Entries, OldMetaIndex->Entries);
+ std::swap(SignedBy, OldMetaIndex->SignedBy);
+ std::swap(Suite, OldMetaIndex->Suite);
+ std::swap(Codename, OldMetaIndex->Codename);
std::swap(Date, OldMetaIndex->Date);
std::swap(ValidUntil, OldMetaIndex->ValidUntil);
std::swap(SupportsAcquireByHash, OldMetaIndex->SupportsAcquireByHash);
+ std::swap(Entries, OldMetaIndex->Entries);
std::swap(LoadedSuccessfully, OldMetaIndex->LoadedSuccessfully);
+
+ OldMetaIndex->SetOrigin(d->Origin);
+ OldMetaIndex->SetLabel(d->Label);
+ OldMetaIndex->SetVersion(d->Version);
+ OldMetaIndex->SetDefaultPin(d->DefaultPin);
}
/*}}}*/
@@ -136,3 +159,8 @@ bool metaIndex::HasSupportForComponent(std::string const &component) const/*{{{*
return true;
}
/*}}}*/
+
+void metaIndex::SetOrigin(std::string const &origin) { d->Origin = origin; }
+void metaIndex::SetLabel(std::string const &label) { d->Label = label; }
+void metaIndex::SetVersion(std::string const &version) { d->Version = version; }
+void metaIndex::SetDefaultPin(signed short const defaultpin) { d->DefaultPin = defaultpin; }
diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h
index 531143bcb..eeeb9d807 100644
--- a/apt-pkg/metaindex.h
+++ b/apt-pkg/metaindex.h
@@ -25,6 +25,8 @@ class IndexTarget;
class pkgCacheGenerator;
class OpProgress;
+class metaIndexPrivate;
+
class metaIndex
{
public:
@@ -43,7 +45,7 @@ public:
TRI_YES, TRI_DONTCARE, TRI_NO, TRI_UNSET
};
private:
- void * const d;
+ metaIndexPrivate * const d;
protected:
std::vector <pkgIndexFile *> *Indexes;
// parsed from the sources.list
@@ -70,8 +72,12 @@ public:
TriState GetTrusted() const;
std::string GetSignedBy() const;
+ std::string GetOrigin() const;
+ std::string GetLabel() const;
+ std::string GetVersion() const;
std::string GetCodename() const;
std::string GetSuite() const;
+ signed short GetDefaultPin() const;
bool GetSupportsAcquireByHash() const;
time_t GetValidUntil() const;
time_t GetDate() const;
@@ -112,6 +118,11 @@ public:
bool IsArchitectureSupported(std::string const &arch) const;
bool IsArchitectureAllSupportedFor(IndexTarget const &target) const;
bool HasSupportForComponent(std::string const &component) const;
+ // FIXME: should be members of the class on abi break
+ APT_HIDDEN void SetOrigin(std::string const &origin);
+ APT_HIDDEN void SetLabel(std::string const &label);
+ APT_HIDDEN void SetVersion(std::string const &version);
+ APT_HIDDEN void SetDefaultPin(signed short const defaultpin);
};
#endif