2014-09-19 08:54:33 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <boost/make_shared.hpp>
|
|
|
|
|
|
|
|
#include <sys/inotify.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include "osquery/status.h"
|
|
|
|
#include "osquery/events.h"
|
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
|
2014-09-25 17:17:32 +00:00
|
|
|
extern std::map<int, std::string> kMaskActions;
|
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
struct INotifyMonitorContext : public MonitorContext {
|
2014-09-23 03:33:58 +00:00
|
|
|
/// Monitor the following filesystem path.
|
2014-09-19 08:54:33 +00:00
|
|
|
std::string path;
|
2014-09-23 03:33:58 +00:00
|
|
|
/// Limit the actions to the monitored mask.
|
|
|
|
uint32_t mask;
|
|
|
|
/// Treat this path as a directory and monitor recursively.
|
|
|
|
bool recursive;
|
|
|
|
|
|
|
|
INotifyMonitorContext() : mask(0), recursive(false) {}
|
2014-09-25 17:17:32 +00:00
|
|
|
void requireAction(std::string action) {
|
|
|
|
for (const auto& bit : kMaskActions) {
|
|
|
|
if (action == bit.second) {
|
|
|
|
mask = mask | bit.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-19 08:54:33 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
struct INotifyEventContext : public EventContext {
|
2014-09-24 18:25:05 +00:00
|
|
|
std::shared_ptr<struct inotify_event> event;
|
2014-09-23 03:33:58 +00:00
|
|
|
std::string path;
|
|
|
|
std::string action;
|
2014-09-19 08:54:33 +00:00
|
|
|
};
|
|
|
|
|
2014-09-24 18:25:05 +00:00
|
|
|
typedef std::shared_ptr<INotifyEventContext> INotifyEventContextRef;
|
|
|
|
typedef std::shared_ptr<INotifyMonitorContext> INotifyMonitorContextRef;
|
2014-09-19 08:54:33 +00:00
|
|
|
|
|
|
|
// Thread-safe containers
|
|
|
|
typedef std::vector<int> DescriptorVector;
|
|
|
|
typedef std::map<std::string, int> PathDescriptorMap;
|
|
|
|
typedef std::map<int, std::string> DescriptorPathMap;
|
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
class INotifyEventType : public EventType {
|
2014-09-23 03:33:58 +00:00
|
|
|
DECLARE_EVENTTYPE(INotifyEventType,
|
2014-09-22 21:35:07 +00:00
|
|
|
INotifyMonitorContext,
|
|
|
|
INotifyEventContext);
|
|
|
|
|
|
|
|
public:
|
2014-09-19 08:54:33 +00:00
|
|
|
void setUp();
|
|
|
|
void configure();
|
|
|
|
void tearDown();
|
|
|
|
|
|
|
|
Status run();
|
|
|
|
Status addMonitor(const MonitorRef monitor);
|
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
INotifyEventType() : EventType() { inotify_handle_ = -1; }
|
2014-09-19 08:54:33 +00:00
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
bool isHandleOpen() { return inotify_handle_ > 0; }
|
2014-09-19 08:54:33 +00:00
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
private:
|
2014-09-19 08:54:33 +00:00
|
|
|
INotifyEventContextRef createEventContext(struct inotify_event* event);
|
|
|
|
|
2014-09-22 21:35:07 +00:00
|
|
|
private:
|
2014-09-19 08:54:33 +00:00
|
|
|
bool isMonitored(const std::string& path);
|
2014-09-23 03:33:58 +00:00
|
|
|
bool shouldFire(const INotifyMonitorContextRef mc,
|
|
|
|
const INotifyEventContextRef ec);
|
2014-09-22 21:35:07 +00:00
|
|
|
int getHandle() { return inotify_handle_; }
|
2014-09-19 08:54:33 +00:00
|
|
|
|
|
|
|
void processDirEvent(struct inotify_event* event);
|
|
|
|
void processNodeEvent(struct inotify_event* event);
|
|
|
|
void processEvent(struct inotify_event* event);
|
|
|
|
|
|
|
|
// Consider an event queue if separating buffering from firing/servicing.
|
|
|
|
DescriptorVector descriptors_;
|
|
|
|
PathDescriptorMap path_descriptors_;
|
|
|
|
DescriptorPathMap descriptor_paths_;
|
|
|
|
int inotify_handle_;
|
|
|
|
};
|
|
|
|
}
|