def test_valid_unsubscription(self): topic = "some/topic" expected = Unsubscription(topic) # without namespace event = broker.zeek.Event("unsubscribe", topic) unsubscription = map_management_message(event, self.module_namespace) self.assertEqual(unsubscription, expected) # with namespace: event = broker.zeek.Event(self.module_namespace + "::unsubscribe", topic) unsubscription = map_management_message(event, self.module_namespace) self.assertEqual(unsubscription, expected)
def test_valid_subscription(self): td = timedelta(days=5) topic = "some/topic" expected = Subscription(topic, td) # without namespace event = broker.zeek.Event("subscribe", topic, td) subscription = map_management_message(event, self.module_namespace) self.assertEqual(subscription, expected) # with namespace: event = broker.zeek.Event(self.module_namespace + "::subscribe", topic, td) subscription = map_management_message(event, self.module_namespace) self.assertEqual(subscription, expected)
def test_invalid_zeek_inputs(self): broker_data = broker.zeek.Event("Hello") # unknown event self.assertIsNone(map_to_internal(broker_data, None)) self.assertIsNone(map_to_internal(broker_data, self.module_namespace)) self.assertIsNone(map_management_message(broker_data, None)) self.assertIsNone( map_management_message(broker_data, self.module_namespace)) # not enough arguments provided broker_data = broker.zeek.Event("sighting", 1, 2) self.assertIsNone(map_to_internal(broker_data, None)) self.assertIsNone(map_to_internal(broker_data, self.module_namespace)) self.assertIsNone(map_management_message(broker_data, None)) self.assertIsNone( map_management_message(broker_data, self.module_namespace)) broker_data = broker.zeek.Event("intel", 42, {}) self.assertIsNone(map_to_internal(broker_data, None)) self.assertIsNone(map_to_internal(broker_data, self.module_namespace)) self.assertIsNone(map_management_message(broker_data, None)) self.assertIsNone( map_management_message(broker_data, self.module_namespace)) broker_data = broker.zeek.Event("subscribe", "topic") self.assertIsNone(map_to_internal(broker_data, None)) self.assertIsNone(map_to_internal(broker_data, self.module_namespace)) self.assertIsNone(map_management_message(broker_data, None)) self.assertIsNone( map_management_message(broker_data, self.module_namespace)) broker_data = broker.zeek.Event("unsubscribe") self.assertIsNone(map_to_internal(broker_data, None)) self.assertIsNone(map_to_internal(broker_data, self.module_namespace)) self.assertIsNone(map_management_message(broker_data, None)) self.assertIsNone( map_management_message(broker_data, self.module_namespace))
def run(self): """ Binds a broker subscriber to the given endpoint. Only listens for management messages, such as un/subscriptions of new clients. """ global logger sub = self.ep.make_subscriber("threatbus/manage") while self._running(): (ready_readers, [], []) = select.select([sub.fd()], [], [], 1) if not ready_readers: continue (topic, broker_data) = sub.get() msg = map_management_message(broker_data, self.module_namespace, logger) if msg: self.manage_subscription(msg)
def manage(logger, module_namespace, ep, subscribe_callback, unsubscribe_callback): """Binds a broker subscriber to the given endpoint. Only listens for management messages, such as un/subscriptions of new clients. @param logger A logging.logger object @param module_namespace A Zeek namespace to accept events from @param ep The broker endpoint used for listening @param subscribe_callback The callback to invoke for new subscriptions @param unsubscribe_callback The callback to invoke for revoked subscriptions """ sub = ep.make_subscriber("threatbus/manage") while True: ready = select.select([sub.fd()], [], []) if not ready[0]: logger.critical("Broker management subscriber filedescriptor error.") (topic, broker_data) = sub.get() msg = map_management_message(broker_data, module_namespace) if msg: logger.debug( f"Received management request: {type(msg).__name__} -- {msg.topic}" ) manage_subscription( ep, module_namespace, msg, subscribe_callback, unsubscribe_callback )