Skip to content

Commit 5924af1

Browse files
committed
[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.
1 parent 436a4b3 commit 5924af1

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

mitogen/core.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3623,7 +3623,7 @@ def _setup_master(self):
36233623
self.broker = Broker(activate_compat=False)
36243624
self.router = Router(self.broker)
36253625
self.router.debug = self.config.get('debug', False)
3626-
self.router.undirectional = self.config['unidirectional']
3626+
self.router.unidirectional = self.config['unidirectional']
36273627
self.router.add_handler(
36283628
fn=self._on_shutdown_msg,
36293629
handle=SHUTDOWN,

tests/router_test.py

+35-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import sys
12
import time
23
import zlib
34

45
import unittest2
56

67
import testlib
8+
import mitogen.core
79
import mitogen.master
810
import mitogen.parent
911
import mitogen.utils
@@ -341,22 +343,42 @@ def test_previously_alive_context_returns_dead(self):
341343
))
342344

343345

346+
def test_siblings_cant_talk(router):
347+
l1 = router.local()
348+
l2 = router.local()
349+
logs = testlib.LogCapturer()
350+
logs.start()
351+
352+
try:
353+
l2.call(ping_context, l1)
354+
except mitogen.core.CallError:
355+
e = sys.exc_info()[1]
356+
357+
msg = mitogen.core.Router.unidirectional_msg % (
358+
l2.context_id,
359+
l1.context_id,
360+
)
361+
assert msg in str(e)
362+
assert 'routing mode prevents forward of ' in logs.stop()
363+
364+
365+
@mitogen.core.takes_econtext
366+
def test_siblings_cant_talk_remote(econtext):
367+
mitogen.parent.upgrade_router(econtext)
368+
test_siblings_cant_talk(econtext.router)
369+
370+
344371
class UnidirectionalTest(testlib.RouterMixin, testlib.TestCase):
345-
def test_siblings_cant_talk(self):
372+
def test_siblings_cant_talk_master(self):
346373
self.router.unidirectional = True
347-
l1 = self.router.local()
348-
l2 = self.router.local()
349-
logs = testlib.LogCapturer()
350-
logs.start()
351-
e = self.assertRaises(mitogen.core.CallError,
352-
lambda: l2.call(ping_context, l1))
374+
test_siblings_cant_talk(self.router)
353375

354-
msg = self.router.unidirectional_msg % (
355-
l2.context_id,
356-
l1.context_id,
357-
)
358-
self.assertTrue(msg in str(e))
359-
self.assertTrue('routing mode prevents forward of ' in logs.stop())
376+
def test_siblings_cant_talk_parent(self):
377+
# ensure 'unidirectional' attribute is respected for contexts started
378+
# by children.
379+
self.router.unidirectional = True
380+
parent = self.router.local()
381+
parent.call(test_siblings_cant_talk_remote)
360382

361383
def test_auth_id_can_talk(self):
362384
self.router.unidirectional = True

0 commit comments

Comments
 (0)