2015-02-04 03:55:16 +00:00
|
|
|
/*
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2015-02-04 03:55:16 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <osquery/core.h>
|
2015-02-05 00:54:44 +00:00
|
|
|
#include <osquery/flags.h>
|
2015-02-19 01:19:45 +00:00
|
|
|
#include <osquery/sql.h>
|
2015-02-04 03:55:16 +00:00
|
|
|
|
|
|
|
namespace osquery {
|
2015-02-05 00:54:44 +00:00
|
|
|
|
|
|
|
DECLARE_string(extensions_socket);
|
2015-03-13 15:11:08 +00:00
|
|
|
DECLARE_string(extensions_autoload);
|
|
|
|
DECLARE_string(extensions_timeout);
|
2015-05-11 08:21:57 +00:00
|
|
|
DECLARE_bool(disable_extensions);
|
2015-03-13 15:11:08 +00:00
|
|
|
|
|
|
|
/// A millisecond internal applied to extension initialization.
|
2016-09-27 00:32:41 +00:00
|
|
|
extern const size_t kExtensionInitializeLatency;
|
2015-02-05 00:54:44 +00:00
|
|
|
|
2015-02-04 03:55:16 +00:00
|
|
|
/**
|
|
|
|
* @brief Helper struct for managing extenion metadata.
|
|
|
|
*
|
|
|
|
* This structure should match the members of Thrift's InternalExtensionInfo.
|
|
|
|
*/
|
|
|
|
struct ExtensionInfo {
|
|
|
|
std::string name;
|
|
|
|
std::string version;
|
2015-02-19 23:19:00 +00:00
|
|
|
std::string min_sdk_version;
|
2015-02-04 03:55:16 +00:00
|
|
|
std::string sdk_version;
|
|
|
|
};
|
|
|
|
|
2015-02-10 20:50:07 +00:00
|
|
|
typedef std::map<RouteUUID, ExtensionInfo> ExtensionList;
|
|
|
|
|
|
|
|
inline std::string getExtensionSocket(
|
|
|
|
RouteUUID uuid, const std::string& path = FLAGS_extensions_socket) {
|
2016-03-05 17:29:51 +00:00
|
|
|
return (uuid == 0) ? path : path + "." + std::to_string(uuid);
|
2015-02-10 20:50:07 +00:00
|
|
|
}
|
|
|
|
|
2015-02-19 23:19:00 +00:00
|
|
|
/// External (extensions) SQL implementation of the osquery query API.
|
|
|
|
Status queryExternal(const std::string& query, QueryData& results);
|
2015-02-19 01:19:45 +00:00
|
|
|
|
2015-02-19 23:19:00 +00:00
|
|
|
/// External (extensions) SQL implementation of the osquery getQueryColumns API.
|
2017-10-13 03:00:51 +00:00
|
|
|
Status getQueryColumnsExternal(const std::string& query, TableColumns& columns);
|
2015-02-19 01:19:45 +00:00
|
|
|
|
2015-02-19 23:19:00 +00:00
|
|
|
/// External (extensions) SQL implementation plugin provider for "sql" registry.
|
2017-01-07 20:21:35 +00:00
|
|
|
class ExternalSQLPlugin : public SQLPlugin {
|
2015-02-04 03:55:16 +00:00
|
|
|
public:
|
2017-10-13 03:00:51 +00:00
|
|
|
Status query(const std::string& query,
|
|
|
|
QueryData& results,
|
|
|
|
bool use_cache = false) const override {
|
|
|
|
return queryExternal(query, results);
|
2015-02-04 03:55:16 +00:00
|
|
|
}
|
|
|
|
|
2017-10-13 03:00:51 +00:00
|
|
|
Status getQueryTables(const std::string& query,
|
2017-03-16 01:48:01 +00:00
|
|
|
std::vector<std::string>& tables) const override {
|
|
|
|
return Status(0, "Not used");
|
|
|
|
}
|
|
|
|
|
2017-10-13 03:00:51 +00:00
|
|
|
Status getQueryColumns(const std::string& query,
|
2016-08-31 22:32:20 +00:00
|
|
|
TableColumns& columns) const override {
|
2017-10-13 03:00:51 +00:00
|
|
|
return getQueryColumnsExternal(query, columns);
|
2015-02-04 03:55:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-02-10 20:50:07 +00:00
|
|
|
/// Status get a list of active extenions.
|
|
|
|
Status getExtensions(ExtensionList& extensions);
|
|
|
|
|
|
|
|
/// Internal getExtensions using a UNIX domain socket path.
|
|
|
|
Status getExtensions(const std::string& manager_path,
|
|
|
|
ExtensionList& extensions);
|
|
|
|
|
2015-02-10 20:00:03 +00:00
|
|
|
/// Ping an extension manager or extension.
|
|
|
|
Status pingExtension(const std::string& path);
|
|
|
|
|
2016-10-25 01:13:44 +00:00
|
|
|
/**
|
|
|
|
* @brief Perform an action while waiting for an the extension timeout.
|
|
|
|
*
|
|
|
|
* We define a 'global' extension timeout using CLI flags.
|
|
|
|
* There are several locations where code may act assuming an extension has
|
|
|
|
* loaded or broadcasted a registry.
|
|
|
|
*
|
|
|
|
* @param predicate return true or set stop to end the timeout loop.
|
|
|
|
* @return the last status from the predicate.
|
|
|
|
*/
|
|
|
|
Status applyExtensionDelay(std::function<Status(bool& stop)> predicate);
|
|
|
|
|
2015-03-03 23:03:14 +00:00
|
|
|
/**
|
|
|
|
* @brief Request the extensions API to autoload any appropriate extensions.
|
|
|
|
*
|
|
|
|
* Extensions may be 'autoloaded' using the `extensions_autoload` command line
|
|
|
|
* argument. loadExtensions should be called before any plugin or registry item
|
|
|
|
* is used. This allows appropriate extensions to expose plugin requirements.
|
|
|
|
*
|
|
|
|
* An 'appropriate' extension is one within the `extensions_autoload` search
|
2016-07-25 16:21:26 +00:00
|
|
|
* path with file ownership equivalent or greater (root) than the osquery
|
2015-03-03 23:03:14 +00:00
|
|
|
* process requesting autoload.
|
2015-03-04 16:45:21 +00:00
|
|
|
*/
|
|
|
|
void loadExtensions();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Load extensions from a delimited search path string.
|
2015-03-03 23:03:14 +00:00
|
|
|
*
|
2016-07-25 16:21:26 +00:00
|
|
|
* @param loadfile Path to file containing newline delimited file paths
|
2015-03-03 23:03:14 +00:00
|
|
|
*/
|
2015-03-17 16:49:30 +00:00
|
|
|
Status loadExtensions(const std::string& loadfile);
|
2015-03-03 23:03:14 +00:00
|
|
|
|
2015-03-04 16:45:21 +00:00
|
|
|
/**
|
|
|
|
* @brief Request the extensions API to autoload any appropriate modules.
|
|
|
|
*
|
|
|
|
* Extension modules are shared libraries that add Plugins to the osquery
|
|
|
|
* core's registry at runtime.
|
|
|
|
*/
|
|
|
|
void loadModules();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Load extenion modules from a delimited search path string.
|
|
|
|
*
|
2016-07-25 16:21:26 +00:00
|
|
|
* @param loadfile Path to file containing newline delimited file paths
|
2015-03-04 16:45:21 +00:00
|
|
|
*/
|
2015-03-17 16:49:30 +00:00
|
|
|
Status loadModules(const std::string& loadfile);
|
2015-03-04 16:45:21 +00:00
|
|
|
|
|
|
|
/// Load all modules in a direcotry.
|
2015-03-17 16:49:30 +00:00
|
|
|
Status loadModuleFile(const std::string& path);
|
2015-03-04 16:45:21 +00:00
|
|
|
|
2017-01-27 23:56:40 +00:00
|
|
|
/**
|
|
|
|
* @brief Initialize the extensions socket path variable for osqueryi.
|
|
|
|
*
|
|
|
|
* If the shell is invoked with a default extensions_socket flag there is a
|
|
|
|
* chance the path is 'overloaded' by multiple shells, use this method to
|
|
|
|
* determine a unique user-local path.
|
|
|
|
*
|
2017-05-05 16:53:12 +00:00
|
|
|
* @param home to user's home directory.
|
2017-01-27 23:56:40 +00:00
|
|
|
*/
|
|
|
|
void initShellSocket(const std::string& home);
|
|
|
|
|
2015-02-04 03:55:16 +00:00
|
|
|
/**
|
|
|
|
* @brief Call a Plugin exposed by an Extension Registry route.
|
|
|
|
*
|
|
|
|
* This is mostly a Registry%-internal method used to call an ExtensionHandler
|
|
|
|
* call API if a Plugin is requested and had matched an Extension route.
|
|
|
|
*
|
|
|
|
* @param uuid Route UUID of the matched Extension
|
|
|
|
* @param registry The string name for the registry.
|
|
|
|
* @param item A string identifier for this registry item.
|
|
|
|
* @param request The plugin request input.
|
|
|
|
* @param response The plugin response output.
|
|
|
|
* @return Success indicates Extension API call success and Extension's
|
|
|
|
* Registry::call success.
|
|
|
|
*/
|
|
|
|
Status callExtension(const RouteUUID uuid,
|
|
|
|
const std::string& registry,
|
|
|
|
const std::string& item,
|
|
|
|
const PluginRequest& request,
|
|
|
|
PluginResponse& response);
|
|
|
|
|
|
|
|
/// Internal callExtension implementation using a UNIX domain socket path.
|
|
|
|
Status callExtension(const std::string& extension_path,
|
|
|
|
const std::string& registry,
|
|
|
|
const std::string& item,
|
|
|
|
const PluginRequest& request,
|
|
|
|
PluginResponse& response);
|
|
|
|
|
|
|
|
/// The main runloop entered by an Extension, start an ExtensionRunner thread.
|
2015-02-19 01:19:45 +00:00
|
|
|
Status startExtension(const std::string& name, const std::string& version);
|
|
|
|
|
|
|
|
/// The main runloop entered by an Extension, start an ExtensionRunner thread.
|
|
|
|
Status startExtension(const std::string& name,
|
|
|
|
const std::string& version,
|
|
|
|
const std::string& min_sdk_version);
|
2015-02-04 03:55:16 +00:00
|
|
|
|
|
|
|
/// Internal startExtension implementation using a UNIX domain socket path.
|
|
|
|
Status startExtension(const std::string& manager_path,
|
|
|
|
const std::string& name,
|
|
|
|
const std::string& version,
|
2015-02-19 01:19:45 +00:00
|
|
|
const std::string& min_sdk_version,
|
2015-02-04 03:55:16 +00:00
|
|
|
const std::string& sdk_version);
|
|
|
|
|
|
|
|
/// Start an ExtensionWatcher thread.
|
|
|
|
Status startExtensionWatcher(const std::string& manager_path,
|
|
|
|
size_t interval,
|
|
|
|
bool fatal);
|
|
|
|
|
|
|
|
/// Start an ExtensionManagerRunner thread.
|
|
|
|
Status startExtensionManager();
|
|
|
|
|
|
|
|
/// Internal startExtensionManager implementation.
|
|
|
|
Status startExtensionManager(const std::string& manager_path);
|
|
|
|
}
|