Completely remove OTR.
Sorry, it just wasn't maintainable. The problem is the current libotr API. I'm sick of working around the strange libotr API, sick of getting HTML messages, sick of losing messages. The final argument for completely removing it was that we can't get the message ID of a sent msg anymore - which we need. I tried to work around this as well, but there seems to be no way to wait for a signal in glib the way I would need it for the workaround (I wanted to emit a signal in inject_message and then wait for it after the call to otr_message_fragment_and_send so the signal can pass us the message id). And the last reason is that we're heading towards a new release and thus want to stabilize the code, thus don't have time to work around even more libotr API strangeness. I will give feedback to the libotr developers, who are currently planning a new API, so that we can hopefully see OTR support once again as soon as libotr4 is released. Kjell already announced that he will continue his branch: https://code.launchpad.net/~afflux/gajim/otr I really hope the libotr devs will provide a sane API with libotr4 so we can integrate OTR support again. Oh, and I added one more try/except block for OS X.
This commit is contained in:
parent
0d645437d8
commit
c2eb4b5a9f
|
@ -71,51 +71,6 @@
|
|||
<signal name="activate" handler="_on_toggle_e2e_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="otr_submenu">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="label" translatable="yes">Off-the-Record Encryption</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child>
|
||||
<widget class="GtkMenu" id="otr_submenu_menu">
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="otr_settings_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">OTR settings / fingerprint</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="_on_otr_settings_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="smp_otr_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Authenticate contact</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="_on_smp_otr_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="start_otr_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Start / Refresh OTR</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="_on_start_otr_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="end_otr_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="label" translatable="yes">End OTR </property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="_on_end_otr_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
|
|
|
@ -1,322 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.4.2 on Wed Mar 26 13:56:40 2008 -->
|
||||
<glade-interface>
|
||||
<widget class="GtkWindow" id="otr_settings_window">
|
||||
<property name="resizable">False</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkNotebook" id="notebook1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="otr_fp_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="our_fp_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Your fingerprint:
|
||||
<span weight="bold" face="monospace">01234567 89ABCDEF 01234567 89ABCDEF 01234567</span></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="their_fp_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Purported fingerprint for asdfasdf@xyzxyzxyz.de:
|
||||
<span weight="bold" face="monospace">01234567 89ABCDEF 01234567 89ABCDEF 01234567</span></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="verified_combobox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="active">1</property>
|
||||
<property name="items">I have NOT
|
||||
I have</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.20000000298023224</property>
|
||||
<property name="label" translatable="yes">verified that the purported fingerprint is in fact the correct fingerprint for that contact.</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Authentication</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="otr_settings_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_allow_v1_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">OTR version 1 allowed</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_allow_v2_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">OTR version 2 allowed</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_require_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Encryption required</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_send_tag_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Show others we understand OTR</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_start_on_tag_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Automatically initiate encryption if partner understands OTR</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_policy_start_on_error_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Automatically start OTR when an OTR error occured</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="otr_default_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Use the default settings</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">OTR Settings</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="settings_cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="settings_ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkWindow" id="otr_smp_window">
|
||||
<property name="resizable">False</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="desc_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="secret_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkProgressBar" id="progressbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="smp_cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="smp_ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
|
@ -1135,9 +1135,6 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
self.status_tooltip = gtk.Tooltips()
|
||||
|
||||
if gajim.otr_module:
|
||||
self.update_otr(True)
|
||||
|
||||
self.update_ui()
|
||||
# restore previous conversation
|
||||
self.restore_conversation()
|
||||
|
@ -1207,52 +1204,6 @@ class ChatControl(ChatControlBase):
|
|||
# The name banner is drawn here
|
||||
ChatControlBase.update_ui(self)
|
||||
|
||||
def get_otr_status(self):
|
||||
if not self.session:
|
||||
return 0
|
||||
|
||||
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]
|
||||
|
||||
if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED:
|
||||
if ctx.active_fingerprint.trust:
|
||||
return 2
|
||||
else:
|
||||
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 = False
|
||||
|
||||
if otr_status > 0:
|
||||
enc_status = True
|
||||
else:
|
||||
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,
|
||||
self.contact.jid)
|
||||
|
@ -1662,15 +1613,6 @@ class ChatControl(ChatControlBase):
|
|||
'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:
|
||||
|
@ -1796,11 +1738,6 @@ class ChatControl(ChatControlBase):
|
|||
history_menuitem = xml.get_widget('history_menuitem')
|
||||
toggle_gpg_menuitem = xml.get_widget('toggle_gpg_menuitem')
|
||||
toggle_e2e_menuitem = xml.get_widget('toggle_e2e_menuitem')
|
||||
otr_submenu = xml.get_widget('otr_submenu')
|
||||
otr_settings_menuitem = xml.get_widget('otr_settings_menuitem')
|
||||
smp_otr_menuitem = xml.get_widget('smp_otr_menuitem')
|
||||
start_otr_menuitem = xml.get_widget('start_otr_menuitem')
|
||||
end_otr_menuitem = xml.get_widget('end_otr_menuitem')
|
||||
send_file_menuitem = xml.get_widget('send_file_menuitem')
|
||||
information_menuitem = xml.get_widget('information_menuitem')
|
||||
convert_to_gc_menuitem = xml.get_widget('convert_to_groupchat')
|
||||
|
@ -1893,32 +1830,6 @@ class ChatControl(ChatControlBase):
|
|||
self._on_convert_to_gc_menuitem_activate)
|
||||
self.handlers[id] = convert_to_gc_menuitem
|
||||
|
||||
if gajim.otr_module:
|
||||
otr_submenu.set_sensitive(True)
|
||||
id = otr_settings_menuitem.connect('activate',
|
||||
self._on_otr_settings_menuitem_activate)
|
||||
self.handlers[id] = otr_settings_menuitem
|
||||
id = start_otr_menuitem.connect('activate',
|
||||
self._on_start_otr_menuitem_activate)
|
||||
self.handlers[id] = start_otr_menuitem
|
||||
id = end_otr_menuitem.connect('activate',
|
||||
self._on_end_otr_menuitem_activate)
|
||||
self.handlers[id] = end_otr_menuitem
|
||||
id = smp_otr_menuitem.connect('activate',
|
||||
self._on_smp_otr_menuitem_activate)
|
||||
self.handlers[id] = smp_otr_menuitem
|
||||
|
||||
ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.account].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]
|
||||
# can end only when PLAINTEXT
|
||||
end_otr_menuitem.set_sensitive(ctx.msgstate !=
|
||||
gajim.otr_module.OTRL_MSGSTATE_PLAINTEXT)
|
||||
# can SMP only when ENCRYPTED
|
||||
smp_otr_menuitem.set_sensitive(ctx.msgstate ==
|
||||
gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED)
|
||||
|
||||
menu.connect('selection-done', self.destroy_menu,
|
||||
send_file_menuitem, convert_to_gc_menuitem,
|
||||
information_menuitem, history_menuitem)
|
||||
|
@ -2406,28 +2317,6 @@ class ChatControl(ChatControlBase):
|
|||
# XXX decide whether to use 4 or 3 message negotiation
|
||||
self.session.negotiate_e2e(False)
|
||||
|
||||
def _on_start_otr_menuitem_activate(self, widget):
|
||||
# ?OTR? gets replaced with a better message internally in otrl_message_sending
|
||||
MessageControl.send_message(self, u'?OTR?', type='chat')
|
||||
def _on_end_otr_menuitem_activate(self, widget):
|
||||
fjid = self.contact.get_full_jid()
|
||||
gajim.otr_module.otrl_message_disconnect(
|
||||
self.session.conn.otr_userstates, (gajim.otr_ui_ops,
|
||||
{'account': self.account, 'urgent': True}),
|
||||
gajim.get_jid_from_account(self.account).encode(),
|
||||
gajim.OTR_PROTO, fjid.encode())
|
||||
gajim.otr_ui_ops.gajim_log(_('Private conversation with ' \
|
||||
'%s lost.') % fjid, self.account, fjid.encode())
|
||||
self.update_otr()
|
||||
def _on_otr_settings_menuitem_activate(self, widget):
|
||||
gajim.otr_windows.ContactOtrWindow(self.contact, self.account, self)
|
||||
def _on_smp_otr_menuitem_activate(self, widget):
|
||||
ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.account].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]
|
||||
ctx.app_data.show(False)
|
||||
|
||||
def got_connected(self):
|
||||
ChatControlBase.got_connected(self)
|
||||
# Refreshing contact
|
||||
|
|
|
@ -313,7 +313,6 @@ class Config:
|
|||
'use_env_http_proxy' : [opt_bool, False],
|
||||
'answer_receipt' : [opt_bool, True, _('Answer to receipt requests')],
|
||||
'request_receipt' : [opt_bool, True, _('Sent receipt requests')],
|
||||
'otr_flags': [opt_int, 58 ],
|
||||
'publish_mood': [opt_bool, True],
|
||||
'publish_activity': [opt_bool, True],
|
||||
'publish_tune': [opt_bool, False],
|
||||
|
@ -372,7 +371,6 @@ class Config:
|
|||
'contacts': ({
|
||||
'gpg_enabled': [ opt_bool, False, _('Is OpenPGP enabled for this contact?')],
|
||||
'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')],
|
||||
'otr_flags': [opt_int, -1 ],
|
||||
}, {}),
|
||||
'rooms': ({
|
||||
'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')],
|
||||
|
|
|
@ -896,20 +896,6 @@ class Connection(ConnectionHandlers):
|
|||
self.on_connect_auth = self._init_roster
|
||||
self.connect_and_auth()
|
||||
|
||||
if gajim.otr_module:
|
||||
try:
|
||||
gajim.otr_module.otrl_privkey_read(self.otr_userstates,
|
||||
os.path.join(gajim.gajimpaths.root,
|
||||
'%s.key' % self.name).encode())
|
||||
gajim.otr_module.otrl_privkey_read_fingerprints(
|
||||
self.otr_userstates, os.path.join(
|
||||
gajim.gajimpaths.root, '%s.fpr' %
|
||||
self.name).encode(),
|
||||
(gajim.otr_add_appdata, self.name))
|
||||
except Exception, e:
|
||||
if not hasattr(e, 'os_errno') or e.os_errno != 2:
|
||||
raise
|
||||
|
||||
def _init_roster(self, con):
|
||||
self.connection = con
|
||||
if not self.connection:
|
||||
|
|
|
@ -1218,9 +1218,6 @@ class ConnectionHandlersBase:
|
|||
# keep track of sessions this connection has with other JIDs
|
||||
self.sessions = {}
|
||||
|
||||
if gajim.otr_module:
|
||||
self.otr_userstates = gajim.otr_module.otrl_userstate_create()
|
||||
|
||||
def _FeatureNegCB(self, con, stanza, session):
|
||||
gajim.log.debug('FeatureNegCB')
|
||||
feature = stanza.getTag(name='feature', namespace=common.xmpp.NS_FEATURE)
|
||||
|
@ -1705,79 +1702,6 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
receipt.setThread(thread_id)
|
||||
con.send(receipt)
|
||||
|
||||
# We don't trust libotr, that's why we only pass the message
|
||||
# to it if necessary. otrl_proto_message_type does this check.
|
||||
if gajim.otr_module and not xep_200_encrypted \
|
||||
and isinstance(msgtxt, unicode) and \
|
||||
gajim.otr_module.otrl_proto_message_type(msgtxt.encode()) != \
|
||||
gajim.otr_module.OTRL_MSGTYPE_NOTOTR:
|
||||
# set to encrypted if it's really encrypted.
|
||||
if gajim.otr_module.otrl_proto_message_type(
|
||||
msgtxt.encode()) != \
|
||||
gajim.otr_module.OTRL_MSGTYPE_TAGGEDPLAINTEXT:
|
||||
encrypted = True
|
||||
|
||||
# TODO: Do we really need .encode()?
|
||||
# yes we do. OTR can't handle unicode.
|
||||
otr_msg_tuple = \
|
||||
gajim.otr_module.otrl_message_receiving(
|
||||
self.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])
|
||||
|
||||
html_node = msg.getTag('html')
|
||||
if html_node:
|
||||
msg.delChild(html_node)
|
||||
msg.setBody(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.encode())
|
||||
|
||||
ctrls = gajim.interface.msg_win_mgr.get_chat_controls(jid, self.name)
|
||||
for ctrl in ctrls:
|
||||
ctrl.update_otr()
|
||||
|
||||
ctx = gajim.otr_module. \
|
||||
otrl_context_find(
|
||||
self.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)
|
||||
|
||||
if msgtxt == '':
|
||||
return
|
||||
elif msgtxt != None and msgtxt != '':
|
||||
gajim.otr_dont_append_tag[frm] = True
|
||||
|
||||
# We're also here if we just don't
|
||||
# support OTR. Thus, we should strip
|
||||
# the tags from plaintext messages
|
||||
# since they look ugly.
|
||||
msgtxt = msgtxt.replace('\x20\x09\x20' \
|
||||
'\x20\x09\x09\x09\x09\x20\x09' \
|
||||
'\x20\x09\x20\x09\x20\x20', '')
|
||||
msgtxt = msgtxt.replace('\x20\x09\x20' \
|
||||
'\x09\x20\x20\x09\x20', '')
|
||||
msgtxt = msgtxt.replace('\x20\x20\x09' \
|
||||
'\x09\x20\x20\x09\x20', '')
|
||||
|
||||
if mtype != 'groupchat':
|
||||
session = self.get_or_create_session(frm, thread_id)
|
||||
|
||||
|
|
|
@ -165,13 +165,6 @@ else:
|
|||
if system('gpg -h >/dev/null 2>&1'):
|
||||
HAVE_GPG = False
|
||||
|
||||
OTR_PROTO = "xmpp"
|
||||
otr_userstates = {}
|
||||
otr_policy = {}
|
||||
|
||||
# list of (full) jids not to attempt OTR with
|
||||
otr_dont_append_tag = {}
|
||||
|
||||
gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'}
|
||||
gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI,
|
||||
xmpp.NS_FILE, xmpp.NS_MUC, xmpp.NS_MUC_USER,
|
||||
|
|
|
@ -99,10 +99,6 @@ class FeaturesWindow:
|
|||
_('Encrypting chatmessages.'),
|
||||
_('Requires python-crypto.'),
|
||||
_('Requires python-crypto.')),
|
||||
_('Off the Record Encryption'): (self.otr_available,
|
||||
_('Encrypting chatmessages in a way that even works through gateways.'),
|
||||
_('Requires pyotr and libotr (see http://trac.gajim.org/wiki/OTR).'),
|
||||
_('Requires pyotr and libotr (see http://trac.gajim.org/wiki/OTR).')),
|
||||
_('RST Generator'): (self.docutils_available,
|
||||
_('Generate XHTML output from RST code (see http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).'),
|
||||
_('Requires python-docutils.'),
|
||||
|
@ -312,11 +308,6 @@ class FeaturesWindow:
|
|||
from common import gajim
|
||||
return gajim.HAVE_PYCRYPTO
|
||||
|
||||
def otr_available(self):
|
||||
if gajim.otr_module:
|
||||
return True
|
||||
return False
|
||||
|
||||
def docutils_available(self):
|
||||
try:
|
||||
import docutils
|
||||
|
|
208
src/gajim.py
208
src/gajim.py
|
@ -266,214 +266,6 @@ from common import helpers
|
|||
from common import optparser
|
||||
from common import dataforms
|
||||
|
||||
from common.xmpp import Message as XmppMessage
|
||||
|
||||
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, context):
|
||||
account = data
|
||||
context.app_data = otr_windows.ContactOtrSMPWindow(
|
||||
unicode(context.username), account)
|
||||
|
||||
gajim.otr_add_appdata = add_appdata
|
||||
|
||||
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)
|
||||
if not isinstance(account, unicode):
|
||||
account = unicode(account)
|
||||
resource=gajim.get_resource_from_jid(fjid)
|
||||
tim = time.localtime()
|
||||
|
||||
if not no_print:
|
||||
ctrl = self.get_control(fjid, account)
|
||||
if ctrl:
|
||||
ctrl.print_conversation_line(u'[OTR] %s' % \
|
||||
msg, 'status', '', None)
|
||||
id = gajim.logger.write('chat_msg_recv', fjid,
|
||||
message='[OTR: %s]' % msg, tim=tim)
|
||||
# gajim.logger.write() only marks a message as unread
|
||||
# (and so only returns an id) when fjid is a real contact
|
||||
# (NOT if it's a GC private chat)
|
||||
if id:
|
||||
gajim.logger.set_read_messages([id])
|
||||
|
||||
def get_control(self, fjid, account):
|
||||
# first try to get the window with the full jid
|
||||
ctrls = gajim.interface.msg_win_mgr.get_chat_controls(fjid, account)
|
||||
if ctrls:
|
||||
# got one, be happy
|
||||
return ctrls[0]
|
||||
|
||||
# otherwise try without the resource
|
||||
ctrls = gajim.interface.msg_win_mgr.get_chat_controls(
|
||||
gajim.get_jid_without_resource(fjid), account)
|
||||
# but only use it when it is not a GC window
|
||||
if ctrls and ctrls[0].TYPE_ID == message_control.TYPE_CHAT:
|
||||
return ctrls[0]
|
||||
|
||||
def policy(self, opdata=None, context=None):
|
||||
policy = gajim.config.get_per('contacts', context.username,
|
||||
"otr_flags")
|
||||
if policy <= 0:
|
||||
policy = gajim.config.get_per('contacts',
|
||||
gajim.get_jid_without_resource(
|
||||
context.username), 'otr_flags')
|
||||
if policy <= 0:
|
||||
policy = gajim.config.get_per('accounts',
|
||||
opdata['account'], 'otr_flags')
|
||||
return policy
|
||||
|
||||
def create_privkey(self, opdata='', accountname='', protocol=''):
|
||||
dialog = gtk.Dialog(
|
||||
title = _('Generating...'),
|
||||
parent = gajim.interface.roster.window,
|
||||
flags = gtk.DIALOG_MODAL,
|
||||
buttons = (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
|
||||
permlabel = gtk.Label(_('Generating a private key for %s...') \
|
||||
% accountname)
|
||||
permlabel.set_padding(20, 20)
|
||||
dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, False)
|
||||
dialog.connect('destroy', otr_dialog_destroy)
|
||||
dialog.connect('response', otr_dialog_destroy)
|
||||
dialog.vbox.pack_start(permlabel)
|
||||
dialog.get_root_window().raise_()
|
||||
dialog.show_all()
|
||||
dialog.map()
|
||||
for c in dialog.get_children():
|
||||
c.show_now()
|
||||
c.map()
|
||||
|
||||
while gtk.events_pending():
|
||||
gtk.main_iteration(block = False)
|
||||
|
||||
otr.otrl_privkey_generate(
|
||||
gajim.connections[opdata['account']].otr_userstates,
|
||||
os.path.join(gajimpaths.root,
|
||||
'%s.key' % opdata['account']).encode(),
|
||||
accountname, gajim.OTR_PROTO)
|
||||
permlabel.set_text(_('Generating a private key for %s...\n' \
|
||||
'done.') % accountname)
|
||||
dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, True)
|
||||
|
||||
def is_logged_in(self, opdata={}, accountname='', protocol='',
|
||||
recipient=""):
|
||||
contact = gajim.contacts.get_contact_from_full_jid(
|
||||
opdata['account'], recipient)
|
||||
if contact:
|
||||
return contact.show \
|
||||
in ['dnd', 'xa', 'chat', 'online', 'away',
|
||||
'invisible']
|
||||
return 0
|
||||
|
||||
def inject_message(self, opdata=None, accountname='', protocol='',
|
||||
recipient='', message=''):
|
||||
msg_type = otr.otrl_proto_message_type(message)
|
||||
|
||||
if 'kwargs' not in opdata or 'urgent' in opdata:
|
||||
# don't use send_message here to have the message
|
||||
# sent immediatly. This results in being able to
|
||||
# disconnect from OTR sessions before quitting
|
||||
stanza = XmppMessage(to = recipient,
|
||||
body = message, typ='chat')
|
||||
gajim.connections[opdata['account']].connection. \
|
||||
send(stanza, now = True)
|
||||
return
|
||||
|
||||
if msg_type == otr.OTRL_MSGTYPE_QUERY:
|
||||
# split away XHTML-contaminated explanatory message
|
||||
message = unicode(message.splitlines()[0])
|
||||
message += _(u'\nThis user has requested an ' \
|
||||
'Off-the-Record private conversation. ' \
|
||||
'However, you do not have a plugin to ' \
|
||||
'support that.\n' \
|
||||
'See http://otr.cypherpunks.ca/ for more ' \
|
||||
'information.')
|
||||
|
||||
gajim.connections[opdata['account']].connection.send(
|
||||
common.xmpp.Message(to = recipient,
|
||||
body = message, typ = 'chat'))
|
||||
return
|
||||
|
||||
gajim.connections[opdata['account']].send_message(recipient,
|
||||
message, **opdata['kwargs'])
|
||||
|
||||
def notify(sef, opdata=None, username='', **kwargs):
|
||||
self.gajim_log('Notify: ' + str(kwargs), opdata['account'],
|
||||
username)
|
||||
|
||||
def display_otr_message(self, opdata=None, username="", msg="", **kwargs):
|
||||
self.gajim_log('OTR Message: ' + msg, opdata['account'],
|
||||
username)
|
||||
return 0
|
||||
|
||||
def update_context_list(self, **kwargs):
|
||||
# FIXME stub FIXME #
|
||||
pass
|
||||
|
||||
def protocol_name(self, opdata=None, protocol=""):
|
||||
return 'XMPP'
|
||||
|
||||
def new_fingerprint(self, opdata=None, username='', fingerprint='',
|
||||
**kwargs):
|
||||
self.gajim_log('New fingerprint for %s: %s' % (username,
|
||||
otr.otrl_privkey_hash_to_human(fingerprint)),
|
||||
opdata['account'], username)
|
||||
|
||||
def write_fingerprints(self, opdata=''):
|
||||
otr.otrl_privkey_write_fingerprints(
|
||||
gajim.connections[opdata['account']].otr_userstates,
|
||||
os.path.join(gajimpaths.root, '%s.fpr' % \
|
||||
opdata['account']).encode())
|
||||
|
||||
def gone_secure(self, opdata='', context=None):
|
||||
trust = context.active_fingerprint.trust \
|
||||
and 'verified' or 'unverified'
|
||||
self.gajim_log('%s secured OTR connection started' % trust,
|
||||
opdata['account'], context.username, no_print = True)
|
||||
|
||||
ctrl = self.get_control(context.username, opdata['account'])
|
||||
if ctrl:
|
||||
ctrl.update_otr(True)
|
||||
|
||||
def gone_insecure(self, opdata='', context=None):
|
||||
self.gajim_log('Private conversation with %s lost.',
|
||||
opdata['account'], context.username)
|
||||
|
||||
ctrl = self.get_control(context.username, opdata['account'])
|
||||
if ctrl:
|
||||
ctrl.update_otr(True)
|
||||
|
||||
def still_secure(self, opdata=None, context=None, is_reply=0):
|
||||
ctrl = self.get_control(context.username, opdata['account'])
|
||||
if ctrl:
|
||||
ctrl.update_otr(True)
|
||||
|
||||
self.gajim_log('OTR connection was refreshed',
|
||||
opdata['account'], context.username)
|
||||
|
||||
def log_message(self, opdata=None, message=''):
|
||||
gajim.log.debug(message)
|
||||
|
||||
def max_message_size(self, **kwargs):
|
||||
return 0
|
||||
|
||||
def account_name(self, opdata=None, account='', protocol=''):
|
||||
return gajim.get_name_from_jid(opdata['account'],
|
||||
unicode(account))
|
||||
|
||||
gajim.otr_ui_ops = OtrlMessageAppOps()
|
||||
|
||||
if verbose: gajim.verbose = True
|
||||
del verbose
|
||||
|
||||
|
|
|
@ -163,46 +163,6 @@ class MessageControl:
|
|||
|
||||
self.set_session(sess)
|
||||
|
||||
xep_200 = bool(self.session) and self.session.enable_encryption
|
||||
|
||||
if gajim.otr_module and not xep_200 and (jid not in gajim.otr_dont_append_tag):
|
||||
if type == 'chat' and isinstance(message, unicode):
|
||||
d = {'kwargs': {'keyID': keyID, 'type': type,
|
||||
'chatstate': chatstate,
|
||||
'msg_id': msg_id,
|
||||
'composing_xep': composing_xep,
|
||||
'resource': self.resource,
|
||||
'user_nick': user_nick,
|
||||
'session': self.session,
|
||||
'original_message': original_message},
|
||||
'account': self.account}
|
||||
|
||||
new_msg = gajim.otr_module.otrl_message_sending(
|
||||
self.session.conn.otr_userstates,
|
||||
(gajim.otr_ui_ops, d),
|
||||
gajim.get_jid_from_account(
|
||||
self.account).encode(),
|
||||
gajim.OTR_PROTO,
|
||||
self.contact.get_full_jid().encode(),
|
||||
message.encode(), None,
|
||||
(gajim.otr_add_appdata, self.account))
|
||||
|
||||
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]
|
||||
|
||||
# we send all because inject_message can filter
|
||||
# on HTML stuff then
|
||||
gajim.otr_module.otrl_message_fragment_and_send(
|
||||
(gajim.otr_ui_ops, d), ctx, new_msg,
|
||||
gajim.otr_module.OTRL_FRAGMENT_SEND_ALL)
|
||||
return
|
||||
|
||||
# Send and update history
|
||||
return conn.send_message(jid, message, keyID, type = type,
|
||||
chatstate = chatstate, msg_id = msg_id, composing_xep = composing_xep,
|
||||
|
|
|
@ -1,357 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
## otr_windows.py
|
||||
##
|
||||
##
|
||||
## Copyright (C) 2008 Kjell Braden <fnord@pentabarf.de>
|
||||
##
|
||||
## 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 <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
import gtkgui_helpers
|
||||
from common import gajim
|
||||
|
||||
our_fp_text = _('Your fingerprint:\n' \
|
||||
'<span weight="bold" face="monospace">%s</span>')
|
||||
their_fp_text = _('Purported fingerprint for %s:\n' \
|
||||
'<span weight="bold" face="monospace">%s</span>')
|
||||
|
||||
class ContactOtrSMPWindow:
|
||||
def gw(self, n):
|
||||
# shorthand for self.xml.get_widget(n)
|
||||
return self.xml.get_widget(n)
|
||||
|
||||
def __init__(self, fjid, account):
|
||||
self.fjid = fjid
|
||||
self.account = account
|
||||
|
||||
self.xml = gtkgui_helpers.get_glade('contact_otr_window.glade')
|
||||
self.window = self.xml.get_widget('otr_smp_window')
|
||||
|
||||
# the contact may be unknown to gajim if ContactOtrSMPWindow
|
||||
# is created very early
|
||||
self.contact = gajim.contacts.get_contact_from_full_jid(
|
||||
account, fjid)
|
||||
if self.contact:
|
||||
self.window.set_title(_('OTR settings for %s') % \
|
||||
self.contact.get_full_jid())
|
||||
|
||||
self.ctx = gajim.otr_module.otrl_context_find(
|
||||
gajim.connections[self.account].otr_userstates,
|
||||
self.fjid.encode(), gajim.get_jid_from_account(
|
||||
self.account).encode(), gajim.OTR_PROTO, 1,
|
||||
(gajim.otr_add_appdata, self.account))[0]
|
||||
|
||||
self.gw('smp_cancel_button').connect('clicked',
|
||||
self._on_destroy)
|
||||
self.gw('smp_ok_button').connect('clicked', self._apply)
|
||||
|
||||
def show(self, response):
|
||||
# re-initialize if contact was unknown when we
|
||||
# initially initialized
|
||||
if not self.contact:
|
||||
self.__init__(self.fjid, self.account)
|
||||
# the contact MUST be known when showing the dialog
|
||||
assert(self.contact)
|
||||
|
||||
self.smp_running = False
|
||||
self.finished = False
|
||||
|
||||
self.gw('smp_cancel_button').set_sensitive(True)
|
||||
self.gw('smp_ok_button').set_sensitive(True)
|
||||
self.gw('progressbar').set_fraction(0)
|
||||
self.gw('secret_entry').set_text('')
|
||||
|
||||
self.response = response
|
||||
if response:
|
||||
self.gw('desc_label').set_markup(_('<b>%s is trying ' \
|
||||
'to authenticate you using a secret only ' \
|
||||
'known to him/her and you.</b> Please enter ' \
|
||||
'your secret below.') % \
|
||||
self.contact.get_full_jid())
|
||||
else:
|
||||
self.gw('desc_label').set_markup(_('<b>You are ' \
|
||||
'trying to authenticate %s using a secret' \
|
||||
'only known to him/her and yourself.</b>' \
|
||||
'Please enter your secret below.') % \
|
||||
self.contact.get_full_jid())
|
||||
|
||||
self.window.show_all()
|
||||
|
||||
def _abort(self, text=None):
|
||||
self.smp_running = False
|
||||
gajim.otr_module.otrl_message_abort_smp(
|
||||
gajim.connections[self.account].otr_userstates,
|
||||
(gajim.otr_ui_ops, {'account': self.account}), self.ctx)
|
||||
if text:
|
||||
gajim.otr_ui_ops.gajim_log(text, self.account,
|
||||
self.contact.get_full_jid())
|
||||
|
||||
def _finish(self, text):
|
||||
self.smp_running = False
|
||||
self.finished = True
|
||||
self.gw('smp_cancel_button').set_sensitive(False)
|
||||
self.gw('smp_ok_button').set_sensitive(True)
|
||||
self.gw('progressbar').set_fraction(1)
|
||||
gajim.otr_ui_ops.gajim_log(text, self.account,
|
||||
self.contact.get_full_jid())
|
||||
self.gw('desc_label').set_markup(text)
|
||||
for ctrl in gajim.interface.msg_win_mgr.get_chat_controls(
|
||||
self.contact.jid, self.account):
|
||||
ctrl.update_otr(True)
|
||||
gajim.otr_ui_ops.write_fingerprints({'account': self.account})
|
||||
|
||||
def handle_tlv(self, tlvs):
|
||||
if not self.contact:
|
||||
self.__init__(self.fjid, self.account)
|
||||
|
||||
if tlvs:
|
||||
nextTLV = self.ctx.smstate.nextExpected;
|
||||
tlv = gajim.otr_module.otrl_tlv_find(tlvs,
|
||||
gajim.otr_module.OTRL_TLV_SMP1)
|
||||
if tlv:
|
||||
if nextTLV != \
|
||||
gajim.otr_module.OTRL_SMP_EXPECT1:
|
||||
self._abort()
|
||||
else:
|
||||
self.show(True)
|
||||
self.gw('progressbar'). \
|
||||
set_fraction(0.3)
|
||||
tlv = gajim.otr_module.otrl_tlv_find(tlvs,
|
||||
gajim.otr_module.OTRL_TLV_SMP2)
|
||||
if tlv:
|
||||
if nextTLV != gajim.otr_module.OTRL_SMP_EXPECT2:
|
||||
self._abort()
|
||||
else:
|
||||
self.ctx.smstate.nextExpected = \
|
||||
gajim.otr_module. \
|
||||
OTRL_SMP_EXPECT4
|
||||
self.gw('progressbar').set_fraction(0.6)
|
||||
tlv = gajim.otr_module.otrl_tlv_find(tlvs,
|
||||
gajim.otr_module.OTRL_TLV_SMP3)
|
||||
if tlv:
|
||||
if nextTLV != gajim.otr_module.OTRL_SMP_EXPECT3:
|
||||
self._abort()
|
||||
else:
|
||||
self.ctx.smstate.nextExpected = \
|
||||
gajim.otr_module. \
|
||||
OTRL_SMP_EXPECT1;
|
||||
if self.ctx.active_fingerprint.trust:
|
||||
self._finish(_('SMP ' \
|
||||
'verifying succeeded'))
|
||||
else:
|
||||
self._finish(_('SMP ' \
|
||||
'verifying failed'))
|
||||
tlv = gajim.otr_module.otrl_tlv_find(tlvs,
|
||||
gajim.otr_module.OTRL_TLV_SMP4)
|
||||
if tlv:
|
||||
if nextTLV != gajim.otr_module.OTRL_SMP_EXPECT4:
|
||||
self._abort()
|
||||
else:
|
||||
self.ctx.smstate.nextExpected = \
|
||||
gajim.otr_module. \
|
||||
OTRL_SMP_EXPECT1;
|
||||
if self.ctx.active_fingerprint.trust:
|
||||
self._finish(_('SMP ' \
|
||||
'verifying succeeded'))
|
||||
else:
|
||||
self._finish(_('SMP ' \
|
||||
'verifying failed'))
|
||||
tlv = gajim.otr_module.otrl_tlv_find(tlvs,
|
||||
gajim.otr_module.OTRL_TLV_SMP_ABORT)
|
||||
if tlv:
|
||||
self._finish(_('SMP verifying aborted'))
|
||||
|
||||
def _on_destroy(self, widget):
|
||||
if self.smp_running:
|
||||
self._abort(_('user aborted SMP authentication'))
|
||||
self.window.hide_all()
|
||||
|
||||
def _apply(self, widget):
|
||||
if self.finished:
|
||||
self.window.hide_all()
|
||||
return
|
||||
secret = self.gw('secret_entry').get_text()
|
||||
if self.response:
|
||||
gajim.otr_module.otrl_message_respond_smp(
|
||||
gajim.connections[self.account].otr_userstates,
|
||||
(gajim.otr_ui_ops, {'account': self.account}),
|
||||
self.ctx, secret)
|
||||
else:
|
||||
gajim.otr_module.otrl_message_initiate_smp(
|
||||
gajim.connections[self.account].otr_userstates,
|
||||
(gajim.otr_ui_ops, {'account': self.account}),
|
||||
self.ctx, secret)
|
||||
self.gw('progressbar').set_fraction(0.3)
|
||||
self.smp_running = True
|
||||
widget.set_sensitive(False)
|
||||
|
||||
class ContactOtrWindow:
|
||||
def gw(self, n):
|
||||
# shorthand for self.xml.get_widget(n)
|
||||
return self.xml.get_widget(n)
|
||||
|
||||
def __init__(self, contact, account, ctrl=None):
|
||||
self.contact = contact
|
||||
self.account = account
|
||||
self.ctrl = ctrl
|
||||
|
||||
self.ctx = gajim.otr_module.otrl_context_find(
|
||||
gajim.connections[self.account].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]
|
||||
|
||||
self.xml = gtkgui_helpers.get_glade('contact_otr_window.glade')
|
||||
self.window = self.xml.get_widget('otr_settings_window')
|
||||
|
||||
self.gw('settings_cancel_button').connect('clicked',
|
||||
self._on_destroy)
|
||||
self.gw('settings_ok_button').connect('clicked', self._apply)
|
||||
self.gw('otr_default_checkbutton').connect('toggled',
|
||||
self._otr_default_checkbutton_toggled)
|
||||
|
||||
self.window.set_title(_('OTR settings for %s') % \
|
||||
self.contact.get_full_jid())
|
||||
|
||||
# always set the label containing our fingerprint
|
||||
self.gw('our_fp_label').set_markup(our_fp_text % \
|
||||
gajim.otr_module.otrl_privkey_fingerprint(
|
||||
gajim.connections[self.account].otr_userstates,
|
||||
gajim.get_jid_from_account(self.account).encode(),
|
||||
gajim.OTR_PROTO))
|
||||
|
||||
if self.ctx.msgstate != \
|
||||
gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED:
|
||||
# make the fingerprint widgets insensitive
|
||||
# when not encrypted
|
||||
for widget in self.gw('otr_fp_vbox').get_children():
|
||||
widget.set_sensitive(False)
|
||||
# show that the fingerprint is unknown
|
||||
self.gw('their_fp_label').set_markup(
|
||||
their_fp_text % (self.contact.get_full_jid(),
|
||||
_('unknown')))
|
||||
self.gw('verified_combobox').set_active(-1)
|
||||
else:
|
||||
# make the fingerprint widgets sensitive when encrypted
|
||||
for widget in self.gw('otr_fp_vbox').get_children():
|
||||
widget.set_sensitive(True)
|
||||
# show their fingerprint
|
||||
self.gw('their_fp_label').set_markup(
|
||||
their_fp_text%(self.contact.get_full_jid(),
|
||||
gajim.otr_module.otrl_privkey_hash_to_human(
|
||||
self.ctx.active_fingerprint.fingerprint)))
|
||||
# set the trust combobox
|
||||
if self.ctx.active_fingerprint.trust:
|
||||
self.gw('verified_combobox').set_active(1)
|
||||
else:
|
||||
self.gw('verified_combobox').set_active(0)
|
||||
|
||||
otr_flags = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'otr_flags')
|
||||
|
||||
if otr_flags >= 0:
|
||||
self.gw('otr_default_checkbutton').set_active(0)
|
||||
for w in self.gw('otr_settings_vbox').get_children():
|
||||
w.set_sensitive(True)
|
||||
else:
|
||||
# per-user settings not available,
|
||||
# using default settings
|
||||
otr_flags = gajim.config.get_per('accounts',
|
||||
self.account, 'otr_flags')
|
||||
self.gw('otr_default_checkbutton').set_active(1)
|
||||
for w in self.gw('otr_settings_vbox').get_children():
|
||||
w.set_sensitive(False)
|
||||
|
||||
self.gw('otr_policy_allow_v1_checkbutton').set_active(
|
||||
otr_flags & gajim.otr_module.OTRL_POLICY_ALLOW_V1)
|
||||
self.gw('otr_policy_allow_v2_checkbutton').set_active(
|
||||
otr_flags & gajim.otr_module.OTRL_POLICY_ALLOW_V2)
|
||||
self.gw('otr_policy_require_checkbutton').set_active(
|
||||
otr_flags & gajim.otr_module.OTRL_POLICY_REQUIRE_ENCRYPTION)
|
||||
self.gw('otr_policy_send_tag_checkbutton').set_active(
|
||||
otr_flags & \
|
||||
gajim.otr_module.OTRL_POLICY_SEND_WHITESPACE_TAG)
|
||||
self.gw('otr_policy_start_on_tag_checkbutton').set_active(
|
||||
otr_flags & \
|
||||
gajim.otr_module.OTRL_POLICY_WHITESPACE_START_AKE)
|
||||
self.gw('otr_policy_start_on_error_checkbutton').set_active(
|
||||
otr_flags & \
|
||||
gajim.otr_module.OTRL_POLICY_ERROR_START_AKE)
|
||||
|
||||
self.window.show_all()
|
||||
|
||||
def _on_destroy(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
def _apply(self, widget):
|
||||
# -1 when nothing is selected
|
||||
# (ie. the connection is not encrypted)
|
||||
trust_state = self.gw('verified_combobox').get_active()
|
||||
if trust_state == 1 and not self.ctx.active_fingerprint.trust:
|
||||
gajim.otr_module.otrl_context_set_trust(
|
||||
self.ctx.active_fingerprint, 'verified')
|
||||
gajim.otr_ui_ops.write_fingerprints(
|
||||
{'account': self.account})
|
||||
elif trust_state == 0:
|
||||
gajim.otr_module.otrl_context_set_trust(
|
||||
self.ctx.active_fingerprint, '')
|
||||
gajim.otr_ui_ops.write_fingerprints(
|
||||
{'account': self.account})
|
||||
|
||||
if not self.ctrl:
|
||||
self.ctrl = gajim.interface.msg_win_mgr.get_control(
|
||||
self.contact.jid, self.account)
|
||||
if self.ctrl:
|
||||
self.ctrl.update_otr(True)
|
||||
|
||||
if self.gw('otr_default_checkbutton').get_active():
|
||||
# default is enabled, so remove any user-specific
|
||||
# settings if available
|
||||
gajim.config.set_per('contacts',
|
||||
self.contact.jid, 'otr_flags', -1)
|
||||
else:
|
||||
# build the flags using the checkboxes
|
||||
flags = 0
|
||||
flags += self.gw('otr_policy_allow_v1_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_ALLOW_V1
|
||||
flags += self.gw('otr_policy_allow_v2_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_ALLOW_V2
|
||||
flags += self.gw('otr_policy_require_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_REQUIRE_ENCRYPTION
|
||||
flags += self.gw('otr_policy_send_tag_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_SEND_WHITESPACE_TAG
|
||||
flags += self.gw(
|
||||
'otr_policy_start_on_tag_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_WHITESPACE_START_AKE
|
||||
flags += self.gw(
|
||||
'otr_policy_start_on_error_checkbutton'). \
|
||||
get_active() and gajim.otr_module. \
|
||||
OTRL_POLICY_ERROR_START_AKE
|
||||
|
||||
gajim.config.add_per('contacts', self.contact.jid)
|
||||
gajim.config.set_per('contacts', self.contact.jid,
|
||||
'otr_flags', flags)
|
||||
|
||||
self._on_destroy(widget)
|
||||
|
||||
def _otr_default_checkbutton_toggled(self, widget):
|
||||
for w in self.gw('otr_settings_vbox').get_children():
|
||||
w.set_sensitive(not widget.get_active())
|
|
@ -1837,19 +1837,6 @@ class RosterWindow:
|
|||
elif gajim.sleeper_state[account] not in ('autoaway', 'autoxa'):
|
||||
gajim.sleeper_state[account] = 'off'
|
||||
|
||||
if gajim.otr_module:
|
||||
# disconnect from ENCRYPTED OTR contexts when going
|
||||
# offline/invisible
|
||||
if status == 'offline' or status == 'invisible':
|
||||
ctx = gajim.connections[account].otr_userstates.context_root
|
||||
while ctx is not None:
|
||||
if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED:
|
||||
disconnected = True
|
||||
gajim.otr_module.otrl_message_disconnect(gajim.connections[
|
||||
account].otr_userstates, (gajim.otr_ui_ops,
|
||||
{'account': account,'urgent': True}), ctx.accountname,
|
||||
ctx.protocol, ctx.username)
|
||||
ctx = ctx.next
|
||||
if to:
|
||||
gajim.connections[account].send_custom_status(status, txt, to)
|
||||
else:
|
||||
|
|
|
@ -72,7 +72,10 @@ class StatusIcon(systray.Systray):
|
|||
self.status_icon.set_tooltip(text)
|
||||
if gajim.events.get_nb_systray_events():
|
||||
if sys.platform == 'darwin':
|
||||
osx.nsapp.requestUserAttention()
|
||||
try:
|
||||
osx.nsapp.requestUserAttention()
|
||||
except NameError:
|
||||
pass
|
||||
state = 'event'
|
||||
self.status_icon.set_blinking(True)
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue