| // Copyright 2018 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 "vm_tools/concierge/seneschal_server_proxy.h" |
| |
| #include <chromeos/dbus/service_constants.h> |
| #include <dbus/message.h> |
| #include <dbus/object_path.h> |
| #include <seneschal/proto_bindings/seneschal_service.pb.h> |
| |
| namespace vm_tools { |
| namespace concierge { |
| |
| // static |
| std::unique_ptr<SeneschalServerProxy> |
| SeneschalServerProxy::SeneschalCreateProxy(dbus::ObjectProxy* seneschal_proxy, |
| dbus::MethodCall* method_call) { |
| std::unique_ptr<dbus::Response> dbus_response = |
| seneschal_proxy->CallMethodAndBlock( |
| method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); |
| if (!dbus_response) { |
| LOG(ERROR) << "Failed to send StartServer message to seneschal service"; |
| return nullptr; |
| } |
| |
| dbus::MessageReader reader(dbus_response.get()); |
| vm_tools::seneschal::StartServerResponse response; |
| if (!reader.PopArrayOfBytesAsProto(&response)) { |
| LOG(ERROR) << "Failed to parse StartServerResponse protobuf"; |
| return nullptr; |
| } |
| |
| if (!response.success()) { |
| LOG(ERROR) << "Failed to start server: " << response.failure_reason(); |
| return nullptr; |
| } |
| |
| return std::unique_ptr<SeneschalServerProxy>( |
| new SeneschalServerProxy(seneschal_proxy, response.handle())); |
| } |
| |
| // static |
| std::unique_ptr<SeneschalServerProxy> SeneschalServerProxy::CreateVsockProxy( |
| dbus::ObjectProxy* seneschal_proxy, |
| uint32_t port, |
| uint32_t accept_cid, |
| std::vector<std::pair<uint32_t, uint32_t>> uid_map, |
| std::vector<std::pair<uint32_t, uint32_t>> gid_map) { |
| dbus::MethodCall method_call(vm_tools::seneschal::kSeneschalInterface, |
| vm_tools::seneschal::kStartServerMethod); |
| dbus::MessageWriter writer(&method_call); |
| |
| vm_tools::seneschal::StartServerRequest request; |
| request.mutable_vsock()->set_port(port); |
| request.mutable_vsock()->set_accept_cid(accept_cid); |
| |
| for (const auto& mapping : uid_map) { |
| seneschal::IdMap* id_map = request.add_uid_maps(); |
| id_map->set_server(mapping.first); |
| id_map->set_client(mapping.second); |
| } |
| |
| for (const auto& mapping : gid_map) { |
| seneschal::IdMap* id_map = request.add_gid_maps(); |
| id_map->set_server(mapping.first); |
| id_map->set_client(mapping.second); |
| } |
| |
| if (!writer.AppendProtoAsArrayOfBytes(request)) { |
| LOG(ERROR) << "Failed to encode StartServerRequest protobuf"; |
| return nullptr; |
| } |
| |
| return SeneschalCreateProxy(seneschal_proxy, &method_call); |
| } |
| |
| // static |
| std::unique_ptr<SeneschalServerProxy> SeneschalServerProxy::CreateFdProxy( |
| dbus::ObjectProxy* seneschal_proxy, const base::ScopedFD& socket_fd) { |
| dbus::MethodCall method_call(vm_tools::seneschal::kSeneschalInterface, |
| vm_tools::seneschal::kStartServerMethod); |
| dbus::MessageWriter writer(&method_call); |
| |
| vm_tools::seneschal::StartServerRequest request; |
| request.mutable_fd(); |
| if (!writer.AppendProtoAsArrayOfBytes(request)) { |
| LOG(ERROR) << "Failed to encode StartServerRequest protobuf"; |
| return nullptr; |
| } |
| |
| writer.AppendFileDescriptor(socket_fd.get()); |
| |
| return SeneschalCreateProxy(seneschal_proxy, &method_call); |
| } |
| |
| SeneschalServerProxy::SeneschalServerProxy(dbus::ObjectProxy* seneschal_proxy, |
| uint32_t handle) |
| : seneschal_proxy_(seneschal_proxy), handle_(handle) {} |
| |
| SeneschalServerProxy::~SeneschalServerProxy() { |
| dbus::MethodCall method_call(vm_tools::seneschal::kSeneschalInterface, |
| vm_tools::seneschal::kStopServerMethod); |
| dbus::MessageWriter writer(&method_call); |
| |
| vm_tools::seneschal::StopServerRequest request; |
| request.set_handle(handle_); |
| |
| if (!writer.AppendProtoAsArrayOfBytes(request)) { |
| LOG(ERROR) << "Failed to encode StopServerRequest protobuf"; |
| return; |
| } |
| |
| std::unique_ptr<dbus::Response> dbus_response = |
| seneschal_proxy_->CallMethodAndBlock( |
| &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); |
| if (!dbus_response) { |
| LOG(ERROR) << "Failed to send StopServer message to seneschal service"; |
| return; |
| } |
| |
| dbus::MessageReader reader(dbus_response.get()); |
| vm_tools::seneschal::StopServerResponse response; |
| if (!reader.PopArrayOfBytesAsProto(&response)) { |
| LOG(ERROR) << "Failed to parse StopServerResponse protobuf"; |
| return; |
| } |
| |
| if (!response.success()) { |
| LOG(ERROR) << "Failed to stop server " << handle_ << ": " |
| << response.failure_reason(); |
| return; |
| } |
| } |
| |
| } // namespace concierge |
| } // namespace vm_tools |