blob: 6da27483582aad49fa172bde6b945224ad8762e0 [file] [log] [blame]
// Copyright 2016 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 <linux/device_jail.h>
#include <stdio.h>
#include <memory>
#include <string>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <brillo/flag_helper.h>
#include "container_utils/device_jail_control.h"
#include "container_utils/device_jail_server.h"
using device_jail::DeviceJailControl;
using device_jail::DeviceJailServer;
namespace {
class RequestHandler : public DeviceJailServer::Delegate {
public:
jail_request_result HandleRequest(const std::string& path) override {
printf("Request for device %s ([a]llow, [D]eny, [l]ockdown, d[e]tach)\n",
path.c_str());
char buf[64];
int ret = read(0, buf, sizeof(buf));
if (ret <= 0 || ret > 2)
return JAIL_REQUEST_DENY;
switch (buf[0]) {
case 'a':
return JAIL_REQUEST_ALLOW;
case 'd':
return JAIL_REQUEST_DENY;
case 'l':
return JAIL_REQUEST_ALLOW_WITH_LOCKDOWN;
case 'e':
return JAIL_REQUEST_ALLOW_WITH_DETACH;
default:
printf("Unrecognized command\n");
return JAIL_REQUEST_DENY;
}
}
};
} // namespace
int main(int argc, char** argv) {
DEFINE_string(add, "", "Path to device to jail.");
DEFINE_string(remove, "", "Path to jail device to remove.");
DEFINE_bool(server, false, "Enable server mode.");
brillo::FlagHelper::Init(argc, argv, "device_jail utility program");
bool add_mode = !FLAGS_add.empty();
bool remove_mode = !FLAGS_remove.empty();
if (add_mode + remove_mode + FLAGS_server != 1)
LOG(FATAL) << "can only have one flag";
if (FLAGS_server) {
base::MessageLoopForIO message_loop;
std::unique_ptr<DeviceJailServer> server =
DeviceJailServer::CreateAndListen(std::make_unique<RequestHandler>(),
&message_loop);
if (!server)
LOG(FATAL) << "could not initialize device jail server";
base::RunLoop().Run();
return 0;
}
std::unique_ptr<DeviceJailControl> jail_control =
DeviceJailControl::Create();
if (!jail_control)
LOG(FATAL) << "could not initialize device jail control";
if (add_mode) {
std::string jail_path;
switch (jail_control->AddDevice(FLAGS_add, &jail_path)) {
case DeviceJailControl::AddResult::ERROR:
LOG(FATAL) << "could not create jail device";
case DeviceJailControl::AddResult::ALREADY_EXISTS:
LOG(INFO) << "jail already exists at " << jail_path;
break;
case DeviceJailControl::AddResult::CREATED:
LOG(INFO) << "created jail at " << jail_path;
break;
}
} else if (remove_mode && !jail_control->RemoveDevice(FLAGS_remove)) {
LOG(FATAL) << "could not remove device";
}
return 0;
}