def makeBroadcasterService(endpoint, local_ivo, test_interval, whitelist): """Create a VOEvent receiver service. The receiver service accepts VOEvent messages submitted to the broker by authors. Parameters ---------- endpoint : implements `twisted.internet.interfaces.IStreamServerEndpoint` The endpoint to which the service will listen. local_ivo : `str` IVOA identifier for the subscriber. test_interval: `int` The interval in seconds between test events to be broadcast. If ``0``, no test events will be sent. whitelist : `list` of `ipaddress.IPv4Network` or `ipaddress.IPv6Network` Only addresses which fall in a network included in the whitelist are permitted to subscribe. """ factory = VOEventBroadcasterFactory(local_ivo, test_interval) if log.LEVEL >= log.Levels.INFO: factory.noisy = False whitelisting_factory = WhitelistingFactory(factory, whitelist, "subscription") if log.LEVEL >= log.Levels.INFO: whitelisting_factory.noisy = False service = StreamServerEndpointService(endpoint, whitelisting_factory) # Shut down, rather than simply logging an error, if we can't bind. service._raiseSynchronously = True return service
def test_empty_whitelist(self): # All connections should be denied factory = WhitelistingFactory(TestFactory(), []) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), None )
def test_empty_whitelist(self): # All connections should be denied and a default message logged. factory = WhitelistingFactory(TestFactory(), []) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), None) self.assertEqual(len(self.observer.messages), 1) self.assertTrue("connection" in self.observer.messages[0][0])
def test_in_whitelist(self): # Connection should be accepted and nothing logged. factory = WhitelistingFactory(TestFactory(), [ip_network('0.0.0.0/0')]) self.assertIsInstance( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), Protocol) self.assertEqual(len(self.observer.messages), 0)
def test_not_in_whitelist(self): # Connection should be accepted and nothing logged. factory = WhitelistingFactory(TestFactory(), [ip_network('127.0.0.1/32')]) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.2', 0)), None )
def test_in_whitelist(self): # Connection should be accepted and nothing logged. factory = WhitelistingFactory(TestFactory(), [ip_network('0.0.0.0/0')]) self.assertIsInstance( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), Protocol ) self.assertEqual(len(self.observer.messages), 0)
def test_empty_whitelist(self): # All connections should be denied and a default message logged. factory = WhitelistingFactory(TestFactory(), []) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), None ) self.assertEqual(len(self.observer.messages), 1) self.assertTrue("connection" in self.observer.messages[0][0])
def makeService(config): event_db = Event_DB(config['eventdb']) LoopingCall(event_db.prune, MAX_AGE).start(PRUNE_INTERVAL) broker_service = MultiService() if config['broadcast']: broadcaster_factory = VOEventBroadcasterFactory( config["local-ivo"], config['broadcast-test-interval'] ) if log.LEVEL >= log.Levels.INFO: broadcaster_factory.noisy = False broadcaster_service = TCPServer( config['broadcast-port'], broadcaster_factory ) broadcaster_service.setName("Broadcaster") broadcaster_service.setServiceParent(broker_service) # If we're running a broadcast, we will rebroadcast any events we # receive to it. config['handlers'].append(EventRelay(broadcaster_factory)) if config['receive']: receiver_factory = VOEventReceiverFactory( local_ivo=config['local-ivo'], validators=[ CheckPreviouslySeen(event_db), CheckSchema( os.path.join(comet.__path__[0], "schema/VOEvent-v2.0.xsd") ), CheckIVORN() ], handlers=config['handlers'] ) if log.LEVEL >= log.Levels.INFO: receiver_factory.noisy = False whitelisting_factory = WhitelistingFactory(receiver_factory, config['whitelist']) if log.LEVEL >= log.Levels.INFO: whitelisting_factory.noisy = False receiver_service = TCPServer(config['receive-port'], whitelisting_factory) receiver_service.setName("Receiver") receiver_service.setServiceParent(broker_service) for host, port in config["remotes"]: subscriber_factory = VOEventSubscriberFactory( local_ivo=config["local-ivo"], validators=[CheckPreviouslySeen(event_db)], handlers=config['handlers'], filters=config['filters'] ) if log.LEVEL >= log.Levels.INFO: subscriber_factory.noisy = False remote_service = TCPClient(host, port, subscriber_factory) remote_service.setName("Remote %s:%d" % (host, port)) remote_service.setServiceParent(broker_service) if not broker_service.services: reactor.callWhenRunning(log.warning, "No services requested; stopping.") reactor.callWhenRunning(reactor.stop) return broker_service
def test_log_message(self): # Should be possible to customize the message which is logged. TEST_STRING = "test-1234" factory = WhitelistingFactory(TestFactory(), [ip_network('127.0.0.1/32')], TEST_STRING) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.2', 0)), None) self.assertFalse("connection" in self.observer.messages[0][0]) self.assertTrue(TEST_STRING in self.observer.messages[0][0])
def test_log_message(self): # Should be possible to customize the message which is logged. TEST_STRING = "test-1234" factory = WhitelistingFactory( TestFactory(), [ip_network('127.0.0.1/32')], TEST_STRING ) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.2', 0)), None ) self.assertFalse("connection" in self.observer.messages[0][0]) self.assertTrue(TEST_STRING in self.observer.messages[0][0])
def makeReceiverService(endpoint, local_ivo, validators, handlers, whitelist): """Create a VOEvent receiver service. The receiver service accepts VOEvent messages submitted to the broker by authors. Parameters ---------- endpoint : implements `twisted.internet.interfaces.IStreamServerEndpoint` The endpoint to which the service will listen. local_ivo : `str` IVOA identifier for the subscriber. validators : `list` of implementers of `~comet.icomet.IValidator`. Validators which will be applied to incoming events. Events which fail validation will be rejected. handlers : `list` of implementers of `~comet.icomet.IHandler`. Handlers to which events which pass validation will be passed. whitelist : `list` of `ipaddress.IPv4Network` or `ipaddress.IPv6Network` Submissions are only accepted from addresses which fall in a network included in the whitelist. Warnings -------- Although a non-TCP endpoint can be specified (a Unix domain socket, for example), the whitelist won't be applied to it correctly (indeed, it will probably break horribly). """ factory = VOEventReceiverFactory(local_ivo=local_ivo, validators=validators, handlers=handlers) if log.LEVEL >= log.Levels.INFO: factory.noisy = False whitelisting_factory = WhitelistingFactory(factory, whitelist, "submission") if log.LEVEL >= log.Levels.INFO: whitelisting_factory.noisy = False service = StreamServerEndpointService(endpoint, whitelisting_factory) # Shut down, rather than simply logging an error, if we can't bind. service._raiseSynchronously = True return service
def test_unix_domain_socket(self): """Test that the whitelist is skipped for Unix domain sockets. """ factory = WhitelistingFactory(TestFactory(), []) # Should be blocking IP addresses self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), None ) # But Unix domain sockets are allowed self.assertIsInstance( factory.buildProtocol(UNIXAddress('/test/address')), Protocol ) # With a warning logged self.assertTrue("Bypassing" in self.observer.messages[1][0])
def create_service(self, consumer): conf = consumer.app.conf local_ivo = get_local_ivo(consumer.app) host, port = get_host_port(conf['voevent_broadcaster_address']) allow = [get_network(a) for a in conf['voevent_broadcaster_whitelist']] conf['voevent_broadcaster_factory'] = self._factory = factory = \ VOEventBroadcasterFactory(local_ivo, 0) if allow: factory = WhitelistingFactory(factory, allow, 'subscription') return TCPServer(port, factory, interface=host)
def test_getattr_delegation(self): """Check that missing attributes are delegated to the wrapped factory. """ factory = WhitelistingFactory(TestFactory(), []) # This attribute is defined on the wrapped factory. self.assertEqual(factory.test_attribute, TestFactory.test_attribute) with self.assertRaises(AttributeError): # This attribute does not exist. factory.bad_attribute
def create_service(self, consumer): from comet.protocol.broadcaster import VOEventBroadcasterFactory from comet.utility import WhitelistingFactory from twisted.application.internet import TCPServer conf = consumer.app.conf local_ivo = get_local_ivo(consumer.app) host, port = get_host_port(conf['voevent_broadcaster_address']) allow = [get_network(a) for a in conf['voevent_broadcaster_whitelist']] conf['voevent_broadcaster_factory'] = self._factory = factory = \ VOEventBroadcasterFactory(local_ivo, 0) if allow: factory = WhitelistingFactory(factory, allow, 'subscription') return TCPServer(port, factory, interface=host)
def makeService(config): event_db = Event_DB(config['eventdb']) LoopingCall(event_db.prune, MAX_AGE).start(PRUNE_INTERVAL) broker_service = MultiService() if config['broadcast']: broadcaster_factory = VOEventBroadcasterFactory( config["local-ivo"], config['broadcast-test-interval'] ) if log.LEVEL >= log.Levels.INFO: broadcaster_factory.noisy = False broadcaster_whitelisting_factory = WhitelistingFactory( broadcaster_factory, config['subscriber-whitelist'], "subscription" ) if log.LEVEL >= log.Levels.INFO: broadcaster_whitelisting_factory.noisy = False broadcaster_service = TCPServer( config['broadcast-port'], broadcaster_whitelisting_factory ) broadcaster_service.setName("Broadcaster") broadcaster_service.setServiceParent(broker_service) # If we're running a broadcast, we will rebroadcast any events we # receive to it. config['handlers'].append(EventRelay(broadcaster_factory)) if config['receive']: receiver_factory = VOEventReceiverFactory( local_ivo=config['local-ivo'], validators=[ CheckPreviouslySeen(event_db), CheckSchema( os.path.join(comet.__path__[0], "schema/VOEvent-v2.0.xsd") ), CheckIVOID() ], handlers=config['handlers'] ) if log.LEVEL >= log.Levels.INFO: receiver_factory.noisy = False author_whitelisting_factory = WhitelistingFactory( receiver_factory, config['author-whitelist'], "submission" ) if log.LEVEL >= log.Levels.INFO: author_whitelisting_factory.noisy = False receiver_service = TCPServer(config['receive-port'], author_whitelisting_factory) receiver_service.setName("Receiver") receiver_service.setServiceParent(broker_service) for host, port in config["remotes"]: subscriber_factory = VOEventSubscriberFactory( local_ivo=config["local-ivo"], validators=[CheckPreviouslySeen(event_db)], handlers=config['handlers'], filters=config['filters'] ) if log.LEVEL >= log.Levels.INFO: subscriber_factory.noisy = False remote_service = TCPClient(host, port, subscriber_factory) remote_service.setName("Remote %s:%d" % (host, port)) remote_service.setServiceParent(broker_service) if not broker_service.services: reactor.callWhenRunning(log.warn, "No services requested; stopping.") reactor.callWhenRunning(reactor.stop) return broker_service
def test_in_whitelist(self): factory = WhitelistingFactory(TestFactory(), [ip_network('0.0.0.0/0')]) self.assertIsInstance( factory.buildProtocol(IPv4Address('TCP', '127.0.0.1', 0)), Protocol )
def test_not_in_whitelist(self): factory = WhitelistingFactory(TestFactory(), [ip_network('127.0.0.1/32')]) self.assertEqual( factory.buildProtocol(IPv4Address('TCP', '127.0.0.2', 0)), None )