git checkout v2.2.1 && \
cmake . && make && make install
-# thrift
-RUN apt-get update --fix-missing && \
- apt-get install -qq libevent-dev libtool flex bison pkg-config g++ libssl-dev
-
-RUN cd /usr/src && \
- git clone https://github.com/apache/thrift.git
-
-RUN cd /usr/src/thrift && \
- git checkout 0.11.0 && \
- ./bootstrap.sh && \
- ./configure --with-boost=/usr --without-ruby --disable-tests \
- --without-php_extension --with-cpp --with-libevent=no \
- --with-python --enable-tutorial=no && \
- make && make install
-
# table gen dependencies
RUN apt-get install -qq python-pip && \
pip install Jinja2
# table dependencies
-RUN apt-get install -qq libprocps-dev libsystemd-dev libudev-dev iptables-dev uuid-dev
+RUN apt-get update --fix-missing
+RUN apt-get install -qq libprocps-dev libsystemd-dev \
+ libudev-dev iptables-dev uuid-dev libssl-dev
# linenoise
RUN cd /usr/src && \
+++ /dev/null
-# Target for generating osquery thirft (extensions) code.
-SET(OSQUERY_THRIFT_DIR "${CMAKE_BINARY_DIR}/generated/gen-cpp")
-SET(OSQUERY_THRIFT_GENERATED_FILES ${OSQUERY_THRIFT_DIR}/Extension.cpp
- ${OSQUERY_THRIFT_DIR}/Extension.h
- ${OSQUERY_THRIFT_DIR}/ExtensionManager.cpp
- ${OSQUERY_THRIFT_DIR}/ExtensionManager.h
- ${OSQUERY_THRIFT_DIR}/osquery_types.cpp
- ${OSQUERY_THRIFT_DIR}/osquery_types.h)
-
-# Allow targets to warn if the thrift interface code is not defined.
-ADD_DEFINITIONS(-DOSQUERY_THRIFT_LIB=thrift
- -DOSQUERY_THRIFT_SERVER_LIB=thrift/server
- -DOSQUERY_THRIFT_POINTER=boost
- -DOSQUERY_THRIFT=)
-
-# For the extensions targets, allow them to include thrift interface headers.
-INCLUDE_DIRECTORIES("${OSQUERY_THRIFT_DIR}")
ENABLE_TESTING()
INCLUDE(CMake/Macro.cmake)
-INCLUDE(CMake/Thrift.cmake)
# Make sure the generated paths exist
EXECUTE_PROCESS(COMMAND mkdir -p "${CMAKE_BINARY_DIR}/generated")
+++ /dev/null
-namespace cpp osquery.extensions
-
-/// Registry operations use a registry name, plugin name, request/response.
-typedef map<string, string> ExtensionPluginRequest
-typedef list<map<string, string>> ExtensionPluginResponse
-
-/// Extensions should request osquery options to set active registries and
-/// bootstrap any config/logger plugins.
-struct InternalOptionInfo {
- 1:string value,
- 2:string default_value,
- 3:string type,
-}
-
-/// Each option (CLI flag) has a unique name.
-typedef map<string, InternalOptionInfo> InternalOptionList
-
-/// When communicating extension metadata, use a thrift-internal structure.
-struct InternalExtensionInfo {
- 1:string name,
- 2:string version,
- 3:string sdk_version,
- 4:string min_sdk_version,
-}
-
-/// Unique ID for each extension.
-typedef i64 ExtensionRouteUUID
-/// A map from each plugin name to its optional route information.
-typedef map<string, ExtensionPluginResponse> ExtensionRouteTable
-/// A map from each registry name.
-typedef map<string, ExtensionRouteTable> ExtensionRegistry
-/// A map from each extension's unique ID to its map of registries.
-typedef map<ExtensionRouteUUID, InternalExtensionInfo> InternalExtensionList
-
-enum ExtensionCode {
- EXT_SUCCESS = 0,
- EXT_FAILED = 1,
- EXT_FATAL = 2,
-}
-
-/// Most communication uses the Status return type.
-struct ExtensionStatus {
- 1:i32 code,
- 2:string message,
- /// Add a thrift Status parameter identifying the request/response.
- 3:ExtensionRouteUUID uuid,
-}
-
-struct ExtensionResponse {
- 1:ExtensionStatus status,
- 2:ExtensionPluginResponse response,
-}
-
-exception ExtensionException {
- 1:i32 code,
- 2:string message,
- 3:ExtensionRouteUUID uuid,
-}
-
-service Extension {
- /// Ping to/from an extension and extension manager for metadata.
- ExtensionStatus ping(),
- /// Call an extension (or core) registry plugin.
- ExtensionResponse call(
- /// The registry name (e.g., config, logger, table, etc).
- 1:string registry,
- /// The registry item name (plugin name).
- 2:string item,
- /// The thrift-equivilent of an osquery::PluginRequest.
- 3:ExtensionPluginRequest request),
-}
-
-/// The extension manager is run by the osquery core process.
-service ExtensionManager extends Extension {
- /// Return the list of active registered extensions.
- InternalExtensionList extensions(),
- /// Return the list of bootstrap or configuration options.
- InternalOptionList options(),
- /// The API endpoint used by an extension to register its plugins.
- ExtensionStatus registerExtension(
- 1:InternalExtensionInfo info,
- 2:ExtensionRegistry registry),
- ExtensionStatus deregisterExtension(
- 1:ExtensionRouteUUID uuid,
- ),
- /// Allow an extension to query using an SQL string.
- ExtensionResponse query(
- 1:string sql,
- ),
- /// Allow an extension to introspect into SQL used in a parsed query.
- ExtensionResponse getQueryColumns(
- 1:string sql,
- ),
-}
ADD_OSQUERY_LINK(glog
gflags
pthread
- libthrift.a
#rocksdb deps
librocksdb.a
snappy
ADD_SUBDIRECTORY(devtools)
ADD_SUBDIRECTORY(dispatcher)
ADD_SUBDIRECTORY(events)
-ADD_SUBDIRECTORY(extensions)
ADD_SUBDIRECTORY(filesystem)
ADD_SUBDIRECTORY(hashing)
ADD_SUBDIRECTORY(killswitch)
}
Schedule::Schedule() {
- if (RegistryFactory::get().external()) {
- // Extensions should not restore or save schedule details.
- return;
- }
// Parse the schedule's query blacklist from backing storage.
restoreScheduleBlacklist(blacklist_);
// extract the "schedule" key and store it as the main pack
auto& rf = RegistryFactory::get();
- if (doc.doc().HasMember("schedule") && !rf.external()) {
+ if (doc.doc().HasMember("schedule")) {
auto& schedule = doc.doc()["schedule"];
if (schedule.IsObject()) {
auto main_doc = JSON::newObject();
}
// extract the "packs" key into additional pack objects
- if (doc.doc().HasMember("packs") && !rf.external()) {
+ if (doc.doc().HasMember("packs")) {
auto& packs = doc.doc()["packs"];
if (packs.IsObject()) {
for (const auto& pack : packs.GetObject()) {
}
Status Config::update(const ConfigMap& config) {
- // A config plugin may call update from an extension. This will update
- // the config instance within the extension process and the update must be
- // reflected in the core.
- if (RegistryFactory::get().external()) {
- for (const auto& source : config) {
- PluginRequest request = {
- {"action", "update"},
- {"source", source.first},
- {"data", source.second},
- };
- // A "update" registry item within core should call the core's update
- // method. The config plugin call action handling must also know to
- // update.
- auto status = Registry::call("config", "update", request);
- if (!status.ok()) {
- // If something goes wrong, do not go with update further
- return status;
- }
- }
- }
-
// Iterate though each source and overwrite config data.
// This will add/overwrite pack data, append to the schedule, change watched
// files, set options, etc.
namespace fs = boost::filesystem;
fs::path getConfDirPathImpl() {
- char const* kEnvVarName = "TEST_CONF_FILES_DIR";
- auto const value_opt = osquery::getEnvVar(kEnvVarName);
- EXPECT_TRUE(static_cast<bool>(value_opt))
- << "Env var " << boost::io::quoted(kEnvVarName) << " was not found, "
- << " looks like cxx_test argument 'env' is not set up.";
- return fs::path(value_opt.get());
+ return fs::path("../../../tools/tests/");
}
}
init.cpp
query.cpp
system.cpp
- watcher.cpp
database/database.cpp
database/in_memory_database.cpp
plugins/logger.cpp
std::string current_value;
auto found = flags::GetCommandLineOption(name.c_str(), ¤t_value);
- // If this is an extension and the flag was not found, forward the request.
- if (Registry::get().external() && !found) {
- PluginResponse resp;
- Registry::call("config", {{"name", name}, {"action", "option"}}, resp);
- if (resp.size() != 0) {
- auto value = resp[0].find("value");
- if (value != resp[0].end()) {
- return value->second;
- }
- }
- }
-
return current_value;
}
#include <osquery/data_logger.h>
#include <osquery/dispatcher.h>
#include <osquery/events.h>
-#include <osquery/extensions.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
#include <osquery/killswitch.h>
#include <osquery/registry.h>
#include <osquery/utils/info/version.h>
#include <osquery/utils/system/time.h>
-
-#include "osquery/core/watcher.h"
+#include <osquery/database.h>
#ifdef __linux__
#include <sys/syscall.h>
volatile std::sig_atomic_t kHandledSignal{0};
-static inline bool hasWorker() {
- return (osquery::Watcher::get().isWorkerValid());
-}
-
void signalHandler(int num) {
// Inform exit status of main threads blocked by service joins.
if (kHandledSignal == 0) {
osquery::kExitCode = 128 + num;
}
- // Handle signals based on a tri-state (worker, watcher, neither).
- if (num == SIGHUP) {
- if (!hasWorker() || hasWorkerVariable()) {
- // Reload configuration.
- }
- } else if (num == SIGTERM || num == SIGINT || num == SIGABRT ||
- num == SIGUSR1) {
+ if (num == SIGTERM || num == SIGINT || num == SIGABRT ||
+ num == SIGUSR1) {
#ifndef WIN32
// Time to stop, set an upper bound time constraint on how long threads
// have to terminate (join). Publishers may be in 20ms or similar sleeps.
// Restore the default signal handler.
std::signal(num, SIG_DFL);
- // The watcher waits for the worker to die.
- if (hasWorker()) {
- // Bind the fate of the worker to this watcher.
- osquery::Watcher::get().bindFates();
- } else {
- // Otherwise the worker or non-watched process joins.
- // Stop thrift services/clients/and their thread pools.
- osquery::Dispatcher::stopServices();
- }
+ osquery::Dispatcher::stopServices();
}
}
}
#endif
- if (hasWorker()) {
- // The signal should be proliferated through the process group.
- // Otherwise the watcher could 'forward' the signal to workers and
- // managed extension processes.
- }
}
}
}
fprintf(stdout, USAGE, binary.c_str(), "");
}
- if (tool == ToolType::EXTENSION) {
- fprintf(stdout, OPTIONS_CLI, " extension");
- Flag::printFlags(false, true);
- } else {
- fprintf(stdout, OPTIONS_CLI, "");
- Flag::printFlags(false, false, true);
- fprintf(stdout, OPTIONS);
- Flag::printFlags();
- }
+ fprintf(stdout, OPTIONS_CLI, "");
+ Flag::printFlags(false, false, true);
+ fprintf(stdout, OPTIONS);
+ Flag::printFlags();
if (tool == ToolType::SHELL) {
// Print shell flags.
// The shell is transient, rewrite config-loaded paths.
FLAGS_disable_logging = true;
// The shell never will not fork a worker.
- FLAGS_disable_watchdog = true;
FLAGS_disable_events = true;
}
}
}
- // If the caller is checking configuration, disable the watchdog/worker.
- if (FLAGS_config_check) {
- FLAGS_disable_watchdog = true;
- }
-
- if (isWatcher()) {
- FLAGS_disable_database = true;
- FLAGS_disable_logging = true;
- }
-
// Initialize the status and results logger.
initStatusLogger(binary_, init_glog);
- if (kToolType != ToolType::EXTENSION) {
- if (isWorker()) {
- VLOG(1) << "osquery worker initialized [watcher="
- << PlatformProcess::getLauncherProcess()->pid() << "]";
- } else {
- VLOG(1) << "osquery initialized [version=" << kVersion << "]";
- }
+ if (isWorker()) {
+ VLOG(1) << "osquery worker initialized [watcher="
+ << PlatformProcess::getLauncherProcess()->pid() << "]";
} else {
- VLOG(1) << "osquery extension initialized [sdk=" << kVersion << "]";
+ VLOG(1) << "osquery initialized [version=" << kVersion << "]";
}
if (default_flags) {
shutdown(EXIT_FAILURE);
}
}
-
- // Nice ourselves if using a watchdog and the level is not too permissive.
- if (!FLAGS_disable_watchdog && FLAGS_watchdog_level >= 0) {
- // Set CPU scheduling I/O limits.
- // On windows these values are inherited so no further calls are needed.
- setToBackgroundPriority();
-
-#ifdef __linux__
- // Using: ioprio_set(IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
- syscall(SYS_ioprio_set, IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
-#elif defined(__APPLE__)
- setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
-#endif
- }
}
void Initializer::initShell() const {
osquery::FLAGS_database_path =
(fs::path(homedir) / "shell.db").make_preferred().string();
}
- initShellSocket(homedir);
} else {
fprintf(
stderr, "Cannot access or create osquery home: %s", homedir.c_str());
- FLAGS_disable_extensions = true;
FLAGS_disable_database = true;
}
}
}
-void Initializer::initWatcher() const {
- // The watcher should not log into or use a persistent database.
- if (isWatcher()) {
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
- }
-
- // The watcher takes a list of paths to autoload extensions from.
- // The loadExtensions call will populate the watcher's list of extensions.
- osquery::loadExtensions();
-
- // Add a watcher service thread to start/watch an optional worker and list
- // of optional extensions from the autoload paths.
- if (Watcher::get().hasManagedExtensions() || !FLAGS_disable_watchdog) {
- Dispatcher::addService(
- std::make_shared<WatcherRunner>(*argc_, *argv_, isWatcher()));
- }
-
- if (isWatcher()) {
- if (shutdown_ != nullptr) {
- shutdown_();
- shutdown_ = nullptr;
- }
-
- // If there are no autoloaded extensions, the watcher service will end,
- // otherwise it will continue as a background thread and respawn them.
- // If the watcher is also a worker watchdog it will do nothing but monitor
- // the extensions and worker process.
- Dispatcher::joinServices();
- // Execution should only reach this point if a signal was handled by the
- // worker and watcher.
- auto retcode = 0;
- if (kHandledSignal > 0) {
- retcode = 128 + kHandledSignal;
- } else if (Watcher::get().getWorkerStatus() >= 0) {
- retcode = Watcher::get().getWorkerStatus();
- } else {
- retcode = EXIT_FAILURE;
- }
- requestShutdown(retcode);
- }
-}
-
void Initializer::initWorker(const std::string& name) const {
// Clear worker's arguments.
auto original_name = std::string((*argv_)[0]);
memset((*argv_)[i], '\0', strlen((*argv_)[i]));
}
}
-
- // Start a 'watcher watcher' thread to exit the process if the watcher exits.
- // In this case the parent process is called the 'watcher' process.
- Dispatcher::addService(std::make_shared<WatcherWatcherRunner>(
- PlatformProcess::getLauncherProcess()));
-}
-
-void Initializer::initWorkerWatcher(const std::string& name) const {
- if (isWorker()) {
- initWorker(name);
- } else {
- // The watcher will forever monitor and spawn additional workers.
- // This initialize will handle work for processes without watchdogs too.
- initWatcher();
- }
}
bool Initializer::isWorker() {
return hasWorkerVariable();
}
-bool Initializer::isWatcher() {
- return !FLAGS_disable_watchdog && !isWorker();
-}
-
void Initializer::initActivePlugin(const std::string& type,
const std::string& name) const {
- auto status = applyExtensionDelay(([type, name](bool& stop) {
- auto rs = RegistryFactory::get().setActive(type, name);
- if (rs.ok()) {
- // The plugin was found, and is now active.
- return rs;
- }
-
- if (!Watcher::get().hasManagedExtensions()) {
- // The plugin must be local, and is not active, problem.
- stop = true;
- }
- return rs;
- }));
-
- if (!status.ok()) {
+ auto rs = RegistryFactory::get().setActive(type, name);
+ if (!rs.ok()) {
LOG(ERROR) << "Cannot activate " << name << " " << type
- << " plugin: " << status.getMessage();
+ << " plugin: " << rs.getMessage();
requestShutdown(EXIT_CATASTROPHIC);
}
}
}
void Initializer::start() const {
- // Pre-extension manager initialization options checking.
- // If the shell or daemon does not need extensions and it will exit quickly,
- // prefer to disable the extension manager.
- if ((FLAGS_config_check || FLAGS_config_dump) &&
- !Watcher::get().hasManagedExtensions()) {
- FLAGS_disable_extensions = true;
- }
-
- // A watcher should not need access to the backing store.
- // If there are spurious access then warning logs will be emitted since the
- // set-allow-open will never be called.
- if (!isWatcher()) {
- DatabasePlugin::setAllowOpen(true);
- // A daemon must always have R/W access to the database.
- DatabasePlugin::setRequireWrite(isDaemon());
-
- for (size_t i = 1; i <= kDatabaseMaxRetryCount; i++) {
- if (DatabasePlugin::initPlugin().ok()) {
- break;
- }
-
- if (i == kDatabaseMaxRetryCount) {
- LOG(ERROR) << RLOG(1629) << binary_
- << " initialize failed: Could not initialize database";
- auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE;
- requestShutdown(retcode);
- }
-
- sleepFor(kDatabaseRetryDelay);
+ DatabasePlugin::setAllowOpen(true);
+ // A daemon must always have R/W access to the database.
+ DatabasePlugin::setRequireWrite(isDaemon());
+
+ for (size_t i = 1; i <= kDatabaseMaxRetryCount; i++) {
+ if (DatabasePlugin::initPlugin().ok()) {
+ break;
}
- // Ensure the database results version is up to date before proceeding
- if (!upgradeDatabase()) {
- LOG(ERROR) << "Failed to upgrade database";
+ if (i == kDatabaseMaxRetryCount) {
+ LOG(ERROR) << RLOG(1629) << binary_
+ << " initialize failed: Could not initialize database";
auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE;
requestShutdown(retcode);
}
+
+ sleepFor(kDatabaseRetryDelay);
}
- // Bind to an extensions socket and wait for registry additions.
- // After starting the extension manager, osquery MUST shutdown using the
- // internal 'shutdown' method.
- auto s = osquery::startExtensionManager();
- if (!s.ok()) {
- auto severity = (Watcher::get().hasManagedExtensions()) ? google::GLOG_ERROR
- : google::GLOG_INFO;
- if (severity == google::GLOG_INFO) {
- VLOG(1) << "Cannot start extension manager: " + s.getMessage();
- } else {
- google::LogMessage(__FILE__, __LINE__, severity).stream()
- << "Cannot start extension manager: " + s.getMessage();
- }
+ // Ensure the database results version is up to date before proceeding
+ if (!upgradeDatabase()) {
+ LOG(ERROR) << "Failed to upgrade database";
+ auto retcode = (isWorker()) ? EXIT_CATASTROPHIC : EXIT_FAILURE;
+ requestShutdown(retcode);
}
+
// Then set the config plugin, which uses a single/active plugin.
initActivePlugin("config", FLAGS_config_plugin);
if (FLAGS_config_check) {
// The initiator requested an initialization and config check.
- s = Config::get().load();
+ auto s = Config::get().load();
if (!s.ok()) {
std::cerr << "Error reading config: " << s.toString() << "\n";
}
}
// Load the osquery config using the default/active config plugin.
- s = Config::get().load();
+ auto s = Config::get().load();
if (!s.ok()) {
auto message = "Error reading config: " + s.toString();
if (isDaemon()) {
DatabasePlugin::shutdown();
auto excode = (kExitCode != 0) ? kExitCode : EXIT_SUCCESS;
- if (isWatcher()) {
- platformMainThreadExit(excode);
- }
exit(excode);
}
}
SHELL_FLAG(bool, shell_only, true, "TEST SHELL DESCRIPTION");
-EXTENSION_FLAG(bool, extension_only, true, "TEST EXTENSION DESCRIPTION");
TEST_F(FlagsTests, test_flag_detail_types) {
EXPECT_TRUE(FLAGS_shell_only);
- EXPECT_TRUE(FLAGS_extension_only);
auto all_flags = Flag::flags();
EXPECT_TRUE(all_flags["shell_only"].detail.shell);
- EXPECT_TRUE(all_flags["extension_only"].detail.external);
}
FLAG_ALIAS(bool, shell_only_alias, shell_only);
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <osquery/config/config.h>
-#include <osquery/core.h>
-#include <osquery/registry.h>
-#include <osquery/system.h>
-#include <osquery/tables.h>
-
-#include "osquery/core/watcher.h"
-#include "osquery/tests/test_util.h"
-
-using namespace testing;
-
-namespace osquery {
-
-DECLARE_uint64(watchdog_delay);
-DECLARE_bool(disable_database);
-
-class WatcherTests : public testing::Test {
- protected:
- WatcherTests() {
- Initializer::platformSetup();
- registryAndPluginInit();
- FLAGS_disable_database = true;
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
-
- Config::get().reset();
- }
-};
-
-/**
- * @brief Begin with a mock watcher runner.
- *
- * The Watcher class implements a small static state.
- *
- * The WatcherRunner class implements the state machine of a watchdog process
- * as a Runnable, in a dedicated thread. We begin testing by exercising parts
- * of that state machine.
- */
-class MockWatcherRunner : public WatcherRunner {
- public:
- MockWatcherRunner(int argc, char** argv, bool use_worker)
- : WatcherRunner(argc, argv, use_worker) {}
-
- /// The state machine requested the 'worker' to stop.
- MOCK_CONST_METHOD1(stopChild, void(const PlatformProcess& child));
-
- /// The state machine is inspecting the 'worker' health and performance.
- MOCK_CONST_METHOD1(isChildSane, Status(const PlatformProcess& child));
-
- private:
- FRIEND_TEST(WatcherTests, test_watcher);
-};
-
-/**
- * @brief A scoped implementation of a cross-platform process.
- *
- * During the WorkerRunner exercises an external cross-platform process
- * representation is provided. To better control the WorkerRunner state machine
- * we will manipulate operating system abstractions to control process state.
- */
-class FakePlatformProcess : public PlatformProcess {
- public:
- /// Simplified ctor set for our use cases.
- FakePlatformProcess(PlatformPidType id) : PlatformProcess(id) {}
-
- ProcessState checkStatus(int& _status) const {
- _status = status_;
- return state_;
- }
-
- private:
- /// Allow our friend test classes to emulate the operating system's PoV.
- void setStatus(ProcessState state, int status) {
- state_ = state;
- status_ = status;
- }
-
- private:
- ProcessState state_{PROCESS_STILL_ALIVE};
- int status_{0};
-
- private:
- FRIEND_TEST(WatcherTests, test_watcherrunner_watch);
- FRIEND_TEST(WatcherTests, test_watcherrunner_stop);
- FRIEND_TEST(WatcherTests, test_watcherrunner_unhealthy_delay);
-};
-
-TEST_F(WatcherTests, test_watcherrunner_watch) {
- MockWatcherRunner runner(0, nullptr, false);
-
- // Use the cross-platform abstractions to inspect the current test process.
- auto test_process = PlatformProcess::getCurrentProcess();
- // Initialize a scoped (fake) process abstraction.
- auto fake_test_process = FakePlatformProcess(test_process->nativeHandle());
-
- // The ::watch method is a single iteration of worker health checking.
- // Unless the watcher has entered a shutdown phase, every iteration should
- // check the worker sanity.
- EXPECT_CALL(runner, isChildSane(_)).WillOnce(Return(Status(0)));
-
- // The above expectation returns a sane child state.
- // This ::watch iteration should NOT attempt to stop the worker.
- EXPECT_CALL(runner, stopChild(_)).Times(0);
-
- // When triggering a watch, set the assumed process status.
- fake_test_process.setStatus(PROCESS_STILL_ALIVE, 0);
-
- // Trigger our expectations.
- EXPECT_TRUE(runner.watch(fake_test_process));
-}
-
-TEST_F(WatcherTests, test_watcherrunner_stop) {
- MockWatcherRunner runner(0, nullptr, false);
-
- auto test_process = PlatformProcess::getCurrentProcess();
- auto fake_test_process = FakePlatformProcess(test_process->nativeHandle());
-
- EXPECT_CALL(runner, isChildSane(_)).Times(0);
- EXPECT_CALL(runner, stopChild(_)).Times(0);
-
- // Now set the process status to an error state.
- fake_test_process.setStatus(PROCESS_ERROR, 0);
-
- // Trigger our expectations, the watch method will now return false.
- EXPECT_FALSE(runner.watch(fake_test_process));
-}
-
-class MockWithWatchWatcherRunner : public WatcherRunner {
- public:
- MockWithWatchWatcherRunner(int argc, char** argv, bool use_worker)
- : WatcherRunner(argc, argv, use_worker) {}
-
- /// This super-mock now mocks the watch method.
- MOCK_CONST_METHOD1(watch, bool(const PlatformProcess& child));
-
- MOCK_CONST_METHOD2(isWatcherHealthy,
- Status(const PlatformProcess& watcher,
- PerformanceState& watcher_state));
-
- /// The state machine is starting, and is forking a managed extension.
- MOCK_METHOD1(createExtension, void(const std::string& extension));
-
- /// The state machine is starting, and is forking the managed 'worker'.
- MOCK_METHOD0(createWorker, void());
-};
-
-TEST_F(WatcherTests, test_watcherrunner_loop) {
- // This time construct the runner with a use_worker=true.
- MockWithWatchWatcherRunner runner(0, nullptr, true);
-
- // Use a method introduced for testing purposes to request a single run of
- // the WatcherRunner's thread entry point.
- runner.runOnce();
-
- // Watch will be called once, for the worker only, since there are no
- // extensions configured.
- EXPECT_CALL(runner, watch(_)).WillOnce(Return(true));
- // Since the watch method is configured to return true, no worker is created.
- EXPECT_CALL(runner, createWorker()).Times(0);
- // The single-loop must check if itself is healthy.
- EXPECT_CALL(runner, isWatcherHealthy(_, _)).WillOnce(Return(Status(0)));
-
- runner.start();
-}
-
-TEST_F(WatcherTests, test_watcherrunner_loop_failure) {
- MockWithWatchWatcherRunner runner(0, nullptr, true);
- runner.runOnce();
-
- // Now the watch method returns false, indicating the previous worker failed
- // performance checked and was stopped.
- EXPECT_CALL(runner, watch(_)).WillOnce(Return(false));
- // Since the watch failed, the thread should spawn another worker.
- EXPECT_CALL(runner, createWorker()).Times(1);
- EXPECT_CALL(runner, isWatcherHealthy(_, _)).WillOnce(Return(Status(0)));
-
- runner.start();
-}
-
-TEST_F(WatcherTests, test_watcherrunner_loop_disabled) {
- // Now construct without using a worker.
- MockWithWatchWatcherRunner runner(0, nullptr, false);
- runner.runOnce();
-
- // There is no worker process, nothing should be watched.
- EXPECT_CALL(runner, watch(_)).Times(0);
- // Without a worker process, the watcher does not watch itself.
- EXPECT_CALL(runner, isWatcherHealthy(_, _)).Times(0);
-
- runner.start();
-}
-
-class FakeWatcherRunner : public WatcherRunner {
- public:
- FakeWatcherRunner(int argc, char** argv, bool use_worker)
- : WatcherRunner(argc, argv, use_worker) {}
-
- /**
- * @brief What the runner's internals will use as process state.
- *
- * Internal calls to getProcessRow will return this structure.
- */
- void setProcessRow(QueryData qd) {
- qd_ = std::move(qd);
- }
-
- /// The tests do not have access to the processes table.
- QueryData getProcessRow(pid_t pid) const {
- return qd_;
- }
-
- private:
- /// If a worker/extension has otherwise gone insane, stop it.
- void stopChild(const PlatformProcess& child) const {}
-
- private:
- QueryData qd_;
-};
-
-TEST_F(WatcherTests, test_watcherrunner_watcherhealth) {
- FakeWatcherRunner runner(0, nullptr, true);
-
- // Construct a process state, assume this would have been returned from the
- // processes table, which the WorkerRunner normally uses internally.
- Row r;
- r["parent"] = INTEGER(1);
- r["user_time"] = INTEGER(100);
- r["system_time"] = INTEGER(100);
- r["resident_size"] = INTEGER(100);
- runner.setProcessRow({r});
-
- // Hold the process and process state externally.
- // Normally the WatcherRunner's entry point will persist these and use them
- // as input to the next testable method to compare changes.
- auto test_process = PlatformProcess::getCurrentProcess();
- PerformanceState state;
- // The inputs are sane.
- EXPECT_TRUE(runner.isWatcherHealthy(*test_process, state));
- // Calling the method again should internally detect no change, this means
- // the state is still normal.
- EXPECT_TRUE(runner.isWatcherHealthy(*test_process, state));
-
- // The state should track the initial memory value.
- EXPECT_EQ(100U, state.initial_footprint);
-
- // The measurement of latency applies an interval value normalization.
- EXPECT_EQ(100U, state.user_time);
- EXPECT_EQ(0U, state.sustained_latency);
-
- // Now we can alter the performance.
- // Let us emulate the watcher having just allocated 1G of memory.
- r["resident_size"] = INTEGER(1024 * 1024 * 1024);
- runner.setProcessRow({r});
-
- auto status = runner.isWatcherHealthy(*test_process, state);
- EXPECT_FALSE(status.ok());
- EXPECT_EQ(status.getMessage(), "Memory limits exceeded");
-
- // Now emulate a rapid increase in CPU requirements.
- r["user_time"] = INTEGER(1024 * 1024 * 1024);
- runner.setProcessRow({r});
- runner.isWatcherHealthy(*test_process, state);
- EXPECT_EQ(1U, state.sustained_latency);
-
- // And again, the CPU continues to increase from the system perspective.
- r["system_time"] = INTEGER(1024 * 1024 * 1024);
- runner.setProcessRow({r});
- runner.isWatcherHealthy(*test_process, state);
- EXPECT_EQ(2U, state.sustained_latency);
-}
-
-TEST_F(WatcherTests, test_watcherrunner_unhealthy_delay) {
- FakeWatcherRunner runner(0, nullptr, true);
-
- auto test_process = PlatformProcess::getCurrentProcess();
- auto fake_test_process = FakePlatformProcess(test_process->nativeHandle());
- fake_test_process.setStatus(PROCESS_STILL_ALIVE, 0);
-
- // Set up a fake test process and place it into an healthy state.
- Row r;
- r["parent"] = INTEGER(test_process->pid());
- r["user_time"] = INTEGER(100);
- r["system_time"] = INTEGER(100);
- r["resident_size"] = INTEGER(100);
- runner.setProcessRow({r});
-
- // Check the fake process sanity, which records the state at t=0.
- EXPECT_TRUE(runner.isChildSane(fake_test_process));
-
- // Update the fake process resident memory, make it unhealthy.
- r["resident_size"] = INTEGER(1024 * 1024 * 1024);
- runner.setProcessRow({r});
-
- // Set the watchdog to delay 1000s.
- auto delay = FLAGS_watchdog_delay;
- FLAGS_watchdog_delay = 1000;
- // Trigger our expectations, the watch method will return true.
- // This will NOT call stopChild as the delay has not passed.
- EXPECT_TRUE(runner.watch(fake_test_process));
-
- // Now set the watchdog to no delay.
- FLAGS_watchdog_delay = 0;
- // This will call stopChild as there is no delay and the child is unhealthy.
- EXPECT_FALSE(runner.watch(fake_test_process));
-
- FLAGS_watchdog_delay = delay;
-}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <chrono>
-#include <cstring>
-
-#include <math.h>
-#include <signal.h>
-
-#ifndef WIN32
-#include <sys/wait.h>
-#endif
-
-#include <boost/filesystem.hpp>
-#include <boost/thread.hpp>
-
-#include <osquery/config/config.h>
-#include <osquery/core/sql/query_data.h>
-#include <osquery/core/watcher.h>
-#include <osquery/data_logger.h>
-#include <osquery/filesystem/fileops.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/process/process.h>
-#include <osquery/sql.h>
-#include <osquery/utils/conversions/tryto.h>
-#include <osquery/utils/info/tool_type.h>
-#include <osquery/utils/system/time.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-const auto kNumOfCPUs = boost::thread::physical_concurrency();
-
-struct LimitDefinition {
- size_t normal;
- size_t restrictive;
- size_t disabled;
-};
-
-struct PerformanceChange {
- size_t sustained_latency;
- size_t footprint;
- size_t iv;
- pid_t parent;
-};
-
-using WatchdogLimitMap = std::map<WatchdogLimitType, LimitDefinition>;
-
-const WatchdogLimitMap kWatchdogLimits = {
- // Maximum MB worker can privately allocate.
- {WatchdogLimitType::MEMORY_LIMIT, {200, 100, 10000}},
- // % of (User + System + Idle) CPU time worker can utilize
- // for LATENCY_LIMIT seconds.
- {WatchdogLimitType::UTILIZATION_LIMIT, {10, 5, 100}},
- // Number of seconds the worker should run, else consider the exit fatal.
- {WatchdogLimitType::RESPAWN_LIMIT, {4, 4, 1000}},
- // If the worker respawns too quickly, backoff on creating additional.
- {WatchdogLimitType::RESPAWN_DELAY, {5, 5, 1}},
- // Seconds of tolerable UTILIZATION_LIMIT sustained latency.
- {WatchdogLimitType::LATENCY_LIMIT, {12, 6, 1000}},
- // How often to poll for performance limit violations.
- {WatchdogLimitType::INTERVAL, {3, 3, 3}},
-};
-
-CLI_FLAG(int32,
- watchdog_level,
- 0,
- "Performance limit level (0=normal, 1=restrictive, -1=off)");
-
-CLI_FLAG(uint64,
- watchdog_memory_limit,
- 0,
- "Override watchdog profile memory limit (e.g., 300, for 300MB)");
-
-CLI_FLAG(uint64,
- watchdog_utilization_limit,
- 0,
- "Override watchdog profile CPU utilization limit");
-
-CLI_FLAG(uint64,
- watchdog_delay,
- 60,
- "Initial delay in seconds before watchdog starts");
-
-HIDDEN_FLAG(uint64,
- watchdog_max_delay,
- 60 * 10,
- "Max delay in seconds between worker respawns");
-
-CLI_FLAG(bool,
- enable_extensions_watchdog,
- false,
- "Enable userland watchdog for extensions processes");
-
-CLI_FLAG(bool, disable_watchdog, false, "Disable userland watchdog process");
-
-void Watcher::resetWorkerCounters(size_t respawn_time) {
- // Reset the monitoring counters for the watcher.
- state_.sustained_latency = 0;
- state_.user_time = 0;
- state_.system_time = 0;
- state_.last_respawn_time = respawn_time;
-}
-
-void Watcher::resetExtensionCounters(const std::string& extension,
- size_t respawn_time) {
- WatcherExtensionsLocker locker;
- auto& state = get().extension_states_[extension];
- state.sustained_latency = 0;
- state.user_time = 0;
- state.system_time = 0;
- state.last_respawn_time = respawn_time;
-}
-
-std::string Watcher::getExtensionPath(const PlatformProcess& child) {
- for (const auto& extension : extensions()) {
- if (*extension.second == child) {
- return extension.first;
- }
- }
- return "";
-}
-
-void Watcher::removeExtensionPath(const std::string& extension) {
- WatcherExtensionsLocker locker;
- extensions_.erase(extension);
- extension_states_.erase(extension);
-}
-
-PerformanceState& Watcher::getState(const PlatformProcess& child) {
- if (child == getWorker()) {
- return state_;
- } else {
- return extension_states_[getExtensionPath(child)];
- }
-}
-
-PerformanceState& Watcher::getState(const std::string& extension) {
- return extension_states_[extension];
-}
-
-void Watcher::setExtension(const std::string& extension,
- const std::shared_ptr<PlatformProcess>& child) {
- WatcherExtensionsLocker locker;
- extensions_[extension] = child;
-}
-
-void Watcher::reset(const PlatformProcess& child) {
- if (child == getWorker()) {
- worker_ = std::make_shared<PlatformProcess>();
- resetWorkerCounters(0);
- return;
- }
-
- // If it was not the worker pid then find the extension name to reset.
- for (const auto& extension : extensions()) {
- if (*extension.second == child) {
- setExtension(extension.first, std::make_shared<PlatformProcess>());
- resetExtensionCounters(extension.first, 0);
- }
- }
-}
-
-void Watcher::addExtensionPath(const std::string& path) {
- setExtension(path, std::make_shared<PlatformProcess>());
- resetExtensionCounters(path, 0);
-}
-
-bool Watcher::hasManagedExtensions() const {
- if (!extensions_.empty()) {
- return true;
- }
-
- // A watchdog process may hint to a worker the number of managed extensions.
- // Setting this counter to 0 will prevent the worker from waiting for missing
- // dependent config plugins. Otherwise, its existence, will cause a worker to
- // wait for missing plugins to broadcast from managed extensions.
- return getEnvVar("OSQUERY_EXTENSIONS").is_initialized();
-}
-
-bool WatcherRunner::ok() const {
- // Inspect the exit code, on success or catastrophic, end the watcher.
- auto status = Watcher::get().getWorkerStatus();
- if (status == EXIT_SUCCESS || status == EXIT_CATASTROPHIC) {
- return false;
- }
- // Watcher is OK to run if a worker or at least one extension exists.
- return (Watcher::get().getWorker().isValid() ||
- Watcher::get().hasManagedExtensions());
-}
-
-void WatcherRunner::start() {
- // Hold the current process (watcher) for inspection too.
- auto& watcher = Watcher::get();
- auto self = PlatformProcess::getCurrentProcess();
-
- // Set worker performance counters to an initial state.
- watcher.resetWorkerCounters(0);
- PerformanceState watcher_state;
-
- // Enter the watch loop.
- do {
- if (use_worker_ && !watch(watcher.getWorker())) {
- if (watcher.fatesBound()) {
- // A signal has interrupted the watcher.
- break;
- }
-
- auto status = watcher.getWorkerStatus();
- if (status == EXIT_CATASTROPHIC) {
- Initializer::requestShutdown(EXIT_CATASTROPHIC);
- break;
- }
-
- if (watcher.workerRestartCount() ==
- getWorkerLimit(WatchdogLimitType::RESPAWN_LIMIT)) {
- // Too many worker restarts.
- Initializer::requestShutdown(EXIT_FAILURE, "Too many worker restarts");
- break;
- }
-
- // The watcher failed, create a worker.
- createWorker();
- }
-
- // After inspecting the worker, check the extensions.
- // Extensions may be active even if a worker/watcher is not used.
- watchExtensions();
-
- if (use_worker_) {
- auto status = isWatcherHealthy(*self, watcher_state);
- if (!status.ok()) {
- Initializer::requestShutdown(
- EXIT_CATASTROPHIC,
- "Watcher has become unhealthy: " + status.getMessage());
- break;
- }
- }
-
- if (run_once_) {
- // A test harness can end the thread immediately.
- break;
- }
- pause(std::chrono::seconds(getWorkerLimit(WatchdogLimitType::INTERVAL)));
- } while (!interrupted() && ok());
-}
-
-void WatcherRunner::stop() {
- auto& watcher = Watcher::get();
-
- for (const auto& extension : watcher.extensions()) {
- try {
- stopChild(*extension.second);
- } catch (std::exception& e) {
- LOG(ERROR) << "[WatcherRunner] couldn't kill the extension "
- << extension.first << "nicely. Reason: " << e.what()
- << std::endl;
- extension.second->kill();
- }
- }
-}
-
-void WatcherRunner::watchExtensions() {
- auto& watcher = Watcher::get();
-
- // Loop over every managed extension and check sanity.
- for (const auto& extension : watcher.extensions()) {
- // Check the extension status, causing a wait.
- int process_status = 0;
- extension.second->checkStatus(process_status);
-
- auto ext_valid = extension.second->isValid();
- auto s = isChildSane(*extension.second);
-
- if (!ext_valid || (!s.ok() && getUnixTime() >= delayedTime())) {
- if (ext_valid && FLAGS_enable_extensions_watchdog) {
- // The extension was already launched once.
- std::stringstream error;
- error << "osquery extension " << extension.first << " ("
- << extension.second->pid() << ") stopping: " << s.getMessage();
- systemLog(error.str());
- LOG(WARNING) << error.str();
- stopChild(*extension.second);
- pause(
- std::chrono::seconds(getWorkerLimit(WatchdogLimitType::INTERVAL)));
- }
-
- // The extension manager also watches for extension-related failures.
- // The watchdog is more general, but may find failed extensions first.
- createExtension(extension.first);
- extension_restarts_[extension.first] += 1;
- } else {
- extension_restarts_[extension.first] = 0;
- }
- }
-}
-
-size_t WatcherRunner::delayedTime() const {
- return Config::getStartTime() + FLAGS_watchdog_delay;
-}
-
-bool WatcherRunner::watch(const PlatformProcess& child) const {
- int process_status = 0;
- ProcessState result = child.checkStatus(process_status);
- if (Watcher::get().fatesBound()) {
- // A signal was handled while the watcher was watching.
- return false;
- }
-
- if (!child.isValid() || result == PROCESS_ERROR) {
- // Worker does not exist or never existed.
- return false;
- } else if (result == PROCESS_STILL_ALIVE) {
- // If the inspect finds problems it will stop/restart the worker.
- auto status = isChildSane(child);
- // A delayed watchdog does not stop the worker process.
- if (!status.ok() && getUnixTime() >= delayedTime()) {
- // Since the watchdog cannot use the logger plugin the error message
- // should be logged to stderr and to the system log.
- std::stringstream error;
- error << "osqueryd worker (" << child.pid()
- << ") stopping: " << status.getMessage();
- systemLog(error.str());
- LOG(WARNING) << error.str();
- stopChild(child);
- return false;
- }
- return true;
- }
-
- if (result == PROCESS_EXITED) {
- // If the worker process existed, store the exit code.
- Watcher::get().worker_status_ = process_status;
- return false;
- }
-
- return true;
-}
-
-void WatcherRunner::stopChild(const PlatformProcess& child) const {
- child.killGracefully();
-
- // Clean up the defunct (zombie) process.
- if (!child.cleanup()) {
- auto child_pid = child.pid();
-
- LOG(WARNING) << "osqueryd worker (" << std::to_string(child_pid)
- << ") could not be stopped. Sending kill signal.";
-
- child.kill();
- if (!child.cleanup()) {
- auto message = std::string("Watcher cannot stop worker process (") +
- std::to_string(child_pid) + ").";
- Initializer::requestShutdown(EXIT_CATASTROPHIC, message);
- }
- }
-}
-
-PerformanceChange getChange(const Row& r, PerformanceState& state) {
- PerformanceChange change;
-
- // IV is the check interval in seconds, and utilization is set per-second.
- change.iv = std::max(getWorkerLimit(WatchdogLimitType::INTERVAL), 1_sz);
- long long user_time = 0, system_time = 0;
- try {
- change.parent =
- static_cast<pid_t>(tryTo<long long>(r.at("parent")).takeOr(0LL));
- user_time = tryTo<long long>(r.at("user_time")).takeOr(0LL);
- system_time = tryTo<long long>(r.at("system_time")).takeOr(0LL);
- change.footprint = tryTo<long long>(r.at("resident_size")).takeOr(0LL);
- } catch (const std::exception& /* e */) {
- state.sustained_latency = 0;
- }
-
- // Check the difference of CPU time used since last check.
- auto percent_ul = getWorkerLimit(WatchdogLimitType::UTILIZATION_LIMIT);
- percent_ul = (percent_ul > 100) ? 100 : percent_ul;
-
- UNSIGNED_BIGINT_LITERAL iv_milliseconds = change.iv * 1000;
- UNSIGNED_BIGINT_LITERAL cpu_ul =
- (percent_ul * iv_milliseconds * kNumOfCPUs) / 100;
-
- auto user_time_diff = user_time - state.user_time;
- auto sys_time_diff = system_time - state.system_time;
- auto cpu_utilization_time = user_time_diff + sys_time_diff;
-
- if (cpu_utilization_time > cpu_ul) {
- state.sustained_latency++;
- } else {
- state.sustained_latency = 0;
- }
- // Update the current CPU time.
- state.user_time = user_time;
- state.system_time = system_time;
-
- // Check if the sustained difference exceeded the acceptable latency limit.
- change.sustained_latency = state.sustained_latency;
-
- // Set the memory footprint as the amount of resident bytes allocated
- // since the process image was created (estimate).
- // A more-meaningful check would limit this to writable regions.
- if (state.initial_footprint == 0) {
- state.initial_footprint = change.footprint;
- }
-
- // Set the measured/limit-applied footprint to the post-launch allocations.
- if (change.footprint < state.initial_footprint) {
- change.footprint = 0;
- } else {
- change.footprint = change.footprint - state.initial_footprint;
- }
-
- return change;
-}
-
-static bool exceededMemoryLimit(const PerformanceChange& change) {
- if (change.footprint == 0) {
- return false;
- }
-
- return (change.footprint >
- getWorkerLimit(WatchdogLimitType::MEMORY_LIMIT) * 1024 * 1024);
-}
-
-static bool exceededCyclesLimit(const PerformanceChange& change) {
- if (change.sustained_latency == 0) {
- return false;
- }
-
- auto latency = change.sustained_latency * change.iv;
- return (latency >= getWorkerLimit(WatchdogLimitType::LATENCY_LIMIT));
-}
-
-Status WatcherRunner::isWatcherHealthy(const PlatformProcess& watcher,
- PerformanceState& watcher_state) const {
- auto rows = getProcessRow(watcher.pid());
- if (rows.size() == 0) {
- // Could not find worker process?
- return Status(1, "Cannot find watcher process");
- }
-
- auto change = getChange(rows[0], watcher_state);
- if (exceededMemoryLimit(change)) {
- return Status(1, "Memory limits exceeded");
- }
-
- return Status(0);
-}
-
-QueryData WatcherRunner::getProcessRow(pid_t pid) const {
- // On Windows, pid_t = DWORD, which is unsigned. However invalidity
- // of processes is denoted by a pid_t of -1. We check for this
- // by comparing the max value of DWORD, or ULONG_MAX, and then casting
- // our query back to an int value, as ULONG_MAX causes boost exceptions
- // as it's out of the range of an int.
- int p = pid;
-#ifdef WIN32
- p = (pid == ULONG_MAX) ? -1 : pid;
-#endif
- return SQL::selectFrom(
- {"parent", "user_time", "system_time", "resident_size"},
- "processes",
- "pid",
- EQUALS,
- INTEGER(p));
-}
-
-Status WatcherRunner::isChildSane(const PlatformProcess& child) const {
- auto rows = getProcessRow(child.pid());
- if (rows.size() == 0) {
- // Could not find worker process?
- return Status(1, "Cannot find process");
- }
-
- PerformanceChange change;
- {
- WatcherExtensionsLocker locker;
- auto& state = Watcher::get().getState(child);
- change = getChange(rows[0], state);
- }
-
- // Only make a decision about the child sanity if it is still the watcher's
- // child. It's possible for the child to die, and its pid reused.
- if (change.parent != PlatformProcess::getCurrentPid()) {
- // The child's parent is not the watcher.
- Watcher::get().reset(child);
- // Do not stop or call the child insane, since it is not our child.
- return Status(0);
- }
-
- if (exceededCyclesLimit(change)) {
- return Status(1,
- "Maximum sustainable CPU utilization limit exceeded: " +
- std::to_string(change.sustained_latency * change.iv));
- }
-
- // Check if the private memory exceeds a memory limit.
- if (exceededMemoryLimit(change)) {
- return Status(
- 1, "Memory limits exceeded: " + std::to_string(change.footprint));
- }
-
- // The worker is sane, no action needed.
- // Attempt to flush status logs to the well-behaved worker.
- if (use_worker_ && child.pid() == Watcher::get().getWorker().pid()) {
- relayStatusLogs();
- }
-
- return Status(0);
-}
-
-void WatcherRunner::createWorker() {
- auto& watcher = Watcher::get();
-
- {
- WatcherExtensionsLocker locker;
- if (watcher.getState(watcher.getWorker()).last_respawn_time >
- getUnixTime() - getWorkerLimit(WatchdogLimitType::RESPAWN_LIMIT)) {
- watcher.workerRestarted();
- LOG(WARNING) << "osqueryd worker respawning too quickly: "
- << watcher.workerRestartCount() << " times";
-
- // The configured automatic delay.
- size_t delay = getWorkerLimit(WatchdogLimitType::RESPAWN_DELAY);
- // Exponential back off for quickly-respawning clients.
- delay += static_cast<size_t>(pow(2, watcher.workerRestartCount()));
- delay = std::min(static_cast<size_t>(FLAGS_watchdog_max_delay), delay);
- pause(std::chrono::seconds(delay));
- }
- }
-
- // Get the path of the current process.
- auto qd = SQL::selectFrom({"path"},
- "processes",
- "pid",
- EQUALS,
- INTEGER(PlatformProcess::getCurrentPid()));
- if (qd.size() != 1 || qd[0].count("path") == 0 || qd[0]["path"].size() == 0) {
- LOG(ERROR) << "osquery watcher cannot determine process path for worker";
- Initializer::requestShutdown(EXIT_FAILURE);
- return;
- }
-
- // Set an environment signaling to potential plugin-dependent workers to wait
- // for extensions to broadcast.
- if (watcher.hasManagedExtensions()) {
- setEnvVar("OSQUERY_EXTENSIONS", "true");
- }
-
- // Get the complete path of the osquery process binary.
- boost::system::error_code ec;
- auto exec_path = fs::system_complete(fs::path(qd[0]["path"]), ec);
- if (!pathExists(exec_path).ok()) {
- LOG(WARNING) << "osqueryd doesn't exist in: " << exec_path.string();
- return;
- }
- if (!safePermissions(
- exec_path.parent_path().string(), exec_path.string(), true)) {
- // osqueryd binary has become unsafe.
- LOG(ERROR) << RLOG(1382)
- << "osqueryd has unsafe permissions: " << exec_path.string();
- Initializer::requestShutdown(EXIT_FAILURE);
- return;
- }
-
- auto worker = PlatformProcess::launchWorker(exec_path.string(), argc_, argv_);
- if (worker == nullptr) {
- // Unrecoverable error, cannot create a worker process.
- LOG(ERROR) << "osqueryd could not create a worker process";
- Initializer::shutdown(EXIT_FAILURE);
- return;
- }
-
- watcher.setWorker(worker);
- watcher.resetWorkerCounters(getUnixTime());
- VLOG(1) << "osqueryd watcher (" << PlatformProcess::getCurrentPid()
- << ") executing worker (" << worker->pid() << ")";
- watcher.worker_status_ = -1;
-}
-
-void WatcherRunner::createExtension(const std::string& extension) {
- auto& watcher = Watcher::get();
-
- {
- WatcherExtensionsLocker locker;
- if (watcher.getState(extension).last_respawn_time >
- getUnixTime() - getWorkerLimit(WatchdogLimitType::RESPAWN_LIMIT)) {
- LOG(WARNING) << "Extension respawning too quickly: " << extension;
- // Unlike a worker, if an extension respawns to quickly we give up.
- }
- }
-
- // Check the path to the previously-discovered extension binary.
- boost::system::error_code ec;
- auto exec_path = fs::system_complete(fs::path(extension), ec);
- if (!pathExists(exec_path).ok()) {
- LOG(WARNING) << "Extension binary doesn't exist in: " << exec_path.string();
- return;
- }
- if (!safePermissions(
- exec_path.parent_path().string(), exec_path.string(), true)) {
- // Extension binary has become unsafe.
- LOG(WARNING) << RLOG(1382)
- << "Extension binary has unsafe permissions: " << extension;
- return;
- }
-
- auto ext_process =
- PlatformProcess::launchExtension(exec_path.string(),
- Flag::getValue("extensions_socket"),
- Flag::getValue("extensions_timeout"),
- Flag::getValue("extensions_interval"),
- Flag::getValue("verbose") == "true");
- if (ext_process == nullptr) {
- // Unrecoverable error, cannot create an extension process.
- LOG(ERROR) << "Cannot create extension process: " << extension;
- Initializer::shutdown(EXIT_FAILURE);
- }
-
- watcher.setExtension(extension, ext_process);
- watcher.resetExtensionCounters(extension, getUnixTime());
- VLOG(1) << "Created and monitoring extension child (" << ext_process->pid()
- << "): " << extension;
-}
-
-void WatcherWatcherRunner::start() {
- while (!interrupted()) {
- if (isLauncherProcessDead(*watcher_)) {
- // Watcher died, the worker must follow.
- VLOG(1) << "osqueryd worker (" << PlatformProcess::getCurrentPid()
- << ") detected killed watcher (" << watcher_->pid() << ")";
- // The watcher watcher is a thread. Do not join services after removing.
- Initializer::requestShutdown();
- break;
- }
- pause(std::chrono::seconds(getWorkerLimit(WatchdogLimitType::INTERVAL)));
- }
-}
-
-size_t getWorkerLimit(WatchdogLimitType name) {
- if (kWatchdogLimits.count(name) == 0) {
- return 0;
- }
-
- if (name == WatchdogLimitType::MEMORY_LIMIT &&
- FLAGS_watchdog_memory_limit > 0) {
- return FLAGS_watchdog_memory_limit;
- }
-
- if (name == WatchdogLimitType::UTILIZATION_LIMIT &&
- FLAGS_watchdog_utilization_limit > 0) {
- return FLAGS_watchdog_utilization_limit;
- }
-
- auto level = FLAGS_watchdog_level;
- // If no level was provided then use the default (config/switch).
- if (level == -1) {
- return kWatchdogLimits.at(name).disabled;
- }
-
- if (level == 1) {
- return kWatchdogLimits.at(name).restrictive;
- }
- return kWatchdogLimits.at(name).normal;
-}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <atomic>
-#include <string>
-
-#ifndef WIN32
-#include <unistd.h>
-#endif
-
-#include <boost/noncopyable.hpp>
-
-#include <osquery/core/sql/query_data.h>
-#include <osquery/database.h>
-#include <osquery/dispatcher.h>
-#include <osquery/flags.h>
-#include <osquery/process/process.h>
-
-namespace osquery {
-
-using ExtensionMap = std::map<std::string, std::shared_ptr<PlatformProcess>>;
-
-DECLARE_bool(disable_watchdog);
-DECLARE_int32(watchdog_level);
-
-class WatcherRunner;
-
-/**
- * @brief Categories of process performance limitations.
- *
- * Performance limits are applied by a watcher thread on autoloaded extensions
- * and a optional daemon worker process. The performance types are identified
- * here, and organized into levels. Such that a caller may enforce rigor or
- * relax the performance expectations of a osquery daemon.
- */
-enum class WatchdogLimitType {
- MEMORY_LIMIT,
- UTILIZATION_LIMIT,
- RESPAWN_LIMIT,
- RESPAWN_DELAY,
- LATENCY_LIMIT,
- INTERVAL,
-};
-
-/**
- * @brief A performance state structure for an autoloaded extension or worker.
- *
- * A watcher thread will continue to check the performance state, and keep a
- * last-checked snapshot for each autoloaded extension and worker process.
- */
-struct PerformanceState {
- /// A counter of how many intervals the process exceeded performance limits.
- size_t sustained_latency;
- /// The last checked user CPU time.
- size_t user_time;
- /// The last checked system CPU time.
- size_t system_time;
- /// A timestamp when the process/worker was last created.
- size_t last_respawn_time;
-
- /// The initial (or as close as possible) process image footprint.
- size_t initial_footprint;
-
- PerformanceState() {
- sustained_latency = 0;
- user_time = 0;
- system_time = 0;
- last_respawn_time = 0;
- initial_footprint = 0;
- }
-};
-
-/**
- * @brief Thread-safe watched child process state manager.
- *
- * The Watcher instance is separated from the WatcherRunner thread to allow
- * signals and osquery-introspection to monitor the autoloaded extensions
- * and optional worker stats. A child-process change signal may indicate an
- * autoloaded extension ended. Tables may also report on the historic worker
- * or extension utilizations.
- *
- * Though not critical, it is preferred to remove the extension's broadcasted
- * routes quickly. Locking access to the extensions list between signals and
- * the WatcherRunner thread allows osquery to tearDown registry changes before
- * attempting to respawn an extension process.
- */
-class Watcher : private boost::noncopyable {
- public:
- /// Instance accessor
- static Watcher& get() {
- static Watcher instance;
- return instance;
- }
-
- /// Become responsible for the worker's fate, but do not guarantee its safety.
- void bindFates() {
- restart_worker_ = false;
- }
-
- /**
- * @brief Return the state of autoloadable extensions.
- *
- * Some initialization decisions are made based on waiting for plugins to
- * broadcast from potentially-loaded extensions. If no extensions are loaded
- * and an active (selected at command line) plugin is missing, fail quickly.
- */
- bool hasManagedExtensions() const;
-
- /// Check the status of the last worker.
- int getWorkerStatus() const {
- return worker_status_;
- }
-
- /// Add extensions autoloadable paths.
- void addExtensionPath(const std::string& path);
-
- /// Lock access to extensions.
- void lock() {
- get().lock_.lock();
- }
-
- /// Unlock access to extensions.
- void unlock() {
- get().lock_.unlock();
- }
-
- /// Allow other parts of the codebase to check worker state.
- bool isWorkerValid() const {
- WriteLock lock(worker_mutex_);
- return worker_->isValid();
- }
-
- private:
- /// Accessor for the worker process.
- PlatformProcess& getWorker() {
- return *worker_;
- }
-
- /// Reset counters after a worker exits.
- void resetWorkerCounters(size_t respawn_time);
-
- /// Reset counters for an extension path.
- void resetExtensionCounters(const std::string& extension,
- size_t respawn_time);
-
- /// Accessor for autoloadable extension paths.
- const ExtensionMap& extensions() const {
- return extensions_;
- }
-
- /// Lookup extension path from pid.
- std::string getExtensionPath(const PlatformProcess& child);
-
- /// Remove an autoloadable extension path.
- void removeExtensionPath(const std::string& extension);
-
- /// Get state information for a worker or extension child.
- PerformanceState& getState(const PlatformProcess& child);
- PerformanceState& getState(const std::string& extension);
-
- /// Setter for worker process.
- void setWorker(const std::shared_ptr<PlatformProcess>& child) {
- WriteLock lock(worker_mutex_);
- worker_ = child;
- }
-
- /// Setter for an extension process.
- void setExtension(const std::string& extension,
- const std::shared_ptr<PlatformProcess>& child);
-
- /// Reset pid and performance counters for a worker or extension process.
- void reset(const PlatformProcess& child);
-
- /// Count the number of worker restarts.
- size_t workerRestartCount() const {
- return worker_restarts_;
- }
-
- /// Check if the worker and watcher's fates are bound.
- bool fatesBound() const {
- return !restart_worker_;
- }
-
- private:
- /// Do not request the lock until extensions are used.
- Watcher() : worker_restarts_(0), lock_(mutex_, std::defer_lock) {
- setWorker(std::make_shared<PlatformProcess>());
- }
-
- Watcher(Watcher const&);
- void operator=(Watcher const&);
- virtual ~Watcher() {}
-
- private:
- /// Inform the watcher that the worker restarted without cause.
- void workerRestarted() {
- worker_restarts_++;
- }
-
- private:
- /// Performance state for the worker process.
- PerformanceState state_;
-
- /// Performance states for each autoloadable extension binary.
- std::map<std::string, PerformanceState> extension_states_;
-
- private:
- /// Keep the single worker process/thread ID for inspection.
- std::shared_ptr<PlatformProcess> worker_;
-
- /// Number of worker restarts NOT induced by a watchdog process.
- size_t worker_restarts_{0};
-
- /// Keep a list of resolved extension paths and their managed pids.
- ExtensionMap extensions_;
-
- /// Paths to autoload extensions.
- std::vector<std::string> extensions_paths_;
-
- /// Bind the fate of the watcher to the worker.
- std::atomic<bool> restart_worker_{true};
-
- /// Record the exit status of the most recent worker.
- std::atomic<int> worker_status_{-1};
-
- private:
- /// Set and access the worker process.
- mutable Mutex worker_mutex_;
-
- /// Mutex and lock around extensions access.
- Mutex mutex_;
-
- /// Mutex and lock around extensions access.
- std::unique_lock<Mutex> lock_;
-
- private:
- friend class WatcherRunner;
-};
-
-/**
- * @brief A scoped locker for iterating over watcher extensions.
- *
- * A lock must be used if any part of osquery wants to enumerate the autoloaded
- * extensions or autoloadable extension paths a Watcher may be monitoring.
- * A signal or WatcherRunner thread may stop or start extensions.
- */
-class WatcherExtensionsLocker {
- public:
- /// Construct and gain watcher lock.
- WatcherExtensionsLocker() {
- Watcher::get().lock();
- }
-
- /// Destruct and release watcher lock.
- ~WatcherExtensionsLocker() {
- Watcher::get().unlock();
- }
-};
-
-/**
- * @brief The watchdog thread responsible for spawning/monitoring children.
- *
- * The WatcherRunner thread will spawn any autoloaded extensions or optional
- * osquery daemon worker processes. It will then poll for their performance
- * state and kill/respawn osquery child processes if they violate limits.
- */
-class WatcherRunner : public InternalRunnable {
- public:
- /**
- * @brief Construct a watcher thread.
- *
- * @param argc The osquery process argc.
- * @param argv The osquery process argv.
- * @param use_worker True if the process should spawn and monitor a worker.
- */
- explicit WatcherRunner(int argc, char** argv, bool use_worker)
- : InternalRunnable("WatcherRunner"),
- argc_(argc),
- argv_(argv),
- use_worker_(use_worker) {
- (void)argc_;
- }
-
- private:
- /// Dispatcher (this service thread's) entry point.
- void start() override;
-
- void stop() override;
-
- /// Boilerplate function to sleep for some configured latency
- bool ok() const;
-
- /// Begin the worker-watcher process.
- virtual bool watch(const PlatformProcess& child) const;
-
- /// Enumerate each extension and check sanity.
- virtual void watchExtensions();
-
- /// Inspect into the memory, CPU, and other worker/extension process states.
- virtual Status isChildSane(const PlatformProcess& child) const;
-
- /// Inspect into the memory and CPU of the watcher process.
- virtual Status isWatcherHealthy(const PlatformProcess& watcher,
- PerformanceState& watcher_state) const;
-
- /// Get row data from the processes table for a given pid.
- virtual QueryData getProcessRow(pid_t pid) const;
-
- private:
- /// Fork and execute a worker process.
- virtual void createWorker();
-
- /// Fork an extension process.
- virtual void createExtension(const std::string& extension);
-
- /// If a worker/extension has otherwise gone insane, stop it.
- virtual void stopChild(const PlatformProcess& child) const;
-
- /// Return the time the watchdog is delayed until (from start of watcher).
- size_t delayedTime() const;
-
- private:
- /// For testing only, ask the WatcherRunner to run a start loop once.
- void runOnce() {
- run_once_ = true;
- }
-
- private:
- /// Keep the invocation daemon's argc to iterate through argv.
- int argc_{0};
-
- /// When a worker child is spawned the argv will be scrubbed.
- char** argv_{nullptr};
-
- /// Spawn/monitor a worker process.
- bool use_worker_{false};
-
- /// If set, the ::start method will run once and return.
- bool run_once_{false};
-
- /// Similarly to the uncontrolled worker restarted, count each extension.
- std::map<std::string, size_t> extension_restarts_;
-
- private:
- FRIEND_TEST(WatcherTests, test_watcherrunner_watch);
- FRIEND_TEST(WatcherTests, test_watcherrunner_stop);
- FRIEND_TEST(WatcherTests, test_watcherrunner_loop);
- FRIEND_TEST(WatcherTests, test_watcherrunner_loop_failure);
- FRIEND_TEST(WatcherTests, test_watcherrunner_loop_disabled);
- FRIEND_TEST(WatcherTests, test_watcherrunner_watcherhealth);
- FRIEND_TEST(WatcherTests, test_watcherrunner_unhealthy_delay);
-};
-
-/// The WatcherWatcher is spawned within the worker and watches the watcher.
-class WatcherWatcherRunner : public InternalRunnable {
- public:
- explicit WatcherWatcherRunner(const std::shared_ptr<PlatformProcess>& watcher)
- : InternalRunnable("WatcherWatcherRunner"), watcher_(watcher) {}
-
- /// Runnable thread's entry point.
- void start() override;
-
- private:
- /// Parent, or watchdog, process ID.
- std::shared_ptr<PlatformProcess> watcher_;
-};
-
-/// Get a performance limit by name and optional level.
-size_t getWorkerLimit(WatchdogLimitType limit);
-}
return Status(1, "Missing domain");
}
- if (RegistryFactory::get().external()) {
- // External registries (extensions) do not have databases active.
- // It is not possible to use an extension-based database.
- PluginRequest request = {
- {"action", "get"}, {"domain", domain}, {"key", key}};
- PluginResponse response;
- auto status = Registry::call("database", request, response);
- if (status.ok()) {
- // Set value from the internally-known "v" key.
- if (response.size() > 0 && response[0].count("v") > 0) {
- value = response[0].at("v");
- }
- }
- return status;
- }
-
ReadLock lock(kDatabaseReset);
if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database value: " + key);
return Status(1, "Missing domain");
}
- // External registries (extensions) do not have databases active.
- // It is not possible to use an extension-based database.
- if (RegistryFactory::get().external()) {
- if (data.size() > 1) {
- return sendPutBatchDatabaseRequest(domain, data);
- } else {
- return sendPutDatabaseRequest(domain, data);
- }
- }
-
ReadLock lock(kDatabaseReset);
if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot set database values");
return Status(1, "Missing domain");
}
- if (RegistryFactory::get().external()) {
- // External registries (extensions) do not have databases active.
- // It is not possible to use an extension-based database.
- PluginRequest request = {
- {"action", "remove"}, {"domain", domain}, {"key", key}};
- return Registry::call("database", request);
- }
-
ReadLock lock(kDatabaseReset);
if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot delete database value: " + key);
return Status(1, "Missing domain");
}
- if (RegistryFactory::get().external()) {
- // External registries (extensions) do not have databases active.
- // It is not possible to use an extension-based database.
- PluginRequest request = {{"action", "remove_range"},
- {"domain", domain},
- {"key", low},
- {"key_high", high}};
- return Registry::call("database", request);
- }
-
ReadLock lock(kDatabaseReset);
if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot delete database values: " + low + " - " +
return Status(1, "Missing domain");
}
- if (RegistryFactory::get().external()) {
- // External registries (extensions) do not have databases active.
- // It is not possible to use an extension-based database.
- PluginRequest request = {{"action", "scan"},
- {"domain", domain},
- {"prefix", prefix},
- {"max", std::to_string(max)}};
- PluginResponse response;
- auto status = Registry::call("database", request, response);
-
- for (const auto& item : response) {
- if (item.count("k") > 0) {
- keys.push_back(item.at("k"));
- }
- }
- return status;
- }
-
ReadLock lock(kDatabaseReset);
if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot scan database values: " + prefix);
SHELL_FLAG(string, A, "", "Select all from a table");
DECLARE_string(nullvalue);
-DECLARE_string(extensions_socket);
DECLARE_string(logger_plugin);
DECLARE_string(logger_path);
DECLARE_string(config_plugin);
".quit Exit this program\n"
".schema [TABLE] Show the CREATE statements\n"
".separator STR Change separator used by output mode\n"
- ".socket Show the osquery extensions socket path\n"
".show Show the current values for various settings\n"
".summary Alias for the show meta command\n"
".tables [TABLE] List names of tables\n"
fprintf(p->out, "\n");
}
- {
- auto results = osquery::SQL::selectAllFrom("osquery_extensions");
- std::vector<std::string> extensions;
- for (const auto& extension : results) {
- extensions.push_back(extension.at("name"));
- }
- fprintf(p->out,
- "%13.13s: %s\n",
- "Extensions",
- osquery::join(extensions, ", ").c_str());
-
- fprintf(p->out,
- "%13.13s: %s\n",
- "Socket",
- osquery::FLAGS_extensions_socket.c_str());
- }
-
fprintf(p->out, "\nShell settings:\n");
fprintf(p->out, "%13.13s: %s\n", "echo", p->echoOn != 0 ? "on" : "off");
fprintf(
return rc;
}
- if (c == 's' && strncmp(azArg[0], "socket", n) == 0 && nArg == 1) {
- fprintf(p->out, "%s\n", osquery::FLAGS_extensions_socket.c_str());
- return rc;
- }
-
// A meta command may act on the database, grab a lock and instance.
auto dbc = osquery::SQLiteDBManager::get();
auto db = dbc->db();
+++ /dev/null
-# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License
-
-ADD_OSQUERY_LIBRARY(osquery_extensions extensions.cpp
- impl_thrift.cpp
- interface.cpp)
-
-ADD_OSQUERY_LIBRARY(osquery_thrift thrift/gen/Extension.cpp
- thrift/gen/ExtensionManager.cpp
- thrift/gen/osquery_constants.cpp
- thrift/gen/osquery_types.cpp)
-
-FILE(GLOB OSQUERY_EXTENSIONS_TESTS "tests/*.cpp")
-ADD_OSQUERY_TEST(${OSQUERY_EXTENSIONS_TESTS})
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <map>
-#include <set>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/core/watcher.h>
-#include <osquery/extensions/interface.h>
-#include <osquery/filesystem/fileops.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/flagalias.h>
-#include <osquery/logger.h>
-#include <osquery/process/process.h>
-#include <osquery/registry.h>
-#include <osquery/sql.h>
-#include <osquery/system.h>
-#include <osquery/utils/config/default_paths.h>
-#include <osquery/utils/conversions/join.h>
-#include <osquery/utils/conversions/split.h>
-#include <osquery/utils/info/platform_type.h>
-#include <osquery/utils/info/version.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-// Millisecond latency between initializing manager pings.
-const size_t kExtensionInitializeLatency = 20;
-
-enum class ExtendableType {
- EXTENSION = 1,
-};
-
-using ExtendableTypeSet = std::map<ExtendableType, std::set<std::string>>;
-
-const std::map<PlatformType, ExtendableTypeSet> kFileExtensions{
- {PlatformType::TYPE_WINDOWS,
- {{ExtendableType::EXTENSION, {".exe", ".ext"}}}},
- {PlatformType::TYPE_LINUX, {{ExtendableType::EXTENSION, {".ext"}}}},
- {PlatformType::TYPE_OSX, {{ExtendableType::EXTENSION, {".ext"}}}},
-};
-
-CLI_FLAG(bool, disable_extensions, false, "Disable extension API");
-
-CLI_FLAG(string,
- extensions_socket,
- OSQUERY_SOCKET "osquery.em",
- "Path to the extensions UNIX domain socket");
-
-CLI_FLAG(string,
- extensions_autoload,
- OSQUERY_HOME "extensions.load",
- "Optional path to a list of autoloaded & managed extensions");
-
-CLI_FLAG(string,
- extensions_timeout,
- "3",
- "Seconds to wait for autoloaded extensions");
-
-CLI_FLAG(string,
- extensions_interval,
- "3",
- "Seconds delay between connectivity checks");
-
-SHELL_FLAG(string, extension, "", "Path to a single extension to autoload");
-
-CLI_FLAG(string,
- extensions_require,
- "",
- "Comma-separated list of required extensions");
-
-/**
- * @brief Alias the extensions_socket (used by core) to a simple 'socket'.
- *
- * Extension binaries will more commonly set the path to an extension manager
- * socket. Alias the long switch name to 'socket' for an easier UX.
- *
- * We include timeout and interval, where the 'extensions_' prefix is removed
- * in the alias since we are already within the context of an extension.
- */
-EXTENSION_FLAG_ALIAS(socket, extensions_socket);
-EXTENSION_FLAG_ALIAS(timeout, extensions_timeout);
-EXTENSION_FLAG_ALIAS(interval, extensions_interval);
-
-/// A Dispatcher service thread that watches an ExtensionManagerHandler.
-class ExtensionWatcher : public InternalRunnable {
- public:
- virtual ~ExtensionWatcher() = default;
- ExtensionWatcher(const std::string& path, size_t interval, bool fatal);
-
- public:
- /// The Dispatcher thread entry point.
- void start() override;
-
- /// Perform health checks.
- virtual void watch();
-
- protected:
- /// Exit the extension process with a fatal if the ExtensionManager dies.
- void exitFatal(int return_code = 1);
-
- protected:
- /// The UNIX domain socket path for the ExtensionManager.
- std::string path_;
-
- /// The internal in milliseconds to ping the ExtensionManager.
- size_t interval_;
-
- /// If the ExtensionManager socket is closed, should the extension exit.
- bool fatal_;
-};
-
-class ExtensionManagerWatcher : public ExtensionWatcher {
- public:
- ExtensionManagerWatcher(const std::string& path, size_t interval)
- : ExtensionWatcher(path, interval, false) {}
-
- /// The Dispatcher thread entry point.
- void start() override;
-
- /// Start a specialized health check for an ExtensionManager.
- void watch() override;
-
- private:
- /// Allow extensions to fail for several intervals.
- std::map<RouteUUID, size_t> failures_;
-};
-
-Status applyExtensionDelay(std::function<Status(bool& stop)> predicate) {
- // Make sure the extension manager path exists, and is writable.
- size_t delay = 0;
- // The timeout is given in seconds, but checked interval is microseconds.
- size_t timeout = atoi(FLAGS_extensions_timeout.c_str()) * 1000;
- if (timeout < kExtensionInitializeLatency * 10) {
- timeout = kExtensionInitializeLatency * 10;
- }
-
- Status status;
- do {
- bool stop = false;
- status = predicate(stop);
- if (stop || status.ok()) {
- break;
- }
-
- // Increase the total wait detail.
- delay += kExtensionInitializeLatency;
- sleepFor(kExtensionInitializeLatency);
- } while (delay < timeout);
- return status;
-}
-
-Status extensionPathActive(const std::string& path, bool use_timeout = false) {
- return applyExtensionDelay(([path, &use_timeout](bool& stop) {
- if (socketExists(path)) {
- try {
- // Create a client with a 10-second receive timeout.
- ExtensionManagerClient client(path, 10 * 1000);
- auto status = client.ping();
- return Status::success();
- } catch (const std::exception& /* e */) {
- // Path might exist without a connected extension or extension manager.
- }
- }
- // Only check active once if this check does not allow a timeout.
- if (!use_timeout) {
- stop = true;
- }
- return Status(1, "Extension socket not available: " + path);
- }));
-}
-
-ExtensionWatcher::ExtensionWatcher(const std::string& path,
- size_t interval,
- bool fatal)
- : InternalRunnable("ExtensionWatcher"),
- path_(path),
- interval_(interval),
- fatal_(fatal) {
- // Set the interval to a minimum of 200 milliseconds.
- interval_ = (interval_ < 200) ? 200 : interval_;
-}
-
-void ExtensionWatcher::start() {
- // Watch the manager, if the socket is removed then the extension will die.
- // A check for sane paths and activity is applied before the watcher
- // service is added and started.
- while (!interrupted()) {
- watch();
- pause(std::chrono::milliseconds(interval_));
- }
-}
-
-void ExtensionManagerWatcher::start() {
- // Watch each extension.
- while (!interrupted()) {
- watch();
- pause(std::chrono::milliseconds(interval_));
- }
-
- // When interrupted, request each extension tear down.
- const auto uuids = RegistryFactory::get().routeUUIDs();
- for (const auto& uuid : uuids) {
- try {
- auto path = getExtensionSocket(uuid);
- ExtensionClient client(path);
- client.shutdown();
- } catch (const std::exception& /* e */) {
- VLOG(1) << "Extension UUID " << uuid << " shutdown request failed";
- continue;
- }
- }
-}
-
-void ExtensionWatcher::exitFatal(int return_code) {
- // Exit the extension.
- // We will save the wanted return code and raise an interrupt.
- // This interrupt will be handled by the main thread then join the watchers.
- Initializer::requestShutdown(return_code);
-}
-
-void ExtensionWatcher::watch() {
- // Attempt to ping the extension core.
- // This does NOT use pingExtension to avoid the latency checks applied.
- Status status;
- bool core_sane = true;
- if (socketExists(path_)) {
- try {
- ExtensionManagerClient client(path_);
- // Ping the extension manager until it goes down.
- status = client.ping();
- } catch (const std::exception& /* e */) {
- core_sane = false;
- }
- } else {
- // The previously-writable extension socket is not usable.
- core_sane = false;
- }
-
- if (!core_sane) {
- VLOG(1) << "Extension watcher ending: osquery core has gone away";
- exitFatal(0);
- }
-
- if (status.getCode() != (int)ExtensionCode::EXT_SUCCESS && fatal_) {
- // The core may be healthy but return a failed ping status.
- exitFatal();
- }
-}
-
-void ExtensionManagerWatcher::watch() {
- // Watch the set of extensions, if the socket is removed then the extension
- // will be deregistered.
- const auto uuids = RegistryFactory::get().routeUUIDs();
-
- Status status;
- for (const auto& uuid : uuids) {
- auto path = getExtensionSocket(uuid);
- auto exists = socketExists(path);
-
- if (!exists.ok() && failures_[uuid] == 0) {
- // If there was never a failure then this is the first attempt.
- // Allow the extension to be latent and respect the autoload timeout.
- VLOG(1) << "Extension UUID " << uuid << " initial check failed";
- exists = extensionPathActive(path, true);
- }
-
- // All extensions will have a single failure (and odd use of the counting).
- // If failures get to 2 then the extension will be removed.
- failures_[uuid] = 1;
- if (exists.ok()) {
- try {
- ExtensionClient client(path);
- // Ping the extension until it goes down.
- status = client.ping();
- } catch (const std::exception& /* e */) {
- failures_[uuid] += 1;
- continue;
- }
- } else {
- // Immediate fail non-writable paths.
- failures_[uuid] += 1;
- continue;
- }
-
- if (status.getCode() != (int)ExtensionCode::EXT_SUCCESS) {
- LOG(INFO) << "Extension UUID " << uuid << " ping failed";
- failures_[uuid] += 1;
- } else {
- failures_[uuid] = 1;
- }
- }
-
- for (const auto& uuid : failures_) {
- if (uuid.second > 1) {
- LOG(INFO) << "Extension UUID " << uuid.first << " has gone away";
- RegistryFactory::get().removeBroadcast(uuid.first);
- failures_[uuid.first] = 1;
- }
- }
-}
-
-void initShellSocket(const std::string& homedir) {
- if (!Flag::isDefault("extensions_socket")) {
- return;
- }
-
- if (isPlatform(PlatformType::TYPE_WINDOWS)) {
- osquery::FLAGS_extensions_socket = "\\\\.\\pipe\\shell.em";
- } else {
- osquery::FLAGS_extensions_socket =
- (fs::path(homedir) / "shell.em").make_preferred().string();
- }
-
- if (extensionPathActive(FLAGS_extensions_socket, false) ||
- !socketExists(FLAGS_extensions_socket, true)) {
- // If there is an existing shell using this socket, or the socket cannot
- // be used (another user using the same path?)
- FLAGS_extensions_socket += std::to_string((uint16_t)rand());
- }
-}
-
-void loadExtensions() {
- // Disabling extensions will disable autoloading.
- if (FLAGS_disable_extensions) {
- return;
- }
-
- // Optionally autoload extensions, sanitize the binary path and inform
- // the osquery watcher to execute the extension when started.
- auto status = loadExtensions(
- fs::path(FLAGS_extensions_autoload).make_preferred().string());
- if (!status.ok()) {
- VLOG(1) << "Could not autoload extensions: " << status.what();
- }
-}
-
-static bool isFileSafe(std::string& path, ExtendableType type) {
- boost::trim(path);
- // A 'type name' may be used in verbose log output.
- std::string type_name =
- ((type == ExtendableType::EXTENSION) ? "extension" : "module");
- if (path.size() == 0 || path[0] == '#' || path[0] == ';') {
- return false;
- }
-
- // Resolve acceptable extension binaries from autoload paths.
- if (isDirectory(path).ok()) {
- VLOG(1) << "Cannot autoload " << type_name << " from directory: " << path;
- return false;
- }
-
- std::set<std::string> exts;
- if (isPlatform(PlatformType::TYPE_LINUX)) {
- exts = kFileExtensions.at(PlatformType::TYPE_LINUX).at(type);
- } else if (isPlatform(PlatformType::TYPE_OSX)) {
- exts = kFileExtensions.at(PlatformType::TYPE_OSX).at(type);
- } else {
- exts = kFileExtensions.at(PlatformType::TYPE_WINDOWS).at(type);
- }
-
- // Only autoload file which were safe at the time of discovery.
- // If the binary later becomes unsafe (permissions change) then it will fail
- // to reload if a reload is ever needed.
- fs::path extendable(path);
- // Set the output sanitized path.
- path = extendable.string();
- if (!pathExists(path).ok()) {
- LOG(WARNING) << type_name << " doesn't exist at: " << path;
- return false;
- }
- if (!safePermissions(extendable.parent_path().string(), path, true)) {
- LOG(WARNING) << "Will not autoload " << type_name
- << " with unsafe directory permissions: " << path;
- return false;
- }
-
- if (exts.find(extendable.extension().string()) == exts.end()) {
- std::string ends = osquery::join(exts, "', '");
- LOG(WARNING) << "Will not autoload " << type_name
- << " not ending in one of '" << ends << "': " << path;
- return false;
- }
-
- VLOG(1) << "Found autoloadable " << type_name << ": " << path;
- return true;
-}
-
-Status loadExtensions(const std::string& loadfile) {
- if (!FLAGS_extension.empty()) {
- // This is a shell-only development flag for quickly loading/using a single
- // extension. It bypasses the safety check.
- Watcher::get().addExtensionPath(FLAGS_extension);
- }
-
- std::string autoload_paths;
- if (!readFile(loadfile, autoload_paths).ok()) {
- return Status(1, "Failed reading: " + loadfile);
- }
-
- // The set of binaries to auto-load, after safety is confirmed.
- std::set<std::string> autoload_binaries;
- for (auto& path : osquery::split(autoload_paths, "\n")) {
- if (isDirectory(path)) {
- std::vector<std::string> paths;
- listFilesInDirectory(path, paths, true);
- for (auto& embedded_path : paths) {
- if (isFileSafe(embedded_path, ExtendableType::EXTENSION)) {
- autoload_binaries.insert(std::move(embedded_path));
- }
- }
- } else if (isFileSafe(path, ExtendableType::EXTENSION)) {
- autoload_binaries.insert(path);
- }
- }
-
- for (const auto& binary : autoload_binaries) {
- // After the path is sanitized the watcher becomes responsible for
- // forking and executing the extension binary.
- Watcher::get().addExtensionPath(binary);
- }
- return Status::success();
-}
-
-Status startExtension(const std::string& name, const std::string& version) {
- return startExtension(name, version, "0.0.0");
-}
-
-Status startExtension(const std::string& name,
- const std::string& version,
- const std::string& min_sdk_version) {
- // Tell the registry that this is an extension.
- // When a broadcast is requested this registry should not send core plugins.
- RegistryFactory::get().setExternal();
-
- // Latency converted to milliseconds, used as a thread interruptible.
- auto latency = atoi(FLAGS_extensions_interval.c_str()) * 1000;
- auto status = startExtensionWatcher(FLAGS_extensions_socket, latency, true);
- if (!status.ok()) {
- // If the threaded watcher fails to start, fail the extension.
- return status;
- }
-
- status = startExtension(
- FLAGS_extensions_socket, name, version, min_sdk_version, kSDKVersion);
- if (!status.ok()) {
- // If the extension failed to start then the EM is most likely unavailable.
- return status;
- }
- return Status(0);
-}
-
-Status startExtension(const std::string& manager_path,
- const std::string& name,
- const std::string& version,
- const std::string& min_sdk_version,
- const std::string& sdk_version) {
- // Make sure the extension manager path exists, and is writable.
- auto status = extensionPathActive(manager_path, true);
- if (!status.ok()) {
- return status;
- }
-
- // The Registry broadcast is used as the ExtensionRegistry.
- auto broadcast = RegistryFactory::get().getBroadcast();
- // The extension will register and provide name, version, sdk details.
- ExtensionInfo info;
- info.name = name;
- info.version = version;
- info.sdk_version = sdk_version;
- info.min_sdk_version = min_sdk_version;
-
- // If registration is successful, we will also request the manager's options.
- OptionList options;
- // Register the extension's registry broadcast with the manager.
- RouteUUID uuid = 0;
- try {
- ExtensionManagerClient client(manager_path);
- status = client.registerExtension(info, broadcast, uuid);
- // The main reason for a failed registry is a duplicate extension name
- // (the extension process is already running), or the extension broadcasts
- // a duplicate registry item.
- if (status.getCode() == (int)ExtensionCode::EXT_FAILED) {
- return status;
- }
- // Request the core options, mainly to set the active registry plugins for
- // logger and config.
- options = client.options();
- } catch (const std::exception& e) {
- return Status(1, "Extension register failed: " + std::string(e.what()));
- }
-
- // Now that the UUID is known, try to clean up stale socket paths.
- auto extension_path = getExtensionSocket(uuid, manager_path);
-
- status = socketExists(extension_path, true);
- if (!status) {
- return status;
- }
-
- // Set the active config and logger plugins. The core will arbitrate if the
- // plugins are not available in the extension's local registry.
- auto& rf = RegistryFactory::get();
- rf.setActive("config", options["config_plugin"].value);
- rf.setActive("logger", options["logger_plugin"].value);
- // Set up all lazy registry plugins and the active config/logger plugin.
- rf.setUp();
-
- // Start the extension's Thrift server
- Dispatcher::addService(std::make_shared<ExtensionRunner>(manager_path, uuid));
- VLOG(1) << "Extension (" << name << ", " << uuid << ", " << version << ", "
- << sdk_version << ") registered";
- return Status(0, std::to_string(uuid));
-}
-Status ExternalSQLPlugin::query(const std::string& query,
- QueryData& results,
- bool use_cache) const {
- static_cast<void>(use_cache);
- // Make sure the extension path exists, and is writable.
- auto status = extensionPathActive(FLAGS_extensions_socket);
- if (!status.ok()) {
- return status;
- }
-
- try {
- ExtensionManagerClient client(FLAGS_extensions_socket);
- status = client.query(query, results);
- } catch (const std::exception& e) {
- return Status(1, "Extension call failed: " + std::string(e.what()));
- }
-
- return status;
-}
-
-Status ExternalSQLPlugin::getQueryColumns(const std::string& query,
- TableColumns& columns) const {
- // Make sure the extension path exists, and is writable.
- auto status = extensionPathActive(FLAGS_extensions_socket);
- if (!status.ok()) {
- return status;
- }
-
- QueryData qd;
- try {
- ExtensionManagerClient client(FLAGS_extensions_socket);
- status = client.getQueryColumns(query, qd);
- } catch (const std::exception& e) {
- return Status(1, "Extension call failed: " + std::string(e.what()));
- }
-
- // Translate response map: {string: string} to a vector: pair(name, type).
- for (const auto& column : qd) {
- for (const auto& col : column) {
- columns.push_back(std::make_tuple(
- col.first, columnTypeName(col.second), ColumnOptions::DEFAULT));
- }
- }
-
- return status;
-}
-
-Status pingExtension(const std::string& path) {
- if (FLAGS_disable_extensions) {
- return Status(1, "Extensions disabled");
- }
-
- // Make sure the extension path exists, and is writable.
- auto status = extensionPathActive(path);
- if (!status.ok()) {
- return status;
- }
-
- try {
- ExtensionClient client(path);
- status = client.ping();
- } catch (const std::exception& e) {
- return Status(1, "Extension call failed: " + std::string(e.what()));
- }
-
- return Status(0, status.getMessage());
-}
-
-Status getExtensions(ExtensionList& extensions) {
- if (FLAGS_disable_extensions) {
- return Status(1, "Extensions disabled");
- }
- return getExtensions(FLAGS_extensions_socket, extensions);
-}
-
-Status getExtensions(const std::string& manager_path,
- ExtensionList& extensions) {
- // Make sure the extension path exists, and is writable.
- auto status = extensionPathActive(manager_path);
- if (!status.ok()) {
- return status;
- }
-
- ExtensionList ext_list;
- try {
- ExtensionManagerClient client(manager_path);
- ext_list = client.extensions();
- } catch (const std::exception& e) {
- return Status(1, "Extension call failed: " + std::string(e.what()));
- }
-
- // Add the extension manager to the list called (core).
- extensions[0] = {"core", kVersion, "0.0.0", kSDKVersion};
-
- // Convert from Thrift-internal list type to RouteUUID/ExtenionInfo type.
- for (const auto& ext : ext_list) {
- extensions[ext.first] = {ext.second.name,
- ext.second.version,
- ext.second.min_sdk_version,
- ext.second.sdk_version};
- }
-
- return Status::success();
-}
-
-Status callExtension(const RouteUUID uuid,
- const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) {
- if (FLAGS_disable_extensions) {
- return Status(1, "Extensions disabled");
- }
- return callExtension(
- getExtensionSocket(uuid), registry, item, request, response);
-}
-
-Status callExtension(const std::string& extension_path,
- const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) {
- // Make sure the extension manager path exists, and is writable.
- auto status = extensionPathActive(extension_path);
- if (!status.ok()) {
- return status;
- }
-
- try {
- ExtensionClient client(extension_path);
- status = client.call(registry, item, request, response);
- } catch (const std::exception& e) {
- return Status(1, "Extension call failed: " + std::string(e.what()));
- }
-
- return status;
-}
-
-Status startExtensionWatcher(const std::string& manager_path,
- size_t interval,
- bool fatal) {
- // Make sure the extension manager path exists, and is writable.
- auto status = extensionPathActive(manager_path, true);
- if (!status.ok()) {
- return status;
- }
-
- // Start a extension watcher, if the manager dies, so should we.
- Dispatcher::addService(
- std::make_shared<ExtensionWatcher>(manager_path, interval, fatal));
- return Status::success();
-}
-
-Status startExtensionManager() {
- if (FLAGS_disable_extensions) {
- return Status(1, "Extensions disabled");
- }
- return startExtensionManager(FLAGS_extensions_socket);
-}
-
-Status startExtensionManager(const std::string& manager_path) {
- // Check if the socket location is ready for a new Thrift server.
- // We expect the path to be invalid or a removal attempt to succeed.
- auto status = socketExists(manager_path, true);
- if (!status.ok()) {
- return status;
- }
-
- // Seconds converted to milliseconds, used as a thread interruptible.
- auto latency = atoi(FLAGS_extensions_interval.c_str()) * 1000;
- // Start a extension manager watcher, to monitor all registered extensions.
- Dispatcher::addService(
- std::make_shared<ExtensionManagerWatcher>(manager_path, latency));
-
- // Start the extension manager thread.
- Dispatcher::addService(
- std::make_shared<ExtensionManagerRunner>(manager_path));
-
- // The shell or daemon flag configuration may require an extension.
- if (!FLAGS_extensions_require.empty()) {
- bool waited = false;
- auto extensions = osquery::split(FLAGS_extensions_require, ",");
- for (const auto& extension : extensions) {
- status = applyExtensionDelay(([extension, &waited](bool& stop) {
- ExtensionList registered_extensions;
- if (getExtensions(registered_extensions).ok()) {
- for (const auto& existing : registered_extensions) {
- if (existing.second.name == extension) {
- return pingExtension(getExtensionSocket(existing.first));
- }
- }
- }
-
- if (waited) {
- // If we have already waited for the timeout period, stop early.
- stop = true;
- }
- return Status(1, "Extension not autoloaded: " + extension);
- }));
-
- // A required extension was not loaded.
- waited = true;
- if (!status.ok()) {
- LOG(WARNING) << status.getMessage();
- return status;
- }
- }
- }
-
- return Status::success();
-}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/system.h>
-
-#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/server/TThreadedServer.h>
-#include <thrift/transport/TBufferTransports.h>
-
-#ifdef WIN32
-#include <thrift/transport/TPipe.h>
-#include <thrift/transport/TPipeServer.h>
-#else
-#include <thrift/transport/TServerSocket.h>
-#include <thrift/transport/TSocket.h>
-#endif
-
-#include "Extension.h"
-#include "ExtensionManager.h"
-
-#include "osquery/extensions/interface.h"
-
-#include <limits>
-
-namespace osquery {
-
-using namespace apache::thrift::protocol;
-using namespace apache::thrift::transport;
-using namespace apache::thrift::server;
-using namespace apache::thrift::concurrency;
-
-#ifdef WIN32
-using TPlatformServerSocket = TPipeServer;
-using TPlatformSocket = TPipe;
-#else
-using TPlatformServerSocket = TServerSocket;
-using TPlatformSocket = TSocket;
-#endif
-
-class ExtensionHandler : virtual public extensions::ExtensionIf,
- public ExtensionInterface {
- public:
- ExtensionHandler() : ExtensionInterface(0) {}
- explicit ExtensionHandler(RouteUUID uuid) : ExtensionInterface(uuid) {}
-
- public:
- using ExtensionInterface::ping;
- void ping(extensions::ExtensionStatus& _return) override;
-
- using ExtensionInterface::call;
- void call(extensions::ExtensionResponse& _return,
- const std::string& registry,
- const std::string& item,
- const extensions::ExtensionPluginRequest& request) override;
-
- using ExtensionInterface::shutdown;
- void shutdown() override;
-
- protected:
- /// UUID accessor.
- RouteUUID getUUID() const;
-};
-
-#ifdef WIN32
-#pragma warning(push, 3)
-#pragma warning(disable : 4250)
-#endif
-
-class ExtensionManagerHandler : virtual public extensions::ExtensionManagerIf,
- public ExtensionManagerInterface,
- public ExtensionHandler {
- public:
- ExtensionManagerHandler() = default;
-
- public:
- using ExtensionManagerInterface::extensions;
- void extensions(extensions::InternalExtensionList& _return) override;
-
- using ExtensionManagerInterface::options;
- void options(extensions::InternalOptionList& _return) override;
-
- using ExtensionManagerInterface::registerExtension;
- void registerExtension(
- extensions::ExtensionStatus& _return,
- const extensions::InternalExtensionInfo& info,
- const extensions::ExtensionRegistry& registry) override;
-
- using ExtensionManagerInterface::deregisterExtension;
- void deregisterExtension(extensions::ExtensionStatus& _return,
- const extensions::ExtensionRouteUUID uuid) override;
-
- using ExtensionManagerInterface::query;
- void query(extensions::ExtensionResponse& _return,
- const std::string& sql) override;
-
- using ExtensionManagerInterface::getQueryColumns;
- void getQueryColumns(extensions::ExtensionResponse& _return,
- const std::string& sql) override;
-
- public:
- using ExtensionHandler::call;
- using ExtensionHandler::ping;
- using ExtensionHandler::shutdown;
-};
-
-#ifdef WIN32
-#pragma warning(pop)
-#endif
-
-struct ImplExtensionRunner {
- std::shared_ptr<TServerTransport> transport;
- std::shared_ptr<TThreadedServer> server;
- std::shared_ptr<TProcessor> processor;
-};
-
-struct ImplExtensionClient {
- std::shared_ptr<extensions::ExtensionClient> e;
- std::shared_ptr<extensions::ExtensionManagerClient> em;
-
- std::shared_ptr<TBufferedTransport> transport;
- std::shared_ptr<TPlatformSocket> socket;
-};
-
-void ExtensionHandler::ping(extensions::ExtensionStatus& _return) {
- auto s = ExtensionInterface::ping();
- _return.code = (int)extensions::ExtensionCode::EXT_SUCCESS;
- _return.uuid = s.getCode();
- _return.message = s.getMessage();
-}
-
-void ExtensionHandler::call(extensions::ExtensionResponse& _return,
- const std::string& registry,
- const std::string& item,
- const extensions::ExtensionPluginRequest& request) {
- PluginRequest plugin_request;
- for (const auto& request_item : request) {
- // Create a PluginRequest from an ExtensionPluginRequest.
- plugin_request[request_item.first] = request_item.second;
- }
-
- PluginResponse response;
- auto s = ExtensionInterface::call(registry, item, plugin_request, response);
- _return.status.code = s.getCode();
- _return.status.message = s.getMessage();
- _return.status.uuid = getUUID();
-
- if (s.ok()) {
- for (const auto& response_item : response) {
- // Translate a PluginResponse to an ExtensionPluginResponse.
- _return.response.push_back(response_item);
- }
- }
-}
-
-void ExtensionHandler::shutdown() {}
-
-RouteUUID ExtensionHandler::getUUID() const {
- return uuid_;
-}
-
-void ExtensionManagerHandler::extensions(
- extensions::InternalExtensionList& _return) {
- //_return = ExtensionManagerInterface::extensions();
- auto extensions = ExtensionManagerInterface::extensions();
- for (const auto& extension : extensions) {
- auto& ext = _return[extension.first];
- ext.min_sdk_version = extension.second.min_sdk_version;
- ext.version = extension.second.version;
- ext.sdk_version = extension.second.sdk_version;
- ext.name = extension.second.name;
- }
-}
-
-void ExtensionManagerHandler::options(extensions::InternalOptionList& _return) {
- auto options = ExtensionManagerInterface::options();
- for (const auto& option : options) {
- _return[option.first].value = option.second.value;
- _return[option.first].default_value = option.second.default_value;
- _return[option.first].type = option.second.type;
- }
-}
-
-void ExtensionManagerHandler::registerExtension(
- extensions::ExtensionStatus& _return,
- const extensions::InternalExtensionInfo& info,
- const extensions::ExtensionRegistry& registry) {
- extensions::ExtensionRegistry er;
- for (const auto& rt : registry) {
- er[rt.first] = rt.second;
- }
-
- RouteUUID uuid;
- auto s = ExtensionManagerInterface::registerExtension(
- {info.name, info.version, info.sdk_version, info.min_sdk_version},
- er,
- uuid);
- _return.message = s.getMessage();
- if (s.ok()) {
- _return.code = (int)extensions::ExtensionCode::EXT_SUCCESS;
- _return.uuid = uuid;
- } else {
- _return.code = (int)extensions::ExtensionCode::EXT_FAILED;
- }
-}
-
-void ExtensionManagerHandler::deregisterExtension(
- extensions::ExtensionStatus& _return,
- const extensions::ExtensionRouteUUID uuid) {
- auto s = ExtensionManagerInterface::deregisterExtension(uuid);
- _return.message = s.getMessage();
- if (s.ok()) {
- _return.code = (int)extensions::ExtensionCode::EXT_SUCCESS;
- _return.uuid = getUUID();
- } else {
- _return.code = (int)extensions::ExtensionCode::EXT_FAILED;
- }
-}
-
-void ExtensionManagerHandler::query(extensions::ExtensionResponse& _return,
- const std::string& sql) {
- QueryData qd;
- auto s = ExtensionManagerInterface::query(sql, qd);
- for (auto& row : qd) {
- _return.response.emplace_back(std::move(row));
- }
- _return.status.message = s.getMessage();
- if (s.ok()) {
- _return.status.code = (int)extensions::ExtensionCode::EXT_SUCCESS;
- _return.status.uuid = getUUID();
- } else {
- _return.status.code = (int)extensions::ExtensionCode::EXT_FAILED;
- }
-}
-
-void ExtensionManagerHandler::getQueryColumns(
- extensions::ExtensionResponse& _return, const std::string& sql) {
- QueryData qd;
- auto s = ExtensionManagerInterface::getQueryColumns(sql, qd);
- for (auto& row : qd) {
- _return.response.emplace_back(std::move(row));
- }
- _return.status.message = s.getMessage();
- if (s.ok()) {
- _return.status.code = (int)extensions::ExtensionCode::EXT_SUCCESS;
- _return.status.uuid = getUUID();
- } else {
- _return.status.code = (int)extensions::ExtensionCode::EXT_FAILED;
- }
-}
-
-ExtensionRunnerInterface::~ExtensionRunnerInterface() {
- removePath(path_);
-};
-
-ExtensionRunnerInterface::ExtensionRunnerInterface()
- : server_{std::make_unique<ImplExtensionRunner>()} {}
-
-void ExtensionRunnerInterface::serve() {
- // Start the Thrift server's run loop.
- server_->server->serve();
-}
-
-void ExtensionRunnerInterface::connect() {
- server_->transport = std::make_shared<TPlatformServerSocket>(path_);
-
- // Construct the service's transport, protocol, thread pool.
- auto transport_fac = std::make_shared<TBufferedTransportFactory>();
- auto protocol_fac = std::make_shared<TBinaryProtocolFactory>();
-
- server_->server = std::make_shared<TThreadedServer>(
- server_->processor, server_->transport, transport_fac, protocol_fac);
-}
-
-void ExtensionRunnerInterface::init(RouteUUID uuid, bool manager) {
- manager_ = manager;
-
- // Create the thrift instances.
- if (!manager_) {
- auto handler = std::make_shared<ExtensionHandler>(uuid);
- server_->processor =
- std::make_shared<extensions::ExtensionProcessor>(handler);
- } else {
- auto handler = std::make_shared<ExtensionManagerHandler>();
- server_->processor =
- std::make_shared<extensions::ExtensionManagerProcessor>(handler);
- }
-}
-
-void ExtensionRunnerInterface::stopServer() {
- // In most cases the service thread has started before the stop request.
- if (server_->server != nullptr) {
- server_->server->stop();
- }
-}
-
-void ExtensionRunnerInterface::stopServerManager() {
- if (server_->server != nullptr) {
- removeStalePaths(path_);
- }
-}
-
-void ExtensionClientCore::init(const std::string& path, bool manager) {
- path_ = path;
- manager_ = manager;
-
- client_ = std::make_unique<ImplExtensionClient>();
- client_->socket = std::make_shared<TPlatformSocket>(path);
-#ifndef WIN32
- client_->socket->setMaxRecvRetries(std::numeric_limits<int>::max());
-#endif
- client_->transport = std::make_shared<TBufferedTransport>(client_->socket);
- auto protocol = std::make_shared<TBinaryProtocol>(client_->transport);
-
- if (!manager_) {
- client_->e = std::make_shared<extensions::ExtensionClient>(protocol);
- } else {
- client_->em =
- std::make_shared<extensions::ExtensionManagerClient>(protocol);
- }
-
- (void)client_->transport->open();
-}
-
-ExtensionClientCore::~ExtensionClientCore() {
- try {
- client_->transport->close();
- } catch (const std::exception& /* e */) {
- // The transport/socket may have exited.
- }
-}
-
-void ExtensionClientCore::setTimeouts(size_t timeouts) {
-#if !defined(WIN32)
- // Windows TPipe does not support timeouts.
- client_->socket->setRecvTimeout(timeouts);
- client_->socket->setSendTimeout(timeouts);
-#endif
-}
-
-bool ExtensionClientCore::manager() {
- return manager_;
-}
-
-ExtensionClient::ExtensionClient(const std::string& path, size_t timeout) {
- init(path, false);
- setTimeouts(timeout);
-}
-
-ExtensionManagerClient::ExtensionManagerClient(const std::string& path,
- size_t timeout) {
- init(path, true);
- setTimeouts(timeout);
-}
-
-Status ExtensionClient::ping() {
- extensions::ExtensionStatus status;
- auto client = manager() ? client_->em : client_->e;
- client->ping(status);
- if (status.code != (int)extensions::ExtensionCode::EXT_FAILED) {
- return Status(0, status.message);
- }
- return Status(1);
-}
-
-Status ExtensionClient::call(const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) {
- extensions::ExtensionResponse er;
- auto client = manager() ? client_->em : client_->e;
- client->call(er, registry, item, request);
- for (const auto& r : er.response) {
- response.push_back(r);
- }
-
- return Status(er.status.code, er.status.message);
-}
-
-void ExtensionClient::shutdown() {
- auto client = manager() ? client_->em : client_->e;
- client->shutdown();
-}
-
-ExtensionList ExtensionManagerClient::extensions() {
- ExtensionList el;
- extensions::InternalExtensionList iel;
- client_->em->extensions(iel);
- for (const auto& extension : iel) {
- auto& ext = el[extension.first];
- ext.min_sdk_version = extension.second.min_sdk_version;
- ext.version = extension.second.version;
- ext.sdk_version = extension.second.sdk_version;
- ext.name = extension.second.name;
- }
- return el;
-}
-
-OptionList ExtensionManagerClient::options() {
- OptionList ol;
- extensions::InternalOptionList iol;
- client_->em->options(iol);
- for (const auto& option : iol) {
- auto& opt = option.second;
- ol[option.first] = {opt.value, opt.default_value, opt.type};
- }
- return ol;
-}
-
-Status ExtensionManagerClient::registerExtension(
- const ExtensionInfo& info,
- const extensions::ExtensionRegistry& registry,
- RouteUUID& uuid) {
- extensions::InternalExtensionInfo iei;
- iei.name = info.name;
- iei.version = info.version;
- iei.sdk_version = info.sdk_version;
- iei.min_sdk_version = info.min_sdk_version;
- extensions::ExtensionStatus status;
- client_->em->registerExtension(status, iei, registry);
- uuid = status.uuid;
- return Status(status.code, status.message);
-}
-
-Status ExtensionManagerClient::query(const std::string& sql, QueryData& qd) {
- extensions::ExtensionResponse er;
- client_->em->query(er, sql);
- for (const auto& row : er.response) {
- qd.push_back(row);
- }
-
- return Status::success();
-}
-
-Status ExtensionManagerClient::getQueryColumns(const std::string& sql,
- QueryData& qd) {
- extensions::ExtensionResponse er;
- client_->em->getQueryColumns(er, sql);
- for (const auto& row : er.response) {
- qd.push_back(row);
- }
-
- return Status(er.status.code, er.status.message);
-}
-
-Status ExtensionManagerClient::deregisterExtension(RouteUUID uuid) {
- extensions::ExtensionStatus status;
- client_->em->deregisterExtension(status, uuid);
- return Status(status.code, status.message);
-}
-
-ExtensionClient::~ExtensionClient() {}
-
-ExtensionManagerClient::~ExtensionManagerClient() {}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <chrono>
-#include <cstdlib>
-#include <string>
-#include <vector>
-
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/system.h>
-#include <osquery/sql.h>
-
-#include "osquery/extensions/interface.h"
-
-#include <osquery/utils/conversions/split.h>
-#include <osquery/utils/info/platform_type.h>
-#include <osquery/utils/info/version.h>
-
-using chrono_clock = std::chrono::high_resolution_clock;
-
-namespace osquery {
-
-const std::vector<std::string> kSDKVersionChanges = {
- {"1.7.7"},
-};
-
-Status ExtensionInterface::ping() {
- // Need to translate return code into 0 and extract the UUID.
- assert(uuid_ < INT_MAX);
- return Status(static_cast<int>(uuid_), "pong");
-}
-
-Status ExtensionInterface::call(const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) {
- // Call will receive an extension or core's request to call the other's
- // internal registry call. It is the ONLY actor that resolves registry
- // item aliases.
- auto local_item = RegistryFactory::get().getAlias(registry, item);
- if (local_item.empty()) {
- // Extensions may not know about active (non-option based registries).
- local_item = RegistryFactory::get().getActive(registry);
- }
-
- return RegistryFactory::call(registry, local_item, request, response);
-}
-
-void ExtensionInterface::shutdown() {
- // Request a graceful shutdown of the Thrift listener.
- VLOG(1) << "Extension " << uuid_ << " requested shutdown";
- Initializer::requestShutdown(EXIT_SUCCESS);
-}
-
-ExtensionList ExtensionManagerInterface::extensions() {
- refresh();
-
- ReadLock lock(extensions_mutex_);
- return extensions_;
-}
-
-OptionList ExtensionManagerInterface::options() {
- OptionList options;
- auto flags = Flag::flags();
- for (const auto& flag : flags) {
- options[flag.first].value = flag.second.value;
- options[flag.first].default_value = flag.second.default_value;
- options[flag.first].type = flag.second.type;
- }
- return options;
-}
-
-Status ExtensionManagerInterface::registerExtension(
- const ExtensionInfo& info,
- const ExtensionRegistry& registry,
- RouteUUID& uuid) {
- if (exists(info.name)) {
- LOG(WARNING) << "Refusing to register duplicate extension " << info.name;
- return Status((int)ExtensionCode::EXT_FAILED,
- "Duplicate extension registered");
- }
-
- // Enforce API change requirements.
- for (const auto& change : kSDKVersionChanges) {
- if (!versionAtLeast(change, info.sdk_version)) {
- LOG(WARNING) << "Could not add extension " << info.name
- << ": incompatible extension SDK " << info.sdk_version;
- return Status((int)ExtensionCode::EXT_FAILED,
- "Incompatible extension SDK version");
- }
- }
-
- // srand must be called in the active thread on Windows due to thread safety
- if (isPlatform(PlatformType::TYPE_WINDOWS)) {
- std::srand(static_cast<unsigned int>(
- chrono_clock::now().time_since_epoch().count()));
- }
- // Every call to registerExtension is assigned a new RouteUUID.
- uuid = static_cast<uint16_t>(rand());
- LOG(INFO) << "Registering extension (" << info.name << ", " << uuid
- << ", version=" << info.version << ", sdk=" << info.sdk_version
- << ")";
-
- auto status = RegistryFactory::get().addBroadcast(uuid, registry);
- if (!status.ok()) {
- LOG(WARNING) << "Could not add extension " << info.name << ": "
- << status.getMessage();
- return Status((int)ExtensionCode::EXT_FAILED,
- "Failed adding registry: " + status.getMessage());
- }
-
- WriteLock lock(extensions_mutex_);
- extensions_[uuid] = info;
- return Status::success();
-}
-
-Status ExtensionManagerInterface::query(const std::string& sql, QueryData& qd) {
- return osquery::query(sql, qd);
-}
-
-Status ExtensionManagerInterface::deregisterExtension(RouteUUID uuid) {
- {
- ReadLock lock(extensions_mutex_);
- if (extensions_.count(uuid) == 0) {
- return Status((int)ExtensionCode::EXT_FAILED, "No extension UUID found");
- }
- }
-
- // On success return the uuid of the now de-registered extension.
- RegistryFactory::get().removeBroadcast(uuid);
-
- WriteLock lock(extensions_mutex_);
- extensions_.erase(uuid);
- return Status::success();
-}
-
-Status ExtensionManagerInterface::getQueryColumns(const std::string& sql,
- QueryData& qd) {
- TableColumns columns;
- auto status = osquery::getQueryColumns(sql, columns);
- if (status.ok()) {
- for (const auto& col : columns) {
- qd.push_back({{std::get<0>(col), columnTypeName(std::get<1>(col))}});
- }
- }
- return status;
-}
-
-void ExtensionManagerInterface::refresh() {
- std::vector<RouteUUID> removed_routes;
- const auto uuids = RegistryFactory::get().routeUUIDs();
-
- WriteLock lock(extensions_mutex_);
- for (const auto& ext : extensions_) {
- // Find extension UUIDs that have gone away.
- if (std::find(uuids.begin(), uuids.end(), ext.first) == uuids.end()) {
- removed_routes.push_back(ext.first);
- }
- }
-
- // Remove each from the manager's list of extension metadata.
- for (const auto& uuid : removed_routes) {
- extensions_.erase(uuid);
- }
-}
-
-bool ExtensionManagerInterface::exists(const std::string& name) {
- refresh();
-
- // Search the remaining extension list for duplicates.
- ReadLock lock(extensions_mutex_);
- for (const auto& extension : extensions_) {
- if (extension.second.name == name) {
- return true;
- }
- }
- return false;
-}
-
-void removeStalePaths(const std::string& manager) {
- std::vector<std::string> paths;
- // Attempt to remove all stale extension sockets.
- resolveFilePattern(manager + ".*", paths);
- for (const auto& path : paths) {
- removePath(path);
- }
-}
-
-ExtensionRunnerCore::~ExtensionRunnerCore() = default;
-
-ExtensionRunnerCore::ExtensionRunnerCore(const std::string& path)
- : InternalRunnable("ExtensionRunnerCore"), ExtensionRunnerInterface() {
- path_ = path;
-}
-
-void ExtensionRunnerCore::stop() {
- {
- WriteLock lock(service_start_);
- service_stopping_ = true;
- }
-
- stopServer();
-}
-
-void ExtensionRunnerCore::startServer() {
- {
- WriteLock lock(service_start_);
- // A request to stop the service may occur before the thread starts.
- if (service_stopping_) {
- return;
- }
-
- if (!isPlatform(PlatformType::TYPE_WINDOWS)) {
- // Before starting and after stopping the manager, remove stale sockets.
- // This is not relevant in Windows
- removeStalePaths(path_);
- }
-
- connect();
- }
-
- serve();
-}
-
-ExtensionRunner::ExtensionRunner(const std::string& manager_path,
- RouteUUID uuid)
- : ExtensionRunnerCore(""), uuid_(uuid) {
- path_ = getExtensionSocket(uuid, manager_path);
-}
-
-RouteUUID ExtensionRunner::getUUID() const {
- return uuid_;
-}
-
-void ExtensionRunner::start() {
- setThreadName(name() + " " + path_);
- init(uuid_);
-
- VLOG(1) << "Extension service starting: " << path_;
- try {
- startServer();
- } catch (const std::exception& e) {
- LOG(ERROR) << "Cannot start extension handler: " << path_ << " ("
- << e.what() << ")";
- }
-}
-
-ExtensionManagerRunner::ExtensionManagerRunner(const std::string& manager_path)
- : ExtensionRunnerCore(manager_path) {}
-
-ExtensionManagerRunner::~ExtensionManagerRunner() {
- // Only attempt to remove stale paths if the server was started.
- WriteLock lock(service_start_);
- stopServerManager();
-}
-
-void ExtensionManagerRunner::start() {
- init(0, true);
-
- VLOG(1) << "Extension manager service starting: " << path_;
- try {
- startServer();
- } catch (const std::exception& e) {
- LOG(WARNING) << "Extensions disabled: cannot start extension manager ("
- << path_ << ") (" << e.what() << ")";
- }
-}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <osquery/dispatcher.h>
-#include <osquery/extensions.h>
-#include <osquery/query.h>
-
-namespace osquery {
-
-/**
- * An option is a 'basic' flag, the only important information is value.
- */
-struct Option {
- /// Current flag value.
- std::string value;
- /// Initial flag value.
- std::string default_value;
- /// String representation of type (unused).
- std::string type;
-};
-
-/// This is replicated from the Thrift IDL.
-enum class ExtensionCode {
- EXT_SUCCESS = 0,
- EXT_FAILED = 1,
- EXT_FATAL = 2,
-};
-
-using OptionList = std::map<std::string, Option>;
-using ExtensionRouteTable = std::map<std::string, PluginResponse>;
-using ExtensionRegistry = std::map<std::string, ExtensionRouteTable>;
-
-/**
- * @brief The basic API functions that our Thrift server and client implements.
- *
- * We include this abstract to force the server (interface) and clients to
- * include the required APIs.
- *
- * For each interface, a child must implement the actual Thrift endpoints and
- * call the methods included here, which contain the logic. This is a little
- * bit of overhead that was already a sunk cost for osquery-- meaning we
- * were already translating Thrift structures to library structures.
- */
-class ExtensionAPI {
- public:
- virtual ~ExtensionAPI() = default;
-
- public:
- virtual Status ping() = 0;
- virtual Status call(const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) = 0;
- virtual void shutdown() = 0;
-};
-
-class ExtensionManagerAPI {
- public:
- virtual ~ExtensionManagerAPI() = default;
-
- public:
- virtual ExtensionList extensions() = 0;
- virtual OptionList options() = 0;
- virtual Status registerExtension(const ExtensionInfo& info,
- const ExtensionRegistry& registry,
- RouteUUID& uuid) = 0;
- virtual Status deregisterExtension(RouteUUID uuid) = 0;
- virtual Status query(const std::string& sql, QueryData& qd) = 0;
- virtual Status getQueryColumns(const std::string& sql, QueryData& qd) = 0;
-};
-
-/**
- * @brief The Thrift API server used by an osquery Extension process.
- *
- * An extension will load and start a thread to serve the ExtensionHandler
- * Thrift runloop. This handler is the implementation of the thrift IDL spec.
- * It implements all the Extension API handlers.
- *
- */
-class ExtensionInterface : public ExtensionAPI {
- public:
- ExtensionInterface() : ExtensionInterface(0) {}
- explicit ExtensionInterface(RouteUUID uuid) : uuid_(uuid) {}
-
- public:
- virtual Status ping() override;
- virtual Status call(const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) override;
- virtual void shutdown() override;
-
- protected:
- /// Transient UUID assigned to the extension after registering.
- std::atomic<RouteUUID> uuid_;
-};
-
-/**
- * @brief The Thrift API server used by an osquery process.
- *
- * An extension will load and start a thread to serve the
- * ExtensionManagerHandler. This listens for extensions and allows them to
- * register their Registry route information. Calls to the registry may then
- * match a route exposed by an extension.
- * This handler is the implementation of the thrift IDL spec.
- * It implements all the ExtensionManager API handlers.
- *
- */
-class ExtensionManagerInterface : public ExtensionInterface,
- public ExtensionManagerAPI {
- public:
- /// Return a list of Route UUIDs and extension metadata.
- virtual ExtensionList extensions() override;
-
- /**
- * @brief Return a map of osquery options (Flags, bootstrap CLI flags).
- *
- * osquery options are set via command line flags or overridden by a config
- * options dictionary. There are some CLI-only flags that should never
- * be overridden. If a bootstrap flag is changed there is undefined behavior
- * since bootstrap candidates are settings needed before a configuration
- * plugin is setUp.
- *
- * Extensions may broadcast config or logger plugins that need a snapshot
- * of the current options. The best example is the `config_plugin` bootstrap
- * flag.
- */
- virtual OptionList options() override;
-
- /**
- * @brief Request a Route UUID and advertise a set of Registry routes.
- *
- * When an Extension starts it must call registerExtension using a well known
- * ExtensionManager UNIX domain socket path. The ExtensionManager will check
- * the broadcasted routes for duplicates as well as enforce SDK version
- * compatibility checks. On success the Extension is returned a Route UUID and
- * begins to serve the ExtensionHandler Thrift API.
- *
- * @return The output Status and optional assigned RouteUUID.
- * @param info The osquery Thrift-internal Extension metadata container.
- * @param registry The Extension's Registry::getBroadcast information.
- */
- virtual Status registerExtension(const ExtensionInfo& info,
- const ExtensionRegistry& registry,
- RouteUUID& uuid) override;
-
- /**
- * @brief Request an Extension removal and removal of Registry routes.
- *
- * When an Extension process is graceful killed it should deregister.
- * Other privileged tools may choose to deregister an Extension by
- * the transient Extension's Route UUID, obtained using
- * ExtensionManagerHandler::extensions.
- *
- * @param _return The output Status.
- * @param uuid The assigned Route UUID to deregister.
- */
- virtual Status deregisterExtension(RouteUUID uuid) override;
-
- /**
- * @brief Execute an SQL statement in osquery core.
- *
- * Extensions do not have access to the internal SQLite implementation.
- * For complex queries (beyond select all from a table) the statement must
- * be passed into SQLite.
- *
- * @param _return The output Status and QueryData (as response).
- * @param sql The sql statement.
- */
- virtual Status query(const std::string& sql, QueryData& qd) override;
-
- /**
- * @brief Get SQL column information for SQL statements in osquery core.
- *
- * Extensions do not have access to the internal SQLite implementation.
- * For complex queries (beyond metadata for a table) the statement must
- * be passed into SQLite.
- *
- * @param _return The output Status and TableColumns (as response).
- * @param sql The sql statement.
- */
- virtual Status getQueryColumns(const std::string& sql,
- QueryData& qd) override;
-
- private:
- /// Check if an extension exists by the name it registered.
- bool exists(const std::string& name);
-
- /// Introspect into the registry, checking if any extension routes have been
- /// removed.
- void refresh();
-
- /// Maintain a map of extension UUID to metadata for tracking deregistration.
- ExtensionList extensions_;
-
- /// Mutex for extensions accessors.
- Mutex extensions_mutex_;
-};
-
-struct ImplExtensionRunner;
-struct ImplExtensionClient;
-
-/**
- * This implements a small API around setting up and running Thrift
- * Servers. The implementation details and members are private and stored in
- * the PIMPL structures defined above.
- *
- * An implementation will exist for Apache Thrift and for FBThrift.
- */
-class ExtensionRunnerInterface {
- public:
- virtual ~ExtensionRunnerInterface();
- ExtensionRunnerInterface();
-
- /**
- * Call into the Thrift server's server implementation.
- */
- void serve();
-
- /// Set up structures.
- void connect();
-
- /// Create handler/processor.
- void init(RouteUUID uuid, bool manager = false);
-
- /// Stop server.
- void stopServer();
-
- /// Stop server manager.
- void stopServerManager();
-
- protected:
- /// The UNIX domain socket used for requests from the ExtensionManager.
- std::string path_;
-
- /// True if the extension is an extension manager.
- bool manager_;
-
- /// Thrift server implementation.
- std::unique_ptr<ImplExtensionRunner> server_;
-};
-
-class ExtensionRunnerCore : public InternalRunnable,
- public ExtensionRunnerInterface {
- public:
- virtual ~ExtensionRunnerCore();
- explicit ExtensionRunnerCore(const std::string& path);
-
- public:
- /// Given a handler transport and protocol start a thrift threaded server.
- void startServer();
-
- // The Dispatcher thread service stop point.
- void stop() override;
-
- protected:
- /// Protect the service start and stop, this mutex protects server creation.
- Mutex service_start_;
-
- /// Record a dispatcher's request to stop the service.
- bool service_stopping_{false};
-};
-
-/**
- * @brief A Dispatcher service thread that starts ExtensionHandler.
- *
- * This runner will start a Thrift Extension server, call serve, and wait
- * until the extension exists or the ExtensionManager (core) terminates or
- * deregisters the extension.
- *
- */
-class ExtensionRunner : public ExtensionRunnerCore {
- public:
- ExtensionRunner(const std::string& manager_path, RouteUUID uuid);
-
- public:
- void start() override;
-
- /// Access the UUID provided by the ExtensionManager.
- RouteUUID getUUID() const;
-
- private:
- /// The unique and transient Extension UUID assigned by the ExtensionManager.
- RouteUUID uuid_;
-};
-
-/**
- * @brief A Dispatcher service thread that starts ExtensionManagerHandler.
- *
- * This runner will start a Thrift ExtensionManager server, call serve, and wait
- * until for extensions to register, or thrift API calls.
- *
- */
-class ExtensionManagerRunner : public ExtensionRunnerCore {
- public:
- virtual ~ExtensionManagerRunner();
- explicit ExtensionManagerRunner(const std::string& manager_path);
-
- public:
- void start() override;
-};
-
-/// Internal accessor for extension clients.
-class ExtensionClientCore : private boost::noncopyable {
- public:
- virtual ~ExtensionClientCore();
-
- public:
- /**
- * @brief Initialize the UNIX socket from a string pathname.
- *
- * A very basic client can just store the string.
- * More complex clients can create the client structure.
- */
- void init(const std::string& path, bool manager = false);
-
- /// Set the receive and send timeout.
- void setTimeouts(size_t timeout);
-
- /// Check if the client is an extension manager.
- bool manager();
-
- protected:
- /// Path to extension server socket.
- std::string path_;
-
- /// True if the client is an extension manager client.
- bool manager_;
-
- /// Thrift client implementation.
- std::unique_ptr<ImplExtensionClient> client_;
-};
-
-/// Internal accessor for a client to an extension (from an extension manager).
-class ExtensionClient : public ExtensionClientCore, public ExtensionAPI {
- public:
- /**
- * @brief Create a client to a client extension.
- *
- * @note The default timeout to wait for buffered (whole-content) responses
- * is 5 minutes.
- * @param path This is the socket path for the client communication.
- * @param timeout [optional] time in milliseconds to wait for input.
- */
- explicit ExtensionClient(const std::string& path, size_t timeout = 5000 * 60);
- ~ExtensionClient();
-
- protected:
- ExtensionClient() = default;
-
- public:
- /// Ping a server and have it fill in the extension's UUID as the code.
- Status ping() override;
-
- /// Call an extension's plugin.
- Status call(const std::string& registry,
- const std::string& item,
- const PluginRequest& request,
- PluginResponse& response) override;
-
- /// Request that the extension stop.
- void shutdown() override;
-};
-
-/// Internal accessor for a client to an extension manager (from an extension).
-class ExtensionManagerClient : public ExtensionClient,
- public ExtensionManagerAPI {
- public:
- /**
- * @brief Create a client to a manager extension.
- *
- * @param path This is the socket path for the manager communication.
- * @param timeout [optional] time in milliseconds to wait for input.
- */
- explicit ExtensionManagerClient(const std::string& path,
- size_t timeout = 5000 * 60);
- ~ExtensionManagerClient();
-
- public:
- /// List all osquery extensions.
- ExtensionList extensions() override;
-
- /// List all osquery options (gflags).
- OptionList options() override;
-
- /// Regiester yourself as a new extension.
- Status registerExtension(const ExtensionInfo& info,
- const ExtensionRegistry& registry,
- RouteUUID& uuid) override;
-
- /// Remove an extension.
- Status deregisterExtension(RouteUUID uuid) override;
-
- /// Issue a query.
- Status query(const std::string& sql, QueryData& qd) override;
-
- /// Get column information from a query.
- Status getQueryColumns(const std::string& sql, QueryData& qd) override;
-};
-
-/// Attempt to remove all stale extension sockets.
-void removeStalePaths(const std::string& manager);
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#ifdef GTEST_HAS_TR1_TUPLE
-#undef GTEST_HAS_TR1_TUPLE
-#define GTEST_HAS_TR1_TUPLE 0
-#endif
-
-#include <stdexcept>
-
-#include <gtest/gtest.h>
-
-#include <osquery/extensions.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/registry_factory.h>
-
-#include <osquery/utils/info/platform_type.h>
-
-#include <osquery/database.h>
-#include <osquery/extensions/interface.h>
-#include <osquery/filesystem/fileops.h>
-#include <osquery/process/process.h>
-
-#include <boost/filesystem.hpp>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-DECLARE_bool(disable_database);
-
-const int kDelay = 20;
-const int kTimeout = 3000;
-
-class ExtensionsTest : public testing::Test {
- protected:
- void SetUp() override {
- Initializer::platformSetup();
- registryAndPluginInit();
- FLAGS_disable_database = true;
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
-
- if (!isPlatform(PlatformType::TYPE_WINDOWS)) {
- socket_path =
- (fs::temp_directory_path() /
- fs::unique_path("osquery.extensions_test.testextmgr.%%%%.%%%%"))
- .string();
- removePath(socket_path);
- if (pathExists(socket_path).ok()) {
- throw std::domain_error("Cannot test sockets: " + socket_path);
- }
- } else {
- socket_path =
- "\\\\.\\pipe\\" +
- fs::unique_path("osquery.extensions_test.testextmgr.%%%%.%%%%")
- .string();
- }
- }
-
- void TearDown() override {
- Dispatcher::stopServices();
- Dispatcher::joinServices();
- if (!isPlatform(PlatformType::TYPE_WINDOWS)) {
- fs::remove(fs::path(socket_path));
- }
- }
-
- bool ping(int attempts = 3) {
- // Calling open will except if the socket does not exist.
- for (int i = 0; i < attempts; ++i) {
- try {
- ExtensionManagerClient client(socket_path);
-
- auto status = client.ping();
- return (status.getCode() == (int)ExtensionCode::EXT_SUCCESS);
- } catch (const std::exception& /* e */) {
- sleepFor(kDelay);
- }
- }
-
- return false;
- }
-
- QueryData query(const std::string& sql, int attempts = 3) {
- // Calling open will except if the socket does not exist.
- QueryData qd;
- for (int i = 0; i < attempts; ++i) {
- try {
- ExtensionManagerClient client(socket_path);
-
- client.query(sql, qd);
- } catch (const std::exception& /* e */) {
- sleepFor(kDelay);
- }
- }
-
- return qd;
- }
-
- ExtensionList registeredExtensions(int attempts = 3) {
- ExtensionList extensions;
- for (int i = 0; i < attempts; ++i) {
- if (getExtensions(socket_path, extensions).ok()) {
- break;
- }
- }
-
- return extensions;
- }
-
- bool socketExistsLocal(const std::string& check_path) {
- // Wait until the runnable/thread created the socket.
- int delay = 0;
- while (delay < kTimeout) {
- if (osquery::socketExists(check_path).ok()) {
- return true;
- }
- sleepFor(kDelay);
- delay += kDelay;
- }
- return false;
- }
-
- public:
- std::string socket_path;
-};
-
-TEST_F(ExtensionsTest, test_manager_runnable) {
- // Start a testing extension manager.
- auto status = startExtensionManager(socket_path);
- EXPECT_TRUE(status.ok()) << " error " << status.what();
- // Call success if the Unix socket was created.
- EXPECT_TRUE(socketExistsLocal(socket_path));
-}
-
-TEST_F(ExtensionsTest, test_extension_runnable) {
- auto status = startExtensionManager(socket_path);
- EXPECT_TRUE(status.ok()) << " error " << status.what();
- // Wait for the extension manager to start.
- EXPECT_TRUE(socketExistsLocal(socket_path));
-
- // Test the extension manager API 'ping' call.
- EXPECT_TRUE(ping());
-}
-
-// TODO: fix it and enable, please
-TEST_F(ExtensionsTest, DISABLED_test_extension_start) {
- auto status = startExtensionManager(socket_path);
- EXPECT_TRUE(status.ok());
- EXPECT_TRUE(socketExistsLocal(socket_path));
-
- auto& rf = RegistryFactory::get();
- // Now allow duplicates (for testing, since EM/E are the same).
- rf.allowDuplicates(true);
- status = startExtension(socket_path, "test", "0.1", "0.0.0", "9.9.9");
- // This will not be false since we are allowing duplicate items.
- // Otherwise, starting an extension and extensionManager would fatal.
- ASSERT_NE(status.getCode(), (int)ExtensionCode::EXT_FAILED) << status.what();
-
- // Checks for version comparisons (also used by packs).
- ASSERT_FALSE(versionAtLeast("1.1.1", "0.0.1"));
- ASSERT_TRUE(versionAtLeast("1.1.1", "1.1.1"));
- ASSERT_TRUE(versionAtLeast("1.1.1", "1.1.2"));
-
- // The `startExtension` internal call (exposed for testing) returns the
- // uuid of the extension in the success status.
- RouteUUID uuid = (RouteUUID)stoi(status.getMessage(), nullptr, 0);
-
- // We can test-wait for the extensions's socket to open.
- EXPECT_TRUE(socketExistsLocal(socket_path + "." + std::to_string(uuid)));
-
- // Then clean up the registry modifications.
- rf.removeBroadcast(uuid);
- rf.allowDuplicates(false);
-}
-
-class ExtensionPlugin : public Plugin {
- public:
- Status call(const PluginRequest& request, PluginResponse& response) {
- for (const auto& request_item : request) {
- response.push_back({{request_item.first, request_item.second}});
- }
- return Status::success();
- }
-};
-
-class TestExtensionPlugin : public ExtensionPlugin {};
-
-CREATE_REGISTRY(ExtensionPlugin, "extension_test");
-
-// TODO: fix it and enable, please
-TEST_F(ExtensionsTest, DISABLED_test_extension_broadcast) {
- auto status = startExtensionManager(socket_path);
- EXPECT_TRUE(status.ok());
- EXPECT_TRUE(socketExistsLocal(socket_path));
-
- auto& rf = RegistryFactory::get();
- // This time we're going to add a plugin to the extension_test registry.
- rf.registry("extension_test")
- ->add("test_item", std::make_shared<TestExtensionPlugin>());
-
- // Now we create a registry alias that will be broadcasted but NOT used for
- // internal call lookups. Aliasing was introduced for testing such that an
- // EM/E could exist in the same process (the same registry) without having
- // duplicate registry items in the internal registry list AND extension
- // registry route table.
- rf.addAlias("extension_test", "test_item", "test_alias");
- rf.allowDuplicates(true);
-
- // Before registering the extension there is NO route to "test_alias" since
- // alias resolutions are performed by the EM.
- EXPECT_TRUE(rf.exists("extension_test", "test_item"));
- EXPECT_FALSE(rf.exists("extension_test", "test_alias"));
-
- status = startExtension(socket_path, "test", "0.1", "0.0.0", "0.0.0");
- EXPECT_TRUE(status.ok());
-
- RouteUUID uuid;
- try {
- uuid = (RouteUUID)stoi(status.getMessage(), nullptr, 0);
- } catch (const std::exception& /* e */) {
- EXPECT_TRUE(false);
- return;
- }
-
- auto ext_socket = socket_path + "." + std::to_string(uuid);
- EXPECT_TRUE(socketExistsLocal(ext_socket));
-
- // Make sure the EM registered the extension (called in start extension).
- auto extensions = registeredExtensions();
- // Expect two, since `getExtensions` includes the core.
- ASSERT_EQ(extensions.size(), 2U);
- EXPECT_EQ(extensions.count(uuid), 1U);
- EXPECT_EQ(extensions.at(uuid).name, "test");
- EXPECT_EQ(extensions.at(uuid).version, "0.1");
- EXPECT_EQ(extensions.at(uuid).sdk_version, "0.0.0");
-
- // We are broadcasting to our own registry in the test, which internally has
- // a "test_item" aliased to "test_alias", "test_item" is internally callable
- // but "test_alias" can only be resolved by an EM call.
- EXPECT_TRUE(rf.exists("extension_test", "test_item"));
- // Now "test_alias" exists since it is in the extensions route table.
- EXPECT_TRUE(rf.exists("extension_test", "test_alias"));
-
- PluginResponse response;
- // This registry call will fail, since "test_alias" cannot be resolved using
- // a local registry call.
- status = Registry::call("extension_test", "test_alias", {{}}, response);
- EXPECT_FALSE(status.ok());
-
- // The following will be the result of a:
- // Registry::call("extension_test", "test_alias", {{}}, response);
- status = callExtension(ext_socket,
- "extension_test",
- "test_alias",
- {{"test_key", "test_value"}},
- response);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ(response.size(), 1U);
- EXPECT_EQ(response[0]["test_key"], "test_value");
-
- rf.removeBroadcast(uuid);
- rf.allowDuplicates(false);
-}
-
-}
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#include "Extension.h"
-
-namespace osquery { namespace extensions {
-
-
-Extension_ping_args::~Extension_ping_args() throw() {
-}
-
-
-uint32_t Extension_ping_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_ping_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_ping_args");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_ping_pargs::~Extension_ping_pargs() throw() {
-}
-
-
-uint32_t Extension_ping_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_ping_pargs");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_ping_result::~Extension_ping_result() throw() {
-}
-
-
-uint32_t Extension_ping_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_ping_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("Extension_ping_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_ping_presult::~Extension_ping_presult() throw() {
-}
-
-
-uint32_t Extension_ping_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-Extension_call_args::~Extension_call_args() throw() {
-}
-
-
-uint32_t Extension_call_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->registry);
- this->__isset.registry = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->item);
- this->__isset.item = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 3:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- this->request.clear();
- uint32_t _size24;
- ::apache::thrift::protocol::TType _ktype25;
- ::apache::thrift::protocol::TType _vtype26;
- xfer += iprot->readMapBegin(_ktype25, _vtype26, _size24);
- uint32_t _i28;
- for (_i28 = 0; _i28 < _size24; ++_i28)
- {
- std::string _key29;
- xfer += iprot->readString(_key29);
- std::string& _val30 = this->request[_key29];
- xfer += iprot->readString(_val30);
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.request = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_call_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_call_args");
-
- xfer += oprot->writeFieldBegin("registry", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString(this->registry);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("item", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->item);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_MAP, 3);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->request.size()));
- std::map<std::string, std::string> ::const_iterator _iter31;
- for (_iter31 = this->request.begin(); _iter31 != this->request.end(); ++_iter31)
- {
- xfer += oprot->writeString(_iter31->first);
- xfer += oprot->writeString(_iter31->second);
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_call_pargs::~Extension_call_pargs() throw() {
-}
-
-
-uint32_t Extension_call_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_call_pargs");
-
- xfer += oprot->writeFieldBegin("registry", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString((*(this->registry)));
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("item", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString((*(this->item)));
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("request", ::apache::thrift::protocol::T_MAP, 3);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*(this->request)).size()));
- std::map<std::string, std::string> ::const_iterator _iter32;
- for (_iter32 = (*(this->request)).begin(); _iter32 != (*(this->request)).end(); ++_iter32)
- {
- xfer += oprot->writeString(_iter32->first);
- xfer += oprot->writeString(_iter32->second);
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_call_result::~Extension_call_result() throw() {
-}
-
-
-uint32_t Extension_call_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_call_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("Extension_call_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_call_presult::~Extension_call_presult() throw() {
-}
-
-
-uint32_t Extension_call_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-Extension_shutdown_args::~Extension_shutdown_args() throw() {
-}
-
-
-uint32_t Extension_shutdown_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_shutdown_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_shutdown_args");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_shutdown_pargs::~Extension_shutdown_pargs() throw() {
-}
-
-
-uint32_t Extension_shutdown_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("Extension_shutdown_pargs");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_shutdown_result::~Extension_shutdown_result() throw() {
-}
-
-
-uint32_t Extension_shutdown_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t Extension_shutdown_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("Extension_shutdown_result");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-Extension_shutdown_presult::~Extension_shutdown_presult() throw() {
-}
-
-
-uint32_t Extension_shutdown_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-void ExtensionClient::ping(ExtensionStatus& _return)
-{
- send_ping();
- recv_ping(_return);
-}
-
-void ExtensionClient::send_ping()
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("ping", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_ping_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionClient::recv_ping(ExtensionStatus& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("ping") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- Extension_ping_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "ping failed: unknown result");
-}
-
-void ExtensionClient::call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request)
-{
- send_call(registry, item, request);
- recv_call(_return);
-}
-
-void ExtensionClient::send_call(const std::string& registry, const std::string& item, const ExtensionPluginRequest& request)
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("call", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_call_pargs args;
- args.registry = ®istry;
- args.item = &item;
- args.request = &request;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionClient::recv_call(ExtensionResponse& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("call") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- Extension_call_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "call failed: unknown result");
-}
-
-void ExtensionClient::shutdown()
-{
- send_shutdown();
- recv_shutdown();
-}
-
-void ExtensionClient::send_shutdown()
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("shutdown", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_shutdown_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionClient::recv_shutdown()
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("shutdown") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- Extension_shutdown_presult result;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- return;
-}
-
-bool ExtensionProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
- ProcessMap::iterator pfn;
- pfn = processMap_.find(fname);
- if (pfn == processMap_.end()) {
- iprot->skip(::apache::thrift::protocol::T_STRUCT);
- iprot->readMessageEnd();
- iprot->getTransport()->readEnd();
- ::apache::thrift::TApplicationException x(::apache::thrift::TApplicationException::UNKNOWN_METHOD, "Invalid method name: '"+fname+"'");
- oprot->writeMessageBegin(fname, ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return true;
- }
- (this->*(pfn->second))(seqid, iprot, oprot, callContext);
- return true;
-}
-
-void ExtensionProcessor::process_ping(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("Extension.ping", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Extension.ping");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "Extension.ping");
- }
-
- Extension_ping_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "Extension.ping", bytes);
- }
-
- Extension_ping_result result;
- try {
- iface_->ping(result.success);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "Extension.ping");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("ping", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "Extension.ping");
- }
-
- oprot->writeMessageBegin("ping", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "Extension.ping", bytes);
- }
-}
-
-void ExtensionProcessor::process_call(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("Extension.call", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Extension.call");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "Extension.call");
- }
-
- Extension_call_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "Extension.call", bytes);
- }
-
- Extension_call_result result;
- try {
- iface_->call(result.success, args.registry, args.item, args.request);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "Extension.call");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("call", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "Extension.call");
- }
-
- oprot->writeMessageBegin("call", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "Extension.call", bytes);
- }
-}
-
-void ExtensionProcessor::process_shutdown(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("Extension.shutdown", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "Extension.shutdown");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "Extension.shutdown");
- }
-
- Extension_shutdown_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "Extension.shutdown", bytes);
- }
-
- Extension_shutdown_result result;
- try {
- iface_->shutdown();
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "Extension.shutdown");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("shutdown", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "Extension.shutdown");
- }
-
- oprot->writeMessageBegin("shutdown", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "Extension.shutdown", bytes);
- }
-}
-
-::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > ExtensionProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
- ::apache::thrift::ReleaseHandler< ExtensionIfFactory > cleanup(handlerFactory_);
- ::apache::thrift::stdcxx::shared_ptr< ExtensionIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
- ::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > processor(new ExtensionProcessor(handler));
- return processor;
-}
-
-void ExtensionConcurrentClient::ping(ExtensionStatus& _return)
-{
- int32_t seqid = send_ping();
- recv_ping(_return, seqid);
-}
-
-int32_t ExtensionConcurrentClient::send_ping()
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("ping", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_ping_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionConcurrentClient::recv_ping(ExtensionStatus& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("ping") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- Extension_ping_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "ping failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionConcurrentClient::call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request)
-{
- int32_t seqid = send_call(registry, item, request);
- recv_call(_return, seqid);
-}
-
-int32_t ExtensionConcurrentClient::send_call(const std::string& registry, const std::string& item, const ExtensionPluginRequest& request)
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("call", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_call_pargs args;
- args.registry = ®istry;
- args.item = &item;
- args.request = &request;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionConcurrentClient::recv_call(ExtensionResponse& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("call") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- Extension_call_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "call failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionConcurrentClient::shutdown()
-{
- int32_t seqid = send_shutdown();
- recv_shutdown(seqid);
-}
-
-int32_t ExtensionConcurrentClient::send_shutdown()
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("shutdown", ::apache::thrift::protocol::T_CALL, cseqid);
-
- Extension_shutdown_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionConcurrentClient::recv_shutdown(const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("shutdown") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- Extension_shutdown_presult result;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- sentry.commit();
- return;
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-}} // namespace
-
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#ifndef Extension_H
-#define Extension_H
-
-#include <thrift/TDispatchProcessor.h>
-#include <thrift/async/TConcurrentClientSyncInfo.h>
-#include "osquery_types.h"
-
-namespace osquery { namespace extensions {
-
-#ifdef _MSC_VER
- #pragma warning( push )
- #pragma warning (disable : 4250 ) //inheriting methods via dominance
-#endif
-
-class ExtensionIf {
- public:
- virtual ~ExtensionIf() {}
- virtual void ping(ExtensionStatus& _return) = 0;
- virtual void call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request) = 0;
- virtual void shutdown() = 0;
-};
-
-class ExtensionIfFactory {
- public:
- typedef ExtensionIf Handler;
-
- virtual ~ExtensionIfFactory() {}
-
- virtual ExtensionIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
- virtual void releaseHandler(ExtensionIf* /* handler */) = 0;
-};
-
-class ExtensionIfSingletonFactory : virtual public ExtensionIfFactory {
- public:
- ExtensionIfSingletonFactory(const ::apache::thrift::stdcxx::shared_ptr<ExtensionIf>& iface) : iface_(iface) {}
- virtual ~ExtensionIfSingletonFactory() {}
-
- virtual ExtensionIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
- return iface_.get();
- }
- virtual void releaseHandler(ExtensionIf* /* handler */) {}
-
- protected:
- ::apache::thrift::stdcxx::shared_ptr<ExtensionIf> iface_;
-};
-
-class ExtensionNull : virtual public ExtensionIf {
- public:
- virtual ~ExtensionNull() {}
- void ping(ExtensionStatus& /* _return */) {
- return;
- }
- void call(ExtensionResponse& /* _return */, const std::string& /* registry */, const std::string& /* item */, const ExtensionPluginRequest& /* request */) {
- return;
- }
- void shutdown() {
- return;
- }
-};
-
-
-class Extension_ping_args {
- public:
-
- Extension_ping_args(const Extension_ping_args&);
- Extension_ping_args& operator=(const Extension_ping_args&);
- Extension_ping_args() {
- }
-
- virtual ~Extension_ping_args() throw();
-
- bool operator == (const Extension_ping_args & /* rhs */) const
- {
- return true;
- }
- bool operator != (const Extension_ping_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_ping_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class Extension_ping_pargs {
- public:
-
-
- virtual ~Extension_ping_pargs() throw();
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _Extension_ping_result__isset {
- _Extension_ping_result__isset() : success(false) {}
- bool success :1;
-} _Extension_ping_result__isset;
-
-class Extension_ping_result {
- public:
-
- Extension_ping_result(const Extension_ping_result&);
- Extension_ping_result& operator=(const Extension_ping_result&);
- Extension_ping_result() {
- }
-
- virtual ~Extension_ping_result() throw();
- ExtensionStatus success;
-
- _Extension_ping_result__isset __isset;
-
- void __set_success(const ExtensionStatus& val);
-
- bool operator == (const Extension_ping_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const Extension_ping_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_ping_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _Extension_ping_presult__isset {
- _Extension_ping_presult__isset() : success(false) {}
- bool success :1;
-} _Extension_ping_presult__isset;
-
-class Extension_ping_presult {
- public:
-
-
- virtual ~Extension_ping_presult() throw();
- ExtensionStatus* success;
-
- _Extension_ping_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-typedef struct _Extension_call_args__isset {
- _Extension_call_args__isset() : registry(false), item(false), request(false) {}
- bool registry :1;
- bool item :1;
- bool request :1;
-} _Extension_call_args__isset;
-
-class Extension_call_args {
- public:
-
- Extension_call_args(const Extension_call_args&);
- Extension_call_args& operator=(const Extension_call_args&);
- Extension_call_args() : registry(), item() {
- }
-
- virtual ~Extension_call_args() throw();
- std::string registry;
- std::string item;
- ExtensionPluginRequest request;
-
- _Extension_call_args__isset __isset;
-
- void __set_registry(const std::string& val);
-
- void __set_item(const std::string& val);
-
- void __set_request(const ExtensionPluginRequest& val);
-
- bool operator == (const Extension_call_args & rhs) const
- {
- if (!(registry == rhs.registry))
- return false;
- if (!(item == rhs.item))
- return false;
- if (!(request == rhs.request))
- return false;
- return true;
- }
- bool operator != (const Extension_call_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_call_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class Extension_call_pargs {
- public:
-
-
- virtual ~Extension_call_pargs() throw();
- const std::string* registry;
- const std::string* item;
- const ExtensionPluginRequest* request;
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _Extension_call_result__isset {
- _Extension_call_result__isset() : success(false) {}
- bool success :1;
-} _Extension_call_result__isset;
-
-class Extension_call_result {
- public:
-
- Extension_call_result(const Extension_call_result&);
- Extension_call_result& operator=(const Extension_call_result&);
- Extension_call_result() {
- }
-
- virtual ~Extension_call_result() throw();
- ExtensionResponse success;
-
- _Extension_call_result__isset __isset;
-
- void __set_success(const ExtensionResponse& val);
-
- bool operator == (const Extension_call_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const Extension_call_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_call_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _Extension_call_presult__isset {
- _Extension_call_presult__isset() : success(false) {}
- bool success :1;
-} _Extension_call_presult__isset;
-
-class Extension_call_presult {
- public:
-
-
- virtual ~Extension_call_presult() throw();
- ExtensionResponse* success;
-
- _Extension_call_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-
-class Extension_shutdown_args {
- public:
-
- Extension_shutdown_args(const Extension_shutdown_args&);
- Extension_shutdown_args& operator=(const Extension_shutdown_args&);
- Extension_shutdown_args() {
- }
-
- virtual ~Extension_shutdown_args() throw();
-
- bool operator == (const Extension_shutdown_args & /* rhs */) const
- {
- return true;
- }
- bool operator != (const Extension_shutdown_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_shutdown_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class Extension_shutdown_pargs {
- public:
-
-
- virtual ~Extension_shutdown_pargs() throw();
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class Extension_shutdown_result {
- public:
-
- Extension_shutdown_result(const Extension_shutdown_result&);
- Extension_shutdown_result& operator=(const Extension_shutdown_result&);
- Extension_shutdown_result() {
- }
-
- virtual ~Extension_shutdown_result() throw();
-
- bool operator == (const Extension_shutdown_result & /* rhs */) const
- {
- return true;
- }
- bool operator != (const Extension_shutdown_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const Extension_shutdown_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class Extension_shutdown_presult {
- public:
-
-
- virtual ~Extension_shutdown_presult() throw();
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-class ExtensionClient : virtual public ExtensionIf {
- public:
- ExtensionClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
- setProtocol(prot);
- }
- ExtensionClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
- setProtocol(iprot,oprot);
- }
- private:
- void setProtocol(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
- setProtocol(prot,prot);
- }
- void setProtocol(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
- piprot_=iprot;
- poprot_=oprot;
- iprot_ = iprot.get();
- oprot_ = oprot.get();
- }
- public:
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
- return piprot_;
- }
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
- return poprot_;
- }
- void ping(ExtensionStatus& _return);
- void send_ping();
- void recv_ping(ExtensionStatus& _return);
- void call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request);
- void send_call(const std::string& registry, const std::string& item, const ExtensionPluginRequest& request);
- void recv_call(ExtensionResponse& _return);
- void shutdown();
- void send_shutdown();
- void recv_shutdown();
- protected:
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
- ::apache::thrift::protocol::TProtocol* iprot_;
- ::apache::thrift::protocol::TProtocol* oprot_;
-};
-
-class ExtensionProcessor : public ::apache::thrift::TDispatchProcessor {
- protected:
- ::apache::thrift::stdcxx::shared_ptr<ExtensionIf> iface_;
- virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
- private:
- typedef void (ExtensionProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
- typedef std::map<std::string, ProcessFunction> ProcessMap;
- ProcessMap processMap_;
- void process_ping(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_call(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_shutdown(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- public:
- ExtensionProcessor(::apache::thrift::stdcxx::shared_ptr<ExtensionIf> iface) :
- iface_(iface) {
- processMap_["ping"] = &ExtensionProcessor::process_ping;
- processMap_["call"] = &ExtensionProcessor::process_call;
- processMap_["shutdown"] = &ExtensionProcessor::process_shutdown;
- }
-
- virtual ~ExtensionProcessor() {}
-};
-
-class ExtensionProcessorFactory : public ::apache::thrift::TProcessorFactory {
- public:
- ExtensionProcessorFactory(const ::apache::thrift::stdcxx::shared_ptr< ExtensionIfFactory >& handlerFactory) :
- handlerFactory_(handlerFactory) {}
-
- ::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
-
- protected:
- ::apache::thrift::stdcxx::shared_ptr< ExtensionIfFactory > handlerFactory_;
-};
-
-class ExtensionMultiface : virtual public ExtensionIf {
- public:
- ExtensionMultiface(std::vector<apache::thrift::stdcxx::shared_ptr<ExtensionIf> >& ifaces) : ifaces_(ifaces) {
- }
- virtual ~ExtensionMultiface() {}
- protected:
- std::vector<apache::thrift::stdcxx::shared_ptr<ExtensionIf> > ifaces_;
- ExtensionMultiface() {}
- void add(::apache::thrift::stdcxx::shared_ptr<ExtensionIf> iface) {
- ifaces_.push_back(iface);
- }
- public:
- void ping(ExtensionStatus& _return) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->ping(_return);
- }
- ifaces_[i]->ping(_return);
- return;
- }
-
- void call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->call(_return, registry, item, request);
- }
- ifaces_[i]->call(_return, registry, item, request);
- return;
- }
-
- void shutdown() {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->shutdown();
- }
- ifaces_[i]->shutdown();
- }
-
-};
-
-// The 'concurrent' client is a thread safe client that correctly handles
-// out of order responses. It is slower than the regular client, so should
-// only be used when you need to share a connection among multiple threads
-class ExtensionConcurrentClient : virtual public ExtensionIf {
- public:
- ExtensionConcurrentClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
- setProtocol(prot);
- }
- ExtensionConcurrentClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
- setProtocol(iprot,oprot);
- }
- private:
- void setProtocol(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
- setProtocol(prot,prot);
- }
- void setProtocol(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
- piprot_=iprot;
- poprot_=oprot;
- iprot_ = iprot.get();
- oprot_ = oprot.get();
- }
- public:
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
- return piprot_;
- }
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
- return poprot_;
- }
- void ping(ExtensionStatus& _return);
- int32_t send_ping();
- void recv_ping(ExtensionStatus& _return, const int32_t seqid);
- void call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request);
- int32_t send_call(const std::string& registry, const std::string& item, const ExtensionPluginRequest& request);
- void recv_call(ExtensionResponse& _return, const int32_t seqid);
- void shutdown();
- int32_t send_shutdown();
- void recv_shutdown(const int32_t seqid);
- protected:
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_;
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_;
- ::apache::thrift::protocol::TProtocol* iprot_;
- ::apache::thrift::protocol::TProtocol* oprot_;
- ::apache::thrift::async::TConcurrentClientSyncInfo sync_;
-};
-
-#ifdef _MSC_VER
- #pragma warning( pop )
-#endif
-
-}} // namespace
-
-#endif
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#include "ExtensionManager.h"
-
-namespace osquery { namespace extensions {
-
-
-ExtensionManager_extensions_args::~ExtensionManager_extensions_args() throw() {
-}
-
-
-uint32_t ExtensionManager_extensions_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_extensions_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_extensions_args");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_extensions_pargs::~ExtensionManager_extensions_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_extensions_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_extensions_pargs");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_extensions_result::~ExtensionManager_extensions_result() throw() {
-}
-
-
-uint32_t ExtensionManager_extensions_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- this->success.clear();
- uint32_t _size33;
- ::apache::thrift::protocol::TType _ktype34;
- ::apache::thrift::protocol::TType _vtype35;
- xfer += iprot->readMapBegin(_ktype34, _vtype35, _size33);
- uint32_t _i37;
- for (_i37 = 0; _i37 < _size33; ++_i37)
- {
- ExtensionRouteUUID _key38;
- xfer += iprot->readI64(_key38);
- InternalExtensionInfo& _val39 = this->success[_key38];
- xfer += _val39.read(iprot);
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_extensions_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_extensions_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_I64, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
- std::map<ExtensionRouteUUID, InternalExtensionInfo> ::const_iterator _iter40;
- for (_iter40 = this->success.begin(); _iter40 != this->success.end(); ++_iter40)
- {
- xfer += oprot->writeI64(_iter40->first);
- xfer += _iter40->second.write(oprot);
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_extensions_presult::~ExtensionManager_extensions_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_extensions_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- (*(this->success)).clear();
- uint32_t _size41;
- ::apache::thrift::protocol::TType _ktype42;
- ::apache::thrift::protocol::TType _vtype43;
- xfer += iprot->readMapBegin(_ktype42, _vtype43, _size41);
- uint32_t _i45;
- for (_i45 = 0; _i45 < _size41; ++_i45)
- {
- ExtensionRouteUUID _key46;
- xfer += iprot->readI64(_key46);
- InternalExtensionInfo& _val47 = (*(this->success))[_key46];
- xfer += _val47.read(iprot);
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-ExtensionManager_options_args::~ExtensionManager_options_args() throw() {
-}
-
-
-uint32_t ExtensionManager_options_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- xfer += iprot->skip(ftype);
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_options_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_options_args");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_options_pargs::~ExtensionManager_options_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_options_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_options_pargs");
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_options_result::~ExtensionManager_options_result() throw() {
-}
-
-
-uint32_t ExtensionManager_options_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- this->success.clear();
- uint32_t _size48;
- ::apache::thrift::protocol::TType _ktype49;
- ::apache::thrift::protocol::TType _vtype50;
- xfer += iprot->readMapBegin(_ktype49, _vtype50, _size48);
- uint32_t _i52;
- for (_i52 = 0; _i52 < _size48; ++_i52)
- {
- std::string _key53;
- xfer += iprot->readString(_key53);
- InternalOptionInfo& _val54 = this->success[_key53];
- xfer += _val54.read(iprot);
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_options_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_options_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_MAP, 0);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->success.size()));
- std::map<std::string, InternalOptionInfo> ::const_iterator _iter55;
- for (_iter55 = this->success.begin(); _iter55 != this->success.end(); ++_iter55)
- {
- xfer += oprot->writeString(_iter55->first);
- xfer += _iter55->second.write(oprot);
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_options_presult::~ExtensionManager_options_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_options_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- (*(this->success)).clear();
- uint32_t _size56;
- ::apache::thrift::protocol::TType _ktype57;
- ::apache::thrift::protocol::TType _vtype58;
- xfer += iprot->readMapBegin(_ktype57, _vtype58, _size56);
- uint32_t _i60;
- for (_i60 = 0; _i60 < _size56; ++_i60)
- {
- std::string _key61;
- xfer += iprot->readString(_key61);
- InternalOptionInfo& _val62 = (*(this->success))[_key61];
- xfer += _val62.read(iprot);
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-ExtensionManager_registerExtension_args::~ExtensionManager_registerExtension_args() throw() {
-}
-
-
-uint32_t ExtensionManager_registerExtension_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->info.read(iprot);
- this->__isset.info = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_MAP) {
- {
- this->registry.clear();
- uint32_t _size63;
- ::apache::thrift::protocol::TType _ktype64;
- ::apache::thrift::protocol::TType _vtype65;
- xfer += iprot->readMapBegin(_ktype64, _vtype65, _size63);
- uint32_t _i67;
- for (_i67 = 0; _i67 < _size63; ++_i67)
- {
- std::string _key68;
- xfer += iprot->readString(_key68);
- ExtensionRouteTable& _val69 = this->registry[_key68];
- {
- _val69.clear();
- uint32_t _size70;
- ::apache::thrift::protocol::TType _ktype71;
- ::apache::thrift::protocol::TType _vtype72;
- xfer += iprot->readMapBegin(_ktype71, _vtype72, _size70);
- uint32_t _i74;
- for (_i74 = 0; _i74 < _size70; ++_i74)
- {
- std::string _key75;
- xfer += iprot->readString(_key75);
- ExtensionPluginResponse& _val76 = _val69[_key75];
- {
- _val76.clear();
- uint32_t _size77;
- ::apache::thrift::protocol::TType _etype80;
- xfer += iprot->readListBegin(_etype80, _size77);
- _val76.resize(_size77);
- uint32_t _i81;
- for (_i81 = 0; _i81 < _size77; ++_i81)
- {
- {
- _val76[_i81].clear();
- uint32_t _size82;
- ::apache::thrift::protocol::TType _ktype83;
- ::apache::thrift::protocol::TType _vtype84;
- xfer += iprot->readMapBegin(_ktype83, _vtype84, _size82);
- uint32_t _i86;
- for (_i86 = 0; _i86 < _size82; ++_i86)
- {
- std::string _key87;
- xfer += iprot->readString(_key87);
- std::string& _val88 = _val76[_i81][_key87];
- xfer += iprot->readString(_val88);
- }
- xfer += iprot->readMapEnd();
- }
- }
- xfer += iprot->readListEnd();
- }
- }
- xfer += iprot->readMapEnd();
- }
- }
- xfer += iprot->readMapEnd();
- }
- this->__isset.registry = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_registerExtension_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_registerExtension_args");
-
- xfer += oprot->writeFieldBegin("info", ::apache::thrift::protocol::T_STRUCT, 1);
- xfer += this->info.write(oprot);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("registry", ::apache::thrift::protocol::T_MAP, 2);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_MAP, static_cast<uint32_t>(this->registry.size()));
- std::map<std::string, ExtensionRouteTable> ::const_iterator _iter89;
- for (_iter89 = this->registry.begin(); _iter89 != this->registry.end(); ++_iter89)
- {
- xfer += oprot->writeString(_iter89->first);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(_iter89->second.size()));
- std::map<std::string, ExtensionPluginResponse> ::const_iterator _iter90;
- for (_iter90 = _iter89->second.begin(); _iter90 != _iter89->second.end(); ++_iter90)
- {
- xfer += oprot->writeString(_iter90->first);
- {
- xfer += oprot->writeListBegin(::apache::thrift::protocol::T_MAP, static_cast<uint32_t>(_iter90->second.size()));
- std::vector<std::map<std::string, std::string> > ::const_iterator _iter91;
- for (_iter91 = _iter90->second.begin(); _iter91 != _iter90->second.end(); ++_iter91)
- {
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*_iter91).size()));
- std::map<std::string, std::string> ::const_iterator _iter92;
- for (_iter92 = (*_iter91).begin(); _iter92 != (*_iter91).end(); ++_iter92)
- {
- xfer += oprot->writeString(_iter92->first);
- xfer += oprot->writeString(_iter92->second);
- }
- xfer += oprot->writeMapEnd();
- }
- }
- xfer += oprot->writeListEnd();
- }
- }
- xfer += oprot->writeMapEnd();
- }
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_registerExtension_pargs::~ExtensionManager_registerExtension_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_registerExtension_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_registerExtension_pargs");
-
- xfer += oprot->writeFieldBegin("info", ::apache::thrift::protocol::T_STRUCT, 1);
- xfer += (*(this->info)).write(oprot);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("registry", ::apache::thrift::protocol::T_MAP, 2);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_MAP, static_cast<uint32_t>((*(this->registry)).size()));
- std::map<std::string, ExtensionRouteTable> ::const_iterator _iter93;
- for (_iter93 = (*(this->registry)).begin(); _iter93 != (*(this->registry)).end(); ++_iter93)
- {
- xfer += oprot->writeString(_iter93->first);
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_LIST, static_cast<uint32_t>(_iter93->second.size()));
- std::map<std::string, ExtensionPluginResponse> ::const_iterator _iter94;
- for (_iter94 = _iter93->second.begin(); _iter94 != _iter93->second.end(); ++_iter94)
- {
- xfer += oprot->writeString(_iter94->first);
- {
- xfer += oprot->writeListBegin(::apache::thrift::protocol::T_MAP, static_cast<uint32_t>(_iter94->second.size()));
- std::vector<std::map<std::string, std::string> > ::const_iterator _iter95;
- for (_iter95 = _iter94->second.begin(); _iter95 != _iter94->second.end(); ++_iter95)
- {
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*_iter95).size()));
- std::map<std::string, std::string> ::const_iterator _iter96;
- for (_iter96 = (*_iter95).begin(); _iter96 != (*_iter95).end(); ++_iter96)
- {
- xfer += oprot->writeString(_iter96->first);
- xfer += oprot->writeString(_iter96->second);
- }
- xfer += oprot->writeMapEnd();
- }
- }
- xfer += oprot->writeListEnd();
- }
- }
- xfer += oprot->writeMapEnd();
- }
- }
- xfer += oprot->writeMapEnd();
- }
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_registerExtension_result::~ExtensionManager_registerExtension_result() throw() {
-}
-
-
-uint32_t ExtensionManager_registerExtension_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_registerExtension_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_registerExtension_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_registerExtension_presult::~ExtensionManager_registerExtension_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_registerExtension_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-ExtensionManager_deregisterExtension_args::~ExtensionManager_deregisterExtension_args() throw() {
-}
-
-
-uint32_t ExtensionManager_deregisterExtension_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_I64) {
- xfer += iprot->readI64(this->uuid);
- this->__isset.uuid = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_deregisterExtension_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_deregisterExtension_args");
-
- xfer += oprot->writeFieldBegin("uuid", ::apache::thrift::protocol::T_I64, 1);
- xfer += oprot->writeI64(this->uuid);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_deregisterExtension_pargs::~ExtensionManager_deregisterExtension_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_deregisterExtension_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_deregisterExtension_pargs");
-
- xfer += oprot->writeFieldBegin("uuid", ::apache::thrift::protocol::T_I64, 1);
- xfer += oprot->writeI64((*(this->uuid)));
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_deregisterExtension_result::~ExtensionManager_deregisterExtension_result() throw() {
-}
-
-
-uint32_t ExtensionManager_deregisterExtension_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_deregisterExtension_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_deregisterExtension_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_deregisterExtension_presult::~ExtensionManager_deregisterExtension_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_deregisterExtension_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-ExtensionManager_query_args::~ExtensionManager_query_args() throw() {
-}
-
-
-uint32_t ExtensionManager_query_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->sql);
- this->__isset.sql = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_query_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_query_args");
-
- xfer += oprot->writeFieldBegin("sql", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString(this->sql);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_query_pargs::~ExtensionManager_query_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_query_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_query_pargs");
-
- xfer += oprot->writeFieldBegin("sql", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString((*(this->sql)));
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_query_result::~ExtensionManager_query_result() throw() {
-}
-
-
-uint32_t ExtensionManager_query_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_query_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_query_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_query_presult::~ExtensionManager_query_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_query_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-
-ExtensionManager_getQueryColumns_args::~ExtensionManager_getQueryColumns_args() throw() {
-}
-
-
-uint32_t ExtensionManager_getQueryColumns_args::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->sql);
- this->__isset.sql = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_getQueryColumns_args::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_getQueryColumns_args");
-
- xfer += oprot->writeFieldBegin("sql", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString(this->sql);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_getQueryColumns_pargs::~ExtensionManager_getQueryColumns_pargs() throw() {
-}
-
-
-uint32_t ExtensionManager_getQueryColumns_pargs::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionManager_getQueryColumns_pargs");
-
- xfer += oprot->writeFieldBegin("sql", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString((*(this->sql)));
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_getQueryColumns_result::~ExtensionManager_getQueryColumns_result() throw() {
-}
-
-
-uint32_t ExtensionManager_getQueryColumns_result::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->success.read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionManager_getQueryColumns_result::write(::apache::thrift::protocol::TProtocol* oprot) const {
-
- uint32_t xfer = 0;
-
- xfer += oprot->writeStructBegin("ExtensionManager_getQueryColumns_result");
-
- if (this->__isset.success) {
- xfer += oprot->writeFieldBegin("success", ::apache::thrift::protocol::T_STRUCT, 0);
- xfer += this->success.write(oprot);
- xfer += oprot->writeFieldEnd();
- }
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-
-ExtensionManager_getQueryColumns_presult::~ExtensionManager_getQueryColumns_presult() throw() {
-}
-
-
-uint32_t ExtensionManager_getQueryColumns_presult::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 0:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += (*(this->success)).read(iprot);
- this->__isset.success = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-void ExtensionManagerClient::extensions(InternalExtensionList& _return)
-{
- send_extensions();
- recv_extensions(_return);
-}
-
-void ExtensionManagerClient::send_extensions()
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("extensions", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_extensions_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_extensions(InternalExtensionList& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("extensions") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_extensions_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "extensions failed: unknown result");
-}
-
-void ExtensionManagerClient::options(InternalOptionList& _return)
-{
- send_options();
- recv_options(_return);
-}
-
-void ExtensionManagerClient::send_options()
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("options", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_options_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_options(InternalOptionList& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("options") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_options_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "options failed: unknown result");
-}
-
-void ExtensionManagerClient::registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry)
-{
- send_registerExtension(info, registry);
- recv_registerExtension(_return);
-}
-
-void ExtensionManagerClient::send_registerExtension(const InternalExtensionInfo& info, const ExtensionRegistry& registry)
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("registerExtension", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_registerExtension_pargs args;
- args.info = &info;
- args.registry = ®istry;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_registerExtension(ExtensionStatus& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("registerExtension") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_registerExtension_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "registerExtension failed: unknown result");
-}
-
-void ExtensionManagerClient::deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid)
-{
- send_deregisterExtension(uuid);
- recv_deregisterExtension(_return);
-}
-
-void ExtensionManagerClient::send_deregisterExtension(const ExtensionRouteUUID uuid)
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("deregisterExtension", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_deregisterExtension_pargs args;
- args.uuid = &uuid;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_deregisterExtension(ExtensionStatus& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("deregisterExtension") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_deregisterExtension_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "deregisterExtension failed: unknown result");
-}
-
-void ExtensionManagerClient::query(ExtensionResponse& _return, const std::string& sql)
-{
- send_query(sql);
- recv_query(_return);
-}
-
-void ExtensionManagerClient::send_query(const std::string& sql)
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("query", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_query_pargs args;
- args.sql = &sql;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_query(ExtensionResponse& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("query") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_query_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "query failed: unknown result");
-}
-
-void ExtensionManagerClient::getQueryColumns(ExtensionResponse& _return, const std::string& sql)
-{
- send_getQueryColumns(sql);
- recv_getQueryColumns(_return);
-}
-
-void ExtensionManagerClient::send_getQueryColumns(const std::string& sql)
-{
- int32_t cseqid = 0;
- oprot_->writeMessageBegin("getQueryColumns", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_getQueryColumns_pargs args;
- args.sql = &sql;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-}
-
-void ExtensionManagerClient::recv_getQueryColumns(ExtensionResponse& _return)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- iprot_->readMessageBegin(fname, mtype, rseqid);
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("getQueryColumns") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- ExtensionManager_getQueryColumns_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- return;
- }
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getQueryColumns failed: unknown result");
-}
-
-bool ExtensionManagerProcessor::dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext) {
- ProcessMap::iterator pfn;
- pfn = processMap_.find(fname);
- if (pfn == processMap_.end()) {
- return ExtensionProcessor::dispatchCall(iprot, oprot, fname, seqid, callContext);
- }
- (this->*(pfn->second))(seqid, iprot, oprot, callContext);
- return true;
-}
-
-void ExtensionManagerProcessor::process_extensions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.extensions", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.extensions");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.extensions");
- }
-
- ExtensionManager_extensions_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.extensions", bytes);
- }
-
- ExtensionManager_extensions_result result;
- try {
- iface_->extensions(result.success);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.extensions");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("extensions", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.extensions");
- }
-
- oprot->writeMessageBegin("extensions", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.extensions", bytes);
- }
-}
-
-void ExtensionManagerProcessor::process_options(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.options", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.options");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.options");
- }
-
- ExtensionManager_options_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.options", bytes);
- }
-
- ExtensionManager_options_result result;
- try {
- iface_->options(result.success);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.options");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("options", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.options");
- }
-
- oprot->writeMessageBegin("options", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.options", bytes);
- }
-}
-
-void ExtensionManagerProcessor::process_registerExtension(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.registerExtension", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.registerExtension");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.registerExtension");
- }
-
- ExtensionManager_registerExtension_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.registerExtension", bytes);
- }
-
- ExtensionManager_registerExtension_result result;
- try {
- iface_->registerExtension(result.success, args.info, args.registry);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.registerExtension");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("registerExtension", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.registerExtension");
- }
-
- oprot->writeMessageBegin("registerExtension", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.registerExtension", bytes);
- }
-}
-
-void ExtensionManagerProcessor::process_deregisterExtension(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.deregisterExtension", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.deregisterExtension");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.deregisterExtension");
- }
-
- ExtensionManager_deregisterExtension_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.deregisterExtension", bytes);
- }
-
- ExtensionManager_deregisterExtension_result result;
- try {
- iface_->deregisterExtension(result.success, args.uuid);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.deregisterExtension");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("deregisterExtension", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.deregisterExtension");
- }
-
- oprot->writeMessageBegin("deregisterExtension", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.deregisterExtension", bytes);
- }
-}
-
-void ExtensionManagerProcessor::process_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.query", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.query");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.query");
- }
-
- ExtensionManager_query_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.query", bytes);
- }
-
- ExtensionManager_query_result result;
- try {
- iface_->query(result.success, args.sql);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.query");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("query", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.query");
- }
-
- oprot->writeMessageBegin("query", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.query", bytes);
- }
-}
-
-void ExtensionManagerProcessor::process_getQueryColumns(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext)
-{
- void* ctx = NULL;
- if (this->eventHandler_.get() != NULL) {
- ctx = this->eventHandler_->getContext("ExtensionManager.getQueryColumns", callContext);
- }
- ::apache::thrift::TProcessorContextFreer freer(this->eventHandler_.get(), ctx, "ExtensionManager.getQueryColumns");
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preRead(ctx, "ExtensionManager.getQueryColumns");
- }
-
- ExtensionManager_getQueryColumns_args args;
- args.read(iprot);
- iprot->readMessageEnd();
- uint32_t bytes = iprot->getTransport()->readEnd();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postRead(ctx, "ExtensionManager.getQueryColumns", bytes);
- }
-
- ExtensionManager_getQueryColumns_result result;
- try {
- iface_->getQueryColumns(result.success, args.sql);
- result.__isset.success = true;
- } catch (const std::exception& e) {
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->handlerError(ctx, "ExtensionManager.getQueryColumns");
- }
-
- ::apache::thrift::TApplicationException x(e.what());
- oprot->writeMessageBegin("getQueryColumns", ::apache::thrift::protocol::T_EXCEPTION, seqid);
- x.write(oprot);
- oprot->writeMessageEnd();
- oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
- return;
- }
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->preWrite(ctx, "ExtensionManager.getQueryColumns");
- }
-
- oprot->writeMessageBegin("getQueryColumns", ::apache::thrift::protocol::T_REPLY, seqid);
- result.write(oprot);
- oprot->writeMessageEnd();
- bytes = oprot->getTransport()->writeEnd();
- oprot->getTransport()->flush();
-
- if (this->eventHandler_.get() != NULL) {
- this->eventHandler_->postWrite(ctx, "ExtensionManager.getQueryColumns", bytes);
- }
-}
-
-::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > ExtensionManagerProcessorFactory::getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) {
- ::apache::thrift::ReleaseHandler< ExtensionManagerIfFactory > cleanup(handlerFactory_);
- ::apache::thrift::stdcxx::shared_ptr< ExtensionManagerIf > handler(handlerFactory_->getHandler(connInfo), cleanup);
- ::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > processor(new ExtensionManagerProcessor(handler));
- return processor;
-}
-
-void ExtensionManagerConcurrentClient::extensions(InternalExtensionList& _return)
-{
- int32_t seqid = send_extensions();
- recv_extensions(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_extensions()
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("extensions", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_extensions_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_extensions(InternalExtensionList& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("extensions") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_extensions_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "extensions failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionManagerConcurrentClient::options(InternalOptionList& _return)
-{
- int32_t seqid = send_options();
- recv_options(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_options()
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("options", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_options_pargs args;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_options(InternalOptionList& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("options") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_options_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "options failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionManagerConcurrentClient::registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry)
-{
- int32_t seqid = send_registerExtension(info, registry);
- recv_registerExtension(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_registerExtension(const InternalExtensionInfo& info, const ExtensionRegistry& registry)
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("registerExtension", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_registerExtension_pargs args;
- args.info = &info;
- args.registry = ®istry;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_registerExtension(ExtensionStatus& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("registerExtension") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_registerExtension_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "registerExtension failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionManagerConcurrentClient::deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid)
-{
- int32_t seqid = send_deregisterExtension(uuid);
- recv_deregisterExtension(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_deregisterExtension(const ExtensionRouteUUID uuid)
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("deregisterExtension", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_deregisterExtension_pargs args;
- args.uuid = &uuid;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_deregisterExtension(ExtensionStatus& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("deregisterExtension") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_deregisterExtension_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "deregisterExtension failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionManagerConcurrentClient::query(ExtensionResponse& _return, const std::string& sql)
-{
- int32_t seqid = send_query(sql);
- recv_query(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_query(const std::string& sql)
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("query", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_query_pargs args;
- args.sql = &sql;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_query(ExtensionResponse& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("query") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_query_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "query failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-void ExtensionManagerConcurrentClient::getQueryColumns(ExtensionResponse& _return, const std::string& sql)
-{
- int32_t seqid = send_getQueryColumns(sql);
- recv_getQueryColumns(_return, seqid);
-}
-
-int32_t ExtensionManagerConcurrentClient::send_getQueryColumns(const std::string& sql)
-{
- int32_t cseqid = this->sync_.generateSeqId();
- ::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);
- oprot_->writeMessageBegin("getQueryColumns", ::apache::thrift::protocol::T_CALL, cseqid);
-
- ExtensionManager_getQueryColumns_pargs args;
- args.sql = &sql;
- args.write(oprot_);
-
- oprot_->writeMessageEnd();
- oprot_->getTransport()->writeEnd();
- oprot_->getTransport()->flush();
-
- sentry.commit();
- return cseqid;
-}
-
-void ExtensionManagerConcurrentClient::recv_getQueryColumns(ExtensionResponse& _return, const int32_t seqid)
-{
-
- int32_t rseqid = 0;
- std::string fname;
- ::apache::thrift::protocol::TMessageType mtype;
-
- // the read mutex gets dropped and reacquired as part of waitForWork()
- // The destructor of this sentry wakes up other clients
- ::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);
-
- while(true) {
- if(!this->sync_.getPending(fname, mtype, rseqid)) {
- iprot_->readMessageBegin(fname, mtype, rseqid);
- }
- if(seqid == rseqid) {
- if (mtype == ::apache::thrift::protocol::T_EXCEPTION) {
- ::apache::thrift::TApplicationException x;
- x.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- sentry.commit();
- throw x;
- }
- if (mtype != ::apache::thrift::protocol::T_REPLY) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
- }
- if (fname.compare("getQueryColumns") != 0) {
- iprot_->skip(::apache::thrift::protocol::T_STRUCT);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- // in a bad state, don't commit
- using ::apache::thrift::protocol::TProtocolException;
- throw TProtocolException(TProtocolException::INVALID_DATA);
- }
- ExtensionManager_getQueryColumns_presult result;
- result.success = &_return;
- result.read(iprot_);
- iprot_->readMessageEnd();
- iprot_->getTransport()->readEnd();
-
- if (result.__isset.success) {
- // _return pointer has now been filled
- sentry.commit();
- return;
- }
- // in a bad state, don't commit
- throw ::apache::thrift::TApplicationException(::apache::thrift::TApplicationException::MISSING_RESULT, "getQueryColumns failed: unknown result");
- }
- // seqid != rseqid
- this->sync_.updatePending(fname, mtype, rseqid);
-
- // this will temporarily unlock the readMutex, and let other clients get work done
- this->sync_.waitForWork(seqid);
- } // end while(true)
-}
-
-}} // namespace
-
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#ifndef ExtensionManager_H
-#define ExtensionManager_H
-
-#include <thrift/TDispatchProcessor.h>
-#include <thrift/async/TConcurrentClientSyncInfo.h>
-#include "osquery_types.h"
-#include "Extension.h"
-
-namespace osquery { namespace extensions {
-
-#ifdef _MSC_VER
- #pragma warning( push )
- #pragma warning (disable : 4250 ) //inheriting methods via dominance
-#endif
-
-class ExtensionManagerIf : virtual public ExtensionIf {
- public:
- virtual ~ExtensionManagerIf() {}
- virtual void extensions(InternalExtensionList& _return) = 0;
- virtual void options(InternalOptionList& _return) = 0;
- virtual void registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry) = 0;
- virtual void deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid) = 0;
- virtual void query(ExtensionResponse& _return, const std::string& sql) = 0;
- virtual void getQueryColumns(ExtensionResponse& _return, const std::string& sql) = 0;
-};
-
-class ExtensionManagerIfFactory : virtual public ExtensionIfFactory {
- public:
- typedef ExtensionManagerIf Handler;
-
- virtual ~ExtensionManagerIfFactory() {}
-
- virtual ExtensionManagerIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0;
- virtual void releaseHandler(ExtensionIf* /* handler */) = 0;
-};
-
-class ExtensionManagerIfSingletonFactory : virtual public ExtensionManagerIfFactory {
- public:
- ExtensionManagerIfSingletonFactory(const ::apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf>& iface) : iface_(iface) {}
- virtual ~ExtensionManagerIfSingletonFactory() {}
-
- virtual ExtensionManagerIf* getHandler(const ::apache::thrift::TConnectionInfo&) {
- return iface_.get();
- }
- virtual void releaseHandler(ExtensionIf* /* handler */) {}
-
- protected:
- ::apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> iface_;
-};
-
-class ExtensionManagerNull : virtual public ExtensionManagerIf , virtual public ExtensionNull {
- public:
- virtual ~ExtensionManagerNull() {}
- void extensions(InternalExtensionList& /* _return */) {
- return;
- }
- void options(InternalOptionList& /* _return */) {
- return;
- }
- void registerExtension(ExtensionStatus& /* _return */, const InternalExtensionInfo& /* info */, const ExtensionRegistry& /* registry */) {
- return;
- }
- void deregisterExtension(ExtensionStatus& /* _return */, const ExtensionRouteUUID /* uuid */) {
- return;
- }
- void query(ExtensionResponse& /* _return */, const std::string& /* sql */) {
- return;
- }
- void getQueryColumns(ExtensionResponse& /* _return */, const std::string& /* sql */) {
- return;
- }
-};
-
-
-class ExtensionManager_extensions_args {
- public:
-
- ExtensionManager_extensions_args(const ExtensionManager_extensions_args&);
- ExtensionManager_extensions_args& operator=(const ExtensionManager_extensions_args&);
- ExtensionManager_extensions_args() {
- }
-
- virtual ~ExtensionManager_extensions_args() throw();
-
- bool operator == (const ExtensionManager_extensions_args & /* rhs */) const
- {
- return true;
- }
- bool operator != (const ExtensionManager_extensions_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_extensions_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_extensions_pargs {
- public:
-
-
- virtual ~ExtensionManager_extensions_pargs() throw();
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_extensions_result__isset {
- _ExtensionManager_extensions_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_extensions_result__isset;
-
-class ExtensionManager_extensions_result {
- public:
-
- ExtensionManager_extensions_result(const ExtensionManager_extensions_result&);
- ExtensionManager_extensions_result& operator=(const ExtensionManager_extensions_result&);
- ExtensionManager_extensions_result() {
- }
-
- virtual ~ExtensionManager_extensions_result() throw();
- InternalExtensionList success;
-
- _ExtensionManager_extensions_result__isset __isset;
-
- void __set_success(const InternalExtensionList& val);
-
- bool operator == (const ExtensionManager_extensions_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_extensions_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_extensions_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_extensions_presult__isset {
- _ExtensionManager_extensions_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_extensions_presult__isset;
-
-class ExtensionManager_extensions_presult {
- public:
-
-
- virtual ~ExtensionManager_extensions_presult() throw();
- InternalExtensionList* success;
-
- _ExtensionManager_extensions_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-
-class ExtensionManager_options_args {
- public:
-
- ExtensionManager_options_args(const ExtensionManager_options_args&);
- ExtensionManager_options_args& operator=(const ExtensionManager_options_args&);
- ExtensionManager_options_args() {
- }
-
- virtual ~ExtensionManager_options_args() throw();
-
- bool operator == (const ExtensionManager_options_args & /* rhs */) const
- {
- return true;
- }
- bool operator != (const ExtensionManager_options_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_options_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_options_pargs {
- public:
-
-
- virtual ~ExtensionManager_options_pargs() throw();
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_options_result__isset {
- _ExtensionManager_options_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_options_result__isset;
-
-class ExtensionManager_options_result {
- public:
-
- ExtensionManager_options_result(const ExtensionManager_options_result&);
- ExtensionManager_options_result& operator=(const ExtensionManager_options_result&);
- ExtensionManager_options_result() {
- }
-
- virtual ~ExtensionManager_options_result() throw();
- InternalOptionList success;
-
- _ExtensionManager_options_result__isset __isset;
-
- void __set_success(const InternalOptionList& val);
-
- bool operator == (const ExtensionManager_options_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_options_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_options_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_options_presult__isset {
- _ExtensionManager_options_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_options_presult__isset;
-
-class ExtensionManager_options_presult {
- public:
-
-
- virtual ~ExtensionManager_options_presult() throw();
- InternalOptionList* success;
-
- _ExtensionManager_options_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-typedef struct _ExtensionManager_registerExtension_args__isset {
- _ExtensionManager_registerExtension_args__isset() : info(false), registry(false) {}
- bool info :1;
- bool registry :1;
-} _ExtensionManager_registerExtension_args__isset;
-
-class ExtensionManager_registerExtension_args {
- public:
-
- ExtensionManager_registerExtension_args(const ExtensionManager_registerExtension_args&);
- ExtensionManager_registerExtension_args& operator=(const ExtensionManager_registerExtension_args&);
- ExtensionManager_registerExtension_args() {
- }
-
- virtual ~ExtensionManager_registerExtension_args() throw();
- InternalExtensionInfo info;
- ExtensionRegistry registry;
-
- _ExtensionManager_registerExtension_args__isset __isset;
-
- void __set_info(const InternalExtensionInfo& val);
-
- void __set_registry(const ExtensionRegistry& val);
-
- bool operator == (const ExtensionManager_registerExtension_args & rhs) const
- {
- if (!(info == rhs.info))
- return false;
- if (!(registry == rhs.registry))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_registerExtension_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_registerExtension_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_registerExtension_pargs {
- public:
-
-
- virtual ~ExtensionManager_registerExtension_pargs() throw();
- const InternalExtensionInfo* info;
- const ExtensionRegistry* registry;
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_registerExtension_result__isset {
- _ExtensionManager_registerExtension_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_registerExtension_result__isset;
-
-class ExtensionManager_registerExtension_result {
- public:
-
- ExtensionManager_registerExtension_result(const ExtensionManager_registerExtension_result&);
- ExtensionManager_registerExtension_result& operator=(const ExtensionManager_registerExtension_result&);
- ExtensionManager_registerExtension_result() {
- }
-
- virtual ~ExtensionManager_registerExtension_result() throw();
- ExtensionStatus success;
-
- _ExtensionManager_registerExtension_result__isset __isset;
-
- void __set_success(const ExtensionStatus& val);
-
- bool operator == (const ExtensionManager_registerExtension_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_registerExtension_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_registerExtension_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_registerExtension_presult__isset {
- _ExtensionManager_registerExtension_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_registerExtension_presult__isset;
-
-class ExtensionManager_registerExtension_presult {
- public:
-
-
- virtual ~ExtensionManager_registerExtension_presult() throw();
- ExtensionStatus* success;
-
- _ExtensionManager_registerExtension_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-typedef struct _ExtensionManager_deregisterExtension_args__isset {
- _ExtensionManager_deregisterExtension_args__isset() : uuid(false) {}
- bool uuid :1;
-} _ExtensionManager_deregisterExtension_args__isset;
-
-class ExtensionManager_deregisterExtension_args {
- public:
-
- ExtensionManager_deregisterExtension_args(const ExtensionManager_deregisterExtension_args&);
- ExtensionManager_deregisterExtension_args& operator=(const ExtensionManager_deregisterExtension_args&);
- ExtensionManager_deregisterExtension_args() : uuid(0) {
- }
-
- virtual ~ExtensionManager_deregisterExtension_args() throw();
- ExtensionRouteUUID uuid;
-
- _ExtensionManager_deregisterExtension_args__isset __isset;
-
- void __set_uuid(const ExtensionRouteUUID val);
-
- bool operator == (const ExtensionManager_deregisterExtension_args & rhs) const
- {
- if (!(uuid == rhs.uuid))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_deregisterExtension_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_deregisterExtension_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_deregisterExtension_pargs {
- public:
-
-
- virtual ~ExtensionManager_deregisterExtension_pargs() throw();
- const ExtensionRouteUUID* uuid;
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_deregisterExtension_result__isset {
- _ExtensionManager_deregisterExtension_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_deregisterExtension_result__isset;
-
-class ExtensionManager_deregisterExtension_result {
- public:
-
- ExtensionManager_deregisterExtension_result(const ExtensionManager_deregisterExtension_result&);
- ExtensionManager_deregisterExtension_result& operator=(const ExtensionManager_deregisterExtension_result&);
- ExtensionManager_deregisterExtension_result() {
- }
-
- virtual ~ExtensionManager_deregisterExtension_result() throw();
- ExtensionStatus success;
-
- _ExtensionManager_deregisterExtension_result__isset __isset;
-
- void __set_success(const ExtensionStatus& val);
-
- bool operator == (const ExtensionManager_deregisterExtension_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_deregisterExtension_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_deregisterExtension_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_deregisterExtension_presult__isset {
- _ExtensionManager_deregisterExtension_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_deregisterExtension_presult__isset;
-
-class ExtensionManager_deregisterExtension_presult {
- public:
-
-
- virtual ~ExtensionManager_deregisterExtension_presult() throw();
- ExtensionStatus* success;
-
- _ExtensionManager_deregisterExtension_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-typedef struct _ExtensionManager_query_args__isset {
- _ExtensionManager_query_args__isset() : sql(false) {}
- bool sql :1;
-} _ExtensionManager_query_args__isset;
-
-class ExtensionManager_query_args {
- public:
-
- ExtensionManager_query_args(const ExtensionManager_query_args&);
- ExtensionManager_query_args& operator=(const ExtensionManager_query_args&);
- ExtensionManager_query_args() : sql() {
- }
-
- virtual ~ExtensionManager_query_args() throw();
- std::string sql;
-
- _ExtensionManager_query_args__isset __isset;
-
- void __set_sql(const std::string& val);
-
- bool operator == (const ExtensionManager_query_args & rhs) const
- {
- if (!(sql == rhs.sql))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_query_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_query_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_query_pargs {
- public:
-
-
- virtual ~ExtensionManager_query_pargs() throw();
- const std::string* sql;
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_query_result__isset {
- _ExtensionManager_query_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_query_result__isset;
-
-class ExtensionManager_query_result {
- public:
-
- ExtensionManager_query_result(const ExtensionManager_query_result&);
- ExtensionManager_query_result& operator=(const ExtensionManager_query_result&);
- ExtensionManager_query_result() {
- }
-
- virtual ~ExtensionManager_query_result() throw();
- ExtensionResponse success;
-
- _ExtensionManager_query_result__isset __isset;
-
- void __set_success(const ExtensionResponse& val);
-
- bool operator == (const ExtensionManager_query_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_query_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_query_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_query_presult__isset {
- _ExtensionManager_query_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_query_presult__isset;
-
-class ExtensionManager_query_presult {
- public:
-
-
- virtual ~ExtensionManager_query_presult() throw();
- ExtensionResponse* success;
-
- _ExtensionManager_query_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-typedef struct _ExtensionManager_getQueryColumns_args__isset {
- _ExtensionManager_getQueryColumns_args__isset() : sql(false) {}
- bool sql :1;
-} _ExtensionManager_getQueryColumns_args__isset;
-
-class ExtensionManager_getQueryColumns_args {
- public:
-
- ExtensionManager_getQueryColumns_args(const ExtensionManager_getQueryColumns_args&);
- ExtensionManager_getQueryColumns_args& operator=(const ExtensionManager_getQueryColumns_args&);
- ExtensionManager_getQueryColumns_args() : sql() {
- }
-
- virtual ~ExtensionManager_getQueryColumns_args() throw();
- std::string sql;
-
- _ExtensionManager_getQueryColumns_args__isset __isset;
-
- void __set_sql(const std::string& val);
-
- bool operator == (const ExtensionManager_getQueryColumns_args & rhs) const
- {
- if (!(sql == rhs.sql))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_getQueryColumns_args &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_getQueryColumns_args & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-
-class ExtensionManager_getQueryColumns_pargs {
- public:
-
-
- virtual ~ExtensionManager_getQueryColumns_pargs() throw();
- const std::string* sql;
-
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_getQueryColumns_result__isset {
- _ExtensionManager_getQueryColumns_result__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_getQueryColumns_result__isset;
-
-class ExtensionManager_getQueryColumns_result {
- public:
-
- ExtensionManager_getQueryColumns_result(const ExtensionManager_getQueryColumns_result&);
- ExtensionManager_getQueryColumns_result& operator=(const ExtensionManager_getQueryColumns_result&);
- ExtensionManager_getQueryColumns_result() {
- }
-
- virtual ~ExtensionManager_getQueryColumns_result() throw();
- ExtensionResponse success;
-
- _ExtensionManager_getQueryColumns_result__isset __isset;
-
- void __set_success(const ExtensionResponse& val);
-
- bool operator == (const ExtensionManager_getQueryColumns_result & rhs) const
- {
- if (!(success == rhs.success))
- return false;
- return true;
- }
- bool operator != (const ExtensionManager_getQueryColumns_result &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionManager_getQueryColumns_result & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
-};
-
-typedef struct _ExtensionManager_getQueryColumns_presult__isset {
- _ExtensionManager_getQueryColumns_presult__isset() : success(false) {}
- bool success :1;
-} _ExtensionManager_getQueryColumns_presult__isset;
-
-class ExtensionManager_getQueryColumns_presult {
- public:
-
-
- virtual ~ExtensionManager_getQueryColumns_presult() throw();
- ExtensionResponse* success;
-
- _ExtensionManager_getQueryColumns_presult__isset __isset;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
-
-};
-
-class ExtensionManagerClient : virtual public ExtensionManagerIf, public ExtensionClient {
- public:
- ExtensionManagerClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) :
- ExtensionClient(prot, prot) {}
- ExtensionManagerClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) : ExtensionClient(iprot, oprot) {}
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
- return piprot_;
- }
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
- return poprot_;
- }
- void extensions(InternalExtensionList& _return);
- void send_extensions();
- void recv_extensions(InternalExtensionList& _return);
- void options(InternalOptionList& _return);
- void send_options();
- void recv_options(InternalOptionList& _return);
- void registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry);
- void send_registerExtension(const InternalExtensionInfo& info, const ExtensionRegistry& registry);
- void recv_registerExtension(ExtensionStatus& _return);
- void deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid);
- void send_deregisterExtension(const ExtensionRouteUUID uuid);
- void recv_deregisterExtension(ExtensionStatus& _return);
- void query(ExtensionResponse& _return, const std::string& sql);
- void send_query(const std::string& sql);
- void recv_query(ExtensionResponse& _return);
- void getQueryColumns(ExtensionResponse& _return, const std::string& sql);
- void send_getQueryColumns(const std::string& sql);
- void recv_getQueryColumns(ExtensionResponse& _return);
-};
-
-class ExtensionManagerProcessor : public ExtensionProcessor {
- protected:
- ::apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> iface_;
- virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
- private:
- typedef void (ExtensionManagerProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
- typedef std::map<std::string, ProcessFunction> ProcessMap;
- ProcessMap processMap_;
- void process_extensions(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_options(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_registerExtension(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_deregisterExtension(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_query(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- void process_getQueryColumns(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
- public:
- ExtensionManagerProcessor(::apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> iface) :
- ExtensionProcessor(iface),
- iface_(iface) {
- processMap_["extensions"] = &ExtensionManagerProcessor::process_extensions;
- processMap_["options"] = &ExtensionManagerProcessor::process_options;
- processMap_["registerExtension"] = &ExtensionManagerProcessor::process_registerExtension;
- processMap_["deregisterExtension"] = &ExtensionManagerProcessor::process_deregisterExtension;
- processMap_["query"] = &ExtensionManagerProcessor::process_query;
- processMap_["getQueryColumns"] = &ExtensionManagerProcessor::process_getQueryColumns;
- }
-
- virtual ~ExtensionManagerProcessor() {}
-};
-
-class ExtensionManagerProcessorFactory : public ::apache::thrift::TProcessorFactory {
- public:
- ExtensionManagerProcessorFactory(const ::apache::thrift::stdcxx::shared_ptr< ExtensionManagerIfFactory >& handlerFactory) :
- handlerFactory_(handlerFactory) {}
-
- ::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);
-
- protected:
- ::apache::thrift::stdcxx::shared_ptr< ExtensionManagerIfFactory > handlerFactory_;
-};
-
-class ExtensionManagerMultiface : virtual public ExtensionManagerIf, public ExtensionMultiface {
- public:
- ExtensionManagerMultiface(std::vector<apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> >& ifaces) : ifaces_(ifaces) {
- std::vector<apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> >::iterator iter;
- for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {
- ExtensionMultiface::add(*iter);
- }
- }
- virtual ~ExtensionManagerMultiface() {}
- protected:
- std::vector<apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> > ifaces_;
- ExtensionManagerMultiface() {}
- void add(::apache::thrift::stdcxx::shared_ptr<ExtensionManagerIf> iface) {
- ExtensionMultiface::add(iface);
- ifaces_.push_back(iface);
- }
- public:
- void extensions(InternalExtensionList& _return) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->extensions(_return);
- }
- ifaces_[i]->extensions(_return);
- return;
- }
-
- void options(InternalOptionList& _return) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->options(_return);
- }
- ifaces_[i]->options(_return);
- return;
- }
-
- void registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->registerExtension(_return, info, registry);
- }
- ifaces_[i]->registerExtension(_return, info, registry);
- return;
- }
-
- void deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->deregisterExtension(_return, uuid);
- }
- ifaces_[i]->deregisterExtension(_return, uuid);
- return;
- }
-
- void query(ExtensionResponse& _return, const std::string& sql) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->query(_return, sql);
- }
- ifaces_[i]->query(_return, sql);
- return;
- }
-
- void getQueryColumns(ExtensionResponse& _return, const std::string& sql) {
- size_t sz = ifaces_.size();
- size_t i = 0;
- for (; i < (sz - 1); ++i) {
- ifaces_[i]->getQueryColumns(_return, sql);
- }
- ifaces_[i]->getQueryColumns(_return, sql);
- return;
- }
-
-};
-
-// The 'concurrent' client is a thread safe client that correctly handles
-// out of order responses. It is slower than the regular client, so should
-// only be used when you need to share a connection among multiple threads
-class ExtensionManagerConcurrentClient : virtual public ExtensionManagerIf, public ExtensionConcurrentClient {
- public:
- ExtensionManagerConcurrentClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) :
- ExtensionConcurrentClient(prot, prot) {}
- ExtensionManagerConcurrentClient(apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) : ExtensionConcurrentClient(iprot, oprot) {}
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {
- return piprot_;
- }
- apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {
- return poprot_;
- }
- void extensions(InternalExtensionList& _return);
- int32_t send_extensions();
- void recv_extensions(InternalExtensionList& _return, const int32_t seqid);
- void options(InternalOptionList& _return);
- int32_t send_options();
- void recv_options(InternalOptionList& _return, const int32_t seqid);
- void registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry);
- int32_t send_registerExtension(const InternalExtensionInfo& info, const ExtensionRegistry& registry);
- void recv_registerExtension(ExtensionStatus& _return, const int32_t seqid);
- void deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid);
- int32_t send_deregisterExtension(const ExtensionRouteUUID uuid);
- void recv_deregisterExtension(ExtensionStatus& _return, const int32_t seqid);
- void query(ExtensionResponse& _return, const std::string& sql);
- int32_t send_query(const std::string& sql);
- void recv_query(ExtensionResponse& _return, const int32_t seqid);
- void getQueryColumns(ExtensionResponse& _return, const std::string& sql);
- int32_t send_getQueryColumns(const std::string& sql);
- void recv_getQueryColumns(ExtensionResponse& _return, const int32_t seqid);
-};
-
-#ifdef _MSC_VER
- #pragma warning( pop )
-#endif
-
-}} // namespace
-
-#endif
+++ /dev/null
-// This autogenerated skeleton file illustrates how to build a server.
-// You should copy it to another filename to avoid overwriting it.
-
-#include "ExtensionManager.h"
-#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/server/TSimpleServer.h>
-#include <thrift/transport/TServerSocket.h>
-#include <thrift/transport/TBufferTransports.h>
-
-using namespace ::apache::thrift;
-using namespace ::apache::thrift::protocol;
-using namespace ::apache::thrift::transport;
-using namespace ::apache::thrift::server;
-
-using namespace ::osquery::extensions;
-
-class ExtensionManagerHandler : virtual public ExtensionManagerIf {
- public:
- ExtensionManagerHandler() {
- // Your initialization goes here
- }
-
- void extensions(InternalExtensionList& _return) {
- // Your implementation goes here
- printf("extensions\n");
- }
-
- void options(InternalOptionList& _return) {
- // Your implementation goes here
- printf("options\n");
- }
-
- void registerExtension(ExtensionStatus& _return, const InternalExtensionInfo& info, const ExtensionRegistry& registry) {
- // Your implementation goes here
- printf("registerExtension\n");
- }
-
- void deregisterExtension(ExtensionStatus& _return, const ExtensionRouteUUID uuid) {
- // Your implementation goes here
- printf("deregisterExtension\n");
- }
-
- void query(ExtensionResponse& _return, const std::string& sql) {
- // Your implementation goes here
- printf("query\n");
- }
-
- void getQueryColumns(ExtensionResponse& _return, const std::string& sql) {
- // Your implementation goes here
- printf("getQueryColumns\n");
- }
-
-};
-
-int main(int argc, char **argv) {
- int port = 9090;
- ::apache::thrift::stdcxx::shared_ptr<ExtensionManagerHandler> handler(new ExtensionManagerHandler());
- ::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new ExtensionManagerProcessor(handler));
- ::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
- ::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
- ::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
-
- TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
- server.serve();
- return 0;
-}
-
+++ /dev/null
-// This autogenerated skeleton file illustrates how to build a server.
-// You should copy it to another filename to avoid overwriting it.
-
-#include "Extension.h"
-#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/server/TSimpleServer.h>
-#include <thrift/transport/TServerSocket.h>
-#include <thrift/transport/TBufferTransports.h>
-
-using namespace ::apache::thrift;
-using namespace ::apache::thrift::protocol;
-using namespace ::apache::thrift::transport;
-using namespace ::apache::thrift::server;
-
-using namespace ::osquery::extensions;
-
-class ExtensionHandler : virtual public ExtensionIf {
- public:
- ExtensionHandler() {
- // Your initialization goes here
- }
-
- void ping(ExtensionStatus& _return) {
- // Your implementation goes here
- printf("ping\n");
- }
-
- void call(ExtensionResponse& _return, const std::string& registry, const std::string& item, const ExtensionPluginRequest& request) {
- // Your implementation goes here
- printf("call\n");
- }
-
- void shutdown() {
- // Your implementation goes here
- printf("shutdown\n");
- }
-
-};
-
-int main(int argc, char **argv) {
- int port = 9090;
- ::apache::thrift::stdcxx::shared_ptr<ExtensionHandler> handler(new ExtensionHandler());
- ::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new ExtensionProcessor(handler));
- ::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
- ::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
- ::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
-
- TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
- server.serve();
- return 0;
-}
-
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#include "osquery_constants.h"
-
-namespace osquery { namespace extensions {
-
-const osqueryConstants g_osquery_constants;
-
-osqueryConstants::osqueryConstants() {
-}
-
-}} // namespace
-
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#ifndef osquery_CONSTANTS_H
-#define osquery_CONSTANTS_H
-
-#include "osquery_types.h"
-
-namespace osquery { namespace extensions {
-
-class osqueryConstants {
- public:
- osqueryConstants();
-
-};
-
-extern const osqueryConstants g_osquery_constants;
-
-}} // namespace
-
-#endif
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#include "osquery_types.h"
-
-#include <algorithm>
-#include <ostream>
-
-#include <thrift/TToString.h>
-
-namespace osquery { namespace extensions {
-
-int _kExtensionCodeValues[] = {
- ExtensionCode::EXT_SUCCESS,
- ExtensionCode::EXT_FAILED,
- ExtensionCode::EXT_FATAL
-};
-const char* _kExtensionCodeNames[] = {
- "EXT_SUCCESS",
- "EXT_FAILED",
- "EXT_FATAL"
-};
-const std::map<int, const char*> _ExtensionCode_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(3, _kExtensionCodeValues, _kExtensionCodeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));
-
-std::ostream& operator<<(std::ostream& out, const ExtensionCode::type& val) {
- std::map<int, const char*>::const_iterator it = _ExtensionCode_VALUES_TO_NAMES.find(val);
- if (it != _ExtensionCode_VALUES_TO_NAMES.end()) {
- out << it->second;
- } else {
- out << static_cast<int>(val);
- }
- return out;
-}
-
-
-InternalOptionInfo::~InternalOptionInfo() throw() {
-}
-
-
-void InternalOptionInfo::__set_value(const std::string& val) {
- this->value = val;
-}
-
-void InternalOptionInfo::__set_default_value(const std::string& val) {
- this->default_value = val;
-}
-
-void InternalOptionInfo::__set_type(const std::string& val) {
- this->type = val;
-}
-std::ostream& operator<<(std::ostream& out, const InternalOptionInfo& obj)
-{
- obj.printTo(out);
- return out;
-}
-
-
-uint32_t InternalOptionInfo::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->value);
- this->__isset.value = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->default_value);
- this->__isset.default_value = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 3:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->type);
- this->__isset.type = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t InternalOptionInfo::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("InternalOptionInfo");
-
- xfer += oprot->writeFieldBegin("value", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString(this->value);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("default_value", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->default_value);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("type", ::apache::thrift::protocol::T_STRING, 3);
- xfer += oprot->writeString(this->type);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-void swap(InternalOptionInfo &a, InternalOptionInfo &b) {
- using ::std::swap;
- swap(a.value, b.value);
- swap(a.default_value, b.default_value);
- swap(a.type, b.type);
- swap(a.__isset, b.__isset);
-}
-
-InternalOptionInfo::InternalOptionInfo(const InternalOptionInfo& other0) {
- value = other0.value;
- default_value = other0.default_value;
- type = other0.type;
- __isset = other0.__isset;
-}
-InternalOptionInfo& InternalOptionInfo::operator=(const InternalOptionInfo& other1) {
- value = other1.value;
- default_value = other1.default_value;
- type = other1.type;
- __isset = other1.__isset;
- return *this;
-}
-void InternalOptionInfo::printTo(std::ostream& out) const {
- using ::apache::thrift::to_string;
- out << "InternalOptionInfo(";
- out << "value=" << to_string(value);
- out << ", " << "default_value=" << to_string(default_value);
- out << ", " << "type=" << to_string(type);
- out << ")";
-}
-
-
-InternalExtensionInfo::~InternalExtensionInfo() throw() {
-}
-
-
-void InternalExtensionInfo::__set_name(const std::string& val) {
- this->name = val;
-}
-
-void InternalExtensionInfo::__set_version(const std::string& val) {
- this->version = val;
-}
-
-void InternalExtensionInfo::__set_sdk_version(const std::string& val) {
- this->sdk_version = val;
-}
-
-void InternalExtensionInfo::__set_min_sdk_version(const std::string& val) {
- this->min_sdk_version = val;
-}
-std::ostream& operator<<(std::ostream& out, const InternalExtensionInfo& obj)
-{
- obj.printTo(out);
- return out;
-}
-
-
-uint32_t InternalExtensionInfo::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->name);
- this->__isset.name = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->version);
- this->__isset.version = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 3:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->sdk_version);
- this->__isset.sdk_version = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 4:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->min_sdk_version);
- this->__isset.min_sdk_version = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t InternalExtensionInfo::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("InternalExtensionInfo");
-
- xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 1);
- xfer += oprot->writeString(this->name);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("version", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->version);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("sdk_version", ::apache::thrift::protocol::T_STRING, 3);
- xfer += oprot->writeString(this->sdk_version);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("min_sdk_version", ::apache::thrift::protocol::T_STRING, 4);
- xfer += oprot->writeString(this->min_sdk_version);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-void swap(InternalExtensionInfo &a, InternalExtensionInfo &b) {
- using ::std::swap;
- swap(a.name, b.name);
- swap(a.version, b.version);
- swap(a.sdk_version, b.sdk_version);
- swap(a.min_sdk_version, b.min_sdk_version);
- swap(a.__isset, b.__isset);
-}
-
-InternalExtensionInfo::InternalExtensionInfo(const InternalExtensionInfo& other2) {
- name = other2.name;
- version = other2.version;
- sdk_version = other2.sdk_version;
- min_sdk_version = other2.min_sdk_version;
- __isset = other2.__isset;
-}
-InternalExtensionInfo& InternalExtensionInfo::operator=(const InternalExtensionInfo& other3) {
- name = other3.name;
- version = other3.version;
- sdk_version = other3.sdk_version;
- min_sdk_version = other3.min_sdk_version;
- __isset = other3.__isset;
- return *this;
-}
-void InternalExtensionInfo::printTo(std::ostream& out) const {
- using ::apache::thrift::to_string;
- out << "InternalExtensionInfo(";
- out << "name=" << to_string(name);
- out << ", " << "version=" << to_string(version);
- out << ", " << "sdk_version=" << to_string(sdk_version);
- out << ", " << "min_sdk_version=" << to_string(min_sdk_version);
- out << ")";
-}
-
-
-ExtensionStatus::~ExtensionStatus() throw() {
-}
-
-
-void ExtensionStatus::__set_code(const int32_t val) {
- this->code = val;
-}
-
-void ExtensionStatus::__set_message(const std::string& val) {
- this->message = val;
-}
-
-void ExtensionStatus::__set_uuid(const ExtensionRouteUUID val) {
- this->uuid = val;
-}
-std::ostream& operator<<(std::ostream& out, const ExtensionStatus& obj)
-{
- obj.printTo(out);
- return out;
-}
-
-
-uint32_t ExtensionStatus::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_I32) {
- xfer += iprot->readI32(this->code);
- this->__isset.code = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->message);
- this->__isset.message = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 3:
- if (ftype == ::apache::thrift::protocol::T_I64) {
- xfer += iprot->readI64(this->uuid);
- this->__isset.uuid = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionStatus::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionStatus");
-
- xfer += oprot->writeFieldBegin("code", ::apache::thrift::protocol::T_I32, 1);
- xfer += oprot->writeI32(this->code);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->message);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("uuid", ::apache::thrift::protocol::T_I64, 3);
- xfer += oprot->writeI64(this->uuid);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-void swap(ExtensionStatus &a, ExtensionStatus &b) {
- using ::std::swap;
- swap(a.code, b.code);
- swap(a.message, b.message);
- swap(a.uuid, b.uuid);
- swap(a.__isset, b.__isset);
-}
-
-ExtensionStatus::ExtensionStatus(const ExtensionStatus& other4) {
- code = other4.code;
- message = other4.message;
- uuid = other4.uuid;
- __isset = other4.__isset;
-}
-ExtensionStatus& ExtensionStatus::operator=(const ExtensionStatus& other5) {
- code = other5.code;
- message = other5.message;
- uuid = other5.uuid;
- __isset = other5.__isset;
- return *this;
-}
-void ExtensionStatus::printTo(std::ostream& out) const {
- using ::apache::thrift::to_string;
- out << "ExtensionStatus(";
- out << "code=" << to_string(code);
- out << ", " << "message=" << to_string(message);
- out << ", " << "uuid=" << to_string(uuid);
- out << ")";
-}
-
-
-ExtensionResponse::~ExtensionResponse() throw() {
-}
-
-
-void ExtensionResponse::__set_status(const ExtensionStatus& val) {
- this->status = val;
-}
-
-void ExtensionResponse::__set_response(const ExtensionPluginResponse& val) {
- this->response = val;
-}
-std::ostream& operator<<(std::ostream& out, const ExtensionResponse& obj)
-{
- obj.printTo(out);
- return out;
-}
-
-
-uint32_t ExtensionResponse::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_STRUCT) {
- xfer += this->status.read(iprot);
- this->__isset.status = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_LIST) {
- {
- this->response.clear();
- uint32_t _size6;
- ::apache::thrift::protocol::TType _etype9;
- xfer += iprot->readListBegin(_etype9, _size6);
- this->response.resize(_size6);
- uint32_t _i10;
- for (_i10 = 0; _i10 < _size6; ++_i10)
- {
- {
- this->response[_i10].clear();
- uint32_t _size11;
- ::apache::thrift::protocol::TType _ktype12;
- ::apache::thrift::protocol::TType _vtype13;
- xfer += iprot->readMapBegin(_ktype12, _vtype13, _size11);
- uint32_t _i15;
- for (_i15 = 0; _i15 < _size11; ++_i15)
- {
- std::string _key16;
- xfer += iprot->readString(_key16);
- std::string& _val17 = this->response[_i10][_key16];
- xfer += iprot->readString(_val17);
- }
- xfer += iprot->readMapEnd();
- }
- }
- xfer += iprot->readListEnd();
- }
- this->__isset.response = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionResponse::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionResponse");
-
- xfer += oprot->writeFieldBegin("status", ::apache::thrift::protocol::T_STRUCT, 1);
- xfer += this->status.write(oprot);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("response", ::apache::thrift::protocol::T_LIST, 2);
- {
- xfer += oprot->writeListBegin(::apache::thrift::protocol::T_MAP, static_cast<uint32_t>(this->response.size()));
- std::vector<std::map<std::string, std::string> > ::const_iterator _iter18;
- for (_iter18 = this->response.begin(); _iter18 != this->response.end(); ++_iter18)
- {
- {
- xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>((*_iter18).size()));
- std::map<std::string, std::string> ::const_iterator _iter19;
- for (_iter19 = (*_iter18).begin(); _iter19 != (*_iter18).end(); ++_iter19)
- {
- xfer += oprot->writeString(_iter19->first);
- xfer += oprot->writeString(_iter19->second);
- }
- xfer += oprot->writeMapEnd();
- }
- }
- xfer += oprot->writeListEnd();
- }
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-void swap(ExtensionResponse &a, ExtensionResponse &b) {
- using ::std::swap;
- swap(a.status, b.status);
- swap(a.response, b.response);
- swap(a.__isset, b.__isset);
-}
-
-ExtensionResponse::ExtensionResponse(const ExtensionResponse& other20) {
- status = other20.status;
- response = other20.response;
- __isset = other20.__isset;
-}
-ExtensionResponse& ExtensionResponse::operator=(const ExtensionResponse& other21) {
- status = other21.status;
- response = other21.response;
- __isset = other21.__isset;
- return *this;
-}
-void ExtensionResponse::printTo(std::ostream& out) const {
- using ::apache::thrift::to_string;
- out << "ExtensionResponse(";
- out << "status=" << to_string(status);
- out << ", " << "response=" << to_string(response);
- out << ")";
-}
-
-
-ExtensionException::~ExtensionException() throw() {
-}
-
-
-void ExtensionException::__set_code(const int32_t val) {
- this->code = val;
-}
-
-void ExtensionException::__set_message(const std::string& val) {
- this->message = val;
-}
-
-void ExtensionException::__set_uuid(const ExtensionRouteUUID val) {
- this->uuid = val;
-}
-std::ostream& operator<<(std::ostream& out, const ExtensionException& obj)
-{
- obj.printTo(out);
- return out;
-}
-
-
-uint32_t ExtensionException::read(::apache::thrift::protocol::TProtocol* iprot) {
-
- ::apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
- uint32_t xfer = 0;
- std::string fname;
- ::apache::thrift::protocol::TType ftype;
- int16_t fid;
-
- xfer += iprot->readStructBegin(fname);
-
- using ::apache::thrift::protocol::TProtocolException;
-
-
- while (true)
- {
- xfer += iprot->readFieldBegin(fname, ftype, fid);
- if (ftype == ::apache::thrift::protocol::T_STOP) {
- break;
- }
- switch (fid)
- {
- case 1:
- if (ftype == ::apache::thrift::protocol::T_I32) {
- xfer += iprot->readI32(this->code);
- this->__isset.code = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 2:
- if (ftype == ::apache::thrift::protocol::T_STRING) {
- xfer += iprot->readString(this->message);
- this->__isset.message = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- case 3:
- if (ftype == ::apache::thrift::protocol::T_I64) {
- xfer += iprot->readI64(this->uuid);
- this->__isset.uuid = true;
- } else {
- xfer += iprot->skip(ftype);
- }
- break;
- default:
- xfer += iprot->skip(ftype);
- break;
- }
- xfer += iprot->readFieldEnd();
- }
-
- xfer += iprot->readStructEnd();
-
- return xfer;
-}
-
-uint32_t ExtensionException::write(::apache::thrift::protocol::TProtocol* oprot) const {
- uint32_t xfer = 0;
- ::apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
- xfer += oprot->writeStructBegin("ExtensionException");
-
- xfer += oprot->writeFieldBegin("code", ::apache::thrift::protocol::T_I32, 1);
- xfer += oprot->writeI32(this->code);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 2);
- xfer += oprot->writeString(this->message);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldBegin("uuid", ::apache::thrift::protocol::T_I64, 3);
- xfer += oprot->writeI64(this->uuid);
- xfer += oprot->writeFieldEnd();
-
- xfer += oprot->writeFieldStop();
- xfer += oprot->writeStructEnd();
- return xfer;
-}
-
-void swap(ExtensionException &a, ExtensionException &b) {
- using ::std::swap;
- swap(a.code, b.code);
- swap(a.message, b.message);
- swap(a.uuid, b.uuid);
- swap(a.__isset, b.__isset);
-}
-
-ExtensionException::ExtensionException(const ExtensionException& other22) : TException() {
- code = other22.code;
- message = other22.message;
- uuid = other22.uuid;
- __isset = other22.__isset;
-}
-ExtensionException& ExtensionException::operator=(const ExtensionException& other23) {
- code = other23.code;
- message = other23.message;
- uuid = other23.uuid;
- __isset = other23.__isset;
- return *this;
-}
-void ExtensionException::printTo(std::ostream& out) const {
- using ::apache::thrift::to_string;
- out << "ExtensionException(";
- out << "code=" << to_string(code);
- out << ", " << "message=" << to_string(message);
- out << ", " << "uuid=" << to_string(uuid);
- out << ")";
-}
-
-const char* ExtensionException::what() const throw() {
- try {
- std::stringstream ss;
- ss << "TException - service has thrown: " << *this;
- this->thriftTExceptionMessageHolder_ = ss.str();
- return this->thriftTExceptionMessageHolder_.c_str();
- } catch (const std::exception&) {
- return "TException - service has thrown: ExtensionException";
- }
-}
-
-}} // namespace
+++ /dev/null
-/**
- * Autogenerated by Thrift Compiler (0.11.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- * @generated
- */
-#ifndef osquery_TYPES_H
-#define osquery_TYPES_H
-
-#include <iosfwd>
-
-#include <thrift/Thrift.h>
-#include <thrift/TApplicationException.h>
-#include <thrift/TBase.h>
-#include <thrift/protocol/TProtocol.h>
-#include <thrift/transport/TTransport.h>
-
-#include <thrift/stdcxx.h>
-
-
-namespace osquery { namespace extensions {
-
-struct ExtensionCode {
- enum type {
- EXT_SUCCESS = 0,
- EXT_FAILED = 1,
- EXT_FATAL = 2
- };
-};
-
-extern const std::map<int, const char*> _ExtensionCode_VALUES_TO_NAMES;
-
-std::ostream& operator<<(std::ostream& out, const ExtensionCode::type& val);
-
-typedef std::map<std::string, std::string> ExtensionPluginRequest;
-
-typedef std::vector<std::map<std::string, std::string> > ExtensionPluginResponse;
-
-typedef std::map<std::string, class InternalOptionInfo> InternalOptionList;
-
-typedef int64_t ExtensionRouteUUID;
-
-typedef std::map<std::string, ExtensionPluginResponse> ExtensionRouteTable;
-
-typedef std::map<std::string, ExtensionRouteTable> ExtensionRegistry;
-
-typedef std::map<ExtensionRouteUUID, class InternalExtensionInfo> InternalExtensionList;
-
-class InternalOptionInfo;
-
-class InternalExtensionInfo;
-
-class ExtensionStatus;
-
-class ExtensionResponse;
-
-class ExtensionException;
-
-typedef struct _InternalOptionInfo__isset {
- _InternalOptionInfo__isset() : value(false), default_value(false), type(false) {}
- bool value :1;
- bool default_value :1;
- bool type :1;
-} _InternalOptionInfo__isset;
-
-class InternalOptionInfo : public virtual ::apache::thrift::TBase {
- public:
-
- InternalOptionInfo(const InternalOptionInfo&);
- InternalOptionInfo& operator=(const InternalOptionInfo&);
- InternalOptionInfo() : value(), default_value(), type() {
- }
-
- virtual ~InternalOptionInfo() throw();
- std::string value;
- std::string default_value;
- std::string type;
-
- _InternalOptionInfo__isset __isset;
-
- void __set_value(const std::string& val);
-
- void __set_default_value(const std::string& val);
-
- void __set_type(const std::string& val);
-
- bool operator == (const InternalOptionInfo & rhs) const
- {
- if (!(value == rhs.value))
- return false;
- if (!(default_value == rhs.default_value))
- return false;
- if (!(type == rhs.type))
- return false;
- return true;
- }
- bool operator != (const InternalOptionInfo &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const InternalOptionInfo & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
- virtual void printTo(std::ostream& out) const;
-};
-
-void swap(InternalOptionInfo &a, InternalOptionInfo &b);
-
-std::ostream& operator<<(std::ostream& out, const InternalOptionInfo& obj);
-
-typedef struct _InternalExtensionInfo__isset {
- _InternalExtensionInfo__isset() : name(false), version(false), sdk_version(false), min_sdk_version(false) {}
- bool name :1;
- bool version :1;
- bool sdk_version :1;
- bool min_sdk_version :1;
-} _InternalExtensionInfo__isset;
-
-class InternalExtensionInfo : public virtual ::apache::thrift::TBase {
- public:
-
- InternalExtensionInfo(const InternalExtensionInfo&);
- InternalExtensionInfo& operator=(const InternalExtensionInfo&);
- InternalExtensionInfo() : name(), version(), sdk_version(), min_sdk_version() {
- }
-
- virtual ~InternalExtensionInfo() throw();
- std::string name;
- std::string version;
- std::string sdk_version;
- std::string min_sdk_version;
-
- _InternalExtensionInfo__isset __isset;
-
- void __set_name(const std::string& val);
-
- void __set_version(const std::string& val);
-
- void __set_sdk_version(const std::string& val);
-
- void __set_min_sdk_version(const std::string& val);
-
- bool operator == (const InternalExtensionInfo & rhs) const
- {
- if (!(name == rhs.name))
- return false;
- if (!(version == rhs.version))
- return false;
- if (!(sdk_version == rhs.sdk_version))
- return false;
- if (!(min_sdk_version == rhs.min_sdk_version))
- return false;
- return true;
- }
- bool operator != (const InternalExtensionInfo &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const InternalExtensionInfo & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
- virtual void printTo(std::ostream& out) const;
-};
-
-void swap(InternalExtensionInfo &a, InternalExtensionInfo &b);
-
-std::ostream& operator<<(std::ostream& out, const InternalExtensionInfo& obj);
-
-typedef struct _ExtensionStatus__isset {
- _ExtensionStatus__isset() : code(false), message(false), uuid(false) {}
- bool code :1;
- bool message :1;
- bool uuid :1;
-} _ExtensionStatus__isset;
-
-class ExtensionStatus : public virtual ::apache::thrift::TBase {
- public:
-
- ExtensionStatus(const ExtensionStatus&);
- ExtensionStatus& operator=(const ExtensionStatus&);
- ExtensionStatus() : code(0), message(), uuid(0) {
- }
-
- virtual ~ExtensionStatus() throw();
- int32_t code;
- std::string message;
- ExtensionRouteUUID uuid;
-
- _ExtensionStatus__isset __isset;
-
- void __set_code(const int32_t val);
-
- void __set_message(const std::string& val);
-
- void __set_uuid(const ExtensionRouteUUID val);
-
- bool operator == (const ExtensionStatus & rhs) const
- {
- if (!(code == rhs.code))
- return false;
- if (!(message == rhs.message))
- return false;
- if (!(uuid == rhs.uuid))
- return false;
- return true;
- }
- bool operator != (const ExtensionStatus &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionStatus & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
- virtual void printTo(std::ostream& out) const;
-};
-
-void swap(ExtensionStatus &a, ExtensionStatus &b);
-
-std::ostream& operator<<(std::ostream& out, const ExtensionStatus& obj);
-
-typedef struct _ExtensionResponse__isset {
- _ExtensionResponse__isset() : status(false), response(false) {}
- bool status :1;
- bool response :1;
-} _ExtensionResponse__isset;
-
-class ExtensionResponse : public virtual ::apache::thrift::TBase {
- public:
-
- ExtensionResponse(const ExtensionResponse&);
- ExtensionResponse& operator=(const ExtensionResponse&);
- ExtensionResponse() {
- }
-
- virtual ~ExtensionResponse() throw();
- ExtensionStatus status;
- ExtensionPluginResponse response;
-
- _ExtensionResponse__isset __isset;
-
- void __set_status(const ExtensionStatus& val);
-
- void __set_response(const ExtensionPluginResponse& val);
-
- bool operator == (const ExtensionResponse & rhs) const
- {
- if (!(status == rhs.status))
- return false;
- if (!(response == rhs.response))
- return false;
- return true;
- }
- bool operator != (const ExtensionResponse &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionResponse & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
- virtual void printTo(std::ostream& out) const;
-};
-
-void swap(ExtensionResponse &a, ExtensionResponse &b);
-
-std::ostream& operator<<(std::ostream& out, const ExtensionResponse& obj);
-
-typedef struct _ExtensionException__isset {
- _ExtensionException__isset() : code(false), message(false), uuid(false) {}
- bool code :1;
- bool message :1;
- bool uuid :1;
-} _ExtensionException__isset;
-
-class ExtensionException : public ::apache::thrift::TException {
- public:
-
- ExtensionException(const ExtensionException&);
- ExtensionException& operator=(const ExtensionException&);
- ExtensionException() : code(0), message(), uuid(0) {
- }
-
- virtual ~ExtensionException() throw();
- int32_t code;
- std::string message;
- ExtensionRouteUUID uuid;
-
- _ExtensionException__isset __isset;
-
- void __set_code(const int32_t val);
-
- void __set_message(const std::string& val);
-
- void __set_uuid(const ExtensionRouteUUID val);
-
- bool operator == (const ExtensionException & rhs) const
- {
- if (!(code == rhs.code))
- return false;
- if (!(message == rhs.message))
- return false;
- if (!(uuid == rhs.uuid))
- return false;
- return true;
- }
- bool operator != (const ExtensionException &rhs) const {
- return !(*this == rhs);
- }
-
- bool operator < (const ExtensionException & ) const;
-
- uint32_t read(::apache::thrift::protocol::TProtocol* iprot);
- uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const;
-
- virtual void printTo(std::ostream& out) const;
- mutable std::string thriftTExceptionMessageHolder_;
- const char* what() const throw();
-};
-
-void swap(ExtensionException &a, ExtensionException &b);
-
-std::ostream& operator<<(std::ostream& out, const ExtensionException& obj);
-
-}} // namespace
-
-#endif
+++ /dev/null
-// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
-
-namespace cpp osquery.extensions
-namespace py osquery.extensions
-
-/// Registry operations use a registry name, plugin name, request/response.
-typedef map<string, string> ExtensionPluginRequest
-typedef list<map<string, string>> ExtensionPluginResponse
-
-/// Extensions should request osquery options to set active registries and
-/// bootstrap any config/logger plugins.
-struct InternalOptionInfo {
- 1:string value,
- 2:string default_value,
- 3:string type,
-}
-
-/// Each option (CLI flag) has a unique name.
-typedef map<string, InternalOptionInfo> InternalOptionList
-
-/// When communicating extension metadata, use a thrift-internal structure.
-struct InternalExtensionInfo {
- 1:string name,
- 2:string version,
- 3:string sdk_version,
- 4:string min_sdk_version,
-}
-
-/// Unique ID for each extension.
-typedef i64 ExtensionRouteUUID
-/// A map from each plugin name to its optional route information.
-typedef map<string, ExtensionPluginResponse> ExtensionRouteTable
-/// A map from each registry name.
-typedef map<string, ExtensionRouteTable> ExtensionRegistry
-/// A map from each extension's unique ID to its map of registries.
-typedef map<ExtensionRouteUUID, InternalExtensionInfo> InternalExtensionList
-
-enum ExtensionCode {
- EXT_SUCCESS = 0,
- EXT_FAILED = 1,
- EXT_FATAL = 2,
-}
-
-/// Most communication uses the Status return type.
-struct ExtensionStatus {
- 1:i32 code,
- 2:string message,
- /// Add a thrift Status parameter identifying the request/response.
- 3:ExtensionRouteUUID uuid,
-}
-
-struct ExtensionResponse {
- 1:ExtensionStatus status,
- 2:ExtensionPluginResponse response,
-}
-
-exception ExtensionException {
- 1:i32 code,
- 2:string message,
- 3:ExtensionRouteUUID uuid,
-}
-
-service Extension {
- /// Ping to/from an extension and extension manager for metadata.
- ExtensionStatus ping(),
- /// Call an extension (or core) registry plugin.
- ExtensionResponse call(
- /// The registry name (e.g., config, logger, table, etc).
- 1:string registry,
- /// The registry item name (plugin name).
- 2:string item,
- /// The thrift-equivalent of an osquery::PluginRequest.
- 3:ExtensionPluginRequest request),
- /// Request that an extension shutdown (does not apply to managers).
- void shutdown(),
-}
-
-/// The extension manager is run by the osquery core process.
-service ExtensionManager extends Extension {
- /// Return the list of active registered extensions.
- InternalExtensionList extensions(),
- /// Return the list of bootstrap or configuration options.
- InternalOptionList options(),
- /// The API endpoint used by an extension to register its plugins.
- ExtensionStatus registerExtension(
- 1:InternalExtensionInfo info,
- 2:ExtensionRegistry registry),
- ExtensionStatus deregisterExtension(
- 1:ExtensionRouteUUID uuid,
- ),
- /// Allow an extension to query using an SQL string.
- ExtensionResponse query(
- 1:string sql,
- ),
- /// Allow an extension to introspect into SQL used in a parsed query.
- ExtensionResponse getQueryColumns(
- 1:string sql,
- ),
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <osquery/core.h>
-#include <osquery/flags.h>
-#include <osquery/registry_interface.h>
-#include <osquery/plugins/sql.h>
-
-namespace osquery {
-
-DECLARE_string(extensions_socket);
-DECLARE_string(extensions_autoload);
-DECLARE_string(extensions_timeout);
-DECLARE_bool(disable_extensions);
-
-/// A millisecond internal applied to extension initialization.
-extern const size_t kExtensionInitializeLatency;
-
-/**
- * @brief Helper struct for managing extension metadata.
- *
- * This structure should match the members of Thrift's InternalExtensionInfo.
- */
-struct ExtensionInfo {
- std::string name;
- std::string version;
- std::string sdk_version;
- std::string min_sdk_version;
-};
-
-typedef std::map<RouteUUID, ExtensionInfo> ExtensionList;
-
-inline std::string getExtensionSocket(
- RouteUUID uuid, const std::string& path = FLAGS_extensions_socket) {
- return (uuid == 0) ? path : path + "." + std::to_string(uuid);
-}
-
-/// External (extensions) SQL implementation plugin provider for "sql" registry.
-class ExternalSQLPlugin : public SQLPlugin {
- public:
- Status query(const std::string& query,
- QueryData& results,
- bool use_cache = false) const override;
-
- Status getQueryTables(const std::string& query,
- std::vector<std::string>& tables) const override {
- static_cast<void>(query);
- static_cast<void>(tables);
- return Status::success();
- }
-
- Status getQueryColumns(const std::string& query,
- TableColumns& columns) const override;
-};
-
-/// 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);
-
-/// Ping an extension manager or extension.
-Status pingExtension(const std::string& path);
-
-/**
- * @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);
-
-/**
- * @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
- * path with file ownership equivalent or greater (root) than the osquery
- * process requesting autoload.
- */
-void loadExtensions();
-
-/**
- * @brief Load extensions from a delimited search path string.
- *
- * @param loadfile Path to file containing newline delimited file paths
- */
-Status loadExtensions(const std::string& loadfile);
-
-/**
- * @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 extension modules from a delimited search path string.
- *
- * @param loadfile Path to file containing newline delimited file paths
- */
-Status loadModules(const std::string& loadfile);
-
-/// Load all modules in a directory.
-Status loadModuleFile(const std::string& path);
-
-/**
- * @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.
- *
- * @param home to user's home directory.
- */
-void initShellSocket(const std::string& home);
-
-/**
- * @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.
-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);
-
-/// Internal startExtension implementation using a UNIX domain socket path.
-Status startExtension(const std::string& manager_path,
- const std::string& name,
- const std::string& version,
- const std::string& min_sdk_version,
- 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);
-}
namespace osquery {
-/// An extension or core's broadcast includes routes from every Registry.
-using RegistryBroadcast = std::map<std::string, RegistryRoutes>;
-
class RegistryFactory : private boost::noncopyable {
public:
/// Singleton accessor.
PluginRef plugin(const std::string& registry_name,
const std::string& item_name) const;
- /// Serialize this core or extension's registry.
- RegistryBroadcast getBroadcast();
-
- /// Add external registry items identified by a Route UUID.
- Status addBroadcast(const RouteUUID& uuid,
- const RegistryBroadcast& broadcast);
-
- /// Given an extension UUID remove all external registry items.
- Status removeBroadcast(const RouteUUID& uuid);
-
/// Adds an alias for an internal registry item. This registry will only
/// broadcast the alias name.
Status addAlias(const std::string& registry_name,
/// Get a list of the registry item names for a given registry.
std::vector<std::string> names(const std::string& registry_name) const;
- /// Get a list of the registered extension UUIDs.
- std::vector<RouteUUID> routeUUIDs() const;
-
/// Return the number of registries.
size_t count() const {
return registries_.size();
return allow_duplicates_;
}
- /// Set the registry external (such that internal events are forwarded).
- /// Once set external, it should not be unset.
- void setExternal() {
- external_ = true;
- }
-
- /// Get the registry external status.
- bool external() {
- return external_;
- }
-
private:
/// Check if the registries are locked.
bool locked() {
/// The primary storage for constructed registries.
std::map<std::string, RegistryInterfaceRef> registries_;
- /**
- * @brief The registry tracks the set of active extension routes.
- *
- * If an extension dies (the process ends or does not respond to a ping),
- * the registry will be notified via the extension watcher.
- * When an operation requests to use that extension route the extension
- * manager will lazily check the registry for changes.
- */
- std::set<RouteUUID> extensions_;
-
- /// Calling startExtension should declare the registry external.
- /// This will cause extension-internal events to forward to osquery core.
- bool external_{false};
-
/// Protector for broadcast lookups and external registry mutations.
mutable Mutex mutex_;
class Status;
-using AddExternalCallback =
- std::function<Status(const std::string&, const PluginResponse&)>;
-
-using RemoveExternalCallback = std::function<void(const std::string&)>;
-
-/// Registry routes are a map of item name to each optional PluginReponse.
-using RegistryRoutes = std::map<std::string, PluginResponse>;
-
-using RouteUUID = uint64_t;
-
/**
* @brief This is the registry interface.
*/
/// Check if a given plugin name is considered internal.
bool isInternal(const std::string& item_name) const;
- /// Allow others to introspect into the routes from extensions.
- std::map<std::string, RouteUUID> getExternal() const;
-
/// Get the 'active' plugin, return success with the active plugin name.
std::string getActive() const;
/// Construct and return a map of plugin names to their implementation.
std::map<std::string, PluginRef> plugins();
- /**
- * @brief Create a routes table for this registry.
- *
- * This is called by the extensions API to allow an extension process to
- * broadcast each registry and the set of plugins (and their optional) route
- * information.
- *
- * The "table" registry and table plugins are the primary user of the route
- * information. Each plugin will include the SQL statement used to attach
- * an equivalent virtual table.
- */
- RegistryRoutes getRoutes() const;
-
protected:
/**
* @brief The only method a plugin user should call.
const PluginRequest& request,
PluginResponse& response);
- /**
- * @brief Add a set of item names broadcasted by an extension uuid.
- *
- * When an extension is registered the RegistryFactory will receive a
- * RegistryBroadcast containing a all of the extension's registry names and
- * the set of items with their optional route info. The factory depends on
- * each registry to manage calls/requests to these external plugins.
- *
- * @param uuid The uuid chosen for the extension.
- * @param routes The plugin name and optional route info list.
- * @return Success if all routes were added, failure if any failed.
- */
- Status addExternal(const RouteUUID& uuid, const RegistryRoutes& routes);
-
- /**
- * @brief Each RegistryType will include a trampoline into the PluginType.
- *
- * A PluginType may act on registry modifications. Each specialized registry
- * will include a trampoline method to call the plugin type's addExternal.
- *
- * @param name Plugin name (not the extension UUID).
- * @param info The route information broadcasted.
- */
- virtual Status addExternalPlugin(const std::string& name,
- const PluginResponse& info) const = 0;
-
- /// Remove all the routes for a given uuid.
- void removeExternal(const RouteUUID& uuid);
-
- /**
- * @brief Each RegistryType will include a trampoline into the PluginType.
- *
- * A PluginType may act on registry modifications. Each specialized registry
- * will include a trampoline method to call the plugin type's removeExternal.
- * @param name Plugin name (not the extension UUID).
- */
- virtual void removeExternalPlugin(const std::string& name) const = 0;
-
/// Allow the registry to introspect into the registered name (for logging).
void setname(const std::string& name);
/// If aliases are used, a map of alias to item name.
std::map<std::string, std::string> aliases_;
- /// Keep a lookup of the external item name to assigned extension UUID.
- std::map<std::string, RouteUUID> external_;
-
- /// Keep a lookup of optional route info. The plugin may handle calls
- /// to external items differently.
- std::map<std::string, PluginResponse> routes_;
-
/// Keep a lookup of registry items that are blacklisted from broadcast.
std::vector<std::string> internal_;
public:
explicit RegistryType(const std::string& name, bool auto_setup = false)
- : RegistryInterface(name, auto_setup),
- add_(&PluginType::addExternal),
- remove_(&PluginType::removeExternal) {}
+ : RegistryInterface(name, auto_setup) {}
~RegistryType() override = default;
Status add(const std::string& plugin_name,
return items_.at(plugin_name);
}
- /// Trampoline function for calling the PluginType's addExternal.
- Status addExternalPlugin(const std::string& name,
- const PluginResponse& info) const override {
- return add_(name, info);
- }
-
- /// Trampoline function for calling the PluginType's removeExternal.
- void removeExternalPlugin(const std::string& name) const override {
- remove_(name);
- }
-
- private:
- AddExternalCallback add_;
- RemoveExternalCallback remove_;
-
private:
FRIEND_TEST(EventsTests, test_event_subscriber_configure);
FRIEND_TEST(VirtualTableTests, test_indexing_costs);
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * 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
-
-#ifndef OSQUERY_BUILD_SDK
-#define OSQUERY_BUILD_SDK
-#endif
-
-#include <osquery/config.h>
-#include <osquery/core.h>
-#include <osquery/database.h>
-#include <osquery/events.h>
-#include <osquery/extensions.h>
-#include <osquery/filesystem.h>
-#include <osquery/flags.h>
-#include <osquery/hash.h>
-#include <osquery/logger.h>
-#include <osquery/registry.h>
-#include <osquery/sql.h>
-#include <osquery/status.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-/**
- * @brief Create the external SQLite implementation wrapper.
- *
- * Anything built with only libosquery and not the 'additional' library will
- * not include a native SQL implementation. This applies to extensions and
- * separate applications built with the osquery SDK.
- *
- * The ExternalSQLPlugin is a wrapper around the SQLite API, which forwards
- * calls to an osquery extension manager (core).
- */
-REGISTER_INTERNAL(ExternalSQLPlugin, "sql", "sql");
-
-/**
- * @brief Mimic the REGISTER macro, extensions should use this helper.
- *
- * The SDK does not provide a REGISTER macro for modules or extensions.
- * Tools built with the osquery SDK should use REGISTER_EXTERNAL to add to
- * their own 'external' registry. This registry will broadcast to the osquery
- * extension manager (core) in an extension.
- *
- * osquery 'modules' should not construct their plugin registrations in
- * global scope (global construction time). Instead they should use the
- * module call-in well defined symbol, declare their SDK constraints, then
- * use the REGISTER_MODULE call within `initModule`.
- */
-#define REGISTER_EXTERNAL(type, registry, name) \
- __attribute__((constructor)) static void type##ExtensionRegistryItem() { \
- Registry::add<type>(registry, name); \
- }
-
-/// Helper macro to write the `initModule` symbol without rewrites.
-#define DECLARE_MODULE(name) \
- extern "C" void initModule(void); \
- __attribute__((constructor)) static void declareModule()
-
-/**
- * @brief Create an osquery extension 'module'.
- *
- * This helper macro creates a constructor to declare an osquery module is
- * loading. The osquery registry is set up when modules (shared objects) are
- * discovered via search paths and opened. At that phase the registry is locked
- * meaning no additional plugins can be registered. To unlock the registry
- * for modifications a module must call Registry::declareModule. This declares
- * and any plugins added will use the metadata in the declare to determine:
- * - The name of the module adding the plugin
- * - The SDK version the module was built with, to determine compatibility
- * - The minimum SDK the module requires from osquery core
- *
- * The registry is again locked when the module load is complete and a well
- * known module-exported symbol is called.
- */
-#define CREATE_MODULE(name, version, min_sdk_version) \
- DECLARE_MODULE(name) { \
- Registry::declareModule( \
- name, version, min_sdk_version, OSQUERY_SDK_VERSION); \
- }
-
-/**
- * @brief Create an osquery extension 'module', if an expression is true.
- *
- * This is a helper testing wrapper around CREATE_MODULE and DECLARE_MODULE.
- * It allows unit and integration tests to generate global construction code
- * that depends on data/variables available during global construction.
- *
- * And example use includes checking if a process environment variable is
- * defined. If defined the module is declared.
- */
-#define CREATE_MODULE_IF(expr, name, version, min_sdk_version) \
- DECLARE_MODULE(name) { \
- if ((expr)) { \
- Registry::declareModule( \
- name, version, min_sdk_version, OSQUERY_SDK_VERSION); \
- } \
- }
-
-/// Helper replacement for REGISTER, used within extension modules.
-#define REGISTER_MODULE(type, registry, name) \
- auto type##ModuleRegistryItem = Registry::add<type>(registry, name)
-
-// Remove registry-helper macros from the SDK.
-#undef REGISTER
-#define REGISTER "Do not REGISTER in the osquery SDK"
-#undef REGISTER_INTERNAL
-#define REGISTER_INTERNAL "Do not REGISTER_INTERNAL in the osquery SDK"
-#undef CREATE_REGISTRY
-#define CREATE_REGISTRY "Do not CREATE_REGISTRY in the osquery SDK"
-#undef CREATE_LAZY_REGISTRY
-#define CREATE_LAZY_REGISTRY "Do not CREATE_LAZY_REGISTRY in the osquery SDK"
-}
UsedColumnsBitset usedColumnsToBitset(const UsedColumns usedColumns) const;
friend class RegistryFactory;
FRIEND_TEST(VirtualTableTests, test_tableplugin_columndefinition);
- FRIEND_TEST(VirtualTableTests, test_extension_tableplugin_columndefinition);
FRIEND_TEST(VirtualTableTests, test_tableplugin_statement);
FRIEND_TEST(VirtualTableTests, test_indexing_costs);
FRIEND_TEST(VirtualTableTests, test_table_results_cache);
#include <osquery/data_logger.h>
#include <osquery/database.h>
#include <osquery/events.h>
-#include <osquery/extensions.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
#include <osquery/killswitch.h>
#include <boost/algorithm/string/predicate.hpp>
#include <osquery/core.h>
-#include <osquery/core/watcher.h>
#include <osquery/database.h>
#include <osquery/devtools/devtools.h>
#include <osquery/dispatcher/scheduler.h>
-#include <osquery/extensions.h>
#include <osquery/filesystem/fileops.h>
#include <osquery/flags.h>
#include <osquery/logger.h>
DECLARE_bool(disable_caching);
-const std::string kWatcherWorkerName{"osqueryd: worker"};
-
int profile(int argc, char* argv[]) {
std::string query;
if (!osquery::platformIsatty(stdin)) {
// A query was set as a positional argument, via stdin, or profiling is on.
osquery::FLAGS_disable_events = true;
osquery::FLAGS_disable_caching = true;
- // The shell may have loaded table extensions, if not, disable the manager.
- if (!osquery::Watcher::get().hasManagedExtensions() &&
- Flag::isDefault("disable_extensions")) {
- osquery::FLAGS_disable_extensions = true;
- }
}
int retcode = 0;
runner.installShutdown(shutdown);
runner.initDaemon();
- // When a watchdog is used, the current daemon will fork/exec into a worker.
- // In either case the watcher may start optionally loaded extensions.
- runner.initWorkerWatcher(kWatcherWorkerName);
-
if (runner.isDaemon()) {
return startDaemon(runner);
}
return std::make_shared<PlatformProcess>(worker_pid);
}
-std::shared_ptr<PlatformProcess> PlatformProcess::launchExtension(
- const std::string& exec_path,
- const std::string& extensions_socket,
- const std::string& extensions_timeout,
- const std::string& extensions_interval,
- bool verbose) {
- auto ext_pid = ::fork();
- if (ext_pid < 0) {
- return std::shared_ptr<PlatformProcess>();
- } else if (ext_pid == 0) {
- setEnvVar("OSQUERY_EXTENSION", std::to_string(::getpid()).c_str());
-
- struct sigaction sig_action;
- sig_action.sa_handler = SIG_DFL;
- sig_action.sa_flags = 0;
- sigemptyset(&sig_action.sa_mask);
-
- for (auto i = NSIG; i >= 0; i--) {
- sigaction(i, &sig_action, nullptr);
- }
-
- std::vector<const char*> arguments;
- arguments.push_back(exec_path.c_str());
- arguments.push_back(exec_path.c_str());
-
- std::string arg_verbose("--verbose");
- if (verbose) {
- arguments.push_back(arg_verbose.c_str());
- }
-
- std::string arg_socket("--socket");
- arguments.push_back(arg_socket.c_str());
- arguments.push_back(extensions_socket.c_str());
-
- std::string arg_timeout("--timeout");
- arguments.push_back(arg_timeout.c_str());
- arguments.push_back(extensions_timeout.c_str());
-
- std::string arg_interval("--interval");
- arguments.push_back(arg_interval.c_str());
- arguments.push_back(extensions_interval.c_str());
- arguments.push_back(nullptr);
-
- char* const* argv = const_cast<char* const*>(&arguments[1]);
- ::execve(arguments[0], argv, ::environ);
-
- // Code should never reach this point
- LOG(ERROR) << "Could not start extension process: " << exec_path;
- ::exit(EXIT_FAILURE);
- return std::shared_ptr<PlatformProcess>();
- }
-
- return std::make_shared<PlatformProcess>(ext_pid);
-}
-
std::shared_ptr<PlatformProcess> PlatformProcess::launchTestPythonScript(
const std::string& args) {
std::string osquery_path;
const std::string& exec_path, int argc, char** argv);
/**
- * @brief Creates a new extension process.
- *
- * Launches a new extension with various options. Any double quotes in the
- * extension name will be stripped away.
- */
- static std::shared_ptr<PlatformProcess> launchExtension(
- const std::string& exec_path,
- const std::string& extensions_socket,
- const std::string& extensions_timeout,
- const std::string& extensions_interval,
- bool verbose = false);
-
- /**
* @brief Launches a new test Python script.
*
* This will launch a new Python process to run the specified script and
#include <boost/property_tree/json_parser.hpp>
-#include <osquery/extensions.h>
#include <osquery/logger.h>
#include <osquery/registry.h>
}
Status RegistryHelperCore::setActive(const std::string& item_name) {
- if (items_.count(item_name) == 0 && external_.count(item_name) == 0) {
+ if (items_.count(item_name) == 0) {
return Status(1, "Unknown registry item");
}
const std::string& RegistryHelperCore::getActive() const { return active_; }
-RegistryRoutes RegistryHelperCore::getRoutes() const {
- RegistryRoutes route_table;
- for (const auto& item : items_) {
- if (isInternal(item.first)) {
- // This is an internal plugin, do not include the route.
- continue;
- }
-
- bool has_alias = false;
- for (const auto& alias : aliases_) {
- if (alias.second == item.first) {
- // If the item name is masked by at least one alias, it will not
- // broadcast under the internal item name.
- route_table[alias.first] = item.second->routeInfo();
- has_alias = true;
- }
- }
-
- if (!has_alias) {
- route_table[item.first] = item.second->routeInfo();
- }
- }
- return route_table;
-}
-
Status RegistryHelperCore::call(const std::string& item_name,
const PluginRequest& request,
PluginResponse& response) {
return items_.at(item_name)->call(request, response);
}
- if (external_.count(item_name) > 0) {
- // The item is a registered extension, call the extension by UUID.
- return callExtension(external_.at(item_name), name_, item_name, request,
- response);
- } else if (routes_.count(item_name) > 0) {
- // The item has a route, but no extension, pass in the route info.
- response = routes_.at(item_name);
- return Status(0, "Route only");
- } else if (Registry::external()) {
- // If this is an extension's registry forward unknown calls to the core.
- return callExtension(0, name_, item_name, request, response);
- }
-
return Status(1, "Cannot call registry item: " + item_name);
}
/// Facility method to check if a registry item exists.
bool RegistryHelperCore::exists(const std::string& item_name,
bool local) const {
- bool has_local = (items_.count(item_name) > 0);
- bool has_external = (external_.count(item_name) > 0);
- bool has_route = (routes_.count(item_name) > 0);
- return (local) ? has_local : has_local || has_external || has_route;
+ return (items_.count(item_name) > 0);
}
/// Facility method to list the registry item identifiers.
names.push_back(item.first);
}
- // Also add names of external plugins.
- for (const auto& item : external_) {
- names.push_back(item.first);
- }
return names;
}
return instance().registry(registry_name)->get(item_name);
}
-RegistryBroadcast RegistryFactory::getBroadcast() {
- RegistryBroadcast broadcast;
- for (const auto& registry : instance().registries_) {
- broadcast[registry.first] = registry.second->getRoutes();
- }
- return broadcast;
-}
-
-Status RegistryFactory::addBroadcast(const RouteUUID& uuid,
- const RegistryBroadcast& broadcast) {
- if (instance().extensions_.count(uuid) > 0) {
- return Status(1, "Duplicate extension UUID: " + std::to_string(uuid));
- }
-
- // Make sure the extension does not broadcast conflicting registry items.
- if (!Registry::allowDuplicates()) {
- for (const auto& registry : broadcast) {
- for (const auto& item : registry.second) {
- if (Registry::exists(registry.first, item.first)) {
- VLOG(1) << "Extension " << uuid
- << " has duplicate plugin name: " << item.first
- << " in registry: " << registry.first;
- return Status(1, "Duplicate registry item: " + item.first);
- }
- }
- }
- }
-
- // Once duplication is satisfied call each registry's addExternal.
- Status status;
- for (const auto& registry : broadcast) {
- status = RegistryFactory::registry(registry.first)
- ->addExternal(uuid, registry.second);
- if (!status.ok()) {
- // If any registry fails to add the set of external routes, stop.
- break;
- }
-
- for (const auto& plugin : registry.second) {
- VLOG(1) << "Extension " << uuid << " registered " << registry.first
- << " plugin " << plugin.first;
- }
- }
-
- // If any registry failed, remove each (assume a broadcast is atomic).
- if (!status.ok()) {
- for (const auto& registry : broadcast) {
- Registry::registry(registry.first)->removeExternal(uuid);
- }
- }
- instance().extensions_.insert(uuid);
- return status;
-}
-
-Status RegistryFactory::removeBroadcast(const RouteUUID& uuid) {
- if (instance().extensions_.count(uuid) == 0) {
- return Status(1, "Unknown extension UUID: " + std::to_string(uuid));
- }
-
- for (const auto& registry : instance().registries_) {
- registry.second->removeExternal(uuid);
- }
- instance().extensions_.erase(uuid);
- return Status(0, "OK");
-}
-
/// Adds an alias for an internal registry item. This registry will only
/// broadcast the alias name.
Status RegistryFactory::addAlias(const std::string& registry_name,
return instance().registry(registry_name)->names();
}
-std::vector<RouteUUID> RegistryFactory::routeUUIDs() {
- std::vector<RouteUUID> uuids;
- for (const auto& extension : instance().extensions_) {
- uuids.push_back(extension);
- }
- return uuids;
-}
-
size_t RegistryFactory::count() { return instance().registries_.size(); }
size_t RegistryFactory::count(const std::string& registry_name) {
internal_.push_back(item_name);
}
- // The item may belong to a module.
- if (RegistryFactory::usingModule()) {
- modules_[item_name] = RegistryFactory::getModule();
- }
-
return Status(0, "OK");
}
-const std::map<RouteUUID, ModuleInfo>& RegistryFactory::getModules() {
- return instance().modules_;
-}
-
-RouteUUID RegistryFactory::getModule() { return instance().module_uuid_; }
-
-bool RegistryFactory::usingModule() {
- // Check if the registry is allowing a module's registrations.
- return (!instance().locked() && instance().module_uuid_ != 0);
-}
-
-void RegistryFactory::shutdownModule() {
- // TODO: [temporarily disable] should be check.
- //instance().locked(true);
- instance().module_uuid_ = 0;
-}
-
-void RegistryFactory::initModule(const std::string& path) {
- // Begin a module initialization, lock until the module is determined
- // appropriate by requesting a call to `declareModule`.
- instance().module_uuid_ = (RouteUUID)rand();
- instance().modules_[getModule()].path = path;
- instance().locked(true);
-}
-
-void RegistryFactory::declareModule(const std::string& name,
- const std::string& version,
- const std::string& min_sdk_version,
- const std::string& sdk_version) {
- // Check the min_sdk_version against the Registry's SDK version.
- auto& module = instance().modules_[instance().module_uuid_];
- module.name = name;
- module.version = version;
- module.sdk_version = sdk_version;
- instance().locked(false);
-}
-
-RegistryModuleLoader::RegistryModuleLoader(const std::string& path)
- : handle_(nullptr), path_(path) {
- // Tell the registry that we are attempting to construct a module.
- // Locking the registry prevents the module's global initialization from
- // adding or creating registry items.
- RegistryFactory::initModule(path_);
- handle_ = dlopen(path_.c_str(), RTLD_NOW | RTLD_LOCAL);
- if (handle_ == nullptr) {
- VLOG(1) << "Failed to load module: " << path_;
- VLOG(1) << dlerror();
- return;
- }
-
- // The module should have called RegistryFactory::declareModule and unlocked
- // the registry for modification. The module should have done this using
- // the SDK's CREATE_MODULE macro, which adds the global-scope constructor.
- if (RegistryFactory::locked()) {
- VLOG(1) << "Failed to declare module: " << path_;
- dlclose(handle_);
- handle_ = nullptr;
- }
-}
-
-void RegistryModuleLoader::init() {
- if (handle_ == nullptr || RegistryFactory::locked()) {
- handle_ = nullptr;
- return;
- }
-
- // Locate a well-known symbol in the module.
- // This symbol name is protected against rewriting when the module uses the
- // SDK's CREATE_MODULE macro.
- auto initializer = (ModuleInitalizer)dlsym(handle_, "initModule");
- if (initializer != nullptr) {
- initializer();
- VLOG(1) << "Initialized module: " << path_;
- } else {
- VLOG(1) << "Failed to initialize module: " << path_;
- VLOG(1) << dlerror();
- dlclose(handle_);
- handle_ = nullptr;
- }
-}
-
-RegistryModuleLoader::~RegistryModuleLoader() {
- if (handle_ == nullptr) {
- // The module was not loaded or did not initalize.
- RegistryFactory::instance().modules_.erase(RegistryFactory::getModule());
- }
-
- // We do not close the module, and thus are OK with losing a reference to the
- // module's handle. Attempting to close and clean up is very expensive for
- // very little value/features.
- if (!RegistryFactory::locked()) {
- RegistryFactory::shutdownModule();
- }
- // No need to clean this resource.
- handle_ = nullptr;
-}
-
void Plugin::getResponse(const std::string& key,
const PluginResponse& response,
boost::property_tree::ptree& tree) {
#include <cstdlib>
#include <sstream>
-#include <osquery/extensions.h>
#include <osquery/logger.h>
#include <osquery/process/process.h>
+#include <osquery/flags.h>
#include <osquery/registry.h>
#include <osquery/utils/conversions/split.h>
#include <osquery/utils/json/json.h>
return registry(registry_name)->plugin(item_name);
}
-RegistryBroadcast RegistryFactory::getBroadcast() {
- RegistryBroadcast broadcast;
- for (const auto& registry : registries_) {
- broadcast[registry.first] = registry.second->getRoutes();
- }
- return broadcast;
-}
-
-Status RegistryFactory::addBroadcast(const RouteUUID& uuid,
- const RegistryBroadcast& broadcast) {
- {
- ReadLock lock(mutex_);
- if (extensions_.count(uuid) > 0) {
- return Status(1, "Duplicate extension UUID: " + std::to_string(uuid));
- }
- }
-
- // Make sure the extension does not broadcast conflicting registry items.
- if (!allowDuplicates()) {
- for (const auto& registry : broadcast) {
- for (const auto& item : registry.second) {
- if (exists(registry.first, item.first)) {
- VLOG(1) << "Extension " << uuid
- << " has duplicate plugin name: " << item.first
- << " in registry: " << registry.first;
- return Status(1, "Duplicate registry item: " + item.first);
- }
- }
- }
- }
-
- // Once duplication is satisfied call each registry's addExternal.
- Status status;
- for (const auto& registry : broadcast) {
- if (!exists(registry.first)) {
- VLOG(1) << "Extension " << uuid
- << "contains unknown registry: " << registry.first;
- return Status(1, "Unknown registry: " + registry.first);
- }
-
- status = this->registry(registry.first)->addExternal(uuid, registry.second);
- if (!status.ok()) {
- // If any registry fails to add the set of external routes, stop.
- break;
- }
-
- for (const auto& plugin : registry.second) {
- VLOG(1) << "Extension " << uuid << " registered " << registry.first
- << " plugin " << plugin.first;
- }
- }
-
- // If any registry failed, remove each (assume a broadcast is atomic).
- {
- if (!status.ok()) {
- for (const auto& registry : broadcast) {
- this->registry(registry.first)->removeExternal(uuid);
- }
- }
-
- WriteLock lock(mutex_);
- extensions_.insert(uuid);
- }
- return status;
-}
-
-Status RegistryFactory::removeBroadcast(const RouteUUID& uuid) {
- {
- ReadLock lock(mutex_);
- if (extensions_.count(uuid) == 0) {
- return Status(1, "Unknown extension UUID: " + std::to_string(uuid));
- }
- }
-
- for (const auto& registry : registries_) {
- registry.second->removeExternal(uuid);
- }
-
- WriteLock lock(mutex_);
- extensions_.erase(uuid);
- return Status::success();
-}
-
/// Adds an alias for an internal registry item. This registry will only
/// broadcast the alias name.
Status RegistryFactory::addAlias(const std::string& registry_name,
return registry(registry_name)->names();
}
-std::vector<RouteUUID> RegistryFactory::routeUUIDs() const {
- ReadLock lock(mutex_);
- std::vector<RouteUUID> uuids;
- for (const auto& extension : extensions_) {
- uuids.push_back(extension);
- }
- return uuids;
-}
-
size_t RegistryFactory::count(const std::string& registry_name) const {
if (!exists(registry_name)) {
return 0;
* the LICENSE file found in the root directory of this source tree.
*/
-#include <osquery/extensions.h>
#include <osquery/registry_factory.h>
#include <osquery/registry_interface.h>
#include <osquery/utils/conversions/split.h>
return isInternal_(item_name);
}
-std::map<std::string, RouteUUID> RegistryInterface::getExternal() const {
- ReadLock lock(mutex_);
-
- return external_;
-}
-
std::string RegistryInterface::getActive() const {
ReadLock lock(mutex_);
// Default support multiple active plugins.
for (const auto& item : osquery::split(item_name, ",")) {
- if (items_.count(item) == 0 && external_.count(item) == 0) {
+ if (items_.count(item) == 0) {
return Status::failure("Unknown registry plugin: " + item);
}
}
for (const auto& item : osquery::split(item_name, ",")) {
if (exists_(item, true)) {
status = RegistryFactory::get().plugin(name_, item)->setUp();
- } else if (exists_(item, false) && !RegistryFactory::get().external()) {
- // If the active plugin is within an extension we must wait.
- // An extension will first broadcast the registry, then receive the list
- // of active plugins, active them if they are extension-local, and finally
- // start their extension socket.
- status = pingExtension(getExtensionSocket(external_.at(item)));
}
if (!status.ok()) {
return status;
}
-RegistryRoutes RegistryInterface::getRoutes() const {
- ReadLock lock(mutex_);
-
- RegistryRoutes route_table;
- for (const auto& item : items_) {
- if (isInternal_(item.first)) {
- // This is an internal plugin, do not include the route.
- continue;
- }
-
- bool has_alias = false;
- for (const auto& alias : aliases_) {
- if (alias.second == item.first) {
- // If the item name is masked by at least one alias, it will not
- // broadcast under the internal item name.
- route_table[alias.first] = item.second->routeInfo();
- has_alias = true;
- }
- }
-
- if (!has_alias) {
- route_table[item.first] = item.second->routeInfo();
- }
- }
- return route_table;
-}
-
Status RegistryInterface::call(const std::string& item_name,
const PluginRequest& request,
PluginResponse& response) {
return plugin->call(request, response);
}
- RouteUUID uuid;
- {
- ReadLock lock(mutex_);
-
- // Check if the item was broadcasted as a plugin within an extension.
- if (external_.count(item_name) > 0) {
- // The item is a registered extension, call the extension by UUID.
- uuid = external_.at(item_name);
- } else if (routes_.count(item_name) > 0) {
- // The item has a route, but no extension, pass in the route info.
- response = routes_.at(item_name);
- return Status::success();
- } else if (RegistryFactory::get().external()) {
- // If this is an extension's registry forward unknown calls to the core.
- uuid = 0;
- } else {
- return Status::failure("Cannot call registry item: " + item_name);
- }
- }
-
- return callExtension(uuid, name_, item_name, request, response);
+ return Status::failure("Unknown registry name: " + item_name);
}
Status RegistryInterface::addAlias(const std::string& item_name,
}
}
-Status RegistryInterface::addExternal(const RouteUUID& uuid,
- const RegistryRoutes& routes) {
- // Add each route name (item name) to the tracking.
- for (const auto& route : routes) {
- // Keep the routes info assigned to the registry.
- {
- WriteLock wlock(mutex_);
- routes_[route.first] = route.second;
- }
-
- auto status = addExternalPlugin(route.first, route.second);
-
- if (status.ok()) {
- WriteLock wlock(mutex_);
- external_[route.first] = uuid;
- } else {
- return status;
- }
- }
-
- return Status::success();
-}
-
-/// Remove all the routes for a given uuid.
-void RegistryInterface::removeExternal(const RouteUUID& uuid) {
- std::vector<std::string> removed_items;
-
- {
- ReadLock rlock(mutex_);
- // Create list of items to remove by filtering uuid
- for (const auto& item : external_) {
- if (item.second == uuid) {
- removed_items.push_back(item.first);
- }
- }
- }
-
- for (const auto& item : removed_items) {
- removeExternalPlugin(item);
- }
-
- {
- WriteLock wlock(mutex_);
- // Remove items belonging to the external uuid.
- for (const auto& item : removed_items) {
- external_.erase(item);
- routes_.erase(item);
- }
- }
-}
-
/// Facility method to check if a registry item exists.
bool RegistryInterface::exists(const std::string& item_name, bool local) const {
ReadLock lock(mutex_);
names.push_back(item.first);
}
- // Also add names of external plugins.
- for (const auto& item : external_) {
- names.push_back(item.first);
- }
return names;
}
bool RegistryInterface::exists_(const std::string& item_name,
bool local) const {
- bool has_local = (items_.count(item_name) > 0);
- bool has_external = (external_.count(item_name) > 0);
- bool has_route = (routes_.count(item_name) > 0);
- return (local) ? has_local : has_local || has_external || has_route;
+ return (items_.count(item_name) > 0);
}
AutoRegisterInterface::AutoRegisterInterface(const char* _type,
auto ri = TestCoreRegistry::get().plugin("widgets", "special")->routeInfo();
EXPECT_EQ(ri[0].at("name"), "special");
- auto rr = TestCoreRegistry::get().registry("widgets")->getRoutes();
- EXPECT_EQ(rr.size(), 1U);
- EXPECT_EQ(rr.at("special")[0].at("name"), "special");
-
- // Broadcast will include all registries, and all their items.
- auto broadcast_info = TestCoreRegistry::get().getBroadcast();
- EXPECT_TRUE(broadcast_info.size() >= 3U);
- EXPECT_EQ(broadcast_info.at("widgets").at("special")[0].at("name"),
- "special");
-
PluginResponse response;
PluginRequest request;
auto status = TestCoreRegistry::call("widgets", "special", request, response);
+++ /dev/null
-# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License
-
-ADD_OSQUERY_LINK(ssl
- z)
-
-ADD_OSQUERY_LIBRARY(osquery_remote http_client.cpp
- requests.cpp
- uri.cpp
- enroll/enroll.cpp
- enroll/tls_enroll.cpp
- serializers/json.cpp
- transports/tls.cpp)
-
-FILE(GLOB OSQUERY_REMOTE_TESTS "tests/*.cpp")
-FILE(GLOB OSQUERY_REMOTE_EXTRA_TESTS "*/tests/*.cpp")
-ADD_OSQUERY_TEST(${OSQUERY_REMOTE_TESTS}
- ${OSQUERY_REMOTE_EXTRA_TESTS})
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed as defined on the LICENSE file found in the
-# root directory of this source tree.
-
-load("//tools/build_defs/oss/osquery:cxx.bzl", "osquery_cxx_library", "osquery_cxx_test")
-load("//tools/build_defs/oss/osquery:native.bzl", "osquery_target")
-load("//tools/build_defs/oss/osquery:platforms.bzl", "MACOSX")
-load("//tools/build_defs/oss/osquery:third_party.bzl", "osquery_tp_target")
-
-osquery_cxx_library(
- name = "tls_enroll",
- srcs = [
- "enroll.cpp",
- "tls_enroll.cpp",
- ],
- header_namespace = "osquery/remote/enroll",
- exported_headers = [
- "tls_enroll.h",
- ],
- link_whole = True,
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/core:core"),
- osquery_target("osquery/process:process"),
- osquery_target("osquery/remote:http_client"),
- osquery_target("osquery/remote:requests"),
- osquery_target("osquery/remote/serializers:serializer_json"),
- osquery_target("osquery/remote/transports:transports_tls"),
- osquery_target("osquery/utils/json:json"),
- osquery_target("osquery/utils/system:time"),
- osquery_tp_target("boost"),
- ],
-)
-
-osquery_cxx_test(
- name = "remote_enroll_tests",
- srcs = [
- "tests/enroll_tests.cpp",
- ],
- env = {
- "TEST_CONF_FILES_DIR": "$(location {})".format(
- osquery_target("tools/tests:test_files"),
- ),
- },
- platform_srcs = [
- (
- MACOSX,
- ["tests/plugins/tls_enroll_tests.cpp"],
- ),
- ],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/config/tests:test_utils"),
- osquery_target("osquery/database:database"),
- osquery_target("osquery/events:events"),
- osquery_target("osquery/extensions:extensions"),
- osquery_target("osquery/extensions:impl_thrift"),
- osquery_target("osquery/process:process"),
- osquery_target("osquery/remote/enroll:tls_enroll"),
- osquery_target("osquery/remote/tests:remote_test_utils"),
- osquery_target("osquery/utils/conversions:conversions"),
- osquery_target("osquery/utils/info:info"),
- osquery_target("plugins/config:tls_config"),
- osquery_target("plugins/database:ephemeral"),
- osquery_target("plugins/killswitch:killswitch_filesystem"),
- osquery_target("tests:helper"),
- ],
-)
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed in accordance with the terms specified in
-# the LICENSE file found in the root directory of this source tree.
-
-function(osqueryRemoteEnrollTlsenrollMain)
- if(BUILD_TESTING)
- generateOsqueryRemoteenrolltestsTest()
- endif()
-
- generateOsqueryRemoteEnrollTlsenroll()
-endfunction()
-
-function(generateOsqueryRemoteEnrollTlsenroll)
- add_osquery_library(osquery_remote_enroll_tlsenroll EXCLUDE_FROM_ALL
- enroll.cpp
- tls_enroll.cpp
- )
-
- target_link_libraries(osquery_remote_enroll_tlsenroll PUBLIC
- global_cxx_settings
- osquery_core
- osquery_process
- osquery_remote_httpclient
- osquery_remote_requests
- osquery_remote_serializers_serializerjson
- osquery_remote_transports_transportstls
- osquery_utils_json
- osquery_utils_system_time
- thirdparty_boost
- )
-
- enableLinkWholeArchive(osquery_remote_enroll_tlsenroll)
-
- set(public_header_files
- tls_enroll.h
- )
-
- generateIncludeNamespace(osquery_remote_enroll_tlsenroll "osquery/remote/enroll" "FILE_ONLY" ${public_header_files})
-
- add_test(NAME osquery_remote_enroll_remoteenrolltests-test COMMAND osquery_remote_enroll_remoteenrolltests-test)
-
- set_tests_properties(
- osquery_remote_enroll_remoteenrolltests-test
- PROPERTIES ENVIRONMENT "TEST_CONF_FILES_DIR=${TEST_CONFIGS_DIR}"
- )
-endfunction()
-
-function(generateOsqueryRemoteenrolltestsTest)
-
- set(source_files
- tests/enroll_tests.cpp
- )
-
- if(DEFINED PLATFORM_MACOS)
- list(APPEND source_files tests/plugins/tls_enroll_tests.cpp)
- endif()
-
- add_osquery_executable(osquery_remote_enroll_remoteenrolltests-test ${source_files})
-
- target_link_libraries(osquery_remote_enroll_remoteenrolltests-test PRIVATE
- global_cxx_settings
- osquery_config_tests_testutils
- osquery_database
- osquery_events
- osquery_extensions
- osquery_extensions_implthrift
- osquery_process
- osquery_remote_enroll_tlsenroll
- osquery_remote_tests_remotetestutils
- osquery_utils_conversions
- osquery_utils_info
- plugins_config_tlsconfig
- plugins_database_ephemeral
- plugins_killswitch_killswitchfilesystem
- tests_helper
- thirdparty_googletest
- osquery_tools_tests_testfiles
- )
-endfunction()
-
-osqueryRemoteEnrollTlsenrollMain()
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/database.h>
-#include <osquery/enroll.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/flags.h>
-#include <osquery/process/process.h>
-#include <osquery/registry_factory.h>
-#include <osquery/sql.h>
-#include <osquery/utils/system/time.h>
-
-namespace osquery {
-
-/// At startup, always do a new enrollment instead of using a cached one
-CLI_FLAG(bool,
- enroll_always,
- false,
- "On startup, send a new enrollment request");
-
-/// Allow users to disable enrollment features.
-CLI_FLAG(bool,
- disable_enrollment,
- false,
- "Disable enrollment functions on related config/logger plugins");
-
-/// Path to optional enrollment secret data, sent with enrollment requests.
-CLI_FLAG(string,
- enroll_secret_path,
- "",
- "Path to an optional client enrollment-auth secret");
-
-/// Name of optional environment variable holding enrollment secret data.
-CLI_FLAG(string,
- enroll_secret_env,
- "",
- "Name of environment variable holding enrollment-auth secret");
-
-/// Allow users to disable reenrollment if a config/logger endpoint fails.
-CLI_FLAG(bool,
- disable_reenrollment,
- false,
- "Disable re-enrollment attempts if related plugins return invalid");
-
-/**
- * @brief Enroll plugin registry.
- *
- * This creates an osquery registry for "enroll" which may implement
- * EnrollPlugin. Only strings are logged in practice, and EnrollPlugin
- * provides a helper member for transforming PluginRequests to strings.
- */
-CREATE_LAZY_REGISTRY(EnrollPlugin, "enroll");
-
-const std::set<std::string> kEnrollHostDetails{
- "os_version", "osquery_info", "system_info", "platform_info",
-};
-
-Status clearNodeKey() {
- return deleteDatabaseValue(kPersistentSettings, "nodeKey");
-}
-
-std::string getNodeKey(const std::string& enroll_plugin) {
- std::string node_key;
- getDatabaseValue(kPersistentSettings, "nodeKey", node_key);
- if (node_key.size() > 0) {
- // A non-empty node key was found in the backing-store (cache).
- return node_key;
- }
-
- // The node key request time is recorded before the enroll request occurs.
- auto request_time = std::to_string(getUnixTime());
-
- // Request the enroll plugin's node secret.
- PluginResponse response;
- Registry::call("enroll", enroll_plugin, {{"action", "enroll"}}, response);
- if (response.size() > 0 && response[0].count("node_key") != 0) {
- node_key = response[0].at("node_key");
- setDatabaseValue(kPersistentSettings, "nodeKey", node_key);
- // Set the last time a nodeKey was requested from an enrollment endpoint.
- setDatabaseValue(kPersistentSettings, "nodeKeyTime", request_time);
- }
- return node_key;
-}
-
-const std::string getEnrollSecret() {
- std::string enrollment_secret;
-
- if (FLAGS_enroll_secret_path != "") {
- readFile(FLAGS_enroll_secret_path, enrollment_secret);
- boost::trim(enrollment_secret);
- } else {
- auto env_secret = getEnvVar(FLAGS_enroll_secret_env);
- if (env_secret.is_initialized()) {
- enrollment_secret = *env_secret;
- }
- }
-
- return enrollment_secret;
-}
-
-void EnrollPlugin::genHostDetails(JSON& host_details) {
- // Select from each table describing host details.
- for (const auto& table : kEnrollHostDetails) {
- auto results = SQL::selectAllFrom(table);
- if (!results.empty()) {
- JSON details;
- for (const auto& detail : results[0]) {
- details.add(detail.first, detail.second);
- }
- host_details.add(table, details.doc());
- }
- }
-}
-
-Status EnrollPlugin::call(const PluginRequest& request,
- PluginResponse& response) {
- if (FLAGS_disable_enrollment) {
- return Status::success();
- }
-
- // Only support the 'enroll' action.
- if (request.count("action") == 0 || request.at("action") != "enroll") {
- return Status(1, "Enroll plugins require an action");
- }
-
- // The 'enroll' API should return a string and implement caching.
- auto node_key = this->enroll();
- response.push_back({{"node_key", node_key}});
- if (node_key.size() == 0) {
- return Status(1, "No enrollment key found/retrieved");
- } else {
- return Status::success();
- }
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <gtest/gtest.h>
-
-#include <osquery/core.h>
-#include <osquery/database.h>
-#include <osquery/enroll.h>
-#include <osquery/filesystem/fileops.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/flags.h>
-#include <osquery/registry_factory.h>
-#include <osquery/system.h>
-
-#include "osquery/tests/test_util.h"
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-DECLARE_string(enroll_secret_path);
-DECLARE_bool(disable_database);
-
-class EnrollTests : public testing::Test {
- public:
- void SetUp() {
- Initializer::platformSetup();
- registryAndPluginInit();
- FLAGS_disable_database = true;
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
-
- deleteDatabaseValue(kPersistentSettings, "nodeKey");
- deleteDatabaseValue(kPersistentSettings, "nodeKeyTime");
- }
-};
-
-class SimpleEnrollPlugin : public EnrollPlugin {
- protected:
- std::string enroll() {
- return "fetched_a_node_key";
- }
-};
-
-// Register our simple enroll plugin.
-REGISTER(SimpleEnrollPlugin, "enroll", "test_simple");
-
-TEST_F(EnrollTests, test_enroll_secret_retrieval) {
- // Write an example secret (deploy key).
- FLAGS_enroll_secret_path =
- (fs::temp_directory_path() / "secret.txt").make_preferred().string();
- writeTextFile(FLAGS_enroll_secret_path,
- "test_secret\n",
- 0600,
- PF_CREATE_ALWAYS | PF_WRITE);
- // Make sure the file content was read and trimmed.
- auto secret = getEnrollSecret();
- EXPECT_EQ(secret, "test_secret");
-}
-
-TEST_F(EnrollTests, test_enroll_key_retrieval) {
- FLAGS_disable_enrollment = true;
- // Without enrollment, and with an empty nodeKey storage value, no node key
- // will be fetched or returned from cache.
- EXPECT_EQ(getNodeKey("test_simple"), "");
-
- // Turn the enrollment features back on and expect a key.
- FLAGS_disable_enrollment = false;
- EXPECT_EQ(getNodeKey("test_simple"), "fetched_a_node_key");
-}
-
-TEST_F(EnrollTests, test_enroll_key_caching) {
- // Cause a fetch of the node key.
- auto node_key = getNodeKey("test_simple");
-
- // Now fetch the time the node key was last cached from the database.
- std::string key_time;
- auto status = getDatabaseValue(kPersistentSettings, "nodeKeyTime", key_time);
- EXPECT_TRUE(status.ok());
-
- // A subsequent call to getNodeKey will return the same node key.
- // But, our simple enroll plugin is not enforcing any secret check and is
- // always returning the same node key.
- auto node_key2 = getNodeKey("test_simple");
- // In most scenarios subsequent calls to EnrollPlugin::enroll and the backing
- // enrollment service will generate and return different node keys.
- EXPECT_EQ(node_key2, node_key);
-
- // To work around our contrived example we make sure the node time was not
- // updated, meaning no call to EnrollPlugin::enroll occurred.
- std::string key_time2;
- getDatabaseValue(kPersistentSettings, "nodeKeyTime", key_time2);
- EXPECT_EQ(key_time2, key_time);
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include "osquery/remote/transports/tls.h"
-// clang-format on
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include <osquery/config/config.h>
-#include <osquery/database.h>
-#include <osquery/flags.h>
-#include <osquery/sql.h>
-#include <osquery/system.h>
-#include <osquery/registry_factory.h>
-
-#include "osquery/remote/requests.h"
-#include "osquery/remote/serializers/json.h"
-#include <osquery/remote/tests/test_utils.h>
-#include "osquery/tests/test_util.h"
-
-#include <osquery/remote/enroll/tls_enroll.h>
-
-namespace osquery {
-
-DECLARE_string(tls_hostname);
-DECLARE_bool(disable_database);
-
-class TLSEnrollTests : public testing::Test {
- protected:
- void SetUp() override;
- void TearDown() override;
-
- Status testReadRequests(JSON& response_tree);
-
- private:
- std::string test_read_uri_;
-};
-
-void TLSEnrollTests::SetUp() {
- Initializer::platformSetup();
- registryAndPluginInit();
- FLAGS_disable_database = true;
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
-
- // Start a server.
- TLSServerRunner::start();
- TLSServerRunner::setClientConfig();
- clearNodeKey();
-
- test_read_uri_ =
- "https://" + Flag::getValue("tls_hostname") + "/test_read_requests";
-}
-
-void TLSEnrollTests::TearDown() {
- // Stop the server.
- TLSServerRunner::unsetClientConfig();
- TLSServerRunner::stop();
-}
-
-Status TLSEnrollTests::testReadRequests(JSON& response_tree) {
- Request<TLSTransport, JSONSerializer> request_(test_read_uri_);
- request_.setOption("hostname", Flag::getValue("tls_hostname"));
- auto status = request_.call(JSON());
- if (status.ok()) {
- status = request_.getResponse(response_tree);
- } else {
- LOG(ERROR) << status.getMessage();
- }
- return status;
-}
-
-TEST_F(TLSEnrollTests, DISABLED_test_tls_enroll) {
- auto node_key = getNodeKey("tls");
-
- JSON response;
- std::string value;
-
- auto status = testReadRequests(response);
- ASSERT_TRUE(status.ok());
- ASSERT_TRUE(response.doc().IsArray());
- ASSERT_EQ(response.doc().Size(), 1U);
-
- auto const& obj = response.doc()[0];
- ASSERT_TRUE(obj.IsObject());
-
- ASSERT_TRUE(obj.HasMember("command"));
- ASSERT_TRUE(obj["command"].IsString());
- value = obj["command"].GetString();
- EXPECT_EQ(value, "enroll");
-
- ASSERT_TRUE(obj.HasMember("host_identifier"));
- ASSERT_TRUE(obj["host_identifier"].IsString());
- value = obj["host_identifier"].GetString();
- EXPECT_EQ(value, getHostIdentifier());
-
- ASSERT_EQ(kEnrollHostDetails.count("osquery_info"), 1U);
- auto osquery_info = SQL::selectAllFrom("osquery_info");
- ASSERT_EQ(osquery_info.size(), 1U);
- ASSERT_EQ(osquery_info[0].count("uuid"), 1U);
- ASSERT_TRUE(obj.HasMember("host_details"));
- ASSERT_TRUE(obj["host_details"].HasMember("osquery_info"));
- ASSERT_TRUE(obj["host_details"]["osquery_info"].HasMember("uuid"));
- ASSERT_TRUE(obj["host_details"]["osquery_info"]["uuid"].IsString());
- value = obj["host_details"]["osquery_info"]["uuid"].GetString();
- EXPECT_EQ(osquery_info[0]["uuid"], value);
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include <osquery/remote/transports/tls.h>
-// clang-format on
-
-#include "tls_enroll.h"
-
-#include <osquery/enroll.h>
-#include <osquery/flags.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-#include <osquery/sql.h>
-#include <osquery/system.h>
-
-#include <osquery/process/process.h>
-#include <osquery/remote/requests.h>
-#include <osquery/remote/serializers/json.h>
-#include <osquery/utils/info/platform_type.h>
-
-namespace osquery {
-
-DECLARE_string(enroll_secret_path);
-DECLARE_bool(disable_enrollment);
-
-CLI_FLAG(uint64,
- tls_enroll_max_attempts,
- 3,
- "Number of attempts to retry a TLS enroll request, it used to be the "
- "same as [config_tls_max_attempts]");
-
-/// Enrollment TLS endpoint (path) using TLS hostname.
-CLI_FLAG(string,
- enroll_tls_endpoint,
- "",
- "TLS/HTTPS endpoint for client enrollment");
-
-/// Undocumented feature for TLS access token passing.
-HIDDEN_FLAG(bool,
- tls_secret_always,
- false,
- "Include TLS enroll secret in every request");
-
-/// Undocumented feature to override TLS enrollment key name.
-HIDDEN_FLAG(string,
- tls_enroll_override,
- "enroll_secret",
- "Override the TLS enroll secret key name");
-
-std::string TLSEnrollPlugin::enroll() {
- // If no node secret has been negotiated, try a TLS request.
- auto uri = "https://" + FLAGS_tls_hostname + FLAGS_enroll_tls_endpoint;
- if (FLAGS_tls_secret_always) {
- uri += ((uri.find('?') != std::string::npos) ? '&' : '?') +
- FLAGS_tls_enroll_override + "=" + getEnrollSecret();
- }
-
- std::string node_key;
- VLOG(1) << "TLSEnrollPlugin requesting a node enroll key from: " << uri;
- for (size_t i = 1; i <= FLAGS_tls_enroll_max_attempts; i++) {
- auto status = requestKey(uri, node_key);
- if (status.ok() || i == FLAGS_tls_enroll_max_attempts) {
- break;
- }
-
- LOG(WARNING) << "Failed enrollment request to " << uri << " ("
- << status.what() << ") retrying...";
- sleepFor(i * i * 1000);
- }
-
- return node_key;
-}
-
-Status TLSEnrollPlugin::requestKey(const std::string& uri,
- std::string& node_key) {
- // Read the optional enrollment secret data (sent with an enrollment request).
- JSON params;
- params.add(FLAGS_tls_enroll_override, getEnrollSecret());
- params.add("host_identifier", getHostIdentifier());
- params.add("platform_type",
- std::to_string(static_cast<uint64_t>(kPlatformType)));
-
- // Select from each table describing host details.
- JSON host_details;
- genHostDetails(host_details);
- params.add("host_details", host_details.doc());
-
- Request<TLSTransport, JSONSerializer> request(uri);
- request.setOption("hostname", FLAGS_tls_hostname);
- auto status = request.call(params);
- if (!status.ok()) {
- return status;
- }
-
- // The call succeeded, store the node secret key (the enrollment response).
- JSON recv;
- status = request.getResponse(recv);
- if (!status.ok()) {
- return status;
- }
-
- // Support multiple response keys as a node key (identifier).
- auto it = recv.doc().FindMember("node_key");
- if (it == recv.doc().MemberEnd()) {
- it = recv.doc().FindMember("id");
- }
-
- if (it != recv.doc().MemberEnd()) {
- node_key = it->value.IsString() ? it->value.GetString() : "";
- }
-
- if (node_key.empty()) {
- return Status(1, "No node key returned from TLS enroll plugin");
- }
- return Status::success();
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <osquery/enroll.h>
-
-namespace osquery {
-
-class TLSEnrollPlugin : public EnrollPlugin {
- private:
- /// Enroll called, return cached key or if no key cached, call requestKey.
- std::string enroll() override;
-
- private:
- /// Request an enrollment key response from the TLS endpoint.
- Status requestKey(const std::string& uri, std::string& node_key);
-
- private:
- friend class TLSEnrollTests;
-};
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-// TODO(5591) Remove this when addressed by Boost's ASIO config.
-// https://www.boost.org/doc/libs/1_67_0/boost/asio/detail/config.hpp
-// Standard library support for std::string_view.
-#define BOOST_ASIO_DISABLE_STD_STRING_VIEW 1
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include <boost/asio.hpp>
-#include <osquery/remote/http_client.h>
-// clang-format on
-
-#include <osquery/logger.h>
-
-
-namespace osquery {
-namespace http {
-
-const std::string kHTTPSDefaultPort{"443"};
-const std::string kHTTPDefaultPort{"80"};
-const std::string kProxyDefaultPort{"3128"};
-
-const long kSSLShortReadError{0x140000dbL};
-
-/** This class is used to convert boost::system_exception
- * to std::system_exception, since on freebsd osquery is on boost-1.64.
- * Idea taken from boost-1.65
- */
-class adapted_category : public std::error_category {
- public:
- explicit adapted_category(boost::system::error_category const* pc)
- : pc_(pc) {}
-
- const char* name() const noexcept {
- return pc_->name();
- }
-
- std::string message(int ev) const {
- return pc_->message(ev);
- }
-
- private:
- boost::system::error_category const* pc_;
-};
-
-void Client::postResponseHandler(boost_system::error_code const& ec) {
- if ((ec.category() == boost_asio::error::ssl_category) &&
- (ec.value() == kSSLShortReadError)) {
- // Ignoring short read error, set ec_ to success.
- ec_.clear();
- // close connection for security reason.
- LOG(INFO) << "SSL SHORT_READ_ERROR: http_client closing socket";
- closeSocket();
- } else if ((ec.value() != boost_system::errc::operation_canceled) ||
- (ec.category() != boost_asio::error::system_category)) {
- ec_ = ec;
- }
-}
-
-void Client::closeSocket() {
- if (sock_.is_open()) {
- boost_system::error_code rc;
- sock_.shutdown(boost_asio::ip::tcp::socket::shutdown_both, rc);
- sock_.close(rc);
- }
-}
-
-void Client::timeoutHandler(boost_system::error_code const& ec) {
- if (!ec) {
- closeSocket();
- ec_ = boost_system::errc::make_error_code(boost_system::errc::timed_out);
- }
-}
-
-void Client::createConnection() {
- std::string port = (client_options_.proxy_hostname_)
- ? kProxyDefaultPort
- : *client_options_.remote_port_;
-
- std::string connect_host = (client_options_.proxy_hostname_)
- ? *client_options_.proxy_hostname_
- : *client_options_.remote_hostname_;
-
- std::size_t pos;
- if ((pos = connect_host.find(":")) != std::string::npos) {
- port = connect_host.substr(pos + 1);
- connect_host = connect_host.substr(0, pos);
- }
-
- boost_system::error_code rc;
- connect(sock_,
- r_.resolve(boost_asio::ip::tcp::resolver::query{connect_host, port}),
- rc);
-
- if (rc) {
- std::string error("Failed to connect to ");
- if (client_options_.proxy_hostname_) {
- error += "proxy host ";
- }
- error += connect_host + ":" + port;
- throw std::system_error(
- std::error_code(rc.value(), std::generic_category()), error);
- }
-
- if (client_options_.keep_alive_) {
- boost_asio::socket_base::keep_alive option(true);
- sock_.set_option(option);
- }
-
- if (client_options_.proxy_hostname_) {
- std::string remote_host = *client_options_.remote_hostname_;
- std::string remote_port = *client_options_.remote_port_;
-
- beast_http_request req;
- req.method(beast_http::verb::connect);
- req.target(remote_host + ":" + remote_port);
- req.version(11);
- req.prepare_payload();
- beast_http::write(sock_, req);
-
- boost::beast::flat_buffer b;
- beast_http_response_parser rp;
- rp.skip(true);
- beast_http::read_header(sock_, b, rp);
- if (beast_http::to_status_class(rp.get().result()) !=
- beast_http::status_class::successful) {
- throw std::runtime_error(rp.get().reason().data());
- }
- }
-}
-
-void Client::encryptConnection() {
- boost_asio::ssl::context ctx{boost_asio::ssl::context::sslv23};
-
- if (client_options_.always_verify_peer_) {
- ctx.set_verify_mode(boost_asio::ssl::verify_peer);
- } else {
- ctx.set_verify_mode(boost_asio::ssl::verify_none);
- }
-
- if (client_options_.server_certificate_) {
- ctx.set_verify_mode(boost_asio::ssl::verify_peer);
- ctx.load_verify_file(*client_options_.server_certificate_);
- }
-
- if (client_options_.verify_path_) {
- ctx.set_verify_mode(boost_asio::ssl::verify_peer);
- ctx.add_verify_path(*client_options_.verify_path_);
- }
-
- if (client_options_.ciphers_) {
- ::SSL_CTX_set_cipher_list(ctx.native_handle(),
- client_options_.ciphers_->c_str());
- }
-
- if (client_options_.ssl_options_) {
- ctx.set_options(client_options_.ssl_options_);
- }
-
- if (client_options_.client_certificate_file_) {
- ctx.use_certificate_file(*client_options_.client_certificate_file_,
- boost_asio::ssl::context::pem);
- }
-
- if (client_options_.client_private_key_file_) {
- ctx.use_private_key_file(*client_options_.client_private_key_file_,
- boost_asio::ssl::context::pem);
- }
-
- ssl_sock_ = std::make_shared<ssl_stream>(sock_, ctx);
- if (client_options_.sni_hostname_) {
- ::SSL_set_tlsext_host_name(ssl_sock_->native_handle(),
- client_options_.sni_hostname_->c_str());
- }
-
- boost_system::error_code rc;
- ssl_sock_->handshake(boost_asio::ssl::stream_base::client, rc);
-
- if (rc) {
- throw std::system_error(rc.value(), adapted_category(&rc.category()));
- }
-}
-
-template <typename STREAM_TYPE>
-void Client::sendRequest(STREAM_TYPE& stream,
- Request& req,
- beast_http_response_parser& resp) {
- req.target((req.remotePath()) ? *req.remotePath() : "/");
- req.version(11);
-
- if (req[beast_http::field::host].empty()) {
- std::string host_header_value = *client_options_.remote_hostname_;
- if (client_options_.ssl_connection_ &&
- (kHTTPSDefaultPort != *client_options_.remote_port_)) {
- host_header_value += ':' + *client_options_.remote_port_;
- } else if (!client_options_.ssl_connection_ &&
- kHTTPDefaultPort != *client_options_.remote_port_) {
- host_header_value += ':' + *client_options_.remote_port_;
- }
- req.set(beast_http::field::host, host_header_value);
- }
-
- req.prepare_payload();
- req.keep_alive(true);
-
- if (client_options_.timeout_) {
- timer_.async_wait(
- [=](boost_system::error_code const& ec) { timeoutHandler(ec); });
- }
-
- beast_http_request_serializer sr{req};
- beast_http::async_write(
- stream,
- sr,
- [&](boost_system::error_code const& ec, size_t bytes_transferred) {
- if (client_options_.timeout_) {
- timer_.cancel();
- }
-
- if ((ec.value() != boost_system::errc::operation_canceled) ||
- (ec.category() != boost_asio::error::system_category)) {
- ec_ = ec;
- }
- });
-
- {
- boost_system::error_code rc;
- ios_.run(rc);
- ios_.reset();
- if (rc) {
- ec_ = rc;
- }
- }
-
- if (ec_) {
- throw std::system_error(ec_.value(), adapted_category(&ec_.category()));
- }
-
- if (client_options_.timeout_) {
- timer_.async_wait(
- [=](boost_system::error_code const& ec) { timeoutHandler(ec); });
- }
-
- boost::beast::flat_buffer b;
- beast_http::async_read(
- stream,
- b,
- resp,
- [&](boost_system::error_code const& ec, size_t bytes_transferred) {
- if (client_options_.timeout_) {
- timer_.cancel();
- }
- postResponseHandler(ec);
- });
-
- {
- boost_system::error_code rc;
- ios_.run(rc);
- ios_.reset();
- if (rc) {
- ec_ = rc;
- }
- }
-
- if (ec_) {
- throw std::system_error(ec_.value(), adapted_category(&ec_.category()));
- }
-
- if (resp.get()["Connection"] == "close") {
- closeSocket();
- }
-}
-
-bool Client::initHTTPRequest(Request& req) {
- bool create_connection = true;
- if (req.remoteHost()) {
- std::string hostname = *req.remoteHost();
- std::string port;
-
- if (req.remotePort()) {
- port = *req.remotePort();
- } else if (req.protocol() && (*req.protocol()).compare("https") == 0) {
- port = kHTTPSDefaultPort;
- } else {
- port = kHTTPDefaultPort;
- }
-
- bool ssl_connection = false;
- if (req.protocol() && (*req.protocol()).compare("https") == 0) {
- ssl_connection = true;
- }
-
- if (!isSocketOpen() || new_client_options_ ||
- hostname != *client_options_.remote_hostname_ ||
- port != *client_options_.remote_port_ ||
- client_options_.ssl_connection_ != ssl_connection) {
- client_options_.remote_hostname_ = hostname;
- client_options_.remote_port_ = port;
- client_options_.ssl_connection_ = ssl_connection;
- new_client_options_ = false;
- closeSocket();
- } else {
- create_connection = false;
- }
- } else {
- if (!client_options_.remote_hostname_) {
- throw std::runtime_error("Remote hostname missing");
- }
-
- if (!client_options_.remote_port_) {
- if (client_options_.ssl_connection_) {
- client_options_.remote_port_ = kHTTPSDefaultPort;
- } else {
- client_options_.remote_port_ = kHTTPDefaultPort;
- }
- }
- closeSocket();
- }
- return create_connection;
-}
-
-Response Client::sendHTTPRequest(Request& req) {
- if (client_options_.timeout_) {
- timer_.expires_from_now(
- boost::posix_time::seconds(client_options_.timeout_));
- }
-
- bool retry_connect = false;
- do {
- bool create_connection = true;
- if (!retry_connect) {
- create_connection = initHTTPRequest(req);
- }
-
- try {
- beast_http_response_parser resp;
- if (create_connection) {
- createConnection();
-
- if (client_options_.ssl_connection_) {
- encryptConnection();
- }
- }
-
- if (client_options_.ssl_connection_) {
- sendRequest(*ssl_sock_, req, resp);
- } else {
- sendRequest(sock_, req, resp);
- }
-
- switch (resp.get().result()) {
- case beast_http::status::moved_permanently:
- case beast_http::status::found:
- case beast_http::status::see_other:
- case beast_http::status::not_modified:
- case beast_http::status::use_proxy:
- case beast_http::status::temporary_redirect:
- case beast_http::status::permanent_redirect: {
- if (!client_options_.follow_redirects_) {
- return Response(resp.release());
- }
-
- std::string redir_url = Response(resp.release()).headers()["Location"];
- if (!redir_url.size()) {
- throw std::runtime_error(
- "Location header missing in redirect response");
- }
-
- req.uri(redir_url);
- VLOG(1) << "HTTP(S) request re-directed to: " << redir_url;
- break;
- }
- default:
- return Response(resp.release());
- }
- } catch (std::exception const& /* e */) {
- closeSocket();
- if (!retry_connect) {
- retry_connect = true;
- } else {
- throw;
- }
- }
- } while (true);
-
- if (!client_options_.keep_alive_) {
- closeSocket();
- }
-}
-
-Response Client::put(Request& req,
- std::string const& body,
- std::string const& content_type) {
- req.method(beast_http::verb::put);
- req.body() = body;
- if (!content_type.empty()) {
- req.set(beast_http::field::content_type, content_type);
- }
- return sendHTTPRequest(req);
-}
-
-Response Client::post(Request& req,
- std::string const& body,
- std::string const& content_type) {
- req.method(beast_http::verb::post);
- req.body() = body;
- if (!content_type.empty()) {
- req.set(beast_http::field::content_type, content_type);
- }
- return sendHTTPRequest(req);
-}
-
-Response Client::put(Request& req,
- std::string&& body,
- std::string const& content_type) {
- req.method(beast_http::verb::put);
- req.body() = std::move(body);
- if (!content_type.empty()) {
- req.set(beast_http::field::content_type, content_type);
- }
- return sendHTTPRequest(req);
-}
-
-Response Client::post(Request& req,
- std::string&& body,
- std::string const& content_type) {
- req.method(beast_http::verb::post);
- req.body() = std::move(body);
- if (!content_type.empty()) {
- req.set(beast_http::field::content_type, content_type);
- }
- return sendHTTPRequest(req);
-}
-
-Response Client::get(Request& req) {
- req.method(beast_http::verb::get);
- return sendHTTPRequest(req);
-}
-
-Response Client::head(Request& req) {
- req.method(beast_http::verb::head);
- return sendHTTPRequest(req);
-}
-
-Response Client::delete_(Request& req) {
- req.method(beast_http::verb::delete_);
- return sendHTTPRequest(req);
-}
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#ifndef OPENSSL_NO_SSL2
-#define OPENSSL_NO_SSL2 1
-#endif
-
-#ifndef OPENSSL_NO_SSL3
-#define OPENSSL_NO_SSL3 1
-#endif
-
-#define OPENSSL_NO_MD5 1
-#define OPENSSL_NO_DEPRECATED 1
-
-// TODO(5591) Remove this when addressed by Boost's ASIO config.
-// https://www.boost.org/doc/libs/1_67_0/boost/asio/detail/config.hpp
-// Standard library support for std::string_view.
-#define BOOST_ASIO_DISABLE_STD_STRING_VIEW 1
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include <boost/asio/deadline_timer.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/ip/tcp.hpp>
-#include <boost/asio/ssl.hpp>
-// clang-format on
-
-#include <boost/beast/core.hpp>
-#include <boost/beast/http.hpp>
-#include <boost/optional/optional.hpp>
-
-#include <openssl/crypto.h>
-#include <openssl/ssl.h>
-
-#include <osquery/remote/uri.h>
-
-#include <osquery/logger.h>
-
-namespace boost_system = boost::system;
-namespace boost_asio = boost::asio;
-namespace beast_http = boost::beast::http;
-
-namespace osquery {
-namespace http {
-
-typedef boost_asio::ssl::stream<boost_asio::ip::tcp::socket&> ssl_stream;
-typedef beast_http::request<beast_http::string_body> beast_http_request;
-typedef beast_http::response<beast_http::string_body> beast_http_response;
-typedef beast_http::response_parser<beast_http::string_body>
- beast_http_response_parser;
-typedef beast_http::request_serializer<beast_http::string_body>
- beast_http_request_serializer;
-
-template <typename T>
-class HTTP_Request;
-template <typename T>
-class HTTP_Response;
-typedef HTTP_Request<beast_http_request> Request;
-typedef HTTP_Response<beast_http_response> Response;
-
-/**
- * @brief A simple HTTP client class based upon Boost.Beast.
- * This General-purpose HTTP Client allows HTTP and HTTPS.
- *
- * Implements put, post, get, head and delete methods.
- * These methods take request as reference and return response by value.
- *
- * This does not allow HTTP for the TLS logger plugins.
- * It uses a state variable `Options::ssl_connection_` to determine if the
- * connection
- * should be wrapped in a TLS socket.
- */
-class Client {
- public:
- /**
- * @brief Client options class.
- *
- * Behavior of the Client class is driven by its options.
- * E.g. secured client or non-secured client.
- * Or if the client will talk to server via proxy.
- */
- class Options {
- public:
- Options()
- : ssl_options_(0),
- timeout_(0),
- always_verify_peer_(false),
- follow_redirects_(false),
- keep_alive_(false),
- ssl_connection_(false) {}
-
- Options& ssl_connection(bool ct) {
- ssl_connection_ = ct;
- return *this;
- }
-
- Options& keep_alive(bool ka) {
- keep_alive_ = ka;
- return *this;
- }
-
- Options& follow_redirects(bool fr) {
- follow_redirects_ = fr;
- return *this;
- }
-
- Options& always_verify_peer(bool avp) {
- always_verify_peer_ = avp;
- return *this;
- }
-
- Options& timeout(int to) {
- timeout_ = to;
- return *this;
- }
-
- Options& openssl_ciphers(std::string const& ciphers) {
- ciphers_ = ciphers;
- return *this;
- }
-
- Options& openssl_options(long so) {
- ssl_options_ = so;
- return *this;
- }
-
- Options& openssl_verify_path(std::string const& vp) {
- verify_path_ = vp;
- return *this;
- }
-
- Options& openssl_certificate(std::string const& scf) {
- server_certificate_ = scf;
- return *this;
- }
-
- Options& openssl_certificate_file(std::string const& ccf) {
- client_certificate_file_ = ccf;
- return *this;
- }
-
- Options& openssl_private_key_file(std::string const& cpkf) {
- client_private_key_file_ = cpkf;
- return *this;
- }
-
- Options& openssl_sni_hostname(std::string const& sni_h) {
- sni_hostname_ = sni_h;
- return *this;
- }
-
- Options& proxy_hostname(std::string const& prxy_h) {
- proxy_hostname_ = prxy_h;
- return *this;
- }
-
- Options& remote_hostname(std::string const& remote_h) {
- remote_hostname_ = remote_h;
- return *this;
- }
-
- Options& remote_port(std::string const& remote_p) {
- remote_port_ = remote_p;
- return *this;
- }
-
- bool operator==(Options const& ropts) {
- return (server_certificate_ == ropts.server_certificate_) &&
- (verify_path_ == ropts.verify_path_) &&
- (client_certificate_file_ == ropts.client_certificate_file_) &&
- (client_private_key_file_ == ropts.client_private_key_file_) &&
- (ciphers_ == ropts.ciphers_) &&
- (sni_hostname_ == ropts.sni_hostname_) &&
- (ssl_options_ == ropts.ssl_options_) &&
- (always_verify_peer_ == ropts.always_verify_peer_) &&
- (proxy_hostname_ == ropts.proxy_hostname_) &&
- (keep_alive_ == ropts.keep_alive_);
- }
-
- private:
- boost::optional<std::string> server_certificate_;
- boost::optional<std::string> verify_path_;
- boost::optional<std::string> client_certificate_file_;
- boost::optional<std::string> client_private_key_file_;
- boost::optional<std::string> ciphers_;
- boost::optional<std::string> sni_hostname_;
- boost::optional<std::string> proxy_hostname_;
- boost::optional<std::string> remote_hostname_;
- boost::optional<std::string> remote_port_;
- long ssl_options_;
- int timeout_;
- bool always_verify_peer_;
- bool follow_redirects_;
- bool keep_alive_;
- bool ssl_connection_;
- friend class Client;
- };
-
- public:
- Client(Options const& opts = Options())
- : client_options_(opts), r_(ios_), sock_(ios_), timer_(ios_) {
-// Fix #4235, #5341: Boost on Windows requires notification that it should
-// let windows manage thread cleanup. *Do not remove this on Windows*
-#ifdef WIN32
- boost::asio::detail::win_thread::set_terminate_threads(true);
-#endif
- }
-
- void setOptions(Options const& opts) {
- new_client_options_ = !(client_options_ == opts);
- if (new_client_options_) {
- client_options_ = opts;
- }
- }
-
- /// HTTP put request method.
- Response put(Request& req,
- std::string const& body,
- std::string const& content_type = std::string());
-
- /// HTTP put request method with rvalue reference to body param.
- Response put(Request& req,
- std::string&& body,
- std::string const& content_type = std::string());
-
- /// HTTP post request method.
- Response post(Request& req,
- std::string const& body,
- std::string const& content_type = std::string());
-
- /// HTTP post request method with rvalue reference to body param.
- Response post(Request& req,
- std::string&& body,
- std::string const& content_type = std::string());
-
- /// HTTP get request method.
- Response get(Request& req);
-
- /// HTTP head request method.
- Response head(Request& req);
-
- /// HTTP delete_ request method.
- Response delete_(Request& req);
-
- ~Client() {
- closeSocket();
- }
-
- private:
- /// Create Connection to server, if proxy option is set, connect to proxy.
- void createConnection();
-
- /// Convert plain socket to TLS socket.
- void encryptConnection();
-
- template <typename STREAM_TYPE>
- void sendRequest(STREAM_TYPE& stream,
- Request& req,
- beast_http_response_parser& resp);
-
- bool initHTTPRequest(Request& req);
- Response sendHTTPRequest(Request& req);
-
- /// Handles HTTP request timeout.
- void timeoutHandler(boost_system::error_code const& ec);
-
- /**
- * @brief Handles response if requests completes or aborted due to timeout.
- *
- * In the postResponseHandler, treating SHORT_READ_ERROR as success for TLS
- * connections. This can happen if a remote server did not call shutdown on
- * the TLS connection.
- */
- void postResponseHandler(boost_system::error_code const& ec);
-
- bool isSocketOpen() {
- return sock_.is_open();
- }
-
- void closeSocket();
-
- private:
- Options client_options_;
- boost_asio::io_service ios_;
- boost_asio::ip::tcp::resolver r_;
- boost_asio::ip::tcp::socket sock_;
- boost_asio::deadline_timer timer_;
- std::shared_ptr<ssl_stream> ssl_sock_;
- boost_system::error_code ec_;
- bool new_client_options_{true};
-};
-
-/**
- * @brief HTTP request class.
- *
- * This class is inherited from implementation(boost.beast) request class.
- * It extends the functionality via providing URI parsing.
- *
- */
-template <typename T>
-class HTTP_Request : public T {
- public:
- /**
- * @brief HTTP request header helper class.
- *
- * Constructor of this class takes (name, value) pair, which is used to set
- * the request header of a HTTP request with the help of overloaded
- * function 'operator<<' of HTTP_Request class.
- */
- struct Header {
- Header(const std::string& name, const std::string& value)
- : name_(name), value_(value) {}
-
- private:
- std::string name_;
- std::string value_;
- friend class HTTP_Request<T>;
- };
-
- public:
- HTTP_Request(const std::string& url = std::string())
- : uri_(osquery::Uri(url)) {}
-
- /// Returns the host part of a URI.
- boost::optional<std::string> remoteHost() {
- return (!uri_.host().empty()) ? uri_.host()
- : boost::optional<std::string>();
- }
-
- /// Returns the port part of a URI.
- boost::optional<std::string> remotePort() {
- return (uri_.port() > 0) ? std::to_string(uri_.port())
- : boost::optional<std::string>();
- }
-
- /// Returns the path, query, and fragment parts of a URI.
- boost::optional<std::string> remotePath() {
- std::string path;
- if (!uri_.path().empty()) {
- path += uri_.path();
- }
-
- if (!uri_.query().empty()) {
- path += '?' + uri_.query();
- }
-
- if (!uri_.fragment().empty()) {
- path += '#' + uri_.fragment();
- }
- return (!path.empty()) ? path : boost::optional<std::string>();
- }
-
- /// Returns the protocol part of a URI. E.g. 'http' or 'https'
- boost::optional<std::string> protocol() {
- return uri_.scheme().size() ? uri_.scheme()
- : boost::optional<std::string>();
- }
-
- /// overloaded operator to set header of a HTTP request
- HTTP_Request& operator<<(const Header& h) {
- this->T::set(h.name_, h.value_);
- return *this;
- }
-
- /// URI can also be set via this method, useful for redirected request.
- void uri(const std::string& url) {
- uri_ = osquery::Uri(url);
- }
-
- private:
- osquery::Uri uri_;
-};
-
-/**
- * @brief HTTP response class.
- *
- * This class is inherited from implementation(boost.beast) HTTP response class.
- * This class gives convenient access to some functionality of implementation
- * specific HTTP response class.
- *
- */
-template <typename T>
-class HTTP_Response : public T {
- public:
- HTTP_Response() = default;
-
- HTTP_Response(T&& resp) : T(std::move(resp)) {}
-
- template <typename ITER>
- class Iterator;
- class Headers;
-
- /// status of a HTTP response.
- unsigned status() {
- return this->T::result_int();
- }
-
- /// body of a HTTP response.
- const std::string& body() {
- return this->T::body();
- }
-
- /**
- * @brief All headers of a HTTP response.
- *
- * Headers can be accessed via HTTP_Response<T>::Iterator class.
- */
- Headers headers() {
- return Headers(this);
- }
-};
-
-/**
- * @brief HTTP response headers iterator class
- *
- */
-template <typename T>
-template <typename ITER>
-class HTTP_Response<T>::Iterator {
- public:
- Iterator(ITER iter) : iter_(iter) {}
-
- Iterator operator++() {
- ++iter_;
- return *this;
- }
-
- Iterator operator++(int) {
- Iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator!=(const Iterator& it) const {
- return (iter_ != it.iter_);
- }
-
- auto operator-> () {
- return std::make_shared<std::pair<std::string, std::string>>(
- std::string(iter_->name_string()), std::string(iter_->value()));
- }
-
- auto operator*() {
- return std::make_pair(std::string(iter_->name_string()),
- std::string(iter_->value()));
- }
-
- private:
- ITER iter_;
-};
-
-/**
- * @brief HTTP response headers helper class.
- *
- * This class gives convenient access to all the headers of the HTTP response.
- *
- * e.g. -
- * for (const auto& header : resp.headers()) {
- * header.first;
- * header.second;
- * }
- */
-template <typename T>
-class HTTP_Response<T>::Headers {
- public:
- Headers(T* resp) : resp_(resp) {}
-
- std::string operator[](const std::string& name) {
- return std::string(resp_->T::operator[](name));
- }
-
- auto begin() {
- return Iterator<decltype(resp_->T::begin())>(resp_->T::begin());
- }
-
- auto end() {
- return Iterator<decltype(resp_->T::end())>(resp_->T::end());
- }
-
- private:
- T* resp_;
-};
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <cstring>
-#include <string>
-
-#include <zlib.h>
-
-namespace osquery {
-
-#define MOD_GZIP_ZLIB_WINDOWSIZE 15
-#define MOD_GZIP_ZLIB_CFACTOR 9
-
-std::string compressString(const std::string& data) {
- z_stream zs;
- memset(&zs, 0, sizeof(zs));
-
- if (deflateInit2(&zs,
- Z_BEST_COMPRESSION,
- Z_DEFLATED,
- MOD_GZIP_ZLIB_WINDOWSIZE + 16,
- MOD_GZIP_ZLIB_CFACTOR,
- Z_DEFAULT_STRATEGY) != Z_OK) {
- return std::string();
- }
-
- zs.next_in = (Bytef*)data.data();
- zs.avail_in = static_cast<uInt>(data.size());
-
- int ret = Z_OK;
- std::string output;
-
- {
- char buffer[16384] = {0};
- while (ret == Z_OK) {
- zs.next_out = reinterpret_cast<Bytef*>(buffer);
- zs.avail_out = sizeof(buffer);
-
- ret = deflate(&zs, Z_FINISH);
- if (output.size() < zs.total_out) {
- output.append(buffer, zs.total_out - output.size());
- }
- }
- }
-
- deflateEnd(&zs);
- if (ret != Z_STREAM_END) {
- return std::string();
- }
-
- return output;
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <memory>
-#include <utility>
-#include <string>
-
-#include <gtest/gtest_prod.h>
-
-#include <osquery/logger.h>
-#include <osquery/utils/json/json.h>
-#include <osquery/utils/status/status.h>
-
-namespace osquery {
-
-class Serializer;
-
-/**
- * @brief Compress data using GZip.
- *
- * Requests API callers may request data be compressed before sending.
- * The compression step occurs after serialization, immediately before the
- * transport call.
- *
- * @param data The input/output mutable container.
- */
-std::string compressString(const std::string& data);
-
-/**
- * @brief Abstract base class for remote transport implementations
- *
- * To define a new transport mechanism (HTTP, WebSockets, etc) for use with
- * remote connections, subclass osquery::Transport and implement the pure
- * virtual methods (as well as any base methods you may want to implement
- * custom behavior for).
- */
-class Transport {
- public:
- /**
- * @brief Set the destination URI
- *
- * @param A string representing the destination
- *
- * @return success or failure of the operation
- */
- virtual void setDestination(const std::string& destination) {
- destination_ = destination;
- }
-
- /**
- * @brief Set the serializer
- *
- * @param A serializer object
- */
- virtual void setSerializer(const std::shared_ptr<Serializer>& serializer) {
- serializer_ = serializer;
- }
-
- /**
- * @brief Send a simple request to the destination with no parameters
- *
- * @return success or failure of the operation
- */
- virtual Status sendRequest() = 0;
-
- /**
- * @brief Send a simple request to the destination with parameters
- *
- * @param params A string representing the serialized parameters
- * @param compress True of the request was requested to be compressed
- *
- * @return success or failure of the operation
- */
- virtual Status sendRequest(const std::string& params,
- bool compress = false) = 0;
-
- /**
- * @brief Get the status of the response
- *
- * @return success or failure of the operation
- */
- Status getResponseStatus() const { return response_status_; }
-
- /**
- * @brief Get the parameters of the response
- *
- * @return The parameters
- */
- const JSON& getResponseParams() const {
- return response_params_;
- }
-
- template <typename T>
- void setOption(const std::string& name, const T& value) {
- options_.add(name, value);
- }
-
- /**
- * @brief Virtual destructor
- */
- virtual ~Transport() {}
-
- protected:
- /// storage for the transport destination
- std::string destination_;
-
- /// storage for the serializer reference
- std::shared_ptr<Serializer> serializer_{nullptr};
-
- /// storage for response status
- Status response_status_;
-
- /// storage for response parameters
- JSON response_params_;
-
- /// options from request call (use defined by specific transport)
- JSON options_;
-};
-
-/**
- * @brief Abstract base class for serialization implementations
- *
- * To define a new serialization mechanism (JSON, XML, etc) for use with
- * remote connections, subclass osquery::Serializer and implement the pure
- * virtual methods (as well as any base methods you may want to implement
- * custom behavior for).
- */
-class Serializer {
- public:
- /**
- * @brief Returns the HTTP content type, for HTTP/TLS transport
- *
- * If a serializer is going to be used for HTTP/TLS, it probably needs to
- * set its own content type. Return a string with the appropriate content
- * type for serializer.
- *
- * @return The content type
- */
- virtual std::string getContentType() const = 0;
-
- /**
- * @brief Serialize a JSON object into a string
- *
- * @param params a JSON object to be serialized
- * @param serialized the output serialized string
- * @return success or failure of the operation
- */
- virtual Status serialize(const JSON& json, std::string& serialized) = 0;
-
- /**
- * @brief Deserialize a JSON string into a JSON object
- *
- * @param params a string of JSON
- * @param serialized the deserialized JSON object
- * @return success or failure of the operation
- */
- virtual Status deserialize(const std::string& serialized, JSON& params) = 0;
-
- /**
- * @brief Virtual destructor
- */
- virtual ~Serializer() {}
-};
-
-/**
- * @brief Request class for making flexible remote network requests
- */
-template <class TTransport, class TSerializer>
-class Request {
- public:
- /**
- * @brief This is the constructor that you should use to instantiate Request
- *
- * @param destination A string of the remote URI destination
- */
- explicit Request(const std::string& destination)
- : destination_(destination),
- serializer_(std::make_shared<TSerializer>()),
- transport_(std::make_shared<TTransport>()) {
- transport_->setDestination(destination_);
- transport_->setSerializer(serializer_);
- }
-
- private:
- /**
- * @brief Create a request with a customized Transport (testing only).
- *
- * @param destination A string of the remote URI destination
- * @param t A transport shared pointer.
- */
- Request(const std::string& destination, const std::shared_ptr<TTransport>& t)
- : destination_(destination),
- serializer_(std::make_shared<TSerializer>()),
- transport_(t) {
- transport_->setDestination(destination_);
- transport_->setSerializer(serializer_);
- }
-
- public:
- /**
- * @brief Class destructor
- */
- virtual ~Request() {}
-
- /**
- * @brief Send a simple request to the destination with no parameters
- *
- * @return success or failure of the operation
- */
- Status call() { return transport_->sendRequest(); }
-
- /**
- * @brief Send a simple request to the destination with parameters
- *
- * @param params a JSON object representing the parameters
- *
- * @return success or failure of the operation
- */
- Status call(const JSON& params) {
- std::string serialized;
- auto s = serializer_->serialize(params, serialized);
- if (!s.ok()) {
- return s;
- }
-
- bool compress = false;
- auto it = options_.doc().FindMember("compress");
- if (it != options_.doc().MemberEnd() && it->value.IsBool()) {
- compress = it->value.GetBool();
- }
-
- return transport_->sendRequest(serialized, compress);
- }
-
- /**
- * @brief Get the request response
- *
- * @return A pair of a Status and a JSON object of response params
- */
- Status getResponse(JSON& params) {
- params.copyFrom(transport_->getResponseParams().doc());
- return transport_->getResponseStatus();
- }
-
- template <typename T>
- void setOption(const std::string& name, const T& value) {
- options_.add(name, value);
- transport_->setOption(name, value);
- }
-
- private:
- /// storage for the resource destination
- std::string destination_;
-
- /// storage for the serializer to be used
- std::shared_ptr<TSerializer> serializer_{nullptr};
-
- /// storage for the transport to be used
- std::shared_ptr<TTransport> transport_{nullptr};
-
- /// options from request call (duplicated in transport)
- JSON options_;
-
-private:
- FRIEND_TEST(TLSTransportsTests, test_call);
- FRIEND_TEST(TLSTransportsTests, test_call_with_params);
- FRIEND_TEST(TLSTransportsTests, test_call_verify_peer);
- FRIEND_TEST(TLSTransportsTests, test_call_server_cert_pinning);
- FRIEND_TEST(TLSTransportsTests, test_call_client_auth);
-
- friend class TestDistributedPlugin;
-};
-}
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed as defined on the LICENSE file found in the
-# root directory of this source tree.
-
-load("//tools/build_defs/oss/osquery:cxx.bzl", "osquery_cxx_library", "osquery_cxx_test")
-load("//tools/build_defs/oss/osquery:native.bzl", "osquery_target")
-load("//tools/build_defs/oss/osquery:third_party.bzl", "osquery_tp_target")
-
-osquery_cxx_library(
- name = "serializer_json",
- srcs = ["json.cpp"],
- header_namespace = "osquery/remote/serializers",
- exported_headers = ["json.h"],
- tests = [":remote_json_serializers_tests"],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/remote:requests"),
- osquery_target("osquery/utils/json:json"),
- osquery_tp_target("boost"),
- ],
-)
-
-osquery_cxx_test(
- name = "remote_json_serializers_tests",
- srcs = [
- "tests/json_serializers_tests.cpp",
- ],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/remote/serializers:serializer_json"),
- ],
-)
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed in accordance with the terms specified in
-# the LICENSE file found in the root directory of this source tree.
-
-function(osqueryRemoteSerializersMain)
-
- if(BUILD_TESTING)
- generateOsqueryRemoteserializersjsontestsTest()
- endif()
-
- generateOsqueryRemoteSerializersSerializerjson()
-endfunction()
-
-function(generateOsqueryRemoteSerializersSerializerjson)
- add_osquery_library(osquery_remote_serializers_serializerjson EXCLUDE_FROM_ALL
- json.cpp
- )
-
- target_link_libraries(osquery_remote_serializers_serializerjson PUBLIC
- global_cxx_settings
- osquery_remote_requests
- osquery_utils_json
- thirdparty_boost
- )
-
- set(public_header_files
- json.h
- )
-
- generateIncludeNamespace(osquery_remote_serializers_serializerjson "osquery/remote/serializers" "FILE_ONLY" ${public_header_files})
-
- add_test(NAME osquery_remote_serializers_remotejsonserializerstests-test COMMAND osquery_remote_serializers_remotejsonserializerstests-test)
-endfunction()
-
-function(generateOsqueryRemoteserializersjsontestsTest)
- add_osquery_executable(osquery_remote_serializers_remotejsonserializerstests-test tests/json_serializers_tests.cpp)
-
- target_link_libraries(osquery_remote_serializers_remotejsonserializerstests-test PRIVATE
- global_cxx_settings
- osquery_remote_serializers_serializerjson
- thirdparty_googletest
- )
-endfunction()
-
-osqueryRemoteSerializersMain()
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include "json.h"
-
-#include <osquery/utils/json/json.h>
-
-namespace osquery {
-
-Status JSONSerializer::serialize(const JSON& json, std::string& serialized) {
- return json.toString(serialized);
-}
-
-Status JSONSerializer::deserialize(const std::string& serialized, JSON& json) {
- if (serialized.empty()) {
- // Prevent errors from being thrown when a TLS endpoint accepts the JSON
- // payload, but doesn't respond with anything. This has been seen in the
- // wild, for example with Sumo Logic.
- json = JSON();
- return Status::success();
- }
-
- return json.fromString(serialized);
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <osquery/remote/requests.h>
-
-namespace osquery {
-
-/**
- * @brief JSON Serializer
- */
-class JSONSerializer : public Serializer {
- public:
- /**
- * @brief See Serializer::serialize
- */
- Status serialize(const JSON& json, std::string& serialized);
-
- /**
- * @brief See Serializer::desiralize
- */
- Status deserialize(const std::string& serialized, JSON& json);
-
- /**
- * @brief See Serializer::getContentType
- *
- * @return The content type
- */
- std::string getContentType() const { return "application/json"; }
-};
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <gtest/gtest.h>
-
-#include "osquery/remote/serializers/json.h"
-
-namespace osquery {
-
-class JSONSerializersTests : public testing::Test {};
-
-TEST_F(JSONSerializersTests, test_serialize) {
- auto json = JSONSerializer();
- JSON params;
- params.add("foo", "bar");
-
- std::string serialized;
- auto s = json.serialize(params, serialized);
- EXPECT_TRUE(s.ok());
- EXPECT_EQ(serialized, "{\"foo\":\"bar\"}");
-}
-
-TEST_F(JSONSerializersTests, test_deserialize) {
- auto json = JSONSerializer();
- JSON params;
- std::string serialized = "{\"foo\":\"bar\"}";
- auto s = json.deserialize(serialized, params);
-
- JSON expected;
- expected.add("foo", "bar");
-
- EXPECT_TRUE(s.ok());
- EXPECT_EQ(params.doc(), expected.doc());
-}
-}
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed as defined on the LICENSE file found in the
-# root directory of this source tree.
-
-load("//tools/build_defs/oss/osquery:cxx.bzl", "osquery_cxx_library", "osquery_cxx_test")
-load("//tools/build_defs/oss/osquery:native.bzl", "osquery_target")
-
-osquery_cxx_library(
- name = "remote_test_utils",
- srcs = [
- "test_utils.cpp",
- ],
- header_namespace = "osquery/remote/tests",
- exported_headers = [
- "test_utils.h",
- ],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/config/tests:test_utils"),
- osquery_target("osquery/database:database"),
- osquery_target("osquery/events:events"),
- osquery_target("osquery/extensions:extensions"),
- osquery_target("osquery/extensions:impl_thrift"),
- osquery_target("osquery/remote/enroll:tls_enroll"),
- osquery_target("osquery/utils/conversions:conversions"),
- osquery_target("osquery/utils/info:info"),
- osquery_target("plugins/config:tls_config"),
- osquery_target("plugins/database:ephemeral"),
- osquery_target("plugins/killswitch:killswitch_filesystem"),
- osquery_target("tests:helper"),
- ],
-)
-
-osquery_cxx_test(
- name = "requests_tests",
- srcs = [
- "requests_tests.cpp",
- ],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/config/tests:test_utils"),
- osquery_target("osquery/database:database"),
- osquery_target("osquery/events:events"),
- osquery_target("osquery/extensions:extensions"),
- osquery_target("osquery/extensions:impl_thrift"),
- osquery_target("osquery/remote/enroll:tls_enroll"),
- osquery_target("osquery/remote/tests:remote_test_utils"),
- osquery_target("osquery/utils/conversions:conversions"),
- osquery_target("osquery/utils/info:info"),
- osquery_target("plugins/config:tls_config"),
- osquery_target("plugins/database:ephemeral"),
- osquery_target("plugins/killswitch:killswitch_filesystem"),
- osquery_target("tests:helper"),
- ],
-)
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed in accordance with the terms specified in
-# the LICENSE file found in the root directory of this source tree.
-
-function(osqueryRemoteTestsMain)
- generateOsqueryRemoteTestsRemotetestsutils()
- generateOsqueryRemoteTestsRequeststestsTest()
-endfunction()
-
-function(generateOsqueryRemoteTestsRemotetestsutils)
- add_osquery_library(osquery_remote_tests_remotetestutils EXCLUDE_FROM_ALL test_utils.cpp)
-
- set(public_header_files
- test_utils.h
- )
-
- generateIncludeNamespace(osquery_remote_tests_remotetestutils "osquery/remote/tests" "FILE_ONLY" ${public_header_files})
-
- target_link_libraries(osquery_remote_tests_remotetestutils PUBLIC
- global_cxx_settings
- osquery_config_tests_testutils
- osquery_database
- osquery_events
- osquery_extensions
- osquery_extensions_implthrift
- osquery_remote_enroll_tlsenroll
- osquery_utils_conversions
- osquery_utils_info
- plugins_config_tlsconfig
- plugins_database_ephemeral
- plugins_killswitch_killswitchfilesystem
- tests_helper
- )
-endfunction()
-
-function(generateOsqueryRemoteTestsRequeststestsTest)
- add_osquery_executable(osquery_remote_tests_requeststests-test requests_tests.cpp)
-
- target_link_libraries(osquery_remote_tests_requeststests-test PRIVATE
- global_cxx_settings
- osquery_config_tests_testutils
- osquery_database
- osquery_events
- osquery_extensions
- osquery_extensions_implthrift
- osquery_remote_enroll_tlsenroll
- osquery_remote_tests_remotetestutils
- osquery_utils_conversions
- osquery_utils_info
- plugins_config_tlsconfig
- plugins_database_ephemeral
- plugins_killswitch_killswitchfilesystem
- tests_helper
- thirdparty_googletest
- )
-endfunction()
-
-osqueryRemoteTestsMain()
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <gtest/gtest.h>
-
-#include <osquery/remote/requests.h>
-#include <osquery/remote/serializers/json.h>
-#include <osquery/remote/transports/tls.h>
-#include <osquery/remote/uri.h>
-#include <osquery/utils/conversions/tryto.h>
-
-namespace osquery {
-
-class RequestsTests : public testing::Test {
- public:
- void SetUp() {}
-};
-
-class MockTransport : public Transport {
- public:
- Status sendRequest() override {
- response_status_ = Status(0, "OK");
- return response_status_;
- }
-
- Status sendRequest(const std::string& params, bool compress) override {
- response_params_.add("foo", "baz");
- response_status_ = Status(0, "OK");
- return response_status_;
- }
-};
-
-class MockSerializer : public Serializer {
- public:
- std::string getContentType() const {
- return "mock";
- }
-
- Status serialize(const JSON& params, std::string& serialized) {
- return Status::success();
- }
-
- Status deserialize(const std::string& serialized, JSON& params) {
- return Status::success();
- }
-};
-
-TEST_F(RequestsTests, test_url) {
- Uri test("https://facebook.com");
- EXPECT_EQ("https", test.scheme());
- EXPECT_EQ("facebook.com", test.host());
-
- test = Uri("ftp://teddy@facebook.com:21");
- EXPECT_EQ("teddy", test.username());
- uint16_t port(21);
- EXPECT_EQ(port, test.port());
-
- test = Uri("https://osquery.io/schema?scroll=1&offset=2#table");
- EXPECT_EQ("/schema", test.path());
- EXPECT_EQ("table", test.fragment());
- EXPECT_EQ(2_sz, test.getQueryParams().size());
-
- test = Uri("https://[10:10:32::1:f]:8080");
- port = 8080;
- EXPECT_EQ(port, test.port());
- EXPECT_EQ("[10:10:32::1:f]", test.host());
-}
-
-TEST_F(RequestsTests, test_call) {
- Request<MockTransport, MockSerializer> req("foobar");
- auto s1 = req.call();
- EXPECT_TRUE(s1.ok());
-
- JSON params;
- auto s2 = req.getResponse(params);
- EXPECT_TRUE(s2.ok());
- JSON empty;
- EXPECT_EQ(params.doc(), empty.doc());
-}
-
-TEST_F(RequestsTests, test_call_with_params) {
- Request<MockTransport, MockSerializer> req("foobar");
- JSON params;
- params.add("foo", "bar");
- auto s1 = req.call(params);
- EXPECT_TRUE(s1.ok());
-
- JSON recv;
- auto s2 = req.getResponse(recv);
- EXPECT_TRUE(s2.ok());
-
- JSON expected;
- expected.add("foo", "baz");
- EXPECT_EQ(recv.doc(), expected.doc());
-}
-
-class CopyTransport : public Transport {
- public:
- Status sendRequest() override {
- response_status_ = Status(0, "OK");
- return response_status_;
- }
-
- Status sendRequest(const std::string& params, bool compress) override {
- // Optionally compress.
- response_status_ = Status(0, (compress) ? compressString(params) : params);
- return response_status_;
- }
-};
-
-class CopySerializer : public Serializer {
- public:
- std::string getContentType() const {
- return "copy";
- }
-
- Status serialize(const JSON& params, std::string& serialized) {
- auto it = params.doc().FindMember("copy");
- serialized = (it != params.doc().MemberEnd() && it->value.IsString()
- ? it->value.GetString()
- : "");
-
- return Status::success();
- }
-
- Status deserialize(const std::string& serialized, JSON& params) {
- return Status::success();
- }
-};
-
-TEST_F(RequestsTests, test_compression) {
- Request<CopyTransport, CopySerializer> req("foobar");
-
- // Ask the request to compress the output from serialization.
- req.setOption("compress", true);
-
- std::string uncompressed = "stringstringstringstring";
- for (size_t i = 0; i < 10; i++) {
- uncompressed += uncompressed;
- }
-
- // Our special 'copy' serializer copies input from the 'copy' key in params.
- JSON params;
- params.add("copy", uncompressed);
-
- // Similarly, the 'copy' transport copies the request params into the
- // response status.
- req.call(params);
- auto status = req.getResponse(params);
-
- auto compressed = status.getMessage();
-
- /*
- * gzip header has a field that specifies the OS the library was built on
- * we need to skip the 10th byte (index 9) while comparing compressed results
- *
- * Reference: http://www.zlib.org/rfc-gzip.html
- * https://github.com/madler/zlib/blob/master/zutil.h#L86
- */
-
- std::string expected1("\x1F\x8B\b\0\0\0\0\0\x2", 9);
- std::string expected2(
- "\xED\xC4\xB1\r\0\0\x4\0\xB0s\xC5"
- "b\xC0\xFFq\x84\xB5\x1D:"
- "\xDBY1\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xDB"
- "\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xDB\xB6m\xFB\xF1\x1"
- "1j\xA0\xA8\0`\0\0",
- 68);
-
- EXPECT_EQ(compressed.substr(0, 9), expected1);
- EXPECT_EQ(compressed.substr(10), expected2);
- EXPECT_LT(compressed.size(), uncompressed.size());
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <csignal>
-#include <ctime>
-
-#include <thread>
-
-#include <osquery/config/tests/test_utils.h>
-#include <osquery/core.h>
-#include <osquery/database.h>
-#include <osquery/flags.h>
-#include <osquery/process/process.h>
-#include <osquery/remote/tests/test_utils.h>
-#include <osquery/sql.h>
-#include <osquery/tests/test_util.h>
-#include <osquery/utils/json/json.h>
-#include <osquery/utils/system/time.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-DECLARE_string(tls_hostname);
-DECLARE_string(enroll_tls_endpoint);
-DECLARE_string(tls_server_certs);
-DECLARE_string(enroll_secret_path);
-DECLARE_bool(disable_caching);
-
-void TLSServerRunner::start() {
- auto& self = instance();
- if (self.server_ != nullptr) {
- return;
- }
-
- // Pick a port in an ephemeral range at random.
- self.port_ = std::to_string(getUnixTime() % 10000 + 20000);
-
- // Fork then exec a shell.
- auto python_server = (getTestConfigDirectory() / "test_http_server.py")
- .make_preferred()
- .string() +
- " --tls " + self.port_;
- self.server_ = PlatformProcess::launchTestPythonScript(python_server);
- if (self.server_ == nullptr) {
- return;
- }
-
- size_t delay = 0;
- std::string query =
- "select pid from listening_ports where port = '" + self.port_ + "'";
- while (delay < 2 * 1000) {
- auto caching = FLAGS_disable_caching;
- FLAGS_disable_caching = true;
- auto results = SQL(query);
- FLAGS_disable_caching = caching;
- if (!results.rows().empty()) {
- self.server_.reset(
- new PlatformProcess(std::atoi(results.rows()[0].at("pid").c_str())));
- break;
- }
-
- sleepFor(100);
- delay += 100;
- }
-}
-
-void TLSServerRunner::setClientConfig() {
- auto& self = instance();
-
- self.tls_hostname_ = Flag::getValue("tls_hostname");
- Flag::updateValue("tls_hostname", "localhost:" + port());
-
- self.enroll_tls_endpoint_ = Flag::getValue("enroll_tls_endpoint");
- Flag::updateValue("enroll_tls_endpoint", "/enroll");
-
- self.tls_server_certs_ = Flag::getValue("tls_server_certs");
- Flag::updateValue("tls_server_certs",
- (getTestConfigDirectory() / "test_server_ca.pem")
- .make_preferred()
- .string());
-
- self.enroll_secret_path_ = Flag::getValue("enroll_secret_path");
- Flag::updateValue("enroll_secret_path",
- (getTestConfigDirectory() / "test_enroll_secret.txt")
- .make_preferred()
- .string());
-}
-
-void TLSServerRunner::unsetClientConfig() {
- auto& self = instance();
- Flag::updateValue("tls_hostname", self.tls_hostname_);
- Flag::updateValue("enroll_tls_endpoint", self.enroll_tls_endpoint_);
- Flag::updateValue("tls_server_certs", self.tls_server_certs_);
- Flag::updateValue("enroll_secret_path", self.enroll_secret_path_);
-}
-
-void TLSServerRunner::stop() {
- auto& self = instance();
- if (self.server_ != nullptr) {
- self.server_->kill();
- self.server_.reset();
- }
-}
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <string>
-
-#include <boost/noncopyable.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/process/process.h>
-
-namespace osquery {
-
-class TLSServerRunner : private boost::noncopyable {
- public:
- /// Create a singleton TLS server runner.
- static TLSServerRunner& instance() {
- static TLSServerRunner instance;
- return instance;
- }
-
- /// Set associated flags for testing client TLS usage.
- static void setClientConfig();
-
- /// Unset or restore associated flags for testing client TLS usage.
- static void unsetClientConfig();
-
- /// TCP port accessor.
- static const std::string& port() {
- return instance().port_;
- }
-
- /// Start the server if it hasn't started already.
- static void start();
-
- /// Stop the service when the process exits.
- static void stop();
-
- private:
- /// Current server handle.
- std::shared_ptr<PlatformProcess> server_{nullptr};
-
- /// Current server TLS port.
- std::string port_;
-
- private:
- std::string tls_hostname_;
- std::string enroll_tls_endpoint_;
- std::string tls_server_certs_;
- std::string enroll_secret_path_;
-};
-}
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed as defined on the LICENSE file found in the
-# root directory of this source tree.
-
-load("//tools/build_defs/oss/osquery:cxx.bzl", "osquery_cxx_library", "osquery_cxx_test")
-load("//tools/build_defs/oss/osquery:native.bzl", "osquery_target")
-load("//tools/build_defs/oss/osquery:platforms.bzl", "POSIX")
-load("//tools/build_defs/oss/osquery:third_party.bzl", "osquery_tp_target")
-
-osquery_cxx_library(
- name = "transports_tls",
- srcs = ["tls.cpp"],
- header_namespace = "osquery/remote/transports",
- exported_headers = ["tls.h"],
- tests = [":remote_transports_tls_tests"],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery:headers"),
- osquery_target("osquery/core:core"),
- osquery_target("osquery/remote:http_client"),
- osquery_target("osquery/remote:requests"),
- osquery_target("osquery/utils/json:json"),
- osquery_tp_target("boost"),
- ],
-)
-
-osquery_cxx_test(
- name = "remote_transports_tls_tests",
- env = {
- "TEST_CONF_FILES_DIR": "$(location {})".format(
- osquery_target("tools/tests:test_files"),
- ),
- },
- platform_srcs = [
- (
- POSIX,
- [
- "tests/tls_transports_tests.cpp",
- ],
- ),
- ],
- visibility = ["PUBLIC"],
- deps = [
- osquery_target("osquery/config/tests:test_utils"),
- osquery_target("osquery/database:database"),
- osquery_target("osquery/events:events"),
- osquery_target("osquery/extensions:extensions"),
- osquery_target("osquery/extensions:impl_thrift"),
- osquery_target("osquery/remote/enroll:tls_enroll"),
- osquery_target("osquery/remote/tests:remote_test_utils"),
- osquery_target("osquery/utils/conversions:conversions"),
- osquery_target("osquery/utils/info:info"),
- osquery_target("plugins/config:tls_config"),
- osquery_target("plugins/database:ephemeral"),
- osquery_target("plugins/killswitch:killswitch_filesystem"),
- osquery_target("tests:helper"),
- ],
-)
+++ /dev/null
-# Copyright (c) 2014-present, Facebook, Inc.
-# All rights reserved.
-#
-# This source code is licensed in accordance with the terms specified in
-# the LICENSE file found in the root directory of this source tree.
-
-function(osqueryRemoteTransportsMain)
-
- if(BUILD_TESTING AND DEFINED PLATFORM_POSIX)
- generateOsqueryRemoteTransportsRemotetransportstlstestsTest()
- endif()
-
- generateOsqueryRemoteTransportsTransportstls()
-endfunction()
-
-function(generateOsqueryRemoteTransportsTransportstls)
- add_osquery_library(osquery_remote_transports_transportstls EXCLUDE_FROM_ALL
- tls.cpp
- )
-
- target_link_libraries(osquery_remote_transports_transportstls PUBLIC
- global_cxx_settings
- osquery_headers
- osquery_core
- osquery_remote_httpclient
- osquery_remote_requests
- osquery_utils_json
- thirdparty_boost
- )
-
- set(public_header_files
- tls.h
- )
-
- generateIncludeNamespace(osquery_remote_transports_transportstls "osquery/remote/transports" "FILE_ONLY" ${public_header_files})
-
- if(DEFINED PLATFORM_POSIX)
- add_test(NAME osquery_remote_transports_remotetransportstlstests-test COMMAND osquery_remote_transports_remotetransportstlstests-test)
-
- set_tests_properties(
- osquery_remote_transports_remotetransportstlstests-test
- PROPERTIES ENVIRONMENT "TEST_CONF_FILES_DIR=${TEST_CONFIGS_DIR}"
- )
- endif()
-endfunction()
-
-
-function(generateOsqueryRemoteTransportsRemotetransportstlstestsTest)
-
- add_osquery_executable(osquery_remote_transports_remotetransportstlstests-test tests/tls_transports_tests.cpp)
-
- target_link_libraries(osquery_remote_transports_remotetransportstlstests-test PRIVATE
- global_cxx_settings
- osquery_config_tests_testutils
- osquery_database
- osquery_events
- osquery_extensions
- osquery_extensions_implthrift
- osquery_remote_enroll_tlsenroll
- osquery_remote_tests_remotetestutils
- osquery_utils_conversions
- osquery_utils_info
- plugins_config_tlsconfig
- plugins_database_ephemeral
- plugins_killswitch_killswitchfilesystem
- tests_helper
- thirdparty_googletest
- osquery_tools_tests_testfiles
- )
-endfunction()
-
-osqueryRemoteTransportsMain()
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include "osquery/remote/transports/tls.h"
-// clang-format on
-
-#include <thread>
-
-#include <gtest/gtest.h>
-
-#include <osquery/logger.h>
-#include <osquery/system.h>
-#include <osquery/registry_factory.h>
-
-#include "osquery/remote/requests.h"
-#include "osquery/remote/serializers/json.h"
-
-#include "osquery/remote/tests/test_utils.h"
-#include "osquery/config/tests/test_utils.h"
-#include "osquery/tests/test_util.h"
-
-namespace osquery {
-
-DECLARE_bool(disable_database);
-DECLARE_string(tls_server_certs);
-
-class TLSTransportsTests : public testing::Test {
- public:
- bool verify(const Status& status) {
- if (!status.ok()) {
- LOG(ERROR) << "Could not complete TLSRequest (" << status.getCode()
- << "): " << status.what();
- }
-
- // Sometimes the best we can test is the call workflow.
- if (status.getCode() == 1) {
- // The socket bind failed or encountered a connection error in the test.
- LOG(ERROR) << "Not failing TLS-based transport tests";
- return false;
- }
-
- return true;
- }
-
- bool nameError(const Status& status) {
- std::string name_error =
- "Request error: The format of the specified network name is invalid.";
- if (status.getMessage() == name_error) {
- return true;
- }
-
- return false;
- }
-
- void SetUp() override {
- Initializer::platformSetup();
- registryAndPluginInit();
- FLAGS_disable_database = true;
- DatabasePlugin::setAllowOpen(true);
- DatabasePlugin::initPlugin();
-
- certs_ = FLAGS_tls_server_certs;
- FLAGS_tls_server_certs = "";
- TLSServerRunner::start();
- port_ = TLSServerRunner::port();
- }
-
- void TearDown() override {
- TLSServerRunner::stop();
- FLAGS_tls_server_certs = certs_;
- }
-
- protected:
- std::string port_;
- std::string certs_;
-};
-
-TEST_F(TLSTransportsTests, test_call) {
- // Create a transport and use a testing-only 'disableVerifyPeer' call.
- // This allows our client to complete TLS without verifying the fake
- // commonName or fake CA used by the testing server.
- auto t = std::make_shared<TLSTransport>();
- t->disableVerifyPeer();
-
- // Create a request using a TLSTransport and JSONSerializer.
- auto url = "https://localhost:" + port_;
- Request<TLSTransport, JSONSerializer> r(url, t);
-
- // Use the 'call' method on the request without any input parameters.
- // This will use a GET for the URI given in the Request constructor.
- Status status;
- ASSERT_NO_THROW(status = r.call());
- if (verify(status)) {
- JSON recv;
- status = r.getResponse(recv);
- EXPECT_TRUE(status.ok());
- }
-}
-
-TEST_F(TLSTransportsTests, test_call_with_params) {
- // Again, use a fake server/CA/commonName certificate.
- auto t = std::make_shared<TLSTransport>();
- t->disableVerifyPeer();
-
- auto url = "https://localhost:" + port_;
- Request<TLSTransport, JSONSerializer> r(url, t);
-
- // This time we'll construct a request parameter.
- JSON params;
- params.add("foo", "bar");
-
- // The call with a set of a params will push this "JSONSerializer"-serialized
- // data into the body of the request and issue a POST to the URI.
- Status status;
- ASSERT_NO_THROW(status = r.call(params));
- if (verify(status)) {
- JSON recv;
- status = r.getResponse(recv);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ(params.doc(), recv.doc());
- }
-}
-
-TEST_F(TLSTransportsTests, DISABLED_test_call_verify_peer) {
- // Create a default request without a transport that accepts invalid peers.
- auto url = "https://localhost:" + port_;
- Request<TLSTransport, JSONSerializer> r(url);
-
- // The status/call will fail TLS negotiation because our client is trying
- // to verify the fake server, CA, commonName.
- Status status;
- ASSERT_NO_THROW(status = r.call());
- if (verify(status)) {
- EXPECT_FALSE(status.ok());
- // A non-1 exit code means the request failed, but not because of a socket
- // error or request-connection problem.
- EXPECT_EQ(status.getCode(), 2);
- if (!nameError(status)) {
- EXPECT_EQ(status.getMessage(),
- "Request error: certificate verify failed");
- }
- }
-}
-
-TEST_F(TLSTransportsTests, test_call_server_cert_pinning) {
- // Require verification but include the server's certificate that includes
- // an unknown signing CA and wrong commonName.
- auto t = std::make_shared<TLSTransport>();
- t->setPeerCertificate((getTestConfigDirectory() / "test_server_ca.pem").string());
-
- auto url = "https://localhost:" + port_;
- Request<TLSTransport, JSONSerializer> r1(url, t);
-
- Status status;
- ASSERT_NO_THROW(status = r1.call());
- if (verify(status)) {
- EXPECT_TRUE(status.ok());
- }
-
- // Now try with a path that is not a filename.
- t = std::make_shared<TLSTransport>();
- t->setPeerCertificate(getTestConfigDirectory().string());
- Request<TLSTransport, JSONSerializer> r2(url, t);
-
- ASSERT_NO_THROW(status = r2.call());
- if (verify(status)) {
- EXPECT_FALSE(status.ok());
- }
-}
-
-TEST_F(TLSTransportsTests, test_call_client_auth) {
- auto t = std::make_shared<TLSTransport>();
- t->setPeerCertificate((getTestConfigDirectory() / "test_server_ca.pem").string());
- t->setClientCertificate((getTestConfigDirectory() / "test_client.pem").string(),
- (getTestConfigDirectory() / "test_client.key").string());
-
- auto url = "https://localhost:" + port_;
- Request<TLSTransport, JSONSerializer> r(url, t);
-
- Status status;
- ASSERT_NO_THROW(status = r.call());
- if (verify(status)) {
- EXPECT_TRUE(status.ok());
- }
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include "tls.h"
-
-#include <chrono>
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/utils/info/version.h>
-#include <osquery/utils/info/platform_type.h>
-#include <osquery/utils/config/default_paths.h>
-
-#include <boost/filesystem.hpp>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-const std::string kTLSUserAgentBase = "osquery/";
-
-/// TLS server hostname.
-CLI_FLAG(string,
- tls_hostname,
- "",
- "TLS/HTTPS hostname for Config, Logger, and Enroll plugins");
-
-/// Optional HTTP proxy server hostname.
-CLI_FLAG(string, proxy_hostname, "", "Optional HTTP proxy hostname");
-
-/// Path to optional TLS server/CA certificate(s), used for pinning.
-CLI_FLAG(string,
- tls_server_certs,
- OSQUERY_CERTS_HOME "certs.pem",
- "Optional path to a TLS server PEM certificate(s) bundle");
-
-/// Path to optional TLS client certificate, used for enrollment/requests.
-CLI_FLAG(string,
- tls_client_cert,
- "",
- "Optional path to a TLS client-auth PEM certificate");
-
-/// Path to optional TLS client secret key, used for enrollment/requests.
-CLI_FLAG(string,
- tls_client_key,
- "",
- "Optional path to a TLS client-auth PEM private key");
-
-/// Reuse TLS session sockets.
-CLI_FLAG(bool, tls_session_reuse, true, "Reuse TLS session sockets");
-
-/// Tear down TLS sessions after a custom timeout.
-CLI_FLAG(uint32,
- tls_session_timeout,
- 3600,
- "TLS session keep alive timeout in seconds");
-
-#ifndef NDEBUG
-HIDDEN_FLAG(bool,
- tls_allow_unsafe,
- false,
- "Allow TLS server certificate trust failures");
-#endif
-
-HIDDEN_FLAG(bool, tls_dump, false, "Print remote requests and responses");
-
-/// Undocumented feature to override TLS endpoints.
-HIDDEN_FLAG(bool, tls_node_api, false, "Use node key as TLS endpoints");
-
-DECLARE_bool(verbose);
-
-TLSTransport::TLSTransport() : verify_peer_(true) {
- if (FLAGS_tls_server_certs.size() > 0) {
- server_certificate_file_ = FLAGS_tls_server_certs;
- }
-
- if (FLAGS_tls_client_cert.size() > 0 && FLAGS_tls_client_key.size() > 0) {
- client_certificate_file_ = FLAGS_tls_client_cert;
- client_private_key_file_ = FLAGS_tls_client_key;
- }
-}
-
-void TLSTransport::decorateRequest(http::Request& r) {
- r << http::Request::Header("Content-Type", serializer_->getContentType());
- r << http::Request::Header("Accept", serializer_->getContentType());
- r << http::Request::Header("User-Agent", kTLSUserAgentBase + kVersion);
-}
-
-http::Client::Options TLSTransport::getOptions() {
- http::Client::Options options;
- options.follow_redirects(true).always_verify_peer(verify_peer_).timeout(16);
-
- options.keep_alive(FLAGS_tls_session_reuse);
-
- if (FLAGS_proxy_hostname.size() > 0) {
- options.proxy_hostname(FLAGS_proxy_hostname);
- }
-
- options.openssl_ciphers(kTLSCiphers);
- options.openssl_options(SSL_OP_NO_SSLv3 | SSL_OP_NO_SSLv2 | SSL_OP_ALL);
-
- if (server_certificate_file_.size() > 0) {
- if (!osquery::isReadable(server_certificate_file_).ok()) {
- LOG(WARNING) << "Cannot read TLS server certificate(s): "
- << server_certificate_file_;
- } else {
- // There is a non-default server certificate set.
- boost_system::error_code ec;
-
- auto status = fs::status(server_certificate_file_, ec);
-
-#ifndef NDEBUG
- if (!FLAGS_tls_allow_unsafe) {
- // In unsafe mode we skip verification of the server's TLS details
- // to allow people to connect to devservers
-#else
- if (true) {
-#endif
- options.openssl_verify_path(server_certificate_file_);
- }
-
- // On Windows, we cannot set openssl_certificate to a directory
- if (isPlatform(PlatformType::TYPE_WINDOWS) &&
- status.type() != fs::regular_file) {
- LOG(WARNING) << "Cannot set a non-regular file as a certificate: "
- << server_certificate_file_;
- } else {
-#ifndef NDEBUG
- if (!FLAGS_tls_allow_unsafe) {
-#else
- if (true) {
-#endif
- options.openssl_certificate(server_certificate_file_);
- }
- }
- }
- }
-
- if (client_certificate_file_.size() > 0) {
- if (!osquery::isReadable(client_certificate_file_).ok()) {
- LOG(WARNING) << "Cannot read TLS client certificate: "
- << client_certificate_file_;
- } else if (!osquery::isReadable(client_private_key_file_).ok()) {
- LOG(WARNING) << "Cannot read TLS client private key: "
- << client_private_key_file_;
- } else {
- options.openssl_certificate_file(client_certificate_file_);
- options.openssl_private_key_file(client_private_key_file_);
- }
- }
-
- // 'Optionally', though all TLS plugins should set a hostname, supply an SNI
- // hostname. This will reveal the requested domain.
- auto it = options_.doc().FindMember("hostname");
- if (it != options_.doc().MemberEnd() && it->value.IsString()) {
- options.openssl_sni_hostname(it->value.GetString());
- }
-
-#ifndef NDEBUG
- // Configuration may allow unsafe TLS testing if compiled as a debug target.
- if (FLAGS_tls_allow_unsafe) {
- options.always_verify_peer(false);
- }
-#endif
-
- return options;
-}
-
-inline bool tlsFailure(const std::string& what) {
- if (what.find("Error") == 0 || what.find("refused") != std::string::npos) {
- return false;
- }
- return true;
-}
-
-static auto getClient() {
- std::shared_ptr<http::Client> client = nullptr;
- if (FLAGS_tls_session_reuse) {
- thread_local std::shared_ptr<http::Client> tl_client;
- thread_local auto last_time_reseted = std::chrono::system_clock::now();
- client = tl_client;
-
- if (client.get() == nullptr) {
- tl_client = client = std::make_shared<http::Client>();
- }
-
- if (FLAGS_tls_session_timeout > 0 &&
- std::chrono::duration_cast<std::chrono::seconds>(
- std::chrono::system_clock::now() - last_time_reseted)
- .count() > FLAGS_tls_session_timeout) {
- tl_client.reset();
- last_time_reseted = std::chrono::system_clock::now();
- }
- } else {
- client = std::make_shared<http::Client>();
- }
- return client;
-}
-
-Status TLSTransport::sendRequest() {
- if (destination_.find("https://") == std::string::npos) {
- return Status::failure(
- "Cannot create TLS request for non-HTTPS protocol URI");
- }
-
- http::Request r(destination_);
- decorateRequest(r);
-
- VLOG(1) << "TLS/HTTPS GET request to URI: " << destination_;
- try {
- std::shared_ptr<http::Client> client = getClient();
-
- client->setOptions(getOptions());
- response_ = client->get(r);
-
- const auto& response_body = response_.body();
- if (FLAGS_verbose && FLAGS_tls_dump) {
- fprintf(stdout, "%s\n", response_body.c_str());
- }
- response_status_ =
- serializer_->deserialize(response_body, response_params_);
- } catch (const std::exception& e) {
- return Status::failure(std::string("Request error: ") + e.what());
- }
- return response_status_;
-}
-
-Status TLSTransport::sendRequest(const std::string& params, bool compress) {
- if (destination_.find("https://") == std::string::npos) {
- return Status::failure(
- "Cannot create TLS request for non-HTTPS protocol URI");
- }
-
- http::Request r(destination_);
- decorateRequest(r);
- if (compress) {
- // Later, when posting/putting, the data will be optionally compressed.
- r << http::Request::Header("Content-Encoding", "gzip");
- }
-
- // Allow request calls to override the default HTTP POST verb.
- HTTPVerb verb;
- auto it = options_.doc().FindMember("_verb");
-
- verb = (HTTPVerb)(it != options_.doc().MemberEnd() && it->value.IsInt()
- ? it->value.GetInt()
- : HTTP_POST);
-
- VLOG(1) << "TLS/HTTPS " << ((verb == HTTP_POST) ? "POST" : "PUT")
- << " request to URI: " << destination_;
- if (FLAGS_verbose && FLAGS_tls_dump) {
- fprintf(stdout, "%s\n", params.c_str());
- }
-
- try {
- std::shared_ptr<http::Client> client = getClient();
- client->setOptions(getOptions());
-
- if (verb == HTTP_POST) {
- response_ = client->post(r, (compress) ? compressString(params) : params);
- } else {
- response_ = client->put(r, (compress) ? compressString(params) : params);
- }
-
- const auto& response_body = response_.body();
- if (FLAGS_verbose && FLAGS_tls_dump) {
- fprintf(stdout, "%s\n", response_body.c_str());
- }
- response_status_ =
- serializer_->deserialize(response_body, response_params_);
- } catch (const std::exception& e) {
- return Status::failure(std::string("Request error: ") + e.what());
- }
- return response_status_;
-}
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <gtest/gtest_prod.h>
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include <osquery/remote/http_client.h>
-// clang-format on
-
-#include <osquery/flags.h>
-#include <osquery/remote/requests.h>
-
-namespace osquery {
-
-const std::string kTLSCiphers =
- "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:"
- "DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!CBC:!SHA";
-
-/// Path to optional TLS client secret key, used for enrollment/requests.
-DECLARE_string(tls_client_key);
-
-/// Path to optional TLS client certificate (PEM), used for
-/// enrollment/requests.
-DECLARE_string(tls_client_cert);
-
-/// TLS server hostname.
-DECLARE_string(tls_hostname);
-
-/**
- * @brief HTTP verb selections.
- */
-enum HTTPVerb {
- HTTP_POST = 0,
- HTTP_PUT,
-};
-
-/**
- * @brief HTTPS (TLS) transport.
- */
-class TLSTransport : public Transport {
- public:
- /**
- * @brief Send a simple request to the destination with no parameters
- *
- * @return A status indicating socket, network, or transport success/error.
- * Return code (1) for general connectivity problems, return code (2) for TLS
- * specific errors.
- */
- Status sendRequest() override;
-
- /**
- * @brief Send a simple request to the destination with parameters
- *
- * @param params A string representing the serialized parameters
- *
- * @return A status indicating socket, network, or transport success/error.
- * Return code (1) for general connectivity problems, return code (2) for TLS
- * specific errors.
- */
- Status sendRequest(const std::string& params, bool compress = false) override;
-
- /**
- * @brief Class destructor
- */
- virtual ~TLSTransport() {}
-
- public:
- TLSTransport();
-
- http::Client::Options getOptions();
-
- private:
- /// Testing-only, disable peer verification.
- void disableVerifyPeer() {
- verify_peer_ = false;
- }
-
- /// Set TLS-client authentication options.
- void setClientCertificate(const std::string& certificate_file,
- const std::string& private_key_file) {
- client_certificate_file_ = certificate_file;
- client_private_key_file_ = private_key_file;
- }
-
- /// Set TLS server/ca pinning options.
- void setPeerCertificate(const std::string& server_certificate_file) {
- server_certificate_file_ = server_certificate_file;
- }
-
- private:
- /// Optional TLS client-auth client certificate filename.
- std::string client_certificate_file_;
-
- /// Optional TLS client-auth client private key filename.
- std::string client_private_key_file_;
-
- /// Optional TLS server-pinning server certificate/bundle filename.
- std::string server_certificate_file_;
-
- /// Testing-only, disable peer verification.
- bool verify_peer_;
-
- protected:
- /**
- * @brief Modify a request object with base modifications
- *
- * @param The request object, to be modified
- */
- void decorateRequest(http::Request& r);
-
- protected:
- /// Storage for the HTTP response object
- http::Response response_;
-
- private:
- FRIEND_TEST(TLSTransportsTests, test_call);
- FRIEND_TEST(TLSTransportsTests, test_call_with_params);
- FRIEND_TEST(TLSTransportsTests, test_call_verify_peer);
- FRIEND_TEST(TLSTransportsTests, test_call_server_cert_pinning);
- FRIEND_TEST(TLSTransportsTests, test_call_client_auth);
- FRIEND_TEST(TLSTransportsTests, test_call_http);
-
- friend class TestDistributedPlugin;
-
-};
-}
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#include <cctype>
-#include <regex>
-
-#include "osquery/remote/uri.h"
-
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-
-namespace osquery {
-
-static std::string submatch(const std::smatch& m, int idx) {
- auto& sub = m[idx];
- return std::string(sub.first, sub.second);
-}
-
-template <class String>
-static inline void toLower(String& s) {
- for (auto& c : s) {
- c = char(tolower(c));
- }
-}
-
-Uri::Uri(const std::string& str) : hasAuthority_(false), port_(0) {
- static const std::regex uriRegex(
- "([a-zA-Z][a-zA-Z0-9+.-]*):" // scheme:
- "([^?#]*)" // authority and path
- "(?:\\?([^#]*))?" // ?query
- "(?:#(.*))?"); // #fragment
- static const std::regex authorityAndPathRegex("//([^/]*)(/.*)?");
-
- std::smatch match;
- if (!std::regex_match(str, match, uriRegex)) {
- throw std::invalid_argument("Invalid URL");
- }
-
- scheme_ = submatch(match, 1);
- toLower(scheme_);
-
- std::string authorityAndPath(match[2].first, match[2].second);
- std::smatch authorityAndPathMatch;
- if (!std::regex_match(
- authorityAndPath, authorityAndPathMatch, authorityAndPathRegex)) {
- // Does not start with //, doesn't have authority
- hasAuthority_ = false;
- path_ = authorityAndPath;
- } else {
- static const std::regex authorityRegex(
- "(?:([^@:]*)(?::([^@]*))?@)?" // username, password
- "(\\[[^\\]]*\\]|[^\\[:]*)" // host (IP-literal (e.g. '['+IPv6+']',
- // dotted-IPv4, or named host)
- "(?::(\\d*))?"); // port
-
- auto authority = authorityAndPathMatch[1];
- std::smatch authorityMatch;
- if (!std::regex_match(authority.first,
- authority.second,
- authorityMatch,
- authorityRegex)) {
- throw std::invalid_argument("Invalid URI authority");
- }
-
- std::string port(authorityMatch[4].first, authorityMatch[4].second);
- if (!port.empty()) {
- int iport = std::stoi(port);
- if (iport < UINT16_MAX && iport >= 0) {
- port_ = static_cast<uint16_t>(iport);
- }
- }
-
- hasAuthority_ = true;
- username_ = submatch(authorityMatch, 1);
- password_ = submatch(authorityMatch, 2);
- host_ = submatch(authorityMatch, 3);
- path_ = submatch(authorityAndPathMatch, 2);
- }
-
- query_ = submatch(match, 3);
- fragment_ = submatch(match, 4);
-}
-
-std::string Uri::authority() const {
- std::string result;
-
- // Port is 5 characters max and we have up to 3 delimiters.
- result.reserve(host().size() + username().size() + password().size() + 8);
-
- if (!username().empty() || !password().empty()) {
- result.append(username());
-
- if (!password().empty()) {
- result.push_back(':');
- result.append(password());
- }
-
- result.push_back('@');
- }
-
- result.append(host());
-
- if (port() != 0) {
- result.push_back(':');
- result.append(std::to_string(port()));
- }
-
- return result;
-}
-
-std::string Uri::hostname() const {
- if (host_.size() > 0 && host_[0] == '[') {
- return host_.substr(1, host_.size() - 2);
- }
- return host_;
-}
-
-const std::vector<std::pair<std::string, std::string>>& Uri::getQueryParams() {
- if (!query_.empty() && queryParams_.empty()) {
- // Parse query string
- static const std::regex queryParamRegex(
- "(^|&)" /*start of query or start of parameter "&"*/
- "([^=&]*)=?" /*parameter name and "=" if value is expected*/
- "([^=&]*)" /*parameter value*/
- "(?=(&|$))" /*forward reference, next should be end of query or
- start of next parameter*/);
- std::cregex_iterator paramBeginItr(
- query_.data(), query_.data() + query_.size(), queryParamRegex);
- std::cregex_iterator paramEndItr;
- for (auto itr = paramBeginItr; itr != paramEndItr; itr++) {
- if (itr->length(2) == 0) {
- // key is empty, ignore it
- continue;
- }
- queryParams_.emplace_back(
- std::string((*itr)[2].first, (*itr)[2].second), // parameter name
- std::string((*itr)[3].first, (*itr)[3].second) // parameter value
- );
- }
- }
- return queryParams_;
-}
-
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-namespace osquery {
-
-/**
- * Class representing a URI.
- * This URI class is from folly/uri.
- *
- * Consider http://www.facebook.com/foo/bar?key=foo#anchor
- *
- * The URI is broken down into its parts: scheme ("http"), authority
- * (ie. host and port, in most cases: "www.facebook.com"), path
- * ("/foo/bar"), query ("key=foo") and fragment ("anchor"). The scheme is
- * lower-cased.
- *
- * If this Uri represents a URL, note that, to prevent ambiguity, the component
- * parts are NOT percent-decoded; you should do this yourself with
- * uriUnescape() (for the authority and path) and uriUnescape(...,
- * UriEscapeMode::QUERY) (for the query, but probably only after splitting at
- * '&' to identify the individual parameters).
- */
-class Uri {
- public:
- /**
- * Parse a Uri from a string. Throws std::invalid_argument on parse error.
- */
- explicit Uri(const std::string& str);
-
- const std::string& scheme() const {
- return scheme_;
- }
- const std::string& username() const {
- return username_;
- }
- const std::string& password() const {
- return password_;
- }
- /**
- * Get host part of URI. If host is an IPv6 address, square brackets will be
- * returned, for example: "[::1]".
- */
- const std::string& host() const {
- return host_;
- }
- /**
- * Get host part of URI. If host is an IPv6 address, square brackets will not
- * be returned, for example "::1"; otherwise it returns the same thing as
- * host().
- *
- * hostname() is what one needs to call if passing the host to any other tool
- * or API that connects to that host/port; e.g. getaddrinfo() only understands
- * IPv6 host without square brackets
- */
- std::string hostname() const;
- uint16_t port() const {
- return port_;
- }
- const std::string& path() const {
- return path_;
- }
- const std::string& query() const {
- return query_;
- }
- const std::string& fragment() const {
- return fragment_;
- }
-
- std::string authority() const;
-
- void setPort(uint16_t port) {
- hasAuthority_ = true;
- port_ = port;
- }
-
- /**
- * Get query parameters as key-value pairs.
- * e.g. for URI containing query string: key1=foo&key2=&key3&=bar&=bar=
- * In returned list, there are 3 entries:
- * "key1" => "foo"
- * "key2" => ""
- * "key3" => ""
- * Parts "=bar" and "=bar=" are ignored, as they are not valid query
- * parameters. "=bar" is missing parameter name, while "=bar=" has more than
- * one equal signs, we don't know which one is the delimiter for key and
- * value.
- *
- * Note, this method is not thread safe, it might update internal state, but
- * only the first call to this method update the state. After the first call
- * is finished, subsequent calls to this method are thread safe.
- *
- * @return query parameter key-value pairs in a vector, each element is a
- * pair of which the first element is parameter name and the second
- * one is parameter value
- */
- const std::vector<std::pair<std::string, std::string>>& getQueryParams();
-
- private:
- std::string scheme_;
- std::string username_;
- std::string password_;
- std::string host_;
- bool hasAuthority_;
- uint16_t port_;
- std::string path_;
- std::string query_;
- std::string fragment_;
- std::vector<std::pair<std::string, std::string>> queryParams_;
-};
-
-} // namespace osquery
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed in accordance with the terms specified in
- * the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-// clang-format off
-// Keep it on top of all other includes to fix double include WinSock.h header file
-// which is windows specific boost build problem
-#include <osquery/remote/transports/tls.h>
-// clang-format on
-
-#include <osquery/enroll.h>
-#include <osquery/flags.h>
-#include <osquery/system.h>
-
-#include <osquery/process/process.h>
-#include <osquery/remote/requests.h>
-
-namespace osquery {
-
-DECLARE_string(tls_enroll_override);
-DECLARE_string(tls_hostname);
-DECLARE_bool(tls_node_api);
-DECLARE_bool(tls_secret_always);
-DECLARE_bool(disable_reenrollment);
-
-/**
- * @brief Helper class for allowing TLS plugins to easily kick off requests
- *
- * There are many static functions in this class that have very similar
- * behavior, which allow them to be used in many context. Some methods accept
- * parameters, some don't require them. Some have built-in retry logic, some
- * don't.
- */
-class TLSRequestHelper : private boost::noncopyable {
- public:
- /**
- * @brief Using the `tls_hostname` flag and an endpoint, construct a URI
- *
- * @param endpoint is the URI endpoint to be combined with `tls_hostname`
- * @return a string representing the uri
- */
- static std::string makeURI(const std::string& endpoint) {
- auto node_key = getNodeKey("tls");
- auto uri = "https://" + FLAGS_tls_hostname;
- if (FLAGS_tls_node_api) {
- // The TLS API should treat clients as nodes.
- // In this case the node_key acts as an identifier (node) and the
- // endpoints
- // (if provided) are treated as edges from the nodes.
- uri += "/" + node_key;
- }
- uri += endpoint;
-
- // Some APIs may require persistent identification.
- if (FLAGS_tls_secret_always) {
- uri += ((uri.find('?') != std::string::npos) ? "&" : "?") +
- FLAGS_tls_enroll_override + "=" + getEnrollSecret();
- }
- return uri;
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param params is a JSON object containing the params to send to the server.
- * This isn't const because it will be modified to include node_key.
- * @param output is the JSON which will be populated with the deserialized
- * results
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri, JSON& params, JSON& output) {
- auto& params_doc = params.doc();
- auto& output_doc = output.doc();
-
- auto node_key = getNodeKey("tls");
-
- // If using a GET request, append the node_key to the URI variables.
- std::string uri_suffix;
- if (FLAGS_tls_node_api) {
- uri_suffix = "&node_key=" + node_key;
- } else {
- params.add("node_key", node_key);
- }
-
- // Again check for GET to call with/without parameters.
- Request<TLSTransport, TSerializer> request(uri + uri_suffix);
- request.setOption("hostname", FLAGS_tls_hostname);
-
- bool compress = false;
- auto it = params_doc.FindMember("_compress");
- if (it != params_doc.MemberEnd()) {
- compress = true;
- request.setOption("compress", compress);
- params_doc.RemoveMember("_compress");
- }
-
- // The caller-supplied parameters may force a POST request.
- bool force_post = false;
- it = params_doc.FindMember("_verb");
- if (it != params_doc.MemberEnd()) {
- assert(it->value.IsString());
-
- force_post = std::string(it->value.GetString()) == "POST";
- params_doc.RemoveMember("_verb");
- }
-
- bool use_post = true;
- it = params_doc.FindMember("_get");
- if (it != params_doc.MemberEnd()) {
- use_post = false;
- params_doc.RemoveMember("_get");
- }
- bool should_post = (use_post || force_post);
- auto status = (should_post) ? request.call(params) : request.call();
-
- // Restore caller-supplied parameters.
- if (force_post) {
- params.add("_verb", "POST");
- }
-
- if (compress) {
- params.add("_compress", true);
- }
-
- if (!status.ok()) {
- return status;
- }
-
- // The call succeeded, store the enrolled key.
- status = request.getResponse(output);
- if (!status.ok()) {
- return status;
- }
-
- // Receive config or key rejection
- it = output_doc.FindMember("node_invalid");
- if (it != output_doc.MemberEnd()) {
- assert(it->value.IsBool());
-
- if (it->value.GetBool()) {
- if (!FLAGS_disable_reenrollment) {
- clearNodeKey();
- }
-
- std::string message = "Request failed: Invalid node key";
-
- it = output_doc.FindMember("error");
- if (it != output_doc.MemberEnd()) {
- message +=
- ": " + std::string(it->value.IsString() ? it->value.GetString()
- : "<unknown>");
- }
-
- return Status(1, message);
- }
- }
-
- it = output_doc.FindMember("error");
- if (it != output_doc.MemberEnd()) {
- std::string message =
- "Request failed: " + std::string(it->value.IsString()
- ? it->value.GetString()
- : "<unknown>");
-
- return Status(1, message);
- }
-
- return Status::success();
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param output is a JSON object containing the output from the server
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri, JSON& output) {
- JSON params;
- params.add("_get", true);
- return TLSRequestHelper::go<TSerializer>(uri, params, output);
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param params is a JSON object containing the params to send to the server.
- * This isn't const because it will be modified to include node_key.
- * @param output is the string which will be populated with the deserialized
- * results
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri, JSON& params, std::string& output) {
- JSON recv;
- auto s = TLSRequestHelper::go<TSerializer>(uri, params, recv);
- if (s.ok()) {
- auto serializer = TSerializer();
- return serializer.serialize(recv, output);
- }
- return s;
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param output is the string which will be populated with the deserialized
- * results
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri, std::string& output) {
- JSON params;
- params.add("_get", true);
- return TLSRequestHelper::go<TSerializer>(uri, params, output);
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param params is a JSON object containing the params to send to the server.
- * This isn't const because it will be modified to include node_key.
- * @param output is the string which will be populated with the deserialized
- * results
- * @param attempts is the number of attempts to make if the request fails
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri,
- JSON& params,
- std::string& output,
- const size_t attempts) {
- Status s;
- JSON override_params;
- const auto& params_doc = params.doc();
- const auto& override_params_doc = override_params.doc();
-
- for (auto& m : params_doc.GetObject()) {
- std::string name = m.name.GetString();
- if (name.find('_') == 0) {
- override_params.add(name, m.value);
- }
- }
-
- for (size_t i = 1; i <= attempts; i++) {
- s = TLSRequestHelper::go<TSerializer>(uri, params, output);
- if (s.ok()) {
- return s;
- }
- if (i == attempts) {
- break;
- }
- for (auto& m : override_params_doc.GetObject()) {
- params.add(m.name.GetString(), m.value);
- }
- sleepFor(i * i * 1000);
- }
- return s;
- }
-
- /**
- * @brief Send a TLS request
- *
- * @param uri is the URI to send the request to
- * @param output is the string which will be populated with the deserialized
- * results
- * @param attempts is the number of attempts to make if the request fails
- *
- * @return a Status object indicating the success or failure of the operation
- */
- template <class TSerializer>
- static Status go(const std::string& uri,
- std::string& output,
- const size_t attempts) {
- JSON params;
- params.add("_get", true);
- return TLSRequestHelper::go<TSerializer>(uri, params, output, attempts);
- }
-};
-}
EXPECT_EQ("(`foo` INTEGER, `bar` TEXT)", table->columnDefinition(false));
}
-TEST_F(VirtualTableTests, test_extension_tableplugin_columndefinition) {
- auto table = std::make_shared<sampleTablePlugin>();
- EXPECT_EQ("(`foo` INTEGER, `bar` TEXT)", table->columnDefinition(true));
-}
-
class optionsTablePlugin : public TablePlugin {
private:
TableColumns columns() const override {
}
namespace {
-/// A list of tables that come from extensions; it is used to determine which
-/// table can be read/write
-class TableList final {
- std::unordered_set<std::string> table_list;
- mutable Mutex mutex;
-
- public:
- void insert(const std::string& table) {
- WriteLock write_lock(mutex);
- table_list.insert(table);
- }
-
- bool contains(const std::string& table_name) const {
- ReadLock lock(mutex);
-
- return (std::find(table_list.begin(), table_list.end(), table_name) !=
- table_list.end());
- }
-};
-
-TableList extension_table_list;
// A map containing an sqlite module object for each virtual table
std::unordered_map<std::string, struct sqlite3_module> sqlite_module_map;
return SQLITE_ERROR;
}
- // Tables implemented from extensions can be made read/write if they implement
- // the correct methods
- bool is_extension = extension_table_list.contains(name);
+ bool is_extension = false;
// Generate an SQL create table statement from the retrieved column details.
// This call to columnDefinition requests column aliases (as HIDDEN columns).
// Allow the table to receive INSERT/UPDATE/DROP events if it is
// implemented from an extension and is overwriting the right methods
// in the TablePlugin class
- if (extension) {
- extension_table_list.insert(table_name);
- sqlite_module_map[table_name].xUpdate = tables::sqlite::xUpdate;
- }
return &sqlite_module_map[table_name];
}
std::string kTestDataPath{"../../../tools/tests/"};
DECLARE_string(database_path);
-DECLARE_string(extensions_socket);
-DECLARE_string(extensions_autoload);
DECLARE_string(enroll_tls_endpoint);
DECLARE_bool(disable_logging);
DECLARE_bool(disable_database);
fs::remove_all(kTestWorkingDirectory);
fs::create_directories(kTestWorkingDirectory);
FLAGS_database_path = kTestWorkingDirectory + "unittests.db";
- FLAGS_extensions_socket = kTestWorkingDirectory + "unittests.em";
- FLAGS_extensions_autoload = kTestWorkingDirectory + "unittests-ext.load";
FLAGS_disable_logging = true;
FLAGS_disable_database = true;