encryption: Stub functions for encrypted messages.

This commit is contained in:
poljar (Damir Jelić) 2018-05-09 14:00:32 +02:00
parent 320f490273
commit 8a3bda9797
6 changed files with 107 additions and 4 deletions

View file

@ -410,11 +410,12 @@ def room_input_cb(server_name, buffer, input_data):
room_id = key_from_value(server.buffers, buffer) room_id = key_from_value(server.buffers, buffer)
room = server.rooms[room_id] room = server.rooms[room_id]
if room.encrypted:
return W.WEECHAT_RC_OK
formatted_data = Formatted.from_input_line(input_data) formatted_data = Formatted.from_input_line(input_data)
if room.encrypted:
server.send_room_message(room_id, formatted_data)
return W.WEECHAT_RC_OK
message = MatrixSendMessage( message = MatrixSendMessage(
server.client, room_id=room_id, formatted_message=formatted_data) server.client, room_id=room_id, formatted_message=formatted_data)

View file

@ -293,6 +293,20 @@ class MatrixClient:
return HttpRequest(RequestType.POST, self.host, path, content) return HttpRequest(RequestType.POST, self.host, path, content)
def key_claim(self, key_dict):
query_parameters = {"access_token": self.access_token}
path = ("{api}/keys/claim?"
"{query_parameters}").format(
api=MATRIX_API_PATH,
query_parameters=urlencode(query_parameters))
content = {
"one_time_keys": {key_dict}
}
return HttpRequest(RequestType.POST, self.host, path, content)
def mxc_to_http(self, mxc): def mxc_to_http(self, mxc):
# type: (str) -> str # type: (str) -> str
url = urlparse(mxc) url = urlparse(mxc)
@ -618,3 +632,19 @@ class MatrixKeyQueryMessage(MatrixMessage):
server) server)
return self._decode(server, object_hook) return self._decode(server, object_hook)
class MatrixKeyClaimMessage(MatrixMessage):
def __init__(self, client, key_dict):
data = {
"key_dict": key_dict,
}
MatrixMessage.__init__(self, client.keys_query, data)
def decode_body(self, server):
object_hook = partial(MatrixEvents.MatrixKeyClaimEvent.from_dict,
server)
return self._decode(server, object_hook)

View file

@ -134,6 +134,9 @@ def matrix_me_command_cb(data, buffer, args):
room_id=room_id, room_id=room_id,
formatted_message=formatted_data) formatted_message=formatted_data)
if server.rooms[room_id].encrypted:
return W.WEECHAT_RC_OK
server.send_or_queue(message) server.send_or_queue(message)
return W.WEECHAT_RC_OK return W.WEECHAT_RC_OK

View file

@ -20,6 +20,7 @@ from __future__ import unicode_literals
import os import os
import json import json
import sqlite3 import sqlite3
import pprint
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin
from builtins import str, bytes from builtins import str, bytes
@ -34,7 +35,11 @@ try:
from olm.account import Account, OlmAccountError from olm.account import Account, OlmAccountError
from olm.session import (Session, InboundSession, OlmSessionError, from olm.session import (Session, InboundSession, OlmSessionError,
OlmPreKeyMessage) OlmPreKeyMessage)
from olm.group_session import InboundGroupSession, OlmGroupSessionError from olm.group_session import (
InboundGroupSession,
OutboundGroupSession,
OlmGroupSessionError
)
except ImportError: except ImportError:
matrix.globals.ENCRYPTION = False matrix.globals.ENCRYPTION = False
@ -229,6 +234,7 @@ class Olm():
self.sessions = sessions self.sessions = sessions
self.inbound_group_sessions = inbound_group_sessions self.inbound_group_sessions = inbound_group_sessions
self.outbound_group_sessions = {}
def _create_session(self, sender, sender_key, message): def _create_session(self, sender, sender_key, message):
W.prnt("", "matrix: Creating session for {}".format(sender)) W.prnt("", "matrix: Creating session for {}".format(sender))
@ -245,6 +251,32 @@ class Olm():
self.inbound_group_sessions[room_id][session_id] = session self.inbound_group_sessions[room_id][session_id] = session
self._store_inbound_group_session(room_id, session) self._store_inbound_group_session(room_id, session)
def create_outbound_group_session(self, room_id):
session = OutboundGroupSession()
self.outbound_group_sessions[room_id] = session
self.create_group_session(room_id, session.id, session.session_key)
@encrypt_enabled
def get_missing_sessions(self, users):
# type: (List[str]) -> Dict[str, Dict[str, str]]
missing = {}
for user in users:
devices = []
for key in self.device_keys[user]:
# we don't need a session for our own device, skip it
if key.device_id == self.device_id:
continue
if not self.sessions[user][key.device_id]:
devices.append(key.device_id)
if devices:
missing[user] = {device: "ed25519" for device in devices}
return missing
@encrypt_enabled @encrypt_enabled
def decrypt(self, sender, sender_key, message): def decrypt(self, sender, sender_key, message):
plaintext = None plaintext = None

View file

@ -18,6 +18,7 @@ from __future__ import unicode_literals
from builtins import str from builtins import str
import json import json
import pprint
from collections import deque, defaultdict from collections import deque, defaultdict
from functools import partial from functools import partial
@ -337,10 +338,12 @@ class MatrixKeyQueryEvent(MatrixEvent):
device_keys)) device_keys))
return cls(server, keys) return cls(server, keys)
except KeyError: except KeyError:
# TODO error message
return MatrixErrorEvent.from_dict(server, "Error kicking user", return MatrixErrorEvent.from_dict(server, "Error kicking user",
False, parsed_dict) False, parsed_dict)
def execute(self): def execute(self):
# TODO move this logic into an Olm method
olm = self.server.olm olm = self.server.olm
if olm.device_keys == self.keys: if olm.device_keys == self.keys:
@ -350,6 +353,20 @@ class MatrixKeyQueryEvent(MatrixEvent):
# TODO invalidate megolm sessions for rooms that got new devices # TODO invalidate megolm sessions for rooms that got new devices
class MatrixKeyClaimEvent(MatrixEvent):
def __init__(self, server, keys):
self.keys = keys
MatrixEvent.__init__(self, server)
@classmethod
def from_dict(cls, server, parsed_dict):
raise NotImplementedError
def execute(self):
pass
class MatrixBacklogEvent(MatrixEvent): class MatrixBacklogEvent(MatrixEvent):
def __init__(self, server, room_id, end_token, events): def __init__(self, server, room_id, end_token, events):

View file

@ -476,6 +476,26 @@ class MatrixServer:
message = MatrixSyncMessage(self.client, self.next_batch, limit) message = MatrixSyncMessage(self.client, self.next_batch, limit)
self.send_queue.append(message) self.send_queue.append(message)
def send_room_message(self, room_id, formatted_data):
# type: (str, Formatted) -> None
room = self.rooms[room_id]
if not room.encrypted:
return
missing = self.olm.get_missing_sessions(room.users.keys())
if missing:
W.prnt("", "{prefix}matrix: Olm session missing for room, can't"
" encrypt message.")
W.prnt("", pprint.pformat(missing))
# message = MatrixKeyClaimMessage(self.client, missing)
# self.send_or_queue(message)
# TODO claim keys for the missing user/device combinations
return
# self.send_queue.append(message)
@encrypt_enabled @encrypt_enabled
def upload_keys(self, device_keys=False, one_time_keys=False): def upload_keys(self, device_keys=False, one_time_keys=False):
keys = self.olm.account.identity_keys() if device_keys else None keys = self.olm.account.identity_keys() if device_keys else None