From 6dffba3255eb8f25b667853c6c240ca76c31bd36 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Mon, 18 Mar 2024 17:06:10 +0000 Subject: [PATCH 1/2] Revert "src/commands/create: Never use the host's SSH key pair" This reverts commit 1bfede6cc939159c40f856eb5611478f686515c0. --- src/commands/create/mod.rs | 49 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/commands/create/mod.rs b/src/commands/create/mod.rs index 5891848..a2202de 100644 --- a/src/commands/create/mod.rs +++ b/src/commands/create/mod.rs @@ -47,7 +47,7 @@ pub fn create(global_args: &liboci_cli::GlobalOpts, args: &liboci_cli::Create) - set_up_extra_container_mounts_and_devices(&mut spec)?; set_up_security(&mut spec); - set_up_first_boot_config(&spec, &mounts, &custom_options)?; + set_up_first_boot_config(&spec, &mounts, &custom_options, runtime_env)?; set_up_libvirt_domain_xml(&spec, &base_vm_image_info, &mounts, &custom_options)?; adjust_container_rlimits_and_resources(&mut spec); @@ -499,8 +499,9 @@ fn set_up_first_boot_config( spec: &oci_spec::runtime::Spec, mounts: &Mounts, custom_options: &CustomOptions, + env: RuntimeEnv, ) -> Result<()> { - let container_public_key = gen_container_ssh_key_pair(spec)?; + let container_public_key = get_container_ssh_key_pair(spec, env)?; let config = FirstBootConfig { hostname: spec.hostname().as_deref(), @@ -528,22 +529,46 @@ fn set_up_first_boot_config( } /// Returns the public key for the container. -fn gen_container_ssh_key_pair(spec: &oci_spec::runtime::Spec) -> Result { +/// +/// This first attempts to use the current user's key pair, in case the VM does not support +/// cloud-init but the user injected their public key into it themselves. +fn get_container_ssh_key_pair(spec: &oci_spec::runtime::Spec, env: RuntimeEnv) -> Result { let ssh_path = spec.root_path()?.join("root/.ssh"); if !ssh_path.join("id_rsa.pub").exists() { fs::create_dir_all(&ssh_path)?; - let status = Command::new("ssh-keygen") - .arg("-q") - .arg("-f") - .arg(ssh_path.join("id_rsa")) - .arg("-N") - .arg("") - .spawn()? - .wait()?; + let try_copy_user_key_pair = || -> Result { + if env != RuntimeEnv::Other { + // definitely not Podman, we're probably not running as the user that invoked the engine + return Ok(false); + } + + if let Some(user_home_path) = home::home_dir() { + let user_ssh = user_home_path.join(".ssh"); + + if user_ssh.join("id_rsa.pub").is_file() && user_ssh.join("id_rsa").is_file() { + fs::copy(user_ssh.join("id_rsa.pub"), ssh_path.join("id_rsa.pub"))?; + fs::copy(user_ssh.join("id_rsa"), ssh_path.join("id_rsa"))?; + return Ok(true); + } + } + + Ok(false) + }; - ensure!(status.success(), "ssh-keygen failed"); + if !try_copy_user_key_pair()? { + let status = Command::new("ssh-keygen") + .arg("-q") + .arg("-f") + .arg(ssh_path.join("id_rsa")) + .arg("-N") + .arg("") + .spawn()? + .wait()?; + + ensure!(status.success(), "ssh-keygen failed"); + } } Ok(fs::read_to_string(ssh_path.join("id_rsa.pub"))?) From caa191342a6fa29d142f6f447b76f0ac998a8abd Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Mon, 18 Mar 2024 17:07:11 +0000 Subject: [PATCH 2/2] scripts/exec.sh: Avoid asking for passphrase more than once Signed-off-by: Alberto Faria --- scripts/exec.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/exec.sh b/scripts/exec.sh index 51057bd..5bc014b 100644 --- a/scripts/exec.sh +++ b/scripts/exec.sh @@ -19,7 +19,7 @@ if [[ ! -e /crun-vm/ssh-successful ]]; then for (( i = 0; i < 60; ++i )); do set +e - output=$( __ssh "$1" &1 ) + output=$( __ssh "$1" -o BatchMode=yes &1 ) exit_code=$? set -e @@ -32,7 +32,7 @@ if [[ ! -e /crun-vm/ssh-successful ]]; then done - if (( exit_code != 0 )); then + if (( exit_code != 0 )) && ! grep -iqE "Permission denied" <<< "$output"; then >&2 printf '%s\n' "$output" exit "$exit_code" fi