comparison src/plugins/plugin_sec_otr.py @ 1144:2481fa96ac1c

plugin OTR: added ability to drop private key
author Goffi <goffi@goffi.org>
date Wed, 27 Aug 2014 01:27:24 +0200
parents 7fcafc3206b1
children 1ac5ea74dbdf
comparison
equal deleted inserted replaced
1143:3164b509bc99 1144:2481fa96ac1c
34 34
35 NS_OTR = "otr_plugin" 35 NS_OTR = "otr_plugin"
36 PRIVATE_KEY = "PRIVATE KEY" 36 PRIVATE_KEY = "PRIVATE KEY"
37 MAIN_MENU = D_('OTR') 37 MAIN_MENU = D_('OTR')
38 AUTH_TXT = D_("To authenticate your correspondent, you need to give your below fingerprint *BY AN EXTERNAL CANAL* (i.e. not in this chat), and check that the one he give you is the same as below. If there is a mismatch, there can be a spy between you !") 38 AUTH_TXT = D_("To authenticate your correspondent, you need to give your below fingerprint *BY AN EXTERNAL CANAL* (i.e. not in this chat), and check that the one he give you is the same as below. If there is a mismatch, there can be a spy between you !")
39 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 !\n\nAre you sure you want to drop your private key ?")
39 40
40 DEFAULT_POLICY_FLAGS = { 41 DEFAULT_POLICY_FLAGS = {
41 'ALLOW_V1':False, 42 'ALLOW_V1':False,
42 'ALLOW_V2':True, 43 'ALLOW_V2':True,
43 'REQUIRE_ENCRYPTION':True, 44 'REQUIRE_ENCRYPTION':True,
114 profile=client.profile) 115 profile=client.profile)
115 # TODO: send signal to frontends 116 # TODO: send signal to frontends
116 117
117 118
118 class Account(potr.context.Account): 119 class Account(potr.context.Account):
120 #TODO: manage trusted keys: if a fingerprint is not used anymore, we have no way to remove it from database yet (same thing for a correspondent jid)
119 121
120 def __init__(self, host, client): 122 def __init__(self, host, client):
121 log.debug(u"new account: %s" % client.jid) 123 log.debug(u"new account: %s" % client.jid)
122 if not client.jid.resource: 124 if not client.jid.resource:
123 log.warning("Account created without resource") 125 log.warning("Account created without resource")
191 host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100000) 193 host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100000)
192 host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100000) 194 host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100000)
193 host.importMenu((MAIN_MENU, D_("Start/Refresh")), self._startRefresh, security_limit=0, help_string=D_("Start or refresh an OTR session"), type_=C.MENU_SINGLE) 195 host.importMenu((MAIN_MENU, D_("Start/Refresh")), self._startRefresh, security_limit=0, help_string=D_("Start or refresh an OTR session"), type_=C.MENU_SINGLE)
194 host.importMenu((MAIN_MENU, D_("End session")), self._endSession, security_limit=0, help_string=D_("Finish an OTR session"), type_=C.MENU_SINGLE) 196 host.importMenu((MAIN_MENU, D_("End session")), self._endSession, security_limit=0, help_string=D_("Finish an OTR session"), type_=C.MENU_SINGLE)
195 host.importMenu((MAIN_MENU, D_("Authenticate")), self._authenticate, security_limit=0, help_string=D_("Authenticate user/see your fingerprint"), type_=C.MENU_SINGLE) 197 host.importMenu((MAIN_MENU, D_("Authenticate")), self._authenticate, security_limit=0, help_string=D_("Authenticate user/see your fingerprint"), type_=C.MENU_SINGLE)
198 host.importMenu((MAIN_MENU, D_("Drop private key")), self._dropPrivKey, security_limit=0, type_=C.MENU_SINGLE)
196 199
197 def _fixPotr(self): 200 def _fixPotr(self):
198 # FIXME: potr fix for bad unicode handling 201 # FIXME: potr fix for bad unicode handling
199 # this method monkeypatch it, must be removed when potr 202 # this method monkeypatch it, must be removed when potr
200 # is fixed 203 # is fixed
327 xmlui.changeContainer('pairs') 330 xmlui.changeContainer('pairs')
328 xmlui.addLabel(_('Is your correspondent fingerprint the same as here ?')) 331 xmlui.addLabel(_('Is your correspondent fingerprint the same as here ?'))
329 xmlui.addList("match", [('yes', _('yes')),('no', _('no'))], ['yes' if trusted else 'no']) 332 xmlui.addList("match", [('yes', _('yes')),('no', _('no'))], ['yes' if trusted else 'no'])
330 return {'xmlui': xmlui.toXml()} 333 return {'xmlui': xmlui.toXml()}
331 334
335 def _dropPrivKey(self, menu_data, profile):
336 """Drop our private Key
337
338 @param menu_data: %(menu_data)s
339 @param profile: %(doc_profile)s
340 """
341 try:
342 to_jid = jid.JID(menu_data['jid'])
343 if not to_jid.resource:
344 to_jid.resource = self.host.memory.getLastResource(to_jid, profile) # FIXME: temporary and unsecure, must be changed when frontends are refactored
345 except KeyError:
346 log.error(_("jid key is not present !"))
347 return defer.fail(exceptions.DataError)
348
349 client = self.host.getClient(profile)
350 if client.otr_priv_key is None:
351 return {'xmlui': xml_tools.note(_("You don't have a private key yet !")).toXml()}
352
353 def dropKey(data, profile):
354 if C.bool(data['answer']):
355 # we end all sessions
356 ctxMng = self.context_managers[profile]
357 for context in ctxMng.contexts.values():
358 if context.state not in (potr.context.STATE_FINISHED, potr.context.STATE_PLAINTEXT):
359 context.disconnect()
360 client.otr_priv_key = None
361 ctxMng.account.privkey = None
362 ctxMng.account.getPrivkey() # as client.otr_priv_key and account.privkey are None, getPrivkey will generate a new key, and save it
363 return {'xmlui': xml_tools.note(_("Your private key has been dropped")).toXml()}
364 return {}
365
366 submit_id = self.host.registerCallback(dropKey, with_data=True, one_shot=True)
367
368 confirm = xml_tools.XMLUI(C.XMLUI_DIALOG, title=_('Confirm private key drop'), dialog_opt = {'type': C.XMLUI_DIALOG_CONFIRM, 'message': _(DROP_TXT)}, submit_id = submit_id)
369 return {'xmlui': confirm.toXml()}
370
332 def _receivedTreatment(self, data, profile): 371 def _receivedTreatment(self, data, profile):
333 from_jid = jid.JID(data['from']) 372 from_jid = jid.JID(data['from'])
334 log.debug(u"_receivedTreatment [from_jid = %s]" % from_jid) 373 log.debug(u"_receivedTreatment [from_jid = %s]" % from_jid)
335 otrctx = self.context_managers[profile].getContextForUser(from_jid) 374 otrctx = self.context_managers[profile].getContextForUser(from_jid)
336 encrypted = True 375 encrypted = True