summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2019-02-01 14:43:52 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2019-02-01 17:52:03 +0100
commitc2b9b0489538fed4770515bd8853a960b13a2618 (patch)
tree1e667cbb28fb62d22bef583c70f5d3b86aed4d4b
parent8bb2a91a070170d7d8e71206d1c66a26809bdbc3 (diff)
Add a Packages-Require-Authorization Release file field
This new field allows a repository to declare that access to packages requires authorization. The current implementation will set the pin to -32768 if no authorization has been provided in the auth.conf(.d) files. This implementation is suboptimal in two aspects: (1) A repository should behave more like NotSource repositories (2) We only have the host name for the repository, we cannot use paths yet. - We can fix those after an ABI break. The code also adds a check to acquire-item.cc to not use the specified repository as a download source, mimicking NotSource.
-rw-r--r--apt-pkg/acquire-item.cc4
-rw-r--r--apt-pkg/contrib/netrc.cc44
-rw-r--r--apt-pkg/contrib/netrc.h4
-rw-r--r--apt-pkg/deb/debmetaindex.cc1
-rw-r--r--apt-pkg/pkgcache.h8
-rw-r--r--apt-pkg/policy.cc6
-rwxr-xr-xtest/integration/test-packages-require-authorization61
7 files changed, 124 insertions, 4 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 755e1fb59..bb3bc1b56 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -25,6 +25,7 @@
#include <apt-pkg/hashes.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/metaindex.h>
+#include <apt-pkg/netrc.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/sourcelist.h>
@@ -3394,6 +3395,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *const Owner, pkgSourceList *const Sourc
StoreFilename.clear();
std::set<string> targetComponents, targetCodenames, targetSuites;
+ std::vector<std::unique_ptr<FileFd>> authconfs;
for (auto Vf = Version.FileList(); Vf.end() == false; ++Vf)
{
auto const PkgF = Vf.File();
@@ -3401,6 +3403,8 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *const Owner, pkgSourceList *const Sourc
continue;
if (PkgF.Flagged(pkgCache::Flag::NotSource))
continue;
+ if (PkgF.Flagged(pkgCache::Flag::PackagesRequireAuthorization) && !IsAuthorized(PkgF, authconfs))
+ continue;
pkgIndexFile *Index;
if (Sources->FindIndex(PkgF, Index) == false)
continue;
diff --git a/apt-pkg/contrib/netrc.cc b/apt-pkg/contrib/netrc.cc
index 84b4c0ed8..48114ba3c 100644
--- a/apt-pkg/contrib/netrc.cc
+++ b/apt-pkg/contrib/netrc.cc
@@ -13,6 +13,7 @@
#include <config.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/strutl.h>
@@ -149,3 +150,46 @@ void maybe_add_auth(URI &Uri, std::string NetRCFile)
if (fd.Open(NetRCFile, FileFd::ReadOnly))
MaybeAddAuth(fd, Uri);
}
+
+/* Check if we are authorized. */
+bool IsAuthorized(pkgCache::PkgFileIterator const I, std::vector<std::unique_ptr<FileFd>> &authconfs)
+{
+ if (authconfs.empty())
+ {
+ _error->PushToStack();
+ auto const netrc = _config->FindFile("Dir::Etc::netrc");
+ if (not netrc.empty())
+ {
+ authconfs.emplace_back(new FileFd());
+ authconfs.back()->Open(netrc, FileFd::ReadOnly);
+ }
+
+ auto const netrcparts = _config->FindDir("Dir::Etc::netrcparts");
+ if (not netrcparts.empty())
+ {
+ for (auto const &netrc : GetListOfFilesInDir(netrcparts, "conf", true, true))
+ {
+ authconfs.emplace_back(new FileFd());
+ authconfs.back()->Open(netrc, FileFd::ReadOnly);
+ }
+ }
+ _error->RevertToStack();
+ }
+
+ // FIXME: Use the full base url
+ URI uri(std::string("http://") + I.Site() + "/");
+ for (auto &authconf : authconfs)
+ {
+ if (not authconf->IsOpen())
+ continue;
+ if (not authconf->Seek(0))
+ continue;
+
+ MaybeAddAuth(*authconf, uri);
+
+ if (not uri.User.empty() || not uri.Password.empty())
+ return true;
+ }
+
+ return false;
+}
diff --git a/apt-pkg/contrib/netrc.h b/apt-pkg/contrib/netrc.h
index 981494064..80d95acc1 100644
--- a/apt-pkg/contrib/netrc.h
+++ b/apt-pkg/contrib/netrc.h
@@ -13,9 +13,12 @@
#ifndef NETRC_H
#define NETRC_H
+#include <memory>
#include <string>
+#include <vector>
#include <apt-pkg/macros.h>
+#include <apt-pkg/pkgcache.h>
#ifndef APT_8_CLEANER_HEADERS
#include <apt-pkg/strutl.h>
@@ -32,4 +35,5 @@ class FileFd;
APT_DEPRECATED_MSG("Use FileFd-based MaybeAddAuth instead")
void maybe_add_auth(URI &Uri, std::string NetRCFile);
bool MaybeAddAuth(FileFd &NetRCFile, URI &Uri);
+bool IsAuthorized(pkgCache::PkgFileIterator const I, std::vector<std::unique_ptr<FileFd>> &authconfs) APT_HIDDEN;
#endif
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 1afcdf2c0..f88076abf 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -918,6 +918,7 @@ bool debReleaseIndex::Merge(pkgCacheGenerator &Gen,OpProgress * /*Prog*/) const/
#undef APT_INRELEASE
Section.FindFlag("NotAutomatic", File->Flags, pkgCache::Flag::NotAutomatic);
Section.FindFlag("ButAutomaticUpgrades", File->Flags, pkgCache::Flag::ButAutomaticUpgrades);
+ Section.FindFlag("Packages-Require-Authorization", File->Flags, pkgCache::Flag::PackagesRequireAuthorization);
return true;
}
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 5c33c7073..787e3995f 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -182,9 +182,11 @@ class pkgCache /*{{{*/
LocalSource=(1<<1), /*!< local sources can't and will not be verified by hashes */
NoPackages=(1<<2), /*!< the file includes no package records itself, but additions like Translations */
};
- enum ReleaseFileFlags {
- NotAutomatic=(1<<0), /*!< archive has a default pin of 1 */
- ButAutomaticUpgrades=(1<<1), /*!< (together with the previous) archive has a default pin of 100 */
+ enum ReleaseFileFlags
+ {
+ NotAutomatic = (1 << 0), /*!< archive has a default pin of 1 */
+ ButAutomaticUpgrades = (1 << 1), /*!< (together with the previous) archive has a default pin of 100 */
+ PackagesRequireAuthorization = (1 << 2), /*!< (together with the previous) archive has a default pin of 100 */
};
enum ProvidesFlags {
MultiArchImplicit=pkgCache::Dep::MultiArchImplicit, /*!< generated internally, not spelled out in the index */
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index 6de439d32..7986aa506 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -18,6 +18,7 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
+#include <apt-pkg/netrc.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/policy.h>
#include <apt-pkg/strutl.h>
@@ -87,7 +88,8 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(nullptr), VerPins(nullptr),
// ---------------------------------------------------------------------
/* */
bool pkgPolicy::InitDefaults()
-{
+{
+ std::vector<std::unique_ptr<FileFd>> authconfs;
// Initialize the priorities based on the status of the package file
for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I != Cache->FileEnd(); ++I)
{
@@ -98,6 +100,8 @@ bool pkgPolicy::InitDefaults()
PFPriority[I->ID] = 100;
else if (I.Flagged(pkgCache::Flag::NotAutomatic))
PFPriority[I->ID] = 1;
+ if (I.Flagged(pkgCache::Flag::PackagesRequireAuthorization) && !IsAuthorized(I, authconfs))
+ PFPriority[I->ID] = NEVER_PIN;
}
// Apply the defaults..
diff --git a/test/integration/test-packages-require-authorization b/test/integration/test-packages-require-authorization
new file mode 100755
index 000000000..527497ce5
--- /dev/null
+++ b/test/integration/test-packages-require-authorization
@@ -0,0 +1,61 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+setupenvironment
+configarchitecture 'amd64'
+
+insertpackage 'unstable' 'cool' 'amd64' '1.0'
+
+export APT_DONT_SIGN='InRelease'
+setupaptarchive --no-update
+changetowebserver
+
+echo 'Packages-Require-Authorization: yes' >> aptarchive/dists/unstable/Release
+signreleasefiles
+
+testsuccess aptget update
+testsuccessequal "Package files:
+ 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status
+ release a=now
+-32768 http://localhost:${APTHTTPPORT} unstable/main amd64 Packages
+ release a=unstable,n=sid,c=main,b=amd64
+ origin localhost
+Pinned packages:" aptcache policy
+
+mkdir rootdir/etc/apt/auth.conf.d
+cat > rootdir/etc/apt/auth.conf.d/myauth.conf << EOF
+machine localhost
+login username
+password usersPassword
+EOF
+
+
+testsuccessequal "Package files:
+ 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status
+ release a=now
+ 500 http://localhost:${APTHTTPPORT} unstable/main amd64 Packages
+ release a=unstable,n=sid,c=main,b=amd64
+ origin localhost
+Pinned packages:" aptcache policy
+
+
+cat > rootdir/etc/apt/preferences.d/myauth.pref << EOF
+Package: *
+Pin: origin localhost
+Pin-Priority: 990
+
+Package: cool
+Pin: origin localhost
+Pin-Priority: 990
+EOF
+
+testsuccessequal "Package files:
+ 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status
+ release a=now
+ 990 http://localhost:${APTHTTPPORT} unstable/main amd64 Packages
+ release a=unstable,n=sid,c=main,b=amd64
+ origin localhost
+Pinned packages:
+ cool -> 1.0 with priority 990" aptcache policy