# HG changeset patch # User Goffi # Date 1534004695 -7200 # Node ID 7213caa5c5d084d63206ed31236fc38d19df2976 # Parent baccc27d5c5c95c75be5ef437b425d14b894c7bd plugin OTR: integrated in new encryption handler + fixed use of bare jid where full jid was expected diff -r baccc27d5c5c -r 7213caa5c5d0 sat/plugins/plugin_sec_otr.py --- a/sat/plugins/plugin_sec_otr.py Sat Aug 11 18:24:55 2018 +0200 +++ b/sat/plugins/plugin_sec_otr.py Sat Aug 11 18:24:55 2018 +0200 @@ -123,6 +123,7 @@ log.debug(u"setState: %s (old_state=%s)" % (state, old_state)) if state == potr.context.STATE_PLAINTEXT: + client.encryption.stop(self.peer, NS_OTR) feedback = _(u"/!\\ conversation with %(other_jid)s is now UNENCRYPTED") % { "other_jid": self.peer.full() } @@ -130,6 +131,7 @@ OTR_STATE_UNENCRYPTED, self.peer.full(), client.profile ) elif state == potr.context.STATE_ENCRYPTED: + client.encryption.start(self.peer, NS_OTR) try: trusted = self.getCurrentTrust() except TypeError: @@ -153,6 +155,7 @@ OTR_STATE_ENCRYPTED, self.peer.full(), client.profile ) elif state == potr.context.STATE_FINISHED: + client.encryption.stop(self.peer, NS_OTR) feedback = D_(u"OTR conversation with {other_jid} is FINISHED").format( other_jid=self.peer.full() ) @@ -303,6 +306,7 @@ type_=C.MENU_SINGLE, ) host.trigger.add("presenceReceived", self._presenceReceivedTrigger) + self.host.registerEncryptionPlugin(self, u"OTR", NS_OTR) def _skipOTR(self, profile): """Tell the backend to not handle OTR for this profile. @@ -361,6 +365,11 @@ @param to_jid(jid.JID): jid to start encrypted session with """ + encrypted_session = client.encryption.getSession(to_jid.userhostJID()) + if encrypted_session and encrypted_session[u'plugin'].namespace != NS_OTR: + raise exceptions.ConflictError(_( + u"Can't start an OTR session, there is already an encrypted session " + u"with {name}").format(name=encrypted_session[u'plugin'].name)) if not to_jid.resource: to_jid.resource = self.host.memory.getMainResource( client, to_jid @@ -579,6 +588,12 @@ ), ) client.feedback(from_jid, feedback) + except potr.context.NotEncryptedError: + msg = D_(u"WARNING: received OTR encrypted data in an unencrypted context") + log.warning(msg) + feedback = msg + client.feedback(from_jid, msg) + raise failure.Failure(exceptions.CancelError(msg)) except StopIteration: return data else: @@ -603,11 +618,6 @@ # frontends, but we don't want it in # history else: - log.warning( - u"An encrypted message was expected, but got {}".format( - data["message"] - ) - ) raise failure.Failure( exceptions.CancelError("Cancelled by OTR") ) # no message at all (no history, no signal) @@ -646,11 +656,16 @@ return True def _sendMessageDataTrigger(self, client, mess_data): - if not "OTR" in mess_data: + encryption = mess_data.get(C.MESS_KEY_ENCRYPTION) + if encryption is None or encryption['plugin'].namespace != NS_OTR: return - otrctx = mess_data["OTR"] + to_jid = mess_data['to'] + if not to_jid.resource: + to_jid.resource = self.host.memory.getMainResource( + client, to_jid + ) # FIXME: temporary and unsecure, must be changed when frontends + otrctx = client._otr_context_manager.getContextForUser(to_jid) message_elt = mess_data["xml"] - to_jid = mess_data["to"] if otrctx.state == potr.context.STATE_ENCRYPTED: log.debug(u"encrypting message") body = None @@ -668,6 +683,9 @@ log.warning(u"No message found") else: self._p_carbons.setPrivate(message_elt) + self._p_hints.addHintElements(message_elt, [ + self._p_hints.HINT_NO_COPY, + self._p_hints.HINT_NO_PERMANENT_STORE]) otrctx.sendMessage(0, unicode(body).encode("utf-8"), appdata=mess_data) else: feedback = D_( @@ -689,6 +707,10 @@ return True to_jid = copy.copy(mess_data["to"]) + if client.encryption.getSession(to_jid.userhostJID()): + # there is already an encrypted session with this entity + return True + if not to_jid.resource: to_jid.resource = self.host.memory.getMainResource( client, to_jid @@ -697,10 +719,8 @@ otrctx = client._otr_context_manager.getContextForUser(to_jid) if otrctx.state != potr.context.STATE_PLAINTEXT: - self._p_hints.addHint(mess_data, self._p_hints.HINT_NO_COPY) - self._p_hints.addHint(mess_data, self._p_hints.HINT_NO_PERMANENT_STORE) - mess_data["OTR"] = (otrctx) #  this indicate that encryption is needed in - # sendMessageData trigger + client.encryption.start(to_jid, NS_OTR) + client.encryption.setEncryptionFlag(mess_data) if not mess_data["to"].resource: # if not resource was given, we force it here mess_data["to"] = to_jid