[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):
)) ))
class UnidirectionalTest(testlib.RouterMixin, testlib.TestCase): def test_siblings_cant_talk(router):
def test_siblings_cant_talk(self): l1 = router.local()
self.router.unidirectional = True l2 = router.local()
l1 = self.router.local()
l2 = self.router.local()
logs = testlib.LogCapturer() logs = testlib.LogCapturer()
logs.start() logs.start()
e = self.assertRaises(mitogen.core.CallError,
lambda: l2.call(ping_context, l1))
msg = self.router.unidirectional_msg % ( try:
l2.call(ping_context, l1)
except mitogen.core.CallError:
e = sys.exc_info()[1]
msg = mitogen.core.Router.unidirectional_msg % (
l2.context_id, l2.context_id,
l1.context_id, l1.context_id,
) )
self.assertTrue(msg in str(e)) assert msg in str(e)
self.assertTrue('routing mode prevents forward of ' in logs.stop()) 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_master(self):
self.router.unidirectional = True
test_siblings_cant_talk(self.router)
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): def test_auth_id_can_talk(self):
self.router.unidirectional = True self.router.unidirectional = True

Loading…
Cancel
Save