blob: c9dc2a1b426d147827987a8aa052e8bde5c99d8c [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.
#ifndef SOMA_CONTAINER_SPEC_WRAPPER_H_
#define SOMA_CONTAINER_SPEC_WRAPPER_H_
#include <sys/types.h>
#include <set>
#include <string>
#include <vector>
#include <base/files/file_path.h>
#include <base/memory/scoped_vector.h>
#include "soma/device_filter.h"
#include "soma/namespace.h"
#include "soma/port.h"
#include "soma/proto_bindings/soma_container_spec.pb.h"
#include "soma/sysfs_filter.h"
#include "soma/usb_device_filter.h"
namespace soma {
// More friendly wrapper around the ContainerSpec protobuf.
// This class owns an instance of the protobuf and will hand out read-only
// references of it on request. This means a new protobuf is allocated
// and populated every time we go to read a spec, and then it needs to
// be merged into an RPC response. If this is too slow, requiring too
// many copies of the same data, we could change this class to take a
// pointer to a ContainerSpec instead.
class ContainerSpecWrapper {
public:
ContainerSpecWrapper(const std::string& name,
const base::FilePath& service_bundle_path,
uid_t uid,
gid_t gid);
virtual ~ContainerSpecWrapper();
void SetServiceNames(const std::vector<std::string>& service_names);
void SetCommandLine(const std::vector<std::string>& command_line);
void SetNamespaces(const std::set<parser::ns::Kind>& namespaces);
void SetTcpListenPorts(const std::set<parser::port::Number>& ports);
void SetUdpListenPorts(const std::set<parser::port::Number>& ports);
void SetDevicePathFilters(const parser::DevicePathFilter::Set& filters);
void SetDeviceNodeFilters(const parser::DeviceNodeFilter::Set& filters);
// These don't really do anything yet.
void AddSysfsFilter(const std::string& filter);
void AddUSBDeviceFilter(int vid, int pid);
const std::string& name() { return internal_.name(); }
base::FilePath service_bundle_path() {
return base::FilePath(internal_.service_bundle_path());
}
uid_t uid() { return internal_.uid(); }
gid_t gid() { return internal_.gid(); }
// Returns true if name is listed in the spec.
bool ProvidesServiceNamed(const std::string& name) const;
// Returns true if candidate is explicitly allowed.
bool ShouldApplyNamespace(parser::ns::Kind candidate) const;
// Returns true if port is explicitly or implicitly allowed (by wildcarding).
bool TcpListenPortIsAllowed(parser::port::Number port) const;
bool UdpListenPortIsAllowed(parser::port::Number port) const;
// Returns true if there's a DevicePathFilter that matches query.
bool DevicePathIsAllowed(const base::FilePath& query) const;
// Returns true if there's a DeviceNodeFilter that matches major and minor.
bool DeviceNodeIsAllowed(int major, int minor) const;
const ContainerSpec& AsProto() const { return internal_; }
private:
// TODO(cmasone): As we gain more experience with these, investigate whether
// they should also be sets, or at least have set semantics.
ScopedVector<SysfsFilter> sysfs_filters_;
ScopedVector<USBDeviceFilter> usb_device_filters_;
ContainerSpec internal_;
DISALLOW_COPY_AND_ASSIGN(ContainerSpecWrapper);
};
} // namespace soma
#endif // SOMA_CONTAINER_SPEC_WRAPPER_H_