Rework GPG behaviour:
Only encrypt when the receiver is trusted. You have to sign its key or it has to be signed by someone you trust. Fixes #109 Make checkbox insensitive when GPG is disabled on an account (or no passphrase given). Auto assign trusted keys on received presence. Deny encryption on missmatch of assigned key and signing key. Fixes #3376 Do not disable encrypted when receiving an unencrypted message. Print whether a received message was encrypted or not. TODO: Remove togglebutton, its useless now
This commit is contained in:
parent
d17a51c648
commit
6fdd7c0f88
|
@ -1050,15 +1050,17 @@ class ChatControl(ChatControlBase):
|
|||
self.on_avatar_eventbox_button_press_event)
|
||||
self.handlers[id] = widget
|
||||
|
||||
widget = self.xml.get_widget('gpg_togglebutton')
|
||||
id = widget.connect('clicked', self.on_toggle_gpg_togglebutton)
|
||||
self.handlers[id] = widget
|
||||
|
||||
if self.contact.jid in gajim.encrypted_chats[self.account]:
|
||||
self.xml.get_widget('gpg_togglebutton').set_active(True)
|
||||
|
||||
self.set_session(session)
|
||||
|
||||
# Enable ecryption if needed
|
||||
gpg_pref = gajim.config.get_per('contacts', contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref and gajim.config.get_per('accounts', self.account, 'keyid') and\
|
||||
gajim.connections[self.account].USE_GPG:
|
||||
gajim.encrypted_chats[self.account].append(contact.jid)
|
||||
msg = _('GPG encryption enabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
self.status_tooltip = gtk.Tooltips()
|
||||
self.update_ui()
|
||||
# restore previous conversation
|
||||
|
@ -1164,8 +1166,6 @@ class ChatControl(ChatControlBase):
|
|||
gtk.gdk.INTERP_BILINEAR)
|
||||
banner_status_img.set_from_pixbuf(scaled_pix)
|
||||
|
||||
self._update_gpg()
|
||||
|
||||
def draw_banner_text(self):
|
||||
'''Draw the text in the fat line at the top of the window that
|
||||
houses the name, jid.
|
||||
|
@ -1254,34 +1254,26 @@ class ChatControl(ChatControlBase):
|
|||
# setup the label that holds name and jid
|
||||
banner_name_label.set_markup(label_text)
|
||||
|
||||
def on_toggle_gpg_togglebutton(self, widget):
|
||||
gajim.config.set_per('contacts', self.contact.jid, 'gpg_enabled',
|
||||
widget.get_active())
|
||||
|
||||
def _update_gpg(self):
|
||||
tb = self.xml.get_widget('gpg_togglebutton')
|
||||
# we can do gpg
|
||||
# if self.contact is our own contact info (transports),
|
||||
# don't enable pgp
|
||||
if self.contact.keyID and not gajim.jid_is_transport(self.contact.jid):
|
||||
tb.set_sensitive(True)
|
||||
tt = _('OpenPGP Encryption')
|
||||
|
||||
# restore gpg pref
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref == None:
|
||||
gajim.config.add_per('contacts', self.contact.jid)
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
tb.set_active(gpg_pref)
|
||||
|
||||
def _toggle_gpg(self):
|
||||
ec = gajim.encrypted_chats[self.account]
|
||||
if self.contact.jid in ec:
|
||||
# Disable encryption
|
||||
ec.remove(self.contact.jid)
|
||||
gpg_is_active = False
|
||||
msg = _('GPG encryption disabled')
|
||||
else:
|
||||
tb.set_sensitive(False)
|
||||
#we talk about a contact here
|
||||
tt = _('%s has not broadcast an OpenPGP key, nor has one been assigned') %\
|
||||
self.contact.get_shown_name()
|
||||
gtk.Tooltips().set_tip(self.xml.get_widget('gpg_eventbox'), tt)
|
||||
# Enable encryption
|
||||
ec.append(self.contact.jid)
|
||||
gpg_is_active = True
|
||||
msg = _('GPG encryption enabled')
|
||||
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref is None:
|
||||
gajim.config.add_per('contacts', self.contact.jid)
|
||||
gajim.config.set_per('contacts', self.contact.jid, 'gpg_enabled',
|
||||
gpg_is_active)
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
def _process_command(self, message):
|
||||
if message[0] != '/':
|
||||
|
@ -1369,9 +1361,13 @@ class ChatControl(ChatControlBase):
|
|||
encrypted = bool(self.session) and self.session.enable_encryption
|
||||
|
||||
keyID = ''
|
||||
if self.xml.get_widget('gpg_togglebutton').get_active():
|
||||
gpg_pref = gajim.config.get_per('contacts', contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref:
|
||||
keyID = contact.keyID
|
||||
encrypted = True
|
||||
if keyID == '':
|
||||
keyID = 'UNKNOWN'
|
||||
|
||||
chatstates_on = gajim.config.get('outgoing_chat_state_notifications') != \
|
||||
'disabled'
|
||||
|
@ -1401,7 +1397,7 @@ class ChatControl(ChatControlBase):
|
|||
gobject.source_remove(self.possible_paused_timeout_id)
|
||||
gobject.source_remove(self.possible_inactive_timeout_id)
|
||||
self._schedule_activity_timers()
|
||||
|
||||
|
||||
if not ChatControlBase.send_message(self, message, keyID, type = 'chat',
|
||||
chatstate = chatstate_to_send, composing_xep = composing_xep,
|
||||
process_command = process_command):
|
||||
|
@ -1512,17 +1508,14 @@ class ChatControl(ChatControlBase):
|
|||
# GPG encryption
|
||||
ec = gajim.encrypted_chats[self.account]
|
||||
if encrypted and jid not in ec:
|
||||
msg = _('OpenPGP Encryption enabled')
|
||||
msg = _('The following message was encrypted')
|
||||
ChatControlBase.print_conversation_line(self, msg,
|
||||
'status', '', tim)
|
||||
ec.append(jid)
|
||||
self._toggle_gpg()
|
||||
elif not encrypted and jid in ec:
|
||||
msg = _('OpenPGP Encryption disabled')
|
||||
msg = _('The following message was NOT encrypted')
|
||||
ChatControlBase.print_conversation_line(self, msg,
|
||||
'status', '', tim)
|
||||
ec.remove(jid)
|
||||
self.xml.get_widget('gpg_togglebutton').set_active(encrypted)
|
||||
|
||||
if not frm:
|
||||
kind = 'incoming'
|
||||
name = contact.get_shown_name()
|
||||
|
@ -1649,13 +1642,17 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
contact = self.parent_win.get_active_contact()
|
||||
jid = contact.jid
|
||||
|
||||
# check if gpg capabitlies or else make gpg toggle insensitive
|
||||
gpg_btn = self.xml.get_widget('gpg_togglebutton')
|
||||
isactive = gpg_btn.get_active()
|
||||
is_sensitive = gpg_btn.get_property('sensitive')
|
||||
toggle_gpg_menuitem.set_active(isactive)
|
||||
toggle_gpg_menuitem.set_property('sensitive', is_sensitive)
|
||||
|
||||
# check if we support and use gpg
|
||||
if not gajim.config.get_per('accounts', self.account, 'keyid') or\
|
||||
not gajim.connections[self.account].USE_GPG or\
|
||||
gajim.jid_is_transport(jid):
|
||||
toggle_gpg_menuitem.set_sensitive(False)
|
||||
else:
|
||||
toggle_gpg_menuitem.set_sensitive(True)
|
||||
gpg_pref = gajim.config.get_per('contacts', jid,
|
||||
'gpg_enabled')
|
||||
toggle_gpg_menuitem.set_active(bool(gpg_pref))
|
||||
|
||||
# TODO: check that the remote client supports e2e
|
||||
if not gajim.HAVE_PYCRYPTO:
|
||||
|
@ -1694,14 +1691,15 @@ class ChatControl(ChatControlBase):
|
|||
id = send_file_menuitem.connect('activate',
|
||||
self._on_send_file_menuitem_activate)
|
||||
self.handlers[id] = send_file_menuitem
|
||||
id = add_to_roster_menuitem.connect('activate',
|
||||
id = add_to_roster_menuitem.connect('activate',
|
||||
self._on_add_to_roster_menuitem_activate)
|
||||
self.handlers[id] = add_to_roster_menuitem
|
||||
id = toggle_gpg_menuitem.connect('activate',
|
||||
self.handlers[id] = add_to_roster_menuitem
|
||||
id = toggle_gpg_menuitem.connect('activate',
|
||||
self._on_toggle_gpg_menuitem_activate)
|
||||
self.handlers[id] = toggle_gpg_menuitem
|
||||
id = toggle_e2e_menuitem.connect('activate',
|
||||
self._on_toggle_e2e_menuitem_activate)
|
||||
self.handlers[id] = toggle_gpg_menuitem
|
||||
self.handlers[id] = toggle_e2e_menuitem
|
||||
id = information_menuitem.connect('activate',
|
||||
self._on_contact_information_menuitem_activate)
|
||||
self.handlers[id] = information_menuitem
|
||||
|
@ -2154,10 +2152,7 @@ class ChatControl(ChatControlBase):
|
|||
gajim.interface.roster.on_info(widget, self.contact, self.account)
|
||||
|
||||
def _on_toggle_gpg_menuitem_activate(self, widget):
|
||||
# update the button
|
||||
# this is reverse logic, as we are on 'activate' (before change happens)
|
||||
tb = self.xml.get_widget('gpg_togglebutton')
|
||||
tb.set_active(not tb.get_active())
|
||||
self._toggle_gpg()
|
||||
|
||||
def _on_convert_to_gc_menuitem_activate(self, widget):
|
||||
'''user want to invite some friends to chat'''
|
||||
|
|
|
@ -45,8 +45,6 @@ if gajim.HAVE_GPG:
|
|||
self.options.armor = 1
|
||||
self.options.meta_interactive = 0
|
||||
self.options.extra_args.append('--no-secmem-warning')
|
||||
# Nolith's patch - prevent crashs on non fully-trusted keys
|
||||
self.options.extra_args.append('--always-trust')
|
||||
if self.use_agent:
|
||||
self.options.extra_args.append('--use-agent')
|
||||
|
||||
|
@ -173,7 +171,7 @@ if gajim.HAVE_GPG:
|
|||
|
||||
try: proc.wait()
|
||||
except IOError: pass
|
||||
|
||||
|
||||
keyid = ''
|
||||
if resp.has_key('GOODSIG'):
|
||||
keyid = resp['GOODSIG'].split()[0]
|
||||
|
|
|
@ -961,9 +961,15 @@ class Connection(ConnectionHandlers):
|
|||
fjid += '/' + resource
|
||||
msgtxt = msg
|
||||
msgenc = ''
|
||||
|
||||
if keyID and self.USE_GPG:
|
||||
#encrypt
|
||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||
if keyID == 'UNKNOWN':
|
||||
error = _('Neither the remote presence is signed, nor a key was assigned.')
|
||||
elif keyID[8:] == 'MISMATCH':
|
||||
error = _('The contact\'s key does not match the key assigned in Gajim.')
|
||||
else:
|
||||
#encrypt
|
||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||
if msgenc and not error:
|
||||
msgtxt = '[This message is encrypted]'
|
||||
lang = os.getenv('LANG')
|
||||
|
|
|
@ -2199,6 +2199,7 @@ returns the session that we last sent a message to.'''
|
|||
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
||||
#%s is the account name here
|
||||
_('You will be connected to %s without OpenPGP.') % self.name))
|
||||
self.USE_GPG = False
|
||||
signed = ''
|
||||
self.connected = STATUS_LIST.index(show)
|
||||
sshow = helpers.get_xmpp_show(show)
|
||||
|
|
|
@ -1094,3 +1094,36 @@ def get_transport_path(transport):
|
|||
return os.path.join(gajim.MY_ICONSETS_PATH, 'transports', transport)
|
||||
# No transport folder found, use default jabber one
|
||||
return get_iconset_path(gajim.config.get('iconset'))
|
||||
|
||||
def prepare_and_validate_gpg_keyID(account, jid, keyID):
|
||||
'''Returns 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 gajim.connections[account].USE_GPG:
|
||||
if len(keyID) == 16:
|
||||
keyID = keyID[8:]
|
||||
|
||||
attached_keys = gajim.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:
|
||||
# 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:
|
||||
public_keys = gajim.connections[account].ask_gpg_keys()
|
||||
# Assign the corresponding key, if we have it in our keyring
|
||||
if public_keys.has_key(keyID):
|
||||
for u in gajim.contacts.get_contacts(account, jid):
|
||||
u.keyID = keyID
|
||||
keys_str = gajim.config.get_per('accounts', account, 'attached_gpg_keys')
|
||||
keys_str += jid + ' ' + keyID + ' '
|
||||
gajim.config.set_per('accounts', account, 'attached_gpg_keys', keys_str)
|
||||
elif keyID is None:
|
||||
keyID = 'UNKNOWN'
|
||||
return keyID
|
||||
|
||||
|
|
|
@ -579,10 +579,11 @@ class Interface:
|
|||
jid = array[0].split('/')[0]
|
||||
keyID = array[5]
|
||||
contact_nickname = array[7]
|
||||
attached_keys = gajim.config.get_per('accounts', account,
|
||||
'attached_gpg_keys').split()
|
||||
if jid in attached_keys:
|
||||
keyID = attached_keys[attached_keys.index(jid) + 1]
|
||||
|
||||
# Get the proper keyID
|
||||
keyID = helpers.prepare_and_validate_gpg_keyID(account,
|
||||
jid, keyID)
|
||||
|
||||
resource = array[3]
|
||||
if not resource:
|
||||
resource = ''
|
||||
|
|
|
@ -1912,12 +1912,11 @@ class RosterWindow:
|
|||
if keyID[0] == _('None'):
|
||||
if contact.jid in keys:
|
||||
del keys[contact.jid]
|
||||
for u in gajim.contacts.get_contacts(account, contact.jid):
|
||||
u.keyID = ''
|
||||
keyID = ''
|
||||
else:
|
||||
keys[contact.jid] = keyID[0]
|
||||
for u in gajim.contacts.get_contacts(account, contact.jid):
|
||||
u.keyID = keyID[0]
|
||||
keyID = keyID[0]
|
||||
keys[contact.jid] = keyID
|
||||
|
||||
if gajim.interface.msg_win_mgr.has_window(contact.jid, account):
|
||||
ctrl = gajim.interface.msg_win_mgr.get_control(contact.jid, account)
|
||||
ctrl.update_ui()
|
||||
|
@ -1925,6 +1924,9 @@ class RosterWindow:
|
|||
for jid in keys:
|
||||
keys_str += jid + ' ' + keys[jid] + ' '
|
||||
gajim.config.set_per('accounts', account, 'attached_gpg_keys', keys_str)
|
||||
for u in gajim.contacts.get_contacts(account, contact.jid):
|
||||
u.keyID = helpers.prepare_and_validate_gpg_keyID(account,
|
||||
contact.jid, keyID)
|
||||
|
||||
def update_avatar_in_gui(self, jid, account):
|
||||
# Update roster
|
||||
|
|
Loading…
Reference in New Issue