osquery: Remove events
authorSangwan Kwon <sangwan.kwon@samsung.com>
Tue, 14 Jan 2020 05:08:10 +0000 (14:08 +0900)
committerSangwan Kwon <sangwan.kwon@samsung.com>
Tue, 14 Jan 2020 05:08:10 +0000 (14:08 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
36 files changed:
src/osquery/CMakeLists.txt
src/osquery/core/init.cpp
src/osquery/devtools/devtools.h
src/osquery/events/CMakeLists.txt [deleted file]
src/osquery/events/events.cpp [deleted file]
src/osquery/events/linux/auditdnetlink.cpp [deleted file]
src/osquery/events/linux/auditdnetlink.h [deleted file]
src/osquery/events/linux/auditeventpublisher.cpp [deleted file]
src/osquery/events/linux/auditeventpublisher.h [deleted file]
src/osquery/events/linux/inotify.cpp [deleted file]
src/osquery/events/linux/inotify.h [deleted file]
src/osquery/events/linux/process_events.h [deleted file]
src/osquery/events/linux/process_file_events.h [deleted file]
src/osquery/events/linux/selinux_events.h [deleted file]
src/osquery/events/linux/socket_events.h [deleted file]
src/osquery/events/linux/syslog.cpp [deleted file]
src/osquery/events/linux/syslog.h [deleted file]
src/osquery/events/linux/udev.cpp [deleted file]
src/osquery/events/linux/udev.h [deleted file]
src/osquery/events/pathset.h [deleted file]
src/osquery/events/tests/events_database_tests.cpp [deleted file]
src/osquery/events/tests/events_tests.cpp [deleted file]
src/osquery/events/tests/linux/audit_tests.cpp [deleted file]
src/osquery/events/tests/linux/inotify_tests.cpp [deleted file]
src/osquery/events/tests/linux/process_file_events_tests.cpp [deleted file]
src/osquery/events/tests/linux/syslog_tests.cpp [deleted file]
src/osquery/include/osquery/events.h [deleted file]
src/osquery/logger/logger.cpp
src/osquery/logger/tests/logger.cpp
src/osquery/main/main.cpp
src/osquery/sql/virtual_table.cpp
src/osquery/tests/test_util.cpp
src/osquery/tests/test_util.h
tools/codegen/templates/amalgamation.cpp.in
tools/codegen/templates/default.cpp.in
tools/codegen/templates/foreign.cpp.in

index 47aef40b930865b710a4d5c5e501da7a6f077caa..cb80e4e680e72e56ba029869e777b856e0e1e791 100644 (file)
@@ -45,7 +45,6 @@ ENDIF(DEFINED GBS_BUILD)
 ## osquery v4.0.0
 ADD_SUBDIRECTORY(core)
 ADD_SUBDIRECTORY(database)
-ADD_SUBDIRECTORY(events)
 ADD_SUBDIRECTORY(filesystem)
 ADD_SUBDIRECTORY(logger)
 ADD_SUBDIRECTORY(plugins)
index 4237b315c0e2c21202ef19714db99392103ea3b6..340a547b1a288dba0b811eaa9d59a97c4eaadf78 100644 (file)
@@ -37,7 +37,6 @@
 #include "osquery/utils/info/platform_type.h"
 #include <osquery/core.h>
 #include <osquery/data_logger.h>
-#include <osquery/events.h>
 #include <osquery/filesystem/filesystem.h>
 #include <osquery/flags.h>
 #include <osquery/registry.h>
@@ -155,7 +154,6 @@ DECLARE_bool(config_dump);
 DECLARE_bool(database_dump);
 DECLARE_string(database_path);
 DECLARE_bool(disable_database);
-DECLARE_bool(disable_events);
 DECLARE_bool(disable_logging);
 
 CLI_FLAG(bool, S, false, "Run as a shell process");
@@ -298,7 +296,6 @@ Initializer::Initializer(int& argc,
     // The shell is transient, rewrite config-loaded paths.
     FLAGS_disable_logging = true;
     // The shell never will not fork a worker.
-    FLAGS_disable_events = true;
   }
 
   if (default_flags && isReadable(kBackupDefaultFlagfile)) {
@@ -471,10 +468,6 @@ void Initializer::start() const {
     initActivePlugin("logger", FLAGS_logger_plugin);
     initLogger(binary_);
   }
-
-  // Start event threads.
-  osquery::attachEvents();
-  EventFactory::delay();
 }
 
 void Initializer::waitForShutdown() {
@@ -490,9 +483,6 @@ void Initializer::waitForShutdown() {
     }
   }
 
-  // End any event type run loops.
-  EventFactory::end(true);
-
   // Hopefully release memory used by global string constructors in gflags.
   GFLAGS_NAMESPACE::ShutDownCommandLineFlags();
   DatabasePlugin::shutdown();
index c97f8d7186d158812033417feb9621c0641c1520..4c01c40285be2adc8e84aa6db771d563be4362c8 100644 (file)
@@ -26,9 +26,6 @@ DECLARE_string(A);
 /// The shell may request execution of all queries in a pack immediately.
 DECLARE_string(pack);
 
-/// The shell may need to disable events for fast operations.
-DECLARE_bool(disable_events);
-
 /**
  * @brief Run an interactive SQL query shell.
  *
diff --git a/src/osquery/events/CMakeLists.txt b/src/osquery/events/CMakeLists.txt
deleted file mode 100644 (file)
index 673be8d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License
-
-ADD_OSQUERY_LIBRARY(osquery_event events.cpp)
-
-FILE(GLOB OSQUERY_EVENT_TESTS "tests/*.cpp")
-ADD_OSQUERY_TEST(${OSQUERY_EVENT_TESTS})
diff --git a/src/osquery/events/events.cpp b/src/osquery/events/events.cpp
deleted file mode 100644 (file)
index 149521e..0000000
+++ /dev/null
@@ -1,971 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <chrono>
-#include <exception>
-#include <thread>
-
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/lexical_cast.hpp>
-
-#include <osquery/database.h>
-#include <osquery/events.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/sql.h>
-#include <osquery/sql/dynamic_table_row.h>
-#include <osquery/system.h>
-#include <osquery/utils/conversions/split.h>
-#include <osquery/utils/conversions/tryto.h>
-#include <osquery/utils/system/time.h>
-
-namespace osquery {
-
-CREATE_REGISTRY(EventPublisherPlugin, "event_publisher");
-CREATE_REGISTRY(EventSubscriberPlugin, "event_subscriber");
-
-/// Checkpoint interval to inspect max event buffering.
-#define EVENTS_CHECKPOINT 256
-
-FLAG(bool, disable_events, false, "Disable osquery publish/subscribe system");
-
-FLAG(bool,
-     events_optimize,
-     true,
-     "Optimize subscriber select queries (scheduler only)");
-
-// Access this flag through EventSubscriberPlugin::getEventsExpiry to allow for
-// overriding in subclasses
-FLAG(uint64, events_expiry, 3600, "Timeout to expire event subscriber results");
-
-// Access this flag through EventSubscriberPlugin::getEventsMax to allow for
-// overriding in subclasses
-FLAG(uint64, events_max, 50000, "Maximum number of events per type to buffer");
-
-static inline EventTime timeFromRecord(const std::string& record) {
-  // Convert a stored index "as string bytes" to a time value.
-  return static_cast<EventTime>(tryTo<long long>(record).takeOr(0ll));
-}
-
-static inline std::string toIndex(size_t i) {
-  auto str_index = std::to_string(i);
-  if (str_index.size() < 10) {
-    str_index.insert(str_index.begin(), 10 - str_index.size(), '0');
-  }
-  return str_index;
-}
-
-static inline void getOptimizeData(EventTime& o_time,
-                                   size_t& o_eid,
-                                   std::string& query_name,
-                                   const std::string& publisher) {
-  // Read the optimization time for the current executing query.
-  getDatabaseValue(kPersistentSettings, "", query_name);
-  if (query_name.empty()) {
-    o_time = 0;
-    o_eid = 0;
-    return;
-  }
-
-  {
-    std::string content;
-    getDatabaseValue(kEvents, "optimize." + query_name, content);
-    o_time = timeFromRecord(content);
-  }
-
-  {
-    std::string content;
-    getDatabaseValue(kEvents, "optimize_eid." + query_name, content);
-    o_eid = tryTo<std::size_t>(content).takeOr(std::size_t{0});
-  }
-}
-
-static inline void setOptimizeData(EventTime time,
-                                   size_t eid,
-                                   const std::string& publisher) {
-  // Store the optimization time and eid.
-  std::string query_name;
-  getDatabaseValue(kPersistentSettings, "", query_name);
-  if (query_name.empty()) {
-    return;
-  }
-
-  setDatabaseValue(kEvents, "optimize." + query_name, std::to_string(time));
-  setDatabaseValue(kEvents, "optimize_eid." + query_name, toIndex(eid));
-}
-
-EventContextID EventPublisherPlugin::numEvents() const {
-  return next_ec_id_.load();
-}
-
-size_t EventPublisherPlugin::numSubscriptions() {
-  ReadLock lock(subscription_lock_);
-  return subscriptions_.size();
-}
-
-void EventPublisherPlugin::fire(const EventContextRef& ec, EventTime time) {
-  if (isEnding()) {
-    // Cannot emit/fire while ending
-    return;
-  }
-
-  EventContextID ec_id = 0;
-  ec_id = next_ec_id_.fetch_add(1);
-
-  // Fill in EventContext ID and time if needed.
-  if (ec != nullptr) {
-    ec->id = ec_id;
-    if (ec->time == 0) {
-      if (time == 0) {
-        time = getUnixTime();
-      }
-      ec->time = time;
-    }
-  }
-
-  ReadLock lock(subscription_lock_);
-  for (const auto& subscription : subscriptions_) {
-    auto es = EventFactory::getEventSubscriber(subscription->subscriber_name);
-    if (es != nullptr && es->state() == EventState::EVENT_RUNNING) {
-      fireCallback(subscription, ec);
-    }
-  }
-}
-
-std::vector<std::string> EventSubscriberPlugin::getIndexes(EventTime start,
-                                                           EventTime stop,
-                                                           bool sort) {
-  auto index_key = "indexes." + dbNamespace();
-  std::vector<std::string> indexes;
-
-  EventTime l_start = (start > 0) ? start / 60 : 0;
-  EventTime r_stop = (stop > 0) ? stop / 60 + 1 : 0;
-
-  std::string content;
-  getDatabaseValue(kEvents, index_key + ".60", content);
-  if (content.empty()) {
-    return indexes;
-  }
-
-  std::vector<std::string> bins, expirations;
-  boost::split(bins, content, boost::is_any_of(","));
-  for (const auto& bin : bins) {
-    auto step = timeFromRecord(bin);
-    auto step_start = step * 60;
-    auto step_stop = (step + 1) * 60;
-    if (step_stop <= expire_time_) {
-      expirations.push_back(bin);
-    } else if (step_start < expire_time_ && sort) {
-      expireRecords("60", bin, false);
-    }
-
-    if (step >= l_start && (r_stop == 0 || step < r_stop) && sort) {
-      indexes.push_back("60." + bin);
-    }
-  }
-
-  // Rewrite the index lists and delete each expired item.
-  if (!expirations.empty()) {
-    expireIndexes("60", bins, expirations);
-  }
-
-  // Return indexes in binning order.
-  if (sort) {
-    std::sort(indexes.begin(),
-              indexes.end(),
-              [](const std::string& left, const std::string& right) {
-                auto n1 = timeFromRecord(left.substr(left.find('.') + 1));
-                auto n2 = timeFromRecord(right.substr(right.find('.') + 1));
-                return n1 < n2;
-              });
-  }
-
-  // Update the new time that events expire to now - expiry.
-  return indexes;
-}
-
-void EventSubscriberPlugin::expireRecords(const std::string& list_type,
-                                          const std::string& index,
-                                          bool all) {
-  if (!executedAllQueries()) {
-    return;
-  }
-
-  auto record_key = "records." + dbNamespace();
-  auto data_key = "data." + dbNamespace();
-
-  // If the expirations is not removing all records, rewrite the persisting.
-  std::vector<std::string> persisting_records;
-  // Request all records within this list-size + bin offset.
-  auto expired_records = getRecords({list_type + '.' + index}, false);
-  if (all && expired_records.size() > 1) {
-    deleteDatabaseRange(kEvents,
-                        data_key + '.' + expired_records.begin()->first,
-                        data_key + '.' + expired_records.rbegin()->first);
-  } else {
-    for (const auto& record : expired_records) {
-      if (record.second <= expire_time_) {
-        deleteDatabaseValue(kEvents, data_key + '.' + record.first);
-      } else {
-        persisting_records.push_back(record.first + ':' +
-                                     std::to_string(record.second));
-      }
-    }
-  }
-
-  // Either drop or overwrite the record list.
-  if (all) {
-    deleteDatabaseValue(kEvents, record_key + "." + list_type + "." + index);
-  } else if (persisting_records.size() < expired_records.size()) {
-    auto new_records = boost::algorithm::join(persisting_records, ",");
-    setDatabaseValue(
-        kEvents, record_key + "." + list_type + "." + index, new_records);
-  }
-}
-
-void EventSubscriberPlugin::expireIndexes(
-    const std::string& list_type,
-    const std::vector<std::string>& indexes,
-    const std::vector<std::string>& expirations) {
-  if (!executedAllQueries()) {
-    return;
-  }
-
-  auto index_key = "indexes." + dbNamespace();
-
-  // Construct a mutable list of persisting indexes to rewrite as records.
-  std::vector<std::string> persisting_indexes = indexes;
-  // Remove the records using the list of expired indexes.
-  for (const auto& bin : expirations) {
-    expireRecords(list_type, bin, true);
-    persisting_indexes.erase(
-        std::remove(persisting_indexes.begin(), persisting_indexes.end(), bin),
-        persisting_indexes.end());
-  }
-
-  // Update the list of indexes with the non-expired indexes.
-  auto new_indexes = boost::algorithm::join(persisting_indexes, ",");
-  setDatabaseValue(kEvents, index_key + "." + list_type, new_indexes);
-}
-
-void EventSubscriberPlugin::expireCheck() {
-  auto data_key = "data." + dbNamespace();
-  auto eid_key = "eid." + dbNamespace();
-  // Min key will be the last surviving key.
-  size_t threshold_key = 0;
-
-  {
-    auto limit = getEventsMax();
-    std::vector<std::string> keys;
-    scanDatabaseKeys(kEvents, keys, data_key);
-    if (keys.size() <= limit) {
-      return;
-    }
-
-    // There is an overflow of events buffered for this subscriber.
-    LOG(WARNING) << "Expiring events for subscriber: " << getName()
-                 << " (overflowed limit " << limit << ")";
-    VLOG(1) << "Subscriber events " << getName() << " exceeded limit " << limit
-            << " by: " << keys.size() - limit;
-    // Inspect the N-FLAGS_events_max -th event's value and expire before the
-    // time within the content.
-    std::string last_key;
-    getDatabaseValue(kEvents, eid_key, last_key);
-    // The EID is the next-index.
-    // EID - events_max is the most last-recent event to keep.
-    threshold_key = boost::lexical_cast<size_t>(last_key) - getEventsMax();
-
-    // Scan each of the keys in keys, if their ID portion is < threshold.
-    // Nix them, this requires lots of conversions, use with care.
-    std::string max_key;
-    std::string min_key;
-    unsigned long min_key_value = 0;
-    unsigned long max_key_value = 0;
-    for (const auto& key : keys) {
-      auto const key_value =
-          tryTo<unsigned long int>(key.substr(key.rfind('.') + 1), 10)
-              .takeOr(0ul);
-
-      if (key_value < static_cast<unsigned long>(threshold_key)) {
-        min_key_value = (min_key_value == 0 || key_value < min_key_value)
-                            ? key_value
-                            : min_key_value;
-        if (min_key_value == key_value) {
-          min_key = key;
-        }
-
-        max_key_value = (key_value > max_key_value) ? key_value : max_key_value;
-        if (max_key_value == key_value) {
-          max_key = key;
-        }
-      }
-    }
-
-    if (!min_key.empty()) {
-      if (max_key_value == min_key_value) {
-        deleteDatabaseValue(kEvents, min_key);
-      } else {
-        deleteDatabaseRange(kEvents, min_key, max_key);
-      }
-    }
-  }
-
-  // Convert the key index into a time using the content.
-  // The last-recent event is fetched and the corresponding time is used as
-  // the expiration time for the subscriber.
-  std::string content;
-  getDatabaseValue(kEvents, data_key + "." + toIndex(threshold_key), content);
-
-  // Decode the value into a row structure to extract the time.
-  Row r;
-  if (!deserializeRowJSON(content, r) || r.count("time") == 0) {
-    return;
-  }
-
-  // The last time will become the implicit expiration time.
-  size_t last_time = boost::lexical_cast<size_t>(r.at("time"));
-  if (last_time > 0) {
-    expire_time_ = last_time - (last_time % 60);
-  }
-
-  // Finally, attempt an index query to trigger expirations.
-  // In this case the result set is not used.
-  getIndexes(expire_time_, 0, false);
-}
-
-bool EventSubscriberPlugin::executedAllQueries() const {
-  ReadLock lock(event_query_record_);
-  return queries_.size() >= query_count_;
-}
-
-std::vector<EventRecord> EventSubscriberPlugin::getRecords(
-    const std::vector<std::string>& indexes, bool optimize) {
-  auto record_key = "records." + dbNamespace();
-
-  std::vector<EventRecord> records;
-  for (const auto& index : indexes) {
-    std::vector<std::string> bin_records;
-    {
-      std::string record_value;
-      getDatabaseValue(kEvents, record_key + "." + index, record_value);
-      if (record_value.empty()) {
-        // There are actually no events in this bin, interesting error case.
-        continue;
-      }
-
-      // Each list is tokenized into a record=event_id:time.
-      bin_records = split(record_value, ",");
-    }
-
-    // Iterate over every 2 items: EID:TIME.
-    for (const auto& record : bin_records) {
-      const auto vals = split(record, ":");
-      if (vals.size() != 2) {
-        LOG(WARNING) << "Event records mismatch: " << record
-                     << " does not have a matching eid/event_time";
-        continue;
-      }
-      const auto eid = vals[0];
-      const EventTime et = timeFromRecord(vals[1]);
-      if (FLAGS_events_optimize && optimize && et <= optimize_time_ + 1) {
-        auto eidr = timeFromRecord(eid);
-        if (eidr <= optimize_eid_) {
-          continue;
-        }
-      }
-      records.push_back(std::make_pair(eid, et));
-    }
-  }
-
-  return records;
-}
-
-Status EventSubscriberPlugin::recordEvents(
-    const std::vector<std::string>& event_id_list, EventTime event_time) {
-  WriteLock lock(event_record_lock_);
-
-  DatabaseStringValueList database_data;
-  database_data.reserve(2U);
-
-  // The list key includes the list type (bin size) and the list ID (bin).
-  // The list_id is the MOST-Specific key ID, the bin for this list.
-  // If the event time was 13 and the time_list is 5 seconds, lid = 2.
-  auto list_id = boost::lexical_cast<std::string>(event_time / 60);
-  std::string time_value = boost::lexical_cast<std::string>(event_time);
-
-  // The record is identified by the event type then module name.
-  // Append the record (eid, unix_time) to the list bin.
-  auto database_key = "records." + dbNamespace() + ".60." + list_id;
-  auto index_key = "indexes." + dbNamespace() + ".60";
-
-  std::string record_value;
-  getDatabaseValue(kEvents, database_key, record_value);
-
-  for (const auto& eid : event_id_list) {
-    if (record_value.length() == 0) {
-      // This is a new list_id for list_key, append the ID to the indirect
-      // lookup for this list_key.
-      std::string index_value;
-      getDatabaseValue(kEvents, index_key, index_value);
-      if (index_value.length() == 0) {
-        // A new index.
-        index_value = list_id;
-      } else {
-        index_value += "," + list_id;
-      }
-      database_data.push_back(std::make_pair(index_key, index_value));
-      record_value = eid + ":" + time_value;
-    } else {
-      // Tokenize a record using ',' and the EID/time using ':'.
-      record_value += "," + eid + ":" + time_value;
-    }
-  }
-
-  database_data.push_back(std::make_pair(database_key, record_value));
-  auto status = setDatabaseBatch(kEvents, database_data);
-  if (!status.ok()) {
-    LOG(ERROR) << "Could not put Event Records";
-  }
-
-  return status;
-}
-
-size_t EventSubscriberPlugin::getEventsExpiry() {
-  return FLAGS_events_expiry;
-}
-
-size_t EventSubscriberPlugin::getEventsMax() {
-  return FLAGS_events_max;
-}
-
-const std::string EventSubscriberPlugin::getEventID() {
-  Status status;
-  // First get an event ID from the meta key.
-  std::string eid_key = "eid." + dbNamespace();
-
-  {
-    WriteLock lock(event_id_lock_);
-    if (last_eid_ == 0) {
-      std::string last_eid_value;
-      status = getDatabaseValue(kEvents, eid_key, last_eid_value);
-      if (!status.ok() || last_eid_value.empty()) {
-        last_eid_value = "0";
-      }
-      last_eid_ = boost::lexical_cast<size_t>(last_eid_value);
-    }
-
-    if (last_eid_ % 10 == 0) {
-      status = setDatabaseValue(kEvents, eid_key, toIndex(last_eid_ + 10));
-    }
-    last_eid_++;
-  }
-
-  return toIndex(last_eid_);
-}
-
-Status EventSubscriberPlugin::add(const Row& r) {
-  std::vector<Row> batch = {r};
-  return addBatch(batch, getUnixTime());
-}
-
-Status EventSubscriberPlugin::addBatch(std::vector<Row>& row_list) {
-  return addBatch(row_list, getUnixTime());
-}
-
-Status EventSubscriberPlugin::addBatch(std::vector<Row>& row_list,
-                                       EventTime custom_event_time) {
-  DatabaseStringValueList database_data;
-  database_data.reserve(row_list.size());
-
-  std::vector<std::string> event_id_list;
-  event_id_list.reserve(row_list.size());
-
-  auto event_time = custom_event_time != 0 ? custom_event_time : getUnixTime();
-  auto event_time_str = std::to_string(event_time);
-
-  for (auto& row : row_list) {
-    row["time"] = event_time_str;
-    row["eid"] = getEventID();
-
-    // Serialize and store the row data, for query-time retrieval.
-    std::string serialized_row;
-    auto status = serializeRowJSON(row, serialized_row);
-    if (!status.ok()) {
-      VLOG(1) << status.getMessage();
-      continue;
-    }
-
-    // Then remove the newline.
-    if (serialized_row.size() > 0 && serialized_row.back() == '\n') {
-      serialized_row.pop_back();
-    }
-
-    // Logger plugins may request events to be forwarded directly.
-    // If no active logger is marked 'usesLogEvent' then this is a no-op.
-    EventFactory::forwardEvent(serialized_row);
-
-    // Store the event data in the batch
-    database_data.push_back(std::make_pair(
-        "data." + dbNamespace() + "." + row["eid"], serialized_row));
-
-    event_id_list.push_back(std::move(row["eid"]));
-    event_count_++;
-
-    // Use the last EventID and a checkpoint bucket size to periodically apply
-    // buffer eviction. Eviction occurs if the total count exceeds events_max.
-    if (last_eid_ % EVENTS_CHECKPOINT == 0) {
-      expireCheck();
-    }
-  }
-
-  if (database_data.empty()) {
-    return Status(1, "Failed to process the rows");
-  }
-
-  // Save the batched data inside the database
-  auto status = setDatabaseBatch(kEvents, database_data);
-  if (!status.ok()) {
-    return status;
-  }
-
-  return recordEvents(event_id_list, event_time);
-}
-
-EventPublisherRef EventSubscriberPlugin::getPublisher() const {
-  return EventFactory::getEventPublisher(getType());
-}
-
-void EventSubscriberPlugin::removeSubscriptions() {
-  subscription_count_ = 0;
-  auto publisher = getPublisher();
-  if (publisher == nullptr) {
-    LOG(WARNING) << "Cannot remove subscriptions from: " << getName();
-    return;
-  }
-
-  getPublisher()->removeSubscriptions(getName());
-}
-
-void EventFactory::delay() {
-  // Caller may disable event publisher threads.
-  if (FLAGS_disable_events) {
-    return;
-  }
-
-  // Create a thread for each event publisher.
-  auto& ef = EventFactory::getInstance();
-  for (const auto& publisher : EventFactory::getInstance().event_pubs_) {
-    // Publishers that did not set up correctly are put into an ending state.
-    if (!publisher.second->isEnding()) {
-      auto thread_ = std::make_shared<std::thread>(
-          std::bind(&EventFactory::run, publisher.first));
-      ef.threads_.push_back(thread_);
-    }
-  }
-}
-
-Status EventPublisherPlugin::addSubscription(
-    const SubscriptionRef& subscription) {
-  // The publisher threads may be running and if they fire events the list of
-  // subscriptions will be walked.
-  WriteLock lock(subscription_lock_);
-  subscriptions_.push_back(subscription);
-  return Status(0);
-}
-
-void EventPublisherPlugin::removeSubscriptions(const std::string& subscriber) {
-  // See addSubscription for details on the critical section.
-  WriteLock lock(subscription_lock_);
-  auto end =
-      std::remove_if(subscriptions_.begin(),
-                     subscriptions_.end(),
-                     [&subscriber](const SubscriptionRef& subscription) {
-                       return (subscription->subscriber_name == subscriber);
-                     });
-  subscriptions_.erase(end, subscriptions_.end());
-}
-
-void EventFactory::addForwarder(const std::string& logger) {
-  getInstance().loggers_.push_back(logger);
-}
-
-void EventFactory::forwardEvent(const std::string& event) {
-  for (const auto& logger : getInstance().loggers_) {
-    Registry::call("logger", logger, {{"event", event}});
-  }
-}
-
-void EventFactory::configUpdate() {
-  // Scan the schedule for queries that touch "_events" tables.
-  // We will count the queries
-  std::map<std::string, SubscriberExpirationDetails> subscriber_details;
-  auto& ef = EventFactory::getInstance();
-  for (const auto& details : subscriber_details) {
-    if (!ef.exists(details.first)) {
-      continue;
-    }
-
-    WriteLock lock(ef.factory_lock_);
-    auto subscriber = ef.getEventSubscriber(details.first);
-    subscriber->min_expiration_ = details.second.max_interval * 3;
-    subscriber->min_expiration_ += (60 - (subscriber->min_expiration_ % 60));
-
-    // Emit a warning for each subscriber affected by the small expiration.
-    auto expiry = subscriber->getEventsExpiry();
-    if (expiry > 0 && subscriber->min_expiration_ > expiry) {
-      LOG(INFO) << "Subscriber expiration is too low: "
-                << subscriber->getName();
-    }
-    subscriber->query_count_ = details.second.query_count;
-
-    WriteLock subscriber_lock(subscriber->event_query_record_);
-    subscriber->queries_.clear();
-  }
-
-  // If events are enabled configure the subscribers before publishers.
-  if (!FLAGS_disable_events) {
-    RegistryFactory::get().registry("event_subscriber")->configure();
-    RegistryFactory::get().registry("event_publisher")->configure();
-  }
-}
-
-Status EventFactory::run(const std::string& type_id) {
-  if (FLAGS_disable_events) {
-    return Status::success();
-  }
-
-  // An interesting take on an event dispatched entrypoint.
-  // There is little introspection into the event type.
-  // Assume it can either make use of an entrypoint poller/selector or
-  // take care of async callback registrations in setUp/configure/run
-  // only once and handle event queuing/firing in callbacks.
-  EventPublisherRef publisher = nullptr;
-  {
-    auto& ef = EventFactory::getInstance();
-    WriteLock lock(ef.factory_lock_);
-    publisher = ef.getEventPublisher(type_id);
-  }
-
-  if (publisher == nullptr) {
-    return Status(1, "Event publisher is missing");
-  } else if (publisher->hasStarted()) {
-    return Status(1, "Cannot restart an event publisher");
-  }
-  VLOG(1) << "Starting event publisher run loop: " + type_id;
-  publisher->hasStarted(true);
-
-  auto status = Status(0, "OK");
-  while (!publisher->isEnding()) {
-    // Can optionally implement a global cooloff latency here.
-    status = publisher->run();
-    if (!status.ok()) {
-      break;
-    }
-    publisher->restart_count_++;
-  }
-  if (!status.ok()) {
-    // The runloop status is not reflective of the event type's.
-    VLOG(1) << "Event publisher " << publisher->type()
-            << " run loop terminated for reason: " << status.getMessage();
-    // Publishers auto tear down when their run loop stops.
-  }
-  publisher->tearDown();
-  publisher->state(EventState::EVENT_NONE);
-
-  // Do not remove the publisher from the event factory.
-  // If the event factory's `end` method was called these publishers will be
-  // cleaned up after their thread context is removed; otherwise, a removed
-  // thread context and failed publisher will remain available for stats.
-  return Status::success();
-}
-
-// There's no reason for the event factory to keep multiple instances.
-EventFactory& EventFactory::getInstance() {
-  static EventFactory ef;
-  return ef;
-}
-
-Status EventFactory::registerEventPublisher(const PluginRef& pub) {
-  // Try to downcast the plugin to an event publisher.
-  EventPublisherRef specialized_pub;
-  try {
-    auto base_pub = std::dynamic_pointer_cast<EventPublisherPlugin>(pub);
-    specialized_pub = std::static_pointer_cast<BaseEventPublisher>(base_pub);
-  } catch (const std::bad_cast& /* e */) {
-    return Status(1, "Incorrect plugin");
-  }
-
-  if (specialized_pub == nullptr || specialized_pub.get() == nullptr) {
-    return Status::success();
-  }
-
-  auto type_id = specialized_pub->type();
-  if (type_id.empty()) {
-    // This subscriber did not override its name.
-    return Status(1, "Publishers must have a type");
-  }
-
-  auto& ef = EventFactory::getInstance();
-  {
-    WriteLock lock(getInstance().factory_lock_);
-    if (ef.event_pubs_.count(type_id) != 0) {
-      // This is a duplicate event publisher.
-      return Status(1, "Duplicate publisher type");
-    }
-
-    ef.event_pubs_[type_id] = specialized_pub;
-  }
-
-  // Do not set up event publisher if events are disabled.
-  if (!FLAGS_disable_events) {
-    if (specialized_pub->state() != EventState::EVENT_NONE) {
-      specialized_pub->tearDown();
-    }
-
-    auto status = specialized_pub->setUp();
-    specialized_pub->state(EventState::EVENT_SETUP);
-    if (!status.ok()) {
-      // Only start event loop if setUp succeeds.
-      LOG(INFO) << "Event publisher not enabled: " << type_id << ": "
-                << status.what();
-      specialized_pub->isEnding(true);
-      return status;
-    }
-  }
-
-  return Status::success();
-}
-
-Status EventFactory::registerEventSubscriber(const PluginRef& sub) {
-  // Try to downcast the plugin to an event subscriber.
-  EventSubscriberRef specialized_sub;
-  try {
-    auto base_sub = std::dynamic_pointer_cast<EventSubscriberPlugin>(sub);
-    specialized_sub = std::static_pointer_cast<BaseEventSubscriber>(base_sub);
-  } catch (const std::bad_cast& /* e */) {
-    return Status(1, "Incorrect plugin");
-  }
-
-  if (specialized_sub == nullptr || specialized_sub.get() == nullptr) {
-    return Status(1, "Invalid subscriber");
-  }
-
-  // The config may use an "events" key to explicitly enabled or disable
-  // event subscribers. See EventSubscriber::disable.
-  auto name = specialized_sub->getName();
-  if (name.empty()) {
-    // This subscriber did not override its name.
-    return Status(1, "Subscribers must have set a name");
-  }
-
-  if (specialized_sub->state() != EventState::EVENT_NONE) {
-    specialized_sub->tearDown();
-  }
-
-  // Allow subscribers a configure-time setup to determine if they should run.
-  auto status = specialized_sub->setUp();
-  if (!status) {
-    specialized_sub->disabled = true;
-  }
-  specialized_sub->state(EventState::EVENT_SETUP);
-
-  // Let the subscriber initialize any Subscriptions.
-  if (!FLAGS_disable_events && !specialized_sub->disabled) {
-    specialized_sub->expireCheck();
-    status = specialized_sub->init();
-    specialized_sub->state(EventState::EVENT_RUNNING);
-  } else {
-    specialized_sub->state(EventState::EVENT_PAUSED);
-  }
-
-  auto& ef = EventFactory::getInstance();
-  {
-    WriteLock lock(getInstance().factory_lock_);
-    ef.event_subs_[name] = specialized_sub;
-  }
-
-  // Set state of subscriber.
-  if (!status.ok()) {
-    specialized_sub->state(EventState::EVENT_FAILED);
-    return Status(1, status.getMessage());
-  } else {
-    return Status::success();
-  }
-}
-
-Status EventFactory::addSubscription(const std::string& type_id,
-                                     const std::string& name_id,
-                                     const SubscriptionContextRef& mc,
-                                     EventCallback cb) {
-  auto subscription = Subscription::create(name_id, mc, cb);
-  return EventFactory::addSubscription(type_id, subscription);
-}
-
-Status EventFactory::addSubscription(const std::string& type_id,
-                                     const SubscriptionRef& subscription) {
-  EventPublisherRef publisher = getInstance().getEventPublisher(type_id);
-  if (publisher == nullptr) {
-    return Status(1, "Unknown event publisher");
-  }
-
-  // The event factory is responsible for configuring the event types.
-  return publisher->addSubscription(subscription);
-}
-
-size_t EventFactory::numSubscriptions(const std::string& type_id) {
-  EventPublisherRef publisher;
-  try {
-    publisher = EventFactory::getInstance().getEventPublisher(type_id);
-  } catch (std::out_of_range& /* e */) {
-    return 0;
-  }
-  if (publisher == nullptr) {
-    return 0;
-  }
-  return publisher->numSubscriptions();
-}
-
-EventPublisherRef EventFactory::getEventPublisher(const std::string& type_id) {
-  if (getInstance().event_pubs_.count(type_id) == 0) {
-    LOG(ERROR) << "Requested unknown/failed event publisher: " + type_id;
-    return nullptr;
-  }
-  return getInstance().event_pubs_.at(type_id);
-}
-
-EventSubscriberRef EventFactory::getEventSubscriber(
-    const std::string& name_id) {
-  if (!exists(name_id)) {
-    LOG(ERROR) << "Requested unknown event subscriber: " + name_id;
-    return nullptr;
-  }
-  return getInstance().event_subs_.at(name_id);
-}
-
-bool EventFactory::exists(const std::string& name_id) {
-  return (getInstance().event_subs_.count(name_id) > 0);
-}
-
-Status EventFactory::deregisterEventPublisher(const EventPublisherRef& pub) {
-  return EventFactory::deregisterEventPublisher(pub->type());
-}
-
-Status EventFactory::deregisterEventPublisher(const std::string& type_id) {
-  auto& ef = EventFactory::getInstance();
-
-  WriteLock lock(ef.factory_lock_);
-  EventPublisherRef publisher = ef.getEventPublisher(type_id);
-  if (publisher == nullptr) {
-    return Status(1, "No event publisher to deregister");
-  }
-
-  if (!FLAGS_disable_events) {
-    publisher->isEnding(true);
-    if (!publisher->hasStarted()) {
-      // If a publisher's run loop was not started, call tearDown since
-      // the setUp happened at publisher registration time.
-      publisher->tearDown();
-      publisher->state(EventState::EVENT_NONE);
-      // If the run loop did run the tear down and erase will happen in the
-      // event thread wrapper when isEnding is next checked.
-      ef.event_pubs_.erase(type_id);
-    }
-  }
-  return Status::success();
-}
-
-Status EventFactory::deregisterEventSubscriber(const std::string& sub) {
-  auto& ef = EventFactory::getInstance();
-
-  WriteLock lock(ef.factory_lock_);
-  if (ef.event_subs_.count(sub) == 0) {
-    return Status(1, "Event subscriber is missing");
-  }
-
-  auto& subscriber = ef.event_subs_.at(sub);
-  subscriber->state(EventState::EVENT_NONE);
-  subscriber->tearDown();
-  ef.event_subs_.erase(sub);
-  return Status(0);
-}
-
-std::vector<std::string> EventFactory::publisherTypes() {
-  WriteLock lock(getInstance().factory_lock_);
-  std::vector<std::string> types;
-  for (const auto& publisher : getInstance().event_pubs_) {
-    types.push_back(publisher.first);
-  }
-  return types;
-}
-
-std::vector<std::string> EventFactory::subscriberNames() {
-  WriteLock lock(getInstance().factory_lock_);
-  std::vector<std::string> names;
-  for (const auto& subscriber : getInstance().event_subs_) {
-    names.push_back(subscriber.first);
-  }
-  return names;
-}
-
-void EventFactory::end(bool join) {
-  auto& ef = EventFactory::getInstance();
-
-  // Call deregister on each publisher.
-  for (const auto& publisher : ef.publisherTypes()) {
-    deregisterEventPublisher(publisher);
-  }
-
-  // Stop handling exceptions for the publisher threads.
-  for (const auto& thread : ef.threads_) {
-    if (join) {
-      thread->join();
-    } else {
-      thread->detach();
-    }
-  }
-
-  {
-    WriteLock lock(getInstance().factory_lock_);
-    // A small cool off helps OS API event publisher flushing.
-    if (!FLAGS_disable_events) {
-      ef.threads_.clear();
-    }
-
-    // Threads may still be executing, when they finish, release publishers.
-    ef.event_pubs_.clear();
-    ef.event_subs_.clear();
-  }
-}
-
-void attachEvents() {
-  const auto& publishers = RegistryFactory::get().plugins("event_publisher");
-  for (const auto& publisher : publishers) {
-    EventFactory::registerEventPublisher(publisher.second);
-  }
-
-  const auto& subscribers = RegistryFactory::get().plugins("event_subscriber");
-  for (const auto& subscriber : subscribers) {
-    if (!boost::ends_with(subscriber.first, "_events")) {
-      LOG(ERROR) << "Error registering subscriber: " << subscriber.first
-                 << ": Must use a '_events' suffix";
-      continue;
-    }
-
-    auto status = EventFactory::registerEventSubscriber(subscriber.second);
-    if (!status.ok()) {
-      VLOG(1) << "Error registering subscriber: " << subscriber.first << ": "
-              << status.getMessage();
-    }
-  }
-
-  // Configure the event publishers and subscribers.
-  EventFactory::configUpdate();
-}
-} // namespace osquery
diff --git a/src/osquery/events/linux/auditdnetlink.cpp b/src/osquery/events/linux/auditdnetlink.cpp
deleted file mode 100644 (file)
index 4b74793..0000000
+++ /dev/null
@@ -1,881 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <linux/audit.h>
-#include <poll.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <iostream>
-
-#include <boost/utility/string_ref.hpp>
-
-#include <osquery/events/linux/auditdnetlink.h>
-#include <osquery/events/linux/process_events.h>
-#include <osquery/events/linux/process_file_events.h>
-#include <osquery/events/linux/selinux_events.h>
-#include <osquery/events/linux/socket_events.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-#include <osquery/utils/conversions/tryto.h>
-#include <osquery/utils/expected/expected.h>
-#include <osquery/utils/system/time.h>
-
-namespace osquery {
-/// Control the audit subsystem by electing to be the single process sink.
-FLAG(bool, audit_persist, true, "Attempt to retain control of audit");
-
-/// Audit debugger helper
-HIDDEN_FLAG(bool, audit_debug, false, "Debug Linux audit messages");
-
-/// Control the audit subsystem by allowing subscriptions to apply rules.
-FLAG(bool,
-     audit_allow_config,
-     false,
-     "Allow the audit publisher to change auditing configuration");
-
-/// Always uninstall all the audit rules that osquery uses when exiting
-FLAG(bool,
-     audit_force_unconfigure,
-     false,
-     "Always uninstall all rules, regardless of whether they were already "
-     "installed or not");
-
-/// Forces osquery to remove all rules upon startup
-FLAG(bool,
-     audit_force_reconfigure,
-     false,
-     "Configure the audit subsystem from scratch");
-
-// External flags; they are used to determine which rules need to be installed
-DECLARE_bool(audit_allow_fim_events);
-DECLARE_bool(audit_allow_process_events);
-DECLARE_bool(audit_allow_sockets);
-DECLARE_bool(audit_allow_user_events);
-DECLARE_bool(audit_allow_selinux_events);
-
-// user messages should be filtered
-// also, we should handle the 2nd user message type
-namespace {
-bool IsSELinuxRecord(const audit_reply& reply) noexcept {
-  static const auto& selinux_event_set = kSELinuxEventList;
-  return (selinux_event_set.find(reply.type) != selinux_event_set.end());
-}
-
-bool ShouldHandle(const audit_reply& reply) noexcept {
-  if (IsSELinuxRecord(reply)) {
-    return FLAGS_audit_allow_selinux_events;
-  }
-
-  switch (reply.type) {
-  case NLMSG_NOOP:
-  case NLMSG_DONE:
-  case NLMSG_ERROR:
-  case AUDIT_LIST_RULES:
-  case AUDIT_SECCOMP:
-  case AUDIT_GET:
-  case (AUDIT_GET + 1)...(AUDIT_LIST_RULES - 1):
-  case (AUDIT_LIST_RULES + 1)...(AUDIT_FIRST_USER_MSG - 1):
-  case AUDIT_DAEMON_START ... AUDIT_DAEMON_CONFIG: // 1200 - 1203
-  case AUDIT_CONFIG_CHANGE:
-    return false;
-
-  default:
-    return true;
-  }
-}
-} // namespace
-
-enum AuditStatus {
-  AUDIT_DISABLED = 0,
-  AUDIT_ENABLED = 1,
-  AUDIT_IMMUTABLE = 2,
-};
-
-AuditdNetlink::AuditdNetlink() {
-  try {
-    auditd_context_ = std::make_shared<AuditdContext>();
-
-    Dispatcher::addService(
-        std::make_shared<AuditdNetlinkReader>(auditd_context_));
-
-    Dispatcher::addService(
-        std::make_shared<AuditdNetlinkParser>(auditd_context_));
-
-  } catch (const std::bad_alloc&) {
-    VLOG(1) << "Failed to initialize the AuditdNetlink services due to a "
-               "memory allocation error";
-    throw;
-  }
-}
-
-std::vector<AuditEventRecord> AuditdNetlink::getEvents() noexcept {
-  std::vector<AuditEventRecord> record_list;
-
-  {
-    std::unique_lock<std::mutex> queue_lock(
-        auditd_context_->processed_events_mutex);
-
-    if (auditd_context_->processed_records_cv.wait_for(
-            queue_lock, std::chrono::seconds(1)) ==
-        std::cv_status::no_timeout) {
-      record_list = std::move(auditd_context_->processed_events);
-      auditd_context_->processed_events.clear();
-    }
-  }
-
-  return record_list;
-}
-
-AuditdNetlinkReader::AuditdNetlinkReader(AuditdContextRef context)
-    : InternalRunnable("AuditdNetlinkReader"),
-      auditd_context_(std::move(context)),
-      read_buffer_(4096U) {}
-
-void AuditdNetlinkReader::start() {
-  int counter_to_next_status_request = 0;
-  const int status_request_countdown = 1000;
-
-  while (!interrupted()) {
-    if (auditd_context_->acquire_handle) {
-      if (FLAGS_audit_debug) {
-        std::cout << "(re)acquiring the audit handle.." << std::endl;
-      }
-
-      NetlinkStatus netlink_status = acquireHandle();
-
-      if (netlink_status == NetlinkStatus::Disabled ||
-          netlink_status == NetlinkStatus::Error) {
-        std::this_thread::sleep_for(std::chrono::seconds(5));
-        continue;
-      }
-
-      auditd_context_->acquire_handle = false;
-      counter_to_next_status_request = status_request_countdown;
-    }
-
-    if (counter_to_next_status_request == 0) {
-      errno = 0;
-
-      if (audit_request_status(audit_netlink_handle_) <= 0) {
-        if (errno == ENOBUFS) {
-          VLOG(1) << "Warning: Failed to request audit status (ENOBUFS). "
-                     "Retrying again later";
-
-        } else {
-          VLOG(1) << "Error: Failed to request audit status. Requesting a "
-                     "handle reset";
-
-          auditd_context_->acquire_handle = true;
-        }
-      }
-
-      counter_to_next_status_request = status_request_countdown;
-    } else {
-      --counter_to_next_status_request;
-    }
-
-    if (!acquireMessages()) {
-      auditd_context_->acquire_handle = true;
-    }
-  }
-}
-
-void AuditdNetlinkReader::stop() {
-  if (audit_netlink_handle_ == -1) {
-    return;
-  }
-
-  VLOG(1) << "Releasing the audit handle...";
-
-  auditd_context_->unprocessed_records_cv.notify_all();
-  restoreAuditServiceConfiguration();
-
-  audit_close(audit_netlink_handle_);
-  audit_netlink_handle_ = -1;
-}
-
-bool AuditdNetlinkReader::acquireMessages() noexcept {
-  pollfd fds[] = {{audit_netlink_handle_, POLLIN, 0}};
-
-  struct sockaddr_nl nladdr = {};
-  socklen_t nladdrlen = sizeof(nladdr);
-
-  bool reset_handle = false;
-  size_t events_received = 0;
-
-  // Attempt to read as many messages as possible before we exit, and terminate
-  // early if we have been asked to terminate
-  for (events_received = 0;
-       !interrupted() && events_received < read_buffer_.size();
-       events_received++) {
-    errno = 0;
-    int poll_status = ::poll(fds, 1, 2000);
-    if (poll_status == 0) {
-      break;
-    }
-
-    if (poll_status < 0) {
-      if (errno != EINTR) {
-        reset_handle = true;
-        VLOG(1) << "poll() failed with error " << errno;
-      }
-
-      break;
-    }
-
-    if ((fds[0].revents & POLLIN) == 0) {
-      break;
-    }
-
-    audit_reply reply = {};
-    ssize_t len = recvfrom(audit_netlink_handle_,
-                           &reply.msg,
-                           sizeof(reply.msg),
-                           0,
-                           reinterpret_cast<struct sockaddr*>(&nladdr),
-                           &nladdrlen);
-
-    if (len < 0) {
-      VLOG(1) << "Failed to receive data from the audit netlink";
-      reset_handle = true;
-      break;
-    }
-
-    if (nladdrlen != sizeof(nladdr)) {
-      VLOG(1) << "Protocol error";
-      reset_handle = true;
-      break;
-    }
-
-    if (nladdr.nl_pid) {
-      VLOG(1) << "Invalid netlink endpoint";
-      reset_handle = true;
-      break;
-    }
-
-    if (!NLMSG_OK(&reply.msg.nlh, static_cast<unsigned int>(len))) {
-      if (len == sizeof(reply.msg)) {
-        VLOG(1) << "Netlink event too big (EFBIG)";
-      } else {
-        VLOG(1) << "Broken netlink event (EBADE)";
-      }
-
-      reset_handle = true;
-      break;
-    }
-
-    read_buffer_[events_received] = reply;
-  }
-
-  if (events_received != 0) {
-    std::unique_lock<std::mutex> lock(
-        auditd_context_->unprocessed_records_mutex);
-
-    auditd_context_->unprocessed_records.reserve(
-        auditd_context_->unprocessed_records.size() + events_received);
-
-    auditd_context_->unprocessed_records.insert(
-        auditd_context_->unprocessed_records.end(),
-        read_buffer_.begin(),
-        std::next(read_buffer_.begin(), events_received));
-
-    auditd_context_->unprocessed_records_cv.notify_all();
-  }
-
-  if (reset_handle) {
-    VLOG(1) << "Requesting audit handle reset";
-    return false;
-  }
-
-  return true;
-}
-
-bool AuditdNetlinkReader::configureAuditService() noexcept {
-  VLOG(1) << "Attempting to configure the audit service";
-
-  // Want to set a min sane buffer and maximum number of events/second min.
-  // This is normally controlled through the audit config, but we must
-  // enforce sane minimums: -b 8192 -e 100
-  audit_set_backlog_wait_time(audit_netlink_handle_, 1);
-  audit_set_backlog_limit(audit_netlink_handle_, 4096);
-  audit_set_failure(audit_netlink_handle_, AUDIT_FAIL_SILENT);
-
-  // Request only the highest priority of audit status messages.
-  set_aumessage_mode(MSG_QUIET, DBG_NO);
-
-  //
-  // Audit rules
-  //
-
-  // Rules required by the socket_events table
-  if (FLAGS_audit_allow_sockets) {
-    VLOG(1) << "Enabling audit rules for the socket_events table";
-
-    for (int syscall : kSocketEventsSyscalls) {
-      monitored_syscall_list_.insert(syscall);
-    }
-  }
-
-  // Rules required by the process_events table
-  if (FLAGS_audit_allow_process_events) {
-    VLOG(1) << "Enabling audit rules for the process_events table";
-
-    for (int syscall : kProcessEventsSyscalls) {
-      monitored_syscall_list_.insert(syscall);
-    }
-  }
-
-  // Rules required by the process_file_events table
-  if (FLAGS_audit_allow_fim_events) {
-    VLOG(1) << "Enabling audit rules for the process_file_events table";
-
-    for (int syscall : kProcessFileEventsSyscalls) {
-      monitored_syscall_list_.insert(syscall);
-    }
-  }
-
-  // Attempt to add each one of the rules we collected
-  for (int syscall_number : monitored_syscall_list_) {
-    audit_rule_data rule = {};
-    audit_rule_syscall_data(&rule, syscall_number);
-
-    // clang-format off
-    int rule_add_error = audit_add_rule_data(audit_netlink_handle_, &rule,
-      // We want to be notified when we exit from the syscall
-      AUDIT_FILTER_EXIT,
-
-      // Always audit this syscall event
-      AUDIT_ALWAYS
-    );
-    // clang-format on
-
-    // When exiting, don't remove the rules that were already installed, unless
-    // we have been asked to
-    if (rule_add_error >= 0) {
-      if (FLAGS_audit_debug) {
-        std::cout << "Audit rule installed for syscall " << syscall_number
-                  << std::endl;
-      }
-
-      installed_rule_list_.push_back(rule);
-      continue;
-    }
-
-    if (FLAGS_audit_debug) {
-      std::cout << "Audit rule for syscall " << syscall_number
-                << " could not be installed. Errno: " << (-errno) << std::endl;
-    }
-
-    if (FLAGS_audit_force_unconfigure) {
-      installed_rule_list_.push_back(rule);
-    }
-
-    rule_add_error = -rule_add_error;
-
-    if (rule_add_error != EEXIST) {
-      VLOG(1) << "The following syscall number could not be added to the audit "
-                 "service rules: "
-              << syscall_number << ". Some of the auditd "
-              << "table may not work properly (process_events, "
-              << "socket_events, process_file_events, user_events)";
-    }
-  }
-
-  return true;
-}
-
-bool AuditdNetlinkReader::clearAuditConfiguration() noexcept {
-  int seq = audit_request_rules_list_data(audit_netlink_handle_);
-  if (seq <= 0) {
-    VLOG(1) << "Failed to list the audit rules";
-    return false;
-  }
-
-  // Attempt to list all rules
-  std::vector<AuditRuleDataObject> rule_object_list;
-  auto timeout = getUnixTime() + 5;
-
-  for (size_t read_retry = 0U; read_retry < 3U; ++read_retry) {
-    if (timeout < getUnixTime()) {
-      VLOG(1) << "Failed to unconfigure the audit service (timeout)";
-      return false;
-    }
-
-    bool netlink_ready = false;
-
-    for (size_t poll_retry = 0U; poll_retry < 3U; ++poll_retry) {
-      pollfd fds[] = {{audit_netlink_handle_, POLLIN, 0}};
-
-      errno = 0;
-      int poll_status = ::poll(fds, 1, 4);
-      if (poll_status == 0) {
-        continue;
-      }
-
-      if (poll_status < 0) {
-        VLOG(1) << "poll() failed with errno " << errno;
-        return false;
-      }
-
-      if ((fds[0].revents & POLLIN) != 0) {
-        netlink_ready = true;
-        break;
-      }
-    }
-
-    if (!netlink_ready) {
-      VLOG(1) << "Could not read from the audit netlink";
-      return false;
-    }
-
-    // Get the reply from the audit link
-    struct audit_reply reply = {};
-    if (audit_get_reply(
-            audit_netlink_handle_, &reply, GET_REPLY_NONBLOCKING, 0) <= 0) {
-      continue;
-    }
-
-    read_retry = 0;
-    if (reply.nlh->nlmsg_seq != static_cast<unsigned int>(seq)) {
-      continue;
-    }
-
-    if (reply.type == NLMSG_DONE) {
-      // We have finished listing the rules
-      break;
-    }
-
-    if (reply.type == NLMSG_ERROR && reply.error->error != 0) {
-      return false;
-    }
-
-    if (reply.type != AUDIT_LIST_RULES) {
-      // Skip this reply if it is not part of the rule list output
-      continue;
-    }
-
-    // Save the rule
-    const auto reply_size = sizeof(reply) + reply.ruledata->buflen;
-
-    AuditRuleDataObject reply_object(reply_size);
-
-    std::memcpy(reply_object.data(), reply.ruledata, reply_size);
-    rule_object_list.push_back(reply_object);
-  }
-
-  // Delete each rule
-  size_t error_count = 0U;
-  for (auto& rule_object : rule_object_list) {
-    if (!deleteAuditRule(rule_object)) {
-      error_count++;
-    }
-  }
-
-  if (error_count != 0U) {
-    VLOG(1) << error_count << " audit rules could not be correctly removed";
-    return false;
-  }
-
-  VLOG(1) << "The audit configuration has been cleared";
-  return true;
-}
-
-bool AuditdNetlinkReader::deleteAuditRule(
-    const AuditRuleDataObject& rule_object) {
-  if (NLMSG_SPACE(rule_object.size()) > MAX_AUDIT_MESSAGE_LENGTH) {
-    return false;
-  }
-
-  auto rule_data =
-      reinterpret_cast<const struct audit_rule_data*>(rule_object.data());
-
-  struct audit_message request = {};
-  request.nlh.nlmsg_len = static_cast<__u32>(NLMSG_SPACE(rule_object.size()));
-  request.nlh.nlmsg_type = AUDIT_DEL_RULE;
-  request.nlh.nlmsg_flags = NLM_F_REQUEST;
-  std::memcpy(NLMSG_DATA(&request.nlh), rule_data, rule_object.size());
-
-  struct sockaddr_nl address = {};
-  address.nl_family = AF_NETLINK;
-
-  bool success = false;
-
-  for (size_t retry = 0U; retry < 3U; retry++) {
-    ssize_t bytes_sent;
-
-    while (true) {
-      errno = 0;
-      bytes_sent = sendto(audit_netlink_handle_,
-                          &request,
-                          request.nlh.nlmsg_len,
-                          0,
-                          reinterpret_cast<struct sockaddr*>(&address),
-                          sizeof(address));
-      if (bytes_sent >= 0) {
-        break;
-      }
-
-      if (errno != EINTR) {
-        return false;
-      }
-    }
-
-    if (bytes_sent == static_cast<ssize_t>(request.nlh.nlmsg_len)) {
-      success = true;
-      break;
-    }
-  }
-
-  return success;
-}
-
-void AuditdNetlinkReader::restoreAuditServiceConfiguration() noexcept {
-  if (FLAGS_audit_debug) {
-    std::cout << "Uninstalling audit rules" << std::endl;
-  }
-
-  // Remove the rules we have added
-  VLOG(1) << "Uninstalling the audit rules we have installed";
-
-  for (auto& rule : installed_rule_list_) {
-    audit_delete_rule_data(
-        audit_netlink_handle_, &rule, AUDIT_FILTER_EXIT, AUDIT_ALWAYS);
-  }
-
-  installed_rule_list_.clear();
-
-  // Restore audit configuration defaults.
-  if (FLAGS_audit_debug) {
-    std::cout << "Restoring default settings and disabling the service"
-              << std::endl;
-  }
-
-  VLOG(1) << "Restoring the default configuration for the audit service";
-
-  audit_set_backlog_limit(audit_netlink_handle_, 0);
-  audit_set_backlog_wait_time(audit_netlink_handle_, 60000);
-  audit_set_failure(audit_netlink_handle_, AUDIT_FAIL_PRINTK);
-  audit_set_enabled(audit_netlink_handle_, AUDIT_DISABLED);
-}
-
-NetlinkStatus AuditdNetlinkReader::acquireHandle() noexcept {
-  // Returns the audit netlink status
-  auto L_GetNetlinkStatus = [](int netlink_handle) -> NetlinkStatus {
-    if (netlink_handle <= 0) {
-      return NetlinkStatus::Error;
-    }
-
-    errno = 0;
-    if (audit_request_status(netlink_handle) < 0 && errno != ENOBUFS) {
-      VLOG(1) << "Failed to query the audit netlink status";
-      return NetlinkStatus::Error;
-    }
-
-    auto enabled = audit_is_enabled(netlink_handle);
-
-    if (enabled == AUDIT_IMMUTABLE || getuid() != 0 ||
-        !FLAGS_audit_allow_config) {
-      return NetlinkStatus::ActiveImmutable;
-
-    } else if (enabled == AUDIT_ENABLED) {
-      return NetlinkStatus::ActiveMutable;
-
-    } else if (enabled == AUDIT_DISABLED) {
-      return NetlinkStatus::Disabled;
-
-    } else {
-      return NetlinkStatus::Error;
-    }
-  };
-
-  if (audit_netlink_handle_ != -1) {
-    audit_close(audit_netlink_handle_);
-    audit_netlink_handle_ = -1;
-  }
-
-  audit_netlink_handle_ = audit_open();
-  if (audit_netlink_handle_ <= 0) {
-    VLOG(1) << "Failed to acquire the netlink handle";
-
-    audit_netlink_handle_ = -1;
-    return NetlinkStatus::Error;
-  }
-
-  if (audit_set_pid(audit_netlink_handle_, getpid(), WAIT_NO) < 0) {
-    VLOG(1) << "Failed to set the netlink owner";
-
-    audit_close(audit_netlink_handle_);
-    audit_netlink_handle_ = -1;
-
-    return NetlinkStatus::Error;
-  }
-
-  NetlinkStatus netlink_status = L_GetNetlinkStatus(audit_netlink_handle_);
-  if (FLAGS_audit_allow_config &&
-      (netlink_status != NetlinkStatus::ActiveMutable &&
-       netlink_status != NetlinkStatus::ActiveImmutable)) {
-    if (audit_set_enabled(audit_netlink_handle_, AUDIT_ENABLED) < 0) {
-      VLOG(1) << "Failed to enable the audit service";
-
-      audit_close(audit_netlink_handle_);
-      audit_netlink_handle_ = -1;
-
-      return NetlinkStatus::Error;
-    }
-
-    if (FLAGS_audit_debug) {
-      std::cout << "Audit service enabled" << std::endl;
-    }
-  }
-
-  if (FLAGS_audit_allow_config) {
-    if (FLAGS_audit_force_reconfigure) {
-      if (!clearAuditConfiguration()) {
-        audit_netlink_handle_ = -1;
-        return NetlinkStatus::Error;
-      }
-    }
-
-    if (!configureAuditService()) {
-      return NetlinkStatus::ActiveImmutable;
-    }
-
-    if (FLAGS_audit_debug) {
-      std::cout << "Audit service configured" << std::endl;
-    }
-  }
-
-  return NetlinkStatus::ActiveMutable;
-}
-
-AuditdNetlinkParser::AuditdNetlinkParser(AuditdContextRef context)
-    : InternalRunnable("AuditdNetlinkParser"),
-      auditd_context_(std::move(context)) {}
-
-void AuditdNetlinkParser::start() {
-  while (!interrupted()) {
-    std::vector<audit_reply> queue;
-
-    {
-      std::unique_lock<std::mutex> lock(
-          auditd_context_->unprocessed_records_mutex);
-
-      while (auditd_context_->unprocessed_records.empty() && !interrupted()) {
-        auditd_context_->unprocessed_records_cv.wait_for(
-            lock, std::chrono::seconds(1));
-      }
-
-      queue = std::move(auditd_context_->unprocessed_records);
-      auditd_context_->unprocessed_records.clear();
-    }
-
-    std::vector<AuditEventRecord> audit_event_record_queue;
-    audit_event_record_queue.reserve(queue.size());
-
-    for (auto& reply : queue) {
-      if (interrupted()) {
-        break;
-      }
-
-      AdjustAuditReply(reply);
-
-      // This record carries the process id of the controlling daemon; in case
-      // we lost control of the audit service, we are going to request a reset
-      // as soon as we finish processing the pending queue
-      if (reply.type == AUDIT_GET) {
-        reply.status = static_cast<struct audit_status*>(NLMSG_DATA(reply.nlh));
-        auto new_pid = static_cast<pid_t>(reply.status->pid);
-
-        if (new_pid != getpid()) {
-          VLOG(1) << "Audit control lost to pid: " << new_pid;
-
-          if (FLAGS_audit_persist) {
-            VLOG(1) << "Attempting to reacquire control of the audit service";
-            auditd_context_->acquire_handle = true;
-          }
-        }
-
-        continue;
-      }
-
-      // We are not interested in all messages; only get the ones related to
-      // user events, syscalls and SELinux events
-      if (!ShouldHandle(reply)) {
-        continue;
-      }
-
-      AuditEventRecord audit_event_record = {};
-      if (!ParseAuditReply(reply, audit_event_record)) {
-        VLOG(1) << "Malformed audit record received";
-        continue;
-      }
-
-      audit_event_record_queue.push_back(audit_event_record);
-    }
-
-    // Save the new records and notify the reader
-    if (!audit_event_record_queue.empty()) {
-      std::lock_guard<std::mutex> queue_lock(
-          auditd_context_->processed_events_mutex);
-
-      auditd_context_->processed_events.reserve(
-          auditd_context_->processed_events.size() +
-          audit_event_record_queue.size());
-
-      auditd_context_->processed_events.insert(
-          auditd_context_->processed_events.end(),
-          audit_event_record_queue.begin(),
-          audit_event_record_queue.end());
-
-      auditd_context_->processed_records_cv.notify_all();
-    }
-
-    queue.clear();
-    audit_event_record_queue.clear();
-  }
-}
-
-bool AuditdNetlinkParser::ParseAuditReply(
-    const audit_reply& reply, AuditEventRecord& event_record) noexcept {
-  event_record = {};
-
-  if (FLAGS_audit_debug) {
-    std::cout << reply.type << ", " << std::string(reply.message, reply.len)
-              << std::endl;
-  }
-
-  // Parse the record header
-  event_record.type = reply.type;
-  boost::string_ref message_view(reply.message,
-                                 static_cast<unsigned int>(reply.len));
-
-  auto preamble_end = message_view.find("): ");
-  if (preamble_end == std::string::npos) {
-    return false;
-  }
-
-  event_record.time =
-      tryTo<unsigned long int>(message_view.substr(6, 10).to_string(), 10)
-          .takeOr(event_record.time);
-  event_record.audit_id = message_view.substr(6, preamble_end - 6).to_string();
-
-  // SELinux doesn't output valid audit records; just save them as they are
-  if (IsSELinuxRecord(reply)) {
-    event_record.raw_data = reply.message;
-    return true;
-  }
-
-  // Tokenize the message
-  boost::string_ref field_view(message_view.substr(preamble_end + 3));
-
-  // The linear search will construct series of key value pairs.
-  std::string key, value;
-  key.reserve(20);
-  value.reserve(256);
-
-  // There are several ways of representing value data (enclosed strings,
-  // etc).
-  bool found_assignment{false};
-  bool found_enclose{false};
-
-  for (const auto& c : field_view) {
-    // Iterate over each character in the audit message.
-    if ((found_enclose && c == '"') || (!found_enclose && c == ' ')) {
-      if (c == '"') {
-        value += c;
-      }
-
-      // This is a terminating sequence, the end of an enclosure or space
-      // tok.
-      if (!key.empty()) {
-        // Multiple space tokens are supported.
-        event_record.fields.emplace(
-            std::make_pair(std::move(key), std::move(value)));
-      }
-
-      found_enclose = false;
-      found_assignment = false;
-
-      key.clear();
-      value.clear();
-
-    } else if (!found_assignment && c == ' ') {
-      // A field tokenizer.
-
-    } else if (found_assignment) {
-      // Enclosure sequences appear immediately following assignment.
-      if (c == '"') {
-        found_enclose = true;
-      }
-
-      value += c;
-
-    } else if (c == '=') {
-      found_assignment = true;
-
-    } else {
-      key += c;
-    }
-  }
-
-  // Last step, if there was no trailing tokenizer.
-  if (!key.empty()) {
-    event_record.fields.emplace(
-        std::make_pair(std::move(key), std::move(value)));
-  }
-
-  return true;
-}
-
-void AuditdNetlinkParser::AdjustAuditReply(audit_reply& reply) noexcept {
-  reply.type = reply.msg.nlh.nlmsg_type;
-  reply.len = reply.msg.nlh.nlmsg_len;
-  reply.nlh = &reply.msg.nlh;
-
-  reply.status = nullptr;
-  reply.ruledata = nullptr;
-  reply.login = nullptr;
-  reply.message = nullptr;
-  reply.error = nullptr;
-  reply.signal_info = nullptr;
-  reply.conf = nullptr;
-
-  switch (reply.type) {
-  case NLMSG_ERROR: {
-    reply.error = static_cast<struct nlmsgerr*>(NLMSG_DATA(reply.nlh));
-    break;
-  }
-
-  case AUDIT_LIST_RULES: {
-    reply.ruledata =
-        static_cast<struct audit_rule_data*>(NLMSG_DATA(reply.nlh));
-    break;
-  }
-
-  case AUDIT_USER:
-  case AUDIT_LOGIN:
-  case AUDIT_KERNEL:
-  case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
-  case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
-  case AUDIT_FIRST_EVENT ... AUDIT_INTEGRITY_LAST_MSG: {
-    reply.message = static_cast<char*>(NLMSG_DATA(reply.nlh));
-    break;
-  }
-
-  case AUDIT_SIGNAL_INFO: {
-    reply.signal_info = static_cast<audit_sig_info*>(NLMSG_DATA(reply.nlh));
-    break;
-  }
-
-  default:
-    break;
-  }
-}
-} // namespace osquery
diff --git a/src/osquery/events/linux/auditdnetlink.h b/src/osquery/events/linux/auditdnetlink.h
deleted file mode 100644 (file)
index 4476cc3..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <libaudit.h>
-
-#include <atomic>
-#include <condition_variable>
-#include <future>
-#include <map>
-#include <memory>
-#include <set>
-#include <unordered_map>
-#include <vector>
-
-#include <boost/algorithm/hex.hpp>
-
-#include <osquery/dispatcher.h>
-
-namespace osquery {
-
-/// Netlink status, used by AuditNetlink::acquireHandle()
-enum class NetlinkStatus { ActiveMutable, ActiveImmutable, Disabled, Error };
-
-/// Contains an audit_rule_data structure
-using AuditRuleDataObject = std::vector<std::uint8_t>;
-
-/// A single, prepared audit event record.
-struct AuditEventRecord final {
-  /// Record type (i.e.: AUDIT_SYSCALL, AUDIT_PATH, ...)
-  int type;
-
-  /// Event time.
-  unsigned long int time;
-
-  /// Audit event id that owns this record. Remember: PRIMARY KEY(id, timestamp)
-  std::string audit_id;
-
-  /// The field list for this record. Valid for everything except SELinux
-  /// records
-  std::map<std::string, std::string> fields;
-
-  /// The raw message, only valid for SELinux records (because they have broken
-  /// syntax)
-  std::string raw_data;
-};
-
-static_assert(std::is_move_constructible<AuditEventRecord>::value,
-              "not move constructible");
-
-// This structure is used to share data between the reading and processing
-// services
-struct AuditdContext final {
-  /// Unprocessed audit records
-  std::vector<audit_reply> unprocessed_records;
-  static_assert(
-      std::is_move_constructible<decltype(unprocessed_records)>::value,
-      "not move constructible");
-
-  /// Mutex for the list of unprocessed records
-  std::mutex unprocessed_records_mutex;
-
-  /// Processed events condition variable
-  std::condition_variable unprocessed_records_cv;
-
-  /// This queue contains processed events
-  std::vector<AuditEventRecord> processed_events;
-
-  /// Processed events queue mutex.
-  std::mutex processed_events_mutex;
-
-  /// Used to wake up the thread that processes the raw audit records
-  std::condition_variable processed_records_cv;
-
-  /// When set to true, the audit handle is (re)acquired
-  std::atomic_bool acquire_handle{true};
-};
-
-using AuditdContextRef = std::shared_ptr<AuditdContext>;
-
-/// This is the service responsible for reading data from the audit netlink
-class AuditdNetlinkReader final : public InternalRunnable {
- public:
-  explicit AuditdNetlinkReader(AuditdContextRef context);
-
- protected:
-  virtual void start() override;
-  virtual void stop() override;
-
- private:
-  /// Reads as many audit event records as possible before returning.
-  bool acquireMessages() noexcept;
-
-  /// Configures the audit service and applies required rules
-  bool configureAuditService() noexcept;
-
-  /// Clears out the audit configuration
-  bool clearAuditConfiguration() noexcept;
-
-  /// Deletes the given audit rule
-  bool deleteAuditRule(const AuditRuleDataObject& rule_object);
-
-  /// Removes the rules that we have applied
-  void restoreAuditServiceConfiguration() noexcept;
-
-  /// (Re)acquire the netlink handle.
-  NetlinkStatus acquireHandle() noexcept;
-
- private:
-  /// Shared data
-  AuditdContextRef auditd_context_;
-
-  /// Read buffer used when receiving events from the netlink
-  std::vector<audit_reply> read_buffer_;
-
-  /// The set of rules we applied (and that we'll uninstall when exiting)
-  std::vector<audit_rule_data> installed_rule_list_;
-
-  /// The syscalls we are listening for
-  std::set<int> monitored_syscall_list_;
-
-  /// Netlink handle.
-  int audit_netlink_handle_{-1};
-};
-
-/// This service parses the raw audit records
-class AuditdNetlinkParser final : public InternalRunnable {
- public:
-  explicit AuditdNetlinkParser(AuditdContextRef context);
-  virtual void start() override;
-
-  /// Parses an audit_reply structure into an AuditEventRecord object
-  static bool ParseAuditReply(const audit_reply& reply,
-                              AuditEventRecord& event_record) noexcept;
-
-  /// Adjusts the internal pointers of the audit_reply object
-  static void AdjustAuditReply(audit_reply& reply) noexcept;
-
- private:
-  /// Shared data
-  AuditdContextRef auditd_context_;
-};
-
-/// This class provides access to the audit netlink data
-class AuditdNetlink final : private boost::noncopyable {
- public:
-  AuditdNetlink();
-  virtual ~AuditdNetlink() = default;
-
-  /// Prepares the raw audit event records stored in the given context.
-  std::vector<AuditEventRecord> getEvents() noexcept;
-
- private:
-  /// Shared data
-  AuditdContextRef auditd_context_;
-};
-
-/// Handle quote and hex-encoded audit field content.
-inline std::string DecodeAuditPathValues(const std::string& s) {
-  if (s.size() > 1 && s[0] == '"') {
-    return s.substr(1, s.size() - 2);
-  }
-
-  try {
-    return boost::algorithm::unhex(s);
-  } catch (const boost::algorithm::hex_decode_error& e) {
-    return s;
-  }
-}
-} // namespace osquery
diff --git a/src/osquery/events/linux/auditeventpublisher.cpp b/src/osquery/events/linux/auditeventpublisher.cpp
deleted file mode 100644 (file)
index 50cc01d..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <array>
-
-#include <osquery/events/linux/auditeventpublisher.h>
-#include <osquery/events/linux/selinux_events.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/utils/conversions/tryto.h>
-
-namespace osquery {
-/// The audit subsystem may have a performance impact on the system.
-FLAG(bool,
-     disable_audit,
-     true,
-     "Disable receiving events from the audit subsystem");
-
-// External flags; they are used to determine whether we should run or not
-DECLARE_bool(audit_allow_fim_events);
-DECLARE_bool(audit_allow_process_events);
-DECLARE_bool(audit_allow_sockets);
-DECLARE_bool(audit_allow_user_events);
-DECLARE_bool(audit_allow_selinux_events);
-
-REGISTER(AuditEventPublisher, "event_publisher", "auditeventpublisher");
-
-namespace {
-bool IsPublisherEnabled() noexcept {
-  if (FLAGS_disable_audit) {
-    return false;
-  }
-
-  return (FLAGS_audit_allow_fim_events || FLAGS_audit_allow_process_events ||
-          FLAGS_audit_allow_sockets || FLAGS_audit_allow_user_events ||
-          FLAGS_audit_allow_selinux_events);
-}
-} // namespace
-
-std::string AuditEventPublisher::executable_path_;
-
-Status AuditEventPublisher::setUp() {
-  if (!IsPublisherEnabled()) {
-    return Status(1, "Publisher disabled via configuration");
-  }
-
-  if (executable_path_.empty()) {
-    char buffer[PATH_MAX] = {};
-    assert(readlink("/proc/self/exe", buffer, sizeof(buffer)) != -1);
-    executable_path_ = buffer;
-  }
-
-  return Status::success();
-}
-
-void AuditEventPublisher::configure() {
-  if (!IsPublisherEnabled()) {
-    return;
-  }
-
-  if (audit_netlink_ == nullptr) {
-    audit_netlink_ = std::make_unique<AuditdNetlink>();
-  }
-}
-
-void AuditEventPublisher::tearDown() {
-  if (!IsPublisherEnabled()) {
-    return;
-  }
-
-  audit_netlink_.reset();
-}
-
-Status AuditEventPublisher::run() {
-  if (!IsPublisherEnabled()) {
-    return Status(1, "Publisher disabled via configuration");
-  }
-
-  auto audit_event_record_queue = audit_netlink_->getEvents();
-
-  auto event_context = createEventContext();
-
-  // This is a simple estimate based on the process_file_events_tests.cpp
-  // records
-  auto event_count_estimate = audit_event_record_queue.size() / 4U;
-  event_context->audit_events.reserve(event_count_estimate);
-
-  ProcessEvents(event_context, audit_event_record_queue, audit_trace_context_);
-  if (!event_context->audit_events.empty()) {
-    fire(event_context);
-  }
-
-  return Status::success();
-}
-
-void AuditEventPublisher::ProcessEvents(
-    AuditEventContextRef event_context,
-    const std::vector<AuditEventRecord>& record_list,
-    AuditTraceContext& trace_context) noexcept {
-  static const auto& selinux_event_set = kSELinuxEventList;
-
-  // Assemble each record into a AuditEvent object; multi-record events
-  // are complete when we receive the terminator (AUDIT_EOE)
-  for (const auto& audit_event_record : record_list) {
-    auto audit_event_it = trace_context.find(audit_event_record.audit_id);
-
-    // We have two entry points here; the first one is for user messages, while
-    // the second one is for syscalls
-    if (audit_event_record.type >= AUDIT_FIRST_USER_MSG &&
-        audit_event_record.type <= AUDIT_LAST_USER_MSG) {
-      UserAuditEventData data = {};
-      data.user_event_id = static_cast<std::uint64_t>(audit_event_record.type);
-
-      AuditEvent audit_event;
-      audit_event.type = AuditEvent::Type::UserEvent;
-      audit_event.record_list.push_back(std::move(audit_event_record));
-      audit_event.data = data;
-
-      event_context->audit_events.push_back(audit_event);
-
-      // SELinux events
-    } else if (selinux_event_set.find(audit_event_record.type) !=
-               selinux_event_set.end()) {
-      AuditEvent audit_event;
-      audit_event.type = AuditEvent::Type::SELinux;
-      audit_event.record_list.push_back(audit_event_record);
-
-      event_context->audit_events.push_back(audit_event);
-
-    } else if (audit_event_record.type == AUDIT_SYSCALL) {
-      if (audit_event_it != trace_context.end()) {
-        VLOG(1) << "Received a duplicated event.";
-        trace_context.erase(audit_event_it);
-      }
-
-      AuditEvent audit_event;
-      audit_event.type = AuditEvent::Type::Syscall;
-
-      // Estimate based on the process_file_events_tests.cpp records
-      audit_event.record_list.reserve(4U);
-
-      SyscallAuditEventData data;
-
-      std::string raw_executable_path;
-      if (!GetStringFieldFromMap(
-              raw_executable_path, audit_event_record.fields, "exe")) {
-        VLOG(1) << "Malformed AUDIT_SYSCALL record received. The "
-                   "executable path field is either missing or not valid.";
-
-        continue;
-      }
-
-      data.executable_path = DecodeAuditPathValues(raw_executable_path);
-
-      // Do not process events originated by the osquery watchdog or daemon
-      if (executable_path_ == data.executable_path) {
-        continue;
-      }
-
-      if (!GetIntegerFieldFromMap(
-              data.syscall_number, audit_event_record.fields, "syscall")) {
-        VLOG(1) << "Malformed AUDIT_SYSCALL record received. The "
-                   "syscall field "
-                   "is either missing or not valid.";
-
-        continue;
-      }
-
-      std::string syscall_status;
-      GetStringFieldFromMap(
-          syscall_status, audit_event_record.fields, "success", "yes");
-
-      // By discarding this event, we will also automatically discard any other
-      // attached record
-      if (syscall_status != "yes") {
-        continue;
-      }
-
-      std::uint64_t process_id;
-      if (!GetIntegerFieldFromMap(
-              process_id, audit_event_record.fields, "pid")) {
-        VLOG(1) << "Malformed AUDIT_SYSCALL record received. The process id "
-                   "field is either missing or not valid.";
-
-        continue;
-      }
-
-      std::uint64_t parent_process_id;
-      if (!GetIntegerFieldFromMap(
-              parent_process_id, audit_event_record.fields, "ppid")) {
-        VLOG(1) << "Malformed AUDIT_SYSCALL record received. The parent "
-                   "process id field is either missing or not valid.";
-
-        continue;
-      }
-
-      data.process_id = static_cast<pid_t>(process_id);
-      data.parent_process_id = static_cast<pid_t>(parent_process_id);
-      audit_event.data = data;
-
-      std::uint64_t process_uid;
-      if (!GetIntegerFieldFromMap(
-              process_uid, audit_event_record.fields, "uid")) {
-        VLOG(1) << "Missing or invalid uid field in AUDIT_SYSCALL";
-
-        continue;
-      }
-
-      std::uint64_t process_euid;
-      if (!GetIntegerFieldFromMap(
-              process_euid, audit_event_record.fields, "euid")) {
-        VLOG(1) << "Missing or invalid euid field in AUDIT_SYSCALL";
-
-        continue;
-      }
-
-      std::uint64_t process_gid;
-      if (!GetIntegerFieldFromMap(
-              process_gid, audit_event_record.fields, "gid")) {
-        VLOG(1) << "Missing or invalid gid field in AUDIT_SYSCALL";
-
-        continue;
-      }
-
-      std::uint64_t process_egid;
-      if (!GetIntegerFieldFromMap(
-              process_egid, audit_event_record.fields, "egid")) {
-        VLOG(1) << "Missing or invalid egid field in AUDIT_SYSCALL";
-
-        continue;
-      }
-
-      data.process_uid = static_cast<uid_t>(process_uid);
-      data.process_euid = static_cast<uid_t>(process_euid);
-      data.process_gid = static_cast<gid_t>(process_gid);
-      data.process_egid = static_cast<gid_t>(process_egid);
-
-      audit_event.record_list.push_back(audit_event_record);
-      trace_context[audit_event_record.audit_id] = std::move(audit_event);
-
-      // This is the terminator for multi-record audit events
-    } else if (audit_event_record.type == AUDIT_EOE) {
-      if (audit_event_it == trace_context.end()) {
-        continue;
-      }
-
-      auto completed_audit_event = audit_event_it->second;
-      trace_context.erase(audit_event_it);
-
-      event_context->audit_events.push_back(std::move(completed_audit_event));
-
-    } else {
-      if (audit_event_it == trace_context.end()) {
-        continue;
-      }
-
-      audit_event_it->second.record_list.push_back(audit_event_record);
-    }
-  }
-
-  // Drop events that are older than 5 minutes; it means that we have failed to
-  // receive the end of record and will never complete them correctly
-
-  std::time_t current_time;
-  std::time(&current_time);
-
-  std::unordered_map<std::string, std::time_t> timestamp_cache;
-
-  // The first part of the audit id is a timestamp: 1501323932.710:7670542
-  for (auto event_it = trace_context.begin();
-       event_it != trace_context.end();) {
-    const auto& audit_event_id = event_it->first;
-    std::time_t event_timestamp;
-
-    auto timestamp_it = timestamp_cache.find(audit_event_id);
-    if (timestamp_it == timestamp_cache.end()) {
-      std::string string_timestamp = audit_event_id.substr(0, 10);
-
-      event_timestamp = tryTo<long long>(string_timestamp).takeOr(0ll);
-
-      timestamp_cache[audit_event_id] = event_timestamp;
-
-    } else {
-      event_timestamp = timestamp_it->second;
-    }
-
-    if (current_time - event_timestamp >= 300) {
-      event_it = trace_context.erase(event_it);
-    } else {
-      event_it++;
-    }
-  }
-}
-
-const AuditEventRecord* GetEventRecord(const AuditEvent& event,
-                                       int record_type) noexcept {
-  auto it = std::find_if(event.record_list.begin(),
-                         event.record_list.end(),
-                         [record_type](const AuditEventRecord& record) -> bool {
-                           return (record.type == record_type);
-                         });
-
-  if (it == event.record_list.end()) {
-    return nullptr;
-  }
-
-  return &(*it);
-};
-
-bool GetStringFieldFromMap(std::string& value,
-                           const std::map<std::string, std::string>& fields,
-                           const std::string& name,
-                           const std::string& default_value) noexcept {
-  auto it = fields.find(name);
-  if (it == fields.end()) {
-    value = default_value;
-    return false;
-  }
-
-  value = it->second;
-  return true;
-}
-
-bool GetIntegerFieldFromMap(std::uint64_t& value,
-                            const std::map<std::string, std::string>& field_map,
-                            const std::string& field_name,
-                            std::size_t base,
-                            std::uint64_t default_value) noexcept {
-  std::string string_value;
-  if (!GetStringFieldFromMap(string_value, field_map, field_name, "")) {
-    value = default_value;
-    return false;
-  }
-  auto exp = tryTo<std::uint64_t>(string_value, base);
-  value = exp.takeOr(std::move(default_value));
-  return exp.isValue();
-}
-
-void CopyFieldFromMap(Row& row,
-                      const std::map<std::string, std::string>& fields,
-                      const std::string& name,
-                      const std::string& default_value) noexcept {
-  GetStringFieldFromMap(row[name], fields, name, default_value);
-}
-} // namespace osquery
diff --git a/src/osquery/events/linux/auditeventpublisher.h b/src/osquery/events/linux/auditeventpublisher.h
deleted file mode 100644 (file)
index 1e220b0..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <limits>
-#include <memory>
-
-#include <boost/variant.hpp>
-
-#include <osquery/events.h>
-#include <osquery/events/linux/auditdnetlink.h>
-
-namespace osquery {
-
-struct UserAuditEventData final {
-  std::uint64_t user_event_id;
-};
-
-struct SyscallAuditEventData final {
-  std::uint64_t syscall_number;
-
-  pid_t process_id;
-  pid_t parent_process_id;
-
-  uid_t process_uid;
-  uid_t process_euid;
-
-  gid_t process_gid;
-  gid_t process_egid;
-
-  std::string executable_path;
-};
-
-/// Audit event descriptor
-struct AuditEvent final {
-  enum class Type { UserEvent, Syscall, SELinux };
-
-  Type type;
-  boost::variant<UserAuditEventData, SyscallAuditEventData> data;
-
-  std::vector<AuditEventRecord> record_list;
-};
-
-/// Audit event pretty printer, used for the --audit_fim_debug flag
-std::ostream& operator<<(std::ostream& stream, const AuditEvent& audit_event);
-
-struct AuditSubscriptionContext final : public SubscriptionContext {
- private:
-  friend class AuditEventPublisher;
-};
-
-struct AuditEventContext final : public EventContext {
-  std::vector<AuditEvent> audit_events;
-};
-
-using AuditEventContextRef = std::shared_ptr<AuditEventContext>;
-using AuditSubscriptionContextRef = std::shared_ptr<AuditSubscriptionContext>;
-
-/// This type maps audit event id with the corresponding audit event object
-using AuditTraceContext = std::map<std::string, AuditEvent>;
-
-class AuditEventPublisher final
-    : public EventPublisher<AuditSubscriptionContext, AuditEventContext> {
-  DECLARE_PUBLISHER("auditeventpublisher");
-
- public:
-  Status setUp() override;
-  void configure() override;
-  void tearDown() override;
-  Status run() override;
-
-  virtual ~AuditEventPublisher() {
-    tearDown();
-  }
-
-  /// Executable path
-  static std::string executable_path_;
-
-  /// Aggregates raw event records into audit events
-  static void ProcessEvents(AuditEventContextRef event_context,
-                            const std::vector<AuditEventRecord>& record_list,
-                            AuditTraceContext& trace_context) noexcept;
-
- private:
-  /// Netlink reader
-  std::unique_ptr<AuditdNetlink> audit_netlink_;
-
-  /// This is where audit records are assembled
-  AuditTraceContext audit_trace_context_;
-};
-
-/// Extracts the specified audit event record from the given audit event
-const AuditEventRecord* GetEventRecord(const AuditEvent& event,
-                                       int record_type) noexcept;
-
-/// Extracts the specified string key from the given string map
-bool GetStringFieldFromMap(
-    std::string& value,
-    const std::map<std::string, std::string>& fields,
-    const std::string& name,
-    const std::string& default_value = std::string()) noexcept;
-
-/// Extracts the specified integer key from the given string map
-bool GetIntegerFieldFromMap(
-    std::uint64_t& value,
-    const std::map<std::string, std::string>& field_map,
-    const std::string& field_name,
-    std::size_t base = 10,
-    std::uint64_t default_value =
-        std::numeric_limits<std::uint64_t>::max()) noexcept;
-
-/// Copies a named field from the 'fields' map to the specified row
-void CopyFieldFromMap(
-    Row& row,
-    const std::map<std::string, std::string>& fields,
-    const std::string& name,
-    const std::string& default_value = std::string()) noexcept;
-} // namespace osquery
diff --git a/src/osquery/events/linux/inotify.cpp b/src/osquery/events/linux/inotify.cpp
deleted file mode 100644 (file)
index 0705b07..0000000
+++ /dev/null
@@ -1,468 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <sstream>
-
-#include <fnmatch.h>
-#include <linux/limits.h>
-#include <poll.h>
-
-#include <boost/filesystem.hpp>
-
-#include <osquery/config/config.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/utils/system/time.h>
-
-#include "osquery/events/linux/inotify.h"
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-static const size_t kINotifyMaxEvents = 512;
-static const size_t kINotifyEventSize =
-    sizeof(struct inotify_event) + (NAME_MAX + 1);
-static const size_t kINotifyBufferSize =
-    (kINotifyMaxEvents * kINotifyEventSize);
-
-std::map<int, std::string> kMaskActions = {
-    {IN_ACCESS, "ACCESSED"},
-    {IN_ATTRIB, "ATTRIBUTES_MODIFIED"},
-    {IN_CLOSE_WRITE, "UPDATED"},
-    {IN_CREATE, "CREATED"},
-    {IN_DELETE, "DELETED"},
-    {IN_MODIFY, "UPDATED"},
-    {IN_MOVED_FROM, "MOVED_FROM"},
-    {IN_MOVED_TO, "MOVED_TO"},
-    {IN_OPEN, "OPENED"},
-};
-
-const uint32_t kFileDefaultMasks = IN_MOVED_TO | IN_MOVED_FROM | IN_MODIFY |
-                                   IN_DELETE | IN_CREATE | IN_CLOSE_WRITE |
-                                   IN_ATTRIB;
-const uint32_t kFileAccessMasks = IN_OPEN | IN_ACCESS;
-
-REGISTER(INotifyEventPublisher, "event_publisher", "inotify");
-
-Status INotifyEventPublisher::setUp() {
-  inotify_handle_ = ::inotify_init();
-  // If this does not work throw an exception.
-  if (inotify_handle_ == -1) {
-    return Status(1, "Could not start inotify: inotify_init failed");
-  }
-
-  WriteLock lock(scratch_mutex_);
-  scratch_ = (char*)malloc(kINotifyBufferSize);
-  if (scratch_ == nullptr) {
-    return Status(1, "Could not allocate scratch space");
-  }
-  return Status::success();
-}
-
-bool INotifyEventPublisher::needMonitoring(const std::string& path,
-                                           INotifySubscriptionContextRef& isc,
-                                           uint32_t mask,
-                                           bool recursive,
-                                           bool add_watch) {
-  bool rc = true;
-  struct stat file_dir_stat;
-  time_t sc_time = isc->path_sc_time_[path];
-
-  if (stat(path.c_str(), &file_dir_stat) == -1) {
-    LOG(WARNING) << "Failed to do stat on: " << path;
-    return false;
-  }
-
-  if (sc_time != file_dir_stat.st_ctime) {
-    if ((rc = addMonitor(path, isc, isc->mask, isc->recursive, add_watch))) {
-      isc->path_sc_time_[path] = file_dir_stat.st_ctime;
-    }
-  }
-  return rc;
-}
-
-bool INotifyEventPublisher::monitorSubscription(
-    INotifySubscriptionContextRef& sc, bool add_watch) {
-  std::string discovered = sc->path;
-  if (sc->path.find("**") != std::string::npos) {
-    sc->recursive = true;
-    discovered = sc->path.substr(0, sc->path.find("**"));
-    sc->path = discovered;
-  }
-
-  if (sc->path.find('*') != std::string::npos) {
-    // If the wildcard exists within the file (leaf), remove and monitor the
-    // directory instead. Apply a fnmatch on fired events to filter leafs.
-    auto fullpath = fs::path(sc->path);
-    if (fullpath.filename().string().find('*') != std::string::npos) {
-      discovered = fullpath.parent_path().string() + '/';
-    }
-
-    if (discovered.find('*') != std::string::npos) {
-      // If a wildcard exists within the tree (stem), resolve at configure
-      // time and monitor each path.
-      std::vector<std::string> paths;
-      resolveFilePattern(discovered, paths);
-      sc->recursive_match = sc->recursive;
-      for (const auto& _path : paths) {
-        needMonitoring(_path, sc, sc->mask, sc->recursive, add_watch);
-      }
-      return true;
-    }
-  }
-
-  if (isDirectory(discovered) && discovered.back() != '/') {
-    sc->path += '/';
-    discovered += '/';
-  }
-
-  return needMonitoring(discovered, sc, sc->mask, sc->recursive, add_watch);
-}
-
-void INotifyEventPublisher::buildExcludePathsSet() {
-  auto parser = Config::getParser("file_paths");
-
-  WriteLock lock(subscription_lock_);
-  exclude_paths_.clear();
-
-  const auto& doc = parser->getData();
-  if (!doc.doc().HasMember("exclude_paths")) {
-    return;
-  }
-
-  for (const auto& category : doc.doc()["exclude_paths"].GetObject()) {
-    for (const auto& excl_path : category.value.GetArray()) {
-      std::string pattern = excl_path.GetString();
-      if (pattern.empty()) {
-        continue;
-      }
-      exclude_paths_.insert(pattern);
-    }
-  }
-}
-
-void INotifyEventPublisher::configure() {
-  if (inotify_handle_ == -1) {
-    // This publisher has not been setup correctly.
-    return;
-  }
-
-  SubscriptionVector delete_subscriptions;
-  {
-    WriteLock lock(subscription_lock_);
-    auto end = std::remove_if(
-        subscriptions_.begin(),
-        subscriptions_.end(),
-        [&delete_subscriptions](const SubscriptionRef& subscription) {
-          auto inotify_sc = getSubscriptionContext(subscription->context);
-          if (inotify_sc->mark_for_deletion == true) {
-            delete_subscriptions.push_back(subscription);
-            return true;
-          }
-          return false;
-        });
-    subscriptions_.erase(end, subscriptions_.end());
-  }
-
-  for (auto& sub : delete_subscriptions) {
-    auto ino_sc = getSubscriptionContext(sub->context);
-    for (const auto& path : ino_sc->descriptor_paths_) {
-      removeMonitor(path.first, true, true);
-    }
-    ino_sc->descriptor_paths_.clear();
-  }
-  delete_subscriptions.clear();
-
-  buildExcludePathsSet();
-
-  for (auto& sub : subscriptions_) {
-    // Anytime a configure is called, try to monitor all subscriptions.
-    // Configure is called as a response to removing/adding subscriptions.
-    // This means recalculating all monitored paths.
-    auto sc = getSubscriptionContext(sub->context);
-    monitorSubscription(sc);
-  }
-}
-
-void INotifyEventPublisher::tearDown() {
-  if (inotify_handle_ > -1) {
-    ::close(inotify_handle_);
-  }
-  inotify_handle_ = -1;
-
-  WriteLock lock(scratch_mutex_);
-  if (scratch_ != nullptr) {
-    free(scratch_);
-    scratch_ = nullptr;
-  }
-}
-
-void INotifyEventPublisher::handleOverflow() {
-  if (inotify_events_ < kINotifyMaxEvents) {
-    VLOG(1) << "inotify was overflown: increasing scratch buffer";
-    // Exponential increment.
-    inotify_events_ = inotify_events_ * 2;
-  } else if (last_overflow_ != -1 && getUnixTime() - last_overflow_ < 60) {
-    return;
-  } else {
-    VLOG(1) << "inotify was overflown";
-    last_overflow_ = getUnixTime();
-  }
-}
-
-Status INotifyEventPublisher::run() {
-  struct pollfd fds[1];
-  fds[0].fd = getHandle();
-  fds[0].events = POLLIN;
-  int selector = ::poll(fds, 1, 1000);
-  if (selector == -1) {
-    if (errno == EINTR) {
-      return Status::success();
-    }
-    LOG(WARNING) << "Could not read inotify handle";
-    return Status(1, "inotify poll failed");
-  }
-
-  if (selector == 0) {
-    // Read timeout.
-    return Status::success();
-  }
-
-  if (!(fds[0].revents & POLLIN)) {
-    return Status::success();
-  }
-
-  WriteLock lock(scratch_mutex_);
-  ssize_t record_num =
-      ::read(getHandle(), scratch_, inotify_events_ * kINotifyEventSize);
-  if (record_num == 0 || record_num == -1) {
-    return Status(1, "INotify read failed");
-  }
-
-  for (char* p = scratch_; p < scratch_ + record_num;) {
-    // Cast the inotify struct, make shared pointer, and append to contexts.
-    auto event = reinterpret_cast<struct inotify_event*>(p);
-    if (event->mask & IN_Q_OVERFLOW) {
-      // The inotify queue was overflown (try to receive more events from OS).
-      handleOverflow();
-    } else if (event->mask & IN_IGNORED) {
-      // This inotify watch was removed.
-      removeMonitor(event->wd, false);
-    } else if (event->mask & IN_MOVE_SELF) {
-      // This inotify path was moved, but is still watched.
-      removeMonitor(event->wd, true);
-    } else if (event->mask & IN_DELETE_SELF) {
-      // A file was moved to replace the watched path.
-      removeMonitor(event->wd, false);
-    } else {
-      auto ec = createEventContextFrom(event);
-      if (!ec->action.empty()) {
-        fire(ec);
-      }
-    }
-    // Continue to iterate
-    p += (sizeof(struct inotify_event)) + event->len;
-  }
-
-  return Status::success();
-}
-
-INotifyEventContextRef INotifyEventPublisher::createEventContextFrom(
-    struct inotify_event* event) const {
-  auto ec = createEventContext();
-  ec->event = std::make_unique<struct inotify_event>(*event);
-
-  // Get the pathname the watch fired on.
-  {
-    WriteLock lock(path_mutex_);
-    if (descriptor_inosubctx_.find(event->wd) == descriptor_inosubctx_.end()) {
-      // return a blank event context if we can't find the paths for the event
-      return ec;
-    } else {
-      auto isc = descriptor_inosubctx_.at(event->wd);
-      ec->path = isc->descriptor_paths_.at(event->wd);
-      ec->isub_ctx = isc;
-    }
-  }
-
-  if (event->len > 1) {
-    ec->path += event->name;
-  }
-
-  for (const auto& action : kMaskActions) {
-    if (event->mask & action.first) {
-      ec->action = action.second;
-      break;
-    }
-  }
-  return ec;
-}
-
-bool INotifyEventPublisher::shouldFire(const INotifySubscriptionContextRef& sc,
-                                       const INotifyEventContextRef& ec) const {
-  if (sc.get() != ec->isub_ctx.get()) {
-    /// Not my event.
-    return false;
-  }
-
-  // The subscription may supply a required event mask.
-  if (sc->mask != 0 && !(ec->event->mask & sc->mask)) {
-    return false;
-  }
-
-  // inotify will not monitor recursively, new directories need watches.
-  if (sc->recursive && ec->action == "CREATED" && isDirectory(ec->path)) {
-    const_cast<INotifyEventPublisher*>(this)->addMonitor(
-        ec->path + '/',
-        const_cast<INotifySubscriptionContextRef&>(sc),
-        sc->mask,
-        true);
-  }
-
-  // exclude paths should be applied at last
-  auto path = ec->path.substr(0, ec->path.rfind('/'));
-  // Need to have two finds,
-  // what if somebody excluded an individual file inside a directory
-  if (!exclude_paths_.empty() &&
-      (exclude_paths_.find(path) || exclude_paths_.find(ec->path))) {
-    return false;
-  }
-
-  return true;
-}
-
-bool INotifyEventPublisher::addMonitor(const std::string& path,
-                                       INotifySubscriptionContextRef& isc,
-                                       uint32_t mask,
-                                       bool recursive,
-                                       bool add_watch) {
-  {
-    WriteLock lock(path_mutex_);
-    int watch = ::inotify_add_watch(
-        getHandle(), path.c_str(), ((mask == 0) ? kFileDefaultMasks : mask));
-    if (add_watch && watch == -1) {
-      LOG(WARNING) << "Could not add inotify watch on: " << path;
-      return false;
-    }
-
-    if (descriptor_inosubctx_.find(watch) != descriptor_inosubctx_.end()) {
-      auto ino_sc = descriptor_inosubctx_.at(watch);
-      if (inotify_sanity_check) {
-        std::string watched_path = ino_sc->descriptor_paths_[watch];
-        path_descriptors_.erase(watched_path);
-      }
-      ino_sc->descriptor_paths_.erase(watch);
-      descriptor_inosubctx_.erase(watch);
-    }
-
-    // Keep a map of (descriptor -> path)
-    isc->descriptor_paths_[watch] = path;
-    descriptor_inosubctx_[watch] = isc;
-    if (inotify_sanity_check) {
-      // Keep a map of the path -> watch descriptor
-      path_descriptors_[path] = watch;
-    }
-  }
-
-  if (recursive && isDirectory(path).ok()) {
-    std::vector<std::string> children;
-    // Get a list of children of this directory (requested recursive watches).
-    listDirectoriesInDirectory(path, children, true);
-
-    boost::system::error_code ec;
-    for (const auto& child : children) {
-      auto canonicalized = fs::canonical(child, ec).string() + '/';
-      addMonitor(canonicalized, isc, mask, false);
-    }
-  }
-
-  return true;
-}
-
-bool INotifyEventPublisher::removeMonitor(int watch,
-                                          bool force,
-                                          bool batch_del) {
-  {
-    WriteLock lock(path_mutex_);
-    if (descriptor_inosubctx_.find(watch) == descriptor_inosubctx_.end()) {
-      return false;
-    }
-
-    auto isc = descriptor_inosubctx_.at(watch);
-    descriptor_inosubctx_.erase(watch);
-
-    if (inotify_sanity_check) {
-      std::string watched_path = isc->descriptor_paths_[watch];
-      path_descriptors_.erase(watched_path);
-    }
-
-    if (!batch_del) {
-      isc->descriptor_paths_.erase(watch);
-    }
-  }
-
-  if (force) {
-    ::inotify_rm_watch(getHandle(), watch);
-  }
-
-  return true;
-}
-
-void INotifyEventPublisher::removeSubscriptions(const std::string& subscriber) {
-  WriteLock lock(subscription_lock_);
-  std::for_each(subscriptions_.begin(),
-                subscriptions_.end(),
-                [&subscriber](const SubscriptionRef& sub) {
-                  if (sub->subscriber_name == subscriber) {
-                    getSubscriptionContext(sub->context)->mark_for_deletion =
-                        true;
-                  }
-                });
-}
-
-Status INotifyEventPublisher::addSubscription(
-    const SubscriptionRef& subscription) {
-  WriteLock lock(subscription_lock_);
-  auto received_inotify_sc = getSubscriptionContext(subscription->context);
-  for (auto& sub : subscriptions_) {
-    auto inotify_sc = getSubscriptionContext(sub->context);
-    if (*received_inotify_sc == *inotify_sc) {
-      if (inotify_sc->mark_for_deletion) {
-        inotify_sc->mark_for_deletion = false;
-        return Status(0);
-      }
-      // Returning non zero signals EventSubscriber::subscribe
-      // do not bump up subscription_count_.
-      return Status(1);
-    }
-  }
-
-  subscriptions_.push_back(subscription);
-  return Status(0);
-}
-
-bool INotifyEventPublisher::isPathMonitored(const std::string& path) const {
-  WriteLock lock(path_mutex_);
-  std::string parent_path;
-  if (!isDirectory(path).ok()) {
-    if (path_descriptors_.find(path) != path_descriptors_.end()) {
-      // Path is a file, and is directly monitored.
-      return true;
-    }
-    // Important to add a trailing "/" for inotify.
-    parent_path = fs::path(path).parent_path().string() + '/';
-  } else {
-    parent_path = path;
-  }
-  // Directory or parent of file monitoring
-  auto path_iterator = path_descriptors_.find(parent_path);
-  return (path_iterator != path_descriptors_.end());
-}
-}
diff --git a/src/osquery/events/linux/inotify.h b/src/osquery/events/linux/inotify.h
deleted file mode 100644 (file)
index c6abfe3..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <map>
-#include <vector>
-
-#include <sys/inotify.h>
-#include <sys/stat.h>
-
-#include <osquery/events.h>
-
-#include "osquery/events/pathset.h"
-
-namespace osquery {
-
-extern std::map<int, std::string> kMaskActions;
-
-extern const uint32_t kFileDefaultMasks;
-extern const uint32_t kFileAccessMasks;
-
-// INotifySubscriptionContext containers
-using PathDescriptorMap = std::map<std::string, int>;
-using DescriptorPathMap = std::map<int, std::string>;
-using PathStatusChangeTimeMap = std::map<std::string, time_t>;
-
-/**
- * @brief Subscription details for INotifyEventPublisher events.
- *
- * This context is specific to INotifyEventPublisher. It allows the
- * subscribing EventSubscriber to set a path (file or directory) and a
- * limited action mask.
- * Events are passed to the EventSubscriber if they match the context
- * path (or anything within a directory if the path is a directory) and if the
- * event action is part of the mask. If the mask is 0 then all actions are
- * passed to the EventSubscriber.
- */
-struct INotifySubscriptionContext : public SubscriptionContext {
-  /// Subscription the following filesystem path.
-  std::string path;
-
-  /// original path, read from config
-  std::string opath;
-
-  /// Limit the `inotify` actions to the subscription mask (if not 0).
-  uint32_t mask{0};
-
-  /// Treat this path as a directory and subscription recursively.
-  bool recursive{false};
-
-  /// Save the category this path originated form within the config.
-  std::string category;
-
-  /// Lazy deletion of a subscription.
-  bool mark_for_deletion{false};
-
-  /**
-   * @brief Helper method to map a string action to `inotify` action mask bit.
-   *
-   * This helper method will set the `mask` value for this SubscriptionContext.
-   *
-   * @param action The string action, a value in kMaskAction%s.
-   */
-  void requireAction(const std::string& action) {
-    for (const auto& bit : kMaskActions) {
-      if (action == bit.second) {
-        mask = mask | bit.first;
-      }
-    }
-  }
-
- private:
-  /// A configure-time pattern was expanded to match absolute paths.
-  bool recursive_match{false};
-
-  /// Map of inotify watch file descriptor to watched path string.
-  DescriptorPathMap descriptor_paths_;
-
-  /// Map of path and status change time of file/directory.
-  PathStatusChangeTimeMap path_sc_time_;
-
- private:
-  friend class INotifyEventPublisher;
-};
-
-/// Overloaded '==' operator, to check if two inotify subscriptions are same.
-inline bool operator==(const INotifySubscriptionContext& lsc,
-                       const INotifySubscriptionContext& rsc) {
-  return ((lsc.category == rsc.category) && (lsc.opath == rsc.opath));
-}
-
-using INotifySubscriptionContextRef =
-    std::shared_ptr<INotifySubscriptionContext>;
-
-/**
- * @brief Event details for INotifyEventPublisher events.
- */
-struct INotifyEventContext : public EventContext {
-  /// The inotify_event structure if the EventSubscriber want to interact.
-  std::unique_ptr<struct inotify_event> event{nullptr};
-
-  /// A string path parsed from the inotify_event.
-  std::string path;
-
-  /// A string action representing the event action `inotify` bit.
-  std::string action;
-
-  /// A no-op event transaction id.
-  uint32_t transaction_id{0};
-
-  /// This event ctx belongs to isub_ctx
-  INotifySubscriptionContextRef isub_ctx;
-};
-
-using INotifyEventContextRef = std::shared_ptr<INotifyEventContext>;
-
-// Publisher container
-using DescriptorINotifySubCtxMap = std::map<int, INotifySubscriptionContextRef>;
-
-using ExcludePathSet = PathSet<patternedPath>;
-
-/**
- * @brief A Linux `inotify` EventPublisher.
- *
- * This EventPublisher allows EventSubscriber%s to subscription for Linux
- *`inotify` events.
- * Since these events are limited this EventPublisher will optimize the watch
- * descriptors, keep track of the usage, implement optimizations/priority
- * where possible, and abstract file system events to a path/action context.
- *
- * Uses INotifySubscriptionContext and INotifyEventContext for subscriptioning,
- *eventing.
- */
-class INotifyEventPublisher
-    : public EventPublisher<INotifySubscriptionContext, INotifyEventContext> {
-  DECLARE_PUBLISHER("inotify");
-
- public:
-  //@param unit_test publisher is instantiated for unit test.
-  INotifyEventPublisher(bool unit_test = false)
-      : inotify_sanity_check(unit_test) {}
-
-  virtual ~INotifyEventPublisher() {
-    tearDown();
-  }
-
-  /// Create an `inotify` handle descriptor.
-  Status setUp() override;
-
-  /// The configuration finished loading or was updated.
-  void configure() override;
-
-  /// Release the `inotify` handle descriptor.
-  void tearDown() override;
-
-  /// The calling for beginning the thread's run loop.
-  Status run() override;
-
-  /// Mark for delete, subscriptions.
-  void removeSubscriptions(const std::string& subscriber) override;
-
-  /// Only add the subscription, if it not already part of subscription list.
-  Status addSubscription(const SubscriptionRef& subscription) override;
-
- private:
-  /// Helper/specialized event context creation.
-  INotifyEventContextRef createEventContextFrom(
-      struct inotify_event* event) const;
-
-  /// Check if the application-global `inotify` handle is alive.
-  bool isHandleOpen() const {
-    return inotify_handle_ > 0;
-  }
-
-  /// Check all added Subscription%s for a path.
-  /// Used for sanity check from unit test(s).
-  bool isPathMonitored(const std::string& path) const;
-
-  /**
-   * @brief Add an INotify watch (monitor) on this path.
-   *
-   * Check if a given path is already monitored (perhaps the parent path) has
-   * and existing monitor and this is a non-directory leaf? On success the
-   * file descriptor is stored for lookup when events fire.
-   *
-   * A recursive flag will tell addMonitor to enumerate all subdirectories
-   * recursively and add monitors to them.
-   *
-   * @param path complete (non-glob) canonical path to monitor.
-   * @param subscription context tracking the path.
-   * @param recursive perform a single recursive search of subdirectories.
-   * @param add_watch (testing only) should an inotify watch be created.
-   * @return success if the inotify watch was created.
-   */
-  bool addMonitor(const std::string& path,
-                  INotifySubscriptionContextRef& isc,
-                  uint32_t mask,
-                  bool recursive,
-                  bool add_watch = true);
-
-  /**
-   * Some decision making code refactored in needMonitoring before calling
-   * addMonitor in the context of monitorSubscription.
-   * Decision to call addMonitor from the context of monitorSubscription
-   * is done based on the status change time of file/directory, since
-   * creation time is not available on linux.
-   */
-  bool needMonitoring(const std::string& path,
-                      INotifySubscriptionContextRef& isc,
-                      uint32_t mask,
-                      bool recursive,
-                      bool add_watch);
-
-  /// Helper method to parse a subscription and add an equivalent monitor.
-  bool monitorSubscription(INotifySubscriptionContextRef& sc,
-                           bool add_watch = true);
-
-  /// Build the set of excluded paths for which events are not to be propogated.
-  void buildExcludePathsSet();
-
-  /// Remove an INotify watch (monitor) from our tracking.
-  bool removeMonitor(int watch, bool force = false, bool batch_del = false);
-
-  /// Given a SubscriptionContext and INotifyEventContext match path and action.
-  bool shouldFire(const INotifySubscriptionContextRef& mc,
-                  const INotifyEventContextRef& ec) const override;
-
-  /// Get the INotify file descriptor.
-  int getHandle() const {
-    return inotify_handle_;
-  }
-
-  /// Get the number of actual INotify active descriptors.
-  size_t numDescriptors() const {
-    return descriptor_inosubctx_.size();
-  }
-
-  /// If we overflow, try to read more events from OS at time.
-  void handleOverflow();
-
-  /// Map of watched path string to inotify watch file descriptor.
-  /// Used for sanity check from unit test(s).
-  PathDescriptorMap path_descriptors_;
-
-  /// Map of inotify watch file descriptor to subscription context.
-  DescriptorINotifySubCtxMap descriptor_inosubctx_;
-
-  /// Events pertaining to these paths not to be propagated.
-  ExcludePathSet exclude_paths_;
-
-  /// The inotify file descriptor handle.
-  std::atomic<int> inotify_handle_{-1};
-
-  /// Time in seconds of the last inotify overflow.
-  std::atomic<int> last_overflow_{-1};
-
-  /// Tracks how many events to be received from OS.
-  size_t inotify_events_{16};
-
-  /// Enable for sanity check from unit test(s).
-  bool inotify_sanity_check{false};
-
-  /**
-   * @brief Scratch space for reading INotify responses.
-   *
-   * We place this here, and include a mutex to do heap/lazy allocation of the
-   * near-3k buffer when the publisher loads. This reduces the need to stack
-   * allocate a local buffer every 200mils and also improves the eventless-case.
-   *
-   * Allocated during setUp, removed in tearDown, protected by scratch_mutex_.
-   */
-  char* scratch_{nullptr};
-
-  /// Access to path and descriptor mappings.
-  mutable Mutex path_mutex_;
-
-  /// Access the Inofity response scratch space.
-  mutable Mutex scratch_mutex_;
-
- public:
-  friend class INotifyTests;
-  FRIEND_TEST(INotifyTests, test_inotify_init);
-  FRIEND_TEST(INotifyTests, test_inotify_optimization);
-  FRIEND_TEST(INotifyTests, DISABLED_test_inotify_recursion);
-  FRIEND_TEST(INotifyTests, test_inotify_match_subscription);
-  FRIEND_TEST(INotifyTests, test_inotify_embedded_wildcards);
-};
-}
diff --git a/src/osquery/events/linux/process_events.h b/src/osquery/events/linux/process_events.h
deleted file mode 100644 (file)
index f7ffaea..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <asm/unistd_64.h>
-
-#include <set>
-
-const std::set<int> kProcessEventsSyscalls = {
-  __NR_execve};
diff --git a/src/osquery/events/linux/process_file_events.h b/src/osquery/events/linux/process_file_events.h
deleted file mode 100644 (file)
index 171c8b7..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <asm/unistd_64.h>
-
-#include <set>
-
-const std::set<int> kProcessFileEventsSyscalls = {
-  __NR_linkat,
-  __NR_symlink,
-  __NR_symlinkat,
-  __NR_unlink,
-  __NR_unlinkat,
-  __NR_rename,
-  __NR_renameat,
-  __NR_renameat2,
-  __NR_creat,
-  __NR_mknod,
-  __NR_mknodat,
-  __NR_open,
-  __NR_openat,
-  __NR_open_by_handle_at,
-  __NR_name_to_handle_at,
-  __NR_close,
-  __NR_dup,
-  __NR_dup2,
-  __NR_dup3,
-  __NR_pread64,
-  __NR_preadv,
-  __NR_read,
-  __NR_readv,
-  __NR_mmap,
-  __NR_write,
-  __NR_writev,
-  __NR_pwrite64,
-  __NR_pwritev,
-  __NR_truncate,
-  __NR_ftruncate,
-  __NR_clone,
-  __NR_fork,
-  __NR_vfork};
diff --git a/src/osquery/events/linux/selinux_events.h b/src/osquery/events/linux/selinux_events.h
deleted file mode 100644 (file)
index 5f68b57..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <linux/audit.h>
-
-#include <set>
-#include <map>
-
-// This map must contain exactly the same elements that
-// SELinuxEventSubscriber::GetEventSet() returns!
-// clang-format off
-const std::map<int, std::string> kSELinuxRecordLabels = {
-  {AUDIT_USER_AVC, "USER_AVC"},
-  {AUDIT_AVC, "AVC"},
-  {AUDIT_SELINUX_ERR, "SELINUX_ERR"},
-  {AUDIT_AVC_PATH, "AVC_PATH"},
-  {AUDIT_MAC_POLICY_LOAD, "MAC_POLICY_LOAD"},
-  {AUDIT_MAC_STATUS, "MAC_STATUS"},
-  {AUDIT_MAC_CONFIG_CHANGE, "MAC_CONFIG_CHANGE"},
-  {AUDIT_MAC_UNLBL_ALLOW, "MAC_UNLBL_ALLOW"},
-  {AUDIT_MAC_CIPSOV4_ADD, "MAC_CIPSOV4_ADD"},
-  {AUDIT_MAC_CIPSOV4_DEL, "MAC_CIPSOV4_DEL"},
-  {AUDIT_MAC_MAP_ADD, "MAC_MAP_ADD"},
-  {AUDIT_MAC_MAP_DEL, "MAC_MAP_DEL"},
-  {AUDIT_MAC_IPSEC_ADDSA, "MAC_IPSEC_ADDSA"},
-  {AUDIT_MAC_IPSEC_DELSA, "MAC_IPSEC_DELSA"},
-  {AUDIT_MAC_IPSEC_ADDSPD, "MAC_IPSEC_ADDSPD"},
-  {AUDIT_MAC_IPSEC_DELSPD, "MAC_IPSEC_DELSPD"},
-  {AUDIT_MAC_IPSEC_EVENT, "MAC_IPSEC_EVENT"},
-  {AUDIT_MAC_UNLBL_STCADD, "MAC_UNLBL_STCADD"},
-  {AUDIT_MAC_UNLBL_STCDEL, "MAC_UNLBL_STCDEL"}
-};
-// clang-format on
-
-// Documented events that could not be found in the headers:
-// - USER_SELINUX_ERR
-// - USER_MAC_POLICY_LOAD
-// - USER_ROLE_CHANGE
-// - USER_LABEL_EXPORT
-const std::set<int> kSELinuxEventList = {
-    // This is outside the documented numeric range (1400-1499)
-    AUDIT_USER_AVC,
-
-    AUDIT_AVC,
-    AUDIT_SELINUX_ERR,
-    AUDIT_AVC_PATH,
-    AUDIT_MAC_POLICY_LOAD,
-    AUDIT_MAC_STATUS,
-    AUDIT_MAC_CONFIG_CHANGE,
-    AUDIT_MAC_UNLBL_ALLOW,
-    AUDIT_MAC_CIPSOV4_ADD,
-    AUDIT_MAC_CIPSOV4_DEL,
-    AUDIT_MAC_MAP_ADD,
-    AUDIT_MAC_MAP_DEL,
-    AUDIT_MAC_IPSEC_ADDSA,
-    AUDIT_MAC_IPSEC_DELSA,
-    AUDIT_MAC_IPSEC_ADDSPD,
-    AUDIT_MAC_IPSEC_DELSPD,
-    AUDIT_MAC_IPSEC_EVENT,
-    AUDIT_MAC_UNLBL_STCADD,
-    AUDIT_MAC_UNLBL_STCDEL};
diff --git a/src/osquery/events/linux/socket_events.h b/src/osquery/events/linux/socket_events.h
deleted file mode 100644 (file)
index cb5303f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <asm/unistd_64.h>
-
-#include <set>
-
-const std::set<int> kSocketEventsSyscalls = {
-  __NR_bind,
-  __NR_connect};
diff --git a/src/osquery/events/linux/syslog.cpp b/src/osquery/events/linux/syslog.cpp
deleted file mode 100644 (file)
index 6ffd656..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <fcntl.h>
-#include <grp.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <istream>
-#include <string>
-
-#include <boost/algorithm/string/trim.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/property_tree/json_parser.hpp>
-#include <boost/tokenizer.hpp>
-#include <osquery/registry_factory.h>
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-
-#include "osquery/events/linux/syslog.h"
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-FLAG(bool, enable_syslog, false, "Enable the syslog ingestion event publisher");
-
-FLAG(string,
-     syslog_pipe_path,
-     "/var/osquery/syslog_pipe",
-     "Path to the named pipe used for forwarding rsyslog events");
-
-FLAG(uint64,
-     syslog_rate_limit,
-     100,
-     "Maximum number of logs to ingest per run (~200ms between runs)");
-
-REGISTER(SyslogEventPublisher, "event_publisher", "syslog");
-
-// rsyslog needs read/write access, osquery process needs read access
-const mode_t kPipeMode = 0460;
-const std::string kPipeGroupName = "syslog";
-const char* kTimeFormat = "%Y-%m-%dT%H:%M:%S";
-const std::vector<std::string> kCsvFields = {
-    "time", "host", "severity", "facility", "tag", "message"};
-const size_t kErrorThreshold = 10;
-
-Status SyslogEventPublisher::setUp() {
-  if (!FLAGS_enable_syslog) {
-    return Status(1, "Publisher disabled via configuration");
-  }
-
-  Status s;
-  if (!pathExists(FLAGS_syslog_pipe_path)) {
-    VLOG(1) << "Pipe does not exist: creating pipe " << FLAGS_syslog_pipe_path;
-    s = createPipe(FLAGS_syslog_pipe_path);
-    if (!s.ok()) {
-      LOG(WARNING) << RLOG(1964)
-                   << "Problems encountered creating pipe: " << s.getMessage();
-    }
-  }
-
-  fs::file_status file_status = fs::status(FLAGS_syslog_pipe_path);
-  if (file_status.type() != fs::fifo_file) {
-    return Status(1, "Not a FIFO file: " + FLAGS_syslog_pipe_path);
-  }
-
-  // Try to acquire a lock on the pipe, to make sure we're the only osquery
-  // related process reading from it.
-  s = lockPipe(FLAGS_syslog_pipe_path);
-  if (!s.ok()) {
-    return s;
-  }
-
-  // Opening with both flags appears to be the only way to open the pipe
-  // without blocking for a writer. We won't ever write to the pipe, but we
-  // don't want to block here and will instead block waiting for a read in the
-  // run() method
-  readStream_.open(FLAGS_syslog_pipe_path,
-                   std::ifstream::in | std::ifstream::out);
-  if (!readStream_.good()) {
-    return Status(1,
-                  "Error opening pipe for reading: " + FLAGS_syslog_pipe_path);
-  }
-  VLOG(1) << "Successfully opened pipe for syslog ingestion: "
-          << FLAGS_syslog_pipe_path;
-
-  return Status::success();
-}
-
-Status SyslogEventPublisher::createPipe(const std::string& path) {
-  if (mkfifo(FLAGS_syslog_pipe_path.c_str(), kPipeMode) != 0) {
-    return Status(1, "Error in mkfifo: " + std::string(strerror(errno)));
-  }
-
-  // Explicitly set the permissions since the umask will effect the
-  // permissions created by mkfifo
-  if (chmod(FLAGS_syslog_pipe_path.c_str(), kPipeMode) != 0) {
-    return Status(1, "Error in chmod: " + std::string(strerror(errno)));
-  }
-
-  // Try to set the group so that rsyslog will be able to write to the pipe
-  struct group* group = getgrnam(kPipeGroupName.c_str());
-  if (group == nullptr) {
-    VLOG(1) << "No group " << kPipeGroupName
-            << " found. Not changing group for the pipe.";
-    return Status::success();
-  }
-  if (chown(FLAGS_syslog_pipe_path.c_str(), -1, group->gr_gid) == -1) {
-    return Status(1,
-                  "Error in chown to group " + kPipeGroupName + ": " +
-                      std::string(strerror(errno)));
-  }
-  return Status::success();
-}
-
-Status SyslogEventPublisher::lockPipe(const std::string& path) {
-  lockFd_ = open(path.c_str(), O_NONBLOCK);
-  if (lockFd_ == -1) {
-    return Status(
-        1, "Error in open for locking pipe: " + std::string(strerror(errno)));
-  }
-  if (flock(lockFd_, LOCK_EX | LOCK_NB) != 0) {
-    close(lockFd_);
-    lockFd_ = -1;
-    return Status(
-        1, "Unable to acquire pipe lock: " + std::string(strerror(errno)));
-  }
-  return Status::success();
-}
-
-void SyslogEventPublisher::unlockPipe() {
-  if (lockFd_ != -1) {
-    if (flock(lockFd_, LOCK_UN) != 0) {
-      LOG(WARNING) << "Error unlocking pipe: " << std::string(strerror(errno));
-    }
-    close(lockFd_);
-    lockFd_ = -1;
-  }
-}
-
-Status SyslogEventPublisher::run() {
-  // This run function will be called by the event factory with ~100ms pause
-  // (see InterruptableRunnable::pause()) between runs. In case something goes
-  // weird and there is a huge amount of input, we limit how many logs we
-  // take in per run to avoid pegging the CPU.
-  for (size_t i = 0; i < FLAGS_syslog_rate_limit; ++i) {
-    if (readStream_.rdbuf()->in_avail() == 0) {
-      // If there is no pending data, we have flushed everything and can wait
-      // until the next time EventFactory calls run(). This also allows the
-      // thread to join when it is stopped by EventFactory.
-      return Status::success();
-    }
-    std::string line;
-    std::getline(readStream_, line);
-    auto ec = createEventContext();
-    Status status = populateEventContext(line, ec);
-    if (status.ok()) {
-      fire(ec);
-      if (errorCount_ > 0) {
-        --errorCount_;
-      }
-    } else {
-      LOG(ERROR) << status.getMessage() << " in line: " << line;
-      ++errorCount_;
-      if (errorCount_ >= kErrorThreshold) {
-        return Status(1, "Too many errors in syslog parsing.");
-      }
-    }
-  }
-  return Status::success();
-}
-
-void SyslogEventPublisher::tearDown() {
-  unlockPipe();
-}
-
-Status SyslogEventPublisher::populateEventContext(const std::string& line,
-                                                  SyslogEventContextRef& ec) {
-  boost::tokenizer<RsyslogCsvSeparator> tokenizer(line);
-  auto key = kCsvFields.begin();
-  for (std::string value : tokenizer) {
-    if (key == kCsvFields.end()) {
-      return Status(1, "Received more fields than expected");
-    }
-
-    boost::trim(value);
-    if (*key == "time") {
-      ec->fields["datetime"] = value;
-    } else if (*key == "tag" && !value.empty() && value.back() == ':') {
-      // rsyslog sends "tag" with a trailing colon that we don't need
-      ec->fields.emplace(*key, value.substr(0, value.size() - 1));
-    } else {
-      ec->fields.emplace(*key, value);
-    }
-    ++key;
-  }
-
-  if (key == kCsvFields.end()) {
-    return Status::success();
-  } else {
-    return Status(1, "Received fewer fields than expected");
-  }
-}
-
-bool SyslogEventPublisher::shouldFire(const SyslogSubscriptionContextRef& sc,
-                                      const SyslogEventContextRef& ec) const {
-  return true;
-}
-}
diff --git a/src/osquery/events/linux/syslog.h b/src/osquery/events/linux/syslog.h
deleted file mode 100644 (file)
index 3d4cb37..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <stdio.h>
-
-#include <fstream>
-#include <map>
-
-#include <osquery/events.h>
-
-namespace osquery {
-
-/**
- * @brief Subscription context for syslog events
- *
- * Currently there is no use for the subscription context, so this class
- * remains empty.
- */
-
-struct SyslogSubscriptionContext : public SubscriptionContext {
- private:
-  friend class SyslogEventPublisher;
-};
-
-/**
- * @brief Event details for SyslogEventPublisher events
- */
-struct SyslogEventContext : public EventContext {
-  /**
-   * @brief The syslog message tokenized into fields.
-   *
-   * Fields will be stripped of extra space
-   */
-  std::map<std::string, std::string> fields;
-};
-
-using SyslogEventContextRef = std::shared_ptr<SyslogEventContext>;
-using SyslogSubscriptionContextRef = std::shared_ptr<SyslogSubscriptionContext>;
-
-/**
- * @brief Event publisher for syslog lines forwarded through rsyslog
- *
- * This event publisher ingests JSON representations of syslog entries, and
- * publishes them to it's subscribers. In order for it to function properly,
- * rsyslog must be configured to forward JSON to a named pipe that this
- * publisher will read from.
- */
-class SyslogEventPublisher
-    : public EventPublisher<SyslogSubscriptionContext, SyslogEventContext> {
-  DECLARE_PUBLISHER("syslog");
-
- public:
-  Status setUp() override;
-
-  void configure() override {}
-
-  void tearDown() override;
-
-  Status run() override;
-
- public:
-  SyslogEventPublisher() : EventPublisher(), errorCount_(0), lockFd_(-1) {}
-
- private:
-  /// Apply normal subscription to event matching logic.
-  bool shouldFire(const SyslogSubscriptionContextRef& mc,
-                  const SyslogEventContextRef& ec) const override;
-
-  /**
-   * @brief Create the named pipe for log forwarding.
-   *
-   * Attempts to properly set the permissions so that rsyslog will be able to
-   * write logs to the pipe. If osquery is not running with the appropriate
-   * permissions, the named pipe permissions may have to be manually edited by
-   * the user in order for rsyslog to be able to write to it.
-   */
-  Status createPipe(const std::string& path);
-
-  /**
-   * @brief Attempt to lock the pipe for reading.
-   *
-   * We lock the pipe to ensure that (for example) a user opening osqueryi
-   * while osqueryd is running will not try to simultaneously read from the
-   * pipe and invalidate the reads from osqueryd. Only the first osquery
-   * process to successfully lock the pipe will be allowed to read.
-   *
-   * @param path Path to the file to lock.
-   * @return 0 if successful, nonzero if unable to lock the file.
-   */
-  Status lockPipe(const std::string& path);
-
-  /**
-   * @brief Attempt to unlock the pipe.
-   */
-  void unlockPipe();
-
-  /**
-   * @brief Populate the SyslogEventContext with the syslog JSON.
-   *
-   * Performs basic cleanup on the JSON data as it is populated into the
-   * context.
-   */
-  static Status populateEventContext(const std::string& line,
-                                     SyslogEventContextRef& ec);
-
-  /**
-   * @brief Input stream for reading from the pipe.
-   */
-  std::fstream readStream_;
-
-  /**
-   * @brief Counter used to shut down thread when too many errors occur.
-   *
-   * This counter is incremented when an error occurs, and decremented when a
-   * log line is processed successfully. If it goes over kErrorThreshold, the
-   * thread will return a nonzero status and stop, preventing us from flooding
-   * the logs when things are in a bad state.
-   */
-  size_t errorCount_;
-
-  /**
-   * @brief File descriptor used to lock the pipe for reading.
-   *
-   * This fd should not be used for reading from the pipe, instead use
-   * readStream_.
-   */
-  int lockFd_;
-
- private:
-  FRIEND_TEST(SyslogTests, test_populate_event_context);
-};
-
-/**
- * Boost TokenizerFunction functor for tokenizing rsyslog CSV data
- *
- * This functor is intended to be used with boost::tokenizer in order to
- * properly parse CSV data generated by rsyslog. The default
- * boost::escaped_list_separator provided with boost::tokenizer chokes on
- * rsyslog CSV output, because rsyslog escapes " with "", and also does not
- * escape backslashes. Our implementation closely follows the one provided with
- * Boost, but allows for the idiosyncrasies of rsyslog output and simplifies
- * the implementation for our limited use case.
- */
-class RsyslogCsvSeparator {
- public:
-  RsyslogCsvSeparator() : last_(false) {}
-
-  void reset() {
-    last_ = false;
-  }
-
-  template <typename InputIterator, typename Token>
-  bool operator()(InputIterator& next, InputIterator end, Token& tok) {
-    bool in_quote = false;
-    tok = Token();
-
-    if (next == end) {
-      if (last_) {
-        // The last character was a comma, so we got an empty field at the end
-        last_ = false;
-        return true;
-      } else {
-        return false;
-      }
-    }
-    last_ = false;
-    for (; next != end; ++next) {
-      if (*next == ',') {
-        if (!in_quote) {
-          ++next;
-          last_ = true;
-          return true;
-        } else {
-          tok += *next;
-        }
-      } else if (*next == '"') {
-        auto after = next + 1;
-        if (!in_quote) {
-          in_quote = true;
-        } else if (after != end && *after == '"') {
-          // rsyslog escapes " with "", so reverse this by inserting "
-          tok += "\"";
-          ++next;
-        } else {
-          in_quote = false;
-        }
-      } else {
-        tok += *next;
-      }
-    }
-    return true;
-  }
-
- private:
-  bool last_;
-};
-}
diff --git a/src/osquery/events/linux/udev.cpp b/src/osquery/events/linux/udev.cpp
deleted file mode 100644 (file)
index 3736283..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <poll.h>
-
-#include <osquery/events.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-
-#include "osquery/events/linux/udev.h"
-
-namespace osquery {
-
-static const int kUdevMLatency = 200;
-
-REGISTER(UdevEventPublisher, "event_publisher", "udev");
-
-Status UdevEventPublisher::setUp() {
-  // The Setup and Teardown workflows should be protected against races.
-  // Just in case let's protect the publisher's resources.
-  WriteLock lock(mutex_);
-
-  // Create the udev object.
-  handle_ = udev_new();
-  if (handle_ == nullptr) {
-    return Status(1, "Could not create udev object.");
-  }
-
-  // Set up the udev monitor before scanning/polling.
-  monitor_ = udev_monitor_new_from_netlink(handle_, "udev");
-  if (monitor_ == nullptr) {
-    udev_unref(handle_);
-    handle_ = nullptr;
-    return Status(1, "Could not create udev monitor.");
-  }
-
-  udev_monitor_enable_receiving(monitor_);
-  return Status::success();
-}
-
-void UdevEventPublisher::tearDown() {
-  WriteLock lock(mutex_);
-  if (monitor_ != nullptr) {
-    udev_monitor_unref(monitor_);
-    monitor_ = nullptr;
-  }
-
-  if (handle_ != nullptr) {
-    udev_unref(handle_);
-    handle_ = nullptr;
-  }
-}
-
-Status UdevEventPublisher::run() {
-  {
-    WriteLock lock(mutex_);
-    if (monitor_ == nullptr) {
-      return Status(1);
-    }
-    int fd = udev_monitor_get_fd(monitor_);
-    if (fd < 0) {
-      LOG(ERROR) << "Could not get udev monitor fd";
-      return Status::failure("udev monitor failed");
-    }
-
-    struct pollfd fds[1];
-    fds[0].fd = fd;
-    fds[0].events = POLLIN;
-
-    int selector = ::poll(fds, 1, 1000);
-    if (selector == -1 && errno != EINTR && errno != EAGAIN) {
-      LOG(ERROR) << "Could not read udev monitor";
-      return Status(1, "udev monitor failed.");
-    }
-
-    if (selector == 0 || !(fds[0].revents & POLLIN)) {
-      // Read timeout.
-      return Status::success();
-    }
-
-    struct udev_device* device = udev_monitor_receive_device(monitor_);
-    if (device == nullptr) {
-      LOG(ERROR) << "udev monitor returned invalid device";
-      return Status(1, "udev monitor failed.");
-    }
-
-    auto ec = createEventContextFrom(device);
-    fire(ec);
-
-    udev_device_unref(device);
-  }
-
-  pause(std::chrono::milliseconds(kUdevMLatency));
-  return Status::success();
-}
-
-std::string UdevEventPublisher::getValue(struct udev_device* device,
-                                         const std::string& property) {
-  auto value = udev_device_get_property_value(device, property.c_str());
-  if (value != nullptr) {
-    return std::string(value);
-  }
-  return "";
-}
-
-std::string UdevEventPublisher::getAttr(struct udev_device* device,
-                                        const std::string& attr) {
-  auto value = udev_device_get_sysattr_value(device, attr.c_str());
-  if (value != nullptr) {
-    return std::string(value);
-  }
-  return "";
-}
-
-UdevEventContextRef UdevEventPublisher::createEventContextFrom(
-    struct udev_device* device) {
-  auto ec = createEventContext();
-  ec->device = device;
-  // Map the action string to the eventing enum.
-  ec->action = UDEV_EVENT_ACTION_UNKNOWN;
-  ec->action_string = std::string(udev_device_get_action(device));
-  if (ec->action_string == "add") {
-    ec->action = UDEV_EVENT_ACTION_ADD;
-  } else if (ec->action_string == "remove") {
-    ec->action = UDEV_EVENT_ACTION_REMOVE;
-  } else if (ec->action_string == "change") {
-    ec->action = UDEV_EVENT_ACTION_CHANGE;
-  }
-
-  // Set the subscription-aware variables for the event.
-  auto value = udev_device_get_subsystem(device);
-  if (value != nullptr) {
-    ec->subsystem = std::string(value);
-  }
-
-  value = udev_device_get_devnode(device);
-  if (value != nullptr) {
-    ec->devnode = std::string(value);
-  }
-
-  value = udev_device_get_devtype(device);
-  if (value != nullptr) {
-    ec->devtype = std::string(value);
-  }
-
-  value = udev_device_get_driver(device);
-  if (value != nullptr) {
-    ec->driver = std::string(value);
-  }
-
-  return ec;
-}
-
-bool UdevEventPublisher::shouldFire(const UdevSubscriptionContextRef& sc,
-                                    const UdevEventContextRef& ec) const {
-  if (sc->action != UDEV_EVENT_ACTION_ALL) {
-    if (sc->action != ec->action) {
-      return false;
-    }
-  }
-
-  if (sc->subsystem.length() != 0 && sc->subsystem != ec->subsystem) {
-    return false;
-  } else if (sc->devnode.length() != 0 && sc->devnode != ec->devnode) {
-    return false;
-  } else if (sc->devtype.length() != 0 && sc->devtype != ec->devtype) {
-    return false;
-  } else if (sc->driver.length() != 0 && sc->driver != ec->driver) {
-    return false;
-  }
-
-  return true;
-}
-} // namespace osquery
diff --git a/src/osquery/events/linux/udev.h b/src/osquery/events/linux/udev.h
deleted file mode 100644 (file)
index 0fa295b..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <libudev.h>
-
-#include <osquery/events.h>
-#include <osquery/utils/status/status.h>
-
-namespace osquery {
-
-enum udev_event_action {
-  UDEV_EVENT_ACTION_ADD = 1,
-  UDEV_EVENT_ACTION_REMOVE = 2,
-  UDEV_EVENT_ACTION_CHANGE = 3,
-  UDEV_EVENT_ACTION_UNKNOWN = 4,
-
-  // Custom subscriber-only catch-all for actions.
-  UDEV_EVENT_ACTION_ALL = 10,
-};
-
-/**
- * @brief Subscriptioning details for UdevEventPublisher events.
- *
- */
-struct UdevSubscriptionContext : public SubscriptionContext {
-  /// The hardware event action, add/remove/change.
-  udev_event_action action;
-
-  /// Restrict to a specific subsystem.
-  std::string subsystem;
-
-  /// Restrict to a specific devnode.
-  std::string devnode;
-
-  /// Restrict to a specific devtype.
-  std::string devtype;
-
-  /// Limit to a specific driver name.
-  std::string driver;
-};
-
-/**
- * @brief Event details for UdevEventPublisher events.
- */
-struct UdevEventContext : public EventContext {
-  /// A pointer to the device object, most subscribers will only use device.
-  struct udev_device* device{nullptr};
-
-  /// The udev_event_action identifier.
-  udev_event_action action;
-
-  /// Action as a string (as given by udev).
-  std::string action_string;
-
-  std::string subsystem;
-  std::string devnode;
-  std::string devtype;
-  std::string driver;
-};
-
-using UdevEventContextRef = std::shared_ptr<UdevEventContext>;
-using UdevSubscriptionContextRef = std::shared_ptr<UdevSubscriptionContext>;
-
-/**
- * @brief A Linux `udev` EventPublisher.
- *
- */
-class UdevEventPublisher
-    : public EventPublisher<UdevSubscriptionContext, UdevEventContext> {
-  DECLARE_PUBLISHER("udev");
-
- public:
-  virtual ~UdevEventPublisher() {
-    tearDown();
-  }
-
-  Status setUp() override;
-
-  void tearDown() override;
-
-  Status run() override;
-
-  /**
-   * @brief Return a string representation of a udev property.
-   *
-   * @param device the udev device pointer.
-   * @param property the udev property identifier string.
-   * @return string representation of the property or empty if null.
-   */
-  static std::string getValue(struct udev_device* device,
-                              const std::string& property);
-
-  /**
-   * @brief Return a string representation of a udev system attribute.
-   *
-   * @param device the udev device pointer.
-   * @param property the udev system attribute identifier string.
-   * @return string representation of the attribute or empty if null.
-   */
-  static std::string getAttr(struct udev_device* device,
-                             const std::string& attr);
-
- private:
-  /// udev handle (socket descriptor contained within).
-  struct udev* handle_{nullptr};
-
-  /// udev monitor.
-  struct udev_monitor* monitor_{nullptr};
-
-  /// Protection around udev resources.
-  Mutex mutex_;
-
- private:
-  /// Check subscription details.
-  bool shouldFire(const UdevSubscriptionContextRef& mc,
-                  const UdevEventContextRef& ec) const override;
-
-  /// Helper function to create an EventContext using a udev_device pointer.
-  UdevEventContextRef createEventContextFrom(struct udev_device* device);
-};
-}
diff --git a/src/osquery/events/pathset.h b/src/osquery/events/pathset.h
deleted file mode 100644 (file)
index 538360c..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <mutex>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <boost/noncopyable.hpp>
-#include <boost/tokenizer.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-
-namespace osquery {
-
-/**
- * @brief multiset based implementation for path search.
- *
- * 'multiset' is used because with patterns we can serach for equivalent keys.
- * Since  '/This/Path/is' ~= '/This/Path/%' ~= '/This/Path/%%' (equivalent).
- *
- * multiset is protected by lock. It is threadsafe.
- *
- * PathSet can take any of the two policies -
- * 1. patternedPath - Path can contain pattern '%' and '%%'.
- *                    Path components containing only '%' and '%%' are supported
- *                    e.g. '/This/Path/%'.
- *                    Path components containing partial patterns are not
- *                    supported e.g. '/This/Path/xyz%' ('xyz%' will not be
- *                    treated as pattern).
- */
-template <typename PathType>
-class PathSet : private boost::noncopyable {
- public:
-  void insert(const std::string& str) {
-    auto pattern = str;
-    replaceGlobWildcards(pattern);
-    auto vpath = PathType::createVPath(pattern);
-
-    WriteLock lock(mset_lock_);
-    for (auto& path : vpath) {
-      paths_.insert(std::move(path));
-    }
-  }
-
-  bool find(const std::string& str) const {
-    auto path = PathType::createPath(str);
-
-    ReadLock lock(mset_lock_);
-    if (paths_.find(path) != paths_.end()) {
-      return true;
-    }
-    return false;
-  }
-
-  void clear() {
-    WriteLock lock(mset_lock_);
-    paths_.clear();
-  }
-
-  bool empty() const {
-    ReadLock lock(mset_lock_);
-    return paths_.empty();
-  }
-
- private:
-  typedef typename PathType::Path Path;
-  typedef typename PathType::Compare Compare;
-  std::multiset<Path, Compare> paths_;
-  mutable Mutex mset_lock_;
-};
-
-class patternedPath {
- public:
-  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
-  typedef std::vector<std::string> Path;
-  typedef std::vector<Path> VPath;
-  struct Compare {
-    bool operator()(const Path& lhs, const Path& rhs) const {
-      size_t psize = (lhs.size() < rhs.size()) ? lhs.size() : rhs.size();
-      unsigned ndx;
-      for (ndx = 0; ndx < psize; ++ndx) {
-        if (lhs[ndx] == "**" || rhs[ndx] == "**") {
-          return false;
-        }
-
-        if (lhs[ndx] == "*" || rhs[ndx] == "*") {
-          continue;
-        }
-
-        int rc = lhs[ndx].compare(rhs[ndx]);
-
-        if (rc > 0) {
-          return false;
-        }
-
-        if (rc < 0) {
-          return true;
-        }
-      }
-
-      if ((ndx == rhs.size() && rhs[ndx - 1] == "*") ||
-          (ndx == lhs.size() && lhs[ndx - 1] == "*")) {
-        return false;
-      }
-
-      return (lhs.size() < rhs.size());
-    }
-  };
-
-  static Path createPath(const std::string& str) {
-    boost::char_separator<char> sep{"/"};
-    tokenizer tokens(str, sep);
-    Path path;
-
-    if (str == "/") {
-      path.push_back("");
-    }
-
-    for (std::string component : tokens) {
-      path.push_back(std::move(component));
-    }
-    return path;
-  }
-
-  static VPath createVPath(const std::string& str) {
-    boost::char_separator<char> sep{"/"};
-    tokenizer tokens(str, sep);
-    VPath vpath;
-    Path path;
-
-    if (str == "/") {
-      path.push_back("");
-    }
-
-    for (std::string component : tokens) {
-      if (component == "**") {
-        vpath.push_back(path);
-        path.push_back(std::move(component));
-        break;
-      }
-      path.push_back(std::move(component));
-    }
-    vpath.push_back(std::move(path));
-    return vpath;
-  }
-};
-
-} // namespace osquery
diff --git a/src/osquery/events/tests/events_database_tests.cpp b/src/osquery/events/tests/events_database_tests.cpp
deleted file mode 100644 (file)
index a66d67c..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <memory>
-
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem/operations.hpp>
-
-#include <gtest/gtest.h>
-
-#include <osquery/core.h>
-#include <osquery/core/sql/row.h>
-#include <osquery/database.h>
-#include <osquery/events.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/system.h>
-#include <osquery/tables.h>
-#include <osquery/utils/system/time.h>
-
-namespace osquery {
-DECLARE_bool(disable_database);
-
-static TableRows genRows(EventSubscriberPlugin* sub) {
-  auto vtc = std::make_shared<VirtualTableContent>();
-  QueryContext context(vtc);
-  TableRows results;
-  return results;
-}
-
-DECLARE_uint64(events_expiry);
-DECLARE_uint64(events_max);
-DECLARE_bool(events_optimize);
-
-class EventsDatabaseTests : public ::testing::Test {
-  void SetUp() override {
-    registryAndPluginInit();
-
-    FLAGS_disable_database = true;
-    DatabasePlugin::setAllowOpen(true);
-    DatabasePlugin::initPlugin();
-
-    std::vector<std::string> event_keys;
-    scanDatabaseKeys(kEvents, event_keys);
-    for (const auto& key : event_keys) {
-      deleteDatabaseValue(kEvents, key);
-    }
-  }
-
-  void TearDown() override {
-    FLAGS_events_optimize = optimize_;
-  }
-
- private:
-  bool optimize_;
-};
-
-class DBFakeEventPublisher
-    : public EventPublisher<SubscriptionContext, EventContext> {
-  DECLARE_PUBLISHER("DBFakePublisher");
-};
-
-class DBFakeEventSubscriber : public EventSubscriber<DBFakeEventPublisher> {
- public:
-  DBFakeEventSubscriber() {
-    setName("DBFakeSubscriber");
-    setEventsMax(FLAGS_events_max);
-    setEventsExpiry(FLAGS_events_expiry);
-  }
-
-  /// Add num_of_events fake events at time t
-  Status testAdd(time_t t, size_t num_of_events = 1) {
-    auto indexes = getIndexes(0, t);
-    auto records = getRecords(indexes);
-    const size_t old_records_size = records.size();
-
-    Row r;
-    r["testing"] = "hello from space";
-    r["time"] = INTEGER(t);
-    r["uptime"] = INTEGER(10);
-
-    std::vector<Row> row_list;
-    for (size_t i = 0U; i < num_of_events; i++) {
-      row_list.push_back(r);
-    }
-
-    auto status = addBatch(row_list, t);
-    if (!status.ok()) {
-      return Status::failure(
-          "Failed to save the batch to the database, with error: " +
-          status.getMessage());
-    }
-
-    indexes = getIndexes(0, t);
-    records = getRecords(indexes);
-
-    if (records.size() != row_list.size() + old_records_size) {
-      return Status::failure("We expected " + std::to_string(row_list.size()) +
-                             " records but only " +
-                             std::to_string(records.size()) + " were found!");
-    }
-
-    return Status::success();
-  }
-
-  size_t getEventsMax() override {
-    return max_;
-  }
-
-  void setEventsMax(size_t max) {
-    max_ = max;
-  }
-
-  size_t getEventsExpiry() override {
-    return expiry_;
-  }
-
-  void setEventsExpiry(size_t expiry) {
-    expiry_ = expiry;
-  }
-
- private:
-  size_t max_;
-
-  size_t expiry_;
-};
-
-TEST_F(EventsDatabaseTests, test_event_module_id) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  sub->doNotExpire();
-
-  // Not normally available outside of EventSubscriber->Add().
-  auto event_id1 = sub->getEventID();
-  EXPECT_EQ(event_id1, "0000000001");
-  auto event_id2 = sub->getEventID();
-  EXPECT_EQ(event_id2, "0000000002");
-}
-
-TEST_F(EventsDatabaseTests, test_event_add) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(1);
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsDatabaseTests, test_event_add_batch) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(1, 10);
-  EXPECT_TRUE(status.ok()) << status.getMessage();
-}
-
-TEST_F(EventsDatabaseTests, test_record_indexing) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(2);
-  status = sub->testAdd(11);
-  status = sub->testAdd(61);
-  status = sub->testAdd((1 * 3600) + 1);
-  status = sub->testAdd((2 * 3600) + 1);
-
-  // An "all" range, will pick up everything in the largest index.
-  auto indexes = sub->getIndexes(0, 3 * 3600);
-  auto output = boost::algorithm::join(indexes, ", ");
-  EXPECT_EQ("60.0, 60.1, 60.60, 60.120", output);
-
-  // Restrict range to "most specific", which is an index by 10.
-  indexes = sub->getIndexes(0, 5);
-  output = boost::algorithm::join(indexes, ", ");
-  // The order 10, 0th index include results with t = [0, 10).
-  EXPECT_EQ("60.0", output);
-
-  // Add specific indexes to the upper bound.
-  status = sub->testAdd((2 * 3600) + 11);
-  status = sub->testAdd((2 * 3600) + 61);
-  indexes = sub->getIndexes(2 * 3600, (2 * 3600) + 62);
-  output = boost::algorithm::join(indexes, ", ");
-  EXPECT_EQ("60.120, 60.121", output);
-
-  // Request specific lower and upper bounding.
-  indexes = sub->getIndexes(2, (2 * 3600) + 62);
-  output = boost::algorithm::join(indexes, ", ");
-  EXPECT_EQ("60.0, 60.1, 60.60, 60.120, 60.121", output);
-}
-
-TEST_F(EventsDatabaseTests, test_record_range) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(1);
-  status = sub->testAdd(2);
-  status = sub->testAdd(11);
-  status = sub->testAdd(61);
-  status = sub->testAdd((1 * 3600) + 1);
-  status = sub->testAdd((2 * 3600) + 1);
-
-  // Search within a specific record range.
-  auto indexes = sub->getIndexes(0, 10);
-  EXPECT_EQ(1U, indexes.size());
-  auto records = sub->getRecords(indexes);
-  // This will return 3 results, ::get filters records by an absolute range.
-  EXPECT_EQ(3U, records.size()); // 1, 2, 11
-
-  // Search within a large bound.
-  indexes = sub->getIndexes(3, 3601);
-  // This will include the 0-10 bucket meaning 1, 2 will show up.
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(5U, records.size()); // 1, 2, 11, 61, 3601
-
-  // Get all of the records.
-  indexes = sub->getIndexes(0, 3 * 3600);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(6U, records.size()); // 1, 2, 11, 61, 3601, 7201
-
-  // stop = 0 is an alias for everything.
-  indexes = sub->getIndexes(0, 0);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(6U, records.size());
-
-  for (size_t j = 0; j < 30; j++) {
-    // 110 is 10 below an index (60.2).
-    sub->testAdd(110 + static_cast<int>(j));
-  }
-
-  indexes = sub->getIndexes(110, 0);
-  auto output = boost::algorithm::join(indexes, ", ");
-  EXPECT_EQ("60.1, 60.2, 60.60, 60.120", output);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(33U, records.size()); // (61) 110 - 139 + 3601, 7201
-}
-
-TEST_F(EventsDatabaseTests, test_record_corruption) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-
-  std::string corrupted_index = "60.25440186";
-  std::string key =
-      "records.DBFakePublisher.DBFakeSubscriber." + corrupted_index;
-  std::string value =
-      "0002985852:1526411162,0002985853:1526411162,00?\16?\bE/"
-      "?:1526411170,0002985912:1526411170,0002?\16?\bE/"
-      "?526411178,0002985921:1526411178,0002985922:1526411178";
-
-  // Set some corrupted values in the DB
-  auto s = setDatabaseValue(kEvents, key, value);
-  auto records = sub->getRecords({corrupted_index});
-
-  // We should gracefully skip over corrupted record entries
-  EXPECT_EQ(6U, records.size());
-}
-
-TEST_F(EventsDatabaseTests, test_record_expiration) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(1);
-  status = sub->testAdd(2);
-  status = sub->testAdd(11);
-  status = sub->testAdd(61);
-  status = sub->testAdd((1 * 3600) + 1);
-  status = sub->testAdd((2 * 3600) + 1);
-
-  // No expiration
-  auto indexes = sub->getIndexes(0, 5000);
-  auto records = sub->getRecords(indexes);
-  EXPECT_EQ(5U, records.size()); // 1, 2, 11, 61, 3601
-
-  sub->expire_events_ = true;
-  sub->expire_time_ = 10;
-  indexes = sub->getIndexes(0, 5000);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(3U, records.size()); // 11, 61, 3601
-
-  indexes = sub->getIndexes(0, 5000);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(3U, records.size()); // 11, 61, 3601
-
-  indexes = sub->getIndexes(0, 5000);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(3U, records.size()); // 11, 61, 3601
-
-  indexes = sub->getIndexes(0, 5000);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(3U, records.size()); // 11, 61, 3601
-
-  // Check that get/deletes did not act on cache.
-  // This implies that RocksDB is flushing the requested delete records.
-  sub->expire_time_ = 0;
-  indexes = sub->getIndexes(0, 5000);
-  records = sub->getRecords(indexes);
-  EXPECT_EQ(3U, records.size()); // 11, 61, 3601
-}
-
-TEST_F(EventsDatabaseTests, test_gentable) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  auto status = sub->testAdd(1);
-  status = sub->testAdd(2);
-  status = sub->testAdd(11);
-  status = sub->testAdd(61);
-  status = sub->testAdd((1 * 3600) + 1);
-  status = sub->testAdd((2 * 3600) + 1);
-
-  ASSERT_EQ(0U, sub->optimize_time_);
-  ASSERT_EQ(0U, sub->expire_time_);
-  ASSERT_EQ(0U, sub->min_expiration_);
-
-  auto t = getUnixTime();
-  sub->testAdd(t - 1);
-  sub->testAdd(t);
-  sub->testAdd(t + 1);
-
-  // Test the expire workflow by creating a short expiration time.
-  sub->setEventsExpiry(10);
-
-  std::vector<std::string> keys;
-  scanDatabaseKeys("events", keys);
-  // 9 data records, 1 eid counter, 3 indexes, 15 index records.
-  // Depending on the moment, an additional 3 indexes may be introduced.
-  EXPECT_LE(16U, keys.size());
-
-  // Perform a "select" equivalent.
-  auto results = genRows(sub.get());
-
-  // Expect all non-expired results: 11, +
-  EXPECT_EQ(9U, results.size());
-  // The expiration time is now - events_expiry +/ 60.
-  EXPECT_LT(t - (sub->getEventsExpiry() * 2), sub->expire_time_ + 60);
-  EXPECT_GT(t, sub->expire_time_);
-  // The optimize time will not be changed.
-  ASSERT_EQ(0U, sub->optimize_time_);
-
-  results = genRows(sub.get());
-  EXPECT_EQ(3U, results.size());
-
-  results = genRows(sub.get());
-  EXPECT_EQ(3U, results.size());
-
-  keys.clear();
-  scanDatabaseKeys("events", keys);
-  EXPECT_LE(6U, keys.size());
-}
-
-TEST_F(EventsDatabaseTests, test_optimize) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  for (size_t i = 800; i < 800 + 10; ++i) {
-    sub->testAdd(i);
-  }
-
-  // Lie about the tool type to enable optimizations.
-  auto default_type = kToolType;
-  kToolType = ToolType::DAEMON;
-  FLAGS_events_optimize = true;
-
-  // Must also define an executing query.
-  setDatabaseValue(kPersistentSettings, "", "events_db_test");
-
-  auto t = getUnixTime();
-  auto results = genRows(sub.get());
-  EXPECT_EQ(10U, results.size());
-  // Optimization will set the time NOW as the minimum event time.
-  // Thus it is not possible to set event in past.
-  EXPECT_GE(sub->optimize_time_ + 100, t);
-  EXPECT_LE(sub->optimize_time_ - 100, t);
-  // The last EID returned will also be stored for duplication checks.
-  EXPECT_EQ(10U, sub->optimize_eid_);
-
-  for (size_t i = t + 800; i < t + 800 + 10; ++i) {
-    sub->testAdd(i);
-  }
-
-  results = genRows(sub.get());
-  EXPECT_EQ(10U, results.size());
-
-  // The optimize time should have been written to the database.
-  // It should be the same as the current (relative) optimize time.
-  std::string content;
-  getDatabaseValue("events", "optimize.events_db_test", content);
-  EXPECT_EQ(std::to_string(sub->optimize_time_), content);
-
-  // Restore the tool type.
-  kToolType = default_type;
-}
-
-TEST_F(EventsDatabaseTests, test_expire_check) {
-  auto sub = std::make_shared<DBFakeEventSubscriber>();
-  // Set the max number of buffered events to something reasonably small.
-  sub->setEventsMax(50);
-  size_t t = 10000;
-
-  // We are still at the mercy of the opaque EVENTS_CHECKPOINT define.
-  for (size_t x = 0; x < 3; x++) {
-    size_t num_events = 256 * x;
-    for (size_t i = 0; i < num_events; i++) {
-      sub->testAdd(t++);
-    }
-
-    // Since events tests are dependent, expect 257 + 3 events.
-    auto results = genRows(sub.get());
-    if (x == 0) {
-      // The first iteration is dependent on previous test state.
-      continue;
-    }
-
-    // The number of events should remain constant.
-    // In practice there may be an event still in the write queue.
-    EXPECT_LT(results.size(), 60U);
-  }
-
-  // Try again, this time with a scan
-  for (size_t k = 0; k < 3; k++) {
-    for (size_t x = 0; x < 3; x++) {
-      size_t num_events = 256 * x;
-      for (size_t i = 0; i < num_events; i++) {
-        sub->testAdd(t++);
-      }
-
-      // Records hold the event_id + time indexes.
-      // Data hosts the event_id + JSON content.
-      auto record_key = "records." + sub->dbNamespace();
-      auto data_key = "data." + sub->dbNamespace();
-
-      std::vector<std::string> records, datas;
-      scanDatabaseKeys(kEvents, records, record_key);
-      scanDatabaseKeys(kEvents, datas, data_key);
-
-      EXPECT_LT(records.size(), 20U);
-      EXPECT_LT(datas.size(), 60U);
-    }
-  }
-}
-} // namespace osquery
diff --git a/src/osquery/events/tests/events_tests.cpp b/src/osquery/events/tests/events_tests.cpp
deleted file mode 100644 (file)
index 5341a15..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <boost/filesystem/operations.hpp>
-
-#include <gflags/gflags.h>
-#include <gtest/gtest.h>
-
-#include <osquery/database.h>
-#include <osquery/events.h>
-#include <osquery/registry_factory.h>
-#include <osquery/tables.h>
-#include <osquery/utils/info/tool_type.h>
-
-namespace osquery {
-DECLARE_bool(disable_database);
-
-class EventsTests : public ::testing::Test {
- protected:
-  void SetUp() override {
-    kToolType = ToolType::TEST;
-    registryAndPluginInit();
-
-    // Force registry to use ephemeral database plugin
-    FLAGS_disable_database = true;
-    DatabasePlugin::setAllowOpen(true);
-    DatabasePlugin::initPlugin();
-
-    RegistryFactory::get().registry("config_parser")->setUp();
-  }
-  void TearDown() override {
-    EventFactory::end(true);
-  }
-};
-
-// The most basic event publisher uses useless Subscription/Event.
-class BasicEventPublisher
-    : public EventPublisher<SubscriptionContext, EventContext> {};
-
-class AnotherBasicEventPublisher
-    : public EventPublisher<SubscriptionContext, EventContext> {};
-
-// Create some semi-useless subscription and event structures.
-struct FakeSubscriptionContext : SubscriptionContext {
-  int require_this_value;
-};
-
-struct FakeEventContext : EventContext {
-  int required_value;
-};
-
-// Typedef the shared_ptr accessors.
-using FakeSubscriptionContextRef = std::shared_ptr<FakeSubscriptionContext>;
-using FakeEventContextRef = std::shared_ptr<FakeEventContext>;
-
-// Now a publisher with a type.
-class FakeEventPublisher
-    : public EventPublisher<FakeSubscriptionContext, FakeEventContext> {
-  DECLARE_PUBLISHER("FakePublisher");
-};
-
-class AnotherFakeEventPublisher
-    : public EventPublisher<FakeSubscriptionContext, FakeEventContext> {
-  DECLARE_PUBLISHER("AnotherFakePublisher");
-};
-
-TEST_F(EventsTests, test_event_publisher) {
-  auto pub = std::make_shared<FakeEventPublisher>();
-  EXPECT_EQ(pub->type(), "FakePublisher");
-
-  // Test type names.
-  auto pub_sub = pub->createSubscriptionContext();
-  EXPECT_EQ(typeid(FakeSubscriptionContext), typeid(*pub_sub));
-}
-
-TEST_F(EventsTests, test_register_event_publisher) {
-  auto basic_pub = std::make_shared<BasicEventPublisher>();
-  auto status = EventFactory::registerEventPublisher(basic_pub);
-  EXPECT_FALSE(status.ok());
-
-  // Set a name for the publisher, which becomes the type by default.
-  basic_pub->setName("BasicPublisher");
-  status = EventFactory::registerEventPublisher(basic_pub);
-  EXPECT_TRUE(status.ok());
-
-  // This class is the SAME, there was no type override.
-  auto another_basic_pub = std::make_shared<AnotherBasicEventPublisher>();
-  another_basic_pub->setName(basic_pub->getName());
-  status = EventFactory::registerEventPublisher(another_basic_pub);
-  EXPECT_FALSE(status.ok());
-
-  // This class is different but also uses different types!
-  auto fake_pub = std::make_shared<FakeEventPublisher>();
-  status = EventFactory::registerEventPublisher(fake_pub);
-  EXPECT_TRUE(status.ok());
-
-  // May also register a similar (same EC, SC), but different publisher.
-  auto another_fake_pub = std::make_shared<AnotherFakeEventPublisher>();
-  status = EventFactory::registerEventPublisher(another_fake_pub);
-  EXPECT_TRUE(status.ok());
-
-  status = EventFactory::deregisterEventPublisher(basic_pub->type());
-  EXPECT_TRUE(status.ok());
-  status = EventFactory::deregisterEventPublisher(fake_pub->type());
-  EXPECT_TRUE(status.ok());
-  status = EventFactory::deregisterEventPublisher(another_fake_pub->type());
-  EXPECT_TRUE(status.ok());
-
-  // Attempting to deregister a publisher a second time.
-  status = EventFactory::deregisterEventPublisher(another_fake_pub->type());
-  EXPECT_FALSE(status.ok());
-
-  // Attempting to deregister a publish that failed registering.
-  status = EventFactory::deregisterEventPublisher(another_basic_pub->type());
-  EXPECT_FALSE(status.ok());
-}
-
-TEST_F(EventsTests, test_event_publisher_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());
-
-  // It is possible to deregister by base event publisher type.
-  auto status = EventFactory::deregisterEventPublisher(pub2);
-  EXPECT_TRUE(status.ok());
-  // And attempting to deregister by type afterward will fail.
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_FALSE(status.ok());
-}
-
-TEST_F(EventsTests, test_duplicate_event_publisher) {
-  auto pub = std::make_shared<BasicEventPublisher>();
-  pub->setName("BasicPublisher");
-  auto status = EventFactory::registerEventPublisher(pub);
-  EXPECT_TRUE(status.ok());
-
-  // Make sure only the first event type was recorded.
-  EXPECT_EQ(EventFactory::numEventPublishers(), 1U);
-}
-
-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(), 0U);
-  attachEvents();
-
-  // Store the number of default event publishers (in core).
-  size_t default_publisher_count = EventFactory::numEventPublishers();
-
-  auto& rf = RegistryFactory::get();
-  // Now add another registry item, but do not yet attach it.
-  rf.registry("event_publisher")
-      ->add("unique", std::make_shared<UniqueEventPublisher>());
-  EXPECT_EQ(EventFactory::numEventPublishers(), default_publisher_count);
-
-  // Now attach and make sure it was added.
-  attachEvents();
-  EXPECT_EQ(EventFactory::numEventPublishers(), default_publisher_count + 1U);
-
-  auto status = EventFactory::deregisterEventPublisher("unique");
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_create_subscription) {
-  std::string basic_publisher_type = "BasicPublisher";
-
-  auto pub = std::make_shared<BasicEventPublisher>();
-  pub->setName(basic_publisher_type);
-  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.
-  auto subscription = Subscription::create("FakeSubscriber");
-  auto status = EventFactory::addSubscription("FakePublisher", subscription);
-  EXPECT_FALSE(status.ok());
-
-  // In this case we can still add a blank subscription to an existing event
-  // type.
-  status = EventFactory::addSubscription(basic_publisher_type, subscription);
-  EXPECT_TRUE(status.ok());
-
-  // Make sure the subscription is added.
-  EXPECT_EQ(EventFactory::numSubscriptions(basic_publisher_type), 1U);
-
-  status = EventFactory::deregisterEventPublisher(basic_publisher_type);
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_multiple_subscriptions) {
-  std::string basic_publisher_type = "BasicPublisher";
-
-  auto pub = std::make_shared<BasicEventPublisher>();
-  pub->setName(basic_publisher_type);
-  EventFactory::registerEventPublisher(pub);
-
-  auto subscription = Subscription::create("subscriber");
-  auto status =
-      EventFactory::addSubscription(basic_publisher_type, subscription);
-  status = EventFactory::addSubscription(basic_publisher_type, subscription);
-  EXPECT_TRUE(status.ok());
-
-  EXPECT_EQ(EventFactory::numSubscriptions(basic_publisher_type), 2U);
-
-  status = EventFactory::deregisterEventPublisher(basic_publisher_type);
-  EXPECT_TRUE(status.ok());
-}
-
-struct TestSubscriptionContext : public SubscriptionContext {
-  int smallest;
-};
-
-class TestEventPublisher
-    : public EventPublisher<TestSubscriptionContext, EventContext> {
-  DECLARE_PUBLISHER("TestPublisher");
-
- public:
-  Status setUp() override {
-    smallest_ever_ += 1;
-    return Status::success();
-  }
-
-  void configure() override {
-    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() override {
-    smallest_ever_ += 1;
-  }
-
-  // Custom methods do not make sense, but for testing it exists.
-  int getTestValue() {
-    return smallest_ever_;
-  }
-
- public:
-  bool configure_run{false};
-
- private:
-  int smallest_ever_{0};
-};
-
-TEST_F(EventsTests, test_create_custom_event_publisher) {
-  auto basic_pub = std::make_shared<BasicEventPublisher>();
-  basic_pub->setName("BasicPublisher");
-  EventFactory::registerEventPublisher(basic_pub);
-
-  auto pub = std::make_shared<TestEventPublisher>();
-  auto status = EventFactory::registerEventPublisher(pub);
-  ASSERT_TRUE(status.ok());
-
-  // These event types have unique event type IDs
-  EXPECT_EQ(EventFactory::numEventPublishers(), 2U);
-
-  // Make sure the setUp function was called.
-  EXPECT_EQ(pub->getTestValue(), 1);
-
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-  status = EventFactory::deregisterEventPublisher(basic_pub->type());
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_custom_subscription) {
-  // Step 1, register event type
-  auto pub = std::make_shared<TestEventPublisher>();
-  auto status = EventFactory::registerEventPublisher(pub);
-  ASSERT_TRUE(status.ok());
-
-  // Step 2, create and configure a subscription context
-  auto sc = std::make_shared<TestSubscriptionContext>();
-  sc->smallest = -1;
-
-  // Step 3, add the subscription to the event type
-  status = EventFactory::addSubscription("TestPublisher", "TestSubscriber", sc);
-  EXPECT_TRUE(status.ok());
-  EXPECT_EQ(pub->numSubscriptions(), 1U);
-  // Run configure on this publisher.
-  pub->configure();
-
-  // The event type must run configure for each added subscription.
-  EXPECT_TRUE(pub->configure_run);
-  EXPECT_EQ(pub->getTestValue(), -1);
-
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_tear_down) {
-  auto pub = std::make_shared<TestEventPublisher>();
-  auto status = EventFactory::registerEventPublisher(pub);
-  ASSERT_TRUE(status.ok());
-
-  // Make sure set up incremented the test value.
-  EXPECT_EQ(pub->getTestValue(), 1);
-
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-
-  // Make sure tear down incremented the test value.
-  EXPECT_EQ(pub->getTestValue(), 2);
-
-  // Once more, now deregistering all event types.
-  status = EventFactory::registerEventPublisher(pub);
-  EXPECT_TRUE(status.ok());
-
-  EXPECT_EQ(pub->getTestValue(), 3);
-  EventFactory::end();
-  EXPECT_EQ(pub->getTestValue(), 4);
-
-  // Make sure the factory state represented.
-  EXPECT_EQ(EventFactory::numEventPublishers(), 0U);
-
-  // Implicit deregister due to end of event factory.
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_FALSE(status.ok());
-}
-
-static int kBellHathTolled = 0;
-
-Status TestTheeCallback(const EventContextRef& ec,
-                        const SubscriptionContextRef& sc) {
-  kBellHathTolled += 1;
-  return Status::success();
-}
-
-class FakeEventSubscriber : public EventSubscriber<FakeEventPublisher> {
- public:
-  bool bellHathTolled{false};
-  bool contextBellHathTolled{false};
-  bool shouldFireBethHathTolled{false};
-  size_t timesConfigured{0};
-
-  FakeEventSubscriber() {
-    setName("fake_events");
-  }
-
-  explicit FakeEventSubscriber(bool skip_name) {
-    if (!skip_name) {
-      FakeEventSubscriber();
-    }
-  }
-
-  void configure() override {
-    timesConfigured++;
-  }
-
-  Status Callback(const ECRef& ec, const SCRef& sc) {
-    // We don't care about the subscription or the event contexts.
-    bellHathTolled = true;
-    return Status::success();
-  }
-
-  Status SpecialCallback(const ECRef& ec, const SCRef& sc) {
-    // Now we care that the event context is corrected passed.
-    if (ec->required_value == 42) {
-      contextBellHathTolled = true;
-    }
-    return Status::success();
-  }
-
-  void lateInit() {
-    auto sub_ctx = createSubscriptionContext();
-    subscribe(&FakeEventSubscriber::Callback, sub_ctx);
-  }
-
-  void laterInit() {
-    auto sub_ctx = createSubscriptionContext();
-    sub_ctx->require_this_value = 42;
-    subscribe(&FakeEventSubscriber::SpecialCallback, sub_ctx);
-  }
-
- private:
-  FRIEND_TEST(EventsTests, test_subscriber_names);
-  FRIEND_TEST(EventsTests, test_event_subscriber_configure);
-};
-
-TEST_F(EventsTests, test_event_subscriber) {
-  auto sub = std::make_shared<FakeEventSubscriber>();
-  EXPECT_EQ(sub->getType(), "FakePublisher");
-  EXPECT_EQ(sub->getName(), "fake_events");
-}
-
-TEST_F(EventsTests, test_event_subscriber_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();
-  pub->configure();
-  EXPECT_EQ(pub->numSubscriptions(), 1U);
-
-  auto ec = pub->createEventContext();
-  pub->fire(ec, 0);
-
-  EXPECT_TRUE(sub->bellHathTolled);
-
-  auto status = EventFactory::deregisterEventSubscriber(sub->getName());
-  EXPECT_TRUE(status.ok());
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_event_subscriber_context) {
-  auto pub = std::make_shared<FakeEventPublisher>();
-  EventFactory::registerEventPublisher(pub);
-
-  auto sub = std::make_shared<FakeEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  sub->laterInit();
-  pub->configure();
-  auto ec = pub->createEventContext();
-  ec->required_value = 42;
-  pub->fire(ec, 0);
-
-  EXPECT_TRUE(sub->contextBellHathTolled);
-
-  auto status = EventFactory::deregisterEventSubscriber(sub->getName());
-  EXPECT_TRUE(status.ok());
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(EventsTests, test_fire_event) {
-  auto pub = std::make_shared<BasicEventPublisher>();
-  pub->setName("BasicPublisher");
-  auto status = EventFactory::registerEventPublisher(pub);
-  ASSERT_TRUE(status.ok());
-
-  auto sub = std::make_shared<FakeEventSubscriber>();
-  status = EventFactory::registerEventSubscriber(sub);
-  ASSERT_TRUE(status.ok());
-
-  auto subscription = Subscription::create("fake_events");
-  subscription->callback = TestTheeCallback;
-  status = EventFactory::addSubscription("BasicPublisher", subscription);
-  ASSERT_TRUE(status.ok());
-
-  pub->configure();
-
-  // The event context creation would normally happen in the event type.
-  auto ec = pub->createEventContext();
-  pub->fire(ec, 0);
-  EXPECT_EQ(kBellHathTolled, 1);
-
-  auto second_subscription = Subscription::create("fake_events");
-  status = EventFactory::addSubscription("BasicPublisher", second_subscription);
-  ASSERT_TRUE(status.ok());
-
-  pub->configure();
-
-  // Now there are two subscriptions (one sans callback).
-  pub->fire(ec, 0);
-  EXPECT_EQ(kBellHathTolled, 2);
-
-  // Now both subscriptions have callbacks.
-  second_subscription->callback = TestTheeCallback;
-  pub->fire(ec, 0);
-  EXPECT_EQ(kBellHathTolled, 4);
-
-  status = EventFactory::deregisterEventSubscriber(sub->getName());
-  EXPECT_TRUE(status.ok());
-
-  status = EventFactory::deregisterEventPublisher(pub->type());
-  EXPECT_TRUE(status.ok());
-}
-
-class SubFakeEventSubscriber : public FakeEventSubscriber {
- public:
-  SubFakeEventSubscriber() : FakeEventSubscriber(true) {
-    setName("sub_fake_events");
-  }
-
- private:
-  FRIEND_TEST(EventsTests, test_subscriber_names);
-};
-
-TEST_F(EventsTests, test_subscriber_names) {
-  auto subsub = std::make_shared<SubFakeEventSubscriber>();
-  EXPECT_EQ(subsub->getType(), "FakePublisher");
-  EXPECT_EQ(subsub->getName(), "sub_fake_events");
-  EXPECT_EQ(subsub->dbNamespace(), "FakePublisher.sub_fake_events");
-
-  auto sub = std::make_shared<FakeEventSubscriber>();
-  EXPECT_EQ(sub->getName(), "fake_events");
-  EXPECT_EQ(sub->dbNamespace(), "FakePublisher.fake_events");
-}
-
-class DisabledEventSubscriber : public EventSubscriber<FakeEventPublisher> {
- public:
-  DisabledEventSubscriber() : EventSubscriber(false) {}
-};
-
-TEST_F(EventsTests, test_event_toggle_subscribers) {
-  // Make sure subscribers can disable themselves using the event subscriber
-  // constructor parameter.
-  auto sub = std::make_shared<DisabledEventSubscriber>();
-  sub->setName("disabled_events");
-  EXPECT_TRUE(sub->disabled);
-
-  // Normal subscribers will be enabled.
-  auto sub2 = std::make_shared<SubFakeEventSubscriber>();
-  EXPECT_FALSE(sub2->disabled);
-
-  // Registering a disabled subscriber will put it into a paused state.
-  EventFactory::registerEventSubscriber(sub);
-  EXPECT_EQ(sub->state(), EventState::EVENT_PAUSED);
-
-  auto status = EventFactory::deregisterEventSubscriber(sub->getName());
-  EXPECT_TRUE(status.ok());
-}
-}
diff --git a/src/osquery/events/tests/linux/audit_tests.cpp b/src/osquery/events/tests/linux/audit_tests.cpp
deleted file mode 100644 (file)
index aa47c84..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <stdio.h>
-
-#include <gtest/gtest.h>
-
-#include <cstdint>
-#include <ctime>
-
-#include <sstream>
-
-#include <osquery/events.h>
-#include <osquery/flags.h>
-#include <osquery/tables.h>
-
-#include "osquery/events/linux/auditdnetlink.h"
-#include "osquery/tests/test_util.h"
-
-namespace osquery {
-
-DECLARE_bool(audit_allow_unix);
-
-/// Internal audit subscriber (socket events) testable methods.
-extern void parseSockAddr(const std::string& saddr, Row& r, bool& unix_socket);
-
-using StringMap = std::map<std::string, std::string>;
-
-/// Generates a fake audit id
-std::string generateAuditId(std::uint32_t event_id) noexcept {
-  std::stringstream str_helper;
-  str_helper << std::time(nullptr) << ".000:" << event_id;
-
-  return str_helper.str();
-}
-
-class AuditTests : public testing::Test {
- protected:
-  void SetUp() override {
-    Row().swap(row_);
-  }
-
- protected:
-  Row row_;
-};
-
-TEST_F(AuditTests, test_handle_reply) {
-  // A 'fake' audit message.
-  std::string message =
-      "audit(1440542781.644:403030): argc=3 a0=\"H=1 \" a1=\"/bin/sh\" a2=c";
-
-  struct audit_reply reply;
-  reply.type = 1;
-  reply.len = message.size();
-  reply.message = (char*)malloc(sizeof(char) * (message.size() + 1));
-  memset((void*)reply.message, 0, message.size() + 1);
-  memcpy((void*)reply.message, message.c_str(), message.size());
-
-  // Perform the parsing.
-  AuditEventRecord audit_event_record = {};
-  bool parser_status =
-      AuditdNetlinkParser::ParseAuditReply(reply, audit_event_record);
-  EXPECT_EQ(parser_status, true);
-
-  free((char*)reply.message);
-
-  EXPECT_EQ(reply.type, audit_event_record.type);
-  EXPECT_EQ("1440542781.644:403030", audit_event_record.audit_id);
-  EXPECT_EQ(audit_event_record.fields.size(), 4U);
-  EXPECT_EQ(audit_event_record.fields.count("argc"), 1U);
-  EXPECT_EQ(audit_event_record.fields["argc"], "3");
-  EXPECT_EQ(audit_event_record.fields["a0"], "\"H=1 \"");
-  EXPECT_EQ(audit_event_record.fields["a1"], "\"/bin/sh\"");
-  EXPECT_EQ(audit_event_record.fields["a2"], "c");
-}
-
-TEST_F(AuditTests, test_audit_value_decode) {
-  // In the normal case the decoding only removes '"' characters from the ends.
-  auto decoded_normal = DecodeAuditPathValues("\"/bin/ls\"");
-  EXPECT_EQ(decoded_normal, "/bin/ls");
-
-  // If the first char is not '"', the value is expected to be hex-encoded.
-  auto decoded_hex = DecodeAuditPathValues("736C6565702031");
-  EXPECT_EQ(decoded_hex, "sleep 1");
-
-  // When the hex fails to decode the input value is returned as the result.
-  auto decoded_fail = DecodeAuditPathValues("7");
-  EXPECT_EQ(decoded_fail, "7");
-}
-
-size_t kAuditCounter{0};
-
-bool SimpleUpdate(size_t t, const StringMap& f, StringMap& m) {
-  kAuditCounter++;
-  for (const auto& i : f) {
-    m[i.first] = i.second;
-  }
-  return true;
-}
-
-TEST_F(AuditTests, test_parse_sock_addr) {
-  Row r;
-  std::string msg = "02001F907F0000010000000000000000";
-  bool unix_socket;
-  parseSockAddr(msg, r, unix_socket);
-  ASSERT_FALSE(r["remote_address"].empty());
-  EXPECT_EQ(r["remote_address"], "127.0.0.1");
-  EXPECT_EQ(r["family"], "2");
-  EXPECT_EQ(r["remote_port"], "8080");
-
-  Row r3;
-  std::string msg2 = "0A001F9100000000FE80000000000000022522FFFEB03684000000";
-  parseSockAddr(msg2, r3, unix_socket);
-  ASSERT_FALSE(r3["remote_address"].empty());
-  EXPECT_EQ(r3["remote_address"], "fe80:0000:0000:0000:0225:22ff:feb0:3684");
-  EXPECT_EQ(r3["remote_port"], "8081");
-
-  auto socket_flag = FLAGS_audit_allow_unix;
-  FLAGS_audit_allow_unix = true;
-  Row r4;
-  std::string msg3 = "01002F746D702F6F7371756572792E656D0000";
-  parseSockAddr(msg3, r4, unix_socket);
-  ASSERT_FALSE(r4["socket"].empty());
-  EXPECT_EQ(r4["socket"], "/tmp/osquery.em");
-
-  msg3 = "0100002F746D702F6F7371756572792E656D";
-  parseSockAddr(msg3, r4, unix_socket);
-  EXPECT_EQ(r4["socket"], "/tmp/osquery.em");
-  FLAGS_audit_allow_unix = socket_flag;
-}
-}
diff --git a/src/osquery/events/tests/linux/inotify_tests.cpp b/src/osquery/events/tests/linux/inotify_tests.cpp
deleted file mode 100644 (file)
index b5f4ada..0000000
+++ /dev/null
@@ -1,548 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <stdio.h>
-
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-
-#include <gflags/gflags.h>
-#include <gtest/gtest.h>
-
-#include <osquery/database.h>
-#include <osquery/events.h>
-#include <osquery/events/linux/inotify.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/registry_factory.h>
-#include <osquery/tables.h>
-#include <osquery/utils/info/tool_type.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-DECLARE_bool(disable_database);
-
-const int kMaxEventLatency = 3000;
-
-class INotifyTests : public testing::Test {
- protected:
-  void SetUp() override {
-    kToolType = ToolType::TEST;
-    registryAndPluginInit();
-
-    FLAGS_disable_database = true;
-    DatabasePlugin::setAllowOpen(true);
-    DatabasePlugin::initPlugin();
-
-    // INotify will use data from the config and config parsers.
-    Registry::get().registry("config_parser")->setUp();
-
-    // Create a basic path trigger, this is a file path.
-    real_test_path =
-        fs::weakly_canonical(fs::temp_directory_path() /
-                             fs::unique_path("inotify-trigger.%%%%.%%%%"))
-            .string();
-    // Create a similar directory for embedded paths and directories.
-    real_test_dir =
-        fs::weakly_canonical(fs::temp_directory_path() /
-                             fs::unique_path("inotify-trigger.%%%%.%%%%"))
-            .string();
-
-    // Create the embedded paths.
-    real_test_dir_path = real_test_dir + "/1";
-    real_test_sub_dir = real_test_dir + "/2";
-    real_test_sub_dir_path = real_test_sub_dir + "/1";
-  }
-
-  void TearDown() override {
-    // End the event loops, and join on the threads.
-    removePath(real_test_dir);
-    removePath(real_test_path);
-  }
-
-  void StartEventLoop() {
-    event_pub_ = std::make_shared<INotifyEventPublisher>(true);
-    auto status = EventFactory::registerEventPublisher(event_pub_);
-    FILE* fd = fopen(real_test_path.c_str(), "w");
-    fclose(fd);
-    temp_thread_ = std::thread(EventFactory::run, "inotify");
-  }
-
-  void StopEventLoop() {
-    while (!event_pub_->hasStarted()) {
-      ::usleep(20);
-    }
-
-    EventFactory::end(true);
-    temp_thread_.join();
-  }
-
-  void SubscriptionAction(const std::string& path,
-                          uint32_t mask = IN_ALL_EVENTS,
-                          EventCallback ec = nullptr) {
-    auto sc = std::make_shared<INotifySubscriptionContext>();
-    sc->path = path;
-    sc->mask = mask;
-
-    EventFactory::addSubscription("inotify", "TestSubscriber", sc, ec);
-    event_pub_->configure();
-  }
-
-  bool WaitForEvents(size_t max, size_t num_events = 0) {
-    size_t delay = 0;
-    while (delay <= max * 1000) {
-      if (num_events > 0 && event_pub_->numEvents() >= num_events) {
-        return true;
-      } else if (num_events == 0 && event_pub_->numEvents() > 0) {
-        return true;
-      }
-      delay += 50;
-      ::usleep(50);
-    }
-    return false;
-  }
-
-  void TriggerEvent(const std::string& path) {
-    FILE* fd = fopen(path.c_str(), "w");
-    fputs("inotify", fd);
-    fclose(fd);
-  }
-
-  void addMonitor(const std::string& path,
-                  uint32_t mask,
-                  bool recursive,
-                  bool add_watch) {
-    auto sc = event_pub_->createSubscriptionContext();
-    event_pub_->addMonitor(path, sc, mask, recursive, add_watch);
-  }
-
-  void RemoveAll(std::shared_ptr<INotifyEventPublisher>& pub) {
-    pub->subscriptions_.clear();
-    // Reset monitors.
-    std::vector<int> wds;
-    for (const auto& path : pub->descriptor_inosubctx_) {
-      wds.push_back(path.first);
-    }
-    for (const auto& wd : wds) {
-      pub->removeMonitor(wd, true);
-    }
-  }
-
- protected:
-  /// Internal state managers: publisher reference.
-  std::shared_ptr<INotifyEventPublisher> event_pub_{nullptr};
-
-  /// Internal state managers: event publisher thread.
-  std::thread temp_thread_;
-
-  /// Transient paths ./inotify-trigger.
-  std::string real_test_path;
-
-  /// Transient paths ./inotify-triggers/.
-  std::string real_test_dir;
-
-  /// Transient paths ./inotify-triggers/1.
-  std::string real_test_dir_path;
-
-  /// Transient paths ./inotify-triggers/2/.
-  std::string real_test_sub_dir;
-
-  /// Transient paths ./inotify-triggers/2/1.
-  std::string real_test_sub_dir_path;
-};
-
-TEST_F(INotifyTests, test_register_event_pub) {
-  auto pub = std::make_shared<INotifyEventPublisher>(true);
-  auto status = EventFactory::registerEventPublisher(pub);
-  EXPECT_TRUE(status.ok());
-
-  // Make sure only one event type exists
-  EXPECT_EQ(EventFactory::numEventPublishers(), 1U);
-  // And deregister
-  status = EventFactory::deregisterEventPublisher("inotify");
-  EXPECT_TRUE(status.ok());
-}
-
-TEST_F(INotifyTests, test_inotify_init) {
-  // Handle should not be initialized during ctor.
-  auto event_pub = std::make_shared<INotifyEventPublisher>(true);
-  EXPECT_FALSE(event_pub->isHandleOpen());
-
-  // Registering the event type initializes inotify.
-  auto status = EventFactory::registerEventPublisher(event_pub);
-  EXPECT_TRUE(status.ok());
-  EXPECT_TRUE(event_pub->isHandleOpen());
-
-  // Similarly deregistering closes the handle.
-  EventFactory::deregisterEventPublisher("inotify");
-  EXPECT_FALSE(event_pub->isHandleOpen());
-}
-
-TEST_F(INotifyTests, test_inotify_add_subscription_missing_path) {
-  auto pub = std::make_shared<INotifyEventPublisher>(true);
-  EventFactory::registerEventPublisher(pub);
-
-  // This subscription path is fake, and will succeed.
-  auto mc = std::make_shared<INotifySubscriptionContext>();
-  mc->path = "/this/path/is/fake";
-
-  auto subscription = Subscription::create("TestSubscriber", mc);
-  auto status = EventFactory::addSubscription("inotify", subscription);
-  EXPECT_TRUE(status.ok());
-  EventFactory::deregisterEventPublisher("inotify");
-}
-
-TEST_F(INotifyTests, test_inotify_add_subscription_success) {
-  auto pub = std::make_shared<INotifyEventPublisher>(true);
-  EventFactory::registerEventPublisher(pub);
-
-  // This subscription path *should* be real.
-  auto mc = std::make_shared<INotifySubscriptionContext>();
-  mc->path = "/";
-  mc->mask = IN_ALL_EVENTS;
-
-  auto subscription = Subscription::create("TestSubscriber", mc);
-  auto status = EventFactory::addSubscription("inotify", subscription);
-  EXPECT_TRUE(status.ok());
-  EventFactory::deregisterEventPublisher("inotify");
-}
-
-TEST_F(INotifyTests, test_inotify_match_subscription) {
-  event_pub_ = std::make_shared<INotifyEventPublisher>(true);
-  addMonitor("/etc", IN_ALL_EVENTS, false, false);
-  EXPECT_EQ(event_pub_->path_descriptors_.count("/etc"), 1U);
-  // This will fail because there is no trailing "/" at the end.
-  // The configure component should take care of these paths.
-  EXPECT_FALSE(event_pub_->isPathMonitored("/etc/passwd"));
-  event_pub_->path_descriptors_.clear();
-
-  // Calling addMonitor the correct way.
-  addMonitor("/etc/", IN_ALL_EVENTS, false, false);
-  EXPECT_TRUE(event_pub_->isPathMonitored("/etc/passwd"));
-  event_pub_->path_descriptors_.clear();
-
-  // Test the matching capability.
-  {
-    auto sc = event_pub_->createSubscriptionContext();
-    sc->path = "/etc";
-    event_pub_->monitorSubscription(sc, false);
-    EXPECT_EQ(sc->path, "/etc/");
-    EXPECT_TRUE(event_pub_->isPathMonitored("/etc/"));
-    EXPECT_TRUE(event_pub_->isPathMonitored("/etc/passwd"));
-  }
-
-  std::vector<std::string> valid_dirs = {"/etc", "/etc/", "/etc/*"};
-  for (const auto& dir : valid_dirs) {
-    event_pub_->path_descriptors_.clear();
-    auto sc = event_pub_->createSubscriptionContext();
-    sc->path = dir;
-    event_pub_->monitorSubscription(sc, false);
-    auto ec = event_pub_->createEventContext();
-    ec->isub_ctx = sc;
-    ec->path = "/etc/";
-    EXPECT_TRUE(event_pub_->shouldFire(sc, ec));
-    ec->path = "/etc/passwd";
-    EXPECT_TRUE(event_pub_->shouldFire(sc, ec));
-  }
-
-  std::vector<std::string> exclude_paths = {
-      "/etc/ssh/%%", "/etc/", "/etc/ssl/openssl.cnf", "/"};
-  for (const auto& path : exclude_paths) {
-    event_pub_->exclude_paths_.insert(path);
-  }
-
-  {
-    event_pub_->path_descriptors_.clear();
-    auto sc = event_pub_->createSubscriptionContext();
-    sc->path = "/etc/%%";
-    auto ec = event_pub_->createEventContext();
-    ec->isub_ctx = sc;
-    ec->path = "/etc/ssh/ssh_config";
-    EXPECT_FALSE(event_pub_->shouldFire(sc, ec));
-    ec->path = "/etc/passwd";
-    EXPECT_FALSE(event_pub_->shouldFire(sc, ec));
-    ec->path = "/etc/group";
-    EXPECT_FALSE(event_pub_->shouldFire(sc, ec));
-    ec->path = "/etc/ssl/openssl.cnf";
-    EXPECT_FALSE(event_pub_->shouldFire(sc, ec));
-    ec->path = "/etc/ssl/certs/";
-    EXPECT_TRUE(event_pub_->shouldFire(sc, ec));
-  }
-}
-
-class TestINotifyEventSubscriber
-    : public EventSubscriber<INotifyEventPublisher> {
- public:
-  TestINotifyEventSubscriber() {
-    setName("TestINotifyEventSubscriber");
-  }
-
-  Status init() override {
-    callback_count_ = 0;
-    return Status::success();
-  }
-
-  Status SimpleCallback(const ECRef& ec, const SCRef& sc) {
-    callback_count_ += 1;
-    return Status::success();
-  }
-
-  Status Callback(const ECRef& ec, const SCRef& sc) {
-    // The following comments are an example Callback routine.
-    // Row r;
-    // r["action"] = ec->action;
-    // r["path"] = ec->path;
-
-    // Normally would call Add here.
-    callback_count_++;
-
-    WriteLock lock(actions_lock_);
-    actions_.push_back(ec->action);
-    return Status::success();
-  }
-
-  SCRef GetSubscription(const std::string& path,
-                        uint32_t mask = IN_ALL_EVENTS) {
-    auto mc = createSubscriptionContext();
-    mc->path = path;
-    mc->mask = mask;
-    return mc;
-  }
-
-  void WaitForEvents(int max, int num_events = 1) {
-    int delay = 0;
-    while (delay < max * 1000) {
-      if (callback_count_ >= num_events) {
-        return;
-      }
-      ::usleep(50);
-      delay += 50;
-    }
-  }
-
-  std::vector<std::string> actions() {
-    WriteLock lock(actions_lock_);
-    return actions_;
-  }
-
-  int count() {
-    return callback_count_;
-  }
-
- public:
-  std::atomic<int> callback_count_{0};
-  std::vector<std::string> actions_;
-
- private:
-  Mutex actions_lock_;
-
- private:
-  FRIEND_TEST(INotifyTests, test_inotify_fire_event);
-  FRIEND_TEST(INotifyTests, test_inotify_event_action);
-  FRIEND_TEST(INotifyTests, test_inotify_optimization);
-  FRIEND_TEST(INotifyTests, test_inotify_directory_watch);
-  FRIEND_TEST(INotifyTests, DISABLED_test_inotify_recursion);
-  FRIEND_TEST(INotifyTests, test_inotify_embedded_wildcards);
-};
-
-TEST_F(INotifyTests, test_inotify_run) {
-  // Assume event type is registered.
-  event_pub_ = std::make_shared<INotifyEventPublisher>(true);
-  auto status = EventFactory::registerEventPublisher(event_pub_);
-  EXPECT_TRUE(status.ok());
-
-  // Create a temporary file to watch, open writeable
-  FILE* fd = fopen(real_test_path.c_str(), "w");
-
-  // Create a subscriber.
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  // Create a subscription context
-  auto mc = std::make_shared<INotifySubscriptionContext>();
-  mc->path = real_test_path;
-  mc->mask = IN_ALL_EVENTS;
-  status = EventFactory::addSubscription(
-      "inotify", Subscription::create("TestINotifyEventSubscriber", mc));
-  EXPECT_TRUE(status.ok());
-  event_pub_->configure();
-
-  // Create an event loop thread (similar to main)
-  std::thread temp_thread(EventFactory::run, "inotify");
-  EXPECT_TRUE(event_pub_->numEvents() == 0);
-
-  // Cause an inotify event by writing to the watched path.
-  fputs("inotify", fd);
-  fclose(fd);
-
-  // Wait for the thread's run loop to select.
-  WaitForEvents(kMaxEventLatency);
-  EXPECT_TRUE(event_pub_->numEvents() > 0);
-  EventFactory::end();
-  temp_thread.join();
-}
-
-TEST_F(INotifyTests, test_inotify_fire_event) {
-  // Assume event type is registered.
-  StartEventLoop();
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  // Create a subscriptioning context, note the added Event to the symbol
-  auto sc = sub->GetSubscription(real_test_path, 0);
-  sub->subscribe(&TestINotifyEventSubscriber::SimpleCallback, sc);
-  event_pub_->configure();
-
-  TriggerEvent(real_test_path);
-  sub->WaitForEvents(kMaxEventLatency);
-
-  // Make sure our expected event fired (aka subscription callback was called).
-  EXPECT_TRUE(sub->count() > 0);
-  StopEventLoop();
-}
-
-TEST_F(INotifyTests, test_inotify_event_action) {
-  // Assume event type is registered.
-  StartEventLoop();
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  auto sc = sub->GetSubscription(real_test_path, IN_ALL_EVENTS);
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc);
-  event_pub_->configure();
-
-  TriggerEvent(real_test_path);
-  sub->WaitForEvents(kMaxEventLatency, 2);
-
-  // Make sure the inotify action was expected.
-  EXPECT_GT(sub->actions().size(), 0U);
-  if (sub->actions().size() >= 2) {
-    EXPECT_EQ(sub->actions()[0], "UPDATED");
-  }
-
-  StopEventLoop();
-}
-
-TEST_F(INotifyTests, test_inotify_optimization) {
-  // Assume event type is registered.
-  StartEventLoop();
-  fs::create_directory(real_test_dir);
-
-  // Adding a descriptor to a directory will monitor files within.
-  SubscriptionAction(real_test_dir);
-  EXPECT_TRUE(event_pub_->isPathMonitored(real_test_dir_path));
-
-  // Adding a subscription to a file within a monitored directory is fine
-  // but this will NOT cause an additional INotify watch.
-  SubscriptionAction(real_test_dir_path);
-  EXPECT_EQ(event_pub_->numDescriptors(), 1U);
-  StopEventLoop();
-}
-
-TEST_F(INotifyTests, test_inotify_directory_watch) {
-  StartEventLoop();
-
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  fs::create_directory(real_test_dir);
-  fs::create_directory(real_test_sub_dir);
-
-  // Subscribe to the directory inode
-  auto mc = sub->createSubscriptionContext();
-  mc->path = real_test_dir;
-  mc->recursive = true;
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, mc);
-  event_pub_->configure();
-
-  // Trigger on a subdirectory's file.
-  TriggerEvent(real_test_sub_dir_path);
-
-  sub->WaitForEvents(kMaxEventLatency, 1);
-  EXPECT_TRUE(sub->count() > 0);
-  StopEventLoop();
-}
-
-TEST_F(INotifyTests, DISABLED_test_inotify_recursion) {
-  // Create a non-registered publisher and subscriber.
-  auto pub = std::make_shared<INotifyEventPublisher>(true);
-  EventFactory::registerEventPublisher(pub);
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-
-  // Create a mock directory structure.
-  fs::create_directory(real_test_dir);
-
-  // Create and test several subscriptions.
-  auto sc = sub->createSubscriptionContext();
-
-  sc->path = real_test_dir + "/*";
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc);
-  // Trigger a configure step manually.
-  pub->configure();
-
-  // Expect a single monitor on the root of the fake tree.
-  EXPECT_EQ(pub->path_descriptors_.size(), 1U);
-  EXPECT_EQ(pub->path_descriptors_.count(real_test_dir + "/"), 1U);
-  RemoveAll(pub);
-
-  // Make sure monitors are empty.
-  EXPECT_EQ(pub->numDescriptors(), 0U);
-
-  auto sc2 = sub->createSubscriptionContext();
-  sc2->path = real_test_dir + "/**";
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc2);
-  pub->configure();
-
-  // Expect only the directories to be monitored.
-  // TODO test fails in the following assert.
-  EXPECT_EQ(pub->path_descriptors_.size(), 11U);
-  RemoveAll(pub);
-
-  // Use a directory structure that includes a loop.
-  boost::system::error_code ec;
-  fs::create_symlink(real_test_dir, real_test_dir + "/link", ec);
-
-  auto sc3 = sub->createSubscriptionContext();
-  sc3->path = real_test_dir + "/**";
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, sc3);
-  pub->configure();
-
-  // Also expect canonicalized resolution (to prevent loops).
-  EXPECT_EQ(pub->path_descriptors_.size(), 9U);
-  RemoveAll(pub);
-
-  EventFactory::deregisterEventPublisher("inotify");
-}
-
-TEST_F(INotifyTests, test_inotify_embedded_wildcards) {
-  // Assume event type is not registered.
-  event_pub_ = std::make_shared<INotifyEventPublisher>(true);
-  EventFactory::registerEventPublisher(event_pub_);
-
-  auto sub = std::make_shared<TestINotifyEventSubscriber>();
-  EventFactory::registerEventSubscriber(sub);
-
-  // Create ./inotify-triggers/2/1/.
-  fs::create_directories(real_test_dir + "/2/1");
-
-  // Create a subscription to match an embedded wildcard: "*"
-  // The assumption is a watch will be created on the 'most-specific' directory
-  // before the wildcard request.
-  auto mc = sub->createSubscriptionContext();
-  mc->path = real_test_dir + "/*/1";
-  mc->recursive = true;
-  sub->subscribe(&TestINotifyEventSubscriber::Callback, mc);
-
-  // Now the publisher must be configured.
-  event_pub_->configure();
-
-  // Assume there is one watched path: real_test_dir.
-  ASSERT_EQ(event_pub_->numDescriptors(), 1U);
-  EXPECT_EQ(event_pub_->path_descriptors_.count(real_test_dir + "/2/1/"), 1U);
-}
-}
diff --git a/src/osquery/events/tests/linux/process_file_events_tests.cpp b/src/osquery/events/tests/linux/process_file_events_tests.cpp
deleted file mode 100644 (file)
index 9005bfa..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <gtest/gtest.h>
-
-#include <linux/audit.h>
-#include <cstdint>
-#include <cstdio>
-#include <ctime>
-#include <string>
-#include <vector>
-#include <sstream>
-
-#include <osquery/events.h>
-#include <osquery/events/linux/auditeventpublisher.h>
-#include <osquery/flags.h>
-#include <osquery/tables.h>
-#include <osquery/tables/events/linux/process_file_events.h>
-
-namespace osquery {
-extern std::vector<std::pair<int, std::string>> complete_event_list;
-extern StringList included_file_paths;
-extern std::string generateAuditId(std::uint32_t event_id) noexcept;
-
-class AuditdFimTests : public testing::Test {
- protected:
-  void SetUp() override {
-    Row().swap(row_);
-  }
-
- protected:
-  Row row_;
-};
-
-void DumpRow(Row r) {
-  std::cout << "  " << r["operation"] << " " << r["path1"];
-  if (r.find("path2") != r.end()) {
-    std::cout << " " << r["path2"];
-  }
-
-  std::cout << "\n";
-}
-
-void DumpRowList(const std::vector<Row>& row_list) {
-  for (const auto& r : row_list) {
-    DumpRow(r);
-  }
-}
-
-TEST_F(AuditdFimTests, row_emission) {
-  std::vector<AuditEventRecord> event_record_list;
-
-  // Parse the raw messages and make sure we get the right amount
-  // of records
-  for (const auto& record_descriptor : complete_event_list) {
-    std::string audit_message_copy = record_descriptor.second;
-
-    audit_reply reply = {};
-    reply.type = record_descriptor.first;
-    reply.len = audit_message_copy.size();
-    reply.message = &audit_message_copy[0];
-
-    AuditEventRecord audit_event_record = {};
-
-    bool parser_status =
-        AuditdNetlinkParser::ParseAuditReply(reply, audit_event_record);
-    EXPECT_EQ(parser_status, true);
-
-    event_record_list.push_back(audit_event_record);
-  }
-
-  EXPECT_EQ(event_record_list.size(), 243U);
-
-  // Assemble the audit records into audit events, and make sure
-  // we get the correct amount of objects
-  auto event_context = std::make_shared<AuditEventContext>();
-  AuditTraceContext audit_trace_context;
-
-  AuditEventPublisher::ProcessEvents(
-      event_context, event_record_list, audit_trace_context);
-
-  EXPECT_EQ(audit_trace_context.size(), 0U);
-  EXPECT_EQ(event_context->audit_events.size(), 71U);
-
-  // Configure what we want to log and what we want to ignore
-  AuditdFimContext fim_context;
-  fim_context.included_path_list = included_file_paths;
-
-  // Emit the rows, showing only writes
-  std::vector<Row> emitted_row_list;
-  Status status = ProcessFileEventSubscriber::ProcessEvents(
-      emitted_row_list, fim_context, event_context->audit_events);
-
-  EXPECT_EQ(status.ok(), true);
-  // @TODO fix failing test
-  // EXPECT_EQ(emitted_row_list.size(), 15U);
-}
-
-// clang-format off
-StringList included_file_paths = {
-  "/etc/ld.so.cache",
-  "/home/alessandro/test_file",
-  "/lib64/libc.so.6",
-  "/lib64/libgcc_s.so.1",
-  "/lib64/libm.so.6",
-  "/lib64/libstdc++.so.6",
-  "/home/alessandro/test_file",
-  "/home/alessandro/test_file1",
-  "/home/alessandro/test_file2",
-  "/home/alessandro/test_file3",
-  "/home/alessandro/test_file4",
-  "/home/alessandro/test_file5",
-  "/home/alessandro/test_file7",
-  "/home/alessandro/test_file_rename",
-  "/home/alessandro/test_file_renameat"
-};
-
-std::vector<std::pair<int, std::string>> complete_event_list = {
-  {1300, "audit(1502573850.697:38395): arch=c000003e syscall=9 success=yes exit=140095431475200 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38395): "},
-  {1300, "audit(1502573850.697:38396): arch=c000003e syscall=2 success=yes exit=3 a0=7f6a824d4df5 a1=80000 a2=1 a3=7f6a826db4f8 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.697:38396):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.697:38396): item=0 name=\"/etc/ld.so.cache\" inode=67842177 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:ld_so_cache_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.697:38396): "},
-  {1300, "audit(1502573850.697:38397): arch=c000003e syscall=9 success=yes exit=140095431385088 a0=0 a1=15e5b a2=1 a3=2 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38397): fd=3 flags=0x2"},
-  {1320, "audit(1502573850.697:38397): "},
-  {1300, "audit(1502573850.697:38398): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=15e5b a2=1 a3=2 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38398): "},
-  {1300, "audit(1502573850.697:38399): arch=c000003e syscall=2 success=yes exit=3 a0=7f6a826d8640 a1=80000 a2=7f6a826db150 a3=7f6a826d8640 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.697:38399):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.697:38399): item=0 name=\"/lib64/libstdc++.so.6\" inode=33604382 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:lib_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.697:38399): "},
-  {1300, "audit(1502573850.697:38400): arch=c000003e syscall=0 success=yes exit=832 a0=3 a1=7fff15c09350 a2=340 a3=7f6a826d8640 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38400): "},
-  {1300, "audit(1502573850.697:38401): arch=c000003e syscall=9 success=yes exit=140095426068480 a0=0 a1=308420 a2=5 a3=802 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38401): fd=3 flags=0x802"},
-  {1320, "audit(1502573850.697:38401): "},
-  {1300, "audit(1502573850.697:38402): arch=c000003e syscall=9 success=yes exit=140095429120000 a0=7f6a82499000 a1=b000 a2=3 a3=812 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38402): fd=3 flags=0x812"},
-  {1320, "audit(1502573850.697:38402): "},
-  {1300, "audit(1502573850.697:38403): arch=c000003e syscall=9 success=yes exit=140095429165056 a0=7f6a824a4000 a1=14420 a2=3 a3=32 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38403): "},
-  {1300, "audit(1502573850.697:38404): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=7f6a826d8698 a2=0 a3=31 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38404): "},
-  {1300, "audit(1502573850.697:38405): arch=c000003e syscall=2 success=yes exit=3 a0=7f6a826d8b08 a1=80000 a2=7f6a826db150 a3=7f6a826d8b08 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.697:38405):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.697:38405): item=0 name=\"/lib64/libm.so.6\" inode=33604048 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:lib_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.697:38405): "},
-  {1300, "audit(1502573850.697:38406): arch=c000003e syscall=0 success=yes exit=832 a0=3 a1=7fff15c09320 a2=340 a3=7f6a826d8b08 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38406): "},
-  {1300, "audit(1502573850.697:38407): arch=c000003e syscall=9 success=yes exit=140095422914560 a0=0 a1=301148 a2=5 a3=802 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38407): fd=3 flags=0x802"},
-  {1320, "audit(1502573850.697:38407): "},
-  {1300, "audit(1502573850.697:38408): arch=c000003e syscall=9 success=yes exit=140095426060288 a0=7f6a821ae000 a1=2000 a2=3 a3=812 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38408): fd=3 flags=0x812"},
-  {1320, "audit(1502573850.697:38408): "},
-  {1300, "audit(1502573850.697:38409): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=7f6a826d8b60 a2=0 a3=31 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38409): "},
-  {1300, "audit(1502573850.697:38410): arch=c000003e syscall=2 success=yes exit=3 a0=7f6a826d8fd0 a1=80000 a2=7f6a826db150 a3=7f6a826d8fd0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.697:38410):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.697:38410): item=0 name=\"/lib64/libgcc_s.so.1\" inode=33554508 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:lib_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.697:38410): "},
-  {1300, "audit(1502573850.697:38411): arch=c000003e syscall=0 success=yes exit=832 a0=3 a1=7fff15c092f0 a2=340 a3=7f6a826d8fd0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38411): "},
-  {1300, "audit(1502573850.697:38412): arch=c000003e syscall=9 success=yes exit=140095431380992 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38412): "},
-  {1300, "audit(1502573850.697:38413): arch=c000003e syscall=9 success=yes exit=140095420727296 a0=0 a1=215400 a2=5 a3=802 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38413): fd=3 flags=0x802"},
-  {1320, "audit(1502573850.697:38413): "},
-  {1300, "audit(1502573850.697:38414): arch=c000003e syscall=9 success=yes exit=140095422906368 a0=7f6a81eac000 a1=2000 a2=3 a3=812 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.697:38414): fd=3 flags=0x812"},
-  {1320, "audit(1502573850.697:38414): "},
-  {1300, "audit(1502573850.697:38415): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=7f6a826c1040 a2=0 a3=31 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.697:38415): "},
-  {1300, "audit(1502573850.698:38416): arch=c000003e syscall=2 success=yes exit=3 a0=7f6a826c14b0 a1=80000 a2=7f6a826db150 a3=7f6a826c14b0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.698:38416):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.698:38416): item=0 name=\"/lib64/libc.so.6\" inode=33604039 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:lib_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.698:38416): "},
-  {1300, "audit(1502573850.698:38417): arch=c000003e syscall=0 success=yes exit=832 a0=3 a1=7fff15c092c0 a2=340 a3=7f6a826c14b0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38417): "},
-  {1300, "audit(1502573850.698:38418): arch=c000003e syscall=9 success=yes exit=140095416791040 a0=0 a1=3c0200 a2=5 a3=802 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.698:38418): fd=3 flags=0x802"},
-  {1320, "audit(1502573850.698:38418): "},
-  {1300, "audit(1502573850.698:38419): arch=c000003e syscall=9 success=yes exit=140095420682240 a0=7f6a81c8d000 a1=6000 a2=3 a3=812 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573850.698:38419): fd=3 flags=0x812"},
-  {1320, "audit(1502573850.698:38419): "},
-  {1300, "audit(1502573850.698:38420): arch=c000003e syscall=9 success=yes exit=140095420706816 a0=7f6a81c93000 a1=4200 a2=3 a3=32 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38420): "},
-  {1300, "audit(1502573850.698:38421): arch=c000003e syscall=3 success=yes exit=0 a0=3 a1=7f6a826c1508 a2=0 a3=31 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38421): "},
-  {1300, "audit(1502573850.698:38422): arch=c000003e syscall=9 success=yes exit=140095431376896 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38422): "},
-  {1300, "audit(1502573850.698:38423): arch=c000003e syscall=9 success=yes exit=140095431368704 a0=0 a1=2000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38423): "},
-  {1300, "audit(1502573850.698:38424): arch=c000003e syscall=9 success=yes exit=140095431364608 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.698:38424): "},
-  {1300, "audit(1502573850.698:38425): arch=c000003e syscall=87 success=yes exit=0 a0=40219c a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.698:38425):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.698:38425): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.698:38425): item=1 name=\"test_file\" inode=724389 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.698:38425): "},
-  {1300, "audit(1502573850.699:38428): arch=c000003e syscall=87 success=yes exit=0 a0=4021ff a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.699:38428):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.699:38428): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.699:38428): item=1 name=\"test_file3\" inode=724389 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.699:38428): "},
-  {1300, "audit(1502573850.699:38429): arch=c000003e syscall=87 success=yes exit=0 a0=40220a a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.699:38429):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.699:38429): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.699:38429): item=1 name=\"test_file4\" inode=724416 dev=fd:02 mode=0120777 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.699:38429): "},
-  {1300, "audit(1502573850.699:38430): arch=c000003e syscall=87 success=yes exit=0 a0=40242d a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.699:38430):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.699:38430): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.699:38430): item=1 name=\"test_file5\" inode=724406 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.699:38430): "},
-  {1300, "audit(1502573850.699:38431): arch=c000003e syscall=87 success=yes exit=0 a0=402451 a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.699:38431):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.699:38431): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.699:38431): item=1 name=\"test_file6\" inode=724418 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.699:38431): "},
-  {1300, "audit(1502573850.699:38432): arch=c000003e syscall=87 success=yes exit=0 a0=402477 a1=7fff15c0ab48 a2=7fff15c0ab58 a3=7fff15c0a7d0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.699:38432):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.699:38432): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573850.699:38432): item=1 name=\"test_file7\" inode=724419 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573850.699:38432): "},
-  {1300, "audit(1502573850.725:38494): arch=c000003e syscall=257 success=yes exit=3 a0=ffffffffffffff9c a1=40259e a2=90800 a3=0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573850.725:38494):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573850.725:38494): item=0 name=\".\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573850.725:38494): "},
-  {1300, "audit(1502573850.725:38495): arch=c000003e syscall=9 success=yes exit=140095431471104 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.725:38495): "},
-  {1300, "audit(1502573850.725:38496): arch=c000003e syscall=1 success=yes exit=18 a0=1 a1=7f6a826d7000 a2=12 a3=0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.725:38496): "},
-  {1300, "audit(1502573850.725:38497): arch=c000003e syscall=9 success=yes exit=140095431467008 a0=0 a1=1000 a2=3 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.725:38497): "},
-  {1300, "audit(1502573850.726:38498): arch=c000003e syscall=1 success=yes exit=31 a0=1 a1=7f6a826d7000 a2=1f a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.726:38498): "},
-  {1300, "audit(1502573850.726:46799): arch=c000003e syscall=0 success=yes exit=1 a0=0 a1=7f6a826d6000 a2=400 a3=22 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573850.726:46799): "},
-  {1300, "audit(1502573858.178:46800): arch=c000003e syscall=76 success=yes exit=0 a0=40219c a1=c a2=a a3=7fff15c0a7c0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46800):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46800): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46800): "},
-  {1300, "audit(1502573858.178:46801): arch=c000003e syscall=86 success=yes exit=0 a0=40219c a1=402191 a2=a a3=7fff15c0a7c0 items=3 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46801):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46801): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1302, "audit(1502573858.178:46801): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46801): item=2 name=\"test_file1\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46801): "},
-  {1300, "audit(1502573858.178:46802): arch=c000003e syscall=88 success=yes exit=0 a0=40219c a1=4021cc a2=a a3=7fff15c0a7c0 items=3 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46802):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46802): item=0 name=\"test_file\" objtype=UNKNOWN"},
-  {1302, "audit(1502573858.178:46802): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46802): item=2 name=\"test_file2\" inode=724389 dev=fd:02 mode=0120777 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46802): "},
-  {1300, "audit(1502573858.178:46803): arch=c000003e syscall=265 success=yes exit=0 a0=3 a1=40219c a2=3 a3=4021ff items=3 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46803):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46803): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1302, "audit(1502573858.178:46803): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46803): item=2 name=\"test_file3\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46803): "},
-  {1300, "audit(1502573858.178:46804): arch=c000003e syscall=266 success=yes exit=0 a0=40219c a1=3 a2=40220a a3=7fff15c0a7c0 items=3 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46804):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46804): item=0 name=\"test_file\" objtype=UNKNOWN"},
-  {1302, "audit(1502573858.178:46804): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46804): item=2 name=\"test_file4\" inode=724406 dev=fd:02 mode=0120777 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46804): "},
-  {1300, "audit(1502573858.178:46805): arch=c000003e syscall=82 success=yes exit=0 a0=40219c a1=402215 a2=40220a a3=7fff15c0a7c0 items=4 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46805):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46805): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46805): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46805): item=2 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1302, "audit(1502573858.178:46805): item=3 name=\"test_file_rename\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46805): "},
-  {1300, "audit(1502573858.178:46806): arch=c000003e syscall=264 success=yes exit=0 a0=3 a1=402215 a2=3 a3=40224e items=4 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46806):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46806): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46806): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46806): item=2 name=\"test_file_rename\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1302, "audit(1502573858.178:46806): item=3 name=\"test_file_renameat\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46806): "},
-  {1300, "audit(1502573858.178:46807): arch=c000003e syscall=316 success=yes exit=0 a0=3 a1=40224e a2=3 a3=40219c items=4 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46807):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46807): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46807): item=1 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46807): item=2 name=\"test_file_renameat\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1302, "audit(1502573858.178:46807): item=3 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46807): "},
-  {1300, "audit(1502573858.178:46808): arch=c000003e syscall=87 success=yes exit=0 a0=402191 a1=40224e a2=3 a3=40219c items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46808):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46808): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46808): item=1 name=\"test_file1\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573858.178:46808): "},
-  {1300, "audit(1502573858.178:46809): arch=c000003e syscall=263 success=yes exit=0 a0=3 a1=4021cc a2=0 a3=7fff15c0a7b0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46809):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46809): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46809): item=1 name=\"test_file2\" inode=724389 dev=fd:02 mode=0120777 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=DELETE"},
-  {1320, "audit(1502573858.178:46809): "},
-  {1300, "audit(1502573858.178:46810): arch=c000003e syscall=2 success=yes exit=4 a0=4022c6 a1=42 a2=0 a3=7fff15c0a3a0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46810):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46810): item=0 name=\"/home/alessandro/\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46810): item=1 name=\"/home/alessandro/test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46810): "},
-  {1300, "audit(1502573858.178:46811): arch=c000003e syscall=32 success=yes exit=5 a0=4 a1=42 a2=0 a3=7fff15c0a3a0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.178:46811): "},
-  {1300, "audit(1502573858.178:46812): arch=c000003e syscall=33 success=yes exit=10 a0=4 a1=a a2=0 a3=7fff15c0a3a0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.178:46812): "},
-  {1300, "audit(1502573858.178:46813): arch=c000003e syscall=292 success=yes exit=11 a0=4 a1=b a2=0 a3=7fff15c0a3a0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.178:46813): "},
-  {1300, "audit(1502573858.178:46814): arch=c000003e syscall=3 success=yes exit=0 a0=b a1=b a2=0 a3=7fff15c0a3a0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.178:46814): "},
-  {1300, "audit(1502573858.178:46815): arch=c000003e syscall=257 success=yes exit=6 a0=3 a1=40219c a2=0 a3=0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46815):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46815): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46815): "},
-  {1300, "audit(1502573858.178:46816): arch=c000003e syscall=303 success=yes exit=0 a0=ffffff9c a1=40219c a2=7fff15c0a620 a3=7fff15c0aa2c items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46816):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46816): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46816): "},
-  {1300, "audit(1502573858.178:46817): arch=c000003e syscall=304 success=yes exit=7 a0=ffffff9c a1=7fff15c0a620 a2=2 a3=7fff15c0a3a0 items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46817):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46817): item=0 name="" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46817): "},
-  {1300, "audit(1502573858.178:46818): arch=c000003e syscall=303 success=yes exit=0 a0=3 a1=40219c a2=7fff15c0a620 a3=7fff15c0aa2c items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46818):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46818): item=0 name=\"test_file\" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46818): "},
-  {1300, "audit(1502573858.178:46819): arch=c000003e syscall=304 success=yes exit=8 a0=3 a1=7fff15c0a620 a2=2 a3=7fff15c0aa2c items=1 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46819):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46819): item=0 name="" inode=98362 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=NORMAL"},
-  {1320, "audit(1502573858.178:46819): "},
-  {1300, "audit(1502573858.178:46820): arch=c000003e syscall=133 success=yes exit=0 a0=40242d a1=81a4 a2=0 a3=7fff15c0a380 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46820):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46820): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46820): item=1 name=\"test_file5\" inode=560977 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46820): "},
-  {1300, "audit(1502573858.178:46821): arch=c000003e syscall=259 success=yes exit=0 a0=3 a1=402451 a2=81a4 a3=0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46821):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46821): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46821): item=1 name=\"test_file6\" inode=560986 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46821): "},
-  {1300, "audit(1502573858.178:46822): arch=c000003e syscall=85 success=yes exit=9 a0=402477 a1=81a4 a2=81a4 a3=7fff15c0a3a0 items=2 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1307, "audit(1502573858.178:46822):  cwd=\"/home/alessandro\""},
-  {1302, "audit(1502573858.178:46822): item=0 name=\"/home/alessandro\" inode=67 dev=fd:02 mode=040700 ouid=1000 ogid=1000 rdev=00:00 obj=unconfined_u:object_r:user_home_dir_t:s0 objtype=PARENT"},
-  {1302, "audit(1502573858.178:46822): item=1 name=\"test_file7\" inode=560990 dev=fd:02 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_home_t:s0 objtype=CREATE"},
-  {1320, "audit(1502573858.178:46822): "},
-  {1300, "audit(1502573858.179:46823): arch=c000003e syscall=0 success=yes exit=10 a0=4 a1=7fff15c0a640 a2=a a3=7fff15c0a3c0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.179:46823): "},
-  {1300, "audit(1502573858.179:46824): arch=c000003e syscall=1 success=yes exit=1024 a0=4 a1=7fff15c0a640 a2=400 a3=7fff15c0a3c0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.179:46824): "},
-  {1300, "audit(1502573858.179:46825): arch=c000003e syscall=17 success=yes exit=10 a0=4 a1=7fff15c0a640 a2=a a3=1 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.179:46825): "},
-  {1300, "audit(1502573858.179:46826): arch=c000003e syscall=18 success=yes exit=1024 a0=4 a1=7fff15c0a640 a2=400 a3=1 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.179:46826): "},
-  {1300, "audit(1502573858.179:46827): arch=c000003e syscall=77 success=yes exit=0 a0=4 a1=b a2=400 a3=7fff15c0a7c0 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1320, "audit(1502573858.179:46827): "},
-  {1300, "audit(1502573858.179:46828): arch=c000003e syscall=9 success=yes exit=140095431462912 a0=0 a1=a a2=7 a3=1 items=0 ppid=4316 pid=5581 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm=\"mytest\" exe=\"/home/alessandro/mytest\" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)"},
-  {1323, "audit(1502573858.179:46828): fd=4 flags=0x1"},
-  {1320, "audit(1502573858.179:46828): "}
-};
-// clang-format on
-} // namespace osquery
diff --git a/src/osquery/events/tests/linux/syslog_tests.cpp b/src/osquery/events/tests/linux/syslog_tests.cpp
deleted file mode 100644 (file)
index 25e6720..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include <boost/tokenizer.hpp>
-
-#include "osquery/events/linux/syslog.h"
-#include "osquery/tests/test_util.h"
-
-namespace osquery {
-
-class SyslogTests : public testing::Test {
- public:
-  std::vector<std::string> splitCsv(std::string line) {
-    boost::tokenizer<RsyslogCsvSeparator> tokenizer(line);
-    std::vector<std::string> result(tokenizer.begin(), tokenizer.end());
-    return result;
-  }
-};
-
-TEST_F(SyslogTests, test_populate_event_context) {
-  std::string line =
-      R"|("2016-03-22T21:17:01.701882+00:00","vagrant-ubuntu-trusty-64","6","cron","CRON[16538]:"," (root) CMD (   cd / && run-parts --report /etc/cron.hourly)")|";
-  SyslogEventPublisher pub;
-  auto ec = pub.createEventContext();
-  Status status = pub.populateEventContext(line, ec);
-
-  ASSERT_TRUE(status.ok());
-  // Note: the time-parsing was removed to allow events to auto-assign.
-  ASSERT_EQ(0U, ec->time);
-  ASSERT_EQ("2016-03-22T21:17:01.701882+00:00", ec->fields.at("datetime"));
-  ASSERT_EQ("vagrant-ubuntu-trusty-64", ec->fields.at("host"));
-  ASSERT_EQ("6", ec->fields.at("severity"));
-  ASSERT_EQ("cron", ec->fields.at("facility"));
-  ASSERT_EQ("CRON[16538]", ec->fields.at("tag"));
-  ASSERT_EQ("(root) CMD (   cd / && run-parts --report /etc/cron.hourly)",
-            ec->fields.at("message"));
-
-  // Too few fields
-
-  std::string bad_line =
-      R"("2016-03-22T21:17:01.701882+00:00","vagrant-ubuntu-trusty-64","6","cron",)";
-  ec = pub.createEventContext();
-  status = pub.populateEventContext(bad_line, ec);
-  ASSERT_FALSE(status.ok());
-  ASSERT_NE(std::string::npos, status.getMessage().find("fewer"));
-
-  // Too many fields
-  bad_line = R"("2016-03-22T21:17:01.701882+00:00","","6","","","","")";
-  ec = pub.createEventContext();
-  status = pub.populateEventContext(bad_line, ec);
-  ASSERT_FALSE(status.ok());
-  ASSERT_NE(std::string::npos, status.getMessage().find("more"));
-}
-
-TEST_F(SyslogTests, test_csv_separator) {
-  ASSERT_EQ(std::vector<std::string>({"", "", "", "", ""}), splitCsv(",,,,"));
-  ASSERT_EQ(std::vector<std::string>({" ", " ", " ", " ", " "}),
-            splitCsv(" , , , , "));
-  ASSERT_EQ(std::vector<std::string>({"foo", "bar", "baz"}),
-            splitCsv("foo,bar,baz"));
-  ASSERT_EQ(std::vector<std::string>({"foo", "bar", "baz"}),
-            splitCsv("\"foo\",\"bar\",\"baz\""));
-  ASSERT_EQ(std::vector<std::string>({",foo,", ",bar", "baz,"}),
-            splitCsv("\",foo,\",\",bar\",\"baz,\""));
-  ASSERT_EQ(std::vector<std::string>({",f\\oo,", ",ba\\'r", "baz\\,"}),
-            splitCsv("\",f\\oo,\",\",ba\\'r\",\"baz\\,\""));
-  ASSERT_EQ(std::vector<std::string>({"\",f\\o\"o,", "\",ba\\'r", "baz\\,\""}),
-            splitCsv("\"\"\",f\\o\"\"o,\",\"\"\",ba\\'r\",\"baz\\,\"\"\""));
-  ASSERT_EQ(std::vector<std::string>({"\",f\\ø\"o,", "\",bá\\'r", "baz\\,\""}),
-            splitCsv("\"\"\",f\\ø\"\"o,\",\"\"\",bá\\'r\",\"baz\\,\"\"\""));
-}
-}
diff --git a/src/osquery/include/osquery/events.h b/src/osquery/include/osquery/events.h
deleted file mode 100644 (file)
index 862a70b..0000000
+++ /dev/null
@@ -1,1087 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <atomic>
-#include <functional>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <thread>
-#include <utility>
-#include <vector>
-
-#include <gtest/gtest_prod.h>
-
-#include <osquery/core.h>
-#include <osquery/tables.h>
-#include <osquery/utils/status/status.h>
-#include <osquery/utils/mutex.h>
-
-namespace osquery {
-
-struct Subscription;
-template <class SC, class EC>
-class EventPublisher;
-template <class PUB>
-class EventSubscriber;
-class EventFactory;
-
-using EventID = const std::string;
-using EventContextID = uint64_t;
-using EventTime = uint64_t;
-using EventRecord = std::pair<std::string, EventTime>;
-
-/**
- * @brief An EventPublisher will define a SubscriptionContext for
- * EventSubscriber%s to use.
- *
- * Most EventPublisher%s will require specific information for interacting with
- * an OS to receive events. The SubscriptionContext contains information the
- * EventPublisher will use to register OS API callbacks, create
- * subscriptioning/listening handles, etc.
- *
- * Linux `inotify` should implement a SubscriptionContext that subscribes
- * filesystem events based on a filesystem path. `libpcap` will subscribe on
- * networking protocols at various stacks. Process creation may subscribe on
- * process name, parent pid, etc.
- */
-struct SubscriptionContext : private boost::noncopyable {};
-
-/**
- * @brief An EventSubscriber EventCallback method will receive an EventContext.
- *
- * The EventContext contains the event-related data supplied by an
- * EventPublisher when the event occurs. If a subscribing EventSubscriber
- * would be called for the event, the EventSubscriber%'s EventCallback is
- * passed an EventContext.
- */
-struct EventContext : private boost::noncopyable {
-  /// An unique counting ID specific to the EventPublisher%'s fired events.
-  EventContextID id{0};
-
-  /// The time the event occurred, as determined by the publisher.
-  EventTime time{0};
-};
-
-using SubscriptionRef = std::shared_ptr<Subscription>;
-using BaseEventPublisher = EventPublisher<SubscriptionContext, EventContext>;
-using EventPublisherRef = std::shared_ptr<BaseEventPublisher>;
-using SubscriptionContextRef = std::shared_ptr<SubscriptionContext>;
-using EventContextRef = std::shared_ptr<EventContext>;
-using BaseEventSubscriber = EventSubscriber<BaseEventPublisher>;
-using EventSubscriberRef = std::shared_ptr<EventSubscriber<BaseEventPublisher>>;
-
-/**
- * @brief EventSubscriber%s and Publishers may exist in various states.
- *
- * The class will move through states when osquery is initializing the
- * registry, starting event publisher loops, and requesting initialization of
- * each subscriber and the optional set of subscriptions it creates. If this
- * initialization fails the publishers or EventFactory may eject, warn, or
- * otherwise not use the subscriber's subscriptions.
- *
- * The supported states are:
- * - None: The default state, uninitialized.
- * - Setup: The Subscriber is attached and has run setup.
- * - Running: Subscriber is ready for events.
- * - Paused: Subscriber was initialized but is not currently accepting events.
- * - Failed: Subscriber failed to initialize or is otherwise offline.
- */
-enum class EventState {
-  EVENT_NONE = 0,
-  EVENT_SETUP,
-  EVENT_RUNNING,
-  EVENT_PAUSED,
-  EVENT_FAILED,
-};
-
-/// Use a single placeholder for the EventContextRef passed to EventCallback.
-using EventCallback = std::function<Status(const EventContextRef&,
-                                           const SubscriptionContextRef&)>;
-
-/// An EventPublisher must track every subscription added.
-using SubscriptionVector = std::vector<SubscriptionRef>;
-
-/// The set of search-time binned lookup tables.
-extern const std::vector<size_t> kEventTimeLists;
-
-/**
- * @brief Details for each subscriber as it relates to the schedule.
- *
- * This is populated for each configuration update by scanning the schedule.
- */
-struct SubscriberExpirationDetails {
- public:
-  /// The max internal is the minimum wait time for expiring subscriber data.
-  size_t max_interval{0};
-
-  /// The number of queries that should run between intervals.
-  size_t query_count{0};
-};
-
-/**
- * @brief DECLARE_PUBLISHER supplies needed boilerplate code that applies a
- * string-type EventPublisherID to identify the publisher declaration.
- */
-#define DECLARE_PUBLISHER(TYPE)                                                \
- public:                                                                       \
-  const std::string type() const override final {                              \
-    return TYPE;                                                               \
-  }
-
-/**
- * @brief A Subscription is used to configure an EventPublisher and bind a
- * callback to a SubscriptionContext.
- *
- * A Subscription is the input to an EventPublisher when the EventPublisher
- * decides on the scope and details of the events it watches/generates.
- * An example includes a filesystem change event. A subscription would include
- * a path with optional recursion and attribute selectors as well as a callback
- * function to fire when an event for that path and selector occurs.
- *
- * A Subscription also functions to greatly scope an EventPublisher%'s work.
- * Using the same filesystem example and the Linux inotify subsystem a
- * Subscription limits the number of inode watches to only those requested by
- * appropriate EventSubscriber%s.
- * Note: EventSubscriber%s and Subscriptions can be configured by the osquery
- * user.
- *
- * Subscriptions are usually created with EventFactory members:
- *
- * @code{.cpp}
- *   EventFactory::addSubscription("MyEventPublisher", my_subscription_context);
- * @endcode
- */
-struct Subscription : private boost::noncopyable {
- public:
-  // EventSubscriber name.
-  std::string subscriber_name;
-
-  /// An EventPublisher%-specific SubscriptionContext.
-  SubscriptionContextRef context;
-
-  /// An EventSubscription member EventCallback method.
-  EventCallback callback;
-
-  explicit Subscription(std::string name) : subscriber_name(std::move(name)){};
-
-  static SubscriptionRef create(const std::string& name) {
-    return std::make_shared<Subscription>(name);
-  }
-
-  static SubscriptionRef create(const std::string& name,
-                                const SubscriptionContextRef& mc,
-                                EventCallback ec = nullptr) {
-    auto subscription = std::make_shared<Subscription>(name);
-    subscription->context = mc;
-    subscription->callback = std::move(ec);
-    return subscription;
-  }
-
- public:
-  Subscription() = delete;
-};
-
-class Eventer {
- public:
-  /**
-   * @brief Request the subscriber's initialization state.
-   *
-   * When event subscribers are created (initialized) they are expected to emit
-   * a set of subscriptions to their publisher "type". If the subscriber fails
-   * to initialize then the publisher may remove any intermediate subscriptions.
-   */
-  EventState state() const {
-    return state_;
-  }
-
- protected:
-  /// Set the subscriber state.
-  void state(EventState state) {
-    state_ = state;
-  }
-
- private:
-  /// The event subscriber's run state.
-  EventState state_{EventState::EVENT_NONE};
-
-  friend class EventFactory;
-};
-
-class EventPublisherPlugin : public Plugin,
-                             public Eventer {
- public:
-  /**
-   * @brief A new Subscription was added, potentially change state based on all
-   * subscriptions for this EventPublisher.
-   *
-   * `configure` allows the EventPublisher to optimize on the state of all
-   * subscriptions. An example is Linux `inotify` where multiple
-   * EventSubscription%s will subscription identical paths, e.g., /etc for
-   * config changes. Since Linux `inotify` has a subscription limit, `configure`
-   * can dedup paths.
-   */
-  void configure() override{};
-
-  /**
-   * @brief Perform handle opening, OS API callback registration.
-   *
-   * `setUp` is the event framework's EventPublisher constructor equivalent.
-   * This is called in the main thread before the publisher's run loop has
-   * started, immediately following registration.
-   */
-  Status setUp() override {
-    return Status::success();
-  }
-
-  /**
-   * @brief Perform handle closing, resource cleanup.
-   *
-   * osquery is about to end, the EventPublisher should close handle descriptors
-   * unblock resources, and prepare to exit. This will be called from the main
-   * thread after the run loop thread has exited.
-   */
-  void tearDown() override {}
-
-  /**
-   * @brief Implement a "step" of an optional run loop.
-   *
-   * @return A SUCCESS status will immediately call `run` again. A FAILED status
-   * will exit the run loop and the thread.
-   */
-  virtual Status run() {
-    return Status(1, "No run loop required");
-  }
-
-  /// This is a plugin type and must implement a call method.
-  Status call(const PluginRequest& /*request*/,
-              PluginResponse& /*response*/) override {
-    return Status(0);
-  }
-
-  /**
-   * @brief A new EventSubscriber is subscribing events of this publisher type.
-   *
-   * @param subscription The Subscription context information and optional
-   * EventCallback.
-   *
-   * @return If the Subscription is not appropriate (mismatched type) fail.
-   */
-  virtual Status addSubscription(const SubscriptionRef& subscription);
-
-  /// Remove all subscriptions from a named subscriber.
-  virtual void removeSubscriptions(const std::string& subscriber);
-
- public:
-  /// Overriding the EventPublisher constructor is not recommended.
-  EventPublisherPlugin() = default;
-  ~EventPublisherPlugin() override = default;
-
-  /// Return a string identifier associated with this EventPublisher.
-  virtual const std::string type() const {
-    return getName();
-  }
-
- public:
-  /// Number of Subscription%s watching this EventPublisher.
-  size_t numSubscriptions();
-
-  /**
-   * @brief The number of events fired by this EventPublisher.
-   *
-   * @return The number of events.
-   */
-  EventContextID numEvents() const;
-
-  /// Check if the EventFactory is ending all publisher threads.
-  bool isEnding() const {
-    return ending_;
-  }
-
-  /// Set the ending status for this publisher.
-  void isEnding(bool ending) {
-    ending_ = ending;
-  }
-
-  /// Check if the publisher's run loop has started.
-  bool hasStarted() const {
-    return started_;
-  }
-
-  /// Set the run or started status for this publisher.
-  void hasStarted(bool started) {
-    started_ = started;
-  }
-
-  /// Get the number of publisher restarts.
-  size_t restartCount() const {
-    return restart_count_;
-  }
-
- public:
-  explicit EventPublisherPlugin(EventPublisherPlugin const&) = delete;
-  EventPublisherPlugin& operator=(EventPublisherPlugin const&) = delete;
-
- protected:
-  /**
-   * @brief The generic check loop to call SubscriptionContext callback methods.
-   *
-   * It is NOT recommended to override `fire`. The simple logic of enumerating
-   * the Subscription%s and using `shouldFire` is more appropriate.
-   *
-   * @param ec The EventContext created and fired by the EventPublisher.
-   * @param time The most accurate time associated with the event.
-   */
-  void fire(const EventContextRef& ec, EventTime time = 0);
-
-  /// The internal fire method used by the typed EventPublisher.
-  virtual void fireCallback(const SubscriptionRef& sub,
-                            const EventContextRef& ec) const = 0;
-
-  /// A lock for subscription manipulation.
-  mutable Mutex subscription_lock_;
-
-  /// The EventPublisher will keep track of Subscription%s that contain callins.
-  SubscriptionVector subscriptions_;
-
-  /// An Event ID is assigned by the EventPublisher within the EventContext.
-  /// This is not used to store event date in the backing store.
-  std::atomic<EventContextID> next_ec_id_{0};
-
- private:
-  /// Set ending to True to cause event type run loops to finish.
-  std::atomic<bool> ending_{false};
-
-  /// Set to indicate whether the event run loop ever started.
-  std::atomic<bool> started_{false};
-
-  /// A helper count of event publisher runloop iterations.
-  std::atomic<size_t> restart_count_{0};
-
- private:
-  /// Enable event factory "callins" through static publisher callbacks.
-  friend class EventFactory;
-
- private:
-  FRIEND_TEST(EventsTests, test_event_publisher);
-  FRIEND_TEST(EventsTests, test_fire_event);
-};
-
-class EventSubscriberPlugin : public Plugin, public Eventer {
- public:
-  /**
-   * @brief Add Subscription%s to the EventPublisher this module will act on.
-   *
-   * When the EventSubscriber%'s `init` method is called you are assured the
-   * EventPublisher has `setUp` and is ready to subscription for events.
-   */
-  virtual Status init() {
-    return Status(0);
-  }
-
-  /// This is a plugin type and must implement a call method.
-  Status call(const PluginRequest& /*request*/,
-              PluginResponse& /*response*/) override {
-    return Status(0);
-  }
-
- protected:
-  /**
-   * @brief Store parsed event data from an EventCallback in a backing store.
-   *
-   * This method stores a single event
-   *
-   * @param r The row to add
-   *
-   * @return Was the element added to the backing store.
-   */
-  Status add(const Row& r);
-
-  /**
-   * @brief Store parsed event data from an EventCallback in a backing store.
-   *
-   * Within a EventCallback the EventSubscriber has an opportunity to create
-   * an osquery Row element, add the relevant table data for the EventSubscriber
-   * and store that element in the osquery backing store. At query-time
-   * the added data will apply selection criteria and return these elements.
-   * The backing store data retrieval is optimized by time-based indexes. It
-   * is important to added EventTime as it relates to "when the event occurred".
-   *
-   * @param row_list A (writable) vector of osquery Row elements.
-   *
-   * @return Was the element added to the backing store.
-   */
-  Status addBatch(std::vector<Row>& row_list);
-
- private:
-  /// Overload add for tests and allow them to override the event time.
-  virtual Status addBatch(std::vector<Row>& row_list,
-                          EventTime custom_event_time) final;
-
- private:
-  /*
-   * @brief When `get`ing event results, return EventID%s from time indexes.
-   *
-   * Used by EventSubscriber::get to retrieve EventID, EventTime indexes. This
-   * applies the lookup-efficiency checks for time list appropriate bins.
-   * If the time range in 24 hours and there is a 24-hour list bin it will
-   * be queried using a single backing store `Get` followed by two `Get`s of
-   * the most-specific boundary lists.
-   *
-   * @param index the set of index to scan.
-   * @param optimize if true apply optimization checks.
-   *
-   * @return List of EventID, EventTime%s
-   */
-  std::vector<EventRecord> getRecords(const std::vector<std::string>& indexes,
-                                      bool optimize = true);
-
-  /**
-   * @brief Get a unique storage-related EventID.
-   *
-   * An EventID is an index/element-identifier for the backing store.
-   * Each EventPublisher maintains a fired EventContextID to identify the many
-   * events that may or may not be fired based on subscription criteria for this
-   * EventSubscriber. This EventContextID is NOT the same as an EventID.
-   * EventSubscriber development should not require use of EventID%s. If this
-   * indexing is required within-EventCallback consider an
-   * EventSubscriber%-unique indexing, counting mechanic.
-   *
-   * @return A unique ID for backing storage.
-   */
-  const std::string getEventID();
-
-  /**
-   * @brief Plan the best set of indexes for event record access.
-   *
-   * @param start an inclusive time to begin searching.
-   * @param stop an inclusive time to end searching.
-   * @param sort if true the indexes will be sorted.
-   *
-   * @return List of 'index.step' index strings.
-   */
-  std::vector<std::string> getIndexes(EventTime start,
-                                      EventTime stop,
-                                      bool sort = true);
-
-  /**
-   * @brief Expire indexes and eventually records.
-   *
-   * @param list_type the string representation of list binning type.
-   * @param indexes complete set of 'index.step' indexes for the list_type.
-   * @param expirations of the indexes, the set to expire.
-   */
-  void expireIndexes(const std::string& list_type,
-                     const std::vector<std::string>& indexes,
-                     const std::vector<std::string>& expirations);
-
-  /// Expire all datums within a bin.
-  void expireRecords(const std::string& list_type,
-                     const std::string& index,
-                     bool all);
-
-  /**
-   * @brief Inspect the number of events, expire those overflowing events_max.
-   *
-   * When the event manager starts, or after a checkpoint number of events,
-   * the EventFactory will call expireCheck for each subscriber.
-   *
-   * The subscriber must count the number of buffered records and check if
-   * that count exceeds the configured `events_max` limit. If an overflow
-   * occurs the subscriber will expire N-events_max from the end of the queue.
-   */
-  void expireCheck();
-
-  /**
-   * @brief Add an EventID, EventTime pair to all matching list types.
-   *
-   * The list types are defined by time size. Based on the EventTime this pair
-   * is added to the list bin for each list type. If there are two list types:
-   * 60 seconds and 3600 seconds and `time` is 92, this pair will be added to
-   * list type 1 bin 4 and list type 2 bin 1.
-   *
-   * @param event_id_list A vector of (unique) EventIDs
-   * @param event_time The event time for this batch
-   *
-   * @return Were the indexes recorded.
-   */
-
-  Status recordEvents(const std::vector<std::string>& event_id_list,
-                      EventTime event_time);
-
-  /**
-   * @brief Get the expiration timeout for this event type
-   *
-   * The default implementation retrieves this value from FLAGS_events_expiry.
-   * This method can be overridden to allow custom event expiration timeouts in
-   * subclasses of EventSubscriberPlugin.
-   *
-   * @return The events expiration timeout for this event type
-   */
-  virtual size_t getEventsExpiry();
-
-  /**
-   * @brief Get the max number of events for this event type
-   *
-   * The default implementation retrieves this value from FLAGS_events_max.
-   * This method can be overridden to allow custom max event numbers in
-   * subclasses of EventSubscriberPlugin.
-   *
-   * @return The max number of events for this event type
-   */
-  virtual size_t getEventsMax();
-
- public:
-  /**
-   * @brief A single instance requirement for static callback facilities.
-   *
-   * The EventSubscriber constructor is NOT responsible for adding
-   * Subscription%s. Please use `init` for adding Subscription%s as all
-   * EventPublisher instances will have run `setUp` and initialized their run
-   * loops.
-   */
-  EventSubscriberPlugin()
-      : expire_events_(true), expire_time_(0), optimize_time_(0) {}
-  ~EventSubscriberPlugin() override = default;
-
-  /// Number of Subscription%s this EventSubscriber has used.
-  size_t numSubscriptions() const {
-    return subscription_count_;
-  }
-
-  /// The number of events this EventSubscriber has received.
-  EventContextID numEvents() const {
-    return event_count_;
-  }
-
-  /// Compare the number of queries run against the queries configured.
-  bool executedAllQueries() const;
-
- public:
-  explicit EventSubscriberPlugin(EventSubscriberPlugin const&) = delete;
-  EventSubscriberPlugin& operator=(EventSubscriberPlugin const&) = delete;
-
- protected:
-  /**
-   * @brief Backing storage indexing namespace.
-   *
-   * The backing storage will accumulate events for this subscriber. A namespace
-   * is provided to prevent event indexing collisions between subscribers and
-   * publishers. The namespace is a combination of the publisher and subscriber
-   * registry plugin names.
-   */
-  /// See getType for lookup rational.
-  virtual const std::string dbNamespace() const {
-    return getType() + '.' + getName();
-  }
-
-  /// Disable event expiration for this subscriber.
-  void doNotExpire() {
-    expire_events_ = false;
-  }
-
-  /// Trampoline into the EventFactory and lookup the name of the publisher.
-  virtual const std::string& getType() const = 0;
-
-  /// Get a handle to the EventPublisher.
-  EventPublisherRef getPublisher() const;
-
-  /// Remove all subscriptions from this subscriber.
-  void removeSubscriptions();
-
- protected:
-  /// A helper value counting the number of fired events tracked by publishers.
-  EventContextID event_count_{0};
-
-  /// A helper value counting the number of subscriptions created.
-  size_t subscription_count_{0};
-
- private:
-  Status setUp() override {
-    return Status::success();
-  }
-
- private:
-  /// Do not respond to periodic/scheduled/triggered event expiration requests.
-  bool expire_events_{false};
-
-  /// Events before the expire_time_ are invalid and will be purged.
-  EventTime expire_time_{0};
-
-  /// Cached value of last generated EventID.
-  size_t last_eid_{0};
-
-  /**
-   * @brief Optimize subscriber selects by tracking the last select time.
-   *
-   * Event subscribers may optimize selects when used in a daemon schedule by
-   * requiring an event 'time' constraint and otherwise applying a minimum time
-   * as the last time the scheduled query ran.
-   */
-  EventTime optimize_time_{0};
-
-  /**
-   * @brief Last event ID returned while using events-optimization.
-   *
-   * A time with second precision is not sufficient, but it works for index
-   * retrieval. While sorting using the time optimization, discard events
-   * before or equal to the optimization ID.
-   */
-  size_t optimize_eid_{0};
-
-  /// The minimum acceptable expiration, based on the query schedule.
-  std::atomic<size_t> min_expiration_{0};
-
-  /// The number of scheduled queries using this subscriber.
-  std::atomic<size_t> query_count_{0};
-
-  /// Set of queries that have used this subscriber table.
-  std::set<std::string> queries_;
-
-  /// Lock used when incrementing the EventID database index.
-  Mutex event_id_lock_;
-
-  /// Lock used when recording an EventID and time into search bins.
-  Mutex event_record_lock_;
-
-  /// Lock used when recording queries executing against this subscriber.
-  mutable Mutex event_query_record_;
-
- private:
-  friend class EventFactory;
-  friend class EventPublisherPlugin;
-
- private:
-  FRIEND_TEST(EventsDatabaseTests, test_event_module_id);
-  FRIEND_TEST(EventsDatabaseTests, test_record_indexing);
-  FRIEND_TEST(EventsDatabaseTests, test_record_range);
-  FRIEND_TEST(EventsDatabaseTests, test_record_expiration);
-  FRIEND_TEST(EventsDatabaseTests, test_gentable);
-  FRIEND_TEST(EventsDatabaseTests, test_expire_check);
-  FRIEND_TEST(EventsDatabaseTests, test_optimize);
-  FRIEND_TEST(EventsDatabaseTests, test_record_corruption);
-  FRIEND_TEST(EventsTests, test_event_subscriber_configure);
-  friend class DBFakeEventSubscriber;
-  friend class BenchmarkEventSubscriber;
-};
-
-/**
- * @brief A factory for associating event generators to EventPublisherID%s.
- *
- * This factory both registers new event types and the subscriptions that use
- * them. An EventPublisher is also a factory, the single event factory
- * arbitrates Subscription creation and management for each associated
- * EventPublisher.
- *
- * Since event types may be plugins, they are created using the factory.
- * Since subscriptions may be configured/disabled they are also factory-managed.
- */
-class EventFactory : private boost::noncopyable {
- public:
-  /// Access to the EventFactory instance.
-  static EventFactory& getInstance();
-
-  /**
-   * @brief Add an EventPublisher to the factory.
-   *
-   * The registration is mostly abstracted using osquery's registry.
-   *
-   * @param pub If for some reason the caller needs access to the
-   * EventPublisher instance they can register-by-instance.
-   *
-   * Access to the EventPublisher instance is not discouraged, but using the
-   * EventFactory `getEventPublisher` accessor is encouraged.
-   */
-  static Status registerEventPublisher(const PluginRef& pub);
-
-  /**
-   * @brief Add an EventSubscriber to the factory.
-   *
-   * The registration is mostly abstracted using osquery's registry.
-   */
-  template <class T>
-  static Status registerEventSubscriber() {
-    auto sub = std::make_shared<T>();
-    return registerEventSubscriber(sub);
-  };
-
-  /**
-   * @brief Add an EventSubscriber to the factory.
-   *
-   * The registration is mostly abstracted using osquery's registry.
-   *
-   * @param sub If the caller must access the EventSubscriber instance
-   * control may be passed to the registry.
-   *
-   * Access to the EventSubscriber instance outside of the within-instance
-   * table generation method and set of EventCallback%s is discouraged.
-   */
-  static Status registerEventSubscriber(const PluginRef& sub);
-
-  /**
-   * @brief Add a SubscriptionContext and EventCallback Subscription to an
-   * EventPublisher.
-   *
-   * Create a Subscription from a given SubscriptionContext and EventCallback
-   * and add that Subscription to the EventPublisher associated identifier.
-   *
-   * @param type_id ID string for an EventPublisher receiving the Subscription.
-   * @param name_id ID string for the EventSubscriber.
-   * @param sc A SubscriptionContext related to the EventPublisher.
-   * @param cb When the EventPublisher fires an event the SubscriptionContext
-   * will be evaluated, if the event matches optional specifics in the context
-   * this callback function will be called. It should belong to an
-   * EventSubscription.
-   *
-   * @return Was the SubscriptionContext appropriate for the EventPublisher.
-   */
-  static Status addSubscription(const std::string& type_id,
-                                const std::string& name_id,
-                                const SubscriptionContextRef& sc,
-                                EventCallback cb = nullptr);
-
-  /// Add a Subscription using a caller Subscription instance.
-  static Status addSubscription(const std::string& type_id,
-                                const SubscriptionRef& subscription);
-
-  /// Get the total number of Subscription%s across ALL EventPublisher%s.
-  static size_t numSubscriptions(const std::string& type_id);
-
-  /// Get the number of EventPublishers.
-  static size_t numEventPublishers() {
-    return EventFactory::getInstance().event_pubs_.size();
-  }
-
-  /**
-   * @brief Halt the EventPublisher run loop.
-   *
-   * Any EventSubscriber%s with Subscription%s for this EventPublisher will
-   * become useless. osquery callers MUST deregister events.
-   * EventPublisher%s assume they can hook/trampoline, which requires cleanup.
-   * This will tear down and remove the publisher if the run loop did not start.
-   * Otherwise it will call end on the publisher and assume the run loop will
-   * tear down and remove.
-   *
-   * @param pub The string label for the EventPublisher.
-   *
-   * @return Did the EventPublisher deregister cleanly.
-   */
-  static Status deregisterEventPublisher(const EventPublisherRef& pub);
-
-  /// Deregister an EventPublisher by publisher name.
-  static Status deregisterEventPublisher(const std::string& type_id);
-
-  /// Deregister an EventSubscriber by the subscriber name.
-  static Status deregisterEventSubscriber(const std::string& sub);
-
-  /// Return an instance to a registered EventPublisher.
-  static EventPublisherRef getEventPublisher(const std::string& pub);
-
-  /// Return an instance to a registered EventSubscriber.
-  static EventSubscriberRef getEventSubscriber(const std::string& sub);
-
-  /// Check if an event subscriber exists.
-  static bool exists(const std::string& sub);
-
-  /// Return a list of publisher types, these are their registry names.
-  static std::vector<std::string> publisherTypes();
-
-  /// Return a list of subscriber registry names,
-  static std::vector<std::string> subscriberNames();
-
-  /// Set log forwarding by adding a logger receiver.
-  static void addForwarder(const std::string& logger);
-
-  /// Optionally forward events to loggers.
-  static void forwardEvent(const std::string& event);
-
-  /**
-   * @brief The event factory, subscribers, and publishers respond to updates.
-   *
-   * This should be called by the Config instance when configuration data is
-   * updated. It is separate from the config parser that takes configuration
-   * information specific to events and acts. This allows the event factory
-   * to make changes relative to the schedule or packs.
-   */
-  static void configUpdate();
-
- public:
-  /// The dispatched event thread's entry-point (if needed).
-  static Status run(const std::string& type_id);
-
-  /// An initializer's entry-point for spawning all event type run loops.
-  static void delay();
-
-  /// If a static EventPublisher callback wants to fire
-  template <typename PUB>
-  static void fire(const EventContextRef& ec) {
-    auto event_pub = getEventPublisher(getType<PUB>());
-    event_pub->fire(ec);
-  }
-
-  /**
-   * @brief Return the publisher registry name given a type.
-   *
-   * Subscriber initialization and runtime static callbacks can lookup the
-   * publisher type name, which is the registry plugin name. This allows static
-   * callbacks to fire into subscribers.
-   */
-  template <class PUB>
-  static const std::string getType() {
-    auto pub = std::make_shared<PUB>();
-    return pub->type();
-  }
-
-  /**
-   * @brief End all EventPublisher run loops and deregister.
-   *
-   * End is NOT the same as deregistration. End will call deregister on all
-   * publishers then either join or detach their run loop threads.
-   * See EventFactory::deregisterEventPublisher for actions taken during
-   * deregistration.
-   *
-   * @param join if true, threads will be joined
-   */
-  static void end(bool join = false);
-
- public:
-  EventFactory(EventFactory const&) = delete;
-  EventFactory& operator=(EventFactory const&) = delete;
-
- private:
-  /// An EventFactory will exist for the lifetime of the application.
-  EventFactory() = default;
-  ~EventFactory() = default;
-
- private:
-  /// Set of registered EventPublisher instances.
-  std::map<std::string, EventPublisherRef> event_pubs_;
-
-  /// Set of instantiated EventSubscriber subscriptions.
-  std::map<std::string, EventSubscriberRef> event_subs_;
-
-  /// Set of running EventPublisher run loop threads.
-  std::vector<std::shared_ptr<std::thread>> threads_;
-
-  /// Set of logger plugins to forward events.
-  std::vector<std::string> loggers_;
-
-  /// Factory publisher state manipulation.
-  Mutex factory_lock_;
-};
-
-/**
- * @brief Generate OS events of a type (FS, Network, Syscall, ioctl).
- *
- * A 'class' of OS events is abstracted into an EventPublisher responsible for
- * remaining as agile as possible given a known-set of subscriptions.
- *
- * The life cycle of an EventPublisher may include, `setUp`, `configure`, `run`,
- * `tearDown`, and `fire`. `setUp` and `tearDown` happen when osquery starts and
- * stops either as a daemon or interactive shell. `configure` is a pseudo-start
- * called every time a Subscription is added. EventPublisher%s can adjust their
- * scope/agility specific to each added subscription by overriding
- *`addSubscription`, and/or globally in `configure`.
- *
- * Not all EventPublisher%s leverage pure async OS APIs, and most will require a
- * run loop either polling with a timeout on a descriptor or for a change. When
- * osquery initializes the EventFactory will optionally create a thread for each
- * EventPublisher using `run` as the thread's entrypoint. `run` is called in a
- * within-thread loop where returning a FAILED status ends the run loop and
- * shuts down the thread.
- *
- * To opt-out of polling in a thread, consider the following run implementation:
- *
- * @code{.cpp}
- *   Status run() { return Status(1, "Not Implemented"); }
- * @endcode
- *
- * The final life cycle component, `fire` will iterate over the EventPublisher
- * Subscription%s and call `shouldFire` for each, using the EventContext fired.
- * The `shouldFire` method should check the subscription-specific selectors and
- * only call the Subscription%'s callback function if the EventContext
- * (thus event) matches.
- */
-template <typename SC, typename EC>
-class EventPublisher : public EventPublisherPlugin {
- public:
-  /// A nested helper typename for the templated SubscriptionContextRef.
-  using SCRef = typename std::shared_ptr<SC>;
-  /// A nested helper typename for the templated EventContextRef.
-  using ECRef = typename std::shared_ptr<EC>;
-
- public:
-  EventPublisher() = default;
-  ~EventPublisher() override = default;
-
-  /// Up-cast a base EventContext reference to the templated ECRef.
-  static ECRef getEventContext(const EventContextRef& ec) {
-    return std::static_pointer_cast<EC>(ec);
-  };
-
-  /// Up-cast a base SubscriptionContext reference to the templated SCRef.
-  static SCRef getSubscriptionContext(const SubscriptionContextRef& sc) {
-    return std::static_pointer_cast<SC>(sc);
-  }
-
-  /// Create a EventContext based on the templated type.
-  static ECRef createEventContext() {
-    return std::make_shared<EC>();
-  }
-
-  /// Create a SubscriptionContext based on the templated type.
-  static SCRef createSubscriptionContext() {
-    return std::make_shared<SC>();
-  }
-
- protected:
-  /**
-   * @brief The internal `fire` phase of publishing.
-   *
-   * This is a template-generated method that up-casts the generic fired
-   * event/subscription contexts, and calls the callback if the event should
-   * fire given a subscription.
-   *
-   * @param sub The SubscriptionContext and optional EventCallback.
-   * @param ec The event that was fired.
-   */
-  void fireCallback(const SubscriptionRef& sub,
-                    const EventContextRef& ec) const override {
-    auto pub_sc = getSubscriptionContext(sub->context);
-    auto pub_ec = getEventContext(ec);
-    if (shouldFire(pub_sc, pub_ec) && sub->callback != nullptr) {
-      sub->callback(pub_ec, pub_sc);
-    }
-  }
-
- protected:
-  /**
-   * @brief The generic `fire` will call `shouldFire` for each Subscription.
-   *
-   * @param sc A SubscriptionContext with optional specifications for events
-   * details.
-   * @param ec The event fired with event details.
-   *
-   * @return should the Subscription%'s EventCallback be called for this event.
-   */
-  virtual bool shouldFire(const SCRef& sc, const ECRef& ec) const {
-    (void)sc;
-    (void)ec;
-    return true;
-  }
-
- private:
-  FRIEND_TEST(EventsTests, test_event_subscriber_subscribe);
-  FRIEND_TEST(EventsTests, test_event_subscriber_context);
-  FRIEND_TEST(EventsTests, test_fire_event);
-};
-
-/**
- * @brief An interface binding Subscriptions, event response, and table
- *generation.
- *
- * Use the EventSubscriber interface when adding event subscriptions and
- * defining callin functions. The EventCallback is usually a member function
- * for an EventSubscriber. The EventSubscriber interface includes a very
- * important `add` method that abstracts the needed event to backing store
- * interaction.
- *
- * Storing event data in the backing store must match a table spec for queries.
- * Small overheads exist that help query-time indexing and lookups.
- */
-template <class PUB>
-class EventSubscriber : public EventSubscriberPlugin {
- protected:
-  using SCRef = typename PUB::SCRef;
-  using ECRef = typename PUB::ECRef;
-
- public:
-  /**
-   * @brief The registry plugin name for the subscriber's publisher.
-   *
-   * During event factory initialization the subscribers 'peek' at the registry
-   * plugin name assigned to publishers. The corresponding publisher name is
-   * interpreted as the subscriber's event 'type'.
-   */
-  const std::string& getType() const override {
-    static const std::string type = EventFactory::getType<PUB>();
-    return type;
-  };
-
- protected:
-  /// Helper function to call the publisher's templated subscription generator.
-  SCRef createSubscriptionContext() const {
-    return PUB::createSubscriptionContext();
-  }
-
-  /**
-   * @brief Bind a registered EventSubscriber member function to a Subscription.
-   *
-   * @param entry A templated EventSubscriber member function.
-   * @param sc The subscription context.
-   */
-  template <class T, typename E>
-  void subscribe(Status (T::*entry)(const std::shared_ptr<E>&, const SCRef&),
-                 const SCRef& sc) {
-    using std::placeholders::_1;
-    using std::placeholders::_2;
-    using CallbackFunc =
-        Status (T::*)(const EventContextRef&, const SubscriptionContextRef&);
-
-    // Down-cast the pointer to the member function.
-    auto base_entry = reinterpret_cast<CallbackFunc>(entry);
-    // Up-cast the EventSubscriber to the caller.
-    auto sub = dynamic_cast<T*>(this);
-    if (base_entry != nullptr && sub != nullptr) {
-      // Create a callable through the member function using the instance of the
-      // EventSubscriber and a single parameter placeholder (the EventContext).
-      auto cb = std::bind(base_entry, sub, _1, _2);
-      // Add a subscription using the callable and SubscriptionContext.
-      Status stat =
-          EventFactory::addSubscription(sub->getType(), sub->getName(), sc, cb);
-      if (stat.ok()) {
-        subscription_count_++;
-      }
-    }
-  }
-
- public:
-  explicit EventSubscriber(bool enabled = true)
-      : EventSubscriberPlugin(), disabled(!enabled) {}
-  ~EventSubscriber() override = default;
-
- protected:
-  /**
-   * @brief Allow subscriber implementations to default disable themselves.
-   *
-   * A subscriber may induce latency on a system within the callback routines.
-   * Before the initialization and set up is performed the EventFactory can
-   * choose to exclude a subscriber if it is not explicitly enabled within
-   * the config.
-   *
-   * EventSubscriber%s that should be default-disabled should set this flag
-   * in their constructor or worst case before EventSubsciber::init.
-   */
-  bool disabled{false};
-
- private:
-  friend class EventFactory;
-
- private:
-  FRIEND_TEST(EventsTests, test_event_sub);
-  FRIEND_TEST(EventsTests, test_event_sub_subscribe);
-  FRIEND_TEST(EventsTests, test_event_sub_context);
-  FRIEND_TEST(EventsTests, test_event_toggle_subscribers);
-};
-
-/// Iterate the event publisher registry and create run loops for each using
-/// the event factory.
-void attachEvents();
-} // namespace osquery
index 55aa29e4a1ae14cb429a233962611865d3cad67b..c41e3c92af0be387752842a72ce652d28facfb7a 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <osquery/data_logger.h>
 #include <osquery/database.h>
-#include <osquery/events.h>
 #include <osquery/filesystem/filesystem.h>
 #include <osquery/flags.h>
 #include <osquery/plugins/logger.h>
@@ -43,15 +42,6 @@ FLAG(bool, disable_logging, false, "Disable ERROR/INFO logging");
 
 FLAG(string, logger_plugin, "filesystem", "Logger plugin name");
 
-/// Log each added or removed line individually, as an "event".
-FLAG(bool, logger_event_type, true, "Log scheduled results as events");
-
-/// Log each row from a snapshot query individually, as an "event".
-FLAG(bool,
-     logger_snapshot_event_type,
-     false,
-     "Log scheduled snapshot results as events");
-
 /// Alias for the minloglevel used internally by GLOG.
 FLAG(int32, logger_min_status, 0, "Minimum level for status log recording");
 
@@ -274,10 +264,6 @@ void initLogger(const std::string& name) {
       // return a success status after initialization.
       BufferedLogSink::get().addPlugin(logger);
     }
-
-    if ((status.getCode() & LOGGER_FEATURE_LOGEVENT) > 0) {
-      EventFactory::addForwarder(logger);
-    }
   }
 
   if (forward) {
@@ -408,13 +394,10 @@ Status logQueryLogItem(const QueryLogItem& results,
 
   std::vector<std::string> json_items;
   Status status;
-  if (FLAGS_logger_event_type) {
-    status = serializeQueryLogItemAsEventsJSON(results, json_items);
-  } else {
-    std::string json;
-    status = serializeQueryLogItemJSON(results, json);
-    json_items.emplace_back(json);
-  }
+  std::string json;
+  status = serializeQueryLogItemJSON(results, json);
+  json_items.emplace_back(json);
+
   if (!status.ok()) {
     return status;
   }
@@ -432,13 +415,10 @@ Status logSnapshotQuery(const QueryLogItem& item) {
 
   std::vector<std::string> json_items;
   Status status;
-  if (FLAGS_logger_snapshot_event_type) {
-    status = serializeQueryLogItemAsEventsJSON(item, json_items);
-  } else {
-    std::string json;
-    status = serializeQueryLogItemJSON(item, json);
-    json_items.emplace_back(json);
-  }
+  std::string json;
+  status = serializeQueryLogItemJSON(item, json);
+  json_items.emplace_back(json);
+
   if (!status.ok()) {
     return status;
   }
index df511bb833a13f048d475d03c381f0636bd52b33..83b2c5428c03cf5a75525f15b3b72b0cad2fe83c 100644 (file)
@@ -26,8 +26,6 @@ DECLARE_int32(logger_min_status);
 DECLARE_int32(logger_min_stderr);
 DECLARE_bool(logger_secondary_status_only);
 DECLARE_bool(logger_status_sync);
-DECLARE_bool(logger_event_type);
-DECLARE_bool(logger_snapshot_event_type);
 DECLARE_bool(disable_logging);
 DECLARE_bool(log_numerics_as_numbers);
 
@@ -284,10 +282,8 @@ TEST_F(LoggerTests, test_logger_snapshots) {
   logSnapshotQuery(item);
   EXPECT_EQ(2U, LoggerTests::snapshot_rows_added);
 
-  FLAGS_logger_snapshot_event_type = true;
   logSnapshotQuery(item);
   EXPECT_EQ(4U, LoggerTests::snapshot_rows_added);
-  FLAGS_logger_snapshot_event_type = false;
 }
 
 class SecondTestLoggerPlugin : public LoggerPlugin {
@@ -357,11 +353,9 @@ TEST_F(LoggerTests, test_logger_scheduled_query) {
   EXPECT_EQ(1U, LoggerTests::log_lines.size());
 
   // The entire removed/added is one event when result events is false.
-  FLAGS_logger_event_type = false;
   item.results.removed.push_back({{"test_column", "test_new_value\n"}});
   logQueryLogItem(item);
   EXPECT_EQ(2U, LoggerTests::log_lines.size());
-  FLAGS_logger_event_type = true;
 
   // Now the two removed will be individual events.
   logQueryLogItem(item);
index aa10f0ebeb8fb517073ed46d1f1f7470e119aadc..1b954baf50c0a2b0a3179da770dd5723a2b55577 100644 (file)
@@ -91,7 +91,6 @@ int startShell(osquery::Initializer& runner, int argc, char* argv[]) {
       !osquery::FLAGS_A.empty() || !osquery::FLAGS_pack.empty() ||
       osquery::FLAGS_L || osquery::FLAGS_profile > 0) {
     // A query was set as a positional argument, via stdin, or profiling is on.
-    osquery::FLAGS_disable_events = true;
     osquery::FLAGS_disable_caching = true;
   }
 
index ebddd4c6f7c23d845e35b48ee7118f219f2ec05a..592a69aff8e24f7257e94a6b6f65fd08ad428a5c 100644 (file)
@@ -31,8 +31,6 @@ FLAG(uint64,
 
 SHELL_FLAG(bool, planner, false, "Enable osquery runtime planner output");
 
-DECLARE_bool(disable_events);
-
 RecursiveMutex kAttachMutex;
 
 namespace tables {
@@ -844,8 +842,7 @@ static int xFilter(sqlite3_vtab_cursor* pVtabCursor,
 
   // For event-based tables, help the caller if events are disabled.
   bool events_satisfied =
-      ((content->attributes & TableAttributes::EVENT_BASED) == 0 ||
-       !FLAGS_disable_events);
+      ((content->attributes & TableAttributes::EVENT_BASED) == 0);
 
   std::map<std::string, ColumnOptions> options;
   for (size_t i = 0; i < content->columns.size(); ++i) {
index 2102794212da6736f35d81a28f41f5c78ffd6c5d..00787322726f64c1241e73a75c97f1c4631b7e83 100644 (file)
@@ -130,12 +130,4 @@ ScheduledQuery getOsqueryScheduledQuery() {
   return sq;
 }
 
-TableRows genRows(EventSubscriberPlugin* sub) {
-  auto vtc = std::make_shared<VirtualTableContent>();
-  QueryContext context(vtc);
-
-  TableRows results;
-  return results;
-}
-
 } // namespace osquery
index 4de9428fe6b2c33ad8f585cea34b6ab54663f5d9..8edb254b82230b724f8392da97e99c24f0924178 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <osquery/core.h>
 #include <osquery/database.h>
-#include <osquery/events.h>
 #include <osquery/filesystem/filesystem.h>
 
 namespace osquery {
@@ -67,7 +66,4 @@ extern const size_t kExpectedExtensionArgsCount;
 
 ScheduledQuery getOsqueryScheduledQuery();
 
-// Helper function to generate all rows from a generator-based table.
-TableRows genRows(EventSubscriberPlugin* sub);
-
 } // namespace osquery
index a0d263382c7a9eb8844d95e46fa69901f486acfa..0ee93937d6303e86c08cb2091fab25efe1055915 100644 (file)
@@ -10,7 +10,6 @@
 ** This file is generated. Do not modify it manually!
 */
 
-#include <osquery/events.h>
 #include <osquery/logger.h>
 #include <osquery/sql/dynamic_table_row.h>
 #include <osquery/tables.h>
index 574ce0d3b874f8d9493588dc97ccd9eba9d76018..d5be51a0824ff1f825496cf69bc8a8f87b9f480b 100644 (file)
@@ -25,7 +25,6 @@
 ** This file is generated. Do not modify it manually!
 */
 
-#include <osquery/events.h>
 #include <osquery/logger.h>
 #include <osquery/tables.h>
 #include <osquery/registry_factory.h>
@@ -133,16 +132,7 @@ class {{table_name_cc}}TablePlugin : public TablePlugin {
   bool usesGenerator() const override { return true; }
 
   void generator(RowYield& yield, QueryContext& context) override {
-{% if class_name != "" %}\
-    if (EventFactory::exists(getName())) {
-      auto subscriber = EventFactory::getEventSubscriber(getName());
-      return subscriber->{{function}}(yield, context);
-    } else {
-      LOG(ERROR) << "Subscriber table missing: " << getName();
-    }
-{% else %}\
     tables::{{function}}(yield, context);
-{% endif %}\
   }
 {% else %}\
   TableRows generate(QueryContext& context) override {
index a9c4748fe9d9520099a729cced752f3d7df2f2e5..45ce8cd1f71e4cf5f490350170b738f344c8fa81 100644 (file)
@@ -10,7 +10,6 @@
 ** This file is generated. Do not modify it manually!
 */
 
-#include <osquery/events.h>
 #include <osquery/logger.h>
 #include <osquery/tables.h>
 #include <osquery/registry_factory.h>