pygpgme-0.3/0000775000175000017500000000000011726117114013247 5ustar jamesjames00000000000000pygpgme-0.3/setup.py0000755000175000017500000000271711724067625015002 0ustar jamesjames00000000000000#!/usr/bin/env python """A Python module for working with OpenPGP messages PyGPGME is a Python module that lets you sign, verify, encrypt and decrypt messages using the OpenPGP format. It is built on top of the GNU Privacy Guard and the GPGME library. """ from distutils.core import setup, Extension gpgme = Extension( 'gpgme._gpgme', ['src/gpgme.c', 'src/pygpgme-error.c', 'src/pygpgme-data.c', 'src/pygpgme-context.c', 'src/pygpgme-key.c', 'src/pygpgme-signature.c', 'src/pygpgme-import.c', 'src/pygpgme-keyiter.c', 'src/pygpgme-constants.c', 'src/pygpgme-genkey.c', ], libraries=['gpgme']) description, long_description = __doc__.split("\n\n", 1) setup(name='pygpgme', version='0.3', author='James Henstridge', author_email='james@jamesh.id.au', description=description, long_description=long_description, license='LGPL', classifiers=[ 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'Operating System :: POSIX', 'Programming Language :: C', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Security :: Cryptography', 'Topic :: Software Development :: Libraries :: Python Modules' ], url='https://launchpad.net/pygpgme', ext_modules=[gpgme], packages=['gpgme']) pygpgme-0.3/NEWS0000664000175000017500000000157511726116655013767 0ustar jamesjames00000000000000pygpgme-0.3: 2012-03-08 * Add support for Python 3 (tested with Python 3.2). Data being encrypted, decrypted, signed or verified is treated as bytes, while textual data (including textual representations of binary data like key IDs) uses the string/unicode type. * The test suite has been moved to the toplevel and is no longer installed with the extension. * The examples directory is now included in tarball releases. pygpgme-0.2: 2011-08-17 * Update the code base to work with newer versions of GPGME * Update extension code to make it easier to port to Python 3 (this version still doesn't support Python 3). In general, this involves making sure we return Unicode strings for textual data and byte strings for binary data. * Add support for the genkey API. * Add support for symmetric encryption in encrypt(). pygpgme-0.1: 2006-03-27 * Initial Release. pygpgme-0.3/Makefile0000644000175000017500000000035311622631741014710 0ustar jamesjames00000000000000PYTHON = python build: $(PYTHON) setup.py build_ext -i check: build GPG_AGENT_INFO= $(PYTHON) test_all.py -v clean: $(PYTHON) setup.py clean dist: build $(PYTHON) setup.py sdist --force-manifest .PHONY: build check clean dist pygpgme-0.3/tests/0000775000175000017500000000000011726117114014411 5ustar jamesjames00000000000000pygpgme-0.3/tests/test_export.py0000644000175000017500000000402611724064241017343 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO from textwrap import dedent import gpgme from tests.util import GpgHomeTestCase class ExportTestCase(GpgHomeTestCase): import_keys = ['signonly.pub', 'signonly.sec'] def test_export_by_fingerprint(self): ctx = gpgme.Context() ctx.armor = True keydata = BytesIO() ctx.export('15E7CE9BF1771A4ABC550B31F540A569CB935A42', keydata) self.assertTrue(keydata.getvalue().startswith( b'-----BEGIN PGP PUBLIC KEY BLOCK-----\n')) def test_export_by_email(self): ctx = gpgme.Context() ctx.armor = True keydata = BytesIO() ctx.export('signonly@example.org', keydata) self.assertTrue(keydata.getvalue().startswith( b'-----BEGIN PGP PUBLIC KEY BLOCK-----\n')) def test_export_by_name(self): ctx = gpgme.Context() ctx.armor = True keydata = BytesIO() ctx.export('Sign Only', keydata) self.assertTrue(keydata.getvalue().startswith( b'-----BEGIN PGP PUBLIC KEY BLOCK-----\n')) def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_progress.py0000644000175000017500000000370211723067052017670 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import os try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO from textwrap import dedent import gpgme from tests.util import GpgHomeTestCase class ProgressTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key1.sec'] def progress_cb(self, what, type_, current, total): self.progress_cb_called = True def test_sign_with_progress_cb(self): ctx = gpgme.Context() key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] ctx.progress_cb = self.progress_cb plaintext = BytesIO(b'Hello World\n') signature = BytesIO() self.progress_cb_called = False new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) # ensure that progress_cb has been run self.assertEqual(self.progress_cb_called, True) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_CLEAR) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_delete.py0000644000175000017500000000442711723067677017310 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import gpgme from tests.util import GpgHomeTestCase class DeleteTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key1.sec', 'key2.pub'] def test_delete_public_key(self): ctx = gpgme.Context() # key2 key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.delete(key) # check that it is deleted self.assertRaises(gpgme.GpgmeError, ctx.get_key, '93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') def test_delete_public_key_with_secret_key(self): ctx = gpgme.Context() # key1 key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertRaises(gpgme.GpgmeError, ctx.delete, key) def test_delete_secret_key(self): ctx = gpgme.Context() # key1 key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.delete(key, True) def test_delete_non_existant(self): ctx = gpgme.Context() # key2 key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.delete(key) # delete it again try: ctx.delete(key) except gpgme.GpgmeError as exc: self.assertEqual(exc.args[0], gpgme.ERR_SOURCE_GPGME) self.assertEqual(exc.args[1], gpgme.ERR_NO_PUBKEY) else: self.fail('gpgme.GpgmeError was not raised') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_genkey.py0000644000175000017500000000741111724065605017312 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO import gpgme from tests.util import GpgHomeTestCase # See /usr/share/doc/gnupg/DETAILS.gz # XXX we are using a passwordless key because the passphrase_cb # backend seems to be currently broken. signing_only_param = """ Key-Type: RSA Key-Usage: sign Key-Length: 1024 Name-Real: Testing Name-Comment: comment Name-Email: someone@example.com Expire-Date: 0 """ class GenerateKeyTestCase(GpgHomeTestCase): def assertCanSign(self, key): """Check that the given key can be used to create signatures.""" ctx = gpgme.Context() ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() ctx.armor = True new_sigs = ctx.sign( plaintext, signature, gpgme.SIG_MODE_DETACH) signature.seek(0) plaintext.seek(0) sigs = ctx.verify(signature, plaintext, None) self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].fpr, key.subkeys[0].fpr) def _test_generate_signing_only_keys(self): ctx = gpgme.Context() result = ctx.genkey(signing_only_param) self.assertEqual(result.primary, True) self.assertEqual(result.sub, False) self.assertEqual(len(result.fpr), 40) # The generated key is part of the current keyring. key = ctx.get_key(result.fpr, True) self.assertEqual(key.revoked, False) self.assertEqual(key.expired, False) self.assertEqual(key.secret, True) self.assertEqual(key.protocol, gpgme.PROTOCOL_OpenPGP) # Single signing-only RSA key. self.assertEqual(len(key.subkeys), 1) subkey = key.subkeys[0] self.assertEqual(subkey.secret, True) self.assertEqual(subkey.pubkey_algo, gpgme.PK_RSA) self.assertEqual(subkey.length, 1024) self.assertEqual(key.can_sign, True) self.assertEqual(key.can_encrypt, False) # The only UID available matches the given parameters. [uid] = key.uids self.assertEqual(uid.name, 'Testing') self.assertEqual(uid.comment, 'comment') self.assertEqual(uid.email, 'someone@example.com') # Finally check if the generated key can perform signatures. self.assertCanSign(key) def test_invalid_parameters(self): ctx = gpgme.Context() try: ctx.genkey('garbage parameters') except gpgme.GpgmeError as exc: self.assertTrue(hasattr(exc, "result")) result = exc.result self.assertEqual(result.primary, False) self.assertEqual(result.sub, False) self.assertEqual(result.fpr, None) else: self.fail("GpgmeError not raised") def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) if __name__ == '__main__': unittest.main() pygpgme-0.3/tests/test_sign_verify.py0000644000175000017500000003174111723313360020350 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO from textwrap import dedent import gpgme from tests.util import GpgHomeTestCase class SignVerifyTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key1.sec', 'key2.pub', 'key2.sec', 'signonly.pub', 'signonly.sec'] def test_verify_normal(self): signature = BytesIO(dedent(''' -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.1 (GNU/Linux) owGbwMvMwCTotjv0Q0dM6hLG00JJDM7nNx31SM3JyVcIzy/KSeHqsGdmBQvCVAky pR9hmGfw0qo3bfpWZwun5euYAsUcVkyZMJlhfvkU6UBjD8WF9RfeND05zC/TK+H+ EQA= =HCW0 -----END PGP MESSAGE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137685189) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_verify_detached(self): signature = BytesIO(dedent(''' -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQBDz7ReRrtV8IhcZaQRAtuUAJwMiJeS5QPohToxA3+vp+z5c3jr1wCdHhGP hhSTiguzgSYNwKSuV6SLGOM= =dyZS -----END PGP SIGNATURE----- ''').encode('ASCII')) signed_text = BytesIO(b'Hello World\n') ctx = gpgme.Context() sigs = ctx.verify(signature, signed_text, None) self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137685598) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_verify_clearsign(self): signature = BytesIO(dedent(''' -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello World -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDz7DiRrtV8IhcZaQRAjuYAJ43/NhhNHx+gzGBUqtIK5LpENTCGgCfV3aO ZTFlGRyKN26HccsC6ZWcPUQ= =kZ2c -----END PGP SIGNATURE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137684706) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_verify_multiple_sigs(self): signature = BytesIO(dedent(''' -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello World -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDz7V9RrtV8IhcZaQRAia/AJ9eC/Q3pssWW9PWckQ3+1kbiIiEVQCfSeFv 7SlUCFJOs/sfl+EtaOafgQGJAhUDBQFDz7V9LPRrf8l+aw8BAia/EAClI1X/hL38 6NeOnMD6zXNm7r20Qkpp7PT63PqUa9dU1P+Ha2Uju5C2jBVYouDOpHnEsw3AqItl M0y6xiBAbXbdv0K2OdX8/290g/uODQE/oRGu+YtIh8HcY9N1JmzYw6msRO1LD/Oo xVqfyJiPx+Ol3juAuVqggBzQQmhQpZ7MfHcZSIWxYtRZNlCGYp2lUVae7fJlrJc8 DvTkGSkdqBRoDqy0rKcdXRuExXyq081m7bli2sMvImejmEsqyMcbZrkW69v+/BQD Tki8tEkxINw1YHhcBDI0KAn3SuynY+i132oU2qJWQF3ZBRqEbD0IxfakPSZyhJKj sxk38VHgA+5r/QKRs+4n3z09yFqNIWpnvVVZ2iMfKhHtKd1nNq6tOzHiQrmdSdyK dwRaRm4Zt0hWT8v+CXX/RPK5xGL3FCZQs7VTO0ANHR7cIS+v3ChaHO6naQSBQMrW 7l69hTh009LFIKlYJ+7ZBS2pySkvHmEzJKl4Ko4UfOeD2xDsq5nHhi/AJ7TXtHCo TLo8OwJvfiW6Fa9zzu6IkerhQlZrvbLOkmBpuyFo0UEuM/89bquaZ3GoEj3hePsZ nD9LtsgsjkFV1jZQ4n/wM3jolo0aA4+ZEBCgw9XJUSZ67m+jvFNBvZtDqWnbQWxe FsW3EQWNlQnwkn2lic51Cdp3w7yPH5CKfw== =0A7N -----END PGP SIGNATURE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 2) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1137685885) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) self.assertEqual(sigs[1].summary, 0) self.assertEqual(sigs[1].fpr, '93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') self.assertEqual(sigs[1].status, None) self.assertEqual(sigs[1].notations, []) self.assertEqual(sigs[1].timestamp, 1137685885) self.assertEqual(sigs[1].exp_timestamp, 0) self.assertEqual(sigs[1].wrong_key_usage, False) self.assertEqual(sigs[1].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[1].validity_reason, None) def test_verify_no_signature(self): signature = BytesIO(dedent(''' -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello World -----BEGIN PGP SIGNATURE----- -----END PGP SIGNATURE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'') self.assertEqual(len(sigs), 0) def test_verify_bad_signature(self): signature = BytesIO(dedent(''' -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello World -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iNhhNHx+gzGBUqtIK5LpENTCGgCfV3aO -----END PGP SIGNATURE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() try: ctx.verify(signature, None, plaintext) except gpgme.GpgmeError as exc: self.assertEqual(exc.args[0], gpgme.ERR_SOURCE_GPGME) self.assertEqual(exc.args[1], gpgme.ERR_NO_DATA) else: self.fail('gpgme.GpgmeError not raised') def test_sign_normal(self): ctx = gpgme.Context() ctx.armor = False key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_NORMAL) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_NORMAL) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # now verify the signature signature.seek(0) plaintext = BytesIO() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_sign_normal_armor(self): ctx = gpgme.Context() ctx.armor = True key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_NORMAL) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_NORMAL) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # now verify the signature signature.seek(0) plaintext = BytesIO() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_sign_detatch(self): ctx = gpgme.Context() ctx.armor = True key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_DETACH) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_DETACH) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # now verify the signature signature.seek(0) plaintext.seek(0) sigs = ctx.verify(signature, plaintext, None) self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_sign_clearsign(self): ctx = gpgme.Context() ctx.armor = True key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_CLEAR) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # now verify the signature signature.seek(0) plaintext = BytesIO() sigs = ctx.verify(signature, None, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_editkey.py0000644000175000017500000000650011723312713017456 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import os try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO import gpgme import gpgme.editutil from tests.util import GpgHomeTestCase class EditKeyTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key1.sec', 'key2.pub', 'signonly.pub', 'signonly.sec'] def edit_quit_cb(self, status, args, fd): if status in [gpgme.STATUS_EOF, gpgme.STATUS_GOT_IT]: return self.status = status self.args = args os.write(fd, b'quit\n') def test_edit_quit(self): ctx = gpgme.Context() key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') output = BytesIO() self.status = None self.args = None ctx.edit(key, self.edit_quit_cb, output) self.assertEqual(self.status, gpgme.STATUS_GET_LINE) self.assertEqual(self.args, 'keyedit.prompt') def test_edit_ownertrust(self): ctx = gpgme.Context() key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') self.assertEqual(key.owner_trust, gpgme.VALIDITY_UNKNOWN) # try setting each validity: for trust in [gpgme.VALIDITY_NEVER, gpgme.VALIDITY_MARGINAL, gpgme.VALIDITY_FULL, gpgme.VALIDITY_ULTIMATE]: gpgme.editutil.edit_trust(ctx, key, trust) key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') self.assertEqual(key.owner_trust, trust) def test_edit_sign(self): ctx = gpgme.Context() # we set the keylist mode so we can see signatures ctx.keylist_mode = gpgme.KEYLIST_MODE_SIGS ctx.signers = [ctx.get_key('15E7CE9BF1771A4ABC550B31F540A569CB935A42')] key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # check that there are no signatures from 0xCB935A42 for uid in key.uids: sigs = [sig for sig in uid.signatures if sig.keyid == 'F540A569CB935A42'] self.assertEqual(len(sigs), 0) gpgme.editutil.edit_sign(ctx, key, check=0) key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # check that there is a signature from 0xCB935A42 on each UID for uid in key.uids: sigs = [sig for sig in uid.signatures if sig.keyid == 'F540A569CB935A42'] self.assertEqual(len(sigs), 1) def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_context.py0000644000175000017500000001243211724044660017511 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os import unittest import gpgme from tests.util import GpgHomeTestCase class ContextTestCase(GpgHomeTestCase): def test_constructor(self): ctx = gpgme.Context() def test_protocol(self): ctx = gpgme.Context() # XXX: this should use symbolic constant names self.assertEqual(ctx.protocol, gpgme.PROTOCOL_OpenPGP) ctx.protocol = gpgme.PROTOCOL_CMS self.assertEqual(ctx.protocol, gpgme.PROTOCOL_CMS) ctx.protocol = gpgme.PROTOCOL_OpenPGP self.assertEqual(ctx.protocol, gpgme.PROTOCOL_OpenPGP) # check error on setting to invalid protocol value def set_protocol(ctx, value): ctx.protocol = value self.assertRaises(gpgme.GpgmeError, set_protocol, ctx, 999) def del_protocol(ctx): del ctx.protocol self.assertRaises(AttributeError, del_protocol, ctx) def test_armor(self): ctx = gpgme.Context() self.assertEqual(ctx.armor, False) ctx.armor = True self.assertEqual(ctx.armor, True) ctx.armor = False self.assertEqual(ctx.armor, False) def del_armor(ctx): del ctx.armor self.assertRaises(AttributeError, del_armor, ctx) def test_textmode(self): ctx = gpgme.Context() self.assertEqual(ctx.textmode, False) ctx.textmode = True self.assertEqual(ctx.textmode, True) ctx.textmode = False self.assertEqual(ctx.textmode, False) def del_textmode(ctx): del ctx.textmode self.assertRaises(AttributeError, del_textmode, ctx) def test_include_certs(self): ctx = gpgme.Context() # XXX: 20060413 jamesh # gpgme 1.0.x and 1.1.x have different default values for # include_certs, so I am disabling this test for now. #self.assertEqual(ctx.include_certs, 1) ctx.include_certs = 2 self.assertEqual(ctx.include_certs, 2) def del_include_certs(ctx): del ctx.include_certs self.assertRaises(AttributeError, del_include_certs, ctx) def test_keylist_mode(self): ctx = gpgme.Context() self.assertEqual(ctx.keylist_mode, gpgme.KEYLIST_MODE_LOCAL) ctx.keylist_mode = gpgme.KEYLIST_MODE_EXTERN self.assertEqual(ctx.keylist_mode, gpgme.KEYLIST_MODE_EXTERN) ctx.keylist_mode = gpgme.KEYLIST_MODE_LOCAL | gpgme.KEYLIST_MODE_EXTERN self.assertEqual(ctx.keylist_mode, gpgme.KEYLIST_MODE_LOCAL | gpgme.KEYLIST_MODE_EXTERN) def del_keylist_mode(ctx): del ctx.keylist_mode self.assertRaises(AttributeError, del_keylist_mode, ctx) def test_passphrase_cb(self): ctx = gpgme.Context() def passphrase_cb(uid_hint, passphrase_info, prev_was_bad, fd): pass self.assertEqual(ctx.passphrase_cb, None) ctx.passphrase_cb = passphrase_cb self.assertEqual(ctx.passphrase_cb, passphrase_cb) ctx.passphrase_cb = None self.assertEqual(ctx.passphrase_cb, None) ctx.passphrase_cb = passphrase_cb del ctx.passphrase_cb self.assertEqual(ctx.passphrase_cb, None) def test_progress_cb(self): ctx = gpgme.Context() def progress_cb(what, type, current, total): pass self.assertEqual(ctx.progress_cb, None) ctx.progress_cb = progress_cb self.assertEqual(ctx.progress_cb, progress_cb) ctx.progress_cb = None self.assertEqual(ctx.progress_cb, None) ctx.progress_cb = progress_cb del ctx.progress_cb self.assertEqual(ctx.progress_cb, None) def test_set_engine_info(self): # Add a key using the default $GNUPGHOME based keyring. ctx = gpgme.Context() with self.keyfile('key1.pub') as fp: ctx.import_(fp) # If we set $GNUPGHOME to a dummy value, we can't read in the # keywe just loaded. os.environ['GNUPGHOME'] = '/no/such/dir' ctx = gpgme.Context() self.assertRaises(gpgme.GpgmeError, ctx.get_key, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # But if we configure the context using set_engine_info(), it # will find the key. ctx = gpgme.Context() ctx.set_engine_info(gpgme.PROTOCOL_OpenPGP, None, self._gpghome) key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertTrue(key) def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_keylist.py0000644000175000017500000000541311722717176017521 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import gpgme from tests.util import GpgHomeTestCase class KeylistTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key2.pub', 'revoked.pub', 'signonly.pub', 'key1.sec'] def test_listall(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist()) self.assertTrue(keyids, set(['46BB55F0885C65A4', '2CF46B7FC97E6B0F', 'F540A569CB935A42', '2EF658C987754368'])) def test_list_by_email(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist('key1@example.org')) self.assertTrue(keyids, set(['46BB55F0885C65A4'])) keyids = set(key.subkeys[0].keyid for key in ctx.keylist(['key1@example.org', 'signonly@example.com'])) self.assertTrue(keyids, set(['46BB55F0885C65A4', 'F540A569CB935A42'])) def test_list_by_name(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist('Key 1')) self.assertTrue(keyids, set(['46BB55F0885C65A4'])) def test_list_by_email_substring(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist('@example.org')) self.assertTrue(keyids, set(['46BB55F0885C65A4', '2CF46B7FC97E6B0F', 'F540A569CB935A42', '2EF658C987754368'])) def test_list_secret(self): ctx = gpgme.Context() keyids = set(key.subkeys[0].keyid for key in ctx.keylist(None, True)) self.assertTrue(keyids, set(['46BB55F0885C65A4'])) def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_encrypt_decrypt.py0000644000175000017500000002052511723313444021243 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os import unittest try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO from textwrap import dedent import gpgme from tests.util import GpgHomeTestCase class EncryptDecryptTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key1.sec', 'key2.pub', 'key2.sec', 'signonly.pub', 'signonly.sec'] def test_decrypt(self): ciphertext = BytesIO(dedent(''' -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.1 (GNU/Linux) hQIMA6lSIdANy91kARAAtXjViihD6DVBAYGdVs0a2sMPGRXjIR5Tw1ONKx4MtKn+ pydR+/+0rBRGaQXe/mMODA8gqADQjz7PcTMWBa7ja969+K2nw7j5DUIMatonQVMf vpc7ze5hovZ1jXYAgmmXdUzDmk8ZkpHaEc5mMMAHYKFn+mm37AFY5JUjg2Ae9k3H 29t+pW+n9ncn/QBImW3oVslZ8Fza1xOIWZTUrmvtU0vELdlIxy+d945bvD9EhmTK zRrD5m8V1etWINO2tE1Xhd4lV1KxncHzWafXLB5BKprztTqFUXNPAfnucYIczDon 5VvkOz3WAtl/93o85hUKhbgGK0dvU3m+bj620ZUE5oDpPB4l1CiO5RqUFYtyN4LF OSAceVOh7X764VLtpAzuOpNfTYgvzIFJqrFOZHlf3XJRdGdpJuxMe8BwhdLyDscx pap4QxajOUSUAeS45x6ERA7xHO0QOwXZNzoxiOt9KRaoIhEacu70A9xRcGNJfZE2 3z/AEMKr2CK6ny9/S8UQEhNvn1/gYfSXakFjWjM6PUXJSnz8WGjpFKKITpex3WBz m/X8bKgG3fT92zqJdYocrl4wgz4Dt3+KirnGG4gITxaEYpTT0y6l6NAO60De0oRh yqk+ulj2pvAlA82Ph0vTGZ9uOQGbrfN+NhwsG0HMNq+vmjShS1jJbSfoEt1AAIPS RwGMq7SDk/V7nhKqZcxeIWdtRIgFvEf0KljthkOZxT/GozNjQclak7Kt69K2qyvt XUfidNAhuOmeZ4pF31qSFiAnKRbzjzHp =1s5N -----END PGP MESSAGE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() ctx.decrypt(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'hello world\n') def test_decrypt_verify(self): ciphertext = BytesIO(dedent(''' -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.1 (GNU/Linux) hQIMA6lSIdANy91kAQ/9GGQxL/OWvxrTchSMmIhsvwONJNlFE5cMIC0xejY4eN+t HtTg8V1fWXLRw7WY6FNFLeoR2hzqaZWw15lU55TmSJfJmK2mdUZu/IhSpCUFMEFW ZQpxslKq7N+S8NZHgq1WG32Ar1auOEflBQUMhj7sRSAtkvU7fWrTwf4Q4mcIV68P LiAAQoKxXNNVam9+EV/b3kx3bnJPKTn+ArpJf5Im+5XOGOeu9Ll0QUTbicgFhfpR esR6dKI/Ji5FGIu01kYNrDjDeMcJuzI52kNNoT+GJ72R+Gp4bZk2ycd+eVo3eeUW klO8K+7E5bd5ni+1H+ZWbVp9bn7Q++mFP6Mruv+v9Di5mvFXxMoFuB/8NzcilFVt h5VOexW1OaZk2bMp9bXVja/N7Y1oAADhINk0feaKkwYVOBJU9kJtL2O1WQui85Q3 2dsL0YRJiR6mXesTezglZO44gsVAvCH8RUCtBnfEazfBg4jhcCHy6ooDgd0M4vcw xG4U7IyDU5xyLi9QrTaSg5LzzwNFqb5k/lTemZw3ob3uwZinWewASLwn5N5OPVRs gFT0eL0TfvDzHURsM/7QDvq9HX6JS7buyOlr5cZAsdSvm0FyE6YOkSvZR2jwp3vV jfs7RHjq9V7jzPVVKHnWEDoJfchkT/3KyMRCIM/ukBk9MwTZTIJRhjTA2Xd4kWTS kQEaU/OjumXPtw/T1pUH23nAkVssHsj8qgtxkFSmG/wrwNmfYx4tDhvgsHMJhar9 hqQKBMsGmLD6RNWKhF/LryNBKI2IRgJabKKYbbOsydom/hw8ZF4aWaZTcCBMoBB2 nhOi8WEIeWp93FGfHBa60nSBNGwgt24NmoFaXMjnCrJY/yK0L0MAajUC150OhtvG OSk= =fl3U -----END PGP MESSAGE----- ''').encode('ASCII')) plaintext = BytesIO() ctx = gpgme.Context() sigs = ctx.decrypt_verify(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'hello world\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].notations, []) self.assertEqual(sigs[0].timestamp, 1138049495) self.assertEqual(sigs[0].exp_timestamp, 0) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_encrypt(self): plaintext = BytesIO(b'Hello World\n') ciphertext = BytesIO() ctx = gpgme.Context() recipient = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.encrypt([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext) # rewind ciphertext buffer, and try to decrypt: ciphertext.seek(0) plaintext = BytesIO() ctx.decrypt(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') def test_encrypt_armor(self): plaintext = BytesIO(b'Hello World\n') ciphertext = BytesIO() ctx = gpgme.Context() ctx.armor = True recipient = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.encrypt([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext) # rewind ciphertext buffer, and try to decrypt: ciphertext.seek(0) plaintext = BytesIO() ctx.decrypt(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') def test_encrypt_symmetric(self): plaintext = BytesIO(b'Hello World\n') ciphertext = BytesIO() def passphrase(uid_hint, passphrase_info, prev_was_bad, fd): os.write(fd, b'Symmetric passphrase\n') ctx = gpgme.Context() ctx.armor = True ctx.passphrase_cb = passphrase ctx.encrypt(None, 0, plaintext, ciphertext) self.assertTrue( ciphertext.getvalue().startswith(b'-----BEGIN PGP MESSAGE-----')) # Rewind ciphertext buffer and try to decrypt it: ciphertext.seek(0) plaintext = BytesIO() ctx.decrypt(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') def test_encrypt_sign(self): plaintext = BytesIO(b'Hello World\n') ciphertext = BytesIO() ctx = gpgme.Context() ctx.armor = True signer = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') recipient = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') ctx.signers = [signer] new_sigs = ctx.encrypt_sign([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext) self.assertEqual(len(new_sigs), 1) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_NORMAL) self.assertEqual(new_sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') # rewind ciphertext buffer, and try to decrypt: ciphertext.seek(0) plaintext = BytesIO() sigs = ctx.decrypt_verify(ciphertext, plaintext) self.assertEqual(plaintext.getvalue(), b'Hello World\n') self.assertEqual(len(sigs), 1) self.assertEqual(sigs[0].summary, 0) self.assertEqual(sigs[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(sigs[0].status, None) self.assertEqual(sigs[0].wrong_key_usage, False) self.assertEqual(sigs[0].validity, gpgme.VALIDITY_UNKNOWN) self.assertEqual(sigs[0].validity_reason, None) def test_encrypt_to_signonly(self): plaintext = BytesIO(b'Hello World\n') ciphertext = BytesIO() ctx = gpgme.Context() recipient = ctx.get_key('15E7CE9BF1771A4ABC550B31F540A569CB935A42') try: ctx.encrypt([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext) except gpgme.GpgmeError as exc: self.assertEqual(exc.args[0], gpgme.ERR_SOURCE_UNKNOWN) self.assertEqual(exc.args[1], gpgme.ERR_GENERAL) else: self.fail('gpgme.GpgmeError not raised') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/keys/0000775000175000017500000000000011726117114015364 5ustar jamesjames00000000000000pygpgme-0.3/tests/keys/passphrase.sec0000644000175000017500000000202510431015202020211 0ustar jamesjames00000000000000C՚pCsdQbeJ4yQ/o#h3Tu2.lB8;ӈ 8iҸgh%g?"˶W S#6#O4%U.`7øeͪxj"vW&H*@,e=2һȆ7wݶ;C¦ FE_칸]WnvP~go~R}e|`t̮7jrW)€g[`-meYt-_Z00/@COlC+{EQ7߰Kntyou Խ88_ͨ_`rQ `x>>e eۅABxY؋% yM OIJ$[*Passphrase (test) ^C՚p  Tܻq8b߇Nƫb8"2bkjhe.IwuPWC՚uH\dNX;Y0`, KS69!d*]<y3SZ{r*.zVDjqEB(t%F~v|P܍W=3y%> G1 ̧)sFsW4Y\/AΔrRAqfQ Ri M(amD(l!Ziz^H{[\BUSftV%h<}vMZq?'L`m;8˓hHKXZ^XMaCQH`rQ `?PZ8f92EU+${#$lM fM.f7 z0O<>Ko)ں݈I C՚u TܻUl=mD=!R͖FIebW:a OQl(pygpgme-0.3/tests/keys/signonly.pub0000644000175000017500000000771610431015202017732 0ustar jamesjames00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) 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 IiupsX+7alW4D8gI++6xtVTyanhtymAW =WN/+ -----END PGP PUBLIC KEY BLOCK----- pygpgme-0.3/tests/keys/signonly.sec0000644000175000017500000001020310431015202017677 0ustar jamesjames00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) 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 ewllGZCqbWy9TQ== =pPlO -----END PGP PRIVATE KEY BLOCK----- pygpgme-0.3/tests/keys/passphrase.pub0000644000175000017500000000161410431015202020230 0ustar jamesjames00000000000000C՚pCsdQbeJ4yQ/o#h3Tu2.lB8;ӈ 8iҸgh%g?"˶W S#6#O4%U.`7øeͪxj"vW&H*@,e=2һȆ7wݶ;C¦ FE_칸]WnvP~go~R}e|`t̮7jrW)€g[`-meYt-_Z00/@COlC+{EQ7߰Kntyou Խ88_ͨ_̴*Passphrase (test) ^C՚p  Tܻ$5-sם6r\.WmHtfcAI C՚uH\dNX;Y0`, KS69!d*]<y3SZ{r*.zVDjqEB(t%F~v|P܍W=3y%> G1 ̧)sFsW4Y\/AΔrRAqfQ Ri M(amD(l!Ziz^H{[\BUSftV%h<}vMZq?'L`m;8˓hHKXZ^XMaCQHI C՚u TܻU5J~2_L/$a@ sa_=[$pygpgme-0.3/tests/keys/key2.sec0000644000175000017500000001466310431015202016725 0ustar jamesjames00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) 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 FTstUwJS/LPkRekNydTPD70NpRap =e8Ot -----END PGP PRIVATE KEY BLOCK----- pygpgme-0.3/tests/keys/key1.pub0000644000175000017500000000320110431015202016722 0ustar jamesjames00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) mQGiBEPN6eMRBAC3/jKHCnI9c9fATgGLV4x53wN6ZZoqzcgks4rR9BgrYLvPBzDX em74/m5uRMY90hGzJw8kb/rG8ZznJTU/ZE50qCmEEQuTyZar80LEb4ujbqTfZzGK v3blpSS+f5ON+2VATiL85roJ7BhpMnhUvS7nk/rSoKFYz+sdf/l3SR76ywCgg+OK ISC9UWqI9wlyhs7BpZib6SkEAJ7SzSDHNFI0Uvl5/+QYwy1N9IxCx6po7OJuBFK8 9XBSbqRnnrlcCko/qTIuPxy9R9g+0JPhi2cNB++f3I/TPz73Xsg7JjkNnqD7aZS7 MXRlzxESuu7Br+JVwzIERfXDLuA0pnMy+nt1mhuUFxc4dFEzD0DDsbFNWmo57rlr t2BZA/4naBrB6L763BMIzebjTCOJ5d0/4pbqlQrP2O+2BxKvkb7OA3ySgXlTpQsb Q1E5D+prEI6fTKeqytar9NR2FuOc61kEEmN4ACdEX5FWSYM0grAm68BfJ3Q2IHCV pVMF4ExSWlRb05k3TK1HDqjoj8uXMACmz5XAU+69q8ydh3B1LrQYS2V5IDEgPGtl eTFAZXhhbXBsZS5vcmc+iF4EExECAB4FAkPN6eMCGwMGCwkIBwMCAxUCAwMWAgEC HgECF4AACgkQRrtV8IhcZaSq1QCeObAJFNF3yGlgfV26ACIZyM84gXcAn1yM0T5/ Qcwkbeu4J/e2PKw/uQ7QuQINBEPN6eoQCACMxxJidY6L1c5zHgU7vZ3yRvnp8tkr ShyNtwj6MCgyp9kHK8lgndsIpwXWxfXsSbTPT6wtdH15is7uitHjG1tKphmNgkTH KEE62ZMAP5XSfr0ntd9fMxGAqlKcsjdnkC4m/FQzJSFQRnZE9OsGMbACaCtEfc6t LU8e3th/tyFCT3nTkfHLYmfVeBWjbsZPoAVcDVAs094E05EmA7lg72PJwzgxyKRM 4rO1DLgUf9zeXbukYA98SMAPLzf1X9/zY4CfMCicrFkFOkul/maXF7chfxrQqabn etu9XvAO/nxE5lJvtHu0hQotmK3WyAQidPP+fx3dPO2SLVi2bEt4Wy7HAAMFB/4n rQbjh1x5fjNyLu+UlQL8xpKf3NDreP7ncvUmXn516wNxzk8S5KEDrxAwevEeixxY 2LPTE4FbbUhIEkRilz22YIWxrFaKywAkbomGFaHkj5miily2daS1bxYidkjb4mGU DFujMMIOqI1N3Ag4lNo9NP7XkESj6uqcBOS6pd735pFg0j3+9+HGT1e1dwynoMdS 60oSnCMEaD2xod1T5We2vofgwj53w/4yug0h84dWYSKFfgOgycslBJ1Z2aJDp664 /Ora5PpPjBw6pHklvmOiLWD0UEL3nv/B7UxU+UgD3fYZ63j5RKuvmzw9YdHtVUyH kRy7A70j1pHt1aDt7GqoiEkEGBECAAkFAkPN6eoCGwwACgkQRrtV8IhcZaR5XACf fc3iRAkf1hOGAx7Qi4yIqfVoG+4AoIAlsvKuGQ/9Q7fSSBsp1mWTLl4D =A4B6 -----END PGP PUBLIC KEY BLOCK----- pygpgme-0.3/tests/keys/key2.pub0000644000175000017500000000615510431015202016736 0ustar jamesjames00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) 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 zw+9DaUWqQ== =guWc -----END PGP PUBLIC KEY BLOCK----- pygpgme-0.3/tests/keys/revoked.pub0000644000175000017500000000265610431015202017525 0ustar jamesjames00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) mQGiBEPN7RMRBACqAXL6t6ZVuyFkjqM8FH52eN06p+XFHG+PqxXYTnUUWyumLO5T Pjmpgf22QmHnSI6IaB13rC7v5gA2B4z5P6/j/LTV51d/T/0thFy/p7XINSBw+CES 6RpST3AWdkmj+TvX4Kb4xP9klIbcC3cFexLKjWe+V78Nli05DpqR3V8rZwCguKwn MyaMS4smhncgSbdFZ/jSbN8D/iU7vlQ2r1tiH5G70WWyeV/+8Rz/gOEhlKo+Yfds x3t94qpWr+qn7u9615w9eX4WYyGmRXdxEzQqAyagqkXZBNyPNE1nA6/lCx/2hAlQ mPOSN2F7YII29RuRjNF3Cd1z/RuobP0yjmXyIYOo4Qf1/GKHWjp0Xu+qcCPDmnmD a6YHA/0Xwe2VSY9BQg74FI+L7C83R3Xm9qubgkWpyYwrpN/aSlVCywqG3VjYNAZ5 RvXfkFW43r0dURAMz6I01X/LrkIWxvgz2pii7qfjs1pBGNM2kYK3Vwzcdp7Lg9uf /c5aljGBDpn7SF4jBenOPH51LYI8N9NIMioEmOyaD1jrBvmk7ohcBCARAgAcBQJD ze1GFR0DVGVzdCBvZiByZXZva2VkIGtleQAKCRAu9ljJh3VDaH0bAJ9K2nuztlmt b8tMy9+FApwomHC0kQCfSLAgQa9hZS1TyPtHXGAMoghNif20HVJldm9rZWQgPHJl dm9rZWRAZXhhbXBsZS5vcmc+iF4EExECAB4FAkPN7RMCGwMGCwkIBwMCAxUCAwMW AgECHgECF4AACgkQLvZYyYd1Q2jE8gCeP9IXvrznkFehQGBMf3gGeO57GJgAn2uL DkgH811s1LN9GKqKBGbCLH5CuQENBEPN7RcQBADoHXOivf3MqUR99JJTQtYo9b3f zQzZIgMtqmOwCFfe/jWA0VNf1svUemhXgiqi/gQUC2JLIJgIArhlxey5mU1gn7L/ OMtwKfXD5zUrOKptTby8RIcySv20LR+vh6SmeYTI9ELdlwrG2efYDWtl2jBodnHf 1u38PjzE2NhvqqjdNwADBQQAlIbPfQmFSnB8YRsLCq6w9Qc/kqwPcAgGbPsIaFsG qLc0HRk4/SivyH+i/TTUlpcQ3gXoZ/eUInO9R2IMmQzg+J4XAtx/llSJ0krO27Cy qs0QLdvtpaN9dvunhf7FGduHmJys8uPcxo6h/TvBsVUF1ZJCWZzCT7iMOjUZYSau 99SISQQYEQIACQUCQ83tFwIbDAAKCRAu9ljJh3VDaOcpAKCFql4b4u7YEr3enZx5 3c2YXJUubQCeP+/3+KFxmfr+NS5d08JjplMT96I= =+ttA -----END PGP PUBLIC KEY BLOCK----- pygpgme-0.3/tests/keys/key1.sec0000644000175000017500000000335110431015202016714 0ustar jamesjames00000000000000-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v1.4.1 (GNU/Linux) lQG7BEPN6eMRBAC3/jKHCnI9c9fATgGLV4x53wN6ZZoqzcgks4rR9BgrYLvPBzDX em74/m5uRMY90hGzJw8kb/rG8ZznJTU/ZE50qCmEEQuTyZar80LEb4ujbqTfZzGK v3blpSS+f5ON+2VATiL85roJ7BhpMnhUvS7nk/rSoKFYz+sdf/l3SR76ywCgg+OK ISC9UWqI9wlyhs7BpZib6SkEAJ7SzSDHNFI0Uvl5/+QYwy1N9IxCx6po7OJuBFK8 9XBSbqRnnrlcCko/qTIuPxy9R9g+0JPhi2cNB++f3I/TPz73Xsg7JjkNnqD7aZS7 MXRlzxESuu7Br+JVwzIERfXDLuA0pnMy+nt1mhuUFxc4dFEzD0DDsbFNWmo57rlr t2BZA/4naBrB6L763BMIzebjTCOJ5d0/4pbqlQrP2O+2BxKvkb7OA3ySgXlTpQsb Q1E5D+prEI6fTKeqytar9NR2FuOc61kEEmN4ACdEX5FWSYM0grAm68BfJ3Q2IHCV pVMF4ExSWlRb05k3TK1HDqjoj8uXMACmz5XAU+69q8ydh3B1LgAAni2eZ4K2MRJq oqJc5SsgIMHzLXw2CTi0GEtleSAxIDxrZXkxQGV4YW1wbGUub3JnPoheBBMRAgAe BQJDzenjAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEEa7VfCIXGWkqtUAnjI7 uB1911Iaf5Ab4xmriEfKbj+EAJ93FeHcuajBs6TEoLKLNetpCf8TCJ0CPQRDzenq EAgAjMcSYnWOi9XOcx4FO72d8kb56fLZK0ocjbcI+jAoMqfZByvJYJ3bCKcF1sX1 7Em0z0+sLXR9eYrO7orR4xtbSqYZjYJExyhBOtmTAD+V0n69J7XfXzMRgKpSnLI3 Z5AuJvxUMyUhUEZ2RPTrBjGwAmgrRH3OrS1PHt7Yf7chQk9505Hxy2Jn1XgVo27G T6AFXA1QLNPeBNORJgO5YO9jycM4McikTOKztQy4FH/c3l27pGAPfEjADy839V/f 82OAnzAonKxZBTpLpf5mlxe3IX8a0Kmm53rbvV7wDv58ROZSb7R7tIUKLZit1sgE InTz/n8d3Tztki1YtmxLeFsuxwADBQf+J60G44dceX4zci7vlJUC/MaSn9zQ63j+ 53L1Jl5+desDcc5PEuShA68QMHrxHoscWNiz0xOBW21ISBJEYpc9tmCFsaxWissA JG6JhhWh5I+ZoopctnWktW8WInZI2+JhlAxbozDCDqiNTdwIOJTaPTT+15BEo+rq nATkuqXe9+aRYNI9/vfhxk9XtXcMp6DHUutKEpwjBGg9saHdU+Vntr6H4MI+d8P+ MroNIfOHVmEihX4DoMnLJQSdWdmiQ6euuPzq2uT6T4wcOqR5Jb5joi1g9FBC957/ we1MVPlIA932Get4+USrr5s8PWHR7VVMh5EcuwO9I9aR7dWg7exqqAABUwYkXGcj ydeyTvGPtJx23TAu6UCJ9ycRv1DEjZXgyz/0KJa8MuLdp6PKq/YYWYhJBBgRAgAJ BQJDzenqAhsMAAoJEEa7VfCIXGWkeVwAn1Z2OsXbZ32B+U/jvl5QG0NE66+cAJ4r jyoVKtrbw0t7+xoBOMft2cv6Xw== =kwYN -----END PGP PRIVATE KEY BLOCK----- pygpgme-0.3/tests/test_passphrase.py0000644000175000017500000000571411723312661020201 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import os try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO from textwrap import dedent import gpgme from tests.util import GpgHomeTestCase class PassphraseTestCase(GpgHomeTestCase): import_keys = ['passphrase.pub', 'passphrase.sec'] def test_sign_without_passphrase_cb(self): ctx = gpgme.Context() key = ctx.get_key('EFB052B4230BBBC51914BCBB54DCBBC8DBFB9EB3') ctx.signers = [key] plaintext = BytesIO(b'Hello World\n') signature = BytesIO() try: new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) except gpgme.GpgmeError as exc: self.assertEqual(exc.args[0], gpgme.ERR_SOURCE_GPGME) self.assertEqual(exc.args[1], gpgme.ERR_BAD_PASSPHRASE) else: self.fail('gpgme.GpgmeError not raised') def passphrase_cb(self, uid_hint, passphrase_info, prev_was_bad, fd): self.uid_hint = uid_hint self.passphrase_info = passphrase_info self.prev_was_bad = prev_was_bad os.write(fd, b'test\n') def test_sign_with_passphrase_cb(self): ctx = gpgme.Context() key = ctx.get_key('EFB052B4230BBBC51914BCBB54DCBBC8DBFB9EB3') ctx.signers = [key] ctx.passphrase_cb = self.passphrase_cb plaintext = BytesIO(b'Hello World\n') signature = BytesIO() self.uid_hint = None self.passphrase_info = None self.prev_was_bad = None new_sigs = ctx.sign(plaintext, signature, gpgme.SIG_MODE_CLEAR) # ensure that passphrase_cb has been run, and the data it was passed self.assertEqual(self.uid_hint, '54DCBBC8DBFB9EB3 Passphrase (test) ') self.assertEqual(self.passphrase_info, '54DCBBC8DBFB9EB3 54DCBBC8DBFB9EB3 17 0') self.assertEqual(self.prev_was_bad, False) self.assertEqual(new_sigs[0].type, gpgme.SIG_MODE_CLEAR) self.assertEqual(new_sigs[0].fpr, 'EFB052B4230BBBC51914BCBB54DCBBC8DBFB9EB3') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/test_import.py0000644000175000017500000001702211724045442017336 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO import gpgme from tests.util import GpgHomeTestCase class ImportTestCase(GpgHomeTestCase): def test_import_file(self): ctx = gpgme.Context() with self.keyfile('key1.pub') as fp: result = ctx.import_(fp) self.assertEqual(result.considered, 1) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 1) self.assertEqual(result.imported_rsa, 0) self.assertEqual(result.unchanged, 0) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 0) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 0) self.assertEqual(result.secret_imported, 0) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 1) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') def test_import_secret_file(self): ctx = gpgme.Context() with self.keyfile('key1.sec') as fp: result = ctx.import_(fp) self.assertEqual(result.considered, 1) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 1) self.assertEqual(result.imported_rsa, 0) self.assertEqual(result.unchanged, 0) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 0) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 1) self.assertEqual(result.secret_imported, 1) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 2) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW | gpgme.IMPORT_SECRET)) self.assertEqual(result.imports[1], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') # can we get the secret key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4', True) def test_import_stringio(self): with self.keyfile('key1.pub') as fp: data = fp.read() fp = BytesIO(data) ctx = gpgme.Context() result = ctx.import_(fp) self.assertEqual(len(result.imports), 1) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') def test_import_concat(self): keys = [] for filename in ['key1.pub', 'key1.sec', 'key2.pub']: with self.keyfile(filename) as fp: keys.append(fp.read()) fp = BytesIO(b'\n'.join(keys)) ctx = gpgme.Context() result = ctx.import_(fp) self.assertEqual(result.considered, 3) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 2) self.assertEqual(result.imported_rsa, 1) self.assertEqual(result.unchanged, 0) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 1) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 1) self.assertEqual(result.secret_imported, 1) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 4) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW)) self.assertEqual(result.imports[1], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_NEW | gpgme.IMPORT_SECRET)) self.assertEqual(result.imports[2], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, gpgme.IMPORT_SIG)) self.assertEqual(result.imports[3], ('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F', None, gpgme.IMPORT_NEW)) # can we get the public keys? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') # can we get the secret key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4', True) def test_import_empty(self): fp = BytesIO(b'') ctx = gpgme.Context() result = ctx.import_(fp) self.assertEqual(result.considered, 0) self.assertEqual(len(result.imports), 0) def test_import_twice(self): ctx = gpgme.Context() with self.keyfile('key1.pub') as fp: result = ctx.import_(fp) with self.keyfile('key1.pub') as fp: result = ctx.import_(fp) self.assertEqual(result.considered, 1) self.assertEqual(result.no_user_id, 0) self.assertEqual(result.imported, 0) self.assertEqual(result.imported_rsa, 0) self.assertEqual(result.unchanged, 1) self.assertEqual(result.new_user_ids, 0) self.assertEqual(result.new_sub_keys, 0) self.assertEqual(result.new_signatures, 0) self.assertEqual(result.new_revocations, 0) self.assertEqual(result.secret_read, 0) self.assertEqual(result.secret_imported, 0) self.assertEqual(result.secret_unchanged, 0) self.assertEqual(result.skipped_new_keys, 0) self.assertEqual(result.not_imported, 0) self.assertEqual(len(result.imports), 1) self.assertEqual(result.imports[0], ('E79A842DA34A1CA383F64A1546BB55F0885C65A4', None, 0)) # can we get the public key? key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/__init__.py0000644000175000017500000000354711722717176016543 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest def test_suite(): import tests.test_context import tests.test_keys import tests.test_keylist import tests.test_import import tests.test_export import tests.test_delete import tests.test_sign_verify import tests.test_encrypt_decrypt import tests.test_passphrase import tests.test_progress import tests.test_editkey import tests.test_genkey suite = unittest.TestSuite() suite.addTest(tests.test_context.test_suite()) suite.addTest(tests.test_keys.test_suite()) suite.addTest(tests.test_keylist.test_suite()) suite.addTest(tests.test_import.test_suite()) suite.addTest(tests.test_export.test_suite()) suite.addTest(tests.test_delete.test_suite()) suite.addTest(tests.test_sign_verify.test_suite()) suite.addTest(tests.test_encrypt_decrypt.test_suite()) suite.addTest(tests.test_passphrase.test_suite()) suite.addTest(tests.test_progress.test_suite()) suite.addTest(tests.test_editkey.test_suite()) suite.addTest(tests.test_genkey.test_suite()) return suite pygpgme-0.3/tests/test_keys.py0000644000175000017500000003012011722717176017001 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import unittest import gpgme from tests.util import GpgHomeTestCase class KeyTestCase(GpgHomeTestCase): import_keys = ['key1.pub', 'key2.pub', 'revoked.pub', 'signonly.pub'] def test_key1(self): ctx = gpgme.Context() key = ctx.get_key('E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(key.revoked, False) self.assertEqual(key.expired, False) self.assertEqual(key.invalid, False) self.assertEqual(key.can_encrypt, True) self.assertEqual(key.can_sign, True) self.assertEqual(key.can_certify, True) self.assertEqual(key.secret, False) self.assertEqual(key.can_authenticate, False) self.assertEqual(key.protocol, gpgme.PROTOCOL_OpenPGP) self.assertEqual(len(key.subkeys), 2) self.assertEqual(len(key.uids), 1) self.assertEqual(key.subkeys[0].revoked, False) self.assertEqual(key.subkeys[0].expired, False) self.assertEqual(key.subkeys[0].disabled, False) self.assertEqual(key.subkeys[0].invalid, False) self.assertEqual(key.subkeys[0].can_encrypt, False) self.assertEqual(key.subkeys[0].can_sign, True) self.assertEqual(key.subkeys[0].can_certify, True) self.assertEqual(key.subkeys[0].secret, False) self.assertEqual(key.subkeys[0].can_authenticate, False) self.assertEqual(key.subkeys[0].pubkey_algo, gpgme.PK_DSA) self.assertEqual(key.subkeys[0].length, 1024) self.assertEqual(key.subkeys[0].keyid, '46BB55F0885C65A4') self.assertEqual(key.subkeys[0].fpr, 'E79A842DA34A1CA383F64A1546BB55F0885C65A4') self.assertEqual(key.subkeys[0].timestamp, 1137568227) self.assertEqual(key.subkeys[0].expires, 0) self.assertEqual(key.subkeys[1].revoked, False) self.assertEqual(key.subkeys[1].expired, False) self.assertEqual(key.subkeys[1].disabled, False) self.assertEqual(key.subkeys[1].invalid, False) self.assertEqual(key.subkeys[1].can_encrypt, True) self.assertEqual(key.subkeys[1].can_sign, False) self.assertEqual(key.subkeys[1].can_certify, False) self.assertEqual(key.subkeys[1].secret, False) self.assertEqual(key.subkeys[1].can_authenticate, False) self.assertEqual(key.subkeys[1].pubkey_algo, gpgme.PK_ELG_E) self.assertEqual(key.subkeys[1].length, 2048) self.assertEqual(key.subkeys[1].keyid, '659A6AC69BC3B085') # Some versions of libgpgme fill this one in and others don't #self.assertEqual(key.subkeys[1].fpr, None) self.assertEqual(key.subkeys[1].timestamp, 1137568234) self.assertEqual(key.subkeys[1].expires, 0) self.assertEqual(key.uids[0].revoked, False) self.assertEqual(key.uids[0].invalid, False) self.assertEqual(key.uids[0].validity, 0) self.assertEqual(key.uids[0].uid, 'Key 1 ') self.assertEqual(key.uids[0].name, 'Key 1') self.assertEqual(key.uids[0].email, 'key1@example.org') self.assertEqual(key.uids[0].comment, '') def test_key2(self): ctx = gpgme.Context() key = ctx.get_key('93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') self.assertEqual(key.revoked, False) self.assertEqual(key.expired, False) self.assertEqual(key.invalid, False) self.assertEqual(key.can_encrypt, True) self.assertEqual(key.can_sign, True) self.assertEqual(key.can_certify, True) self.assertEqual(key.secret, False) self.assertEqual(key.can_authenticate, False) self.assertEqual(key.protocol, gpgme.PROTOCOL_OpenPGP) self.assertEqual(len(key.subkeys), 2) self.assertEqual(len(key.uids), 1) self.assertEqual(key.subkeys[0].revoked, False) self.assertEqual(key.subkeys[0].expired, False) self.assertEqual(key.subkeys[0].disabled, False) self.assertEqual(key.subkeys[0].invalid, False) self.assertEqual(key.subkeys[0].can_encrypt, False) self.assertEqual(key.subkeys[0].can_sign, True) self.assertEqual(key.subkeys[0].can_certify, True) self.assertEqual(key.subkeys[0].secret, False) self.assertEqual(key.subkeys[0].can_authenticate, False) self.assertEqual(key.subkeys[0].pubkey_algo, gpgme.PK_RSA) self.assertEqual(key.subkeys[0].length, 4096) self.assertEqual(key.subkeys[0].keyid, '2CF46B7FC97E6B0F') self.assertEqual(key.subkeys[0].fpr, '93C2240D6B8AA10AB28F701D2CF46B7FC97E6B0F') self.assertEqual(key.subkeys[0].timestamp, 1137568343) self.assertEqual(key.subkeys[0].expires, 0) self.assertEqual(key.subkeys[1].revoked, False) self.assertEqual(key.subkeys[1].expired, False) self.assertEqual(key.subkeys[1].disabled, False) self.assertEqual(key.subkeys[1].invalid, False) self.assertEqual(key.subkeys[1].can_encrypt, True) self.assertEqual(key.subkeys[1].can_sign, False) self.assertEqual(key.subkeys[1].can_certify, False) self.assertEqual(key.subkeys[1].secret, False) self.assertEqual(key.subkeys[1].can_authenticate, False) self.assertEqual(key.subkeys[1].pubkey_algo, gpgme.PK_RSA) self.assertEqual(key.subkeys[1].length, 4096) self.assertEqual(key.subkeys[1].keyid, 'A95221D00DCBDD64') # Some versions of libgpgme fill this one in and others don't #self.assertEqual(key.subkeys[1].fpr, None) self.assertEqual(key.subkeys[1].timestamp, 1137568395) self.assertEqual(key.subkeys[1].expires, 0) self.assertEqual(key.uids[0].revoked, False) self.assertEqual(key.uids[0].invalid, False) self.assertEqual(key.uids[0].validity, 0) self.assertEqual(key.uids[0].uid, 'Key 2 ') self.assertEqual(key.uids[0].name, 'Key 2') self.assertEqual(key.uids[0].email, 'key2@example.org') self.assertEqual(key.uids[0].comment, '') def test_revoked(self): ctx = gpgme.Context() key = ctx.get_key('B6525A39EB81F88B4D2CFB3E2EF658C987754368') self.assertEqual(key.revoked, True) self.assertEqual(key.expired, False) self.assertEqual(key.invalid, False) self.assertEqual(key.can_encrypt, False) self.assertEqual(key.can_sign, True) self.assertEqual(key.can_certify, True) self.assertEqual(key.secret, False) self.assertEqual(key.can_authenticate, False) self.assertEqual(key.protocol, gpgme.PROTOCOL_OpenPGP) self.assertEqual(len(key.subkeys), 2) self.assertEqual(len(key.uids), 1) self.assertEqual(key.subkeys[0].revoked, True) self.assertEqual(key.subkeys[0].expired, False) self.assertEqual(key.subkeys[0].disabled, False) self.assertEqual(key.subkeys[0].invalid, False) self.assertEqual(key.subkeys[0].can_encrypt, False) self.assertEqual(key.subkeys[0].can_sign, True) self.assertEqual(key.subkeys[0].can_certify, True) self.assertEqual(key.subkeys[0].secret, False) self.assertEqual(key.subkeys[0].can_authenticate, False) self.assertEqual(key.subkeys[0].pubkey_algo, gpgme.PK_DSA) self.assertEqual(key.subkeys[0].length, 1024) self.assertEqual(key.subkeys[0].keyid, '2EF658C987754368') self.assertEqual(key.subkeys[0].fpr, 'B6525A39EB81F88B4D2CFB3E2EF658C987754368') self.assertEqual(key.subkeys[0].timestamp, 1137569043) self.assertEqual(key.subkeys[0].expires, 0) self.assertEqual(key.subkeys[1].revoked, True) self.assertEqual(key.subkeys[1].expired, False) self.assertEqual(key.subkeys[1].disabled, False) self.assertEqual(key.subkeys[1].invalid, False) self.assertEqual(key.subkeys[1].can_encrypt, True) self.assertEqual(key.subkeys[1].can_sign, False) self.assertEqual(key.subkeys[1].can_certify, False) self.assertEqual(key.subkeys[1].secret, False) self.assertEqual(key.subkeys[1].can_authenticate, False) self.assertEqual(key.subkeys[1].pubkey_algo, gpgme.PK_ELG_E) self.assertEqual(key.subkeys[1].length, 1024) self.assertEqual(key.subkeys[1].keyid, 'E50B59CF50CE4D54') # Some versions of libgpgme fill this one in and others don't #self.assertEqual(key.subkeys[1].fpr, None) self.assertEqual(key.subkeys[1].timestamp, 1137569047) self.assertEqual(key.subkeys[1].expires, 0) self.assertEqual(key.uids[0].revoked, True) self.assertEqual(key.uids[0].invalid, False) self.assertEqual(key.uids[0].validity, 0) self.assertEqual(key.uids[0].uid, 'Revoked ') self.assertEqual(key.uids[0].name, 'Revoked') self.assertEqual(key.uids[0].email, 'revoked@example.org') self.assertEqual(key.uids[0].comment, '') def test_signonly(self): ctx = gpgme.Context() key = ctx.get_key('15E7CE9BF1771A4ABC550B31F540A569CB935A42') self.assertEqual(key.revoked, False) self.assertEqual(key.expired, False) self.assertEqual(key.invalid, False) self.assertEqual(key.can_encrypt, False) self.assertEqual(key.can_sign, True) self.assertEqual(key.can_certify, True) self.assertEqual(key.secret, False) self.assertEqual(key.can_authenticate, False) self.assertEqual(key.protocol, gpgme.PROTOCOL_OpenPGP) self.assertEqual(len(key.subkeys), 1) self.assertEqual(len(key.uids), 2) self.assertEqual(key.subkeys[0].revoked, False) self.assertEqual(key.subkeys[0].expired, False) self.assertEqual(key.subkeys[0].disabled, False) self.assertEqual(key.subkeys[0].invalid, False) self.assertEqual(key.subkeys[0].can_encrypt, False) self.assertEqual(key.subkeys[0].can_sign, True) self.assertEqual(key.subkeys[0].can_certify, True) self.assertEqual(key.subkeys[0].secret, False) self.assertEqual(key.subkeys[0].can_authenticate, False) self.assertEqual(key.subkeys[0].pubkey_algo, gpgme.PK_RSA) self.assertEqual(key.subkeys[0].length, 4096) self.assertEqual(key.subkeys[0].keyid, 'F540A569CB935A42') self.assertEqual(key.subkeys[0].fpr, '15E7CE9BF1771A4ABC550B31F540A569CB935A42') self.assertEqual(key.subkeys[0].timestamp, 1137568835) self.assertEqual(key.subkeys[0].expires, 0) self.assertEqual(key.uids[0].revoked, False) self.assertEqual(key.uids[0].invalid, False) self.assertEqual(key.uids[0].validity, 0) self.assertEqual(key.uids[0].uid, 'Sign Only ') self.assertEqual(key.uids[0].name, 'Sign Only') self.assertEqual(key.uids[0].email, 'signonly@example.org') self.assertEqual(key.uids[0].comment, '') self.assertEqual(key.uids[1].revoked, False) self.assertEqual(key.uids[1].invalid, False) self.assertEqual(key.uids[1].validity, 0) self.assertEqual(key.uids[1].uid, 'Sign Only (work address) ') self.assertEqual(key.uids[1].name, 'Sign Only') self.assertEqual(key.uids[1].email, 'signonly@example.com') self.assertEqual(key.uids[1].comment, 'work address') def test_suite(): loader = unittest.TestLoader() return loader.loadTestsFromName(__name__) pygpgme-0.3/tests/util.py0000644000175000017500000000330511724045207015740 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os import shutil import tempfile import unittest import gpgme __all__ = ['GpgHomeTestCase'] keydir = os.path.join(os.path.dirname(__file__), 'keys') class GpgHomeTestCase(unittest.TestCase): gpg_conf_contents = '' import_keys = [] def keyfile(self, key): return open(os.path.join(keydir, key), 'rb') def setUp(self): self._gpghome = tempfile.mkdtemp(prefix='tmp.gpghome') os.environ['GNUPGHOME'] = self._gpghome fp = open(os.path.join(self._gpghome, 'gpg.conf'), 'wb') fp.write(self.gpg_conf_contents.encode('UTF-8')) fp.close() # import requested keys into the keyring ctx = gpgme.Context() for key in self.import_keys: with self.keyfile(key) as fp: ctx.import_(fp) def tearDown(self): del os.environ['GNUPGHOME'] shutil.rmtree(self._gpghome, ignore_errors=True) pygpgme-0.3/gpgme/0000775000175000017500000000000011726117114014346 5ustar jamesjames00000000000000pygpgme-0.3/gpgme/__init__.py0000644000175000017500000000161511622631741016462 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from gpgme._gpgme import * # create constants make_constants(globals()) del make_constants pygpgme-0.3/gpgme/editutil.py0000644000175000017500000001223311724115663016547 0ustar jamesjames00000000000000# pygpgme - a Python wrapper for the gpgme library # Copyright (C) 2006 James Henstridge # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """Utilities related to editing keys. Currently only contains a utility function for editing the owner trust value of a key in a keyring. """ __metaclass__ = type __all__ = ['edit_sign', 'edit_trust'] import functools import os try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO import gpgme def key_editor(function): """A decorator that lets key editor callbacks be written as generators.""" @functools.wraps(function) def wrapper(ctx, key, *args, **kwargs): # Start the generator and run it once. gen = function(ctx, key, *args, **kwargs) try: # XXX: this is for Python 2.x compatibility. try: gen.__next__() except AttributeError: gen.next() except StopIteration: return def edit_callback(status, args, fd): if status in (gpgme.STATUS_EOF, gpgme.STATUS_GOT_IT, gpgme.STATUS_NEED_PASSPHRASE, gpgme.STATUS_GOOD_PASSPHRASE, gpgme.STATUS_BAD_PASSPHRASE, gpgme.STATUS_USERID_HINT, gpgme.STATUS_SIGEXPIRED, gpgme.STATUS_KEYEXPIRED, gpgme.STATUS_PROGRESS, gpgme.STATUS_KEY_CREATED, gpgme.STATUS_ALREADY_SIGNED): return try: data = gen.send((status, args)) except StopIteration: raise gpgme.error(gpgme.ERR_SOURCE_UNKNOWN, gpgme.ERR_GENERAL) if data is not None: os.write(fd, data.encode('ASCII')) output = BytesIO() try: ctx.edit(key, edit_callback, output) finally: gen.close() return wrapper @key_editor def edit_trust(ctx, key, trust): """Edit the trust level of the given key.""" if trust not in (gpgme.VALIDITY_UNDEFINED, gpgme.VALIDITY_NEVER, gpgme.VALIDITY_MARGINAL, gpgme.VALIDITY_FULL, gpgme.VALIDITY_ULTIMATE): raise ValueError('Bad trust value %d' % trust) status, args = yield None assert args == 'keyedit.prompt' status, args = yield 'trust\n' assert args == 'edit_ownertrust.value' status, args = yield '%d\n' % trust if args == 'edit_ownertrust.set_ultimate.okay': status, args = yield 'Y\n' assert args == 'keyedit.prompt' status, args = yield 'quit\n' assert args == 'keyedit.save.okay' status, args = yield 'Y\n' @key_editor def edit_sign(ctx, key, index=0, local=False, norevoke=False, expire=True, check=0): """Sign the given key. index: the index of the user ID to sign, starting at 1. Sign all user IDs if set to 0. local: make a local signature norevoke: make a non-revokable signature command: the type of signature. One of sign, lsign, tsign or nrsign. expire: whether the signature should expire with the key. check: Amount of checking performed. One of: 0 - no answer 1 - no checking 2 - casual checking 3 - careful checking """ if index < 0 or index > len(key.uids): raise ValueError('user ID index out of range') command = 'sign' if local: command = 'l%s' % command if norevoke: command = 'nr%s' % command if check not in [0, 1, 2, 3]: raise ValueError('check must be one of 0, 1, 2, 3') status, args = yield None assert args == 'keyedit.prompt' status, args = yield 'uid %d\n' % index assert args == 'keyedit.prompt' status, args = yield '%s\n' % command while args != 'keyedit.prompt': if args == 'keyedit.sign_all.okay': status, args = yield 'Y\n' elif args == 'sign_uid.expire': status, args = yield '%s\n' % ('Y' if expire else 'N') elif args == 'sign_uid.class': status, args = yield '%d\n' % check elif args == 'sign_uid.okay': status, args = yield 'Y\n' else: raise AssertionError("Unexpected state %r" % ((status, args),)) status, args = yield 'quit\n' assert args == 'keyedit.save.okay' status, args = yield 'Y\n' pygpgme-0.3/test_all.py0000644000175000017500000000024211722717036015431 0ustar jamesjames00000000000000import sys import unittest import tests def test_suite(): return tests.test_suite() if __name__ == '__main__': unittest.main(defaultTest='test_suite') pygpgme-0.3/src/0000775000175000017500000000000011726117114014036 5ustar jamesjames00000000000000pygpgme-0.3/src/pygpgme-error.c0000644000175000017500000001131711723313022016773 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "pygpgme.h" PyObject *pygpgme_error = NULL; PyObject * pygpgme_error_object(gpgme_error_t err) { char buf[256] = { '\0' }; PyObject *exc = NULL, *source = NULL, *code = NULL, *strerror = NULL; if (err == GPG_ERR_NO_ERROR) Py_RETURN_NONE; if (!(source = PyInt_FromLong(gpgme_err_source(err)))) goto end; if (!(code = PyInt_FromLong(gpgme_err_code(err)))) goto end; /* get the error string */ if (gpgme_strerror_r(err, buf, sizeof(buf) - 1) != 0) strcpy(buf, "Unknown"); if (!(strerror = PyUnicode_DecodeUTF8(buf, strlen(buf), "replace"))) goto end; exc = PyObject_CallFunction(pygpgme_error, "OOO", source, code, strerror); if (!exc) goto end; /* set the source and code as attributes of the exception object: */ PyObject_SetAttrString(exc, "source", source); PyObject_SetAttrString(exc, "code", code); PyObject_SetAttrString(exc, "strerror", strerror); /* pygpgme 0.1 set the "message" attribute on exceptions, but * Python 2.6 classes this exception attribute as deprecated (even * though we weren't using it in the deprecated fashion). * * We now set the "strerror" attribute for this information, which * is similar to IOError/OSError. * * For backward compatibility, we still set "message" on Python * versions before 3.0. The hack below is to avoid issuing a * deprecation warning. */ #if PY_VERSION_HEX < 0x03000000 # if PY_VERSION_HEX >= 0x02060000 { PyBaseExceptionObject *base_exc = (PyBaseExceptionObject *)exc; PyObject *old_message = base_exc->message; Py_INCREF(strerror); base_exc->message = strerror; Py_XDECREF(old_message); } # else PyObject_SetAttrString(exc, "message", strerror); # endif #endif end: Py_XDECREF(strerror); Py_XDECREF(code); Py_XDECREF(source); return exc; } /* check whether the given gpgme_error_t value indicates an error. If so, * raise an equivalent Python exception and return TRUE */ int pygpgme_check_error(gpgme_error_t err) { PyObject *exc; if (err == GPG_ERR_NO_ERROR) return 0; exc = pygpgme_error_object(err); if (!exc) return -1; PyErr_SetObject(pygpgme_error, exc); return -1; } gpgme_error_t pygpgme_check_pyerror(void) { PyObject *err_type, *err_value, *err_traceback; gpgme_error_t err; PyObject *args = NULL, *source = NULL, *code = NULL; if (!PyErr_Occurred()) return GPG_ERR_NO_ERROR; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); err = gpgme_error(GPG_ERR_GENERAL); /* get the first argument of the exception */ args = PyObject_GetAttrString(err_value, "args"); if (args == NULL) goto end; source = PyTuple_GetItem(args, 0); if (source == NULL) goto end; if (PyErr_GivenExceptionMatches(err_type, pygpgme_error)) { code = PyTuple_GetItem(args, 1); if (code == NULL) goto end; if (PyInt_Check(source) && PyInt_Check(code)) err = gpgme_err_make(PyInt_AsLong(source), PyInt_AsLong(code)); } else if (PyErr_GivenExceptionMatches(err_type, PyExc_IOError) || PyErr_GivenExceptionMatches(err_type, PyExc_OSError)) { if (PyInt_Check(source)) err = gpgme_err_code_from_errno(PyInt_AsLong(source)); } end: Py_XDECREF(err_type); Py_XDECREF(err_value); Py_XDECREF(err_traceback); Py_XDECREF(args); PyErr_Clear(); return err; } int pygpgme_no_constructor(PyObject *self, PyObject *args, PyObject *kwargs) { PyErr_Format(PyExc_NotImplementedError, "can not directly create instances of %s", self->ob_type->tp_name); return -1; } pygpgme-0.3/src/pygpgme-data.c0000644000175000017500000001146511622631741016570 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "pygpgme.h" /* called when a Python exception is set. Clears the exception and tries * to set errno appropriately. */ static void set_errno(void) { PyObject *exc, *value, *tb, *py_errno; PyErr_Fetch(&exc, &value, &tb); /* if we have an IOError, try and get the actual errno */ if (PyErr_GivenExceptionMatches(exc, PyExc_IOError) && value != NULL) { py_errno = PyObject_GetAttrString(value, "errno"); if (py_errno != NULL && PyInt_Check(py_errno)) { errno = PyInt_AsLong(py_errno); } else { PyErr_Clear(); errno = EINVAL; } Py_XDECREF(py_errno); } else { errno = EINVAL; } Py_XDECREF(tb); Py_XDECREF(value); Py_DECREF(exc); } static ssize_t read_cb(void *handle, void *buffer, size_t size) { PyGILState_STATE state; PyObject *fp = handle; PyObject *result; int result_size; state = PyGILState_Ensure(); result = PyObject_CallMethod(fp, "read", "l", (long)size); /* check for exceptions or non-string return values */ if (result == NULL) { set_errno(); result_size = -1; goto end; } /* if we don't have a string return value, consider that an error too */ if (!PyBytes_Check(result)) { Py_DECREF(result); errno = EINVAL; result_size = -1; goto end; } /* copy the result into the given buffer */ result_size = PyBytes_Size(result); if (result_size > size) result_size = size; memcpy(buffer, PyBytes_AsString(result), result_size); Py_DECREF(result); end: PyGILState_Release(state); return result_size; } static ssize_t write_cb(void *handle, const void *buffer, size_t size) { PyGILState_STATE state; PyObject *fp = handle; PyObject *py_buffer = NULL; PyObject *result = NULL; ssize_t bytes_written = -1; state = PyGILState_Ensure(); py_buffer = PyBytes_FromStringAndSize(buffer, size); if (py_buffer == NULL) { set_errno(); goto end; } result = PyObject_CallMethod(fp, "write", "O", py_buffer); if (result == NULL) { set_errno(); goto end; } bytes_written = size; end: Py_XDECREF(result); Py_XDECREF(py_buffer); PyGILState_Release(state); return bytes_written; } static off_t seek_cb(void *handle, off_t offset, int whence) { PyGILState_STATE state; PyObject *fp = handle; PyObject *result; state = PyGILState_Ensure(); result = PyObject_CallMethod(fp, "seek", "li", (long)offset, whence); if (result == NULL) { set_errno(); offset = -1; goto end; } Py_DECREF(result); /* now get the file location */ result = PyObject_CallMethod(fp, "tell", NULL); if (result == NULL) { set_errno(); offset = -1; goto end; } if (!PyInt_Check(result)) { Py_DECREF(result); errno = EINVAL; offset = -1; goto end; } offset = PyInt_AsLong(result); Py_DECREF(result); end: PyGILState_Release(state); return offset; } static void release_cb(void *handle) { PyGILState_STATE state; PyObject *fp = handle; state = PyGILState_Ensure(); Py_DECREF(fp); PyGILState_Release(state); } static struct gpgme_data_cbs python_data_cbs = { .read = read_cb, .write = write_cb, .seek = seek_cb, .release = release_cb, }; /* create a gpgme data object wrapping a Python file like object */ int pygpgme_data_new(gpgme_data_t *dh, PyObject *fp) { gpgme_error_t error; if (fp == Py_None) { *dh = NULL; return 0; } error = gpgme_data_new_from_cbs(dh, &python_data_cbs, fp); if (pygpgme_check_error(error)) { *dh = NULL; return -1; } /* if no error, then the new gpgme_data_t object owns a reference to * the python object */ Py_INCREF(fp); return 0; } pygpgme-0.3/src/pygpgme-key.c0000644000175000017500000004056711622631741016454 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "pygpgme.h" static void pygpgme_subkey_dealloc(PyGpgmeSubkey *self) { self->subkey = NULL; Py_XDECREF(self->parent); self->parent = NULL; PyObject_Del(self); } static PyObject * pygpgme_subkey_get_revoked(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->revoked); } static PyObject * pygpgme_subkey_get_expired(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->expired); } static PyObject * pygpgme_subkey_get_disabled(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->disabled); } static PyObject * pygpgme_subkey_get_invalid(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->invalid); } static PyObject * pygpgme_subkey_get_can_encrypt(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->can_encrypt); } static PyObject * pygpgme_subkey_get_can_sign(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->can_sign); } static PyObject * pygpgme_subkey_get_can_certify(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->can_certify); } static PyObject * pygpgme_subkey_get_secret(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->secret); } static PyObject * pygpgme_subkey_get_can_authenticate(PyGpgmeSubkey *self) { return PyBool_FromLong(self->subkey->can_authenticate); } static PyObject * pygpgme_subkey_get_pubkey_algo(PyGpgmeSubkey *self) { return PyInt_FromLong(self->subkey->pubkey_algo); } static PyObject * pygpgme_subkey_get_length(PyGpgmeSubkey *self) { return PyInt_FromLong(self->subkey->length); } static PyObject * pygpgme_subkey_get_keyid(PyGpgmeSubkey *self) { if (self->subkey->keyid) return PyUnicode_DecodeASCII(self->subkey->keyid, strlen(self->subkey->keyid), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_subkey_get_fpr(PyGpgmeSubkey *self) { if (self->subkey->fpr) return PyUnicode_DecodeASCII(self->subkey->fpr, strlen(self->subkey->fpr), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_subkey_get_timestamp(PyGpgmeSubkey *self) { return PyInt_FromLong(self->subkey->timestamp); } static PyObject * pygpgme_subkey_get_expires(PyGpgmeSubkey *self) { return PyInt_FromLong(self->subkey->expires); } static PyGetSetDef pygpgme_subkey_getsets[] = { { "revoked", (getter)pygpgme_subkey_get_revoked }, { "expired", (getter)pygpgme_subkey_get_expired }, { "disabled", (getter)pygpgme_subkey_get_disabled }, { "invalid", (getter)pygpgme_subkey_get_invalid }, { "can_encrypt", (getter)pygpgme_subkey_get_can_encrypt }, { "can_sign", (getter)pygpgme_subkey_get_can_sign }, { "can_certify", (getter)pygpgme_subkey_get_can_certify }, { "secret", (getter)pygpgme_subkey_get_secret }, { "can_authenticate", (getter)pygpgme_subkey_get_can_authenticate }, { "pubkey_algo", (getter)pygpgme_subkey_get_pubkey_algo }, { "length", (getter)pygpgme_subkey_get_length }, { "keyid", (getter)pygpgme_subkey_get_keyid }, { "fpr", (getter)pygpgme_subkey_get_fpr }, { "timestamp", (getter)pygpgme_subkey_get_timestamp }, { "expires", (getter)pygpgme_subkey_get_expires }, { NULL, (getter)0, (setter)0 } }; PyTypeObject PyGpgmeSubkey_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.Subkey", sizeof(PyGpgmeSubkey), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_subkey_dealloc, .tp_getset = pygpgme_subkey_getsets, }; static void pygpgme_key_sig_dealloc(PyGpgmeKeySig *self) { self->key_sig = NULL; Py_XDECREF(self->parent); self->parent = NULL; PyObject_Del(self); } static PyObject * pygpgme_key_sig_get_revoked(PyGpgmeKeySig *self) { return PyBool_FromLong(self->key_sig->revoked); } static PyObject * pygpgme_key_sig_get_expired(PyGpgmeKeySig *self) { return PyBool_FromLong(self->key_sig->expired); } static PyObject * pygpgme_key_sig_get_invalid(PyGpgmeKeySig *self) { return PyBool_FromLong(self->key_sig->invalid); } static PyObject * pygpgme_key_sig_get_exportable(PyGpgmeKeySig *self) { return PyBool_FromLong(self->key_sig->exportable); } static PyObject * pygpgme_key_sig_get_pubkey_algo(PyGpgmeKeySig *self) { return PyInt_FromLong(self->key_sig->pubkey_algo); } static PyObject * pygpgme_key_sig_get_keyid(PyGpgmeKeySig *self) { if (self->key_sig->keyid) return PyUnicode_DecodeASCII(self->key_sig->keyid, strlen(self->key_sig->keyid), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_sig_get_timestamp(PyGpgmeKeySig *self) { return PyInt_FromLong(self->key_sig->timestamp); } static PyObject * pygpgme_key_sig_get_expires(PyGpgmeKeySig *self) { return PyInt_FromLong(self->key_sig->expires); } static PyObject * pygpgme_key_sig_get_status(PyGpgmeKeySig *self) { return pygpgme_error_object(self->key_sig->status); } static PyObject * pygpgme_key_sig_get_uid(PyGpgmeKeySig *self) { if (self->key_sig->uid) return PyUnicode_DecodeUTF8(self->key_sig->uid, strlen(self->key_sig->uid), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_sig_get_name(PyGpgmeKeySig *self) { if (self->key_sig->name) return PyUnicode_DecodeUTF8(self->key_sig->name, strlen(self->key_sig->name), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_sig_get_email(PyGpgmeKeySig *self) { if (self->key_sig->email) return PyUnicode_DecodeUTF8(self->key_sig->email, strlen(self->key_sig->email), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_sig_get_comment(PyGpgmeKeySig *self) { if (self->key_sig->comment) return PyUnicode_DecodeUTF8(self->key_sig->comment, strlen(self->key_sig->comment), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_sig_get_sig_class(PyGpgmeKeySig *self) { return PyInt_FromLong(self->key_sig->sig_class); } static PyGetSetDef pygpgme_key_sig_getsets[] = { { "revoked", (getter)pygpgme_key_sig_get_revoked }, { "expired", (getter)pygpgme_key_sig_get_expired }, { "invalid", (getter)pygpgme_key_sig_get_invalid }, { "exportable", (getter)pygpgme_key_sig_get_exportable }, { "pubkey_algo", (getter)pygpgme_key_sig_get_pubkey_algo }, { "keyid", (getter)pygpgme_key_sig_get_keyid }, { "timestamp", (getter)pygpgme_key_sig_get_timestamp }, { "expires", (getter)pygpgme_key_sig_get_expires }, { "status", (getter)pygpgme_key_sig_get_status }, { "uid", (getter)pygpgme_key_sig_get_uid }, { "name", (getter)pygpgme_key_sig_get_name }, { "email", (getter)pygpgme_key_sig_get_email }, { "comment", (getter)pygpgme_key_sig_get_comment }, { "sig_class", (getter)pygpgme_key_sig_get_sig_class }, { NULL, (getter)0, (setter)0 } }; PyTypeObject PyGpgmeKeySig_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.KeySig", sizeof(PyGpgmeKeySig), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_key_sig_dealloc, .tp_getset = pygpgme_key_sig_getsets, }; static void pygpgme_user_id_dealloc(PyGpgmeUserId *self) { self->user_id = NULL; Py_XDECREF(self->parent); self->parent = NULL; PyObject_Del(self); } static PyObject * pygpgme_user_id_get_revoked(PyGpgmeUserId *self) { return PyBool_FromLong(self->user_id->revoked); } static PyObject * pygpgme_user_id_get_invalid(PyGpgmeUserId *self) { return PyBool_FromLong(self->user_id->invalid); } static PyObject * pygpgme_user_id_get_validity(PyGpgmeUserId *self) { return PyInt_FromLong(self->user_id->validity); } static PyObject * pygpgme_user_id_get_uid(PyGpgmeUserId *self) { if (self->user_id->uid) return PyUnicode_DecodeUTF8(self->user_id->uid, strlen(self->user_id->uid), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_user_id_get_name(PyGpgmeUserId *self) { if (self->user_id->name) return PyUnicode_DecodeUTF8(self->user_id->name, strlen(self->user_id->name), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_user_id_get_email(PyGpgmeUserId *self) { if (self->user_id->email) return PyUnicode_DecodeUTF8(self->user_id->email, strlen(self->user_id->email), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_user_id_get_comment(PyGpgmeUserId *self) { if (self->user_id->comment) return PyUnicode_DecodeUTF8(self->user_id->comment, strlen(self->user_id->comment), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_user_id_get_signatures(PyGpgmeUserId *self) { PyObject *ret; gpgme_key_sig_t sig; ret = PyList_New(0); if (ret == NULL) return NULL; for (sig = self->user_id->signatures; sig != NULL; sig = sig->next) { PyGpgmeKeySig *item; item = PyObject_New(PyGpgmeKeySig, &PyGpgmeKeySig_Type); if (item == NULL) { Py_DECREF(ret); return NULL; } item->key_sig = sig; Py_INCREF(self); item->parent = (PyObject *)self; PyList_Append(ret, (PyObject *)item); Py_DECREF(item); } return ret; } static PyGetSetDef pygpgme_user_id_getsets[] = { { "revoked", (getter)pygpgme_user_id_get_revoked }, { "invalid", (getter)pygpgme_user_id_get_invalid }, { "validity", (getter)pygpgme_user_id_get_validity }, { "uid", (getter)pygpgme_user_id_get_uid }, { "name", (getter)pygpgme_user_id_get_name }, { "email", (getter)pygpgme_user_id_get_email }, { "comment", (getter)pygpgme_user_id_get_comment }, { "signatures", (getter)pygpgme_user_id_get_signatures }, { NULL, (getter)0, (setter)0 } }; PyTypeObject PyGpgmeUserId_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.UserId", sizeof(PyGpgmeUserId), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_user_id_dealloc, .tp_getset = pygpgme_user_id_getsets, }; static void pygpgme_key_dealloc(PyGpgmeKey *self) { gpgme_key_unref(self->key); self->key = NULL; PyObject_Del(self); } static PyObject * pygpgme_key_get_revoked(PyGpgmeKey *self) { return PyBool_FromLong(self->key->revoked); } static PyObject * pygpgme_key_get_expired(PyGpgmeKey *self) { return PyBool_FromLong(self->key->expired); } static PyObject * pygpgme_key_get_disabled(PyGpgmeKey *self) { return PyBool_FromLong(self->key->disabled); } static PyObject * pygpgme_key_get_invalid(PyGpgmeKey *self) { return PyBool_FromLong(self->key->invalid); } static PyObject * pygpgme_key_get_can_encrypt(PyGpgmeKey *self) { return PyBool_FromLong(self->key->can_encrypt); } static PyObject * pygpgme_key_get_can_sign(PyGpgmeKey *self) { return PyBool_FromLong(self->key->can_sign); } static PyObject * pygpgme_key_get_can_certify(PyGpgmeKey *self) { return PyBool_FromLong(self->key->can_certify); } static PyObject * pygpgme_key_get_secret(PyGpgmeKey *self) { return PyBool_FromLong(self->key->secret); } static PyObject * pygpgme_key_get_can_authenticate(PyGpgmeKey *self) { return PyBool_FromLong(self->key->can_authenticate); } static PyObject * pygpgme_key_get_protocol(PyGpgmeKey *self) { return PyInt_FromLong(self->key->protocol); } static PyObject * pygpgme_key_get_issuer_serial(PyGpgmeKey *self) { if (self->key->issuer_serial) /* Haven't tested this, so perhaps it should be UTF8 */ return PyUnicode_DecodeASCII(self->key->issuer_serial, strlen(self->key->issuer_serial), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_get_issuer_name(PyGpgmeKey *self) { if (self->key->issuer_name) return PyUnicode_DecodeUTF8(self->key->issuer_name, strlen(self->key->issuer_name), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_get_chain_id(PyGpgmeKey *self) { if (self->key->chain_id) /* Haven't tested this, so perhaps it should be UTF8 */ return PyUnicode_DecodeASCII(self->key->chain_id, strlen(self->key->chain_id), "replace"); else Py_RETURN_NONE; } static PyObject * pygpgme_key_get_owner_trust(PyGpgmeKey *self) { return PyInt_FromLong(self->key->owner_trust); } static PyObject * pygpgme_key_get_subkeys(PyGpgmeKey *self) { PyObject *ret; gpgme_subkey_t subkey; ret = PyList_New(0); if (ret == NULL) return NULL; for (subkey = self->key->subkeys; subkey != NULL; subkey = subkey->next) { PyGpgmeSubkey *item; item = PyObject_New(PyGpgmeSubkey, &PyGpgmeSubkey_Type); if (item == NULL) { Py_DECREF(ret); return NULL; } item->subkey = subkey; Py_INCREF(self); item->parent = (PyObject *)self; PyList_Append(ret, (PyObject *)item); Py_DECREF(item); } return ret; } static PyObject * pygpgme_key_get_uids(PyGpgmeKey *self) { PyObject *ret; gpgme_user_id_t uid; ret = PyList_New(0); if (ret == NULL) return NULL; for (uid = self->key->uids; uid != NULL; uid = uid->next) { PyGpgmeUserId *item; item = PyObject_New(PyGpgmeUserId, &PyGpgmeUserId_Type); if (item == NULL) { Py_DECREF(ret); return NULL; } item->user_id = uid; Py_INCREF(self); item->parent = (PyObject *)self; PyList_Append(ret, (PyObject *)item); Py_DECREF(item); } return ret; } static PyObject * pygpgme_key_get_keylist_mode(PyGpgmeKey *self) { return PyInt_FromLong(self->key->keylist_mode); } static PyGetSetDef pygpgme_key_getsets[] = { { "revoked", (getter)pygpgme_key_get_revoked }, { "expired", (getter)pygpgme_key_get_expired }, { "disabled", (getter)pygpgme_key_get_disabled }, { "invalid", (getter)pygpgme_key_get_invalid }, { "can_encrypt", (getter)pygpgme_key_get_can_encrypt }, { "can_sign", (getter)pygpgme_key_get_can_sign }, { "can_certify", (getter)pygpgme_key_get_can_certify }, { "secret", (getter)pygpgme_key_get_secret }, { "can_authenticate", (getter)pygpgme_key_get_can_authenticate }, { "protocol", (getter)pygpgme_key_get_protocol }, { "issuer_serial", (getter)pygpgme_key_get_issuer_serial }, { "issuer_name", (getter)pygpgme_key_get_issuer_name }, { "chain_id", (getter)pygpgme_key_get_chain_id }, { "owner_trust", (getter)pygpgme_key_get_owner_trust }, { "subkeys", (getter)pygpgme_key_get_subkeys }, { "uids", (getter)pygpgme_key_get_uids }, { "keylist_mode", (getter)pygpgme_key_get_keylist_mode }, { NULL, (getter)0, (setter)0 } }; PyTypeObject PyGpgmeKey_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.Key", sizeof(PyGpgmeKey), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_key_dealloc, .tp_getset = pygpgme_key_getsets, }; PyObject * pygpgme_key_new(gpgme_key_t key) { PyGpgmeKey *self; self = PyObject_New(PyGpgmeKey, &PyGpgmeKey_Type); if (self == NULL) return NULL; gpgme_key_ref(key); self->key = key; return (PyObject *)self; } pygpgme-0.3/src/pygpgme-genkey.c0000644000175000017500000000461211622631741017135 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" #include static void pygpgme_genkey_result_dealloc(PyGpgmeGenkeyResult *self) { Py_XDECREF(self->primary); Py_XDECREF(self->sub); Py_XDECREF(self->fpr); PyObject_Del(self); } static PyMemberDef pygpgme_genkey_result_members[] = { { "primary", T_OBJECT, offsetof(PyGpgmeGenkeyResult, primary), READONLY}, { "sub", T_OBJECT, offsetof(PyGpgmeGenkeyResult, sub), READONLY}, { "fpr", T_OBJECT, offsetof(PyGpgmeGenkeyResult, fpr), READONLY}, { NULL, 0, 0, 0} }; PyTypeObject PyGpgmeGenkeyResult_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.GenkeyResult", sizeof(PyGpgmeGenkeyResult), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_genkey_result_dealloc, .tp_members = pygpgme_genkey_result_members, }; PyObject * pygpgme_genkey_result(gpgme_ctx_t ctx) { gpgme_genkey_result_t result; PyGpgmeGenkeyResult *self; result = gpgme_op_genkey_result(ctx); if (result == NULL) Py_RETURN_NONE; self = PyObject_New(PyGpgmeGenkeyResult, &PyGpgmeGenkeyResult_Type); if (!self) return NULL; self->primary = PyBool_FromLong(result->primary); self->sub = PyBool_FromLong(result->sub); if (result->fpr) self->fpr = PyUnicode_DecodeASCII(result->fpr, strlen(result->fpr), "replace"); else { Py_INCREF(Py_None); self->fpr = Py_None; } return (PyObject *) self; } pygpgme-0.3/src/gpgme.c0000644000175000017500000000664211722716025015311 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "pygpgme.h" static PyMethodDef pygpgme_functions[] = { { "make_constants", (PyCFunction)pygpgme_make_constants, METH_VARARGS }, { NULL, NULL, 0 } }; #if PY_VERSION_HEX >= 0x03000000 static PyModuleDef pygpgme_module = { PyModuleDef_HEAD_INIT, "gpgme._gpgme", .m_size = -1, .m_methods = pygpgme_functions }; #endif static PyObject * create_module(void) { const char *gpgme_version; PyObject *mod; pygpgme_error = PyErr_NewException("gpgme.GpgmeError", PyExc_RuntimeError, NULL); #define INIT_TYPE(type) \ if (!Py_TYPE(&type)) \ Py_TYPE(&type) = &PyType_Type; \ if (!type.tp_alloc) \ type.tp_alloc = PyType_GenericAlloc; \ if (!type.tp_new) \ type.tp_new = PyType_GenericNew; \ if (PyType_Ready(&type) < 0) \ return NULL #define ADD_TYPE(type) \ Py_INCREF(&PyGpgme ## type ## _Type); \ PyModule_AddObject(mod, #type, (PyObject *)&PyGpgme ## type ## _Type) INIT_TYPE(PyGpgmeContext_Type); INIT_TYPE(PyGpgmeKey_Type); INIT_TYPE(PyGpgmeSubkey_Type); INIT_TYPE(PyGpgmeUserId_Type); INIT_TYPE(PyGpgmeKeySig_Type); INIT_TYPE(PyGpgmeNewSignature_Type); INIT_TYPE(PyGpgmeSignature_Type); INIT_TYPE(PyGpgmeImportResult_Type); INIT_TYPE(PyGpgmeGenkeyResult_Type); INIT_TYPE(PyGpgmeKeyIter_Type); #if PY_VERSION_HEX >= 0x03000000 mod = PyModule_Create(&pygpgme_module); #else mod = Py_InitModule("gpgme._gpgme", pygpgme_functions); #endif ADD_TYPE(Context); ADD_TYPE(Key); ADD_TYPE(Subkey); ADD_TYPE(UserId); ADD_TYPE(KeySig); ADD_TYPE(NewSignature); ADD_TYPE(Signature); ADD_TYPE(ImportResult); ADD_TYPE(GenkeyResult); ADD_TYPE(KeyIter); Py_INCREF(pygpgme_error); PyModule_AddObject(mod, "GpgmeError", pygpgme_error); gpgme_version = gpgme_check_version(NULL); if (gpgme_version == NULL) { PyErr_SetString(PyExc_ImportError, "Unable to initialize gpgme."); Py_DECREF(mod); return NULL; } PyModule_AddObject(mod, "gpgme_version", PyUnicode_DecodeASCII(gpgme_version, strlen(gpgme_version), "replace")); return mod; } #if PY_VERSION_HEX >= 0x03000000 PyMODINIT_FUNC PyInit__gpgme(void) { return create_module(); } #else PyMODINIT_FUNC init_gpgme(void) { create_module(); } #endif pygpgme-0.3/src/pygpgme-context.c0000644000175000017500000010607411724064752017351 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" static gpgme_error_t pygpgme_passphrase_cb(void *hook, const char *uid_hint, const char *passphrase_info, int prev_was_bad, int fd) { PyObject *callback, *ret; PyGILState_STATE state; gpgme_error_t err; state = PyGILState_Ensure(); callback = (PyObject *)hook; ret = PyObject_CallFunction(callback, "zzii", uid_hint, passphrase_info, prev_was_bad, fd); err = pygpgme_check_pyerror(); Py_XDECREF(ret); PyGILState_Release(state); return err; } static void pygpgme_progress_cb(void *hook, const char *what, int type, int current, int total) { PyObject *callback, *ret; PyGILState_STATE state; state = PyGILState_Ensure(); callback = (PyObject *)hook; ret = PyObject_CallFunction(callback, "ziii", what, type, current, total); PyErr_Clear(); Py_XDECREF(ret); PyGILState_Release(state); } static void pygpgme_context_dealloc(PyGpgmeContext *self) { gpgme_passphrase_cb_t passphrase_cb; gpgme_progress_cb_t progress_cb; PyObject *callback; if (self->ctx) { /* free the passphrase callback */ gpgme_get_passphrase_cb(self->ctx, &passphrase_cb, (void **)&callback); if (passphrase_cb == pygpgme_passphrase_cb) { Py_DECREF(callback); } /* free the progress callback */ gpgme_get_progress_cb(self->ctx, &progress_cb, (void **)&callback); if (progress_cb == pygpgme_progress_cb) { Py_DECREF(callback); } gpgme_release(self->ctx); } self->ctx = NULL; PyObject_Del(self); } static int pygpgme_context_init(PyGpgmeContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { NULL }; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist)) return -1; if (self->ctx != NULL) { PyErr_SetString(PyExc_ValueError, "context already initialised"); return -1; } if (pygpgme_check_error(gpgme_new(&self->ctx))) return -1; return 0; } static PyObject * pygpgme_context_get_protocol(PyGpgmeContext *self) { return PyInt_FromLong(gpgme_get_protocol(self->ctx)); } static int pygpgme_context_set_protocol(PyGpgmeContext *self, PyObject *value) { gpgme_protocol_t protocol; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } protocol = PyInt_AsLong(value); if (PyErr_Occurred()) return -1; if (pygpgme_check_error(gpgme_set_protocol(self->ctx, protocol))) return -1; return 0; } static PyObject * pygpgme_context_get_armor(PyGpgmeContext *self) { return PyBool_FromLong(gpgme_get_armor(self->ctx)); } static int pygpgme_context_set_armor(PyGpgmeContext *self, PyObject *value) { int armor; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } armor = PyInt_AsLong(value) != 0; if (PyErr_Occurred()) return -1; gpgme_set_armor(self->ctx, armor); return 0; } static PyObject * pygpgme_context_get_textmode(PyGpgmeContext *self) { return PyBool_FromLong(gpgme_get_textmode(self->ctx)); } static int pygpgme_context_set_textmode(PyGpgmeContext *self, PyObject *value) { int textmode; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } textmode = PyInt_AsLong(value) != 0; if (PyErr_Occurred()) return -1; gpgme_set_textmode(self->ctx, textmode); return 0; } static PyObject * pygpgme_context_get_include_certs(PyGpgmeContext *self) { return PyInt_FromLong(gpgme_get_include_certs(self->ctx)); } static int pygpgme_context_set_include_certs(PyGpgmeContext *self, PyObject *value) { int nr_of_certs; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } nr_of_certs = PyInt_AsLong(value); if (PyErr_Occurred()) return -1; gpgme_set_include_certs(self->ctx, nr_of_certs); return 0; } static PyObject * pygpgme_context_get_keylist_mode(PyGpgmeContext *self) { return PyInt_FromLong(gpgme_get_keylist_mode(self->ctx)); } static int pygpgme_context_set_keylist_mode(PyGpgmeContext *self, PyObject *value) { gpgme_keylist_mode_t keylist_mode; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } keylist_mode = PyInt_AsLong(value); if (PyErr_Occurred()) return -1; if (pygpgme_check_error(gpgme_set_keylist_mode(self->ctx, keylist_mode))) return -1; return 0; } static PyObject * pygpgme_context_get_passphrase_cb(PyGpgmeContext *self) { gpgme_passphrase_cb_t passphrase_cb; PyObject *callback; /* free the passphrase callback */ gpgme_get_passphrase_cb(self->ctx, &passphrase_cb, (void **)&callback); if (passphrase_cb == pygpgme_passphrase_cb) { Py_INCREF(callback); return callback; } else { Py_RETURN_NONE; } } static int pygpgme_context_set_passphrase_cb(PyGpgmeContext *self, PyObject *value) { gpgme_passphrase_cb_t passphrase_cb; PyObject *callback; /* free the passphrase callback */ gpgme_get_passphrase_cb(self->ctx, &passphrase_cb, (void **)&callback); if (passphrase_cb == pygpgme_passphrase_cb) { Py_DECREF(callback); } /* callback of None == unset */ if (value == Py_None) value = NULL; if (value != NULL) { Py_INCREF(value); gpgme_set_passphrase_cb(self->ctx, pygpgme_passphrase_cb, value); } else { gpgme_set_passphrase_cb(self->ctx, NULL, NULL); } return 0; } static PyObject * pygpgme_context_get_progress_cb(PyGpgmeContext *self) { gpgme_progress_cb_t progress_cb; PyObject *callback; /* free the progress callback */ gpgme_get_progress_cb(self->ctx, &progress_cb, (void **)&callback); if (progress_cb == pygpgme_progress_cb) { Py_INCREF(callback); return callback; } else { Py_RETURN_NONE; } } static int pygpgme_context_set_progress_cb(PyGpgmeContext *self, PyObject *value) { gpgme_progress_cb_t progress_cb; PyObject *callback; /* free the progress callback */ gpgme_get_progress_cb(self->ctx, &progress_cb, (void **)&callback); if (progress_cb == pygpgme_progress_cb) { Py_DECREF(callback); } /* callback of None == unset */ if (value == Py_None) value = NULL; if (value != NULL) { Py_INCREF(value); gpgme_set_progress_cb(self->ctx, pygpgme_progress_cb, value); } else { gpgme_set_progress_cb(self->ctx, NULL, NULL); } return 0; } static PyObject * pygpgme_context_get_signers(PyGpgmeContext *self) { PyObject *list, *tuple; gpgme_key_t key; int i; list = PyList_New(0); for (i = 0, key = gpgme_signers_enum(self->ctx, 0); key != NULL; key = gpgme_signers_enum(self->ctx, ++i)) { PyObject *item; item = pygpgme_key_new(key); gpgme_key_unref(key); if (item == NULL) { Py_DECREF(list); return NULL; } PyList_Append(list, item); Py_DECREF(item); } tuple = PySequence_Tuple(list); Py_DECREF(list); return tuple; } static int pygpgme_context_set_signers(PyGpgmeContext *self, PyObject *value) { PyObject *signers = NULL; int i, length, ret = 0; if (value == NULL) { PyErr_SetString(PyExc_AttributeError, "Can not delete attribute"); return -1; } signers = PySequence_Fast(value, "signers must be a sequence of keys"); if (!signers) { ret = -1; goto end; } gpgme_signers_clear(self->ctx); length = PySequence_Fast_GET_SIZE(signers); for (i = 0; i < length; i++) { PyObject *item = PySequence_Fast_GET_ITEM(signers, i); if (!PyObject_TypeCheck(item, &PyGpgmeKey_Type)) { PyErr_SetString(PyExc_TypeError, "signers must be a sequence of keys"); ret = -1; goto end; } gpgme_signers_add(self->ctx, ((PyGpgmeKey *)item)->key); } end: Py_XDECREF(signers); return ret; } static PyGetSetDef pygpgme_context_getsets[] = { { "protocol", (getter)pygpgme_context_get_protocol, (setter)pygpgme_context_set_protocol }, { "armor", (getter)pygpgme_context_get_armor, (setter)pygpgme_context_set_armor }, { "textmode", (getter)pygpgme_context_get_textmode, (setter)pygpgme_context_set_textmode }, { "include_certs", (getter)pygpgme_context_get_include_certs, (setter)pygpgme_context_set_include_certs }, { "keylist_mode", (getter)pygpgme_context_get_keylist_mode, (setter)pygpgme_context_set_keylist_mode }, { "passphrase_cb", (getter)pygpgme_context_get_passphrase_cb, (setter)pygpgme_context_set_passphrase_cb }, { "progress_cb", (getter)pygpgme_context_get_progress_cb, (setter)pygpgme_context_set_progress_cb }, { "signers", (getter)pygpgme_context_get_signers, (setter)pygpgme_context_set_signers }, { NULL, (getter)0, (setter)0 } }; static PyObject * pygpgme_context_set_engine_info(PyGpgmeContext *self, PyObject *args) { int protocol; const char *file_name, *home_dir; if (!PyArg_ParseTuple(args, "izz", &protocol, &file_name, &home_dir)) return NULL; if (pygpgme_check_error(gpgme_ctx_set_engine_info(self->ctx, protocol, file_name, home_dir))) return NULL; Py_RETURN_NONE; } static PyObject * pygpgme_context_set_locale(PyGpgmeContext *self, PyObject *args) { int category; const char *value; if (!PyArg_ParseTuple(args, "iz", &category, &value)) return NULL; if (pygpgme_check_error(gpgme_set_locale(self->ctx, category, value))) return NULL; Py_RETURN_NONE; } static PyObject * pygpgme_context_get_key(PyGpgmeContext *self, PyObject *args) { const char *fpr; int secret = 0; gpgme_error_t err; gpgme_key_t key; PyObject *ret; if (!PyArg_ParseTuple(args, "s|i", &fpr, &secret)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_get_key(self->ctx, fpr, &key, secret); Py_END_ALLOW_THREADS; if (pygpgme_check_error(err)) return NULL; ret = pygpgme_key_new(key); gpgme_key_unref(key); return ret; } /* XXX: cancel -- not needed unless we wrap the async calls */ /* annotate exception with encrypt_result data */ static void decode_encrypt_result(PyGpgmeContext *self) { PyObject *err_type, *err_value, *err_traceback; gpgme_encrypt_result_t res; gpgme_invalid_key_t key; PyObject *list; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; res = gpgme_op_encrypt_result(self->ctx); if (res == NULL) goto end; list = PyList_New(0); for (key = res->invalid_recipients; key != NULL; key = key->next) { PyObject *item, *py_fpr, *err; if (key->fpr) py_fpr = PyUnicode_DecodeASCII(key->fpr, strlen(key->fpr), "replace"); else { py_fpr = Py_None; Py_INCREF(py_fpr); } err = pygpgme_error_object(key->reason); item = Py_BuildValue("(NN)", py_fpr, err); PyList_Append(list, item); Py_DECREF(item); } PyObject_SetAttrString(err_value, "invalid_recipients", list); Py_DECREF(list); end: PyErr_Restore(err_type, err_value, err_traceback); } static PyObject * pygpgme_context_encrypt(PyGpgmeContext *self, PyObject *args) { PyObject *py_recp, *py_plain, *py_cipher, *recp_seq = NULL, *result = NULL; int flags, i, length; gpgme_key_t *recp = NULL; gpgme_data_t plain = NULL, cipher = NULL; gpgme_error_t err; if (!PyArg_ParseTuple(args, "OiOO", &py_recp, &flags, &py_plain, &py_cipher)) goto end; if (py_recp != Py_None) { recp_seq = PySequence_Fast(py_recp, "first argument must be a " "sequence or None"); if (recp_seq == NULL) goto end; length = PySequence_Fast_GET_SIZE(recp_seq); recp = malloc((length + 1) * sizeof (gpgme_key_t)); for (i = 0; i < length; i++) { PyObject *item = PySequence_Fast_GET_ITEM(recp_seq, i); if (!PyObject_TypeCheck(item, &PyGpgmeKey_Type)) { PyErr_SetString(PyExc_TypeError, "items in first argument " "must be gpgme.Key objects"); goto end; } recp[i] = ((PyGpgmeKey *)item)->key; } recp[i] = NULL; } if (pygpgme_data_new(&plain, py_plain)) goto end; if (pygpgme_data_new(&cipher, py_cipher)) goto end; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_encrypt(self->ctx, recp, flags, plain, cipher); Py_END_ALLOW_THREADS; if (pygpgme_check_error(err)) { decode_encrypt_result(self); goto end; } Py_INCREF(Py_None); result = Py_None; end: if (recp != NULL) free(recp); Py_XDECREF(recp_seq); if (plain != NULL) gpgme_data_release(plain); if (cipher != NULL) gpgme_data_release(cipher); return result; } static PyObject * pygpgme_context_encrypt_sign(PyGpgmeContext *self, PyObject *args) { PyObject *py_recp, *py_plain, *py_cipher, *recp_seq = NULL, *result = NULL; int flags, i, length; gpgme_key_t *recp = NULL; gpgme_data_t plain = NULL, cipher = NULL; gpgme_error_t err; gpgme_sign_result_t sign_result; if (!PyArg_ParseTuple(args, "OiOO", &py_recp, &flags, &py_plain, &py_cipher)) goto end; recp_seq = PySequence_Fast(py_recp, "first argument must be a sequence"); if (recp_seq == NULL) goto end; length = PySequence_Fast_GET_SIZE(recp_seq); recp = malloc((length + 1) * sizeof (gpgme_key_t)); for (i = 0; i < length; i++) { PyObject *item = PySequence_Fast_GET_ITEM(recp_seq, i); if (!PyObject_TypeCheck(item, &PyGpgmeKey_Type)) { PyErr_SetString(PyExc_TypeError, "items in first argument " "must be gpgme.Key objects"); goto end; } recp[i] = ((PyGpgmeKey *)item)->key; } recp[i] = NULL; if (pygpgme_data_new(&plain, py_plain)) goto end; if (pygpgme_data_new(&cipher, py_cipher)) goto end; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_encrypt_sign(self->ctx, recp, flags, plain, cipher); Py_END_ALLOW_THREADS; sign_result = gpgme_op_sign_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; gpgme_invalid_key_t key; decode_encrypt_result(self); PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (sign_result == NULL) goto error_end; if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto error_end; list = PyList_New(0); for (key = sign_result->invalid_signers; key != NULL; key = key->next) { PyObject *item, *py_fpr, *err; if (key->fpr) py_fpr = PyUnicode_DecodeASCII(key->fpr, strlen(key->fpr), "replace"); else { py_fpr = Py_None; Py_INCREF(py_fpr); } err = pygpgme_error_object(key->reason); item = Py_BuildValue("(NN)", py_fpr, err); PyList_Append(list, item); Py_DECREF(item); } PyObject_SetAttrString(err_value, "invalid_signers", list); Py_DECREF(list); list = pygpgme_newsiglist_new(sign_result->signatures); PyObject_SetAttrString(err_value, "signatures", list); Py_DECREF(list); error_end: PyErr_Restore(err_type, err_value, err_traceback); goto end; } if (sign_result) result = pygpgme_newsiglist_new(sign_result->signatures); else result = PyList_New(0); end: if (recp != NULL) free(recp); Py_XDECREF(recp_seq); if (plain != NULL) gpgme_data_release(plain); if (cipher != NULL) gpgme_data_release(cipher); return result; } static void decode_decrypt_result(PyGpgmeContext *self) { PyObject *err_type, *err_value, *err_traceback; PyObject *value; gpgme_decrypt_result_t res; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; res = gpgme_op_decrypt_result(self->ctx); if (res == NULL) goto end; if (res->unsupported_algorithm) { value = PyUnicode_DecodeUTF8(res->unsupported_algorithm, strlen(res->unsupported_algorithm), "replace"); } else { Py_INCREF(Py_None); value = Py_None; } if (value) { PyObject_SetAttrString(err_value, "unsupported_algorithm", value); Py_DECREF(value); } value = PyBool_FromLong(res->wrong_key_usage); if (value) { PyObject_SetAttrString(err_value, "wrong_key_usage", value); Py_DECREF(value); } end: PyErr_Restore(err_type, err_value, err_traceback); } static PyObject * pygpgme_context_decrypt(PyGpgmeContext *self, PyObject *args) { PyObject *py_cipher, *py_plain; gpgme_data_t cipher, plain; gpgme_error_t err; if (!PyArg_ParseTuple(args, "OO", &py_cipher, &py_plain)) return NULL; if (pygpgme_data_new(&cipher, py_cipher)) { return NULL; } if (pygpgme_data_new(&plain, py_plain)) { gpgme_data_release(cipher); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_decrypt(self->ctx, cipher, plain); Py_END_ALLOW_THREADS; gpgme_data_release(cipher); gpgme_data_release(plain); if (pygpgme_check_error(err)) { decode_decrypt_result(self); return NULL; } Py_RETURN_NONE; } static PyObject * pygpgme_context_decrypt_verify(PyGpgmeContext *self, PyObject *args) { PyObject *py_cipher, *py_plain; gpgme_data_t cipher, plain; gpgme_error_t err; gpgme_verify_result_t result; if (!PyArg_ParseTuple(args, "OO", &py_cipher, &py_plain)) return NULL; if (pygpgme_data_new(&cipher, py_cipher)) { return NULL; } if (pygpgme_data_new(&plain, py_plain)) { gpgme_data_release(cipher); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_decrypt_verify(self->ctx, cipher, plain); Py_END_ALLOW_THREADS; gpgme_data_release(cipher); gpgme_data_release(plain); if (pygpgme_check_error(err)) { decode_decrypt_result(self); return NULL; } result = gpgme_op_verify_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (result == NULL) goto end; if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; list = pygpgme_siglist_new(result->signatures); PyObject_SetAttrString(err_value, "signatures", list); Py_DECREF(list); end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } if (result) return pygpgme_siglist_new(result->signatures); else return PyList_New(0); } static PyObject * pygpgme_context_sign(PyGpgmeContext *self, PyObject *args) { PyObject *py_plain, *py_sig; gpgme_data_t plain, sig; int sig_mode = GPGME_SIG_MODE_NORMAL; gpgme_error_t err; gpgme_sign_result_t result; if (!PyArg_ParseTuple(args, "OO|i", &py_plain, &py_sig, &sig_mode)) return NULL; if (pygpgme_data_new(&plain, py_plain)) return NULL; if (pygpgme_data_new(&sig, py_sig)) { gpgme_data_release(plain); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_sign(self->ctx, plain, sig, sig_mode); Py_END_ALLOW_THREADS; gpgme_data_release(plain); gpgme_data_release(sig); result = gpgme_op_sign_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; gpgme_invalid_key_t key; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (result == NULL) goto end; if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; list = PyList_New(0); for (key = result->invalid_signers; key != NULL; key = key->next) { PyObject *item, *py_fpr, *err; if (key->fpr) py_fpr = PyUnicode_DecodeASCII(key->fpr, strlen(key->fpr), "replace"); else { py_fpr = Py_None; Py_INCREF(py_fpr); } err = pygpgme_error_object(key->reason); item = Py_BuildValue("(NN)", py_fpr, err); PyList_Append(list, item); Py_DECREF(item); } PyObject_SetAttrString(err_value, "invalid_signers", list); Py_DECREF(list); list = pygpgme_newsiglist_new(result->signatures); PyObject_SetAttrString(err_value, "signatures", list); Py_DECREF(list); end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } if (result) return pygpgme_newsiglist_new(result->signatures); else return PyList_New(0); } static PyObject * pygpgme_context_verify(PyGpgmeContext *self, PyObject *args) { PyObject *py_sig, *py_signed_text, *py_plaintext; gpgme_data_t sig, signed_text, plaintext; gpgme_error_t err; gpgme_verify_result_t result; if (!PyArg_ParseTuple(args, "OOO", &py_sig, &py_signed_text, &py_plaintext)) return NULL; if (pygpgme_data_new(&sig, py_sig)) { return NULL; } if (pygpgme_data_new(&signed_text, py_signed_text)) { gpgme_data_release(sig); return NULL; } if (pygpgme_data_new(&plaintext, py_plaintext)) { gpgme_data_release(sig); gpgme_data_release(signed_text); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_verify(self->ctx, sig, signed_text, plaintext); Py_END_ALLOW_THREADS; gpgme_data_release(sig); gpgme_data_release(signed_text); gpgme_data_release(plaintext); result = gpgme_op_verify_result(self->ctx); /* annotate exception */ if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyObject *list; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (result == NULL) goto end; if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; list = pygpgme_siglist_new(result->signatures); PyObject_SetAttrString(err_value, "signatures", list); Py_DECREF(list); end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } if (result) return pygpgme_siglist_new(result->signatures); else return PyList_New(0); } static PyObject * pygpgme_context_import(PyGpgmeContext *self, PyObject *args) { PyObject *py_keydata, *result; gpgme_data_t keydata; gpgme_error_t err; if (!PyArg_ParseTuple(args, "O", &py_keydata)) return NULL; if (pygpgme_data_new(&keydata, py_keydata)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_import(self->ctx, keydata); Py_END_ALLOW_THREADS; gpgme_data_release(keydata); result = pygpgme_import_result(self->ctx); if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; if (result != NULL) { PyObject_SetAttrString(err_value, "result", result); Py_DECREF(result); } end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } return result; } static void free_key_patterns(char **patterns) { int i; for (i = 0; patterns[i] != NULL; i++) { free(patterns[i]); } free(patterns); } /* This function should probably be changed to not accept bytes() when * Python 2.x support is dropped. */ static int parse_key_patterns(PyObject *py_pattern, char ***patterns) { int result = -1, length, i; PyObject *list = NULL; *patterns = NULL; if (py_pattern == Py_None) { result = 0; } else if (PyUnicode_Check(py_pattern) || PyBytes_Check(py_pattern)) { PyObject *bytes; if (PyUnicode_Check(py_pattern)) { bytes = PyUnicode_AsUTF8String(py_pattern); if (bytes == NULL) goto end; } else { bytes = py_pattern; Py_INCREF(bytes); } *patterns = calloc(2, sizeof (char *)); if (*patterns == NULL) { PyErr_NoMemory(); Py_DECREF(bytes); goto end; } (*patterns)[0] = strdup(PyBytes_AsString(bytes)); if ((*patterns)[0] == NULL) { PyErr_NoMemory(); Py_DECREF(bytes); goto end; } result = 0; } else { /* We must have a sequence of strings. */ list = PySequence_Fast(py_pattern, "first argument must be a string or sequence of strings"); if (list == NULL) goto end; length = PySequence_Fast_GET_SIZE(list); *patterns = calloc((length + 1), sizeof(char *)); if (*patterns == NULL) { PyErr_NoMemory(); goto end; } for (i = 0; i < length; i++) { PyObject *item = PySequence_Fast_GET_ITEM(list, i); PyObject *bytes; if (PyBytes_Check(item)) { bytes = item; Py_INCREF(bytes); } else if (PyUnicode_Check(item)) { bytes = PyUnicode_AsUTF8String(item); if (bytes == NULL) { goto end; } } else { PyErr_SetString(PyExc_TypeError, "first argument must be a string or sequence of strings"); goto end; } (*patterns)[i] = strdup(PyBytes_AsString(bytes)); if ((*patterns)[i] == NULL) { PyErr_NoMemory(); Py_DECREF(bytes); goto end; } } result = 0; } end: Py_XDECREF(list); /* cleanup the partial pattern list if there was an error*/ if (result < 0 && *patterns != NULL) { free_key_patterns(*patterns); *patterns = NULL; } return result; } static PyObject * pygpgme_context_export(PyGpgmeContext *self, PyObject *args) { PyObject *py_pattern, *py_keydata; char **patterns = NULL; gpgme_data_t keydata; gpgme_error_t err; if (!PyArg_ParseTuple(args, "OO", &py_pattern, &py_keydata)) return NULL; if (parse_key_patterns(py_pattern, &patterns) < 0) return NULL; if (pygpgme_data_new(&keydata, py_keydata)) { if (patterns) free_key_patterns(patterns); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_export_ext(self->ctx, (const char **)patterns, 0, keydata); Py_END_ALLOW_THREADS; if (patterns) free_key_patterns(patterns); gpgme_data_release(keydata); if (pygpgme_check_error(err)) return NULL; Py_RETURN_NONE; } static PyObject * pygpgme_context_genkey(PyGpgmeContext *self, PyObject *args) { PyObject *py_pubkey = Py_None, *py_seckey = Py_None; const char *parms; gpgme_data_t pubkey = NULL, seckey = NULL; PyObject *result; gpgme_error_t err; if (!PyArg_ParseTuple(args, "z|OO", &parms, &py_pubkey, &py_seckey)) return NULL; if (pygpgme_data_new(&pubkey, py_pubkey)) return NULL; if (pygpgme_data_new(&seckey, py_seckey)) { gpgme_data_release(pubkey); return NULL; } Py_BEGIN_ALLOW_THREADS; err = gpgme_op_genkey(self->ctx, parms, pubkey, seckey); Py_END_ALLOW_THREADS; gpgme_data_release(seckey); gpgme_data_release(pubkey); result = pygpgme_genkey_result(self->ctx); if (pygpgme_check_error(err)) { PyObject *err_type, *err_value, *err_traceback; PyErr_Fetch(&err_type, &err_value, &err_traceback); PyErr_NormalizeException(&err_type, &err_value, &err_traceback); if (!PyErr_GivenExceptionMatches(err_type, pygpgme_error)) goto end; if (result != NULL) { PyObject_SetAttrString(err_value, "result", result); Py_DECREF(result); } end: PyErr_Restore(err_type, err_value, err_traceback); return NULL; } return (PyObject *) result; } static PyObject * pygpgme_context_delete(PyGpgmeContext *self, PyObject *args) { PyGpgmeKey *key; int allow_secret = 0; gpgme_error_t err; if (!PyArg_ParseTuple(args, "O!|i", &PyGpgmeKey_Type, &key, &allow_secret)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_delete(self->ctx, key->key, allow_secret); Py_END_ALLOW_THREADS; if (pygpgme_check_error(err)) return NULL; Py_RETURN_NONE; } static gpgme_error_t pygpgme_edit_cb(void *user_data, gpgme_status_code_t status, const char *args, int fd) { PyObject *callback, *ret; PyGILState_STATE state; gpgme_error_t err; state = PyGILState_Ensure(); callback = (PyObject *)user_data; ret = PyObject_CallFunction(callback, "lzi", (long)status, args, fd); err = pygpgme_check_pyerror(); Py_XDECREF(ret); PyGILState_Release(state); return err; } static PyObject * pygpgme_context_edit(PyGpgmeContext *self, PyObject *args) { PyGpgmeKey *key; PyObject *callback, *py_out; gpgme_data_t out; gpgme_error_t err; if (!PyArg_ParseTuple(args, "O!OO", &PyGpgmeKey_Type, &key, &callback, &py_out)) return NULL; if (pygpgme_data_new(&out, py_out)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_edit(self->ctx, key->key, pygpgme_edit_cb, (void *)callback, out); Py_END_ALLOW_THREADS; gpgme_data_release(out); if (pygpgme_check_error(err)) return NULL; Py_RETURN_NONE; } static PyObject * pygpgme_context_card_edit(PyGpgmeContext *self, PyObject *args) { PyGpgmeKey *key; PyObject *callback, *py_out; gpgme_data_t out; gpgme_error_t err; if (!PyArg_ParseTuple(args, "O!OO", &PyGpgmeKey_Type, &key, &callback, &py_out)) return NULL; if (pygpgme_data_new(&out, py_out)) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_card_edit(self->ctx, key->key, pygpgme_edit_cb, (void *)callback, out); Py_END_ALLOW_THREADS; gpgme_data_release(out); if (pygpgme_check_error(err)) return NULL; Py_RETURN_NONE; } static PyObject * pygpgme_context_keylist(PyGpgmeContext *self, PyObject *args) { PyObject *py_pattern = Py_None; char **patterns = NULL; int secret_only = 0; gpgme_error_t err; PyGpgmeKeyIter *ret; if (!PyArg_ParseTuple(args, "|Oi", &py_pattern, &secret_only)) return NULL; if (parse_key_patterns(py_pattern, &patterns) < 0) return NULL; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_keylist_ext_start(self->ctx, (const char **)patterns, secret_only, 0); Py_END_ALLOW_THREADS; if (patterns) free_key_patterns(patterns); if (pygpgme_check_error(err)) return NULL; /* return a KeyIter object */ ret = PyObject_New(PyGpgmeKeyIter, &PyGpgmeKeyIter_Type); if (!ret) return NULL; Py_INCREF(self); ret->ctx = self; return (PyObject *)ret; } // pygpgme_context_trustlist static PyMethodDef pygpgme_context_methods[] = { { "set_engine_info", (PyCFunction)pygpgme_context_set_engine_info, METH_VARARGS }, { "set_locale", (PyCFunction)pygpgme_context_set_locale, METH_VARARGS }, { "get_key", (PyCFunction)pygpgme_context_get_key, METH_VARARGS }, { "encrypt", (PyCFunction)pygpgme_context_encrypt, METH_VARARGS }, { "encrypt_sign", (PyCFunction)pygpgme_context_encrypt_sign, METH_VARARGS }, { "decrypt", (PyCFunction)pygpgme_context_decrypt, METH_VARARGS }, { "decrypt_verify", (PyCFunction)pygpgme_context_decrypt_verify, METH_VARARGS }, { "sign", (PyCFunction)pygpgme_context_sign, METH_VARARGS }, { "verify", (PyCFunction)pygpgme_context_verify, METH_VARARGS }, { "import_", (PyCFunction)pygpgme_context_import, METH_VARARGS }, { "export", (PyCFunction)pygpgme_context_export, METH_VARARGS }, { "genkey", (PyCFunction)pygpgme_context_genkey, METH_VARARGS }, { "delete", (PyCFunction)pygpgme_context_delete, METH_VARARGS }, { "edit", (PyCFunction)pygpgme_context_edit, METH_VARARGS }, { "card_edit", (PyCFunction)pygpgme_context_card_edit, METH_VARARGS }, { "keylist", (PyCFunction)pygpgme_context_keylist, METH_VARARGS }, // trustlist { NULL, 0, 0 } }; PyTypeObject PyGpgmeContext_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.Context", sizeof(PyGpgmeContext), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_dealloc = (destructor)pygpgme_context_dealloc, .tp_init = (initproc)pygpgme_context_init, .tp_getset = pygpgme_context_getsets, .tp_methods = pygpgme_context_methods, }; pygpgme-0.3/src/pycompat.h0000644000175000017500000000336311722716416016054 0ustar jamesjames00000000000000 #ifndef PYGPGME_COMPAT_H #define PYGPGME_COMPAT_H #if PY_VERSION_HEX < 0x02060000 # define PyVarObject_HEAD_INIT(type, size) \ PyObject_HEAD_INIT(type) size, # define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) # define PyBytesObject PyStringObject # define PyBytes_Type PyString_Type # define PyBytes_Check PyString_Check # define PyBytes_CheckExact PyString_CheckExact # define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED # define PyBytes_AS_STRING PyString_AS_STRING # define PyBytes_GET_SIZE PyString_GET_SIZE # define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS # define PyBytes_FromStringAndSize PyString_FromStringAndSize # define PyBytes_FromString PyString_FromString # define PyBytes_FromFormatV PyString_FromFormatV # define PyBytes_FromFormat PyString_FromFormat # define PyBytes_Size PyString_Size # define PyBytes_AsString PyString_AsString # define PyBytes_Repr PyString_Repr # define PyBytes_Concat PyString_Concat # define PyBytes_ConcatAndDel PyString_ConcatAndDel # define PyBytes_Format PyString_Format # define PyBytes_DecodeEscape PyString_DecodeEscape # define PyBytes_Decode PyString_Decode # define PyBytes_Encode PyString_Encode # define PyBytes_AsEncodedObject PyString_AsEncodedObject # define PyBytes_AsEncodedString PyString_AsEncodedString # define PyBytes_AsDecodedObject PyString_AsDecodedObject # define PyBytes_AsDecodedString PyString_AsDecodedString # define PyBytes_AsStringAndSize PyString_AsStringAndSize #endif #if PY_VERSION_HEX > 0x03000000 /* Ugh. I'll need to fix this code, but the text/bytes changes take precedence. */ # define PyInt_Check PyLong_Check # define PyInt_FromLong PyLong_FromLong # define PyInt_AsLong PyLong_AsLong #endif #endif /* PYGPGME_COMPAT_H */ pygpgme-0.3/src/pygpgme.h0000644000175000017500000000771011622631741015664 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PYGPGME_H #define PYGPGME_H #include #include #include "pycompat.h" #define HIDDEN __attribute__((visibility("hidden"))) typedef struct { PyObject_HEAD gpgme_ctx_t ctx; } PyGpgmeContext; typedef struct { PyObject_HEAD gpgme_key_t key; } PyGpgmeKey; typedef struct { PyObject_HEAD gpgme_subkey_t subkey; PyObject *parent; } PyGpgmeSubkey; typedef struct { PyObject_HEAD gpgme_user_id_t user_id; PyObject *parent; } PyGpgmeUserId; typedef struct { PyObject_HEAD gpgme_key_sig_t key_sig; PyObject *parent; } PyGpgmeKeySig; typedef struct { PyObject_HEAD PyObject *type; PyObject *pubkey_algo; PyObject *hash_algo; PyObject *timestamp; PyObject *fpr; PyObject *sig_class; } PyGpgmeNewSignature; typedef struct { PyObject_HEAD PyObject *summary; PyObject *fpr; PyObject *status; PyObject *notations; PyObject *timestamp; PyObject *exp_timestamp; PyObject *wrong_key_usage; PyObject *validity; PyObject *validity_reason; } PyGpgmeSignature; typedef struct { PyObject_HEAD PyObject *considered; PyObject *no_user_id; PyObject *imported; PyObject *imported_rsa; PyObject *unchanged; PyObject *new_user_ids; PyObject *new_sub_keys; PyObject *new_signatures; PyObject *new_revocations; PyObject *secret_read; PyObject *secret_imported; PyObject *secret_unchanged; PyObject *skipped_new_keys; PyObject *not_imported; PyObject *imports; } PyGpgmeImportResult; typedef struct { PyObject_HEAD PyObject *primary; PyObject *sub; PyObject *fpr; } PyGpgmeGenkeyResult; typedef struct { PyObject_HEAD PyGpgmeContext *ctx; } PyGpgmeKeyIter; extern HIDDEN PyObject *pygpgme_error; extern HIDDEN PyTypeObject PyGpgmeContext_Type; extern HIDDEN PyTypeObject PyGpgmeKey_Type; extern HIDDEN PyTypeObject PyGpgmeSubkey_Type; extern HIDDEN PyTypeObject PyGpgmeUserId_Type; extern HIDDEN PyTypeObject PyGpgmeKeySig_Type; extern HIDDEN PyTypeObject PyGpgmeNewSignature_Type; extern HIDDEN PyTypeObject PyGpgmeSignature_Type; extern HIDDEN PyTypeObject PyGpgmeImportResult_Type; extern HIDDEN PyTypeObject PyGpgmeGenkeyResult_Type; extern HIDDEN PyTypeObject PyGpgmeKeyIter_Type; HIDDEN int pygpgme_check_error (gpgme_error_t err); HIDDEN PyObject *pygpgme_error_object (gpgme_error_t err); HIDDEN gpgme_error_t pygpgme_check_pyerror (void); HIDDEN int pygpgme_no_constructor (PyObject *self, PyObject *args, PyObject *kwargs); HIDDEN int pygpgme_data_new (gpgme_data_t *dh, PyObject *fp); HIDDEN PyObject *pygpgme_key_new (gpgme_key_t key); HIDDEN PyObject *pygpgme_newsiglist_new (gpgme_new_signature_t siglist); HIDDEN PyObject *pygpgme_siglist_new (gpgme_signature_t siglist); HIDDEN PyObject *pygpgme_import_result (gpgme_ctx_t ctx); HIDDEN PyObject *pygpgme_genkey_result (gpgme_ctx_t ctx); HIDDEN PyObject *pygpgme_make_constants (PyObject *self, PyObject *args); #endif pygpgme-0.3/src/pygpgme-keyiter.c0000644000175000017500000000460511622631741017331 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" static void pygpgme_keyiter_dealloc(PyGpgmeKeyIter *self) { if (self->ctx) { gpgme_error_t err = gpgme_op_keylist_end(self->ctx->ctx); PyObject *exc = pygpgme_error_object(err); if (exc != NULL && exc != Py_None) { PyErr_WriteUnraisable(exc); } Py_XDECREF(exc); Py_DECREF(self->ctx); self->ctx = NULL; } PyObject_Del(self); } static PyObject * pygpgme_keyiter_iter(PyGpgmeKeyIter *self) { Py_INCREF(self); return (PyObject *)self; } static PyObject * pygpgme_keyiter_next(PyGpgmeKeyIter *self) { gpgme_key_t key = NULL; gpgme_error_t err; PyObject *ret; Py_BEGIN_ALLOW_THREADS; err = gpgme_op_keylist_next(self->ctx->ctx, &key); Py_END_ALLOW_THREADS; /* end iteration */ if (gpgme_err_source(err) == GPG_ERR_SOURCE_GPGME && gpgme_err_code(err) == GPG_ERR_EOF) { PyErr_SetNone(PyExc_StopIteration); return NULL; } if (pygpgme_check_error(err)) return NULL; if (key == NULL) Py_RETURN_NONE; ret = pygpgme_key_new(key); gpgme_key_unref(key); return ret; } PyTypeObject PyGpgmeKeyIter_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.KeyIter", sizeof(PyGpgmeKeyIter), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_keyiter_dealloc, .tp_iter = (getiterfunc)pygpgme_keyiter_iter, .tp_iternext = (iternextfunc)pygpgme_keyiter_next, }; pygpgme-0.3/src/pygpgme-constants.c0000644000175000017500000003406410431015202017654 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" struct pygpgme_constant { const char name[28]; long value; }; #define CONST(name) { #name, GPGME_##name } static const struct pygpgme_constant constants[] = { /* gpgme_data_encoding_t */ CONST(DATA_ENCODING_NONE), CONST(DATA_ENCODING_BINARY), CONST(DATA_ENCODING_BASE64), CONST(DATA_ENCODING_ARMOR), /* gpgme_pubkey_algo_t */ CONST(PK_RSA), CONST(PK_RSA_E), CONST(PK_RSA_S), CONST(PK_ELG_E), CONST(PK_DSA), CONST(PK_ELG), /* gpgme_hash_algo_t */ CONST(MD_NONE), CONST(MD_MD5), CONST(MD_SHA1), CONST(MD_RMD160), CONST(MD_MD2), CONST(MD_TIGER), CONST(MD_HAVAL), CONST(MD_SHA256), CONST(MD_SHA384), CONST(MD_SHA512), CONST(MD_MD4), CONST(MD_CRC32), CONST(MD_CRC32_RFC1510), CONST(MD_CRC24_RFC2440), /* gpgme_sig_mode_t */ CONST(SIG_MODE_NORMAL), CONST(SIG_MODE_DETACH), CONST(SIG_MODE_CLEAR), /* gpgme_validity_t */ CONST(VALIDITY_UNKNOWN), CONST(VALIDITY_UNDEFINED), CONST(VALIDITY_NEVER), CONST(VALIDITY_MARGINAL), CONST(VALIDITY_FULL), CONST(VALIDITY_ULTIMATE), /* gpgme_protocol_t */ CONST(PROTOCOL_OpenPGP), CONST(PROTOCOL_CMS), /* gpgme_keylist_mode_t */ CONST(KEYLIST_MODE_LOCAL), CONST(KEYLIST_MODE_EXTERN), CONST(KEYLIST_MODE_SIGS), CONST(KEYLIST_MODE_VALIDATE), /* gpgme_status_code_t */ CONST(STATUS_EOF), CONST(STATUS_ENTER), CONST(STATUS_LEAVE), CONST(STATUS_ABORT), CONST(STATUS_GOODSIG), CONST(STATUS_BADSIG), CONST(STATUS_ERRSIG), CONST(STATUS_BADARMOR), CONST(STATUS_RSA_OR_IDEA), CONST(STATUS_KEYEXPIRED), CONST(STATUS_KEYREVOKED), CONST(STATUS_TRUST_UNDEFINED), CONST(STATUS_TRUST_NEVER), CONST(STATUS_TRUST_MARGINAL), CONST(STATUS_TRUST_FULLY), CONST(STATUS_TRUST_ULTIMATE), CONST(STATUS_SHM_INFO), CONST(STATUS_SHM_GET), CONST(STATUS_SHM_GET_BOOL), CONST(STATUS_SHM_GET_HIDDEN), CONST(STATUS_NEED_PASSPHRASE), CONST(STATUS_VALIDSIG), CONST(STATUS_SIG_ID), CONST(STATUS_ENC_TO), CONST(STATUS_NODATA), CONST(STATUS_BAD_PASSPHRASE), CONST(STATUS_NO_PUBKEY), CONST(STATUS_NO_SECKEY), CONST(STATUS_NEED_PASSPHRASE_SYM), CONST(STATUS_DECRYPTION_FAILED), CONST(STATUS_DECRYPTION_OKAY), CONST(STATUS_MISSING_PASSPHRASE), CONST(STATUS_GOOD_PASSPHRASE), CONST(STATUS_GOODMDC), CONST(STATUS_BADMDC), CONST(STATUS_ERRMDC), CONST(STATUS_IMPORTED), CONST(STATUS_IMPORT_OK), CONST(STATUS_IMPORT_PROBLEM), CONST(STATUS_IMPORT_RES), CONST(STATUS_FILE_START), CONST(STATUS_FILE_DONE), CONST(STATUS_FILE_ERROR), CONST(STATUS_BEGIN_DECRYPTION), CONST(STATUS_END_DECRYPTION), CONST(STATUS_BEGIN_ENCRYPTION), CONST(STATUS_END_ENCRYPTION), CONST(STATUS_DELETE_PROBLEM), CONST(STATUS_GET_BOOL), CONST(STATUS_GET_LINE), CONST(STATUS_GET_HIDDEN), CONST(STATUS_GOT_IT), CONST(STATUS_PROGRESS), CONST(STATUS_SIG_CREATED), CONST(STATUS_SESSION_KEY), CONST(STATUS_NOTATION_NAME), CONST(STATUS_NOTATION_DATA), CONST(STATUS_POLICY_URL), CONST(STATUS_BEGIN_STREAM), CONST(STATUS_END_STREAM), CONST(STATUS_KEY_CREATED), CONST(STATUS_USERID_HINT), CONST(STATUS_UNEXPECTED), CONST(STATUS_INV_RECP), CONST(STATUS_NO_RECP), CONST(STATUS_ALREADY_SIGNED), CONST(STATUS_SIGEXPIRED), CONST(STATUS_EXPSIG), CONST(STATUS_EXPKEYSIG), CONST(STATUS_TRUNCATED), CONST(STATUS_ERROR), CONST(STATUS_NEWSIG), CONST(STATUS_REVKEYSIG), /* gpgme_encrypt_flags_t */ CONST(ENCRYPT_ALWAYS_TRUST), /* gpgme_sigsum_t */ CONST(SIGSUM_VALID), CONST(SIGSUM_GREEN), CONST(SIGSUM_RED), CONST(SIGSUM_KEY_REVOKED), CONST(SIGSUM_KEY_EXPIRED), CONST(SIGSUM_SIG_EXPIRED), CONST(SIGSUM_KEY_MISSING), CONST(SIGSUM_CRL_MISSING), CONST(SIGSUM_CRL_TOO_OLD), CONST(SIGSUM_BAD_POLICY), CONST(SIGSUM_SYS_ERROR), /* import status */ CONST(IMPORT_NEW), CONST(IMPORT_UID), CONST(IMPORT_SIG), CONST(IMPORT_SUBKEY), CONST(IMPORT_SECRET), /* gpg-error.h constants */ #undef CONST #define CONST(name) { #name, GPG_##name } CONST(ERR_SOURCE_UNKNOWN), CONST(ERR_SOURCE_GCRYPT), CONST(ERR_SOURCE_GPG), CONST(ERR_SOURCE_GPGSM), CONST(ERR_SOURCE_GPGAGENT), CONST(ERR_SOURCE_PINENTRY), CONST(ERR_SOURCE_SCD), CONST(ERR_SOURCE_GPGME), CONST(ERR_SOURCE_KEYBOX), CONST(ERR_SOURCE_KSBA), CONST(ERR_SOURCE_DIRMNGR), CONST(ERR_SOURCE_GSTI), CONST(ERR_SOURCE_USER_1), CONST(ERR_SOURCE_USER_2), CONST(ERR_SOURCE_USER_3), CONST(ERR_SOURCE_USER_4), CONST(ERR_NO_ERROR), CONST(ERR_GENERAL), CONST(ERR_UNKNOWN_PACKET), CONST(ERR_UNKNOWN_VERSION), CONST(ERR_PUBKEY_ALGO), CONST(ERR_DIGEST_ALGO), CONST(ERR_BAD_PUBKEY), CONST(ERR_BAD_SECKEY), CONST(ERR_BAD_SIGNATURE), CONST(ERR_NO_PUBKEY), CONST(ERR_CHECKSUM), CONST(ERR_BAD_PASSPHRASE), CONST(ERR_CIPHER_ALGO), CONST(ERR_KEYRING_OPEN), CONST(ERR_INV_PACKET), CONST(ERR_INV_ARMOR), CONST(ERR_NO_USER_ID), CONST(ERR_NO_SECKEY), CONST(ERR_WRONG_SECKEY), CONST(ERR_BAD_KEY), CONST(ERR_COMPR_ALGO), CONST(ERR_NO_PRIME), CONST(ERR_NO_ENCODING_METHOD), CONST(ERR_NO_ENCRYPTION_SCHEME), CONST(ERR_NO_SIGNATURE_SCHEME), CONST(ERR_INV_ATTR), CONST(ERR_NO_VALUE), CONST(ERR_NOT_FOUND), CONST(ERR_VALUE_NOT_FOUND), CONST(ERR_SYNTAX), CONST(ERR_BAD_MPI), CONST(ERR_INV_PASSPHRASE), CONST(ERR_SIG_CLASS), CONST(ERR_RESOURCE_LIMIT), CONST(ERR_INV_KEYRING), CONST(ERR_TRUSTDB), CONST(ERR_BAD_CERT), CONST(ERR_INV_USER_ID), CONST(ERR_UNEXPECTED), CONST(ERR_TIME_CONFLICT), CONST(ERR_KEYSERVER), CONST(ERR_WRONG_PUBKEY_ALGO), CONST(ERR_TRIBUTE_TO_D_A), CONST(ERR_WEAK_KEY), CONST(ERR_INV_KEYLEN), CONST(ERR_INV_ARG), CONST(ERR_BAD_URI), CONST(ERR_INV_URI), CONST(ERR_NETWORK), CONST(ERR_UNKNOWN_HOST), CONST(ERR_SELFTEST_FAILED), CONST(ERR_NOT_ENCRYPTED), CONST(ERR_NOT_PROCESSED), CONST(ERR_UNUSABLE_PUBKEY), CONST(ERR_UNUSABLE_SECKEY), CONST(ERR_INV_VALUE), CONST(ERR_BAD_CERT_CHAIN), CONST(ERR_MISSING_CERT), CONST(ERR_NO_DATA), CONST(ERR_BUG), CONST(ERR_NOT_SUPPORTED), CONST(ERR_INV_OP), CONST(ERR_TIMEOUT), CONST(ERR_INTERNAL), CONST(ERR_EOF_GCRYPT), CONST(ERR_INV_OBJ), CONST(ERR_TOO_SHORT), CONST(ERR_TOO_LARGE), CONST(ERR_NO_OBJ), CONST(ERR_NOT_IMPLEMENTED), CONST(ERR_CONFLICT), CONST(ERR_INV_CIPHER_MODE), CONST(ERR_INV_FLAG), CONST(ERR_INV_HANDLE), CONST(ERR_TRUNCATED), CONST(ERR_INCOMPLETE_LINE), CONST(ERR_INV_RESPONSE), CONST(ERR_NO_AGENT), CONST(ERR_AGENT), CONST(ERR_INV_DATA), CONST(ERR_ASSUAN_SERVER_FAULT), CONST(ERR_ASSUAN), CONST(ERR_INV_SESSION_KEY), CONST(ERR_INV_SEXP), CONST(ERR_UNSUPPORTED_ALGORITHM), CONST(ERR_NO_PIN_ENTRY), CONST(ERR_PIN_ENTRY), CONST(ERR_BAD_PIN), CONST(ERR_INV_NAME), CONST(ERR_BAD_DATA), CONST(ERR_INV_PARAMETER), CONST(ERR_WRONG_CARD), CONST(ERR_NO_DIRMNGR), CONST(ERR_DIRMNGR), CONST(ERR_CERT_REVOKED), CONST(ERR_NO_CRL_KNOWN), CONST(ERR_CRL_TOO_OLD), CONST(ERR_LINE_TOO_LONG), CONST(ERR_NOT_TRUSTED), CONST(ERR_CANCELED), CONST(ERR_BAD_CA_CERT), CONST(ERR_CERT_EXPIRED), CONST(ERR_CERT_TOO_YOUNG), CONST(ERR_UNSUPPORTED_CERT), CONST(ERR_UNKNOWN_SEXP), CONST(ERR_UNSUPPORTED_PROTECTION), CONST(ERR_CORRUPTED_PROTECTION), CONST(ERR_AMBIGUOUS_NAME), CONST(ERR_CARD), CONST(ERR_CARD_RESET), CONST(ERR_CARD_REMOVED), CONST(ERR_INV_CARD), CONST(ERR_CARD_NOT_PRESENT), CONST(ERR_NO_PKCS15_APP), CONST(ERR_NOT_CONFIRMED), CONST(ERR_CONFIGURATION), CONST(ERR_NO_POLICY_MATCH), CONST(ERR_INV_INDEX), CONST(ERR_INV_ID), CONST(ERR_NO_SCDAEMON), CONST(ERR_SCDAEMON), CONST(ERR_UNSUPPORTED_PROTOCOL), CONST(ERR_BAD_PIN_METHOD), CONST(ERR_CARD_NOT_INITIALIZED), CONST(ERR_UNSUPPORTED_OPERATION), CONST(ERR_WRONG_KEY_USAGE), CONST(ERR_NOTHING_FOUND), CONST(ERR_WRONG_BLOB_TYPE), CONST(ERR_MISSING_VALUE), CONST(ERR_HARDWARE), CONST(ERR_PIN_BLOCKED), CONST(ERR_USE_CONDITIONS), CONST(ERR_PIN_NOT_SYNCED), CONST(ERR_INV_CRL), CONST(ERR_BAD_BER), CONST(ERR_INV_BER), CONST(ERR_ELEMENT_NOT_FOUND), CONST(ERR_IDENTIFIER_NOT_FOUND), CONST(ERR_INV_TAG), CONST(ERR_INV_LENGTH), CONST(ERR_INV_KEYINFO), CONST(ERR_UNEXPECTED_TAG), CONST(ERR_NOT_DER_ENCODED), CONST(ERR_NO_CMS_OBJ), CONST(ERR_INV_CMS_OBJ), CONST(ERR_UNKNOWN_CMS_OBJ), CONST(ERR_UNSUPPORTED_CMS_OBJ), CONST(ERR_UNSUPPORTED_ENCODING), CONST(ERR_UNSUPPORTED_CMS_VERSION), CONST(ERR_UNKNOWN_ALGORITHM), CONST(ERR_INV_ENGINE), CONST(ERR_PUBKEY_NOT_TRUSTED), CONST(ERR_DECRYPT_FAILED), CONST(ERR_KEY_EXPIRED), CONST(ERR_SIG_EXPIRED), CONST(ERR_ENCODING_PROBLEM), CONST(ERR_INV_STATE), CONST(ERR_DUP_VALUE), CONST(ERR_MISSING_ACTION), CONST(ERR_MODULE_NOT_FOUND), CONST(ERR_INV_OID_STRING), CONST(ERR_INV_TIME), CONST(ERR_INV_CRL_OBJ), CONST(ERR_UNSUPPORTED_CRL_VERSION), CONST(ERR_INV_CERT_OBJ), CONST(ERR_UNKNOWN_NAME), CONST(ERR_LOCALE_PROBLEM), CONST(ERR_NOT_LOCKED), CONST(ERR_PROTOCOL_VIOLATION), CONST(ERR_INV_MAC), CONST(ERR_INV_REQUEST), CONST(ERR_BUFFER_TOO_SHORT), CONST(ERR_SEXP_INV_LEN_SPEC), CONST(ERR_SEXP_STRING_TOO_LONG), CONST(ERR_SEXP_UNMATCHED_PAREN), CONST(ERR_SEXP_NOT_CANONICAL), CONST(ERR_SEXP_BAD_CHARACTER), CONST(ERR_SEXP_BAD_QUOTATION), CONST(ERR_SEXP_ZERO_PREFIX), CONST(ERR_SEXP_NESTED_DH), CONST(ERR_SEXP_UNMATCHED_DH), CONST(ERR_SEXP_UNEXPECTED_PUNC), CONST(ERR_SEXP_BAD_HEX_CHAR), CONST(ERR_SEXP_ODD_HEX_NUMBERS), CONST(ERR_SEXP_BAD_OCT_CHAR), CONST(ERR_USER_1), CONST(ERR_USER_2), CONST(ERR_USER_3), CONST(ERR_USER_4), CONST(ERR_USER_5), CONST(ERR_USER_6), CONST(ERR_USER_7), CONST(ERR_USER_8), CONST(ERR_USER_9), CONST(ERR_USER_10), CONST(ERR_USER_11), CONST(ERR_USER_12), CONST(ERR_USER_13), CONST(ERR_USER_14), CONST(ERR_USER_15), CONST(ERR_USER_16), CONST(ERR_UNKNOWN_ERRNO), CONST(ERR_EOF), CONST(ERR_E2BIG), CONST(ERR_EACCES), CONST(ERR_EADDRINUSE), CONST(ERR_EADDRNOTAVAIL), CONST(ERR_EADV), CONST(ERR_EAFNOSUPPORT), CONST(ERR_EAGAIN), CONST(ERR_EALREADY), CONST(ERR_EAUTH), CONST(ERR_EBACKGROUND), CONST(ERR_EBADE), CONST(ERR_EBADF), CONST(ERR_EBADFD), CONST(ERR_EBADMSG), CONST(ERR_EBADR), CONST(ERR_EBADRPC), CONST(ERR_EBADRQC), CONST(ERR_EBADSLT), CONST(ERR_EBFONT), CONST(ERR_EBUSY), CONST(ERR_ECANCELED), CONST(ERR_ECHILD), CONST(ERR_ECHRNG), CONST(ERR_ECOMM), CONST(ERR_ECONNABORTED), CONST(ERR_ECONNREFUSED), CONST(ERR_ECONNRESET), CONST(ERR_ED), CONST(ERR_EDEADLK), CONST(ERR_EDEADLOCK), CONST(ERR_EDESTADDRREQ), CONST(ERR_EDIED), CONST(ERR_EDOM), CONST(ERR_EDOTDOT), CONST(ERR_EDQUOT), CONST(ERR_EEXIST), CONST(ERR_EFAULT), CONST(ERR_EFBIG), CONST(ERR_EFTYPE), CONST(ERR_EGRATUITOUS), CONST(ERR_EGREGIOUS), CONST(ERR_EHOSTDOWN), CONST(ERR_EHOSTUNREACH), CONST(ERR_EIDRM), CONST(ERR_EIEIO), CONST(ERR_EILSEQ), CONST(ERR_EINPROGRESS), CONST(ERR_EINTR), CONST(ERR_EINVAL), CONST(ERR_EIO), CONST(ERR_EISCONN), CONST(ERR_EISDIR), CONST(ERR_EISNAM), CONST(ERR_EL2HLT), CONST(ERR_EL2NSYNC), CONST(ERR_EL3HLT), CONST(ERR_EL3RST), CONST(ERR_ELIBACC), CONST(ERR_ELIBBAD), CONST(ERR_ELIBEXEC), CONST(ERR_ELIBMAX), CONST(ERR_ELIBSCN), CONST(ERR_ELNRNG), CONST(ERR_ELOOP), CONST(ERR_EMEDIUMTYPE), CONST(ERR_EMFILE), CONST(ERR_EMLINK), CONST(ERR_EMSGSIZE), CONST(ERR_EMULTIHOP), CONST(ERR_ENAMETOOLONG), CONST(ERR_ENAVAIL), CONST(ERR_ENEEDAUTH), CONST(ERR_ENETDOWN), CONST(ERR_ENETRESET), CONST(ERR_ENETUNREACH), CONST(ERR_ENFILE), CONST(ERR_ENOANO), CONST(ERR_ENOBUFS), CONST(ERR_ENOCSI), CONST(ERR_ENODATA), CONST(ERR_ENODEV), CONST(ERR_ENOENT), CONST(ERR_ENOEXEC), CONST(ERR_ENOLCK), CONST(ERR_ENOLINK), CONST(ERR_ENOMEDIUM), CONST(ERR_ENOMEM), CONST(ERR_ENOMSG), CONST(ERR_ENONET), CONST(ERR_ENOPKG), CONST(ERR_ENOPROTOOPT), CONST(ERR_ENOSPC), CONST(ERR_ENOSR), CONST(ERR_ENOSTR), CONST(ERR_ENOSYS), CONST(ERR_ENOTBLK), CONST(ERR_ENOTCONN), CONST(ERR_ENOTDIR), CONST(ERR_ENOTEMPTY), CONST(ERR_ENOTNAM), CONST(ERR_ENOTSOCK), CONST(ERR_ENOTSUP), CONST(ERR_ENOTTY), CONST(ERR_ENOTUNIQ), CONST(ERR_ENXIO), CONST(ERR_EOPNOTSUPP), CONST(ERR_EOVERFLOW), CONST(ERR_EPERM), CONST(ERR_EPFNOSUPPORT), CONST(ERR_EPIPE), CONST(ERR_EPROCLIM), CONST(ERR_EPROCUNAVAIL), CONST(ERR_EPROGMISMATCH), CONST(ERR_EPROGUNAVAIL), CONST(ERR_EPROTO), CONST(ERR_EPROTONOSUPPORT), CONST(ERR_EPROTOTYPE), CONST(ERR_ERANGE), CONST(ERR_EREMCHG), CONST(ERR_EREMOTE), CONST(ERR_EREMOTEIO), CONST(ERR_ERESTART), CONST(ERR_EROFS), CONST(ERR_ERPCMISMATCH), CONST(ERR_ESHUTDOWN), CONST(ERR_ESOCKTNOSUPPORT), CONST(ERR_ESPIPE), CONST(ERR_ESRCH), CONST(ERR_ESRMNT), CONST(ERR_ESTALE), CONST(ERR_ESTRPIPE), CONST(ERR_ETIME), CONST(ERR_ETIMEDOUT), CONST(ERR_ETOOMANYREFS), CONST(ERR_ETXTBSY), CONST(ERR_EUCLEAN), CONST(ERR_EUNATCH), CONST(ERR_EUSERS), CONST(ERR_EWOULDBLOCK), CONST(ERR_EXDEV), CONST(ERR_EXFULL), }; static const int n_constants = sizeof(constants) / sizeof(constants[0]); PyObject * pygpgme_make_constants(PyObject *self, PyObject *args) { PyObject *dict; int i; if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) return NULL; for (i = 0; i < n_constants; i++) { PyObject *item; item = PyInt_FromLong(constants[i].value); PyDict_SetItemString(dict, constants[i].name, item); Py_DECREF(item); } Py_RETURN_NONE; } pygpgme-0.3/src/pygpgme-signature.c0000644000175000017500000001505711622631741017661 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" #include static void pygpgme_newsig_dealloc(PyGpgmeNewSignature *self) { Py_XDECREF(self->type); Py_XDECREF(self->pubkey_algo); Py_XDECREF(self->hash_algo); Py_XDECREF(self->timestamp); Py_XDECREF(self->fpr); Py_XDECREF(self->sig_class); PyObject_Del(self); } static PyMemberDef pygpgme_newsig_members[] = { { "type", T_OBJECT, offsetof(PyGpgmeNewSignature, type), READONLY}, { "pubkey_algo", T_OBJECT, offsetof(PyGpgmeNewSignature, pubkey_algo), READONLY}, { "hash_algo", T_OBJECT, offsetof(PyGpgmeNewSignature, hash_algo), READONLY}, { "timestamp", T_OBJECT, offsetof(PyGpgmeNewSignature, timestamp), READONLY}, { "fpr", T_OBJECT, offsetof(PyGpgmeNewSignature, fpr), READONLY}, { "sig_class", T_OBJECT, offsetof(PyGpgmeNewSignature, sig_class), READONLY}, { NULL, 0, 0, 0} }; PyTypeObject PyGpgmeNewSignature_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.NewSignature", sizeof(PyGpgmeNewSignature), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_newsig_dealloc, .tp_members = pygpgme_newsig_members, }; PyObject * pygpgme_newsiglist_new(gpgme_new_signature_t siglist) { PyObject *list; gpgme_new_signature_t sig; list = PyList_New(0); for (sig = siglist; sig != NULL; sig = sig->next) { PyGpgmeNewSignature *item = PyObject_New(PyGpgmeNewSignature, &PyGpgmeNewSignature_Type); if (item == NULL) { Py_DECREF(list); return NULL; } item->type = PyInt_FromLong(sig->type); item->pubkey_algo = PyInt_FromLong(sig->pubkey_algo); item->hash_algo = PyInt_FromLong(sig->hash_algo); item->timestamp = PyInt_FromLong(sig->timestamp); if (sig->fpr) { item->fpr = PyUnicode_DecodeASCII(sig->fpr, strlen(sig->fpr), "replace"); } else { Py_INCREF(Py_None); item->fpr = Py_None; } item->sig_class = PyInt_FromLong(sig->sig_class); if (PyErr_Occurred()) { Py_DECREF(item); Py_DECREF(list); return NULL; } PyList_Append(list, (PyObject *)item); Py_DECREF(item); } return list; } static void pygpgme_sig_dealloc(PyGpgmeSignature *self) { Py_XDECREF(self->summary); Py_XDECREF(self->fpr); Py_XDECREF(self->status); Py_XDECREF(self->notations); Py_XDECREF(self->timestamp); Py_XDECREF(self->exp_timestamp); Py_XDECREF(self->wrong_key_usage); Py_XDECREF(self->validity); Py_XDECREF(self->validity_reason); PyObject_Del(self); } static PyMemberDef pygpgme_sig_members[] = { { "summary", T_OBJECT, offsetof(PyGpgmeSignature, summary), READONLY}, { "fpr", T_OBJECT, offsetof(PyGpgmeSignature, fpr), READONLY}, { "status", T_OBJECT, offsetof(PyGpgmeSignature, status), READONLY}, { "notations", T_OBJECT, offsetof(PyGpgmeSignature, notations), READONLY}, { "timestamp", T_OBJECT, offsetof(PyGpgmeSignature, timestamp), READONLY}, { "exp_timestamp", T_OBJECT, offsetof(PyGpgmeSignature, exp_timestamp), READONLY}, { "wrong_key_usage", T_OBJECT, offsetof(PyGpgmeSignature, wrong_key_usage), READONLY}, { "validity", T_OBJECT, offsetof(PyGpgmeSignature, validity), READONLY}, { "validity_reason", T_OBJECT, offsetof(PyGpgmeSignature, validity_reason), READONLY}, { NULL, 0, 0, 0} }; PyTypeObject PyGpgmeSignature_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.Signature", sizeof(PyGpgmeSignature), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_sig_dealloc, .tp_members = pygpgme_sig_members, }; PyObject * pygpgme_siglist_new(gpgme_signature_t siglist) { PyObject *list; gpgme_signature_t sig; gpgme_sig_notation_t not; list = PyList_New(0); for (sig = siglist; sig != NULL; sig = sig->next) { PyGpgmeSignature *item = PyObject_New(PyGpgmeSignature, &PyGpgmeSignature_Type); if (item == NULL) { Py_DECREF(list); return NULL; } item->summary = PyInt_FromLong(sig->summary); if (sig->fpr) { item->fpr = PyUnicode_DecodeASCII(sig->fpr, strlen(sig->fpr), "replace"); } else { Py_INCREF(Py_None); item->fpr = Py_None; } item->status = pygpgme_error_object(sig->status); item->notations = PyList_New(0); for (not = sig->notations; not != NULL; not = not->next) { PyObject *py_name, *py_value, *py_not; py_name = PyUnicode_DecodeUTF8(not->name, not->name_len, "replace"); py_value = PyBytes_FromStringAndSize(not->value, not->value_len); py_not = Py_BuildValue("(NN)", py_name, py_value); if (!py_not) break; PyList_Append(item->notations, py_not); Py_DECREF(py_not); } item->timestamp = PyInt_FromLong(sig->timestamp); item->exp_timestamp = PyInt_FromLong(sig->exp_timestamp); item->wrong_key_usage = PyBool_FromLong(sig->wrong_key_usage); item->validity = PyInt_FromLong(sig->validity); item->validity_reason = pygpgme_error_object(sig->validity_reason); if (PyErr_Occurred()) { Py_DECREF(item); Py_DECREF(list); return NULL; } PyList_Append(list, (PyObject *)item); Py_DECREF(item); } return list; } pygpgme-0.3/src/pygpgme-import.c0000644000175000017500000001152111622631741017162 0ustar jamesjames00000000000000/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* pygpgme - a Python wrapper for the gpgme library Copyright (C) 2006 James Henstridge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pygpgme.h" #include static void pygpgme_import_dealloc(PyGpgmeImportResult *self) { Py_XDECREF(self->considered); Py_XDECREF(self->no_user_id); Py_XDECREF(self->imported); Py_XDECREF(self->imported_rsa); Py_XDECREF(self->unchanged); Py_XDECREF(self->new_user_ids); Py_XDECREF(self->new_sub_keys); Py_XDECREF(self->new_signatures); Py_XDECREF(self->new_revocations); Py_XDECREF(self->secret_read); Py_XDECREF(self->secret_imported); Py_XDECREF(self->secret_unchanged); Py_XDECREF(self->skipped_new_keys); Py_XDECREF(self->not_imported); Py_XDECREF(self->imports); PyObject_Del(self); } static PyMemberDef pygpgme_import_members[] = { { "considered", T_OBJECT, offsetof(PyGpgmeImportResult, considered), READONLY}, { "no_user_id", T_OBJECT, offsetof(PyGpgmeImportResult, no_user_id), READONLY}, { "imported", T_OBJECT, offsetof(PyGpgmeImportResult, imported), READONLY}, { "imported_rsa", T_OBJECT, offsetof(PyGpgmeImportResult, imported_rsa), READONLY}, { "unchanged", T_OBJECT, offsetof(PyGpgmeImportResult, unchanged), READONLY}, { "new_user_ids", T_OBJECT, offsetof(PyGpgmeImportResult, new_user_ids), READONLY}, { "new_sub_keys", T_OBJECT, offsetof(PyGpgmeImportResult, new_sub_keys), READONLY}, { "new_signatures", T_OBJECT, offsetof(PyGpgmeImportResult, new_signatures), READONLY}, { "new_revocations", T_OBJECT, offsetof(PyGpgmeImportResult, new_revocations), READONLY}, { "secret_read", T_OBJECT, offsetof(PyGpgmeImportResult, secret_read), READONLY}, { "secret_imported", T_OBJECT, offsetof(PyGpgmeImportResult, secret_imported), READONLY}, { "secret_unchanged", T_OBJECT, offsetof(PyGpgmeImportResult, secret_unchanged), READONLY}, { "skipped_new_keys", T_OBJECT, offsetof(PyGpgmeImportResult, skipped_new_keys), READONLY}, { "not_imported", T_OBJECT, offsetof(PyGpgmeImportResult, not_imported), READONLY}, { "imports", T_OBJECT, offsetof(PyGpgmeImportResult, imports), READONLY}, { NULL, 0, 0, 0} }; PyTypeObject PyGpgmeImportResult_Type = { PyVarObject_HEAD_INIT(NULL, 0) "gpgme.Import", sizeof(PyGpgmeImportResult), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_init = pygpgme_no_constructor, .tp_dealloc = (destructor)pygpgme_import_dealloc, .tp_members = pygpgme_import_members, }; PyObject * pygpgme_import_result(gpgme_ctx_t ctx) { gpgme_import_result_t result; gpgme_import_status_t status; PyGpgmeImportResult *self; result = gpgme_op_import_result(ctx); if (result == NULL) Py_RETURN_NONE; self = PyObject_New(PyGpgmeImportResult, &PyGpgmeImportResult_Type); if (!self) return NULL; #define ADD_INT(name) \ self->name = PyInt_FromLong(result->name) ADD_INT(considered); ADD_INT(no_user_id); ADD_INT(imported); ADD_INT(imported_rsa); ADD_INT(unchanged); ADD_INT(new_user_ids); ADD_INT(new_sub_keys); ADD_INT(new_signatures); ADD_INT(new_revocations); ADD_INT(secret_read); ADD_INT(secret_imported); ADD_INT(secret_unchanged); ADD_INT(skipped_new_keys); ADD_INT(not_imported); self->imports = PyList_New(0); if (!self->imports) return NULL; for (status = result->imports; status != NULL; status = status->next) { PyObject *py_fpr, *item; if (status->fpr) py_fpr = PyUnicode_DecodeASCII(status->fpr, strlen(status->fpr), "replace"); else { py_fpr = Py_None; Py_INCREF(py_fpr); } item = Py_BuildValue("(NNi)", py_fpr, pygpgme_error_object(status->result), status->status); if (!item) { Py_DECREF(self); return NULL; } PyList_Append(self->imports, item); Py_DECREF(item); } return (PyObject *)self; } pygpgme-0.3/examples/0000775000175000017500000000000011726117114015065 5ustar jamesjames00000000000000pygpgme-0.3/examples/encrypt.py0000644000175000017500000000051311724072577017133 0ustar jamesjames00000000000000import gpgme try: from io import BytesIO except ImportError: from StringIO import StringIO as BytesIO ctx = gpgme.Context() ctx.armor = True key = ctx.get_key('B10A449E4CFB9A60A2DB996701AF93D991CFA34D') plain = BytesIO(b'Hello World\n') cipher = BytesIO() ctx.encrypt([key], 0, plain, cipher) print(cipher.getvalue()) pygpgme-0.3/MANIFEST.in0000644000175000017500000000036411726116730015011 0ustar jamesjames00000000000000include Makefile include NEWS include MANIFEST.in include test_all.py recursive-include examples *.py recursive-include gpgme *.py recursive-include tests *.py include tests/keys/*.pub include tests/keys/*.sec include src/*.c include src/*.h pygpgme-0.3/PKG-INFO0000664000175000017500000000157111726117114014350 0ustar jamesjames00000000000000Metadata-Version: 1.0 Name: pygpgme Version: 0.3 Summary: A Python module for working with OpenPGP messages Home-page: https://launchpad.net/pygpgme Author: James Henstridge Author-email: james@jamesh.id.au License: LGPL Description: PyGPGME is a Python module that lets you sign, verify, encrypt and decrypt messages using the OpenPGP format. It is built on top of the GNU Privacy Guard and the GPGME library. Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) Classifier: Operating System :: POSIX Classifier: Programming Language :: C Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Software Development :: Libraries :: Python Modules pygpgme-0.3/README0000644000175000017500000000231210431015202014106 0ustar jamesjames00000000000000A Python binding for the gpgme library, used to drive the gpg command line program. More information about gpgme can be found here: http://www.gnupg.org/(en)/related_software/gpgme/index.html This binding stays fairly close to the C API with the following exceptions: * Memory management is not exposed to the user * Functions like gpgme_get_foo()/gpgme_set_foo() are converted to attribute access on gpgme.Context objects. * Functions that take gpgme_data_t arguments take arbitrary Python file-like objects. The read(), write(), seek() and tell() methods may be used on the object. * Non-zero gpgme_error_t return values are converted to gpgme.error exceptions. * Only the synchronous versions of functions have been wrapped. However, the Python global interpreter lock is dropped, so should play nicely in multi-threaded Python programs. * Function pairs like gpgme_op_import()/gpgme_op_import_result() are combined into single method calls. * The Python version of gpgme_op_keylist() returns an iterator over the matched keys, rather than requiring the user to use a special iteration function. This library is licensed under the LGPL, the same license as the gpgme library.