diff --git a/slixmpp/plugins/xep_0380/__init__.py b/slixmpp/plugins/xep_0380/__init__.py new file mode 100644 index 00000000..fec9f60f --- /dev/null +++ b/slixmpp/plugins/xep_0380/__init__.py @@ -0,0 +1,15 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2016 Emmanuel Gil Peyrot + This file is part of Slixmpp. + + See the file LICENSE for copying permission. +""" + +from slixmpp.plugins.base import register_plugin + +from slixmpp.plugins.xep_0380.stanza import Encryption +from slixmpp.plugins.xep_0380.eme import XEP_0380 + + +register_plugin(XEP_0380) diff --git a/slixmpp/plugins/xep_0380/eme.py b/slixmpp/plugins/xep_0380/eme.py new file mode 100644 index 00000000..7ff09f65 --- /dev/null +++ b/slixmpp/plugins/xep_0380/eme.py @@ -0,0 +1,66 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2016 Emmanuel Gil Peyrot + This file is part of Slixmpp. + + See the file LICENSE for copying permission. +""" + +import logging + +import slixmpp +from slixmpp.stanza import Message +from slixmpp.xmlstream.handler import Callback +from slixmpp.xmlstream.matcher import StanzaPath +from slixmpp.xmlstream import register_stanza_plugin, ElementBase, ET +from slixmpp.plugins import BasePlugin +from slixmpp.plugins.xep_0380 import stanza, Encryption + + +log = logging.getLogger(__name__) + + +class XEP_0380(BasePlugin): + + """ + XEP-0380: Explicit Message Encryption + """ + + name = 'xep_0380' + description = 'XEP-0380: Explicit Message Encryption' + dependencies = {'xep_0030'} + default_config = { + 'template': 'This message is encrypted with {name} ({namespace})', + } + + mechanisms = { + 'jabber:x:encrypted': 'Legacy OpenPGP', + 'urn:xmpp:ox:0': 'OpenPGP for XMPP', + 'urn:xmpp:otr:0': 'OTR', + 'eu.siacs.conversations.axolotl': 'Legacy OMEMO', + 'urn:xmpp:omemo:0': 'OMEMO', + } + + def plugin_init(self): + self.xmpp.register_handler( + Callback('Explicit Message Encryption', + StanzaPath('message/eme'), + self._handle_eme)) + + register_stanza_plugin(Message, Encryption) + + def plugin_end(self): + self.xmpp.remove_handler('Chat State') + + def session_bind(self, jid): + self.xmpp.plugin['xep_0030'].add_feature(Encryption.namespace) + + def replace_body_with_eme(self, msg): + eme = msg['eme'] + namespace = eme['namespace'] + name = self.mechanisms[namespace] if namespace in self.mechanisms else eme['name'] + body = self.config['template'].format(name=name, namespace=namespace) + msg['body'] = body + + def _handle_eme(self, msg): + self.xmpp.event('message_encryption', msg) diff --git a/slixmpp/plugins/xep_0380/stanza.py b/slixmpp/plugins/xep_0380/stanza.py new file mode 100644 index 00000000..7dd678b1 --- /dev/null +++ b/slixmpp/plugins/xep_0380/stanza.py @@ -0,0 +1,16 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2016 Emmanuel Gil Peyrot + This file is part of Slixmpp. + + See the file LICENSE for copying permission. +""" + +from slixmpp.xmlstream import ElementBase + + +class Encryption(ElementBase): + name = 'encryption' + namespace = 'urn:xmpp:eme:0' + plugin_attrib = 'eme' + interfaces = {'namespace', 'name'} diff --git a/tests/test_stanza_xep_0380.py b/tests/test_stanza_xep_0380.py new file mode 100644 index 00000000..9ed349bf --- /dev/null +++ b/tests/test_stanza_xep_0380.py @@ -0,0 +1,37 @@ +import unittest +from slixmpp import Message +from slixmpp.test import SlixTest +import slixmpp.plugins.xep_0380 as xep_0380 +from slixmpp.xmlstream import register_stanza_plugin + + +class TestEME(SlixTest): + + def setUp(self): + register_stanza_plugin(Message, xep_0380.stanza.Encryption) + + def testCreateEME(self): + """Testing creating EME.""" + + xmlstring = """ + + + + """ + + msg = self.Message() + self.check(msg, "") + + msg['eme']['namespace'] = 'urn:xmpp:otr:0' + self.check(msg, xmlstring % ('urn:xmpp:otr:0', '')) + + msg['eme']['namespace'] = 'urn:xmpp:openpgp:0' + self.check(msg, xmlstring % ('urn:xmpp:openpgp:0', '')) + + msg['eme']['name'] = 'OX' + self.check(msg, xmlstring % ('urn:xmpp:openpgp:0', ' name="OX"')) + + del msg['eme'] + self.check(msg, "") + +suite = unittest.TestLoader().loadTestsFromTestCase(TestEME)