Skip to content

Commit

Permalink
Merge pull request #407 from mvo5/tweak-root-ssh-keys
Browse files Browse the repository at this point in the history
osconfig: install root ssh keys to /var/roothome
  • Loading branch information
cgwalters authored Mar 21, 2024
2 parents 4222b38 + 119dbb4 commit e01a518
Showing 1 changed file with 39 additions and 4 deletions.
43 changes: 39 additions & 4 deletions lib/src/install/osconfig.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::borrow::Cow;
use std::io::Write;

use anyhow::Result;
use anyhow::{Context, Result};
use camino::{Utf8Path, Utf8PathBuf};
use cap_std::fs::Dir;
use cap_std_ext::cap_std;
use cap_std_ext::{cap_std, dirext::CapStdExtDirExt};
use fn_error_context::context;
use ostree_ext::ostree;

Expand All @@ -17,8 +19,22 @@ pub(crate) fn inject_root_ssh_authorized_keys(
) -> Result<()> {
// While not documented right now, this one looks like it does not newline wrap
let b64_encoded = ostree_ext::glib::base64_encode(contents.as_bytes());

// Eagerly resolve the path of /root in order to avoid tmpfiles.d clashes/problems.
// If it's local state (i.e. /root -> /var/roothome) then we resolve that symlink now.
let roothome_meta = root.symlink_metadata_optional("root")?;
let root_path = if roothome_meta.as_ref().filter(|m| m.is_symlink()).is_some() {
let path = root.read_link("root")?;
Utf8PathBuf::try_from(path)
.context("Reading /root symlink")
.map(Cow::Owned)?
} else {
Cow::Borrowed(Utf8Path::new("root"))
};

// See the example in https://systemd.io/CREDENTIALS/
let tmpfiles_content = format!("f~ /root/.ssh/authorized_keys 600 root root - {b64_encoded}\n");
let tmpfiles_content =
format!("f~ /{root_path}/.ssh/authorized_keys 600 root root - {b64_encoded}\n");

crate::lsm::ensure_dir_labeled(root, ETC_TMPFILES, None, 0o755.into(), sepolicy)?;
let tmpfiles_dir = root.open_dir(ETC_TMPFILES)?;
Expand All @@ -35,11 +51,30 @@ pub(crate) fn inject_root_ssh_authorized_keys(
}

#[test]
fn test_inject_root_ssh() -> Result<()> {
fn test_inject_root_ssh_symlinked() -> Result<()> {
let root = &cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;

// The code expects this to exist, reasonably so
root.create_dir("etc")?;
// Test with a symlink
root.symlink("var/roothome", "root")?;
inject_root_ssh_authorized_keys(root, None, "ssh-ed25519 ABCDE example@demo\n").unwrap();

let content = root.read_to_string(format!("etc/tmpfiles.d/{ROOT_SSH_TMPFILE}"))?;
assert_eq!(
content,
"f~ /var/roothome/.ssh/authorized_keys 600 root root - c3NoLWVkMjU1MTkgQUJDREUgZXhhbXBsZUBkZW1vCg==\n"
);

Ok(())
}

#[test]
fn test_inject_root_ssh_dir() -> Result<()> {
let root = &cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;

root.create_dir("etc")?;
root.create_dir("root")?;
inject_root_ssh_authorized_keys(root, None, "ssh-ed25519 ABCDE example@demo\n").unwrap();

let content = root.read_to_string(format!("etc/tmpfiles.d/{ROOT_SSH_TMPFILE}"))?;
Expand Down

0 comments on commit e01a518

Please sign in to comment.