Mercurial > libervia-backend
comparison sat/memory/encryption.py @ 2651:ebcff5423465
core (memory/encryption): start improvments, stop and getSession:
- "start" won't do anything if session is already encrypted with requested algorithm, and will raise a ConflictError if it's already encrypted but with an other algorithm
- implemented "stop", with an optional namespace to check we are stopping the expected algorithm
- "getSession" retrieve the current encryption session of a jid, if any
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 11 Aug 2018 18:24:55 +0200 |
parents | 712cb4ff3e13 |
children | 4e130cc9bfc0 |
comparison
equal
deleted
inserted
replaced
2650:3a8e7ec4648a | 2651:ebcff5423465 |
---|---|
59 name=name, | 59 name=name, |
60 namespace=namespace, | 60 namespace=namespace, |
61 priority=priority) | 61 priority=priority) |
62 cls.plugins.append(plg) | 62 cls.plugins.append(plg) |
63 cls.plugins.sort(key=lambda p: p.priority) | 63 cls.plugins.sort(key=lambda p: p.priority) |
64 log.info(_(u"Encryption plugin registered: {name}").format(name=name)) | |
64 | 65 |
65 def start(self, entity, namespace=None): | 66 def start(self, entity, namespace=None): |
66 """Start an encrypted session with an entity | 67 """Start an encrypted session with an entity |
67 | 68 |
68 @param entity(jid.JID): entity to start an encrypted session with | 69 @param entity(jid.JID): entity to start an encrypted session with |
72 """ | 73 """ |
73 if not self.plugins: | 74 if not self.plugins: |
74 raise exceptions.NotFound(_(u"No encryption plugin is registered, " | 75 raise exceptions.NotFound(_(u"No encryption plugin is registered, " |
75 u"an encryption session can't be started")) | 76 u"an encryption session can't be started")) |
76 | 77 |
77 bare_jid = entity.userhostJID() | |
78 if bare_jid in self._sessions: | |
79 plg = self._sessions[bare_jid]['plugin'] | |
80 | |
81 msg = (_(u"Session with {bare_jid} is already encrypted with {name}." | |
82 u"Please stop encryption session before changing algorithm.") | |
83 .format(bare_jid=bare_jid, name=plg.name)) | |
84 log.warning(msg) | |
85 raise exceptions.ConflictError(msg) | |
86 | |
87 if namespace is None: | 78 if namespace is None: |
88 plg = self.plugins[0] | 79 plg = self.plugins[0] |
89 else: | 80 else: |
90 try: | 81 try: |
91 plg = next(p for p in self.plugins if p.namespace == namespace) | 82 plg = next(p for p in self.plugins if p.namespace == namespace) |
92 except StopIteration: | 83 except StopIteration: |
93 raise exceptions.NotFound(_( | 84 raise exceptions.NotFound(_( |
94 u"Can't find requested encryption plugin: {namespace}").format( | 85 u"Can't find requested encryption plugin: {namespace}").format( |
95 namespace=namespace)) | 86 namespace=namespace)) |
96 | 87 |
88 bare_jid = entity.userhostJID() | |
89 if bare_jid in self._sessions: | |
90 plg = self._sessions[bare_jid]['plugin'] | |
91 if plg.namespace == namespace: | |
92 log.info(_(u"Session with {bare_jid} is already encrypted with {name}." | |
93 u"Nothing to do.") | |
94 .format(bare_jid=bare_jid, name=plg.name)) | |
95 return | |
96 | |
97 msg = (_(u"Session with {bare_jid} is already encrypted with {name}. " | |
98 u"Please stop encryption session before changing algorithm.") | |
99 .format(bare_jid=bare_jid, name=plg.name)) | |
100 log.warning(msg) | |
101 raise exceptions.ConflictError(msg) | |
102 | |
97 data = {"plugin": plg} | 103 data = {"plugin": plg} |
98 if entity.resource: | 104 if entity.resource: |
99 # indicate that we encrypt only for some devices | 105 # indicate that we encrypt only for some devices |
100 data['directed_devices'] = [entity.resource] | 106 data['directed_devices'] = [entity.resource] |
101 | 107 |
102 self._sessions[entity.userhostJID()] = data | 108 self._sessions[entity.userhostJID()] = data |
103 log.info(_(u"Encryption session as been set for {bare_jid} with " | 109 log.info(_(u"Encryption session has been set for {bare_jid} with " |
104 u"{encryption_name}").format( | 110 u"{encryption_name}").format( |
105 bare_jid=bare_jid.userhost(), encryption_name=plg.name)) | 111 bare_jid=bare_jid.userhost(), encryption_name=plg.name)) |
112 | |
113 def stop(self, entity, namespace=None): | |
114 """Stop an encrypted session with an entity | |
115 | |
116 @param entity(jid.JID): entity with who the encrypted session must be stopped | |
117 must be bare jid is the algorithm encrypt for all devices | |
118 @param namespace(unicode): namespace of the session to stop | |
119 when specified, used to check we stop the right encryption session | |
120 """ | |
121 session = self.getSession(entity.userhostJID()) | |
122 if not session: | |
123 raise exceptions.NotFound(_(u"There is no encrypted session with this " | |
124 u"entity.")) | |
125 if namespace is not None and session[u'plugin'].namespace != namespace: | |
126 raise exceptions.InternalError(_( | |
127 u"The encrypted session is not run with the expected plugin: encrypted " | |
128 u"with {current_name} and was expecting {expected_name}").format( | |
129 current_name=session[u'plugin'].namespace, | |
130 expected_name=namespace)) | |
131 if entity.resource: | |
132 try: | |
133 directed_devices = session[u'directed_devices'] | |
134 except KeyError: | |
135 raise exceptions.NotFound(_( | |
136 u"There is a session for the whole entity (i.e. all devices of the " | |
137 u"entity), not a directed one. Please use bare jid if you want to " | |
138 u"stop the whole encryption with this entity.")) | |
139 | |
140 try: | |
141 directed_devices.remove(entity.resource) | |
142 except ValueError: | |
143 raise exceptions.NotFound(_(u"There is no directed session with this " | |
144 u"entity.")) | |
145 else: | |
146 del self._sessions[entity] | |
147 | |
148 log.info(_(u"Encrypted session stopped with entity {entity}").format( | |
149 entity=entity.full())) | |
150 | |
151 def getSession(self, entity): | |
152 """Get encryption session for this contact | |
153 | |
154 @param entity(jid.JID): get the session for this entity | |
155 must be a bare jid | |
156 @return (dict, None): encrypted session data | |
157 None if there is not encryption for this session with this jid | |
158 """ | |
159 if entity.resource: | |
160 raise exceptions.InternalError(u"Full jid given when expecting bare jid") | |
161 return self._sessions.get(entity) | |
106 | 162 |
107 ## Triggers ## | 163 ## Triggers ## |
108 | 164 |
109 def setEncryptionFlag(self, mess_data): | 165 def setEncryptionFlag(self, mess_data): |
110 """Set "encryption" key in mess_data if session with destinee is encrypted""" | 166 """Set "encryption" key in mess_data if session with destinee is encrypted""" |