diff -Nru python-apt-1.9.0ubuntu1/apt/cache.py python-apt-1.9.0ubuntu1.1/apt/cache.py --- python-apt-1.9.0ubuntu1/apt/cache.py 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/apt/cache.py 2020-01-15 16:35:02.000000000 +0100 @@ -62,6 +62,10 @@ """Exception that is thrown when fetching fails.""" +class UntrustedException(FetchFailedException): + """Exception that is thrown when fetching fails for trust reasons""" + + class LockFailedException(IOError): """Exception that is thrown when locking fails.""" @@ -416,8 +420,17 @@ reqreinst.add(pkg.get_fullname(pretty=True)) return reqreinst - def _run_fetcher(self, fetcher): - # type: (apt_pkg.Acquire) -> int + def _run_fetcher(self, fetcher, allow_unauthenticated): + # type: (apt_pkg.Acquire, Optional[bool]) -> int + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b("APT::Get::" + "AllowUnauthenticated", False) + + untrusted = [item for item in fetcher.items if not item.is_trusted] + if untrusted and not allow_unauthenticated: + raise UntrustedException("Untrusted packages:\n%s" % + "\n".join(i.desc_uri for i in untrusted)) + # do the actual fetching res = fetcher.run() @@ -440,8 +453,12 @@ raise FetchFailedException(err_msg) return res - def _fetch_archives(self, fetcher, pm): - # type: (apt_pkg.Acquire, apt_pkg.PackageManager) -> int + def _fetch_archives(self, + fetcher, # type: apt_pkg.Acquire + pm, # type: apt_pkg.PackageManager + allow_unauthenticated, # type: Optional[bool] + ): + # type: (...) -> int """ fetch the needed archives """ if self._records is None: raise CacheClosedException( @@ -450,12 +467,17 @@ # this may as well throw a SystemError exception if not pm.get_archives(fetcher, self._list, self._records): return False + # now run the fetcher, throw exception if something fails to be # fetched - return self._run_fetcher(fetcher) + return self._run_fetcher(fetcher, allow_unauthenticated) - def fetch_archives(self, progress=None, fetcher=None): - # type: (AcquireProgress, apt_pkg.Acquire) -> int + def fetch_archives(self, + progress=None, # type: Optional[AcquireProgress] + fetcher=None, # type: Optional[apt_pkg.Acquire] + allow_unauthenticated=None, # type: Optional[bool] + ): + # type: (...) -> int """Fetch the archives for all packages marked for install/upgrade. You can specify either an :class:`apt.progress.base.AcquireProgress()` @@ -466,6 +488,10 @@ an exception of type :class:`FetchFailedException` or :class:`FetchCancelledException` is raised. + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + .. versionadded:: 0.8.0 """ if progress is not None and fetcher is not None: @@ -477,7 +503,8 @@ with self._archive_lock: return self._fetch_archives(fetcher, - apt_pkg.PackageManager(self._depcache)) + apt_pkg.PackageManager(self._depcache), + allow_unauthenticated) def is_virtual_package(self, pkgname): # type: (str) -> bool @@ -607,8 +634,12 @@ install_progress.finish_update() return res - def commit(self, fetch_progress=None, install_progress=None): - # type: (AcquireProgress, InstallProgress) -> bool + def commit(self, + fetch_progress=None, # type: Optional[AcquireProgress] + install_progress=None, # type: Optional[InstallProgress] + allow_unauthenticated=None, # type: Optional[bool] + ): + # type: (...) -> bool """Apply the marked changes to the cache. The first parameter, *fetch_progress*, refers to a FetchProgress() @@ -617,6 +648,10 @@ The second parameter, *install_progress*, is a apt.progress.InstallProgress() object. + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. """ # FIXME: # use the new acquire/pkgmanager interface here, @@ -638,7 +673,8 @@ with self._archive_lock: while True: # fetch archives first - res = self._fetch_archives(fetcher, pm) + res = self._fetch_archives(fetcher, pm, + allow_unauthenticated) # then install res = self.install_archives(pm, install_progress) @@ -986,7 +1022,7 @@ apt_pkg.config.set("Dir::Cache::Archives", "/tmp/pytest") pm = apt_pkg.PackageManager(cache._depcache) fetcher = apt_pkg.Acquire(apt.progress.text.AcquireProgress()) - cache._fetch_archives(fetcher, pm) + cache._fetch_archives(fetcher, pm, None) #sys.exit(1) print("Testing filtered cache (argument is old cache)") diff -Nru python-apt-1.9.0ubuntu1/apt/package.py python-apt-1.9.0ubuntu1.1/apt/package.py --- python-apt-1.9.0ubuntu1/apt/package.py 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/apt/package.py 2020-01-15 16:35:02.000000000 +0100 @@ -107,6 +107,10 @@ """Raised when a file could not be fetched.""" +class UntrustedError(FetchError): + """Raised when a file did not have a trusted hash.""" + + class BaseDependency(object): """A single dependency.""" @@ -533,6 +537,7 @@ def _records(self): # type: () -> apt_pkg.PackageRecords """Internal helper that moves the Records to the right position.""" + # If changing lookup, change fetch_binary() as well if not self.package._pcache._records.lookup(self._cand.file_list[0]): raise LookupError("Could not lookup record") @@ -849,8 +854,9 @@ except StopIteration: return None - def fetch_binary(self, destdir='', progress=None): - # type: (str, AcquireProgress) -> str + def fetch_binary(self, destdir='', progress=None, + allow_unauthenticated=None): + # type: (str, Optional[AcquireProgress], Optional[bool]) -> str """Fetch the binary version of the package. The parameter *destdir* specifies the directory where the package will @@ -860,15 +866,39 @@ object. If not specified or None, apt.progress.text.AcquireProgress() is used. + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + .. versionadded:: 0.7.10 """ + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b("APT::Get::" + "AllowUnauthenticated", False) base = os.path.basename(self._records.filename) destfile = os.path.join(destdir, base) - if _file_is_same(destfile, self.size, self._records.md5_hash): + if _file_is_same(destfile, self.size, self._records.hashes): logging.debug('Ignoring already existing file: %s' % destfile) return os.path.abspath(destfile) + + # Verify that the index is actually trusted + pfile, offset = self._cand.file_list[0] + index = self.package._pcache._list.find_index(pfile) + + if not (allow_unauthenticated or (index and index.is_trusted)): + raise UntrustedError("Could not fetch %s %s source package: " + "Source %r is not trusted" % + (self.package.name, self.version, + getattr(index, "describe", ""))) + if not self.uri: + raise ValueError("No URI for this binary.") + hashes = self._records.hashes + if not (allow_unauthenticated or hashes.usable): + raise UntrustedError("The item %r could not be fetched: " + "No trusted hash found." % + destfile) acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) - acqfile = apt_pkg.AcquireFile(acq, self.uri, self._records.md5_hash, # type: ignore # TODO: Do not use MD5 # nopep8 + acqfile = apt_pkg.AcquireFile(acq, self.uri, hashes, self.size, base, destfile=destfile) acq.run() @@ -878,8 +908,9 @@ return os.path.abspath(destfile) - def fetch_source(self, destdir="", progress=None, unpack=True): - # type: (str, AcquireProgress, bool) -> str + def fetch_source(self, destdir="", progress=None, unpack=True, + allow_unauthenticated=None): + # type: (str, Optional[AcquireProgress], bool, Optional[bool]) -> str """Get the source code of a package. The parameter *destdir* specifies the directory where the source will @@ -894,7 +925,15 @@ If *unpack* is ``True``, the path to the extracted directory is returned. Otherwise, the path to the .dsc file is returned. - """ + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + """ + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b("APT::Get::" + "AllowUnauthenticated", False) + src = apt_pkg.SourceRecords() acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) @@ -909,6 +948,12 @@ if not source_lookup: raise ValueError("No source for %r" % self) files = list() + + if not (allow_unauthenticated or src.index.is_trusted): + raise UntrustedError("Could not fetch %s %s source package: " + "Source %r is not trusted" % + (self.package.name, self.version, + src.index.describe)) for fil in src.files: base = os.path.basename(fil.path) destfile = os.path.join(destdir, base) @@ -917,8 +962,14 @@ if _file_is_same(destfile, fil.size, fil.hashes): logging.debug('Ignoring already existing file: %s' % destfile) continue - files.append(apt_pkg.AcquireFile(acq, src.index.archive_uri(fil.path), - str(fil.hashes.find("SHA256")), fil.size, base, destfile=destfile)) + + if not (allow_unauthenticated or fil.hashes.usable): + raise UntrustedError("The item %r could not be fetched: " + "No trusted hash found." % + destfile) + files.append(apt_pkg.AcquireFile(acq, + src.index.archive_uri(fil.path), + fil.hashes, fil.size, base, destfile=destfile)) acq.run() if dsc is None: diff -Nru python-apt-1.9.0ubuntu1/data/templates/Debian.mirrors python-apt-1.9.0ubuntu1.1/data/templates/Debian.mirrors --- python-apt-1.9.0ubuntu1/data/templates/Debian.mirrors 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/data/templates/Debian.mirrors 2020-01-15 16:35:02.000000000 +0100 @@ -3,6 +3,7 @@ http://mirrors.asnet.am/debian/ #LOC:AR http://debian.unnoba.edu.ar/debian/ +http://mirror.sitsa.com.ar/debian/ #LOC:AT http://debian.anexia.at/debian/ http://debian.inode.at/debian/ @@ -22,6 +23,7 @@ http://mirror.launtel.net.au/debian/ http://mirror.linux.org.au/debian/ http://mirror.overthewire.com.au/debian/ +http://mirror.realcompute.io/debian/ http://mirror.waia.asn.au/debian/ #LOC:BE http://ftp.be.debian.org/debian/ @@ -35,13 +37,15 @@ http://debian.telecoms.bg/debian/ http://ftp.bg.debian.org/debian/ http://ftp.uni-sofia.bg/debian/ +http://mirrors.netix.net/debian/ #LOC:BR http://alcateia.ufscar.br/debian/ http://debian.c3sl.ufpr.br/debian/ http://debian.pop-sc.rnp.br/debian/ http://ftp.br.debian.org/debian/ +http://mirror.nbtelecom.com.br/debian/ +http://mirror.unesp.br/debian/ http://repositorio.nti.ufal.br/debian/ -http://sft.if.usp.br/debian/ #LOC:BY http://ftp.by.debian.org/debian/ http://ftp.byfly.by/debian/ @@ -68,6 +72,7 @@ http://debian.utalca.cl/debian/ http://ftp.cl.debian.org/debian/ http://mirror.insacom.cl/debian/ +http://mirror.ufro.cl/debian/ #LOC:CN http://ftp.cn.debian.org/debian/ http://ftp2.cn.debian.org/debian/ @@ -77,6 +82,7 @@ http://mirrors.tuna.tsinghua.edu.cn/debian/ http://mirrors.ustc.edu.cn/debian/ #LOC:CR +http://debianmirror.una.ac.cr/debian/ http://mirrors.ucr.ac.cr/debian/ #LOC:CZ http://debian.ignum.cz/debian/ @@ -119,6 +125,7 @@ http://mirror.23media.de/debian/ http://mirror.de.leaseweb.net/debian/ http://mirror.eu.oneandone.net/debian/ +http://mirror.ipb.de/debian/ http://mirror.netcologne.de/debian/ http://mirror.united-gameserver.de/debian/ http://mirror.wtnet.de/debian/ @@ -127,7 +134,7 @@ #LOC:DK http://ftp.dk.debian.org/debian/ http://mirror.asergo.com/debian/ -http://mirror.iodc.dk/debian/ +http://mirror.netcrunch.dk/debian/ http://mirror.one.com/debian/ http://mirrors.dotsrc.org/debian/ http://mirrors.rackhosting.com/debian/ @@ -208,9 +215,9 @@ #LOC:HU http://ftp.bme.hu/debian/ http://ftp.fsn.hu/debian/ -http://ftp.gtx.hu/debian/ http://ftp.hu.debian.org/debian/ http://ftp.kfki.hu/linux/debian/ +http://repo.jztkft.hu/debian/ #LOC:ID http://kartolo.sby.datautama.net.id/debian/ http://kebo.pens.ac.id/debian/ @@ -220,10 +227,10 @@ http://mirror.isoc.org.il/pub/debian/ #LOC:IN http://debianmirror.nkn.in/debian/ +http://debmirror.hbcse.tifr.res.in/debian/ http://mirror.cse.iitk.ac.in/debian/ #LOC:IR http://debian.asis.ai/debian/ -http://debian.parspack.com/debian/ http://mirror.aminidc.com/debian/ #LOC:IT http://debian.connesi.it/debian/ @@ -247,6 +254,8 @@ #LOC:KE http://debian.mirror.ac.ke/debian/ http://debian.mirror.liquidtelecom.com/debian/ +#LOC:KG +http://mir.linux.kg/debian/ #LOC:KR http://ftp.harukasan.org/debian/ http://ftp.kaist.ac.kr/debian/ @@ -269,6 +278,7 @@ #LOC:MD http://ftp.md.debian.org/debian/ http://mirror.as43289.net/debian/ +http://mirrors.mivocloud.com/debian/ #LOC:MK http://mirror.onevip.mk/debian/ #LOC:MX @@ -280,14 +290,15 @@ #LOC:NL http://debian.mirror.cambrium.nl/debian/ http://debian.snt.utwente.nl/debian/ +http://debian.voipgrow.com/debian/ http://debmirror.tuxis.nl/debian/ -http://ftp.debian.nl/debian/ http://ftp.debian.org/debian/ +http://ftp.debian.xs4all.net/debian/ http://ftp.nl.debian.org/debian/ http://ftp.nluug.nl/debian/ http://mirror.dataone.nl/debian/ http://mirror.duocast.net/debian/ -http://mirror.i3d.net/pub/debian/ +http://mirror.i3d.net/debian/ http://mirror.neostrada.nl/debian/ http://mirror.nforce.com/debian/ http://mirror.nl.datapacket.com/debian/ @@ -298,6 +309,7 @@ http://mirror.seedvps.com/debian/ http://mirror.serverius.net/debian/ http://mirror.vpgrp.io/debian/ +http://mirrors.xtom.nl/debian/ #LOC:NO http://ftp.no.debian.org/debian/ http://ftp.uio.no/debian/ @@ -339,6 +351,7 @@ http://ftp.psn.ru/debian/ http://ftp.ru.debian.org/debian/ http://mirror.corbina.net/debian/ +http://mirror.docker.ru/debian/ http://mirror.mephi.ru/debian/ http://mirror.truenetwork.ru/debian/ http://mirrors.powernet.com.ru/debian/ @@ -352,7 +365,6 @@ http://mirror.zetup.net/debian/ http://mirrors.glesys.net/debian/ #LOC:SG -http://ftp.sg.debian.org/debian/ http://mirror.0x.sg/debian/ #LOC:SI http://ftp.arnes.si/debian/ @@ -390,20 +402,19 @@ http://debian.cc.lehigh.edu/debian/ http://debian.cs.binghamton.edu/debian/ http://debian.csail.mit.edu/debian/ -http://debian.cse.msu.edu/debian/ http://debian.ec.as6453.net/debian/ http://debian.gtisc.gatech.edu/debian/ http://debian.mirror.constant.com/debian/ http://debian.mirrors.pair.com/debian/ http://debian.osuosl.org/debian/ http://debian.uchicago.edu/debian/ -http://ftp.naz.com/debian/ http://ftp.us.debian.org/debian/ http://ftp.utexas.edu/debian/ http://mirror.cc.columbia.edu/debian/ http://mirror.cogentco.com/debian/ http://mirror.keystealth.org/debian/ http://mirror.math.princeton.edu/pub/debian/ +http://mirror.pit.teraswitch.com/debian/ http://mirror.siena.edu/debian/ http://mirror.sjc02.svwh.net/debian/ http://mirror.steadfast.net/debian/ @@ -412,7 +423,6 @@ http://mirrors.accretive-networks.net/debian/ http://mirrors.advancedhosters.com/debian/ http://mirrors.bloomu.edu/debian/ -http://mirrors.cat.pdx.edu/debian/ http://mirrors.edge.kernel.org/debian/ http://mirrors.gigenet.com/debian/ http://mirrors.lug.mtu.edu/debian/ @@ -421,10 +431,12 @@ http://mirrors.syringanetworks.net/debian/ http://mirrors.wikimedia.org/debian/ http://mirrors.xmission.com/debian/ +http://mirrors.xtom.com/debian/ http://repo.ialab.dsu.edu/debian/ +http://us.mirror.nsec.pt/debian/ http://www.gtlib.gatech.edu/debian/ #LOC:UY -http://repo.cure.edu.uy/debian/ +http://debian.repo.cure.edu.uy/debian/ #LOC:VN http://debian.xtdv.net/debian/ #LOC:ZA diff -Nru python-apt-1.9.0ubuntu1/data/templates/Ubuntu.mirrors python-apt-1.9.0ubuntu1.1/data/templates/Ubuntu.mirrors --- python-apt-1.9.0ubuntu1/data/templates/Ubuntu.mirrors 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/data/templates/Ubuntu.mirrors 2020-01-15 16:35:02.000000000 +0100 @@ -4,6 +4,7 @@ #LOC:AR http://ubuntu.unc.edu.ar/ubuntu/ #LOC:AT +http://mirror.easyname.at/ubuntu-archive/ http://mirror.kumi.systems/ubuntu/ http://ubuntu.anexia.at/ubuntu/ http://ubuntu.inode.at/ubuntu/ @@ -19,6 +20,7 @@ http://mirror.launtel.net.au/ubuntu/ http://mirror.netspace.net.au/pub/ubuntu/ http://mirror.overthewire.com.au/ubuntu/ +http://mirror.realcompute.io/ubuntu/ http://mirror.solnode.io/ubuntu/releases/ http://mirror.tcc.wa.edu.au/ubuntu/ http://mirror.waia.asn.au/ubuntu/ @@ -29,6 +31,7 @@ #LOC:AZ http://aze.archive.ubuntu.com/ubuntu/ http://mirror.datacenter.az/ubuntu/ +http://mirror.yer.az/ubuntu/ #LOC:BA http://archive.ubuntu.mirror.ba/ubuntu/ #LOC:BD @@ -37,10 +40,10 @@ http://mirror.xeonbd.com/ubuntu-archive/ #LOC:BE http://ftp.belnet.be/ubuntu/ -http://gaosu.rave.org/ubuntu/ http://mirror.unix-solutions.be/ubuntu/ #LOC:BG http://mirror.telepoint.bg/ubuntu/ +http://mirrors.daticum.com/ubuntu/archive/ http://mirrors.neterra.net/ubuntu/ http://ubuntu.ipacct.com/ubuntu/ http://ubuntu.uni-sofia.bg/ubuntu/ @@ -50,7 +53,6 @@ http://mirror.ufam.edu.br/ubuntu/ http://mirror.ufca.edu.br/mirror/ubuntu-archive/ http://mirror.ufscar.br/ubuntu/ -http://mirror.usetelecom.com.br/ubuntu/ http://repositorio.nti.ufal.br/ubuntu/ http://sft.if.usp.br/ubuntu/ http://ubuntu-archive.locaweb.com.br/ubuntu/ @@ -64,6 +66,7 @@ ftp://ftp.cs.mun.ca/pub/mirror/ubuntu/ http://archive.ubuntu.mirror.rafal.ca/ubuntu/ http://gpl.savoirfairelinux.net/pub/mirrors/ubuntu/ +http://mirror.ca-tr.kamatera.com/ubuntu/ http://mirror.cedille.club/ubuntu/ http://mirror.clibre.uqam.ca/ubuntu/ http://mirror.csclub.uwaterloo.ca/ubuntu/ @@ -74,6 +77,7 @@ http://muug.ca/mirror/ubuntu/ http://ubuntu.bhs.mirrors.ovh.net/ubuntu/ http://ubuntu.ca-west.mirror.fullhost.io/ubuntu/ +http://ubuntu.maxime.vip/ubuntu/ http://ubuntu.mirror.globo.tech/ http://ubuntu.mirror.iweb.ca/ http://ubuntu.mirror.rafal.ca/ubuntu/ @@ -93,15 +97,14 @@ http://mirrors.cn99.com/ubuntu/ http://mirrors.cqu.edu.cn/ubuntu/ http://mirrors.dgut.edu.cn/ubuntu/ +http://mirrors.huaweicloud.com/repository/ubuntu/ http://mirrors.nju.edu.cn/ubuntu/ http://mirrors.njupt.edu.cn/ubuntu/ -http://mirrors.nwafu.edu.cn/ubuntu/ http://mirrors.sohu.com/ubuntu/ http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ http://mirrors.ustc.edu.cn/ubuntu/ http://mirrors.yun-idc.com/ubuntu/ #LOC:CO -http://mirror.edatel.net.co/ubuntu/ http://mirror.unimagdalena.edu.co/ubuntu/ http://mirror.upb.edu.co/ubuntu/ #LOC:CR @@ -113,14 +116,11 @@ http://ftp.cvut.cz/ubuntu/ http://ftp.sh.cvut.cz/ubuntu/ http://mirror.dkm.cz/ubuntu/ -http://mirror.vutbr.cz/ubuntu/archive/ http://ucho.ignum.cz/ubuntu/ #LOC:DE ftp://ftp.fu-berlin.de/linux/ubuntu/ ftp://ftp.rrzn.uni-hannover.de/pub/mirror/linux/ubuntu http://artfiles.org/ubuntu.com/ -http://de.archive.ubuntu.com/ubuntu/ -http://de2.archive.ubuntu.com/ubuntu/ http://debian.charite.de/ubuntu/ http://ftp-stud.hs-esslingen.de/ubuntu/ http://ftp.fau.de/ubuntu/ @@ -137,27 +137,32 @@ http://ftp.uni-mainz.de/ubuntu/ http://ftp.uni-stuttgart.de/ubuntu/ http://ftp5.gwdg.de/pub/linux/debian/ubuntu/ +http://linux.darkpenguin.net/distros/ubuntu-archive/ http://mirror.23media.com/ubuntu/ http://mirror.de.leaseweb.net/ubuntu/ +http://mirror.eu-fr.kamatera.com/ubuntu/ http://mirror.funkfreundelandshut.de/ubuntu/ http://mirror.ipb.de/ubuntu/ http://mirror.kamp.de/ubuntu/ http://mirror.netcologne.de/ubuntu/ +http://mirror.plustech.de/ubuntu/ http://mirror.ratiokontakt.de/mirror/ubuntu/ http://mirror.serverloft.eu/ubuntu/ubuntu/ http://mirror.stw-aachen.de/ubuntu/ http://mirror.wtnet.de/ubuntu/ http://mirror2.tuxinator.org/ubuntu/ http://packages.oth-regensburg.de/ubuntu/ -http://pubmirror01.lwlcom.net/ubuntu/ http://suse.uni-leipzig.de/pub/releases.ubuntu.com/ubuntu/ http://ubuntu.cybertips.info/ubuntu/ http://ubuntu.mirror.lrz.de/ubuntu/ http://ubuntu.mirror.tudos.de/ubuntu/ http://ubuntu.unitedcolo.de/ubuntu/ #LOC:DK +http://ftp.klid.dk/ftp/ubuntu/ +http://klid.dk/ftp/ubuntu/ http://mirror.easyspeedy.com/ubuntu/ http://mirror.iodc.dk/ubuntu/ +http://mirror.netcrunch.dk/ubuntu/ http://mirror.netsite.dk/ubuntu/archive/ http://mirror.one.com/ubuntu/ http://mirrors.dotsrc.org/ubuntu/ @@ -170,10 +175,9 @@ http://ftp.estpak.ee/ubuntu/ #LOC:ES ftp://ftp.csuc.cat/ubuntu/archieve/ -http://dafi.inf.um.es/ubuntu/ http://es-mirrors.evowise.com/ubuntu/ +http://ftp.caliu.cat/pub/distribucions/ubuntu/archive/ http://ftp.udc.es/ubuntu/ -http://linuxmirror.es/ubuntu/ http://mirror.tedra.es/ubuntu/ http://softlibre.unizar.es/ubuntu/archive/ http://ubuntu.cica.es/ubuntu/ @@ -190,6 +194,7 @@ http://miroir.univ-lorraine.fr/ubuntu/ http://mirror.plusserver.com/ubuntu/ubuntu/ http://mirror.ubuntu.ikoula.com/ +http://mirror.ubuntu.ikoula.com/ubuntu/ http://mirrors.ircam.fr/pub/ubuntu/archive/ http://ubuntu.mirror.serverloft.de/ubuntu/ http://ubuntu.mirrors.ovh.net/ubuntu/ @@ -198,25 +203,24 @@ http://www-ftp.lip6.fr/pub/linux/distributions/Ubuntu/archive/ #LOC:GB http://archive.ubuntu.com/ubuntu/ -http://ftp.ticklers.org/archive.ubuntu.org/ubuntu/ http://mirror.as29550.net/archive.ubuntu.com/ http://mirror.bytemark.co.uk/ubuntu/ +http://mirror.eu-lo.kamatera.com/ubuntu/ http://mirror.freethought-internet.co.uk/ubuntu/ http://mirror.mythic-beasts.com/ubuntu/ http://mirror.ox.ac.uk/sites/archive.ubuntu.com/ubuntu/ http://mirror.sax.uk.as61049.net/ubuntu/ http://mirror.sov.uk.goscomb.net/ubuntu/ http://mirror.vorboss.net/ubuntu-archive/ +http://mirrors.coreix.net/ubuntu/ http://mirrors.melbourne.co.uk/ubuntu/ http://mirrors.ukfast.co.uk/sites/archive.ubuntu.com/ http://mozart.ee.ic.ac.uk/ubuntu-archive/ -http://repo.bigstepcloud.com/ubuntu/ http://ubuntu.mirrors.uk2.net/ubuntu/ http://ubuntu.positive-internet.com/ubuntu/ http://uk-mirrors.evowise.com/ubuntu/ http://www.mirrorservice.org/sites/archive.ubuntu.com/ubuntu/ #LOC:GE -http://ge.archive.ubuntu.com/ubuntu/ http://ubuntu.grena.ge/ubuntu/ #LOC:GL http://mirror.greennet.gl/ubuntu/ @@ -226,6 +230,7 @@ http://ubuntu.otenet.gr/ #LOC:HK http://ftp.cuhk.edu.hk/pub/Linux/ubuntu/ +http://hk.mirrors.thegigabit.com/ubuntu/ http://mirror-hk.koddos.net/ubuntu/ http://mirror.xtom.com.hk/ubuntu/ #LOC:HR @@ -235,17 +240,28 @@ http://mirror.niif.hu/ubuntu/ http://mirrors.sth.sze.hu/ubuntu/ http://quantum-mirror.hu/mirrors/pub/ubuntu/ +http://repo.jztkft.hu/ubuntu/ #LOC:ID http://kambing.ui.ac.id/ubuntu/ http://kartolo.sby.datautama.net.id/ubuntu/ http://kebo.pens.ac.id/ubuntu/ +http://kebo.vlsm.org/ubuntu/ http://mirror.biznetgio.com/ubuntu/ http://mirror.deace.id/ubuntu/ +http://mirror.labkom.id/ubuntu/ http://mirror.poliwangi.ac.id/ubuntu/ +http://mirror.telkomuniversity.ac.id/ubuntu/ http://mirror.unej.ac.id/ubuntu/ http://repo.unpatti.ac.id/ubuntu/ http://suro.ubaya.ac.id/ubuntu/ +#LOC:IE +http://ftp.heanet.ie/pub/ubuntu/ #LOC:IL +http://mirror.il-jr.kamatera.com/ubuntu/ +http://mirror.il-pt.kamatera.com/ubuntu/ +http://mirror.il-rh.kamatera.com/ubuntu/ +http://mirror.il-ta.kamatera.com/ubuntu/ +http://mirror.il.kamatera.com/ubuntu/ http://mirror.isoc.org.il/pub/ubuntu/ http://rep-ubuntu-il.upress.io/ubuntu/ #LOC:IN @@ -253,19 +269,17 @@ http://mirrors.piconets.webwerks.in/ubuntu-mirror/ubuntu/ http://repos.del.extreme-ix.org/ubuntu/ http://ubuntu-archive.mirrors.estointernet.in/ -http://ubuntu.mirror.snu.edu.in/ubuntu/ +http://ubuntu.hbcse.tifr.res.in/ubuntu/ #LOC:IR http://archive.ubuntu.petiak.ir/ubuntu/ http://ir.ubuntu.sindad.cloud/ubuntu/ http://mirror.0-1.cloud/ubuntu/ http://mirror.aminidc.com/ubuntu/ http://mirror.armaghan.net/ubuntu/ -http://mirror.iranserver.com/ubuntu/ http://mirror.rasanegar.com/ubuntu/archive/ http://mirror.xaas.ir/ubuntu/ http://repo.iut.ac.ir/repo/Ubuntu/ http://ubuntu-mirror.parsdev.net/ubuntu-archive/ -http://ubuntu.asis.ac/ http://ubuntu.hostiran.ir/ubuntuarchive/ http://ubuntu.parspack.net/ubuntu/ #LOC:IS @@ -289,11 +303,12 @@ #LOC:KE http://ubuntu.mirror.ac.ke/ubuntu/ #LOC:KR +http://ftp.daum.net/ubuntu/ http://ftp.harukasan.org/ubuntu/ http://ftp.lanet.kr/ubuntu/ http://ftp.neowiz.com/ubuntu/ -http://kr.archive.ubuntu.com/ubuntu/ http://mirror.kakao.com/ubuntu/ +http://mirror.yongbok.net/ubuntu/ #LOC:KW http://ubuntu.archive.kw.zain.com/ #LOC:KZ @@ -323,14 +338,12 @@ #LOC:MN http://mirror.datacenter.mn/ubuntu/ #LOC:MY +http://my.mirrors.thegigabit.com/ubuntu/ http://ubuntu.ipserverone.com/ubuntu/ http://ubuntu.mirror.myduniahost.com/ubuntu/ http://ubuntu.tuxuri.com/ubuntu/ -#LOC:NA -http://download.nust.na/pub/ubuntu/ubuntu/ #LOC:NC http://archive.ubuntu.nautile.nc/ubuntu/ -http://ubuntu.lagoon.nc/ubuntu/ #LOC:NL ftp://ftpserv.tudelft.nl/pub/Linux/archive.ubuntu.com/ http://ftp.nluug.nl/os/Linux/distr/ubuntu/ @@ -339,17 +352,16 @@ http://mirror.1000mbps.com/ubuntu/ http://mirror.amsiohosting.net/archive.ubuntu.com/ http://mirror.dataone.nl/ubuntu-archive/ +http://mirror.eu.kamatera.com/ubuntu/ http://mirror.hostnet.nl/ubuntu/archive/ http://mirror.i3d.net/pub/ubuntu/ http://mirror.nforce.com/pub/linux/ubuntu/ http://mirror.nl.datapacket.com/ubuntu/ http://mirror.nl.leaseweb.net/ubuntu/ http://mirror.previder.nl/ubuntu/ -http://mirror.redium.net/pub/linux/ubuntu/ http://mirror.serverion.com/ubuntu/ http://mirror.serverius.net/ubuntu/ http://mirror.transip.net/ubuntu/ubuntu/ -http://mirror.vpgrp.io/ubuntu/ http://mirrors.xtom.nl/ubuntu/ http://nl.archive.ubuntu.com/ubuntu/ http://nl3.archive.ubuntu.com/ubuntu/ @@ -366,7 +378,6 @@ #LOC:NZ http://ftp.citylink.co.nz/ubuntu/ http://mirror.fsmg.org.nz/ubuntu/ -http://nz.archive.ubuntu.com/ubuntu/ http://ubuntu.mirrors.theom.nz/ http://ucmirror.canterbury.ac.nz/ubuntu/ #LOC:PF @@ -383,16 +394,17 @@ http://ftp.agh.edu.pl/ubuntu/ http://ftp.icm.edu.pl/pub/Linux/ubuntu/ http://ftp.vectranet.pl/ubuntu/ +http://mirror.onet.pl/pub/mirrors/ubuntu/ http://piotrkosoft.net/pub/mirrors/ubuntu/ http://ubuntu.man.lodz.pl/ubuntu/ http://ubuntu.task.gda.pl/ubuntu/ +#LOC:PR +http://mirrors.upr.edu/ubuntu/ #LOC:PT http://archive.ubuntumirror.dei.uc.pt/ubuntu/ http://ftp.rnl.tecnico.ulisboa.pt/pub/ubuntu/archive/ http://glua.ua.pt/pub/ubuntu/ -http://mirrors.ptisp.pt/ubuntu/ http://mirrors.up.pt/ubuntu/ -http://mirrors.webtuga.pt/ubuntu/ #LOC:RO http://ftp.upcnet.ro/mirrors/ubuntu.com/ubuntu/ http://mirrors.nav.ro/ubuntu/ @@ -406,8 +418,6 @@ #LOC:RU http://mirror.corbina.net/ubuntu/ http://mirror.docker.ru/ubuntu/ -http://mirror.linux-ia64.org/ubuntu/ -http://mirror.logol.ru/ubuntu/ http://mirror.timeweb.ru/ubuntu/ http://mirror.truenetwork.ru/ubuntu/ http://mirror.yandex.ru/ubuntu/ @@ -424,9 +434,9 @@ http://mirror.zetup.net/ubuntu/ http://ubuntu.mirror.su.se/ubuntu/ #LOC:SG +http://download.nus.edu.sg/mirror/ubuntu/ http://mirror.0x.sg/ubuntu/ http://mirror.aktkn.sg/ubuntu/ -http://mirror.nus.edu.sg/ubuntu/ #LOC:SI http://ftp.arnes.si/pub/mirrors/ubuntu/ #LOC:SK @@ -457,7 +467,7 @@ http://ftp.tku.edu.tw/ubuntu/ http://ftp.ubuntu-tw.net/ubuntu/ http://ftp.yzu.edu.tw/ubuntu/ -http://mirror.ncunwlab.tk/ubuntu/ +http://mirror.nwlab.tk/ubuntu/ http://mirror01.idc.hinet.net/ubuntu/ http://ubuntu.cs.nctu.edu.tw/ubuntu/ http://ubuntu.stu.edu.tw/ubuntu/ @@ -475,12 +485,13 @@ http://mirror.renu.ac.ug/ubuntu/ #LOC:US http://archive.linux.duke.edu/ubuntu/ -http://fireball-public.phys.wvu.edu/mirror/ubuntu/ http://ftp.usf.edu/pub/ubuntu/ http://ftp.ussg.iu.edu/linux/ubuntu/ http://ftp.utexas.edu/ubuntu/ http://la-mirrors.evowise.com/ubuntu/ +http://lug.mtu.edu/ubuntu/ http://mirror.ancl.hawaii.edu/linux/ubuntu/ +http://mirror.arizona.edu/ubuntu/ http://mirror.atlantic.net/ubuntu/ http://mirror.cc.columbia.edu/pub/linux/ubuntu/archive/ http://mirror.cc.vt.edu/pub2/ubuntu/ @@ -491,6 +502,7 @@ http://mirror.cs.unm.edu/archive/ http://mirror.enzu.com/ubuntu/ http://mirror.genesisadaptive.com/ubuntu/ +http://mirror.lcsee.wvu.edu/ubuntu/ http://mirror.lstn.net/ubuntu/ http://mirror.math.princeton.edu/pub/ubuntu/ http://mirror.math.ucdavis.edu/ubuntu/ @@ -510,13 +522,17 @@ http://mirror.umd.edu/ubuntu/ http://mirror.uoregon.edu/ubuntu/ http://mirror.us-midwest-1.nexcess.net/ubuntu/ +http://mirror.us-ny2.kamatera.com/ubuntu/ +http://mirror.us-sc.kamatera.com/ubuntu/ +http://mirror.us-tx.kamatera.com/ubuntu/ http://mirror.us.leaseweb.net/ubuntu/ -http://mirrordenver.fdcservers.net/ubuntu/ +http://mirror.vcu.edu/pub/gnu+linux/ubuntu/ http://mirrors.accretive-networks.net/ubuntu/ http://mirrors.advancedhosters.com/ubuntu/ http://mirrors.arpnetworks.com/Ubuntu/ http://mirrors.bloomu.edu/ubuntu/ http://mirrors.cat.pdx.edu/ubuntu/ +http://mirrors.codec-cluster.org/ubuntu/ http://mirrors.easynews.com/linux/ubuntu/ http://mirrors.gigenet.com/ubuntuarchive/ http://mirrors.liquidweb.com/ubuntu/ @@ -529,6 +545,7 @@ http://mirrors.sonic.net/ubuntu/ http://mirrors.syringanetworks.net/ubuntu-archive/ http://mirrors.tripadvisor.com/ubuntu/ +http://mirrors.us.kernel.org/ubuntu/ http://mirrors.usinternet.com/ubuntu/archive/ http://mirrors.vcea.wsu.edu/ubuntu/ http://mirrors.wikimedia.org/ubuntu/ @@ -540,6 +557,7 @@ http://repo.ialab.dsu.edu/ubuntu/ http://repo.miserver.it.umich.edu/ubuntu/ http://repos.forethought.net/ubuntu/ +http://ubuntu-mirror.netzyp.com/ubuntu/ http://ubuntu.cs.utah.edu/ubuntu/ http://ubuntu.mirror.constant.com/ http://ubuntu.mirror.frontiernet.net/ubuntu/ @@ -547,10 +565,11 @@ http://ubuntu.mirrors.tds.net/pub/ubuntu/ http://ubuntu.osuosl.org/ubuntu/ http://ubuntu.securedservers.com/ -http://us.archive.ubuntu.com/ubuntu/ +http://us.mirror.nsec.pt/ubuntu/ http://www.club.cc.cmu.edu/pub/ubuntu/ http://www.gtlib.gatech.edu/pub/ubuntu/ #LOC:UY +http://repos.interior.edu.uy/ubuntu/ http://ubuntu.repo.cure.edu.uy/mirror/ #LOC:UZ http://ubuntu.snet.uz/ubuntu/ diff -Nru python-apt-1.9.0ubuntu1/debian/changelog python-apt-1.9.0ubuntu1.1/debian/changelog --- python-apt-1.9.0ubuntu1/debian/changelog 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/debian/changelog 2020-01-15 16:35:02.000000000 +0100 @@ -1,3 +1,26 @@ +python-apt (1.9.0ubuntu1.1) eoan-security; urgency=medium + + * SECURITY UPDATE: Check that repository is trusted before downloading + files from it (LP: #1858973) + - apt/cache.py: Add checks to fetch_archives() and commit() + - apt/package.py: Add checks to fetch_binary() and fetch_source() + - CVE-2019-15796 + * SECURITY UPDATE: Do not use MD5 for verifying downloadeds + (Closes: #944696) (#LP: #1858972) + - apt/package.py: Use all hashes when fetching packages, and + check that we have trusted hashes when downloading + - CVE-2019-15795 + * To work around the new checks, the parameter allow_unauthenticated=True + can be passed to the functions. It defaults to the value of the + APT::Get::AllowUnauthenticated option. + - Bump Breaks aptdaemon (<< 1.1.1+bzr982-0ubuntu28.1), as it will have + to set that parameter after having done validation. + * Automatic changes and fixes for external regressions: + - Adjustments to test suite and CI to fix CI regressions + - Automatic mirror list update + + -- Julian Andres Klode Wed, 15 Jan 2020 16:35:02 +0100 + python-apt (1.9.0ubuntu1) eoan; urgency=medium * apt/package.py: Use SHA256 instead of MD5 for fetching checks. diff -Nru python-apt-1.9.0ubuntu1/debian/control python-apt-1.9.0ubuntu1.1/debian/control --- python-apt-1.9.0ubuntu1/debian/control 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/debian/control 2020-01-15 16:35:02.000000000 +0100 @@ -38,7 +38,7 @@ debdelta (<< 0.41+), python-dogtail (<< 0.6.1-3.1+), python-software-properties (<< 0.70.debian-1+), - aptdaemon (<< 0.11+bzr343-1~), + aptdaemon (<< 1.1.1+bzr982-0ubuntu28.1), apt-forktracer (<< 0.3), apt-listchanges (<< 2.85), aptoncd (<< 0.1.98+bzr117), diff -Nru python-apt-1.9.0ubuntu1/debian/rules python-apt-1.9.0ubuntu1.1/debian/rules --- python-apt-1.9.0ubuntu1/debian/rules 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/debian/rules 2020-01-15 16:35:02.000000000 +0100 @@ -12,6 +12,12 @@ export pyversions := $(CURDIR)/utils/pyversions export DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie +# Workaround bug in gcc -flto on Ubuntu disco. +ifeq (yes,$(shell dpkg-vendor --derives-from Ubuntu && echo yes)) +DEB_CFLAGS_MAINT_APPEND+=-fno-lto +endif + + %: dh $@ --with python2,python3,sphinxdoc diff -Nru python-apt-1.9.0ubuntu1/doc/source/library/apt_pkg.rst python-apt-1.9.0ubuntu1.1/doc/source/library/apt_pkg.rst --- python-apt-1.9.0ubuntu1/doc/source/library/apt_pkg.rst 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/doc/source/library/apt_pkg.rst 2020-01-15 16:35:02.000000000 +0100 @@ -1793,8 +1793,8 @@ of apt is supported. The parameter *hash* refers to the hash of the file. If this is set - libapt will check the file after downloading. See :class:`HashString` - for the combined form string format description. + libapt will check the file after downloading. This should be an instance + of :class:`apt_pkg.HashStringList`. The parameter *size* can be used to specify the size of the package, which can then be used to calculate the progress and validate the download. @@ -1818,6 +1818,11 @@ In terms of attributes, this class is a subclass of :class:`AcquireItem` and thus inherits all its attributes. + .. versionchanged:: 1.8.5 + + The *hash* parameter now accepts an :class:`apt_pkg.HashStringList`, + the old *md5* parameter has been removed (backported from 1.9.1) + .. class:: AcquireWorker An :class:`AcquireWorker` object represents a sub-process responsible for @@ -1914,6 +1919,8 @@ .. autoattribute:: hashvalue + .. autoattribute:: usable + .. method:: verify_file(filename: str) -> bool Verify that the file given by the parameter *filename* matches the @@ -1930,6 +1937,8 @@ Get the :class:`HashString` object at the specified index. + .. autoattribute:: usable + The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, :func:`sha1sum` and :func:`sha256sum` for creating a single hash from a :class:`bytes` or :class:`file` object: diff -Nru python-apt-1.9.0ubuntu1/.gitlab-ci.yml python-apt-1.9.0ubuntu1.1/.gitlab-ci.yml --- python-apt-1.9.0ubuntu1/.gitlab-ci.yml 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/.gitlab-ci.yml 2020-01-15 16:35:02.000000000 +0100 @@ -1,15 +1,24 @@ -image: debian:testing +image: ubuntu:eoan variables: DEBIAN_FRONTEND: noninteractive -test: +typing: script: - apt update - apt install -q -y python3-pip - - apt build-dep -q -y ./ - - python3 -m pip install -U mypy - - env python3 tests/testmanual_pep8.py + - python3 -m pip install -U mypy==0.670 - env MYPYPATH=$PWD/typehinting/ mypy ./apt + +pep8: + script: + - apt update + - apt install -q -y pep8 + - env python3 tests/testmanual_pep8.py + +test: + script: + - apt update + - apt build-dep -q -y ./ - dpkg-buildpackage - make -C doc html artifacts: diff -Nru python-apt-1.9.0ubuntu1/python/acquire-item.cc python-apt-1.9.0ubuntu1.1/python/acquire-item.cc --- python-apt-1.9.0ubuntu1/python/acquire-item.cc 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/python/acquire-item.cc 2020-01-15 16:35:02.000000000 +0100 @@ -237,10 +237,12 @@ static PyObject *acquirefile_new(PyTypeObject *type, PyObject *Args, PyObject * kwds) { PyObject *pyfetcher; - const char *uri, *hash, *md5, *descr, *shortDescr; + PyObject *pyhashes = nullptr; + HashStringList hashes; + const char *uri, *md5, *descr, *shortDescr; PyApt_Filename destDir, destFile; int size = 0; - uri = hash = md5 = descr = shortDescr = destDir = destFile = ""; + uri = md5 = descr = shortDescr = destDir = destFile = ""; // "md5" is only in this list for backward compatiblity, everyone should // use "hash" @@ -248,14 +250,15 @@ "destdir", "destfile", "md5", NULL }; #if PY_MAJOR_VERSION >= 3 - const char *fmt = "O!s|sissO&O&$s"; + const char *fmt = "O!s|OissO&O&$s"; #else // no "$" support to indicate that the remaining args are keyword only // in py2.x :/ - const char *fmt = "O!s|sissO&O&s"; + const char *fmt = "O!s|OissO&O&s"; #endif if (PyArg_ParseTupleAndKeywords(Args, kwds, fmt, kwlist, - &PyAcquire_Type, &pyfetcher, &uri, &hash, + &PyAcquire_Type, &pyfetcher, &uri, + &pyhashes, &size, &descr, &shortDescr, PyApt_Filename::Converter, &destDir, PyApt_Filename::Converter, &destFile, @@ -266,14 +269,22 @@ PyErr_Warn(PyExc_DeprecationWarning, "Using the md5 keyword is deprecated, please use 'hash' instead"); } - // support "md5" keyword for backward compatiblity - if (strlen(hash) == 0 && strlen(md5) != 0) - hash = md5; + + if (pyhashes == nullptr && strlen(md5) != 0) + hashes = HashStringList(md5); + else if (pyhashes == nullptr) + ; + else if (PyString_Check(pyhashes)) + hashes = HashStringList(PyString_AsString(pyhashes)); + else if (PyObject_TypeCheck(pyhashes, &PyHashStringList_Type)) + hashes = GetCpp (pyhashes); + else + return PyErr_SetString(PyExc_TypeError, "'hash' value must be an apt_pkg.HashStringList or a string"), nullptr; pkgAcquire *fetcher = GetCpp(pyfetcher); pkgAcqFile *af = new pkgAcqFile(fetcher, // owner uri, // uri - HashStringList(hash), // hash + hashes, // hash size, // size descr, // descr shortDescr, @@ -286,7 +297,7 @@ static char *acquirefile_doc = - "AcquireFile(owner, uri[, md5, size, descr, short_descr, destdir," + "AcquireFile(owner, uri[, hash: Union[apt_pkg.HashStringList, str], size, descr, short_descr, destdir," "destfile])\n\n" "Represent a file to be fetched. The parameter 'owner' points to\n" "an apt_pkg.Acquire object and the parameter 'uri' to the source\n" @@ -303,7 +314,7 @@ "and something like 'http://localhost sid/main python-apt 0.7.94.2'\n" "as 'descr'." "\n" - "The parameters 'md5' and 'size' are used to verify the resulting\n" + "The parameters 'hash' and 'size' are used to verify the resulting\n" "file. The parameter 'size' is also to calculate the total amount\n" "of data to be fetched and is useful for resuming a interrupted\n" "download.\n\n" diff -Nru python-apt-1.9.0ubuntu1/python/hashstring.cc python-apt-1.9.0ubuntu1.1/python/hashstring.cc --- python-apt-1.9.0ubuntu1/python/hashstring.cc 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/python/hashstring.cc 2020-01-15 16:35:02.000000000 +0100 @@ -63,6 +63,11 @@ const HashString *hash = GetCpp(self); return CppPyString(hash->HashValue()); } +static PyObject *hashstring_get_usable(PyObject *self) +{ + const HashString *hash = GetCpp(self); + return PyBool_FromLong(hash->usable()); +} static char *hashstring_verify_file_doc = "verify_file(filename: str) -> bool\n\n" @@ -90,6 +95,8 @@ "The value of the hash, as a hexadecimal string\n" "\n" ".. versionadded:: 1.9.0"}, + {"usable",(getter)hashstring_get_usable,0, + "True if the hashstring is a trusted hash type."}, {NULL} }; diff -Nru python-apt-1.9.0ubuntu1/python/hashstringlist.cc python-apt-1.9.0ubuntu1.1/python/hashstringlist.cc --- python-apt-1.9.0ubuntu1/python/hashstringlist.cc 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/python/hashstringlist.cc 2020-01-15 16:35:02.000000000 +0100 @@ -93,6 +93,9 @@ static PyObject *hashstringlist_get_file_size(PyObject *self, void*) { return MkPyNumber(GetCpp(self).FileSize()); } +static PyObject *hashstringlist_get_usable(PyObject *self, void*) { + return PyBool_FromLong(GetCpp(self).usable()); +} static int hashstringlist_set_file_size(PyObject *self, PyObject *value, void *) { if (PyLong_Check(value)) { @@ -161,6 +164,8 @@ static PyGetSetDef hashstringlist_getset[] = { {"file_size",hashstringlist_get_file_size,hashstringlist_set_file_size, "If a file size is part of the list, return it, otherwise 0."}, + {"usable",hashstringlist_get_usable,nullptr, + "True if at least one safe/trusted hash is in the list."}, {} }; diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/key.gpg.base64 python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/key.gpg.base64 --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/key.gpg.base64 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/key.gpg.base64 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,62 @@ +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 +qipSuMIYrosA diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/seckey.asc python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/seckey.asc --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/seckey.asc 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/seckey.asc 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,158 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +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 +DZeT+S/3tXCwy1Jtoi7vcaoqUrjCGK6LAA== +=mcY/ +-----END PGP PRIVATE KEY BLOCK----- diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Packages python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Packages --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Packages 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Packages 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,26 @@ +Package: signed-not-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./signed-not-usable_1.0_all.deb +Size: 35 +MD5sum: f3034b91e355ba6046ff535ed044dcb5 +Description: Dummy package + +Package: signed-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./signed-usable_1.0_all.deb +Size: 31 +MD5sum: 2d5166c110423c2d7c016642af4bd2eb +SHA256: 20edddf30a1bedf669f19caffa347299239b2a700ff428e33abc75e902f1d737 +Description: Dummy package diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Release python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Release --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Release 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Release 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,17 @@ +Date: Fri, 13 Dec 2019 16:11:05 +0000 +MD5Sum: + 21b1df48cfe01053dd2245763423cefb 668 Packages + 6715b0d77e7ea43fb252c78f1f826096 38 Release + 30432690119177a7f0c822c12f96e665 579 Sources +SHA1: + 910742c214560ce8ecdcb89c86fb1c0afa5a5373 668 Packages + 4a252d8c4ebc30d7330938a7dee06288877c4e3f 38 Release + 3147ec4b880bbb2cfa2a3f903b86d1dd2249488d 579 Sources +SHA256: + 445d75ee95443b89849b17f73ae434423d01c603f03c894a7be7851d36a5365d 668 Packages + c0ac431b6ea236c4d12e904b556bbb1f8d0abc733041cab4d65bfd3fd9704183 38 Release + 99140dde6468a8e073d8830faaf90e40c374957b98c1be446308dc8296ce5934 579 Sources +SHA512: + fdc2f7552c06ea197c8c40a44602218703a08d1b6a86f9319cc13a56ea8e7f7103c10aea6ee221b0bc88432ebb2651e3d2e5a93a3900fec5630db2e41684c57b 668 Packages + 5800d40647c79881b15119bbc576b12926151a2df37b96e18abc5fb04986663fa01867a83a1919225365b590a15e22032d12175eaf76336f167688c5a817ca13 38 Release + d0dd2a03687df03e4728219b9b149d514f8a734fcdeee8e45cb31229fc0f915eab634a50f934a60df42682e6dfbc65b962109bda616af642d6ee4cf821a877a1 579 Sources diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Release.gpg python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Release.gpg --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Release.gpg 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Release.gpg 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,14 @@ +-----BEGIN PGP SIGNATURE----- + +iQHFBAABCgAvFiEEJIBsPhVxGFtaHobENN7p9ZyTYfkFAl3zuBkRHHRlc3RAZXhh +bXBsZS5jb20ACgkQNN7p9ZyTYfkkrwv9HBgaZjSf3Bib9FH2alGZkBHKRcE2gWKf +d4PBXKLGgUutCy2g1Dn+FyBYB4OCf3H7ZsD6JFqrYSmLyGHAo+5QTMaPcRlVGoN8 +GL/fxJOEkRJruyC3k36toZTgXI/DGvSv1882syHTG0jOm8to95wiaQKDysTKOOTp +p1HJbX5DX+Wf2rXA/CL8KdH7rHzkIdhjdL4hucDw+JvNSywPEn0RSfvjtUS04d7G +Rw8H2PXyEnreO6OmMdwEmtImouIVxNZDFEEWUhdwujMnDtxM16uIIRLXa1sWQAzZ +M7RHNIhQHP1EvPuQRnKknacKUwchpg/IklxxruaRtjELSUMF5UOXJdnJFb3t6+pT +HBaW/c5piLfMsIV5U/bjQA76Ta4NccH5hah8x6+SjEZiP5RxSfQ9wpblYQeOmaUB +xi0tF6Ukqp5zfPi1RblziWZbN2/ty5zXpPOYbDT2geWo+8bVEhG6HwtHvpzuVymR +qtjOlCujLlkNZKG5jBHoOhuQjNPm+8RY +=wnyK +-----END PGP SIGNATURE----- diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1 @@ +i am signed-not-usable_1.0_all.deb diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: signed-not-usable +Binary: signed-not-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-not-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1 @@ +i am signed-usable_1.0_all.deb diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: signed-usable +Binary: signed-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Sources python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Sources --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/signed/Sources 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/signed/Sources 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,21 @@ +Package: signed-not-usable +Format: 3.0 (native) +Binary: signed-not-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-not-usable deb admin important arch=all +Files: + f2ae6d320641e8e241efcba02b5540fb 323 signed-not-usable_1.0.dsc + +Package: signed-usable +Format: 3.0 (native) +Binary: signed-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-usable deb admin important arch=all +Files: + 491c58f65f493e838880a6ff30064c57 311 signed-usable_1.0.dsc +Checksums-Sha256: + 7a277156805101ce917dbb8d443d7087cc0ad333d25304f284976dba36339487 311 signed-usable_1.0.dsc diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Packages python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Packages --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Packages 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Packages 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,26 @@ +Package: unsigned-unusable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./unsigned-unusable_1.0_all.deb +Size: 35 +MD5sum: 368e155b22e873eb71ae43b80379c0ea +Description: Dummy package + +Package: unsigned-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./unsigned-usable_1.0_all.deb +Size: 33 +MD5sum: 0a0bb7636879ae8a38b679bc3d09b627 +SHA256: ddc71095223eb039cce782e813782b917502e0f3c99a1142ea2d92b34737a243 +Description: Dummy package diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Release python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Release --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Release 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Release 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,17 @@ +Date: Fri, 13 Dec 2019 16:04:58 +0000 +MD5Sum: + dd9db6eb770d950241fc5dfd1b94d4c5 672 Packages + 808b5c1ee28bdae1ffe98a8ee632a4ff 38 Release + bb3efd66e75fa995971ddf8d3bdcd6cb 592 Sources +SHA1: + 4b83e0112704ce4aa20d5833dfad0617404cb48f 672 Packages + 9cba73573f2824f5691293802046a707d1493cdf 38 Release + 4e4a503ec704e11c963c042f44a3ad9da7f30b88 592 Sources +SHA256: + e7a1760be467c66c570e3a5feddfb8d82a14cb4a201382353e4d9bf4c8fb530a 672 Packages + b7efc8e49608e74fefd10f93081843b66200cf9b3d12af7e7772138d8d9fd514 38 Release + f1bea3fd5e27e0a2b606ef23690a611b6a1b60baf42284d5469431dfae4c316a 592 Sources +SHA512: + 4d951a837afed5be1aa89e594587b34f533408b28e4f3b0ffd2c69e5edf45873e24ace59126b12c8f83734ca5daa1d901f2f51170ac325b2787b3674e7226d93 672 Packages + 31d2d8013ee14aa414abf831819f2896f2d9c323fbfcfbc24bf7d602e1855a97ae049125397afd909e8a78aa0c016469731742f7dded416680fced49cce4b088 38 Release + e476cf4357f0f5ec00529dd96b782d9ed52e94db06020ad64ec976f4be6f3783151267fd9916857bedd1c3b693a338f53501d09200a0834c004da54f5acbfca0 592 Sources diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Sources python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Sources --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/Sources 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/Sources 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,22 @@ +Package: unsigned-unusable +Format: 3.0 (native) +Binary: unsigned-unusable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-unusable deb admin important arch=all +Files: + c9c8d679a878ca08faca12baf5e2398d 323 unsigned-not-usable_1.0.dsc + + +Package: unsigned-usable +Format: 3.0 (native) +Binary: unsigned-usable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-usable deb admin important arch=all +Files: + 864f4834dabbd30e6472902b000d7a76 317 unsigned-usable_1.0.dsc +Checksums-Sha256: + eb6c1ebc468b4687bb6bffe25afd5ab1e1812beb9577fac7560396bcb7775939 317 unsigned-usable_1.0.dsc diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: unsigned-unusable +Binary: unsigned-unusable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-unusable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1 @@ +i am unsigned-unusable_1.0_all.deb diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1 @@ +i am unsigned-usable_1.0_all.deb diff -Nru python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc --- python-apt-1.9.0ubuntu1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: unsigned-usable +Binary: unsigned-usable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff -Nru python-apt-1.9.0ubuntu1/tests/testcommon.py python-apt-1.9.0ubuntu1.1/tests/testcommon.py --- python-apt-1.9.0ubuntu1/tests/testcommon.py 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/tests/testcommon.py 2020-01-15 16:35:02.000000000 +0100 @@ -2,6 +2,7 @@ import apt_pkg +import sys import unittest @@ -18,3 +19,14 @@ apt_pkg.init_config() apt_pkg.init_system() + + if (sys.version_info.major, sys.version_info.minor) < (3, 2): + def assertRaisesRegex(self, exc_typ, regex, func, *args, **kwds): + """Compatibility helper""" + try: + func(*args, **kwds) + except Exception as exc: + self.assertIsInstance(exc, exc_typ) + self.assertRegexpMatches(str(exc), regex) + else: + self.fail("Did not raise exception") diff -Nru python-apt-1.9.0ubuntu1/tests/test_paths.py python-apt-1.9.0ubuntu1.1/tests/test_paths.py --- python-apt-1.9.0ubuntu1/tests/test_paths.py 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/tests/test_paths.py 2020-01-15 16:35:02.000000000 +0100 @@ -61,6 +61,26 @@ destfile=self.file_bytes, hash="sha1:41050ed528554fdd6c6c9a086ddd6bdba5857b21") + def test_acquire_hashes(self): + hs = apt_pkg.HashString("d41d8cd98f00b204e9800998ecf8427e") + hsl = apt_pkg.HashStringList() + hsl.append(hs) + apt_pkg.AcquireFile(apt_pkg.Acquire(), + "http://example.com", + hash=hsl, + destdir=self.file_unicode, + destfile=self.file_unicode) + apt_pkg.AcquireFile(apt_pkg.Acquire(), + "http://example.com", + hash=str(hs), + destdir=self.file_unicode, + destfile=self.file_unicode) + self.assertRaises(TypeError, apt_pkg.AcquireFile, apt_pkg.Acquire(), + "http://example.com", + hash=hs, + destdir=self.file_unicode, + destfile=self.file_unicode) + def test_ararchive(self): archive = apt_inst.ArArchive(u"data/test_debs/data-tar-xz.deb") diff -Nru python-apt-1.9.0ubuntu1/tests/test_signed_usable.py python-apt-1.9.0ubuntu1.1/tests/test_signed_usable.py --- python-apt-1.9.0ubuntu1/tests/test_signed_usable.py 1970-01-01 01:00:00.000000000 +0100 +++ python-apt-1.9.0ubuntu1.1/tests/test_signed_usable.py 2020-01-15 16:35:02.000000000 +0100 @@ -0,0 +1,413 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2019 Canonical Ltd +# +# SPDX-License-Identifier: GPL-2.0+ + + +import base64 +import os +import shutil +import tempfile +import unittest + +import apt_pkg +import apt +import apt.progress.base +import apt.progress.text + +import testcommon + +# A change in APT to early fail acquire items with weak hashes caused it +# to call progress methods before calling Start(), which confused python-apt's +# locking handling. Hence we need to skip such tests for now, until we can test +# against an apt version with the fix: +# +# https://salsa.debian.org/apt-team/apt/commit/84176f6c +# +RUN_CRASHING_TESTS = False + +# Message APT gives us when hashes are too weak +CACHE_MSG_WEAK_HASH = ( + "Insufficient information available to perform this download securely" +) + + +class TestSignedUsable(testcommon.TestCase): + """Test fetch_binary() and fetch_source() signature checking.""" + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.clear("APT::Update::Post-Invoke") + apt_pkg.config.clear("APT::Update::Post-Invoke-Success") + self.chroot_path = chroot_path = tempfile.mkdtemp() + repo_path = os.path.abspath("./data/test-signed-usable-repo/") + # Inits the dirs for us + apt.cache.Cache(rootdir=chroot_path) + # Change directory + self.cwd = os.getcwd() + os.chdir(chroot_path) + with open( + os.path.join(self.chroot_path, "etc/apt/sources.list"), "w" + ) as sources_list: + sources_list.write("deb copy:%s/signed/ /\n" % repo_path) + sources_list.write("deb copy:%s/unsigned/ /\n" % repo_path) + sources_list.write("deb-src copy:%s/signed/ /\n" % repo_path) + sources_list.write("deb-src copy:%s/unsigned/ /\n" % repo_path) + + with open(os.path.join(repo_path, "key.gpg.base64"), "rb") as pubkey64: + with open( + os.path.join(self.chroot_path, "etc/apt/trusted.gpg"), "wb" + ) as tgt: + tgt.write(base64.b64decode(pubkey64.read())) + + self.cache = apt.cache.Cache(rootdir=chroot_path) + apt_pkg.config["Acquire::AllowInsecureRepositories"] = "true" + self.cache.update() + apt_pkg.config["Acquire::AllowInsecureRepositories"] = "false" + self.cache.open() + + self.progress = apt.progress.text.AcquireProgress + apt.progress.text.AcquireProgress = apt.progress.base.AcquireProgress + + # Disable actual installation of downloaded items + self.cache.install_archives = ( + lambda *a, **b: apt_pkg.PackageManager.RESULT_COMPLETED + ) + + def tearDown(self): + # this resets the rootdir apt_pkg.config to ensure it does not + # "pollute" the later tests + apt.cache.Cache(rootdir="/") + os.chdir(self.cwd) + shutil.rmtree(self.chroot_path) + + apt.progress.text.AcquireProgress = self.progress + + def doInstall(self, name, bargs): + install_progress = apt.progress.base.InstallProgress() + self.cache[name].mark_install() + try: + self.cache.commit(install_progress=install_progress, **bargs) + finally: + # Workaround install progress leaking files + install_progress.write_stream.close() + install_progress.status_stream.close() + for fname in os.listdir( + os.path.join(self.chroot_path, "var/cache/apt/archives") + ): + if os.path.isfile( + os.path.join( + self.chroot_path, "var/cache/apt/archives", fname + ) + ): + os.unlink( + os.path.join( + self.chroot_path, "var/cache/apt/archives", fname + ) + ) + self.cache[name].mark_keep() + + def doFetchArchives(self, name, bargs): + fetcher = apt_pkg.Acquire() + self.cache[name].mark_install() + try: + self.cache.fetch_archives(fetcher=fetcher, **bargs) + finally: + for fname in os.listdir( + os.path.join(self.chroot_path, "var/cache/apt/archives") + ): + if fname.endswith(".deb"): + os.unlink( + os.path.join( + self.chroot_path, "var/cache/apt/archives", fname + ) + ) + self.cache[name].mark_keep() + + def testDefaultDenyButExplicitAllowUnauthenticated(self): + """Deny by config (default), but pass allow_unauthenticated=True""" + + bargs = dict(allow_unauthenticated=True) + sargs = dict(allow_unauthenticated=True, unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + + self.doInstall("unsigned-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.doFetchArchives("unsigned-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.cache["signed-not-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-not-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-usable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-unusable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-unusable"].candidate.fetch_source(**sargs) + + def testDefaultAllow(self): + """Allow by config APT::Get::AllowUnauthenticated = True""" + apt_pkg.config["APT::Get::AllowUnauthenticated"] = "true" + + bargs = dict() + sargs = dict(unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + self.doInstall("unsigned-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.doFetchArchives("unsigned-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.cache["signed-not-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-not-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-usable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-unusable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-unusable"].candidate.fetch_source(**sargs) + + def testDefaultDeny(self): + """Test APT::Get::AllowUnauthenticated = False (default)""" + self.doInstall("signed-usable", {}) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-unusable", + {}, + ) + + self.doFetchArchives("signed-usable", {}) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-unusable", + {}, + ) + + self.cache["signed-usable"].candidate.fetch_binary() + self.cache["signed-usable"].candidate.fetch_source(unpack=False) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_source, + unpack=False, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_source, + unpack=False, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_source, + unpack=False, + ) + + def testDefaultAllowButExplicitDeny(self): + """Allow by config, but pass allow_unauthenticated=False""" + apt_pkg.config["APT::Get::AllowUnauthenticated"] = "true" + + bargs = dict(allow_unauthenticated=False) + sargs = dict(allow_unauthenticated=False, unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_source, + **sargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_source, + **sargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_source, + **sargs + ) + + +if __name__ == "__main__": + unittest.main() diff -Nru python-apt-1.9.0ubuntu1/typehinting/apt_pkg.pyi python-apt-1.9.0ubuntu1.1/typehinting/apt_pkg.pyi --- python-apt-1.9.0ubuntu1/typehinting/apt_pkg.pyi 2019-08-06 14:34:24.000000000 +0200 +++ python-apt-1.9.0ubuntu1.1/typehinting/apt_pkg.pyi 2020-01-15 16:35:02.000000000 +0100 @@ -7,6 +7,9 @@ OpProgress, ) +class FileLike(Protocol): + def fileno(self) -> int: ... + class Cdrom: def add(self, progress: CdromProgress) -> bool: ... def ident(self, progress: CdromProgress) -> str: ... @@ -117,6 +120,7 @@ md5_hash: str sha1_hash: str sha256_hash: str + hashes: HashStringList def __init__(self, cache: Cache) -> None: ... def lookup(self, packagefile: Tuple[PackageFile, int], index: int=0) -> bool: ... @@ -209,8 +213,28 @@ shortdesc: str uri: str +class Hashes: + def __init__(self, object: Union[bytes, FileLike, int]) -> None: ... + hashes: HashStringList + +class HashString: + def __init__(self, type: str, hash: Optional[str] = None) -> None: ... + def verify_file(self, filename: str) -> bool: ... + + hashtype: str + hashvalue: str + usable: bool + +class HashStringList: + def append(self, object: HashString) -> None: ... + def find(self, type: str = "") -> HashString: ... + def verify_file(self, filename: str) -> bool: ... + + file_size: int + usable: bool + class AcquireFile(AcquireItem): - def __init__(self, owner: Acquire, uri: str, md5: str="", size: int=0, descr: str="", short_descr: str="", destdir: str="", destfile: str="") -> None: ... + def __init__(self, owner: Acquire, uri: str, hash: Optional[Union[HashStringList, str]], size: int=0, descr: str="", short_descr: str="", destdir: str="", destfile: str="") -> None: ... class IndexFile: def archive_uri(self, path: str) -> str: ... @@ -221,13 +245,20 @@ label: str size: int +class SourceRecordFiles: + + hashes: HashStringList + path: str + size: int + type: str + class SourceRecords: def lookup(self, name: str) -> bool: ... def restart(self) -> None: ... def step(self) -> bool: ... binaries: List[str] version: str - files: List[Tuple[str, int, str, str]] + files: List[SourceRecordFiles] index: IndexFile package: str section: str