Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0380.py @ 2750:ae495f27b316
plugin XEP-0380: Explicit Message Encryption implementation
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 04 Jan 2019 11:14:53 +0100 |
parents | |
children | 3bea6b5ae972 |
comparison
equal
deleted
inserted
replaced
2749:4b8271399f67 | 2750:ae495f27b316 |
---|---|
1 #!/usr/bin/env python2 | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # SAT plugin for Explicit Message Encryption | |
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from sat.core.i18n import _, D_ | |
21 from sat.core.constants import Const as C | |
22 from sat.core.log import getLogger | |
23 from twisted.words.protocols.jabber import jid | |
24 | |
25 log = getLogger(__name__) | |
26 | |
27 PLUGIN_INFO = { | |
28 C.PI_NAME: u"Explicit Message Encryption", | |
29 C.PI_IMPORT_NAME: u"XEP-0380", | |
30 C.PI_TYPE: u"SEC", | |
31 C.PI_PROTOCOLS: [u"XEP-0380"], | |
32 C.PI_DEPENDENCIES: [], | |
33 C.PI_MAIN: u"XEP_0380", | |
34 C.PI_HANDLER: u"no", | |
35 C.PI_DESCRIPTION: _(u"""Implementation of Explicit Message Encryption"""), | |
36 } | |
37 | |
38 NS_EME = u"urn:xmpp:eme:0" | |
39 KNOWN_NAMESPACES = { | |
40 u"urn:xmpp:otr:0": u"OTR", | |
41 u"jabber:x:encrypted": u"Legacy OpenPGP", | |
42 u"urn:xmpp:openpgp:0": u"OpenPGP for XMPP", | |
43 } | |
44 | |
45 | |
46 class XEP_0380(object): | |
47 | |
48 def __init__(self, host): | |
49 self.host = host | |
50 host.trigger.add("sendMessage", self._sendMessageTrigger) | |
51 host.trigger.add("MessageReceived", self._MessageReceivedTrigger, priority=100) | |
52 | |
53 def _addEMEElement(self, mess_data, namespace, name): | |
54 message_elt = mess_data[u'xml'] | |
55 encryption_elt = message_elt.addElement((NS_EME, u'encryption')) | |
56 encryption_elt[u'namespace'] = namespace | |
57 if name is not None: | |
58 encryption_elt[u'name'] = name | |
59 return mess_data | |
60 | |
61 def _sendMessageTrigger(self, client, mess_data, __, post_xml_treatments): | |
62 encryption = mess_data.get(C.MESS_KEY_ENCRYPTION) | |
63 if encryption is not None: | |
64 namespace = encryption['plugin'].namespace | |
65 if namespace not in KNOWN_NAMESPACES: | |
66 name = encryption[u'plugin'].name | |
67 else: | |
68 name = None | |
69 post_xml_treatments.addCallback( | |
70 self._addEMEElement, namespace=namespace, name=name) | |
71 return True | |
72 | |
73 def _MessageReceivedTrigger(self, client, message_elt, post_treat): | |
74 try: | |
75 encryption_elt = next(message_elt.elements(NS_EME, u'encryption')) | |
76 except StopIteration: | |
77 return True | |
78 | |
79 namespace = encryption_elt['namespace'] | |
80 if namespace in client.encryption.getNamespaces(): | |
81 # message is encrypted and we can decrypt it | |
82 return True | |
83 | |
84 name = KNOWN_NAMESPACES.get(namespace, encryption_elt.getAttribute(u"name")) | |
85 | |
86 # at this point, message is encrypted but we know that we can't decrypt it, | |
87 # we need to notify the user | |
88 sender_s = message_elt[u'from'] | |
89 to_jid = jid.JID(message_elt[u'from']) | |
90 algorithm = u"{} [{}]".format(name, namespace) if name else namespace | |
91 log.warning( | |
92 _(u"Message from {sender} is encrypted with {algorithm} and we can't " | |
93 u"decrypt it.".format(sender=message_elt['from'], algorithm=algorithm))) | |
94 | |
95 user_msg = D_( | |
96 u"User {sender} sent you an encrypted message (encrypted with {algorithm}), " | |
97 u"and we can't decrypt it.").format(sender=sender_s, algorithm=algorithm) | |
98 | |
99 extra = {C.MESS_EXTRA_INFO: u"UNKNOWN_ENCRYPTION"} | |
100 client.feedback(to_jid, user_msg, extra) | |
101 return False |