mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-21 20:24:32 +03:00
Merge branch 'shhs' of ssh://github.com/matrix-org/synapse into shhs
This commit is contained in:
commit
8d9a56e0a6
8 changed files with 124 additions and 65 deletions
|
@ -1,46 +0,0 @@
|
||||||
version: 2
|
|
||||||
jobs:
|
|
||||||
dockerhubuploadrelease:
|
|
||||||
machine: true
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run: docker build -f docker/Dockerfile --label gitsha1=${CIRCLE_SHA1} -t matrixdotorg/synapse:${CIRCLE_TAG} -t matrixdotorg/synapse:${CIRCLE_TAG}-py3 .
|
|
||||||
- run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
|
|
||||||
- run: docker push matrixdotorg/synapse:${CIRCLE_TAG}
|
|
||||||
- run: docker push matrixdotorg/synapse:${CIRCLE_TAG}-py3
|
|
||||||
dockerhubuploadreleaseshhs:
|
|
||||||
machine: true
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run: docker build -f docker/Dockerfile --label gitsha1=${CIRCLE_SHA1} -t matrixdotorg/synapse:${CIRCLE_TAG} --build-arg PYTHON_VERSION=3.7 .
|
|
||||||
- run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
|
|
||||||
- run: docker push matrixdotorg/synapse:${CIRCLE_TAG}
|
|
||||||
dockerhubuploadlatest:
|
|
||||||
machine: true
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run: docker build -f docker/Dockerfile --label gitsha1=${CIRCLE_SHA1} -t matrixdotorg/synapse:latest -t matrixdotorg/synapse:latest-py3 .
|
|
||||||
- run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
|
|
||||||
- run: docker push matrixdotorg/synapse:latest
|
|
||||||
- run: docker push matrixdotorg/synapse:latest-py3
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
build:
|
|
||||||
jobs:
|
|
||||||
- dockerhubuploadrelease:
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: /v[0-9].[0-9]+.[0-9]+.*/
|
|
||||||
branches:
|
|
||||||
ignore: /.*/
|
|
||||||
- dockerhubuploadreleaseshhs:
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: /shhs-v[0-9]+.[0-9]+.*/
|
|
||||||
branches:
|
|
||||||
ignore: /.*/
|
|
||||||
- dockerhubuploadlatest:
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only: master
|
|
28
CHANGES.md
28
CHANGES.md
|
@ -1,3 +1,22 @@
|
||||||
|
Synapse 1.2.1 (2019-07-26)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Security update
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This release includes *four* security fixes:
|
||||||
|
|
||||||
|
- Prevent an attack where a federated server could send redactions for arbitrary events in v1 and v2 rooms. ([\#5767](https://github.com/matrix-org/synapse/issues/5767))
|
||||||
|
- Prevent a denial-of-service attack where cycles of redaction events would make Synapse spin infinitely. Thanks to `@lrizika:matrix.org` for identifying and responsibly disclosing this issue. ([0f2ecb961](https://github.com/matrix-org/synapse/commit/0f2ecb961))
|
||||||
|
- Prevent an attack where users could be joined or parted from public rooms without their consent. Thanks to @Dylanger for identifying and responsibly disclosing this issue. ([\#5744](https://github.com/matrix-org/synapse/issues/5744))
|
||||||
|
- Fix a vulnerability where a federated server could spoof read-receipts from
|
||||||
|
users on other servers. Thanks to @Dylanger for identifying this issue too. ([\#5743](https://github.com/matrix-org/synapse/issues/5743))
|
||||||
|
|
||||||
|
Additionally, the following fix was in Synapse **1.2.0**, but was not correctly
|
||||||
|
identified during the original release:
|
||||||
|
|
||||||
|
- It was possible for a room moderator to send a redaction for an `m.room.create` event, which would downgrade the room to version 1. Thanks to `/dev/ponies` for identifying and responsibly disclosing this issue! ([\#5701](https://github.com/matrix-org/synapse/issues/5701))
|
||||||
|
|
||||||
Synapse 1.2.0 (2019-07-25)
|
Synapse 1.2.0 (2019-07-25)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -16,6 +35,14 @@ Bugfixes
|
||||||
Synapse 1.2.0rc1 (2019-07-22)
|
Synapse 1.2.0rc1 (2019-07-22)
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
Security fixes
|
||||||
|
--------------
|
||||||
|
|
||||||
|
This update included a security fix which was initially incorrectly flagged as
|
||||||
|
a regular bug fix.
|
||||||
|
|
||||||
|
- It was possible for a room moderator to send a redaction for an `m.room.create` event, which would downgrade the room to version 1. Thanks to `/dev/ponies` for identifying and responsibly disclosing this issue! ([\#5701](https://github.com/matrix-org/synapse/issues/5701))
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
@ -41,7 +68,6 @@ Bugfixes
|
||||||
- Fix bug in #5626 that prevented the original_event field from actually having the contents of the original event in a call to `/relations`. ([\#5654](https://github.com/matrix-org/synapse/issues/5654))
|
- Fix bug in #5626 that prevented the original_event field from actually having the contents of the original event in a call to `/relations`. ([\#5654](https://github.com/matrix-org/synapse/issues/5654))
|
||||||
- Fix 3PID bind requests being sent to identity servers as `application/x-form-www-urlencoded` data, which is deprecated. ([\#5658](https://github.com/matrix-org/synapse/issues/5658))
|
- Fix 3PID bind requests being sent to identity servers as `application/x-form-www-urlencoded` data, which is deprecated. ([\#5658](https://github.com/matrix-org/synapse/issues/5658))
|
||||||
- Fix some problems with authenticating redactions in recent room versions. ([\#5699](https://github.com/matrix-org/synapse/issues/5699), [\#5700](https://github.com/matrix-org/synapse/issues/5700), [\#5707](https://github.com/matrix-org/synapse/issues/5707))
|
- Fix some problems with authenticating redactions in recent room versions. ([\#5699](https://github.com/matrix-org/synapse/issues/5699), [\#5700](https://github.com/matrix-org/synapse/issues/5700), [\#5707](https://github.com/matrix-org/synapse/issues/5707))
|
||||||
- Ignore redactions of m.room.create events. ([\#5701](https://github.com/matrix-org/synapse/issues/5701))
|
|
||||||
|
|
||||||
|
|
||||||
Updates to the Docker image
|
Updates to the Docker image
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
matrix-synapse-py3 (1.2.1) stable; urgency=medium
|
||||||
|
|
||||||
|
* New synapse release 1.2.1.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Fri, 26 Jul 2019 11:32:47 +0100
|
||||||
|
|
||||||
matrix-synapse-py3 (1.2.0) stable; urgency=medium
|
matrix-synapse-py3 (1.2.0) stable; urgency=medium
|
||||||
|
|
||||||
[ Amber Brown ]
|
[ Amber Brown ]
|
||||||
|
|
|
@ -35,4 +35,4 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
__version__ = "1.2.0"
|
__version__ = "1.2.1"
|
||||||
|
|
|
@ -369,7 +369,7 @@ class FederationServer(FederationBase):
|
||||||
logger.warn("Room version %s not in %s", room_version, supported_versions)
|
logger.warn("Room version %s not in %s", room_version, supported_versions)
|
||||||
raise IncompatibleRoomVersionError(room_version=room_version)
|
raise IncompatibleRoomVersionError(room_version=room_version)
|
||||||
|
|
||||||
pdu = yield self.handler.on_make_join_request(room_id, user_id)
|
pdu = yield self.handler.on_make_join_request(origin, room_id, user_id)
|
||||||
time_now = self._clock.time_msec()
|
time_now = self._clock.time_msec()
|
||||||
defer.returnValue(
|
defer.returnValue(
|
||||||
{"event": pdu.get_pdu_json(time_now), "room_version": room_version}
|
{"event": pdu.get_pdu_json(time_now), "room_version": room_version}
|
||||||
|
@ -423,7 +423,7 @@ class FederationServer(FederationBase):
|
||||||
def on_make_leave_request(self, origin, room_id, user_id):
|
def on_make_leave_request(self, origin, room_id, user_id):
|
||||||
origin_host, _ = parse_server_name(origin)
|
origin_host, _ = parse_server_name(origin)
|
||||||
yield self.check_server_matches_acl(origin_host, room_id)
|
yield self.check_server_matches_acl(origin_host, room_id)
|
||||||
pdu = yield self.handler.on_make_leave_request(room_id, user_id)
|
pdu = yield self.handler.on_make_leave_request(origin, room_id, user_id)
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
|
||||||
|
|
|
@ -1204,11 +1204,28 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@log_function
|
@log_function
|
||||||
def on_make_join_request(self, room_id, user_id):
|
def on_make_join_request(self, origin, room_id, user_id):
|
||||||
""" We've received a /make_join/ request, so we create a partial
|
""" We've received a /make_join/ request, so we create a partial
|
||||||
join event for the room and return that. We do *not* persist or
|
join event for the room and return that. We do *not* persist or
|
||||||
process it until the other server has signed it and sent it back.
|
process it until the other server has signed it and sent it back.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
origin (str): The (verified) server name of the requesting server.
|
||||||
|
room_id (str): Room to create join event in
|
||||||
|
user_id (str): The user to create the join for
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deferred[FrozenEvent]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if get_domain_from_id(user_id) != origin:
|
||||||
|
logger.info(
|
||||||
|
"Got /make_join request for user %r from different origin %s, ignoring",
|
||||||
|
user_id,
|
||||||
|
origin,
|
||||||
|
)
|
||||||
|
raise SynapseError(403, "User not from origin", Codes.FORBIDDEN)
|
||||||
|
|
||||||
event_content = {"membership": Membership.JOIN}
|
event_content = {"membership": Membership.JOIN}
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
|
@ -1411,11 +1428,27 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
@log_function
|
@log_function
|
||||||
def on_make_leave_request(self, room_id, user_id):
|
def on_make_leave_request(self, origin, room_id, user_id):
|
||||||
""" We've received a /make_leave/ request, so we create a partial
|
""" We've received a /make_leave/ request, so we create a partial
|
||||||
leave event for the room and return that. We do *not* persist or
|
leave event for the room and return that. We do *not* persist or
|
||||||
process it until the other server has signed it and sent it back.
|
process it until the other server has signed it and sent it back.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
origin (str): The (verified) server name of the requesting server.
|
||||||
|
room_id (str): Room to create leave event in
|
||||||
|
user_id (str): The user to create the leave for
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deferred[FrozenEvent]
|
||||||
"""
|
"""
|
||||||
|
if get_domain_from_id(user_id) != origin:
|
||||||
|
logger.info(
|
||||||
|
"Got /make_leave request for user %r from different origin %s, ignoring",
|
||||||
|
user_id,
|
||||||
|
origin,
|
||||||
|
)
|
||||||
|
raise SynapseError(403, "User not from origin", Codes.FORBIDDEN)
|
||||||
|
|
||||||
room_version = yield self.store.get_room_version(room_id)
|
room_version = yield self.store.get_room_version(room_id)
|
||||||
builder = self.event_builder_factory.new(
|
builder = self.event_builder_factory.new(
|
||||||
room_version,
|
room_version,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import logging
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.handlers._base import BaseHandler
|
from synapse.handlers._base import BaseHandler
|
||||||
from synapse.types import ReadReceipt
|
from synapse.types import ReadReceipt, get_domain_from_id
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -40,7 +40,19 @@ class ReceiptsHandler(BaseHandler):
|
||||||
def _received_remote_receipt(self, origin, content):
|
def _received_remote_receipt(self, origin, content):
|
||||||
"""Called when we receive an EDU of type m.receipt from a remote HS.
|
"""Called when we receive an EDU of type m.receipt from a remote HS.
|
||||||
"""
|
"""
|
||||||
receipts = [
|
receipts = []
|
||||||
|
for room_id, room_values in content.items():
|
||||||
|
for receipt_type, users in room_values.items():
|
||||||
|
for user_id, user_values in users.items():
|
||||||
|
if get_domain_from_id(user_id) != origin:
|
||||||
|
logger.info(
|
||||||
|
"Received receipt for user %r from server %s, ignoring",
|
||||||
|
user_id,
|
||||||
|
origin,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
receipts.append(
|
||||||
ReadReceipt(
|
ReadReceipt(
|
||||||
room_id=room_id,
|
room_id=room_id,
|
||||||
receipt_type=receipt_type,
|
receipt_type=receipt_type,
|
||||||
|
@ -48,10 +60,7 @@ class ReceiptsHandler(BaseHandler):
|
||||||
event_ids=user_values["event_ids"],
|
event_ids=user_values["event_ids"],
|
||||||
data=user_values.get("data", {}),
|
data=user_values.get("data", {}),
|
||||||
)
|
)
|
||||||
for room_id, room_values in content.items()
|
)
|
||||||
for receipt_type, users in room_values.items()
|
|
||||||
for user_id, user_values in users.items()
|
|
||||||
]
|
|
||||||
|
|
||||||
yield self._handle_new_receipts(receipts)
|
yield self._handle_new_receipts(receipts)
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,14 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if original_event.room_id != entry.event.room_id:
|
||||||
|
logger.info(
|
||||||
|
"Withholding redaction %s of event %s from a different room",
|
||||||
|
event_id,
|
||||||
|
redacted_event_id,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
if entry.event.internal_metadata.need_to_check_redaction():
|
if entry.event.internal_metadata.need_to_check_redaction():
|
||||||
original_domain = get_domain_from_id(original_event.sender)
|
original_domain = get_domain_from_id(original_event.sender)
|
||||||
redaction_domain = get_domain_from_id(entry.event.sender)
|
redaction_domain = get_domain_from_id(entry.event.sender)
|
||||||
|
@ -629,6 +637,10 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
# we choose to ignore redactions of m.room.create events.
|
# we choose to ignore redactions of m.room.create events.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if original_ev.type == "m.room.redaction":
|
||||||
|
# ... and redaction events
|
||||||
|
return None
|
||||||
|
|
||||||
redaction_map = yield self._get_events_from_cache_or_db(redactions)
|
redaction_map = yield self._get_events_from_cache_or_db(redactions)
|
||||||
|
|
||||||
for redaction_id in redactions:
|
for redaction_id in redactions:
|
||||||
|
@ -636,9 +648,21 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
if not redaction_entry:
|
if not redaction_entry:
|
||||||
# we don't have the redaction event, or the redaction event was not
|
# we don't have the redaction event, or the redaction event was not
|
||||||
# authorized.
|
# authorized.
|
||||||
|
logger.debug(
|
||||||
|
"%s was redacted by %s but redaction not found/authed",
|
||||||
|
original_ev.event_id,
|
||||||
|
redaction_id,
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
redaction_event = redaction_entry.event
|
redaction_event = redaction_entry.event
|
||||||
|
if redaction_event.room_id != original_ev.room_id:
|
||||||
|
logger.debug(
|
||||||
|
"%s was redacted by %s but redaction was in a different room!",
|
||||||
|
original_ev.event_id,
|
||||||
|
redaction_id,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
# Starting in room version v3, some redactions need to be
|
# Starting in room version v3, some redactions need to be
|
||||||
# rechecked if we didn't have the redacted event at the
|
# rechecked if we didn't have the redacted event at the
|
||||||
|
@ -650,8 +674,15 @@ class EventsWorkerStore(SQLBaseStore):
|
||||||
redaction_event.internal_metadata.recheck_redaction = False
|
redaction_event.internal_metadata.recheck_redaction = False
|
||||||
else:
|
else:
|
||||||
# Senders don't match, so the event isn't actually redacted
|
# Senders don't match, so the event isn't actually redacted
|
||||||
|
logger.debug(
|
||||||
|
"%s was redacted by %s but the senders don't match",
|
||||||
|
original_ev.event_id,
|
||||||
|
redaction_id,
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
logger.debug("Redacting %s due to %s", original_ev.event_id, redaction_id)
|
||||||
|
|
||||||
# we found a good redaction event. Redact!
|
# we found a good redaction event. Redact!
|
||||||
redacted_event = prune_event(original_ev)
|
redacted_event = prune_event(original_ev)
|
||||||
redacted_event.unsigned["redacted_by"] = redaction_id
|
redacted_event.unsigned["redacted_by"] = redaction_id
|
||||||
|
|
Loading…
Reference in a new issue