From aba813975abb880f8b27d659147f7760c02f99e7 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 27 Jun 2023 19:14:43 +0200 Subject: update: Add notice about missing Signed-By in deb822 sources We want to gently steer users towards having Signed-By for each source such that we can retire a shared keyring across sources which improves resilience against configuration issues and incompetent malicious actors. --- apt-pkg/deb/debmetaindex.cc | 3 +++ apt-pkg/metaindex.cc | 5 ++++- apt-pkg/metaindex.h | 12 +++++++++++- apt-pkg/sourcelist.cc | 2 ++ apt-private/private-update.cc | 14 ++++++++++++++ doc/examples/configure-index | 1 + test/integration/test-apt-get-update-sourceslist-warning | 12 ++++++++++++ 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index ef6bce261..744a5cab7 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1397,6 +1397,9 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ Deb->SetSnapshot(GetSnapshotOption(Options, "snapshot")) == false) return false; + if (GetBoolOption(Options, "sourceslist-entry-is-deb822", false)) + Deb->SetFlag(metaIndex::Flag::DEB822); + std::map::const_iterator const signedby = Options.find("signed-by"); if (signedby == Options.end()) { diff --git a/apt-pkg/metaindex.cc b/apt-pkg/metaindex.cc index 97996b3f1..f3df9b159 100644 --- a/apt-pkg/metaindex.cc +++ b/apt-pkg/metaindex.cc @@ -11,8 +11,9 @@ #include /*}}}*/ -class metaIndexPrivate /*{{{*/ +struct metaIndexPrivate /*{{{*/ { + int Flags; }; /*}}}*/ @@ -69,6 +70,8 @@ APT_PURE signed short metaIndex::GetDefaultPin() const { return 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; } +APT_PURE bool metaIndex::HasFlag(metaIndex::Flag Flag) const { return d->Flags & int(Flag); } +void metaIndex::SetFlag(metaIndex::Flag Flag) { d->Flags |= int(Flag); } APT_PURE metaIndex::TriState metaIndex::GetLoadedSuccessfully() const { return LoadedSuccessfully; } APT_PURE std::string metaIndex::GetExpectedDist() const { return Dist; } /*}}}*/ diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index b8db21705..3e9cf3718 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -30,7 +30,13 @@ public: enum APT_HIDDEN TriState { TRI_YES, TRI_DONTCARE, TRI_NO, TRI_UNSET }; -private: + + enum class APT_HIDDEN Flag + { + DEB822 = 0x01, + }; + + private: metaIndexPrivate * const d; protected: std::vector *Indexes; @@ -74,6 +80,10 @@ public: time_t GetValidUntil() const; time_t GetDate() const; virtual time_t GetNotBefore() const = 0; +#ifdef APT_COMPILING_APT + bool HasFlag(Flag flag) const; +#endif + void SetFlag(Flag flag) APT_HIDDEN; std::string GetExpectedDist() const; bool CheckDist(std::string const &MaybeDist) const; diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 055cf4142..e11afceed 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -143,6 +143,8 @@ bool pkgSourceList::Type::ParseStanza(vector &List, /*{{{*/ Options["sourceslist-entry"] = entry; } + Options["sourceslist-entry-is-deb822"] = "true"; + // now create one item per suite/section auto const list_uris = FindMultiValue(Tags, "URIs"); auto const list_comp = FindMultiValue(Tags, "Components"); diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc index d6f7d62dd..cc0753c26 100644 --- a/apt-private/private-update.cc +++ b/apt-private/private-update.cc @@ -233,6 +233,20 @@ bool DoUpdate() } } + if (_config->FindB("APT::Get::Update::SourceListWarnings::SignedBy", SLWarnings)) + { + for (auto *S : *List) + { + if (not S->HasFlag(metaIndex::Flag::DEB822) || not S->GetSignedBy().empty()) + continue; + + URI uri(S->GetURI()); + // TRANSLATOR: the first is manpage reference, the last the URI from a sources.list + _error->Notice(_("Missing Signed-By in the %s entry for '%s'"), + "sources.list(5)", URI::ArchiveOnly(uri).c_str()); + } + } + // show basic stats (if the user whishes) if (_config->FindB("APT::Cmd::Show-Update-Stats", false) == true) { diff --git a/doc/examples/configure-index b/doc/examples/configure-index index d220a814f..6a168192c 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -130,6 +130,7 @@ APT { APTAuth ""; NonFreeFirmware ""; + SignedBy ""; }; }; }; diff --git a/test/integration/test-apt-get-update-sourceslist-warning b/test/integration/test-apt-get-update-sourceslist-warning index 02e1ccb29..3a3cb2e9f 100755 --- a/test/integration/test-apt-get-update-sourceslist-warning +++ b/test/integration/test-apt-get-update-sourceslist-warning @@ -38,6 +38,17 @@ testsuccessequal "$BOILERPLATE" apt update --no-download echo 'deb-src http://example.org/debian bookworm main non-free' > rootdir/etc/apt/sources.list.d/example.list testsuccessequal "$BOILERPLATE" apt update --no-download +msgmsg 'Suggest Signed-By for deb822 sources.list(5) entries' +rm rootdir/etc/apt/sources.list.d/example.list +echo 'Types: deb +URIs: http://example.org/debian +Suites: bookworm +Components: main +' > rootdir/etc/apt/sources.list.d/example.sources +testsuccessequal "$BOILERPLATE +N: Missing Signed-By in the sources.list(5) entry for 'http://example.org/debian'" apt update --no-download +rm rootdir/etc/apt/sources.list.d/example.sources + msgmsg 'Is non-free-firmware missing?' echo 'deb http://example.org/debian bookworm main non-free' > rootdir/etc/apt/sources.list.d/example.list cat >> rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_non-free_binary-amd64_Packages <