def test_verify_expired_but_valid(self): self.requireFeature(features.gpgme) self.import_keys() content = """-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 bazaar-ng testament short form 1 revision-id: [email protected] sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iJwEAQECAAYFAk42esUACgkQHOJve0+NFRPc5wP7BoZkzBU8JaHMLv/LmqLr0sUz zuE51ofZZ19L7KVtQWsOi4jFy0fi4A5TFwO8u9SOfoREGvkw292Uty9subSouK5/ mFmDOYPQ+O83zWgYZsBmMJWYDZ+X9I6XXZSbPtV/7XyTjaxtl5uRnDVJjg+AzKvD dTp8VatVVrwuvzOPDVc= =uHen -----END PGP SIGNATURE----- """ plain = """bazaar-ng testament short form 1 revision-id: [email protected] sha1: 59ab434be4c2d5d646dee84f514aa09e1b72feeb """ my_gpg = gpg.GPGStrategy(FakeConfig()) self.assertEqual((gpg.SIGNATURE_EXPIRED, u'4F8D1513'), my_gpg.verify(content, plain))
def test_signing_command_line_from_email(self): # Not setting gpg_signing_key will use the mail part of 'email' my_gpg = gpg.GPGStrategy(FakeConfig(''' email=Amy <*****@*****.**> gpg_signing_command=false''')) self.assertEqual(['false', '--clearsign', '-u', '*****@*****.**'], my_gpg._command_line())
def test_set_acceptable_keys(self): self.requireFeature(features.gpgme) self.import_keys() my_gpg = gpg.GPGStrategy(FakeConfig()) my_gpg.set_acceptable_keys("*****@*****.**") self.assertEqual(my_gpg.acceptable_keys, [u'B5DEED5FCB15DAE6ECEF919587681B1EE3080E45'])
def test_verify_bad_testament(self): self.requireFeature(features.gpgme) self.import_keys() content = """-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 bazaar-ng testament short form 1 revision-id: [email protected] sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAEBAgAGBQJN+ekFAAoJEIdoGx7jCA5FGtEH/i+XxJRvqU6wdBtLVrGBMAGk FZ5VP+KyXYtymSbgSstj/vM12NeMIeFs3xGnNnYuX1MIcY6We5TKtCH0epY6ym5+ 6g2Q2QpQ5/sT2d0mWzR0K4uVngmxVQaXTdk5PdZ40O7ULeDLW6CxzxMHyUL1rsIx 7UBUTBh1O/1n3ZfD99hUkm3hVcnsN90uTKH59zV9NWwArU0cug60+5eDKJhSJDbG rIwlqbFAjDZ7L/48e+IaYIJwBZFzMBpJKdCxzALLtauMf+KK8hGiL2hrRbWm7ty6 NgxfkMYOB4rDPdSstT35N+5uBG3n/UzjxHssi0svMfVETYYX40y57dm2eZQXFp8= =iwsn -----END PGP SIGNATURE----- """ plain = """bazaar-ng testament short form 1 revision-id: [email protected] sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 """ my_gpg = gpg.GPGStrategy(FakeConfig()) my_gpg.set_acceptable_keys("*****@*****.**") self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, plain))
def to_signed(self, branch): """Serialize as a signed string. :param branch: The source branch, to get the signing strategy :return: a string """ my_gpg = gpg.GPGStrategy(branch.get_config()) return my_gpg.sign(''.join(self.to_lines()))
def test_set_acceptable_keys_unknown(self): self.requireFeature(features.gpgme) my_gpg = gpg.GPGStrategy(FakeConfig()) self.notes = [] def note(*args): self.notes.append(args[0] % args[1:]) self.overrideAttr(trace, 'note', note) my_gpg.set_acceptable_keys("unknown") self.assertEqual(my_gpg.acceptable_keys, []) self.assertEqual(self.notes, ['No GnuPG key results for pattern: unknown'])
def run(self, location=None, committer=None, dry_run=False): if location is None: bzrdir = controldir.ControlDir.open_containing('.')[0] else: # Passed in locations should be exact bzrdir = controldir.ControlDir.open(location) branch = bzrdir.open_branch() repo = branch.repository branch_config = branch.get_config_stack() if committer is None: committer = branch_config.get('email') gpg_strategy = gpg.GPGStrategy(branch_config) count = 0 repo.lock_write() try: graph = repo.get_graph() repo.start_write_group() try: for rev_id, parents in graph.iter_ancestry( [branch.last_revision()]): if _mod_revision.is_null(rev_id): continue if parents is None: # Ignore ghosts continue if repo.has_signature_for_revision_id(rev_id): continue rev = repo.get_revision(rev_id) if rev.committer != committer: continue # We have a revision without a signature who has a # matching committer, start signing self.outf.write("%s\n" % rev_id) count += 1 if not dry_run: repo.sign_revision(rev_id, gpg_strategy) except: repo.abort_write_group() raise else: repo.commit_write_group() finally: repo.unlock() self.outf.write( ngettext('Signed %d revision.\n', 'Signed %d revisions.\n', count) % count)
def assertProduces(self, content): # This needs a 'cat' command or similar to work. my_gpg = gpg.GPGStrategy(FakeConfig()) if sys.platform == 'win32': # Windows doesn't come with cat, and we don't require it # so lets try using python instead. # But stupid windows and line-ending conversions. # It is too much work to make sys.stdout be in binary mode. # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443 my_gpg._command_line = lambda: [ sys.executable, '-c', 'import sys; sys.stdout.write(sys.stdin.read())' ] new_content = content.replace('\n', '\r\n') self.assertEqual(new_content, my_gpg.sign(content)) else: my_gpg._command_line = lambda: ['cat', '-'] self.assertEqual(content, my_gpg.sign(content))
def test_verify_unknown_key(self): self.requireFeature(features.gpgme) self.import_keys() content = """-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 asdf -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAEBAgAGBQJOORKwAAoJENf6AkFdUeVvJDYH/1Cz+AJn1Jvy5n64o+0fZ5Ow Y7UQb4QQTIOV7jI7n4hv/yBzuHrtImFzYvQl/o2Ezzi8B8L5gZtQy+xCUF+Q8iWs gytZ5JUtSze7hDZo1NUl4etjoRGYqRfrUcvE2LkVH2dFbDGyyQfVmoeSHa5akuuP QZmyg2F983rACVIpGvsqTH6RcBdvE9vx68lugeKQA8ArDn39/74FBFipFzrXSPij eKFpl+yZmIb3g6HkPIC8o4j/tMvc37xF1OG5sBu8FT0+FC+VgY7vAblneDftAbyP sIODx4WcfJtjLG/qkRYqJ4gDHo0eMpTJSk2CWebajdm4b+JBrM1F9mgKuZFLruE= =RNR5 -----END PGP SIGNATURE----- """ plain = "asdf\n" my_gpg = gpg.GPGStrategy(FakeConfig()) self.assertEqual((gpg.SIGNATURE_KEY_MISSING, u'5D51E56F'), my_gpg.verify(content, plain))
def test_verify_revoked_signature(self): self.requireFeature(features.gpgme) self.import_keys() content = """-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 asdf -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iJwEAQECAAYFAk45V18ACgkQjs6dvEpb0cSIZQP/eOGTXGPlrNwvDkcX2d8O///I ecB4sUIUEpv1XAk1MkNu58lsjjK72lRaLusEGqd7HwrFmpxVeVs0oWLg23PNPCFs yJBID9ma+VxFVPtkEFnrc1R72sBJLfBcTxMkwVTC8eeznjdtn+cg+aLkxbPdrGnr JFA6kUIJU2w9LU/b88Y= =UuRX -----END PGP SIGNATURE----- """ plain = """asdf\n""" my_gpg = gpg.GPGStrategy(FakeConfig()) my_gpg.set_acceptable_keys("*****@*****.**") self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, plain))
def test_verify_invalid(self): self.requireFeature(features.gpgme) self.import_keys() content = """-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 bazaar-ng testament short form 1 revision-id: [email protected] sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iEYEARECAAYFAk33gYsACgkQpQbm1N1NUIhiDACglOuQDlnSF4NxfHSkN/zrmFy8 nswAoNGXAVuR9ONasAKIGBNUE0b+lols =SOuC -----END PGP SIGNATURE----- """ plain = """bazaar-ng testament short form 1 revision-id: [email protected] sha1: 6411f9bdf6571200357140c9ce7c0f50106ac9a4 """ my_gpg = gpg.GPGStrategy(FakeConfig()) self.assertEqual((gpg.SIGNATURE_NOT_VALID, None), my_gpg.verify(content, plain))
def run(self, acceptable_keys=None, revision=None, verbose=None, location=u'.'): bzrdir = controldir.ControlDir.open_containing(location)[0] branch = bzrdir.open_branch() repo = branch.repository branch_config = branch.get_config_stack() gpg_strategy = gpg.GPGStrategy(branch_config) gpg_strategy.set_acceptable_keys(acceptable_keys) def write(string): self.outf.write(string + "\n") def write_verbose(string): self.outf.write(" " + string + "\n") self.add_cleanup(repo.lock_read().unlock) #get our list of revisions revisions = [] if revision is not None: if len(revision) == 1: revno, rev_id = revision[0].in_history(branch) revisions.append(rev_id) elif len(revision) == 2: from_revno, from_revid = revision[0].in_history(branch) to_revno, to_revid = revision[1].in_history(branch) if to_revid is None: to_revno = branch.revno() if from_revno is None or to_revno is None: raise errors.BzrCommandError( gettext( 'Cannot verify a range of non-revision-history revisions' )) for revno in range(from_revno, to_revno + 1): revisions.append(branch.get_rev_id(revno)) else: #all revisions by default including merges graph = repo.get_graph() revisions = [] for rev_id, parents in graph.iter_ancestry( [branch.last_revision()]): if _mod_revision.is_null(rev_id): continue if parents is None: # Ignore ghosts continue revisions.append(rev_id) count, result, all_verifiable = gpg.bulk_verify_signatures( repo, revisions, gpg_strategy) if all_verifiable: write(gettext("All commits signed with verifiable keys")) if verbose: for message in gpg.verbose_valid_message(result): write_verbose(message) return 0 else: write(gpg.valid_commits_message(count)) if verbose: for message in gpg.verbose_valid_message(result): write_verbose(message) write(gpg.expired_commit_message(count)) if verbose: for message in gpg.verbose_expired_key_message(result, repo): write_verbose(message) write(gpg.unknown_key_message(count)) if verbose: for message in gpg.verbose_missing_key_message(result): write_verbose(message) write(gpg.commit_not_valid_message(count)) if verbose: for message in gpg.verbose_not_valid_message(result, repo): write_verbose(message) write(gpg.commit_not_signed_message(count)) if verbose: for message in gpg.verbose_not_signed_message(result, repo): write_verbose(message) return 1
def test_checks_return_code(self): # This test needs a unix like platform - one with 'false' to run. # if you have one, please make this work :) my_gpg = gpg.GPGStrategy(FakeConfig()) self.assertRaises(errors.SigningFailed, my_gpg.sign, 'content')
def test_signing_command_line(self): my_gpg = gpg.GPGStrategy(FakeConfig()) self.assertEqual(['false', '--clearsign'], my_gpg._command_line())
def refresh_view(self): """get the revisions wanted by the user, do the verifications and popular the tree widget with the results""" self.throbber.show() bzrdir = _mod_bzrdir.BzrDir.open_containing(self.location)[0] branch = bzrdir.open_branch() repo = branch.repository branch_config = branch.get_config() gpg_strategy = gpg.GPGStrategy(branch_config) gpg_strategy.set_acceptable_keys(self.acceptable_keys) if branch.name is None: header = branch.user_url else: header = branch.name self.ui.treeWidget.setHeaderLabels([str(header)]) #get our list of revisions revisions = [] if self.revision is not None: if len(self.revision) == 1: revno, rev_id = self.revision[0].in_history(branch) revisions.append(rev_id) elif len(sel.revision) == 2: from_revno, from_revid = self.revision[0].in_history(branch) to_revno, to_revid = self.revision[1].in_history(branch) if to_revid is None: to_revno = branch.revno() if from_revno is None or to_revno is None: raise errors.BzrCommandError('Cannot verify a range of '\ 'non-revision-history revisions') for revno in range(from_revno, to_revno + 1): revisions.append(branch.get_rev_id(revno)) else: #all revisions by default including merges graph = repo.get_graph() revisions = [] repo.lock_read() for rev_id, parents in graph.iter_ancestry( [branch.last_revision()]): if _mod_revision.is_null(rev_id): continue if parents is None: # Ignore ghosts continue revisions.append(rev_id) repo.unlock() count, result, all_verifiable =\ gpg_strategy.do_verifications(revisions, repo, QApplication.processEvents) if all_verifiable: message = QTreeWidgetItem( [gettext("All commits signed with verifiable keys")]) self.ui.treeWidget.addTopLevelItem(message) for verbose_message in gpg_strategy.verbose_valid_message(result): QTreeWidgetItem(message, [verbose_message]) else: valid_commit_message = QTreeWidgetItem( [gpg_strategy.valid_commits_message(count)]) self.ui.treeWidget.addTopLevelItem(valid_commit_message) for verbose_message in gpg_strategy.verbose_valid_message(result): QTreeWidgetItem(valid_commit_message, [verbose_message]) expired_key_message = QTreeWidgetItem( [gpg_strategy.expired_commit_message(count)]) self.ui.treeWidget.addTopLevelItem(expired_key_message) for verbose_message in \ gpg_strategy.verbose_expired_key_message(result, repo): QTreeWidgetItem(expired_key_message, [verbose_message]) unknown_key_message = QTreeWidgetItem( [gpg_strategy.unknown_key_message(count)]) self.ui.treeWidget.addTopLevelItem(unknown_key_message) for verbose_message in gpg_strategy.verbose_missing_key_message( result): QTreeWidgetItem(unknown_key_message, [verbose_message]) commit_not_valid_message = QTreeWidgetItem( [gpg_strategy.commit_not_valid_message(count)]) self.ui.treeWidget.addTopLevelItem(commit_not_valid_message) for verbose_message in gpg_strategy.verbose_not_valid_message( result, repo): QTreeWidgetItem(commit_not_valid_message, [verbose_message]) commit_not_signed_message = QTreeWidgetItem( [gpg_strategy.commit_not_signed_message(count)]) self.ui.treeWidget.addTopLevelItem(commit_not_signed_message) for verbose_message in gpg_strategy.verbose_not_signed_message( result, repo): QTreeWidgetItem(commit_not_signed_message, [verbose_message]) self.throbber.hide()
def setUp(self): super(TestCommandLine, self).setUp() self.my_gpg = gpg.GPGStrategy(FakeConfig())