From b4927cd30d3f02b6018949de761d9d71af375419 Mon Sep 17 00:00:00 2001
From: Kjell Braden <afflux.gajim@pentabarf.de>
Date: Mon, 16 Apr 2012 21:37:24 +0200
Subject: [PATCH] updated gotr to version 1.5

---
 gotr/manifest.ini |  2 +-
 gotr/otrmodule.py | 94 +++++++++++++++++++++++++++++++----------------
 2 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/gotr/manifest.ini b/gotr/manifest.ini
index 31d474ae..15cd2c63 100644
--- a/gotr/manifest.ini
+++ b/gotr/manifest.ini
@@ -1,7 +1,7 @@
 [info]
 name: Off-The-Record Encryption
 short_name: gotr
-version: 1.4
+version: 1.5
 description: See http://www.cypherpunks.ca/otr/
 authors: Kjell Braden <afflux.gajim@pentabarf.de>
 homepage: http://gajim-otr.pentabarf.de
diff --git a/gotr/otrmodule.py b/gotr/otrmodule.py
index 21711c88..4ce51997 100644
--- a/gotr/otrmodule.py
+++ b/gotr/otrmodule.py
@@ -24,12 +24,12 @@
 Off-The-Record encryption plugin.
 
 :author: Kjell self.Braden <kb.otr@pentabarf.de>
-:since: 20 May 2011
-:copyright: Copyright (2011) Kjell Braden <kb.otr@pentabarf.de>
+:since: 2008
+:copyright: Copyright 2008-2012 Kjell Braden <afflux@pentabarf.de>
 :license: GPL
 '''
 
-MINVERSION = (1,0,0,'beta4')
+MINVERSION = (1,0,0,'beta5')
 IGNORE = True
 PASS = False
 
@@ -77,11 +77,18 @@ try:
 except ImportError:
     HAS_POTR = False
 
+def get_jid_from_fjid(fjid):
+    return gajim.get_room_and_nick_from_fjid(fjid)[0]
+
 class GajimContext(potr.context.Context):
-    __slots__ = ['smpWindow']
+    # self.peer is fjid
+    # self.jid does not contain resource
+    __slots__ = ['smpWindow', 'jid']
 
     def __init__(self, account, peer):
         super(GajimContext, self).__init__(account, peer)
+        self.jid = get_jid_from_fjid(peer)
+        self.trustName = self.jid
         self.smpWindow = ui.ContactOtrSmpWindow(self)
 
     def inject(self, msg, appdata=None):
@@ -137,8 +144,7 @@ class GajimContext(potr.context.Context):
         self.user.plugin.update_context_list()
 
     def getPolicy(self, key):
-        jid = gajim.get_room_and_nick_from_fjid(self.peer)[0]
-        ret = self.user.plugin.get_flags(self.user.accountname, jid)[key]
+        ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key]
         log.debug('getPolicy(key=%s) = %s', key, ret)
         return ret
 
@@ -191,7 +197,8 @@ class GajimOtrAccount(potr.context.Account):
                     if acc != self.name or proto != PROTOCOL:
                         continue
 
-                    self.getContext(ctx, newCtxCb).setTrust(fpr, trust)
+                    jid = get_jid_from_fjid(ctx)
+                    self.setTrust(jid, fpr, trust)
         except IOError, e:
             if e.errno != 2:
                 log.exception('IOError occurred when loading fpr file for %s',
@@ -200,10 +207,10 @@ class GajimOtrAccount(potr.context.Account):
     def saveTrusts(self):
         try:
             with open(self.keyFilePath + '.fpr', 'w') as fprFile:
-                for uid, ctx in self.ctxs.iteritems():
-                    for fpr, trust in ctx.trust.iteritems():
+                for uid, trusts in self.trusts.iteritems():
+                    for fpr, trustVal in trusts.iteritems():
                         fprFile.write('\t'.join(
-                                (uid, self.name, PROTOCOL, fpr, trust)))
+                                (uid, self.name, PROTOCOL, fpr, trustVal)))
                         fprFile.write('\n')
         except IOError, e:
             log.exception('IOError occurred when loading fpr file for %s',
@@ -237,6 +244,7 @@ class OtrPlugin(GajimPlugin):
             acc = str(acc)
             if acc not in self.config or None not in self.config[acc]:
                 self.config[acc] = {None:DEFAULTFLAGS.copy()}
+        self.update_context_list()
 
     @log_calls('OtrPlugin')
     def activate(self):
@@ -370,27 +378,42 @@ class OtrPlugin(GajimPlugin):
     def update_context_list(self):
         self.config_dialog.fpr_model.clear()
         for us in self.us.itervalues():
-            for uid, ctx in us.ctxs.iteritems():
-                for fpr, trust in ctx.trust.iteritems():
-                    trust = False
-                    if ctx.state == potr.context.STATE_ENCRYPTED:
-                        if ctx.getCurrentKey().cfingerprint() == fpr:
-                            state = "encrypted"
-                            tip = enc_tip
-                            trust = bool(ctx.getCurrentTrust())
-                        else:
-                            state = "unused"
-                            tip = unused_tip
-                    elif ctx.state == potr.context.STATE_FINISHED:
-                        state = "finished"
-                        tip = ended_tip
-                    else:
-                        state = 'inactive'
-                        tip = inactive_tip
+            usedFpr = set()
+            for fjid, ctx in us.ctxs.iteritems():
+                # get active contexts first
+                key = ctx.getCurrentKey()
+                if not key:
+                    continue
+                fpr = key.cfingerprint()
+                usedFpr.add(fpr)
+
+                human_hash = potr.human_hash(fpr)
+                trust = bool(us.getTrust(ctx.trustName, fpr))
+
+                if ctx.state == potr.context.STATE_ENCRYPTED:
+                    state = "encrypted"
+                    tip = enc_tip
+                elif ctx.state == potr.context.STATE_FINISHED:
+                    state = "finished"
+                    tip = ended_tip
+                else:
+                    state = 'inactive'
+                    tip = inactive_tip
+
+                self.config_dialog.fpr_model.append((fjid, state, trust,
+                        '<tt>%s</tt>' % human_hash, us.name, tip, fpr))
+
+            for uid, trusts in us.trusts.iteritems():
+                for fpr, trust in trusts.iteritems():
+                    if fpr in usedFpr:
+                        continue
+
+                    state = 'inactive'
+                    tip = inactive_tip
 
                     human_hash = potr.human_hash(fpr)
 
-                    self.config_dialog.fpr_model.append((uid, state, trust,
+                    self.config_dialog.fpr_model.append((uid, state, bool(trust),
                             '<tt>%s</tt>' % human_hash, us.name, tip, fpr))
 
     @classmethod
@@ -470,22 +493,31 @@ class OtrPlugin(GajimPlugin):
             ctx = self.us[account].getContext(event.fjid)
             msgtxt, tlvs = ctx.receiveMessage(event.msgtxt,
                             appdata={'session':event.session})
+        except potr.context.NotOTRMessage, e:
+            # received message was not OTR - pass it on
+            return PASS
         except potr.context.UnencryptedMessage, e:
+            # we are encrypted but got some plaintext
+            # display it with a warning
             tlvs = []
             msgtxt = _('The following message received from %(jid)s was '
                     '*not encrypted*: [%(error)s]') % {'jid': event.fjid,
                     'error': e.args[0]}
         except potr.context.NotEncryptedError, e:
+            # we got some encrypted data
+            # but we don't have an encrypted session
             self.gajim_log(_('The encrypted message received from %s is '
                     'unreadable, as you are not currently communicating '
                     'privately') % event.fjid, account, event.fjid)
             return IGNORE
         except potr.context.ErrorReceived, e:
+            # got a protocol error
             self.gajim_log(_('We received the following OTR error '
                     'message from %(jid)s: [%(error)s]') % {'jid': event.fjid,
                     'error': e.args[0].error})
             return IGNORE
         except RuntimeError, e:
+            # generic library bug?
             self.gajim_log(_('The following error occurred when trying to '
                     'decrypt a message from %(jid)s: [%(error)s]') % {
                     'jid': event.fjid, 'error': e},
@@ -494,12 +526,12 @@ class OtrPlugin(GajimPlugin):
 
         if ctx is not None:
             ctx.smpWindow.handle_tlv(tlvs)
-        if not msgtxt:
-            return IGNORE
 
-        event.msgtxt = unicode(msgtxt)
+        event.msgtxt = unicode(msgtxt or '')
         event.stanza.setBody(event.msgtxt)
 
+        # every message that went through OTR (ie. was OTR-related) gets
+        # stripped from html. I don't like html.
         html_node = event.stanza.getTag('html')
         if html_node:
             event.stanza.delChild(html_node)
-- 
GitLab