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 v2 5/9] rsync: Load and update keys early
Date: Fri, 02 Feb 2018 20:42:56
Message-Id: 20180202204223.9003-5-mgorny@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH v2 1/9] rsync: Verify the value of sync-rsync-verify-jobs by "Michał Górny"
1 Load and update keys early to avoid delaying failures post rsync. Any
2 failure will prevent verification from happening, and presumably most of
3 the users will prefer fixing it and trying to sync again. For that case,
4 it is better to perform the task before actual rsync to avoid
5 unnecessarily rsyncing twice.
6 ---
7 pym/portage/sync/modules/rsync/rsync.py | 103 ++++++++++++++++++--------------
8 1 file changed, 57 insertions(+), 46 deletions(-)
9
10 diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py
11 index 5c0b53f9e..dc4674548 100644
12 --- a/pym/portage/sync/modules/rsync/rsync.py
13 +++ b/pym/portage/sync/modules/rsync/rsync.py
14 @@ -110,7 +110,33 @@ class RsyncSync(NewBase):
15 level=logging.WARNING, noiselevel=-1)
16 self.verify_jobs = None
17
18 + openpgp_env = None
19 + if self.verify_metamanifest and gemato is not None:
20 + # Use isolated environment if key is specified,
21 + # system environment otherwise
22 + if self.repo.sync_openpgp_key_path is not None:
23 + openpgp_env = gemato.openpgp.OpenPGPEnvironment()
24 + else:
25 + openpgp_env = gemato.openpgp.OpenPGPSystemEnvironment()
26 +
27 try:
28 + # Load and update the keyring early. If it fails, then verification
29 + # will not be performed and the user will have to fix it and try again,
30 + # so we may as well bail out before actual rsync happens.
31 + if openpgp_env is not None and self.repo.sync_openpgp_key_path is not None:
32 + try:
33 + out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,))
34 + with io.open(self.repo.sync_openpgp_key_path, 'rb') as f:
35 + openpgp_env.import_key(f)
36 + out.ebegin('Refreshing keys from keyserver')
37 + openpgp_env.refresh_keys()
38 + out.eend(0)
39 + except GematoException as e:
40 + writemsg_level("!!! Manifest verification impossible due to keyring problem:\n%s\n"
41 + % (e,),
42 + level=logging.ERROR, noiselevel=-1)
43 + return (1, False)
44 +
45 # Real local timestamp file.
46 self.servertimestampfile = os.path.join(
47 self.repo.location, "metadata", "timestamp.chk")
48 @@ -299,52 +325,36 @@ class RsyncSync(NewBase):
49 level=logging.ERROR, noiselevel=-1)
50 exitcode = 127
51 else:
52 - # Use isolated environment if key is specified,
53 - # system environment otherwise
54 - if self.repo.sync_openpgp_key_path is not None:
55 - openpgp_env_cls = gemato.openpgp.OpenPGPEnvironment
56 - else:
57 - openpgp_env_cls = gemato.openpgp.OpenPGPSystemEnvironment
58 -
59 try:
60 - with openpgp_env_cls() as openpgp_env:
61 - if self.repo.sync_openpgp_key_path is not None:
62 - out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,))
63 - with io.open(self.repo.sync_openpgp_key_path, 'rb') as f:
64 - openpgp_env.import_key(f)
65 - out.ebegin('Refreshing keys from keyserver')
66 - openpgp_env.refresh_keys()
67 - out.eend(0)
68 -
69 - # we always verify the Manifest signature, in case
70 - # we had to deal with key revocation case
71 - m = gemato.recursiveloader.ManifestRecursiveLoader(
72 - os.path.join(self.repo.location, 'Manifest'),
73 - verify_openpgp=True,
74 - openpgp_env=openpgp_env,
75 - max_jobs=self.verify_jobs)
76 - if not m.openpgp_signed:
77 - raise RuntimeError('OpenPGP signature not found on Manifest')
78 -
79 - ts = m.find_timestamp()
80 - if ts is None:
81 - raise RuntimeError('Timestamp not found in Manifest')
82 -
83 - out.einfo('Manifest timestamp: %s UTC' % (ts.ts,))
84 - out.einfo('Valid OpenPGP signature found:')
85 - out.einfo('- primary key: %s' % (
86 - m.openpgp_signature.primary_key_fingerprint))
87 - out.einfo('- subkey: %s' % (
88 - m.openpgp_signature.fingerprint))
89 - out.einfo('- timestamp: %s UTC' % (
90 - m.openpgp_signature.timestamp))
91 -
92 - # if nothing has changed, skip the actual Manifest
93 - # verification
94 - if not local_state_unchanged:
95 - out.ebegin('Verifying %s' % (self.repo.location,))
96 - m.assert_directory_verifies()
97 - out.eend(0)
98 + # we always verify the Manifest signature, in case
99 + # we had to deal with key revocation case
100 + m = gemato.recursiveloader.ManifestRecursiveLoader(
101 + os.path.join(self.repo.location, 'Manifest'),
102 + verify_openpgp=True,
103 + openpgp_env=openpgp_env,
104 + max_jobs=self.verify_jobs)
105 + if not m.openpgp_signed:
106 + raise RuntimeError('OpenPGP signature not found on Manifest')
107 +
108 + ts = m.find_timestamp()
109 + if ts is None:
110 + raise RuntimeError('Timestamp not found in Manifest')
111 +
112 + out.einfo('Manifest timestamp: %s UTC' % (ts.ts,))
113 + out.einfo('Valid OpenPGP signature found:')
114 + out.einfo('- primary key: %s' % (
115 + m.openpgp_signature.primary_key_fingerprint))
116 + out.einfo('- subkey: %s' % (
117 + m.openpgp_signature.fingerprint))
118 + out.einfo('- timestamp: %s UTC' % (
119 + m.openpgp_signature.timestamp))
120 +
121 + # if nothing has changed, skip the actual Manifest
122 + # verification
123 + if not local_state_unchanged:
124 + out.ebegin('Verifying %s' % (self.repo.location,))
125 + m.assert_directory_verifies()
126 + out.eend(0)
127 except GematoException as e:
128 writemsg_level("!!! Manifest verification failed:\n%s\n"
129 % (e,),
130 @@ -353,7 +363,8 @@ class RsyncSync(NewBase):
131
132 return (exitcode, updatecache_flg)
133 finally:
134 - pass
135 + if openpgp_env is not None:
136 + openpgp_env.close()
137
138
139 def _process_exitcode(self, exitcode, syncuri, out, maxretries):
140 --
141 2.16.1