comparison src/browser/sat_browser/plugin_sec_otr.py @ 525:307f84fee972

browser_side (plugin OTR): avoid unecessary waiting time on menu callbacks when the private key or the context doesn't exist
author souliane <souliane@mailoo.org>
date Wed, 03 Sep 2014 19:21:40 +0200
parents d41e850b31b9
children ac66b8b11ab8
comparison
equal deleted inserted replaced
524:d41e850b31b9 525:307f84fee972
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 45 FEEDBACK_NOT_PRIVATE = D_("You haven't started any private conversation with %s yet.")
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,
121 else: 121 else:
122 feedback = _("Error: successfully ake'd with %s but the conversation is not private!") 122 feedback = _("Error: successfully ake'd with %s but the conversation is not private!")
123 123
124 elif status == otr.context.STATUS_END_OTR: 124 elif status == otr.context.STATUS_END_OTR:
125 if msg_state == otr.context.STATE_PLAINTEXT: 125 if msg_state == otr.context.STATE_PLAINTEXT:
126 feedback = _("You haven't start any private conversation with %s yet.") 126 feedback = FEEDBACK_NOT_PRIVATE
127 elif msg_state == otr.context.STATE_ENCRYPTED: 127 elif msg_state == otr.context.STATE_ENCRYPTED:
128 feedback = _("%s has ended his/her private conversation with you; you should do the same.") 128 feedback = _("%s has ended his/her private conversation with you; you should do the same.")
129 elif msg_state == otr.context.STATE_FINISHED: 129 elif msg_state == otr.context.STATE_FINISHED:
130 feedback = _("Private conversation with %s lost.") 130 feedback = _("Private conversation with %s lost.")
131 131
251 def __init__(self, host): 251 def __init__(self, host):
252 self.host = host 252 self.host = host
253 self.account = Account(host) 253 self.account = Account(host)
254 self.contexts = {} 254 self.contexts = {}
255 255
256 def startContext(self, other_jid): 256 def startContext(self, other_jid, create=True):
257 assert isinstance(other_jid, jid.JID) 257 assert isinstance(other_jid, jid.JID)
258 # FIXME upstream: apparently pyjamas doesn't implement setdefault well, it ignores JID.__hash__ redefinition 258 # FIXME upstream: apparently pyjamas doesn't implement setdefault well, it ignores JID.__hash__ redefinition
259 #context = self.contexts.setdefault(other_jid, Context(self.host, self.account, other_jid)) 259 #context = self.contexts.setdefault(other_jid, Context(self.host, self.account, other_jid))
260 if other_jid not in self.contexts: 260 if other_jid not in self.contexts:
261 self.contexts[other_jid] = Context(self.host, self.account, other_jid) 261 if create:
262 self.contexts[other_jid] = Context(self.host, self.account, other_jid)
263 else:
264 return None
262 return self.contexts[other_jid] 265 return self.contexts[other_jid]
263 266
264 def getContextForUser(self, other): 267 def getContextForUser(self, other, create=True):
265 log.debug(u"getContextForUser [%s]" % other) 268 log.debug(u"getContextForUser [%s]" % other)
266 if not other.resource: 269 if not other.resource:
267 log.error("getContextForUser called with a bare jid") 270 log.error("getContextForUser called with a bare jid")
268 return self.startContext(other) 271 return self.startContext(other, create)
269 272
270 273
271 class OTR(object): 274 class OTR(object):
272 275
273 def __init__(self, host): 276 def __init__(self, host):
357 """End an OTR session 360 """End an OTR session
358 361
359 @param menu_data: %(menu_data)s 362 @param menu_data: %(menu_data)s
360 """ 363 """
361 def cb(other_jid): 364 def cb(other_jid):
362 otrctx = self.context_manager.getContextForUser(other_jid) 365 def not_available():
366 self.host.newMessageCb(other_jid, FEEDBACK_NOT_PRIVATE % other_jid.full(), "headline", self.host.whoami, {})
367
368 priv_key = self.context_manager.account.privkey
369 if priv_key is None:
370 not_available()
371 return
372
373 otrctx = self.context_manager.getContextForUser(other_jid, create=False)
374 if otrctx is None:
375 not_available()
376 return
363 otrctx.disconnect() 377 otrctx.disconnect()
364 try: 378 try:
365 other_jid = menu_data['jid'] 379 other_jid = menu_data['jid']
366 self.fixResource(other_jid, cb) 380 self.fixResource(other_jid, cb)
367 except KeyError: 381 except KeyError:
372 """Authenticate other user and see our own fingerprint 386 """Authenticate other user and see our own fingerprint
373 387
374 @param menu_data: %(menu_data)s 388 @param menu_data: %(menu_data)s
375 @param profile: %(doc_profile)s 389 @param profile: %(doc_profile)s
376 """ 390 """
391 def not_available():
392 dialog.InfoDialog(_("No running session"), _("You must start a private conversation before authenticating your correspondent."), AddStyleName="maxWidthLimit").show()
393
394 priv_key = self.context_manager.account.privkey
395 if priv_key is None:
396 not_available()
397 return
398
377 def cb(to_jid): 399 def cb(to_jid):
378 otrctx = self.context_manager.getContextForUser(to_jid) 400 otrctx = self.context_manager.getContextForUser(to_jid, create=False)
401 if otrctx is None:
402 not_available()
403 return
379 otr_version = otrctx.getUsedVersion() 404 otr_version = otrctx.getUsedVersion()
380 if otr_version == otr.context.OTR_VERSION_2: 405 if otr_version == otr.context.OTR_VERSION_2:
381 otrctx.fingerprintAuthCb() 406 otrctx.fingerprintAuthCb()
382 elif otr_version == otr.context.OTR_VERSION_3: 407 elif otr_version == otr.context.OTR_VERSION_3:
383 otrctx.smpAuthCb('question', None, 'asked') 408 otrctx.smpAuthCb('question', None, 'asked')
384 else: 409 else:
385 dialog.InfoDialog(_("No running session"), _("You must start a private conversation before authenticating your correspondent."), AddStyleName="maxWidthLimit").show() 410 not_available()
386 411
387 try: 412 try:
388 to_jid = menu_data['jid'] 413 to_jid = menu_data['jid']
389 self.fixResource(to_jid, cb) 414 self.fixResource(to_jid, cb)
390 except KeyError: 415 except KeyError:
395 """Drop our private Key 420 """Drop our private Key
396 421
397 @param menu_data: %(menu_data)s 422 @param menu_data: %(menu_data)s
398 @param profile: %(doc_profile)s 423 @param profile: %(doc_profile)s
399 """ 424 """
425 priv_key = self.context_manager.account.privkey
426 if priv_key is None:
427 # we have no private key yet
428 dialog.InfoDialog(_("No private key"), _("You don't have any private key yet."), AddStyleName="maxWidthLimit").show()
429 return
430
400 def cb(to_jid): 431 def cb(to_jid):
401 priv_key = self.context_manager.account.privkey
402
403 if priv_key is None:
404 # we have no private key yet
405 dialog.InfoDialog(_("No private key"), _("You don't have any private key yet!"), AddStyleName="maxWidthLimit").show()
406 return
407
408 def dropKey(confirm): 432 def dropKey(confirm):
409 if confirm: 433 if confirm:
410 # we end all sessions 434 # we end all sessions
411 for context in self.context_manager.contexts.values(): 435 for context in self.context_manager.contexts.values():
412 if context.state not in (otr.context.STATE_FINISHED, otr.context.STATE_PLAINTEXT): 436 if context.state not in (otr.context.STATE_FINISHED, otr.context.STATE_PLAINTEXT):