Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-portage-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-portage-dev] [PATCH 2/2] git: Support running the verification against sync-openpgp-key-path
Date: Thu, 01 Feb 2018 13:31:29
Message-Id: 20180201133114.27437-2-mgorny@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH 1/2] git: Support verifying commit signature post-sync by "Michał Górny"
1 ---
2 pym/portage/sync/modules/git/git.py | 100 +++++++++++++++++++++++++-----------
3 1 file changed, 69 insertions(+), 31 deletions(-)
4
5 diff --git a/pym/portage/sync/modules/git/git.py b/pym/portage/sync/modules/git/git.py
6 index 7e5ddf3b5..2b40db0fa 100644
7 --- a/pym/portage/sync/modules/git/git.py
8 +++ b/pym/portage/sync/modules/git/git.py
9 @@ -1,6 +1,7 @@
10 # Copyright 2005-2018 Gentoo Foundation
11 # Distributed under the terms of the GNU General Public License v2
12
13 +import io
14 import logging
15 import subprocess
16
17 @@ -13,6 +14,11 @@ bad = create_color_func("BAD")
18 warn = create_color_func("WARN")
19 from portage.sync.syncbase import NewBase
20
21 +try:
22 + import gemato.openpgp
23 +except ImportError:
24 + gemato = None
25 +
26
27 class GitSync(NewBase):
28 '''Git sync class'''
29 @@ -141,39 +147,71 @@ class GitSync(NewBase):
30 'sync-git-verify-commit-signature', 'false') != 'true'):
31 return True
32
33 - rev_cmd = [self.bin_command, "log", "--pretty=format:%G?", "-1"]
34 - try:
35 - status = (portage._unicode_decode(
36 - subprocess.check_output(rev_cmd,
37 - cwd=portage._unicode_encode(self.repo.location)))
38 - .strip())
39 - except subprocess.CalledProcessError:
40 - return False
41 -
42 - out = EOutput()
43 - if status == 'G': # good signature is good
44 - out.einfo('Trusted signature found on top commit')
45 - return True
46 - elif status == 'U': # untrusted
47 - out.ewarn('Top commit signature is valid but not trusted')
48 - return True
49 + if self.repo.openpgp_key_path is not None:
50 + if gemato is None:
51 + writemsg_level("!!! Verifying against specified key requires gemato installed",
52 + level=logging.ERROR, noiselevel=-1)
53 + return False
54 + openpgp_env = gemato.openpgp.OpenPGPEnvironment()
55 else:
56 - if status == 'B':
57 - expl = 'bad signature'
58 - elif status == 'X':
59 - expl = 'expired signature'
60 - elif status == 'Y':
61 - expl = 'expired key'
62 - elif status == 'R':
63 - expl = 'revoked key'
64 - elif status == 'E':
65 - expl = 'unable to verify signature (missing key?)'
66 - elif status == 'N':
67 - expl = 'no signature'
68 + openpgp_env = None
69 +
70 + try:
71 + out = EOutput()
72 + env = None
73 + if openpgp_env is not None:
74 + try:
75 + out.einfo('Using keys from %s' % (self.repo.openpgp_key_path,))
76 + with io.open(self.repo.openpgp_key_path, 'rb') as f:
77 + openpgp_env.import_key(f)
78 + out.ebegin('Refreshing keys from keyserver')
79 + openpgp_env.refresh_keys()
80 + out.eend(0)
81 + except Exception as e:
82 + writemsg_level("!!! Verification impossible due to keyring problem:\n%s\n"
83 + % (e,),
84 + level=logging.ERROR, noiselevel=-1)
85 + return (1, False)
86 +
87 + env = os.environ.copy()
88 + env['GNUPGHOME'] = openpgp_env.home
89 +
90 + rev_cmd = [self.bin_command, "log", "--pretty=format:%G?", "-1"]
91 + try:
92 + status = (portage._unicode_decode(
93 + subprocess.check_output(rev_cmd,
94 + cwd=portage._unicode_encode(self.repo.location),
95 + env=env))
96 + .strip())
97 + except subprocess.CalledProcessError:
98 + return False
99 +
100 + if status == 'G': # good signature is good
101 + out.einfo('Trusted signature found on top commit')
102 + return True
103 + elif status == 'U': # untrusted
104 + out.ewarn('Top commit signature is valid but not trusted')
105 + return True
106 else:
107 - expl = 'unknown issue'
108 - out.eerror('No valid signature found: %s' % (expl,))
109 - return False
110 + if status == 'B':
111 + expl = 'bad signature'
112 + elif status == 'X':
113 + expl = 'expired signature'
114 + elif status == 'Y':
115 + expl = 'expired key'
116 + elif status == 'R':
117 + expl = 'revoked key'
118 + elif status == 'E':
119 + expl = 'unable to verify signature (missing key?)'
120 + elif status == 'N':
121 + expl = 'no signature'
122 + else:
123 + expl = 'unknown issue'
124 + out.eerror('No valid signature found: %s' % (expl,))
125 + return False
126 + finally:
127 + if openpgp_env is not None:
128 + openpgp_env.close()
129
130 def retrieve_head(self, **kwargs):
131 '''Get information about the head commit'''
132 --
133 2.16.1