diff --git a/securesystemslib/gpg/constants.py b/securesystemslib/gpg/constants.py index df023428..1cb4b172 100644 --- a/securesystemslib/gpg/constants.py +++ b/securesystemslib/gpg/constants.py @@ -24,13 +24,20 @@ log = logging.getLogger(__name__) +GPG_TIMEOUT = 10 + @functools.lru_cache(maxsize=3) def is_available_gnupg(gnupg: str) -> bool: """Returns whether gnupg points to a gpg binary.""" gpg_version_cmd = gnupg + " --version" try: - process.run(gpg_version_cmd, stdout=process.PIPE, stderr=process.PIPE) + process.run( + gpg_version_cmd, + stdout=process.PIPE, + stderr=process.PIPE, + timeout=GPG_TIMEOUT, + ) return True except (OSError, subprocess.TimeoutExpired): return False diff --git a/securesystemslib/gpg/functions.py b/securesystemslib/gpg/functions.py index c299bea1..6fc65309 100644 --- a/securesystemslib/gpg/functions.py +++ b/securesystemslib/gpg/functions.py @@ -25,6 +25,7 @@ ) from securesystemslib.gpg.constants import ( FULLY_SUPPORTED_MIN_VERSION, + GPG_TIMEOUT, NO_GPG_MSG, SHA256, gpg_export_pubkey_command, @@ -127,6 +128,7 @@ def create_signature(content, keyid=None, homedir=None): check=False, stdout=process.PIPE, stderr=process.PIPE, + timeout=GPG_TIMEOUT, ) # TODO: It's suggested to take a look at `--status-fd` for proper error @@ -307,7 +309,9 @@ def export_pubkey(keyid, homedir=None): # TODO: Consider adopting command error handling from `create_signature` # above, e.g. in a common 'run gpg command' utility function command = gpg_export_pubkey_command(keyid=keyid, homearg=homearg) - gpg_process = process.run(command, stdout=process.PIPE, stderr=process.PIPE) + gpg_process = process.run( + command, stdout=process.PIPE, stderr=process.PIPE, timeout=GPG_TIMEOUT + ) key_packet = gpg_process.stdout key_bundle = get_pubkey_bundle(key_packet, keyid) diff --git a/tests/test_gpg.py b/tests/test_gpg.py index a65919d1..36fa47e3 100644 --- a/tests/test_gpg.py +++ b/tests/test_gpg.py @@ -44,6 +44,7 @@ parse_signature_packet, ) from securesystemslib.gpg.constants import ( + GPG_TIMEOUT, PACKET_TYPE_PRIMARY_KEY, PACKET_TYPE_SUB_KEY, PACKET_TYPE_USER_ATTR, @@ -218,14 +219,18 @@ def setUpClass(self): # pylint: disable=bad-classmethod-argument # erroneous gpg data in tests below. keyid = "F557D0FF451DEF45372591429EA70BD13D883381" cmd = gpg_export_pubkey_command(keyid=keyid, homearg=homearg) - proc = process.run(cmd, stdout=process.PIPE, stderr=process.PIPE) + proc = process.run( + cmd, stdout=process.PIPE, stderr=process.PIPE, timeout=GPG_TIMEOUT + ) self.raw_key_data = proc.stdout self.raw_key_bundle = parse_pubkey_bundle(self.raw_key_data) # Export pubkey bundle with expired key for key expiration tests keyid = "E8AC80C924116DABB51D4B987CB07D6D2C199C7C" cmd = gpg_export_pubkey_command(keyid=keyid, homearg=homearg) - proc = process.run(cmd, stdout=process.PIPE, stderr=process.PIPE) + proc = process.run( + cmd, stdout=process.PIPE, stderr=process.PIPE, timeout=GPG_TIMEOUT + ) self.raw_expired_key_bundle = parse_pubkey_bundle(proc.stdout) def test_parse_pubkey_payload_errors(self):