| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | 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 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RUN_CRASHING_TESTS = False |
| |
|
| | |
| | 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/") |
| | |
| | apt.cache.Cache(rootdir=chroot_path) |
| | |
| | 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 |
| |
|
| | |
| | self.cache.install_archives = ( |
| | lambda *a, **b: apt_pkg.PackageManager.RESULT_COMPLETED |
| | ) |
| |
|
| | def tearDown(self): |
| | |
| | |
| | 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() |
| |
|