Added table for the packs and check for already scheduled queries

This commit is contained in:
Javier Marcos 2015-05-21 13:42:45 -07:00
parent 81819e3d64
commit 886ad6e928
7 changed files with 89 additions and 45 deletions

View File

@ -105,6 +105,12 @@ class Config : private boost::noncopyable {
*/
static void addScheduledQuery(const std::string name, const std::string query, const int interval);
/**
* @brief Checks if the query is already added to the schedule
*
*/
static bool checkScheduledQuery(const std::string query);
/**
* @brief Check to ensure that the config is accessible and properly
* formatted

View File

@ -18,6 +18,9 @@ file(GLOB OSQUERY_CONFIG_PARSERS "parsers/*.cpp")
ADD_OSQUERY_LIBRARY(FALSE osquery_config_plugins
${OSQUERY_CONFIG_PLUGINS}
)
ADD_OSQUERY_LIBRARY(TRUE osquery_config_parsers
${OSQUERY_CONFIG_PARSERS}
)

View File

@ -307,6 +307,19 @@ Status Config::checkConfig() {
return load();
}
bool Config::checkScheduledQuery(const std::string query) {
bool result = false;
ConfigDataInstance config;
for (const auto& scheduled_query : config.schedule()) {
if (scheduled_query.second.query == query) {
result = true;
}
}
return result;
}
void Config::recordQueryPerformance(const std::string& name,
size_t delay,
size_t size,

View File

@ -15,12 +15,11 @@
#include <osquery/filesystem.h>
#include <osquery/config.h>
#include <osquery/logger.h>
#include <osquery/query_packs.h>
#include "query_packs.h"
namespace pt = boost::property_tree;
namespace osquery {
namespace tables {
pt::ptree QueryPackSingleEntry(const pt::ptree& pack_data) {
// Extract all the pack fields
@ -92,7 +91,7 @@ bool versionChecker(const std::string& pack_version) {
return false;
}
std::map<std::string, pt::ptree> QueryPackParsePacks(const pt::ptree& raw_packs, bool check_platform, bool check_version) {
std::map<std::string, pt::ptree> QueryPackConfigParserPlugin::QueryPackParsePacks(const pt::ptree& raw_packs, bool check_platform, bool check_version) {
std::map<std::string, pt::ptree> result;
// Iterate through all the pack elements
@ -128,9 +127,13 @@ std::map<std::string, pt::ptree> QueryPackParsePacks(const pt::ptree& raw_packs,
Status QueryPackConfigParserPlugin::update(const std::map<std::string, ConfigTree>& config) {
Status status;
const auto& pack_config = config.at("packs");
data_.add_child("packs", pack_config);
// Iterate through all the packs to get the configuration
for(auto const &pack_element : pack_config) {
// Iterate through all the packs to get the configuration
auto pack_name = std::string(pack_element.first.data());
auto pack_path = std::string(pack_element.second.data());
@ -169,6 +172,7 @@ Status QueryPackConfigParserPlugin::update(const std::map<std::string, ConfigTre
}
}
}
return Status(0, "OK");
}
@ -176,4 +180,3 @@ Status QueryPackConfigParserPlugin::update(const std::map<std::string, ConfigTre
REGISTER(QueryPackConfigParserPlugin, "config_parser", "packs");
}
}

View File

@ -2,7 +2,6 @@
#include <osquery/tables.h>
namespace osquery {
namespace tables {
/**
* @brief A simple ConfigParserPlugin for a "packs" dictionary key.
@ -21,4 +20,3 @@ class QueryPackConfigParserPlugin : public ConfigParserPlugin {
};
}
}

View File

@ -13,12 +13,12 @@
#include <osquery/logger.h>
#include <osquery/database.h>
#include "osquery/config/parsers/query_packs.h"
#include "osquery/core/test_util.h"
namespace pt = boost::property_tree;
namespace osquery {
namespace tables {
std::map<std::string, pt::ptree> QueryPackParsePacks(const pt::ptree& raw_packs, bool check_platform, bool check_version);
@ -29,7 +29,13 @@ std::map<std::string, pt::ptree> getQueryPacksContent() {
Status status = osquery::parseJSON(pack_path, pack_tree);
pt::ptree pack_file_element = pack_tree.get_child("test_pack_test");
result = QueryPackParsePacks(pack_file_element, false, true);
ConfigDataInstance config;
const auto& pack_parser = config.getParser("packs");
if (pack_parser == nullptr) {
return result;
}
const auto& queryPackParser = std::static_pointer_cast<QueryPackConfigParserPlugin>(pack_parser);
result = queryPackParser->QueryPackParsePacks(pack_file_element, false, true);
return result;
}
@ -69,4 +75,3 @@ TEST_F(QueryPacksConfigTests, test_query_packs_configuration) {
EXPECT_EQ(expected["launchd"].get<std::string>("value"), data["launchd"].get<std::string>("value"));
}
}
}

View File

@ -9,7 +9,6 @@
*/
#include <osquery/config.h>
#include <osquery/query_packs.h>
#include <osquery/core.h>
#include <osquery/extensions.h>
#include <osquery/flags.h>
@ -19,6 +18,8 @@
#include <osquery/tables.h>
#include <osquery/filesystem.h>
#include "osquery/config/parsers/query_packs.h"
namespace osquery {
namespace tables {
@ -163,10 +164,11 @@ QueryData genOsquerySchedule(QueryContext& context) {
}
QueryData genOsqueryPacks(QueryContext& context) {
Row r;
QueryData results;
ConfigDataInstance config;
const auto& pack_config = config.getParsedData("packs");
// Get the instance for the parser
const auto& pack_parser = config.getParser("packs");
if (pack_parser == nullptr) {
return results;
@ -176,48 +178,62 @@ QueryData genOsqueryPacks(QueryContext& context) {
return results;
}
for(auto const &pack_element : pack_config) {
Row r;
// Get the loaded data tree from global JSON configuration
const auto& packs_parsed_data = config.getParsedData("packs");
if (packs_parsed_data.count("packs") == 0) {
return results;
}
// Iterate through all the packs to get the configuration
auto pack_name = std::string(pack_element.first.data());
auto pack_path = std::string(pack_element.second.data());
r["name"] = TEXT(pack_name);
r["path"] = TEXT(pack_path);
// Read each pack configuration in JSON
pt::ptree pack_tree;
Status status = osquery::parseJSON(pack_path, pack_tree);
// Get all the parsed elements from the pack JSON file
if (pack_tree.count(pack_name) == 0) {
// Iterate through all the packs to get the configuration
for(auto const &pack_element : packs_parsed_data) {
// Make sure the element has items
if (pack_element.second.size() == 0) {
continue;
}
pt::ptree pack_file_element = pack_tree.get_child(pack_name);
std::string pack_name;
std::string pack_path;
// Get all the valid packs and return them in a map
// Find all the packs from loaded configuration
for (auto const &conf_element : pack_element.second) {
pack_name = std::string(conf_element.first.data());
pack_path = std::string(conf_element.second.data());
std::map<std::string, pt::ptree> clean_packs = queryPackParser->QueryPackParsePacks(pack_file_element, false, false);
// Read each pack configuration in JSON
pt::ptree pack_tree;
Status status = osquery::parseJSON(pack_path, pack_tree);
// Iterate through the already parsed and valid packs
std::map<std::string, pt::ptree>::iterator pk = clean_packs.begin();
for(pk=clean_packs.begin(); pk!=clean_packs.end(); ++pk) {
// Adding a prefix to the pack queries, to be easily found in the scheduled queries
std::string pk_name = "pack_" + pack_name + "_" + pk->first;
pt::ptree pk_data = pk->second;
// Get all the parsed elements from the pack JSON file
if (pack_tree.count(pack_name) == 0) {
continue;
}
pt::ptree pack_file_element = pack_tree.get_child(pack_name);
r["query_name"] = TEXT(pk->first);
// Get all the valid packs and return them in a map
std::map<std::string, pt::ptree> clean_packs = queryPackParser->QueryPackParsePacks(pack_file_element, false, false);
// Query data to return as Row
r["query"] = TEXT(pk_data.get<std::string>("query"));
r["interval"] = INTEGER(pk_data.get<int>("interval"));
r["platform"] = TEXT(pk_data.get<std::string>("platform"));
r["version"] = TEXT(pk_data.get<std::string>("version"));
r["description"] = TEXT(pk_data.get<std::string>("description"));
r["value"] = TEXT(pk_data.get<std::string>("value"));
// Iterate through the already parsed and valid packs
std::map<std::string, pt::ptree>::iterator pk = clean_packs.begin();
for(pk=clean_packs.begin(); pk!=clean_packs.end(); ++pk) {
// Adding a prefix to the pack queries, to be easily found in the scheduled queries
std::string pk_name = "pack_" + pack_name + "_" + pk->first;
pt::ptree pk_data = pk->second;
results.push_back(r);
// Query data to return as Row
r["query_name"] = TEXT(pk->first);
r["name"] = TEXT(pack_name);
r["path"] = TEXT(pack_path);
r["query"] = TEXT(pk_data.get<std::string>("query"));
r["interval"] = INTEGER(pk_data.get<int>("interval"));
r["platform"] = TEXT(pk_data.get<std::string>("platform"));
r["version"] = TEXT(pk_data.get<std::string>("version"));
r["description"] = TEXT(pk_data.get<std::string>("description"));
r["value"] = TEXT(pk_data.get<std::string>("value"));
r["scheduled_name"] = TEXT(pk_name);
int scheduled = Config::checkScheduledQuery(r["query"]) ? 1 : 0;
r["scheduled"] = INTEGER(scheduled);
results.push_back(r);
}
}
}