]> git.saurik.com Git - apt.git/commitdiff
add insecure (and weak) allow-options for sources.list
authorDavid Kalnischkies <david@kalnischkies.de>
Mon, 20 Jun 2016 18:50:43 +0000 (20:50 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 22 Jun 2016 12:05:01 +0000 (14:05 +0200)
Weak had no dedicated option before and Insecure and Downgrade were both
global options, which given the effect they all have on security is
rather bad. Setting them for individual repositories only isn't great
but at least slightly better and also more consistent with other
settings for repositories.

16 files changed:
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/acquire-worker.cc
apt-pkg/deb/debmetaindex.cc
apt-pkg/deb/debmetaindex.h
apt-pkg/indexcopy.cc
apt-pkg/indexfile.cc
apt-pkg/indexfile.h
apt-pkg/init.cc
apt-private/private-cmndline.cc
doc/apt-secure.8.xml
doc/apt.conf.5.xml
doc/sources.list.5.xml
test/integration/test-apt-update-nofallback
test/integration/test-apt-update-weak-hashes
test/integration/test-releasefile-verification

index 63b3c9a1f9806cc95fe5bbb684842b2060876287..a4b1d489736670c0622828a2bfc091e4910e0f7e 100644 (file)
@@ -175,7 +175,7 @@ static void ReportMirrorFailureToCentral(pkgAcquire::Item const &I, std::string
 }
                                                                        /*}}}*/
 
-static bool MessageInsecureRepository(bool const isError, char const * const msg, std::string const &repo)/*{{{*/
+static APT_NONNULL(2) bool MessageInsecureRepository(bool const isError, char const * const msg, std::string const &repo)/*{{{*/
 {
    std::string m;
    strprintf(m, msg, repo.c_str());
@@ -195,7 +195,28 @@ static bool MessageInsecureRepository(bool const isError, char const * const msg
                                                                        /*}}}*/
 // AllowInsecureRepositories                                           /*{{{*/
 enum class InsecureType { UNSIGNED, WEAK, NORELEASE };
-static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType msg, std::string const &repo,
+static bool TargetIsAllowedToBe(IndexTarget const &Target, InsecureType const type)
+{
+   if (_config->FindB("Acquire::AllowInsecureRepositories"))
+      return true;
+
+   if (Target.OptionBool(IndexTarget::ALLOW_INSECURE))
+      return true;
+
+   switch (type)
+   {
+      case InsecureType::UNSIGNED: break;
+      case InsecureType::NORELEASE: break;
+      case InsecureType::WEAK:
+        if (_config->FindB("Acquire::AllowWeakRepositories"))
+           return true;
+        if (Target.OptionBool(IndexTarget::ALLOW_WEAK))
+           return true;
+        break;
+   }
+   return false;
+}
+static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType const msg, std::string const &repo,
       metaIndex const * const MetaIndexParser, pkgAcqMetaClearSig * const TransactionManager, pkgAcquire::Item * const I)
 {
    // we skip weak downgrades as its unlikely that a repository gets really weaker –
@@ -213,7 +234,8 @@ static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType msg, std
            case InsecureType::NORELEASE: msgstr = _("The repository '%s' does no longer have a Release file."); break;
            case InsecureType::WEAK: /* unreachable */ break;
         }
-        if (_config->FindB("Acquire::AllowDowngradeToInsecureRepositories"))
+        if (_config->FindB("Acquire::AllowDowngradeToInsecureRepositories") ||
+              TransactionManager->Target.OptionBool(IndexTarget::ALLOW_DOWNGRADE_TO_INSECURE))
         {
            // meh, the users wants to take risks (we still mark the packages
            // from this repository as unauthenticated)
@@ -241,7 +263,7 @@ static bool APT_NONNULL(3, 4, 5) AllowInsecureRepositories(InsecureType msg, std
       case InsecureType::WEAK: msgstr = _("The repository '%s' provides only weak security information."); break;
    }
 
-   if (_config->FindB("Acquire::AllowInsecureRepositories") == true)
+   if (TargetIsAllowedToBe(TransactionManager->Target, msg) == true)
    {
       MessageInsecureRepository(false, msgstr, repo);
       return true;
@@ -277,7 +299,20 @@ APT_CONST bool pkgAcqTransactionItem::HashesRequired() const
       we can at least trust them for integrity of the download itself.
       Only repositories without a Release file can (obviously) not have
       hashes – and they are very uncommon and strongly discouraged */
-   return TransactionManager->MetaIndexParser->GetLoadedSuccessfully() == metaIndex::TRI_YES;
+   if (TransactionManager->MetaIndexParser->GetLoadedSuccessfully() != metaIndex::TRI_YES)
+      return false;
+   if (TargetIsAllowedToBe(Target, InsecureType::WEAK))
+   {
+      /* If we allow weak hashes, we check that we have some (weak) and then
+         declare hashes not needed. That will tip us in the right direction
+        as if hashes exist, they will be used, even if not required */
+      auto const hsl = GetExpectedHashes();
+      if (hsl.usable())
+        return true;
+      if (hsl.empty() == false)
+        return false;
+   }
+   return true;
 }
 HashStringList pkgAcqTransactionItem::GetExpectedHashes() const
 {
@@ -1333,7 +1368,7 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify)                  /*{{{*/
            auto const hashes = GetExpectedHashesFor(Target.MetaKey);
            if (hashes.empty() == false)
            {
-              if (hashes.usable() == false)
+              if (hashes.usable() == false && TargetIsAllowedToBe(TransactionManager->Target, InsecureType::WEAK) == false)
               {
                  new CleanupItem(Owner, TransactionManager, Target);
                  _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' provides only weak security information for it"),
@@ -1525,8 +1560,7 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire * const Owner,  /*{{{*/
       IndexTarget const &DetachedDataTarget, IndexTarget const &DetachedSigTarget,
       metaIndex * const MetaIndexParser) :
    pkgAcqMetaIndex(Owner, this, ClearsignedTarget, DetachedSigTarget),
-   d(NULL), ClearsignedTarget(ClearsignedTarget),
-   DetachedDataTarget(DetachedDataTarget),
+   d(NULL), DetachedDataTarget(DetachedDataTarget),
    MetaIndexParser(MetaIndexParser), LastMetaIndexParser(NULL)
 {
    // index targets + (worst case:) Release/Release.gpg
@@ -1640,7 +1674,7 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c
       if(CheckStopAuthentication(this, Message))
          return;
 
-      if(AllowInsecureRepositories(InsecureType::UNSIGNED, ClearsignedTarget.Description, TransactionManager->MetaIndexParser, TransactionManager, this) == true)
+      if(AllowInsecureRepositories(InsecureType::UNSIGNED, Target.Description, TransactionManager->MetaIndexParser, TransactionManager, this) == true)
       {
         Status = StatDone;
 
index 92f1ac215d26cacbfbbc6bae4367864ac06a5519..ac4994738a5c1730d4decc489e3682f32ac1c6dc 100644 (file)
@@ -368,12 +368,13 @@ class APT_HIDDEN pkgAcqTransactionItem: public pkgAcquire::Item           /*{{{*/
 {
    void * const d;
    protected:
-   IndexTarget const Target;
    HashStringList GetExpectedHashesFor(std::string const &MetaKey) const;
 
    bool QueueURI(pkgAcquire::ItemDesc &Item) APT_OVERRIDE;
 
    public:
+   IndexTarget const Target;
+
    /** \brief storge name until a transaction is finished */
    std::string PartialFile;
 
@@ -559,8 +560,6 @@ class APT_HIDDEN pkgAcqMetaSig : public pkgAcqTransactionItem
 class APT_HIDDEN pkgAcqMetaClearSig : public pkgAcqMetaIndex
 {
    void * const d;
-
-   IndexTarget const ClearsignedTarget;
    IndexTarget const DetachedDataTarget;
 
  public:
index d3d95998c021a7d736c96ae8496c0a17f3c224ae..9ed7b5b28fb0d5cc3d42b09cdf14089134f5a63a 100644 (file)
@@ -378,6 +378,7 @@ bool pkgAcquire::Worker::RunMessages()
 
            bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
               StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
+           auto const forcedHash = _config->Find("Acquire::ForceHash");
            for (auto const Owner: ItmOwners)
            {
               HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
@@ -395,9 +396,10 @@ bool pkgAcquire::Worker::RunMessages()
 
               // decide if what we got is what we expected
               bool consideredOkay = false;
-              if (ExpectedHashes.usable())
+              if ((forcedHash.empty() && ExpectedHashes.empty() == false) ||
+                    (forcedHash.empty() == false && ExpectedHashes.usable()))
               {
-                 if (ReceivedHashes.usable() == false)
+                 if (ReceivedHashes.empty())
                  {
                     /* IMS-Hits can't be checked here as we will have uncompressed file,
                        but the hashes for the compressed file. What we have was good through
@@ -410,16 +412,8 @@ bool pkgAcquire::Worker::RunMessages()
                     consideredOkay = false;
 
               }
-              else if (Owner->HashesRequired() == true)
-                 consideredOkay = false;
               else
-              {
-                 consideredOkay = true;
-                 // even if the hashes aren't usable to declare something secure
-                 // we can at least use them to declare it an integrity failure
-                 if (ExpectedHashes.empty() == false && ReceivedHashes != ExpectedHashes && _config->Find("Acquire::ForceHash").empty())
-                    consideredOkay = false;
-              }
+                 consideredOkay = !Owner->HashesRequired();
 
               if (consideredOkay == true)
                  consideredOkay = Owner->VerifyDone(Message, Config);
index 0c9cde620e048f4299ced4b48e890c4d31212678..2671fc30dd235420e9dccd75d8c358f0b774ca4e 100644 (file)
@@ -51,8 +51,9 @@ class APT_HIDDEN debReleaseIndexPrivate                                       /*{{{*/
 
    std::vector<std::string> Architectures;
    std::vector<std::string> NoSupportForAll;
+   std::map<std::string, std::string> const ReleaseOptions;
 
-   debReleaseIndexPrivate() : CheckValidUntil(metaIndex::TRI_UNSET), ValidUntilMin(0), ValidUntilMax(0) {}
+   debReleaseIndexPrivate(std::map<std::string, std::string> const &Options) : CheckValidUntil(metaIndex::TRI_UNSET), ValidUntilMin(0), ValidUntilMax(0), ReleaseOptions(Options) {}
 };
                                                                        /*}}}*/
 // ReleaseIndex::MetaIndex* - display helpers                          /*{{{*/
@@ -96,11 +97,11 @@ std::string debReleaseIndex::MetaIndexURI(const char *Type) const
 }
                                                                        /*}}}*/
 // ReleaseIndex Con- and Destructors                                   /*{{{*/
-debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist) :
-                                       metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate())
+debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, std::map<std::string, std::string> const &Options) :
+                                       metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate(Options))
 {}
-debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const pTrusted) :
-                                       metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate())
+debReleaseIndex::debReleaseIndex(std::string const &URI, std::string const &Dist, bool const pTrusted, std::map<std::string, std::string> const &Options) :
+                                       metaIndex(URI, Dist, "deb"), d(new debReleaseIndexPrivate(Options))
 {
    Trusted = pTrusted ? TRI_YES : TRI_NO;
 }
@@ -112,17 +113,10 @@ debReleaseIndex::~debReleaseIndex() {
 // ReleaseIndex::GetIndexTargets                                       /*{{{*/
 static void GetIndexTargetsFor(char const * const Type, std::string const &URI, std::string const &Dist,
       std::vector<debReleaseIndexPrivate::debSectionEntry> const &entries,
-      std::vector<IndexTarget> &IndexTargets)
+      std::vector<IndexTarget> &IndexTargets, std::map<std::string, std::string> const &ReleaseOptions)
 {
    bool const flatArchive = (Dist[Dist.length() - 1] == '/');
-   std::string baseURI = URI;
-   if (flatArchive)
-   {
-      if (Dist != "/")
-         baseURI += Dist;
-   }
-   else
-      baseURI += "dists/" + Dist + "/";
+   std::string const baseURI = constructMetaIndexURI(URI, Dist, "");
    std::string const Release = (Dist == "/") ? "" : Dist;
    std::string const Site = ::URI::ArchiveOnly(URI);
 
@@ -292,8 +286,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
                  }
 
                  // not available in templates, but in the indextarget
-                 Options.insert(std::make_pair("BASE_URI", baseURI));
-                 Options.insert(std::make_pair("REPO_URI", URI));
+                 Options.insert(ReleaseOptions.begin(), ReleaseOptions.end());
                  Options.insert(std::make_pair("IDENTIFIER", Identifier));
                  Options.insert(std::make_pair("TARGET_OF", Type));
                  Options.insert(std::make_pair("CREATED_BY", *T));
@@ -317,7 +310,7 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
                        MetaKey,
                        ShortDesc,
                        LongDesc,
-                       Options.find("BASE_URI")->second + MetaKey,
+                       baseURI + MetaKey,
                        IsOpt,
                        KeepCompressed,
                        Options
@@ -344,8 +337,8 @@ static void GetIndexTargetsFor(char const * const Type, std::string const &URI,
 std::vector<IndexTarget> debReleaseIndex::GetIndexTargets() const
 {
    std::vector<IndexTarget> IndexTargets;
-   GetIndexTargetsFor("deb-src", URI, Dist, d->DebSrcEntries, IndexTargets);
-   GetIndexTargetsFor("deb", URI, Dist, d->DebEntries, IndexTargets);
+   GetIndexTargetsFor("deb-src", URI, Dist, d->DebSrcEntries, IndexTargets, d->ReleaseOptions);
+   GetIndexTargetsFor("deb", URI, Dist, d->DebEntries, IndexTargets, d->ReleaseOptions);
    return IndexTargets;
 }
                                                                        /*}}}*/
@@ -542,11 +535,11 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
 metaIndex * debReleaseIndex::UnloadedClone() const                     /*{{{*/
 {
    if (Trusted == TRI_NO)
-      return new debReleaseIndex(URI, Dist, false);
+      return new debReleaseIndex(URI, Dist, false, d->ReleaseOptions);
    else if (Trusted == TRI_YES)
-      return new debReleaseIndex(URI, Dist, true);
+      return new debReleaseIndex(URI, Dist, true, d->ReleaseOptions);
    else
-      return new debReleaseIndex(URI, Dist);
+      return new debReleaseIndex(URI, Dist, d->ReleaseOptions);
 }
                                                                        /*}}}*/
 bool debReleaseIndex::parseSumData(const char *&Start, const char *End,        /*{{{*/
@@ -611,7 +604,7 @@ bool debReleaseIndex::parseSumData(const char *&Start, const char *End,     /*{{{*/
 
 bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll)/*{{{*/
 {
-#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, false, std::map<std::string,std::string>())
+#define APT_TARGET(X) IndexTarget("", X, MetaIndexInfo(X), MetaIndexURI(X), false, false, d->ReleaseOptions)
    pkgAcqMetaClearSig * const TransactionManager = new pkgAcqMetaClearSig(Owner,
         APT_TARGET("InRelease"), APT_TARGET("Release"), APT_TARGET("Release.gpg"), this);
 #undef APT_TARGET
@@ -751,6 +744,10 @@ std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()             /*{{{*/
    return Indexes;
 }
                                                                        /*}}}*/
+std::map<std::string, std::string> debReleaseIndex::GetReleaseOptions()
+{
+   return d->ReleaseOptions;
+}
 
 static bool ReleaseFileName(debReleaseIndex const * const That, std::string &ReleaseFile)/*{{{*/
 {
@@ -900,7 +897,7 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type               /*{{{*/
       return metaIndex::TRI_DONTCARE;
    }
 
-   time_t GetTimeOption(std::map<std::string, std::string>const &Options, char const * const name) const
+   static time_t GetTimeOption(std::map<std::string, std::string>const &Options, char const * const name)
    {
       std::map<std::string, std::string>::const_iterator const opt = Options.find(name);
       if (opt == Options.end())
@@ -908,12 +905,74 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type             /*{{{*/
       return strtoull(opt->second.c_str(), NULL, 10);
    }
 
+   static bool GetBoolOption(std::map<std::string, std::string> const &Options, char const * const name, bool const defVal)
+   {
+      std::map<std::string, std::string>::const_iterator const opt = Options.find(name);
+      if (opt == Options.end())
+        return defVal;
+      return StringToBool(opt->second, defVal);
+   }
+
+   static std::vector<std::string> GetMapKeys(std::map<std::string, std::string> const &Options)
+   {
+      std::vector<std::string> ret;
+      ret.reserve(Options.size());
+      for (auto &&O: Options)
+        ret.emplace_back(O.first);
+      std::sort(ret.begin(), ret.end());
+      return ret;
+   }
+
+   static bool MapsAreEqual(std::map<std::string, std::string> const &OptionsA,
+        std::map<std::string, std::string> const &OptionsB,
+        std::string const &URI, std::string const &Dist)
+   {
+      auto const KeysA = GetMapKeys(OptionsA);
+      auto const KeysB = GetMapKeys(OptionsB);
+      auto const m = std::mismatch(KeysA.begin(), KeysA.end(), KeysB.begin());
+      if (m.first != KeysA.end())
+      {
+        if (std::find(KeysB.begin(), KeysB.end(), *m.first) == KeysB.end())
+           return _error->Error(_("Conflicting values set for option %s regarding source %s %s"), m.first->c_str(), "<set>", "<unset>");
+        else
+           return _error->Error(_("Conflicting values set for option %s regarding source %s %s"), m.second->c_str(), "<set>", "<unset>");
+      }
+      if (m.second != KeysB.end())
+      {
+        if (std::find(KeysA.begin(), KeysA.end(), *m.second) == KeysA.end())
+           return _error->Error(_("Conflicting values set for option %s regarding source %s %s"), m.first->c_str(), "<set>", "<unset>");
+        else
+           return _error->Error(_("Conflicting values set for option %s regarding source %s %s"), m.second->c_str(), "<set>", "<unset>");
+      }
+      for (auto&& key: KeysA)
+      {
+        if (key == "BASE_URI" || key == "REPO_URI")
+           continue;
+        auto const a = OptionsA.find(key);
+        auto const b = OptionsB.find(key);
+        if (unlikely(a == OptionsA.end() || b == OptionsB.end()) || a->second != b->second)
+           return _error->Error(_("Conflicting values set for option %s regarding source %s %s"), key.c_str(), URI.c_str(), Dist.c_str());
+      }
+      return true;
+   }
+
    protected:
 
    bool CreateItemInternal(std::vector<metaIndex *> &List, std::string const &URI,
                           std::string const &Dist, std::string const &Section,
                           bool const &IsSrc, std::map<std::string, std::string> const &Options) const
    {
+      std::map<std::string,std::string> ReleaseOptions = {{
+        { "BASE_URI", constructMetaIndexURI(URI, Dist, "") },
+        { "REPO_URI", URI },
+      }};
+      if (GetBoolOption(Options, "allow-insecure", _config->FindB("Acquire::AllowInsecureRepositories")))
+        ReleaseOptions.emplace("ALLOW_INSECURE", "true");
+      if (GetBoolOption(Options, "allow-weak", _config->FindB("Acquire::AllowWeakRepositories")))
+        ReleaseOptions.emplace("ALLOW_WEAK", "true");
+      if (GetBoolOption(Options, "allow-downgrade-to-insecure", _config->FindB("Acquire::AllowDowngradeToInsecureRepositories")))
+        ReleaseOptions.emplace("ALLOW_DOWNGRADE_TO_INSECURE", "true");
+
       debReleaseIndex * Deb = nullptr;
       std::string const FileName = URItoFileName(constructMetaIndexURI(URI, Dist, "Release"));
       for (auto const &I: List)
@@ -931,6 +990,8 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type               /*{{{*/
            corresponds to. */
         if (URItoFileName(D->MetaIndexURI("Release")) == FileName)
         {
+           if (MapsAreEqual(ReleaseOptions, D->GetReleaseOptions(), URI, Dist) == false)
+              return false;
            Deb = D;
            break;
         }
@@ -939,7 +1000,7 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type              /*{{{*/
       // No currently created Release file indexes this entry, so we create a new one.
       if (Deb == nullptr)
       {
-        Deb = new debReleaseIndex(URI, Dist);
+        Deb = new debReleaseIndex(URI, Dist, ReleaseOptions);
         List.push_back(Deb);
       }
 
@@ -993,12 +1054,7 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type             /*{{{*/
         }), mytargets.end());
       }
 
-      bool UsePDiffs = _config->FindB("Acquire::PDiffs", true);
-      {
-        std::map<std::string, std::string>::const_iterator const opt = Options.find("pdiffs");
-        if (opt != Options.end())
-           UsePDiffs = StringToBool(opt->second);
-      }
+      bool const UsePDiffs = GetBoolOption(Options, "pdiffs", _config->FindB("Acquire::PDiffs", true));
 
       std::string UseByHash = _config->Find("APT::Acquire::By-Hash", "yes");
       UseByHash = _config->Find("Acquire::By-Hash", UseByHash);
index 2bb9ed69305c47f8776acfa9d47e595e798e8bf2..f903617f7d828be7cbb877c7a9cbff0d4a48a737 100644 (file)
@@ -34,8 +34,8 @@ class APT_HIDDEN debReleaseIndex : public metaIndex
    APT_HIDDEN std::string MetaIndexFile(const char *Types) const;
    APT_HIDDEN std::string MetaIndexURI(const char *Type) const;
 
-   debReleaseIndex(std::string const &URI, std::string const &Dist);
-   debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted);
+   debReleaseIndex(std::string const &URI, std::string const &Dist, std::map<std::string,std::string> const &Options);
+   debReleaseIndex(std::string const &URI, std::string const &Dist, bool const Trusted, std::map<std::string,std::string> const &Options);
    virtual ~debReleaseIndex();
 
    virtual std::string ArchiveURI(std::string const &File) const APT_OVERRIDE {return URI + File;};
@@ -56,6 +56,7 @@ class APT_HIDDEN debReleaseIndex : public metaIndex
    bool SetValidUntilMin(time_t const Valid);
    bool SetValidUntilMax(time_t const Valid);
    bool SetSignedBy(std::string const &SignedBy);
+   std::map<std::string, std::string> GetReleaseOptions();
 
    virtual bool IsTrusted() const APT_OVERRIDE;
    bool IsArchitectureSupported(std::string const &arch) const;
index 4aade6e8a45d58966a2a47d94131565262933175..4a35e3847005bd32dcb4812bceb45a0f7aa62997 100644 (file)
@@ -550,7 +550,7 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
       if(Debug)
         cout << "Signature verify for: " << *I << endl;
 
-      metaIndex *MetaIndex = new debReleaseIndex("","");
+      metaIndex *MetaIndex = new debReleaseIndex("","", {});
       string prefix = *I; 
 
       string const releasegpg = *I+"Release.gpg";
index 7ded0101b66faa6a73d42e730c85dd0bc3974ce2..b1435d32c168f44d373559757909004d2f103e5f 100644 (file)
@@ -147,6 +147,9 @@ std::string IndexTarget::Option(OptionKeys const EnumKey) const             /*{{{*/
       APT_CASE(SOURCESENTRY);
       APT_CASE(BY_HASH);
       APT_CASE(KEEPCOMPRESSEDAS);
+      APT_CASE(ALLOW_INSECURE);
+      APT_CASE(ALLOW_WEAK);
+      APT_CASE(ALLOW_DOWNGRADE_TO_INSECURE);
 #undef APT_CASE
       case FILENAME: return _config->FindDir("Dir::State::lists") + URItoFileName(URI);
       case EXISTING_FILENAME:
@@ -170,7 +173,7 @@ std::string IndexTarget::Option(OptionKeys const EnumKey) const             /*{{{*/
                                                                        /*}}}*/
 bool IndexTarget::OptionBool(OptionKeys const EnumKey) const           /*{{{*/
 {
-   return StringToBool(Option(EnumKey));
+   return StringToBool(Option(EnumKey), false);
 }
                                                                        /*}}}*/
 std::string IndexTarget::Format(std::string format) const              /*{{{*/
index 76a3d069e58d390c410ace72c95c395fc679bd3c..68753a40af1e6362970b621466df70f52111947f 100644 (file)
@@ -93,6 +93,9 @@ class IndexTarget                                                     /*{{{*/
       KEEPCOMPRESSEDAS,
       FALLBACK_OF,
       IDENTIFIER,
+      ALLOW_INSECURE,
+      ALLOW_WEAK,
+      ALLOW_DOWNGRADE_TO_INSECURE,
    };
    std::string Option(OptionKeys const Key) const;
    bool OptionBool(OptionKeys const Key) const;
index c77e8e2feddead88a9fcd8ae6c2a948048e7ea9b..70a119a6efd1064ce81a310fe8ca0ef7a062fb7c 100644 (file)
@@ -87,6 +87,7 @@ bool pkgInitConfig(Configuration &Cnf)
 
    // Repository security
    Cnf.CndSet("Acquire::AllowInsecureRepositories", false);
+   Cnf.CndSet("Acquire::AllowWeakRepositories", false);
    Cnf.CndSet("Acquire::AllowDowngradeToInsecureRepositories", false);
 
    // Default cdrom mount point
index 481c23c942f9a9acfc3659022e78f5fdfcd76896..1d1efc669520fdb10b208bac58e3a27dd46bec2c 100644 (file)
@@ -265,6 +265,7 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
    addArg(0,"arch-only","APT::Get::Arch-Only",0);
    addArg(0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0);
    addArg(0,"allow-insecure-repositories","Acquire::AllowInsecureRepositories",0);
+   addArg(0,"allow-weak-repositories","Acquire::AllowWeakRepositories",0);
    addArg(0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean);
    addArg(0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean);
    addArg(0,"fix-policy","APT::Get::Fix-Policy-Broken",0);
index 2c1c192d4dfe64558eedec34521d49bbdc988f54..79bb86a0f874c54ae799503d208e5d22e971176a 100644 (file)
    <para>
    You can force all APT clients to raise only warnings by setting the
    configuration option <option>Acquire::AllowInsecureRepositories</option> to
-   <literal>true</literal>. Note that this option will eventually be removed.
+   <literal>true</literal>. Individual repositories can also be allowed to be insecure
+   via the &sources-list; option <literal>allow-insecure=yes</literal>.
+   Note that insecure repositories are strongly discouraged and all options
+   to force apt to continue supporting them will eventually be removed.
    Users also have the <option>Trusted</option> option available to disable
    even the warnings, but be sure to understand the implications as detailed in
    &sources-list;.
@@ -87,7 +90,8 @@
    irrespective of the option to allow or forbid usage of insecure repositories.
    The error can be overcome by additionally setting
    <option>Acquire::AllowDowngradeToInsecureRepositories</option>
-   to <literal>true</literal>.
+   to <literal>true</literal> or for Individual repositories with the &sources-list;
+   option <literal>allow-downgrade-to-insecure=yes</literal>.
    </para>
 
    <para>
index 01540160583544a2e274a0578cefca63a220d8a5..dfdd0eabf5e7ddb00cbc21126d2af0499a74a025 100644 (file)
@@ -653,7 +653,17 @@ APT::Compressor::rev {
           Allow update operations to load data files from
           repositories without sufficient security information.
           The default value is "<literal>false</literal>".
-          Concept and implications of this are detailed in &apt-secure;.
+          Concept, implications as well as alternatives are detailed in &apt-secure;.
+        </para></listitem>
+     </varlistentry>
+
+     <varlistentry><term><option>AllowWeakRepositories</option></term>
+        <listitem><para>
+          Allow update operations to load data files from
+          repositories which provide security information, but these
+          are deemed no longer cryptographically strong enough.
+          The default value is "<literal>false</literal>".
+          Concept, implications as well as alternatives are detailed in &apt-secure;.
         </para></listitem>
      </varlistentry>
 
@@ -664,9 +674,7 @@ APT::Compressor::rev {
           for a previously trusted repository apt will refuse the update. This
           option can be used to override this protection. You almost certainly
           never want to enable this. The default is <literal>false</literal>.
-
-          Note that apt will still consider packages from this source
-          untrusted and warns about them if you try to install them.
+          Concept, implications as well as alternatives are detailed in &apt-secure;.
         </para></listitem>
      </varlistentry>
 
index 0c93adc42fed2e093d96373a5feab2f879b04496..a67b50ecf618623f9e0aea4d5f653f0331b1744b 100644 (file)
@@ -269,6 +269,14 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
        anomalies.
 
        <itemizedlist>
+         <listitem><para><option>Allow-Insecure</option> (<option>allow-insecure</option>),
+               <option>Allow-Weak</option> (<option>allow-weak</option>) and
+               <option>Allow-Downgrade-To-Insecure</option> (<option>allow-downgrade-to-insecure</option>)
+               are boolean values which all default to <literal>no</literal>.
+               If set to <literal>yes</literal> they circumvent parts of &apt-secure;
+               and should therefore not be used lightly!
+         </para></listitem>
+
          <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.
index 40fbae56097f6c768504179e176b2729185359bd..60f329a4a0e9c1cfb64091d808c42aa18b223048 100755 (executable)
@@ -93,10 +93,16 @@ test_from_inrelease_to_unsigned_with_override()
     find "$APTARCHIVE" -name '*Packages*' -exec touch -d '+2 hours' {} \;
 
     # and ensure we can update to it (with enough force) 
+    testfailure apt update
     testfailure aptget update
     testfailure aptget update --allow-insecure-repositories
-    testwarning aptget update --allow-insecure-repositories \
-        -o Acquire::AllowDowngradeToInsecureRepositories=1 -o Debug::pkgAcquire::Worker=1 -o Debug::pkgAcquire::Auth=1
+    testfailure aptget update --no-allow-insecure-repositories
+    sed -i 's#^deb\(-src\)\? #deb\1 [allow-downgrade-to-insecure=yes] #' rootdir/etc/apt/sources.list.d/*
+    testfailure aptget update --no-allow-insecure-repositories
+    testfailure apt update
+    testwarning apt update --allow-insecure-repositories \
+        -o Debug::pkgAcquire::Worker=1 -o Debug::pkgAcquire::Auth=1
+    sed -i 's#^deb\(-src\)\? \[allow-downgrade-to-insecure=yes\] #deb\1 #' rootdir/etc/apt/sources.list.d/*
     # but that the individual packages are still considered untrusted
     testfailureequal "WARNING: The following packages cannot be authenticated!
   evil
index 29343565f51e3918e8a964cdda8804f6a34bab53..b07dba6a218ed174966a6597b35ec0ab5f728103 100755 (executable)
@@ -58,6 +58,16 @@ N: See apt-secure(8) manpage for repository creation and user configuration deta
                testbadpkg 'foo'
        fi
 
+       msgmsg "$TYPE contains only weak hashes, but source allows weak"
+       sed -i 's#^deb\(-src\)\? #deb\1 [allow-weak=yes] #' rootdir/etc/apt/sources.list.d/*
+       genericprepare
+       testwarningmsg "W: No Hash entry in Release file ${MANGLED} which is considered strong enough for security purposes
+W: The repository 'file:${APTARCHIVE} unstable $(basename "$FILENAME")' provides only weak security information.
+N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
+N: See apt-secure(8) manpage for repository creation and user configuration details." apt update "$@"
+       testbadpkg 'foo'
+       sed -i 's#^deb\(-src\)\? \[allow-weak=yes\] #deb\1 #' rootdir/etc/apt/sources.list.d/*
+
        msgmsg "$TYPE contains no hashes"
        generatereleasefiles
        sed -i -e '/^ / d' -e '/^MD5Sum:/ d' "$APTARCHIVE/dists/unstable/Release"
@@ -85,10 +95,15 @@ N: See apt-secure(8) manpage for repository creation and user configuration deta
        sed -i '/^ [0-9a-fA-Z]\{64\} .*Sources$/d' "$APTARCHIVE/dists/unstable/Release"
        signreleasefiles
        preparetest
-       # trust is a repository property, so individual files can't be insecure
-       testwarningmsg "W: Skipping acquire of configured file 'main/source/Sources' as repository 'file:${APTARCHIVE} unstable InRelease' provides only weak security information for it" apt update "$@"
+       if [ -z "$1" ]; then
+               testwarningmsg "W: Skipping acquire of configured file 'main/source/Sources' as repository 'file:${APTARCHIVE} unstable InRelease' provides only weak security information for it" apt update
+               testnosrcpackage foo
+       else
+               rm -f rootdir/var/lib/apt/lists/partial/*
+               testsuccess apt update "$@"
+               testnotempty apt showsrc foo
+       fi
        testsuccess apt show foo
-       testnosrcpackage foo
 }
 
 genericprepare() {
@@ -107,14 +122,14 @@ preparetest() {
        genericprepare
 }
 testrun 'InRelease' "${APTARCHIVE}/dists/unstable/InRelease"
-testrun 'InRelease' "${APTARCHIVE}/dists/unstable/InRelease" --allow-insecure-repositories -o APT::Get::List-Cleanup=0
+testrun 'InRelease' "${APTARCHIVE}/dists/unstable/InRelease" --allow-weak-repositories -o APT::Get::List-Cleanup=0
 
 preparetest() {
        rm -f "${APTARCHIVE}/dists/unstable/InRelease"
        genericprepare
 }
 testrun 'Release+Release.gpg' "${APTARCHIVE}/dists/unstable/Release"
-testrun 'Release+Release.gpg' "${APTARCHIVE}/dists/unstable/Release" --allow-insecure-repositories -o APT::Get::List-Cleanup=0
+testrun 'Release+Release.gpg' "${APTARCHIVE}/dists/unstable/Release" --allow-weak-repositories -o APT::Get::List-Cleanup=0
 
 preparetest() {
        rm -f "${APTARCHIVE}/dists/unstable/InRelease" "${APTARCHIVE}/dists/unstable/Release.gpg"
@@ -128,7 +143,7 @@ generatereleasefiles 'now - 7 days'
 signreleasefiles
 testfailure apt update
 testnopkg 'foo'
-testwarning apt update --allow-insecure-repositories
+testwarning apt update --allow-weak-repositories
 testbadpkg 'foo'
 
 confighashes 'MD5' 'SHA256'
@@ -153,7 +168,7 @@ testnopkg foo3
 testnotempty find rootdir/var/lib/apt/lists -maxdepth 1 -name '*InRelease' -o -name '*Release.gpg'
 testnotempty apt show foo2
 testnotempty apt showsrc foo2
-testwarning apt update --allow-insecure-repositories
+testwarning apt update --allow-weak-repositories
 testnopkg foo2
 testbadpkg foo3
 
index 217319cab91357d0c8adc1c077ee22ccdc92f298..500c7b0bdaf9b7bfc00f3654ff41c5a08758af31 100755 (executable)
@@ -414,6 +414,11 @@ runfailure() {
                testnopackage 'apt'
                testwarning aptget update --allow-insecure-repositories -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
                failaptold
+               rm -rf rootdir/var/lib/apt/lists
+               sed -i 's#^deb\(-src\)\? #deb\1 [allow-insecure=yes] #' rootdir/etc/apt/sources.list.d/*
+               testwarning aptget update --no-allow-insecure-repositories -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
+               failaptold
+               sed -i 's#^deb\(-src\)\? \[allow-insecure=yes\] #deb\1 #' rootdir/etc/apt/sources.list.d/*
 
                msgmsg 'Cold archive signed by' 'Marvin Paranoid'
                prepare "${PKGFILE}"