2 * Copyright (c) 2018-present, Facebook, Inc.
5 * This source code is licensed in accordance with the terms specified in
6 * the LICENSE file found in the root directory of this source tree.
9 #include <osquery/core.h>
10 #include <osquery/registry_factory.h>
15 #include <vist/logger.hpp>
16 #include <osquery/registry.h>
17 #include <osquery/utils/conversions/split.h>
18 #include <osquery/utils/json/json.h>
22 RegistryFactory& RegistryFactory::get() {
23 static RegistryFactory instance;
27 void RegistryFactory::add(const std::string& name, RegistryInterfaceRef reg) {
29 throw std::runtime_error("Cannot add duplicate registry: " + name);
31 registries_[name] = std::move(reg);
34 RegistryInterfaceRef RegistryFactory::registry(const std::string& t) const {
36 throw std::runtime_error("Unknown registry requested: " + t);
38 return registries_.at(t);
41 std::map<std::string, RegistryInterfaceRef> RegistryFactory::all() const {
45 std::map<std::string, PluginRef> RegistryFactory::plugins(
46 const std::string& registry_name) const {
47 return registry(registry_name)->plugins();
50 PluginRef RegistryFactory::plugin(const std::string& registry_name,
51 const std::string& item_name) const {
52 return registry(registry_name)->plugin(item_name);
55 /// Adds an alias for an internal registry item. This registry will only
56 /// broadcast the alias name.
57 Status RegistryFactory::addAlias(const std::string& registry_name,
58 const std::string& item_name,
59 const std::string& alias) {
60 if (!exists(registry_name)) {
61 return Status(1, "Unknown registry: " + registry_name);
63 return registries_.at(registry_name)->addAlias(item_name, alias);
66 /// Returns the item_name or the item alias if an alias exists.
67 std::string RegistryFactory::getAlias(const std::string& registry_name,
68 const std::string& alias) const {
69 if (!exists(registry_name)) {
72 return registries_.at(registry_name)->getAlias(alias);
75 Status RegistryFactory::call(const std::string& registry_name,
76 const std::string& item_name,
77 const PluginRequest& request,
78 PluginResponse& response) {
79 // Forward factory call to the registry.
81 if (item_name.find(',') != std::string::npos) {
82 // Call is multiplexing plugins (usually for multiple loggers).
83 for (const auto& item : osquery::split(item_name, ",")) {
84 get().registry(registry_name)->call(item, request, response);
86 // All multiplexed items are called without regard for statuses.
89 return get().registry(registry_name)->call(item_name, request, response);
90 } catch (const std::exception& e) {
91 ERROR(OSQUERY) << registry_name << " registry " << item_name
92 << " plugin caused exception: " << e.what();
93 return Status(1, e.what());
95 ERROR(OSQUERY) << registry_name << " registry " << item_name
96 << " plugin caused unknown exception";
97 return Status(2, "Unknown exception");
101 Status RegistryFactory::call(const std::string& registry_name,
102 const std::string& item_name,
103 const PluginRequest& request) {
104 PluginResponse response;
105 // Wrapper around a call expecting a response.
106 return call(registry_name, item_name, request, response);
109 Status RegistryFactory::call(const std::string& registry_name,
110 const PluginRequest& request,
111 PluginResponse& response) {
112 auto plugin = get().registry(registry_name)->getActive();
113 return call(registry_name, plugin, request, response);
116 Status RegistryFactory::call(const std::string& registry_name,
117 const PluginRequest& request) {
118 PluginResponse response;
119 return call(registry_name, request, response);
122 Status RegistryFactory::setActive(const std::string& registry_name,
123 const std::string& item_name) {
124 WriteLock lock(mutex_);
125 return registry(registry_name)->setActive(item_name);
128 std::string RegistryFactory::getActive(const std::string& registry_name) const {
129 return registry(registry_name)->getActive();
132 void RegistryFactory::setUp() {
133 for (const auto& registry : get().all()) {
134 registry.second->setUp();
138 bool RegistryFactory::exists(const std::string& registry_name,
139 const std::string& item_name,
141 if (!exists(registry_name)) {
145 // Check the registry.
146 return registry(registry_name)->exists(item_name, local);
149 std::vector<std::string> RegistryFactory::names() const {
150 std::vector<std::string> names;
151 for (const auto& registry : all()) {
152 names.push_back(registry.second->getName());
157 std::vector<std::string> RegistryFactory::names(
158 const std::string& registry_name) const {
159 if (registries_.at(registry_name) == nullptr) {
160 std::vector<std::string> names;
163 return registry(registry_name)->names();
166 size_t RegistryFactory::count(const std::string& registry_name) const {
167 if (!exists(registry_name)) {
170 return registry(registry_name)->count();
173 } // namespace osquery