1
0
Fork 1
mirror of https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git synced 2025-07-13 19:39:51 +03:00
pmbootstrap/test/test_apk_static.py
BO41 944f539dd6
args.logfd: remove (MR 2114)
Replace "args.logfd" with "pmb.helpers.logging.logfd" in order to avoid
passing "args" to all functions that only use it to write to logfd. This
is the first step to get rid of this args-passed-to-all-functions
pattern in pmbootstrap.
2021-10-10 16:59:17 +02:00

131 lines
4.7 KiB
Python

# Copyright 2021 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import copy
import sys
import tarfile
import glob
import pytest
import pmb_test # noqa
import pmb.chroot.apk_static
import pmb.config
import pmb.parse.apkindex
import pmb.helpers.logging
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "chroot"]
args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(pmb.helpers.logging.logfd.close)
return args
def test_read_signature_info(args):
# Tempfolder inside chroot for fake apk files
tmp_path = "/tmp/test_read_signature_info"
tmp_path_outside = args.work + "/chroot_native" + tmp_path
if os.path.exists(tmp_path_outside):
pmb.chroot.root(args, ["rm", "-r", tmp_path])
pmb.chroot.user(args, ["mkdir", "-p", tmp_path])
# No signature found
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/no_sig.apk",
"/etc/issue"])
with tarfile.open(tmp_path_outside + "/no_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Could not find signature" in str(e.value)
# Signature file with invalid name
pmb.chroot.user(args, ["mkdir", "-p", tmp_path + "/sbin"])
pmb.chroot.user(args, ["cp", "/etc/issue", tmp_path +
"/sbin/apk.static.SIGN.RSA.invalid.pub"])
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/invalid_sig.apk",
"sbin/apk.static.SIGN.RSA.invalid.pub"],
working_dir=tmp_path)
with tarfile.open(tmp_path_outside + "/invalid_sig.apk", "r:gz") as tar:
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.read_signature_info(tar)
assert "Invalid signature key" in str(e.value)
# Signature file with realistic name
path = glob.glob(pmb.config.apk_keys_path + "/*.pub")[0]
name = os.path.basename(path)
path_archive = "sbin/apk.static.SIGN.RSA." + name
pmb.chroot.user(args, ["mv",
f"{tmp_path}/sbin/apk.static.SIGN.RSA.invalid.pub",
f"{tmp_path}/{path_archive}"])
pmb.chroot.user(args, ["tar", "-czf", tmp_path + "/realistic_name_sig.apk",
path_archive], working_dir=tmp_path)
with tarfile.open(f"{tmp_path_outside}/realistic_name_sig.apk", "r:gz")\
as tar:
sigfilename, sigkey_path = pmb.chroot.apk_static.read_signature_info(
tar)
assert sigfilename == path_archive
assert sigkey_path == path
# Clean up
pmb.chroot.user(args, ["rm", "-r", tmp_path])
def test_successful_extraction(args, tmpdir):
if os.path.exists(args.work + "/apk.static"):
os.remove(args.work + "/apk.static")
pmb.chroot.apk_static.init(args)
assert os.path.exists(args.work + "/apk.static")
os.remove(args.work + "/apk.static")
def test_signature_verification(args, tmpdir):
if os.path.exists(args.work + "/apk.static"):
os.remove(args.work + "/apk.static")
version = pmb.parse.apkindex.package(args, "apk-tools-static")["version"]
apk_path = pmb.chroot.apk_static.download(
args, f"apk-tools-static-{version}.apk")
# Extract to temporary folder
with tarfile.open(apk_path, "r:gz") as tar:
sigfilename, sigkey_path = pmb.chroot.apk_static.read_signature_info(
tar)
files = pmb.chroot.apk_static.extract_temp(tar, sigfilename)
# Verify signature (successful)
pmb.chroot.apk_static.verify_signature(args, files, sigkey_path)
# Append data to extracted apk.static
with open(files["apk"]["temp_path"], "ab") as handle:
handle.write("appended something".encode())
# Verify signature again (fail) (this deletes the tempfiles)
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.verify_signature(args, files, sigkey_path)
assert "Failed to validate signature" in str(e.value)
#
# Test "apk.static --version" check
#
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.extract(args, "99.1.2-r1", apk_path)
assert "downgrade attack" in str(e.value)
def test_outdated_version(args, monkeypatch):
if os.path.exists(args.work + "/apk.static"):
os.remove(args.work + "/apk.static")
# Change min version for all branches
min_copy = copy.copy(pmb.config.apk_tools_min_version)
for key, old_ver in min_copy.items():
min_copy[key] = "99.1.2-r1"
monkeypatch.setattr(pmb.config, "apk_tools_min_version", min_copy)
with pytest.raises(RuntimeError) as e:
pmb.chroot.apk_static.init(args)
assert "outdated version" in str(e.value)