astra / tests /test_signed_usable.py
Lorenzob's picture
Upload folder using huggingface_hub
859a779 verified
raw
history blame
13.9 kB
#!/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):
self.cache[name].mark_install()
try:
with apt.progress.base.InstallProgress() as ip:
self.cache.commit(install_progress=ip, **bargs)
finally:
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()