blob: 4b9596543f239d5f6904e0c8ec0fa4712d6763a0 [file] [log] [blame]
// Copyright (c) 2011 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 <stdio.h>
#include <iostream>
#include <string>
#include <base/command_line.h>
#include <base/file_util.h>
#include <chromeos/syslog_logging.h>
#include "entd/entd.h"
#include "entd/extensions.h"
#include "entd/callback_server.h"
#include "entd/http.h"
#include "entd/tpm.h"
#include "entd/utils.h"
namespace switches {
// Path to search for extensions; can contain ~ or env variables (e.g. ${HOME})
static const char kExtensionPath[] = "extension-path";
// User Name
static const char kUsername[] = "username";
// Policy files
static const char kManifest[] = "manifest";
static const char kPolicy[] = "policy";
static const char kUtility[] = "utility";
// Root CA for HTTPS requests.
static const char kRootCAFile[] = "root-ca-file";
// If specified, then self-signed server certs are ok for HTTPS
static const char kAllowSelfSigned[] = "allow-self-signed";
// If specified, then file operations are allowed (e.g. for testing)
static const char kAllowFileIO[] = "allow-file-io";
// If specified, don't watch for signals. This allows the process to exit
// automatically when all events have been processed. See the comment in
// entd.h for a little more info.
static const char kAllowDirtyExit[] = "allow-dirty-exit";
// Syslogging is enabled by default if stdout is not a tty. These flags can
// be used to override the default logic.
static const char kEnableSyslog[] = "enable-syslog";
static const char kDisableSyslog[] = "disable-syslog";
static const char kLibcrosLocation[] = "libcros-location";
static const char kCallbackOrigin[] = "callback-origin";
static const char kSessionId[] = "session-id";
static const char kSetLsbRelease[] = "lsb-release";
} // namespace switches
// Return values:
// 0: Entd completed successfully and should not be restarted.
// 1: Entd encountered a failure, but will probably fail again if restarted,
// so please don't.
// 2: Entd has NOT encountered a failure, but would like to be restarted.
// >2: Entd has encountered a failure, restarting may help.
//
// So, exit with a zero or one means leave it down, otherwise restart.
//
int main(int argc, char** argv) {
std::string manifest, policy, utility;
CommandLine::Init(argc, argv);
CommandLine* cl = CommandLine::ForCurrentProcess();
int log_flags = chromeos::kLogToStderr;
if (cl->HasSwitch(switches::kEnableSyslog) ||
(!isatty(STDOUT_FILENO) && !cl->HasSwitch(switches::kDisableSyslog))) {
// If syslog was explicitly enabled, or stdout is not a tty and syslog
// was not explicitly disabled, then send all LOG(...) messages to syslog.
log_flags |= chromeos::kLogToSyslog;
}
chromeos::InitLog(log_flags);
LOG(INFO) << "Starting entd";
std::string base_extension_path =
cl->GetSwitchValueASCII(switches::kExtensionPath);
std::string username = cl->GetSwitchValueASCII(switches::kUsername);
std::string root_ca_file = cl->GetSwitchValueASCII(switches::kRootCAFile);
// Get file paths from a valid policy extension if it exists
std::string extension_path;
bool valid_policy = false;
if (!base_extension_path.empty()) {
valid_policy = entd::extensions::FindValidPolicy(base_extension_path,
&extension_path);
}
if (valid_policy) {
FilePath path = FilePath(extension_path).Append("policy.js");
if (file_util::PathExists(path))
policy = path.value();
path = FilePath(extension_path).Append("manifest.json");
if (file_util::PathExists(path))
manifest = path.value();
path = FilePath(extension_path).Append("root-ca.pem");
if (file_util::PathExists(path)) {
root_ca_file = path.value();
} else {
// Backwards compatibility for old filename with underscore.
path = FilePath(extension_path).Append("root_ca.pem");
if (file_util::PathExists(path))
root_ca_file = path.value();
}
}
// Command line switches for policy files override extension filepaths
if (cl->HasSwitch(switches::kPolicy))
policy = cl->GetSwitchValueASCII(switches::kPolicy);
if (cl->HasSwitch(switches::kManifest))
manifest = cl->GetSwitchValueASCII(switches::kManifest);
if (cl->HasSwitch(switches::kUtility))
utility = cl->GetSwitchValueASCII(switches::kUtility);
if (cl->HasSwitch(switches::kAllowSelfSigned)) {
LOG(INFO) << "Allowing self-signed certs.";
entd::Http::allow_self_signed_certs = true;
}
if (cl->HasSwitch(switches::kLibcrosLocation)) {
entd::Entd::libcros_location = cl->GetSwitchValueASCII(
switches::kLibcrosLocation);
LOG(INFO) << "Setting libcros location: " << entd::Entd::libcros_location;
}
if (cl->HasSwitch(switches::kAllowFileIO)) {
LOG(INFO) << "Allowing File IO.";
entd::Entd::allow_file_io = true;
}
if (!root_ca_file.empty()) {
LOG(INFO) << "Setting root CA file: " << root_ca_file;
entd::Http::root_ca_file = root_ca_file;
}
if (cl->HasSwitch(switches::kAllowDirtyExit)) {
LOG(INFO) << "Allowing dirty exits.";
entd::Entd::allow_dirty_exit = true;
}
if (cl->HasSwitch(switches::kCallbackOrigin)) {
entd::CallbackServer::required_origin = cl->GetSwitchValueASCII(
switches::kCallbackOrigin);
LOG(INFO) << "Setting callback origin: " <<
entd::CallbackServer::required_origin;
}
if (cl->HasSwitch(switches::kSessionId)) {
entd::CallbackServer::set_session_id(cl->GetSwitchValueASCII(
switches::kSessionId));
LOG(INFO) << "Setting session id: " <<
entd::CallbackServer::session_id();
}
entd::Entd d;
d.Initialize();
if (!username.empty())
d.SetUsername(username);
if (!utility.empty())
d.SetUtilityFile(utility);
if (!manifest.empty())
d.SetManifestFile(manifest);
if (!policy.empty())
d.SetPolicyFile(policy);
if (cl->HasSwitch(switches::kSetLsbRelease))
d.SetLsbRelease(cl->GetSwitchValueASCII(switches::kSetLsbRelease));
uint32_t rv = d.Run();
LOG(INFO) << "Exiting entd with code: " << rv;
return rv;
}