2014-12-18 18:50:47 +00:00
|
|
|
/*
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2014-12-18 18:50:47 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
2015-05-12 06:31:13 +00:00
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
2014-12-18 18:50:47 +00:00
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-09-10 01:54:53 +00:00
|
|
|
#pragma once
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2016-03-05 17:29:51 +00:00
|
|
|
#include <atomic>
|
2015-05-24 01:52:42 +00:00
|
|
|
#include <map>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <boost/property_tree/ptree.hpp>
|
|
|
|
|
|
|
|
#include <osquery/registry.h>
|
|
|
|
#include <osquery/status.h>
|
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
|
2016-03-05 17:29:51 +00:00
|
|
|
/**
|
|
|
|
* @brief A list of supported backing storage categories: called domains.
|
|
|
|
*
|
|
|
|
* RocksDB has a concept of "column families" which are kind of like tables
|
|
|
|
* in other databases. kDomainds is populated with a list of all column
|
|
|
|
* families. If a string exists in kDomains, it's a column family in the
|
|
|
|
* database.
|
|
|
|
*
|
|
|
|
* For SQLite-backed storage these are tables using a keyed index.
|
|
|
|
*/
|
|
|
|
extern const std::vector<std::string> kDomains;
|
|
|
|
|
2015-05-24 01:52:42 +00:00
|
|
|
/**
|
|
|
|
* @brief A backing storage domain name, used for key/value based storage.
|
|
|
|
*
|
|
|
|
* There are certain "cached" variables such as a node-unique UUID or negotiated
|
|
|
|
* 'node_key' following enrollment. If a value or setting must persist between
|
|
|
|
* osqueryi or osqueryd runs it should be stored using the kPersistentSetting%s
|
|
|
|
* domain.
|
|
|
|
*/
|
|
|
|
extern const std::string kPersistentSettings;
|
|
|
|
|
|
|
|
/// The "domain" where the results of scheduled queries are stored.
|
|
|
|
extern const std::string kQueries;
|
|
|
|
|
|
|
|
/// The "domain" where event results are stored, queued for querytime retrieval.
|
|
|
|
extern const std::string kEvents;
|
|
|
|
|
2015-05-29 00:21:20 +00:00
|
|
|
/**
|
|
|
|
* @brief The "domain" where buffered log results are stored.
|
|
|
|
*
|
|
|
|
* Logger plugins may shuttle logs to a remote endpoint or API call
|
|
|
|
* asynchronously. The backing store can be used to buffer results and status
|
|
|
|
* logs until the logger plugin-specific thread decided to flush.
|
|
|
|
*/
|
|
|
|
extern const std::string kLogs;
|
|
|
|
|
2015-05-24 01:52:42 +00:00
|
|
|
/**
|
|
|
|
* @brief A variant type for the SQLite type affinities.
|
|
|
|
*/
|
2015-12-03 08:53:54 +00:00
|
|
|
using RowData = std::string;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief A single row from a database query
|
|
|
|
*
|
|
|
|
* Row is a simple map where individual column names are keys, which map to
|
|
|
|
* the Row's respective value
|
|
|
|
*/
|
2015-12-03 08:53:54 +00:00
|
|
|
using Row = std::map<std::string, RowData>;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a Row into a property tree
|
|
|
|
*
|
|
|
|
* @param r the Row to serialize
|
|
|
|
* @param tree the output property tree
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status serializeRow(const Row& r, boost::property_tree::ptree& tree);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a Row object into a JSON string
|
|
|
|
*
|
|
|
|
* @param r the Row to serialize
|
|
|
|
* @param json the output JSON string
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
|
|
|
Status serializeRowJSON(const Row& r, std::string& json);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Deserialize a Row object from a property tree
|
|
|
|
*
|
|
|
|
* @param tree the input property tree
|
|
|
|
* @param r the output Row structure
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status deserializeRow(const boost::property_tree::ptree& tree, Row& r);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Deserialize a Row object from a JSON string
|
|
|
|
*
|
|
|
|
* @param json the input JSON string
|
|
|
|
* @param r the output Row structure
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
|
|
|
Status deserializeRowJSON(const std::string& json, Row& r);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The result set returned from a osquery SQL query
|
|
|
|
*
|
|
|
|
* QueryData is the canonical way to represent the results of SQL queries in
|
|
|
|
* osquery. It's just a vector of Row's.
|
|
|
|
*/
|
2015-12-03 08:53:54 +00:00
|
|
|
using QueryData = std::vector<Row>;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryData object into a property tree
|
|
|
|
*
|
|
|
|
* @param q the QueryData to serialize
|
|
|
|
* @param tree the output property tree
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status serializeQueryData(const QueryData& q,
|
|
|
|
boost::property_tree::ptree& tree);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryData object into a JSON string
|
|
|
|
*
|
|
|
|
* @param q the QueryData to serialize
|
|
|
|
* @param json the output JSON string
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
|
|
|
Status serializeQueryDataJSON(const QueryData& q, std::string& json);
|
|
|
|
|
|
|
|
/// Inverse of serializeQueryData, convert property tree to QueryData.
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status deserializeQueryData(const boost::property_tree::ptree& tree,
|
|
|
|
QueryData& qd);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Inverse of serializeQueryDataJSON, convert a JSON string to QueryData.
|
|
|
|
Status deserializeQueryDataJSON(const std::string& json, QueryData& qd);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Data structure representing the difference between the results of
|
|
|
|
* two queries
|
|
|
|
*
|
|
|
|
* The representation of two diffed QueryData result sets. Given and old and
|
|
|
|
* new QueryData, DiffResults indicates the "added" subset of rows and the
|
|
|
|
* "removed" subset of rows.
|
|
|
|
*/
|
|
|
|
struct DiffResults {
|
|
|
|
/// vector of added rows
|
|
|
|
QueryData added;
|
|
|
|
|
|
|
|
/// vector of removed rows
|
|
|
|
QueryData removed;
|
|
|
|
|
|
|
|
/// equals operator
|
|
|
|
bool operator==(const DiffResults& comp) const {
|
|
|
|
return (comp.added == added) && (comp.removed == removed);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// not equals operator
|
2016-08-31 22:32:20 +00:00
|
|
|
bool operator!=(const DiffResults& comp) const {
|
|
|
|
return !(*this == comp);
|
|
|
|
}
|
2015-05-24 01:52:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a DiffResults object into a property tree
|
|
|
|
*
|
|
|
|
* @param d the DiffResults to serialize
|
|
|
|
* @param tree the output property tree
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status serializeDiffResults(const DiffResults& d,
|
|
|
|
boost::property_tree::ptree& tree);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a DiffResults object into a JSON string
|
|
|
|
*
|
|
|
|
* @param d the DiffResults to serialize
|
|
|
|
* @param json the output JSON string
|
|
|
|
*
|
|
|
|
* @return an instance of osquery::Status, indicating the success or failure
|
|
|
|
* of the operation
|
|
|
|
*/
|
|
|
|
Status serializeDiffResultsJSON(const DiffResults& d, std::string& json);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Diff two QueryData objects and create a DiffResults object
|
|
|
|
*
|
|
|
|
* @param old_ the "old" set of results
|
|
|
|
* @param new_ the "new" set of results
|
|
|
|
*
|
|
|
|
* @return a DiffResults object which indicates the change from old_ to new_
|
|
|
|
*
|
|
|
|
* @see DiffResults
|
|
|
|
*/
|
|
|
|
DiffResults diff(const QueryData& old_, const QueryData& new_);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add a Row to a QueryData if the Row hasn't appeared in the QueryData
|
|
|
|
* already
|
|
|
|
*
|
|
|
|
* Note that this function will iterate through the QueryData list until a
|
|
|
|
* given Row is found (or not found). This shouldn't be that significant of an
|
|
|
|
* overhead for most use-cases, but it's worth keeping in mind before you use
|
|
|
|
* this in it's current state.
|
|
|
|
*
|
|
|
|
* @param q the QueryData list to append to
|
|
|
|
* @param r the Row to add to q
|
|
|
|
*
|
|
|
|
* @return true if the Row was added to the QueryData, false if it was not
|
|
|
|
*/
|
|
|
|
bool addUniqueRowToQueryData(QueryData& q, const Row& r);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Construct a new QueryData from an existing one, replacing all
|
2016-07-25 16:21:26 +00:00
|
|
|
* non-ASCII characters with their \\u encoding.
|
2015-05-24 01:52:42 +00:00
|
|
|
*
|
|
|
|
* This function is intended as a workaround for
|
|
|
|
* https://svn.boost.org/trac/boost/ticket/8883,
|
|
|
|
* and will allow rows containing data with non-ASCII characters to be stored in
|
|
|
|
* the database and parsed back into a property tree.
|
|
|
|
*
|
|
|
|
* @param oldData the old QueryData to copy
|
|
|
|
* @param newData the new escaped QueryData object
|
|
|
|
*/
|
|
|
|
void escapeQueryData(const QueryData& oldData, QueryData& newData);
|
|
|
|
|
|
|
|
/**
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
* @brief performance statistics about a query
|
2015-05-24 01:52:42 +00:00
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
struct QueryPerformance {
|
2015-05-24 01:52:42 +00:00
|
|
|
/// Number of executions.
|
|
|
|
size_t executions;
|
|
|
|
|
2015-11-02 18:33:20 +00:00
|
|
|
/// Last UNIX time in seconds the query was executed successfully.
|
|
|
|
size_t last_executed;
|
|
|
|
|
2015-05-24 01:52:42 +00:00
|
|
|
/// Total wall time taken
|
2015-06-12 21:09:42 +00:00
|
|
|
unsigned long long int wall_time;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Total user time (cycles)
|
2015-06-12 21:09:42 +00:00
|
|
|
unsigned long long int user_time;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Total system time (cycles)
|
2015-06-12 21:09:42 +00:00
|
|
|
unsigned long long int system_time;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Average memory differentials. This should be near 0.
|
2015-07-02 17:32:11 +00:00
|
|
|
unsigned long long int average_memory;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Total characters, bytes, generated by query.
|
2015-06-12 21:09:42 +00:00
|
|
|
unsigned long long int output_size;
|
2015-05-24 01:52:42 +00:00
|
|
|
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
QueryPerformance()
|
|
|
|
: executions(0),
|
2015-11-02 18:33:20 +00:00
|
|
|
last_executed(0),
|
2015-05-24 01:52:42 +00:00
|
|
|
wall_time(0),
|
|
|
|
user_time(0),
|
|
|
|
system_time(0),
|
2015-07-02 17:32:11 +00:00
|
|
|
average_memory(0),
|
2015-05-24 01:52:42 +00:00
|
|
|
output_size(0) {}
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2016-08-31 22:32:20 +00:00
|
|
|
* @brief Represents the relevant parameters of a scheduled query.
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
*
|
|
|
|
* Within the context of osqueryd, a scheduled query may have many relevant
|
|
|
|
* attributes. Those attributes are represented in this data structure.
|
|
|
|
*/
|
|
|
|
struct ScheduledQuery {
|
|
|
|
/// The SQL query.
|
|
|
|
std::string query;
|
|
|
|
|
|
|
|
/// How often the query should be executed, in second.
|
|
|
|
size_t interval;
|
|
|
|
|
|
|
|
/// A temporary splayed internal.
|
|
|
|
size_t splayed_interval;
|
|
|
|
|
|
|
|
/// Set of query options.
|
|
|
|
std::map<std::string, bool> options;
|
|
|
|
|
|
|
|
ScheduledQuery() : interval(0), splayed_interval(0) {}
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// equals operator
|
|
|
|
bool operator==(const ScheduledQuery& comp) const {
|
|
|
|
return (comp.query == query) && (comp.interval == interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// not equals operator
|
2016-08-31 22:32:20 +00:00
|
|
|
bool operator!=(const ScheduledQuery& comp) const {
|
|
|
|
return !(*this == comp);
|
|
|
|
}
|
2015-05-24 01:52:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Query results from a schedule, snapshot, or ad-hoc execution.
|
|
|
|
*
|
|
|
|
* When a scheduled query yields new results, we need to log that information
|
|
|
|
* to our upstream logging receiver. A QueryLogItem contains metadata and
|
|
|
|
* results in potentially-differential form for a logger.
|
|
|
|
*/
|
|
|
|
struct QueryLogItem {
|
|
|
|
/// Differential results from the query.
|
|
|
|
DiffResults results;
|
|
|
|
|
|
|
|
/// Optional snapshot results, no differential applied.
|
|
|
|
QueryData snapshot_results;
|
|
|
|
|
|
|
|
/// The name of the scheduled query.
|
|
|
|
std::string name;
|
|
|
|
|
|
|
|
/// The identifier (hostname, or uuid) of the host.
|
|
|
|
std::string identifier;
|
|
|
|
|
|
|
|
/// The time that the query was executed, seconds as UNIX time.
|
2016-03-29 06:37:34 +00:00
|
|
|
size_t time{0};
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// The time that the query was executed, an ASCII string.
|
|
|
|
std::string calendar_time;
|
|
|
|
|
2016-03-29 06:37:34 +00:00
|
|
|
/// A set of additional fields to emit with the log line.
|
|
|
|
std::map<std::string, std::string> decorations;
|
|
|
|
|
2015-05-24 01:52:42 +00:00
|
|
|
/// equals operator
|
|
|
|
bool operator==(const QueryLogItem& comp) const {
|
|
|
|
return (comp.results == results) && (comp.name == name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// not equals operator
|
2016-08-31 22:32:20 +00:00
|
|
|
bool operator!=(const QueryLogItem& comp) const {
|
|
|
|
return !(*this == comp);
|
|
|
|
}
|
2015-05-24 01:52:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryLogItem object into a property tree
|
|
|
|
*
|
|
|
|
* @param item the QueryLogItem to serialize
|
|
|
|
* @param tree the output property tree
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status serializeQueryLogItem(const QueryLogItem& item,
|
|
|
|
boost::property_tree::ptree& tree);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryLogItem object into a JSON string
|
|
|
|
*
|
|
|
|
* @param item the QueryLogItem to serialize
|
|
|
|
* @param json the output JSON string
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
|
|
|
Status serializeQueryLogItemJSON(const QueryLogItem& item, std::string& json);
|
|
|
|
|
|
|
|
/// Inverse of serializeQueryLogItem, convert property tree to QueryLogItem.
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status deserializeQueryLogItem(const boost::property_tree::ptree& tree,
|
|
|
|
QueryLogItem& item);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/// Inverse of serializeQueryLogItem, convert a JSON string to QueryLogItem.
|
|
|
|
Status deserializeQueryLogItemJSON(const std::string& json, QueryLogItem& item);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryLogItem object into a property tree
|
|
|
|
* of events, a list of actions.
|
|
|
|
*
|
|
|
|
* @param item the QueryLogItem to serialize
|
|
|
|
* @param tree the output property tree
|
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
[fix #1390] query pack re-org
This commit contains the features specified in #1390 as well as a
refactoring of the general osquery configuration code.
The API for the config plugins hasn't changed, although now there's a
`genPack` method that config plugins can implement. If a plugin doesn't
implement `genPack`, then the map<string, string> format cannot be used.
The default config plugin, the filesystem plugin, now implements
`genPack`, so existing query packs code will continue to work as it
always has.
Now many other config plugins can implement custom pack handling for
what makes sense in their context. `genPacks` is not a pure virtual, so
it doesn't have to be implemented in your plugin if you don't want to
use it. Also, more importantly, all config plugins can use the standard
inline pack format if they want to use query packs. Which is awesome.
For more information, refer to #1390, the documentation and the doxygen
comments included with this pull requests, as well as the following
example config which is now supported, regardless of what config plugin
you're using:
```json
{
"options": {
"enable_monitor": "true"
},
"packs": {
"core_os_monitoring": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"kernel_modules": {
"query": "SELECT name, size FROM kernel_modules;",
"interval": 600
},
"system_controls": {
"query": "SELECT * FROM system_controls;",
"interval": 600,
"snapshot": true,
},
"usb_devices": {
"query": "SELECT * FROM usb_devices;",
"interval": 600
}
}
},
"osquery_internal_info": {
"version": "1.4.5",
"discovery": [
"select pid from processes where name like '%osqueryd%';"
],
"queries": {
"info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 60,
"snapshot": true
},
"registry": {
"query": "SELECT * FROM osquery_registry;",
"interval": 600,
"snapshot": true
},
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;",
"interval": 60,
"snapshot": true
}
}
}
}
}
```
The `osquery_packs` table was modified to remove the superfluous
columns which could already have been found in `osquery_schedule`. Two
more columns were added in their place, representing stats about pack's
discovery query execution history.
Notably, the internal API for the `osquery::Config` class has changed
rather dramatically as apart of the refactoring. We think this is an
improvement. While strictly adhering to the osquery config plugin
interface will have avoided any compatibility errors, advanced users may
notice compilation errors if they access config data directly. All
internal users of the config have obviously been updated. Yet another
reason to merge your code into mainline; we update it for you when we
refactor!
2015-08-19 20:27:49 +00:00
|
|
|
Status serializeQueryLogItemAsEvents(const QueryLogItem& item,
|
|
|
|
boost::property_tree::ptree& tree);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Serialize a QueryLogItem object into a JSON string of events,
|
|
|
|
* a list of actions.
|
|
|
|
*
|
|
|
|
* @param i the QueryLogItem to serialize
|
2016-07-25 16:21:26 +00:00
|
|
|
* @param items vector of JSON output strings
|
2015-05-24 01:52:42 +00:00
|
|
|
*
|
|
|
|
* @return Status indicating the success or failure of the operation
|
|
|
|
*/
|
|
|
|
Status serializeQueryLogItemAsEventsJSON(const QueryLogItem& i,
|
2015-12-03 08:53:54 +00:00
|
|
|
std::vector<std::string>& items);
|
2015-05-24 01:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief An osquery backing storage (database) type that persists executions.
|
|
|
|
*
|
|
|
|
* The osquery tools need a high-performance storage and indexing mechanism for
|
|
|
|
* storing intermediate results from EventPublisher%s, persisting one-time
|
|
|
|
* generated values, and performing non-memory backed differentials.
|
|
|
|
*
|
|
|
|
* Practically, osquery is built around RocksDB's performance guarantees and
|
|
|
|
* all of the internal APIs expect RocksDB's indexing and read performance.
|
|
|
|
* However, access to this representation of a backing-store is still abstracted
|
|
|
|
* to removing RocksDB as a dependency for the osquery SDK.
|
|
|
|
*/
|
|
|
|
class DatabasePlugin : public Plugin {
|
2016-03-05 17:29:51 +00:00
|
|
|
public:
|
2015-05-24 01:52:42 +00:00
|
|
|
/**
|
|
|
|
* @brief Perform a domain and key lookup from the backing store.
|
|
|
|
*
|
|
|
|
* Database value access indexing is abstracted into domains and keys.
|
|
|
|
* Both are string values but exist separately for simple indexing without
|
|
|
|
* API-enforcing tokenization. In some cases we do add a component-specific
|
|
|
|
* tokeninzation to keys.
|
|
|
|
*
|
|
|
|
* @param domain A string value representing abstract storage indexing.
|
|
|
|
* @param key A string value representing the lookup/retrieval key.
|
|
|
|
* @param value The output parameter, left empty if the key does not exist.
|
|
|
|
* @return Failure if the data could not be accessed. It is up to the plugin
|
|
|
|
* to determine if a missing key means a non-success status.
|
|
|
|
*/
|
|
|
|
virtual Status get(const std::string& domain,
|
|
|
|
const std::string& key,
|
|
|
|
std::string& value) const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Store a string-represented value using a domain and key index.
|
|
|
|
*
|
|
|
|
* See DatabasePlugin::get for discussion around domain and key use.
|
|
|
|
*
|
|
|
|
* @param domain A string value representing abstract storage indexing.
|
|
|
|
* @param key A string value representing the lookup/retrieval key.
|
|
|
|
* @param value A string value representing the data.
|
|
|
|
* @return Failure if the data could not be stored. It is up to the plugin
|
|
|
|
* to determine if a conflict/overwrite should return different status text.
|
|
|
|
*/
|
|
|
|
virtual Status put(const std::string& domain,
|
|
|
|
const std::string& key,
|
|
|
|
const std::string& value) = 0;
|
|
|
|
|
|
|
|
/// Data removal method.
|
|
|
|
virtual Status remove(const std::string& domain, const std::string& k) = 0;
|
|
|
|
|
|
|
|
virtual Status scan(const std::string& domain,
|
2016-01-21 08:23:05 +00:00
|
|
|
std::vector<std::string>& results,
|
2016-03-05 17:29:51 +00:00
|
|
|
const std::string& prefix,
|
2016-01-21 08:23:05 +00:00
|
|
|
size_t max = 0) const {
|
2015-05-24 01:52:42 +00:00
|
|
|
return Status(0, "Not used");
|
|
|
|
}
|
|
|
|
|
2016-03-05 17:29:51 +00:00
|
|
|
/**
|
|
|
|
* @brief Shutdown the database and release initialization resources.
|
|
|
|
*
|
2016-07-25 16:21:26 +00:00
|
|
|
* Assume that a plugin may override #tearDown and choose to close resources
|
2016-03-05 17:29:51 +00:00
|
|
|
* when the registry is stopping. Most plugins will implement a mutex around
|
2016-07-25 16:21:26 +00:00
|
|
|
* initialization and destruction and assume #setUp and #tearDown will
|
2016-03-05 17:29:51 +00:00
|
|
|
* dictate the flow in most situations.
|
|
|
|
*/
|
|
|
|
virtual ~DatabasePlugin() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Support the registry calling API for extensions.
|
|
|
|
*
|
|
|
|
* The database plugin "fast-calls" directly to local plugins.
|
|
|
|
* Extensions cannot use an extension-local backing store so their requests
|
|
|
|
* are routed like all other plugins.
|
|
|
|
*/
|
|
|
|
Status call(const PluginRequest& request, PluginResponse& response) override;
|
|
|
|
|
2015-05-24 01:52:42 +00:00
|
|
|
public:
|
2016-03-05 17:29:51 +00:00
|
|
|
/// Database-specific workflow: reset the originally request instance.
|
|
|
|
virtual Status reset() final;
|
|
|
|
|
|
|
|
/// Database-specific workflow: perform an initialize, then reset.
|
|
|
|
bool checkDB();
|
|
|
|
|
|
|
|
/// Require all DBHandle accesses to open a read and write handle.
|
2016-08-31 22:32:20 +00:00
|
|
|
static void setRequireWrite(bool rw) {
|
|
|
|
kDBHandleOptionRequireWrite = rw;
|
|
|
|
}
|
2016-03-05 17:29:51 +00:00
|
|
|
|
|
|
|
/// Allow DBHandle creations.
|
2016-08-31 22:32:20 +00:00
|
|
|
static void setAllowOpen(bool ao) {
|
|
|
|
kDBHandleOptionAllowOpen = ao;
|
|
|
|
}
|
2016-03-05 17:29:51 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
/// Control availability of the RocksDB handle (default false).
|
|
|
|
static bool kDBHandleOptionAllowOpen;
|
|
|
|
|
|
|
|
/// The database must be opened in a R/W mode (default false).
|
|
|
|
static bool kDBHandleOptionRequireWrite;
|
|
|
|
|
|
|
|
/// A queryable mutex around database sanity checking.
|
|
|
|
static std::atomic<bool> kCheckingDB;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief Allow the initializer to check the active database plugin.
|
|
|
|
*
|
2016-07-25 16:21:26 +00:00
|
|
|
* Unlink the initializer's Initializer::initActivePlugin helper method, the
|
|
|
|
* database plugin should always be within the core. There is no need to
|
|
|
|
* discover the active plugin via the registry or extensions API.
|
2016-03-05 17:29:51 +00:00
|
|
|
*
|
|
|
|
* The database should setUp in preparation for accesses.
|
|
|
|
*/
|
|
|
|
static bool initPlugin();
|
|
|
|
|
|
|
|
/// Allow shutdown before exit.
|
|
|
|
static void shutdown();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// The database was opened in a ReadOnly mode.
|
|
|
|
bool read_only_{false};
|
|
|
|
|
|
|
|
/// True if the database was started in an in-memory mode.
|
|
|
|
bool in_memory_{false};
|
|
|
|
|
|
|
|
/// Original requested path on disk.
|
|
|
|
std::string path_;
|
2015-05-24 01:52:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Lookup a value from the active osquery DatabasePlugin storage.
|
|
|
|
*
|
|
|
|
* See DatabasePlugin::get for discussion around domain and key use.
|
|
|
|
* Extensions, components, plugins, and core code should use getDatabaseValue
|
|
|
|
* as a wrapper around the current tool's choice of a backing storage plugin.
|
|
|
|
*
|
|
|
|
* @param domain A string value representing abstract storage indexing.
|
|
|
|
* @param key A string value representing the lookup/retrieval key.
|
|
|
|
* @param value The output parameter, left empty if the key does not exist.
|
|
|
|
* @return Storage operation status.
|
|
|
|
*/
|
|
|
|
Status getDatabaseValue(const std::string& domain,
|
|
|
|
const std::string& key,
|
|
|
|
std::string& value);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set or put a value into the active osquery DatabasePlugin storage.
|
|
|
|
*
|
|
|
|
* See DatabasePlugin::get for discussion around domain and key use.
|
|
|
|
* Extensions, components, plugins, and core code should use setDatabaseValue
|
|
|
|
* as a wrapper around the current tool's choice of a backing storage plugin.
|
|
|
|
*
|
|
|
|
* @param domain A string value representing abstract storage indexing.
|
|
|
|
* @param key A string value representing the lookup/retrieval key.
|
|
|
|
* @param value A string value representing the data.
|
|
|
|
* @return Storage operation status.
|
|
|
|
*/
|
|
|
|
Status setDatabaseValue(const std::string& domain,
|
|
|
|
const std::string& key,
|
|
|
|
const std::string& value);
|
|
|
|
|
|
|
|
/// Remove a domain/key identified value from backing-store.
|
|
|
|
Status deleteDatabaseValue(const std::string& domain, const std::string& key);
|
|
|
|
|
2015-05-29 00:21:20 +00:00
|
|
|
/// Get a list of keys for a given domain.
|
|
|
|
Status scanDatabaseKeys(const std::string& domain,
|
2016-01-21 08:23:05 +00:00
|
|
|
std::vector<std::string>& keys,
|
|
|
|
size_t max = 0);
|
2015-05-29 00:21:20 +00:00
|
|
|
|
2016-03-05 17:29:51 +00:00
|
|
|
/// Get a list of keys for a given domain.
|
|
|
|
Status scanDatabaseKeys(const std::string& domain,
|
|
|
|
std::vector<std::string>& keys,
|
|
|
|
const std::string& prefix,
|
|
|
|
size_t max = 0);
|
|
|
|
|
2015-12-04 23:41:40 +00:00
|
|
|
/// Allow callers to scan each column family and print each value.
|
|
|
|
void dumpDatabase();
|
2015-05-24 01:52:42 +00:00
|
|
|
}
|