summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <harmenstoppels@gmail.com>2021-08-26 21:59:44 +0200
committerGitHub <noreply@github.com>2021-08-26 12:59:44 -0700
commit23106ac0f55623a155c1e74633890f7fb7d52d36 (patch)
tree66b39efc8c7b251549a927ef33bb7d0dddce3b8f
parent29d1bc6546def4bcd09c0a5b533de9f39a78d910 (diff)
downloadspack-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
-rw-r--r--lib/spack/spack/util/gpg.py45
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):