ADD_SUBDIRECTORY(events)
ADD_SUBDIRECTORY(filesystem)
ADD_SUBDIRECTORY(hashing)
-ADD_SUBDIRECTORY(killswitch)
ADD_SUBDIRECTORY(logger)
ADD_SUBDIRECTORY(numeric_monitoring)
ADD_SUBDIRECTORY(plugins)
#include <osquery/flagalias.h>
#include <osquery/flags.h>
#include <osquery/hashing/hashing.h>
-#include <osquery/killswitch.h>
#include <osquery/logger.h>
#include <osquery/packs.h>
#include <osquery/registry.h>
}
loaded_ = true;
- if (Killswitch::get().isConfigBackupEnabled()) {
- if (FLAGS_config_enable_backup && is_first_time_refresh.exchange(false)) {
- const auto result = restoreConfigBackup();
- if (!result) {
- return Status::failure(result.getError().getMessage());
- } else {
- update(*result);
- }
- }
- } else {
- LOG(INFO) << "Config backup is disabled by the killswitch";
- }
-
return status;
} else if (getRefresh() != FLAGS_config_refresh) {
VLOG(1) << "Normal configuration delay restored";
#include <osquery/events.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
-#include <osquery/killswitch.h>
#include <osquery/numeric_monitoring.h>
#include <osquery/process/process.h>
#include <osquery/registry.h>
DECLARE_string(config_plugin);
DECLARE_string(logger_plugin);
DECLARE_string(numeric_monitoring_plugins);
-DECLARE_string(killswitch_plugin);
DECLARE_bool(config_check);
DECLARE_bool(config_dump);
DECLARE_bool(database_dump);
DECLARE_bool(disable_database);
DECLARE_bool(disable_events);
DECLARE_bool(disable_logging);
-DECLARE_bool(enable_killswitch);
DECLARE_bool(enable_numeric_monitoring);
CLI_FLAG(bool, S, false, "Run as a shell process");
initLogger(binary_);
}
- if (FLAGS_enable_killswitch) {
- initActivePlugin("killswitch", FLAGS_killswitch_plugin);
- }
if (FLAGS_enable_numeric_monitoring) {
initActivePlugin(monitoring::registryName(),
FLAGS_numeric_monitoring_plugins);
}
- if (Killswitch::get().isAppStartMonitorEnabled()) {
- monitoring::record("osquery.start", 1, monitoring::PreAggregationType::Sum);
- }
-
// Start event threads.
osquery::attachEvents();
EventFactory::delay();
#include <osquery/data_logger.h>
#include <osquery/database.h>
#include <osquery/flags.h>
-#include <osquery/killswitch.h>
#include <osquery/numeric_monitoring.h>
#include <osquery/process/process.h>
#include <osquery/query.h>
+++ /dev/null
-/**
- * Copyright (c) 2014-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under both the Apache 2.0 license (found in
- * the LICENSE file in the root directory of this source tree) and the GPLv2
- * may select, at your option, one of the above-listed licenses.
- */
-
-#pragma once
-
-#include <string>
-
-#include <boost/core/noncopyable.hpp>
-#include <gtest/gtest_prod.h>
-
-#include <osquery/core.h>
-#include <osquery/utils/expected/expected.h>
-#include <osquery/utils/status/status.h>
-
-namespace osquery {
-
-class Killswitch : private boost::noncopyable {
- public:
- static const char* killswitch_;
- static const char* action_;
- static const char* isEnabled_;
- static const char* key_;
- static const char* refresh_;
-
- private:
- Killswitch();
-
- public:
- virtual ~Killswitch();
-
- // Author: @guliashvili
- // Creation Time: 5/09/2018
- bool isPosixProfilingEnabled();
-
- // Author: @guliashvili
- // Creation Time: 4/09/2018
- bool isTotalQueryCounterMonitorEnabled();
-
- // Author: @guliashvili
- // Creation Time: 3/09/2018
- bool isAppStartMonitorEnabled();
-
- // Author: @guliashvili
- // Creation Time: 3/09/2018
- bool isWindowsProfilingEnabled();
-
- // Author: @guliashvili
- // Creation Time: 24/08/2018
- bool isConfigBackupEnabled();
-
- static Killswitch& get() {
- static Killswitch killswitch;
- return killswitch;
- }
-
- Status refresh();
-
- private:
- bool isNewCodeEnabled(const std::string& key);
-
- enum class IsEnabledError {
- CallFailed = 1,
- IncorrectResponseFormat = 2,
- IncorrectValue = 3
- };
- Expected<bool, Killswitch::IsEnabledError> isEnabled(const std::string& key);
-
- FRIEND_TEST(KillswitchTests, test_killswitch_plugin);
-};
-
-} // namespace osquery
+++ /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_killswitch killswitch.cpp
- killswitch_plugin.cpp
- killswitch_refreshable_plugin.cpp)
-
-FILE(GLOB OSQUERY_KS_TESTS "tests/*.cpp")
-ADD_OSQUERY_TEST(${OSQUERY_KS_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 <string>
-
-#include <osquery/flags.h>
-#include <osquery/killswitch.h>
-#include <osquery/logger.h>
-#include <osquery/registry_factory.h>
-
-namespace osquery {
-
-const char* Killswitch::killswitch_ = "killswitch";
-const char* Killswitch::action_ = "action";
-const char* Killswitch::isEnabled_ = "isEnabled";
-const char* Killswitch::key_ = "key";
-const char* Killswitch::refresh_ = "refresh";
-
-FLAG(bool, enable_killswitch, false, "Enable killswitch plugin");
-FLAG(string,
- killswitch_plugin,
- "killswitch_filesystem",
- "Killswitch plugin name.");
-
-Killswitch::Killswitch() {}
-Killswitch::~Killswitch() = default;
-
-bool Killswitch::isPosixProfilingEnabled() {
- return isNewCodeEnabled("posixProfilingSwitch");
-}
-
-bool Killswitch::isTotalQueryCounterMonitorEnabled() {
- return isNewCodeEnabled("totalQueryCounterMonitorSwitch");
-}
-
-bool Killswitch::isAppStartMonitorEnabled() {
- return isNewCodeEnabled("appStartMonitorSwitch");
-}
-
-bool Killswitch::isWindowsProfilingEnabled() {
- return isNewCodeEnabled("windowsProfilingSwitch");
-}
-
-bool Killswitch::isConfigBackupEnabled() {
- return isNewCodeEnabled("configBackupSwitch");
-}
-
-bool Killswitch::isNewCodeEnabled(const std::string& key) {
- auto result = isEnabled(key);
- if (result) {
- return *result;
- } else {
- VLOG(1) << result.getError().getMessage();
- return true;
- }
-}
-
-Expected<bool, Killswitch::IsEnabledError> Killswitch::isEnabled(
- const std::string& key) {
- PluginResponse response;
- auto status = Registry::call(
- Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::isEnabled_}, {Killswitch::key_, key}},
- response);
- if (!status.ok()) {
- return createError(Killswitch::IsEnabledError::CallFailed)
- << status.getMessage();
- }
-
- if (response.size() != 1) {
- return createError(Killswitch::IsEnabledError::IncorrectResponseFormat)
- << "Response size should be 1 but is "
- << std::to_string(response.size());
- }
- const auto& response_map = response[0];
- const auto& is_enabled_item = response_map.find(Killswitch::isEnabled_);
- if (is_enabled_item == response_map.end()) {
- return createError(Killswitch::IsEnabledError::IncorrectResponseFormat)
- << "isEnabled key missing in response of the action: isEnabled";
- }
-
- const auto& is_enabled_value = is_enabled_item->second;
- if (is_enabled_value == "1") {
- return true;
- } else if (is_enabled_value == "0") {
- return false;
- } else {
- return createError(Killswitch::IsEnabledError::IncorrectValue)
- << "Unknown isEnabled value " << is_enabled_value;
- }
-}
-
-Status Killswitch::refresh() {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::refresh_}},
- response);
- return status;
-}
-
-} // 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 <string>
-
-#include <osquery/flags.h>
-#include <osquery/killswitch/killswitch_plugin.h>
-#include <osquery/registry_factory.h>
-
-namespace osquery {
-
-CREATE_REGISTRY(KillswitchPlugin, Killswitch::killswitch_);
-
-Expected<std::unordered_map<std::string, bool>,
- KillswitchPlugin::ParseMapJSONError>
-KillswitchPlugin::parseMapJSON(const std::string& content) {
- std::unordered_map<std::string, bool> result;
-
- auto doc = JSON::newObject();
- if (!doc.fromString(content) || !doc.doc().IsObject()) {
- return createError(
- KillswitchPlugin::ParseMapJSONError::UnknownParsingProblem)
- << "Error parsing the killswitch JSON. Content : " << content;
- }
-
- const auto table = doc.doc().FindMember("table");
- if (table == doc.doc().MemberEnd()) {
- return createError(KillswitchPlugin::ParseMapJSONError::MissingKey)
- << "Killswitch key table containing map was not found";
- }
- if (!table->value.IsObject()) {
- return createError(KillswitchPlugin::ParseMapJSONError::IncorrectValueType)
- << "Killswitch table value is not an object";
- }
-
- for (const auto& keyValue : table->value.GetObject()) {
- if (!keyValue.name.IsString()) {
- return createError(KillswitchPlugin::ParseMapJSONError::IncorrectKeyType)
- << "Killswitch config key was not string";
- }
- auto key = keyValue.name.GetString();
- if (!keyValue.value.IsBool()) {
- return createError(
- KillswitchPlugin::ParseMapJSONError::IncorrectValueType)
- << "At Killswitch config key: " << key << " value was not bool";
- }
- bool value = keyValue.value.GetBool();
- result[key] = value;
- }
-
- return result;
-}
-
-Status KillswitchPlugin::call(const PluginRequest& request,
- PluginResponse& response) {
- auto action = request.find(Killswitch::action_);
- if (action == request.end()) {
- return Status(1, "Killswitch plugins require an action");
- }
- if (action->second == Killswitch::isEnabled_) {
- auto key = request.find(Killswitch::key_);
- if (key == request.end()) {
- return Status(1, "isEnabled action requires key");
- }
-
- auto result = isEnabled(key->second);
-
- if (result) {
- response.push_back({{Killswitch::isEnabled_, std::to_string(*result)}});
- return Status::success();
- } else {
- return Status::failure(result.getError().getMessage());
- }
- }
- return Status(1, "Could not find appropriate action mapping");
-}
-
-void KillswitchPlugin::setCache(
- const std::unordered_map<std::string, bool>& killswitchMap) {
- WriteLock wlock(mutex_);
- killswitchMap_ = killswitchMap;
-}
-
-void KillswitchPlugin::addCacheEntry(const std::string& key, bool value) {
- WriteLock wlock(mutex_);
- killswitchMap_[key] = value;
-}
-
-Expected<bool, KillswitchPlugin::IsEnabledError> KillswitchPlugin::isEnabled(
- const std::string& key) {
- ReadLock rlock(mutex_);
- if (killswitchMap_.find(key) != killswitchMap_.end()) {
- return killswitchMap_[key];
- } else {
- return createError(KillswitchPlugin::IsEnabledError::NoKeyFound)
- << "Could not find key " << key;
- }
-}
-
-} // 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 <unordered_map>
-
-#include <gtest/gtest_prod.h>
-
-#include <osquery/core.h>
-#include <osquery/killswitch.h>
-#include <osquery/plugins/plugin.h>
-#include <osquery/query.h>
-#include <osquery/utils/expected/expected.h>
-#include <osquery/utils/mutex.h>
-
-namespace osquery {
-
-/**
- * @brief Interface class for killswitch plugins.
- */
-class KillswitchPlugin : public Plugin {
- public:
- /// Main entrypoint for killswitch plugin requests
- virtual Status call(const PluginRequest& request,
- PluginResponse& response) override;
-
- protected:
- void addCacheEntry(const std::string& key, bool value);
- void setCache(const std::unordered_map<std::string, bool>& killswitchMap);
-
- enum class ParseMapJSONError {
- IncorrectKeyType = 1,
- IncorrectValueType = 2,
- UnknownParsingProblem = 3,
- MissingKey = 4
- };
- static Expected<std::unordered_map<std::string, bool>, ParseMapJSONError>
- parseMapJSON(const std::string& content);
-
- private:
- enum class IsEnabledError { NoKeyFound = 1 };
- Expected<bool, IsEnabledError> isEnabled(const std::string& key);
- std::unordered_map<std::string, bool> killswitchMap_;
- mutable Mutex mutex_;
-
- private:
- FRIEND_TEST(KillswitchTests, test_killswitch_plugin);
- FRIEND_TEST(KillswitchFilesystemTests,
- test_killswitch_filesystem_plugin_legit);
-};
-} // 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 <osquery/dispatcher.h>
-#include <osquery/flags.h>
-#include <osquery/killswitch.h>
-#include <osquery/killswitch/killswitch_refreshable_plugin.h>
-
-namespace osquery {
-
-FLAG(uint32,
- killswitch_refresh_rate,
- 10,
- "Refresh rate of killswitch in seconds");
-
-namespace {
-class KillswitchRefresher : public InternalRunnable {
- public:
- explicit KillswitchRefresher(std::chrono::seconds update_interval)
- : InternalRunnable("KillswitchRefreshRunner"),
- update_interval_(update_interval) {}
- /// A simple wait/interruptible lock.
- void start() override {
- while (!interrupted()) {
- pause(std::chrono::milliseconds(update_interval_));
- osquery::Killswitch::get().refresh();
- }
- }
-
- private:
- const std::chrono::seconds update_interval_;
-};
-} // namespace
-
-Status KillswitchRefreshablePlugin::setUp() {
- if (FLAGS_killswitch_refresh_rate > 0) {
- Dispatcher::addService(std::make_shared<KillswitchRefresher>(
- std::chrono::seconds(FLAGS_killswitch_refresh_rate)));
- }
- return Status::success();
-}
-
-Status KillswitchRefreshablePlugin::call(const PluginRequest& request,
- PluginResponse& response) {
- auto action = request.find(Killswitch::action_);
- if (action == request.end()) {
- return Status::failure("Config plugins require an action");
- }
-
- if (action->second == Killswitch::refresh_) {
- auto result = refresh();
- if (result) {
- return Status::success();
- } else {
- return Status::failure(result.getError().getMessage());
- }
- } else {
- return KillswitchPlugin::call(request, response);
- }
-}
-
-} // 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/utils/expected/expected.h>
-
-#include "osquery/killswitch/killswitch_plugin.h"
-
-namespace osquery {
-
-/**
- * @brief Interface class for killswitch plugins.
- */
-class KillswitchRefreshablePlugin : public KillswitchPlugin {
- public:
- Status setUp() override;
-
- /// Main entrypoint for killswitch plugin requests
- virtual Status call(const PluginRequest& request,
- PluginResponse& response) override;
-
- protected:
- enum class RefreshError { NoContentReached = 1, ParsingError = 2 };
- virtual ExpectedSuccess<RefreshError> refresh() = 0;
-};
-} // 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 <gtest/gtest.h>
-
-#include <osquery/core.h>
-#include <osquery/flags.h>
-#include <osquery/killswitch.h>
-#include <osquery/killswitch/killswitch_plugin.h>
-#include <osquery/registry.h>
-#include <osquery/system.h>
-
-namespace osquery {
-
-DECLARE_uint32(killswitch_refresh_rate);
-
-class KillswitchTests : public testing::Test {
-public:
- void SetUp() override {
- Initializer::platformSetup();
- registryAndPluginInit();
- }
-};
-
-TEST_F(KillswitchTests, test_killswitch_plugin) {
- auto& rf = RegistryFactory::get();
- auto plugin = std::make_shared<KillswitchPlugin>();
- rf.registry(Killswitch::killswitch_)->add("test", plugin);
- EXPECT_TRUE(rf.setActive(Killswitch::killswitch_, "test").ok());
-
- {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::isEnabled_},
- {Killswitch::key_, "testSwitch"}},
- response);
- EXPECT_FALSE(status.ok());
- }
-
- {
- PluginResponse response;
- auto status = Registry::call(
- Killswitch::killswitch_, {{Killswitch::key_, "testSwitch"}}, response);
- EXPECT_FALSE(status.ok());
- }
-
- {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, "testSwitch"}},
- response);
- EXPECT_FALSE(status.ok());
- }
-
- plugin->addCacheEntry("testSwitch", true);
-
- {
- auto result = plugin->isEnabled("testSwitch");
- EXPECT_TRUE(result);
- EXPECT_TRUE(*result);
- EXPECT_TRUE(Killswitch::get().isNewCodeEnabled("testSwitch"));
- }
- {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::isEnabled_},
- {Killswitch::key_, "testSwitch"}},
- response);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ(response[0][Killswitch::isEnabled_], std::string("1"));
- auto result = Killswitch::get().isEnabled("testSwitch");
- EXPECT_TRUE(result);
- EXPECT_TRUE(*result);
- EXPECT_TRUE(Killswitch::get().isNewCodeEnabled("testSwitch"));
- }
-
- plugin->addCacheEntry("testSwitch", false);
-
- {
- auto result = plugin->isEnabled("testSwitch");
- EXPECT_TRUE(result);
- EXPECT_FALSE(*result);
- EXPECT_FALSE(Killswitch::get().isNewCodeEnabled("testSwitch"));
- }
- {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::isEnabled_},
- {Killswitch::key_, "testSwitch"}},
- response);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ(response[0][Killswitch::isEnabled_], std::string("0"));
- auto result = Killswitch::get().isEnabled("testSwitch");
- EXPECT_TRUE(result);
- EXPECT_FALSE(*result);
- EXPECT_FALSE(Killswitch::get().isNewCodeEnabled("testSwitch"));
- }
-
- plugin->setCache(std::unordered_map<std::string, bool>());
-
- {
- PluginResponse response;
- auto status = Registry::call(Killswitch::killswitch_,
- {{Killswitch::action_, Killswitch::isEnabled_},
- {Killswitch::key_, "testSwitch"}},
- response);
- EXPECT_FALSE(status.ok());
- EXPECT_EQ(response.size(), 0);
- auto result = Killswitch::get().isEnabled("testSwitch");
- EXPECT_FALSE(result);
-
- EXPECT_TRUE(Killswitch::get().isNewCodeEnabled("testSwitch"));
- }
-
- EXPECT_FALSE(Killswitch::get().refresh());
-
- rf.registry(Killswitch::killswitch_)->remove("test");
-}
-
-} // namespace osquery
#include <osquery/events.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/flags.h>
-#include <osquery/killswitch.h>
#include <osquery/numeric_monitoring.h>
#include <osquery/plugins/logger.h>
#include <osquery/registry_factory.h>
return Status::success();
}
- if (Killswitch::get().isTotalQueryCounterMonitorEnabled()) {
- monitoring::record(
- kTotalQueryCounterMonitorPath, 1, monitoring::PreAggregationType::Sum);
- }
-
std::vector<std::string> json_items;
Status status;
if (FLAGS_logger_event_type) {
return Status::success();
}
- if (Killswitch::get().isTotalQueryCounterMonitorEnabled()) {
- monitoring::record(
- kTotalQueryCounterMonitorPath, 1, monitoring::PreAggregationType::Sum);
- }
-
std::vector<std::string> json_items;
Status status;
if (FLAGS_logger_snapshot_event_type) {