summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gemato/cli.py42
-rw-r--r--tests/test_openpgp.py38
2 files changed, 78 insertions, 2 deletions
diff --git a/gemato/cli.py b/gemato/cli.py
index d3692bb..22b19f7 100644
--- a/gemato/cli.py
+++ b/gemato/cli.py
@@ -10,6 +10,8 @@ import datetime
import logging
import multiprocessing
import os.path
+import signal
+import subprocess
import sys
import timeit
@@ -561,14 +563,50 @@ class OpenPGPVerifyCommand(VerifyingOpenPGPMixin, GematoCommand):
return 0 if ret else 1
+class GnuPGWrapCommand(VerifyingOpenPGPMixin, GematoCommand):
+ name = 'gpg-wrap'
+ help = ('Run specified command with GNUPGHOME set to OpenPGP '
+ 'verification environment (with keys loaded)')
+
+ def add_options(self, subp):
+ super().add_options(subp)
+
+ subp.add_argument(
+ 'argv', nargs='+',
+ help='Command to execute')
+
+ def parse_args(self, args, argp):
+ super().parse_args(args, argp)
+
+ if args.openpgp_key is None:
+ argp.error('gpg-wrap requires --openpgp-key to be specified')
+ self.argv = args.argv
+
+ def __call__(self):
+ super().__call__()
+ assert isinstance(self.openpgp_env, OpenPGPEnvironment)
+ os.environ['GNUPGHOME'] = self.openpgp_env._home
+ p = subprocess.Popen(self.argv)
+ ret = p.wait()
+ if ret < 0:
+ logging.error(f'Child process terminated due to signal: '
+ f'{signal.strsignal(-ret)}')
+ return ret
+
+
def main(argv):
argp = argparse.ArgumentParser(
prog=argv[0],
description='Gentoo Manifest Tool')
subp = argp.add_subparsers()
- commands = [VerifyCommand, UpdateCommand, CreateCommand,
- HashCommand, OpenPGPVerifyCommand]
+ commands = [VerifyCommand,
+ UpdateCommand,
+ CreateCommand,
+ HashCommand,
+ OpenPGPVerifyCommand,
+ GnuPGWrapCommand,
+ ]
for cmdclass in commands:
cmd = cmdclass()
cmdp = subp.add_parser(cmd.name, help=cmd.help)
diff --git a/tests/test_openpgp.py b/tests/test_openpgp.py
index dbb71e5..69f0aad 100644
--- a/tests/test_openpgp.py
+++ b/tests/test_openpgp.py
@@ -6,6 +6,8 @@
import datetime
import io
import os
+import shlex
+import signal
import tempfile
import pytest
@@ -841,3 +843,39 @@ def test_refresh_wkd_fallback_to_hkp(openpgp_env_with_refresh,
])
def test_get_wkd_url(email, expected):
assert OpenPGPEnvironment.get_wkd_url(email) == expected
+
+
+@pytest.mark.parametrize(
+ 'command,expected,match',
+ [('true', 0, None),
+ ('false', 1, None),
+ ('gpg --verify {tmp_path}/Manifest', 0, None),
+ ('gpg --verify {tmp_path}/Manifest.subkey', 2, None),
+ ('sh -c "kill $$"', -signal.SIGTERM,
+ f'Child process terminated due to signal: '
+ f'{signal.strsignal(signal.SIGTERM)}'),
+ ('sh -c "kill -USR1 $$"', -signal.SIGUSR1,
+ f'Child process terminated due to signal: '
+ f'{signal.strsignal(signal.SIGUSR1)}'),
+ ])
+def test_cli_gpg_wrap(tmp_path, caplog, command, expected, match):
+ with open(tmp_path / '.key.bin', 'wb') as f:
+ f.write(VALID_PUBLIC_KEY)
+ with open(tmp_path / 'Manifest', 'w') as f:
+ f.write(SIGNED_MANIFEST)
+ with open(tmp_path / 'Manifest.subkey', 'w') as f:
+ f.write(SUBKEY_SIGNED_MANIFEST)
+
+ command = [x.replace('{tmp_path}', str(tmp_path))
+ for x in shlex.split(command)]
+ retval = gemato.cli.main(['gemato', 'gpg-wrap',
+ '--openpgp-key',
+ str(tmp_path / '.key.bin'),
+ '--no-refresh-keys',
+ '--'] + command)
+ if str(OpenPGPNoImplementation('')) in caplog.text:
+ pytest.skip('OpenPGP implementation missing')
+
+ assert retval == expected
+ if match is not None:
+ assert match in caplog.text