comparison src/browser/sat_browser/plugin_sec_otr.py @ 530:1735aaeac652

plugin OTR: forces FINISHED state if we are in ENCRYPTED state on contact disconnection
author souliane <souliane@mailoo.org>
date Fri, 05 Sep 2014 11:53:55 +0200
parents 9bfd71e2b35c
children 793f12d1f970
comparison
equal deleted inserted replaced
529:9bfd71e2b35c 530:1735aaeac652
40 AUTH_INFO_TXT = D_("Authenticating a correspondent helps ensure that the person you are talking to is who he or she claims to be.{eol}{eol}").format(eol=DIALOG_EOL) 40 AUTH_INFO_TXT = D_("Authenticating a correspondent helps ensure that the person you are talking to is who he or she claims to be.{eol}{eol}").format(eol=DIALOG_EOL)
41 AUTH_FINGERPRINT_TXT = D_("<i>To verify the fingerprint, contact your correspondent via some other authenticated channel (i.e. not in this chat), such as the telephone or GPG-signed email. Each of you should tell your fingerprint to the other.</i>{eol}{eol}").format(eol=DIALOG_EOL) 41 AUTH_FINGERPRINT_TXT = D_("<i>To verify the fingerprint, contact your correspondent via some other authenticated channel (i.e. not in this chat), such as the telephone or GPG-signed email. Each of you should tell your fingerprint to the other.</i>{eol}{eol}").format(eol=DIALOG_EOL)
42 AUTH_QUEST_DEF = D_("<i>To authenticate using a question, pick a question whose answer is known only to you and your correspondent. Enter this question and this answer, then wait for your correspondent to enter the answer too. If the answers don't match, then you may be talking to an imposter.</i>{eol}{eol}").format(eol=DIALOG_EOL) 42 AUTH_QUEST_DEF = D_("<i>To authenticate using a question, pick a question whose answer is known only to you and your correspondent. Enter this question and this answer, then wait for your correspondent to enter the answer too. If the answers don't match, then you may be talking to an imposter.</i>{eol}{eol}").format(eol=DIALOG_EOL)
43 AUTH_QUEST_ASK = D_("<i>Your correspondent is attempting to determine if he or she is really talking to you, or if it's someone pretending to be you. Your correspondent has asked a question, indicated below. To authenticate to your correspondent, enter the answer and click OK.</i>{eol}{eol}").format(eol=DIALOG_EOL) 43 AUTH_QUEST_ASK = D_("<i>Your correspondent is attempting to determine if he or she is really talking to you, or if it's someone pretending to be you. Your correspondent has asked a question, indicated below. To authenticate to your correspondent, enter the answer and click OK.</i>{eol}{eol}").format(eol=DIALOG_EOL)
44 AUTH_SECRET_TXT = D_("{eol}{eol}Enter secret answer here: (case sensitive){eol}").format(eol=DIALOG_EOL) 44 AUTH_SECRET_TXT = D_("{eol}{eol}Enter secret answer here: (case sensitive){eol}").format(eol=DIALOG_EOL)
45 FEEDBACK_NOT_PRIVATE = D_("You haven't started any private conversation with %s yet.") 45 FEEDBACK_NOT_PRIVATE = D_("Your conversation with %s is not encrypted.")
46 46
47 DROP_TXT = D_("You private key is used to encrypt messages for your correspondent, nobody except you must know it, if you are in doubt, you should drop it!{eol}{eol}Are you sure you want to drop your private key?").format(eol=DIALOG_EOL) 47 DROP_TXT = D_("You private key is used to encrypt messages for your correspondent, nobody except you must know it, if you are in doubt, you should drop it!{eol}{eol}Are you sure you want to drop your private key?").format(eol=DIALOG_EOL)
48 48
49 DEFAULT_POLICY_FLAGS = { 49 DEFAULT_POLICY_FLAGS = {
50 'ALLOW_V2': True, 50 'ALLOW_V2': True,
223 def disconnect(self): 223 def disconnect(self):
224 """Disconnect the session.""" 224 """Disconnect the session."""
225 if self.state != otr.context.STATE_PLAINTEXT: 225 if self.state != otr.context.STATE_PLAINTEXT:
226 super(Context, self).disconnect() 226 super(Context, self).disconnect()
227 227
228 def finish(self):
229 """Finish the session - avoid to send any message but the user still has to end the session himself."""
230 if self.state == otr.context.STATE_ENCRYPTED:
231 super(Context, self).finish()
232
228 233
229 class Account(otr.context.Account): 234 class Account(otr.context.Account):
230 235
231 def __init__(self, host): 236 def __init__(self, host):
232 log.debug(u"new account: %s" % host.whoami.full()) 237 log.debug(u"new account: %s" % host.whoami.full())
264 #context = self.contexts.setdefault(other_jid, Context(self.host, self.account, other_jid)) 269 #context = self.contexts.setdefault(other_jid, Context(self.host, self.account, other_jid))
265 if other_jid not in self.contexts: 270 if other_jid not in self.contexts:
266 self.contexts[other_jid] = Context(self.host, self.account, other_jid) 271 self.contexts[other_jid] = Context(self.host, self.account, other_jid)
267 return self.contexts[other_jid] 272 return self.contexts[other_jid]
268 273
269 def getContextForUser(self, other, create=True): 274 def getContextForUser(self, other_jid, start=True):
270 log.debug(u"getContextForUser [%s]" % other) 275 """Get the context for the given JID
271 if not other.resource: 276
277 @param other_jid (JID): your correspondent
278 @param start (bool): start non-existing context if True
279 @return: Context
280 """
281 log.debug(u"getContextForUser [%s]" % other_jid)
282 if not other_jid.resource:
272 log.error("getContextForUser called with a bare jid") 283 log.error("getContextForUser called with a bare jid")
273 if start: 284 if start:
274 return self.startContext(other_jid) 285 return self.startContext(other_jid)
275 else: 286 else:
276 return self.contexts.get(other_jid, None) 287 return self.contexts.get(other_jid, None)
349 self.fixResource(to_jid, cb) 360 self.fixResource(to_jid, cb)
350 else: 361 else:
351 cb(to_jid) 362 cb(to_jid)
352 return False # interrupt the main process 363 return False # interrupt the main process
353 364
365 def presenceReceivedTrigger(self, entity, show, priority, statuses):
366 if show == "unavailable":
367 self.endSession(entity, finish=True)
368 return True
369
370 def endSession(self, other_jid, profile, finish=False):
371 """Finish or disconnect an OTR session
372
373 @param other_jid (JID): str
374 @param finish: if True, finish the session but do not disconnect it
375 @return: True if the session has been finished or disconnected, False if there was nothing to do
376 """
377 def cb(other_jid):
378 def not_available():
379 if not finish:
380 self.host.newMessageCb(other_jid, FEEDBACK_NOT_PRIVATE % other_jid.full(), "headline", self.host.whoami, {})
381
382 priv_key = self.context_manager.account.privkey
383 if priv_key is None:
384 not_available()
385 return
386
387 otrctx = self.context_manager.getContextForUser(other_jid, start=False)
388 if otrctx is None:
389 not_available()
390 return
391 if finish:
392 otrctx.finish()
393 else:
394 otrctx.disconnect()
395
396 self.fixResource(other_jid, cb)
397
354 # Menu callbacks 398 # Menu callbacks
355 399
356 def _startRefresh(self, menu_data): 400 def _startRefresh(self, menu_data):
357 """Start or refresh an OTR session 401 """Start or refresh an OTR session
358 402
372 def _endSession(self, menu_data): 416 def _endSession(self, menu_data):
373 """End an OTR session 417 """End an OTR session
374 418
375 @param menu_data: %(menu_data)s 419 @param menu_data: %(menu_data)s
376 """ 420 """
377 def cb(other_jid):
378 def not_available():
379 self.host.newMessageCb(other_jid, FEEDBACK_NOT_PRIVATE % other_jid.full(), "headline", self.host.whoami, {})
380
381 priv_key = self.context_manager.account.privkey
382 if priv_key is None:
383 not_available()
384 return
385
386 otrctx = self.context_manager.getContextForUser(other_jid, create=False)
387 if otrctx is None:
388 not_available()
389 return
390 otrctx.disconnect()
391 try: 421 try:
392 other_jid = menu_data['jid'] 422 other_jid = menu_data['jid']
393 self.fixResource(other_jid, cb)
394 except KeyError: 423 except KeyError:
395 log.error(_("jid key is not present !")) 424 log.error(_("jid key is not present !"))
396 return None 425 return None
426 self.endSession(other_jid)
397 427
398 def _authenticate(self, menu_data, profile): 428 def _authenticate(self, menu_data, profile):
399 """Authenticate other user and see our own fingerprint 429 """Authenticate other user and see our own fingerprint
400 430
401 @param menu_data: %(menu_data)s 431 @param menu_data: %(menu_data)s
459 to_jid = menu_data['jid'] 489 to_jid = menu_data['jid']
460 self.fixResource(to_jid, cb) 490 self.fixResource(to_jid, cb)
461 except KeyError: 491 except KeyError:
462 log.error(_("jid key is not present !")) 492 log.error(_("jid key is not present !"))
463 return None 493 return None
464