From 52ca8676700368098ca0689c424f972ac54ac780 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Wed, 24 Sep 2014 17:25:41 +0100 Subject: [PATCH] Sign federation transactions --- synapse/federation/replication.py | 9 ++++++++- tests/federation/test_federation.py | 5 ++++- tests/handlers/test_federation.py | 7 ++++++- tests/handlers/test_presence.py | 21 +++++++++++++++++++-- tests/handlers/test_room.py | 5 ++++- tests/handlers/test_typing.py | 6 +++++- tests/rest/test_presence.py | 15 ++++++++++++--- tests/utils.py | 15 +++++++++++++++ 8 files changed, 73 insertions(+), 10 deletions(-) diff --git a/synapse/federation/replication.py b/synapse/federation/replication.py index 96b82f00c..84977e7e5 100644 --- a/synapse/federation/replication.py +++ b/synapse/federation/replication.py @@ -25,6 +25,8 @@ from .persistence import PduActions, TransactionActions from synapse.util.logutils import log_function +from syutil.crypto.jsonsign import sign_json + import logging @@ -489,7 +491,7 @@ class _TransactionQueue(object): """ def __init__(self, hs, transaction_actions, transport_layer): - + self.signing_key = hs.config.signing_key[0] self.server_name = hs.hostname self.transaction_actions = transaction_actions self.transport_layer = transport_layer @@ -604,6 +606,9 @@ class _TransactionQueue(object): # Actually send the transaction + server_name = self.server_name + signing_key = self.signing_key + # FIXME (erikj): This is a bit of a hack to make the Pdu age # keys work def cb(transaction): @@ -613,6 +618,8 @@ class _TransactionQueue(object): if "age_ts" in p: p["age"] = now - int(p["age_ts"]) + transaction = sign_json(transaction, server_name, signing_key) + return transaction code, response = yield self.transport_layer.send_transaction( diff --git a/tests/federation/test_federation.py b/tests/federation/test_federation.py index bb17e9aaf..eafc7879e 100644 --- a/tests/federation/test_federation.py +++ b/tests/federation/test_federation.py @@ -19,7 +19,7 @@ from tests import unittest # python imports from mock import Mock, ANY -from ..utils import MockHttpResource, MockClock +from ..utils import MockHttpResource, MockClock, MockKey from synapse.server import HomeServer from synapse.federation import initialize_http_replication @@ -64,6 +64,8 @@ class FederationTestCase(unittest.TestCase): self.mock_persistence.get_received_txn_response.return_value = ( defer.succeed(None) ) + self.mock_config = Mock() + self.mock_config.signing_key = [MockKey()] self.clock = MockClock() hs = HomeServer("test", resource_for_federation=self.mock_resource, @@ -71,6 +73,7 @@ class FederationTestCase(unittest.TestCase): db_pool=None, datastore=self.mock_persistence, clock=self.clock, + config=self.mock_config, ) self.federation = initialize_http_replication(hs) self.distributor = hs.get_distributor() diff --git a/tests/handlers/test_federation.py b/tests/handlers/test_federation.py index eb6b7c22e..5c6999727 100644 --- a/tests/handlers/test_federation.py +++ b/tests/handlers/test_federation.py @@ -26,12 +26,16 @@ from synapse.federation.units import Pdu from mock import NonCallableMock, ANY -from ..utils import get_mock_call_args +from ..utils import get_mock_call_args, MockKey class FederationTestCase(unittest.TestCase): def setUp(self): + + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] + self.hostname = "test" hs = HomeServer( self.hostname, @@ -48,6 +52,7 @@ class FederationTestCase(unittest.TestCase): "room_member_handler", "federation_handler", ]), + config=self.mock_config, ) self.datastore = hs.get_datastore() diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py index 765929d20..fe4b892ff 100644 --- a/tests/handlers/test_presence.py +++ b/tests/handlers/test_presence.py @@ -17,11 +17,12 @@ from tests import unittest from twisted.internet import defer, reactor -from mock import Mock, call, ANY +from mock import Mock, call, ANY, NonCallableMock import json from tests.utils import ( - MockHttpResource, MockClock, DeferredMockCallable, SQLiteMemoryDbPool + MockHttpResource, MockClock, DeferredMockCallable, SQLiteMemoryDbPool, + MockKey ) from synapse.server import HomeServer @@ -67,12 +68,16 @@ class PresenceStateTestCase(unittest.TestCase): db_pool = SQLiteMemoryDbPool() yield db_pool.prepare() + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] + hs = HomeServer("test", clock=MockClock(), db_pool=db_pool, handlers=None, resource_for_federation=Mock(), http_client=None, + config=self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) @@ -214,6 +219,9 @@ class PresenceInvitesTestCase(unittest.TestCase): db_pool = SQLiteMemoryDbPool() yield db_pool.prepare() + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] + hs = HomeServer("test", clock=MockClock(), db_pool=db_pool, @@ -221,6 +229,7 @@ class PresenceInvitesTestCase(unittest.TestCase): resource_for_client=Mock(), resource_for_federation=self.mock_federation_resource, http_client=self.mock_http_client, + config=self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) @@ -503,6 +512,9 @@ class PresencePushTestCase(unittest.TestCase): self.mock_federation_resource = MockHttpResource() + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] + hs = HomeServer("test", clock=self.clock, db_pool=None, @@ -520,6 +532,7 @@ class PresencePushTestCase(unittest.TestCase): resource_for_client=Mock(), resource_for_federation=self.mock_federation_resource, http_client=self.mock_http_client, + config=self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) @@ -995,6 +1008,9 @@ class PresencePollingTestCase(unittest.TestCase): self.mock_federation_resource = MockHttpResource() + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] + hs = HomeServer("test", clock=MockClock(), db_pool=None, @@ -1009,6 +1025,7 @@ class PresencePollingTestCase(unittest.TestCase): resource_for_client=Mock(), resource_for_federation=self.mock_federation_resource, http_client=self.mock_http_client, + config = self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) diff --git a/tests/handlers/test_room.py b/tests/handlers/test_room.py index a1a2e8049..c88d1c884 100644 --- a/tests/handlers/test_room.py +++ b/tests/handlers/test_room.py @@ -24,6 +24,7 @@ from synapse.api.constants import Membership from synapse.handlers.room import RoomMemberHandler, RoomCreationHandler from synapse.handlers.profile import ProfileHandler from synapse.server import HomeServer +from ..utils import MockKey from mock import Mock, NonCallableMock @@ -31,6 +32,8 @@ from mock import Mock, NonCallableMock class RoomMemberHandlerTestCase(unittest.TestCase): def setUp(self): + self.mock_config = NonCallableMock() + self.mock_config.signing_key = [MockKey()] self.hostname = "red" hs = HomeServer( self.hostname, @@ -38,7 +41,6 @@ class RoomMemberHandlerTestCase(unittest.TestCase): ratelimiter=NonCallableMock(spec_set=[ "send_message", ]), - config=NonCallableMock(), datastore=NonCallableMock(spec_set=[ "persist_event", "get_joined_hosts_for_room", @@ -57,6 +59,7 @@ class RoomMemberHandlerTestCase(unittest.TestCase): ]), auth=NonCallableMock(spec_set=["check"]), state_handler=NonCallableMock(spec_set=["handle_new_event"]), + config=self.mock_config, ) self.federation = NonCallableMock(spec_set=[ diff --git a/tests/handlers/test_typing.py b/tests/handlers/test_typing.py index a66f208ab..0ab829b9a 100644 --- a/tests/handlers/test_typing.py +++ b/tests/handlers/test_typing.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock, call, ANY import json -from ..utils import MockHttpResource, MockClock, DeferredMockCallable +from ..utils import MockHttpResource, MockClock, DeferredMockCallable, MockKey from synapse.server import HomeServer from synapse.handlers.typing import TypingNotificationHandler @@ -61,6 +61,9 @@ class TypingNotificationsTestCase(unittest.TestCase): self.mock_federation_resource = MockHttpResource() + self.mock_config = Mock() + self.mock_config.signing_key = [MockKey()] + hs = HomeServer("test", clock=self.clock, db_pool=None, @@ -75,6 +78,7 @@ class TypingNotificationsTestCase(unittest.TestCase): resource_for_client=Mock(), resource_for_federation=self.mock_federation_resource, http_client=self.mock_http_client, + config=self.mock_config, ) hs.handlers = JustTypingNotificationHandlers(hs) diff --git a/tests/rest/test_presence.py b/tests/rest/test_presence.py index ea3478ac5..20fd17900 100644 --- a/tests/rest/test_presence.py +++ b/tests/rest/test_presence.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock -from ..utils import MockHttpResource +from ..utils import MockHttpResource, MockKey from synapse.api.constants import PresenceState from synapse.handlers.presence import PresenceHandler @@ -45,7 +45,8 @@ class PresenceStateTestCase(unittest.TestCase): def setUp(self): self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) - + self.mock_config = Mock() + self.mock_config.signing_key = [MockKey()] hs = HomeServer("test", db_pool=None, datastore=Mock(spec=[ @@ -55,6 +56,7 @@ class PresenceStateTestCase(unittest.TestCase): http_client=None, resource_for_client=self.mock_resource, resource_for_federation=self.mock_resource, + config=self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) @@ -119,6 +121,8 @@ class PresenceListTestCase(unittest.TestCase): def setUp(self): self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) + self.mock_config = Mock() + self.mock_config.signing_key = [MockKey()] hs = HomeServer("test", db_pool=None, @@ -134,7 +138,8 @@ class PresenceListTestCase(unittest.TestCase): ]), http_client=None, resource_for_client=self.mock_resource, - resource_for_federation=self.mock_resource + resource_for_federation=self.mock_resource, + config=self.mock_config, ) hs.handlers = JustPresenceHandlers(hs) @@ -225,6 +230,9 @@ class PresenceEventStreamTestCase(unittest.TestCase): def setUp(self): self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) + self.mock_config = Mock() + self.mock_config.signing_key = [MockKey()] + # HIDEOUS HACKERY # TODO(paul): This should be injected in via the HomeServer DI system from synapse.streams.events import ( @@ -255,6 +263,7 @@ class PresenceEventStreamTestCase(unittest.TestCase): "cancel_call_later", "time_msec", ]), + config=self.mock_config, ) hs.get_clock().time_msec.return_value = 1000000 diff --git a/tests/utils.py b/tests/utils.py index bc5d35e56..beb2aef08 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -108,6 +108,21 @@ class MockHttpResource(HttpServer): self.callbacks.append((method, path_pattern, callback)) +class MockKey(object): + alg = "mock_alg" + version = "mock_version" + + @property + def verify_key(self): + return self + + def sign(self, message): + return b"\x9a\x87$" + + def verify(self, message, sig): + assert sig == b"\x9a\x87$" + + class MockClock(object): now = 1000