Commit 3e416ede authored by Philipp Hörist's avatar Philipp Hörist

asd

parent 44534c13
......@@ -18,7 +18,7 @@ from gajim.common.connection_handlers_events import (
from omemo.xmpp import (
NS_NOTIFY, NS_OMEMO, NS_EME, NS_HINTS, BundleInformationAnnouncement,
BundleInformationQuery, DeviceListAnnouncement, DevicelistQuery,
OmemoMessage, successful, unpack_device_bundle,
build_omemo_stanza, successful, unpack_device_bundle,
unpack_device_list_update, unpack_encrypted)
from omemoimpl.session_manager import SessionManager
......@@ -56,6 +56,8 @@ class OMEMOConnection:
self.query_for_bundles = []
self.query_for_devicelists = []
self._bundles = {}
app.ged.register_event_handler('pep-received', ged.PRECORE,
self.handle_device_list_update)
app.ged.register_event_handler('signed-in', ged.PRECORE,
......@@ -215,6 +217,8 @@ class OMEMOConnection:
-------
Return means that the Event is passed on to Gajim
"""
return
#TODO
if msg.conn.name != self.account:
return
omemo_encrypted_tag = msg.msg_.getTag('encrypted', namespace=NS_OMEMO)
......@@ -269,6 +273,13 @@ class OMEMOConnection:
msg_dict = unpack_encrypted(msg.stanza.getTag
('encrypted', namespace=NS_OMEMO))
own_id = self.omemo.get_own_device_id()
if own_id not in msg_dict['keys']:
log.warning('OMEMO message does not contain our device key')
msg.encrypted = 'drop'
return
key_message = msg_dict['keys'][own_id][0]
if msg.mtype == 'groupchat':
address_tag = msg.stanza.getTag('addresses',
namespace=nbxmpp.NS_ADDRESS)
......@@ -293,7 +304,7 @@ class OMEMOConnection:
log.debug('GroupChat Message from: %s', from_jid)
plaintext = ''
if msg_dict['sid'] == self.omemo.own_device_id:
if msg_dict['sid'] == self.omemo.get_own_device_id():
if msg_dict['payload'] in self.gc_message:
plaintext = self.gc_message[msg_dict['payload']]
del self.gc_message[msg_dict['payload']]
......@@ -303,11 +314,13 @@ class OMEMOConnection:
msg.encrypted = 'drop'
return
else:
msg_dict['sender_jid'] = app. \
get_jid_without_resource(from_jid)
plaintext = self.omemo.decrypt_msg(msg_dict)
from_jid = app.get_jid_without_resource(from_jid)
_, plaintext = self.omemo.decrypt(
from_jid, msg_dict['sid'], msg_dict['iv'],
key_message, msg_dict['payload'], key_message[1])
if not plaintext:
log.warning('plaintext is None')
msg.encrypted = 'drop'
return
......@@ -522,45 +535,45 @@ class OMEMOConnection:
"""
if event.conn.name != self.account:
return
try:
self.cleanup_stanza(event)
if not event.message:
callback(event)
return
to_jid = app.get_jid_without_resource(event.jid)
plaintext = event.message.encode('utf8')
msg_dict = self.omemo.create_msg(self.own_jid, to_jid, plaintext)
if not msg_dict:
raise OMEMOError('Error while encrypting')
self.cleanup_stanza(event)
except OMEMOError as error:
log.error(error)
app.nec.push_incoming_event(
MessageNotSentEvent(
None, conn=conn, jid=event.jid, message=event.message,
error=error, time_=time.time(), session=event.session))
if not event.message:
callback(event)
return
encrypted_node = OmemoMessage(msg_dict)
event.msg_iq.addChild(node=encrypted_node)
to_jid = app.get_jid_without_resource(event.jid)
plaintext = event.message.encode('utf8')
msg_dict = self.omemo.encrypt(to_jid, plaintext, bundles=self._bundles, devices=None, callback=self._on_encrypt_error)
if to_jid in self._bundles:
del self._bundles[to_jid]
# "iv": aes_gcm_iv,
# "messages": messages, {"message", "pre_key"}
# "payload": ciphertext,
# "cipher": aes_gcm
if not msg_dict:
return
# XEP-0380: Explicit Message Encryption
eme_node = Node('encryption', attrs={'xmlns': NS_EME,
'name': 'OMEMO',
'namespace': NS_OMEMO})
event.msg_iq.addChild(node=eme_node)
# except OMEMOError as error:
# log.error(error)
# app.nec.push_incoming_event(
# MessageNotSentEvent(
# None, conn=conn, jid=event.jid, message=event.message,
# error=error, time_=time.time(), session=event.session))
# return
# Store Hint for MAM
store = Node('store', attrs={'xmlns': NS_HINTS})
event.msg_iq.addChild(node=store)
build_omemo_stanza(event.msg_iq, msg_dict)
self.print_msg_to_log(event.msg_iq)
event.xhtml = None
event.encrypted = self.plugin.encryption_name
callback(event)
def _on_encrypt_error(self, *args):
log.error('Encrypt Error')
log.error(*args)
@staticmethod
def cleanup_stanza(obj):
''' We make sure only allowed tags are in the stanza '''
......@@ -697,8 +710,10 @@ class OMEMOConnection:
if devices_without_session:
for device_id in devices_without_session:
self.fetch_device_bundle_information(self.own_jid,
device_id)
if self.own_jid in self._bundles:
if device_id in self._bundles[self.own_jid]:
self.fetch_device_bundle_information(self.own_jid,
device_id)
# Fetch Bundles of contacts devices
if contact_jid not in self.query_for_bundles:
......@@ -710,10 +725,12 @@ class OMEMOConnection:
if devices_without_session:
for device_id in devices_without_session:
self.fetch_device_bundle_information(contact_jid,
device_id)
if contact_jid in self._bundles:
if device_id in self._bundles[contact_jid]:
self.fetch_device_bundle_information(contact_jid,
device_id)
if self.omemo.getTrustedFingerprints(contact_jid):
if contact_jid not in self._bundles:
return False
return True
......@@ -759,9 +776,18 @@ class OMEMOConnection:
log.warning('Failed to build Session with %s', jid)
return
if self.omemo.build_session(jid, device_id, bundle):
log.info('%s => session created for: %s',
self.account, jid)
self.omemo.save_bundle(jid, device_id, bundle)
if jid not in self._bundles:
self._bundles[jid] = {device_id: bundle}
else:
self._bundles[jid][device_id] = bundle
log.info('bundle received, %s %s', jid, device_id)
# key_transport_message = self.omemo.buid_session(
# jid, device_id, bundle, self._on_session_build_error)
# log.info('%s => session created for: %s',
# self.account, jid)
# Trigger dialog to trust new Fingerprints if
# the Chat Window is Open
# TODO
......@@ -770,6 +796,10 @@ class OMEMOConnection:
# if ctrl:
# self.plugin.new_fingerprints_available(ctrl)
def _on_session_build_error(self, *args):
log.error('Session build error')
log.error(*args)
def query_devicelist(self, jid=None, fetch_bundle=False):
""" Query own devicelist from the server """
if jid in self.query_for_devicelists:
......
......@@ -18,6 +18,9 @@ class SessionManager:
def set_devicelist(self, device_list, jid=None):
self._sm.newDeviceList(device_list, jid)
def get_devicelist(self, jid, active=True):
return self._store.loadDevices(jid, active)
def get_own_device_id(self):
return self._store.own_device_id
......@@ -30,5 +33,20 @@ class SessionManager:
def get_trusted_fingerprints(self, jid):
return self._store.getTrustedFingerprints(jid)
def save_bundle(self, jid, device_id, bundle):
fingerprint = bundle.fingerprint
self._store.storeBundle(jid, device_id, fingerprint)
def clear_devicelist(self):
return
\ No newline at end of file
return
def encrypt(self, jids, plaintext, bundles=None, devices=None, callback=None):
return self._sm.encryptMessage(jids, plaintext, bundles, devices, callback)
def decrypt(self, jid, sid, iv, message, payload, prekey):
if prekey:
return self._sm.decryptMessage(jid, sid, iv, message, payload)
return self._sm.decryptPreKeyMessage(jid, sid, iv, message, payload)
def buid_session(self, jid, device, bundle, callback):
return self._sm.buildSession(jid, device, bundle, callback)
......@@ -169,3 +169,12 @@ class SQLiteDatabase(Storage, DeviceManager):
def getTrustedFingerprints(self, jid):
return True
def storeBundle(self, jid, device_id, fingerprint):
q = '''UPDATE sessions SET fingerprint = ?
WHERE jid = ? and device_id = ?'''
self._con.execute(q, (fingerprint, jid, device_id))
self._con.commit()
def isTrusted(self, *args):
return True
\ No newline at end of file
......@@ -56,12 +56,6 @@ except Exception as error:
log.error(error)
ERROR_MSG = PROTOBUF_MISSING
try:
import axolotl
except Exception as error:
log.error(error)
ERROR_MSG = AXOLOTL_MISSING
if not ERROR_MSG:
try:
from omemo.omemo_connection import OMEMOConnection
......@@ -221,42 +215,40 @@ class OmemoPlugin(GajimPlugin):
return self.connections[account].omemo
def before_sendmessage(self, chat_control):
return
#TODO
# account = chat_control.account
# contact = chat_control.contact
# con = self.connections[account]
# self.new_fingerprints_available(chat_control)
# if isinstance(chat_control, GroupchatControl):
# room = chat_control.room_jid
# missing = True
# own_jid = app.get_jid_from_account(account)
# for nick in con.groupchat[room]:
# real_jid = con.groupchat[room][nick]
# if real_jid == own_jid:
# continue
# if not con.are_keys_missing(real_jid):
# missing = False
# if missing:
# log.info('%s => No Trusted Fingerprints for %s',
# account, room)
# self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
# else:
# # check if we have devices for the contact
# if not self.get_omemo(account).device_list_for(contact.jid):
# con.query_devicelist(contact.jid, True)
# self.print_message(chat_control, UserMessages.QUERY_DEVICES)
# chat_control.sendmessage = False
# return
# # check if bundles are missing for some devices
# if con.are_keys_missing(contact.jid):
# log.info('%s => No Trusted Fingerprints for %s',
# account, contact.jid)
# self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
# chat_control.sendmessage = False
# else:
# log.debug('%s => Sending Message to %s',
# account, contact.jid)
account = chat_control.account
contact = chat_control.contact
con = self.connections[account]
self.new_fingerprints_available(chat_control)
if isinstance(chat_control, GroupchatControl):
room = chat_control.room_jid
missing = True
own_jid = app.get_jid_from_account(account)
for nick in con.groupchat[room]:
real_jid = con.groupchat[room][nick]
if real_jid == own_jid:
continue
if not con.are_keys_missing(real_jid):
missing = False
if missing:
log.info('%s => No Trusted Fingerprints for %s',
account, room)
self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
else:
# check if we have devices for the contact
if not self.get_omemo(account).get_devicelist(contact.jid):
con.query_devicelist(contact.jid, True)
self.print_message(chat_control, UserMessages.QUERY_DEVICES)
chat_control.sendmessage = False
return
# check if bundles are missing for some devices
if con.are_keys_missing(contact.jid):
log.info('%s => No Trusted Fingerprints for %s',
account, contact.jid)
self.print_message(chat_control, UserMessages.NO_FINGERPRINTS)
chat_control.sendmessage = False
else:
log.debug('%s => Sending Message to %s',
account, contact.jid)
def new_fingerprints_available(self, chat_control):
return
......
......@@ -78,23 +78,29 @@ class DeviceListAnnouncement(Iq):
self.addChild(node=pubsub)
class OmemoMessage(Node):
def __init__(self, msg_dict):
# , contact_jid, key, iv, payload, dev_id, my_dev_id):
Node.__init__(self, 'encrypted', attrs={'xmlns': NS_OMEMO})
header = Node('header', attrs={'sid': msg_dict['sid']})
for rid, (key, prekey) in msg_dict['keys'].items():
if prekey:
child = header.addChild('key',
attrs={'prekey': 'true', 'rid': rid})
else:
child = header.addChild('key',
attrs={'rid': rid})
child.addData(b64encode(key).decode('utf-8'))
header.addChild('iv').addData(b64encode(msg_dict['iv']).decode('utf-8'))
self.addChild(node=header)
self.addChild('payload').addData(b64encode(msg_dict['payload'])
.decode('utf-8'))
def build_omemo_stanza(message_node, msg_dict):
encrypted = message_node.addChild('encrypted', attrs={'xmlns': NS_OMEMO})
header = encrypted.addChild('header', attrs={'sid': msg_dict['sid']})
for device_id in msg_dict['messages']:
data = msg_dict['messages']['device_id']
if data['pre_key']:
child = header.addChild('key',
attrs={'prekey': 'true', 'rid': device_id})
else:
child = header.addChild('key',
attrs={'rid': device_id})
child.addData(b64encode(data['message']).decode('utf-8'))
header.addChild('iv').addData(b64encode(msg_dict['iv']).decode('utf-8'))
encrypted.addChild('payload').addData(
b64encode(msg_dict['payload']).decode('utf-8'))
# XEP-0380: Explicit Message Encryption
message_node.addChild('encryption', attrs={'xmlns': NS_EME,
'name': 'OMEMO',
'namespace': NS_OMEMO})
# Store Hint for MAM
message_node.addChild('store', attrs={'xmlns': NS_HINTS})
class BundleInformationQuery(Iq):
......@@ -280,7 +286,11 @@ def unpack_encrypted(encrypted_node):
log.warning('Omemo key without data')
continue
keys[int(rid)] = decode_data(kn)
prekey = False
if kn.getAttr('prekey') == 'true':
prekey = True
keys[int(rid)] = (decode_data(kn), prekey)
result = {'sid': sid, 'iv': iv, 'keys': keys, 'payload': payload}
return result
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment