119
113
return (count, result, all_verifiable)
121
115
def valid_commits_message(self, count):
122
return i18n.gettext("{0} commits with valid signatures").format(
116
return gettext(u"{0} commits with valid signatures").format(
123
117
count[SIGNATURE_VALID])
125
119
def unknown_key_message(self, count):
126
return i18n.ngettext("{0} commit with unknown key",
127
"{0} commits with unknown keys",
120
return ngettext(u"{0} commit with unknown key",
121
u"{0} commits with unknown keys",
128
122
count[SIGNATURE_KEY_MISSING]).format(
129
123
count[SIGNATURE_KEY_MISSING])
131
125
def commit_not_valid_message(self, count):
132
return i18n.ngettext("{0} commit not valid",
133
"{0} commits not valid",
126
return ngettext(u"{0} commit not valid",
127
u"{0} commits not valid",
134
128
count[SIGNATURE_NOT_VALID]).format(
135
129
count[SIGNATURE_NOT_VALID])
137
131
def commit_not_signed_message(self, count):
138
return i18n.ngettext("{0} commit not signed",
139
"{0} commits not signed",
132
return ngettext(u"{0} commit not signed",
133
u"{0} commits not signed",
140
134
count[SIGNATURE_NOT_SIGNED]).format(
141
135
count[SIGNATURE_NOT_SIGNED])
137
def expired_commit_message(self, count):
138
return ngettext(u"{0} commit with key now expired",
139
u"{0} commits with key now expired",
140
count[SIGNATURE_EXPIRED]).format(
141
count[SIGNATURE_EXPIRED])
144
144
def _set_gpg_tty():
145
145
tty = os.environ.get('TTY')
235
242
except gpgme.GpgmeError,error:
236
243
raise errors.SignatureVerificationFailed(error[2])
245
# No result if input is invalid.
246
# test_verify_invalid()
238
247
if len(result) == 0:
239
248
return SIGNATURE_NOT_VALID, None
249
# User has specified a list of acceptable keys, check our result is in it.
250
# test_verify_unacceptable_key()
240
251
fingerprint = result[0].fpr
241
252
if self.acceptable_keys is not None:
242
if not fingerprint in self.acceptable_keys:
253
if not fingerprint in self.acceptable_keys:
243
254
return SIGNATURE_KEY_MISSING, fingerprint[-8:]
255
# Check the signature actually matches the testament.
256
# test_verify_bad_testament()
244
257
if testament != plain_output.getvalue():
245
return SIGNATURE_NOT_VALID, None
258
return SIGNATURE_NOT_VALID, None
259
# Yay gpgme set the valid bit.
260
# Can't write a test for this one as you can't set a key to be
261
# trusted using gpgme.
246
262
if result[0].summary & gpgme.SIGSUM_VALID:
247
263
key = self.context.get_key(fingerprint)
248
264
name = key.uids[0].name
249
265
email = key.uids[0].email
250
266
return SIGNATURE_VALID, name + " <" + email + ">"
267
# Sigsum_red indicates a problem, unfortunatly I have not been able
268
# to write any tests which actually set this.
251
269
if result[0].summary & gpgme.SIGSUM_RED:
252
270
return SIGNATURE_NOT_VALID, None
271
# GPG does not know this key.
272
# test_verify_unknown_key()
253
273
if result[0].summary & gpgme.SIGSUM_KEY_MISSING:
254
274
return SIGNATURE_KEY_MISSING, fingerprint[-8:]
255
#summary isn't set if sig is valid but key is untrusted
275
# Summary isn't set if sig is valid but key is untrusted
276
# but if user has explicity set the key as acceptable we can validate it.
256
277
if result[0].summary == 0 and self.acceptable_keys is not None:
257
278
if fingerprint in self.acceptable_keys:
258
return SIGNATURE_VALID, None
260
return SIGNATURE_KEY_MISSING, None
279
# test_verify_untrusted_but_accepted()
280
return SIGNATURE_VALID, None
281
# test_verify_valid_but_untrusted()
282
if result[0].summary == 0 and self.acceptable_keys is None:
283
return SIGNATURE_NOT_VALID, None
284
if result[0].summary & gpgme.SIGSUM_KEY_EXPIRED:
285
expires = self.context.get_key(result[0].fpr).subkeys[0].expires
286
if expires > result[0].timestamp:
287
# The expired key was not expired at time of signing.
288
# test_verify_expired_but_valid()
289
return SIGNATURE_EXPIRED, fingerprint[-8:]
291
# I can't work out how to create a test where the signature
292
# was expired at the time of signing.
293
return SIGNATURE_NOT_VALID, None
294
# A signature from a revoked key gets this.
295
# test_verify_revoked_signature()
296
if result[0].summary & gpgme.SIGSUM_SYS_ERROR:
297
return SIGNATURE_NOT_VALID, None
298
# Other error types such as revoked keys should (I think) be caught by
299
# SIGSUM_RED so anything else means something is buggy.
261
300
raise errors.SignatureVerificationFailed("Unknown GnuPG key "\
262
301
"verification result")
292
332
self.acceptable_keys.append(key.subkeys[0].fpr)
293
333
trace.mutter("Added acceptable key: " + key.subkeys[0].fpr)
294
334
if not found_key:
295
trace.note(i18n.gettext(
296
"No GnuPG key results for pattern: {}"
336
"No GnuPG key results for pattern: {0}"
297
337
).format(pattern))
299
def do_verifications(self, revisions, repository):
339
def do_verifications(self, revisions, repository,
340
process_events_callback=None):
300
341
"""do verifications on a set of revisions
302
343
:param revisions: list of revision ids to verify
303
344
:param repository: repository object
345
:param process_events_callback: method to call for GUI frontends that
346
want to keep their UI refreshed
305
348
:return: count dictionary of results of each type,
306
349
result list for each revision,
377
423
signers[fingerprint] += 1
379
425
for fingerprint, number in signers.items():
380
result.append( i18n.ngettext("Unknown key {0} signed {1} commit",
381
"Unknown key {0} signed {1} commits",
426
result.append( ngettext(u"Unknown key {0} signed {1} commit",
427
u"Unknown key {0} signed {1} commits",
382
428
number).format(fingerprint, number) )
431
def verbose_expired_key_message(self, result, repo):
432
"""takes a verify result and returns list of expired key info"""
434
fingerprint_to_authors = {}
435
for rev_id, validity, fingerprint in result:
436
if validity == SIGNATURE_EXPIRED:
437
revision = repo.get_revision(rev_id)
438
authors = ', '.join(revision.get_apparent_authors())
439
signers.setdefault(fingerprint, 0)
440
signers[fingerprint] += 1
441
fingerprint_to_authors[fingerprint] = authors
443
for fingerprint, number in signers.items():
444
result.append(ngettext(u"{0} commit by author {1} with "\
445
"key {2} now expired",
446
u"{0} commits by author {1} with key {2} now "\
448
number).format(number,
449
fingerprint_to_authors[fingerprint], fingerprint) )
385
452
def valid_commits_message(self, count):
386
453
"""returns message for number of commits"""
387
return i18n.gettext("{0} commits with valid signatures").format(
454
return gettext(u"{0} commits with valid signatures").format(
388
455
count[SIGNATURE_VALID])
390
457
def unknown_key_message(self, count):
391
458
"""returns message for number of commits"""
392
return i18n.ngettext("{0} commit with unknown key",
393
"{0} commits with unknown keys",
394
count[SIGNATURE_KEY_MISSING]).format(
459
return ngettext(u"{0} commit with unknown key",
460
u"{0} commits with unknown keys",
461
count[SIGNATURE_KEY_MISSING]).format(
395
462
count[SIGNATURE_KEY_MISSING])
397
464
def commit_not_valid_message(self, count):
398
465
"""returns message for number of commits"""
399
return i18n.ngettext("{0} commit not valid",
400
"{0} commits not valid",
401
count[SIGNATURE_NOT_VALID]).format(
466
return ngettext(u"{0} commit not valid",
467
u"{0} commits not valid",
468
count[SIGNATURE_NOT_VALID]).format(
402
469
count[SIGNATURE_NOT_VALID])
404
471
def commit_not_signed_message(self, count):
405
472
"""returns message for number of commits"""
406
return i18n.ngettext("{0} commit not signed",
407
"{0} commits not signed",
408
count[SIGNATURE_NOT_SIGNED]).format(
473
return ngettext(u"{0} commit not signed",
474
u"{0} commits not signed",
475
count[SIGNATURE_NOT_SIGNED]).format(
409
476
count[SIGNATURE_NOT_SIGNED])
478
def expired_commit_message(self, count):
479
"""returns message for number of commits"""
480
return ngettext(u"{0} commit with key now expired",
481
u"{0} commits with key now expired",
482
count[SIGNATURE_EXPIRED]).format(
483
count[SIGNATURE_EXPIRED])