Changeset 9602 for trunk/src/gajim.py

Show
Ignore:
Timestamp:
05/09/08 14:35:25 (7 months ago)
Author:
js
Message:

Added OTR support.
Work done by Kjell Braden <fnord@…>.
Some fixes done by me.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/gajim.py

    r9579 r9602  
    253253from common import optparser 
    254254from common import dataforms 
     255 
     256from common.xmpp import Message as XmppMessage 
     257 
     258try: 
     259        import otr, otr_windows 
     260         
     261        gajim.otr_module = otr 
     262        gajim.otr_windows = otr_windows 
     263except ImportError: 
     264        gajim.otr_module = None 
     265        gajim.otr_windows = None 
     266 
     267def add_appdata(data=None, context=None): 
     268        account = data 
     269        context.app_data = otr_windows.ContactOtrSMPWindow(unicode(context.username), 
     270                account) 
     271 
     272gajim.otr_add_appdata = add_appdata 
     273 
     274 
     275def otr_dialog_destroy(widget, *args, **kwargs): 
     276        widget.destroy() 
     277 
     278class 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 
     420gajim.otr_ui_ops = OtrlMessageAppOps() 
    255421 
    256422if verbose: gajim.verbose = True 
     
    31613327                        gajim.transport_avatar[a] = {} 
    31623328 
     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 
    31633348                if gajim.config.get('remote_control'): 
    31643349                        try: