diff options
author | Harmen Stoppels <harmenstoppels@gmail.com> | 2021-08-26 21:59:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-26 12:59:44 -0700 |
commit | 23106ac0f55623a155c1e74633890f7fb7d52d36 (patch) | |
tree | 66b39efc8c7b251549a927ef33bb7d0dddce3b8f /lib | |
parent | 29d1bc6546def4bcd09c0a5b533de9f39a78d910 (diff) | |
download | spack-23106ac0f55623a155c1e74633890f7fb7d52d36.tar.gz spack-23106ac0f55623a155c1e74633890f7fb7d52d36.tar.bz2 spack-23106ac0f55623a155c1e74633890f7fb7d52d36.tar.xz spack-23106ac0f55623a155c1e74633890f7fb7d52d36.zip |
Set pubkey trust to ultimate during `gpg trust` (#24976)
* Set pubkey trust to ultimate during `gpg trust`
Tries to solve the same problem as #24760 without surpressing stderr
from gpg commands.
This PR makes every imported key trusted in the gpg database.
Note: I've outlined
[here](https://github.com/spack/spack/pull/24760#issuecomment-883183175)
that gpg's trust model makes sense, since how can we trust a random
public key we download from a binary cache?
* Fix test
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/util/gpg.py | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/lib/spack/spack/util/gpg.py b/lib/spack/spack/util/gpg.py index 787f205a13..ddc69c9579 100644 --- a/lib/spack/spack/util/gpg.py +++ b/lib/spack/spack/util/gpg.py @@ -133,20 +133,33 @@ def _parse_secret_keys_output(output): def _parse_public_keys_output(output): + """ + Returns a list of public keys with their fingerprints + """ keys = [] found_pub = False + current_pub_key = '' for line in output.split('\n'): if found_pub: if line.startswith('fpr'): - keys.append(line.split(':')[9]) + keys.append((current_pub_key, line.split(':')[9])) found_pub = False elif line.startswith('ssb'): found_pub = False elif line.startswith('pub'): + current_pub_key = line.split(':')[4] found_pub = True return keys +def _get_unimported_public_keys(output): + keys = [] + for line in output.split('\n'): + if line.startswith('pub'): + keys.append(line.split(':')[4]) + return keys + + class SpackGPGError(spack.error.SpackError): """Class raised when GPG errors are detected.""" @@ -182,7 +195,7 @@ def signing_keys(*args): @_autoinit -def public_keys(*args): +def public_keys_to_fingerprint(*args): """Return the keys that can be used to verify binaries.""" output = GPG( '--list-public-keys', '--with-colons', '--fingerprint', @@ -192,6 +205,13 @@ def public_keys(*args): @_autoinit +def public_keys(*args): + """Return a list of fingerprints""" + keys_and_fpr = public_keys_to_fingerprint(*args) + return [key_and_fpr[1] for key_and_fpr in keys_and_fpr] + + +@_autoinit def export_keys(location, keys, secret=False): """Export public keys to a location passed as argument. @@ -208,13 +228,32 @@ def export_keys(location, keys, secret=False): @_autoinit def trust(keyfile): - """Import a public key from a file. + """Import a public key from a file and trust it. Args: keyfile (str): file with the public key """ + # Get the public keys we are about to import + output = GPG('--with-colons', keyfile, output=str, error=str) + keys = _get_unimported_public_keys(output) + + # Import them GPG('--import', keyfile) + # Set trust to ultimate + key_to_fpr = dict(public_keys_to_fingerprint()) + for key in keys: + # Skip over keys we cannot find a fingerprint for. + if key not in key_to_fpr: + continue + + fpr = key_to_fpr[key] + r, w = os.pipe() + with contextlib.closing(os.fdopen(r, 'r')) as r: + with contextlib.closing(os.fdopen(w, 'w')) as w: + w.write("{0}:6:\n".format(fpr)) + GPG('--import-ownertrust', input=r) + @_autoinit def untrust(signing, *keys): |