OTR Plugin

SleekXMPP Plugin to use OTR

Uses Python-Potr in combination with SleekXMPP to enable OTR messaging for Jabber clients. This plugin adds the event ‘message_received’, which forwards decrypted messages as well. Use that instead of the ‘message’ event. Furthermore, the plugin fires ‘otr_event’ events. These events always consist of a dictionary with the following content (keys):

jid:The Jabber ID this event is about (This is a SleekXMPP JID object)
type:The name of the event type that is fired, e.g. “otr_enabled”
data:Accompanying data for the event, this may be of any class, but we would recommend using strings. Currently, no events use this field.

List of event types

otr_enabled:OTR was off and is now on
otr_disabled:OTR was on and is now off
otr_already_setup:
 OTR conversation was finished and is refreshed
smp_started:User tried to start SMP
smp_question_used:
 User tried to start SMP with a question
smp_aborted:SMP was aborted from either side.
correct_secret_received:
 User supplied the secret through anothes channel and was received correctly. SMP trust is now established.
incorrect_secret_received:
 No trust has been established after SMP
unsafe_secret_received:
 Not implemented in this plugin. Can be used if you have a way to check the strength of secrets. Look at core.otrbot.state.action_check_secret_safe() for an example

Credits

The following two scripts have been used as a basis for this plugin:

class otrbot.otrplugin.plugin.OtrPlugin(xmpp, config=None)

OtrPlugin: enables OTR commands

plugin_init()

Initialise plugin. Sets the description (needed for being a SleekXMPP plugin) to the docstring of this class. Makes this plugin handle the ‘message’ event and registers the OtrMessage stanza plugin.

setup_otr(xmpp_account)

Setup OTR account to be used for encryption and decryption. This function should be run after plugin_init and before anything else.

Parameters:xmpp_account (dict) – An account as found in the sample settings. This needs at least a JID. Private keys for the account will be generated automatically
set_secret(jid, secret, start_smp=False)

Set the secret in the otr_context for this jid to this secret. Create a context if it does not exist for this jid.

Parameters:
  • jid (str) – The jabber ID to set the secret for
  • secret (str) – The secret that should be set.
  • start_smp (bool) – If this is true, smpGotSecret is run in the OtrContext. If SMP has not started yet, this means that the bot will start it.
decrypt(message)

Try to decrypt a message and sets message.otr_state to a state from OTR_STATES. Then launches the event ‘message_received’, unless the message was empty.

Parameters:message (str) – A string that can be decrypted by Python-Potr
encrypt(jid, message_string)

Send message “message” to “jid” if encryption is possible. If there’s no encryption, “jid” is asked to enable encryption(?)

Parameters:
  • jid (str) – a JID to whom the message will be sent
  • message_string (str) – A message to send
Returns:

The message as it was sent

emit_event(jid, event, data=None)

Emit an otr_event on xmpp

Parameters:
  • jid (str) – The JID that the event is for/started by
  • event (str) – The type of the event
  • data – accompanying data. For example the event ‘message_received’ has the message body in the data variable. This variable may be of any data type.
send_plain(jid, message_string)

Send a message over xmpp without checking anything. The :class OtrContext uses this to inject messages

Parameters:
  • jid (JID) – The Jabber ID to send to
  • message_string (str) – The message to send

Otr Context that keeps all the otr-relevant information for a certain peer

class otrbot.otrplugin.context.OtrContext(account, otr_plugin, peer, fingerprint)

Knows how peers can be contacted (OTR enabled or not, etc.) Implements these functions from Context:

  • getPolicy
  • setState
  • inject

Create a context for the account to OTR-message with.

Parameters:
  • account (OtrAccount) – The OTR account
  • otr_plugin (OtrPlugin) – An OTR plugin instance
  • peer (str) – A JID
  • fingerprint (str) – fingerprint for the JID, becomes lower case, is allowed to be None
emit_event(event, data=None)

Makes the otr_plugin emit an event for self.peer

Parameters:
  • event (str) – An otr_event type that can be executed by the OtrBot.
  • data (str) – The data of the event, e.g., a message for a message_received event.
processTLVs(tlvs, appdata=None)

Process typle/length/value records. First check if message is an SMP message and fire the appropriate otr_event if so. Then call the super to do further processing.

Parameters:
  • tlvs (list) – a list of TLV objects
  • appdata – Gets passed to super
getPolicy(key)

Returns the default policy from DEFAULT_POLICY_FLAGS. Returns False if the policy does not exist.

Parameters:key

The policy that should be returned. Possible keys:

  • ALLOW_V1
  • ALLOW_V2
  • REQUIRE_ENCRYPTION
  • SEND_TAG
  • WHITESPACE_START_AKE
  • ERROR_START_AKE
setState(new_state)

Sets trust based on their fingerprint

Parameters:new_state (int) – The new state corresponding to the possible states in potr.context.
inject(msg, appdata=None)

Use OtrPlugin to send a message. This will be encrypted if possible.

Parameters:
  • msg (str) – The message that will be injected.
  • appdata (dict) – This is not used.
smpAbort(appdata=None)

This function is overriden in order to fire an “smp_aborted” otr_event when it is called.

Parameters:appdata (dict) – This is forwarded to other calls.

Simple implementation of the abstract potr Account class.

class otrbot.otrplugin.account.OtrAccount(otr_plugin, jid, private_key=None)

Implementation of potr Account class

Taken from OtrXMPPChannel

Init and create a private key if needed

loadPrivkey()

overload not-implemented load function

savePrivkey()

Should be overloaded, but don’t know with what functionality

saveTrusts()

Should be overloaded, but don’t know with what functionality. Apparently this function is called after a user ends a private conversation

Simple implementation of the abstract potr Manager class.

class otrbot.otrplugin.manager.OtrManager(jid, otr_plugin)

Class that retrieves contexts for messages. The contexts manage decryption and encryption of messages

Initialise with account and empty contexts dictionary. The dictionary wil contain bare JIDs and OtrContext objects. Each JID will talk to a different OtrAccount instance of the bot. This way, the bot always has a different fingerprint for each session, enabling a user to go through the same steps several times.

contexts = None

Dictionary of people the bot is talking to - Keys: str of bare jids - Values: OtrContexts objects

get_context(jid)

Return the context for the conversation with JID jid. If it does not exist, a new account (with a new random private key) is created for the session with the jid.

Parameters:
  • jid (str) – the Jabber ID of the peer
  • fingerprint (str) – An optional fingerprint of the JID for trying to manually establish trust (not tested).
destroy_context(jid)

Remove the context with JID jid from the contexts

Parameters:jid (JID) –
destroy_all_contexts()

Remove all context for converations