osquery-1/osquery/events/events_tests.cpp

382 lines
12 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
2015-03-03 00:48:01 +00:00
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
2014-12-14 11:43:31 +00:00
#include <typeinfo>
2014-12-15 05:20:20 +00:00
#include <boost/filesystem/operations.hpp>
2014-09-30 02:06:33 +00:00
#include <gtest/gtest.h>
2015-04-01 08:10:28 +00:00
#include <osquery/database.h>
#include <osquery/events.h>
#include <osquery/tables.h>
namespace osquery {
2014-12-15 05:20:20 +00:00
const std::string kTestingEventsDBPath = "/tmp/rocksdb-osquery-testevents";
2014-12-14 11:43:31 +00:00
class EventsTests : public ::testing::Test {
2014-09-30 02:06:33 +00:00
public:
2014-12-15 05:20:20 +00:00
void SetUp() {
// Setup a testing DB instance
DBHandle::getInstanceAtPath(kTestingEventsDBPath);
}
void TearDown() { EventFactory::end(); }
};
2014-12-14 11:43:31 +00:00
// The most basic event publisher uses useless Subscription/Event.
class BasicEventPublisher
: public EventPublisher<SubscriptionContext, EventContext> {};
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
2014-12-14 11:43:31 +00:00
class AnotherBasicEventPublisher
: public EventPublisher<SubscriptionContext, EventContext> {};
2014-12-15 05:20:20 +00:00
// Create some semi-useless subscription and event structures.
struct FakeSubscriptionContext : SubscriptionContext {
int require_this_value;
};
struct FakeEventContext : EventContext {
int required_value;
};
2014-12-14 11:43:31 +00:00
// Typdef the shared_ptr accessors.
typedef std::shared_ptr<FakeSubscriptionContext> FakeSubscriptionContextRef;
typedef std::shared_ptr<FakeEventContext> FakeEventContextRef;
// Now a publisher with a type.
class FakeEventPublisher
: public EventPublisher<FakeSubscriptionContext, FakeEventContext> {
2014-12-15 02:03:41 +00:00
DECLARE_PUBLISHER("FakePublisher");
};
2014-12-14 11:43:31 +00:00
class AnotherFakeEventPublisher
: public EventPublisher<FakeSubscriptionContext, FakeEventContext> {
2014-12-15 02:03:41 +00:00
DECLARE_PUBLISHER("AnotherFakePublisher");
};
2014-12-14 11:43:31 +00:00
TEST_F(EventsTests, test_event_pub) {
auto pub = std::make_shared<FakeEventPublisher>();
2014-12-15 02:03:41 +00:00
EXPECT_EQ(pub->type(), "FakePublisher");
2014-12-14 11:43:31 +00:00
// Test type names.
auto pub_sub = pub->createSubscriptionContext();
EXPECT_EQ(typeid(FakeSubscriptionContext), typeid(*pub_sub));
}
TEST_F(EventsTests, test_register_event_pub) {
2015-01-30 18:44:25 +00:00
auto basic_pub = std::make_shared<BasicEventPublisher>();
auto status = EventFactory::registerEventPublisher(basic_pub);
2014-12-14 11:43:31 +00:00
// This class is the SAME, there was no type override.
2015-01-30 18:44:25 +00:00
auto another_basic_pub = std::make_shared<AnotherBasicEventPublisher>();
status = EventFactory::registerEventPublisher(another_basic_pub);
2014-12-14 11:43:31 +00:00
EXPECT_FALSE(status.ok());
// This class is different but also uses different types!
2015-01-30 18:44:25 +00:00
auto fake_pub = std::make_shared<FakeEventPublisher>();
status = EventFactory::registerEventPublisher(fake_pub);
EXPECT_TRUE(status.ok());
2014-12-14 11:43:31 +00:00
// May also register the event_pub instance
2015-01-30 18:44:25 +00:00
auto another_fake_pub = std::make_shared<AnotherFakeEventPublisher>();
status = EventFactory::registerEventPublisher(another_fake_pub);
2014-12-14 11:43:31 +00:00
EXPECT_TRUE(status.ok());
}
2014-12-15 02:03:41 +00:00
TEST_F(EventsTests, test_event_pub_types) {
auto pub = std::make_shared<FakeEventPublisher>();
EXPECT_EQ(pub->type(), "FakePublisher");
EventFactory::registerEventPublisher(pub);
auto pub2 = EventFactory::getEventPublisher("FakePublisher");
EXPECT_EQ(pub->type(), pub2->type());
}
TEST_F(EventsTests, test_create_event_pub) {
2015-01-30 18:44:25 +00:00
auto pub = std::make_shared<BasicEventPublisher>();
auto status = EventFactory::registerEventPublisher(pub);
EXPECT_TRUE(status.ok());
// Make sure only the first event type was recorded.
EXPECT_EQ(EventFactory::numEventPublishers(), 1);
}
2015-01-30 18:44:25 +00:00
class UniqueEventPublisher
: public EventPublisher<FakeSubscriptionContext, FakeEventContext> {
DECLARE_PUBLISHER("unique");
};
TEST_F(EventsTests, test_create_using_registry) {
// The events API uses attachEvents to move registry event publishers and
// subscribers into the events factory.
EXPECT_EQ(EventFactory::numEventPublishers(), 0);
attachEvents();
// Store the number of default event publishers (in core).
int default_publisher_count = EventFactory::numEventPublishers();
// Now add another registry item, but do not yet attach it.
auto UniqueEventPublisherRegistryItem =
Registry::add<UniqueEventPublisher>("event_publisher", "unique");
2015-01-30 18:44:25 +00:00
EXPECT_EQ(EventFactory::numEventPublishers(), default_publisher_count);
// Now attach and make sure it was added.
attachEvents();
EXPECT_EQ(EventFactory::numEventPublishers(), default_publisher_count + 1);
}
TEST_F(EventsTests, test_create_subscription) {
2015-01-30 18:44:25 +00:00
auto pub = std::make_shared<BasicEventPublisher>();
EventFactory::registerEventPublisher(pub);
// Make sure a subscription cannot be added for a non-existent event type.
// Note: It normally would not make sense to create a blank subscription.
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
auto subscription = Subscription::create("FakeSubscriber");
2014-12-15 02:03:41 +00:00
auto status = EventFactory::addSubscription("FakePublisher", subscription);
EXPECT_FALSE(status.ok());
2014-10-04 00:50:25 +00:00
// In this case we can still add a blank subscription to an existing event
// type.
2014-12-14 11:43:31 +00:00
status = EventFactory::addSubscription("publisher", subscription);
EXPECT_TRUE(status.ok());
// Make sure the subscription is added.
2014-12-14 11:43:31 +00:00
EXPECT_EQ(EventFactory::numSubscriptions("publisher"), 1);
}
TEST_F(EventsTests, test_multiple_subscriptions) {
Status status;
2015-01-30 18:44:25 +00:00
auto pub = std::make_shared<BasicEventPublisher>();
EventFactory::registerEventPublisher(pub);
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
auto subscription = Subscription::create("subscriber");
2014-12-14 11:43:31 +00:00
status = EventFactory::addSubscription("publisher", subscription);
status = EventFactory::addSubscription("publisher", subscription);
2014-12-14 11:43:31 +00:00
EXPECT_EQ(EventFactory::numSubscriptions("publisher"), 2);
}
struct TestSubscriptionContext : public SubscriptionContext {
int smallest;
};
2014-12-14 11:43:31 +00:00
class TestEventPublisher
: public EventPublisher<TestSubscriptionContext, EventContext> {
2014-12-15 02:03:41 +00:00
DECLARE_PUBLISHER("TestPublisher");
2014-12-15 05:20:20 +00:00
public:
2014-12-08 10:22:59 +00:00
Status setUp() {
smallest_ever_ += 1;
return Status(0, "OK");
}
void configure() {
int smallest_subscription = smallest_ever_;
configure_run = true;
for (const auto& subscription : subscriptions_) {
auto subscription_context = getSubscriptionContext(subscription->context);
if (smallest_subscription > subscription_context->smallest) {
smallest_subscription = subscription_context->smallest;
}
}
smallest_ever_ = smallest_subscription;
}
void tearDown() { smallest_ever_ += 1; }
TestEventPublisher() : EventPublisher() {
smallest_ever_ = 0;
configure_run = false;
}
// Custom methods do not make sense, but for testing it exists.
int getTestValue() { return smallest_ever_; }
public:
bool configure_run;
private:
int smallest_ever_;
};
TEST_F(EventsTests, test_create_custom_event_pub) {
2015-01-30 18:44:25 +00:00
auto basic_pub = std::make_shared<BasicEventPublisher>();
EventFactory::registerEventPublisher(basic_pub);
2014-12-14 11:43:31 +00:00
auto pub = std::make_shared<TestEventPublisher>();
2015-01-30 18:44:25 +00:00
auto status = EventFactory::registerEventPublisher(pub);
// These event types have unique event type IDs
EXPECT_TRUE(status.ok());
EXPECT_EQ(EventFactory::numEventPublishers(), 2);
// Make sure the setUp function was called.
2014-12-14 11:43:31 +00:00
EXPECT_EQ(pub->getTestValue(), 1);
}
TEST_F(EventsTests, test_custom_subscription) {
// Step 1, register event type
2014-12-14 11:43:31 +00:00
auto pub = std::make_shared<TestEventPublisher>();
auto status = EventFactory::registerEventPublisher(pub);
// Step 2, create and configure a subscription context
2014-12-14 11:43:31 +00:00
auto sc = std::make_shared<TestSubscriptionContext>();
sc->smallest = -1;
// Step 3, add the subscription to the event type
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
status = EventFactory::addSubscription("TestPublisher", "TestSubscriber", sc);
EXPECT_TRUE(status.ok());
2014-12-14 11:43:31 +00:00
EXPECT_EQ(pub->numSubscriptions(), 1);
// The event type must run configure for each added subscription.
2014-12-14 11:43:31 +00:00
EXPECT_TRUE(pub->configure_run);
EXPECT_EQ(pub->getTestValue(), -1);
}
TEST_F(EventsTests, test_tear_down) {
2014-12-14 11:43:31 +00:00
auto pub = std::make_shared<TestEventPublisher>();
auto status = EventFactory::registerEventPublisher(pub);
// Make sure set up incremented the test value.
2014-12-14 11:43:31 +00:00
EXPECT_EQ(pub->getTestValue(), 1);
2014-12-15 02:03:41 +00:00
status = EventFactory::deregisterEventPublisher("TestPublisher");
EXPECT_TRUE(status.ok());
// Make sure tear down inremented the test value.
2014-12-14 11:43:31 +00:00
EXPECT_EQ(pub->getTestValue(), 2);
// Once more, now deregistering all event types.
2014-12-14 11:43:31 +00:00
status = EventFactory::registerEventPublisher(pub);
EXPECT_EQ(pub->getTestValue(), 3);
EventFactory::end();
2014-12-14 11:43:31 +00:00
EXPECT_EQ(pub->getTestValue(), 4);
// Make sure the factory state represented.
EXPECT_EQ(EventFactory::numEventPublishers(), 0);
}
static int kBellHathTolled = 0;
Status TestTheeCallback(EventContextRef context, const void* user_data) {
kBellHathTolled += 1;
return Status(0, "OK");
}
2014-12-15 05:20:20 +00:00
class FakeEventSubscriber : public EventSubscriber<FakeEventPublisher> {
public:
bool bellHathTolled;
bool contextBellHathTolled;
bool shouldFireBethHathTolled;
FakeEventSubscriber() {
2015-04-01 04:18:56 +00:00
setName("FakeSubscriber");
2014-12-15 05:20:20 +00:00
bellHathTolled = false;
contextBellHathTolled = false;
shouldFireBethHathTolled = false;
}
Status Callback(const EventContextRef& ec, const void* user_data) {
2014-12-15 05:20:20 +00:00
// We don't care about the subscription or the event contexts.
bellHathTolled = true;
return Status(0, "OK");
}
Status SpecialCallback(const FakeEventContextRef& ec, const void* user_data) {
2014-12-15 05:20:20 +00:00
// Now we care that the event context is corrected passed.
if (ec->required_value == 42) {
contextBellHathTolled = true;
}
return Status(0, "OK");
}
void lateInit() {
auto sub_ctx = createSubscriptionContext();
subscribe(&FakeEventSubscriber::Callback, sub_ctx, nullptr);
2014-12-15 05:20:20 +00:00
}
void laterInit() {
auto sub_ctx = createSubscriptionContext();
sub_ctx->require_this_value = 42;
subscribe(&FakeEventSubscriber::SpecialCallback, sub_ctx, nullptr);
2014-12-15 05:20:20 +00:00
}
};
TEST_F(EventsTests, test_event_sub) {
auto sub = std::make_shared<FakeEventSubscriber>();
EXPECT_EQ(sub->type(), "FakePublisher");
2015-04-01 04:18:56 +00:00
EXPECT_EQ(sub->getName(), "FakeSubscriber");
2014-12-15 05:20:20 +00:00
}
TEST_F(EventsTests, test_event_sub_subscribe) {
auto pub = std::make_shared<FakeEventPublisher>();
EventFactory::registerEventPublisher(pub);
auto sub = std::make_shared<FakeEventSubscriber>();
EventFactory::registerEventSubscriber(sub);
// Don't overload the normal `init` Subscription member.
sub->lateInit();
EXPECT_EQ(pub->numSubscriptions(), 1);
auto ec = pub->createEventContext();
pub->fire(ec, 0);
EXPECT_TRUE(sub->bellHathTolled);
}
TEST_F(EventsTests, test_event_sub_context) {
auto pub = std::make_shared<FakeEventPublisher>();
EventFactory::registerEventPublisher(pub);
auto sub = std::make_shared<FakeEventSubscriber>();
EventFactory::registerEventSubscriber(sub);
sub->laterInit();
auto ec = pub->createEventContext();
ec->required_value = 42;
pub->fire(ec, 0);
EXPECT_TRUE(sub->contextBellHathTolled);
}
TEST_F(EventsTests, test_fire_event) {
Status status;
2014-12-14 11:43:31 +00:00
auto pub = std::make_shared<BasicEventPublisher>();
status = EventFactory::registerEventPublisher(pub);
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
auto sub = std::make_shared<FakeEventSubscriber>();
auto subscription = Subscription::create("FakeSubscriber");
subscription->callback = TestTheeCallback;
2014-12-14 11:43:31 +00:00
status = EventFactory::addSubscription("publisher", subscription);
2014-09-19 08:54:33 +00:00
// The event context creation would normally happen in the event type.
2014-12-14 11:43:31 +00:00
auto ec = pub->createEventContext();
pub->fire(ec, 0);
EXPECT_EQ(kBellHathTolled, 1);
Implement YARA table. Currently only for OS X, will port to others soon. Also need to add tests. Remove old comment and add loading message. Implement YARA table for Linux. Use mask properly. Use the various masks to specify the kinds of events we are interested in. This removes the need to do the dirty "DELETED" check when the event fires. Make getYARAFiles return a const map. Switch to LOG(WARNING) and emit error number. Add vim .swp files to .gitignore. Add yara_utils.(c|h). Start to condense common code between the Linux and Darwin YARA tables into a yara_utils.h. Right now it includes a function to compile rules and store the results back in the map, indexed by category. It also has the callback used by YARA when a rule is processed. I can not move much more than that for the row creation code because the structures used in the event callback are slightly different. Include a better error message. The errors are still printed by the compiler callback, but this will allow my future work to return a Status from the event initialization to print a useful message in summary. Make Subscriber init() return Status. Each EventSubscriber::init() now returns a Status. If the init() fails for any reason the EventSubscriber is still stored but the failure is tracked. EventSubscribers now have a state member, which represents the current state of the subscriber. The current supported states are: uninitialized, running, paused, failed. Currently the only meaningful ones are running and failed, but I put paused in there as a forward-looking feature. Subscriptions now have a subscriber_name member. This is used in EventPublisherPlugin::fire() as a lookup to get the EventSubscriber and check the state. If the EventSubscriber is not running the event will not fire. Only the EventSubscribers on OS X are using this. I'll do the Linux implementation next. Chase the init() changes to Linux. This brings the Linux YARA table in line with the OS X one. Require a EventSubscriberID when creating a subscription. Now that Subscriptions are "tied" to EventSubscribers you must create a Subscription with the name of the Subscriber it is for. This is because when the event fires the list of Subscriptions is walked and the name is used to lookup the EventSubscriber and make sure it is in the running state. Fix various tests. Some tests would fire an event with only a Subscription, which is no longer a valid thing to do. For these tests an EventSubscription is created and registered in the EventFactory. When Subscriptions are created pass the name of the EventSubscriber to them. In some cases where no event is ever fired it is fine to pass a bogus name. Fix inotify tests. Move a test down so the class is defined and make sure to create an EventSubscriber and use it properly. Add support for yara to provision.sh. Right now this grabs yara 3.3.0 and applies the patch to fix min() and max(), which is commit fc4696c8b725be1ac099d340359c8d550d116041 in the yara repo. This has been tested under Ubuntu 14.04 only. Remove NOMINMAX. This is no longer necessary after the patch was backported to 3.3.0. Revert "Add support for yara to provision.sh." This reverts commit a8bd371498c0979f070adeff23d05571882ac3f1. Use vendored YARA code in third-party. This switches to using the YARA code contained in third-party, including the patch to fix min/max macros. Fix mismerge. Remove unused function after merge. Well, soon to be unused as soon as I fix up the Linux YARA table. ;) Chase config changes. Make the Linux YARA table use ConfigDataInstance along with files() and yaraFiles().
2015-03-10 13:22:16 +00:00
auto second_subscription = Subscription::create("FakeSubscriber");
2014-12-14 11:43:31 +00:00
status = EventFactory::addSubscription("publisher", second_subscription);
// Now there are two subscriptions (one sans callback).
2014-12-14 11:43:31 +00:00
pub->fire(ec, 0);
EXPECT_EQ(kBellHathTolled, 2);
// Now both subscriptions have callbacks.
second_subscription->callback = TestTheeCallback;
2014-12-14 11:43:31 +00:00
pub->fire(ec, 0);
EXPECT_EQ(kBellHathTolled, 4);
}
}