diff options
Diffstat (limited to 'cmdline')
-rw-r--r-- | cmdline/apt-get.cc | 122 | ||||
-rw-r--r--[-rwxr-xr-x] | cmdline/apt-key.in (renamed from cmdline/apt-key) | 46 | ||||
-rw-r--r-- | cmdline/makefile | 8 |
3 files changed, 137 insertions, 39 deletions
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 912b2d609..7e59f3d67 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -50,6 +50,8 @@ #include <apt-pkg/pkgrecords.h> #include <apt-pkg/indexfile.h> #include <apt-pkg/upgrade.h> +#include <apt-pkg/metaindex.h> +#include <apt-pkg/indexrecords.h> #include <apt-private/private-download.h> #include <apt-private/private-install.h> @@ -61,6 +63,8 @@ #include <apt-private/private-moo.h> #include <apt-private/private-utils.h> +#include <apt-pkg/debmetaindex.h> + #include <apt-private/acqprogress.h> #include <set> @@ -130,22 +134,80 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, return true; } /*}}}*/ + + +// helper that can go wit hthe next ABI break +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) +std::string MetaIndexFileNameOnDisk(metaIndex *metaindex) +{ + // FIXME: this cast is the horror, the horror + debReleaseIndex *r = (debReleaseIndex*)metaindex; + + // see if we have a InRelease file + std::string PathInRelease = r->MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return r->MetaIndexFile("Release"); + + return ""; +} +#endif + +// GetReleaseForSourceRecord - Return Suite for the given srcrecord /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, + pkgSrcRecords::Parser *Parse) +{ + // try to find release + const pkgIndexFile& CurrentIndexFile = Parse->Index(); + + for (pkgSourceList::const_iterator S = SrcList->begin(); + S != SrcList->end(); ++S) + { + vector<pkgIndexFile *> *Indexes = (*S)->GetIndexFiles(); + for (vector<pkgIndexFile *>::const_iterator IF = Indexes->begin(); + IF != Indexes->end(); ++IF) + { + if (&CurrentIndexFile == (*IF)) + { +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) + std::string path = MetaIndexFileNameOnDisk(*S); +#else + std::string path = (*S)->LocalFileName(); +#endif + if (path != "") + { + indexRecords records; + records.Load(path); + return records.GetSuite(); + } + } + } + } + return ""; +} + /*}}}*/ // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords &SrcRecs,string &Src, - pkgDepCache &Cache) + CacheFile &CacheFile) { string VerTag; - string DefRel = _config->Find("APT::Default-Release"); + string RelTag = _config->Find("APT::Default-Release"); string TmpSrc = Name; + pkgDepCache *Cache = CacheFile.GetDepCache(); // extract the version/release from the pkgname const size_t found = TmpSrc.find_last_of("/="); if (found != string::npos) { if (TmpSrc[found] == '/') - DefRel = TmpSrc.substr(found+1); + RelTag = TmpSrc.substr(found+1); else VerTag = TmpSrc.substr(found+1); TmpSrc = TmpSrc.substr(0,found); @@ -155,10 +217,10 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, install a version and determine the source package name, then look in the archive for a source package of the same name. */ bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source"); - const pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); + const pkgCache::PkgIterator Pkg = Cache->FindPkg(TmpSrc); if (MatchSrcOnly == false && Pkg.end() == false) { - if(VerTag.empty() == false || DefRel.empty() == false) + if(VerTag.empty() == false || RelTag.empty() == false) { bool fuzzy = false; // we have a default release, try to locate the pkg. we do it like @@ -180,7 +242,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } // We match against a concrete version (or a part of this version) if (VerTag.empty() == false && - (fuzzy == true || Cache.VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match + (fuzzy == true || Cache->VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match (fuzzy == false || strncmp(VerTag.c_str(), Ver.VerStr(), VerTag.size()) != 0)) // fuzzy match continue; @@ -198,8 +260,8 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, // or we match against a release if(VerTag.empty() == false || - (VF.File().Archive() != 0 && VF.File().Archive() == DefRel) || - (VF.File().Codename() != 0 && VF.File().Codename() == DefRel)) + (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || + (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { pkgRecords::Parser &Parse = Recs.Lookup(VF); Src = Parse.SourcePkg(); @@ -217,22 +279,14 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, if (Src.empty() == false) break; } - if (Src.empty() == true) - { - // Sources files have no codename information - if (VerTag.empty() == true && DefRel.empty() == false) - { - _error->Error(_("Ignore unavailable target release '%s' of package '%s'"), DefRel.c_str(), TmpSrc.c_str()); - return 0; - } - } } if (Src.empty() == true) { // if we don't have found a fitting package yet so we will // choose a good candidate and proceed with that. // Maybe we will find a source later on with the right VerTag - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); + // or RelTag + pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); @@ -244,7 +298,9 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, } if (Src.empty() == true) + { Src = TmpSrc; + } else { /* if we have a source pkg name, make sure to only search @@ -262,6 +318,7 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgSrcRecords::Parser *Last = 0; unsigned long Offset = 0; string Version; + pkgSourceList *SrcList = CacheFile.GetSourceList(); /* Iterate over all of the hits, which includes the resulting binary packages in the search */ @@ -273,25 +330,40 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, { const string Ver = Parse->Version(); + // See if we need to look for a specific release tag + if (RelTag != "") + { + const string Rel = GetReleaseForSourceRecord(SrcList, Parse); + + if (Rel == RelTag) + { + ioprintf(c1out, "Selectied version '%s' (%s) for %s\n", + Ver.c_str(), RelTag.c_str(), Src.c_str()); + Last = Parse; + Offset = Parse->Offset(); + break; + } + } + // Ignore all versions which doesn't fit if (VerTag.empty() == false && - Cache.VS().CmpVersion(VerTag, Ver) != 0) // exact match + Cache->VS().CmpVersion(VerTag, Ver) != 0) // exact match continue; // Newer version or an exact match? Save the hit - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0) { + if (Last == 0 || Cache->VS().CmpVersion(Version,Ver) < 0) { Last = Parse; Offset = Parse->Offset(); Version = Ver; } - // was the version check above an exact match? If so, we don't need to look further - if (VerTag.empty() == false && VerTag.size() == Ver.size()) + // was the version check above an exact match? + // If so, we don't need to look further + if (VerTag.empty() == false && (VerTag == Ver)) break; } if (Last != 0 || VerTag.empty() == true) break; - //if (VerTag.empty() == false && Last == 0) _error->Error(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str()); return 0; } @@ -628,7 +700,7 @@ bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); if (Last == 0) { delete[] Dsc; @@ -925,7 +997,7 @@ bool DoBuildDep(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); if (Last == 0) return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); diff --git a/cmdline/apt-key b/cmdline/apt-key.in index 713a41c07..779872b4c 100755..100644 --- a/cmdline/apt-key +++ b/cmdline/apt-key.in @@ -25,17 +25,15 @@ GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" GPG="$GPG_CMD" -MASTER_KEYRING="" -#MASTER_KEYRING=/usr/share/keyrings/debian-master-keyring.gpg +MASTER_KEYRING='&keyring-master-filename;' eval $(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring) -ARCHIVE_KEYRING_URI="" -#ARCHIVE_KEYRING_URI=http://ftp.debian.org/debian/debian-archive-keyring.gpg -eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) - -ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg +ARCHIVE_KEYRING='&keyring-filename;' eval $(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring) -REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg +REMOVED_KEYS='&keyring-removed-filename;' eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys) +ARCHIVE_KEYRING_URI='&keyring-uri;' +eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) +TMP_KEYRING=/var/lib/apt/keyrings/maybe-import-keyring.gpg requires_root() { if [ "$(id -u)" -ne 0 ]; then @@ -57,7 +55,7 @@ init_keyring() { add_keys_with_verify_against_master_keyring() { ADD_KEYRING=$1 MASTER=$2 - + if [ ! -f "$ADD_KEYRING" ]; then echo "ERROR: '$ADD_KEYRING' not found" return @@ -72,12 +70,28 @@ add_keys_with_verify_against_master_keyring() { # all keys that are exported must have a valid signature # from a key in the $distro-master-keyring add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^pub | cut -d: -f5` + all_add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5` master_keys=`$GPG_CMD --keyring $MASTER --with-colons --list-keys | grep ^pub | cut -d: -f5` + + # ensure there are no colisions LP: #857472 + for all_add_key in $all_add_keys; do + for master_key in $master_keys; do + if [ "$all_add_key" = "$master_key" ]; then + echo >&2 "Keyid collision for '$all_add_key' detected, operation aborted" + return 1 + fi + done + done + for add_key in $add_keys; do - ADDED=0 + # export the add keyring one-by-one + rm -f $TMP_KEYRING + $GPG_CMD --keyring $ADD_KEYRING --output $TMP_KEYRING --export $add_key + # check if signed with the master key and only add in this case + ADDED=0 for master_key in $master_keys; do - if $GPG_CMD --keyring $ADD_KEYRING --list-sigs --with-colons $add_key | grep ^sig | cut -d: -f5 | grep -q $master_key; then - $GPG_CMD --quiet --batch --keyring $ADD_KEYRING --export $add_key | $GPG --import + if $GPG_CMD --keyring $MASTER --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then + $GPG --import $TMP_KEYRING ADDED=1 fi done @@ -85,12 +99,16 @@ add_keys_with_verify_against_master_keyring() { echo >&2 "Key '$add_key' not added. It is not signed with a master key" fi done + rm -f $TMP_KEYRING } # update the current archive signing keyring from a network URI # the archive-keyring keys needs to be signed with the master key # (otherwise it does not make sense from a security POV) net_update() { + # Disabled for now as code is insecure (LP: #1013639 (and 857472, 1013128)) + exit 1 + if [ -z "$ARCHIVE_KEYRING_URI" ]; then echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set" exit 1 @@ -110,7 +128,7 @@ net_update() { if [ -e $keyring ]; then old_mtime=$(stat -c %Y $keyring) fi - (cd /var/lib/apt/keyrings; wget -q -N $ARCHIVE_KEYRING_URI) + (cd /var/lib/apt/keyrings; wget --timeout=90 -q -N $ARCHIVE_KEYRING_URI) if [ ! -e $keyring ]; then return fi @@ -124,7 +142,7 @@ net_update() { update() { if [ ! -f $ARCHIVE_KEYRING ]; then echo >&2 "ERROR: Can't find the archive-keyring" - echo >&2 "Is the debian-archive-keyring package installed?" + echo >&2 "Is the &keyring-package; package installed?" exit 1 fi requires_root diff --git a/cmdline/makefile b/cmdline/makefile index e77ad5669..06f170b6a 100644 --- a/cmdline/makefile +++ b/cmdline/makefile @@ -41,6 +41,14 @@ SOURCE = apt-cdrom.cc include $(PROGRAM_H) # The apt-key program +apt-key: apt-key.in + sed -e "s#&keyring-filename;#$(shell ../vendor/getinfo keyring-filename)#" \ + -e "s#&keyring-removed-filename;#$(shell ../vendor/getinfo keyring-removed-filename)#" \ + -e "s#&keyring-master-filename;#$(shell ../vendor/getinfo keyring-master-filename)#" \ + -e "s#&keyring-uri;#$(shell ../vendor/getinfo keyring-uri)#" \ + -e "s#&keyring-package;#$(shell ../vendor/getinfo keyring-package)#" $< > $@ + chmod 755 $@ + SOURCE=apt-key TO=$(BIN) TARGET=program |