From 9d75c779827afa6b348d3a8da5e5c87252e9fc0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Tue, 16 Apr 2019 23:16:41 +0200 Subject: [PATCH] Remove GPG code from Gajim Code moved into plugin --- gajim/app_actions.py | 5 - gajim/application.py | 6 - gajim/chat_control.py | 17 +-- gajim/chat_control_base.py | 4 +- gajim/common/app.py | 43 ------ gajim/common/config.py | 3 - gajim/common/connection.py | 140 ++---------------- gajim/common/connection_handlers_events.py | 17 --- gajim/common/const.py | 1 - gajim/common/contacts.py | 17 +-- gajim/common/gpg.py | 146 ------------------ gajim/common/helpers.py | 48 ------ gajim/common/modules/httpupload.py | 5 +- gajim/common/modules/presence.py | 20 +-- gajim/common/zeroconf/connection_zeroconf.py | 12 +- gajim/data/gui/choose_gpg_key_dialog.ui | 115 --------------- gajim/data/gui/contact_context_menu.ui | 10 +- gajim/data/gui/tooltip_roster_contact.ui | 32 +--- gajim/dialogs.py | 67 --------- gajim/gajim_remote.py | 11 +- gajim/gtk/account_wizard.py | 2 - gajim/gtk/accounts.py | 14 +- gajim/gtk/features.py | 7 - gajim/gtk/tooltips.py | 15 +- gajim/gui_interface.py | 147 +------------------ gajim/gui_menu_builder.py | 8 - gajim/options_dialog.py | 55 ------- gajim/remote_control.py | 34 ++--- gajim/roster_window.py | 69 +-------- mypy.ini | 3 - 30 files changed, 64 insertions(+), 1009 deletions(-) delete mode 100644 gajim/common/gpg.py delete mode 100644 gajim/data/gui/choose_gpg_key_dialog.ui diff --git a/gajim/app_actions.py b/gajim/app_actions.py index 8ca7a9884..bf0e9494d 100644 --- a/gajim/app_actions.py +++ b/gajim/app_actions.py @@ -179,11 +179,6 @@ def on_merge_accounts(action, param): app.interface.roster.setup_and_draw_roster() -def on_use_pgp_agent(action, param): - action.set_state(param) - app.config.set('use_gpg_agent', param.get_boolean()) - - def on_add_account(action, param): if 'account_creation_wizard' in app.interface.instances: app.interface.instances['account_creation_wizard'].window.present() diff --git a/gajim/application.py b/gajim/application.py index 0562a0df1..0da3d6ee7 100644 --- a/gajim/application.py +++ b/gajim/application.py @@ -388,12 +388,6 @@ class GajimApplication(Gtk.Application): act.connect('change-state', app_actions.on_merge_accounts) self.add_action(act) - act = Gio.SimpleAction.new_stateful( - 'agent', None, - GLib.Variant.new_boolean(app.config.get('use_gpg_agent'))) - act.connect('change-state', app_actions.on_use_pgp_agent) - self.add_action(act) - # General Actions general_actions = [ diff --git a/gajim/chat_control.py b/gajim/chat_control.py index 01b59319c..bcc7bd03d 100644 --- a/gajim/chat_control.py +++ b/gajim/chat_control.py @@ -399,12 +399,8 @@ class ChatControl(ChatControlBase): 'Show a list of formattings')) else: self._formattings_button.set_sensitive(False) - if self.contact.supports(NS_XHTML_IM): - self._formattings_button.set_tooltip_text(_('Formatting is not ' - 'available so long as GPG is active')) - else: - self._formattings_button.set_tooltip_text(_('This contact does ' - 'not support HTML')) + self._formattings_button.set_tooltip_text( + _('This contact does not support HTML')) # Jingle detection if self.contact.supports(NS_JINGLE_ICE_UDP) and \ @@ -922,7 +918,7 @@ class ChatControl(ChatControlBase): correct_id=obj.correct_id, additional_data=obj.additional_data) - def send_message(self, message, keyID='', xhtml=None, + def send_message(self, message, xhtml=None, process_commands=True, attention=False): """ Send a message to contact @@ -939,12 +935,8 @@ class ChatControl(ChatControlBase): if message in ('', None, '\n'): return None - contact = self.contact - keyID = contact.keyID - ChatControlBase.send_message(self, message, - keyID, type_='chat', xhtml=xhtml, process_commands=process_commands, @@ -1426,9 +1418,6 @@ class ChatControl(ChatControlBase): self.update_actions() def update_status_display(self, name, uf_show, status): - """ - Print the contact's status and update the status/GPG image - """ self.update_ui() self.parent_win.redraw_tab(self) diff --git a/gajim/chat_control_base.py b/gajim/chat_control_base.py index 435b40904..d66c639c5 100644 --- a/gajim/chat_control_base.py +++ b/gajim/chat_control_base.py @@ -773,7 +773,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): label = labels[lname] return label - def send_message(self, message, keyID='', type_='chat', + def send_message(self, message, type_='chat', resource=None, xhtml=None, process_commands=True, attention=False): """ Send the given message to the active tab. Doesn't return None if error @@ -797,7 +797,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): app.nec.push_outgoing_event(MessageOutgoingEvent(None, account=self.account, jid=self.contact.jid, message=message, - keyID=keyID, type_=type_, chatstate=chatstate, + type_=type_, chatstate=chatstate, resource=resource, user_nick=self.user_nick, xhtml=xhtml, label=label, control=self, attention=attention, correct_id=correct_id, automatic_message=False, encryption=self.encryption)) diff --git a/gajim/common/app.py b/gajim/common/app.py index 53d1221dd..1158759d1 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -35,7 +35,6 @@ import sys import logging import uuid from pathlib import Path -from distutils.version import LooseVersion as V from collections import namedtuple import nbxmpp @@ -191,8 +190,6 @@ caps_hash = {} # type: Dict[str, List[str]] _dependencies = { 'AVAHI': False, 'PYBONJOUR': False, - 'PYGPG': False, - 'GPG_BINARY': False, 'FARSTREAM': False, 'GEOCLUE': False, 'UPNP': False, @@ -203,9 +200,6 @@ _dependencies = { def is_installed(dependency): - if dependency == 'GPG': - # Alias for checking python-gnupg and the GPG binary - return _dependencies['PYGPG'] and _dependencies['GPG_BINARY'] if dependency == 'ZEROCONF': # Alias for checking zeroconf libs return _dependencies['AVAHI'] or _dependencies['PYBONJOUR'] @@ -246,40 +240,6 @@ def detect_dependencies(): except Exception: pass - # python-gnupg - try: - import gnupg - # We need https://pypi.python.org/pypi/python-gnupg - # but https://pypi.python.org/pypi/gnupg shares the same package name. - # It cannot be used as a drop-in replacement. - # We test with a version check if python-gnupg is installed as it is - # on a much lower version number than gnupg - # Also we need at least python-gnupg 0.3.8 - v_gnupg = gnupg.__version__ - if V(v_gnupg) < V('0.3.8') or V(v_gnupg) > V('1.0.0'): - log('gajim').info('Gajim needs python-gnupg >= 0.3.8') - raise ImportError - _dependencies['PYGPG'] = True - except ImportError: - pass - - # GPG BINARY - import subprocess - - def test_gpg(binary='gpg'): - if os.name == 'nt': - gpg_cmd = binary + ' -h >nul 2>&1' - else: - gpg_cmd = binary + ' -h >/dev/null 2>&1' - if subprocess.call(gpg_cmd, shell=True): - return False - return True - - if test_gpg(binary='gpg2'): - _dependencies['GPG_BINARY'] = 'gpg2' - elif test_gpg(binary='gpg'): - _dependencies['GPG_BINARY'] = 'gpg' - # FARSTREAM try: if os.name == 'nt': @@ -354,9 +314,6 @@ def detect_dependencies(): log('gajim').info('Used language: %s', LANG) -def get_gpg_binary(): - return _dependencies['GPG_BINARY'] - def get_an_id(): return str(uuid.uuid4()) diff --git a/gajim/common/config.py b/gajim/common/config.py index 3dd989126..996ede061 100644 --- a/gajim/common/config.py +++ b/gajim/common/config.py @@ -167,7 +167,6 @@ class Config: 'time_stamp': [opt_str, '[%X] ', _('This option let you customize timestamp that is printed in conversation. For example "[%H:%M] " will show "[hour:minute] ". See python doc on strftime for full documentation: http://docs.python.org/lib/module-time.html')], 'before_nickname': [opt_str, '', _('Characters that are printed before the nickname in conversations')], 'after_nickname': [opt_str, ':', _('Characters that are printed after the nickname in conversations')], - 'use_gpg_agent': [opt_bool, False], 'change_roster_title': [opt_bool, True, _('Add * and [n] in roster title?')], 'restore_lines': [opt_int, 10, _('How many history messages should be restored when a chat tab/window is reopened?')], 'restore_timeout': [opt_int, -1, _('How far back in time (minutes) history is restored. -1 means no limit.')], @@ -285,7 +284,6 @@ class Config: 'positive_184_ack': [opt_bool, False, _('If enabled, Gajim will show an icon to show that sent message has been received by your contact')], 'show_avatar_in_tabs': [opt_bool, False, _('Show a mini avatar in chat window tabs and in window icon')], 'use_keyring': [opt_bool, True, _('If true, Gajim will use the Systems Keyring to store account passwords.')], - 'pgp_encoding': [opt_str, '', _('Sets the encoding used by python-gnupg'), True], 'remote_commands': [opt_bool, False, _('If true, Gajim will execute XEP-0146 Commands.')], 'dark_theme': [opt_int, 2, _('2: System, 1: Enabled, 0: Disabled')], 'threshold_options': [opt_str, '1, 2, 4, 10, 0', _('Options in days which can be chosen in the sync threshold menu'), True], @@ -325,7 +323,6 @@ class Config: 'active': [opt_bool, True, _('If False, this account will be disabled and will not appear in roster window.'), True], 'proxy': [opt_str, '', '', True], 'keyid': [opt_str, '', '', True], - 'gpg_sign_presence': [opt_bool, True, _('If disabled, don\'t sign presences with GPG key, even if GPG is configured.')], 'keyname': [opt_str, '', '', True], 'allow_plaintext_connection': [opt_bool, False, _('Allow plaintext connections')], 'tls_version': [opt_str, '1.2', ''], diff --git a/gajim/common/connection.py b/gajim/common/connection.py index 8fc4d8fc7..c34b160dd 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -55,7 +55,6 @@ from nbxmpp.const import Event from gajim import common from gajim.common import helpers from gajim.common import app -from gajim.common import gpg from gajim.common import passwords from gajim.common import idle from gajim.common import modules @@ -66,8 +65,6 @@ from gajim.common.nec import NetworkEvent from gajim.common.contacts import GC_Contact from gajim.common.connection_handlers import ConnectionHandlers from gajim.common.connection_handlers_events import OurShowEvent -from gajim.common.connection_handlers_events import BadGPGPassphraseEvent -from gajim.common.connection_handlers_events import GPGPasswordRequiredEvent from gajim.common.connection_handlers_events import InformationEvent from gajim.common.connection_handlers_events import StanzaMessageOutgoingEvent from gajim.common.connection_handlers_events import GcStanzaMessageOutgoingEvent @@ -105,11 +102,6 @@ class CommonConnection: self.is_zeroconf = False self.password = None self.server_resource = self._compute_resource() - self.gpg = None - self.USE_GPG = False - if app.is_installed('GPG'): - self.USE_GPG = True - self.gpg = gpg.GnuPG() self.status = '' self.old_show = '' self.priority = app.get_priority(name, 'offline') @@ -187,43 +179,6 @@ class CommonConnection: if kill_core and app.account_is_connected(self.name): self.disconnect(reconnect=False) - def test_gpg_passphrase(self, password): - """ - Returns 'ok', 'bad_pass' or 'expired' - """ - if not self.gpg: - return False - self.gpg.passphrase = password - keyID = app.config.get_per('accounts', self.name, 'keyid') - signed = self.gpg.sign('test', keyID) - self.gpg.password = None - if signed == 'KEYEXPIRED': - return 'expired' - if signed == 'BAD_PASSPHRASE': - return 'bad_pass' - return 'ok' - - def get_signed_msg(self, msg, callback=None): - """ - Returns the signed message if possible or an empty string if gpg is not - used or None if waiting for passphrase - - callback is the function to call when user give the passphrase - """ - signed = '' - keyID = app.config.get_per('accounts', self.name, 'keyid') - if keyID and self.USE_GPG: - if self.gpg.passphrase is None and not self.gpg.use_agent: - # We didn't set a passphrase - return None - signed = self.gpg.sign(msg, keyID) - if signed == 'BAD_PASSPHRASE': - self.USE_GPG = False - signed = '' - app.nec.push_incoming_event(BadGPGPassphraseEvent(None, - conn=self)) - return signed - def get_status(self): return app.SHOW_LIST[self.connected] @@ -432,25 +387,6 @@ class CommonConnection: """ raise NotImplementedError - def gpg_passphrase(self, passphrase): - if self.gpg: - if self.gpg.use_agent: - self.gpg.passphrase = None - else: - self.gpg.passphrase = passphrase - - def ask_gpg_keys(self, keyID=None): - if self.gpg: - if keyID: - return self.gpg.get_key(keyID) - return self.gpg.get_keys() - return None - - def ask_gpg_secrete_keys(self): - if self.gpg: - return self.gpg.get_secret_keys() - return None - def _event_dispatcher(self, realm, event, data): if realm == '': if event == 'STANZA RECEIVED': @@ -467,9 +403,7 @@ class CommonConnection: def change_status(self, show, msg, auto=False): if not msg: msg = '' - sign_msg = False - if not auto and not show == 'offline': - sign_msg = True + if show != 'invisible': # We save it only when privacy list is accepted self.status = msg @@ -478,10 +412,7 @@ class CommonConnection: # recconect before we auth to server self.old_show = show self.server_resource = self._compute_resource() - if app.is_installed('GPG'): - self.USE_GPG = True - self.gpg = gpg.GnuPG() - self.connect_and_init(show, msg, sign_msg) + self.connect_and_init(show, msg) return if show == 'offline': @@ -615,7 +546,7 @@ class Connection(CommonConnection, ConnectionHandlers): app.nec.push_incoming_event(OurShowEvent(None, conn=self, show='connecting')) self.retrycount += 1 - self.connect_and_init(self.old_show, self.status, self.USE_GPG) + self.connect_and_init(self.old_show, self.status) else: log.info('Reconnect successfull') # reconnect succeeded @@ -784,9 +715,7 @@ class Connection(CommonConnection, ConnectionHandlers): app.nec.push_incoming_event(NetworkEvent( 'account-not-created', conn=self, reason=reason)) return - if app.is_installed('GPG'): - self.USE_GPG = True - self.gpg = gpg.GnuPG() + app.nec.push_incoming_event( NetworkEvent('account-created', conn=self, @@ -1439,7 +1368,7 @@ class Connection(CommonConnection, ConnectionHandlers): if self.connection: self.connection.send(' ') - def send_invisible_presence(self, msg, signed, initial=False): + def send_invisible_presence(self, msg, initial=False): if not app.account_is_connected(self.name): return if not self.get_module('PrivacyLists').supported: @@ -1461,7 +1390,6 @@ class Connection(CommonConnection, ConnectionHandlers): self.get_module('PrivacyLists').set_invisible_rule( callback=self._continue_invisible, msg=msg, - signed=signed, initial=initial) def _continue_invisible(self, con, iq_obj, msg, signed, initial): @@ -1475,8 +1403,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.get_module('Presence').send_presence( priority=priority, - status=msg, - sign=signed) + status=msg) self.priority = priority app.nec.push_incoming_event(OurShowEvent(None, conn=self, @@ -1501,19 +1428,14 @@ class Connection(CommonConnection, ConnectionHandlers): # Inform GUI we just signed in app.nec.push_incoming_event(NetworkEvent('signed-in', conn=self)) - def get_signed_presence(self, msg, callback=None): - if app.config.get_per('accounts', self.name, 'gpg_sign_presence'): - return self.get_signed_msg(msg, callback) - return '' - def connect_and_auth(self): self.on_connect_success = self._connect_success self.on_connect_failure = self._connect_failure self.connect() - def connect_and_init(self, show, msg, sign_msg): + def connect_and_init(self, show, msg): self.disable_reconnect_timer() - self.continue_connect_info = [show, msg, sign_msg] + self.continue_connect_info = [show, msg] self.connect_and_auth() def _discover_server(self): @@ -1564,40 +1486,16 @@ class Connection(CommonConnection, ConnectionHandlers): app.proxy65_manager.resolve(proxy, self.connection, our_jid, testit=testit) - def send_first_presence(self): - if self.connected > 1 and self.continue_connect_info: - msg = self.continue_connect_info[1] - sign_msg = self.continue_connect_info[2] - signed = '' - send_first_presence = True - if sign_msg: - signed = self.get_signed_presence(msg, - self._send_first_presence) - if signed is None: - app.nec.push_incoming_event(GPGPasswordRequiredEvent(None, - conn=self, callback=self._send_first_presence)) - # _send_first_presence will be called when user enter - # passphrase - send_first_presence = False - if send_first_presence: - self._send_first_presence(signed) - - def _send_first_presence(self, signed=''): + def send_first_presence(self, signed=''): + if self.connected <= 1 or not self.continue_connect_info: + return show = self.continue_connect_info[0] msg = self.continue_connect_info[1] - sign_msg = self.continue_connect_info[2] - if sign_msg and not signed: - signed = self.get_signed_presence(msg) - if signed is None: - app.nec.push_incoming_event(BadGPGPassphraseEvent(None, - conn=self)) - self.USE_GPG = False - signed = '' self.connected = app.SHOW_LIST.index(show) sshow = helpers.get_xmpp_show(show) # send our presence if show == 'invisible': - self.send_invisible_presence(msg, signed, True) + self.send_invisible_presence(msg, True) return if show not in ['offline', 'online', 'chat', 'away', 'xa', 'dnd']: return @@ -1606,8 +1504,7 @@ class Connection(CommonConnection, ConnectionHandlers): self.get_module('Presence').send_presence( priority=priority, show=sshow, - status=msg, - sign=signed) + status=msg) if self.connection: self.priority = priority @@ -1643,18 +1540,15 @@ class Connection(CommonConnection, ConnectionHandlers): status=msg) else: - signed = self.get_signed_presence(msg) priority = app.get_priority(self.name, sshow) self.get_module('Presence').send_presence( jid, priority=priority, show=sshow, - status=msg, - sign=signed) + status=msg) def _change_to_invisible(self, msg): - signed = self.get_signed_presence(msg) - self.send_invisible_presence(msg, signed) + self.send_invisible_presence(msg) def _change_from_invisible(self): if self.get_module('PrivacyLists').supported: @@ -1663,13 +1557,11 @@ class Connection(CommonConnection, ConnectionHandlers): def _update_status(self, show, msg, idle_time=None): xmpp_show = helpers.get_xmpp_show(show) priority = app.get_priority(self.name, xmpp_show) - signed = self.get_signed_presence(msg) self.get_module('Presence').send_presence( priority=priority, show=xmpp_show, status=msg, - sign=signed, idle_time=idle_time) if self.connection: @@ -1862,7 +1754,7 @@ class Connection(CommonConnection, ConnectionHandlers): def send_gc_message(self, obj): obj.stanza_id = self.connection.send(obj.msg_iq) app.nec.push_incoming_event(MessageSentEvent( - None, conn=self, jid=obj.jid, message=obj.message, keyID=None, + None, conn=self, jid=obj.jid, message=obj.message, automatic_message=obj.automatic_message, stanza_id=obj.stanza_id, additional_data=obj.additional_data)) diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 901deebea..d3c4d1978 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -153,15 +153,6 @@ class NewAccountConnectedEvent(nec.NetworkIncomingEvent): class NewAccountNotConnectedEvent(nec.NetworkIncomingEvent): name = 'new-account-not-connected' -class BadGPGPassphraseEvent(nec.NetworkIncomingEvent): - name = 'bad-gpg-passphrase' - - def generate(self): - self.account = self.conn.name - self.use_gpg_agent = app.config.get('use_gpg_agent') - self.keyID = app.config.get_per('accounts', self.conn.name, 'keyid') - return True - class ConnectionLostEvent(nec.NetworkIncomingEvent): name = 'connection-lost' @@ -170,13 +161,6 @@ class ConnectionLostEvent(nec.NetworkIncomingEvent): show='offline')) return True -class GPGPasswordRequiredEvent(nec.NetworkIncomingEvent): - name = 'gpg-password-required' - - def generate(self): - self.keyid = app.config.get_per('accounts', self.conn.name, 'keyid') - return True - class FileRequestReceivedEvent(nec.NetworkIncomingEvent): name = 'file-request-received' @@ -610,7 +594,6 @@ class MessageOutgoingEvent(nec.NetworkOutgoingEvent): def init(self): self.additional_data = AdditionalDataDict() self.message = None - self.keyID = None self.type_ = 'chat' self.kind = None self.timestamp = None diff --git a/gajim/common/const.py b/gajim/common/const.py index 8f6b4ca23..3ad4ccfff 100644 --- a/gajim/common/const.py +++ b/gajim/common/const.py @@ -23,7 +23,6 @@ class OptionKind(IntEnum): PRIORITY = 9 FILECHOOSER = 10 CHANGEPASSWORD = 11 - GPG = 12 @unique diff --git a/gajim/common/contacts.py b/gajim/common/contacts.py index 45420850c..16516de29 100644 --- a/gajim/common/contacts.py +++ b/gajim/common/contacts.py @@ -137,7 +137,7 @@ class Contact(CommonContact): Information concerning a contact """ def __init__(self, jid, account, name='', groups=None, show='', status='', - sub='', ask='', resource='', priority=0, keyID='', client_caps=None, + sub='', ask='', resource='', priority=0, client_caps=None, chatstate=None, idle_time=None, avatar_sha=None, groupchat=False, is_pm_contact=False): if not isinstance(jid, str): @@ -159,7 +159,6 @@ class Contact(CommonContact): self.ask = ask self.priority = priority - self.keyID = keyID self.idle_time = idle_time self.pep = {} @@ -306,7 +305,7 @@ class LegacyContactsAPI: self._metacontact_manager.remove_account(account) def create_contact(self, jid, account, name='', groups=None, show='', - status='', sub='', ask='', resource='', priority=0, keyID='', + status='', sub='', ask='', resource='', priority=0, client_caps=None, chatstate=None, idle_time=None, avatar_sha=None, groupchat=False): if groups is None: @@ -315,36 +314,36 @@ class LegacyContactsAPI: account = self._accounts.get(account, account) return Contact(jid=jid, account=account, name=name, groups=groups, show=show, status=status, sub=sub, ask=ask, resource=resource, - priority=priority, keyID=keyID, client_caps=client_caps, + priority=priority, client_caps=client_caps, chatstate=chatstate, idle_time=idle_time, avatar_sha=avatar_sha, groupchat=groupchat) def create_self_contact(self, jid, account, resource, show, status, priority, - name='', keyID=''): + name=''): conn = common.app.connections[account] nick = name or common.app.nicks[account] account = self._accounts.get(account, account) # Use Account object if available self_contact = self.create_contact(jid=jid, account=account, name=nick, groups=['self_contact'], show=show, status=status, - sub='both', ask='none', priority=priority, keyID=keyID, + sub='both', ask='none', priority=priority, resource=resource) self_contact.pep = conn.pep return self_contact def create_not_in_roster_contact(self, jid, account, resource='', name='', - keyID='', groupchat=False): + groupchat=False): # Use Account object if available account = self._accounts.get(account, account) return self.create_contact(jid=jid, account=account, resource=resource, name=name, groups=[_('Not in Roster')], show='not in roster', - status='', sub='none', keyID=keyID, groupchat=groupchat) + status='', sub='none', groupchat=groupchat) def copy_contact(self, contact): return self.create_contact(contact.jid, contact.account, name=contact.name, groups=contact.groups, show=contact.show, status=contact.status, sub=contact.sub, ask=contact.ask, resource=contact.resource, priority=contact.priority, - keyID=contact.keyID, client_caps=contact.client_caps, + client_caps=contact.client_caps, chatstate=contact.chatstate_enum, idle_time=contact.idle_time, avatar_sha=contact.avatar_sha) diff --git a/gajim/common/gpg.py b/gajim/common/gpg.py deleted file mode 100644 index efd023940..000000000 --- a/gajim/common/gpg.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright (C) 2003-2014 Yann Leboulanger -# Copyright (C) 2005 Alex Mauer -# Copyright (C) 2005-2006 Nikos Kouremenos -# Copyright (C) 2007 Stephan Erb -# Copyright (C) 2008 Jean-Marie Traissard -# Jonathan Schleifer -# -# This file is part of Gajim. -# -# Gajim 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; version 3 only. -# -# Gajim 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 Gajim. If not, see . - -import os -from gajim.common import app - -if app.is_installed('GPG'): - import gnupg - - class GnuPG(gnupg.GPG): - def __init__(self): - use_agent = app.config.get('use_gpg_agent') - gnupg.GPG.__init__(self, gpgbinary=app.get_gpg_binary(), use_agent=use_agent) - encoding = app.config.get('pgp_encoding') - if encoding: - self.encoding = encoding - self.decode_errors = 'replace' - self.passphrase = None - self.always_trust = [] # list of keyID to always trust - - def encrypt(self, str_, recipients, always_trust=False): - trust = always_trust - if not trust: - # check if we trust all keys - trust = True - for key in recipients: - if key not in self.always_trust: - trust = False - if not trust: - # check that we'll be able to encrypt - result = super(GnuPG, self).list_keys(keys=recipients) - for key in result: - if key['trust'] not in ('f', 'u'): - if key['keyid'][-8:] not in self.always_trust: - return '', 'NOT_TRUSTED ' + key['keyid'][-8:] - trust = True - result = super(GnuPG, self).encrypt(str_.encode('utf8'), recipients, - always_trust=trust, passphrase=self.passphrase) - - if result.ok: - error = '' - else: - error = result.status - - return self._stripHeaderFooter(str(result)), error - - def decrypt(self, str_, keyID): - data = self._addHeaderFooter(str_, 'MESSAGE') - result = super(GnuPG, self).decrypt(data.encode('utf8'), - passphrase=self.passphrase) - - return result.data.decode('utf8') - - def sign(self, str_, keyID): - result = super(GnuPG, self).sign(str_.encode('utf8'), keyid=keyID, detach=True, - passphrase=self.passphrase) - - if result.fingerprint: - return self._stripHeaderFooter(str(result)) - if hasattr(result, 'status') and result.status == 'key expired': - return 'KEYEXPIRED' - return 'BAD_PASSPHRASE' - - def verify(self, str_, sign): - if str_ is None: - return '' - # Hash algorithm is not transfered in the signed presence stanza so try - # all algorithms. Text name for hash algorithms from RFC 4880 - section 9.4 - hash_algorithms = ['SHA512', 'SHA384', 'SHA256', 'SHA224', 'SHA1', 'RIPEMD160'] - for algo in hash_algorithms: - data = os.linesep.join( - ['-----BEGIN PGP SIGNED MESSAGE-----', - 'Hash: ' + algo, - '', - str_, - self._addHeaderFooter(sign, 'SIGNATURE')] - ) - result = super(GnuPG, self).verify(data.encode('utf8')) - if result.valid: - return result.key_id - - return '' - - def get_key(self, keyID): - return super(GnuPG, self).list_keys(keys=[keyID]) - - def get_keys(self, secret=False): - keys = {} - result = super(GnuPG, self).list_keys(secret=secret) - - for key in result: - # Take first not empty uid - keys[key['keyid'][8:]] = [uid for uid in key['uids'] if uid][0] - return keys - - def get_secret_keys(self): - return self.get_keys(True) - - def _stripHeaderFooter(self, data): - """ - Remove header and footer from data - """ - if not data: - return '' - lines = data.splitlines() - while lines[0] != '': - lines.remove(lines[0]) - while lines[0] == '': - lines.remove(lines[0]) - i = 0 - for line in lines: - if line: - if line[0] == '-': - break - i = i+1 - line = '\n'.join(lines[0:i]) - return line - - def _addHeaderFooter(self, data, type_): - """ - Add header and footer from data - """ - out = "-----BEGIN PGP %s-----" % type_ + os.linesep - out = out + "Version: PGP" + os.linesep - out = out + os.linesep - out = out + data + os.linesep - out = out + "-----END PGP %s-----" % type_ + os.linesep - return out diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index f57dd6d01..5aad753ba 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -1108,54 +1108,6 @@ def get_current_show(account): status = app.connections[account].connected return app.SHOW_LIST[status] -def prepare_and_validate_gpg_keyID(account, jid, keyID): - """ - Return an eight char long keyID that can be used with for GPG encryption - with this contact - - If the given keyID is None, return UNKNOWN; if the key does not match the - assigned key XXXXXXXXMISMATCH is returned. If the key is trusted and not yet - assigned, assign it. - """ - if app.connections[account].USE_GPG: - if keyID and len(keyID) == 16: - keyID = keyID[8:] - - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - - if jid in attached_keys and keyID: - attachedkeyID = attached_keys[attached_keys.index(jid) + 1] - if attachedkeyID != keyID: - # Get signing subkeys for the attached key - subkeys = [] - for key in app.connections[account].gpg.list_keys(): - if key['keyid'][8:] == attachedkeyID: - subkeys = [subkey[0][8:] for subkey in key['subkeys'] \ - if subkey[1] == 's'] - break - - if keyID not in subkeys: - # Mismatch! Another gpg key was expected - keyID += 'MISMATCH' - elif jid in attached_keys: - # An unsigned presence, just use the assigned key - keyID = attached_keys[attached_keys.index(jid) + 1] - elif keyID: - full_key = app.connections[account].ask_gpg_keys(keyID=keyID) - # Assign the corresponding key, if we have it in our keyring - if full_key: - for u in app.contacts.get_contacts(account, jid): - u.keyID = keyID - keys_str = app.config.get_per('accounts', account, - 'attached_gpg_keys') - keys_str += jid + ' ' + keyID + ' ' - app.config.set_per('accounts', account, 'attached_gpg_keys', - keys_str) - elif keyID is None: - keyID = 'UNKNOWN' - return keyID - def update_optional_features(account=None): if account is not None: accounts = [account] diff --git a/gajim/common/modules/httpupload.py b/gajim/common/modules/httpupload.py index 46f1789bc..6bb3cb616 100644 --- a/gajim/common/modules/httpupload.py +++ b/gajim/common/modules/httpupload.py @@ -329,7 +329,7 @@ class HTTPUpload(BaseModule): else: app.nec.push_outgoing_event(MessageOutgoingEvent( None, account=self._account, jid=file.contact.jid, - message=message, keyID=file.key_id, type_='chat', + message=message, type_='chat', automatic_message=False, session=file.session)) else: @@ -353,9 +353,6 @@ class File: setattr(self, key, val) self.encrypted = False self.contact = contact - self.key_id = None - if hasattr(contact, 'keyID'): - self.key_id = contact.keyID self.stream = None self.path = path self.put = None diff --git a/gajim/common/modules/presence.py b/gajim/common/modules/presence.py index b4ba0102e..d9ea98c1e 100644 --- a/gajim/common/modules/presence.py +++ b/gajim/common/modules/presence.py @@ -25,7 +25,6 @@ from gajim.common.i18n import _ from gajim.common.nec import NetworkEvent from gajim.common.const import KindConstant from gajim.common.const import ShowConstant -from gajim.common.helpers import prepare_and_validate_gpg_keyID from gajim.common.modules.base import BaseModule @@ -94,12 +93,6 @@ class Presence(BaseModule): self._log.warning(stanza) return - key_id = '' - if properties.signed is not None and self._con.USE_GPG: - key_id = self._con.gpg.verify(properties.status, properties.signed) - key_id = prepare_and_validate_gpg_keyID( - self._account, properties.jid.getBare(), key_id) - show = properties.show.value if properties.type.is_unavailable: show = 'offline' @@ -107,7 +100,6 @@ class Presence(BaseModule): event_attrs = { 'conn': self._con, 'stanza': stanza, - 'keyID': key_id, 'prio': properties.priority, 'need_add_in_roster': False, 'popup': False, @@ -185,13 +177,6 @@ class Presence(BaseModule): contact.show = event.show contact.status = properties.status contact.priority = properties.priority - attached_keys = app.config.get_per('accounts', self._account, - 'attached_gpg_keys').split() - if jid in attached_keys: - contact.keyID = attached_keys[attached_keys.index(jid) + 1] - else: - # Do not override assigned key - contact.keyID = event.keyID contact.idle_time = properties.idle_timestamp event.contact = contact @@ -355,7 +340,7 @@ class Presence(BaseModule): def get_presence(self, to=None, typ=None, priority=None, show=None, status=None, nick=None, caps=True, - sign=None, idle_time=None): + idle_time=None): if show not in ('chat', 'away', 'xa', 'dnd'): # Gajim sometimes passes invalid show values here # until this is fixed this is a workaround @@ -365,9 +350,6 @@ class Presence(BaseModule): nick_tag = presence.setTag('nick', namespace=nbxmpp.NS_NICK) nick_tag.setData(nick) - if sign: - presence.setTag(nbxmpp.NS_SIGNED + ' x').setData(sign) - if idle_time is not None: idle_node = presence.setTag('idle', namespace=nbxmpp.NS_IDLE) idle_node.setAttr('since', idle_time) diff --git a/gajim/common/zeroconf/connection_zeroconf.py b/gajim/common/zeroconf/connection_zeroconf.py index 8a780740b..cdd8a6f70 100644 --- a/gajim/common/zeroconf/connection_zeroconf.py +++ b/gajim/common/zeroconf/connection_zeroconf.py @@ -156,7 +156,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): def _on_remove_service(self, jid): self.roster.delItem(jid) # 'NOTIFY' (account, (jid, status, status message, resource, priority, - # keyID, timestamp)) + # timestamp)) self._on_presence(jid, show='offline', status='') def _on_presence(self, jid, show=None, status=None): @@ -169,7 +169,6 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): event_attrs = { 'conn': self, - 'keyID': None, 'prio': 0, 'need_add_in_roster': False, 'popup': False, @@ -216,13 +215,6 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): contact.show = event.show contact.status = event.status contact.priority = event.prio - attached_keys = app.config.get_per('accounts', self.name, - 'attached_gpg_keys').split() - if jid in attached_keys: - contact.keyID = attached_keys[attached_keys.index(jid) + 1] - else: - # Do not override assigned key - contact.keyID = event.keyID contact.idle_time = event.idle_time event.contact = contact @@ -363,7 +355,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): else: self.reannounce() - def connect_and_init(self, show, msg, sign_msg): + def connect_and_init(self, show, msg): # to check for errors from zeroconf check = True if not self.connect(show, msg): diff --git a/gajim/data/gui/choose_gpg_key_dialog.ui b/gajim/data/gui/choose_gpg_key_dialog.ui deleted file mode 100644 index 7a6c2f0ad..000000000 --- a/gajim/data/gui/choose_gpg_key_dialog.ui +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - False - 6 - 550 - 300 - dialog - - - True - False - vertical - 6 - - - True - False - end - - - gtk-cancel - True - True - True - False - True - - - False - False - 0 - - - - - gtk-ok - True - True - True - True - False - True - - - False - False - 1 - - - - - False - False - end - 0 - - - - - True - False - 6 - vertical - 6 - - - True - False - 0 - - - False - False - 0 - - - - - True - True - in - - - True - True - - - - - - - - True - True - 1 - - - - - True - True - 2 - - - - - - button26 - button27 - - - diff --git a/gajim/data/gui/contact_context_menu.ui b/gajim/data/gui/contact_context_menu.ui index 96522d17a..891211169 100644 --- a/gajim/data/gui/contact_context_menu.ui +++ b/gajim/data/gui/contact_context_menu.ui @@ -1,5 +1,5 @@ - + @@ -100,14 +100,6 @@ True - - - False - Assign Open_PGP Key... - True - - - False diff --git a/gajim/data/gui/tooltip_roster_contact.ui b/gajim/data/gui/tooltip_roster_contact.ui index 1ce0c1132..e51db35f3 100644 --- a/gajim/data/gui/tooltip_roster_contact.ui +++ b/gajim/data/gui/tooltip_roster_contact.ui @@ -182,32 +182,6 @@ 9 - - - True - False - end - start - OpenPGP: - - - 0 - 10 - - - - - True - False - start - start - True - - - 1 - 10 - - True @@ -300,5 +274,11 @@ + + + + + + diff --git a/gajim/dialogs.py b/gajim/dialogs.py index 95ae1ad06..2a78bd554 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -284,73 +284,6 @@ class PassphraseDialog: if self.cancel_handler and not self.ok: self.cancel_handler() -class ChooseGPGKeyDialog: - """ - Class for GPG key dialog - """ - - def __init__(self, title_text, prompt_text, secret_keys, on_response, - selected=None, transient_for=None): - '''secret_keys : {keyID: userName, ...}''' - self.on_response = on_response - xml = get_builder('choose_gpg_key_dialog.ui') - self.window = xml.get_object('choose_gpg_key_dialog') - self.window.set_title(title_text) - self.window.set_transient_for(transient_for) - self.keys_treeview = xml.get_object('keys_treeview') - prompt_label = xml.get_object('prompt_label') - prompt_label.set_text(prompt_text) - model = Gtk.ListStore(str, str) - model.set_sort_func(1, self.sort_keys) - model.set_sort_column_id(1, Gtk.SortType.ASCENDING) - self.keys_treeview.set_model(model) - #columns - renderer = Gtk.CellRendererText() - self.keys_treeview.insert_column_with_attributes(-1, _('KeyID'), - renderer, text=0) - col = self.keys_treeview.get_column(0) - col.set_sort_column_id(0) - renderer = Gtk.CellRendererText() - self.keys_treeview.insert_column_with_attributes(-1, _('Contact name'), - renderer, text=1) - col = self.keys_treeview.get_column(1) - col.set_sort_column_id(1) - self.keys_treeview.set_search_column(1) - self.fill_tree(secret_keys, selected) - self.window.connect('response', self.on_dialog_response) - self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) - self.window.show_all() - - def sort_keys(self, model, iter1, iter2, data=None): - value1 = model[iter1][1] - value2 = model[iter2][1] - if value1 == _('None'): - return -1 - if value2 == _('None'): - return 1 - if value1 < value2: - return -1 - return 1 - - def on_dialog_response(self, dialog, response): - selection = self.keys_treeview.get_selection() - (model, iter_) = selection.get_selected() - if iter_ and response == Gtk.ResponseType.OK: - keyID = [model[iter_][0], model[iter_][1]] - else: - keyID = None - self.on_response(keyID) - self.window.destroy() - - def fill_tree(self, list_, selected): - model = self.keys_treeview.get_model() - for keyID in list_.keys(): - iter_ = model.append((keyID, list_[keyID])) - if keyID == selected: - path = model.get_path(iter_) - self.keys_treeview.set_cursor(path) - - class ChangeActivityDialog: PAGELIST = [ 'doing_chores', 'drinking', 'eating', 'exercising', 'grooming', diff --git a/gajim/gajim_remote.py b/gajim/gajim_remote.py index 32e2d2a61..6db2fd90e 100644 --- a/gajim/gajim_remote.py +++ b/gajim/gajim_remote.py @@ -115,28 +115,21 @@ class GajimRemote: ] ], 'send_chat_message': [ - _('Sends new chat message to a contact in the roster. Both OpenPGP key ' - 'and account are optional. If you want to set only \'account\', ' - 'without \'OpenPGP key\', just set \'OpenPGP key\' to \'\'.'), + _('Sends new chat message to a contact in the roster. Account is optional.'), [ ('jid', _('JID of the contact that will receive the message'), True), (Q_('?CLI:message'), _('message contents'), True), - (_('PGP key'), _('if specified, the message will be encrypted ' - 'using this public key'), False), (Q_('?CLI:account'), _('if specified, the message will be sent ' 'using this account'), False), ] ], 'send_single_message': [ _('Sends a chat message to someone on your roster. ' - 'Optionally with OpenPGP key and account. If you want ' - 'to only set the latter, set OpenPGP key to "".'), + 'Account is optional.'), [ ('jid', _('JID of the contact that will receive the message'), True), (_('subject'), _('message subject'), True), (Q_('?CLI:message'), _('message contents'), True), - (_('PGP key'), _('if specified, the message will be encrypted ' - 'using this public key'), False), (Q_('?CLI:account'), _('if specified, the message will be sent ' 'using this account'), False), ] diff --git a/gajim/gtk/account_wizard.py b/gajim/gtk/account_wizard.py index 5c6d7d64e..06d8ece7a 100644 --- a/gajim/gtk/account_wizard.py +++ b/gajim/gtk/account_wizard.py @@ -537,8 +537,6 @@ class AccountCreationWizard: config['use_custom_host'] = False config['custom_port'] = 0 config['custom_host'] = '' - config['keyname'] = '' - config['keyid'] = '' return config def save_account(self, login, server, savepass, password, anonymous=False): diff --git a/gajim/gtk/accounts.py b/gajim/gtk/accounts.py index 8ba9f9009..a688a184b 100644 --- a/gajim/gtk/accounts.py +++ b/gajim/gtk/accounts.py @@ -183,11 +183,10 @@ class AccountsWindow(Gtk.ApplicationWindow): def get_relogin_options(account): if account == app.ZEROCONF_ACC_NAME: options = ['zeroconf_first_name', 'zeroconf_last_name', - 'zeroconf_jabber_id', 'zeroconf_email', 'keyid'] + 'zeroconf_jabber_id', 'zeroconf_email'] else: options = ['client_cert', 'proxy', 'resource', - 'use_custom_host', 'custom_host', 'custom_port', - 'keyid'] + 'use_custom_host', 'custom_host', 'custom_port'] values = [] for option in options: @@ -567,9 +566,6 @@ class PreferencesPage(GenericOptionPage): options = [ Option(OptionKind.SWITCH, _('Merge Accounts'), OptionType.ACTION, 'merge'), - - Option(OptionKind.SWITCH, _('Use PGP Agent'), - OptionType.ACTION, 'agent'), ] GenericOptionPage.__init__(self, None, None, options) @@ -605,9 +601,6 @@ class AccountPage(GenericOptionPage): Option(OptionKind.DIALOG, _('Client Certificate'), OptionType.DIALOG, props={'dialog': CertificateDialog}), - - Option(OptionKind.GPG, _('OpenPGP Key'), OptionType.DIALOG, - props={'dialog': None}), ] GenericOptionPage.__init__(self, account, parent, options) @@ -704,9 +697,6 @@ class ZeroConfPage(GenericOptionPage): Option(OptionKind.SWITCH, _('Global Status'), OptionType.ACCOUNT_CONFIG, 'sync_with_global_status', desc=_('Synchronize the status of all accounts')), - - Option(OptionKind.GPG, _('OpenPGP Key'), - OptionType.DIALOG, props={'dialog': None}), ] GenericOptionPage.__init__(self, account, parent, options) diff --git a/gajim/gtk/features.py b/gajim/gtk/features.py index 9f8ed0979..34c345049 100644 --- a/gajim/gtk/features.py +++ b/gajim/gtk/features.py @@ -112,13 +112,6 @@ class FeaturesDialog(Gtk.Dialog): _('Requires: pybonjour and bonjour SDK running (%(url)s)') % {'url': 'https://developer.apple.com/opensource/)'}, None), - Feature(_('OpenPGP Message Encryption'), - app.is_installed('GPG'), - _('Enables Gajim to encrypt chat messages with OpenPGP'), - _('Requires: gpg and python-gnupg (%(url)s)') - % {'url': 'https://bitbucket.org/vinay.sajip/python-gnupg'}, - _('Requires: gpg.exe in your PATH environment variable'), - None), Feature(_('RST XHTML Generator'), self.docutils_available(), _('Enables Gajim to generate XHTML output from RST ' diff --git a/gajim/gtk/tooltips.py b/gajim/gtk/tooltips.py index 59c50a173..9466f32d1 100644 --- a/gajim/gtk/tooltips.py +++ b/gajim/gtk/tooltips.py @@ -335,9 +335,7 @@ class RosterTooltip(StatusTable): status=connection.status, resource=connection.server_resource, priority=connection.priority) - if app.connections[account].gpg: - contact.keyID = app.config.get_per( - 'accounts', connection.name, 'keyid') + contacts.append(contact) # Username/Account/Groupchat @@ -438,17 +436,6 @@ class RosterTooltip(StatusTable): self._ui.sub.show() self._ui.sub_label.show() - if self.prim_contact.keyID: - key_id = None - if len(self.prim_contact.keyID) == 8: - key_id = self.prim_contact.keyID - elif len(self.prim_contact.keyID) == 16: - key_id = self.prim_contact.keyID[8:] - if key_id: - self._ui.pgp.set_text(key_id) - self._ui.pgp.show() - self._ui.pgp_label.show() - self._set_idle_time(contact) # Avatar diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index d206d817e..6eb47f96e 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -230,9 +230,7 @@ class Interface: if name in self.instances[account]['online_dialog']: # destroy handler may have already removed it del self.instances[account]['online_dialog'][name] - for request in self.gpg_passphrase.values(): - if request: - request.interrupt(account=account) + if account in self.pass_dialog: self.pass_dialog[account].window.destroy() if obj.show == 'offline': @@ -306,7 +304,7 @@ class Interface: def handle_event_presence(self, obj): # 'NOTIFY' (account, (jid, status, status message, resource, - # priority, # keyID, timestamp)) + # priority, timestamp)) # # Contact changed show account = obj.conn.name @@ -390,7 +388,7 @@ class Interface: @staticmethod def handle_event_msgsent(obj): - #('MSGSENT', account, (jid, msg, keyID)) + #('MSGSENT', account, (jid, msg)) # do not play sound when standalone chatstate message (eg no msg) if obj.message and app.config.get_per('soundevents', 'message_sent', 'enabled'): @@ -438,16 +436,11 @@ class Interface: self.roster.remove_contact_from_groups(c.jid, account, [_('Not in Roster'), _('Observers')], update=False) else: - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if obj.jid in attached_keys: - keyID = attached_keys[attached_keys.index(obj.jid) + 1] name = obj.jid.split('@', 1)[0] name = name.split('%', 1)[0] contact1 = app.contacts.create_contact(jid=obj.jid, account=account, name=name, groups=[], show='online', - status='online', ask='to', resource=obj.resource, keyID=keyID) + status='online', ask='to', resource=obj.resource) app.contacts.add_contact(account, contact1) self.roster.add_contact(obj.jid, account) InformationDialog(_('Authorization accepted'), @@ -571,28 +564,6 @@ class Interface: text, room_jid=muc) - def forget_gpg_passphrase(self, keyid): - if keyid in self.gpg_passphrase: - del self.gpg_passphrase[keyid] - return False - - def handle_event_bad_gpg_passphrase(self, obj): - #('BAD_PASSPHRASE', account, ()) - if obj.use_gpg_agent: - sectext = _('You configured Gajim to use OpenPGP agent, but there ' - 'is no OpenPGP agent running or it returned a wrong passphrase.' - '\n') - sectext += _('You are currently connected without your OpenPGP ' - 'key.') - WarningDialog(_('Wrong passphrase'), sectext) - else: - account = obj.conn.name - app.notification.popup( - 'warning', account, account, '', 'dialog-warning', - _('Wrong OpenPGP passphrase'), - _('You are currently connected without your OpenPGP key.')) - self.forget_gpg_passphrase(obj.keyID) - @staticmethod def handle_event_client_cert_passphrase(obj): def on_ok(passphrase, checked): @@ -607,15 +578,6 @@ class Interface: _('Enter the certificate passphrase for account %s') % \ obj.conn.name, ok_handler=on_ok, cancel_handler=on_cancel) - def handle_event_gpg_password_required(self, obj): - #('GPG_PASSWORD_REQUIRED', account, (callback,)) - if obj.keyid in self.gpg_passphrase: - request = self.gpg_passphrase[obj.keyid] - else: - request = PassphraseRequest(obj.keyid) - self.gpg_passphrase[obj.keyid] = request - request.add_callback(obj.conn.name, obj.callback) - def handle_event_password_required(self, obj): #('PASSWORD_REQUIRED', account, None) account = obj.conn.name @@ -652,14 +614,10 @@ class Interface: if obj.sub == 'remove': return # Add new contact to roster - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if obj.jid in attached_keys: - keyID = attached_keys[attached_keys.index(obj.jid) + 1] + contact = app.contacts.create_contact(jid=obj.jid, account=account, name=obj.nickname, groups=obj.groups, - show='offline', sub=obj.sub, ask=obj.ask, keyID=keyID, + show='offline', sub=obj.sub, ask=obj.ask, avatar_sha=obj.avatar_sha) app.contacts.add_contact(account, contact) self.roster.add_contact(obj.jid, account) @@ -750,13 +708,8 @@ class Interface: def handle_event_file_request(self, obj): account = obj.conn.name if obj.jid not in app.contacts.get_jid_list(account): - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if obj.jid in attached_keys: - keyID = attached_keys[attached_keys.index(obj.jid) + 1] contact = app.contacts.create_not_in_roster_contact(jid=obj.jid, - account=account, keyID=keyID) + account=account) app.contacts.add_contact(account, contact) self.roster.add_contact(obj.jid, account) contact = app.contacts.get_first_contact_from_jid(account, obj.jid) @@ -1287,7 +1240,6 @@ class Interface: self.handlers = { 'DB_ERROR': [self.handle_event_db_error], 'file-send-error': [self.handle_event_file_send_error], - 'bad-gpg-passphrase': [self.handle_event_bad_gpg_passphrase], 'bookmarks-received': [self.handle_event_bookmarks], 'client-cert-passphrase': [ self.handle_event_client_cert_passphrase], @@ -1296,7 +1248,6 @@ class Interface: 'file-request-received': [self.handle_event_file_request], 'muc-invitation': [self.handle_event_gc_invitation], 'muc-decline': [self.handle_event_gc_decline], - 'gpg-password-required': [self.handle_event_gpg_password_required], 'http-auth-received': [self.handle_event_http_auth], 'information': [self.handle_event_information], 'iq-error-received': [self.handle_event_iq_error], @@ -2326,7 +2277,6 @@ class Interface: self.minimized_controls = {} self.status_sent_to_users = {} self.status_sent_to_groups = {} - self.gpg_passphrase = {} self.pass_dialog = {} self.db_error_dialog = None @@ -2492,89 +2442,6 @@ class Interface: self.network_state = self.network_monitor.get_network_available() -class PassphraseRequest: - def __init__(self, keyid): - self.keyid = keyid - self.callbacks = [] - self.dialog_created = False - self.dialog = None - self.passphrase = None - self.completed = False - - def interrupt(self, account=None): - if account: - for (acct, cb) in self.callbacks: - if acct == account: - self.callbacks.remove((acct, cb)) - else: - self.callbacks = [] - if not self.callbacks: - self.dialog.window.destroy() - - def run_callback(self, account, callback): - app.connections[account].gpg_passphrase(self.passphrase) - callback() - - def add_callback(self, account, cb): - if self.completed: - self.run_callback(account, cb) - else: - self.callbacks.append((account, cb)) - if not self.dialog_created: - self.create_dialog(account) - - def complete(self, passphrase): - self.passphrase = passphrase - self.completed = True - if passphrase is not None: - GLib.timeout_add_seconds(30, app.interface.forget_gpg_passphrase, - self.keyid) - for (account, cb) in self.callbacks: - self.run_callback(account, cb) - self.callbacks = [] - - def create_dialog(self, account): - title = _('Passphrase Required') - second = _('Enter OpenPGP key passphrase for key %(keyid)s ' - '(account %(account)s).') % {'keyid': self.keyid, - 'account': account} - - def _cancel(): - # user cancelled, continue without GPG - self.complete(None) - - def _ok(passphrase, checked, count): - result = app.connections[account].test_gpg_passphrase(passphrase) - if result == 'ok': - # passphrase is good - self.complete(passphrase) - return - - if result == 'expired': - ErrorDialog( - _('OpenPGP key expired'), - _('Your OpenPGP key has expired, you will be connected to ' - '%s without OpenPGP.') % account) - # Don't try to connect with GPG - app.connections[account].continue_connect_info[2] = False - self.complete(None) - return - - if count < 3: - # ask again - dialogs.PassphraseDialog( - _('Wrong Passphrase'), - _('Please retype your OpenPGP passphrase or press Cancel.'), - ok_handler=(_ok, count + 1), cancel_handler=_cancel) - else: - # user failed 3 times, continue without GPG - self.complete(None) - - self.dialog = dialogs.PassphraseDialog( - title, second, ok_handler=(_ok, 1), cancel_handler=_cancel) - self.dialog_created = True - - class ThreadInterface: def __init__(self, func, func_args=(), callback=None, callback_args=()): """ diff --git a/gajim/gui_menu_builder.py b/gajim/gui_menu_builder.py index a227fd68d..013284a27 100644 --- a/gajim/gui_menu_builder.py +++ b/gajim/gui_menu_builder.py @@ -217,7 +217,6 @@ control=None, gc_contact=None, is_anonymous=True): rename_menuitem = xml.get_object('rename_menuitem') edit_groups_menuitem = xml.get_object('edit_groups_menuitem') send_file_menuitem = xml.get_object('send_file_menuitem') - assign_openpgp_key_menuitem = xml.get_object('assign_openpgp_key_menuitem') information_menuitem = xml.get_object('information_menuitem') history_menuitem = xml.get_object('history_menuitem') send_custom_status_menuitem = xml.get_object('send_custom_status_menuitem') @@ -290,16 +289,9 @@ control=None, gc_contact=None, is_anonymous=True): # contact is in normal group edit_groups_menuitem.connect('activate', roster.on_edit_groups, [(contact, account)]) - - if app.connections[account].gpg: - assign_openpgp_key_menuitem.connect('activate', - roster.on_assign_pgp_key, contact, account) - else: - assign_openpgp_key_menuitem.set_sensitive(False) else: # contact is in group 'Not in Roster' edit_groups_menuitem.set_sensitive(False) - assign_openpgp_key_menuitem.set_sensitive(False) # Hide items when it's self contact row if our_jid: diff --git a/gajim/options_dialog.py b/gajim/options_dialog.py index e91dccbf5..b5d5cefd5 100644 --- a/gajim/options_dialog.py +++ b/gajim/options_dialog.py @@ -5,8 +5,6 @@ from gajim.common.i18n import _ from gajim import gtkgui_helpers from gajim.common.const import OptionKind, OptionType from gajim.common.exceptions import GajimGeneralException -from gajim import dialogs -from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.dialogs import ChangePasswordDialog from gajim.gtk.util import get_image_button @@ -74,7 +72,6 @@ class OptionsBox(Gtk.ListBox): OptionKind.PRIORITY: PriorityOption, OptionKind.HOSTNAME: CutstomHostnameOption, OptionKind.CHANGEPASSWORD: ChangePasswordOption, - OptionKind.GPG: GPGOption, } if extend is not None: @@ -566,55 +563,3 @@ class ChangePasswordOption(DialogOption): con = app.connections[self.account] activatable = con.connected >= 2 and con.register_supported self.get_parent().set_activatable(activatable) - - -class GPGOption(DialogOption): - def __init__(self, *args, **kwargs): - DialogOption.__init__(self, *args, **kwargs) - - def show_dialog(self, parent): - secret_keys = app.connections[self.account].ask_gpg_secrete_keys() - secret_keys[_('None')] = _('None') - - if not secret_keys: - ErrorDialog( - _('Failed to get secret keys'), - _('There is no OpenPGP secret key available.'), - transient_for=parent) - return - - dialog = dialogs.ChooseGPGKeyDialog( - _('OpenPGP Key Selection'), _('Choose your OpenPGP key'), - secret_keys, self.on_key_selected, transient_for=parent) - dialog.window.connect('destroy', self.on_destroy) - - def on_key_selected(self, keyID): - if keyID is None: - return - keyid_new, keyname_new = keyID - - keyid = app.config.get_per('accounts', self.account, 'keyid') - - if keyid_new == _('None'): - if keyid == '': - return - app.config.set_per('accounts', self.account, 'keyname', '') - app.config.set_per('accounts', self.account, 'keyid', '') - else: - if keyid == keyid_new: - return - app.config.set_per( - 'accounts', self.account, 'keyname', keyname_new) - app.config.set_per( - 'accounts', self.account, 'keyid', keyid_new) - - def get_option_value(self): - keyid = app.config.get_per('accounts', self.account, 'keyid') - keyname = app.config.get_per('accounts', self.account, 'keyname') - if keyid is not None: - return '\n'.join((keyid, keyname)) - return '' - - def set_activatable(self, name, value): - active = self.account in app.connections - self.get_parent().set_activatable(app.is_installed('GPG') and active) diff --git a/gajim/remote_control.py b/gajim/remote_control.py index ca1ee742a..987581755 100644 --- a/gajim/remote_control.py +++ b/gajim/remote_control.py @@ -194,7 +194,6 @@ class GajimRemote(Server): - @@ -214,7 +213,6 @@ class GajimRemote(Server): - @@ -339,7 +337,7 @@ class GajimRemote(Server): except AttributeError: chatstate = '' self.raise_signal('MessageSent', (obj.conn.name, [ - obj.jid, obj.message, obj.keyID, chatstate])) + obj.jid, obj.message, chatstate])) def on_time(self, obj): self.raise_signal('EntityTime', (obj.conn.name, [obj.jid.getStripped(), @@ -360,7 +358,7 @@ class GajimRemote(Server): else: return self.raise_signal(event, (obj.conn.name, [obj.jid, obj.show, - obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp])) + obj.status, obj.resource, obj.prio, obj.timestamp])) def on_subscribe_presence_received(self, obj): self.raise_signal('Subscribe', (obj.conn.name, [obj.jid, obj.status, @@ -504,7 +502,6 @@ class GajimRemote(Server): def _send_message(self, jid, message, - keyID, account, type_='chat', subject=None): @@ -514,8 +511,6 @@ class GajimRemote(Server): """ if not jid or not message: return False - if not keyID: - keyID = '' connected_account = self._get_account_and_contact(account, jid)[0] if connected_account: @@ -534,29 +529,25 @@ class GajimRemote(Server): account=connected_account, jid=jid, message=message, - keyID=keyID, type_=type_, control=ctrl)) return True return False - def send_chat_message(self, jid, message, keyID, account): + def send_chat_message(self, jid, message, account): """ - Send chat 'message' to 'jid', using account (optional) 'account'. If keyID - is specified, encrypt the message with the pgp key + Send chat 'message' to 'jid', using account (optional) 'account'. """ jid = self._get_real_jid(jid, account) - return self._send_message(jid, message, keyID, account) + return self._send_message(jid, message, account) - def send_single_message(self, jid, subject, message, keyID, account): + def send_single_message(self, jid, subject, message, account): """ - Send single 'message' to 'jid', using account (optional) 'account'. If - keyID is specified, encrypt the message with the pgp key + Send single 'message' to 'jid', using account (optional) 'account'. """ jid = self._get_real_jid(jid, account) - return self._send_message(jid, message, keyID, account, 'normal', - subject) + return self._send_message(jid, message, account, 'normal', subject) def send_groupchat_message(self, room_jid, message, account): """ @@ -879,14 +870,7 @@ class GajimRemote(Server): contact_dict['name'] = GLib.Variant('s', name) contact_dict['show'] = GLib.Variant('s', prim_contact.show) contact_dict['jid'] = GLib.Variant('s', prim_contact.jid) - if prim_contact.keyID: - keyID = None - if len(prim_contact.keyID) == 8: - keyID = prim_contact.keyID - elif len(prim_contact.keyID) == 16: - keyID = prim_contact.keyID[8:] - if keyID: - contact_dict['openpgp'] = GLib.Variant('s', keyID) + resources = GLib.VariantBuilder(GLib.VariantType('a(sis)')) for contact in contacts: resource_props = (contact.resource, int(contact.priority), diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 222b27fcb..462e8dcd4 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -998,14 +998,9 @@ class RosterWindow: # FIXME: integrate into add_contact() def add_to_not_in_the_roster(self, account, jid, nick='', resource='', groupchat=False): - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if jid in attached_keys: - keyID = attached_keys[attached_keys.index(jid) + 1] contact = app.contacts.create_not_in_roster_contact( jid=jid, account=account, resource=resource, name=nick, - keyID=keyID, groupchat=groupchat) + groupchat=groupchat) app.contacts.add_contact(account, contact) self.add_contact(contact.jid, account) return contact @@ -1871,19 +1866,13 @@ class RosterWindow: show = 'offline' # show is offline by default status = '' # no status message by default - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if jid in attached_keys: - keyID = attached_keys[attached_keys.index(jid) + 1] - if app.jid_is_transport(jid): array[jid]['groups'] = [_('Transports')] #TRANSP - potential contact1 = app.contacts.create_contact(jid=ji, account=account, name=name, groups=array[jid]['groups'], show=show, status=status, sub=array[jid]['subscription'], - ask=array[jid]['ask'], resource=resource, keyID=keyID) + ask=array[jid]['ask'], resource=resource) app.contacts.add_contact(account, contact1) # If we already have chat windows opened, update them with new @@ -2031,14 +2020,9 @@ class RosterWindow: jid, txt, nickname, groups_list, auto_auth) contact = app.contacts.get_contact_with_highest_priority(account, jid) if not contact: - keyID = '' - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if jid in attached_keys: - keyID = attached_keys[attached_keys.index(jid) + 1] contact = app.contacts.create_contact(jid=jid, account=account, name=nickname, groups=groups_list, show='requested', status='', - ask='none', sub='subscribe', keyID=keyID) + ask='none', sub='subscribe') app.contacts.add_contact(account, contact) else: if not _('Not in Roster') in contact.get_shown_groups(): @@ -2079,13 +2063,6 @@ class RosterWindow: if app.connections[account].connected < 2: self.set_connecting_state(account) - keyid = app.config.get_per('accounts', account, 'keyid') - if keyid and not app.connections[account].gpg: - WarningDialog(_('OpenPGP is not usable'), - _('Gajim needs python-gnupg >= 0.3.8\n' - 'Beware there is an incompatible Python package called gnupg.\n' - 'You will be connected to %s without OpenPGP.') % account) - self.send_status_continue(account, status, txt, auto, to) def send_pep(self, account, pep_dict): @@ -2941,46 +2918,6 @@ class RosterWindow: _('Also remove all contacts in this group from your roster'), on_response_ok=on_ok) - def on_assign_pgp_key(self, widget, contact, account): - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - keys = {} - keyID = _('None') - for i in range(len(attached_keys) // 2): - keys[attached_keys[2*i]] = attached_keys[2*i+1] - if attached_keys[2*i] == contact.jid: - keyID = attached_keys[2*i+1] - public_keys = app.connections[account].ask_gpg_keys() - public_keys[_('None')] = _('None') - - def on_key_selected(keyID): - if keyID is None: - return - if keyID[0] == _('None'): - if contact.jid in keys: - del keys[contact.jid] - keyID = '' - else: - keyID = keyID[0] - keys[contact.jid] = keyID - - ctrl = app.interface.msg_win_mgr.get_control(contact.jid, account) - if ctrl: - ctrl.update_ui() - - keys_str = '' - for jid in keys: - keys_str += jid + ' ' + keys[jid] + ' ' - app.config.set_per('accounts', account, 'attached_gpg_keys', - keys_str) - for u in app.contacts.get_contacts(account, contact.jid): - u.keyID = helpers.prepare_and_validate_gpg_keyID(account, - contact.jid, keyID) - - dialogs.ChooseGPGKeyDialog(_('Assign OpenPGP Key'), - _('Select a key to apply to the contact'), public_keys, - on_key_selected, selected=keyID, transient_for=self.window) - def on_edit_groups(self, widget, list_): dialogs.EditGroupsDialog(list_) diff --git a/mypy.ini b/mypy.ini index 764759e90..e9c1fb647 100644 --- a/mypy.ini +++ b/mypy.ini @@ -27,9 +27,6 @@ ignore_missing_imports = True [mypy-pybonjour.*] ignore_missing_imports = True -[mypy-gnupg.*] -ignore_missing_imports = True - [mypy-encodings.*] ignore_missing_imports = True