2015-02-26 22:10:39 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <boost/algorithm/string/trim.hpp>
|
|
|
|
|
|
|
|
#include <osquery/filesystem.h>
|
|
|
|
#include <osquery/tables.h>
|
|
|
|
|
|
|
|
#include "osquery/tables/system/sysctl_utils.h"
|
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
namespace tables {
|
|
|
|
|
|
|
|
const std::vector<std::string> kControlSettingsFiles = {"/etc/sysctl.conf"};
|
|
|
|
|
|
|
|
const std::vector<std::string> kControlSettingsDirs = {
|
|
|
|
"/run/sysctl.d/%.conf",
|
|
|
|
"/etc/sysctl.d/%.conf",
|
|
|
|
"/usr/local/lib/sysctl.d/%.conf",
|
|
|
|
"/usr/lib/sysctl.d/%.conf",
|
|
|
|
"/lib/sysctl.d/%.conf",
|
|
|
|
};
|
|
|
|
|
|
|
|
std::string stringFromMIB(const int* oid, size_t oid_size) {
|
|
|
|
std::string result;
|
|
|
|
for (size_t i = 0; i < oid_size; ++i) {
|
|
|
|
// Walk an int-encoded MIB and return the string representation, '.'.
|
|
|
|
if (result.size() > 0) {
|
|
|
|
result += ".";
|
|
|
|
}
|
|
|
|
result += std::to_string(oid[i]);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-04-17 00:40:19 +00:00
|
|
|
void genControlInfoFromOIDString(
|
|
|
|
const std::string& oid_string,
|
|
|
|
QueryData& results,
|
|
|
|
const std::map<std::string, std::string>& config) {
|
2015-02-26 22:10:39 +00:00
|
|
|
int request[CTL_DEBUG_MAXID + 2] = {0};
|
|
|
|
auto tokens = osquery::split(oid_string, ".");
|
|
|
|
if (tokens.size() > CTL_DEBUG_MAXID) {
|
|
|
|
// OID input string was too large.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert the string into an int array.
|
|
|
|
for (size_t i = 0; i < tokens.size(); ++i) {
|
|
|
|
request[i] = atol(tokens.at(i).c_str());
|
|
|
|
}
|
|
|
|
genControlInfo((int*)request, tokens.size(), results, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
void genControlConfigFromPath(const std::string& path,
|
|
|
|
std::map<std::string, std::string>& config) {
|
|
|
|
std::string content;
|
|
|
|
if (!osquery::readFile(path, content).ok()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& line : split(content, "\n")) {
|
|
|
|
boost::trim(line);
|
|
|
|
if (line[0] == '#' || line[0] == ';') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to tokenize the config line using '='.
|
|
|
|
auto detail = split(line, "=");
|
|
|
|
if (detail.size() == 2) {
|
|
|
|
boost::trim(detail[0]);
|
|
|
|
boost::trim(detail[1]);
|
|
|
|
config[detail[0]] = detail[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryData genSystemControls(QueryContext& context) {
|
|
|
|
QueryData results;
|
|
|
|
|
|
|
|
// Read the sysctl.conf values.
|
|
|
|
std::map<std::string, std::string> config;
|
|
|
|
for (const auto& path : kControlSettingsFiles) {
|
|
|
|
genControlConfigFromPath(path, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& dirs : kControlSettingsDirs) {
|
|
|
|
std::vector<std::string> configs;
|
|
|
|
if (resolveFilePattern(dirs, configs).ok()) {
|
|
|
|
for (const auto& path : configs) {
|
|
|
|
genControlConfigFromPath(path, config);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate through the sysctl-defined macro of control types.
|
2015-05-29 20:47:04 +00:00
|
|
|
if (context.constraints["name"].exists(EQUALS)) {
|
2015-02-26 22:10:39 +00:00
|
|
|
// Request MIB information by the description (name).
|
|
|
|
auto names = context.constraints["name"].getAll(EQUALS);
|
|
|
|
for (const auto& name : names) {
|
|
|
|
genControlInfoFromName(name, results, config);
|
|
|
|
}
|
2015-05-29 20:47:04 +00:00
|
|
|
} else if (context.constraints["oid"].exists(EQUALS)) {
|
2015-02-26 22:10:39 +00:00
|
|
|
// Request MIB by OID as a string, parse into set of INTs.
|
|
|
|
auto oids = context.constraints["oid"].getAll(EQUALS);
|
|
|
|
for (const auto& oid_string : oids) {
|
|
|
|
genControlInfoFromOIDString(oid_string, results, config);
|
|
|
|
}
|
2015-05-29 20:47:04 +00:00
|
|
|
} else if (context.constraints["subsystem"].exists(EQUALS)) {
|
2015-02-26 22:10:39 +00:00
|
|
|
// Limit the MIB search to a subsystem name (first find the INT).
|
|
|
|
auto subsystems = context.constraints["subsystem"].getAll(EQUALS);
|
|
|
|
for (const auto& subsystem : subsystems) {
|
|
|
|
genAllControls(results, config, subsystem);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
genAllControls(results, config, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|