2014-12-18 18:50:47 +00:00
|
|
|
/*
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2014-12-18 18:50:47 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
2015-04-24 08:44:41 +00:00
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
2014-12-18 18:50:47 +00:00
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
2014-12-01 09:05:46 +00:00
|
|
|
|
2014-12-03 23:14:02 +00:00
|
|
|
#include <osquery/flags.h>
|
2014-12-01 09:05:46 +00:00
|
|
|
|
2015-02-17 08:36:20 +00:00
|
|
|
namespace boost {
|
|
|
|
template <>
|
|
|
|
bool lexical_cast<bool, std::string>(const std::string& arg) {
|
|
|
|
std::istringstream ss(arg);
|
|
|
|
bool b;
|
|
|
|
ss >> std::boolalpha >> b;
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
std::string lexical_cast<std::string, bool>(const bool& b) {
|
|
|
|
std::ostringstream ss;
|
|
|
|
ss << std::boolalpha << b;
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-21 01:03:30 +00:00
|
|
|
namespace flags = GFLAGS_NAMESPACE;
|
|
|
|
|
2014-12-01 09:05:46 +00:00
|
|
|
namespace osquery {
|
|
|
|
|
2015-02-17 08:36:20 +00:00
|
|
|
int Flag::create(const std::string& name, const FlagDetail& flag) {
|
2015-02-17 00:26:06 +00:00
|
|
|
instance().flags_.insert(std::make_pair(name, flag));
|
|
|
|
return 0;
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
|
|
|
|
2015-03-03 23:03:14 +00:00
|
|
|
int Flag::createAlias(const std::string& alias, const FlagDetail& flag) {
|
2015-02-25 04:29:57 +00:00
|
|
|
instance().aliases_.insert(std::make_pair(alias, flag));
|
2015-02-17 00:26:06 +00:00
|
|
|
return 0;
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status Flag::getDefaultValue(const std::string& name, std::string& value) {
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::CommandLineFlagInfo info;
|
|
|
|
if (!flags::GetCommandLineFlagInfo(name.c_str(), &info)) {
|
2015-02-17 00:26:06 +00:00
|
|
|
return Status(1, "Flags name not found.");
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
2015-02-17 00:26:06 +00:00
|
|
|
|
|
|
|
value = info.default_value;
|
2014-12-01 09:05:46 +00:00
|
|
|
return Status(0, "OK");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Flag::isDefault(const std::string& name) {
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::CommandLineFlagInfo info;
|
|
|
|
if (!flags::GetCommandLineFlagInfo(name.c_str(), &info)) {
|
2014-12-01 09:05:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-02-17 00:26:06 +00:00
|
|
|
return info.is_default;
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
|
|
|
|
2014-12-16 09:51:54 +00:00
|
|
|
std::string Flag::getValue(const std::string& name) {
|
|
|
|
std::string current_value;
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::GetCommandLineOption(name.c_str(), ¤t_value);
|
2014-12-16 09:51:54 +00:00
|
|
|
return current_value;
|
|
|
|
}
|
|
|
|
|
2015-02-17 08:36:20 +00:00
|
|
|
std::string Flag::getType(const std::string& name) {
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::CommandLineFlagInfo info;
|
|
|
|
if (!flags::GetCommandLineFlagInfo(name.c_str(), &info)) {
|
2015-02-17 08:36:20 +00:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return info.type;
|
|
|
|
}
|
|
|
|
|
2015-02-25 04:29:57 +00:00
|
|
|
std::string Flag::getDescription(const std::string& name) {
|
|
|
|
if (instance().flags_.count(name)) {
|
|
|
|
return instance().flags_.at(name).description;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (instance().aliases_.count(name)) {
|
2015-03-03 23:03:14 +00:00
|
|
|
return getDescription(instance().aliases_.at(name).description);
|
2015-02-25 04:29:57 +00:00
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2014-12-01 09:05:46 +00:00
|
|
|
Status Flag::updateValue(const std::string& name, const std::string& value) {
|
2015-04-24 08:44:41 +00:00
|
|
|
if (instance().flags_.count(name) > 0) {
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::SetCommandLineOption(name.c_str(), value.c_str());
|
2015-04-24 08:44:41 +00:00
|
|
|
return Status(0, "OK");
|
2015-04-30 01:53:25 +00:00
|
|
|
} else if (instance().aliases_.count(name) > 0) {
|
|
|
|
// Updating a flag by an alias name.
|
|
|
|
auto& real_name = instance().aliases_.at(name).description;
|
2016-03-21 01:03:30 +00:00
|
|
|
flags::SetCommandLineOption(real_name.c_str(), value.c_str());
|
2015-04-30 01:53:25 +00:00
|
|
|
return Status(0, "OK");
|
2015-04-24 08:44:41 +00:00
|
|
|
}
|
|
|
|
return Status(1, "Flag not found");
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
|
|
|
|
2015-02-17 00:26:06 +00:00
|
|
|
std::map<std::string, FlagInfo> Flag::flags() {
|
2016-03-21 01:03:30 +00:00
|
|
|
std::vector<flags::CommandLineFlagInfo> info;
|
|
|
|
flags::GetAllFlags(&info);
|
2015-02-17 00:26:06 +00:00
|
|
|
|
|
|
|
std::map<std::string, FlagInfo> flags;
|
|
|
|
for (const auto& flag : info) {
|
|
|
|
if (instance().flags_.count(flag.name) == 0) {
|
|
|
|
// This flag info was not defined within osquery.
|
|
|
|
continue;
|
|
|
|
}
|
2015-02-17 08:36:20 +00:00
|
|
|
|
|
|
|
// Set the flag info from the internal info kept by Gflags, except for
|
|
|
|
// the stored description. Gflag keeps an "unknown" value if the flag
|
|
|
|
// was declared without a definition.
|
2016-03-21 01:03:30 +00:00
|
|
|
flags[flag.name] = {flag.type, instance().flags_.at(flag.name).description,
|
|
|
|
flag.default_value, flag.current_value,
|
2015-02-17 00:26:06 +00:00
|
|
|
instance().flags_.at(flag.name)};
|
|
|
|
}
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2015-03-03 23:03:14 +00:00
|
|
|
void Flag::printFlags(bool shell, bool external, bool cli) {
|
2016-03-21 01:03:30 +00:00
|
|
|
std::vector<flags::CommandLineFlagInfo> info;
|
|
|
|
flags::GetAllFlags(&info);
|
2015-05-11 08:21:57 +00:00
|
|
|
auto& details = instance().flags_;
|
2015-02-17 00:26:06 +00:00
|
|
|
|
2016-08-24 16:44:16 +00:00
|
|
|
std::map<std::string, const flags::CommandLineFlagInfo*> ordered_info;
|
|
|
|
for (const auto& flag : info) {
|
|
|
|
ordered_info[flag.name] = &flag;
|
|
|
|
}
|
|
|
|
|
2015-04-30 01:53:25 +00:00
|
|
|
// Determine max indent needed for all flag names.
|
2015-02-17 00:26:06 +00:00
|
|
|
size_t max = 0;
|
2015-05-11 08:21:57 +00:00
|
|
|
for (const auto& flag : details) {
|
|
|
|
max = (max > flag.first.size()) ? max : flag.first.size();
|
2015-02-17 00:26:06 +00:00
|
|
|
}
|
2015-04-30 01:53:25 +00:00
|
|
|
// Additional index for flag values.
|
2015-05-11 08:21:57 +00:00
|
|
|
max += 6;
|
2015-02-17 00:26:06 +00:00
|
|
|
|
2016-02-09 05:50:08 +00:00
|
|
|
// Show the Gflags-specific 'flagfile'.
|
|
|
|
if (!shell && cli) {
|
|
|
|
fprintf(stdout, " --flagfile PATH");
|
|
|
|
fprintf(stdout, "%s", std::string(max - 8 - 5, ' ').c_str());
|
|
|
|
fprintf(stdout, " Line-delimited file of additional flags\n");
|
|
|
|
}
|
|
|
|
|
2015-02-25 04:29:57 +00:00
|
|
|
auto& aliases = instance().aliases_;
|
2016-08-24 16:44:16 +00:00
|
|
|
for (const auto& flag : ordered_info) {
|
|
|
|
if (details.count(flag.second->name) > 0) {
|
|
|
|
const auto& detail = details.at(flag.second->name);
|
2015-02-25 04:29:57 +00:00
|
|
|
if ((shell && !detail.shell) || (!shell && detail.shell) ||
|
2015-03-03 23:03:14 +00:00
|
|
|
(external && !detail.external) || (!external && detail.external) ||
|
2015-06-30 18:48:11 +00:00
|
|
|
(cli && !detail.cli) || (!cli && detail.cli) || detail.hidden) {
|
2015-02-25 04:29:57 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-24 16:44:16 +00:00
|
|
|
} else if (aliases.count(flag.second->name) > 0) {
|
|
|
|
const auto& alias = aliases.at(flag.second->name);
|
2015-02-25 04:29:57 +00:00
|
|
|
// Aliases are only printed if this is an external tool and the alias
|
|
|
|
// is external.
|
|
|
|
if (!alias.external || !external) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// This flag was not defined as an osquery flag or flag alias.
|
2015-02-17 00:26:06 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-08-24 16:44:16 +00:00
|
|
|
fprintf(stdout, " --%s", flag.second->name.c_str());
|
2015-02-17 00:26:06 +00:00
|
|
|
|
2015-05-11 08:21:57 +00:00
|
|
|
int pad = max;
|
2016-08-24 16:44:16 +00:00
|
|
|
if (flag.second->type != "bool") {
|
2015-02-17 00:26:06 +00:00
|
|
|
fprintf(stdout, " VALUE");
|
|
|
|
pad -= 6;
|
|
|
|
}
|
2016-08-24 16:44:16 +00:00
|
|
|
pad -= flag.second->name.size();
|
2015-02-17 00:26:06 +00:00
|
|
|
|
2015-05-11 08:21:57 +00:00
|
|
|
if (pad > 0 && pad < 80) {
|
|
|
|
// Never pad more than 80 characters.
|
|
|
|
fprintf(stdout, "%s", std::string(pad, ' ').c_str());
|
|
|
|
}
|
2016-08-24 16:44:16 +00:00
|
|
|
fprintf(stdout, " %s\n", getDescription(flag.second->name).c_str());
|
2014-12-01 09:05:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|