mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-06 09:35:20 +00:00
Config MD5 a bit more deterministic
``` $ ./build/darwin/osquery/osqueryi --config_path=/asdfasdfadfs E0903 11:45:02.050308 1990836992 init.cpp:370] Error reading config: config file does not exist Using a virtual database. Need help, type '.help' osquery> .mode line osquery> .all osquery_info pid = 33700 version = 1.5.2-43-gb06fa92 config_md5 = config_valid = 0 config_path = /asdfasdfadfs extensions = active build_platform = darwin build_distro = 10.10 osquery> .exit $ ./build/darwin/osquery/osqueryi osquery> .mode line osquery> .all osquery_info pid = 33781 version = 1.5.2-43-gb06fa92 config_md5 = 8a432ac93d3de080c62d77ba99b89783 config_valid = 1 config_path = /var/osquery/osquery.conf extensions = active build_platform = darwin build_distro = 10.10 osquery> .exit ```
This commit is contained in:
parent
b06fa92e76
commit
de58353131
@ -91,7 +91,7 @@ class Schedule {
|
||||
*/
|
||||
class Config {
|
||||
private:
|
||||
Config() : schedule_(Schedule()){};
|
||||
Config() : schedule_(Schedule()), valid_(false){};
|
||||
|
||||
protected:
|
||||
typedef boost::unique_lock<boost::shared_mutex> WriteLock;
|
||||
@ -172,6 +172,17 @@ class Config {
|
||||
*/
|
||||
Status getMD5(std::string& hash);
|
||||
|
||||
/**
|
||||
* @brief Hash a source's config data
|
||||
*
|
||||
* @param source is the place where the config content came from
|
||||
* @param content is the content of the config data for a given source
|
||||
*/
|
||||
void hashSource(const std::string& source, const std::string& content);
|
||||
|
||||
/// Whether or not the last loaded config was valid
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* @brief Add a pack to the osquery schedule
|
||||
*/
|
||||
@ -270,7 +281,8 @@ class Config {
|
||||
Schedule schedule_;
|
||||
std::map<std::string, QueryPerformance> performance_;
|
||||
std::map<std::string, std::vector<std::string> > files_;
|
||||
std::string hash_;
|
||||
std::map<std::string, std::string> hash_;
|
||||
bool valid_;
|
||||
|
||||
private:
|
||||
friend class ConfigTests;
|
||||
|
@ -34,6 +34,7 @@ boost::shared_mutex config_schedule_mutex_;
|
||||
boost::shared_mutex config_performance_mutex_;
|
||||
boost::shared_mutex config_files_mutex_;
|
||||
boost::shared_mutex config_hash_mutex_;
|
||||
boost::shared_mutex config_valid_mutex_;
|
||||
|
||||
void Config::addPack(const Pack& pack) {
|
||||
WriteLock wlock(config_schedule_mutex_);
|
||||
@ -78,7 +79,7 @@ void Config::clearSchedule() {
|
||||
|
||||
void Config::clearHash() {
|
||||
WriteLock wlock(config_hash_mutex_);
|
||||
std::string().swap(hash_);
|
||||
hash_.erase(hash_.begin(), hash_.end());
|
||||
}
|
||||
|
||||
void Config::clearFiles() {
|
||||
@ -86,7 +87,13 @@ void Config::clearFiles() {
|
||||
files_.erase(files_.begin(), files_.end());
|
||||
}
|
||||
|
||||
bool Config::isValid() {
|
||||
ReadLock rlock(config_valid_mutex_);
|
||||
return valid_;
|
||||
}
|
||||
|
||||
Status Config::load() {
|
||||
valid_ = false;
|
||||
auto& config_plugin = Registry::getActive("config");
|
||||
if (!Registry::exists("config", config_plugin)) {
|
||||
return Status(1, "Missing config plugin " + config_plugin);
|
||||
@ -102,6 +109,7 @@ Status Config::load() {
|
||||
clearSchedule();
|
||||
clearHash();
|
||||
clearFiles();
|
||||
valid_ = true;
|
||||
|
||||
// if there was a response, parse it and update internal state
|
||||
if (response.size() > 0) {
|
||||
@ -130,6 +138,8 @@ Status Config::update(const std::map<std::string, std::string>& config) {
|
||||
}
|
||||
|
||||
for (const auto& source : config) {
|
||||
hashSource(source.first, source.second);
|
||||
|
||||
// load the config (source.second) into a pt::ptree
|
||||
std::stringstream json;
|
||||
json << source.second;
|
||||
@ -270,53 +280,30 @@ void Config::getPerformanceStats(
|
||||
}
|
||||
}
|
||||
|
||||
void Config::hashSource(const std::string& source, const std::string& content) {
|
||||
WriteLock wlock(config_hash_mutex_);
|
||||
hash_[source] =
|
||||
hashFromBuffer(HASH_TYPE_MD5, &(content.c_str())[0], content.size());
|
||||
}
|
||||
|
||||
Status Config::getMD5(std::string& hash) {
|
||||
if (hash_.empty()) {
|
||||
std::vector<char> buffer;
|
||||
auto add = [&buffer](const std::string& text) {
|
||||
for (const auto& c : text) {
|
||||
buffer.push_back(c);
|
||||
}
|
||||
};
|
||||
scheduledQueries(
|
||||
[&add, &buffer](const std::string& name, const ScheduledQuery& query) {
|
||||
add(name);
|
||||
add(query.query);
|
||||
add(std::to_string(query.interval));
|
||||
for (const auto& it : query.options) {
|
||||
add(it.first);
|
||||
add(it.second ? "true" : "false");
|
||||
}
|
||||
});
|
||||
|
||||
auto parsers = Registry::all("config_parser");
|
||||
for (const auto& parser : parsers) {
|
||||
add(parser.first);
|
||||
try {
|
||||
if (parser.second == nullptr || parser.second.get() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
auto plugin =
|
||||
std::static_pointer_cast<ConfigParserPlugin>(parser.second);
|
||||
if (plugin == nullptr || plugin.get() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
std::stringstream ss;
|
||||
pt::write_json(ss, plugin->getData());
|
||||
add(ss.str());
|
||||
} catch (const std::bad_cast& e) {
|
||||
LOG(ERROR) << "Error casting config parser plugin: " << e.what();
|
||||
} catch (const pt::ptree_error& e) {
|
||||
LOG(ERROR)
|
||||
<< "Error writing config parser content to JSON: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(buffer.begin(), buffer.end());
|
||||
hash_ = hashFromBuffer(HASH_TYPE_MD5, &buffer[0], buffer.size());
|
||||
if (valid_) {
|
||||
return Status(1, "Current config is not valid");
|
||||
}
|
||||
|
||||
hash = hash_;
|
||||
ReadLock rlock(config_hash_mutex_);
|
||||
std::vector<char> buffer;
|
||||
buffer.reserve(hash_.size() * 32);
|
||||
auto add = [&buffer](const std::string& text) {
|
||||
for (const auto& c : text) {
|
||||
buffer.push_back(c);
|
||||
}
|
||||
};
|
||||
for (const auto it : hash_) {
|
||||
add(it.second);
|
||||
}
|
||||
|
||||
hash = hashFromBuffer(HASH_TYPE_MD5, &buffer[0], buffer.size());
|
||||
return Status(0, "OK");
|
||||
}
|
||||
|
||||
|
@ -365,7 +365,10 @@ void Initializer::start() {
|
||||
}
|
||||
|
||||
// Load the osquery config using the default/active config plugin.
|
||||
Config::getInstance().load();
|
||||
auto s = Config::getInstance().load();
|
||||
if (!s.ok()) {
|
||||
LOG(ERROR) << "Error reading config: " << s.toString();
|
||||
}
|
||||
|
||||
// Initialize the status and result plugin logger.
|
||||
initActivePlugin("logger", FLAGS_logger_plugin);
|
||||
|
@ -144,6 +144,8 @@ QueryData genOsqueryInfo(QueryContext& context) {
|
||||
VLOG(1) << "Could not retrieve config hash: " << s.toString();
|
||||
}
|
||||
|
||||
r["config_valid"] = Config::getInstance().isValid() ? INTEGER(1) : INTEGER(0);
|
||||
|
||||
r["config_path"] = Flag::getValue("config_path");
|
||||
r["extensions"] =
|
||||
(pingExtension(FLAGS_extensions_socket).ok()) ? "active" : "inactive";
|
||||
|
@ -3,13 +3,12 @@ description("Top level information about the running version of osquery.")
|
||||
schema([
|
||||
Column("pid", INTEGER, "Process (or thread) ID"),
|
||||
Column("version", TEXT, "osquery toolkit version"),
|
||||
Column("config_md5", TEXT, "md5 hash of the working configuration"),
|
||||
Column("config_path", TEXT,
|
||||
"Optional: path to filesystem config plugin content"),
|
||||
Column("config_md5", TEXT, "md5 hash of the working configuration state"),
|
||||
Column("config_valid", INTEGER, "1 if the config was loaded and considered valid, else 0"),
|
||||
Column("config_path", TEXT, "Optional: path to filesystem config plugin content"),
|
||||
Column("extensions", TEXT, "osquery extensions status"),
|
||||
Column("build_platform", TEXT, "osquery toolkit build platform"),
|
||||
Column("build_distro", TEXT,
|
||||
"osquery toolkit platform distribution name (os version)"),
|
||||
Column("build_distro", TEXT, "osquery toolkit platform distribution name (os version)"),
|
||||
])
|
||||
attributes(utility=True)
|
||||
implementation("osquery@genOsqueryInfo")
|
||||
|
Loading…
Reference in New Issue
Block a user