// 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.

syntax = "proto3";
option optimize_for = LITE_RUNTIME;

// This file defines messages for starting, stopping, and managing 9p servers
// with access to the user's home directory.
package vm_tools.seneschal;
option go_package = "seneschal_proto";

// Defines a path to be shared with a 9p server.
message SharedPath {
  // Path to be shared.  Must be relative, must not have any ".." elements, and
  // must not end with ".".  The destination path is constructed by appending
  // the name of the storage location and this path to the root of the server.
  // So if |path| is "foo/bar" and the |storage_location| field of the
  // SharePathRequest is "DOWNLOADS", then the destination path will be
  // "/Downloads/foo/bar".  Any ancestor directories will be automatically
  // created but will not be writable unless they have been shared via a
  // SharePathRequest.
  string path = 1;

  // Whether the path should be writable by the server.  Due to limitations in
  // the way bind mounts interact with user namespaces, setting this to false
  // will not currently do anything.  All shared paths are writable.  Maybe
  // one day if the linux developers decide that dropping privileges should
  // not require having additional privileges that you wouldn't otherwise need
  // we can maybe do something useful with this.
  bool writable = 2;
}

// Defines the vsock address on which a server should listen for requests.
// The server will always use context id 2 (VM host) as its address.
message VsockAddress {
  // The port number on which the server should listen for requests.
  uint32 port = 1;

  // The context id from which this server should accept connections.
  uint32 accept_cid = 2;
}

// Defines the unix address on which a server should listen for requests.
message UnixAddress {
  // The path on the system where the server should listen for requests.
  string path = 1;
}

// Defines the network address on which a server should listen for requests.
// The server will always use localhost as its address.
message NetworkAddress {
  // The port on which the server should listen for requests.
  uint32 port = 1;
}

// Indicates that the message includes a file descriptor on which the server
// should listen for requests.
message FileDescriptor {}

// Information that must be included with every StartServer dbus request.
message StartServerRequest {
  // The address on which the server should listen for requests.
  oneof listen_address {
    VsockAddress vsock = 1;
    UnixAddress unix_addr = 2;
    NetworkAddress net = 3;
    FileDescriptor fd = 4;
  }
}

// Information sent back by seneschal in response to a StartServer message.
message StartServerResponse {
  // Set to true if the server was started successfully.
  bool success = 1;

  // The handle with which to refer to this server in future requests.  Only
  // valid if |success| is true.
  uint32 handle = 2;

  // The reason why the server failed to start, if any.  Only valid when
  // |success| is false.
  string failure_reason = 3;
}

// Information that must be included with every StopServer request.
message StopServerRequest {
  // The handle to the server that should be stopped.
  uint32 handle = 1;
}

// Information sent back by seneschal when it receives a StopServer requests.
message StopServerResponse {
  // If true, then the server was successfully stopped.
  bool success = 1;

  // The reason why the server could not be stopped, if any.  Only valid when
  // |success| is false.
  string failure_reason = 2;
}

// Information that must be included with every SharePath request.
message SharePathRequest {
  // The handle to the server with whom the path should be shared.
  uint32 handle = 1;

  // The actual path to be shared.  Must be relative to |storage_location|
  // and must not contain any "../" elements or end with ".".
  SharedPath shared_path = 2;

  // The location where the path to be shared lives.
  enum StorageLocation {
    // The user's Downloads/ directory.
    DOWNLOADS = 0;
  }
  StorageLocation storage_location = 3;

  // The user's cryptohome.  This is the <hash> part of /home/user/<hash>.
  string owner_id = 4;
}

// Information sent back by seneschal when it receives a SharePath request.
message SharePathResponse {
  // If true, then the path was shared successfully.
  bool success = 1;

  // The path relative to the server's root where the shared path can be
  // accessed.  Only valid if |success| is true.
  string path = 2;

  // The reason why the path could not be shared, if any.  Only valid when
  // |success| is false.
  string failure_reason = 3;
}