mirror of
https://mau.dev/maunium/synapse.git
synced 2024-12-14 19:53:51 +01:00
Synapse 0.33.1 (2018-08-02)
=========================== SECURITY FIXES -------------- - Fix a potential issue where servers could request events for rooms they have not joined. (`#3641 <https://github.com/matrix-org/synapse/issues/3641>`_) - Fix a potential issue where users could see events in private rooms before they joined. (`#3642 <https://github.com/matrix-org/synapse/issues/3642>`_) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJbYxcCAAoJEIofk9V1tejVg8YIAJU1xoZ2zSnordJczpvVZbzx Rsstk/wvE2dSGJL22gfSLzQNCbQvF4aOul1LAGJfbEQWc46BcNpyuWUxjTd3FaF7 SfbWdkDh1w3ROSuiPA8j4CnH6EwP0w2itIBhFG7JpVEXjRgCyc1iMUl/oQESv82g UQyr6t/G68mE8xHm0eqvNfCjVAMSZDAnOzYZa7vfZJBqlZiGHB6Z1nsvsS3nZqQd BQQi/pQTXxsIL2egSvuycykiZtEZcm+QDRFi6hIatv5LRFOsQUqKVTB/D7XOoSbP RPOzcaSjv4mZ9a4NBzFMVVzzTRbr2EnipPd2ePrnJoOnl2eNRO4Won8zl4h+OQc= =U/ir -----END PGP SIGNATURE----- Merge tag 'v0.33.1' Synapse 0.33.1 (2018-08-02) =========================== SECURITY FIXES -------------- - Fix a potential issue where servers could request events for rooms they have not joined. (`#3641 <https://github.com/matrix-org/synapse/issues/3641>`_) - Fix a potential issue where users could see events in private rooms before they joined. (`#3642 <https://github.com/matrix-org/synapse/issues/3642>`_)
This commit is contained in:
commit
43ecfe0b10
9 changed files with 73 additions and 19 deletions
10
CHANGES.rst
10
CHANGES.rst
|
@ -1,3 +1,13 @@
|
||||||
|
Synapse 0.33.1 (2018-08-02)
|
||||||
|
===========================
|
||||||
|
|
||||||
|
SECURITY FIXES
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- Fix a potential issue where servers could request events for rooms they have not joined. (`#3641 <https://github.com/matrix-org/synapse/issues/3641>`_)
|
||||||
|
- Fix a potential issue where users could see events in private rooms before they joined. (`#3642 <https://github.com/matrix-org/synapse/issues/3642>`_)
|
||||||
|
|
||||||
|
|
||||||
Synapse 0.33.0 (2018-07-19)
|
Synapse 0.33.0 (2018-07-19)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
""" This is a reference implementation of a Matrix home server.
|
""" This is a reference implementation of a Matrix home server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.33.0"
|
__version__ = "0.33.1"
|
||||||
|
|
|
@ -425,6 +425,7 @@ class FederationServer(FederationBase):
|
||||||
ret = yield self.handler.on_query_auth(
|
ret = yield self.handler.on_query_auth(
|
||||||
origin,
|
origin,
|
||||||
event_id,
|
event_id,
|
||||||
|
room_id,
|
||||||
signed_auth,
|
signed_auth,
|
||||||
content.get("rejects", []),
|
content.get("rejects", []),
|
||||||
content.get("missing", []),
|
content.get("missing", []),
|
||||||
|
|
|
@ -19,10 +19,12 @@ import random
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership
|
||||||
|
from synapse.api.errors import AuthError
|
||||||
from synapse.events import EventBase
|
from synapse.events import EventBase
|
||||||
from synapse.events.utils import serialize_event
|
from synapse.events.utils import serialize_event
|
||||||
from synapse.types import UserID
|
from synapse.types import UserID
|
||||||
from synapse.util.logutils import log_function
|
from synapse.util.logutils import log_function
|
||||||
|
from synapse.visibility import filter_events_for_client
|
||||||
|
|
||||||
from ._base import BaseHandler
|
from ._base import BaseHandler
|
||||||
|
|
||||||
|
@ -129,11 +131,13 @@ class EventStreamHandler(BaseHandler):
|
||||||
class EventHandler(BaseHandler):
|
class EventHandler(BaseHandler):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_event(self, user, event_id):
|
def get_event(self, user, room_id, event_id):
|
||||||
"""Retrieve a single specified event.
|
"""Retrieve a single specified event.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user (synapse.types.UserID): The user requesting the event
|
user (synapse.types.UserID): The user requesting the event
|
||||||
|
room_id (str|None): The expected room id. We'll return None if the
|
||||||
|
event's room does not match.
|
||||||
event_id (str): The event ID to obtain.
|
event_id (str): The event ID to obtain.
|
||||||
Returns:
|
Returns:
|
||||||
dict: An event, or None if there is no event matching this ID.
|
dict: An event, or None if there is no event matching this ID.
|
||||||
|
@ -142,13 +146,26 @@ class EventHandler(BaseHandler):
|
||||||
AuthError if the user does not have the rights to inspect this
|
AuthError if the user does not have the rights to inspect this
|
||||||
event.
|
event.
|
||||||
"""
|
"""
|
||||||
event = yield self.store.get_event(event_id)
|
event = yield self.store.get_event(event_id, check_room_id=room_id)
|
||||||
|
|
||||||
if not event:
|
if not event:
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
return
|
return
|
||||||
|
|
||||||
if hasattr(event, "room_id"):
|
users = yield self.store.get_users_in_room(event.room_id)
|
||||||
yield self.auth.check_joined_room(event.room_id, user.to_string())
|
is_peeking = user.to_string() not in users
|
||||||
|
|
||||||
|
filtered = yield filter_events_for_client(
|
||||||
|
self.store,
|
||||||
|
user.to_string(),
|
||||||
|
[event],
|
||||||
|
is_peeking=is_peeking
|
||||||
|
)
|
||||||
|
|
||||||
|
if not filtered:
|
||||||
|
raise AuthError(
|
||||||
|
403,
|
||||||
|
"You don't have permission to access that event."
|
||||||
|
)
|
||||||
|
|
||||||
defer.returnValue(event)
|
defer.returnValue(event)
|
||||||
|
|
|
@ -1349,6 +1349,11 @@ class FederationHandler(BaseHandler):
|
||||||
def get_state_for_pdu(self, room_id, event_id):
|
def get_state_for_pdu(self, room_id, event_id):
|
||||||
"""Returns the state at the event. i.e. not including said event.
|
"""Returns the state at the event. i.e. not including said event.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
event = yield self.store.get_event(
|
||||||
|
event_id, allow_none=False, check_room_id=room_id,
|
||||||
|
)
|
||||||
|
|
||||||
state_groups = yield self.store.get_state_groups(
|
state_groups = yield self.store.get_state_groups(
|
||||||
room_id, [event_id]
|
room_id, [event_id]
|
||||||
)
|
)
|
||||||
|
@ -1359,8 +1364,7 @@ class FederationHandler(BaseHandler):
|
||||||
(e.type, e.state_key): e for e in state
|
(e.type, e.state_key): e for e in state
|
||||||
}
|
}
|
||||||
|
|
||||||
event = yield self.store.get_event(event_id)
|
if event.is_state():
|
||||||
if event and event.is_state():
|
|
||||||
# Get previous state
|
# Get previous state
|
||||||
if "replaces_state" in event.unsigned:
|
if "replaces_state" in event.unsigned:
|
||||||
prev_id = event.unsigned["replaces_state"]
|
prev_id = event.unsigned["replaces_state"]
|
||||||
|
@ -1391,6 +1395,10 @@ class FederationHandler(BaseHandler):
|
||||||
def get_state_ids_for_pdu(self, room_id, event_id):
|
def get_state_ids_for_pdu(self, room_id, event_id):
|
||||||
"""Returns the state at the event. i.e. not including said event.
|
"""Returns the state at the event. i.e. not including said event.
|
||||||
"""
|
"""
|
||||||
|
event = yield self.store.get_event(
|
||||||
|
event_id, allow_none=False, check_room_id=room_id,
|
||||||
|
)
|
||||||
|
|
||||||
state_groups = yield self.store.get_state_groups_ids(
|
state_groups = yield self.store.get_state_groups_ids(
|
||||||
room_id, [event_id]
|
room_id, [event_id]
|
||||||
)
|
)
|
||||||
|
@ -1399,8 +1407,7 @@ class FederationHandler(BaseHandler):
|
||||||
_, state = state_groups.items().pop()
|
_, state = state_groups.items().pop()
|
||||||
results = state
|
results = state
|
||||||
|
|
||||||
event = yield self.store.get_event(event_id)
|
if event.is_state():
|
||||||
if event and event.is_state():
|
|
||||||
# Get previous state
|
# Get previous state
|
||||||
if "replaces_state" in event.unsigned:
|
if "replaces_state" in event.unsigned:
|
||||||
prev_id = event.unsigned["replaces_state"]
|
prev_id = event.unsigned["replaces_state"]
|
||||||
|
@ -1706,8 +1713,19 @@ class FederationHandler(BaseHandler):
|
||||||
defer.returnValue(context)
|
defer.returnValue(context)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_query_auth(self, origin, event_id, remote_auth_chain, rejects,
|
def on_query_auth(self, origin, event_id, room_id, remote_auth_chain, rejects,
|
||||||
missing):
|
missing):
|
||||||
|
in_room = yield self.auth.check_host_in_room(
|
||||||
|
room_id,
|
||||||
|
origin
|
||||||
|
)
|
||||||
|
if not in_room:
|
||||||
|
raise AuthError(403, "Host not in room.")
|
||||||
|
|
||||||
|
event = yield self.store.get_event(
|
||||||
|
event_id, allow_none=False, check_room_id=room_id
|
||||||
|
)
|
||||||
|
|
||||||
# Just go through and process each event in `remote_auth_chain`. We
|
# Just go through and process each event in `remote_auth_chain`. We
|
||||||
# don't want to fall into the trap of `missing` being wrong.
|
# don't want to fall into the trap of `missing` being wrong.
|
||||||
for e in remote_auth_chain:
|
for e in remote_auth_chain:
|
||||||
|
@ -1717,7 +1735,6 @@ class FederationHandler(BaseHandler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Now get the current auth_chain for the event.
|
# Now get the current auth_chain for the event.
|
||||||
event = yield self.store.get_event(event_id)
|
|
||||||
local_auth_chain = yield self.store.get_auth_chain(
|
local_auth_chain = yield self.store.get_auth_chain(
|
||||||
[auth_id for auth_id, _ in event.auth_events],
|
[auth_id for auth_id, _ in event.auth_events],
|
||||||
include_given=True
|
include_given=True
|
||||||
|
|
|
@ -88,7 +88,7 @@ class EventRestServlet(ClientV1RestServlet):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_GET(self, request, event_id):
|
def on_GET(self, request, event_id):
|
||||||
requester = yield self.auth.get_user_by_req(request)
|
requester = yield self.auth.get_user_by_req(request)
|
||||||
event = yield self.event_handler.get_event(requester.user, event_id)
|
event = yield self.event_handler.get_event(requester.user, None, event_id)
|
||||||
|
|
||||||
time_now = self.clock.time_msec()
|
time_now = self.clock.time_msec()
|
||||||
if event:
|
if event:
|
||||||
|
|
|
@ -508,7 +508,7 @@ class RoomEventServlet(ClientV1RestServlet):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def on_GET(self, request, room_id, event_id):
|
def on_GET(self, request, room_id, event_id):
|
||||||
requester = yield self.auth.get_user_by_req(request)
|
requester = yield self.auth.get_user_by_req(request)
|
||||||
event = yield self.event_handler.get_event(requester.user, event_id)
|
event = yield self.event_handler.get_event(requester.user, room_id, event_id)
|
||||||
|
|
||||||
time_now = self.clock.time_msec()
|
time_now = self.clock.time_msec()
|
||||||
if event:
|
if event:
|
||||||
|
|
|
@ -343,6 +343,7 @@ class EventFederationWorkerStore(EventsWorkerStore, SignatureWorkerStore,
|
||||||
table="events",
|
table="events",
|
||||||
keyvalues={
|
keyvalues={
|
||||||
"event_id": event_id,
|
"event_id": event_id,
|
||||||
|
"room_id": room_id,
|
||||||
},
|
},
|
||||||
retcol="depth",
|
retcol="depth",
|
||||||
allow_none=True,
|
allow_none=True,
|
||||||
|
|
|
@ -19,7 +19,7 @@ from canonicaljson import json
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.errors import SynapseError
|
from synapse.api.errors import NotFoundError
|
||||||
# these are only included to make the type annotations work
|
# these are only included to make the type annotations work
|
||||||
from synapse.events import EventBase # noqa: F401
|
from synapse.events import EventBase # noqa: F401
|
||||||
from synapse.events import FrozenEvent
|
from synapse.events import FrozenEvent
|
||||||
|
@ -76,7 +76,7 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_event(self, event_id, check_redacted=True,
|
def get_event(self, event_id, check_redacted=True,
|
||||||
get_prev_content=False, allow_rejected=False,
|
get_prev_content=False, allow_rejected=False,
|
||||||
allow_none=False):
|
allow_none=False, check_room_id=None):
|
||||||
"""Get an event from the database by event_id.
|
"""Get an event from the database by event_id.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -87,7 +87,9 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
include the previous states content in the unsigned field.
|
include the previous states content in the unsigned field.
|
||||||
allow_rejected (bool): If True return rejected events.
|
allow_rejected (bool): If True return rejected events.
|
||||||
allow_none (bool): If True, return None if no event found, if
|
allow_none (bool): If True, return None if no event found, if
|
||||||
False throw an exception.
|
False throw a NotFoundError
|
||||||
|
check_room_id (str|None): if not None, check the room of the found event.
|
||||||
|
If there is a mismatch, behave as per allow_none.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Deferred : A FrozenEvent.
|
Deferred : A FrozenEvent.
|
||||||
|
@ -99,10 +101,16 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
allow_rejected=allow_rejected,
|
allow_rejected=allow_rejected,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not events and not allow_none:
|
event = events[0] if events else None
|
||||||
raise SynapseError(404, "Could not find event %s" % (event_id,))
|
|
||||||
|
|
||||||
defer.returnValue(events[0] if events else None)
|
if event is not None and check_room_id is not None:
|
||||||
|
if event.room_id != check_room_id:
|
||||||
|
event = None
|
||||||
|
|
||||||
|
if event is None and not allow_none:
|
||||||
|
raise NotFoundError("Could not find event %s" % (event_id,))
|
||||||
|
|
||||||
|
defer.returnValue(event)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_events(self, event_ids, check_redacted=True,
|
def get_events(self, event_ids, check_redacted=True,
|
||||||
|
|
Loading…
Reference in a new issue