osquery-1/osquery/events/darwin/fsevents.h

117 lines
3.2 KiB
C
Raw Normal View History

// Copyright 2004-present Facebook. All Rights Reserved.
#pragma once
#include <map>
#include <string>
#include <vector>
#include <boost/make_shared.hpp>
#include <CoreServices/CoreServices.h>
#include <osquery/events.h>
#include <osquery/status.h>
namespace osquery {
extern std::map<FSEventStreamEventFlags, std::string> kMaskActions;
struct FSEventsSubscriptionContext : public SubscriptionContext {
/// Subscription the following filesystem path.
std::string path;
/// Limit the FSEvents actions to the subscriptioned mask (if not 0).
FSEventStreamEventFlags mask;
void requireAction(std::string action) {
for (const auto& bit : kMaskActions) {
if (action == bit.second) {
mask = mask & bit.first;
}
}
}
FSEventsSubscriptionContext() : mask(0) {}
};
struct FSEventsEventContext : public EventContext {
ConstFSEventStreamRef fsevent_stream;
FSEventStreamEventFlags fsevent_flags;
FSEventStreamEventId fsevent_id;
std::string path;
std::string action;
FSEventsEventContext() : fsevent_flags(0), fsevent_id(0) {}
};
typedef std::shared_ptr<FSEventsEventContext> FSEventsEventContextRef;
2014-10-07 23:01:30 +00:00
typedef std::shared_ptr<FSEventsSubscriptionContext>
2014-10-28 00:37:36 +00:00
FSEventsSubscriptionContextRef;
/**
* @brief An osquery EventPublisher for the Apple FSEvents notification API.
*
* This exposes a lightweight filesystem eventing type by wrapping Apple's
* preferred implementation of FSEvents handling.
*
*/
2014-12-15 06:17:38 +00:00
class FSEventsEventPublisher
: public EventPublisher<FSEventsSubscriptionContext, FSEventsEventContext> {
DECLARE_PUBLISHER("FSEventsEventPublisher");
public:
void configure();
void tearDown();
// Entrypoint to the run loop
Status run();
public:
/// FSEvents registers a client callback instead of using a select/poll loop.
static void Callback(ConstFSEventStreamRef fsevent_stream,
void* callback_info,
size_t num_events,
void* event_paths,
const FSEventStreamEventFlags fsevent_flags[],
const FSEventStreamEventId fsevent_ids[]);
public:
2014-10-07 23:01:30 +00:00
FSEventsEventPublisher()
: EventPublisher(), stream_(nullptr), run_loop_(nullptr) {}
bool shouldFire(const FSEventsSubscriptionContextRef mc,
const FSEventsEventContextRef ec);
private:
// Restart the run loop.
void restart();
// Stop the stream and the run loop.
void stop();
// Cause the FSEvents to flush kernel-buffered events.
void flush(bool async = false);
private:
// Check if the stream (and run loop) are running.
bool isStreamRunning();
// Count the number of subscriptioned paths.
size_t numSubscriptionedPaths();
private:
FSEventStreamRef stream_;
bool stream_started_;
std::set<std::string> paths_;
private:
CFRunLoopRef run_loop_;
private:
friend class FSEventsTests;
FRIEND_TEST(FSEventsTests, test_register_event_pub);
FRIEND_TEST(FSEventsTests, test_fsevents_add_subscription_missing_path);
FRIEND_TEST(FSEventsTests, test_fsevents_add_subscription_success);
FRIEND_TEST(FSEventsTests, test_fsevents_run);
FRIEND_TEST(FSEventsTests, test_fsevents_fire_event);
FRIEND_TEST(FSEventsTests, test_fsevents_event_action);
};
}