mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-06 09:35:20 +00:00
Add flag aliasing, logger/flag tests
This commit is contained in:
parent
fc64965c68
commit
1f8dacec3c
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#define STRIP_FLAG_HELP 1
|
#define STRIP_FLAG_HELP 1
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
@ -19,6 +21,16 @@
|
|||||||
|
|
||||||
#define GFLAGS_NAMESPACE google
|
#define GFLAGS_NAMESPACE google
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
/// We define a lexical_cast template for boolean for Gflags boolean string
|
||||||
|
/// values.
|
||||||
|
template <>
|
||||||
|
bool lexical_cast<bool, std::string>(const std::string& arg);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string lexical_cast<std::string, bool>(const bool& b);
|
||||||
|
}
|
||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
struct FlagDetail {
|
struct FlagDetail {
|
||||||
@ -39,7 +51,7 @@ struct FlagInfo {
|
|||||||
* @brief A small tracking wrapper for options, binary flags.
|
* @brief A small tracking wrapper for options, binary flags.
|
||||||
*
|
*
|
||||||
* The osquery-specific gflags-like options define macro `FLAG` uses a Flag
|
* The osquery-specific gflags-like options define macro `FLAG` uses a Flag
|
||||||
& instance to track the options data.
|
* instance to track the options data.
|
||||||
*/
|
*/
|
||||||
class Flag {
|
class Flag {
|
||||||
public:
|
public:
|
||||||
@ -51,9 +63,9 @@ class Flag {
|
|||||||
*
|
*
|
||||||
* @return A mostly needless flag instance.
|
* @return A mostly needless flag instance.
|
||||||
*/
|
*/
|
||||||
static int create(const std::string& name, FlagDetail flag);
|
static int create(const std::string& name, const FlagDetail& flag);
|
||||||
|
|
||||||
/// Create a glags alias to name, using the Flag::getValue accessor.
|
/// Create a Gflags alias to name, using the Flag::getValue accessor.
|
||||||
static int createAlias(const std::string& alias, const std::string& name);
|
static int createAlias(const std::string& alias, const std::string& name);
|
||||||
|
|
||||||
static Flag& instance() {
|
static Flag& instance() {
|
||||||
@ -106,16 +118,18 @@ class Flag {
|
|||||||
*/
|
*/
|
||||||
static std::string getValue(const std::string& name);
|
static std::string getValue(const std::string& name);
|
||||||
|
|
||||||
template <typename T>
|
/*
|
||||||
static T getValue(const std::string& name) {
|
* @brief Get the type as a string of an osquery flag.
|
||||||
T intermediate;
|
*
|
||||||
return intermediate;
|
* @param name the flag name.
|
||||||
}
|
*/
|
||||||
|
static std::string getType(const std::string& name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Print help-style output to stdout for a given flag set.
|
* @brief Print help-style output to stdout for a given flag set.
|
||||||
*
|
*
|
||||||
* @param shell_only Only print shell flags.
|
* @param shell Only print shell flags.
|
||||||
|
* @param external Only print external flags (from extensions).
|
||||||
*/
|
*/
|
||||||
static void printFlags(bool shell = false, bool external = false);
|
static void printFlags(bool shell = false, bool external = false);
|
||||||
|
|
||||||
@ -123,6 +137,34 @@ class Flag {
|
|||||||
std::map<std::string, FlagDetail> flags_;
|
std::map<std::string, FlagDetail> flags_;
|
||||||
std::map<std::string, std::string> aliases_;
|
std::map<std::string, std::string> aliases_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper accessor/assignment alias class to support deprecated flags.
|
||||||
|
*
|
||||||
|
* This templated class wraps Flag::updateValue and Flag::getValue to 'alias'
|
||||||
|
* a deprecated flag name as the updated name. The helper macro FLAG_ALIAS
|
||||||
|
* will create a global variable instances of this wrapper using the same
|
||||||
|
* Gflags naming scheme to prevent collisions and support existing callsites.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class FlagAlias {
|
||||||
|
public:
|
||||||
|
FlagAlias& operator=(T const& v) {
|
||||||
|
Flag::updateValue(name_, boost::lexical_cast<std::string>(v));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const { return boost::lexical_cast<T>(Flag::getValue(name_)); }
|
||||||
|
|
||||||
|
FlagAlias(const std::string& alias,
|
||||||
|
const std::string& type,
|
||||||
|
const std::string& name,
|
||||||
|
T* storage)
|
||||||
|
: name_(name) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -143,11 +185,10 @@ class Flag {
|
|||||||
#define SHELL_FLAG(t, n, v, d) OSQUERY_FLAG(t, n, v, d, true, false)
|
#define SHELL_FLAG(t, n, v, d) OSQUERY_FLAG(t, n, v, d, true, false)
|
||||||
#define EXTENSION_FLAG(t, n, v, d) OSQUERY_FLAG(t, n, v, d, false, true)
|
#define EXTENSION_FLAG(t, n, v, d) OSQUERY_FLAG(t, n, v, d, false, true)
|
||||||
|
|
||||||
#define FLAG_ALIAS(t, n, a) \
|
#define FLAG_ALIAS(t, a, n) \
|
||||||
DEFINE_##t(a, FLAGS_##n); \
|
FlagAlias<t> FLAGS_##a(#a, #t, #n, &FLAGS_##n); \
|
||||||
namespace flags { \
|
namespace flags { \
|
||||||
|
static GFLAGS_NAMESPACE::FlagRegisterer oflag_##a( \
|
||||||
|
#a, #t, #a, #a, &FLAGS_##n, &FLAGS_##n); \
|
||||||
const int flag_alias_##a = Flag::createAlias(#a, #n); \
|
const int flag_alias_##a = Flag::createAlias(#a, #n); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_osquery_flag(t, n, v, d) FLAG(t, n, v, d)
|
|
||||||
#define DEFINE_shell_flag(t, n, v, d) SHELL_FLAG(t, n, v, d)
|
|
||||||
|
@ -104,7 +104,7 @@ class LoggerPlugin : public Plugin {
|
|||||||
* has been loaded (which may include additional CLI flag-options).
|
* has been loaded (which may include additional CLI flag-options).
|
||||||
*
|
*
|
||||||
* All of these actions may have generated VERBOSE, INFO, WARNING, or ERROR
|
* All of these actions may have generated VERBOSE, INFO, WARNING, or ERROR
|
||||||
* logs. The internal logging facility is, glog, collects these intermediate
|
* logs. The internal logging facility, Glog, collects these intermediate
|
||||||
* status logs and a customized log sink buffers them until the active
|
* status logs and a customized log sink buffers them until the active
|
||||||
* osquery logger's `init` method is called.
|
* osquery logger's `init` method is called.
|
||||||
*
|
*
|
||||||
@ -144,7 +144,7 @@ class LoggerPlugin : public Plugin {
|
|||||||
void initStatusLogger(const std::string& name);
|
void initStatusLogger(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the osquery Logger facility by dump the buffered status
|
* @brief Initialize the osquery Logger facility by dumping the buffered status
|
||||||
* logs and configurating status log forwarding.
|
* logs and configurating status log forwarding.
|
||||||
*
|
*
|
||||||
* initLogger will disable the `BufferedLogSink` facility, dump any status logs
|
* initLogger will disable the `BufferedLogSink` facility, dump any status logs
|
||||||
|
@ -28,10 +28,7 @@ typedef std::map<std::string, std::vector<std::string> > EventFileMap_t;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string, config_plugin, "filesystem", "Config type (plugin)");
|
||||||
config_plugin,
|
|
||||||
"filesystem",
|
|
||||||
"Config type (plugin)");
|
|
||||||
|
|
||||||
// This lock is used to protect the entirety of the OSqueryConfig struct
|
// This lock is used to protect the entirety of the OSqueryConfig struct
|
||||||
// Is should be used when ever accessing the structs members, reading or
|
// Is should be used when ever accessing the structs members, reading or
|
||||||
|
@ -21,10 +21,7 @@ using osquery::Status;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string, config_path, "/var/osquery/osquery.conf", "Path to config file");
|
||||||
config_path,
|
|
||||||
"/var/osquery/osquery.conf",
|
|
||||||
"Path to config file");
|
|
||||||
|
|
||||||
class FilesystemConfigPlugin : public ConfigPlugin {
|
class FilesystemConfigPlugin : public ConfigPlugin {
|
||||||
public:
|
public:
|
||||||
|
@ -22,9 +22,10 @@ ADD_OSQUERY_LIBRARY(TRUE osquery_test_util
|
|||||||
test_util.cpp
|
test_util.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ADD_OSQUERY_TEST(TRUE flags_tests flags_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE hash_test hash_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE hash_test hash_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE status_test status_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE status_test status_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE tables_tests tables_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE tables_tests tables_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE test_util_tests test_util_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE test_util_tests test_util_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE text_tests text_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE text_tests text_tests.cpp)
|
||||||
ADD_OSQUERY_TEST(TRUE conversions_tests conversions_tests.cpp)
|
ADD_OSQUERY_TEST(TRUE conversions_tests conversions_tests.cpp)
|
||||||
|
@ -10,9 +10,26 @@
|
|||||||
|
|
||||||
#include <osquery/flags.h>
|
#include <osquery/flags.h>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
template <>
|
||||||
|
bool lexical_cast<bool, std::string>(const std::string& arg) {
|
||||||
|
std::istringstream ss(arg);
|
||||||
|
bool b;
|
||||||
|
ss >> std::boolalpha >> b;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string lexical_cast<std::string, bool>(const bool& b) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << std::boolalpha << b;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
int Flag::create(const std::string& name, FlagDetail flag) {
|
int Flag::create(const std::string& name, const FlagDetail& flag) {
|
||||||
instance().flags_.insert(std::make_pair(name, flag));
|
instance().flags_.insert(std::make_pair(name, flag));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -47,6 +64,14 @@ std::string Flag::getValue(const std::string& name) {
|
|||||||
return current_value;
|
return current_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Flag::getType(const std::string& name) {
|
||||||
|
GFLAGS_NAMESPACE::CommandLineFlagInfo info;
|
||||||
|
if (!GFLAGS_NAMESPACE::GetCommandLineFlagInfo(name.c_str(), &info)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return info.type;
|
||||||
|
}
|
||||||
|
|
||||||
Status Flag::updateValue(const std::string& name, const std::string& value) {
|
Status Flag::updateValue(const std::string& name, const std::string& value) {
|
||||||
GFLAGS_NAMESPACE::SetCommandLineOption(name.c_str(), value.c_str());
|
GFLAGS_NAMESPACE::SetCommandLineOption(name.c_str(), value.c_str());
|
||||||
return Status(0, "OK");
|
return Status(0, "OK");
|
||||||
@ -62,8 +87,12 @@ std::map<std::string, FlagInfo> Flag::flags() {
|
|||||||
// This flag info was not defined within osquery.
|
// This flag info was not defined within osquery.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the flag info from the internal info kept by Gflags, except for
|
||||||
|
// the stored description. Gflag keeps an "unknown" value if the flag
|
||||||
|
// was declared without a definition.
|
||||||
flags[flag.name] = {flag.type,
|
flags[flag.name] = {flag.type,
|
||||||
flag.description,
|
instance().flags_.at(flag.name).description,
|
||||||
flag.default_value,
|
flag.default_value,
|
||||||
flag.current_value,
|
flag.current_value,
|
||||||
instance().flags_.at(flag.name)};
|
instance().flags_.at(flag.name)};
|
||||||
|
145
osquery/core/flags_tests.cpp
Normal file
145
osquery/core/flags_tests.cpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <osquery/core.h>
|
||||||
|
#include <osquery/flags.h>
|
||||||
|
#include <osquery/logger.h>
|
||||||
|
|
||||||
|
namespace osquery {
|
||||||
|
|
||||||
|
DECLARE_string(test_string_flag);
|
||||||
|
|
||||||
|
class FlagsTests : public testing::Test {
|
||||||
|
public:
|
||||||
|
FlagsTests() {}
|
||||||
|
|
||||||
|
void SetUp() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
FLAG(string, test_string_flag, "TEST STRING", "TEST DESCRIPTION");
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_set_get) {
|
||||||
|
// Test the core gflags functionality.
|
||||||
|
EXPECT_EQ(FLAGS_test_string_flag, "TEST STRING");
|
||||||
|
|
||||||
|
// Check that the gflags flag name was recorded in the osquery flag tracker.
|
||||||
|
auto all_flags = Flag::flags();
|
||||||
|
EXPECT_EQ(all_flags.count("test_string_flag"), 1);
|
||||||
|
|
||||||
|
// Update the value of the flag, and access through the osquery wrapper.
|
||||||
|
FLAGS_test_string_flag = "NEW TEST STRING";
|
||||||
|
EXPECT_EQ(Flag::getValue("test_string_flag"), "NEW TEST STRING");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_defaults) {
|
||||||
|
// Make sure the flag value was not reset.
|
||||||
|
EXPECT_EQ(FLAGS_test_string_flag, "NEW TEST STRING");
|
||||||
|
|
||||||
|
// Now test that the default value is tracked.
|
||||||
|
EXPECT_FALSE(Flag::isDefault("test_string_flag"));
|
||||||
|
|
||||||
|
// Check the default value accessor.
|
||||||
|
std::string default_value;
|
||||||
|
auto status = Flag::getDefaultValue("test_mistake", default_value);
|
||||||
|
EXPECT_FALSE(status.ok());
|
||||||
|
status = Flag::getDefaultValue("test_string_flag", default_value);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
EXPECT_EQ(default_value, "TEST STRING");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_details) {
|
||||||
|
// Make sure flag details are tracked correctly.
|
||||||
|
auto all_flags = Flag::flags();
|
||||||
|
auto flag_info = all_flags["test_string_flag"];
|
||||||
|
|
||||||
|
EXPECT_EQ(flag_info.type, "string");
|
||||||
|
EXPECT_EQ(flag_info.description, "TEST DESCRIPTION");
|
||||||
|
EXPECT_EQ(flag_info.default_value, "TEST STRING");
|
||||||
|
EXPECT_EQ(flag_info.value, "NEW TEST STRING");
|
||||||
|
EXPECT_EQ(flag_info.detail.shell, false);
|
||||||
|
EXPECT_EQ(flag_info.detail.external, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_FLAG(bool, shell_only, true, "TEST SHELL DESCRIPTION");
|
||||||
|
EXTENSION_FLAG(bool, extension_only, true, "TEST EXTENSION DESCRIPTION");
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_flag_detail_types) {
|
||||||
|
EXPECT_TRUE(FLAGS_shell_only);
|
||||||
|
EXPECT_TRUE(FLAGS_extension_only);
|
||||||
|
|
||||||
|
auto all_flags = Flag::flags();
|
||||||
|
EXPECT_TRUE(all_flags["shell_only"].detail.shell);
|
||||||
|
EXPECT_TRUE(all_flags["extension_only"].detail.external);
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAG_ALIAS(bool, shell_only_alias, shell_only);
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_aliases) {
|
||||||
|
EXPECT_TRUE(FLAGS_shell_only_alias);
|
||||||
|
FLAGS_shell_only = false;
|
||||||
|
EXPECT_FALSE(FLAGS_shell_only);
|
||||||
|
EXPECT_FALSE(FLAGS_shell_only_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
FLAG(int32, test_int32, 1, "none");
|
||||||
|
FLAG_ALIAS(google::int32, test_int32_alias, test_int32);
|
||||||
|
|
||||||
|
FLAG(int64, test_int64, (int64_t)1 << 34, "none");
|
||||||
|
FLAG_ALIAS(google::int64, test_int64_alias, test_int64);
|
||||||
|
|
||||||
|
FLAG(double, test_double, 4.2, "none");
|
||||||
|
FLAG_ALIAS(double, test_double_alias, test_double);
|
||||||
|
|
||||||
|
FLAG(string, test_string, "test", "none");
|
||||||
|
FLAG_ALIAS(std::string, test_string_alias, test_string);
|
||||||
|
|
||||||
|
TEST_F(FlagsTests, test_alias_types) {
|
||||||
|
// Test int32 lexical casting both ways.
|
||||||
|
EXPECT_EQ(FLAGS_test_int32_alias, 1);
|
||||||
|
FLAGS_test_int32_alias = 2;
|
||||||
|
EXPECT_EQ(FLAGS_test_int32, 2);
|
||||||
|
FLAGS_test_int32 = 3;
|
||||||
|
EXPECT_EQ(FLAGS_test_int32_alias, 3);
|
||||||
|
EXPECT_TRUE(FLAGS_test_int32_alias > 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(FLAGS_test_int64_alias, (int64_t)1 << 34);
|
||||||
|
FLAGS_test_int64_alias = (int64_t)1 << 35;
|
||||||
|
EXPECT_EQ(FLAGS_test_int64, (int64_t)1 << 35);
|
||||||
|
FLAGS_test_int64 = (int64_t)1 << 36;
|
||||||
|
EXPECT_EQ(FLAGS_test_int64_alias, (int64_t)1 << 36);
|
||||||
|
EXPECT_TRUE(FLAGS_test_int64_alias > 0);
|
||||||
|
|
||||||
|
EXPECT_EQ(FLAGS_test_double_alias, 4.2);
|
||||||
|
FLAGS_test_double_alias = 2.4;
|
||||||
|
EXPECT_EQ(FLAGS_test_double, 2.4);
|
||||||
|
FLAGS_test_double = 22.44;
|
||||||
|
EXPECT_EQ(FLAGS_test_double_alias, 22.44);
|
||||||
|
EXPECT_TRUE(FLAGS_test_double_alias > 0);
|
||||||
|
|
||||||
|
// Compile-time type checking will not compare typename T to const char*
|
||||||
|
std::string value = FLAGS_test_string_alias;
|
||||||
|
EXPECT_EQ(value, "test");
|
||||||
|
FLAGS_test_string_alias = "test2";
|
||||||
|
EXPECT_EQ(FLAGS_test_string, "test2");
|
||||||
|
FLAGS_test_string = "test3";
|
||||||
|
|
||||||
|
// Test both the copy and assignment constructor aliases.
|
||||||
|
value = FLAGS_test_string_alias;
|
||||||
|
auto value2 = (std::string)FLAGS_test_string_alias;
|
||||||
|
EXPECT_EQ(value, "test3");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
@ -25,14 +25,11 @@ const std::string kDescription =
|
|||||||
"relational database";
|
"relational database";
|
||||||
const std::string kEpilog = "osquery project page <http://osquery.io>.";
|
const std::string kEpilog = "osquery project page <http://osquery.io>.";
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, config_check, false, "Check the format of an osquery config");
|
||||||
config_check,
|
|
||||||
false,
|
|
||||||
"Check the format of an osquery config");
|
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
DEFINE_osquery_flag(bool, daemonize, false, "Run as daemon (osqueryd only)");
|
FLAG(bool, daemonize, false, "Run as daemon (osqueryd only)");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -35,16 +35,13 @@ namespace fs = boost::filesystem;
|
|||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
/// The path to the pidfile for osqueryd
|
/// The path to the pidfile for osqueryd
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
pidfile,
|
pidfile,
|
||||||
"/var/osquery/osqueryd.pidfile",
|
"/var/osquery/osqueryd.pidfile",
|
||||||
"The path to the pidfile for osqueryd");
|
"The path to the pidfile for osqueryd");
|
||||||
|
|
||||||
/// Should the daemon force unload previously-running osqueryd daemons.
|
/// Should the daemon force unload previously-running osqueryd daemons.
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, force, false, "Force osqueryd to kill previously-running daemons");
|
||||||
force,
|
|
||||||
false,
|
|
||||||
"Force osqueryd to kill previously-running daemons");
|
|
||||||
|
|
||||||
std::string getHostname() {
|
std::string getHostname() {
|
||||||
char hostname[256]; // Linux max should be 64.
|
char hostname[256]; // Linux max should be 64.
|
||||||
|
@ -41,16 +41,12 @@ const std::map<WatchdogLimitType, std::vector<size_t> > kWatchdogLimits = {
|
|||||||
// How often to poll for performance limit violations.
|
// How often to poll for performance limit violations.
|
||||||
{INTERVAL, {3, 3, 3}}, };
|
{INTERVAL, {3, 3, 3}}, };
|
||||||
|
|
||||||
DEFINE_osquery_flag(
|
FLAG(int32,
|
||||||
int32,
|
watchdog_level,
|
||||||
watchdog_level,
|
1,
|
||||||
1,
|
"Performance limit level (0=loose, 1=normal, 2=restrictive)");
|
||||||
"Performance limit level (0=loose, 1=normal, 2=restrictive)");
|
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, disable_watchdog, false, "Disable userland watchdog process");
|
||||||
disable_watchdog,
|
|
||||||
false,
|
|
||||||
"Disable userland watchdog process");
|
|
||||||
|
|
||||||
bool Watcher::ok() {
|
bool Watcher::ok() {
|
||||||
::sleep(getWorkerLimit(INTERVAL));
|
::sleep(getWorkerLimit(INTERVAL));
|
||||||
|
@ -32,15 +32,15 @@ const std::string kEvents = "events";
|
|||||||
|
|
||||||
const std::vector<std::string> kDomains = {kConfigurations, kQueries, kEvents};
|
const std::vector<std::string> kDomains = {kConfigurations, kQueries, kEvents};
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
db_path,
|
db_path,
|
||||||
"/var/osquery/osquery.db",
|
"/var/osquery/osquery.db",
|
||||||
"If using a disk-based backing store, specify a path");
|
"If using a disk-based backing store, specify a path");
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool,
|
||||||
use_in_memory_database,
|
use_in_memory_database,
|
||||||
false,
|
false,
|
||||||
"Keep osquery backing-store in memory");
|
"Keep osquery backing-store in memory");
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// constructors and destructors
|
// constructors and destructors
|
||||||
|
@ -4108,43 +4108,37 @@ static char *cmdline_option_value(int argc, char **argv, int i) {
|
|||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
/// Define flags used by the shell. They are parsed by the drop-in shell.
|
/// Define flags used by the shell. They are parsed by the drop-in shell.
|
||||||
DEFINE_shell_flag(bool, bail, false, "stop after hitting an error");
|
SHELL_FLAG(bool, bail, false, "stop after hitting an error");
|
||||||
DEFINE_shell_flag(bool, batch, false, "force batch I/O");
|
SHELL_FLAG(bool, batch, false, "force batch I/O");
|
||||||
DEFINE_shell_flag(bool, column, false, "set output mode to 'column'");
|
SHELL_FLAG(bool, column, false, "set output mode to 'column'");
|
||||||
DEFINE_shell_flag(string, cmd, "", "run \"COMMAND\" before reading stdin");
|
SHELL_FLAG(string, cmd, "", "run \"COMMAND\" before reading stdin");
|
||||||
DEFINE_shell_flag(bool, csv, false, "set output mode to 'csv'");
|
SHELL_FLAG(bool, csv, false, "set output mode to 'csv'");
|
||||||
DEFINE_shell_flag(bool, json, false, "set output mode to 'json'");
|
SHELL_FLAG(bool, json, false, "set output mode to 'json'");
|
||||||
DEFINE_shell_flag(bool, echo, false, "print commands before execution");
|
SHELL_FLAG(bool, echo, false, "print commands before execution");
|
||||||
DEFINE_shell_flag(string, init, "", "read/process named file");
|
SHELL_FLAG(string, init, "", "read/process named file");
|
||||||
DEFINE_shell_flag(bool, header, true, "turn headers on or off");
|
SHELL_FLAG(bool, header, true, "turn headers on or off");
|
||||||
DEFINE_shell_flag(bool, html, false, "set output mode to HTML");
|
SHELL_FLAG(bool, html, false, "set output mode to HTML");
|
||||||
DEFINE_shell_flag(bool, interactive, false, "force interactive I/O");
|
SHELL_FLAG(bool, interactive, false, "force interactive I/O");
|
||||||
DEFINE_shell_flag(bool, line, false, "set output mode to 'line'");
|
SHELL_FLAG(bool, line, false, "set output mode to 'line'");
|
||||||
DEFINE_shell_flag(bool, list, false, "set output mode to 'list'");
|
SHELL_FLAG(bool, list, false, "set output mode to 'list'");
|
||||||
DEFINE_shell_flag(int64, mmap, 0, "default mmap size set to N");
|
SHELL_FLAG(int64, mmap, 0, "default mmap size set to N");
|
||||||
DEFINE_shell_flag(string,
|
SHELL_FLAG(string,
|
||||||
nullvalue,
|
nullvalue,
|
||||||
"",
|
"",
|
||||||
"set text string for NULL values. Default ''");
|
"set text string for NULL values. Default ''");
|
||||||
DEFINE_shell_flag(string,
|
SHELL_FLAG(string, separator, "|", "set output field separator. Default: '|'");
|
||||||
separator,
|
SHELL_FLAG(bool, stats, false, "print memory stats before each finalize");
|
||||||
"|",
|
SHELL_FLAG(string, vfs, "", "use NAME as the default VFS");
|
||||||
"set output field separator. Default: '|'");
|
|
||||||
DEFINE_shell_flag(bool,
|
|
||||||
stats,
|
|
||||||
false,
|
|
||||||
"print memory stats before each finalize");
|
|
||||||
DEFINE_shell_flag(string, vfs, "", "use NAME as the default VFS");
|
|
||||||
|
|
||||||
/// Optional flags enabled at compile time.
|
/// Optional flags enabled at compile time.
|
||||||
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
|
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
|
||||||
DEFINE_shell_flag(int64, heap, 0, "Size of heap for memsys3 or memsys5");
|
SHELL_FLAG(int64, heap, 0, "Size of heap for memsys3 or memsys5");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_ENABLE_MULTIPLEX
|
#ifdef SQLITE_ENABLE_MULTIPLEX
|
||||||
DEFINE_shell_flag(bool, multiplex, false, "enable the multiplexor VFS");
|
SHELL_FLAG(bool, multiplex, false, "enable the multiplexor VFS");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SQLITE_ENABLE_VFSTRACE
|
#ifdef SQLITE_ENABLE_VFSTRACE
|
||||||
DEFINE_shell_flag(bool, vfstrace, false, "enable tracing of all VFS calls");
|
SHELL_FLAG(bool, vfstrace, false, "enable tracing of all VFS calls");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int launchIntoShell(int argc, char **argv) {
|
int launchIntoShell(int argc, char **argv) {
|
||||||
|
@ -21,10 +21,7 @@ using namespace apache::thrift::concurrency;
|
|||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
/// The worker_threads define the default thread pool size.
|
/// The worker_threads define the default thread pool size.
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32, worker_threads, 4, "Number of work dispatch threads");
|
||||||
worker_threads,
|
|
||||||
4,
|
|
||||||
"Number of work dispatch threads");
|
|
||||||
|
|
||||||
void interruptableSleep(size_t milli) {
|
void interruptableSleep(size_t milli) {
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(milli));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(milli));
|
||||||
|
@ -22,15 +22,15 @@ namespace pt = boost::property_tree;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32,
|
||||||
distributed_get_queries_retries,
|
distributed_get_queries_retries,
|
||||||
3,
|
3,
|
||||||
"Times to retry retrieving distributed queries");
|
"Times to retry retrieving distributed queries");
|
||||||
|
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32,
|
||||||
distributed_write_results_retries,
|
distributed_write_results_retries,
|
||||||
3,
|
3,
|
||||||
"Times to retry writing distributed query results");
|
"Times to retry writing distributed query results");
|
||||||
|
|
||||||
Status MockDistributedProvider::getQueriesJSON(std::string& query_json) {
|
Status MockDistributedProvider::getQueriesJSON(std::string& query_json) {
|
||||||
query_json = queriesJSON_;
|
query_json = queriesJSON_;
|
||||||
|
@ -26,15 +26,9 @@ namespace osquery {
|
|||||||
/// Helper cooloff (ms) macro to prevent thread failure thrashing.
|
/// Helper cooloff (ms) macro to prevent thread failure thrashing.
|
||||||
#define EVENTS_COOLOFF 20
|
#define EVENTS_COOLOFF 20
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, disable_events, false, "Disable osquery events pubsub");
|
||||||
disable_events,
|
|
||||||
false,
|
|
||||||
"Disable osquery events pubsub");
|
|
||||||
|
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32, events_expiry, 86000, "Timeout to expire event pubsub results");
|
||||||
events_expiry,
|
|
||||||
86000,
|
|
||||||
"Timeout to expire event pubsub results");
|
|
||||||
|
|
||||||
const std::vector<size_t> kEventTimeLists = {
|
const std::vector<size_t> kEventTimeLists = {
|
||||||
1 * 60 * 60, // 1 hour
|
1 * 60 * 60, // 1 hour
|
||||||
|
@ -28,12 +28,12 @@ using namespace osquery::extensions;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool, disable_extensions, false, "Disable extension API");
|
FLAG(bool, disable_extensions, false, "Disable extension API");
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
extensions_socket,
|
extensions_socket,
|
||||||
"/var/osquery/osquery.em",
|
"/var/osquery/osquery.em",
|
||||||
"Path to the extensions UNIX domain socket")
|
"Path to the extensions UNIX domain socket")
|
||||||
|
|
||||||
namespace extensions {
|
namespace extensions {
|
||||||
|
|
||||||
|
@ -22,10 +22,7 @@ namespace pt = boost::property_tree;
|
|||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
// run this benchmark with --iterations=9001 to parse over 9000 property lists
|
// run this benchmark with --iterations=9001 to parse over 9000 property lists
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32, plist_iterations, 100, "Iterations to execute plist benchmark");
|
||||||
plist_iterations,
|
|
||||||
100,
|
|
||||||
"Iterations to execute plist benchmark");
|
|
||||||
|
|
||||||
class PlistBenchmark : public testing::Test {};
|
class PlistBenchmark : public testing::Test {};
|
||||||
|
|
||||||
|
@ -25,10 +25,7 @@ namespace osquery {
|
|||||||
|
|
||||||
const std::string kLinuxMemPath = "/dev/mem";
|
const std::string kLinuxMemPath = "/dev/mem";
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, disable_memory, false, "Disable physical memory reads");
|
||||||
disable_memory,
|
|
||||||
false,
|
|
||||||
"Disable physical memory reads");
|
|
||||||
|
|
||||||
Status readMem(int fd, size_t base, size_t length, uint8_t* buffer) {
|
Status readMem(int fd, size_t base, size_t length, uint8_t* buffer) {
|
||||||
if (lseek(fd, base, SEEK_SET) == -1) {
|
if (lseek(fd, base, SEEK_SET) == -1) {
|
||||||
|
@ -21,23 +21,15 @@ namespace pt = boost::property_tree;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
/// `logger` defines the default log receiver plugin name.
|
FLAG(bool, verbose, false, "Enable verbose informational messages");
|
||||||
DEFINE_osquery_flag(string,
|
FLAG_ALIAS(bool, verbose_debug, verbose);
|
||||||
logger_plugin,
|
FLAG_ALIAS(bool, debug, verbose);
|
||||||
"filesystem",
|
|
||||||
"The default logger plugin");
|
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, disable_logging, false, "Disable ERROR/INFO logging");
|
||||||
log_result_events,
|
|
||||||
true,
|
|
||||||
"Log scheduled results as events");
|
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(string, logger_plugin, "filesystem", "The default logger plugin");
|
||||||
verbose, // debug, verbose_debug
|
|
||||||
false,
|
|
||||||
"Enable verbose informational messages");
|
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool, disable_logging, false, "Disable ERROR/INFO logging");
|
FLAG(bool, log_result_events, true, "Log scheduled results as events");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A custom Glog log sink for forwarding or buffering status logs.
|
* @brief A custom Glog log sink for forwarding or buffering status logs.
|
||||||
|
@ -11,33 +11,126 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <osquery/core.h>
|
#include <osquery/core.h>
|
||||||
|
#include <osquery/flags.h>
|
||||||
#include <osquery/logger.h>
|
#include <osquery/logger.h>
|
||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
|
DECLARE_string(logger_plugin);
|
||||||
|
|
||||||
class LoggerTests : public testing::Test {
|
class LoggerTests : public testing::Test {
|
||||||
public:
|
public:
|
||||||
LoggerTests() { Registry::setUp(); }
|
LoggerTests() {}
|
||||||
|
|
||||||
|
void SetUp() {
|
||||||
|
log_lines.clear();
|
||||||
|
status_messages.clear();
|
||||||
|
statuses_logged = 0;
|
||||||
|
last_status = {O_INFO, "", -1, ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track lines emitted to logString
|
||||||
|
static std::vector<std::string> log_lines;
|
||||||
|
|
||||||
|
// Track the results of init
|
||||||
|
static StatusLogLine last_status;
|
||||||
|
static std::vector<std::string> status_messages;
|
||||||
|
|
||||||
|
// Count calls to logStatus
|
||||||
|
static int statuses_logged;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> LoggerTests::log_lines;
|
||||||
|
StatusLogLine LoggerTests::last_status;
|
||||||
|
std::vector<std::string> LoggerTests::status_messages;
|
||||||
|
int LoggerTests::statuses_logged = 0;
|
||||||
|
|
||||||
class TestLoggerPlugin : public LoggerPlugin {
|
class TestLoggerPlugin : public LoggerPlugin {
|
||||||
public:
|
public:
|
||||||
TestLoggerPlugin() {}
|
TestLoggerPlugin() {}
|
||||||
|
|
||||||
Status logString(const std::string& s) { return Status(0, s); }
|
Status logString(const std::string& s) {
|
||||||
|
LoggerTests::log_lines.push_back(s);
|
||||||
|
return Status(0, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status init(const std::string& name, const std::vector<StatusLogLine>& log) {
|
||||||
|
for (const auto& status : log) {
|
||||||
|
LoggerTests::status_messages.push_back(status.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.size() > 0) {
|
||||||
|
LoggerTests::last_status = log.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "RETURN_FAILURE") {
|
||||||
|
return Status(1, "OK");
|
||||||
|
} else {
|
||||||
|
return Status(0, "OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status logStatus(const std::vector<StatusLogLine>& log) {
|
||||||
|
++LoggerTests::statuses_logged;
|
||||||
|
return Status(0, "OK");
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~TestLoggerPlugin() {}
|
virtual ~TestLoggerPlugin() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(LoggerTests, test_plugin) {
|
TEST_F(LoggerTests, test_plugin) {
|
||||||
Registry::add<TestLoggerPlugin>("logger", "test");
|
Registry::add<TestLoggerPlugin>("logger", "test");
|
||||||
|
Registry::setUp();
|
||||||
|
|
||||||
auto s = Registry::call("logger", "test", {{"string", "foobar"}});
|
auto s = Registry::call("logger", "test", {{"string", "foobar"}});
|
||||||
EXPECT_EQ(s.ok(), true);
|
EXPECT_TRUE(s.ok());
|
||||||
|
EXPECT_EQ(LoggerTests::log_lines.back(), "foobar");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LoggerTests, test_logger_init) {
|
||||||
|
// Expect the logger to have been registered from the first test.
|
||||||
|
EXPECT_TRUE(Registry::exists("logger", "test"));
|
||||||
|
|
||||||
|
FLAGS_logger_plugin = "test";
|
||||||
|
initStatusLogger("logger_test");
|
||||||
|
// This will be printed to stdout.
|
||||||
|
LOG(WARNING) << "Logger test is generating a warning status (1)";
|
||||||
|
initLogger("logger_test");
|
||||||
|
|
||||||
|
// The warning message will have been buffered and sent to the active logger
|
||||||
|
// which is test.
|
||||||
|
EXPECT_EQ(LoggerTests::status_messages.size(), 1);
|
||||||
|
|
||||||
|
// The logStatus API should NOT have been called. It will only be used if
|
||||||
|
// (1) The active logger's init returns success within initLogger and
|
||||||
|
// (2) for status logs generated after initLogger is called.
|
||||||
|
EXPECT_EQ(LoggerTests::statuses_logged, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LoggerTests, test_logger_log_status) {
|
||||||
|
// This will be printed to stdout.
|
||||||
|
LOG(WARNING) << "Logger test is generating a warning status (2)";
|
||||||
|
|
||||||
|
// The second warning status will be sent to the logger plugin.
|
||||||
|
EXPECT_EQ(LoggerTests::statuses_logged, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LoggerTests, test_logger_variations) {
|
||||||
|
// Init the logger for a second time, this should only be done for testing.
|
||||||
|
// This time we'll trigger the init method to fail and prevent additional
|
||||||
|
// status messages from trigger logStatus.
|
||||||
|
initLogger("RETURN_FAILURE");
|
||||||
|
|
||||||
|
// This will be printed to stdout.
|
||||||
|
LOG(WARNING) << "Logger test is generating a warning status (3)";
|
||||||
|
|
||||||
|
// Since the initLogger call triggered a failed init, meaning the logger
|
||||||
|
// does NOT handle Glog logs, there will be no statuses logged.
|
||||||
|
EXPECT_EQ(LoggerTests::statuses_logged, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
osquery::initOsquery(argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,13 @@
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
active_scribe_category,
|
active_scribe_category,
|
||||||
"osquery",
|
"osquery",
|
||||||
"The path of the scribe category to be used if scribe "
|
"The path of the scribe category to be used if scribe "
|
||||||
"logging is enabled.");
|
"logging is enabled.");
|
||||||
|
|
||||||
DEFINE_osquery_flag(bool,
|
FLAG(bool, dev_machine, false, "Set to true if the machine is a dev machine.");
|
||||||
dev_machine,
|
|
||||||
false,
|
|
||||||
"Set to true if the machine is a dev machine.");
|
|
||||||
|
|
||||||
class ScribeLoggerPlugin : public LoggerPlugin {
|
class ScribeLoggerPlugin : public LoggerPlugin {
|
||||||
public:
|
public:
|
||||||
|
@ -19,10 +19,11 @@ namespace fs = boost::filesystem;
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
logger_path, // osquery_log_dir
|
logger_path,
|
||||||
"/var/log/osquery/",
|
"/var/log/osquery/",
|
||||||
"Directory path for ERROR/WARN/INFO and results logging");
|
"Directory path for ERROR/WARN/INFO and results logging");
|
||||||
|
FLAG_ALIAS(std::string, osquery_log_dir, logger_path);
|
||||||
|
|
||||||
const std::string kFilesystemLoggerFilename = "osqueryd.results.log";
|
const std::string kFilesystemLoggerFilename = "osqueryd.results.log";
|
||||||
|
|
||||||
|
@ -22,15 +22,12 @@
|
|||||||
|
|
||||||
namespace osquery {
|
namespace osquery {
|
||||||
|
|
||||||
DEFINE_osquery_flag(string,
|
FLAG(string,
|
||||||
host_identifier,
|
host_identifier,
|
||||||
"hostname",
|
"hostname",
|
||||||
"Field used to identify the host running osqueryd");
|
"Field used to identify the host running osqueryd");
|
||||||
|
|
||||||
DEFINE_osquery_flag(int32,
|
FLAG(int32, schedule_splay_percent, 10, "Percent to splay config times");
|
||||||
schedule_splay_percent,
|
|
||||||
10,
|
|
||||||
"Percent to splay config times");
|
|
||||||
|
|
||||||
Status getHostIdentifier(std::string& ident) {
|
Status getHostIdentifier(std::string& ident) {
|
||||||
std::shared_ptr<DBHandle> db;
|
std::shared_ptr<DBHandle> db;
|
||||||
|
Loading…
Reference in New Issue
Block a user