diff 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
line wrap: on
line diff
--- a/src/plugins/plugin_sec_otr.py	Wed Aug 27 01:27:05 2014 +0200
+++ b/src/plugins/plugin_sec_otr.py	Wed Aug 27 01:27:24 2014 +0200
@@ -36,6 +36,7 @@
 PRIVATE_KEY = "PRIVATE KEY"
 MAIN_MENU = D_('OTR')
 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 !")
+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 ?")
 
 DEFAULT_POLICY_FLAGS = {
   'ALLOW_V1':False,
@@ -116,6 +117,7 @@
 
 
 class Account(potr.context.Account):
+    #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)
 
     def __init__(self, host, client):
         log.debug(u"new account: %s" % client.jid)
@@ -193,6 +195,7 @@
         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)
         host.importMenu((MAIN_MENU, D_("End session")), self._endSession, security_limit=0, help_string=D_("Finish an OTR session"), type_=C.MENU_SINGLE)
         host.importMenu((MAIN_MENU, D_("Authenticate")), self._authenticate, security_limit=0, help_string=D_("Authenticate user/see your fingerprint"), type_=C.MENU_SINGLE)
+        host.importMenu((MAIN_MENU, D_("Drop private key")), self._dropPrivKey, security_limit=0, type_=C.MENU_SINGLE)
 
     def _fixPotr(self):
         # FIXME: potr fix for bad unicode handling
@@ -329,6 +332,42 @@
         xmlui.addList("match", [('yes', _('yes')),('no', _('no'))], ['yes' if trusted else 'no'])
         return {'xmlui': xmlui.toXml()}
 
+    def _dropPrivKey(self, menu_data, profile):
+        """Drop our private Key
+
+        @param menu_data: %(menu_data)s
+        @param profile: %(doc_profile)s
+        """
+        try:
+            to_jid = jid.JID(menu_data['jid'])
+            if not to_jid.resource:
+                to_jid.resource = self.host.memory.getLastResource(to_jid, profile) # FIXME: temporary and unsecure, must be changed when frontends are refactored
+        except KeyError:
+            log.error(_("jid key is not present !"))
+            return defer.fail(exceptions.DataError)
+
+        client = self.host.getClient(profile)
+        if client.otr_priv_key is None:
+            return {'xmlui': xml_tools.note(_("You don't have a private key yet !")).toXml()}
+
+        def dropKey(data, profile):
+            if C.bool(data['answer']):
+                # we end all sessions
+                ctxMng = self.context_managers[profile]
+                for context in ctxMng.contexts.values():
+                    if context.state not in (potr.context.STATE_FINISHED, potr.context.STATE_PLAINTEXT):
+                        context.disconnect()
+                    client.otr_priv_key = None
+                    ctxMng.account.privkey = None
+                    ctxMng.account.getPrivkey() # as client.otr_priv_key and account.privkey are None, getPrivkey will generate a new key, and save it
+                return {'xmlui': xml_tools.note(_("Your private key has been dropped")).toXml()}
+            return {}
+
+        submit_id = self.host.registerCallback(dropKey, with_data=True, one_shot=True)
+
+        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)
+        return {'xmlui': confirm.toXml()}
+
     def _receivedTreatment(self, data, profile):
         from_jid = jid.JID(data['from'])
         log.debug(u"_receivedTreatment [from_jid = %s]" % from_jid)