Skip to content

Commit

Permalink
Merge 3bc3d06 into 21a3bc6
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-leonard-ct committed Apr 22, 2024
2 parents 21a3bc6 + 3bc3d06 commit 39660bf
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 23 deletions.
54 changes: 52 additions & 2 deletions src/machine/machine-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ static int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {

switch (m->class) {

case MACHINE_VM:
case MACHINE_HOST:
*ret = NULL;
break;
Expand Down Expand Up @@ -585,7 +586,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
sd_bus *container_bus = NULL;
_cleanup_close_ int master = -EBADF, slave = -EBADF;
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
_cleanup_free_ char *command_line = NULL;
_cleanup_free_ char *command_line = NULL, *ssh_path = NULL;
Machine *m = ASSERT_PTR(userdata);
const char *p, *unit, *user, *path, *description, *utmp_id;
int r;
Expand Down Expand Up @@ -638,6 +639,55 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
if (!strv_env_is_valid(env))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");

/* if we are a VM we need to transform args/path/env into an SSH command line */
if (m->class == MACHINE_VM) {
_cleanup_strv_free_ char **ssh_cmdline = NULL;

if (isempty(m->address) || isempty(m->ssh_private_key_path))
return -EOPNOTSUPP;

r = find_executable("ssh", &ssh_path);
if (r < 0)
return r;

ssh_cmdline = strv_new("ssh", "-o", "IdentitiesOnly yes");
if (!ssh_cmdline)
return -ENOMEM;

r = strv_extend(&ssh_cmdline, "-o");
if (r < 0)
return r;

r = strv_extendf(&ssh_cmdline, "IdentityFile=%s", m->ssh_private_key_path);
if (r < 0)
return r;

STRV_FOREACH(envvar, env) {
r = strv_extend(&ssh_cmdline, "-o");
if (r < 0)
return r;

r = strv_extendf(&ssh_cmdline, "SetEnv %s", *envvar);
if (r < 0)
return r;
}

r = strv_extend(&ssh_cmdline, m->address);
if (r < 0)
return r;

r = strv_extend(&ssh_cmdline, path);
if (r < 0)
return r;

r = strv_extend_strv(&ssh_cmdline, strv_skip(args, 1), /* filter_duplicates= */ false);
if (r < 0)
return r;

path = ssh_path;
strv_free_and_replace(args, ssh_cmdline);
}

command_line = strv_join(args, " ");
if (!command_line)
return -ENOMEM;
Expand Down Expand Up @@ -718,7 +768,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
if (r < 0)
return r;

if (!strv_isempty(env)) {
if (!strv_isempty(env) && m->class != MACHINE_VM) {
r = sd_bus_message_open_container(tm, 'r', "sv");
if (r < 0)
return r;
Expand Down
4 changes: 4 additions & 0 deletions src/machine/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ Machine* machine_free(Machine *m) {
free(m->service);
free(m->root_directory);
free(m->netif);
free(m->address);
free(m->ssh_private_key_path);
return mfree(m);
}

Expand Down Expand Up @@ -599,6 +601,7 @@ int machine_openpt(Machine *m, int flags, char **ret_slave) {

switch (m->class) {

case MACHINE_VM:
case MACHINE_HOST:
return openpt_allocate(flags, ret_slave);

Expand All @@ -618,6 +621,7 @@ int machine_open_terminal(Machine *m, const char *path, int mode) {

switch (m->class) {

case MACHINE_VM:
case MACHINE_HOST:
return open_terminal(path, mode);

Expand Down
3 changes: 3 additions & 0 deletions src/machine/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ struct Machine {
int *netif;
size_t n_netif;

char *address;
char *ssh_private_key_path;

LIST_HEAD(Operation, operations);

LIST_FIELDS(Machine, gc_queue);
Expand Down
48 changes: 38 additions & 10 deletions src/machine/machined-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ static int method_list_machines(sd_bus_message *message, void *userdata, sd_bus_
return sd_bus_send(NULL, reply, NULL);
}

static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, bool read_ssh, Machine **_m, sd_bus_error *error) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
const char *name, *service, *class, *root_directory;
const char *name, *service, *class, *root_directory, *address = NULL, *ssh_private_key_path = NULL;
const int32_t *netif = NULL;
MachineClass c;
uint32_t leader;
Expand Down Expand Up @@ -267,6 +267,12 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
}
}

if (read_ssh) {
r = sd_bus_message_read(message, "ss", &address, &ssh_private_key_path);
if (r < 0)
return r;
}

if (isempty(class))
c = _MACHINE_CLASS_INVALID;
else {
Expand Down Expand Up @@ -337,6 +343,20 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
m->n_netif = n_netif;
}

if (!isempty(address) && !isempty(ssh_private_key_path)) {
m->address = strdup(address);
if (!m->address) {
r = -ENOMEM;
goto fail;
}

m->ssh_private_key_path = strdup(ssh_private_key_path);
if (!m->ssh_private_key_path) {
r = -ENOMEM;
goto fail;
}
}

*_m = m;

return 1;
Expand All @@ -346,14 +366,14 @@ static int method_create_or_register_machine(Manager *manager, sd_bus_message *m
return r;
}

static int method_create_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
static int method_create_machine_internal(sd_bus_message *message, bool read_network, bool read_ssh, void *userdata, sd_bus_error *error) {
Manager *manager = ASSERT_PTR(userdata);
Machine *m = NULL;
int r;

assert(message);

r = method_create_or_register_machine(manager, message, read_network, &m, error);
r = method_create_or_register_machine(manager, message, read_network, read_ssh, &m, error);
if (r < 0)
return r;

Expand All @@ -374,22 +394,22 @@ static int method_create_machine_internal(sd_bus_message *message, bool read_net
}

static int method_create_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_create_machine_internal(message, true, userdata, error);
return method_create_machine_internal(message, /* read_network= */ true, /* read_ssh= */ false, userdata, error);
}

static int method_create_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_create_machine_internal(message, false, userdata, error);
return method_create_machine_internal(message, /* read_network= */ false, /* read_ssh= */ false, userdata, error);
}

static int method_register_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
static int method_register_machine_internal(sd_bus_message *message, bool read_network, bool read_ssh, void *userdata, sd_bus_error *error) {
Manager *manager = ASSERT_PTR(userdata);
_cleanup_free_ char *p = NULL;
Machine *m = NULL;
int r;

assert(message);

r = method_create_or_register_machine(manager, message, read_network, &m, error);
r = method_create_or_register_machine(manager, message, read_network, read_ssh, &m, error);
if (r < 0)
return r;

Expand Down Expand Up @@ -418,12 +438,16 @@ static int method_register_machine_internal(sd_bus_message *message, bool read_n
return r;
}

static int method_register_machine_with_ssh(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_register_machine_internal(message, /* read_network= */ false, /* read_ssh= */ true, userdata, error);
}

static int method_register_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_register_machine_internal(message, true, userdata, error);
return method_register_machine_internal(message, /* read_network= */ true, /* read_ssh= */ false, userdata, error);
}

static int method_register_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_register_machine_internal(message, false, userdata, error);
return method_register_machine_internal(message, /* read_network= */ false, /* read_ssh= */ false, userdata, error);
}

static int redirect_method_to_machine(sd_bus_message *message, Manager *m, sd_bus_error *error, sd_bus_message_handler_t method) {
Expand Down Expand Up @@ -1047,6 +1071,10 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_ARGS("s", name, "ay", id, "s", service, "s", class, "u", leader, "s", root_directory, "ai", ifindices),
SD_BUS_RESULT("o", path),
method_register_machine_with_network, 0),
SD_BUS_METHOD_WITH_ARGS("RegisterMachineWithSSH",
SD_BUS_ARGS("s", name, "ay", id, "s", service, "s", class, "u", leader, "s", root_directory, "s", address, "s", private_key_path),
SD_BUS_RESULT("o", path),
method_register_machine_with_ssh, 0),
SD_BUS_METHOD_WITH_ARGS("UnregisterMachine",
SD_BUS_ARGS("s", name),
SD_BUS_NO_RESULT,
Expand Down
18 changes: 14 additions & 4 deletions src/vmspawn/vmspawn-register.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@
#include "string-util.h"
#include "vmspawn-register.h"

int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, const char *service, const char *directory) {
int register_machine(
sd_bus *bus,
const char *machine_name,
sd_id128_t uuid,
const char *service,
const char *directory,
const char *address,
const char *key_path) {

_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;

Expand All @@ -21,16 +29,18 @@ int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, con
r = bus_call_method(
bus,
bus_machine_mgr,
"RegisterMachine",
"RegisterMachineWithSSH",
&error,
NULL,
"sayssus",
"sayssusss",
machine_name,
SD_BUS_MESSAGE_APPEND_ID128(uuid),
service,
"vm",
(uint32_t) getpid_cached(),
strempty(directory));
strempty(directory),
strempty(address),
strempty(key_path));
if (r < 0)
return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));

Expand Down
9 changes: 8 additions & 1 deletion src/vmspawn/vmspawn-register.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,12 @@
#include "sd-bus.h"
#include "sd-id128.h"

int register_machine(sd_bus *bus, const char *machine_name, sd_id128_t uuid, const char *service, const char *directory);
int register_machine(
sd_bus *bus,
const char *machine_name,
sd_id128_t uuid,
const char *service,
const char *directory,
const char *address,
const char *key_path);
int unregister_machine(sd_bus *bus, const char *machine_name);
28 changes: 22 additions & 6 deletions src/vmspawn/vmspawn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,12 +1222,6 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
if (r < 0)
return r;

if (arg_register) {
r = register_machine(bus, arg_machine, arg_uuid, trans_scope, arg_directory);
if (r < 0)
return r;
}

bool use_kvm = arg_kvm > 0;
if (arg_kvm < 0) {
r = qemu_check_kvm_support();
Expand Down Expand Up @@ -1867,6 +1861,17 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
r = unit_name_to_prefix(trans_scope, &scope_prefix);
if (r < 0)
return log_error_errno(r, "Failed to strip .scope suffix from scope: %m");

/* on distros that provide their own sshd@.service file we need to provide a dropin which
* picks up our public key credential */
r = machine_credential_set(&arg_credentials,
"systemd.unit-dropin.sshd-vsock@.service:"
"[Service]\n"
"ExecStart=\n"
"ExecStart=/usr/sbin/sshd -i -o 'AuthorizedKeysFile=${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys'\n"
"ImportCredential=ssh.ephemeral-authorized_keys-all\n");
if (r < 0)
return log_error_errno(r, "Failed to set credential systemd.unit-dropin.sshd-vsock@.service: %m");
}

if (ARCHITECTURE_SUPPORTS_SMBIOS)
Expand Down Expand Up @@ -1919,6 +1924,17 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) {
log_debug("Executing: %s", joined);
}

if (arg_register) {
_cleanup_free_ char *vm_address = NULL;

if (child_cid != VMADDR_CID_ANY && asprintf(&vm_address, "vsock/%u", child_cid) < 0)
return log_oom();

r = register_machine(bus, arg_machine, arg_uuid, trans_scope, arg_directory, vm_address, ssh_private_key_path);
if (r < 0)
return r;
}

assert_se(sigprocmask_many(SIG_BLOCK, /* old_sigset=*/ NULL, SIGCHLD, SIGWINCH) >= 0);

_cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL;
Expand Down

0 comments on commit 39660bf

Please sign in to comment.