~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/gpg.py

  • Committer: Vincent Ladeuil
  • Date: 2012-03-09 11:01:58 UTC
  • mto: This revision was merged to the branch mainline in revision 6489.
  • Revision ID: v.ladeuil+lp@free.fr-20120309110158-62om0ttqa0ooeuw5
Fix the forgotten reference to what's new as part of the 2.6 series initialization.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
    )
41
41
""")
42
42
 
43
 
from bzrlib.symbol_versioning import (
44
 
    deprecated_in,
45
 
    deprecated_method,
46
 
    )
47
 
 
48
43
#verification results
49
44
SIGNATURE_VALID = 0
50
45
SIGNATURE_KEY_MISSING = 1
53
48
SIGNATURE_EXPIRED = 4
54
49
 
55
50
 
56
 
def bulk_verify_signatures(repository, revids, strategy,
57
 
        process_events_callback=None):
58
 
    """Do verifications on a set of revisions
59
 
 
60
 
    :param repository: repository object
61
 
    :param revids: list of revision ids to verify
62
 
    :param strategy: GPG strategy to use
63
 
    :param process_events_callback: method to call for GUI frontends that
64
 
        want to keep their UI refreshed
65
 
 
66
 
    :return: count dictionary of results of each type,
67
 
             result list for each revision,
68
 
             boolean True if all results are verified successfully
69
 
    """
70
 
    count = {SIGNATURE_VALID: 0,
71
 
             SIGNATURE_KEY_MISSING: 0,
72
 
             SIGNATURE_NOT_VALID: 0,
73
 
             SIGNATURE_NOT_SIGNED: 0,
74
 
             SIGNATURE_EXPIRED: 0}
75
 
    result = []
76
 
    all_verifiable = True
77
 
    total = len(revids)
78
 
    pb = ui.ui_factory.nested_progress_bar()
79
 
    try:
80
 
        for i, (rev_id, verification_result, uid) in enumerate(
81
 
                repository.verify_revision_signatures(
82
 
                    revids, strategy)):
83
 
            pb.update("verifying signatures", i, total)
84
 
            result.append([rev_id, verification_result, uid])
85
 
            count[verification_result] += 1
86
 
            if verification_result != SIGNATURE_VALID:
87
 
                all_verifiable = False
88
 
            if process_events_callback is not None:
89
 
                process_events_callback()
90
 
    finally:
91
 
        pb.finished()
92
 
    return (count, result, all_verifiable)
93
 
 
94
 
 
95
51
class DisabledGPGStrategy(object):
96
52
    """A GPG Strategy that makes everything fail."""
97
53
 
142
98
                else:
143
99
                    self.acceptable_keys.append(pattern)
144
100
 
145
 
    @deprecated_method(deprecated_in((2, 6, 0)))
146
101
    def do_verifications(self, revisions, repository):
147
 
        return bulk_verify_signatures(repository, revisions, self)
 
102
        count = {SIGNATURE_VALID: 0,
 
103
                 SIGNATURE_KEY_MISSING: 0,
 
104
                 SIGNATURE_NOT_VALID: 0,
 
105
                 SIGNATURE_NOT_SIGNED: 0,
 
106
                 SIGNATURE_EXPIRED: 0}
 
107
        result = []
 
108
        all_verifiable = True
 
109
        for rev_id in revisions:
 
110
            verification_result, uid =\
 
111
                repository.verify_revision_signature(rev_id,self)
 
112
            result.append([rev_id, verification_result, uid])
 
113
            count[verification_result] += 1
 
114
            if verification_result != SIGNATURE_VALID:
 
115
                all_verifiable = False
 
116
        return (count, result, all_verifiable)
148
117
 
149
 
    @deprecated_method(deprecated_in((2, 6, 0)))
150
118
    def valid_commits_message(self, count):
151
 
        return valid_commits_message(count)
 
119
        return gettext(u"{0} commits with valid signatures").format(
 
120
                                        count[SIGNATURE_VALID])
152
121
 
153
 
    @deprecated_method(deprecated_in((2, 6, 0)))
154
122
    def unknown_key_message(self, count):
155
 
        return unknown_key_message(count)
 
123
        return ngettext(u"{0} commit with unknown key",
 
124
                             u"{0} commits with unknown keys",
 
125
                             count[SIGNATURE_KEY_MISSING]).format(
 
126
                                        count[SIGNATURE_KEY_MISSING])
156
127
 
157
 
    @deprecated_method(deprecated_in((2, 6, 0)))
158
128
    def commit_not_valid_message(self, count):
159
 
        return commit_not_valid_message(count)
 
129
        return ngettext(u"{0} commit not valid",
 
130
                             u"{0} commits not valid",
 
131
                             count[SIGNATURE_NOT_VALID]).format(
 
132
                                            count[SIGNATURE_NOT_VALID])
160
133
 
161
 
    @deprecated_method(deprecated_in((2, 6, 0)))
162
134
    def commit_not_signed_message(self, count):
163
 
        return commit_not_signed_message(count)
 
135
        return ngettext(u"{0} commit not signed",
 
136
                             u"{0} commits not signed",
 
137
                             count[SIGNATURE_NOT_SIGNED]).format(
 
138
                                        count[SIGNATURE_NOT_SIGNED])
164
139
 
165
 
    @deprecated_method(deprecated_in((2, 6, 0)))
166
140
    def expired_commit_message(self, count):
167
 
        return expired_commit_message(count)
 
141
        return ngettext(u"{0} commit with key now expired",
 
142
                        u"{0} commits with key now expired",
 
143
                        count[SIGNATURE_EXPIRED]).format(
 
144
                                        count[SIGNATURE_EXPIRED])
168
145
 
169
146
 
170
147
def _set_gpg_tty():
213
190
            # use the user email address
214
191
            key = config.extract_email_address(self._config_stack.get('email'))
215
192
        return [self._config_stack.get('gpg_signing_command'), '--clearsign',
216
 
                '-u', key, '--no-tty']
 
193
                '-u', key]
217
194
 
218
195
    def sign(self, content):
219
196
        if isinstance(content, unicode):
253
230
 
254
231
    def verify(self, content, testament):
255
232
        """Check content has a valid signature.
256
 
 
 
233
        
257
234
        :param content: the commit signature
258
235
        :param testament: the valid testament string for the commit
259
 
 
 
236
        
260
237
        :return: SIGNATURE_VALID or a failed SIGNATURE_ value, key uid if valid
261
238
        """
262
239
        try:
331
308
 
332
309
    def set_acceptable_keys(self, command_line_input):
333
310
        """Set the acceptable keys for verifying with this GPGStrategy.
334
 
 
 
311
        
335
312
        :param command_line_input: comma separated list of patterns from
336
313
                                command line
337
314
        :return: nothing
366
343
                            "No GnuPG key results for pattern: {0}"
367
344
                                ).format(pattern))
368
345
 
369
 
    @deprecated_method(deprecated_in((2, 6, 0)))
370
346
    def do_verifications(self, revisions, repository,
371
347
                            process_events_callback=None):
372
348
        """do verifications on a set of revisions
373
 
 
 
349
        
374
350
        :param revisions: list of revision ids to verify
375
351
        :param repository: repository object
376
352
        :param process_events_callback: method to call for GUI frontends that
377
 
            want to keep their UI refreshed
378
 
 
 
353
                                                want to keep their UI refreshed
 
354
        
379
355
        :return: count dictionary of results of each type,
380
356
                 result list for each revision,
381
357
                 boolean True if all results are verified successfully
382
358
        """
383
 
        return bulk_verify_signatures(repository, revisions, self,
384
 
            process_events_callback)
 
359
        count = {SIGNATURE_VALID: 0,
 
360
                 SIGNATURE_KEY_MISSING: 0,
 
361
                 SIGNATURE_NOT_VALID: 0,
 
362
                 SIGNATURE_NOT_SIGNED: 0,
 
363
                 SIGNATURE_EXPIRED: 0}
 
364
        result = []
 
365
        all_verifiable = True
 
366
        for rev_id in revisions:
 
367
            verification_result, uid =\
 
368
                repository.verify_revision_signature(rev_id, self)
 
369
            result.append([rev_id, verification_result, uid])
 
370
            count[verification_result] += 1
 
371
            if verification_result != SIGNATURE_VALID:
 
372
                all_verifiable = False
 
373
            if process_events_callback is not None:
 
374
                process_events_callback()
 
375
        return (count, result, all_verifiable)
385
376
 
386
 
    @deprecated_method(deprecated_in((2, 6, 0)))
387
377
    def verbose_valid_message(self, result):
388
378
        """takes a verify result and returns list of signed commits strings"""
389
 
        return verbose_valid_message(result)
390
 
 
391
 
    @deprecated_method(deprecated_in((2, 6, 0)))
 
379
        signers = {}
 
380
        for rev_id, validity, uid in result:
 
381
            if validity == SIGNATURE_VALID:
 
382
                signers.setdefault(uid, 0)
 
383
                signers[uid] += 1
 
384
        result = []
 
385
        for uid, number in signers.items():
 
386
             result.append( ngettext(u"{0} signed {1} commit",
 
387
                             u"{0} signed {1} commits",
 
388
                             number).format(uid, number) )
 
389
        return result
 
390
 
 
391
 
392
392
    def verbose_not_valid_message(self, result, repo):
393
393
        """takes a verify result and returns list of not valid commit info"""
394
 
        return verbose_not_valid_message(result, repo)
 
394
        signers = {}
 
395
        for rev_id, validity, empty in result:
 
396
            if validity == SIGNATURE_NOT_VALID:
 
397
                revision = repo.get_revision(rev_id)
 
398
                authors = ', '.join(revision.get_apparent_authors())
 
399
                signers.setdefault(authors, 0)
 
400
                signers[authors] += 1
 
401
        result = []
 
402
        for authors, number in signers.items():
 
403
            result.append( ngettext(u"{0} commit by author {1}",
 
404
                                 u"{0} commits by author {1}",
 
405
                                 number).format(number, authors) )
 
406
        return result
395
407
 
396
 
    @deprecated_method(deprecated_in((2, 6, 0)))
397
408
    def verbose_not_signed_message(self, result, repo):
398
409
        """takes a verify result and returns list of not signed commit info"""
399
 
        return verbose_not_valid_message(result, repo)
 
410
        signers = {}
 
411
        for rev_id, validity, empty in result:
 
412
            if validity == SIGNATURE_NOT_SIGNED:
 
413
                revision = repo.get_revision(rev_id)
 
414
                authors = ', '.join(revision.get_apparent_authors())
 
415
                signers.setdefault(authors, 0)
 
416
                signers[authors] += 1
 
417
        result = []
 
418
        for authors, number in signers.items():
 
419
            result.append( ngettext(u"{0} commit by author {1}",
 
420
                                 u"{0} commits by author {1}",
 
421
                                 number).format(number, authors) )
 
422
        return result
400
423
 
401
 
    @deprecated_method(deprecated_in((2, 6, 0)))
402
424
    def verbose_missing_key_message(self, result):
403
425
        """takes a verify result and returns list of missing key info"""
404
 
        return verbose_missing_key_message(result)
 
426
        signers = {}
 
427
        for rev_id, validity, fingerprint in result:
 
428
            if validity == SIGNATURE_KEY_MISSING:
 
429
                signers.setdefault(fingerprint, 0)
 
430
                signers[fingerprint] += 1
 
431
        result = []
 
432
        for fingerprint, number in signers.items():
 
433
            result.append( ngettext(u"Unknown key {0} signed {1} commit",
 
434
                                 u"Unknown key {0} signed {1} commits",
 
435
                                 number).format(fingerprint, number) )
 
436
        return result
405
437
 
406
 
    @deprecated_method(deprecated_in((2, 6, 0)))
407
438
    def verbose_expired_key_message(self, result, repo):
408
439
        """takes a verify result and returns list of expired key info"""
409
 
        return verbose_expired_key_message(result, repo)
 
440
        signers = {}
 
441
        fingerprint_to_authors = {}
 
442
        for rev_id, validity, fingerprint in result:
 
443
            if validity == SIGNATURE_EXPIRED:
 
444
                revision = repo.get_revision(rev_id)
 
445
                authors = ', '.join(revision.get_apparent_authors())
 
446
                signers.setdefault(fingerprint, 0)
 
447
                signers[fingerprint] += 1
 
448
                fingerprint_to_authors[fingerprint] = authors
 
449
        result = []
 
450
        for fingerprint, number in signers.items():
 
451
            result.append(
 
452
                ngettext(u"{0} commit by author {1} with key {2} now expired",
 
453
                         u"{0} commits by author {1} with key {2} now expired",
 
454
                         number).format(
 
455
                    number, fingerprint_to_authors[fingerprint], fingerprint) )
 
456
        return result
410
457
 
411
 
    @deprecated_method(deprecated_in((2, 6, 0)))
412
458
    def valid_commits_message(self, count):
413
459
        """returns message for number of commits"""
414
 
        return valid_commits_message(count)
 
460
        return gettext(u"{0} commits with valid signatures").format(
 
461
                                        count[SIGNATURE_VALID])
415
462
 
416
 
    @deprecated_method(deprecated_in((2, 6, 0)))
417
463
    def unknown_key_message(self, count):
418
464
        """returns message for number of commits"""
419
 
        return unknown_key_message(count)
 
465
        return ngettext(u"{0} commit with unknown key",
 
466
                        u"{0} commits with unknown keys",
 
467
                        count[SIGNATURE_KEY_MISSING]).format(
 
468
                                        count[SIGNATURE_KEY_MISSING])
420
469
 
421
 
    @deprecated_method(deprecated_in((2, 6, 0)))
422
470
    def commit_not_valid_message(self, count):
423
471
        """returns message for number of commits"""
424
 
        return commit_not_valid_message(count)
 
472
        return ngettext(u"{0} commit not valid",
 
473
                        u"{0} commits not valid",
 
474
                        count[SIGNATURE_NOT_VALID]).format(
 
475
                                            count[SIGNATURE_NOT_VALID])
425
476
 
426
 
    @deprecated_method(deprecated_in((2, 6, 0)))
427
477
    def commit_not_signed_message(self, count):
428
478
        """returns message for number of commits"""
429
 
        return commit_not_signed_message(count)
 
479
        return ngettext(u"{0} commit not signed",
 
480
                        u"{0} commits not signed",
 
481
                        count[SIGNATURE_NOT_SIGNED]).format(
 
482
                                        count[SIGNATURE_NOT_SIGNED])
430
483
 
431
 
    @deprecated_method(deprecated_in((2, 6, 0)))
432
484
    def expired_commit_message(self, count):
433
485
        """returns message for number of commits"""
434
 
        return expired_commit_message(count)
435
 
 
436
 
 
437
 
def valid_commits_message(count):
438
 
    """returns message for number of commits"""
439
 
    return gettext(u"{0} commits with valid signatures").format(
440
 
                                    count[SIGNATURE_VALID])
441
 
 
442
 
 
443
 
def unknown_key_message(count):
444
 
    """returns message for number of commits"""
445
 
    return ngettext(u"{0} commit with unknown key",
446
 
                    u"{0} commits with unknown keys",
447
 
                    count[SIGNATURE_KEY_MISSING]).format(
448
 
                                    count[SIGNATURE_KEY_MISSING])
449
 
 
450
 
 
451
 
def commit_not_valid_message(count):
452
 
    """returns message for number of commits"""
453
 
    return ngettext(u"{0} commit not valid",
454
 
                    u"{0} commits not valid",
455
 
                    count[SIGNATURE_NOT_VALID]).format(
456
 
                                        count[SIGNATURE_NOT_VALID])
457
 
 
458
 
 
459
 
def commit_not_signed_message(count):
460
 
    """returns message for number of commits"""
461
 
    return ngettext(u"{0} commit not signed",
462
 
                    u"{0} commits not signed",
463
 
                    count[SIGNATURE_NOT_SIGNED]).format(
464
 
                                    count[SIGNATURE_NOT_SIGNED])
465
 
 
466
 
 
467
 
def expired_commit_message(count):
468
 
    """returns message for number of commits"""
469
 
    return ngettext(u"{0} commit with key now expired",
470
 
                    u"{0} commits with key now expired",
471
 
                    count[SIGNATURE_EXPIRED]).format(
472
 
                                count[SIGNATURE_EXPIRED])
473
 
 
474
 
 
475
 
def verbose_expired_key_message(result, repo):
476
 
    """takes a verify result and returns list of expired key info"""
477
 
    signers = {}
478
 
    fingerprint_to_authors = {}
479
 
    for rev_id, validity, fingerprint in result:
480
 
        if validity == SIGNATURE_EXPIRED:
481
 
            revision = repo.get_revision(rev_id)
482
 
            authors = ', '.join(revision.get_apparent_authors())
483
 
            signers.setdefault(fingerprint, 0)
484
 
            signers[fingerprint] += 1
485
 
            fingerprint_to_authors[fingerprint] = authors
486
 
    result = []
487
 
    for fingerprint, number in signers.items():
488
 
        result.append(
489
 
            ngettext(u"{0} commit by author {1} with key {2} now expired",
490
 
                     u"{0} commits by author {1} with key {2} now expired",
491
 
                     number).format(
492
 
                number, fingerprint_to_authors[fingerprint], fingerprint))
493
 
    return result
494
 
 
495
 
 
496
 
def verbose_valid_message(result):
497
 
    """takes a verify result and returns list of signed commits strings"""
498
 
    signers = {}
499
 
    for rev_id, validity, uid in result:
500
 
        if validity == SIGNATURE_VALID:
501
 
            signers.setdefault(uid, 0)
502
 
            signers[uid] += 1
503
 
    result = []
504
 
    for uid, number in signers.items():
505
 
         result.append(ngettext(u"{0} signed {1} commit",
506
 
                                u"{0} signed {1} commits",
507
 
                                number).format(uid, number))
508
 
    return result
509
 
 
510
 
 
511
 
def verbose_not_valid_message(result, repo):
512
 
    """takes a verify result and returns list of not valid commit info"""
513
 
    signers = {}
514
 
    for rev_id, validity, empty in result:
515
 
        if validity == SIGNATURE_NOT_VALID:
516
 
            revision = repo.get_revision(rev_id)
517
 
            authors = ', '.join(revision.get_apparent_authors())
518
 
            signers.setdefault(authors, 0)
519
 
            signers[authors] += 1
520
 
    result = []
521
 
    for authors, number in signers.items():
522
 
        result.append(ngettext(u"{0} commit by author {1}",
523
 
                               u"{0} commits by author {1}",
524
 
                               number).format(number, authors))
525
 
    return result
526
 
 
527
 
 
528
 
def verbose_not_signed_message(result, repo):
529
 
    """takes a verify result and returns list of not signed commit info"""
530
 
    signers = {}
531
 
    for rev_id, validity, empty in result:
532
 
        if validity == SIGNATURE_NOT_SIGNED:
533
 
            revision = repo.get_revision(rev_id)
534
 
            authors = ', '.join(revision.get_apparent_authors())
535
 
            signers.setdefault(authors, 0)
536
 
            signers[authors] += 1
537
 
    result = []
538
 
    for authors, number in signers.items():
539
 
        result.append(ngettext(u"{0} commit by author {1}",
540
 
                               u"{0} commits by author {1}",
541
 
                               number).format(number, authors))
542
 
    return result
543
 
 
544
 
 
545
 
def verbose_missing_key_message(result):
546
 
    """takes a verify result and returns list of missing key info"""
547
 
    signers = {}
548
 
    for rev_id, validity, fingerprint in result:
549
 
        if validity == SIGNATURE_KEY_MISSING:
550
 
            signers.setdefault(fingerprint, 0)
551
 
            signers[fingerprint] += 1
552
 
    result = []
553
 
    for fingerprint, number in signers.items():
554
 
        result.append(ngettext(u"Unknown key {0} signed {1} commit",
555
 
                               u"Unknown key {0} signed {1} commits",
556
 
                               number).format(fingerprint, number))
557
 
    return result
 
486
        return ngettext(u"{0} commit with key now expired",
 
487
                        u"{0} commits with key now expired",
 
488
                        count[SIGNATURE_EXPIRED]).format(
 
489
                                    count[SIGNATURE_EXPIRED])