diff --git a/src/chat_control.py b/src/chat_control.py index b98b33f1c..ea82c4aad 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1205,31 +1205,48 @@ class ChatControl(ChatControlBase): # The name banner is drawn here ChatControlBase.update_ui(self) - def update_otr(self, print_status=False): - # retrieve the OTR context from the chat's contact data - ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.account].otr_userstates, + def get_otr_status(self): + ctx = gajim.otr_module.otrl_context_find( + self.session.conn.otr_userstates, self.contact.get_full_jid().encode(), - gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1, - (gajim.otr_add_appdata, self.account))[0] - - enc_status = False - otr_status_text = "" + gajim.get_jid_from_account(self.account).encode(), + gajim.OTR_PROTO, 1, (gajim.otr_add_appdata, + self.account))[0] + if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED: - enc_status = True if ctx.active_fingerprint.trust: - otr_status_text = u"authenticated secure OTR connection" + return 2 else: - otr_status_text = u'*unauthenticated* secure OTR connection' + return 1 elif ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_FINISHED: + return 3 + return 0 + + def update_otr(self, print_status=False): + otr_status_text = '' + otr_status = self.get_otr_status() + authenticated = True + + if otr_status > 0: enc_status = True - otr_status_text = u"finished OTR connection" else: - # nothing to print - print_status = False - self._show_lock_image(enc_status, u'OTR', enc_status, True) - if print_status: - self.print_conversation_line(u" [OTR] %s"%otr_status_text, 'status', - '', None) + enc_status = False + + if otr_status == 1: + otr_status_text = u'*unauthenticated* secure OTR ' + \ + u'connection' + elif otr_status == 2: + otr_status_text = u'authenticated secure OTR ' + \ + u'connection' + authenticated = True + elif otr_status == 3: + otr_status_text = u'finished OTR connection' + + self._show_lock_image(enc_status, u'OTR', enc_status, True, + authenticated) + if print_status and otr_status_text != '': + self.print_conversation_line(u'[OTR] %s' % \ + otr_status_text, 'status', '', None) def _update_banner_state_image(self): contact = gajim.contacts.get_contact_with_highest_priority(self.account, @@ -1391,12 +1408,23 @@ class ChatControl(ChatControlBase): self._show_lock_image(self.gpg_is_active, 'GPG', self.gpg_is_active, self.session and \ self.session.is_loggable()) - def _show_lock_image(self, visible, enc_type = '', enc_enabled = False, chat_logged = False): + def _show_lock_image(self, visible, enc_type = '', enc_enabled = False, chat_logged = False, authenticated = False): '''Set lock icon visibility and create tooltip''' + # TODO: Make translatable status_string = enc_enabled and 'is' or 'is NOT' logged_string = chat_logged and 'will' or 'will NOT' - tooltip = '%s Encryption %s active. \nYour chat session %s be logged.' %\ - (enc_type, status_string, logged_string) + + if enc_type == 'OTR': + authenticated_string = authenticated \ + and ' and authenticated' \ + or ' and NOT authenticated' + else: + authenticated_string = '' + + tooltip = ('%s Encryption %s active%s. \n' + \ + 'Your chat session %s be logged.') % \ + (enc_type, status_string, authenticated_string, + logged_string) self.lock_tooltip.set_tip(self.lock_image, tooltip) self.widget_set_visible(self.lock_image, not visible) @@ -1604,6 +1632,7 @@ class ChatControl(ChatControlBase): def print_conversation(self, text, frm='', tim=None, encrypted=False, subject=None, xhtml=None, simple=False): + # TODO: contact? ITYM frm. '''Print a line in the conversation: if contact is set to status: it's a status message if contact is set to another value: it's an outgoing message @@ -1622,21 +1651,34 @@ class ChatControl(ChatControlBase): name = '' else: if self.session and self.session.enable_encryption: + # ESessions if not encrypted: - msg = _('The following message was NOT encrypted') - ChatControlBase.print_conversation_line(self, msg, - 'status', '', tim) + msg = _('The following message was ' + \ + 'NOT encrypted') + ChatControlBase.print_conversation_line( + self, msg, 'status', '', tim) + elif gajim.otr_module and self.get_otr_status() > 0: + # OTR + # TODO: This is not shown when the window + # isn't open - needs fixing! + if not encrypted and frm == '': + msg = _('The following message was ' + \ + 'NOT encrypted') + ChatControlBase.print_conversation_line( + self, msg, 'status', '', tim) else: # GPG encryption if encrypted and not self.gpg_is_active: - msg = _('The following message was encrypted') - ChatControlBase.print_conversation_line(self, msg, - 'status', '', tim) + msg = _('The following message was ' + \ + 'encrypted') + ChatControlBase.print_conversation_line( + self, msg, 'status', '', tim) self._toggle_gpg() elif not encrypted and self.gpg_is_active: - msg = _('The following message was NOT encrypted') - ChatControlBase.print_conversation_line(self, msg, - 'status', '', tim) + msg = _('The following message was ' + \ + 'NOT encrypted') + ChatControlBase.print_conversation_line( + self, msg, 'status', '', tim) if not frm: kind = 'incoming' name = contact.get_shown_name() diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 8a8f925b8..8f95cdd78 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -1711,36 +1711,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, elif invite is not None: self.dispatch_invite_message(invite, frm) else: - # XXX this shouldn't be hardcoded if isinstance(session, ChatControlSession): - if gajim.otr_module and isinstance(msgtxt, unicode): - otr_msg_tuple = gajim.otr_module.otrl_message_receiving( - gajim.connections[self.name].otr_userstates, - (gajim.otr_ui_ops, {'account':self.name}), - gajim.get_jid_from_account(self.name).encode(), - gajim.OTR_PROTO, frm.encode(), msgtxt.encode(), - (gajim.otr_add_appdata, self.name)) - msgtxt = unicode(otr_msg_tuple[1]) - # OTR messages are unformatted, or rather contain the same - # text in and - msghtml = msgtxt - - - if gajim.otr_module.otrl_tlv_find(otr_msg_tuple[2], - gajim.otr_module.OTRL_TLV_DISCONNECTED) != None: - gajim.otr_ui_ops.gajim_log("%s has ended his/her private conversation" - " with you; you should do the same."%frm, self.name, - frm) - if session.control: - session.control.update_ui() - - ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.name].otr_userstates, frm.encode(), - gajim.get_jid_from_account(self.name).encode(), gajim.OTR_PROTO, 1, - (gajim.otr_add_appdata, self.name))[0] - - tlvs = otr_msg_tuple[2] - ctx.app_data.handle_tlv(tlvs) - session.received(frm, msgtxt, tim, encrypted, subject, msg) else: session.received(msg) diff --git a/src/gajim.py b/src/gajim.py index 87608ac64..b613516d4 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -256,26 +256,13 @@ from common import dataforms from common.xmpp import Message as XmppMessage -## We disable OTR for now as libotr's API is just totally broken. -## If you don't care about losing messages because they were unencrypted -## and libotr only noticing us via a HTML string about this (which is only -## displayed as a notice) and don't fear other bugs, you can manually -## enable it here. -## -## OTR will *NOT* be reenabled by default until the developers of libotr -## fix their very broken API! - -#try: -# import otr, otr_windows -# -# gajim.otr_module = otr -# gajim.otr_windows = otr_windows -#except ImportError: -# gajim.otr_module = None -# gajim.otr_windows = None - -gajim.otr_module = None -gajim.otr_windows = None +try: + import otr, otr_windows + gajim.otr_module = otr + gajim.otr_windows = otr_windows +except ImportError: + gajim.otr_module = None + gajim.otr_windows = None def add_appdata(data=None, context=None): account = data @@ -289,7 +276,6 @@ def otr_dialog_destroy(widget, *args, **kwargs): widget.destroy() class OtrlMessageAppOps: - def gajim_log(self, msg, account, fjid, no_print=False): if not isinstance(fjid, unicode): fjid = unicode(fjid) diff --git a/src/session.py b/src/session.py index 00d9feb52..b5a49b4b9 100644 --- a/src/session.py +++ b/src/session.py @@ -81,6 +81,55 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession): return log_type = 'chat_msg_recv' + + if gajim.otr_module and \ + isinstance(msgtxt, unicode) and \ + msgtxt.find('?OTR') != -1: + # TODO: Do we really need .encode()? + otr_msg_tuple = \ + gajim.otr_module.otrl_message_receiving( + self.conn.otr_userstates, + (gajim.otr_ui_ops, + {'account': self.conn.name}), + gajim.get_jid_from_account( + self.conn.name).encode(), + gajim.OTR_PROTO, + full_jid_with_resource.encode(), + msgtxt.encode(), + (gajim.otr_add_appdata, self.conn.name)) + msgtxt = unicode(otr_msg_tuple[1]) + xhtml = None + + if gajim.otr_module.otrl_tlv_find( + otr_msg_tuple[2], + gajim.otr_module.OTRL_TLV_DISCONNECTED) != None: + gajim.otr_ui_ops.gajim_log(_("%s " + \ + "has ended his/her private " + \ + "conversation with you; " + \ + "should do the same.") % \ + full_jid_with_resource, + self.conn.name, + full_jid_with_resource.encode()) + + if self.control: + control.update_ui() + + ctx = gajim.otr_module. \ + otrl_context_find( + self.conn.otr_userstates, + full_jid_with_resource.encode(), + gajim.get_jid_from_account( + self.conn.name).encode(), + gajim.OTR_PROTO, 1, + (gajim.otr_add_appdata, + self.conn.name))[0] + tlvs = otr_msg_tuple[2] + ctx.app_data.handle_tlv(tlvs) + + encrypted = True + + if msgtxt == '': + return else: log_type = 'single_msg_recv'