[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.
pull/618/head
David Wilson 5 years ago
parent 436a4b3b3c
commit 5924af1566

@ -3623,7 +3623,7 @@ class ExternalContext(object):
self.broker = Broker(activate_compat=False) self.broker = Broker(activate_compat=False)
self.router = Router(self.broker) self.router = Router(self.broker)
self.router.debug = self.config.get('debug', False) self.router.debug = self.config.get('debug', False)
self.router.undirectional = self.config['unidirectional'] self.router.unidirectional = self.config['unidirectional']
self.router.add_handler( self.router.add_handler(
fn=self._on_shutdown_msg, fn=self._on_shutdown_msg,
handle=SHUTDOWN, handle=SHUTDOWN,

@ -1,9 +1,11 @@
import sys
import time import time
import zlib import zlib
import unittest2 import unittest2
import testlib import testlib
import mitogen.core
import mitogen.master import mitogen.master
import mitogen.parent import mitogen.parent
import mitogen.utils 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): class UnidirectionalTest(testlib.RouterMixin, testlib.TestCase):
def test_siblings_cant_talk(self): def test_siblings_cant_talk_master(self):
self.router.unidirectional = True self.router.unidirectional = True
l1 = self.router.local() test_siblings_cant_talk(self.router)
l2 = self.router.local()
logs = testlib.LogCapturer()
logs.start()
e = self.assertRaises(mitogen.core.CallError,
lambda: l2.call(ping_context, l1))
msg = self.router.unidirectional_msg % ( def test_siblings_cant_talk_parent(self):
l2.context_id, # ensure 'unidirectional' attribute is respected for contexts started
l1.context_id, # by children.
) self.router.unidirectional = True
self.assertTrue(msg in str(e)) parent = self.router.local()
self.assertTrue('routing mode prevents forward of ' in logs.stop()) parent.call(test_siblings_cant_talk_remote)
def test_auth_id_can_talk(self): def test_auth_id_can_talk(self):
self.router.unidirectional = True self.router.unidirectional = True

Loading…
Cancel
Save