From 58a7011348b599415e93e2ba2c0e3a65b62d28cc Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Mon, 12 Sep 2016 00:27:36 +0200 Subject: [PATCH] apt: Validate trusted keys This checks that the specified keyrings exist, and are valid. Closes #323 --- bootstrapvz/common/task_groups.py | 1 + bootstrapvz/common/tasks/apt.py | 32 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/bootstrapvz/common/task_groups.py b/bootstrapvz/common/task_groups.py index a92d748..407a003 100644 --- a/bootstrapvz/common/task_groups.py +++ b/bootstrapvz/common/task_groups.py @@ -121,6 +121,7 @@ def get_apt_group(manifest): if 'sources' in manifest.packages: group.append(apt.AddManifestSources) if 'trusted-keys' in manifest.packages: + group.append(apt.ValidateTrustedKeys) group.append(apt.InstallTrustedKeys) if 'preferences' in manifest.packages: group.append(apt.AddManifestPreferences) diff --git a/bootstrapvz/common/tasks/apt.py b/bootstrapvz/common/tasks/apt.py index 1bb46ad..f19b1f4 100644 --- a/bootstrapvz/common/tasks/apt.py +++ b/bootstrapvz/common/tasks/apt.py @@ -6,6 +6,37 @@ import logging import os +class ValidateTrustedKeys(Task): + description = 'Validate apt trusted keys' + phase = phases.validation + + @classmethod + def run(cls, info): + from bootstrapvz.common.tools import log_call + + for i, key_path in enumerate(info.manifest.packages.get('trusted-keys', {})): + if not os.path.isfile(key_path): + info.manifest.validation_error('File not found: {}'.format(key_path), + ['packages', 'trusted-keys', i]) + + from tempfile import mkdtemp + from shutil import rmtree + tempdir = mkdtemp() + + status, _, _ = log_call( + ['gpg', '--quiet', + '--homedir', tempdir, + '--keyring', key_path, + '-k'] + ) + + rmtree(tempdir) + + if status != 0: + info.manifest.validation_error('Invalid GPG keyring: {}'.format(key_path), + ['packages', 'trusted-keys', i]) + + class AddManifestSources(Task): description = 'Adding sources from the manifest' phase = phases.preparation @@ -70,6 +101,7 @@ class AddManifestPreferences(Task): class InstallTrustedKeys(Task): description = 'Installing trusted keys' phase = phases.package_installation + predecessors = [ValidateTrustedKeys] @classmethod def run(cls, info):