Changeset 9602
- Timestamp:
- 05/09/08 14:35:25 (3 months ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 modified
-
data/glade/chat_control_popup_menu.glade (modified) (1 diff)
-
data/glade/contact_otr_window.glade (added)
-
src/chat_control.py (modified) (4 diffs)
-
src/common/config.py (modified) (2 diffs)
-
src/common/connection_handlers.py (modified) (1 diff)
-
src/common/connection.py (modified) (3 diffs)
-
src/common/gajim.py (modified) (1 diff)
-
src/gajim.py (modified) (2 diffs)
-
src/message_control.py (modified) (2 diffs)
-
src/otr_windows.py (added)
-
src/roster_window.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/glade/chat_control_popup_menu.glade
r8891 r9602 73 73 </child> 74 74 <child> 75 <widget class="GtkMenuItem" id="otr_submenu"> 76 <property name="no_show_all">True</property> 77 <property name="label" translatable="yes">Off-the-Record Encryption</property> 78 <property name="use_underline">True</property> 79 <child> 80 <widget class="GtkMenu" id="otr_submenu_menu"> 81 <child> 82 <widget class="GtkMenuItem" id="otr_settings_menuitem"> 83 <property name="visible">True</property> 84 <property name="label" translatable="yes">OTR settings / fingerprint</property> 85 <property name="use_underline">True</property> 86 <signal name="activate" handler="_on_otr_settings_menuitem_activate"/> 87 </widget> 88 </child> 89 <child> 90 <widget class="GtkMenuItem" id="smp_otr_menuitem"> 91 <property name="visible">True</property> 92 <property name="label" translatable="yes">Authenticate contact</property> 93 <property name="use_underline">True</property> 94 <signal name="activate" handler="_on_smp_otr_menuitem_activate"/> 95 </widget> 96 </child> 97 <child> 98 <widget class="GtkMenuItem" id="start_otr_menuitem"> 99 <property name="visible">True</property> 100 <property name="label" translatable="yes">Start / Refresh OTR</property> 101 <property name="use_underline">True</property> 102 <signal name="activate" handler="_on_start_otr_menuitem_activate"/> 103 </widget> 104 </child> 105 <child> 106 <widget class="GtkMenuItem" id="end_otr_menuitem"> 107 <property name="visible">True</property> 108 <property name="sensitive">False</property> 109 <property name="label" translatable="yes">End OTR </property> 110 <property name="use_underline">True</property> 111 <signal name="activate" handler="_on_end_otr_menuitem_activate"/> 112 </widget> 113 </child> 114 </widget> 115 </child> 116 </widget> 117 </child> 118 <child> 75 119 <widget class="GtkSeparatorMenuItem" id="separatormenuitem1"> 76 120 <property name="visible">True</property> -
trunk/src/chat_control.py
r9601 r9602 1177 1177 1178 1178 def update_ui(self): 1179 if gajim.otr_module: 1180 self.update_otr(True) 1179 1181 # The name banner is drawn here 1180 1182 ChatControlBase.update_ui(self) 1183 1184 def update_otr(self, print_status=False): 1185 # retrieve the OTR context from the chat's contact data 1186 ctx = gajim.otr_module.otrl_context_find(gajim.otr_userstates[self.account], 1187 self.contact.get_full_jid().encode(), 1188 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1, 1189 (gajim.otr_add_appdata, self.account))[0] 1190 1191 enc_status = False 1192 otr_status_text = "" 1193 if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED: 1194 enc_status = True 1195 if ctx.active_fingerprint.trust: 1196 otr_status_text = u"authenticated secure OTR connection" 1197 else: 1198 otr_status_text = u'*unauthenticated* secure OTR connection' 1199 elif ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_FINISHED: 1200 enc_status = True 1201 otr_status_text = u"finished OTR connection" 1202 else: 1203 # nothing to print 1204 print_status = False 1205 self._show_lock_image(enc_status, u'OTR', enc_status, True) 1206 if print_status: 1207 self.print_conversation_line(u" [OTR] %s"%otr_status_text, 'status', 1208 '', None) 1181 1209 1182 1210 def _update_banner_state_image(self): … … 1697 1725 toggle_gpg_menuitem = xml.get_widget('toggle_gpg_menuitem') 1698 1726 toggle_e2e_menuitem = xml.get_widget('toggle_e2e_menuitem') 1727 otr_submenu = xml.get_widget('otr_submenu') 1728 otr_settings_menuitem = xml.get_widget('otr_settings_menuitem') 1729 smp_otr_menuitem = xml.get_widget('smp_otr_menuitem') 1730 start_otr_menuitem = xml.get_widget('start_otr_menuitem') 1731 end_otr_menuitem = xml.get_widget('end_otr_menuitem') 1699 1732 add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem') 1700 1733 send_file_menuitem = xml.get_widget('send_file_menuitem') … … 1782 1815 self._on_convert_to_gc_menuitem_activate) 1783 1816 self.handlers[id] = convert_to_gc_menuitem 1817 1818 if gajim.otr_module: 1819 otr_submenu.show() 1820 id = otr_settings_menuitem.connect('activate', 1821 self._on_otr_settings_menuitem_activate) 1822 self.handlers[id] = otr_settings_menuitem 1823 id = start_otr_menuitem.connect('activate', 1824 self._on_start_otr_menuitem_activate) 1825 self.handlers[id] = start_otr_menuitem 1826 id = end_otr_menuitem.connect('activate', 1827 self._on_end_otr_menuitem_activate) 1828 self.handlers[id] = end_otr_menuitem 1829 id = smp_otr_menuitem.connect('activate', 1830 self._on_smp_otr_menuitem_activate) 1831 self.handlers[id] = smp_otr_menuitem 1832 1833 ctx = gajim.otr_module.otrl_context_find(gajim.otr_userstates[self.account], 1834 self.contact.get_full_jid().encode(), 1835 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1, 1836 (gajim.otr_add_appdata, self.account))[0] 1837 # can end only when PLAINTEXT 1838 end_otr_menuitem.set_sensitive(ctx.msgstate != 1839 gajim.otr_module.OTRL_MSGSTATE_PLAINTEXT) 1840 # can SMP only when ENCRYPTED 1841 smp_otr_menuitem.set_sensitive(ctx.msgstate == 1842 gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED) 1843 1784 1844 menu.connect('selection-done', self.destroy_menu, history_menuitem, 1785 1845 information_menuitem) … … 2260 2320 self.session.negotiate_e2e(False) 2261 2321 2322 def _on_start_otr_menuitem_activate(self, widget): 2323 # ?OTR? gets replaced with a better message internally in otrl_message_sending 2324 MessageControl.send_message(self, u"?OTR?", type="chat") 2325 def _on_end_otr_menuitem_activate(self, widget): 2326 fjid = self.contact.get_full_jid() 2327 gajim.otr_module.otrl_message_disconnect(gajim.otr_userstates[self.account], 2328 (gajim.otr_ui_ops, {'account':self.account,'urgent':True}), 2329 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 2330 fjid.encode()) 2331 gajim.otr_ui_ops.gajim_log("Private conversation with %s lost."%fjid, 2332 self.account, fjid.encode()) 2333 self.update_ui() 2334 def _on_otr_settings_menuitem_activate(self, widget): 2335 gajim.otr_windows.ContactOtrWindow(self.contact, self.account, self) 2336 def _on_smp_otr_menuitem_activate(self, widget): 2337 ctx = gajim.otr_module.otrl_context_find(gajim.otr_userstates[self.account], 2338 self.contact.get_full_jid().encode(), 2339 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 1, 2340 (gajim.otr_add_appdata, self.account))[0] 2341 ctx.app_data.show(False) 2342 2262 2343 def got_connected(self): 2263 2344 ChatControlBase.got_connected(self) -
trunk/src/common/config.py
r9585 r9602 320 320 'zeroconf_email': [ opt_str, '', '', True ], 321 321 'use_env_http_proxy' : [opt_bool, False], 322 'otr_flags': [opt_int, 59 ], 322 323 }, {}), 323 324 'statusmsg': ({ … … 370 371 'gpg_enabled': [ opt_bool, False, _('Is OpenPGP enabled for this contact?')], 371 372 'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')], 373 'otr_flags': [opt_int, -1 ], 372 374 }, {}), 373 375 'rooms': ({ -
trunk/src/common/connection_handlers.py
r9585 r9602 1678 1678 return 1679 1679 elif mtype == 'chat': # it's type 'chat' 1680 1681 if gajim.otr_module and isinstance(msgtxt, unicode): 1682 otr_msg_tuple = gajim.otr_module.otrl_message_receiving( 1683 gajim.otr_userstates[self.name], 1684 (gajim.otr_ui_ops, {'account':self.name}), 1685 gajim.get_jid_from_account(self.name).encode(), 1686 gajim.OTR_PROTO, frm.encode(), msgtxt.encode(), 1687 (gajim.otr_add_appdata, self.name)) 1688 msgtxt = unicode(otr_msg_tuple[1]) 1689 # OTR messages are unformatted, or rather contain the same 1690 # text in <body> and <html> 1691 msghtml = msgtxt 1692 1693 if gajim.otr_module.otrl_tlv_find(otr_msg_tuple[2], 1694 gajim.otr_module.OTRL_TLV_DISCONNECTED) != None: 1695 gajim.otr_ui_ops.gajim_log("%s has ended his/her private conversation" 1696 " with you; you should do the same."%frm, self.name, 1697 frm) 1698 ctrl = gajim.interface.msg_win_mgr.get_control(frm, self.name) 1699 if ctrl: 1700 ctrl.update_ui() 1701 1702 ctx = gajim.otr_module.otrl_context_find(gajim.otr_userstates[self.name], frm.encode(), 1703 gajim.get_jid_from_account(self.name).encode(), gajim.OTR_PROTO, 1, 1704 (gajim.otr_add_appdata, self.name))[0] 1705 tlvs = otr_msg_tuple[2] 1706 ctx.app_data.handle_tlv(tlvs) 1707 1680 1708 if not msg.getTag('body') and chatstate is None: #no <body> 1681 1709 return -
trunk/src/common/connection.py
r9579 r9602 1025 1025 def send_message(self, jid, msg, keyID, type='chat', subject='', 1026 1026 chatstate=None, msg_id=None, composing_xep=None, resource=None, 1027 user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None ):1027 user_nick=None, xhtml=None, session=None, forward_from=None, form_node=None, original_message=None): 1028 1028 if not self.connection: 1029 1029 return 1 … … 1117 1117 msg_iq = session.encrypt_stanza(msg_iq) 1118 1118 1119 1119 1120 self.connection.send(msg_iq) 1120 if not forward_from and session .is_loggable():1121 if not forward_from and session and session.is_loggable(): 1121 1122 no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')\ 1122 1123 .split() … … 1124 1125 if self.name not in no_log_for and ji not in no_log_for: 1125 1126 log_msg = msg 1127 if original_message != None: 1128 log_msg = original_message 1126 1129 if subject: 1127 1130 log_msg = _('Subject: %s\n%s') % (subject, msg) -
trunk/src/common/gajim.py
r9508 r9602 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 = {} 167 171 168 172 gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'} -
trunk/src/gajim.py
r9579 r9602 253 253 from common import optparser 254 254 from common import dataforms 255 256 from common.xmpp import Message as XmppMessage 257 258 try: 259 import otr, otr_windows 260 261 gajim.otr_module = otr 262 gajim.otr_windows = otr_windows 263 except ImportError: 264 gajim.otr_module = None 265 gajim.otr_windows = None 266 267 def add_appdata(data=None, context=None): 268 account = data 269 context.app_data = otr_windows.ContactOtrSMPWindow(unicode(context.username), 270 account) 271 272 gajim.otr_add_appdata = add_appdata 273 274 275 def otr_dialog_destroy(widget, *args, **kwargs): 276 widget.destroy() 277 278 class OtrlMessageAppOps: 279 280 def gajim_log(self, msg, account, fjid, no_print=False): 281 if not isinstance(fjid, unicode): 282 fjid = unicode(fjid) 283 if not isinstance(account, unicode): 284 account = unicode(account) 285 resource=gajim.get_resource_from_jid(fjid) 286 tim = time.localtime() 287 288 if not no_print: 289 ctrl = gajim.interface.msg_win_mgr.get_control( 290 gajim.get_jid_without_resource(fjid), account) 291 if ctrl: 292 ctrl.print_conversation_line(u" [OTR] %s"%msg, 'status', '', None) 293 id = gajim.logger.write('chat_msg_recv', fjid, message=msg, tim=tim) 294 gajim.logger.set_read_messages([id]) 295 296 def policy(self, opdata=None, context=None): 297 policy = gajim.config.get_per("contacts", 298 gajim.get_jid_without_resource(context.username), "otr_flags") 299 if policy <= 0: 300 policy = gajim.config.get_per("accounts", opdata['account'], "otr_flags") 301 return policy 302 303 def create_privkey(self, opdata="", accountname="", protocol=""): 304 dialog = gtk.Dialog(title=_("Generating..."), parent=gajim.interface.roster.window, 305 flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) 306 permlabel = gtk.Label("Generating a private key for %s..."%accountname) 307 permlabel.set_padding(20,20) 308 dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, False) 309 dialog.connect("destroy", otr_dialog_destroy) 310 dialog.connect("response", otr_dialog_destroy) 311 dialog.vbox.pack_start(permlabel) 312 dialog.get_root_window().raise_() 313 dialog.show_all() 314 dialog.map() 315 for c in dialog.get_children(): 316 c.show_now() 317 c.map() 318 319 while gtk.events_pending(): 320 gtk.main_iteration(block=False) 321 322 otr.otrl_privkey_generate(gajim.otr_userstates[opdata['account']], 323 os.path.join(gajimpaths.root, "%s.key"%opdata['account']).encode(), 324 accountname, gajim.OTR_PROTO) 325 permlabel.set_text("Generating a private key for %s...\ndone."%accountname) 326 dialog.set_response_sensitive(gtk.RESPONSE_CLOSE, True) 327 328 def is_logged_in(self, opdata={}, accountname="", protocol="", recipient=""): 329 return gajim.contacts.get_contact_from_full_jid(opdata['account'], recipient).show \ 330 in ['dnd', 'xa', 'chat', 'online', 'away', 'invisible'] 331 332 def inject_message(self, opdata=None, accountname="", protocol="", recipient="", 333 message=""): 334 msg_type = otr.otrl_proto_message_type(message) 335 336 if 'kwargs' not in opdata or 'urgent' in opdata: 337 # don't use send_message here to have the message sent immediatly. 338 # this results in being able to disconnect from OTR sessions before 339 # quitting 340 stanza = XmppMessage(to=recipient, body=message, typ="chat") 341 gajim.connections[opdata['account']].connection.send(stanza, now=True) 342 return 343 344 if msg_type == otr.OTRL_MSGTYPE_QUERY: 345 # split away XHTML-contaminated explanatory message 346 message = unicode(message.splitlines()[0]) 347 message += u"\n%s has requested an Off-the-Record private " \ 348 "conversation. However, you do not have a plugin to " \ 349 "support that.\nSee http://otr.cypherpunks.ca/ for more "\ 350 "information."%gajim.get_jid_from_account(opdata['account']) 351 352 gajim.connections[opdata['account']].send_message(recipient, message, 353 **opdata['kwargs']) 354 355 def notify(sef, opdata=None, username="", **kwargs): 356 self.gajim_log("Notify: "+str(kwargs), opdata['account'], username) 357 358 def display_otr_message(self, opdata=None, username="", msg="", **kwargs): 359 self.gajim_log("OTR Message: "+msg, opdata['account'], username) 360 return 0 361 362 def update_context_list(self, **kwargs): 363 # FIXME stub FIXME # 364 pass 365 366 def protocol_name(self, opdata=None, protocol=""): 367 return "XMPP" 368 369 def new_fingerprint(self, opdata=None, username="", fingerprint="", **kwargs): 370 self.gajim_log("New fingerprint for %s: %s"%(username, 371 otr.otrl_privkey_hash_to_human(fingerprint)), opdata['account'], username) 372 373 def write_fingerprints(self, opdata=""): 374 otr.otrl_privkey_write_fingerprints(gajim.otr_userstates[opdata['account']], 375 os.path.join(gajimpaths.root, "%s.fpr"%opdata['account']).encode()) 376 377 def gone_secure(self, opdata="", context=None): 378 trust = context.active_fingerprint.trust 379 if trust: 380 trust = "verified" 381 else: 382 trust = "unverified" 383 self.gajim_log("%s secured OTR connection started"%trust, 384 opdata['account'], context.username, no_print=True) 385 386 ctrl = gajim.interface.msg_win_mgr.get_control( 387 gajim.get_jid_without_resource(unicode(context.username)), 388 opdata['account']) 389 if ctrl: 390 ctrl.update_otr(True) 391 392 def gone_insecure(self, opdata="", context=None): 393 self.gajim_log("Private conversation with %s lost.", opdata['account'], context.username) 394 395 ctrl = gajim.interface.msg_win_mgr.get_control( 396 gajim.get_jid_without_resource(unicode(context.username)), 397 opdata['account']) 398 if ctrl: 399 ctrl.update_otr() 400 401 def still_secure(self, opdata=None, context=None, is_reply=0): 402 ctrl = gajim.interface.msg_win_mgr.get_control( 403 gajim.get_jid_without_resource(unicode(context.username)), 404 opdata['account']) 405 if ctrl: 406 ctrl.update_otr(True) 407 408 self.gajim_log("OTR connection was refreshed", opdata['account'], 409 context.username) 410 411 def log_message(self, opdata=None, message=""): 412 gajim.log.debug(message) 413 414 def max_message_size(self, **kwargs): 415 return 0 416 417 def account_name(self, opdata=None, account="",protocol=""): 418 return gajim.get_name_from_jid(opdata['account'], unicode(account)) 419 420 gajim.otr_ui_ops = OtrlMessageAppOps() 255 421 256 422 if verbose: gajim.verbose = True … … 3161 3327 gajim.transport_avatar[a] = {} 3162 3328 3329 if gajim.otr_module: 3330 gajim.otr_userstates[a] = otr.otrl_userstate_create() 3331 try: 3332 otr.otrl_privkey_read(gajim.otr_userstates[a], 3333 os.path.join(gajimpaths.root, "%s.key"%a).encode()) 3334 except Exception, e: 3335 if hasattr(e,"os_errno") and e.os_errno == 2: 3336 print "didn't find otr keyfile "+ \ 3337 (os.path.join(gajimpaths.root, "%s.key"%a).encode()) 3338 pass 3339 try: 3340 otr.otrl_privkey_read_fingerprints(gajim.otr_userstates[a], 3341 os.path.join(gajimpaths.root, "%s.fpr"%a).encode(), (add_appdata, a)) 3342 except Exception, e: 3343 if hasattr(e,"os_errno") and e.os_errno == 2: 3344 print "didn't find otr fingerprint file "+ \ 3345 (os.path.join(gajimpaths.root, "%s.fpr"%a).encode()) 3346 pass 3347 3163 3348 if gajim.config.get('remote_control'): 3164 3349 try: -
trunk/src/message_control.py
r9178 r9602 144 144 ''' 145 145 jid = self.contact.jid 146 original_message = message 146 147 147 148 if not self.session: … … 151 152 self.set_session(new_session) 152 153 154 if gajim.otr_module: 155 if type == 'chat' and isinstance(message, unicode): 156 d = {'kwargs':{'keyID':keyID, 'type':type, 157 'chatstate':chatstate, 'msg_id':msg_id, 158 'composing_xep':composing_xep, 'resource':self.resource, 159 'user_nick':user_nick, 'session':self.session, 160 'original_message':original_message}, 'account':self.account} 161 162 new_msg = gajim.otr_module.otrl_message_sending( 163 gajim.otr_userstates[self.account], 164 (gajim.otr_ui_ops, d), 165 gajim.get_jid_from_account(self.account).encode(), gajim.OTR_PROTO, 166 self.contact.get_full_jid().encode(), message.encode(), None) 167 168 context = gajim.otr_module.otrl_context_find( 169 gajim.otr_userstates[self.account], 170 self.contact.get_full_jid().encode(), 171 gajim.get_jid_from_account(self.account).encode(), 172 gajim.OTR_PROTO, 1)[0] 173 174 print repr(context.accountname), repr(context.username) 175 176 # we send all because inject_message can filter on HTML stuff then 177 gajim.otr_module.otrl_message_fragment_and_send( 178 (gajim.otr_ui_ops, d), 179 context, new_msg, gajim.otr_module.OTRL_FRAGMENT_SEND_ALL) 180 return 181 153 182 # Send and update history 154 183 return gajim.connections[self.account].send_message(jid, message, keyID, 155 184 type = type, chatstate = chatstate, msg_id = msg_id, 156 185 composing_xep = composing_xep, resource = self.resource, 157 user_nick = user_nick, session = self.session )186 user_nick = user_nick, session = self.session, original_message = original_message) -
trunk/src/roster_window.py
r9600 r9602 1772 1772 elif gajim.sleeper_state[account] not in ('autoaway', 'autoxa'): 1773 1773 gajim.sleeper_state[account] = 'off' 1774 1775 if gajim.otr_module: 1776 # disconnect from ENCRYPTED OTR contexts when going 1777 # offline/invisible 1778 if status == 'offline' or status == 'invisible': 1779 ctx = gajim.otr_userstates[account].context_root 1780 while ctx is not None: 1781 if ctx.msgstate == gajim.otr_module.OTRL_MSGSTATE_ENCRYPTED: 1782 disconnected = True 1783 gajim.otr_module.otrl_message_disconnect(gajim.otr_userstates[account], 1784 (gajim.otr_ui_ops, 1785 {'account':account,'urgent':True}), ctx.accountname, 1786 ctx.protocol, ctx.username) 1787 ctx = ctx.next 1774 1788 if to: 1775 1789 gajim.connections[account].send_custom_status(status, txt, to)
