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