diff --git a/core/core.py b/core/core.py index c774a7ab2..b2677f16b 100644 --- a/core/core.py +++ b/core/core.py @@ -160,6 +160,22 @@ class MyGnuPG(GnuPGInterface.GnuPG): keyid = string.split(resp['GOODSIG'])[0] return keyid + def get_secret_keys(self): + proc = self.run(['--with-colons', '--list-secret-keys'], \ + create_fhs=['stdout']) + output = proc.handles['stdout'].read() + proc.handles['stdout'].close() + + keys = {} + lines = string.split(output, '\n') + for line in lines: + sline = string.split(line, ':') + if sline[0] == 'sec': + keys[sline[4][8:]] = sline[9] + return keys + try: proc.wait() + except IOError: pass + def stripHeaderFooter(self, data): """Remove header and footer from data""" lines = string.split(data, '\n') @@ -203,6 +219,7 @@ class GajimCore: #connexions {con: name, ...} self.connexions = {} self.gpg = {} + self.gpg_common = MyGnuPG() for a in self.accounts: self.connected[a] = 0 #0:offline, 1:online, 2:away, #3:xa, 4:dnd, 5:invisible @@ -870,6 +887,9 @@ class GajimCore: #('PASSPHRASE', account, passphrase) elif ev[0] == 'PASSPHRASE': self.gpg[ev[1]].passphrase = ev[2] + elif ev[0] == 'GPG_SECRETE_KEYS': + keys = self.gpg_common.get_secret_keys() + self.hub.sendPlugin('GPG_SECRETE_KEYS', ev[1], keys) else: log.debug(_("Unknown Command %s") % ev[0]) if self.mode == 'server': diff --git a/plugins/gtkgui/config.py b/plugins/gtkgui/config.py index 2d51a0e3d..c2cdaf055 100644 --- a/plugins/gtkgui/config.py +++ b/plugins/gtkgui/config.py @@ -251,7 +251,7 @@ class preference_Window: def on_presence_button_clicked(self, widget, data=None): self.change_notebook_page(2) - + def __init__(self, plugin): """Initialize Preference window""" self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Preferences', APP) @@ -341,7 +341,6 @@ class preference_Window: self.xml.signal_connect('on_ok_clicked', self.on_ok) self.xml.signal_connect('on_cancel_clicked', self.on_cancel) - class accountPreference_Window: """Class for account informations""" def delete_event(self, widget): @@ -357,8 +356,8 @@ class accountPreference_Window: def init_account(self, infos): """Initialize window with defaults values""" - if infos.has_key('name'): - self.xml.get_widget("entry_name").set_text(infos['name']) + if infos.has_key('accname'): + self.xml.get_widget("entry_name").set_text(infos['accname']) if infos.has_key('jid'): self.xml.get_widget("entry_jid").set_text(infos['jid']) if infos.has_key('password'): @@ -374,6 +373,19 @@ class accountPreference_Window: if infos.has_key('proxyport'): self.xml.get_widget("entry_proxyport").set_text(str(\ infos['proxyport'])) + if infos.has_key('keyid'): + if infos['keyid']: + self.xml.get_widget('gpg_key_label').set_text(infos['keyid']) + if infos.has_key('keyname'): + self.xml.get_widget('gpg_name_label').set_text(infos['keyname']) + self.xml.get_widget('gpg_pass_checkbutton').set_sensitive(True) + if infos.has_key('savegpgpass'): + self.xml.get_widget('gpg_pass_checkbutton').set_active(\ + infos['savegpgpass']) + self.xml.get_widget('gpg_pass_entry').set_sensitive(True) + if infos.has_key('gpgpass'): + self.xml.get_widget('gpg_pass_entry').set_text(\ + infos['gpgpass']) def on_save_clicked(self, widget): """When save button is clicked : Save informations in config file""" @@ -420,6 +432,17 @@ class accountPreference_Window: warning_Window(_("Priority must be a number")) return 0 (login, hostname) = string.split(jid, '@') + keyName = self.xml.get_widget('gpg_name_label').get_text() + if keyName == '': #no key selected + keyID = '' + save_gpg_pass = 0 + gpg_pass = '' + else: + keyID = self.xml.get_widget('gpg_key_label').get_text() + save_gpg_pass = 0 + if self.xml.get_widget('gpg_pass_checkbutton').get_active(): + save_gpg_pass = 1 + gpg_pass = self.xml.get_widget('gpg_pass_entry').get_text() #if we are modifying an account if self.modify: #if we modify the name of the account @@ -445,7 +468,8 @@ class accountPreference_Window: 'password': entryPass.get_text(), 'ressource': \ entryRessource.get_text(), 'priority' : prio, 'use_proxy': \ useProxy, 'proxyhost': entryProxyhost.get_text(), 'proxyport': \ - proxyPort} + proxyPort, 'keyid': keyID, 'keyname': keyName, 'savegpgpass': \ + save_gpg_pass, 'gpgpass': gpg_pass} self.plugin.send('CONFIG', None, ('accounts', self.plugin.accounts)) #refresh accounts window if self.plugin.windows.has_key('accounts'): @@ -455,21 +479,22 @@ class accountPreference_Window: widget.get_toplevel().destroy() return #if it's a new account - else: - if name in self.plugin.accounts.keys(): - warning_Window(_("An account already has this name")) - return - #if we neeed to register a new account - if check.get_active(): - self.plugin.send('NEW_ACC', None, (hostname, login, \ - entryPass.get_text(), name, entryRessource.get_text(), prio, \ - useProxy, proxyHost, proxyPort)) - check.set_active(FALSE) - return + if name in self.plugin.accounts.keys(): + warning_Window(_("An account already has this name")) + return + #if we neeed to register a new account + if check.get_active(): + self.plugin.send('NEW_ACC', None, (hostname, login, \ + entryPass.get_text(), name, entryRessource.get_text(), prio, \ + useProxy, proxyHost, proxyPort)) + check.set_active(FALSE) + return self.plugin.accounts[name] = {'name': login, 'hostname': hostname,\ 'password': entryPass.get_text(), 'ressource': \ entryRessource.get_text(), 'priority' : prio, 'use_proxy': useProxy, \ - 'proxyhost': entryProxyhost.get_text(), 'proxyport': proxyPort} + 'proxyhost': entryProxyhost.get_text(), 'proxyport': proxyPort, \ + 'keyid': keyID, 'keyname': keyName, 'savegpgpass': save_gpg_pass, \ + 'gpgpass': gpg_pass} self.plugin.send('CONFIG', None, ('accounts', self.plugin.accounts)) #update variables self.plugin.windows[name] = {'infos': {}, 'chats': {}} @@ -496,6 +521,32 @@ class accountPreference_Window: else: warning_Window(_("You must be connected to get your informations")) + def on_choose_gpg(self, widget, data=None): + w = choose_gpg_Window() + self.plugin.windows['gpg_keys'] = w + self.plugin.send('GPG_SECRETE_KEYS', None, ()) + keyID = w.run() + if keyID == -1: + return + if keyID[0] == 'None': + self.xml.get_widget('gpg_key_label').set_text(_('No key selected')) + self.xml.get_widget('gpg_name_label').set_text('') + self.xml.get_widget('gpg_pass_checkbutton').set_sensitive(False) + self.xml.get_widget('gpg_pass_entry').set_sensitive(False) + else: + self.xml.get_widget('gpg_key_label').set_text(keyID[0]) + self.xml.get_widget('gpg_name_label').set_text(keyID[1]) + self.xml.get_widget('gpg_pass_checkbutton').set_sensitive(True) + self.xml.get_widget('gpg_pass_checkbutton').set_active(False) + self.xml.get_widget('gpg_pass_entry').set_text('') + + def on_gpg_pass_checkbutton_toggled(self, widget, data=None): + if self.xml.get_widget('gpg_pass_checkbutton').get_active(): + self.xml.get_widget('gpg_pass_entry').set_sensitive(True) + else: + self.xml.get_widget('gpg_pass_entry').set_sensitive(False) + self.xml.get_widget('gpg_pass_entry').set_text('') + #info must be a dictionnary def __init__(self, plugin, infos = {}): self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Account', APP) @@ -503,9 +554,13 @@ class accountPreference_Window: self.plugin = plugin self.account = '' self.modify = False + self.xml.get_widget('gpg_key_label').set_text('No key selected') + self.xml.get_widget('gpg_name_label').set_text('') + self.xml.get_widget('gpg_pass_checkbutton').set_sensitive(False) + self.xml.get_widget('gpg_pass_entry').set_sensitive(False) if infos: self.modify = True - self.account = infos['name'] + self.account = infos['accname'] self.init_account(infos) self.xml.get_widget("checkbutton").set_sensitive(FALSE) self.xml.signal_connect('gtk_widget_destroy', self.delete_event) @@ -513,7 +568,9 @@ class accountPreference_Window: self.xml.signal_connect('on_edit_details_clicked', \ self.on_edit_details_clicked) self.xml.signal_connect('on_close_clicked', self.on_close) - + self.xml.signal_connect('on_choose_gpg_clicked', self.on_choose_gpg) + self.xml.signal_connect('on_gpg_pass_checkbutton_toggled', \ + self.on_gpg_pass_checkbutton_toggled) class accounts_Window: """Class for accounts window : lists of accounts""" @@ -575,26 +632,14 @@ class accounts_Window: """When modify button is clicked : open the account information window for this account""" if not self.plugin.windows.has_key('accountPreference'): - infos = {} +# infos = {} sel = self.treeview.get_selection() (model, iter) = sel.get_selected() account = model.get_value(iter, 0) - infos['name'] = account - if self.plugin.accounts[account].has_key("name"): - infos['jid'] = self.plugin.accounts[account]["name"] + \ - '@' + self.plugin.accounts[account]["hostname"] - if self.plugin.accounts[account].has_key("password"): - infos['password'] = self.plugin.accounts[account]["password"] - if self.plugin.accounts[account].has_key("ressource"): - infos['ressource'] = self.plugin.accounts[account]["ressource"] - if self.plugin.accounts[account].has_key("priority"): - infos['priority'] = self.plugin.accounts[account]["priority"] - if self.plugin.accounts[account].has_key("use_proxy"): - infos['use_proxy'] = self.plugin.accounts[account]["use_proxy"] - if self.plugin.accounts[account].has_key("proxyhost"): - infos['proxyhost'] = self.plugin.accounts[account]["proxyhost"] - if self.plugin.accounts[account].has_key("proxyport"): - infos['proxyport'] = self.plugin.accounts[account]["proxyport"] + infos = self.plugin.accounts[account] + infos['accname'] = account + infos['jid'] = self.plugin.accounts[account]["name"] + \ + '@' + self.plugin.accounts[account]["hostname"] self.plugin.windows['accountPreference'] = \ accountPreference_Window(self.plugin, infos) diff --git a/plugins/gtkgui/dialogs.py b/plugins/gtkgui/dialogs.py index edbb12094..fb9656065 100644 --- a/plugins/gtkgui/dialogs.py +++ b/plugins/gtkgui/dialogs.py @@ -206,6 +206,40 @@ class passphrase_Window: self.xml.signal_connect('on_Passphrase_key_press_event', \ self.on_key_pressed) +class choose_gpg_Window: + """Class for Away Message Window""" + def run(self): + """Wait for Ok button to be pressed and return the selected key""" + rep = self.xml.get_widget("Choose_gpg_key").run() + if rep == gtk.RESPONSE_OK: + selection = self.treeview.get_selection() + (model, iter) = selection.get_selected() + keyID = [model.get_value(iter, 0), model.get_value(iter, 1)] + else: + keyID = -1 + self.xml.get_widget("Choose_gpg_key").destroy() + return keyID + + def fill_tree(self, list): + model = self.treeview.get_model() + for keyID in list.keys(): + model.append((keyID, list[keyID])) + + def __init__(self): + #list : {keyID: userName, ...} + self.xml = gtk.glade.XML(GTKGUI_GLADE, 'Choose_gpg_key', APP) + self.window = self.xml.get_widget("Choose_gpg_key") + self.treeview = self.xml.get_widget("treeview") + model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) + self.treeview.set_model(model) + #columns + renderer = gtk.CellRendererText() + self.treeview.insert_column_with_attributes(-1, _('KeyID'), renderer, \ + text=0) + renderer = gtk.CellRendererText() + self.treeview.insert_column_with_attributes(-1, _('User name'), renderer,\ + text=1) + class awayMsg_Window: """Class for Away Message Window""" def on_ok(self): diff --git a/plugins/gtkgui/gtkgui.py b/plugins/gtkgui/gtkgui.py index 7c8cb2336..4bef1a401 100644 --- a/plugins/gtkgui/gtkgui.py +++ b/plugins/gtkgui/gtkgui.py @@ -1232,23 +1232,11 @@ class roster_Window: def on_edit_account(self, widget, account): if not self.plugin.windows.has_key('accountPreference'): - infos = {} - infos['name'] = account - if self.plugin.accounts[account].has_key("name"): - infos['jid'] = self.plugin.accounts[account]["name"] + \ - '@' + self.plugin.accounts[account]["hostname"] - if self.plugin.accounts[account].has_key("password"): - infos['password'] = self.plugin.accounts[account]["password"] - if self.plugin.accounts[account].has_key("ressource"): - infos['ressource'] = self.plugin.accounts[account]["ressource"] - if self.plugin.accounts[account].has_key("priority"): - infos['priority'] = self.plugin.accounts[account]["priority"] - if self.plugin.accounts[account].has_key("use_proxy"): - infos['use_proxy'] = self.plugin.accounts[account]["use_proxy"] - if self.plugin.accounts[account].has_key("proxyhost"): - infos['proxyhost'] = self.plugin.accounts[account]["proxyhost"] - if self.plugin.accounts[account].has_key("proxyport"): - infos['proxyport'] = self.plugin.accounts[account]["proxyport"] + infos = self.plugin.accounts[account] + infos['accname'] = account +# if self.plugin.accounts[account].has_key("name"): + infos['jid'] = self.plugin.accounts[account]["name"] + \ + '@' + self.plugin.accounts[account]["hostname"] self.plugin.windows['accountPreference'] = \ accountPreference_Window(self.plugin, infos) @@ -1356,15 +1344,20 @@ class roster_Window: def send_status(self, account, status, txt): if status != 'offline': keyid = None + save_gpg_pass = 0 + if self.plugin.accounts[account].has_key("savegpgpass"): + save_gpg_pass = self.plugin.accounts[account]["savegpgpass"] if self.plugin.accounts[account].has_key("keyid"): keyid = self.plugin.accounts[account]["keyid"] if keyid and not self.plugin.connected[account]: - passphrase = '' - #TODO: ask passphrase - w = passphrase_Window() - passphrase = w.run() - if passphrase == -1: + if save_gpg_pass: + passphrase = self.plugin.accounts[account]['gpgpass'] + else: passphrase = '' + w = passphrase_Window() + passphrase = w.run() + if passphrase == -1: + passphrase = '' self.plugin.send('PASSPHRASE', account, passphrase) self.plugin.send('STATUS', account, (status, txt)) if status == 'online': @@ -2260,6 +2253,14 @@ class plugin: get_property('is-active'): self.systray.add_jid(jid, account) + def handle_event_bad_passphrase(self, account, array): + pass + + def handle_event_gpg_secrete_keys(self, account, keys): + keys['None'] = 'None' + if self.windows.has_key('gpg_keys'): + self.windows['gpg_keys'].fill_tree(keys) + def read_queue(self): """Read queue from the core and execute commands from it""" while self.queueIN.empty() == 0: @@ -2302,6 +2303,10 @@ class plugin: self.handle_event_log_line(ev[1], ev[2]) elif ev[0] == 'GC_MSG': self.handle_event_gc_msg(ev[1], ev[2]) + elif ev[0] == 'BAD_PASSPHRASE': + self.handle_event_bad_passphrase(ev[1], ev[2]) + elif ev[0] == 'GPG_SECRETE_KEYS': + self.handle_event_gpg_secrete_keys(ev[1], ev[2]) return 1 def read_sleepy(self): @@ -2344,7 +2349,7 @@ class plugin: 'NOTIFY', 'MSG', 'MSGERROR', 'SUBSCRIBED', 'UNSUBSCRIBED', \ 'SUBSCRIBE', 'AGENTS', 'AGENT_INFO', 'REG_AGENT_INFO', 'QUIT', \ 'ACC_OK', 'CONFIG', 'MYVCARD', 'VCARD', 'LOG_NB_LINE', 'LOG_LINE', \ - 'VISUAL', 'GC_MSG']) + 'VISUAL', 'GC_MSG', 'BAD_PASSPHRASE', 'GPG_SECRETE_KEYS']) self.send('ASK_CONFIG', None, ('GtkGui', 'GtkGui', {'autopopup':1,\ 'autopopupaway':1,\ 'showoffline':0,\