2014-07-31 00:35:19 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
2014-09-10 01:54:53 +00:00
|
|
|
#pragma once
|
2014-07-31 00:35:19 +00:00
|
|
|
|
|
|
|
#include <deque>
|
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
|
|
|
|
2014-08-05 23:13:55 +00:00
|
|
|
#include <gtest/gtest_prod.h>
|
2014-07-31 00:35:19 +00:00
|
|
|
|
|
|
|
#include "osquery/config.h"
|
|
|
|
#include "osquery/database/db_handle.h"
|
|
|
|
#include "osquery/database/results.h"
|
2014-08-05 23:13:55 +00:00
|
|
|
#include "osquery/status.h"
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
namespace osquery {
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-09-16 00:13:22 +00:00
|
|
|
/// Error message used when a query name isn't found in the database
|
2014-07-31 00:35:19 +00:00
|
|
|
extern const std::string kQueryNameNotFoundError;
|
|
|
|
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief A class that is used to interact with the historical on-disk storage
|
|
|
|
* for a given query.
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
class Query {
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Constructor which sets up necessary parameters of a Query object
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* Given a query, this constructor calculates the value of columnFamily_,
|
|
|
|
* which can be accessed via the getColumnFamilyName getter method.
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param q an OsqueryScheduledQuery struct which represents the query which
|
|
|
|
* you would like to interact with
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-15 18:09:33 +00:00
|
|
|
explicit Query(osquery::OsqueryScheduledQuery q) : query_(q) {}
|
2014-07-31 00:35:19 +00:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Getters and setters
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Getter for the name of a given scheduled query
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return the name of the scheduled query which is being operated on
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
|
|
|
std::string getQueryName();
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Getter for the SQL query of a scheduled query
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return the SQL of the scheduled query which is being operated on
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
std::string getQuery();
|
|
|
|
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Getter for the interval of a scheduled query
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return the interval of the scheduled query which is being operated on
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
int getInterval();
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Data access methods
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Serialize the data in RocksDB into a useful data structure
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method retrieves the data from RocksDB and returns the data in a
|
|
|
|
* HistoricalQueryResults struct.
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param hQR a reference to a HistoricalQueryResults struct which will be
|
|
|
|
* populated with results if the osquery::Status indicates the operation was
|
|
|
|
* successful
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-08-05 23:13:55 +00:00
|
|
|
osquery::Status getHistoricalQueryResults(HistoricalQueryResults& hQR);
|
2014-08-15 07:25:30 +00:00
|
|
|
|
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Serialize the data in RocksDB into a useful data structure using a
|
2014-09-16 00:13:22 +00:00
|
|
|
* custom database handle
|
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method is the same as getHistoricalQueryResults(), but with the
|
|
|
|
* addition of a parameter which allows you to pass a custom RocksDB
|
|
|
|
* database handle. This version of getHistoricalQueryResults should only be
|
|
|
|
* used internally and by unit tests.
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param hQR a reference to a HistoricalQueryResults struct which will be
|
|
|
|
* populated with results if the osquery::Status indicates the operation was
|
|
|
|
* successful @param db the RocksDB database handle to use to acquire the
|
|
|
|
* relevant data
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param db a shared pointer to a custom DBHandle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @see getHistoricalQueryResults
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-08-15 07:25:30 +00:00
|
|
|
osquery::Status getHistoricalQueryResults(HistoricalQueryResults& hQR,
|
2014-09-16 07:36:49 +00:00
|
|
|
std::shared_ptr<DBHandle> db);
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Get the names of all historical queries that are stored in RocksDB
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* If you'd like to perform some database maintenance, getStoredQueryNames()
|
|
|
|
* allows you to get a vector of the names of all queries which are
|
|
|
|
* currently stored in RocksDB
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return a vector containing the string names of all scheduled queries
|
|
|
|
* which currently exist in the database
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
static std::vector<std::string> getStoredQueryNames();
|
2014-08-15 07:25:30 +00:00
|
|
|
|
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Get the names of all historical queries that are stored in RocksDB
|
|
|
|
* using a custom database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method is the same as getStoredQueryNames(), but with the addition
|
|
|
|
* of a parameter which allows you to pass a custom RocksDB database handle.
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param db a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return a vector containing the string names of all scheduled queries
|
|
|
|
* which currently exist in the database
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @see getStoredQueryNames()
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-08-15 07:25:30 +00:00
|
|
|
static std::vector<std::string> getStoredQueryNames(
|
|
|
|
std::shared_ptr<DBHandle> db);
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Accessor method for checking if a given scheduled query exists in
|
|
|
|
* the database
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return a boolean indicating wether or not the scheduled query which is
|
|
|
|
* being operated on already exists in the database
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
bool isQueryNameInDatabase();
|
2014-08-15 07:25:30 +00:00
|
|
|
|
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Accessor method for checking if a given scheduled query exists in
|
|
|
|
* the database, using a custom database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method is the same as isQueryNameInDatabase(), but with the addition
|
|
|
|
* of a parameter which allows you to pass a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param db a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return a boolean indicating wether or not the scheduled query which is
|
|
|
|
* being operated on already exists in the database
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
bool isQueryNameInDatabase(std::shared_ptr<DBHandle> db);
|
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Add a new set of results to the persistant storage
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* Given the results of the execution of a scheduled query, add the results
|
|
|
|
* to the database using addNewResults
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param qd the QueryData object, which has the results of the query which
|
|
|
|
* you would like to store
|
|
|
|
* @param unix_time the time that the query was executed
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:29:28 +00:00
|
|
|
osquery::Status addNewResults(const osquery::QueryData& qd, int unix_time);
|
2014-08-15 07:25:30 +00:00
|
|
|
|
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Add a new set of results to the persistant storage using a custom
|
|
|
|
* database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method is the same as addNewResults(), but with the addition of a
|
|
|
|
* parameter which allows you to pass a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param qd the QueryData object, which has the results of the query which
|
|
|
|
* you would like to store
|
|
|
|
* @param unix_time the time that the query was executed
|
|
|
|
* @param db a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:27:09 +00:00
|
|
|
osquery::Status addNewResults(const osquery::QueryData& qd,
|
2014-08-15 07:25:30 +00:00
|
|
|
int unix_time,
|
|
|
|
std::shared_ptr<DBHandle> db);
|
|
|
|
|
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Add a new set of results to the persistant storage and get back
|
|
|
|
* the diff results.
|
|
|
|
*
|
|
|
|
* Given the results of the execution of a scheduled query, add the results
|
|
|
|
* to the database using addNewResults and get back a data structure
|
|
|
|
* indicating what rows in the query's results have changed.
|
|
|
|
*
|
|
|
|
* @param qd the QueryData object, which has the results of the query which
|
|
|
|
* you would like to store
|
|
|
|
* @param dr a reference to a DiffResults object, which will be populated
|
|
|
|
* with the difference of the execution which is currently in the database
|
|
|
|
* and the execution you just put in the database
|
|
|
|
* @param unix_time the time that the query was executed
|
|
|
|
*
|
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:27:09 +00:00
|
|
|
osquery::Status addNewResults(const osquery::QueryData& qd,
|
|
|
|
osquery::DiffResults& dr,
|
2014-08-15 07:25:30 +00:00
|
|
|
int unix_time);
|
|
|
|
|
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief Add a new set of results to the persistant storage and get back
|
2014-09-16 00:13:22 +00:00
|
|
|
* the diff results, using a custom database handle.
|
|
|
|
*
|
|
|
|
* This method is the same as addNewResults(), but with the addition of a
|
|
|
|
* parameter which allows you to pass a custom RocksDB database handle
|
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param qd the QueryData object, which has the results of the query which
|
|
|
|
* you would like to store
|
|
|
|
* @param dr a reference to a DiffResults object, which will be populated
|
|
|
|
* with the difference of the execution which is currently in the database
|
|
|
|
* and the execution you just put in the database
|
|
|
|
* @param calculate_diff a boolean indicating wether or not you'd like to
|
|
|
|
* calculate the diff result to be stored in the dr parameter.
|
|
|
|
* @param unix_time the time that the query was executed
|
|
|
|
*
|
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:27:09 +00:00
|
|
|
osquery::Status addNewResults(const osquery::QueryData& qd,
|
|
|
|
osquery::DiffResults& dr,
|
2014-08-15 07:25:30 +00:00
|
|
|
bool calculate_diff,
|
|
|
|
int unix_time,
|
|
|
|
std::shared_ptr<DBHandle> db);
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
public:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief A getter for the most recent result set for a scheduled query
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param qd the QueryData object which will be populated if all operations
|
|
|
|
* are successful
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:27:09 +00:00
|
|
|
osquery::Status getCurrentResults(osquery::QueryData& qd);
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
private:
|
2014-09-16 07:28:23 +00:00
|
|
|
/**
|
|
|
|
* @brief A getter for the most recent result set for a scheduled query,
|
|
|
|
* but with the addition of a parameter which allows you to pass a custom
|
|
|
|
* RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* This method is the same as getCurrentResults(), but with addition of a
|
|
|
|
* parameter which allows you to pass a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @param qd the QueryData object which will be populated if all operations
|
|
|
|
* are successful
|
|
|
|
* @param db a custom RocksDB database handle
|
2014-09-16 00:13:22 +00:00
|
|
|
*
|
2014-09-16 07:28:23 +00:00
|
|
|
* @return an instance of osquery::Status indicating the success or failure
|
|
|
|
* of the operation
|
2014-09-16 00:13:22 +00:00
|
|
|
*/
|
2014-09-21 21:27:09 +00:00
|
|
|
osquery::Status getCurrentResults(osquery::QueryData& qd,
|
2014-08-15 07:25:30 +00:00
|
|
|
std::shared_ptr<DBHandle> db);
|
|
|
|
|
|
|
|
private:
|
2014-07-31 00:35:19 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Private members
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2014-09-16 00:13:22 +00:00
|
|
|
/// The scheduled query that Query is operating on
|
2014-09-15 18:09:33 +00:00
|
|
|
osquery::OsqueryScheduledQuery query_;
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
private:
|
2014-07-31 00:35:19 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Unit tests which can access private members
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
FRIEND_TEST(QueryTests, test_private_members);
|
|
|
|
FRIEND_TEST(QueryTests, test_add_and_get_current_results);
|
|
|
|
FRIEND_TEST(QueryTests, test_is_query_name_in_database);
|
|
|
|
FRIEND_TEST(QueryTests, test_get_stored_query_names);
|
|
|
|
FRIEND_TEST(QueryTests, test_get_executions);
|
|
|
|
FRIEND_TEST(QueryTests, test_get_current_results);
|
|
|
|
FRIEND_TEST(QueryTests, test_get_historical_query_results);
|
|
|
|
FRIEND_TEST(QueryTests, test_query_name_not_found_in_db);
|
|
|
|
};
|
2014-08-15 07:25:30 +00:00
|
|
|
}
|