blob: 12d468d0919a5cdf09a7b58b670c6d2d7632448d [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "debugd/src/u2f_tool.h"
#include <set>
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_piece.h>
#include <base/strings/string_split.h>
#include <brillo/file_utils.h>
#include <chromeos/dbus/debugd/dbus-constants.h>
#include "debugd/src/process_with_output.h"
namespace debugd {
namespace {
constexpr char kOverrideConfigDir[] = "/var/lib/u2f/force";
constexpr char kJobName[] = "u2fd";
constexpr const char* kKnownFlags[] = {
u2f_flags::kU2f, u2f_flags::kG2f, u2f_flags::kVerbose,
u2f_flags::kUserKeys, u2f_flags::kAllowlistData,
};
int ControlU2fd(bool start) {
const char* action = start ? "start" : "stop";
return ProcessWithOutput::RunProcess("/sbin/initctl", {action, kJobName},
true, // requires root
false, // disable_sandbox
nullptr, // stdin
nullptr, // stdout
nullptr, // stderr
nullptr);
}
base::FilePath FlagFile(const std::string& flag) {
return base::FilePath(kOverrideConfigDir).Append(flag + ".force");
}
} // namespace
std::string U2fTool::SetFlags(const std::string& flags) {
std::string result;
// Stop the u2fd daemon.
ControlU2fd(false);
LOG(INFO) << "Set u2fd flags:" << flags;
std::set<std::string> all_flags;
for (const char* cur : kKnownFlags) {
all_flags.insert(cur);
// Clean-up existing flag.
base::DeleteFile(FlagFile(cur));
}
// Iterate over the new flags.
for (const std::string& cur : base::SplitString(
flags, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
// Validate the flag name.
if (all_flags.find(cur) != all_flags.end())
brillo::TouchFile(FlagFile(cur.c_str()));
else
result += "Discarded unknown flag '" + cur + "'.\n";
}
// Start the u2fd daemon with the new configuration.
if (ControlU2fd(true))
result += "Failed to restart u2fd.";
// Returns the outcome of the operations (empty for success).
return result;
}
std::string U2fTool::GetFlags() const {
std::vector<std::string> flags;
for (const char* cur : kKnownFlags) {
if (base::PathExists(FlagFile(cur))) {
flags.push_back(cur);
}
}
return base::JoinString(flags, ",");
}
} // namespace debugd