Browse Source

add sources.list Check-Valid-Until and Valid-Until-{Max,Min} options

These options could be set via configuration before, but the connection
to the actual sources is so strong that they should really be set in the
sources.list instead – especially as this can be done a lot more
specific rather than e.g. disabling Valid-Until for all sources at once.

Valid-Until-* names are chosen instead of the Min/Max-ValidTime as this
seems like a better name and their use in the wild is probably low
enough that this isn't going to confuse anyone if we have to names for
the same thing in different areas.

In the longrun, the config options should be removed, but for now
documentation hinting at the new options is good enough as these are the
kind of options you set once across many systems with different apt
versions, so the new way should work everywhere first before we
deprecate the old way.
debian/1.8.y
David Kalnischkies 7 years ago
parent
commit
0741daeb7a
  1. 4
      apt-pkg/acquire-item.cc
  2. 134
      apt-pkg/deb/debmetaindex.cc
  3. 3
      apt-pkg/deb/debmetaindex.h
  4. 3
      apt-pkg/sourcelist.cc
  5. 10
      doc/apt-get.8.xml
  6. 8
      doc/apt.conf.5.xml
  7. 55
      doc/sources.list.5.xml
  8. 9
      test/integration/test-releasefile-valid-until

4
apt-pkg/acquire-item.cc

@ -1041,8 +1041,8 @@ bool pkgAcqMetaBase::VerifyVendor(string const &Message) /*{{{*/
Transformed = "";
}
if (_config->FindB("Acquire::Check-Valid-Until", true) == true &&
TransactionManager->MetaIndexParser->GetValidUntil() > 0) {
if (TransactionManager->MetaIndexParser->GetValidUntil() > 0)
{
time_t const invalid_since = time(NULL) - TransactionManager->MetaIndexParser->GetValidUntil();
if (invalid_since > 0)
{

134
apt-pkg/deb/debmetaindex.cc

@ -44,7 +44,11 @@ class APT_HIDDEN debReleaseIndexPrivate /*{{{*/
std::vector<debSectionEntry> DebEntries;
std::vector<debSectionEntry> DebSrcEntries;
debReleaseIndexPrivate() {}
metaIndex::TriState CheckValidUntil;
time_t ValidUntilMin;
time_t ValidUntilMax;
debReleaseIndexPrivate() : CheckValidUntil(metaIndex::TRI_UNSET), ValidUntilMin(0), ValidUntilMax(0) {}
};
/*}}}*/
// ReleaseIndex::MetaIndex* - display helpers /*{{{*/
@ -283,43 +287,56 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
return false;
}
std::string const Label = Section.FindS("Label");
std::string const StrValidUntil = Section.FindS("Valid-Until");
bool CheckValidUntil = _config->FindB("Acquire::Check-Valid-Until", true);
if (d->CheckValidUntil == metaIndex::TRI_NO)
CheckValidUntil = false;
else if (d->CheckValidUntil == metaIndex::TRI_YES)
CheckValidUntil = true;
// if we have a Valid-Until header in the Release file, use it as default
if (StrValidUntil.empty() == false)
if (CheckValidUntil == true)
{
if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false)
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
if (StrValidUntil.empty() == false)
{
if (ErrorText != NULL)
strprintf(*ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str());
return false;
if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false)
{
if (ErrorText != NULL)
strprintf(*ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str());
return false;
}
}
// get the user settings for this archive and use what expires earlier
time_t MaxAge = d->ValidUntilMax;
if (MaxAge == 0)
{
MaxAge = _config->FindI("Acquire::Max-ValidTime", 0);
if (Label.empty() == false)
MaxAge = _config->FindI(("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge);
}
time_t MinAge = d->ValidUntilMin;
if (MinAge == 0)
{
MinAge = _config->FindI("Acquire::Min-ValidTime", 0);
if (Label.empty() == false)
MinAge = _config->FindI(("Acquire::Min-ValidTime::" + Label).c_str(), MinAge);
}
}
// get the user settings for this archive and use what expires earlier
int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0);
if (Label.empty() == false)
MaxAge = _config->FindI(("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge);
int MinAge = _config->FindI("Acquire::Min-ValidTime", 0);
if (Label.empty() == false)
MinAge = _config->FindI(("Acquire::Min-ValidTime::" + Label).c_str(), MinAge);
LoadedSuccessfully = TRI_YES;
if(MaxAge == 0 &&
(MinAge == 0 || ValidUntil == 0)) // No user settings, use the one from the Release file
return true;
if (MinAge != 0 && ValidUntil != 0) {
time_t const min_date = Date + MinAge;
if (ValidUntil < min_date)
ValidUntil = min_date;
}
if (MaxAge != 0) {
time_t const max_date = Date + MaxAge;
if (ValidUntil == 0 || ValidUntil > max_date)
ValidUntil = max_date;
if (MinAge != 0 && ValidUntil != 0) {
time_t const min_date = Date + MinAge;
if (ValidUntil < min_date)
ValidUntil = min_date;
}
if (MaxAge != 0) {
time_t const max_date = Date + MaxAge;
if (ValidUntil == 0 || ValidUntil > max_date)
ValidUntil = max_date;
}
}
LoadedSuccessfully = TRI_YES;
return true;
}
/*}}}*/
@ -411,7 +428,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/
return true;
}
/*}}}*/
// ReleaseIndex::IsTrusted /*{{{*/
// ReleaseIndex::Set* TriState options /*{{{*/
bool debReleaseIndex::SetTrusted(TriState const pTrusted)
{
if (Trusted == TRI_UNSET)
@ -421,6 +438,32 @@ bool debReleaseIndex::SetTrusted(TriState const pTrusted)
return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Trusted", URI.c_str(), Dist.c_str());
return true;
}
bool debReleaseIndex::SetCheckValidUntil(TriState const pCheckValidUntil)
{
if (d->CheckValidUntil == TRI_UNSET)
d->CheckValidUntil = pCheckValidUntil;
else if (d->CheckValidUntil != pCheckValidUntil)
return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Check-Valid-Until", URI.c_str(), Dist.c_str());
return true;
}
bool debReleaseIndex::SetValidUntilMin(time_t const Valid)
{
if (d->ValidUntilMin == 0)
d->ValidUntilMin = Valid;
else if (d->ValidUntilMin != Valid)
return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Min-ValidTime", URI.c_str(), Dist.c_str());
return true;
}
bool debReleaseIndex::SetValidUntilMax(time_t const Valid)
{
if (d->ValidUntilMax == 0)
d->ValidUntilMax = Valid;
else if (d->ValidUntilMax != Valid)
return _error->Error(_("Conflicting values set for option %s concerning source %s %s"), "Max-ValidTime", URI.c_str(), Dist.c_str());
return true;
}
/*}}}*/
// ReleaseIndex::IsTrusted /*{{{*/
bool debReleaseIndex::IsTrusted() const
{
if (Trusted == TRI_YES)
@ -601,6 +644,22 @@ static std::vector<std::string> parsePlusMinusOptions(std::string const &Name, /
/*}}}*/
class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
{
metaIndex::TriState GetTriStateOption(std::map<std::string, std::string>const &Options, char const * const name) const
{
std::map<std::string, std::string>::const_iterator const opt = Options.find(name);
if (opt != Options.end())
return StringToBool(opt->second, false) ? metaIndex::TRI_YES : metaIndex::TRI_NO;
return metaIndex::TRI_DONTCARE;
}
time_t GetTimeOption(std::map<std::string, std::string>const &Options, char const * const name) const
{
std::map<std::string, std::string>::const_iterator const opt = Options.find(name);
if (opt == Options.end())
return 0;
return strtoull(opt->second.c_str(), NULL, 10);
}
protected:
bool CreateItemInternal(std::vector<metaIndex *> &List, std::string const &URI,
@ -641,13 +700,10 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/
parsePlusMinusOptions("lang", Options, APT::Configuration::getLanguages(true))
);
std::map<std::string, std::string>::const_iterator const trusted = Options.find("trusted");
if (trusted != Options.end())
{
if (Deb->SetTrusted(StringToBool(trusted->second, false) ? debReleaseIndex::TRI_YES : debReleaseIndex::TRI_NO) == false)
return false;
}
else if (Deb->SetTrusted(debReleaseIndex::TRI_DONTCARE) == false)
if (Deb->SetTrusted(GetTriStateOption(Options, "trusted")) == false ||
Deb->SetCheckValidUntil(GetTriStateOption(Options, "check-valid-until")) == false ||
Deb->SetValidUntilMax(GetTimeOption(Options, "valid-until-max")) == false ||
Deb->SetValidUntilMin(GetTimeOption(Options, "valid-until-min")) == false)
return false;
return true;

3
apt-pkg/deb/debmetaindex.h

@ -53,6 +53,9 @@ class APT_HIDDEN debReleaseIndex : public metaIndex
virtual std::vector <pkgIndexFile *> *GetIndexFiles();
bool SetTrusted(TriState const Trusted);
bool SetCheckValidUntil(TriState const Trusted);
bool SetValidUntilMin(time_t const Valid);
bool SetValidUntilMax(time_t const Valid);
virtual bool IsTrusted() const;

3
apt-pkg/sourcelist.cc

@ -103,6 +103,9 @@ bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List, /*{{{*/
APT_PLUSMINUS("Targets", "target");
#undef APT_PLUSMINUS
mapping.insert(std::make_pair("Trusted", "trusted"));
mapping.insert(std::make_pair("Check-Valid-Until", "check-valid-until"));
mapping.insert(std::make_pair("Valid-Until-Min", "valid-until-min"));
mapping.insert(std::make_pair("Valid-Until-Max", "valid-until-max"));
for (std::map<char const * const, char const * const>::const_iterator m = mapping.begin(); m != mapping.end(); ++m)
if (Tags.Exists(m->first))

10
doc/apt-get.8.xml

@ -531,9 +531,13 @@
</varlistentry>
<varlistentry><term><option>--allow-unauthenticated</option></term>
<listitem><para>Ignore if packages can't be authenticated and don't prompt about it.
This is useful for tools like pbuilder.
Configuration Item: <literal>APT::Get::AllowUnauthenticated</literal>.</para></listitem>
<listitem><para>Ignore if packages can't be authenticated and don't prompt
about it. This can be useful while working with local repositories,
but is a huge security risk if data authenticity isn't ensured in
another way by the user itself. The usage of the
<option>Trusted</option> option for &sources-list; entries should
usually be preferred over this global override. Configuration Item:
<literal>APT::Get::AllowUnauthenticated</literal>.</para></listitem>
</varlistentry>
<varlistentry><term><option>--no-allow-insecure-repositories</option></term>

8
doc/apt.conf.5.xml

@ -301,6 +301,8 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
<literal>Valid-Until</literal> header, but if they don't or a
stricter value is desired the <literal>Max-ValidTime</literal>
option below can be used.
The <option>Check-Valid-Until</option> option of &sources-list; entries should be
preferred to disable the check selectively instead of using this global override.
</para></listitem>
</varlistentry>
@ -312,7 +314,8 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
the earlier date of the two is used as the expiration date.
The default value is <literal>0</literal> which stands for "valid forever".
Archive specific settings can be made by appending the label of the archive
to the option name.
to the option name. Preferably, the same can be achieved for specific
&sources-list; entries by using the <option>Valid-Until-Max</option> option there.
</para></listitem>
</varlistentry>
@ -324,7 +327,8 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
frequently updated archive with a <literal>Valid-Until</literal> header
instead of completely disabling the expiration date checking.
Archive specific settings can and should be used by appending the label of
the archive to the option name.
the archive to the option name. Preferably, the same can be achieved for specific
&sources-list; entries by using the <option>Valid-Until-Min</option> option there.
</para></listitem>
</varlistentry>

55
doc/sources.list.5.xml

@ -202,26 +202,26 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
APT versions.
<itemizedlist>
<listitem><para><literal>Architectures</literal>
(<literal>arch</literal>) is a multivalue option defining for
<listitem><para><option>Architectures</option>
(<option>arch</option>) is a multivalue option defining for
which architectures information should be downloaded. If this
option isn't set the default is all architectures as defined by
the <literal>APT::Architectures</literal> config option.
the <option>APT::Architectures</option> config option.
</para></listitem>
<listitem><para><literal>Languages</literal>
(<literal>lang</literal>) is a multivalue option defining for
<listitem><para><option>Languages</option>
(<option>lang</option>) is a multivalue option defining for
which languages information like translated package
descriptions should be downloaded. If this option isn't set
the default is all languages as defined by the
<literal>Acquire::Languages</literal> config option.
<option>Acquire::Languages</option> config option.
</para></listitem>
<listitem><para><literal>Targets</literal>
(<literal>target</literal>) is a multivalue option defining
<listitem><para><option>Targets</option>
(<option>target</option>) is a multivalue option defining
which download targets apt will try to acquire from this
source. If not specified, the default set is defined by the
<literal>APT::Acquire::Targets</literal> configuration scope.
<option>APT::Acquire::Targets</option> configuration scope.
</para></listitem>
</itemizedlist>
@ -232,7 +232,7 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
anomalies.
<itemizedlist>
<listitem><para><literal>Trusted</literal> (<literal>trusted</literal>)
<listitem><para><option>Trusted</option> (<option>trusted</option>)
is a tri-state value which defaults to APT deciding if a source
is considered trusted or if warnings should be raised before e.g.
packages are installed from this source. This option can be used
@ -245,6 +245,41 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
as untrusted even if the authentication checks passed successfully.
The default value can't be set explicitly.
</para></listitem>
<listitem><para><option>Check-Valid-Until</option> (<option>check-valid-until</option>)
is a yes/no value which controls if APT should try to detect
replay attacks. A repository creator can declare until then the
data provided in the repository should be considered valid and
if this time is reached, but no new data is provided the data
is considered expired and an error is raised. Beside
increasing security as a malicious attacker can't sent old data
forever denying a user to be able to upgrade to a new version,
this also helps users identify mirrors which are no longer
updated. Some repositories like historic archives aren't
updated anymore by design through, so this check can be
disabled by setting this option to <literal>no</literal>.
Defaults to the value of configuration option
<option>Acquire::Check-Valid-Until</option> which itself
defaults to <literal>yes</literal>.
</para></listitem>
<listitem><para><option>Valid-Until-Min</option>
(<option>check-valid-min</option>) and
<option>Valid-Until-Max</option>
(<option>valid-until-max</option>) can be used to raise or
lower the time period in seconds in which the data from this
repository is considered valid. -Max can be especially useful
if the repository provides no Valid-Until field on its Release
file to set your own value, while -Min can be used to increase
the valid time on seldomly updated (local) mirrors of a more
frequently updated but less accessible archive (which is in the
sources.list as well) instead of disabling the check entirely.
Default to the value of the configuration options
<option>Acquire::Min-ValidTime</option> and
<option>Acquire::Max-ValidTime</option> which are both unset by
default.
</para></listitem>
</itemizedlist>
</para>

9
test/integration/test-releasefile-valid-until

@ -46,3 +46,12 @@ runtest 'accepted' 'good Min-Valid (bad Until, good Max-Valid) <' 'now - 7 days'
runtest 'rejected' 'bad Max-Valid (bad Until, good Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=2419200
runtest 'rejected' 'bad Max-Valid (bad Until, bad Min-Valid) <' 'now - 7 days' 'now - 2 days' -o Acquire::Min-ValidTime=12096 -o Acquire::Max-ValidTime=241920
runtest 'rejected' 'bad Max-Valid (bad Until, bad Min-Valid) >' 'now - 7 days' 'now - 2 days' -o Acquire::Max-ValidTime=12096 -o Acquire::Min-ValidTime=241920
sed -i -e 's#\(deb\(-src\)\?\) #\1 [check-valid-until=no] #' rootdir/etc/apt/sources.list.d/*
runtest 'accepted' 'bad Until but overriden by sources option' 'now - 7 days' 'now - 4 days'
sed -i -e 's#\(deb\(-src\)\?\) \[check-valid-until=no\] #\1 [valid-until-max=86400] #' rootdir/etc/apt/sources.list.d/*
runtest 'rejected' 'bad Max-Valid (good Until) via sources option' 'now - 7 days' 'now + 4 days'
sed -i -e 's#\(deb\(-src\)\?\) \[valid-until-max=86400\] #\1 [valid-until-min=1209600] #' rootdir/etc/apt/sources.list.d/*
runtest 'accepted' 'good Min-Valid (bad Until) via sources option' 'now - 7 days' 'now - 4 days'

Loading…
Cancel
Save