blob: eb1b8e6e8614e7edb735a8e099e44817c7698166 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 SRC_DEVELOPER_VSOCK_SSHD_HOST_SERVICE_H_
#define SRC_DEVELOPER_VSOCK_SSHD_HOST_SERVICE_H_
#include <fidl/fuchsia.component/cpp/fidl.h>
#include <fidl/fuchsia.vsock/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/wire/unknown_interaction_handler.h>
#include <lib/syslog/cpp/macros.h>
#include <sys/socket.h>
namespace sshd_host {
inline constexpr char kSshDirectory[] = "/data/ssh";
inline constexpr char kAuthorizedKeysPath[] = "/data/ssh/authorized_keys";
// Name of the collection that contains sshd shell child components.
inline constexpr std::string_view kShellCollection = "shell";
// Service relies on the default async dispatcher and is not thread safe.
class Service : public fidl::Server<fuchsia_vsock::Acceptor> {
public:
Service(async_dispatcher_t* dispatcher, uint16_t port);
~Service();
void Accept(AcceptRequest& request, AcceptCompleter::Sync& completer) override;
private:
class Controller;
void Launch(zx::socket socket);
void OnStop(zx_status_t status, Controller* controller);
async_dispatcher_t* dispatcher_;
uint64_t next_child_num_ = 0;
std::optional<fidl::ServerBinding<fuchsia_vsock::Acceptor>> binding_;
class Controller final : public fidl::AsyncEventHandler<fuchsia_component::ExecutionController> {
public:
Controller(Service* service, uint64_t child_num, std::string child_name,
fidl::ClientEnd<fuchsia_component::ExecutionController> client_end,
async_dispatcher_t* dispatcher, fidl::SyncClient<fuchsia_component::Realm> realm)
: service_(service),
child_num_(child_num),
child_name_(std::move(child_name)),
client_(std::move(client_end), dispatcher, this),
realm_(std::move(realm)) {}
void OnStop(fidl::Event<fuchsia_component::ExecutionController::OnStop>& event) final {
service_->OnStop(event.stopped_payload().status().value_or(ZX_OK), this);
}
void on_fidl_error(fidl::UnbindInfo error) final {
FX_LOGS(WARNING) << "encountered FIDL error " << error;
service_->OnStop(error.ToError().status(), this);
}
void handle_unknown_event(
fidl::UnknownEventMetadata<fuchsia_component::ExecutionController> metadata) override {
FX_LOGS(WARNING) << "fuchsia.component/ExecutionController delivered unknown event "
<< metadata.event_ordinal;
}
fidl::Client<fuchsia_component::ExecutionController>& operator->() { return client_; }
Service* service_;
uint64_t child_num_;
std::string child_name_;
fidl::Client<fuchsia_component::ExecutionController> client_;
fidl::SyncClient<fuchsia_component::Realm> realm_;
};
std::vector<fidl::ClientEnd<fuchsia_vsock::Connection>> client_ends_;
std::map<uint64_t, Controller> controllers_;
};
} // namespace sshd_host
#endif // SRC_DEVELOPER_VSOCK_SSHD_HOST_SERVICE_H_