Permalink
Browse files

git: Support verifying commit signature post-sync

Add a new sync-git-verify-commit-signature option (defaulting to false)
that verifies the top commit signature after syncing. The verification
is currently done using built-in git routines.

The verification passes if the signature is good or untrusted.
In the latter case, a warning is printed. In any other case,
the verification causes sync to fail and an appropriate error is output.

Reviewed-by: Zac Medico <zmedico@gentoo.org>
  • Loading branch information...
mgorny committed Feb 1, 2018
1 parent 8d99acd commit 7a507942b669b6a157612e8f7ce3fe362c39b38f
Showing with 52 additions and 3 deletions.
  1. +4 −0 man/portage.5
  2. +2 −1 pym/portage/sync/modules/git/__init__.py
  3. +46 −2 pym/portage/sync/modules/git/git.py
@@ -1007,6 +1007,10 @@ See also example for sync-git-clone-env.
.B sync\-git\-pull\-extra\-opts
Extra options to give to git when updating repository (git pull).
.TP
.B sync\-git\-verify\-commit\-signature = true|false
Require the top commit in the repository to contain a good OpenPGP
signature. Defaults to false.
.TP
.B sync\-hooks\-only\-on\-change
If set to true, then sync of a given repository will not trigger postsync
hooks unless hooks would have executed for a master repository or the
@@ -1,4 +1,4 @@
# Copyright 2014-2017 Gentoo Foundation
# Copyright 2014-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
doc = """Git plug-in module for portage.
@@ -58,6 +58,7 @@ def _check_depth(self, attr):
'sync-git-env',
'sync-git-pull-env',
'sync-git-pull-extra-opts',
'sync-git-verify-commit-signature',
),
}
}
@@ -1,4 +1,4 @@
# Copyright 2005-2017 Gentoo Foundation
# Copyright 2005-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import logging
@@ -7,7 +7,7 @@
import portage
from portage import os
from portage.util import writemsg_level, shlex_split
from portage.output import create_color_func
from portage.output import create_color_func, EOutput
good = create_color_func("GOOD")
bad = create_color_func("BAD")
warn = create_color_func("WARN")
@@ -71,6 +71,7 @@ def new(self, **kwargs):
else:
# default
git_cmd_opts += " --depth 1"
if self.repo.module_specific_options.get('sync-git-clone-extra-opts'):
git_cmd_opts += " %s" % self.repo.module_specific_options['sync-git-clone-extra-opts']
git_cmd = "%s clone%s %s ." % (self.bin_command, git_cmd_opts,
@@ -85,6 +86,8 @@ def new(self, **kwargs):
self.logger(self.xterm_titles, msg)
writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1)
return (exitcode, False)
if not self.verify_head():
return (1, False)
return (os.EX_OK, True)
@@ -125,12 +128,53 @@ def update(self):
self.logger(self.xterm_titles, msg)
writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1)
return (exitcode, False)
if not self.verify_head():
return (1, False)
current_rev = subprocess.check_output(rev_cmd,
cwd=portage._unicode_encode(self.repo.location))
return (os.EX_OK, current_rev != previous_rev)
def verify_head(self):
if (self.repo.module_specific_options.get(
'sync-git-verify-commit-signature', 'false') != 'true'):
return True
rev_cmd = [self.bin_command, "log", "--pretty=format:%G?", "-1"]
try:
status = (portage._unicode_decode(
subprocess.check_output(rev_cmd,
cwd=portage._unicode_encode(self.repo.location)))
.strip())
except subprocess.CalledProcessError:
return False
out = EOutput()
if status == 'G': # good signature is good
out.einfo('Trusted signature found on top commit')
return True
elif status == 'U': # untrusted
out.ewarn('Top commit signature is valid but not trusted')
return True
else:
if status == 'B':
expl = 'bad signature'
elif status == 'X':
expl = 'expired signature'
elif status == 'Y':
expl = 'expired key'
elif status == 'R':
expl = 'revoked key'
elif status == 'E':
expl = 'unable to verify signature (missing key?)'
elif status == 'N':
expl = 'no signature'
else:
expl = 'unknown issue'
out.eerror('No valid signature found: %s' % (expl,))
return False
def retrieve_head(self, **kwargs):
'''Get information about the head commit'''
if kwargs:

0 comments on commit 7a50794

Please sign in to comment.