comparison src/browser/sat_browser/plugin_sec_otr.py @ 914:0c0551967bdf

server, browser: partial Libervia fix Libervia was broken following the refactorings. This commit partially fixes it : Libervia is starting, avatar, blog and message are working again, but not everything is restablished yet. following things have been fixed/changed: - new dependency: shortuuid - D-Bus bridge is working again - fixed naming in several bridge methods - register method changed to register_signal - fixed Chat widget, which was not working anymore since the refactoring - avatar now use avatarGet. Cache dir is accessible using a session specific uuid, to avoid cache leak (i.e. accessing cache of other profiles) - server: new uuid attribute in session data Browser code is not fully working yet, notably OTR and contact list are not fully fixed.
author Goffi <goffi@goffi.org>
date Sun, 26 Feb 2017 18:32:47 +0100
parents e8b133b77aa4
children fd4eae654182
comparison
equal deleted inserted replaced
913:58f611481e6d 914:0c0551967bdf
33 from constants import Const as C 33 from constants import Const as C
34 from sat_frontends.tools import jid 34 from sat_frontends.tools import jid
35 import otrjs_wrapper as otr 35 import otrjs_wrapper as otr
36 import dialog 36 import dialog
37 import chat 37 import chat
38 import uuid
39 import time
38 40
39 41
40 NS_OTR = "otr_plugin" 42 NS_OTR = "otr_plugin"
41 PRIVATE_KEY = "PRIVATE KEY" 43 PRIVATE_KEY = "PRIVATE KEY"
42 MAIN_MENU = D_('OTR') # TODO: get this constant directly from backend's plugin 44 MAIN_MENU = D_('OTR') # TODO: get this constant directly from backend's plugin
160 def receiveMessageCb(self, msg, encrypted): 162 def receiveMessageCb(self, msg, encrypted):
161 assert isinstance(self.peer, jid.JID) 163 assert isinstance(self.peer, jid.JID)
162 if not encrypted: 164 if not encrypted:
163 log.warning(u"A plain-text message has been handled by otr.js") 165 log.warning(u"A plain-text message has been handled by otr.js")
164 log.debug(u"message received (was %s): %s" % ('encrypted' if encrypted else 'plain', msg)) 166 log.debug(u"message received (was %s): %s" % ('encrypted' if encrypted else 'plain', msg))
167 uuid_ = str(uuid.uuid4()) # FIXME
165 if not encrypted: 168 if not encrypted:
166 if self.state == otr.context.STATE_ENCRYPTED: 169 if self.state == otr.context.STATE_ENCRYPTED:
167 log.warning(u"Received unencrypted message in an encrypted context (from %(jid)s)" % {'jid': self.peer}) 170 log.warning(u"Received unencrypted message in an encrypted context (from %(jid)s)" % {'jid': self.peer})
168 self.host.newMessageHandler(unicode(self.peer), RECEIVE_PLAIN_IN_ENCRYPTED_CONTEXT, C.MESS_TYPE_INFO, unicode(self.host.whoami), {}) 171 self.host.newMessageHandler(uuid_, time.time(), unicode(self.peer), unicode(self.host.whoami), {'': RECEIVE_PLAIN_IN_ENCRYPTED_CONTEXT}, {}, C.MESS_TYPE_INFO, {})
169 self.host.newMessageHandler(unicode(self.peer), msg, C.MESS_TYPE_CHAT, unicode(self.host.whoami), {}) 172 self.host.newMessageHandler(uuid_, time.time(), unicode(self.peer), unicode(self.host.whoami), {'': msg}, {}, C.MESS_TYPE_CHAT, {})
170 173
171 def sendMessageCb(self, msg, meta=None): 174 def sendMessageCb(self, msg, meta=None):
172 assert isinstance(self.peer, jid.JID) 175 assert isinstance(self.peer, jid.JID)
173 log.debug(u"message to send%s: %s" % ((' (attached meta data: %s)' % meta) if meta else '', msg)) 176 log.debug(u"message to send%s: %s" % ((' (attached meta data: %s)' % meta) if meta else '', msg))
174 self.host.bridge.call('sendMessage', (None, self.host.sendError), unicode(self.peer), msg, '', C.MESS_TYPE_CHAT, {'send_only': 'true'}) 177 self.host.bridge.call('sendMessage', (None, self.host.sendError), unicode(self.peer), msg, '', C.MESS_TYPE_CHAT, {'send_only': 'true'})
197 elif msg_state == otr.context.STATE_ENCRYPTED: 200 elif msg_state == otr.context.STATE_ENCRYPTED:
198 log.error(END_ENCRYPTED) 201 log.error(END_ENCRYPTED)
199 elif msg_state == otr.context.STATE_FINISHED: 202 elif msg_state == otr.context.STATE_FINISHED:
200 feedback = END_FINISHED 203 feedback = END_FINISHED
201 204
202 self.host.newMessageHandler(unicode(self.peer), feedback.format(jid=other_jid_s), C.MESS_TYPE_INFO, unicode(self.host.whoami), {'header_info': OTR.getInfoText(msg_state, trust)}) 205 uuid_ = str(uuid.uuid4()) # FIXME
206 self.host.newMessageHandler(uuid_, time.time(), unicode(self.peer), unicode(self.host.whoami), {'': feedback.format(jid=other_jid_s)}, {}, C.MESS_TYPE_INFO, {'header_info': OTR.getInfoText(msg_state, trust)})
203 207
204 def setCurrentTrust(self, new_trust='', act='asked', type_='trust'): 208 def setCurrentTrust(self, new_trust='', act='asked', type_='trust'):
205 log.debug(u"setCurrentTrust: trust={trust}, act={act}, type={type}".format(type=type_, trust=new_trust, act=act)) 209 log.debug(u"setCurrentTrust: trust={trust}, act={act}, type={type}".format(type=type_, trust=new_trust, act=act))
206 title = (AUTH_OTHER_TITLE if act == "asked" else AUTH_US_TITLE).format(jid=self.peer) 210 title = (AUTH_OTHER_TITLE if act == "asked" else AUTH_US_TITLE).format(jid=self.peer)
207 old_trust = self.getCurrentTrust() 211 old_trust = self.getCurrentTrust()
220 if act != "asked": 224 if act != "asked":
221 return 225 return
222 otr.context.Context.setCurrentTrust(self, new_trust) 226 otr.context.Context.setCurrentTrust(self, new_trust)
223 if old_trust != new_trust: 227 if old_trust != new_trust:
224 feedback = AUTH_STATUS.format(state=(AUTH_TRUSTED if new_trust else AUTH_UNTRUSTED).lower()) 228 feedback = AUTH_STATUS.format(state=(AUTH_TRUSTED if new_trust else AUTH_UNTRUSTED).lower())
225 self.host.newMessageHandler(unicode(self.peer), feedback, C.MESS_TYPE_INFO, unicode(self.host.whoami), {'header_info': OTR.getInfoText(self.state, new_trust)}) 229 uuid_ = str(uuid.uuid4()) # FIXME
230 self.host.newMessageHandler(uuid_, time.time(), unicode(self.peer), unicode(self.host.whoami), {'': feedback}, {}, C.MESS_TYPE_INFO, {'header_info': OTR.getInfoText(self.state, new_trust)})
226 231
227 def fingerprintAuthCb(self): 232 def fingerprintAuthCb(self):
228 """OTR v2 authentication using manual fingerprint comparison""" 233 """OTR v2 authentication using manual fingerprint comparison"""
229 priv_key = self.user.privkey 234 priv_key = self.user.privkey
230 235
386 def __init__(self, host): 391 def __init__(self, host):
387 log.info(_(u"OTR plugin initialization")) 392 log.info(_(u"OTR plugin initialization"))
388 self.host = host 393 self.host = host
389 self.context_manager = None 394 self.context_manager = None
390 self.host.bridge._registerMethods(["skipOTR"]) 395 self.host.bridge._registerMethods(["skipOTR"])
391 self.host.trigger.add("messageNewTrigger", self.newMessageTg, priority=trigger.TriggerManager.MAX_PRIORITY) # FIXME: need to be fixed after message refactoring 396 self.host.trigger.add("messageNewTrigger", self.newMessageTg, priority=trigger.TriggerManager.MAX_PRIORITY)
392 self.host.trigger.add("sendMessageTrigger", self.sendMessageTg, priority=trigger.TriggerManager.MAX_PRIORITY) 397 self.host.trigger.add("messageSendTrigger", self.sendMessageTg, priority=trigger.TriggerManager.MAX_PRIORITY)
393 398
394 # FIXME: workaround for a pyjamas issue: calling hash on a class method always return a different value if that method is defined directly within the class (with the "def" keyword) 399 # FIXME: workaround for a pyjamas issue: calling hash on a class method always return a different value if that method is defined directly within the class (with the "def" keyword)
395 self._profilePluggedListener = self.profilePluggedListener 400 self._profilePluggedListener = self.profilePluggedListener
396 self._gotMenusListener = self.gotMenusListener 401 self._gotMenusListener = self.gotMenusListener
397 # FIXME: these listeners are never removed, can't be removed by themselves (it modifies the list while looping), maybe need a 'one_shot' argument 402 # FIXME: these listeners are never removed, can't be removed by themselves (it modifies the list while looping), maybe need a 'one_shot' argument
451 456
452 def presenceListener(self, entity, show, priority, statuses, profile): 457 def presenceListener(self, entity, show, priority, statuses, profile):
453 if show == C.PRESENCE_UNAVAILABLE: 458 if show == C.PRESENCE_UNAVAILABLE:
454 self.endSession(entity, disconnect=False) 459 self.endSession(entity, disconnect=False)
455 460
456 def newMessageTg(self, from_jid, msg, msg_type, to_jid, extra, profile): 461 def newMessageTg(self, uid, timestamp, from_jid, to_jid, msg, subject, msg_type, extra, profile):
457 if msg_type != C.MESS_TYPE_CHAT: 462 if msg_type != C.MESS_TYPE_CHAT:
458 return True 463 return True
459 464
465 try:
466 msg = msg.values()[0] # FIXME: Q&D fix for message refactoring, message is now a dict
467 except IndexError:
468 return True
460 tag = otr.proto.checkForOTR(msg) 469 tag = otr.proto.checkForOTR(msg)
461 if tag is None or (tag == otr.context.WHITESPACE_TAG and not DEFAULT_POLICY_FLAGS['WHITESPACE_START_AKE']): 470 if tag is None or (tag == otr.context.WHITESPACE_TAG and not DEFAULT_POLICY_FLAGS['WHITESPACE_START_AKE']):
462 return True 471 return True
463 472
464 other_jid = to_jid if from_jid.bare == self.host.whoami.bare else from_jid 473 other_jid = to_jid if from_jid.bare == self.host.whoami.bare else from_jid
486 otrctx = self.context_manager.getContextForUser(to_jid, start=False) 495 otrctx = self.context_manager.getContextForUser(to_jid, start=False)
487 if otrctx is not None and otrctx.state != otr.context.STATE_PLAINTEXT: 496 if otrctx is not None and otrctx.state != otr.context.STATE_PLAINTEXT:
488 if otrctx.state == otr.context.STATE_ENCRYPTED: 497 if otrctx.state == otr.context.STATE_ENCRYPTED:
489 log.debug(u"encrypting message") 498 log.debug(u"encrypting message")
490 otrctx.sendMessage(message) 499 otrctx.sendMessage(message)
491 self.host.newMessageHandler(unicode(self.host.whoami), message, mess_type, unicode(to_jid), extra) 500 uuid_ = str(uuid.uuid4()) # FIXME
501 self.host.newMessageHandler(uuid_, time.time(), unicode(self.host.whoami), unicode(to_jid), {'': message}, {}, mess_type, extra)
492 else: 502 else:
493 feedback = SEND_PLAIN_IN_FINISHED_CONTEXT 503 feedback = SEND_PLAIN_IN_FINISHED_CONTEXT
494 dialog.InfoDialog(FINISHED_CONTEXT_TITLE.format(jid=to_jid), feedback, AddStyleName="maxWidthLimit").show() 504 dialog.InfoDialog(FINISHED_CONTEXT_TITLE.format(jid=to_jid), feedback, AddStyleName="maxWidthLimit").show()
495 return False # interrupt the main process 505 return False # interrupt the main process
496 506
509 else: # contact disconnected itself so we need to terminate the OTR session but the Chat panel lost its resource 519 else: # contact disconnected itself so we need to terminate the OTR session but the Chat panel lost its resource
510 contexts = self.context_manager.getContextsForBareUser(other_jid) 520 contexts = self.context_manager.getContextsForBareUser(other_jid)
511 for otrctx in contexts: 521 for otrctx in contexts:
512 if otrctx is None or otrctx.state == otr.context.STATE_PLAINTEXT: 522 if otrctx is None or otrctx.state == otr.context.STATE_PLAINTEXT:
513 if disconnect: 523 if disconnect:
514 self.host.newMessageHandler(unicode(other_jid), END_PLAIN_HAS_NOT.format(jid=other_jid), C.MESS_TYPE_INFO, unicode(self.host.whoami), {}) 524 uuid_ = str(uuid.uuid4()) # FIXME
525 self.host.newMessageHandler(uuid_, time.time(), unicode(other_jid), unicode(self.host.whoami), {'': END_PLAIN_HAS_NOT.format(jid=other_jid)}, {}, C.MESS_TYPE_INFO, {})
515 return 526 return
516 if disconnect: 527 if disconnect:
517 otrctx.disconnect() 528 otrctx.disconnect()
518 else: 529 else:
519 otrctx.finish() 530 otrctx.finish()