Browse Source

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.
tags/debian/1.8.0_rc1
Julian Andres Klode 2 years ago
parent
commit
c2b9b04895
7 changed files with 124 additions and 4 deletions
  1. +4
    -0
      apt-pkg/acquire-item.cc
  2. +44
    -0
      apt-pkg/contrib/netrc.cc
  3. +4
    -0
      apt-pkg/contrib/netrc.h
  4. +1
    -0
      apt-pkg/deb/debmetaindex.cc
  5. +5
    -3
      apt-pkg/pkgcache.h
  6. +5
    -1
      apt-pkg/policy.cc
  7. +61
    -0
      test/integration/test-packages-require-authorization

+ 4
- 0
apt-pkg/acquire-item.cc View File

@@ -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;


+ 44
- 0
apt-pkg/contrib/netrc.cc View File

@@ -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;
}

+ 4
- 0
apt-pkg/contrib/netrc.h View File

@@ -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

+ 1
- 0
apt-pkg/deb/debmetaindex.cc View File

@@ -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;
}


+ 5
- 3
apt-pkg/pkgcache.h View File

@@ -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 */


+ 5
- 1
apt-pkg/policy.cc View File

@@ -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..


+ 61
- 0
test/integration/test-packages-require-authorization View File

@@ -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

Loading…
Cancel
Save