From 5924af1566763e48c42028399ea0cd95c457b3dc Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 8 Aug 2019 23:03:43 +0100 Subject: [PATCH] [security] core: undirectional routing wasn't respected in some cases When creating a context using Router.method(via=somechild), unidirectional mode was set on the new child correctly, however if the child were to call Router.method(), due to a typing mistake the new child would start without it. This doesn't impact the Ansible extension, as only forked tasks are started directly by children, and they are not responsible for routing messages. Add test so it can't happen again. --- mitogen/core.py | 2 +- tests/router_test.py | 48 ++++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/mitogen/core.py b/mitogen/core.py index 8428a479..c228079d 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -3623,7 +3623,7 @@ class ExternalContext(object): self.broker = Broker(activate_compat=False) self.router = Router(self.broker) self.router.debug = self.config.get('debug', False) - self.router.undirectional = self.config['unidirectional'] + self.router.unidirectional = self.config['unidirectional'] self.router.add_handler( fn=self._on_shutdown_msg, handle=SHUTDOWN, diff --git a/tests/router_test.py b/tests/router_test.py index 1bd6c26a..2b4a9d78 100644 --- a/tests/router_test.py +++ b/tests/router_test.py @@ -1,9 +1,11 @@ +import sys import time import zlib import unittest2 import testlib +import mitogen.core import mitogen.master import mitogen.parent import mitogen.utils @@ -341,22 +343,42 @@ class NoRouteTest(testlib.RouterMixin, testlib.TestCase): )) +def test_siblings_cant_talk(router): + l1 = router.local() + l2 = router.local() + logs = testlib.LogCapturer() + logs.start() + + try: + l2.call(ping_context, l1) + except mitogen.core.CallError: + e = sys.exc_info()[1] + + msg = mitogen.core.Router.unidirectional_msg % ( + l2.context_id, + l1.context_id, + ) + assert msg in str(e) + assert 'routing mode prevents forward of ' in logs.stop() + + +@mitogen.core.takes_econtext +def test_siblings_cant_talk_remote(econtext): + mitogen.parent.upgrade_router(econtext) + test_siblings_cant_talk(econtext.router) + + class UnidirectionalTest(testlib.RouterMixin, testlib.TestCase): - def test_siblings_cant_talk(self): + def test_siblings_cant_talk_master(self): self.router.unidirectional = True - l1 = self.router.local() - l2 = self.router.local() - logs = testlib.LogCapturer() - logs.start() - e = self.assertRaises(mitogen.core.CallError, - lambda: l2.call(ping_context, l1)) + test_siblings_cant_talk(self.router) - msg = self.router.unidirectional_msg % ( - l2.context_id, - l1.context_id, - ) - self.assertTrue(msg in str(e)) - self.assertTrue('routing mode prevents forward of ' in logs.stop()) + def test_siblings_cant_talk_parent(self): + # ensure 'unidirectional' attribute is respected for contexts started + # by children. + self.router.unidirectional = True + parent = self.router.local() + parent.call(test_siblings_cant_talk_remote) def test_auth_id_can_talk(self): self.router.unidirectional = True