summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2017-10-28 00:14:27 +0200
committerMichał Górny <mgorny@gentoo.org>2017-10-28 00:14:27 +0200
commit2f604806c29b775f542f193d5a67716f648b5e6a (patch)
tree8d97224cc5009072f0ce2a5655cd5f183952d8c6
parent3ed385e9d9fb4cf863b7dff9c542043af85ec78d (diff)
downloadgemato-2f604806c29b775f542f193d5a67716f648b5e6a.tar.gz
recursiveloader: Provide more fine-grained control over signing
-rw-r--r--gemato/recursiveloader.py25
-rw-r--r--tests/test_openpgp.py78
2 files changed, 101 insertions, 2 deletions
diff --git a/gemato/recursiveloader.py b/gemato/recursiveloader.py
index beee4cd..1387212 100644
--- a/gemato/recursiveloader.py
+++ b/gemato/recursiveloader.py
@@ -20,7 +20,8 @@ class ManifestRecursiveLoader(object):
"""
def __init__(self, top_manifest_path,
- verify_openpgp=True, openpgp_env=None):
+ verify_openpgp=True, openpgp_env=None,
+ sign_openpgp=None, openpgp_keyid=None):
"""
Instantiate the loader for a Manifest tree starting at top-level
Manifest @top_manifest_path.
@@ -29,11 +30,21 @@ class ManifestRecursiveLoader(object):
to ManifestFile. If the top-level Manifest is OpenPGP-signed
and the verification succeeds, openpgp_signed property
is set to True.
+
+ @sign_openpgp is passed down to ManifestFile when writing
+ the top-level Manifest. If it is True, the top-level Manifest
+ will be signed. If it is False, it will not be signed.
+ If it is left as None, then it will be signed if it was
+ originally signed. @openpgp_keyid can be used to select the key.
+
+ Sub-Manifests are never signed.
"""
self.root_directory = os.path.dirname(top_manifest_path)
self.loaded_manifests = {}
self.verify_openpgp = verify_openpgp
self.openpgp_env = openpgp_env
+ self.sign_openpgp = sign_openpgp
+ self.openpgp_keyid = openpgp_keyid
# TODO: allow catching OpenPGP exceptions somehow?
m = self.load_manifest(os.path.basename(top_manifest_path))
self.openpgp_signed = m.openpgp_signed
@@ -70,9 +81,19 @@ class ManifestRecursiveLoader(object):
"""
m = self.loaded_manifests[relpath]
path = os.path.join(self.root_directory, relpath)
+
+ # is it top-level Manifest?
+ if relpath in (gemato.compression
+ .get_potential_compressed_names('Manifest')):
+ sign = self.sign_openpgp
+ else:
+ sign = False
+
with gemato.compression.open_potentially_compressed_path(
path, 'w', encoding='utf8') as f:
- m.dump(f, openpgp_env=self.openpgp_env)
+ m.dump(f, sign_openpgp=sign,
+ openpgp_env=self.openpgp_env,
+ openpgp_keyid=self.openpgp_keyid)
def _iter_manifests_for_path(self, path, recursive=False):
"""
diff --git a/tests/test_openpgp.py b/tests/test_openpgp.py
index 8e3adf6..ab0a82b 100644
--- a/tests/test_openpgp.py
+++ b/tests/test_openpgp.py
@@ -680,3 +680,81 @@ class OpenPGPPrivateKeyTest(unittest.TestCase):
self.assertTrue(m2.openpgp_signed)
finally:
shutil.rmtree(d)
+
+ def test_recursive_manifest_loader_save_manifest_force_sign(self):
+ d = tempfile.mkdtemp()
+ try:
+ with io.open(os.path.join(d, 'Manifest'), 'w') as f:
+ f.write(SIGNED_MANIFEST)
+
+ m = gemato.recursiveloader.ManifestRecursiveLoader(
+ os.path.join(d, 'Manifest'),
+ verify_openpgp=False,
+ sign_openpgp=True,
+ openpgp_env=self.env)
+ self.assertFalse(m.openpgp_signed)
+
+ self.env.import_key(io.BytesIO(PRIVATE_KEY))
+ m.save_manifest('Manifest')
+
+ m2 = gemato.manifest.ManifestFile()
+ with io.open(os.path.join(d, 'Manifest'), 'r') as f:
+ m2.load(f, openpgp_env=self.env)
+ self.assertTrue(m2.openpgp_signed)
+ finally:
+ shutil.rmtree(d)
+
+ def test_recursive_manifest_loader_save_manifest_compressed_force_sign(self):
+ d = tempfile.mkdtemp()
+ try:
+ with gemato.compression.open_potentially_compressed_path(
+ os.path.join(d, 'Manifest.gz'), 'w') as cf:
+ cf.write(SIGNED_MANIFEST)
+
+ m = gemato.recursiveloader.ManifestRecursiveLoader(
+ os.path.join(d, 'Manifest.gz'),
+ verify_openpgp=False,
+ sign_openpgp=True,
+ openpgp_env=self.env)
+ self.assertFalse(m.openpgp_signed)
+
+ self.env.import_key(io.BytesIO(PRIVATE_KEY))
+ m.save_manifest('Manifest.gz')
+
+ m2 = gemato.manifest.ManifestFile()
+ with gemato.compression.open_potentially_compressed_path(
+ os.path.join(d, 'Manifest.gz'), 'r') as cf:
+ m2.load(cf, openpgp_env=self.env)
+ self.assertTrue(m2.openpgp_signed)
+ finally:
+ shutil.rmtree(d)
+
+ def test_recursive_manifest_loader_save_submanifest_force_sign(self):
+ """
+ Test that sub-Manifests are not signed.
+ """
+ d = tempfile.mkdtemp()
+ try:
+ with io.open(os.path.join(d, 'Manifest'), 'w') as f:
+ f.write(SIGNED_MANIFEST)
+ os.mkdir(os.path.join(d, 'eclass'))
+ with io.open(os.path.join(d, 'eclass/Manifest'), 'w'):
+ pass
+
+ m = gemato.recursiveloader.ManifestRecursiveLoader(
+ os.path.join(d, 'Manifest'),
+ verify_openpgp=False,
+ sign_openpgp=True,
+ openpgp_env=self.env)
+ self.assertFalse(m.openpgp_signed)
+
+ self.env.import_key(io.BytesIO(PRIVATE_KEY))
+ m.load_manifest('eclass/Manifest')
+ m.save_manifest('eclass/Manifest')
+
+ m2 = gemato.manifest.ManifestFile()
+ with io.open(os.path.join(d, 'eclass/Manifest'), 'r') as f:
+ m2.load(f, openpgp_env=self.env)
+ self.assertFalse(m2.openpgp_signed)
+ finally:
+ shutil.rmtree(d)