diff --git a/osquery/config/config.cpp b/osquery/config/config.cpp index d08d0779db6..3546b58666c 100644 --- a/osquery/config/config.cpp +++ b/osquery/config/config.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -206,14 +207,39 @@ Status Config::load() { return Status(0, "OK"); } +/** + * @brief Boost's 1.59 property tree based JSON parser does not accept comments. + * + * For semi-compatibility with existing configurations we will attempt to strip + * hash and C++ style comments. It is OK for the config update to be latent + * as it is a single event. But some configuration plugins may update running + * configurations. + */ +inline void stripConfigComments(std::string& json) { + std::string sink; + for (auto& line : osquery::split(json, "\n")) { + boost::trim(line); + if (line.size() > 0 && line[0] == '#') { + continue; + } + if (line.size() > 1 && line[0] == '/' && line[1] == '/') { + continue; + } + sink += line + '\n'; + } + json = sink; +} + Status Config::updateSource(const std::string& name, const std::string& json) { hashSource(name, json); // load the config (source.second) into a pt::ptree - std::stringstream json_stream; - json_stream << json; pt::ptree tree; try { + auto clone = json; + stripConfigComments(clone); + std::stringstream json_stream; + json_stream << clone; pt::read_json(json_stream, tree); } catch (const pt::json_parser::json_parser_error& e) { return Status(1, "Error parsing the config JSON"); diff --git a/osquery/config/tests/config_tests.cpp b/osquery/config/tests/config_tests.cpp index 75d5bf391f3..1a6c93142f2 100644 --- a/osquery/config/tests/config_tests.cpp +++ b/osquery/config/tests/config_tests.cpp @@ -29,7 +29,9 @@ namespace osquery { // Blacklist testing methods, internal to config implementations. extern void restoreScheduleBlacklist(std::map& blacklist); -extern void saveScheduleBlacklist(const std::map& blacklist); +extern void saveScheduleBlacklist( + const std::map& blacklist); +extern void stripConfigComments(std::string& json); class ConfigTests : public testing::Test { protected: @@ -85,6 +87,20 @@ TEST_F(ConfigTests, test_bad_config_update) { ASSERT_NO_THROW(Config::getInstance().update({{"bad_source", bad_json}})); } +TEST_F(ConfigTests, test_strip_comments) { + std::string json_comments = + "// Comment\n // Comment //\n # Comment\n# Comment\n{\"options\":{}}"; + + // Test support for stripping C++ and hash style comments from config JSON. + auto actual = json_comments; + stripConfigComments(actual); + std::string expected = "{\"options\":{}}\n"; + EXPECT_EQ(actual, expected); + + // Make sure the config update source logic applies the stripping. + EXPECT_TRUE(Config::getInstance().update({{"data", json_comments}})); +} + class TestConfigParserPlugin : public ConfigParserPlugin { public: std::vector keys() { @@ -158,9 +174,8 @@ TEST_F(ConfigTests, test_get_scheduled_queries) { auto c = Config(); c.addPack("unrestricted_pack", "", getUnrestrictedPack()); c.scheduledQueries( - ([&queries](const std::string&, const ScheduledQuery& query) { - queries.push_back(query); - })); + ([&queries](const std::string&, + const ScheduledQuery& query) { queries.push_back(query); })); EXPECT_EQ(queries.size(), getUnrestrictedPack().get_child("queries").size()); } diff --git a/tools/deployment/osquery.example.conf b/tools/deployment/osquery.example.conf index 26d20e73ffd..7938284c83e 100644 --- a/tools/deployment/osquery.example.conf +++ b/tools/deployment/osquery.example.conf @@ -1,5 +1,5 @@ { - /* Configure the daemon below */ + // Configure the daemon below: "options": { // Select the osquery config plugin. "config_plugin": "filesystem", @@ -52,7 +52,7 @@ "enable_monitor": "true" }, - /* Define a schedule of queries */ + // Define a schedule of queries: "schedule": { // This is a simple example query that outputs basic system information. "system_info": { @@ -63,17 +63,16 @@ } }, - /** - * Add default osquery packs or install your own. - * - * There are several 'default' packs installed with 'make install' or via - * packages and/or Homebrew. - * - * Linux: /usr/share/osquery/packs - * OS X: /var/osquery/packs - * Homebrew: /usr/local/share/osquery/packs - * make install: {PREFIX}/share/osquery/packs - */ + // Add default osquery packs or install your own. + // + // There are several 'default' packs installed with 'make install' or via + // packages and/or Homebrew. + // + // Linux: /usr/share/osquery/packs + // OS X: /var/osquery/packs + // Homebrew: /usr/local/share/osquery/packs + // make install: {PREFIX}/share/osquery/packs + // "packs": { // "osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf", // "incident-response": "/usr/share/osquery/packs/incident-response.conf", diff --git a/tools/provision/lib.sh b/tools/provision/lib.sh index d0c1d68604d..f9e7360a377 100755 --- a/tools/provision/lib.sh +++ b/tools/provision/lib.sh @@ -477,6 +477,7 @@ function package() { unset HOMEBREW_BUILD_FROM_SOURCE export HOMEBREW_MAKE_JOBS=$THREADS export HOMEBREW_NO_EMOJI=1 + HOMEBREW_ARGS="" if [[ $1 = "rocksdb" ]]; then # Build RocksDB from source in brew export LIBNAME=librocksdb_lite