blob: 97e05eb658dbb95b9379889c451f9a199d591cc0 [file] [log] [blame]
// Copyright 2015 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 <string>
#include <sysexits.h>
#include <base/command_line.h>
#include <chromeos/dbus/async_event_sequencer.h>
#include <chromeos/dbus/exported_object_manager.h>
#include <chromeos/daemons/dbus_daemon.h>
#include <chromeos/flag_helper.h>
#include <chromeos/minijail/minijail.h>
#include <chromeos/syslog_logging.h>
#include "webserver/webservd/server.h"
using chromeos::dbus_utils::AsyncEventSequencer;
namespace {
const char kServiceName[] = "org.chromium.WebServer";
const char kRootServicePath[] = "/org/chromium/WebServer";
const char kWebServerUserName[] = "webservd";
const char kWebServerGroupName[] = "webservd";
class Daemon : public chromeos::DBusServiceDaemon {
public:
Daemon(uint16_t http_port, uint16_t https_port, bool debug)
: DBusServiceDaemon{kServiceName, kRootServicePath},
http_port_{http_port},
https_port_{https_port},
debug_{debug} {}
protected:
void RegisterDBusObjectsAsync(AsyncEventSequencer* sequencer) override {
server_.reset(new webservd::Server{object_manager_.get(),
http_port_,
https_port_,
debug_});
server_->RegisterAsync(
sequencer->GetHandler("Server.RegisterAsync() failed.", true));
}
private:
uint16_t http_port_{0};
uint16_t https_port_{0};
bool debug_{false};
std::unique_ptr<webservd::Server> server_;
DISALLOW_COPY_AND_ASSIGN(Daemon);
};
} // namespace
int main(int argc, char* argv[]) {
DEFINE_int32(http_port, 80,
"HTTP port to listen for requests on (0 to disable)");
DEFINE_int32(https_port, 443,
"HTTPS port to listen for requests on (0 to disable)");
DEFINE_bool(log_to_stderr, false, "log trace messages to stderr as well");
DEFINE_bool(debug, false,
"return debug error information in web requests");
chromeos::FlagHelper::Init(argc, argv, "Brillo web server daemon");
int flags = chromeos::kLogToSyslog;
if (FLAGS_log_to_stderr)
flags |= chromeos::kLogToStderr;
chromeos::InitLog(flags | chromeos::kLogHeader);
if (FLAGS_http_port < 0 || FLAGS_http_port > 0xFFFF) {
LOG(ERROR) << "Invalid HTTP port specified: '" << FLAGS_http_port << "'.";
return EX_USAGE;
}
if (FLAGS_https_port < 0 || FLAGS_https_port > 0xFFFF) {
LOG(ERROR) << "Invalid HTTPS port specified: '" << FLAGS_https_port << "'.";
return EX_USAGE;
}
Daemon daemon{static_cast<uint16_t>(FLAGS_http_port),
static_cast<uint16_t>(FLAGS_https_port),
FLAGS_debug};
// Drop privileges and use 'webservd' user. We need to do this after Daemon
// object is constructed since it creates an instance of base::AtExitManager
// which is required for chromeos::Minijail::GetInstance() to work.
chromeos::Minijail* minijail_instance = chromeos::Minijail::GetInstance();
minijail* jail = minijail_instance->New();
minijail_instance->DropRoot(jail, kWebServerUserName, kWebServerGroupName);
// Permissions needed for the daemon to allow it to bind to ports like TCP
// 80.
minijail_instance->UseCapabilities(jail, CAP_TO_MASK(CAP_NET_BIND_SERVICE));
minijail_enter(jail);
minijail_instance->Destroy(jail);
return daemon.Run();
}