summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/metaindex.cc13
-rw-r--r--apt-pkg/metaindex.h5
-rw-r--r--apt-private/private-sources.cc224
-rw-r--r--apt-private/private-sources.h1
-rw-r--r--apt-private/private-update.cc41
-rw-r--r--cmdline/apt.cc1
-rw-r--r--doc/apt-verbatim.ent10
-rw-r--r--doc/sources.list.5.xml6
-rwxr-xr-xtest/integration/test-apt-get-update-sourceslist-warning20
-rwxr-xr-xtest/integration/test-apt-modernize-sources85
-rw-r--r--vendor/CMakeLists.txt13
-rw-r--r--vendor/debian/apt-vendor.ent10
-rw-r--r--vendor/debian/debian.sources.in36
-rw-r--r--vendor/debian/sources.list.in8
-rw-r--r--vendor/ubuntu/apt-vendor.ent10
-rw-r--r--vendor/ubuntu/sources.list.in10
-rw-r--r--vendor/ubuntu/ubuntu.sources.in44
17 files changed, 482 insertions, 55 deletions
diff --git a/apt-pkg/metaindex.cc b/apt-pkg/metaindex.cc
index f3df9b159..10c93de15 100644
--- a/apt-pkg/metaindex.cc
+++ b/apt-pkg/metaindex.cc
@@ -1,6 +1,7 @@
// Include Files /*{{{*/
#include <config.h>
+#include <apt-pkg/fileutl.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/metaindex.h>
#include <apt-pkg/pkgcachegen.h>
@@ -151,3 +152,15 @@ bool metaIndex::HasSupportForComponent(std::string const &) const/*{{{*/
return true;
}
/*}}}*/
+bool metaIndex::Load(std::string *ErrorText) /*{{{*/
+{
+ auto debmeta = dynamic_cast<debReleaseIndex *>(this);
+ if (not debmeta)
+ return false;
+ if (auto f = debmeta->MetaIndexFile("InRelease"); FileExists(f))
+ return Load(f, ErrorText);
+ if (auto f = debmeta->MetaIndexFile("Release"); FileExists(f))
+ return Load(f, ErrorText);
+ return false;
+}
+ /*}}}*/
diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h
index e2a773c31..e6c8b7c64 100644
--- a/apt-pkg/metaindex.h
+++ b/apt-pkg/metaindex.h
@@ -96,6 +96,7 @@ public:
virtual std::vector<pkgIndexFile *> *GetIndexFiles() = 0;
virtual bool IsTrusted() const = 0;
virtual bool Load(std::string const &Filename, std::string * const ErrorText) = 0;
+ bool Load(std::string *const ErrorText);
/** @return a new metaIndex object based on this one, but without information from #Load */
virtual metaIndex * UnloadedClone() const = 0;
// the given metaIndex is potentially invalid after this call and should be deleted
@@ -120,6 +121,10 @@ public:
virtual bool IsArchitectureSupported(std::string const &arch) const;
virtual bool IsArchitectureAllSupportedFor(IndexTarget const &target) const;
virtual bool HasSupportForComponent(std::string const &component) const;
+
+#ifdef APT_COMPILING_APT
+ bool IsTrustedSet() { return Trusted == TRI_YES; }
+#endif
};
#endif
diff --git a/apt-private/private-sources.cc b/apt-private/private-sources.cc
index a7d003f08..84d82af33 100644
--- a/apt-private/private-sources.cc
+++ b/apt-private/private-sources.cc
@@ -6,6 +6,7 @@
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/hashes.h>
+#include <apt-pkg/metaindex.h>
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/strutl.h>
@@ -15,6 +16,7 @@
#include <cstddef>
#include <iostream>
+#include <regex>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
@@ -22,6 +24,8 @@
#include <apti18n.h>
+using std::operator""sv;
+
/* Interface discussion with donkult (for the future):
apt [add-{archive,release,component}|edit|change-release|disable]-sources
and be clever and work out stuff from the Release file
@@ -103,3 +107,223 @@ bool EditSources(CommandLine &CmdL)
return res;
}
/*}}}*/
+
+template <typename T, typename V>
+static auto contains(T const &container, V const &value) -> bool
+{
+ return std::find(container.begin(), container.end(), value) != container.end();
+}
+static auto merge(std::vector<std::string> &a, std::vector<std::string> const &b)
+{
+ for (auto const &e : b)
+ if (not contains(a, e))
+ a.push_back(e);
+}
+
+static bool Modernize(std::string const &filename) /*{{{*/
+{
+ auto isMain = filename == _config->FindFile("Dir::Etc::SourceList");
+ auto simulate = _config->FindB("APT::Get::Simulate");
+
+ std::cerr << "Modernizing " << filename << "...\n";
+ pkgSourceList list;
+ if (not list.Read(filename))
+ return false;
+
+ struct Entry
+ {
+ std::set<std::string> types;
+ std::vector<std::string> uris;
+ std::vector<std::string> suites;
+ std::vector<std::string> components;
+ std::string signedBy;
+ std::map<std::string, std::string> options;
+ std::string origin;
+ bool merged = false;
+
+ auto Merge(Entry &other) -> bool
+ {
+ auto howManyDifferent = (types != other.types) + (uris != other.uris) + (suites != other.suites) + (components != other.components);
+ if (howManyDifferent > 1)
+ return false;
+ if (options != other.options)
+ return false;
+ if (origin != other.origin)
+ return false;
+ if (signedBy.empty() && not other.signedBy.empty() && (uris != other.uris || suites != other.suites))
+ return false;
+ if (not signedBy.empty() && not other.signedBy.empty() && signedBy != other.signedBy)
+ return false;
+
+ types.insert(other.types.begin(), other.types.end());
+ merge(uris, other.uris);
+ merge(suites, other.suites);
+ merge(components, other.components);
+ if (signedBy.empty())
+ signedBy = other.signedBy;
+
+ other.merged = true;
+ return true;
+ }
+ };
+ std::vector<Entry> entries;
+ for (auto const &meta : list)
+ {
+ Entry e;
+
+ e.uris.push_back(meta->GetURI());
+ e.suites.push_back(meta->GetDist());
+ for (auto const &t : meta->GetIndexTargets())
+ {
+ e.types.insert(t.Option(IndexTarget::TARGET_OF));
+ if (not contains(e.components, t.Option(IndexTarget::COMPONENT)))
+ e.components.push_back(t.Option(IndexTarget::COMPONENT));
+ }
+
+ if (meta->IsTrustedSet())
+ e.options["Trusted"] = "yes";
+
+ std::string err;
+ e.signedBy = meta->GetSignedBy();
+ meta->Load(&err);
+ if (e.signedBy.empty() && not meta->GetOrigin().empty())
+ {
+ std::string dir = _config->FindDir("Dir") + std::string{"usr/share/keyrings/"};
+ std::string keyring = meta->GetOrigin() + "-archive-keyring.gpg";
+ std::transform(keyring.begin(), keyring.end(), keyring.begin(), tolower);
+ if (FileExists(dir + keyring))
+ e.signedBy = dir + keyring;
+ }
+ if (auto k = _config->FindDir("Dir::Etc::trustedparts") + flNotDir(std::regex_replace(filename, std::regex("\\.list$"), ".gpg")); FileExists(k))
+ e.signedBy = k;
+ if (auto k = _config->FindDir("Dir::Etc::trustedparts") + flNotDir(std::regex_replace(filename, std::regex("\\.list$"), ".asc")); FileExists(k))
+ e.signedBy = k;
+
+ if (isMain && not meta->GetOrigin().empty())
+ {
+ constexpr auto bad = "\\|{}[]<>\"^~_=!@#$%^&*"sv;
+ e.origin = meta->GetOrigin();
+ std::transform(e.origin.begin(), e.origin.end(), e.origin.begin(), tolower);
+ std::transform(e.origin.begin(), e.origin.end(), e.origin.begin(), [](char c) -> char
+ { return isspace(c) ? '-' : c; });
+ std::transform(e.origin.begin(), e.origin.end(), e.origin.begin(), [bad](char c) -> char
+ { return bad.find(c) != bad.npos ? '-' : c; });
+ std::replace(e.origin.begin(), e.origin.end(), '/', '-');
+ }
+
+ entries.push_back(std::move(e));
+ }
+
+ for (bool merged = false; merged;)
+ {
+ merged = false;
+ for (auto it = entries.begin(); it != entries.end(); ++it)
+ {
+ for (auto it2 = it + 1; it2 != entries.end(); ++it2)
+ if (not it2->merged)
+ merged |= it->Merge(*it2);
+ }
+ }
+
+ std::map<std::string, std::ofstream> streams;
+ for (auto const &e : entries)
+ {
+ std::string outname;
+ if (not isMain)
+ outname = std::regex_replace(filename, std::regex("\\.list$"), ".sources");
+ else if (e.origin.empty())
+ outname = _config->FindDir("Dir::Etc::SourceParts") + "moved-from-main.sources";
+ else
+ outname = _config->FindDir("Dir::Etc::SourceParts") + (e.origin) + ".sources";
+
+ if (auto it = streams.find(outname); it == streams.end())
+ {
+ if (not simulate)
+ std::cerr << "- Writing " << outname << "\n";
+ streams[outname].open(simulate ? "/dev/stdout" : outname, std::ios::app);
+ }
+ auto &out = streams[outname];
+ if (not out)
+ _error->Warning("Cannot open %s for writing.", outname.c_str());
+ if (e.merged)
+ continue;
+
+ if (out.tellp() != 0)
+ out << "\n";
+
+ if (simulate)
+ out << "# Would write to: " << outname << "\n";
+ if (isMain)
+ out << "# Modernized from " << filename << "\n";
+ out << "Types:";
+ for (auto const &t : e.types)
+ out << " " << t;
+ out << "\n";
+ out << "URIs: " << APT::String::Join(e.uris, " ") << "\n";
+ out << "Suites: " << APT::String::Join(e.suites, " ") << "\n";
+ out << "Components: " << APT::String::Join(e.components, " ") << "\n";
+ out << "Signed-By: " << e.signedBy << "\n";
+ for (auto const &[key, value] : e.options)
+ out << key << ": " << value << "\n";
+ if (e.signedBy.empty())
+ _error->Warning("Could not determine Signed-By for URIs: %s, Suites: %s", APT::String::Join(e.uris, " ").c_str(), APT::String::Join(e.suites, " ").c_str());
+ }
+
+ if (not simulate && rename(filename.c_str(), (filename + ".bak").c_str()) != 0)
+ _error->WarningE("rename", "Could not rename %s", filename.c_str());
+
+ _error->DumpErrors();
+ std::cerr << "\n";
+ return true;
+}
+ /*}}}*/
+bool ModernizeSources(CommandLine &) /*{{{*/
+{
+ auto main = _config->FindFile("Dir::Etc::SourceList");
+ auto parts = _config->FindDir("Dir::Etc::SourceParts");
+ std::vector<std::string> files;
+ if (FileExists(main))
+ files.push_back(main);
+ for (auto const &I : GetListOfFilesInDir(parts, std::vector<std::string>{"list", "sources"}, true))
+ if (APT::String::Endswith(I, ".list"))
+ files.push_back(I);
+ if (files.empty())
+ {
+ std::cout << "All sources are modern.\n";
+ return true;
+ }
+
+ // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
+ auto no = _("N");
+
+ std::cout << "The following files need modernizing:\n";
+ for (auto const &I : files)
+ std::cout << " - " << I << "\n";
+ std::cout << "\n"
+ << "Modernizing will replace .list files with the new .sources format,\n"
+ << "add Signed-By values where they can be determined automatically,\n"
+ << "and save the old files into .list.bak files.\n"
+ << "\n"
+ << "This command supports the 'signed-by' and 'trusted' options. If you\n"
+ << "have specified other options inside [] brackets, please transfer them\n"
+ << "manually to the output files; see sources.list(5) for a mapping.\n"
+ << "\n"
+ << "For a simulation, respond " << no << " in the following prompt.\n";
+
+ std::string prompt;
+ strprintf(prompt, _("Rewrite %zu sources?"), files.size());
+ if (YnPrompt(prompt.c_str(), true) == false)
+ {
+ _config->Set("APT::Get::Simulate", true);
+ std::cout << "Simulating only..." << std::endl;
+ // Make it visible.
+ usleep(100 * 1000);
+ }
+
+ bool good = true;
+ for (auto const &I : files)
+ good = good && Modernize(I);
+
+ return good;
+}
+ /*}}}*/
diff --git a/apt-private/private-sources.h b/apt-private/private-sources.h
index 0c421902e..0f1e89af2 100644
--- a/apt-private/private-sources.h
+++ b/apt-private/private-sources.h
@@ -6,5 +6,6 @@
class CommandLine;
APT_PUBLIC bool EditSources(CommandLine &CmdL);
+APT_PUBLIC bool ModernizeSources(CommandLine &CmdL);
#endif
diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc
index 2b96f48fb..bd8823568 100644
--- a/apt-private/private-update.cc
+++ b/apt-private/private-update.cc
@@ -106,23 +106,40 @@ bool DoUpdate()
if (_config->FindB("APT::Get::Update::SourceListWarnings::SignedBy", SLWarnings))
{
- bool allDeb822 = true;
+ bool modernize = false;
for (auto *S : *List)
{
- if (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());
- allDeb822 &= S->HasFlag(metaIndex::Flag::DEB822);
+
+ if (not S->HasFlag(metaIndex::Flag::DEB822))
+ {
+ // TRANSLATOR: the first is manpage reference, the last the URI from a sources.list
+ _error->Audit(_("The %s entry for '%s' should be upgraded to deb822 .sources"),
+ "sources.list(5)", URI::ArchiveOnly(uri).c_str());
+ }
+ if (S->GetSignedBy().empty())
+ {
+ if (S->HasFlag(metaIndex::Flag::DEB822))
+ {
+ // 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());
+ }
+ else
+ {
+ // TRANSLATOR: the first is manpage reference, the last the URI from a sources.list
+ _error->Audit(_("Missing Signed-By in the %s entry for '%s'"),
+ "sources.list(5)", URI::ArchiveOnly(uri).c_str());
+ modernize = true;
+ }
+ }
}
- if (not allDeb822)
+ if (modernize)
{
- _error->Notice(_("Consider migrating all sources.list(5) entries to the deb822 .sources format"));
- _error->Notice(_("The deb822 .sources format supports both embedded as well as external OpenPGP keys"));
- _error->Notice(_("See apt-secure(8) for best practices in configuring repository signing."));
+ _error->Audit(_("Consider migrating all sources.list(5) entries to the deb822 .sources format"));
+ _error->Audit(_("The deb822 .sources format supports both embedded as well as external OpenPGP keys"));
+ _error->Audit(_("See apt-secure(8) for best practices in configuring repository signing."));
+ _error->Notice(_("Some sources can be modernized. Run 'apt modernize-sources' to do so."));
}
}
diff --git a/cmdline/apt.cc b/cmdline/apt.cc
index ef58bcebf..af8a95fa5 100644
--- a/cmdline/apt.cc
+++ b/cmdline/apt.cc
@@ -78,6 +78,7 @@ static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
// misc
{"edit-sources", &EditSources, _("edit the source information file")},
+ {"modernize-sources", &ModernizeSources, _("modernize .list files to .sources files")},
{"moo", &DoMoo, nullptr},
{"satisfy", &DoBuildDep, _("satisfy dependency strings")},
diff --git a/doc/apt-verbatim.ent b/doc/apt-verbatim.ent
index 53b099ad7..85aca1607 100644
--- a/doc/apt-verbatim.ent
+++ b/doc/apt-verbatim.ent
@@ -271,11 +271,11 @@
<!ENTITY apt-product-version "2.9.25">
<!-- (Code)names for various things used all over the place -->
-<!ENTITY debian-oldstable-codename "bullseye">
-<!ENTITY debian-stable-codename "bookworm">
-<!ENTITY debian-testing-codename "trixie">
-<!ENTITY debian-stable-version "12">
-<!ENTITY ubuntu-codename "lunar">
+<!ENTITY debian-oldstable-codename "bookworm">
+<!ENTITY debian-stable-codename "trixie">
+<!ENTITY debian-testing-codename "forky">
+<!ENTITY debian-stable-version "13">
+<!ENTITY ubuntu-codename "plucky">
<!-- good and bad just refers to matching and not matching a pattern…
It is not a remark about the specific perl version.
diff --git a/doc/sources.list.5.xml b/doc/sources.list.5.xml
index 97f639c06..eb734215b 100644
--- a/doc/sources.list.5.xml
+++ b/doc/sources.list.5.xml
@@ -93,6 +93,10 @@
expect to encounter options as they were uncommon before the introduction of
multi-architecture support.
</para>
+ <para>
+ This format is deprecated and may eventually be removed, but not before
+ 2029.
+ </para>
</refsect1>
<refsect1><title>deb822-Style Format</title>
@@ -197,7 +201,7 @@ deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [.
network, followed by distant Internet hosts, for example).</para>
<para>As an example, the sources for your distribution could look like this
- in one-line-style format:
+ in the deprecated one-line-style format:
<literallayout>&sourceslist-list-format;</literallayout> or like this in
deb822 style format:
<literallayout>&sourceslist-sources-format;</literallayout></para>
diff --git a/test/integration/test-apt-get-update-sourceslist-warning b/test/integration/test-apt-get-update-sourceslist-warning
index 7e27e4825..5a941dae6 100755
--- a/test/integration/test-apt-get-update-sourceslist-warning
+++ b/test/integration/test-apt-get-update-sourceslist-warning
@@ -46,14 +46,18 @@ msgmsg 'Detect login info embedded in sources.list'
echo 'deb http://apt:debian@example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
testsuccessequal "$BOILERPLATE
N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'http://example.org/debian'
-N: Missing Signed-By in the sources.list(5) entry for 'http://example.org/debian'
-N: Consider migrating all sources.list(5) entries to the deb822 .sources format
-N: The deb822 .sources format supports both embedded as well as external OpenPGP keys
-N: See apt-secure(8) for best practices in configuring repository signing." apt update --no-download
+A: The sources.list(5) entry for 'http://example.org/debian' should be upgraded to deb822 .sources
+A: Missing Signed-By in the sources.list(5) entry for 'http://example.org/debian'
+A: Consider migrating all sources.list(5) entries to the deb822 .sources format
+A: The deb822 .sources format supports both embedded as well as external OpenPGP keys
+A: See apt-secure(8) for best practices in configuring repository signing.
+N: Some sources can be modernized. Run 'apt modernize-sources' to do so." apt update --no-download --audit
echo 'deb tor+https://apt:debian@example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
testsuccessequal "$BOILERPLATE
N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'tor+https://example.org/debian'
-N: Missing Signed-By in the sources.list(5) entry for 'tor+https://example.org/debian'
-N: Consider migrating all sources.list(5) entries to the deb822 .sources format
-N: The deb822 .sources format supports both embedded as well as external OpenPGP keys
-N: See apt-secure(8) for best practices in configuring repository signing." apt update --no-download
+A: The sources.list(5) entry for 'tor+https://example.org/debian' should be upgraded to deb822 .sources
+A: Missing Signed-By in the sources.list(5) entry for 'tor+https://example.org/debian'
+A: Consider migrating all sources.list(5) entries to the deb822 .sources format
+A: The deb822 .sources format supports both embedded as well as external OpenPGP keys
+A: See apt-secure(8) for best practices in configuring repository signing.
+N: Some sources can be modernized. Run 'apt modernize-sources' to do so." apt update --no-download --audit
diff --git a/test/integration/test-apt-modernize-sources b/test/integration/test-apt-modernize-sources
new file mode 100755
index 000000000..26fd8055a
--- /dev/null
+++ b/test/integration/test-apt-modernize-sources
@@ -0,0 +1,85 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+configarchitecture 'native'
+
+echo 'deb http://example.org/debian stable rocks' > rootdir/etc/apt/sources.list.d/rocks.list
+echo 'deb http://deb.debian.org/debian stable main' >> rootdir/etc/apt/sources.list
+echo 'deb-src http://deb.debian.org/debian stable main' >> rootdir/etc/apt/sources.list
+echo 'deb-src http://deb.debian.org/debian unstable main' >> rootdir/etc/apt/sources.list
+echo 'deb http://example.org/debian stable bananas' >> rootdir/etc/apt/sources.list
+echo 'deb [trusted=yes] http://example.org/debian trusted bananas' >> rootdir/etc/apt/sources.list
+
+
+mkdir -p rootdir/usr/share/keyrings/
+mkdir -p rootdir/var/lib/apt/lists
+echo > rootdir/etc/apt/trusted.gpg.d/rocks.gpg
+echo > rootdir/usr/share/keyrings/debian-archive-keyring.gpg
+echo "Date: $(date -ud '-2 weeks' '+%a, %d %b %Y %H:%M:%S %Z')" > rootdir/var/lib/apt/lists/deb.debian.org_debian_dists_unstable_InRelease
+echo "Date: $(date -ud '-2 weeks' '+%a, %d %b %Y %H:%M:%S %Z')" > rootdir/var/lib/apt/lists/deb.debian.org_debian_dists_stable_InRelease
+echo "Origin: Debian" >> rootdir/var/lib/apt/lists/deb.debian.org_debian_dists_unstable_InRelease
+echo "Origin: Debian" >> rootdir/var/lib/apt/lists/deb.debian.org_debian_dists_stable_InRelease
+
+# We test that appending produces valid output here, so we already configure a source in here.
+echo "Types: deb" >> rootdir/etc/apt/sources.list.d/debian.sources
+echo "URIs: https://deb.debian.org/debian/" >> rootdir/etc/apt/sources.list.d/debian.sources
+echo "Suites: experimental" >> rootdir/etc/apt/sources.list.d/debian.sources
+echo "Components: contrib" >> rootdir/etc/apt/sources.list.d/debian.sources
+echo "Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg" >> rootdir/etc/apt/sources.list.d/debian.sources
+
+testwarning apt modernize-sources -y
+
+testsuccessequal "rootdir/etc/apt/sources.list.bak
+
+rootdir/etc/apt/sources.list.d:
+debian.sources
+moved-from-main.sources
+rocks.list.bak
+rocks.sources" ls -1 rootdir/etc/apt/sources.list*
+
+testfileequal rootdir/etc/apt/sources.list.d/debian.sources "Types: deb
+URIs: https://deb.debian.org/debian/
+Suites: experimental
+Components: contrib
+Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
+
+# Modernized from ${TMPWORKINGDIRECTORY}/rootdir/etc/apt/sources.list
+Types: deb deb-src
+URIs: http://deb.debian.org/debian/
+Suites: stable
+Components: main
+Signed-By: ${TMPWORKINGDIRECTORY}/rootdir/usr/share/keyrings/debian-archive-keyring.gpg
+
+# Modernized from ${TMPWORKINGDIRECTORY}/rootdir/etc/apt/sources.list
+Types: deb-src
+URIs: http://deb.debian.org/debian/
+Suites: unstable
+Components: main
+Signed-By: ${TMPWORKINGDIRECTORY}/rootdir/usr/share/keyrings/debian-archive-keyring.gpg"
+
+testfileequal rootdir/etc/apt/sources.list.d/rocks.sources "Types: deb
+URIs: http://example.org/debian/
+Suites: stable
+Components: rocks
+Signed-By: ${TMPWORKINGDIRECTORY}/rootdir/etc/apt/trusted.gpg.d/rocks.gpg"
+
+testfileequal rootdir/etc/apt/sources.list.d/moved-from-main.sources "# Modernized from ${TMPWORKINGDIRECTORY}/rootdir/etc/apt/sources.list
+Types: deb
+URIs: http://example.org/debian/
+Suites: stable
+Components: bananas
+Signed-By:
+
+# Modernized from ${TMPWORKINGDIRECTORY}/rootdir/etc/apt/sources.list
+Types: deb
+URIs: http://example.org/debian/
+Suites: trusted
+Components: bananas
+Signed-By:
+Trusted: yes"
+
+testsuccessequal "All sources are modern." apt modernize-sources
diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt
index 615d282da..987f7bab3 100644
--- a/vendor/CMakeLists.txt
+++ b/vendor/CMakeLists.txt
@@ -12,8 +12,15 @@ endif()
# Handle sources.list example
if (WITH_DOC OR WITH_DOC_EXAMPLES)
-add_vendor_file(OUTPUT sources.list
- INPUT "${CURRENT_VENDOR}/sources.list.in"
+if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${CURRENT_VENDOR}/${CURRENT_VENDOR}.sources.in")
+ set(sources_in "${CURRENT_VENDOR}/${CURRENT_VENDOR}.sources.in")
+ set(sources_out "${CURRENT_VENDOR}.sources")
+else()
+ set(sources_in "${CURRENT_VENDOR}/sources.list.in")
+ set(sources_out "sources.list")
+endif()
+add_vendor_file(OUTPUT ${sources_out}
+ INPUT "${sources_in}"
MODE 644
VARIABLES sourceslist-list-format
debian-stable-codename
@@ -21,7 +28,7 @@ add_vendor_file(OUTPUT sources.list
debian-testing-codename
ubuntu-codename
current-codename)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sources.list
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${sources_out}
DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples)
endif()
diff --git a/vendor/debian/apt-vendor.ent b/vendor/debian/apt-vendor.ent
index 864f5a8df..8d31a39bf 100644
--- a/vendor/debian/apt-vendor.ent
+++ b/vendor/debian/apt-vendor.ent
@@ -2,15 +2,17 @@
<!ENTITY keyring-distro "Debian">
<!ENTITY keyring-package "<package>debian-archive-keyring</package>">
-<!ENTITY sourceslist-list-format "deb http://deb.debian.org/debian &debian-stable-codename; main contrib non-free non-free-firmware
-deb http://deb.debian.org/debian &debian-stable-codename;-updates main contrib non-free non-free-firmware
-deb http://deb.debian.org/debian-security &debian-stable-codename;-security main contrib non-free non-free-firmware">
+<!ENTITY sourceslist-list-format "deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian &debian-stable-codename; main contrib non-free non-free-firmware
+deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian &debian-stable-codename;-updates main contrib non-free non-free-firmware
+deb [signed-by=/usr/share/keyrings/debian-archive-keyring.gpg] http://deb.debian.org/debian-security &debian-stable-codename;-security main contrib non-free non-free-firmware">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://deb.debian.org/debian
Suites: &debian-stable-codename; &debian-stable-codename;-updates
Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: &debian-stable-codename;-security
-Components: main contrib non-free non-free-firmware">
+Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg">
diff --git a/vendor/debian/debian.sources.in b/vendor/debian/debian.sources.in
new file mode 100644
index 000000000..c7b8232fe
--- /dev/null
+++ b/vendor/debian/debian.sources.in
@@ -0,0 +1,36 @@
+## Debian distribution repository
+##
+## The following settings can be adjusted to configure which packages to use from Debian.
+## Mirror your choices (except for URIs and Suites) in the security section below to
+## ensure timely security updates.
+##
+## Types: Append deb-src to enable the fetching of source package.
+## URIs: A URL to the repository (you may add multiple URLs)
+## Suites: The following additional suites can be configured
+## <name>-updates - Urgent bug fix updates produced after the final release of the
+## distribution.
+## <name>-backports - software from this repository may not have been tested as
+## extensively as that contained in the main release, although it includes
+## newer versions of some applications which may provide useful features.
+## Also, please note that software in backports WILL NOT receive any review
+## or updates from the Debian security team.
+## Components: Aside from main, the following components can be added to the list
+## contrib - Free software that may require non-free software to run.
+## non-free-firmware - Firmware that is non-free
+## non-free - Software that is not under a free license. There may be restrictions
+## on use or modification.
+##
+## See the sources.list(5) manual page for further settings.
+Types: deb
+URIs: http://deb.debian.org/debian
+Suites: &debian-stable-codename; &debian-stable-codename;-updates
+Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
+
+## Debian security updates. Aside from URIs and Suites,
+## this should mirror your choices in the previous section.
+Types: deb
+URIs: http://deb.debian.org/debian-security
+Suites: &debian-stable-codename;-security
+Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
diff --git a/vendor/debian/sources.list.in b/vendor/debian/sources.list.in
deleted file mode 100644
index 8f83dfd79..000000000
--- a/vendor/debian/sources.list.in
+++ /dev/null
@@ -1,8 +0,0 @@
-# See sources.list(5) manpage for more information
-# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.
-&sourceslist-list-format;
-
-# Uncomment if you want the apt-get source function to work
-#deb-src http://deb.debian.org/debian &debian-stable-codename; main contrib non-free
-#deb-src http://deb.debian.org/debian &debian-stable-codename;-updates main contrib non-free
-#deb-src http://deb.debian.org/debian-security &debian-stable-codename;-security main contrib non-free
diff --git a/vendor/ubuntu/apt-vendor.ent b/vendor/ubuntu/apt-vendor.ent
index 9cf7b55fb..8c52fd4f3 100644
--- a/vendor/ubuntu/apt-vendor.ent
+++ b/vendor/ubuntu/apt-vendor.ent
@@ -2,15 +2,17 @@
<!ENTITY keyring-distro "Ubuntu">
<!ENTITY keyring-package "<package>ubuntu-keyring</package>">
-<!ENTITY sourceslist-list-format "deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
-deb http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
-deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted">
+<!ENTITY sourceslist-list-format "deb [signed-by=/usr/share/keyrings/ubuntu-archive-keyring.gpg] http://archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
+deb [signed-by=/usr/share/keyrings/ubuntu-archive-keyring.gpg] http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
+deb [signed-by=/usr/share/keyrings/ubuntu-archive-keyring.gpg] http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted">
<!ENTITY sourceslist-sources-format "Types: deb
URIs: http://us.archive.ubuntu.com/ubuntu
Suites: &ubuntu-codename; &ubuntu-codename;-updates
Components: main restricted
+Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: http://security.ubuntu.com/ubuntu
Suites: &ubuntu-codename;-security
-Components: main restricted">
+Components: main restricted
+Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg">
diff --git a/vendor/ubuntu/sources.list.in b/vendor/ubuntu/sources.list.in
deleted file mode 100644
index 00db2f8cd..000000000
--- a/vendor/ubuntu/sources.list.in
+++ /dev/null
@@ -1,10 +0,0 @@
-# See sources.list(5) manpage for more information
-# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.
-deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
-deb-src http://us.archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
-
-deb http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
-deb-src http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
-
-deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted
-deb-src http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted
diff --git a/vendor/ubuntu/ubuntu.sources.in b/vendor/ubuntu/ubuntu.sources.in
new file mode 100644
index 000000000..0bf527ea9
--- /dev/null
+++ b/vendor/ubuntu/ubuntu.sources.in
@@ -0,0 +1,44 @@
+# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
+# newer versions of the distribution.
+
+## Ubuntu distribution repository
+##
+## The following settings can be adjusted to configure which packages to use from Ubuntu.
+## Mirror your choices (except for URIs and Suites) in the security section below to
+## ensure timely security updates.
+##
+## Types: Append deb-src to enable the fetching of source package.
+## URIs: A URL to the repository (you may add multiple URLs)
+## Suites: The following additional suites can be configured
+## <name>-updates - Major bug fix updates produced after the final release of the
+## distribution.
+## <name>-backports - software from this repository may not have been tested as
+## extensively as that contained in the main release, although it includes
+## newer versions of some applications which may provide useful features.
+## Also, please note that software in backports WILL NOT receive any review
+## or updates from the Ubuntu security team.
+## Components: Aside from main, the following components can be added to the list
+## restricted - Software that may not be under a free license, or protected by patents.
+## universe - Community maintained packages. Software in this repository receives maintenance
+## from volunteers in the Ubuntu community, or a 10 year security maintenance
+## commitment from Canonical when an Ubuntu Pro subscription is attached.
+## multiverse - Community maintained of restricted. Software from this repository is
+## ENTIRELY UNSUPPORTED by the Ubuntu team, and may not be under a free
+## licence. Please satisfy yourself as to your rights to use the software.
+## Also, please note that software in multiverse WILL NOT receive any
+## review or updates from the Ubuntu security team.
+##
+## See the sources.list(5) manual page for further settings.
+Types: deb
+URIs: http://archive.ubuntu.com/ubuntu/
+Suites: &ubuntu-codename; &ubuntu-codename;-updates &ubuntu-codename;-backports
+Components: main universe restricted multiverse
+Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
+
+## Ubuntu security updates. Aside from URIs and Suites,
+## this should mirror your choices in the previous section.
+Types: deb
+URIs: http://security.ubuntu.com/ubuntu/
+Suites: &ubuntu-codename;-security
+Components: main universe restricted multiverse
+Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg