Changeset 9771
- Timestamp:
- 06/08/08 17:27:05 (3 months ago)
- Location:
- trunk
- Files:
-
- 2 removed
- 11 modified
-
data/glade/chat_control_popup_menu.glade (modified) (1 diff)
-
data/glade/contact_otr_window.glade (deleted)
-
src/chat_control.py (modified) (6 diffs)
-
src/common/config.py (modified) (2 diffs)
-
src/common/connection_handlers.py (modified) (2 diffs)
-
src/common/connection.py (modified) (1 diff)
-
src/common/gajim.py (modified) (1 diff)
-
src/features_window.py (modified) (2 diffs)
-
src/gajim.py (modified) (1 diff)
-
src/message_control.py (modified) (1 diff)
-
src/otr_windows.py (deleted)
-
src/roster_window.py (modified) (1 diff)
-
src/statusicon.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/glade/chat_control_popup_menu.glade
r9649 r9771 73 73 </child> 74 74 <child> 75 <widget class="GtkMenuItem" id="otr_submenu">76 <property name="visible">True</property>77 <property name="sensitive">False</property>78 <property name="label" translatable="yes">Off-the-Record Encryption</property>79 <property name="use_underline">True</property>80 <child>81 <widget class="GtkMenu" id="otr_submenu_menu">82 <child>83 <widget class="GtkMenuItem" id="otr_settings_menuitem">84 <property name="visible">True</property>85 <property name="label" translatable="yes">OTR settings / fingerprint</property>86 <property name="use_underline">True</property>87 <signal name="activate" handler="_on_otr_settings_menuitem_activate"/>88 </widget>89 </child>90 <child>91 <widget class="GtkMenuItem" id="smp_otr_menuitem">92 <property name="visible">True</property>93 <property name="label" translatable="yes">Authenticate contact</property>94 <property name="use_underline">True</property>95 <signal name="activate" handler="_on_smp_otr_menuitem_activate"/>96 </widget>97 </child>98 <child>99 <widget class="GtkMenuItem" id="start_otr_menuitem">100 <property name="visible">True</property>101 <property name="label" translatable="yes">Start / Refresh OTR</property>102 <property name="use_underline">True</property>103 <signal name="activate" handler="_on_start_otr_menuitem_activate"/>104 </widget>105 </child>106 <child>107 <widget class="GtkMenuItem" id="end_otr_menuitem">108 <property name="visible">True</property>109 <property name="sensitive">False</property>110 <property name="label" translatable="yes">End OTR </property>111 <property name="use_underline">True</property>112 <signal name="activate" handler="_on_end_otr_menuitem_activate"/>113 </widget>114 </child>115 </widget>116 </child>117 </widget>118 </child>119 <child>120 75 <widget class="GtkSeparatorMenuItem" id="separatormenuitem1"> 121 76 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> -
trunk/src/chat_control.py
r9761 r9771 1136 1136 self.status_tooltip = gtk.Tooltips() 1137 1137 1138 if gajim.otr_module:1139 self.update_otr(True)1140 1141 1138 self.update_ui() 1142 1139 # restore previous conversation … … 1207 1204 # The name banner is drawn here 1208 1205 ChatControlBase.update_ui(self) 1209 1210 def get_otr_status(self):1211 if not self.session:1212 return 01213 1214 ctx = gajim.otr_module.otrl_context_find(1215 self.session.conn.otr_userstates,1216 self.contact.get_full_jid().encode(),1217 gajim.get_jid_from_account(self.account).encode(),1218 gajim.OTR_PROTO, 1, (gajim.otr_add_appdata,1219 self.account))[0]1220 1221 if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED:1222 if ctx.active_fingerprint.trust:1223 return 21224 else:1225 return 11226 elif ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_FINISHED:1227 return 31228 return 01229 1230 def update_otr(self, print_status=False):1231 otr_status_text = ''1232 otr_status = self.get_otr_status()1233 authenticated = False1234 1235 if otr_status > 0:1236 enc_status = True1237 else:1238 enc_status = False1239 1240 if otr_status == 1:1241 otr_status_text = u'*unauthenticated* secure OTR ' + \1242 u'connection'1243 elif otr_status == 2:1244 otr_status_text = u'authenticated secure OTR ' + \1245 u'connection'1246 authenticated = True1247 elif otr_status == 3:1248 otr_status_text = u'finished OTR connection'1249 1250 self._show_lock_image(enc_status, u'OTR', enc_status, True,1251 authenticated)1252 if print_status and otr_status_text != '':1253 self.print_conversation_line(u'[OTR] %s' % \1254 otr_status_text, 'status', '', None)1255 1206 1256 1207 def _update_banner_state_image(self): … … 1659 1610 # ESessions 1660 1611 if not encrypted: 1661 msg = _('The following message was ' + \1662 'NOT encrypted')1663 ChatControlBase.print_conversation_line(1664 self, msg, 'status', '', tim)1665 elif gajim.otr_module and self.get_otr_status() > 0:1666 # OTR1667 # TODO: This is not shown when the window1668 # isn't open - needs fixing!1669 if not encrypted and frm == '':1670 1612 msg = _('The following message was ' + \ 1671 1613 'NOT encrypted') … … 1797 1739 toggle_gpg_menuitem = xml.get_widget('toggle_gpg_menuitem') 1798 1740 toggle_e2e_menuitem = xml.get_widget('toggle_e2e_menuitem') 1799 otr_submenu = xml.get_widget('otr_submenu')1800 otr_settings_menuitem = xml.get_widget('otr_settings_menuitem')1801 smp_otr_menuitem = xml.get_widget('smp_otr_menuitem')1802 start_otr_menuitem = xml.get_widget('start_otr_menuitem')1803 end_otr_menuitem = xml.get_widget('end_otr_menuitem')1804 1741 send_file_menuitem = xml.get_widget('send_file_menuitem') 1805 1742 information_menuitem = xml.get_widget('information_menuitem') … … 1894 1831 self.handlers[id] = convert_to_gc_menuitem 1895 1832 1896 if gajim.otr_module:1897 otr_submenu.set_sensitive(True)1898 id = otr_settings_menuitem.connect('activate',1899 self._on_otr_settings_menuitem_activate)1900 self.handlers[id] = otr_settings_menuitem1901 id = start_otr_menuitem.connect('activate',1902 self._on_start_otr_menuitem_activate)1903 self.handlers[id] = start_otr_menuitem1904 id = end_otr_menuitem.connect('activate',1905 self._on_end_otr_menuitem_activate)1906 self.handlers[id] = end_otr_menuitem1907 id = smp_otr_menuitem.connect('activate',1908 self._on_smp_otr_menuitem_activate)1909 self.handlers[id] = smp_otr_menuitem1910 1911 ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.account].otr_userstates,1912 self.contact.get_full_jid().encode(),1913 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1,1914 (gajim.otr_add_appdata, self.account))[0]1915 # can end only when PLAINTEXT1916 end_otr_menuitem.set_sensitive(ctx.msgstate !=1917 gajim.otr_module.OTRL_MSGSTATE_PLAINTEXT)1918 # can SMP only when ENCRYPTED1919 smp_otr_menuitem.set_sensitive(ctx.msgstate ==1920 gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED)1921 1922 1833 menu.connect('selection-done', self.destroy_menu, 1923 1834 send_file_menuitem, convert_to_gc_menuitem, … … 2407 2318 self.session.negotiate_e2e(False) 2408 2319 2409 def _on_start_otr_menuitem_activate(self, widget):2410 # ?OTR? gets replaced with a better message internally in otrl_message_sending2411 MessageControl.send_message(self, u'?OTR?', type='chat')2412 def _on_end_otr_menuitem_activate(self, widget):2413 fjid = self.contact.get_full_jid()2414 gajim.otr_module.otrl_message_disconnect(2415 self.session.conn.otr_userstates, (gajim.otr_ui_ops,2416 {'account': self.account, 'urgent': True}),2417 gajim.get_jid_from_account(self.account).encode(),2418 gajim.OTR_PROTO, fjid.encode())2419 gajim.otr_ui_ops.gajim_log(_('Private conversation with ' \2420 '%s lost.') % fjid, self.account, fjid.encode())2421 self.update_otr()2422 def _on_otr_settings_menuitem_activate(self, widget):2423 gajim.otr_windows.ContactOtrWindow(self.contact, self.account, self)2424 def _on_smp_otr_menuitem_activate(self, widget):2425 ctx = gajim.otr_module.otrl_context_find(gajim.connections[self.account].otr_userstates,2426 self.contact.get_full_jid().encode(),2427 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1,2428 (gajim.otr_add_appdata, self.account))[0]2429 ctx.app_data.show(False)2430 2431 2320 def got_connected(self): 2432 2321 ChatControlBase.got_connected(self) -
trunk/src/common/config.py
r9764 r9771 314 314 'answer_receipt' : [opt_bool, True, _('Answer to receipt requests')], 315 315 'request_receipt' : [opt_bool, True, _('Sent receipt requests')], 316 'otr_flags': [opt_int, 58 ],317 316 'publish_mood': [opt_bool, True], 318 317 'publish_activity': [opt_bool, True], … … 373 372 'gpg_enabled': [ opt_bool, False, _('Is OpenPGP enabled for this contact?')], 374 373 'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')], 375 'otr_flags': [opt_int, -1 ],376 374 }, {}), 377 375 'rooms': ({ -
trunk/src/common/connection_handlers.py
r9764 r9771 1219 1219 self.sessions = {} 1220 1220 1221 if gajim.otr_module:1222 self.otr_userstates = gajim.otr_module.otrl_userstate_create()1223 1224 1221 def _FeatureNegCB(self, con, stanza, session): 1225 1222 gajim.log.debug('FeatureNegCB') … … 1705 1702 receipt.setThread(thread_id) 1706 1703 con.send(receipt) 1707 1708 # We don't trust libotr, that's why we only pass the message1709 # to it if necessary. otrl_proto_message_type does this check.1710 if gajim.otr_module and not xep_200_encrypted \1711 and isinstance(msgtxt, unicode) and \1712 gajim.otr_module.otrl_proto_message_type(msgtxt.encode()) != \1713 gajim.otr_module.OTRL_MSGTYPE_NOTOTR:1714 # set to encrypted if it's really encrypted.1715 if gajim.otr_module.otrl_proto_message_type(1716 msgtxt.encode()) != \1717 gajim.otr_module.OTRL_MSGTYPE_TAGGEDPLAINTEXT:1718 encrypted = True1719 1720 # TODO: Do we really need .encode()?1721 # yes we do. OTR can't handle unicode.1722 otr_msg_tuple = \1723 gajim.otr_module.otrl_message_receiving(1724 self.otr_userstates,1725 (gajim.otr_ui_ops, {'account': self.name}),1726 gajim.get_jid_from_account(self.name).encode(),1727 gajim.OTR_PROTO,1728 frm.encode(),1729 msgtxt.encode(),1730 (gajim.otr_add_appdata, self.name))1731 msgtxt = unicode(otr_msg_tuple[1])1732 1733 html_node = msg.getTag('html')1734 if html_node:1735 msg.delChild(html_node)1736 msg.setBody(msgtxt)1737 1738 if gajim.otr_module.otrl_tlv_find(1739 otr_msg_tuple[2],1740 gajim.otr_module.OTRL_TLV_DISCONNECTED) != None:1741 gajim.otr_ui_ops.gajim_log(_('%s ' \1742 'has ended his/her private ' \1743 'conversation with you. You should ' \1744 'do the same.') % frm,1745 self.name,1746 frm.encode())1747 1748 ctrls = gajim.interface.msg_win_mgr.get_chat_controls(jid, self.name)1749 for ctrl in ctrls:1750 ctrl.update_otr()1751 1752 ctx = gajim.otr_module. \1753 otrl_context_find(1754 self.otr_userstates,1755 frm.encode(),1756 gajim.get_jid_from_account(1757 self.name).encode(),1758 gajim.OTR_PROTO, 1,1759 (gajim.otr_add_appdata,1760 self.name))[0]1761 tlvs = otr_msg_tuple[2]1762 ctx.app_data.handle_tlv(tlvs)1763 1764 if msgtxt == '':1765 return1766 elif msgtxt != None and msgtxt != '':1767 gajim.otr_dont_append_tag[frm] = True1768 1769 # We're also here if we just don't1770 # support OTR. Thus, we should strip1771 # the tags from plaintext messages1772 # since they look ugly.1773 msgtxt = msgtxt.replace('\x20\x09\x20' \1774 '\x20\x09\x09\x09\x09\x20\x09' \1775 '\x20\x09\x20\x09\x20\x20', '')1776 msgtxt = msgtxt.replace('\x20\x09\x20' \1777 '\x09\x20\x20\x09\x20', '')1778 msgtxt = msgtxt.replace('\x20\x20\x09' \1779 '\x09\x20\x20\x09\x20', '')1780 1704 1781 1705 if mtype != 'groupchat': -
trunk/src/common/connection.py
r9763 r9771 897 897 self.connect_and_auth() 898 898 899 if gajim.otr_module:900 try:901 gajim.otr_module.otrl_privkey_read(self.otr_userstates,902 os.path.join(gajim.gajimpaths.root,903 '%s.key' % self.name).encode())904 gajim.otr_module.otrl_privkey_read_fingerprints(905 self.otr_userstates, os.path.join(906 gajim.gajimpaths.root, '%s.fpr' %907 self.name).encode(),908 (gajim.otr_add_appdata, self.name))909 except Exception, e:910 if not hasattr(e, 'os_errno') or e.os_errno != 2:911 raise912 913 899 def _init_roster(self, con): 914 900 self.connection = con -
trunk/src/common/gajim.py
r9699 r9771 165 165 if system('gpg -h >/dev/null 2>&1'): 166 166 HAVE_GPG = False 167 168 OTR_PROTO = "xmpp"169 otr_userstates = {}170 otr_policy = {}171 172 # list of (full) jids not to attempt OTR with173 otr_dont_append_tag = {}174 167 175 168 gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'} -
trunk/src/features_window.py
r9661 r9771 100 100 _('Requires python-crypto.'), 101 101 _('Requires python-crypto.')), 102 _('Off the Record Encryption'): (self.otr_available,103 _('Encrypting chatmessages in a way that even works through gateways.'),104 _('Requires pyotr and libotr (see http://trac.gajim.org/wiki/OTR).'),105 _('Requires pyotr and libotr (see http://trac.gajim.org/wiki/OTR).')),106 102 _('RST Generator'): (self.docutils_available, 107 103 _('Generate XHTML output from RST code (see http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html).'), … … 313 309 return gajim.HAVE_PYCRYPTO 314 310 315 def otr_available(self):316 if gajim.otr_module:317 return True318 return False319 320 311 def docutils_available(self): 321 312 try: -
trunk/src/gajim.py
r9768 r9771 266 266 from common import optparser 267 267 from common import dataforms 268 269 from common.xmpp import Message as XmppMessage270 271 try:272 import otr, otr_windows273 gajim.otr_module = otr274 gajim.otr_windows = otr_windows275 except ImportError:276 gajim.otr_module = None277 gajim.otr_windows = None278 279 def add_appdata(data, context):280 account = data281 context.app_data = otr_windows.ContactOtrSMPWindow(282 unicode(context.username), account)283 284 gajim.otr_add_appdata = add_appdata285 286 def otr_dialog_destroy(widget, *args, **kwargs):287 widget.destroy()288 289 class OtrlMessageAppOps:290 def gajim_log(self, msg, account, fjid, no_print=False):291 if not isinstance(fjid, unicode):292 fjid = unicode(fjid)293 if not isinstance(account, unicode):294 account = unicode(account)295 resource=gajim.get_resource_from_jid(fjid)296 tim = time.localtime()297 298 if not no_print:299 ctrl = self.get_control(fjid, account)300 if ctrl:301 ctrl.print_conversation_line(u'[OTR] %s' % \302 msg, 'status', '', None)303 id = gajim.logger.write('chat_msg_recv', fjid,304 message='[OTR: %s]' % msg, tim=tim)305 # gajim.logger.write() only marks a message as unread306 # (and so only returns an id) when fjid is a real contact307 # (NOT if it's a GC private chat)308 if id:309 gajim.logger.set_read_messages([id])310 311 def get_control(self, fjid, account):312 # first try to get the window with the full jid313 ctrls = gajim.interface.msg_win_mgr.get_chat_controls(fjid, account)314 if ctrls:315 # got one, be happy316 return ctrls[0]317 318 # otherwise try without the resource319 ctrls = gajim.interface.msg_win_mgr.get_chat_controls(320 gajim.get_jid_without_resource(fjid), account)321 # but only use it when it is not a GC window322 if ctrls and ctrls[0].TYPE_ID == message_control.TYPE_CHAT:323 return ctrls[0]324 325 def policy(self, opdata=None, context=None):326 policy = gajim.config.get_per('contacts', context.username,327 "otr_flags")328 if policy <= 0:329 policy = gajim.config.get_per('contacts',330 gajim.get_jid_without_resource(331 context.username), 'otr_flags')332 if policy <= 0:333 policy = gajim.config.get_per('accounts',334 opdata['account'], 'otr_flags')335 return policy336 337 def create_privkey(self, opdata='', accountname='', protocol=''):338 dialog = gtk.Dialog(339 title = _('Generating...'),340 parent = gajim.interface.roster.window,341 flags = gtk.DIALOG_MODAL,342 buttons = (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))343 permlabel = gtk.Label(_('Generating a private key for %s...') \344 % accountname)345 permlabel.set_padding(20, 20)346 dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, False)347 dialog.connect('destroy', otr_dialog_destroy)348 dialog.connect('response', otr_dialog_destroy)349 dialog.vbox.pack_start(permlabel)350 dialog.get_root_window().raise_()351 dialog.show_all()352 dialog.map()353 for c in dialog.get_children():354 c.show_now()355 c.map()356 357 while gtk.events_pending():358 gtk.main_iteration(block = False)359 360 otr.otrl_privkey_generate(361 gajim.connections[opdata['account']].otr_userstates,362 os.path.join(gajimpaths.root,363 '%s.key' % opdata['account']).encode(),364 accountname, gajim.OTR_PROTO)365 permlabel.set_text(_('Generating a private key for %s...\n' \366 'done.') % accountname)367 dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, True)368 369 def is_logged_in(self, opdata={}, accountname='', protocol='',370 recipient=""):371 contact = gajim.contacts.get_contact_from_full_jid(372 opdata['account'], recipient)373 if contact:374 return contact.show \375 in ['dnd', 'xa', 'chat', 'online', 'away',376 'invisible']377 return 0378 379 def inject_message(self, opdata=None, accountname='', protocol='',380 recipient='', message=''):381 msg_type = otr.otrl_proto_message_type(message)382 383 if 'kwargs' not in opdata or 'urgent' in opdata:384 # don't use send_message here to have the message385 # sent immediatly. This results in being able to386 # disconnect from OTR sessions before quitting387 stanza = XmppMessage(to = recipient,388 body = message, typ='chat')389 gajim.connections[opdata['account']].connection. \390 send(stanza, now = True)391 return392 393 if msg_type == otr.OTRL_MSGTYPE_QUERY:394 # split away XHTML-contaminated explanatory message395 message = unicode(message.splitlines()[0])396 message += _(u'\nThis user has requested an ' \397 'Off-the-Record private conversation. ' \398 'However, you do not have a plugin to ' \399 'support that.\n' \400 'See http://otr.cypherpunks.ca/ for more ' \401 'information.')402 403 gajim.connections[opdata['account']].connection.send(404 common.xmpp.Message(to = recipient,405 body = message, typ = 'chat'))406 return407 408 gajim.connections[opdata['account']].send_message(recipient,409 message, **opdata['kwargs'])410 411 def notify(sef, opdata=None, username='', **kwargs):412 self.gajim_log('Notify: ' + str(kwargs), opdata['account'],413 username)414 415 def display_otr_message(self, opdata=None, username="", msg="", **kwargs):416 self.gajim_log('OTR Message: ' + msg, opdata['account'],417 username)418 return 0419 420 def update_context_list(self, **kwargs):421 # FIXME stub FIXME #422 pass423 424 def protocol_name(self, opdata=None, protocol=""):425 return 'XMPP'426 427 def new_fingerprint(self, opdata=None, username='', fingerprint='',428 **kwargs):429 self.gajim_log('New fingerprint for %s: %s' % (username,430 otr.otrl_privkey_hash_to_human(fingerprint)),431 opdata['account'], username)432 433 def write_fingerprints(self, opdata=''):434 otr.otrl_privkey_write_fingerprints(435 gajim.connections[opdata['account']].otr_userstates,436 os.path.join(gajimpaths.root, '%s.fpr' % \437 opdata['account']).encode())438 439 def gone_secure(self, opdata='', context=None):440 trust = context.active_fingerprint.trust \441 and 'verified' or 'unverified'442 self.gajim_log('%s secured OTR connection started' % trust,443 opdata['account'], context.username, no_print = True)444 445 ctrl = self.get_control(context.username, opdata['account'])446 if ctrl:447 ctrl.update_otr(True)448 449 def gone_insecure(self, opdata=''
