pyme-0.8.1/0000700000175000017500000000000011113133435011445 5ustar belyibelyipyme-0.8.1/examples/0000700000175000017500000000000011112156244013265 5ustar belyibelyipyme-0.8.1/examples/listkeys.py0000600000175000017500000000210111020645560015504 0ustar belyibelyi#!/usr/bin/env python # initial 20080124 bernhard@intevation.de # 20080124-2: removed some superflous imports # This script is Free Software under GNU GPL v>=2. """A test applicaton for gpg_get_key() protocol.CMS. Tested on Debian Sid with python-pyme 0.7.0-3 libgpgme11 1.1.6-1 gpgsm 2.0.8-1 """ from pyme import core def printgetkeyresults(engine): """List all keys for the protocol""" print "Keys for protocol %s (%s, %s):" % \ (core.get_protocol_name(engine.protocol), engine.file_name, engine.version) c = core.Context() c.set_protocol(engine.protocol) for key in c.op_keylist_all(None, False): print "key(%s)" % key.subkeys[0].fpr for uid in key.uids: print "\t%s" % uid.uid def main(): # gpgme_check_version() necessary for initialisation according to # gogme 1.1.6 and this is not done automatically in pyme-0.7.0 print "gpgme version:", core.check_version(None) for eng in core.get_engine_info(): printgetkeyresults(eng) if __name__ == "__main__": main() pyme-0.8.1/examples/simple.py0000700000175000017500000000315510764554424015155 0ustar belyibelyi#!/usr/bin/env python # $Id: simple.py,v 1.5 2008/03/08 18:21:08 belyi Exp $ # Copyright (C) 2005 Igor Belyi # Copyright (C) 2002 John Goerzen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys from pyme import core, constants, errors import pyme.constants.validity core.check_version(None) # Set up our input and output buffers. plain = core.Data('This is my message.') cipher = core.Data() # Initialize our context. c = core.Context() c.set_armor(1) # Set up the recipients. sys.stdout.write("Enter name of your recipient: ") name = sys.stdin.readline().strip() c.op_keylist_start(name, 0) r = c.op_keylist_next() if r == None: print "The key for user \"%s\" was not found" % name else: # Do the encryption. try: c.op_encrypt([r], 1, plain, cipher) cipher.seek(0,0) print cipher.read() except errors.GPGMEError, ex: print ex.getstring() pyme-0.8.1/examples/testCMSgetkey.py0000600000175000017500000000212011112155770016372 0ustar belyibelyi#!/usr/bin/env python # initial 20080124 bernhard@intevation.de # 20080124-2: removed some superflous imports # 20080703: adapted for pyme-0.8.0 # This script is Free Software under GNU GPL v>=2. """A test applicaton for gpg_get_key() protocol.CMS. Tested on Debian Etch with pyme 0.8.0 (manually compiled) libgpgme11 1.1.6-0kk2 gpgsm 2.0.9-0kk2 """ import sys from pyme import core from pyme.constants import protocol def printgetkeyresults(keyfpr): """Run gpgme_get_key().""" # gpgme_check_version() necessary for initialisation according to # gogme 1.1.6 and this is not done automatically in pyme-0.7.0 print "gpgme version:", core.check_version(None) c = core.Context() c.set_protocol(protocol.CMS) key = c.get_key(keyfpr, False) print "got key: ", key.subkeys[0].fpr for uid in key.uids: print uid.uid def main(): if len(sys.argv) < 2: print "fingerprint or unique key ID for gpgme_get_key()" sys.exit(1) printgetkeyresults(sys.argv[1]) if __name__ == "__main__": main() pyme-0.8.1/examples/PyGtkGpgKeys.glade0000600000175000017500000015063610221373475016637 0ustar belyibelyi True GPG Keyring GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False 800 400 True False True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False 0 True GTK_SHADOW_OUT GTK_POS_LEFT GTK_POS_TOP True True _File True True Reload all keys from the keyring _Reload True True True gtk-quit True True _Key Admin True True Generate new key _Generate True True Delete selected keys (including secret ones) _Delete True True Import keys from a file _Import True True Export selected keys into a binary file _Export (binary) True True Export selected keys into an ASCII file Export (_text) True True T_rust True True Unknown key _Undefined True True Do NOT trust anything this key does _Never True True Trust this key but unsure about keys it signed _Marginal True True Trust this key and keys it signed _Full True True This is my own another key U_ltimate True True True Unimplemented Item _Edit True True _View True True _Help True True gtk-about True 0 False True True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_ETCHED_IN GTK_CORNER_TOP_LEFT True True True True False False 0 True True True True 0 False False GPG Password GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE True False True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True password: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False True True True False 0 True * False 0 False False 0 True True New Key Properties GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True 12 2 False 0 0 True Key-Length: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 1 2 fill True Key-Type: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 0 1 fill True Key-Usage: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 2 3 fill True Subkey-Type: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 3 4 fill True Subkey-Length: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 4 5 fill True Subkey-Usage: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 5 6 fill True Name-Real: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 6 7 fill True Name-Comment: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 7 8 fill True Name-Email: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 8 9 fill True Expire-Date: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 9 10 fill True DSA RSA 1 2 0 1 fill True True 1 0 False GTK_UPDATE_ALWAYS False False 1024 1024 4096 1 1024 10 1 2 1 2 True False 0 True True encrypt True GTK_RELIEF_NORMAL True False False True 0 False False True True sign True GTK_RELIEF_NORMAL True False False True 0 False False 1 2 2 3 fill fill True DSA ELG-E RSA 1 2 3 4 fill fill True True 1 0 False GTK_UPDATE_ALWAYS False False 1024 1024 4096 1 1024 10 1 2 4 5 True False 0 True True encrypt True GTK_RELIEF_NORMAL True False False True 0 False False True True sign True GTK_RELIEF_NORMAL True False False True 0 False False 1 2 5 6 fill fill True True True True 0 True * False 1 2 6 7 True True True True 0 True * False 1 2 7 8 True True True True 0 True * False 1 2 8 9 True Passphrase: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 10 11 fill True (repeat): False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 11 12 fill True True True False 0 True * False 1 2 10 11 True True True False 0 True * False 1 2 11 12 True True False 0 True True GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES True Unlimited False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 1 2 9 10 fill fill 0 True True Generating the key... GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE True 600 400 True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END True False 0 True gtk-dialog-info 6 0.5 0.5 0 0 0 False False True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True False True False False True GTK_JUSTIFY_LEFT GTK_WRAP_CHAR False 0 0 0 0 0 0 0 True True 0 True True About PyGtkGpgKeys GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False False True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True gtk-about 6 0.5 0.5 0 0 0 False False 6 True False 0 True <b>PyGtkGpgKeys</b> Graphical example of PyMe abilities. False True GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 10 True True True <i>GNU Public License</i> False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 10 True True True <small>(C) 2005 Igor Belyi</small> False True GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 10 True True 0 True True 0 True True pyme-0.8.1/examples/inter-edit.py0000600000175000017500000000374510764554424015734 0ustar belyibelyi#!/usr/bin/python # $Id: inter-edit.py,v 1.2 2008/03/08 18:21:08 belyi Exp $ # Copyright (C) 2005 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os, sys from pyme import core from pyme.core import Data, Context from pyme.constants import status core.check_version(None) # Get names for the status codes stat2str = {} for name in dir(status): if not name.startswith('__') and name != "util": stat2str[getattr(status, name)] = name # Print the output received since the last prompt before giving the new prompt def edit_fnc(stat, args, helper): global stat_strings try: while True: helper["data"].seek(helper["skip"],0) data = helper["data"].read() helper["skip"] += len(data) print data return raw_input("(%s) %s > " % (stat2str[stat], args)) except EOFError: pass # Simple interactive editor to test editor scripts if len(sys.argv) != 2: sys.stderr.write("Usage: %s \n" % sys.argv[0]) else: c = Context() out = Data() c.op_keylist_start(sys.argv[1], 0) key = c.op_keylist_next() helper = {"skip": 0, "data": out} c.op_edit(key, edit_fnc, helper, out) print "[-- Final output --]" out.seek(helper["skip"],0) print out.read() pyme-0.8.1/examples/PyGtkGpgKeys.gladep0000600000175000017500000000043110221373475017002 0ustar belyibelyi GtkGpgKeys GtkGpgKeys FALSE pyme-0.8.1/examples/hangtest.py0000600000175000017500000000137311050153505015460 0ustar belyibelyifrom pyme import core, constants def Callback(x, y, z): """ Callback to give password """ print "I'm in the callback!" return "abcdabcdfs\n" plaintext = "Hello World!" crypttext = "" #First set of data plaindata1 = core.Data(plaintext) cryptdata1 = core.Data() cont = core.Context() cont.set_armor(True) #ASCII cont.op_keylist_start("Joe Tester", 1) #use first key cont.op_encrypt([cont.op_keylist_next()], 1, plaindata1, cryptdata1) cryptdata1.seek(0,0) crypttext = cryptdata1.read() print "Encrypted Data:\n %s" % crypttext cryptdata2 = core.Data(crypttext) plaindata2 = core.Data() cont.set_passphrase_cb(Callback) cont.op_decrypt(cryptdata2, plaindata2) #freeze here!!!! plaindata2.seek(0,0) print "Decrypted Data:\n %s" % plaindata2.read() pyme-0.8.1/examples/pygpa.py0000700000175000017500000016774710771334750015022 0ustar belyibelyi#!/usr/bin/python # $Id: pygpa.py,v 1.5 2008/03/23 02:01:12 belyi Exp $ # Copyright (C) 2005,2008 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import gtk, gobject, gtk.glade import gettext import time, sys, os from pyme import errors, core from pyme.core import Context, Data, pubkey_algo_name from pyme.constants import validity, status, keylist, sig, sigsum # Enable internationalization using gpa translation pages. gettext.install('gpa', None, 1) gtk.glade.bindtextdomain('gpa') gtk.glade.textdomain('gpa') # Thanks to Bernhard Reiter for pointing out the following: # gpgme_check_version() necessary for initialisation according to # gpgme 1.1.6 and this is not done automatically in pyme-0.7.0 print "gpgme version:", core.check_version() # Helper functions to convert non-string data into printable strings def sec2str(secs, empty="_(Unknown)"): "Convert seconds since 1970 into mm/dd/yy string" if secs > 0: return time.strftime("%m/%d/%y", time.localtime(secs)) elif secs == 0: return empty else: return "" trusts = { validity.UNDEFINED: "Unknown", validity.NEVER: "Never", validity.MARGINAL: "Marginal", validity.FULL: "Full", validity.ULTIMATE: "Ultimate" } def validity2str(valid): "Convert trust integer into a human understandable string" if trusts.has_key(valid): return _("%s" % trusts[valid]) else: return _("Unknown") def keyvalid2str(key): "Create a string representing validity of a key" if key.owner_trust==validity.ULTIMATE: return _("Fully Valid") if key.revoked: return _("Revoked") if key.expired: return _("Expired") if key.disabled: return _("Disabled") if not key.uids or key.uids[0].invalid: return _("Incomplete") return _("Unknown") def subvalid2str(subkey): "Create a string representing validity of a subkey" if subkey.revoked: return _("Revoked") if subkey.expired: return _("Expired") if subkey.disabled: return _("Disabled") if subkey.invalid: return _("Unsigned") return _("Valid") def signstat2str(sig): "Create a string representing validity of a signature" status = _("Unknown") if sig.status == 1: status = _("Valid") elif sig.status == 2: status = _("Bad") if sig.expired: status = _("Expired") elif sig.revoked: status = _("Revoked") return status def sigsum2str(summary): if summary & sigsum.VALID: return _("Valid") if summary & sigsum.RED: return _("Bad") if summary & sigsum.KEY_MISSING: return _("Unknown Key") if summary & sigsum.KEY_REVOKED: return _("Revoked Key") if summary & sigsum.KEY_EXPIRED: return _("Expired Key") return _("Key NOT valid") def class2str(cls): "Convert signature class integer into a human understandable string" if cls==0x10: return _("Generic") if cls==0x11: return _("Persona") if cls==0x12: return _("Casual") if cls==0x13: return _("Positive") return _("Unknown") def algo2str(algo): "Convert algorithm integer into a human understandable string" return pubkey_algo_name(algo) def fpr2str(fpr): "Convert fpr string in a sparsely spaced string for easy reading" result = [] while fpr: result.append(fpr[:4]) fpr = fpr[4:] return " ".join(result) # Helper functions for tasks unrelated to any class def obj2model(objs, columns): "Create a model from the obj (key, subkey, or signature) using columns" model = gtk.ListStore(*[x.ctype for x in columns]) for obj in objs: model.append([x.cfunc(obj) for x in columns]) return model def labels2table(key_labels): "Create a gtk.Table from an array of 2-tuples of strings" table = gtk.Table(len(key_labels), 2) for i, row in enumerate(key_labels): if len(row) != 2: raise ValueError("Unexpected number of rows in labels2table call") label1 = gtk.Label(row[0]) label1.set_alignment(1.0, 0.5) label2 = gtk.Label(row[1]) label2.set_alignment(0.0, 0.5) label2.set_padding(5, 0) table.attach(label1, 0, 1, i, i+1, gtk.FILL, gtk.FILL) table.attach(label2, 1, 2, i, i+1, gtk.FILL, gtk.FILL) return table status2str = {} for name in dir(status): if not name.startswith('__') and name != "util": status2str[getattr(status, name)] = name def editor_func(status, args, val_dict): prompt = "%s %s" % (val_dict["state"], args) if val_dict.has_key(prompt): val_dict["state"] = val_dict[prompt][0] return val_dict[prompt][1] elif args and not val_dict.has_key("ignore %s" % status2str[status]): for error in ["error %s" % status2str[status], "error %s" % prompt]: if val_dict.has_key(error): raise errors.GPGMEError(val_dict[error]) sys.stderr.write(_("Unexpected status and prompt in editor_func: " + "%s %s\n") % (status2str[status], prompt)) raise EOFError() return "" common_dict = { "state": "start", "quit keyedit.save.okay": ("save", "Y"), "ignore NEED_PASSPHRASE": None, "ignore NEED_PASSPHRASE_SYM": None, "ignore BAD_PASSPHRASE": None, "ignore USERID_HINT": None } def change_key_expire(context, key, date): "Change key's expiration date to date" val_dict = common_dict.copy() val_dict.update({ "start keyedit.prompt": ("expire", "expire"), "expire keygen.valid": ("date", date), "date keyedit.prompt": ("quit", "quit") }) out = Data() context.op_edit(key, editor_func, val_dict, out) def change_key_trust(context, key, new_trust): "Change key's trust to new_trust" val_dict = common_dict.copy() val_dict.update({ "start keyedit.prompt": ("trust", "trust"), "trust edit_ownertrust.value": ("value", "%d" % new_trust), "value edit_ownertrust.set_ultimate.okay": ("value", "Y"), "value keyedit.prompt": ("quit", "quit") }) out = Data() context.op_edit(key, editor_func, val_dict, out) def sign_key(context, key, sign_key, local): "Sign key using sign_key. Signature is exportable if local is False" # Values copied from GPG_ERR_CONFLICT = 70 GPG_ERR_UNUSABLE_PUBKEY = 53 val_dict = common_dict.copy() val_dict.update({ "start keyedit.prompt": ("sign", (local and "lsign") or "sign"), "sign keyedit.sign_all.okay": ("sign", "Y"), "sign sign_uid.expire": ("sign", "Y"), "sign sign_uid.class": ("sign", "0"), "sign sign_uid.okay": ("okay", "Y"), "okay keyedit.prompt": ("quit", "quit"), "error ALREADY_SIGNED": GPG_ERR_CONFLICT, "error sign keyedit.prompt": GPG_ERR_UNUSABLE_PUBKEY }) out = Data() context.signers_clear() context.signers_add(sign_key) context.op_edit(key, editor_func, val_dict, out) def trigger_change_password(context, key): "Trigger sequence of passphrase_cb callbacks to change password of the key" val_dict = common_dict.copy() val_dict.update({ "start keyedit.prompt": ("passwd", "passwd"), "passwd keyedit.prompt": ("quit", "quit") }) out = Data() context.op_edit(key, editor_func, val_dict, out) # Helper classes whose instances are used in the major PyGpa class class KeyInfo: """Helper class to represent key information in different views. If KeyInfo instance is initialized with an integer as a key the views correspond to a state when multiple or no keys are selected""" def __init__(self, key, secret=None): self.key = key self.secret = secret def key_print_labels(self, fpr=False): "Create an array of 2-tuples for 'User Name' and 'Key ID' fields" labels = [] if type(self.key) != int: if self.key.uids: labels.append((_("User Name:"), self.key.uids[0].uid)) for uid in self.key.uids[1:]: labels.append(("", uid.uid)) if fpr: labels += [(_("Fingerprint:"), fpr2str(self.key.subkeys[0].fpr))] else: labels += [(_("Key ID:"), self.key.subkeys[0].keyid[-8:])] return labels def key_expires_label(self): return sec2str(self.key.subkeys[0].expires,_("never expires")) def details(self): "Create a widget for 'Details' notebook tab" if type(self.key) == int: if self.key: details=gtk.Label(_("%d keys selected") % self.key) else: details=gtk.Label(_("No keys selected")) details.set_alignment(0.5, 0) return details if self.secret: header = _("The key has both a private and a public part") else: header = _("The key has only a public part") key_info_labels = [("", header)] if self.key.can_certify: if self.key.can_sign: if self.key.can_encrypt: ability = _("The key can be used for certification, " + "signing and encryption.") else: ability = _("The key can be used for certification and " + "signing, but not for encryption.") else: if self.key.can_encrypt: ability = _("The key can be used for certification and " + "encryption.") else: ability = _("The key can be used only for certification.") else: if self.key.can_sign: if self.key.can_encrypt: ability = _("The key can be used only for signing and " + "encryption, but not for certification.") else: ability = _("The key can be used only for signing.") else: if self.key.can_encrypt: ability = _("The key can be used only for encryption.") else: ability = _("This key is useless.") key_info_labels.append(("", ability)) key_info_labels += self.key_print_labels() + [ (_("Fingerprint:"), fpr2str(self.key.subkeys[0].fpr)), (_("Expires at:"), self.key_expires_label()), (_("Owner Trust:"), validity2str(self.key.owner_trust)), (_("Key Validity:"), keyvalid2str(self.key)), (_("Key Type:"), _("%s %u bits") % \ (algo2str(self.key.subkeys[0].pubkey_algo),self.key.subkeys[0].length)), (_("Created at:"), sec2str(self.key.subkeys[0].timestamp)) ] return labels2table(key_info_labels) def sign_model(self): "Create a model for ComboBox of uids in 'Signatures' notebook tab" model = gtk.ListStore(str, gtk.ListStore) if type(self.key) != int: for uid in self.key.uids: model.append([uid.uid, obj2model(uid.signatures,sign_columns)]) return model def subkey_model(self): "Create a model for TreeView in 'Subkeys' notebook tab" if type(self.key) == int: return gtk.ListStore(*[x.ctype for x in subkey_columns]) else: return obj2model(self.key.subkeys, subkey_columns) class Column: "Helper class to represent a column in a TreeView" def __init__(self, name, ctype, cfunc, detail=False): """Column(name, ctype, cfunc): name - Name to use as a column header ctype - type to use in a model definition for this column cfunc - function retrieving column's infromation from an object detail- indicate if it's a detail visible only in detailed view""" self.name = name self.ctype = ctype self.cfunc = cfunc self.detail = detail # Columns for the list of keys which can be used as default def_keys_columns = [ Column(_("Key ID"), str, lambda x,y: x.subkeys[0].keyid[-8:]), Column(_("User Name"), str, lambda x,y: (x.uids and x.uids[0].uid) or _("[Unknown user ID]")), Column(None, gobject.TYPE_PYOBJECT, lambda x,y: KeyInfo(x,y)) ] # Columns for the list of all keys in the keyring keys_columns = [ Column("", str, lambda x,y: (y and "sec") or "pub"), def_keys_columns[0], Column(_("Expiry Date"), str, lambda x,y: sec2str(x.subkeys[0].expires, _("never expires")), True), Column(_("Owner Trust"),str,lambda x,y:validity2str(x.owner_trust),True), Column(_("Key Validity"), str, lambda x,y: keyvalid2str(x), True) ] + def_keys_columns[1:] # Columns for the list of signatures on a uid sign_columns = [ Column(_("Key ID"), str, lambda x: x.keyid[-8:]), Column(_("Status"), str, lambda x: signstat2str(x)), Column(_("Level"), str, lambda x: class2str(x.sig_class)), Column(_("Local"), type(True), lambda x: x.exportable==0), Column(_("User Name"), str, lambda x: x.uid or _("[Unknown user ID]")) ] # Columns for the list of subkeys subkey_columns = [ Column(_("Subkey ID"), str, lambda x: x.keyid[-8:]), Column(_("Status"), str, lambda x: subvalid2str(x)), Column(_("Algorithm"), str, lambda x: algo2str(x.pubkey_algo)), Column(_("Size"), str, lambda x: _("%u bits") % x.length), Column(_("Expiry Date"), str, lambda x: sec2str(x.expires, _("never expires"))), Column(_("Can sign"), type(True), lambda x: x.can_sign), Column(_("Can certify"), type(True), lambda x: x.can_certify), Column(_("Can encrypt"), type(True), lambda x: x.can_encrypt), Column(_("Can authenticate"), type(True), lambda x: x.can_authenticate) ] file_columns = [ Column(_("File"), str, lambda x: x) ] class PyGpa: "Major class representing PyGpa application" def popup(self, dialog, parent=None, title=None): "Common way to popup a dialog defined in Glade" dialog.set_transient_for(parent or self.main_window) if title: dialog.set_title(title) result = dialog.run() dialog.hide() return result def file_popup(self, dialog, parent=None, title=None): return self.popup(dialog, parent or self.filemanager_window, title) def error_message(self, text, parent=None, title=_("Warning")): "Pop up an error message dialog" if type(text) == long: text = errors.GPGMEError(text).getstring() title = "GPGME error" elif isinstance(text, errors.GPGMEError): text = text.getstring() title = "GPGME error" self.error_label.set_text(text) self.popup(self.error_dialog, parent, title) def file_error_message(self, text, parent=None, title=_("Warning")): self.error_message(text, parent or self.filemanager_window, title) def info_message(self, text, parent=None, title=_("Information")): "Pop up an information dialog" self.info_label.set_text(text) self.popup(self.info_dialog, parent, title) def yesno_message(self, text, parent=None): "Pop up a dialog requiring yes/no answer" self.yesno_label.set_text(text) return self.popup(self.yesno_dialog, parent, _("Warning")) == gtk.RESPONSE_YES def on_uid_list_changed(self, uid_list): "this callback is called when uid selection is changed" index = uid_list.get_active() if index == -1: self.sign_treeview.set_model(KeyInfo(0).sign_model()) else: self.sign_treeview.set_model(uid_list.get_model()[index][1]) def get_selected_keys(self, treeview=None): "Helper function to get all selected rows in a treeview" if not treeview: treeview = self.keys_treeview model, rows = treeview.get_selection().get_selected_rows() return [model[path] for path in rows] def on_keys_changed(self, keys_treeview): "this callback is called when key selection is changed" selection = keys_treeview.get_selection() count = selection.count_selected_rows() if count == 1: key_info = self.get_selected_keys()[0][-1] else: key_info = KeyInfo(count) self.update_menu(key_info) # Update Details tab of the notebook old_child = self.details_view.get_child() if old_child: self.details_view.remove(old_child) self.details_view.add(key_info.details()) self.details_view.show_all() # Update Subkeys tab of the notebook self.subkeys_treeview.set_model(key_info.subkey_model()) # Update Signatures tab of the notebook sign_model = key_info.sign_model() self.uid_list.set_model(sign_model) if len(sign_model) < 2: self.uid_list_box.hide() else: self.uid_list_box.show_all() self.uid_list.set_active(0) self.on_uid_list_changed(self.uid_list) def on_keys_button_press(self, obj, event): "callback on a mouse press in the keys_treeview" if event.button == 3: self.popup_menu.popup(None, None, None, event.button, event.time) return True return False def create_popup_menu(self): "create the popup menu shown on right mouse click" self.items = [ (gtk.ImageMenuItem(gtk.STOCK_COPY), self.on_copy_activate), (gtk.ImageMenuItem(gtk.STOCK_PASTE), self.on_paste_activate), (gtk.ImageMenuItem(gtk.STOCK_DELETE), self.on_delete_activate), (gtk.SeparatorMenuItem(), None), (gtk.MenuItem(_("_Sign Keys...")), self.on_sign_keys_activate), (gtk.MenuItem(_("Set _Owner Trust...")), self.on_set_owner_trust_activate), (gtk.MenuItem(_("_Edit Private Key...")), self.on_edit_private_key_activate), (gtk.SeparatorMenuItem(), None), (gtk.MenuItem(_("E_xport Keys...")), self.on_export_keys_activate) ] self.popup_menu = gtk.Menu() for item, callback in self.items: if callback: item.connect("activate", callback) self.popup_menu.append(item) self.popup_menu.show_all() def update_menu(self, key_info): "update sensitivity of menu items depending on what keys are selected" # copy, delete, sign, trust, edit, export if key_info.secret == None: if key_info.key: # more than one key selected values = ( True, True, True, False, False, True) else: # no keys selected values = (False, False, False, False, False, False) elif key_info.secret: if key_info.key == self.default_key: # default key seleted values = ( True, True, False, True, True, True) else: # secret (not default) key selected values = ( True, True, True, True, True, True) else: # public key selected values = ( True, True, True, True, False, True) for w,v in zip((self.copy, self.delete, self.sign_keys, self.set_owner_trust, self.edit_private_key, self.export_keys), values): w.set_sensitive(v) for w,v in zip((self.items[0][0], self.items[2][0], self.items[4][0], self.items[5][0], self.items[6][0], self.items[8][0]), values): w.set_sensitive(v) def setup_columns(self): "Helper function to setup columns of different treeviews" for treeview, columns in \ [(self.keys_treeview, keys_columns), (self.sign_treeview, sign_columns), (self.subkeys_treeview, subkey_columns), (self.def_keys_treeview, def_keys_columns), (self.sign_with_keys_treeview, def_keys_columns), (self.encrypt_with_keys_treeview, def_keys_columns), (self.files_treeview, file_columns)]: for index, item in enumerate([x for x in columns if x.name!=None]): if item.ctype == str: renderer = gtk.CellRendererText() attrs = {"text": index} else: renderer = gtk.CellRendererToggle() attrs = {"active": index} column = treeview.insert_column_with_attributes( index, item.name, renderer, **attrs) column.set_sort_column_id(index) column.set_visible(not item.detail) for index,item in enumerate([x for x in keys_columns if x.name!=None]): if item.name and not item.detail: renderer = gtk.CellRendererText() column = gtk.TreeViewColumn(item.name, renderer, text=index) column.set_sort_column_id(index) self.encrypt_for_keys_treeview.append_column(column) for treeview in [self.encrypt_with_keys_treeview, self.keys_treeview, self.encrypt_for_keys_treeview, self.files_treeview, self.sign_with_keys_treeview]: treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.def_keys_treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) cell = gtk.CellRendererText() self.uid_list.pack_start(cell, True) self.uid_list.add_attribute(cell, 'text', 0) model = gtk.ListStore(str, str) for lines in [(_("days"), "d"), (_("weeks"), "w"), (_("months"), "m"), (_("years"), "y")]: model.append(lines) self.new_expire_unit_combo.set_model(model) self.new_expire_unit_combo.child.set_editable(False) self.new_algorithm_combo.child.set_editable(False) self.files_treeview.set_model(gtk.ListStore(str)) def setup_default_views(self): "Setup initial values for different views" self.update_default_keys() self.on_advanced_mode_toggled(self.advanced_mode_rb) self.create_popup_menu() self.on_keys_changed(self.keys_treeview) def load_keys(self): "Download keys from the keyring" context = Context() sec_keys = {} for key in context.op_keylist_all(None, 1): sec_keys[key.subkeys[0].fpr] = 1 model = gtk.ListStore(*[x.ctype for x in keys_columns]) encrypt_model = gtk.ListStore(*[x.ctype for x in keys_columns]) context.set_keylist_mode(keylist.mode.SIGS) for key in context.op_keylist_all(None, 0): secret = sec_keys.has_key(key.subkeys[0].fpr) data = [x.cfunc(key, secret) for x in keys_columns] if key.can_encrypt: encrypt_model.append(data) model.append(data) self.keys_treeview.set_model(model) self.encrypt_for_keys_treeview.set_model(encrypt_model) def set_default_key(self, key): "Setup default key and update status bar with it" self.default_key = key self.status_uid.set_text((key.uids and key.uids[0].uid) or \ _("[Unknown user ID]")) self.status_keyid.set_text(key.subkeys[0].keyid[-8:]) def on_default_keys_changed(self, treeview): "This callback is called when default key is changed in Preferences" model, rows = treeview.get_selection().get_selected_rows() if model and rows: self.set_default_key(model[rows[0]][-1].key) def add_default_key(self, model, path, iter, def_model): "Helper function to add secret keys to the list of possible defaults" key = model[path][-1] if key.secret: def_model.append([x.cfunc(key.key,True) for x in def_keys_columns]) def add_sig_key(self, model, path, iter, sign_model): "Helper function to add secret keys to the list of possible defaults" key = model[path][-1].key if key.can_sign: sign_model.append([x.cfunc(key,True) for x in def_keys_columns]) def select_default_key(self, model, path, iter): "Helper function to select current default key from the available list" if model[path][-1].key == self.default_key: self.def_keys_treeview.get_selection().select_path(path) def update_default_keys(self): "Update list of default keys" model = gtk.ListStore(*[x.ctype for x in def_keys_columns]) self.keys_treeview.get_model().foreach(self.add_default_key, model) self.def_keys_treeview.set_model(model) model.foreach(self.select_default_key) selection = self.def_keys_treeview.get_selection() if selection.count_selected_rows() != 1: selection.select_path((0,)) self.on_default_keys_changed(self.def_keys_treeview) model = gtk.ListStore(*[x.ctype for x in def_keys_columns]) self.def_keys_treeview.get_model().foreach(self.add_sig_key, model) self.sign_with_keys_treeview.set_model(model) self.encrypt_with_keys_treeview.set_model(model) def on_select_all_activate(self, obj): "This callback is called when SelectAll menu item is selected" self.keys_treeview.get_selection().select_all() def on_file_preferences_activate(self, obj): "Callback called when Preferences menu item is selected in filemanager" self.show_preferences(self.filemanager_window) def on_preferences_activate(self, obj): "Callback called when Preferences menu item is selected in key editor" self.show_preferences(None) def show_preferences(self, parent): "Show preferences positioning its window in the middle of the parent" self.popup(self.preferences_dialog, parent) self.def_keyserver = self.default_keyserver_combox.child.get_text() def on_advanced_mode_toggled(self, radiobutton): "This callback is called when Advanced Mode selection is changed" if radiobutton.get_active(): self.subkeys_notebook_tab.show() self.get_generate_params = self.get_advanced_generate_params else: self.subkeys_notebook_tab.hide() self.get_generate_params = self.get_novice_generate_params def popup_progress_dialog(self, label, parent): self.progress_dialog.set_transient_for(parent) self.progress_label.set_text(label) self.progress_dialog.show_all() gobject.timeout_add(100, self.update_progress) def on_progress_cancel_clicked(self, obj): self.progress_context.cancel() def update_progress(self): "Helper function to show progress while a work on a key is being done" try: status = self.progress_context.wait(0) if status == None or self.progress_func(status): self.new_progressbar.pulse() return True except errors.GPGMEError, exc: self.error_message(exc) self.progress_context = None self.progress_func = None self.progress_dialog.hide() # Let callback to be removed. return False def key_generate_done(self, status): "Helper function called on the completion of a key generation" if status == 0: fpr = self.progress_context.op_genkey_result().fpr self.progress_context.set_keylist_mode(keylist.mode.SIGS) key = self.progress_context.get_key(fpr, 0) data = [x.cfunc(key, True) for x in keys_columns] self.keys_treeview.get_model().append(data) if key.can_encrypt: self.encrypt_for_keys_treeview.get_model().append(data) self.update_default_keys() else: self.error_message(status) return False def on_new_activate(self, obj): "Callback for 'New Key' menu item" params = self.get_generate_params() if params == None: return (key_algo, subkeys, size, userid, email, comment, expire, password, backup) = params gen_string = "\n" + \ "Key-Type: %s\n" % key_algo + \ "Key-Length: %d\n" % size if subkeys: gen_string += "Subkey-Type: %s\n" % subkeys + \ "Subkey-Length: %d\n" % size gen_string += "Name-Real: %s\n" % userid if email: gen_string += "Name-Email: %s\n" % email if comment: gen_string += "Name-Comment: %s\n" % comment if expire: gen_string += "Expire-Date: %s\n" % expire if password: gen_string += "Passphrase: %s\n" % password gen_string += "\n" self.progress_context = Context() self.progress_context.op_genkey_start(gen_string, None, None) self.progress_func = self.key_generate_done self.popup_progress_dialog(_("Generating Key..."), self.main_window) def check_passphrase(self, passphrase, repeat_passphrase, parent): """Helper function to check that enetered password satisfies our requirements""" if not passphrase: self.error_message(_('You did not enter a passphrase.\n' + 'It is needed to protect your private key.'), parent) elif repeat_passphrase != passphrase: self.error_message(_('In "Passphrase" and "Repeat passphrase",\n' + 'you must enter the same passphrase.'), parent) else: return True return False def get_novice_generate_params(self): "Helper function to get generate key parameter in Novice mode" dialogs = [self.generate_userid_dialog, self.generate_email_dialog, self.generate_comment_dialog, self.generate_passphrase_dialog, self.generate_backup_dialog] step = 0 params = None while step>=0: dialog = dialogs[step] dialog.set_transient_for(self.main_window) result = dialog.run() newstep = step if result == 2: if step == 0: userid = self.generate_novice_userid_entry.get_text() if userid: newstep = step + 1 else: self.error_message(_("Please insert your name.")) elif step == 1: email = self.generate_novice_email_entry.get_text() if email: newstep = step + 1 else: self.error_message(_("Please insert your email address")) elif step == 2: comment = self.generate_novice_comment_entry.get_text() newstep = step + 1 elif step == 3: passphrase=self.generate_novice_passphrase_entry.get_text() if self.check_passphrase( passphrase, self.generate_novice_repeat_passphrase_entry.get_text(), dialog): newstep = step + 1 elif step == 4: backup = self.generate_novice_backup_rb.get_active() params = ("DSA", "ELG-E", 1024, userid, email, comment, "", passphrase, backup) newstep = -1 elif result == 1: newstep = step - 1 else: newstep = -1 if newstep != step: dialog.hide() step = newstep self.generate_novice_userid_entry.set_text("") self.generate_novice_email_entry.set_text("") self.generate_novice_comment_entry.set_text("") self.generate_novice_passphrase_entry.set_text("") self.generate_novice_repeat_passphrase_entry.set_text("") return params def on_new_expire_on_rb_toggled(self, expireon_rb): self.new_expire_calendar.set_sensitive(expireon_rb.get_active()) def on_new_expire_after_rb_toggled(self, expireafter_rb): active = expireafter_rb.get_active() self.new_expire_count_entry.set_sensitive(active) self.new_expire_unit_combo.set_sensitive(active) def get_advanced_generate_params(self): "Helper function to get generate key parameter in Advanced mode" params = None self.new_expire_unit_combo.set_active(0) self.new_algorithm_combo.set_active(0) self.new_key_size_combo.set_active(1) self.generate_dialog.set_transient_for(self.main_window) while params == None and self.generate_dialog.run() == gtk.RESPONSE_OK: passphrase = self.new_passphrase_entry.get_text() if not self.check_passphrase( passphrase, self.new_repeat_passphrase_entry.get_text(), self.generate_dialog): continue key_algo, subkeys = { 'DSA and ElGamal (default)': ("DSA", "ELG-E"), 'DSA (sign only)': ("DSA", ""), 'RSA (sign only)': ("RSA", "") }[self.new_algorithm_combo.child.get_text()] try: size = int(self.new_key_size_combo.child.get_text()) except ValueError: self.new_key_size_combo.child.grab_focus() continue userid = self.new_userid_entry.get_text() email = self.new_email_entry.get_text() comment = self.new_comment_entry.get_text() expire = "" if self.new_expire_after_rb.get_active(): model = self.new_expire_unit_combo.get_model() unit = model[(self.new_expire_unit_combo.get_active(),)][1] try: value = int(self.new_expire_count_entry.get_text()) except ValueError: self.new_expire_count_entry.grab_focus() continue expire = "%d%s" % (value, unit) elif self.new_expire_on_rb.get_active(): (year, month, day) = self.new_expire_calendar.get_date() expire = "%04d-%02d-%02d" % (year, month+1, day) params = (key_algo, subkeys, size, userid, email, comment, expire, passphrase, False) self.generate_dialog.hide() self.new_passphrase_entry.set_text("") self.new_repeat_passphrase_entry.set_text("") return params def del_key(self, key, treeview): "Helper function to delete a key from a treeview list" row_list = [] treeview.get_model().foreach(lambda m,p,i,l: l.append(m[p]), row_list) for row in row_list: if row[-1].key.subkeys[0].fpr == key.subkeys[0].fpr: row.model.remove(row.iter) def on_delete_activate(self, obj): "Callback for 'Delete Keys' menu item" message = { True: _("This key has a secret key. Deleting this key cannot be"+ " undone, unless you have a backup copy."), False: _("This key is a public key. Deleting this key cannot be "+ "undone easily, although you may be able to get a new " + "copy from the owner or from a key server.") } keytag = self.delete_key_keyinfo for row in self.get_selected_keys(): self.delete_key_label.set_text(message[row[-1].secret]) table = labels2table(row[-1].key_print_labels()) keytag.add(table) keytag.show_all() if self.popup(self.delete_key_dialog) == gtk.RESPONSE_YES: context = Context() context.op_delete(row[-1].key, 1) if row[-1].key.can_encrypt: self.del_key(row[-1].key, self.encrypt_for_keys_treeview) row.model.remove(row.iter) self.update_default_keys() self.on_keys_changed(self.keys_treeview) keytag.remove(table) def password_cb(self, hint, desc, prev_bad, hook=None): "Callback to setup verification of a passphrase" if prev_bad: header = _("Wrong passphrase, please try again:") else: header = _("Please enter the passphrase for the following key:") self.password_prompt_label.set_text(header) keyid, userid = hint.split(" ", 1) table = labels2table([(_("User Name:"), userid), (_("Key ID:"), keyid[-8:])]) self.password_prompt_keyinfo.add(table) self.password_prompt_keyinfo.show_all() password = None if self.popup(self.password_prompt_dialog) == gtk.RESPONSE_OK: password = self.password_prompt_entry.get_text() self.password_prompt_keyinfo.remove(table) self.password_prompt_entry.set_text("") if not password: GPG_ERR_CANCELED = 99 raise errors.GPGMEError(GPG_ERR_CANCELED) return password def password_change_cb(self, hint, desc, prev_bad, hook): "Callback to setup for passphrase change" if not prev_bad: hook["count"] += 1 if hook["count"] == 1: return self.password_cb(hint, desc, prev_bad) else: password = None self.password_change_dialog.set_transient_for(self.main_window) while password == None and \ self.password_change_dialog.run() == gtk.RESPONSE_OK: password = self.password_change_passphrase.get_text() if not self.check_passphrase( password, self.password_change_repeat_passphrase.get_text(), self.password_change_dialog): password = None self.password_change_dialog.hide() self.password_change_passphrase.set_text("") self.password_change_repeat_passphrase.set_text("") if not password: GPG_ERR_CANCELED = 99 raise errors.GPGMEError(GPG_ERR_CANCELED) return password def on_sign_keys_activate(self, obj): "Callback for 'Sign keys' menu item" context = Context() context.set_passphrase_cb(self.password_cb) context.set_keylist_mode(keylist.mode.SIGS) keytag = self.sign_key_keyinfo for row in self.get_selected_keys(): if row[-1].key == self.default_key: continue if len(row[-1].key.uids) > 1: self.sign_manyuids_label.show() else: self.sign_manyuids_label.hide() table = labels2table(row[-1].key_print_labels(True)) keytag.add(table) keytag.show_all() if self.popup(self.sign_key_dialog) == gtk.RESPONSE_YES: try: sign_key(context, row[-1].key, self.default_key, self.sign_locally_cb.get_active()) row[-1].key=context.get_key(row[-1].key.subkeys[0].fpr,0) self.on_keys_changed(self.keys_treeview) except errors.GPGMEError, exc: self.error_message(exc) keytag.remove(table) def on_change_passphrase_clicked(self, obj, key_info): "Callback for 'Change passphrase' button in editor for a private key" try: context = Context() context.set_passphrase_cb(self.password_change_cb, {"count": 0}) trigger_change_password(context, key_info.key) except errors.GPGMEError, exc: self.error_message(exc) def on_change_expiry_expireon_rb_toggled(self, expire_rb): "Callback for 'never expire' radiobutton in editor for a private key" self.change_expiry_calendar.set_sensitive(expire_rb.get_active()) def on_change_expiration_clicked(self, obj, key_info): "Callback for 'Change expiration' button in editor for a private key" if key_info.key.subkeys[0].expires: year, month, day = time.localtime(key_info.key.subkeys[0].expires)[:3] self.change_expiry_calendar.select_month(month-1, year) self.change_expiry_calendar.select_day(day) self.change_expiry_expireon_rb.set_active(True) else: self.change_expiry_never_rb.set_active(True) if self.popup(self.change_expiry_dialog, self.edit_key_dialog) == gtk.RESPONSE_OK: year, month, day = self.change_expiry_calendar.get_date() expire = "%04d-%02d-%02d" % (year, month+1, day) try: context = Context() context.set_passphrase_cb(self.password_cb) change_key_expire(context, key_info.key, expire) context.set_keylist_mode(keylist.mode.SIGS) key_info.key=context.get_key(key_info.key.subkeys[0].fpr,0) self.on_keys_changed(self.keys_treeview) self.edit_key_date_label.set_text(key_info.key_expires_label()) except errors.GPGMEError, exc: self.error_message(exc) def on_edit_private_key_activate(self, obj): "Callback for 'Edit Private Key' menu item" keys = self.get_selected_keys() if len(keys) != 1 or not keys[0][-1].secret: return key_info = keys[0][-1] table = labels2table(key_info.key_print_labels()) self.edit_key_date_label.set_text(key_info.key_expires_label()) self.edit_key_keyinfo.add(table) self.edit_key_keyinfo.show_all() connect1_id = self.edit_key_change_expiration.connect( "clicked", self.on_change_expiration_clicked, key_info) connect2_id = self.edit_key_change_passphrase.connect( "clicked", self.on_change_passphrase_clicked, key_info) self.popup(self.edit_key_dialog) self.edit_key_change_expiration.disconnect(connect1_id) self.edit_key_change_passphrase.disconnect(connect2_id) self.edit_key_keyinfo.remove(table) def on_set_owner_trust_activate(self, obj): "Callback for 'Set Owner Trust' menu item" keys = self.get_selected_keys() if len(keys) != 1: return key_info = keys[0][-1] table = labels2table(key_info.key_print_labels()) self.ownertrust_key.add(table) self.ownertrust_key.show_all() trust = key_info.key.owner_trust if trust < 0 or not trusts.has_key(trust): trust = validity.UNDEFINED getattr(self, "ownertrust_"+trusts[trust]).set_active(True) if self.popup(self.ownertrust_dialog) == gtk.RESPONSE_OK: for trust, name in trusts.iteritems(): if getattr(self, "ownertrust_"+name).get_active(): try: context = Context() change_key_trust(context, key_info.key, trust) key_info.key.owner_trust = trust self.on_keys_changed(self.keys_treeview) except errors.GPGMEError, exc: self.error_message(exc) break self.ownertrust_key.remove(table) def import_keys_from_data(self, data): "Helper function to import keys into application from a Data() object" context = Context() status = context.op_import(data) if status: self.error_message(status) else: result = context.op_import_result() if result.considered == 0: self.error_message(_("No keys were found.")) else: self.load_keys() self.info_message(_("%i public keys read\n" + "%i public keys imported\n" + "%i public keys unchanged\n" + "%i secret keys read\n" + "%i secret keys imported\n" + "%i secret keys unchanged") % \ (result.considered, result.imported, result.unchanged, result.secret_read, result.secret_imported, result.secret_unchanged)) def import_from_clipboard(self, clipboard, text, data): "Callback to setup extraction of data from a clipboard" if text: self.import_keys_from_data(Data(text)) def on_paste_activate(self, obj): "Callback for 'Paste' menu item" gtk.clipboard_get().request_text(self.import_from_clipboard) def on_import_keys_activate(self, obj): "Callback for 'Import Keys' menu item" import_file = None dialog = self.import_file_dialog dialog.set_transient_for(self.main_window) while import_file == None and dialog.run() == gtk.RESPONSE_OK: try: import_file = file(dialog.get_filename(), "rb") except IOError, strerror: self.error_message(strerror, dialog) import_file = None dialog.hide() if import_file != None: self.import_keys_from_data(Data(file=import_file)) import_file.close() def export_selected_keys(self, armor): "Helper function to export selected keys into a Data() object" context = Context() context.set_armor(armor) export_keys = Data() for row in self.get_selected_keys(): context.op_export(row[-1].key.subkeys[0].fpr, 0, export_keys) export_keys.seek(0,0) return export_keys def on_copy_activate(self, obj): "Callback for 'Copy' menu item" if self.keys_treeview.get_selection().count_selected_rows() > 0: export_keys = self.export_selected_keys(True) gtk.clipboard_get().set_text(export_keys.read()) def verify_output(self, filename, parent): "Helper function to verify that user can write into the filename" if os.path.exists(filename): if os.path.isdir(filename): self.error_message(_("%s is a directory")%filename, parent) return False else: return self.yesno_message(_("The file %s already exists.\n" + "Do you want to overwrite it?") % filename, parent) return True def on_export_keys_activate(self, obj): "Callback for 'Export Keys' menu item" if self.keys_treeview.get_selection().count_selected_rows() < 1: return export_file = None dialog = self.export_file_dialog dialog.set_transient_for(self.main_window) while export_file == None and dialog.run() == gtk.RESPONSE_OK: filename = dialog.get_filename() if self.verify_output(filename, dialog): try: export_file = file(filename, "wb") except IOError, strerror: self.error_message(strerror, dialog) export_file = None dialog.hide() if export_file == None: return export_keys = self.export_selected_keys(export_armor_cb.get_active()) export_file.write(export_keys.read()) export_file.close() def on_files_changed(self, obj): "Callback called when selection of files in filemanager is changed" if self.files_treeview.get_selection().count_selected_rows() < 1: value = False else: value = True for item in (self.sign, self.verify, self.encrypt, self.decrypt): item.set_sensitive(value) def add_file(self, filename, complain=False): "Helper function to add a file into filemanager treeview" model = self.files_treeview.get_model() row_list = [] model.foreach(lambda m,p,i,l: l.append(m[p][0]), row_list) if filename in row_list: if complain: self.file_error_message(_("The file is already open.")) else: item = model.append([filename]) self.files_treeview.get_selection().select_iter(item) self.on_files_changed(None) def on_open_activate(self, obj): "Callback for 'Open' menu item" if self.file_popup(self.open_file_dialog) == gtk.RESPONSE_OK: self.add_file(self.open_file_dialog.get_filename(), True) self.open_file_dialog.unselect_all() def get_selected_files(self): "Helper function to return selected rows in filemanager treeview" return self.get_selected_keys(self.files_treeview) def on_clear_activate(self, obj): "Callback for 'Clear' menu item" for row in self.get_selected_files(): row.model.remove(row.iter) def process_file_start(self, in_name, out_name): "Helper function to start asynchronous processing of one file" if self.verify_output(out_name, self.filemanager_window): try: self.in_data = Data(file=in_name) self.out_data = Data() self.out_name = out_name self.file_func(self.in_data, self.out_data) except errors.GPGMEError, exc: self.file_error_message(exc) def process_file_done(self, status): "The function called when asynchronous processing of the file is done." try: errors.errorcheck(status) self.out_data.seek(0,0) out_file = file(self.out_name, "wb") out_file.write(self.out_data.read()) out_file.close() self.add_file(self.out_name) if self.file_list: self.process_file_start(*(self.file_list.pop(0))) return True except (errors.GPGMEError, IOError), exc: self.file_error_message(exc) # Let python to free the memory. self.out_data = None self.in_data = None self.out_name = None self.file_list = [] self.file_func = None return False def process_files_async(self, file_list, func, label): "Helper function to initialize async processing of the file list" self.file_list = file_list self.file_func = func self.progress_func = self.process_file_done self.process_file_start(*(self.file_list.pop(0))) self.popup_progress_dialog(label, self.filemanager_window) def on_sign_activate(self, obj): "Callback for 'Sign' menu item" files = self.get_selected_files() if not files: return if self.file_popup(self.sign_dialog) == gtk.RESPONSE_OK: context = Context() context.set_passphrase_cb(self.password_cb) context.set_armor(self.sign_armor_cb.get_active()) for rw in self.get_selected_keys(self.sign_with_keys_treeview): context.signers_add(rw[-1].key) for cb,md,ext in [(self.sign_normal, sig.mode.NORMAL, ".gpg"), (self.sign_clear, sig.mode.CLEAR, ".asc"), (self.sign_separate,sig.mode.DETACH,".sig")]: if cb.get_active(): sigmode = md sigext = ext break self.progress_context = context def sign(x,y):self.progress_context.op_sign_start(x,y,sigmode) self.process_files_async([(f[0], f[0]+sigext) for f in files], sign, _("Signing...")) def verify_file_start(self, in_name, out_name): "Helper function to start file signature verification process" try: self.in_name = in_name self.out_name = out_name self.signed = Data(file=self.in_name) if out_name: self.plain1 = Data(file=self.out_name) self.plain2 = None else: self.plain1 = None self.plain2 = Data() self.progress_context.op_verify_start(self.signed, self.plain1, self.plain2) except errors.GPGMEError, exc: self.file_error_message(exc) def verify_file_done(self, status): "The function called when asynchronous file signature verify is done." try: errors.errorcheck(status) result = self.progress_context.op_verify_result() model = gtk.ListStore(str, str, str) treeview = gtk.TreeView(model) treeview.set_rules_hint(True) for index, title in enumerate([_("Key ID"), _("Status"), _("User Name")]): treeview.append_column(gtk.TreeViewColumn( title, gtk.CellRendererText(), text=index)) for sign in result.signatures: key = self.progress_context.get_key(sign.fpr, 0) if key and key.uids: keyid = key.subkeys[0].keyid[-8:] userid = key.uids[0].uid else: keyid = sign.fpr[-8:] userid = _("[Unknown user ID]") model.append([keyid, sigsum2str(sign.summary), userid]) vbox = gtk.VBox() if self.out_name: vbox.add(gtk.Label(_("Verified data in file: %s") % self.out_name)) label = gtk.Label(_("Signatures:")) label.set_alignment(0, 1) vbox.add(label) vbox.add(treeview) self.verified.append((vbox, gtk.Label(self.in_name))) if self.file_list: self.verify_file_start(*(self.file_list.pop(0))) return True except errors.GPGMEError, exc: self.file_error_message(exc) # Let python to free the memory. self.signed = None self.plain1 = None self.plain2 = None self.in_name = None self.out_name = None self.file_list = [] self.progress_dialog.hide() if self.verified: notebook = gtk.Notebook() for page in self.verified: notebook.append_page(*page) self.verify_result.add(notebook) self.verify_result.show_all() self.file_popup(self.verify_dialog) self.verify_result.remove(notebook) self.verified = [] return False def on_verify_activate(self, obj): "Callback for 'Verify' menu item" files = self.get_selected_files() if not files: return self.file_list = [] for onefile in files: in_name = onefile[0] if in_name[-4:] == ".sig": out_name = in_name[:-4] elif in_name[-5:] == ".sign": out_name = in_name[:-5] else: out_name = None self.file_list.append((in_name, out_name)) self.verified = [] self.progress_context = Context() self.progress_func = self.verify_file_done self.verify_file_start(*(self.file_list.pop(0))) self.popup_progress_dialog(_("Verifying..."), self.filemanager_window) def on_encrypt_sign_toggled(self, cb): "Callback for change of the 'Sign' check box in 'Encrypt files' dialog" self.encrypt_with_keys_treeview.set_sensitive(cb.get_active()) def on_encrypt_activate(self, obj): "Callback for 'Encrypt' menu item" files = self.get_selected_files() if not files: return self.on_encrypt_sign_toggled(self.encrypt_sign_cb) if self.file_popup(self.encrypt_dialog) == gtk.RESPONSE_OK: context = Context() context.set_passphrase_cb(self.password_cb) if self.encrypt_armor_cb.get_active(): context.set_armor(True) ext = ".asc" else: context.set_armor(False) ext = ".gpg" keylist = [row[-1].key for row in self.get_selected_keys( self.encrypt_for_keys_treeview)] if self.encrypt_sign_cb.get_active(): for row in self.get_selected_keys( self.encrypt_with_keys_treeview): context.signers_add(row[-1].key) def encrypt(x,y): self.progress_context.op_encrypt_sign_start( keylist, 1, x, y) else: def encrypt(x,y): self.progress_context.op_encrypt_start( keylist, 1, x, y) self.progress_context = context self.process_files_async([(f[0], f[0]+sigext) for f in files], encrypt, _("Encrypting...")) def on_decrypt_activate(self, obj): "Callback for 'Decrypt' menu item" files = self.get_selected_files() if not files: return file_list = [] for onefile in self.get_selected_files(): in_name = onefile[0] if in_name[-4:] in [".asc", ".gpg", ".pgp"]: out_name = in_name[:-4] else: out_name = in_name + ".txt" file_list.append((in_name, out_name)) self.process_context = Context() self.process_files_async(file_list, self.process_context.op_decrypt_start, _("Decrypting...")) def on_select_all_files_activate(self, obj): "Callback for 'Select All' menu item in filemanager" self.files_treeview.get_selection().select_all() def on_keyring_editor_activate(self, obj): "Callback for 'Keyring Editor' menu item" self.main_window.show() def on_keyring_editor_close_activate(self, obj, event=None): "Callback for 'Close' menu item in Keyring Editor" if self.filemanager_window.get_property("visible"): self.main_window.hide() return True else: self.on_quit_activate(None) def on_filemanager_activate(self, obj): "Callback for 'Filemanager' menu item" self.on_files_changed(None) self.filemanager_window.show() def on_filemanager_close_activate(self, obj, event=None): "Callback for 'Close' menu item in Filemanager" if self.main_window.get_property("visible"): self.filemanager_window.hide() return True else: self.on_quit_activate(None) def on_about_activate(self, obj): "Callback for 'About' menu item" self.popup(self.about_dialog) def __repr__(self): return self.__class__.__name__ def __getattr__(self, name): "Dynamic retrieval of widgets from the glade XML" if name.startswith("on_"): self.__dict__[name] = lambda x: sys.stderr.write( _("Callback %s is not implimented yet\n") % name) elif name.startswith("_"): return None else: self.__dict__[name] = self.wtree.get_widget(name) return self.__dict__[name] def __init__(self, path): "PyGpa(path) - path is where pygpa.glade file can be found" gladefile = os.path.join(path, "pygpa.glade") self.wtree = gtk.glade.XML(gladefile, None, gtk.glade.textdomain()) self.wtree.signal_autoconnect(self) self.default_key = None self.load_keys() self.setup_columns() self.setup_default_views() self.in_progress = {} gtk.main() def on_quit_activate(self, obj): gtk.main_quit() PyGpa(os.path.dirname(sys.argv[0])) pyme-0.8.1/examples/pygpa.glade0000600000175000017500000062601610231021604015410 0ustar belyibelyi True PyGpa Keyring Editor GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False 450 500 True True True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False 0 True GTK_SHADOW_OUT GTK_POS_LEFT GTK_POS_TOP True True _File True True gtk-close True True gtk-quit True True _Edit True True gtk-copy True True gtk-paste True True True Select _All True True True Preferences... True True gtk-preferences 1 0.5 0.5 0 0 True _Keys True True New Key... True True gtk-new 1 0.5 0.5 0 0 True Delete Keys... True True gtk-delete 1 0.5 0.5 0 0 True True _Sign keys... True True Set _Owner Trust... True True _Edit Private Key... True True True _Import Keys... True True E_xport Keys... True True _Windows True True _Filemanager True True _Keyring Editor True True _Help True True _About True 0 False True True True 250 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True True True True True True True GTK_POS_TOP False False True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True GTK_SHADOW_IN False False True Details False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab True False 0 True False 0 True Show signatures on user name: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False True True 0 True True 0 False True True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True 0 True True False True True Signatures False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True False True True Subkeys False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 tab True True 0 True True 2 True False 10 True Selected Default Key: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 True True True False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 True True True False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 True True 0 False False Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-ok True GTK_RELIEF_NORMAL True -5 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 8 True 7 2 False 0 4 True True True True 0 True * False 1 2 2 3 fill fill True True True True 0 True * False 1 2 3 4 fill fill True True True True 0 True * False 1 2 4 5 fill fill True True True False 0 True * False 1 2 5 6 fill fill True True True False 0 True * False 1 2 6 7 fill fill True _Algorithm: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 0 1 fill fill True _Key size (bits): True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 1 2 fill fill True _User ID: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 new_userid_entry 0 1 2 3 fill fill True _Email: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 new_email_entry 0 1 3 4 fill fill True _Comment: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 new_comment_entry 0 1 4 5 fill fill True _Passphrase: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 new_passphrase_entry 0 1 5 6 fill fill True _Repeat passphrase: True False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 new_repeat_passphrase_entry 0 1 6 7 fill fill True DSA and ElGamal (default) DSA (sign only) RSA (sign only) 1 2 0 1 fill fill True 768 1024 2048 1 2 1 2 fill fill 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN 5 True 0.5 0.5 1 1 0 0 0 0 True False 5 True True _indefinitely valid True GTK_RELIEF_NORMAL True False False True 0 False False True False 0 True True expire _after True GTK_RELIEF_NORMAL True False False True new_expire_valid_rb 0 False False True True True True 0 True * True 4 0 False False True 0 False False 0 True True True True expire o_n: True GTK_RELIEF_NORMAL True False False True new_expire_valid_rb 0 False False True True GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES 0 True True True Expiration False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False 0 False False What it's all about GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END 10 True False 0 True <big><b>PyGpa</b></big> (symbiosis of PyMe, PyGtk &amp; Glade) False True GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 0 False False True It looks like GPA. It works like GPA. But it is not GPA. False True GTK_JUSTIFY_CENTER False False 0.5 0.5 0 0 0 False False True <i>GNU Public License</i> False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False True <small>(C) 2005 Igor Belyi</small> False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 True True 5 Change key ownertrust GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True False 0 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN True False 0 True True _Unknown True GTK_RELIEF_NORMAL True False False True 0 False False True You don't know how much to trust this user to verify other people's keys. False False GTK_JUSTIFY_LEFT True False 0 0.5 20 0 0 False False True True _Never True GTK_RELIEF_NORMAL True False False True ownertrust_Unknown 0 False False True You don't trust this user at all to verify the validity of other people's keys at all. False False GTK_JUSTIFY_LEFT True False 0 0.5 20 0 0 False False True True _Marginal True GTK_RELIEF_NORMAL True True False True ownertrust_Unknown 0 False False True You don't trust this user's ability to verify the validity of other people's keys enough to consider keys valid based on his/her sole word. However, provided this user's key is valid, you will consider a key signed by this user valid if it is also signed by at least other two marginally trusted users with valid keys False False GTK_JUSTIFY_LEFT True False 0 0.5 20 0 0 False False True True _Full True GTK_RELIEF_NORMAL True False False True ownertrust_Unknown 0 False False True You trust this user's ability to verify the validity of other people's keys so much, that you'll consider valid any key signed by him/her, provided this user's key is valid. False False GTK_JUSTIFY_LEFT True False 0 0.5 20 0 0 False False True True U_ltimate True GTK_RELIEF_NORMAL True False False True ownertrust_Unknown 0 False False True You consider this key valid, and trust the user so much that you will consider any key signed by him/her fully valid. (Warning: This is intended to be used for keys you own. Don't use it with other people's keys unless you really know what you are doing) False False GTK_JUSTIFY_LEFT True False 0 0.5 20 0 0 False False True Owner Trust False True GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 True True 0 True True Settings GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False 350 350 True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-close True GTK_RELIEF_NORMAL True -7 0 False True GTK_PACK_END 4 True False 0 True 0 0.5 GTK_SHADOW_ETCHED_IN 4 True 0.5 0.5 1 1 0 0 0 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True True Default _key: True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 True True True 0 0.5 GTK_SHADOW_ETCHED_IN 4 True 0.5 0.5 1 1 0 0 0 0 True ldap://pgp.surnet.nl:11370 ldap://keyserver.pgp.com hkp://keyserver.kjsl.com True Default key_server: True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False True True 0 0.5 GTK_SHADOW_ETCHED_IN 4 True 0.5 0.5 1 1 0 0 0 0 True True 0 True True _Yes True GTK_RELIEF_NORMAL True False False True 0 False True True True _No True GTK_RELIEF_NORMAL True False False True advanced_mode_rb 0 False True True Use _advanced mode: True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False 0 True True PyGpa GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT False True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END True False 0 True False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 True True True GTK_PROGRESS_LEFT_TO_RIGHT 0 0.10000000149 0 True True 0 True True Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-go-forward True GTK_RELIEF_NORMAL True 2 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True Please insert your full name. Your name will be part of the new key to make it easier for others to identify keys. False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False True False 0 True Your Name: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False True True True True 0 True * False 0 True True 0 False False 0 True True 0 True True Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-go-back True GTK_RELIEF_NORMAL True 1 True True True gtk-go-forward True GTK_RELIEF_NORMAL True 2 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True Please insert your email address. Your email address will be part of the new key to make it easier for others to identify keys. If you have several email addresses, you can add further email adresses later. False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False True False 0 True Your Email Address: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False True True True True 0 True * False 0 False False 0 False False 0 True True 0 True True Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-go-back True GTK_RELIEF_NORMAL True 1 True True True gtk-go-forward True GTK_RELIEF_NORMAL True 2 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True If you want you can supply a comment that further identifies the key to other users. The comment is especially useful if you generate several keys for the same email address. The comment is completely optional. Leave it empty if you don't have a use for it. False False GTK_JUSTIFY_LEFT True False 0.5 0.5 0 0 0 False False True False 0 True Comment: False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False True True True True 0 True * False 0 True True 0 True True 0 True True 0 True True Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-go-back True GTK_RELIEF_NORMAL True 1 True True True gtk-go-forward True GTK_RELIEF_NORMAL True 2 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True Please choose a passphrase for the new key. False False GTK_JUSTIFY_LEFT False False 0 0 0 0 0 True True True 2 2 False 0 0 True Passphrase: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 0 1 fill True Repeat Passphrase: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 1 2 fill True True True False 0 True * False 1 2 0 1 True True True False 0 True * False 1 2 1 2 0 False True 0 True True 0 True True Generate key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True False True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-go-back True GTK_RELIEF_NORMAL True 1 True True True gtk-apply True GTK_RELIEF_NORMAL True -10 True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 0 False True GTK_PACK_END 8 True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True It is recommended that you create a backup copy of your new key, once it has been generated. Do you want to create a backup copy? False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False 8 True False 8 True True Create _backup copy True GTK_RELIEF_NORMAL True False False True 0 False False True True Do it later True GTK_RELIEF_NORMAL True False False True generate_novice_backup_rb 0 False False 0 True True 0 True True 0 True True Warning GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END 8 True False 8 True gtk-dialog-error 6 0.5 0.5 0 0 0 True True True False False GTK_JUSTIFY_LEFT True False 0.5 0.5 0 0 0 True True 0 True True Warning GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-no True GTK_RELIEF_NORMAL True -9 True True True gtk-yes True GTK_RELIEF_NORMAL True -8 0 False True GTK_PACK_END 8 True False 8 True gtk-dialog-warning 6 0.5 0.5 0 0 0 True True True False False GTK_JUSTIFY_LEFT True False 0.5 0.5 0 0 0 True True 0 True True Remove Key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-no True GTK_RELIEF_NORMAL True -9 True True True gtk-yes True GTK_RELIEF_NORMAL True -8 0 False True GTK_PACK_END 8 True False 8 True You have selected the following key for removal: False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 False False True False 0 0 True True True False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False True Are you sure you want to delete this key? False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 True True GTK_FILE_CHOOSER_ACTION_SAVE True False False Export public keys to file GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False 24 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True True gtk-open True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True True _armor True GTK_RELIEF_NORMAL True True False True 0 False False GTK_FILE_CHOOSER_ACTION_OPEN True False False Import public keys from file GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False 24 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True True gtk-open True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END Sign Key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-no True GTK_RELIEF_NORMAL True -9 True True True gtk-yes True GTK_RELIEF_NORMAL True -8 0 False True GTK_PACK_END 8 True False 8 True Do you want to sign the following key? False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 False False True False 0 0 True True True Check the name and fingerprint carefully to be sure that it really is the key you want to sign. False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False True All user names in this key will be signed. False False GTK_JUSTIFY_LEFT True False 0 0.5 0 0 0 False False True The key will be signed with your default private key. False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 False False True True Sign only _locally True GTK_RELIEF_NORMAL True False False True 0 False False 0 True True Enter Passphrase GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True gtk-dialog-question 6 0.5 0.5 0 0 0 True True 8 True False 8 True False False GTK_JUSTIFY_LEFT False False 0 0.5 0 0 0 False False True False 0 0 True True True True True False 0 True * False 0 False False 0 True True 0 True True Choose new passphrase GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END 8 True 2 2 False 0 0 True Passphrase: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 0 1 fill True Repeat Passphrase: False False GTK_JUSTIFY_LEFT False False 1 0.5 0 0 0 1 1 2 fill True True True False 0 True * False 1 2 0 1 True True True False 0 True * False 1 2 1 2 0 True True Edit Key GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-close True GTK_RELIEF_NORMAL True -7 0 False True GTK_PACK_END 8 True False 8 True False 0 0 True True True True Change _passphrase True GTK_RELIEF_NORMAL True 0 False False True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 12 0 5 True False 5 True False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 True True True True Change _expiration True GTK_RELIEF_NORMAL True 0 False False True Expiry Date False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False True 0 True True Change expiry date GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END 8 True False 0 True True _never expire True GTK_RELIEF_NORMAL True True False True 0 False False True True _expire on: True GTK_RELIEF_NORMAL True False False True change_expiry_never_rb 0 False False True True GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES 0 True True 0 True True Information GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-close True GTK_RELIEF_NORMAL True -7 0 False True GTK_PACK_END 8 True False 8 True gtk-dialog-info 6 0.5 0.5 0 0 0 True True True False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 0 False False 0 True True PyGPA - File Manager GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False 450 500 True True True False False GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False 0 True GTK_SHADOW_OUT GTK_POS_LEFT GTK_POS_TOP True True _File True True gtk-open True True gtk-clear True True True _Sign True True _Verify True True _Encrypt True True _Decrypt True True True gtk-close True True gtk-quit True True _Edit True True Select _All True True True Pr_eferences... True True gtk-preferences 1 0.5 0.5 0 0 True _Windows True True _Filemanager True True _Keyring Editor True True _Help True True _About True 0 False False True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True False False True 0 True True GTK_FILE_CHOOSER_ACTION_OPEN True False False Open File GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True False 24 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True True gtk-open True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END Sign files GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END 8 True False 8 True 0 0.5 GTK_SHADOW_ETCHED_IN True 0.5 0.5 1 1 0 0 0 0 5 True False 0 True True si_gn and compress True GTK_RELIEF_NORMAL True False False True 0 False False True True sign, do_n't compress True GTK_RELIEF_NORMAL True False False True sign_normal 0 False False True True sign in separate _file True GTK_RELIEF_NORMAL True False False True sign_normal 0 False False True Signing Mode False False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 False False True True A_rmor True GTK_RELIEF_NORMAL True False False True 0 False False True 0 0.5 GTK_SHADOW_NONE True 0.5 0.5 1 1 0 0 0 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True True Sign _as True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 True True 0 True True Encrypt files GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-cancel True GTK_RELIEF_NORMAL True -6 True True True gtk-ok True GTK_RELIEF_NORMAL True -5 0 False True GTK_PACK_END True False 0 True 0 0.5 GTK_SHADOW_NONE True 0.5 0.5 1 1 0 0 0 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True True _Public Keys True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 True True True True _Sign True GTK_RELIEF_NORMAL True False False True 0 False False True 0 0.5 GTK_SHADOW_NONE True 0.5 0.5 1 1 0 0 0 0 True True GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_SHADOW_IN GTK_CORNER_TOP_LEFT True True True True False True True Sign _as True False GTK_JUSTIFY_LEFT False False 0.5 0.5 0 0 label_item 0 True True True True A_rmor True GTK_RELIEF_NORMAL True False False True 0 False False 0 True True Verify files GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER_ON_PARENT True True True True False False GDK_WINDOW_TYPE_HINT_DIALOG GDK_GRAVITY_NORTH_WEST True True False 0 True GTK_BUTTONBOX_END True True True gtk-close True GTK_RELIEF_NORMAL True -7 0 False True GTK_PACK_END 5 True False 0 0 True True pyme-0.8.1/examples/delkey.py0000700000175000017500000000274010770264550015133 0ustar belyibelyi#!/usr/bin/env python # $Id: delkey.py,v 1.3 2008/03/19 19:28:40 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Sample of key deletion # It deletes keys for joe@foo.bar generated by genkey.pl script from pyme import core core.check_version(None) # Note that we need to collect all keys out of the iterator return by c.op_keylist_all() # method before starting to delete them. If you delete a key in the middle of iteration # c.op_keylist_next() will raise INV_VALUE exception c = core.Context() # 0 in keylist means to list not only public but secret keys as well. for thekey in [x for x in c.op_keylist_all("joe@foo.bar", 0)]: # 1 in delete means to delete not only public but secret keys as well. c.op_delete(thekey, 1) pyme-0.8.1/examples/signverify.py0000700000175000017500000000473610770264550016052 0ustar belyibelyi#!/usr/bin/env python # $Id: signverify.py,v 1.6 2008/03/19 19:28:40 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Sample of unattended signing/verifying of a message. # It uses keys for joe@foo.bar generated by genkey.pl script import sys from pyme import core, callbacks from pyme.constants.sig import mode core.check_version(None) plain = core.Data("Test message") sig = core.Data() c = core.Context() user = "joe@foo.bar" c.signers_clear() # Add joe@foo.bar's keys in the list of signers for sigkey in c.op_keylist_all(user, 1): if sigkey.can_sign: c.signers_add(sigkey) if not c.signers_enum(0): print "No secret %s's keys suitable for signing!" % user sys.exit(0) # This is a map between signer e-mail and its password passlist = { "": "abcdabcdfs" } # callback will return password based on the e-mail listed in the hint. c.set_passphrase_cb(lambda x,y,z: passlist[x[x.rindex("<"):]]) c.op_sign(plain, sig, mode.CLEAR) # Print out the signature (don't forget to rewind since signing put sig at EOF) sig.seek(0,0) signedtext = sig.read() print signedtext # Create Data with signed text. sig2 = core.Data(signedtext) plain2 = core.Data() # Verify. c.op_verify(sig2, None, plain2) result = c.op_verify_result() # List results for all signatures. Status equal 0 means "Ok". index = 0 for sign in result.signatures: index += 1 print "signature", index, ":" print " summary: ", sign.summary print " status: ", sign.status print " timestamp: ", sign.timestamp print " fingerprint:", sign.fpr print " uid: ", c.get_key(sign.fpr, 0).uids[0].uid # Print "unsigned" text. Rewind since verify put plain2 at EOF. plain2.seek(0,0) print "\n", plain2.read() pyme-0.8.1/examples/PyGtkGpgKeys.py0000700000175000017500000006611210770264550016211 0ustar belyibelyi#!/usr/bin/python # $Id: PyGtkGpgKeys.py,v 1.8 2008/03/19 19:28:40 belyi Exp $ # Copyright (C) 2005,2008 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import gtk, gobject, gtk.glade import time, sys, os from pyme import callbacks, core, errors from pyme.core import Data, Context, pubkey_algo_name from pyme import constants from pyme.constants import validity from pyme.constants.keylist import mode # Thanks to Bernhard Reiter for pointing out the following: # gpgme_check_version() necessary for initialisation according to # gpgme 1.1.6 and this is not done automatically in pyme-0.7.0 print "gpgme version:", core.check_version(None) # Convert trust constant into a string trusts = {validity.UNKNOWN: "", validity.UNDEFINED: "Undefined", validity.NEVER: "Never", validity.MARGINAL: "Marginal", validity.FULL: "Full", validity.ULTIMATE: "Ultimate"} # Convert seconds into a date def sec2str(secs): if secs > 0: return time.strftime("%Y-%m-%d", time.gmtime(secs)) elif secs == 0: return "Unlimited" else: return "" index = 0 class KeyColumn: "Helper class for data columns." def __init__(self, name, gtype, vattr=None, tcols=None, func=lambda x:x, view=None): """new(name, qtype, vattr, column, ocolumn, func): name - column title qtype - gobject type to use in TreeStore for this column vattr - column data is visible if method vattr present in the object tcols - list of type specific columns to append its name to. func - function converting object data into viewable presentation view - to put or not the column in the view menu""" global index self.name = name self.type = gtype self.vattr = vattr self.func = func self.view = view self.index = index self.attrs = {} if tcols != None: tcols.append(name) index += 1 # List column names specific to an object type key_columns = [] # names only in key uid_columns = [] # names only in uids sub_columns = [] # names only in subkeys sign_columns = [] # names only in signatures sub_sign_columns = [] # names in subkeys and signatures # Explicite columns visible_columns = [ KeyColumn("Secret", gobject.TYPE_BOOLEAN, "subkeys"), KeyColumn("Name", gobject.TYPE_STRING, "name", uid_columns, lambda x: x.name+(x.comment and " (%s)"%x.comment)), KeyColumn("Email", gobject.TYPE_STRING, "email", uid_columns, lambda x: x.email), KeyColumn("Owner Trust", gobject.TYPE_STRING, "owner_trust", key_columns, lambda x: trusts[x.owner_trust], True), KeyColumn("Type", gobject.TYPE_STRING, "pubkey_algo", sub_sign_columns, lambda x: pubkey_algo_name(x.pubkey_algo)), KeyColumn("Length", gobject.TYPE_INT, "length", sub_columns, lambda x: x.length), KeyColumn("Can Auth", gobject.TYPE_BOOLEAN,"can_authenticate", sub_columns, lambda x: x.can_authenticate, False), KeyColumn("Can Cert", gobject.TYPE_BOOLEAN, "can_certify", sub_columns, lambda x: x.can_certify, False), KeyColumn("Can Encr", gobject.TYPE_BOOLEAN, "can_encrypt", sub_columns, lambda x: x.can_encrypt, False), KeyColumn("Can Sign", gobject.TYPE_BOOLEAN, "can_sign", sub_columns, lambda x: x.can_sign, False), KeyColumn("Created", gobject.TYPE_STRING, "timestamp", sub_sign_columns, lambda x: sec2str(x.timestamp), True), KeyColumn("Expires", gobject.TYPE_STRING, "expires", sub_sign_columns, lambda x: sec2str(x.expires), True), KeyColumn("Id", gobject.TYPE_STRING, "keyid", sub_sign_columns, lambda x: x.keyid) ] helper_columns = [ KeyColumn("Name Invalid", gobject.TYPE_BOOLEAN, None, uid_columns, lambda x: x.revoked or x.invalid), KeyColumn("Subkey Invalid", gobject.TYPE_BOOLEAN, None, sub_sign_columns, lambda x: x.revoked or x.invalid or x.expired), KeyColumn("FPR", gobject.TYPE_STRING, None, sub_columns, lambda x: x.fpr) ] # Calculate implicite columns - defining visibility of the data in a column. # In the same loop calculate tuple for rows having only name in them. name_only = () for item in visible_columns: vis_item = KeyColumn("Show"+item.name, gobject.TYPE_BOOLEAN) helper_columns.append(vis_item) item.attrs["visible"] = vis_item.index name_only += (vis_item.index, item.name == "Name") columns = {} for item in visible_columns + helper_columns: columns[item.name] = item # Use strikethrough to indicate revoked or invalid keys and uids columns["Name"].attrs["strikethrough"] = columns["Name Invalid"].index columns["Id"].attrs["strikethrough"] = columns["Subkey Invalid"].index def pair(name, value): "pair(name, value) creates (index, func(value)) tuple based on column name" item = columns[name] if item.index < len(visible_columns): return (item.index, item.func(value), columns["Show"+name].index, True) else: return (item.index, item.func(value)) class PyGtkGpgKeys: "Main class representing PyGtkGpgKeys application" def error_message(self, text, parent=None): dialog = gtk.MessageDialog(parent or self.mainwin, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, text) dialog.run() dialog.destroy() def yesno_message(self, text, parent=None): dialog = gtk.MessageDialog(parent or self.mainwin, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, text) result = dialog.run() == gtk.RESPONSE_YES dialog.destroy() return result def load_keys(self, first_time=False): if not first_time: self.model.clear() secret_keys = {} for key in self.context.op_keylist_all(None, 1): secret_keys[key.subkeys[0].fpr] = 1 for key in self.context.op_keylist_all(None, 0): self.add_key(key, secret_keys.has_key(key.subkeys[0].fpr)) def add_key(self, key, secret): "self.add_key(key) - add key to the TreeStore model" iter = self.model.append(None) # Can delete only the whole key param = (iter,) + pair("Secret", secret) # Key information is a combination of the key and first uid and subkey for col in key_columns: param += pair(col, key) for col in uid_columns: param += pair(col, key.uids[0]) for col in sub_columns: param += pair(col, key.subkeys[0]) for col in sub_sign_columns: param += pair(col, key.subkeys[0]) self.model.set(*param) if key.uids: self.add_signatures(key.uids[0].signatures, iter) self.add_uids(key.uids[1:], iter) self.add_subkeys(key.subkeys[1:], iter) def add_subkeys(self, subkeys, iter): "self.add_subkeys(subkey, iter) - add subkey as child to key's iter" if not subkeys: return key_iter = self.model.append(iter) self.model.set(key_iter, columns["Name"].index, "Subkeys", *name_only) for subkey in subkeys: child_iter = self.model.append(key_iter) param = (child_iter,) for col in sub_columns: param += pair(col, subkey) for col in sub_sign_columns: param += pair(col, subkey) self.model.set(*param) def add_uids(self, uids, iter): "self.add_uids(uid, iter) - add uid as a child to key's iter" if not uids: return uid_iter = self.model.append(iter) self.model.set(uid_iter,columns["Name"].index,"Other UIDs",*name_only) for uid in uids: child_iter = self.model.append(uid_iter) param = (child_iter,) for col in uid_columns: param += pair(col, uid) self.model.set(*param) self.add_signatures(uid.signatures, child_iter) def add_signatures(self, signs, iter): "self.add_signatures(sign, iter) - add signature as a child to iter" if not signs: return sign_iter = self.model.append(iter) self.model.set(sign_iter,columns["Name"].index,"Signatures",*name_only) for sign in signs: child_iter = self.model.append(sign_iter) param = (child_iter,) for col in uid_columns: param += pair(col, sign) for col in sign_columns: param += pair(col, sign) for col in sub_sign_columns: param += pair(col, sign) self.model.set(*param) def add_columns(self): "Add viewable columns for the data in TreeStore model" view_menu = gtk.Menu() for item in visible_columns: if item.type == gobject.TYPE_BOOLEAN: renderer = gtk.CellRendererToggle() item.attrs["active"] = item.index else: renderer = gtk.CellRendererText() item.attrs["text"] = item.index column = self.treeview.insert_column_with_attributes( item.index, item.name, renderer, **item.attrs) column.set_sort_column_id(item.index) # Create callback for a View menu item if item.view != None: check = gtk.CheckMenuItem(item.name) check.set_active(item.view) check.connect("activate", lambda x, y: y.set_visible(x.get_active()), column) view_menu.append(check) column.set_visible(check.get_active()) view_menu.show_all() self.wtree.get_widget("view_menu").set_submenu(view_menu) def on_GPGKeysView_button_press_event(self, obj, event): if event.button != 3: return False menu = gtk.Menu() for title, callback in [ ("Reload", self.on_reload_activate), (None, None), ("Delete", self.on_delete_activate), ("Export (txt)", self.on_export_keys_text_activate), ("Export (bin)", self.on_export_keys_activate) ]: if title: item = gtk.MenuItem(title) item.connect("activate", callback) else: item = gtk.SeparatorMenuItem() menu.append(item) menu.show_all() menu.popup(None, None, None, event.button, event.time) return True def editor_func(self, status, args, val_dict): state = val_dict["state"] prompt = "%s %s" % (state, args) if val_dict.has_key(prompt): val_dict["state"] = val_dict[prompt][0] return val_dict[prompt][1] elif args: sys.stderr.write("Unexpected prompt in editor_func: %s\n" % prompt) raise EOFError() return "" def change_key_trust(self, key, new_trust): val_dict = { "state": "start", "start keyedit.prompt": ("trust", "trust"), "trust edit_ownertrust.value": ("prompt", "%d" % new_trust), "prompt edit_ownertrust.set_ultimate.okay": ("prompt", "Y"), "prompt keyedit.prompt": ("finish", "quit") } out = Data() self.context.op_edit(key, self.editor_func, val_dict, out) def on_change_trust(self, new_trust): selection = self.treeview.get_selection() if selection.count_selected_rows() <= 0: return key_list = [] selection.selected_foreach(self.collect_keys, key_list) message = "Change trust to %s on the following keys?\n" % \ trusts[new_trust] for key, row in key_list: message += "\n%s\t" % key.subkeys[0].keyid if key.uids: message += key.uids[0].uid else: message += "" if self.yesno_message(message): for key, row in key_list: if key.owner_trust != new_trust: self.change_key_trust(key, new_trust) row[columns["Owner Trust"].index] = trusts[new_trust] def on_undefined_trust_activate(self, obj): self.on_change_trust(1) def on_never_trust_activate(self, obj): self.on_change_trust(2) def on_marginal_trust_activate(self, obj): self.on_change_trust(3) def on_full_trust_activate(self, obj): self.on_change_trust(4) def on_ultimate_trust_activate(self, obj): self.on_change_trust(5) def collect_keys(self, model, path, iter, key_list): row = model[path[:1]] keyid = row[columns["FPR"].index] key = self.context.get_key(keyid, 0) key_list.append((key, row)) def export_keys(self): selection = self.treeview.get_selection() if selection.count_selected_rows() <= 0: return export_file = None dialog = gtk.FileChooserDialog("Export Keys (Public only) into a File", self.mainwin, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) while dialog.run() == gtk.RESPONSE_OK: filename = dialog.get_filename() if os.path.exists(filename): if os.path.isdir(filename): self.error_message("%s is a directory!" % filename, dialog) continue elif not self.yesno_message("%s exists. Override?" % filename, dialog): continue # FIXME. Verify that file can be written to export_file = file(filename, "wb") break dialog.destroy() if export_file == None: return key_list = [] selection.selected_foreach(self.collect_keys, key_list) expkeys = Data() for key, row in key_list: self.context.op_export(key.subkeys[0].fpr, 0, expkeys) expkeys.seek(0,0) export_file.write(expkeys.read()) export_file.close() def on_export_keys_activate(self, obj): self.context.set_armor(0) self.export_keys() def on_export_keys_text_activate(self, obj): self.context.set_armor(1) self.export_keys() def on_import_keys_activate(self, obj): import_file = None dialog = gtk.FileChooserDialog("Import Keys from a File", self.mainwin, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) while dialog.run() == gtk.RESPONSE_OK: filename = dialog.get_filename() if os.path.exists(filename): if os.path.isdir(filename): self.error_message("%s is a directory!" % filename, dialog) else: # FIXME. Verify that file can be open. import_file = filename break else: self.error_message("%s does not exist." % filename, dialog) dialog.destroy() if import_file == None: return impkeys = Data(file=import_file) status = self.context.op_import(impkeys) if status: self.error_message("Import return an error message %d" % status) result = self.context.op_import_result() if result.considered == 0: self.error_message("There's no keys in the file.") # FIXME. Instead of rereading everything we could find out what's new # from the result based on the ORed value of impkey: # constants.import.NEW - The key was new. # constants.import.UID - The key contained new user IDs. # constants.import.SIG - The key contained new signatures. # constants.import.SUBKEY - The key contained new sub keys. # constants.import.SECRET - The key contained a secret key. # It would be nice to highlight new things as well. self.load_keys() #if result: # impkey = result.imports # while impkey: # if impkey.status & constants.import.NEW: # self.add_key(self.context.get_key(impkey.fpr, 0)) # impkey = impkey.next def on_delete_activate(self, obj): "self.on_delete_activate(obj) - callback for key deletion request" selection = self.treeview.get_selection() if selection.count_selected_rows() > 0: key_list = [] selection.selected_foreach(self.collect_keys, key_list) message = "Delete selected keys?\n" for key, row in key_list: message += "\n%s\t" % key.subkeys[0].keyid if key.uids: message += key.uids[0].uid else: message += "" if self.yesno_message(message): for key, row in key_list: self.context.op_delete(key, 1) row.model.remove(row.iter) def get_widget_values(self, widgets): "Create an array of values from widgets' getter methods" return [getattr(self.wtree.get_widget(w),"get_"+f)() for w,f in widgets] def set_widget_values(self, widgets, values): "Set values using widgets' setter methods" for (w,f), v in zip(widgets, values): # ComboBox.set_active_iter(None) does not reset active. Fixing. if f == "active_iter" and v == None: f, v = "active", -1 getattr(self.wtree.get_widget(w), "set_"+f)(v) def key_type_changed(self, which): """self.key_type_changed([\"key\"|\"subkey\"]) - helper function to adjust allowed key length based on the Algorithm selected""" (key_type,) = self.get_widget_values([(which+"_type", "active_iter")]) if key_type: key_type = self.wtree.get_widget(which+"_type").get_model( ).get_value(key_type,0) length_widget = self.wtree.get_widget(which+"_length") if key_type == "DSA": length_widget.set_range(1024, 1024) length_widget.set_value(1024) elif key_type == "RSA" or key_type == "ELG-E": length_widget.set_range(1024, 4096) def on_key_type_changed(self, obj): self.key_type_changed("key") def on_subkey_type_changed(self, obj): self.key_type_changed("subkey") def on_expire_calendar_day_selected(self, obj): "Callback for selecting a day on the calendar" (year, month, day)=self.wtree.get_widget("expire_calendar").get_date() expander = self.wtree.get_widget("expire_date") # Past dates means no expiration date if time.localtime() < (year, month+1, day): expander.set_label("%04d-%02d-%02d" % (year, month+1, day)) else: expander.set_label("Unlimited") expander.set_expanded(False) def on_generate_activate(self, obj): "Callback to generate new key" # Set of (widget, common suffix of getter/setter function) tuples # from the GenerateDialog prompt for new key properties. widgets = [ ("key_type", "active_iter"), ("key_length", "value"), ("key_encrypt", "active"), ("key_sign", "active"), ("subkey_type", "active_iter"), ("subkey_length", "value"), ("subkey_encrypt", "active"), ("subkey_sign", "active"), ("name_real", "text"), ("name_comment", "text"), ("name_email", "text"), ("expire_date", "label"), ("passphrase", "text"), ("passphrase_repeat", "text") ] saved_values = self.get_widget_values(widgets) result = None dialog = self.wtree.get_widget("GenerateDialog") if dialog.run() == gtk.RESPONSE_OK: (key_type, key_length, key_encrypt, key_sign, subkey_type, subkey_length, subkey_encrypt, subkey_sign, name_real, name_comment, name_email, expire_date, passphrase, passphrase2) = self.get_widget_values(widgets) if key_type and passphrase == passphrase2: key_type = self.wtree.get_widget("key_type").get_model( ).get_value(key_type,0) result = "\n" result += "Key-Type: %s\n" % key_type result += "Key-Length: %d\n" % int(key_length) if key_encrypt or key_sign: result += "Key-Usage:" + \ ((key_encrypt and " encrypt") or "") + \ ((key_sign and " sign") or "") + "\n" if subkey_type: subkey_type=self.wtree.get_widget("subkey_type").get_model( ).get_value(subkey_type,0) result += "Subkey-Type: %s\n" % subkey_type result += "Subkey-Length: %d\n" % int(subkey_length) if subkey_encrypt or subkey_sign: result += "Subkey-Usage:" + \ ((subkey_encrypt and " encrypt") or "") + \ ((subkey_sign and " sign") or "") + "\n" if name_real: result += "Name-Real: %s\n" % name_real if name_comment: result += "Name-Comment: %s\n" % name_comment if name_email: result += "Name-Email: %s\n" % name_email if passphrase: result += "Passphrase: %s\n" % passphrase if expire_date != "Unlimited": result += "Expire-Date: %s\n" % expire_date else: result += "Expire-Date: 0\n" result += "\n" else: if not key_type: message = "Type of the primary key is not specified." elif passphrase != passphrase2: message = "Passphrases do not match." else: message = "Unknown error." self.error_message(message, dialog) else: self.set_widget_values(widgets, saved_values) dialog.hide() if result: # Setup and show progress Dialog self.progress = "" self.progress_entry = self.wtree.get_widget( "progress_entry").get_buffer() self.progress_entry.set_text("") gobject.timeout_add(500, self.update_progress) self.wtree.get_widget("GenerateProgress").show_all() # Start asynchronous key generation self.context.op_genkey_start(result, None, None) def gen_progress(self, what=None, type=None, current=None, total=None, hook=None): "Gpg's progress_cb" if self.progress != None: self.progress += "%c" % type else: sys.stderr.write("%c" % type) def update_progress(self): "Timeout callback to yeild to gpg and update progress Dialog view" status = self.context.wait(False) if status == None: self.progress_entry.set_text(self.progress) return True elif status == 0: fpr = self.context.op_genkey_result().fpr self.add_key(self.context.get_key(fpr, 0), True) self.wtree.get_widget("GenerateProgress").hide() self.progress = None if status: self.error_message("Got an error during key generation:\n%s" % errors.GPGMEError(status).getstring()) # Let callback to be removed. return False def on_generating_close_clicked(self, obj): # Request cancelation of the outstanding asynchronous call self.context.cancel() def get_password(self, hint, desc, hook): "Gpg's password_cb" dialog = self.wtree.get_widget("PasswordDialog") label = self.wtree.get_widget("pwd_prompt") entry = self.wtree.get_widget("password") label.set_text("Please supply %s's password%s:" % (hint, (hook and (' '+hook)) or '')) if dialog.run() == gtk.RESPONSE_OK: result = entry.get_text() else: result = "" entry.set_text("") dialog.hide() return result def on_reload_activate(self, obj): self.load_keys() def on_about_activate(self, obj): about = self.wtree.get_widget("AboutDialog") about.run() about.hide() def __init__(self, path): "new(path) path - location of the glade file" gladefile = os.path.join(path, "PyGtkGpgKeys.glade") self.wtree = gtk.glade.XML(gladefile) self.wtree.signal_autoconnect(self) self.mainwin = self.wtree.get_widget("GPGAdminWindow") self.treeview = self.wtree.get_widget("GPGKeysView") self.model = gtk.TreeStore(*[x.type for x in visible_columns + helper_columns]) self.context = Context() self.context.set_passphrase_cb(self.get_password, "") self.progress = None self.context.set_progress_cb(self.gen_progress, None) # Use mode.SIGS to include signatures in the list. self.context.set_keylist_mode(mode.SIGS) self.load_keys(True) self.treeview.set_model(self.model) self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.add_columns() gtk.main() def on_Exit(self, obj): gtk.main_quit() try: # Glade file is expected to be in the same location as this script PyGtkGpgKeys(os.path.dirname(sys.argv[0])) except IOError, message: print "%s:%s" %(sys.argv[0], message) pyme-0.8.1/examples/verifydetails.py0000700000175000017500000000622611112156243016521 0ustar belyibelyi#!/usr/bin/env python # initial 20080123 build from the example: # very simple - probably INCOMPLETE # 20080703 Bernhard # added second usage for detached signatures. # added output of signature.summary (another bitfield) # printing signature bitfield in hex format # # $Id: verifydetails.py,v 1.2 2008/11/23 04:31:31 belyi Exp $ # # Copyright (C) 2004,2008 Igor Belyi # Copyright (c) 2008 Bernhard Reiter # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys from pyme import core, callbacks, constants from pyme.constants.sig import mode from pyme.constants import protocol def print_engine_infos(): print "gpgme version:", core.check_version(None) print "engines:" for engine in core.get_engine_info(): print engine.file_name, engine.version for proto in [protocol.OpenPGP, protocol.CMS]: print core.get_protocol_name(proto), core.engine_check_version(proto) def verifyprintdetails(sigfilename, filefilename=None): """Verify a signature, print a lot of details.""" c = core.Context() # Create Data with signed text. sig2 = core.Data(file=sigfilename) if filefilename: file2 = core.Data(file=filefilename) plain2 = None else: file2 = None plain2 = core.Data() # Verify. c.op_verify(sig2, file2, plain2) result = c.op_verify_result() # List results for all signatures. Status equal 0 means "Ok". index = 0 for sign in result.signatures: index += 1 print "signature", index, ":" print " summary: %#0x" % (sign.summary) print " status: %#0x" % (sign.status) print " timestamp: ", sign.timestamp print " fingerprint:", sign.fpr print " uid: ", c.get_key(sign.fpr, 0).uids[0].uid # Print "unsigned" text if inline signature if plain2: #Rewind since verify put plain2 at EOF. plain2.seek(0,0) print "\n", plain2.read() def main(): print_engine_infos() print argc= len(sys.argv) if argc < 2 or argc > 3: print "need a filename for inline signature" print "or two filename for detached signature and file to check" sys.exit(1) if argc == 2: print "trying to verify file: " + sys.argv[1] verifyprintdetails(sys.argv[1]) if argc == 3: print "trying to verify signature %s for file %s" \ % (sys.argv[1], sys.argv[2]) verifyprintdetails(sys.argv[1], sys.argv[2]) if __name__ == "__main__": main() pyme-0.8.1/examples/exportimport.py0000700000175000017500000000475610770264550016443 0ustar belyibelyi#!/usr/bin/env python # $Id: exportimport.py,v 1.3 2008/03/19 19:28:40 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Sample of export and import of keys # It uses keys for joe@foo.bar generated by genkey.pl script import sys from pyme import core core.check_version(None) expkey = core.Data() c = core.Context() c.set_armor(1) user = "joe@foo.bar" print " - Export %s's public keys - " % user c.op_export(user, 0, expkey) # print out exported data to see how it looks in armor. expkey.seek(0,0) expstring = expkey.read() if expstring: print expstring else: print "No %s's keys to export!" % user sys.exit(0) # delete keys to ensure that they came from our imported data. # Note that since joe's key has private part as well we can only delete # both of them. As a side effect joe won't have private key for this # exported public one. If it's Ok with you uncomment the next 4 lines. #print " - Delete %s's public keys - " % user #for thekey in [x for x in c.op_keylist_all(user, 0)]: # if not thekey.secret: # c.op_delete(thekey, 1) # initialize import data from a string as if it was read from a file. newkey = core.Data(expstring) print " - Import exported keys - " c.op_import(newkey) result = c.op_import_result() # show the import result if result: print " - Result of the import - " for k in dir(result): if not k in result.__dict__ and not k.startswith("_"): if k == "imports": print k, ":" for impkey in result.__getattr__(k): print " fpr=%s result=%d status=%x" % \ (impkey.fpr, impkey.result, impkey.status) else: print k, ":", result.__getattr__(k) else: print " - No import result - " pyme-0.8.1/examples/genkey.py0000700000175000017500000000270010764554424015141 0ustar belyibelyi#!/usr/bin/env python # $Id: genkey.py,v 1.6 2008/03/08 18:21:08 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import core, callbacks # Initialize our context. core.check_version(None) c = core.Context() c.set_armor(1) c.set_progress_cb(callbacks.progress_stdout, None) # This example from the GPGME manual parms = """ Key-Type: DSA Key-Length: 1024 Subkey-Type: ELG-E Subkey-Length: 1024 Name-Real: Joe Tester Name-Comment: with stupid passphrase Name-Email: joe@foo.bar Passphrase: abcdabcdfs Expire-Date: 2010-08-15 """ c.op_genkey(parms, None, None) print c.op_genkey_result().fpr pyme-0.8.1/examples/sign.py0000700000175000017500000000221610764554424014621 0ustar belyibelyi#!/usr/bin/env python # $Id: sign.py,v 1.3 2008/03/08 18:21:08 belyi Exp $ # Copyright (C) 2002 John Goerzen # # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import core, callbacks from pyme.constants.sig import mode core.check_version(None) plain = core.Data("Test message") sig = core.Data() c = core.Context() c.set_passphrase_cb(callbacks.passphrase_stdin, 'for signing') c.op_sign(plain, sig, mode.CLEAR) sig.seek(0,0) print sig.read() pyme-0.8.1/examples/t-edit.py0000600000175000017500000000365010771334464015047 0ustar belyibelyi#!/usr/bin/python # $Id: t-edit.py,v 1.4 2008/03/08 18:21:08 belyi Exp $ # Copyright (C) 2005 Igor Belyi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os from pyme import core from pyme.core import Data, Context core.check_version(None) class KeyEditor: def __init__(self): self.steps = ["fpr", "expire", "1", "primary", "quit"] self.step = 0 def edit_fnc(self, status, args, out): print "[-- Response --]" out.seek(0,0) print out.read(), print "[-- Code: %d, %s --]" % (status, args) if args == "keyedit.prompt": result = self.steps[self.step] self.step += 1 elif args == "keyedit.save.okay": result = "Y" elif args == "keygen.valid": result = "0" else: result = None return result if not os.getenv("GNUPGHOME"): print "Please, set GNUPGHOME env.var. pointing to GPGME's tests/gpg dir" else: c = Context() c.set_passphrase_cb(lambda x,y,z: "abc") out = Data() c.op_keylist_start("Alpha", 0) key = c.op_keylist_next() c.op_edit(key, KeyEditor().edit_fnc, out, out) print "[-- Last response --]" out.seek(0,0) print out.read(), pyme-0.8.1/examples/encrypt-to-all.py0000700000175000017500000000402210770264550016523 0ustar belyibelyi#!/usr/bin/env python # $Id: encrypt-to-all.py,v 1.5 2008/03/19 19:28:40 belyi Exp $ # Copyright (C) 2008 Igor Belyi # Copyright (C) 2002 John Goerzen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ This program will try to encrypt a simple message to each key on your keyring. If your keyring has any invalid keys on it, those keys will be removed and it will re-try the encryption.""" from pyme import core from pyme.core import Data, Context from pyme.constants import validity core.check_version(None) plain = Data('This is my message.') c = Context() c.set_armor(1) def sendto(keylist): cipher = Data() c.op_encrypt(keylist, 1, plain, cipher) cipher.seek(0,0) return cipher.read() names = [] for key in c.op_keylist_all(None, 0): print " *** Found key for %s" % key.uids[0].uid valid = 0 for subkey in key.subkeys: keyid = subkey.keyid if keyid == None: break can_encrypt = subkey.can_encrypt valid += can_encrypt print " Subkey %s: encryption %s" % \ (keyid, can_encrypt and "enabled" or "disabled") if valid: names.append(key) else: print " This key cannot be used for encryption; skipping." passno = 0 print "Encrypting to %d recipients" % len(names) print sendto(names) pyme-0.8.1/pyme/0000700000175000017500000000000011113133434012416 5ustar belyibelyipyme-0.8.1/pyme/errors.py0000600000175000017500000000333610417276466014336 0ustar belyibelyi# $Id: errors.py,v 1.8 2006/04/12 22:20:38 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import pygpgme class GPGMEError(Exception): def __init__(self, error = None, message = None): self.error = error self.message = message def getstring(self): message = "%s: %s" % (pygpgme.gpgme_strsource(self.error), pygpgme.gpgme_strerror(self.error)) if self.message != None: message = "%s: %s" % (self.message, message) return message def getcode(self): return pygpgme.gpgme_err_code(self.error) def getsource(self): return pygpgme.gpgme_err_source(self.error) def __str__(self): return "%s (%d,%d)"%(self.getstring(),self.getsource(),self.getcode()) EOF = getattr(pygpgme, "EOF") def errorcheck(retval, extradata = None): if retval: raise GPGMEError(retval, extradata) pyme-0.8.1/pyme/core.py0000600000175000017500000004161210774621751013746 0ustar belyibelyi# $Id: core.py,v 1.16 2008/04/02 06:12:57 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import generators for portability with python2.2 from __future__ import generators import pygpgme from errors import errorcheck import errors from util import GpgmeWrapper class Context(GpgmeWrapper): """From the GPGME C documentation: * All cryptographic operations in GPGME are performed within a * context, which contains the internal state of the operation as well as * configuration parameters. By using several contexts you can run * several cryptographic operations in parallel, with different * configuration. Thus, this is the place that you will usually start.""" def _getctype(self): return 'gpgme_ctx_t' def _getnameprepend(self): return 'gpgme_' def _errorcheck(self, name): """This function should list all functions returning gpgme_error_t""" if (name.startswith('gpgme_op_') and \ not name.endswith('_result')) or \ name == 'gpgme_signers_add' or \ name == 'gpgme_set_locale' or \ name == 'gpgme_set_keylist_mode' or \ name == 'gpgme_set_protocol': return 1 return 0 def __init__(self, wrapped=None): if wrapped: self.wrapped = wrapped self.own = False else: tmp = pygpgme.new_gpgme_ctx_t_p() errorcheck(pygpgme.gpgme_new(tmp)) self.wrapped = pygpgme.gpgme_ctx_t_p_value(tmp) pygpgme.delete_gpgme_ctx_t_p(tmp) self.own = True self.last_passcb = None self.last_progresscb = None def __del__(self): self._free_passcb() self._free_progresscb() if self.own: pygpgme.gpgme_release(self.wrapped) def _free_passcb(self): if self.last_passcb != None: pygpgme.pygpgme_clear_generic_cb(self.last_passcb) pygpgme.delete_PyObject_p_p(self.last_passcb) self.last_passcb = None def _free_progresscb(self): if self.last_progresscb != None: pygpgme.pygpgme_clear_generic_cb(self.last_progresscb) pygpgme.delete_PyObject_p_p(self.last_progresscb) self.last_progresscb = None def op_keylist_all(self, *args, **kwargs): apply(self.op_keylist_start, args, kwargs) key = self.op_keylist_next() while key: yield key key = self.op_keylist_next() def op_keylist_next(self): """Returns the next key in the list created by a call to op_keylist_start(). The object returned is of type Key.""" ptr = pygpgme.new_gpgme_key_t_p() try: errorcheck(pygpgme.gpgme_op_keylist_next(self.wrapped, ptr)) key = pygpgme.gpgme_key_t_p_value(ptr) except errors.GPGMEError, excp: key = None if excp.getcode() != errors.EOF: raise excp pygpgme.delete_gpgme_key_t_p(ptr) if key: key.__del__ = lambda self: pygpgme.gpgme_key_unref(self) return key def get_key(self, fpr, secret): """Return the key corresponding to the fingerprint 'fpr'""" ptr = pygpgme.new_gpgme_key_t_p() errorcheck(pygpgme.gpgme_get_key(self.wrapped, fpr, ptr, secret)) key = pygpgme.gpgme_key_t_p_value(ptr) pygpgme.delete_gpgme_key_t_p(ptr) if key: key.__del__ = lambda self: pygpgme.gpgme_key_unref(self) return key def op_trustlist_all(self, *args, **kwargs): apply(self.op_trustlist_start, args, kwargs) trust = self.ctx.op_trustlist_next() while trust: yield trust trust = self.ctx.op_trustlist_next() def op_trustlist_next(self): """Returns the next trust item in the list created by a call to op_trustlist_start(). The object returned is of type TrustItem.""" ptr = pygpgme.new_gpgme_trust_item_t_p() try: errorcheck(pygpgme.gpgme_op_trustlist_next(self.wrapped, ptr)) trust = pygpgme.gpgme_trust_item_t_p_value(ptr) except errors.GPGMEError, excp: trust = None if excp.getcode() != errors.EOF: raise pygpgme.delete_gpgme_trust_item_t_p(ptr) return trust def set_passphrase_cb(self, func, hook=None): """Sets the passphrase callback to the function specified by func. When the system needs a passphrase, it will call func with three args: hint, a string describing the key it needs the passphrase for; desc, a string describing the passphrase it needs; prev_bad, a boolean equal True if this is a call made after unsuccessful previous attempt. If hook has a value other than None it will be passed into the func as a forth argument. Please see the GPGME manual for more information. """ self._free_passcb() if func == None: hookdata = None else: self.last_passcb = pygpgme.new_PyObject_p_p() if hook == None: hookdata = func else: hookdata = (func, hook) pygpgme.pygpgme_set_passphrase_cb(self.wrapped, hookdata, self.last_passcb) def set_progress_cb(self, func, hook=None): """Sets the progress meter callback to the function specified by This function will be called to provide an interactive update of the system's progress. Please see the GPGME manual for more information.""" self._free_progresscb() if func == None: hookdata = None else: self.last_progresscb = pygpgme.new_PyObject_p_p() if hook == None: hookdata = func else: hookdata = (func, hook) pygpgme.pygpgme_set_progress_cb(self.wrapped, hookdata, self.last_progresscb) def get_engine_info(self): """Returns this context specific engine info""" return pygpgme.gpgme_ctx_get_engine_info(self.wrapped) def set_engine_info(self, proto, file_name, home_dir=None): """Changes the configuration of the crypto engine implementing the protocol 'proto' for the context. 'file_name' is the file name of the executable program implementing this protocol. 'home_dir' is the directory name of the configuration directory (engine's default is used if omitted).""" errorcheck(pygpgme.gpgme_ctx_set_engine_info(self.wrapped, proto, file_name, home_dir)) def wait(self, hang): """Wait for asynchronous call to finish. Wait forever if hang is True Return: On an async call completion its return status. On timeout - None. Please read the GPGME manual for more information.""" ptr = pygpgme.new_gpgme_error_t_p() context = pygpgme.gpgme_wait(self.wrapped, ptr, hang) status = pygpgme.gpgme_error_t_p_value(ptr) pygpgme.delete_gpgme_error_t_p(ptr) if context == None: errorcheck(status) return None else: return status def op_edit(self, key, func, fnc_value, out): """Start key editing using supplied callback function""" if key == None: raise ValueError("op_edit: First argument cannot be None") opaquedata = (func, fnc_value) errorcheck(pygpgme.gpgme_op_edit(self.wrapped, key, opaquedata, out)) class Data(GpgmeWrapper): """From the GPGME C manual: * A lot of data has to be exchanged between the user and the crypto * engine, like plaintext messages, ciphertext, signatures and information * about the keys. The technical details about exchanging the data * information are completely abstracted by GPGME. The user provides and * receives the data via `gpgme_data_t' objects, regardless of the * communication protocol between GPGME and the crypto engine in use. This Data class is the implementation of the GpgmeData objects. Please see the information about __init__ for instantiation.""" def _getctype(self): return 'gpgme_data_t' def _getnameprepend(self): return 'gpgme_data_' def _errorcheck(self, name): """This function should list all functions returning gpgme_error_t""" if name == 'gpgme_data_release_and_get_mem' or \ name == 'gpgme_data_get_encoding' or \ name == 'gpgme_data_seek': return 0 return 1 def __init__(self, string = None, file = None, offset = None, length = None, cbs = None): """Initialize a new gpgme_data_t object. If no args are specified, make it an empty object. If string alone is specified, initialize it with the data contained there. If file, offset, and length are all specified, file must be either a filename or a file-like object, and the object will be initialized by reading the specified chunk from the file. If cbs is specified, it MUST be a tuple of the form: ((read_cb, write_cb, seek_cb, release_cb), hook) where func is a callback function taking two arguments (count, hook) and returning a string of read data, or None on EOF. This will supply the read() method for the system. If file is specified without any other arguments, then it must be a filename, and the object will be initialized from that file. Any other use will result in undefined or erroneous behavior.""" self.wrapped = None self.last_readcb = None if cbs != None: apply(self.new_from_cbs, cbs) elif string != None: self.new_from_mem(string) elif file != None and offset != None and length != None: self.new_from_filepart(file, offset, length) elif file != None: if type(file) == type("x"): self.new_from_file(file) else: self.new_from_fd(file) else: self.new() def __del__(self): if self.wrapped != None: pygpgme.gpgme_data_release(self.wrapped) self._free_readcb() def _free_readcb(self): if self.last_readcb != None: pygpgme.pygpgme_clear_generic_cb(self.last_readcb) pygpgme.delete_PyObject_p_p(self.last_readcb) self.last_readcb = None def new(self): tmp = pygpgme.new_gpgme_data_t_p() errorcheck(pygpgme.gpgme_data_new(tmp)) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_mem(self, string, copy = 1): tmp = pygpgme.new_gpgme_data_t_p() errorcheck(pygpgme.gpgme_data_new_from_mem(tmp,string,len(string),copy)) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_file(self, filename, copy = 1): tmp = pygpgme.new_gpgme_data_t_p() errorcheck(pygpgme.gpgme_data_new_from_file(tmp, filename, copy)) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_cbs(self, funcs, hook): """Argument funcs must be a 4 element tuple with callbacks: (read_cb, write_cb, seek_cb, release_cb)""" tmp = pygpgme.new_gpgme_data_t_p() self._free_readcb() self.last_readcb = pygpgme.new_PyObject_p_p() hookdata = (funcs, hook) pygpgme.pygpgme_data_new_from_cbs(tmp, hookdata, self.last_readcb) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_filepart(self, file, offset, length): """This wraps the GPGME gpgme_data_new_from_filepart() function. The argument "file" may be: 1. a string specifying a file name, or 3. a a file-like object. supporting the fileno() call and the mode attribute.""" tmp = pygpgme.new_gpgme_data_t_p() filename = None fp = None if type(file) == type("x"): filename = file else: fp = pygpgme.fdopen(file.fileno(), file.mode) if fp == None: raise ValueError, "Failed to open file from %s arg %s" % \ (str(type(file)), str(file)) errorcheck(pygpgme.gpgme_data_new_from_filepart(tmp, filename, fp, offset, length)) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_fd(self, file): """This wraps the GPGME gpgme_data_new_from_fd() function. The argument "file" may be a file-like object, supporting the fileno() call and the mode attribute.""" tmp = pygpgme.new_gpgme_data_t_p() fp = pygpgme.fdopen(file.fileno(), file.mode) if fp == None: raise ValueError, "Failed to open file from %s arg %s" % \ (str(type(file)), str(file)) errorcheck(gpgme_data_new_from_fd(tmp, fp)) self.wrapped = pygpgme.gpgme_data_t_p_value(tmp) pygpgme.delete_gpgme_data_t_p(tmp) def new_from_stream(self, file): """This wrap around gpgme_data_new_from_stream is an alias for new_from_fd() method since in python there's not difference between file stream and file descriptor""" self.new_from_fd(file) def write(self, buffer): errorcheck(pygpgme.gpgme_data_write(self.wrapped, buffer, len(buffer))) def read(self, size = -1): """Read at most size bytes, returned as a string. If the size argument is negative or omitted, read until EOF is reached. Returns the data read, or the empty string if there was no data to read before EOF was reached.""" if size == 0: return '' if size > 0: return pygpgme.gpgme_data_read(self.wrapped, size) else: retval = '' while 1: result = pygpgme.gpgme_data_read(self.wrapped, 10240) if len(result) == 0: break retval += result return retval def pubkey_algo_name(algo): return pygpgme.gpgme_pubkey_algo_name(algo) def hash_algo_name(algo): return pygpgme.gpgme_hash_algo_name(algo) def get_protocol_name(proto): return pygpgme.gpgme_get_protocol_name(proto) def check_version(version=None): return pygpgme.gpgme_check_version(version) def engine_check_version (proto): try: errorcheck(pygpgme.gpgme_engine_check_version(proto)) return True except errors.GPGMEError: return False def get_engine_info(): ptr = pygpgme.new_gpgme_engine_info_t_p() try: errorcheck(pygpgme.gpgme_get_engine_info(ptr)) info = pygpgme.gpgme_engine_info_t_p_value(ptr) except errors.GPGMEError: info = None pygpgme.delete_gpgme_engine_info_t_p(ptr) return info def set_engine_info(proto, file_name, home_dir=None): """Changes the default configuration of the crypto engine implementing the protocol 'proto'. 'file_name' is the file name of the executable program implementing this protocol. 'home_dir' is the directory name of the configuration directory (engine's default is used if omitted).""" errorcheck(pygpgme.gpgme_set_engine_info(proto, file_name, home_dir)) def set_locale(category, value): """Sets the default locale used by contexts""" errorcheck(pygpgme.gpgme_set_locale(None, category, value)) def wait(hang): """Wait for asynchronous call on any Context to finish. Wait forever if hang is True. For finished anynch calls it returns a tuple (status, context): status - status return by asnynchronous call. context - context which caused this call to return. Please read the GPGME manual of more information.""" ptr = pygpgme.new_gpgme_error_t_p() context = pygpgme.gpgme_wait(None, ptr, hang) status = pygpgme.gpgme_error_t_p_value(ptr) pygpgme.delete_gpgme_error_t_p(ptr) if context == None: errorcheck(status) else: context = Context(context) return (status, context) pyme-0.8.1/pyme/util.py0000600000175000017500000000526510773543643014001 0ustar belyibelyi# $Id: util.py,v 1.9 2008/03/29 22:50:11 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import pygpgme from errors import errorcheck def process_constants(starttext, dict): """Called by the constant libraries to load up the appropriate constants from the C library.""" index = len(starttext) for identifier in dir(pygpgme): if not identifier.startswith(starttext): continue name = identifier[index:] dict[name] = getattr(pygpgme, identifier) class GpgmeWrapper(object): """Base class all Pyme wrappers for GPGME functionality. Not to be instantiated directly.""" def __repr__(self): return '' % \ (__name__, self.__class__.__name__, self.wrapped) def __str__(self): return repr(self) def __hash__(self): return hash(repr(self.wrapped)) def __eq__(self, other): if other == None: return False else: return repr(self.wrapped) == repr(other.wrapped) def _getctype(self): raise NotImplementedException def __getattr__(self, name): """On-the-fly function generation.""" if name[0] == '_' or self._getnameprepend() == None: return None name = self._getnameprepend() + name if self._errorcheck(name): def _funcwrap(*args, **kwargs): args = [self.wrapped] + list(args) return errorcheck(apply(getattr(pygpgme, name), args, kwargs), "Invocation of " + name) else: def _funcwrap(*args, **kwargs): args = [self.wrapped] + list(args) return apply(getattr(pygpgme, name), args, kwargs) _funcwrap.__doc__ = getattr(getattr(pygpgme, name), "__doc__") return _funcwrap pyme-0.8.1/pyme/__init__.py0000600000175000017500000001060210350665475014551 0ustar belyibelyi# $Id: __init__.py,v 1.9 2005/12/17 01:34:53 belyi Exp $ """ Pyme: GPGME Interface for Python Copyright (C) 2004 Igor Belyi Copyright (C) 2002 John Goerzen 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Welcome to PyME, the GPGME Interface for Python. "Pyme", when prounced, rhymes with "Pine". The latest release of this package may be obtained from http://pyme.sourceforge.net Previous releases of this package can be obtained from http://quux.org/devel/pyme/ FEATURES -------- * Feature-rich, full implementation of the GPGME library. Supports all GPGME features except interactive editing (coming soon). Callback functions may be written in pure Python. * Ability to sign, encrypt, decrypt, and verify data. * Ability to list keys, export and import keys, and manage the keyring. * Fully object-oriented with convenient classes and modules. GENERAL OVERVIEW ---------------- For those of you familiar with GPGME, you will be right at home here. Pyme is, for the most part, a direct interface to the C GPGME library. However, it is re-packaged in a more Pythonic way -- object-oriented with classes and modules. Take a look at the classes defined here -- they correspond directly to certain object types in GPGME for C. For instance, the following C code: gpgme_ctx_t context; gpgme_new(&context); ... gpgme_op_encrypt(context, recp, 1, plain, cipher); Translates into the following Python code: context = core.Context() ... context.op_encrypt(recp, 1, plain, cipher) The Python module automatically does error-checking and raises Python exception pyme.errors.GPGMEError when GPGME signals an error. getcode() and getsource() of this exception return code and source of the error. IMPORTANT NOTE -------------- This documentation only covers a small subset of available GPGME functions and methods. Please consult the documentation for the C library for comprehensive coverage. This library uses Python's reflection to automatically detect the methods that are available for each class, and as such, most of those methods do not appear explicitly anywhere. You can use dir() python built-in command on an object to see what methods and fields it has but their meaning can be found only in GPGME documentation. QUICK START SAMPLE PROGRAM -------------------------- This program is not for serious encryption, but for example purposes only! import sys from pyme import core, constants # Set up our input and output buffers. plain = core.Data('This is my message.') cipher = core.Data() # Initialize our context. c = core.Context() c.set_armor(1) # Set up the recipients. sys.stdout.write("Enter name of your recipient: ") name = sys.stdin.readline().strip() c.op_keylist_start(name, 0) r = c.op_keylist_next() # Do the encryption. c.op_encrypt([r], 1, plain, cipher) cipher.seek(0,0) print cipher.read() Note that although there is no explicit error checking done here, the Python GPGME library is automatically doing error-checking, and will raise an exception if there is any problem. This program is in the Pyme distribution as examples/simple.py. The examples directory contains more advanced samples as well. FOR MORE INFORMATION -------------------- PYME homepage: http://pyme.sourceforge.net GPGME documentation: http://pyme.sourceforge.net/doc/gpgme/index.html GPGME homepage: http://www.gnupg.org/gpgme.html Base classes: pyme.core (START HERE!) Error classes: pyme.errors Constants: pyme.constants Version information: pyme.version Utilities: pyme.util Base classes are documented at pyme.core. Classes of pyme.util usually are not instantiated by users directly but return by methods of base classes. """ __all__ = ['core', 'errors', 'constants', 'util', 'callbacks', 'version'] pyme-0.8.1/pyme/callbacks.py0000600000175000017500000000353210417276466014737 0ustar belyibelyi# $Id: callbacks.py,v 1.6 2006/04/12 22:20:38 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from getpass import getpass def passphrase_stdin(hint, desc, prev_bad, hook=None): """This is a sample callback that will read a passphrase from the terminal. The hook here, if present, will be used to describe why the passphrase is needed.""" why = '' if hook != None: why = ' ' + hook if prev_bad: why += ' (again)' print "Please supply %s' password%s:" % (hint, why) return getpass() def progress_stdout(what, type, current, total, hook=None): print "PROGRESS UPDATE: what = %s, type = %d, current = %d, total = %d" %\ (what, type, current, total) def readcb_fh(count, hook): """A callback for data. hook should be a Python file-like object.""" if count: # Should return '' on EOF return hook.read(count) else: # Wants to rewind. if not hasattr(hook, 'seek'): return None hook.seek(0, 0) return None pyme-0.8.1/pyme/constants/0000700000175000017500000000000010773534763014457 5ustar belyibelyipyme-0.8.1/pyme/constants/keylist/0000700000175000017500000000000010231621650016120 5ustar belyibelyipyme-0.8.1/pyme/constants/keylist/mode.py0000600000175000017500000000176210231621650017426 0ustar belyibelyi# $Id: mode.py,v 1.4 2005/04/21 03:53:12 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_KEYLIST_MODE_', globals()) pyme-0.8.1/pyme/constants/keylist/__init__.py0000600000175000017500000000013110231616534020233 0ustar belyibelyi# $Id: __init__.py,v 1.2 2004/03/21 02:25:54 belyi Exp $ import mode __all__ = ['mode'] pyme-0.8.1/pyme/constants/import.py0000600000175000017500000000175610231621647016341 0ustar belyibelyi# $Id: import.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_IMPORT_', globals()) pyme-0.8.1/pyme/constants/md.py0000600000175000017500000000174610231621647015426 0ustar belyibelyi# $Id: md.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_MD_', globals()) pyme-0.8.1/pyme/constants/sigsum.py0000600000175000017500000000175610231621647016336 0ustar belyibelyi# $Id: sigsum.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_SIGSUM_', globals()) pyme-0.8.1/pyme/constants/status.py0000600000175000017500000000175610231621647016352 0ustar belyibelyi# $Id: status.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_STATUS_', globals()) pyme-0.8.1/pyme/constants/sig/0000700000175000017500000000000010231621650015216 5ustar belyibelyipyme-0.8.1/pyme/constants/sig/mode.py0000600000175000017500000000175610231621650016527 0ustar belyibelyi# $Id: mode.py,v 1.4 2005/04/21 03:53:12 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_SIG_MODE_', globals()) pyme-0.8.1/pyme/constants/sig/__init__.py0000600000175000017500000000013110231616534017331 0ustar belyibelyi# $Id: __init__.py,v 1.2 2004/03/21 02:25:55 belyi Exp $ import mode __all__ = ['mode'] pyme-0.8.1/pyme/constants/__init__.py0000600000175000017500000000037010350665475016566 0ustar belyibelyi# $Id: __init__.py,v 1.3 2005/12/17 01:34:53 belyi Exp $ from pyme import util util.process_constants('GPGME_', globals()) __all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk', 'protocol', 'sig', 'sigsum', 'status', 'validity'] pyme-0.8.1/pyme/constants/pk.py0000600000175000017500000000174610231621647015440 0ustar belyibelyi# $Id: pk.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_PK_', globals()) pyme-0.8.1/pyme/constants/data/0000700000175000017500000000000010231621650015345 5ustar belyibelyipyme-0.8.1/pyme/constants/data/__init__.py0000600000175000017500000000014110231616534017461 0ustar belyibelyi# $Id: __init__.py,v 1.2 2004/03/21 02:25:54 belyi Exp $ import encoding __all__ = ['encoding'] pyme-0.8.1/pyme/constants/data/encoding.py0000600000175000017500000000176710231621650017522 0ustar belyibelyi# $Id: encoding.py,v 1.4 2005/04/21 03:53:12 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_DATA_ENCODING_', globals()) pyme-0.8.1/pyme/constants/event.py0000600000175000017500000000175410231621647016146 0ustar belyibelyi# $Id: event.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_EVENT_', globals()) pyme-0.8.1/pyme/constants/protocol.py0000600000175000017500000000176210231621647016665 0ustar belyibelyi# $Id: protocol.py,v 1.4 2005/04/21 03:53:11 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_PROTOCOL_', globals()) pyme-0.8.1/pyme/constants/validity.py0000600000175000017500000000176210231621650016643 0ustar belyibelyi# $Id: validity.py,v 1.4 2005/04/21 03:53:12 belyi Exp $ # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from pyme import util util.process_constants('GPGME_VALIDITY_', globals()) pyme-0.8.1/pyme/version.py0000600000175000017500000000326311112620076014465 0ustar belyibelyi# $Id: version.py,v 1.10 2008/11/24 21:44:30 belyi Exp $ productname = 'pyme' versionstr = "0.8.1" revno = long('$Rev: 281 $'[6:-2]) revstr = "Rev %d" % revno datestr = '$Date: 2008/11/24 21:44:30 $' versionlist = versionstr.split(".") major = versionlist[0] minor = versionlist[1] patch = versionlist[2] copyright = "Copyright (C) 2004,2008 Igor Belyi, 2002 John Goerzen" author = "Igor Belyi" author_email = "belyi@users.sourceforge.net" description = "Python support for GPGME GnuPG cryptography library" bigcopyright = """%(productname)s %(versionstr)s (%(revstr)s) %(copyright)s <%(author_email)s>""" % locals() banner = bigcopyright + """ This software comes with ABSOLUTELY NO WARRANTY; see the file COPYING for details. This is free software, and you are welcome to distribute it under the conditions laid out in COPYING.""" homepage = "http://pyme.sourceforge.net" license = """Copyright (C) 2004,2008 Igor Belyi Copyright (C) 2002 John Goerzen 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA""" pyme-0.8.1/gpgme-h-clean.py0000700000175000017500000000311510773543643014447 0ustar belyibelyi#!/usr/bin/env python # $Id: gpgme-h-clean.py,v 1.4 2008/03/29 22:50:11 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import sys, re if len(sys.argv) < 2: sys.stderr.write("Usage: %s gpgme.h\n" % sys.argv[0]) sys.exit(1) deprec_func=re.compile('^(.*typedef.*|.*\(.*\))\s*_GPGME_DEPRECATED;\s*',re.S) line_break=re.compile(';|\\$|\\x0c|^\s*#'); try: gpgme = file(sys.argv[1]) tmp = gpgme.readline() text = '' while tmp: text += re.sub(' class ', ' _py_obsolete_class ', tmp) if line_break.search(tmp): if not deprec_func.search(text): sys.stdout.write(text) text = '' tmp = gpgme.readline() sys.stdout.write(text) gpgme.close() except IOError, errmsg: sys.stderr.write("%s: %s\n" % (sys.argv[0], errmsg)) sys.exit(1) pyme-0.8.1/INSTALL0000600000175000017500000000117110252200627012501 0ustar belyibelyiTo build pyme module without installing it run 'make'. To install pyme module run 'make install'. The module will be installed in the site-packages subdirectory of the python library directory. To delete all files generated during build run 'make reallyclean' To build documentation run 'make docs'. HTML files will be generated in 'doc' subdirectory. To build distribution files including Debian packages run 'make dist' To build distribution archive without Debian packages and without debian subdirectory run 'make nondeb-dist' Note, Debian packages and distribution archive will be generated in the parent directory. pyme-0.8.1/COPYING.LESSER0000600000175000017500000006364010231621205013504 0ustar belyibelyi GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! pyme-0.8.1/gpgme.i0000600000175000017500000001742110771334750012741 0ustar belyibelyi/* # $Id: gpgme.i,v 1.13 2008/03/23 02:01:12 belyi Exp $ # Copyright (C) 2004,2008 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %module pygpgme %include "cpointer.i" %include "cstring.i" // Generate doc strings for all methods. %feature("autodoc", "0"); // Allow use of None for strings. %typemap(in) const char * { if ($input == Py_None) $1 = NULL; else if (PyString_Check($input)) $1 = PyString_AsString($input); else { PyErr_Format(PyExc_TypeError, "arg %d: expected string or None, got %s", $argnum, $input->ob_type->tp_name); return NULL; } } %typemap(freearg) const char * ""; // Release returned buffers as necessary. %typemap(newfree) char * "free($1);"; %newobject gpgme_data_release_and_get_mem; %{ /* Convert object to a pointer to gpgme type */ PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) { PyObject *pyname = NULL, *pypointer = NULL; pyname = PyObject_CallMethod(input, "_getctype", NULL); if (pyname == NULL) { PyErr_Format(PyExc_TypeError, "arg %d: Expected an instance of type %s, but got %s", argnum, objtype, input == Py_None ? "None" : input->ob_type->tp_name); return NULL; } if (strcmp(PyString_AsString(pyname), objtype) != 0) { PyErr_Format(PyExc_TypeError, "arg %d: Expected value of type %s, but got %s", argnum, objtype, PyString_AsString(pyname)); Py_DECREF(pyname); return NULL; } Py_DECREF(pyname); pypointer = PyObject_GetAttrString(input, "wrapped"); if (pypointer == NULL) { PyErr_Format(PyExc_TypeError, "arg %d: Use of uninitialized Python object %s", argnum, objtype); return NULL; } return pypointer; } %} %typemap(arginit) gpgme_key_t recp[] { $1 = NULL; } %typemap(in) gpgme_key_t recp[] { int i, numb = 0; if (!PySequence_Check($input)) { PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t", $argnum); return NULL; } if((numb = PySequence_Length($input)) != 0) { $1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t)); for(i=0; inext) { size++; } $result = PyList_New(size); for (i=0,curr=$1; inext) { PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags); PyList_SetItem($result, i, o); } } // Include mapper for edit callbacks %typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) { $1 = (gpgme_edit_cb_t) pyEditCb; if ($input == Py_None) $2 = NULL; else $2 = $input; } // Include the header file both for cc (first) and for swig (second) // Include for swig locally since we need to fix 'class' usage there. %{ #include %} %include "gpgme.h" %constant long EOF = GPG_ERR_EOF; // Generating and handling pointers-to-pointers. %pointer_functions(gpgme_ctx_t, gpgme_ctx_t_p); %pointer_functions(gpgme_data_t, gpgme_data_t_p); %pointer_functions(gpgme_key_t, gpgme_key_t_p); %pointer_functions(gpgme_error_t, gpgme_error_t_p); %pointer_functions(gpgme_trust_item_t, gpgme_trust_item_t_p); %pointer_functions(gpgme_engine_info_t, gpgme_engine_info_t_p); %pointer_functions(PyObject *, PyObject_p_p); %pointer_functions(void *, void_p_p); // Helper functions. %{ #include %} FILE *fdopen(int fildes, const char *mode); %{ #include "helpers.h" %} %include "helpers.h" %{ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status, const char *args, int fd) { PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL; PyObject *pyopaque = (PyObject *) opaque; gpgme_error_t err_status = 0; pygpgme_exception_init(); if (PyTuple_Check(pyopaque)) { func = PyTuple_GetItem(pyopaque, 0); dataarg = PyTuple_GetItem(pyopaque, 1); pyargs = PyTuple_New(3); } else { func = pyopaque; pyargs = PyTuple_New(2); } PyTuple_SetItem(pyargs, 0, PyInt_FromLong((long) status)); PyTuple_SetItem(pyargs, 1, PyString_FromString(args)); if (dataarg) { Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */ PyTuple_SetItem(pyargs, 2, dataarg); } retval = PyObject_CallObject(func, pyargs); Py_DECREF(pyargs); if (PyErr_Occurred()) { err_status = pygpgme_exception2code(); } else { if (fd>=0 && retval) { write(fd, PyString_AsString(retval), PyString_Size(retval)); write(fd, "\n", 1); } } Py_XDECREF(retval); return err_status; } %} pyme-0.8.1/setup.py0000700000175000017500000000703111112620076013164 0ustar belyibelyi#!/usr/bin/env python # $Id: setup.py,v 1.8 2008/11/24 21:44:30 belyi Exp $ # Module: installer # COPYRIGHT # # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # END OF COPYRIGHT # from distutils.core import setup, Extension from distutils.command.build_ext import build_ext import os, os.path, sys sys.path.append("pyme") import version def getconfig(what): cmd = os.popen("sh gpgme-config --%s" % what, "r") confdata = cmd.read() confdata = confdata.replace("\n", " ") assert cmd.close() == None, "error getting GPG config" confdata = confdata.replace(" ", " ") return [x for x in confdata.split(' ') if x != ''] include_dirs = [os.getcwd()] define_macros = [] library_dirs = [] libs = getconfig('libs') for item in getconfig('cflags'): if item.startswith("-I"): include_dirs.append(item[2:]) elif item.startswith("-D"): defitem = item[2:].split("=", 1) if len(defitem)==2: define_macros.append((defitem[0], defitem[1])) else: define_macros.append((defitem[0], None)) # Adjust include and library locations in case of win32 uname_s = os.popen("uname -s").read() if uname_s.startswith("MINGW32"): mnts = [x.split()[0:3:2] for x in os.popen("mount").read().split("\n") if x] tmplist = [(len(x[1]), x[1], x[0]) for x in mnts] tmplist.sort() tmplist.reverse() extra_dirs = [] for item in include_dirs: for ln, mnt, tgt in tmplist: if item.startswith(mnt): item = os.path.normpath(item[ln:]) while item[0] == os.path.sep: item = item[1:] extra_dirs.append(os.path.join(tgt,item)) break include_dirs += extra_dirs for item in [x[2:] for x in libs if x.startswith("-L")]: for ln, mnt, tgt in tmplist: if item.startswith(mnt): item = os.path.normpath(item[ln:]) while item[0] == os.path.sep: item = item[1:] library_dirs.append(os.path.join(tgt,item)) break swige = Extension("pyme._pygpgme", ["gpgme_wrap.c", "helpers.c"], include_dirs = include_dirs, define_macros = define_macros, library_dirs = library_dirs, extra_link_args = libs) setup(name = "pygpgme", version = version.versionstr, description = version.description, author = version.author, author_email = version.author_email, url = version.homepage, ext_modules=[swige], packages = ['pyme', 'pyme.constants', 'pyme.constants.data', 'pyme.constants.keylist', 'pyme.constants.sig'], license = version.copyright + \ ", Licensed under the GPL version 2" ) pyme-0.8.1/COPYING0000600000175000017500000004311010026724710012505 0ustar belyibelyi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pyme-0.8.1/ChangeLog0000600000175000017500000007312710026724712013241 0ustar belyibelyi------------------------------------------------------------------------ rev 59: jgoerzen | 2002-11-21 08:40:10 -0600 (Thu, 21 Nov 2002) | 2 lines Changed paths: M /pyme/head/debian/rules Fixed a couple of bugs that did not get checked in before. ------------------------------------------------------------------------ rev 58: jgoerzen | 2002-11-21 08:37:39 -0600 (Thu, 21 Nov 2002) | 2 lines Changed paths: M /pyme/head/debian/rules Fixed a bug here ------------------------------------------------------------------------ rev 57: jgoerzen | 2002-11-21 08:33:31 -0600 (Thu, 21 Nov 2002) | 2 lines Changed paths: M /pyme/head/ChangeLog M /pyme/head/debian/changelog M /pyme/head/doc/gpgme/gpgme.html M /pyme/head/doc/gpgme/gpgme_1.html M /pyme/head/doc/gpgme/gpgme_10.html M /pyme/head/doc/gpgme/gpgme_11.html M /pyme/head/doc/gpgme/gpgme_12.html M /pyme/head/doc/gpgme/gpgme_2.html M /pyme/head/doc/gpgme/gpgme_3.html M /pyme/head/doc/gpgme/gpgme_4.html M /pyme/head/doc/gpgme/gpgme_5.html M /pyme/head/doc/gpgme/gpgme_6.html M /pyme/head/doc/gpgme/gpgme_7.html M /pyme/head/doc/gpgme/gpgme_8.html M /pyme/head/doc/gpgme/gpgme_9.html M /pyme/head/doc/gpgme/gpgme_abt.html M /pyme/head/doc/gpgme/gpgme_fot.html M /pyme/head/doc/gpgme/gpgme_ovr.html M /pyme/head/doc/gpgme/gpgme_toc.html M /pyme/head/doc/pyme.aux.html M /pyme/head/doc/pyme.callbacks.html M /pyme/head/doc/pyme.constants.attr.html M /pyme/head/doc/pyme.constants.data.dtype.html M /pyme/head/doc/pyme.constants.data.encoding.html M /pyme/head/doc/pyme.constants.data.html M /pyme/head/doc/pyme.constants.html M /pyme/head/doc/pyme.constants.keylist.html M /pyme/head/doc/pyme.constants.keylist.mode.html M /pyme/head/doc/pyme.constants.protocol.html M /pyme/head/doc/pyme.constants.sig.html M /pyme/head/doc/pyme.constants.sig.mode.html M /pyme/head/doc/pyme.constants.sig.stat.html M /pyme/head/doc/pyme.constants.sigsum.html M /pyme/head/doc/pyme.constants.status.html M /pyme/head/doc/pyme.constants.validity.html M /pyme/head/doc/pyme.core.html M /pyme/head/doc/pyme.errors.html M /pyme/head/doc/pyme.gpgme.html M /pyme/head/doc/pyme.html M /pyme/head/doc/pyme.util.html M /pyme/head/doc/pyme.version.html M /pyme/head/pyme/version.py Prep for 0.5.1 ------------------------------------------------------------------------ rev 56: jgoerzen | 2002-11-20 22:39:02 -0600 (Wed, 20 Nov 2002) | 2 lines Changed paths: M /pyme/head/generated/gpgme_wrap.c M /pyme/head/helpers.c M /pyme/head/helpers.h M /pyme/head/pyme/callbacks.py M /pyme/head/pyme/core.py M /pyme/head/pyme/gpgme.py Beginnings of support for read_cb ------------------------------------------------------------------------ rev 55: jgoerzen | 2002-11-19 15:29:43 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/debian/changelog Removed the debian version number. ------------------------------------------------------------------------ rev 54: jgoerzen | 2002-11-19 15:28:49 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/ChangeLog M /pyme/head/debian/changelog Final prep for 0.5.0. ------------------------------------------------------------------------ rev 53: jgoerzen | 2002-11-19 15:26:50 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile A /pyme/head/debian/README.Debian M /pyme/head/debian/rules A /pyme/head/debian/setup.cfg-2.2 A /pyme/head/debian/setup.cfg-2.3 Updated for Debian packaging. ------------------------------------------------------------------------ rev 52: jgoerzen | 2002-11-19 15:04:01 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/ChangeLog M /pyme/head/Makefile D /pyme/head/debian/README.Debian D /pyme/head/debian/conffiles.ex M /pyme/head/debian/control M /pyme/head/debian/copyright D /pyme/head/debian/cron.d.ex M /pyme/head/debian/docs D /pyme/head/debian/emacsen-install.ex D /pyme/head/debian/emacsen-remove.ex D /pyme/head/debian/emacsen-startup.ex D /pyme/head/debian/init.d.ex D /pyme/head/debian/menu.ex M /pyme/head/debian/rules D /pyme/head/debian/watch.ex M /pyme/head/doc/pyme.aux.html A /pyme/head/doc/pyme.callbacks.html M /pyme/head/doc/pyme.constants.attr.html M /pyme/head/doc/pyme.constants.data.dtype.html M /pyme/head/doc/pyme.constants.data.encoding.html M /pyme/head/doc/pyme.constants.data.html M /pyme/head/doc/pyme.constants.html M /pyme/head/doc/pyme.constants.keylist.html M /pyme/head/doc/pyme.constants.keylist.mode.html M /pyme/head/doc/pyme.constants.protocol.html M /pyme/head/doc/pyme.constants.sig.html M /pyme/head/doc/pyme.constants.sig.mode.html M /pyme/head/doc/pyme.constants.sig.stat.html M /pyme/head/doc/pyme.constants.sigsum.html M /pyme/head/doc/pyme.constants.status.html M /pyme/head/doc/pyme.constants.validity.html M /pyme/head/doc/pyme.core.html M /pyme/head/doc/pyme.errors.html M /pyme/head/doc/pyme.gpgme.html M /pyme/head/doc/pyme.html M /pyme/head/doc/pyme.util.html M /pyme/head/doc/pyme.version.html M /pyme/head/pyme/version.py Preparing for the first release. ------------------------------------------------------------------------ rev 51: jgoerzen | 2002-11-19 14:45:22 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /pyme/head/debian A /pyme/head/debian/README.Debian A /pyme/head/debian/changelog A /pyme/head/debian/conffiles.ex A /pyme/head/debian/control A /pyme/head/debian/copyright A /pyme/head/debian/cron.d.ex A /pyme/head/debian/dirs A /pyme/head/debian/docs A /pyme/head/debian/emacsen-install.ex A /pyme/head/debian/emacsen-remove.ex A /pyme/head/debian/emacsen-startup.ex A /pyme/head/debian/ex.package.doc-base A /pyme/head/debian/init.d.ex A /pyme/head/debian/manpage.1.ex A /pyme/head/debian/manpage.sgml.ex A /pyme/head/debian/menu.ex A /pyme/head/debian/postinst.ex A /pyme/head/debian/postrm.ex A /pyme/head/debian/preinst.ex A /pyme/head/debian/prerm.ex A /pyme/head/debian/rules A /pyme/head/debian/watch.ex M /pyme/head/pyme/__init__.py Added templates from dh_make ------------------------------------------------------------------------ rev 50: jgoerzen | 2002-11-19 14:44:59 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/setup.py Removed debug code ------------------------------------------------------------------------ rev 49: jgoerzen | 2002-11-19 14:30:52 -0600 (Tue, 19 Nov 2002) | 3 lines Changed paths: A /pyme/head/helpers.h Forgot to add this file. ------------------------------------------------------------------------ rev 48: jgoerzen | 2002-11-19 14:29:45 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: D /pyme/head/callback A /pyme/head/examples/genkey.py (from /pyme/head/examples/simple.py:40) M /pyme/head/generated/gpgme_wrap.c M /pyme/head/helpers.c M /pyme/head/pyme/core.py M /pyme/head/pyme/gpgme.py Removed this; I'm doing it better myself. ------------------------------------------------------------------------ rev 47: jgoerzen | 2002-11-19 13:58:13 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile M /pyme/head/generated/gpgme_wrap.c M /pyme/head/gpgme.i M /pyme/head/helpers.c M /pyme/head/pyme/callbacks.py M /pyme/head/pyme/core.py M /pyme/head/pyme/gpgme.py M /pyme/head/setup.py Initial stab at progress stuff. ------------------------------------------------------------------------ rev 46: jgoerzen | 2002-11-19 13:25:55 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/examples/sign.py M /pyme/head/pyme/core.py Finished this. ------------------------------------------------------------------------ rev 45: jgoerzen | 2002-11-19 13:24:27 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/examples/sign.py M /pyme/head/generated/gpgme_wrap.c M /pyme/head/gpgme.i M /pyme/head/helpers.c M /pyme/head/pyme/callbacks.py M /pyme/head/pyme/core.py M /pyme/head/pyme/gpgme.py Seems to be working with hooks now. On to debug :-) ------------------------------------------------------------------------ rev 44: jgoerzen | 2002-11-19 12:12:44 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile A /pyme/head/examples/sign.py M /pyme/head/generated/gpgme_wrap.c M /pyme/head/gpgme.i M /pyme/head/helpers.c A /pyme/head/pyme/callbacks.py M /pyme/head/pyme/core.py M /pyme/head/pyme/gpgme.py The passphrase callback is now working. ------------------------------------------------------------------------ rev 43: jgoerzen | 2002-11-19 11:34:08 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /pyme/head/gpgme.i (from /pyme/head/gpgme.i0:42) D /pyme/head/gpgme.i0 Reverting back ------------------------------------------------------------------------ rev 42: jgoerzen | 2002-11-19 11:33:55 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile M /pyme/head/callback/mkcallback.pl M /pyme/head/generated/gpgme_wrap.c M /pyme/head/gpgme.i0 M /pyme/head/helpers.c M /pyme/head/pyme/gpgme.py First try at callbacks ------------------------------------------------------------------------ rev 41: jgoerzen | 2002-11-19 10:59:34 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile D /pyme/head/gpgme.i A /pyme/head/gpgme.i0 (from /pyme/head/gpgme.i:40) Renamed and updated for callback processing. ------------------------------------------------------------------------ rev 40: jgoerzen | 2002-11-19 10:57:18 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/callback/mkcallback.pl D /pyme/head/callback/mkcallback0.02.pl Updated to handle swig options from the environment. ------------------------------------------------------------------------ rev 39: jgoerzen | 2002-11-19 10:55:12 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /pyme/head/callback A /pyme/head/callback/COPYRIGHT A /pyme/head/callback/Makefile A /pyme/head/callback/Makefile.PL A /pyme/head/callback/Makefile.PY A /pyme/head/callback/Makefile.TCL A /pyme/head/callback/README A /pyme/head/callback/make.pl A /pyme/head/callback/mkcallback.pl A /pyme/head/callback/mkcallback0.02.pl A /pyme/head/callback/test.pl A /pyme/head/callback/test.py A /pyme/head/callback/test.tcl A /pyme/head/callback/testcb.i A /pyme/head/callback/testcb.i0 A /pyme/head/callback/testcb1.i0 Added ------------------------------------------------------------------------ rev 38: jgoerzen | 2002-11-19 10:37:23 -0600 (Tue, 19 Nov 2002) | 4 lines Changed paths: A /pyme/head/ChangeLog M /pyme/head/Makefile A /pyme/head/doc/pyme.aux.html A /pyme/head/doc/pyme.constants.attr.html A /pyme/head/doc/pyme.constants.data.dtype.html A /pyme/head/doc/pyme.constants.data.encoding.html A /pyme/head/doc/pyme.constants.data.html A /pyme/head/doc/pyme.constants.html A /pyme/head/doc/pyme.constants.keylist.html A /pyme/head/doc/pyme.constants.keylist.mode.html A /pyme/head/doc/pyme.constants.protocol.html A /pyme/head/doc/pyme.constants.sig.html A /pyme/head/doc/pyme.constants.sig.mode.html A /pyme/head/doc/pyme.constants.sig.stat.html A /pyme/head/doc/pyme.constants.sigsum.html A /pyme/head/doc/pyme.constants.status.html A /pyme/head/doc/pyme.constants.validity.html A /pyme/head/doc/pyme.core.html A /pyme/head/doc/pyme.errors.html A /pyme/head/doc/pyme.gpgme.html A /pyme/head/doc/pyme.html A /pyme/head/doc/pyme.util.html A /pyme/head/doc/pyme.version.html A /pyme/head/examples/simple.py M /pyme/head/pyme/__init__.py M /pyme/head/pyme/version.py Finishing touches prepping for first release. Added changelog, new docs. ------------------------------------------------------------------------ rev 37: jgoerzen | 2002-11-19 10:15:27 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/examples/encrypt-to-all.py M /pyme/head/pyme/constants/attr.py M /pyme/head/pyme/constants/data/dtype.py M /pyme/head/pyme/constants/data/encoding.py M /pyme/head/pyme/constants/keylist/mode.py M /pyme/head/pyme/constants/protocol.py M /pyme/head/pyme/constants/sig/mode.py M /pyme/head/pyme/constants/sig/stat.py M /pyme/head/pyme/constants/sigsum.py M /pyme/head/pyme/constants/status.py M /pyme/head/pyme/constants/validity.py M /pyme/head/pyme/errors.py Addressing more fallout from the rename. ------------------------------------------------------------------------ rev 36: jgoerzen | 2002-11-19 10:11:11 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /pyme/head/examples/encrypt-to-all.py (from /pyme/head/examples/test.py:33) D /pyme/head/examples/test.py M /pyme/head/generated/gpgme_wrap.c M /pyme/head/gpgme.i A /pyme/head/pyme/gpgme.py (from /pyme/head/pyme/gpgme_c.py:34) D /pyme/head/pyme/gpgme_c.py Updated -- more renaming still. ------------------------------------------------------------------------ rev 35: jgoerzen | 2002-11-19 10:08:31 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /pyme/head/pyme/constants/sig A /pyme/head/pyme/constants/sig/__init__.py A /pyme/head/pyme/constants/sig/mode.py A /pyme/head/pyme/constants/sig/stat.py D /pyme/head/pyme/sig Fixed sig problem ------------------------------------------------------------------------ rev 34: jgoerzen | 2002-11-19 10:05:11 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /pyme/head/Makefile A /pyme/head/doc/gpgme (from /pyme/head/doc/gpgme_c:33) D /pyme/head/doc/gpgme.attr.html D /pyme/head/doc/gpgme.data.dtype.html D /pyme/head/doc/gpgme.data.encoding.html D /pyme/head/doc/gpgme.data.html D /pyme/head/doc/gpgme.errors.html D /pyme/head/doc/gpgme.html D /pyme/head/doc/gpgme.keylist.html D /pyme/head/doc/gpgme.keylist.mode.html D /pyme/head/doc/gpgme.protocol.html D /pyme/head/doc/gpgme.sig.html D /pyme/head/doc/gpgme.sig.mode.html D /pyme/head/doc/gpgme.sig.stat.html D /pyme/head/doc/gpgme.sigsum.html D /pyme/head/doc/gpgme.status.html D /pyme/head/doc/gpgme.util.html D /pyme/head/doc/gpgme.validity.html D /pyme/head/doc/gpgme_c D /pyme/head/generated/gpgme_c_wrap.c A /pyme/head/generated/gpgme_wrap.c (from /pyme/head/generated/gpgme_c_wrap.c:33) D /pyme/head/gpgme A /pyme/head/gpgme.i (from /pyme/head/gpgme_c.i:33) D /pyme/head/gpgme_c.i A /pyme/head/pyme (from /pyme/head/gpgme:33) M /pyme/head/pyme/__init__.py A /pyme/head/pyme/aux.py A /pyme/head/pyme/constants/__init__.py M /pyme/head/pyme/core.py M /pyme/head/pyme/errors.py R /pyme/head/pyme/sig M /pyme/head/pyme/util.py M /pyme/head/pyme/version.py M /pyme/head/setup.py Updated -- progress on renaming ------------------------------------------------------------------------ rev 32: jgoerzen | 2002-11-19 09:30:58 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py M /python-gpgme/head/gpgme/constants/data/__init__.py M /python-gpgme/head/gpgme/constants/keylist/__init__.py Updated. ------------------------------------------------------------------------ rev 31: jgoerzen | 2002-11-19 09:29:14 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py D /python-gpgme/head/gpgme/attr.py A /python-gpgme/head/gpgme/constants/attr.py (from /python-gpgme/head/gpgme/attr.py:29) A /python-gpgme/head/gpgme/constants/protocol.py (from /python-gpgme/head/gpgme/protocol.py:29) D /python-gpgme/head/gpgme/protocol.py Updated. ------------------------------------------------------------------------ rev 30: jgoerzen | 2002-11-19 09:28:09 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py A /python-gpgme/head/gpgme/constants A /python-gpgme/head/gpgme/constants/data (from /python-gpgme/head/gpgme/data:29) A /python-gpgme/head/gpgme/constants/keylist (from /python-gpgme/head/gpgme/keylist:29) A /python-gpgme/head/gpgme/constants/sigsum.py (from /python-gpgme/head/gpgme/sigsum.py:29) A /python-gpgme/head/gpgme/constants/status.py (from /python-gpgme/head/gpgme/status.py:29) A /python-gpgme/head/gpgme/constants/validity.py (from /python-gpgme/head/gpgme/validity.py:29) A /python-gpgme/head/gpgme/core.py (from /python-gpgme/head/gpgme/__init__.py:29) D /python-gpgme/head/gpgme/data D /python-gpgme/head/gpgme/keylist D /python-gpgme/head/gpgme/sigsum.py D /python-gpgme/head/gpgme/status.py D /python-gpgme/head/gpgme/validity.py Some rearranging starting ------------------------------------------------------------------------ rev 29: jgoerzen | 2002-11-19 09:16:51 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/doc/gpgme_c/gpgme.html A /python-gpgme/head/doc/gpgme_c/gpgme_1.html A /python-gpgme/head/doc/gpgme_c/gpgme_10.html A /python-gpgme/head/doc/gpgme_c/gpgme_11.html A /python-gpgme/head/doc/gpgme_c/gpgme_12.html A /python-gpgme/head/doc/gpgme_c/gpgme_2.html A /python-gpgme/head/doc/gpgme_c/gpgme_3.html A /python-gpgme/head/doc/gpgme_c/gpgme_4.html A /python-gpgme/head/doc/gpgme_c/gpgme_5.html A /python-gpgme/head/doc/gpgme_c/gpgme_6.html A /python-gpgme/head/doc/gpgme_c/gpgme_7.html A /python-gpgme/head/doc/gpgme_c/gpgme_8.html A /python-gpgme/head/doc/gpgme_c/gpgme_9.html A /python-gpgme/head/doc/gpgme_c/gpgme_abt.html A /python-gpgme/head/doc/gpgme_c/gpgme_fot.html A /python-gpgme/head/doc/gpgme_c/gpgme_ovr.html A /python-gpgme/head/doc/gpgme_c/gpgme_toc.html A /python-gpgme/head/gpgme/version.py Added other missing files. ------------------------------------------------------------------------ rev 28: jgoerzen | 2002-11-19 09:16:04 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/Makefile M /python-gpgme/head/doc/gpgme.attr.html M /python-gpgme/head/doc/gpgme.data.dtype.html M /python-gpgme/head/doc/gpgme.data.encoding.html M /python-gpgme/head/doc/gpgme.data.html M /python-gpgme/head/doc/gpgme.errors.html M /python-gpgme/head/doc/gpgme.html M /python-gpgme/head/doc/gpgme.keylist.html M /python-gpgme/head/doc/gpgme.keylist.mode.html M /python-gpgme/head/doc/gpgme.protocol.html M /python-gpgme/head/doc/gpgme.sig.html M /python-gpgme/head/doc/gpgme.sig.mode.html M /python-gpgme/head/doc/gpgme.sig.stat.html M /python-gpgme/head/doc/gpgme.sigsum.html M /python-gpgme/head/doc/gpgme.status.html M /python-gpgme/head/doc/gpgme.util.html M /python-gpgme/head/doc/gpgme.validity.html M /python-gpgme/head/examples/test.py D /python-gpgme/head/generated/gpgme_c.py M /python-gpgme/head/gpgme/__init__.py A /python-gpgme/head/gpgme/gpgme_c.py Lots of updates ------------------------------------------------------------------------ rev 27: jgoerzen | 2002-11-19 08:30:32 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: D /python-gpgme/head/buildscripts Removed this directory. ------------------------------------------------------------------------ rev 26: jgoerzen | 2002-11-19 08:30:11 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/Makefile D /python-gpgme/head/buildscripts/Makefile D /python-gpgme/head/buildscripts/makedocs.sh D /python-gpgme/head/buildscripts/runswig.sh M /python-gpgme/head/setup.py Consolidation ------------------------------------------------------------------------ rev 25: jgoerzen | 2002-11-19 08:15:22 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: D /python-gpgme/head/Makefile A /python-gpgme/head/buildscripts A /python-gpgme/head/buildscripts/Makefile (from /python-gpgme/head/Makefile:24) A /python-gpgme/head/buildscripts/makedocs.sh (from /python-gpgme/head/doc/makedocs.sh:24) A /python-gpgme/head/buildscripts/runswig.sh (from /python-gpgme/head/runswig.sh:24) D /python-gpgme/head/doc/makedocs.sh A /python-gpgme/head/examples A /python-gpgme/head/examples/test.py (from /python-gpgme/head/test.py:24) A /python-gpgme/head/generated A /python-gpgme/head/generated/gpgme_c.py (from /python-gpgme/head/gpgme/gpgme_c.py:24) A /python-gpgme/head/generated/gpgme_c_wrap.c (from /python-gpgme/head/gpgme_c_wrap.c:24) D /python-gpgme/head/gpgme/gpgme_c.py D /python-gpgme/head/gpgme_c_wrap.c D /python-gpgme/head/runswig.sh D /python-gpgme/head/test.py Moving lots of things around ------------------------------------------------------------------------ rev 24: jgoerzen | 2002-11-19 08:01:17 -0600 (Tue, 19 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/Makefile M /python-gpgme/head/doc/gpgme.errors.html M /python-gpgme/head/doc/gpgme.html M /python-gpgme/head/doc/makedocs.sh M /python-gpgme/head/gpgme/__init__.py A /python-gpgme/head/gpgme/gpgme_c.py A /python-gpgme/head/gpgme_c_wrap.c M /python-gpgme/head/helpers.c A /python-gpgme/head/runswig.sh A /python-gpgme/head/setup.py M /python-gpgme/head/test.py Lots of updates and work on making it installable. ------------------------------------------------------------------------ rev 23: jgoerzen | 2002-11-18 19:05:03 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/errors.py M /python-gpgme/head/test.py Updated with new features ------------------------------------------------------------------------ rev 22: jgoerzen | 2002-11-18 17:06:42 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/doc/gpgme_c/fdl.texi A /python-gpgme/head/doc/gpgme_c/gpgme.texi A /python-gpgme/head/doc/gpgme_c/gpl.texi A /python-gpgme/head/doc/gpgme_c/version.texi Added. ------------------------------------------------------------------------ rev 21: jgoerzen | 2002-11-18 17:06:17 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/doc/gpgme.html M /python-gpgme/head/doc/gpgme.util.html A /python-gpgme/head/doc/gpgme_c M /python-gpgme/head/gpgme/__init__.py M /python-gpgme/head/test.py Committed. ------------------------------------------------------------------------ rev 20: jgoerzen | 2002-11-18 16:37:23 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py M /python-gpgme/head/gpgme/util.py A /python-gpgme/head/test.py Various bugfixes ------------------------------------------------------------------------ rev 19: jgoerzen | 2002-11-18 16:34:14 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/__init__.py (from /python-gpgme/head/gpgme/wrappers.py:17) D /python-gpgme/head/gpgme/wrappers.py M /python-gpgme/head/gpgme_c.i Using a more versatile method for passing around stuff now. ------------------------------------------------------------------------ rev 18: jgoerzen | 2002-11-18 16:31:27 -0600 (Mon, 18 Nov 2002) | 1 line Changed paths: D /python-gpgme/head/gpgme/__init__.py ------------------------------------------------------------------------ rev 17: jgoerzen | 2002-11-18 16:30:25 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/doc/gpgme.data.dtype.html M /python-gpgme/head/doc/gpgme.data.encoding.html M /python-gpgme/head/doc/gpgme.errors.html M /python-gpgme/head/doc/gpgme.html M /python-gpgme/head/doc/gpgme.keylist.mode.html M /python-gpgme/head/doc/gpgme.sig.mode.html M /python-gpgme/head/doc/gpgme.sig.stat.html M /python-gpgme/head/doc/gpgme.util.html M /python-gpgme/head/doc/makedocs.sh M /python-gpgme/head/gpgme/__init__.py D /python-gpgme/head/gpgme/context.py M /python-gpgme/head/gpgme/util.py A /python-gpgme/head/gpgme/wrappers.py (from /python-gpgme/head/gpgme/__init__.py:16) Updated ------------------------------------------------------------------------ rev 16: jgoerzen | 2002-11-18 16:21:39 -0600 (Mon, 18 Nov 2002) | 1 line Changed paths: M /python-gpgme/head/gpgme/__init__.py A /python-gpgme/head/gpgme/context.py (from /python-gpgme/head/gpgme/__init__.py:10) M /python-gpgme/head/gpgme/errors.py M /python-gpgme/head/gpgme/util.py ------------------------------------------------------------------------ rev 15: jgoerzen | 2002-11-18 16:10:39 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/errors.py Errors working better now. ------------------------------------------------------------------------ rev 14: jgoerzen | 2002-11-18 16:03:08 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/doc A /python-gpgme/head/doc/gpgme.attr.html A /python-gpgme/head/doc/gpgme.data.dtype.html A /python-gpgme/head/doc/gpgme.data.encoding.html A /python-gpgme/head/doc/gpgme.data.html A /python-gpgme/head/doc/gpgme.errors.html A /python-gpgme/head/doc/gpgme.html A /python-gpgme/head/doc/gpgme.keylist.html A /python-gpgme/head/doc/gpgme.keylist.mode.html A /python-gpgme/head/doc/gpgme.protocol.html A /python-gpgme/head/doc/gpgme.sig.html A /python-gpgme/head/doc/gpgme.sig.mode.html A /python-gpgme/head/doc/gpgme.sig.stat.html A /python-gpgme/head/doc/gpgme.sigsum.html A /python-gpgme/head/doc/gpgme.status.html A /python-gpgme/head/doc/gpgme.util.html A /python-gpgme/head/doc/gpgme.validity.html A /python-gpgme/head/doc/makedocs.sh M /python-gpgme/head/gpgme/data/dtype.py M /python-gpgme/head/gpgme/data/encoding.py M /python-gpgme/head/gpgme/keylist/mode.py M /python-gpgme/head/gpgme/sig/mode.py M /python-gpgme/head/gpgme/sig/stat.py Added documentation, fixed import problems in some modules. ------------------------------------------------------------------------ rev 13: jgoerzen | 2002-11-18 15:54:34 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/data A /python-gpgme/head/gpgme/data/__init__.py A /python-gpgme/head/gpgme/data/dtype.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/data/encoding.py (from /python-gpgme/head/gpgme/attr.py:10) D /python-gpgme/head/gpgme/datatype.py A /python-gpgme/head/gpgme/keylist A /python-gpgme/head/gpgme/keylist/__init__.py A /python-gpgme/head/gpgme/keylist/mode.py (from /python-gpgme/head/gpgme/attr.py:10) D /python-gpgme/head/gpgme/keylistmode.py A /python-gpgme/head/gpgme/sig A /python-gpgme/head/gpgme/sig/__init__.py A /python-gpgme/head/gpgme/sig/mode.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/sig/stat.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/sigsum.py (from /python-gpgme/head/gpgme/attr.py:10) Updated ------------------------------------------------------------------------ rev 12: jgoerzen | 2002-11-18 15:50:33 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/datatype.py (from /python-gpgme/head/gpgme/attr.py:10) D /python-gpgme/head/gpgme/keylist.py A /python-gpgme/head/gpgme/keylistmode.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/protocol.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/validity.py (from /python-gpgme/head/gpgme/attr.py:10) Updates. ------------------------------------------------------------------------ rev 11: jgoerzen | 2002-11-18 15:47:41 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/keylist.py (from /python-gpgme/head/gpgme/attr.py:10) A /python-gpgme/head/gpgme/status.py (from /python-gpgme/head/gpgme/attr.py:10) Updated ------------------------------------------------------------------------ rev 10: jgoerzen | 2002-11-18 15:46:15 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py M /python-gpgme/head/gpgme/attr.py A /python-gpgme/head/gpgme/util.py Updated ------------------------------------------------------------------------ rev 9: jgoerzen | 2002-11-18 15:39:29 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/attr.py (from /python-gpgme/head/gpgme/errors.py:8) M /python-gpgme/head/gpgme/errors.py Updated ------------------------------------------------------------------------ rev 8: jgoerzen | 2002-11-18 15:30:44 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/errors.py Added. ------------------------------------------------------------------------ rev 7: jgoerzen | 2002-11-18 15:29:45 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: M /python-gpgme/head/gpgme/__init__.py Rearranged ------------------------------------------------------------------------ rev 6: jgoerzen | 2002-11-18 15:26:42 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme/__init__.py (from /python-gpgme/head/gpgme.py:4) D /python-gpgme/head/gpgme.py Updated ------------------------------------------------------------------------ rev 5: jgoerzen | 2002-11-18 15:26:23 -0600 (Mon, 18 Nov 2002) | 1 line Changed paths: D /python-gpgme/head/gpgme/__init__.py ------------------------------------------------------------------------ rev 4: jgoerzen | 2002-11-18 15:25:59 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/gpgme A /python-gpgme/head/gpgme/__init__.py M /python-gpgme/head/gpgme.py Updated. ------------------------------------------------------------------------ rev 3: jgoerzen | 2002-11-18 15:09:04 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/head/COPYING A /python-gpgme/head/Makefile A /python-gpgme/head/gpgme.py A /python-gpgme/head/gpgme_c.i A /python-gpgme/head/helpers.c Initial add. ------------------------------------------------------------------------ rev 2: jgoerzen | 2002-11-18 15:05:20 -0600 (Mon, 18 Nov 2002) | 2 lines Changed paths: A /python-gpgme/branches A /python-gpgme/head A /python-gpgme/releases A /python-gpgme/tags Added basic structure ------------------------------------------------------------------------ pyme-0.8.1/debian/0000700000175000017500000000000011113133434012666 5ustar belyibelyipyme-0.8.1/debian/examples0000600000175000017500000000003710221335223014430 0ustar belyibelyiexamples/*.py examples/*.glade pyme-0.8.1/debian/control0000600000175000017500000000246611017350011014276 0ustar belyibelyiSource: pyme Section: python Priority: optional Maintainer: Igor Belyi Build-Depends: debhelper (>> 4.1.67), python-central, python2.4-dev, python2.5-dev, libgpgme11-dev, swig XS-Python-Version: 2.4, 2.5 Standards-Version: 3.5.2 Package: python-pyme-doc Architecture: all XB-Python-Version: ${python:Versions} Description: Python interface to the GPGME GnuPG encryption library This package contains the documentation for Pyme. Package: python-pyme Architecture: any Provides: ${python:Provides} Depends: ${python:Depends}, ${shlibs:Depends} XB-Python-Version: ${python:Versions} Suggests: python-pyme-doc Description: Python interface to the GPGME GnuPG encryption library Pyme is, for the most part, a direct interface to the C GPGME library. However, it is re-packaged in a more Pythonic way -- object-oriented with classes and modules. Take a look at the classes defined here -- they correspond directly to certain object types in GPGME for C. . Features: * Feature-rich, full implementation of the GPGME library. Supports all GPGME features. Callback functions may be written in pure Python. * Ability to sign, encrypt, decrypt, and verify data. * Ability to list keys, export and import keys, and manage the keyring. * Fully object-oriented with convenient classes and modules. pyme-0.8.1/debian/rules0000700000175000017500000000375111017347753013772 0ustar belyibelyi#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # This is the debhelper compatibility version to use. export DH_COMPAT=4 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CFLAGS += -g endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. touch configure-stamp build: build-stamp build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. $(MAKE) swig python2.4 setup.py build -b `pwd`/build python2.5 setup.py build -b `pwd`/build $(MAKE) PYSRCURL=file:/usr/share/pyshared/\\1 docs touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. -$(MAKE) reallyclean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/pyme. python2.4 setup.py install --root=`pwd`/debian/python-pyme python2.5 setup.py install --root=`pwd`/debian/python-pyme # Build architecture-independent files here. binary-indep: build install dh_testdir dh_testroot dh_installdocs -i -XCVS dh_installexamples -i -XCVS dh_installmenu -i dh_installchangelogs -i dh_link -i dh_strip -i dh_compress -i dh_fixperms -i dh_pycentral -i dh_installdeb -i dh_shlibdeps -i dh_gencontrol -i dh_md5sums -i dh_builddeb -i # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installdocs -a -XCVS dh_installexamples -a -XCVS dh_installmenu -a dh_installchangelogs -a dh_link -a dh_strip -a dh_compress -a dh_fixperms -a dh_pycentral -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure pyme-0.8.1/debian/README.Debian0000600000175000017500000000027010026724731014740 0ustar belyibelyiPlease note: The documentation for this package is in python-pyme-doc. When you install that package, you can find the documentation and examples in /usr/share/doc/python-pyme-doc. pyme-0.8.1/debian/copyright0000600000175000017500000000221310231620556014627 0ustar belyibelyiThe maintainance of the package was taken over by Igor Belyi on Thu, 18 March 2004