use super::{command_mechanism, ActionMechanism, ActionSpec};
use sysknife_types::RiskLevel;
pub fn specs() -> Vec<ActionSpec> {
vec![
get_authorized_keys("alice"),
add_authorized_key("alice", "ssh-ed25519 AAAA..."),
remove_authorized_key("alice", "ssh-ed25519 AAAA..."),
set_sshd_option("PermitRootLogin", "prohibit-password"),
]
}
const SSHD_OPTION_HELPER: &str = "/usr/lib/sysknife/sshd-option-edit";
pub fn set_sshd_option(option: &str, value: &str) -> ActionSpec {
ActionSpec {
action_name: "SetSshdOption",
mechanism: command_mechanism(
"sudo",
[SSHD_OPTION_HELPER, "--option", option, "--value", value],
),
risk_level: RiskLevel::High,
reboot_required: false,
rollback_available: false,
}
}
pub fn get_authorized_keys(username: &str) -> ActionSpec {
ActionSpec {
action_name: "GetAuthorizedKeys",
mechanism: command_mechanism("cat", [&format!("/home/{username}/.ssh/authorized_keys")]),
risk_level: RiskLevel::Low,
reboot_required: false,
rollback_available: false,
}
}
const ADD_KEY_SCRIPT: &str =
"key=$1; path=$2; grep -Fxq -- \"$key\" \"$path\" 2>/dev/null || printf '%s\\n' \"$key\" >> \"$path\"";
pub fn add_authorized_key(username: &str, public_key: &str) -> ActionSpec {
let keys_path = format!("/home/{username}/.ssh/authorized_keys");
ActionSpec {
action_name: "AddAuthorizedKey",
mechanism: ActionMechanism::Command {
program: "sudo",
args: vec![
"sh".to_string(),
"-c".to_string(),
ADD_KEY_SCRIPT.to_string(),
"sh".to_string(),
public_key.to_string(),
keys_path,
],
},
risk_level: RiskLevel::High,
reboot_required: false,
rollback_available: false,
}
}
const REMOVE_KEY_SCRIPT: &str = "key=$1; path=$2; \
tmp=$(mktemp) || exit 1; \
grep -Fxv -- \"$key\" \"$path\" > \"$tmp\"; rc=$?; \
if [ $rc -gt 1 ]; then rm -f \"$tmp\"; exit $rc; fi; \
cat \"$tmp\" > \"$path\"; rm -f \"$tmp\"";
pub fn remove_authorized_key(username: &str, public_key: &str) -> ActionSpec {
let keys_path = format!("/home/{username}/.ssh/authorized_keys");
ActionSpec {
action_name: "RemoveAuthorizedKey",
mechanism: ActionMechanism::Command {
program: "sudo",
args: vec![
"sh".to_string(),
"-c".to_string(),
REMOVE_KEY_SCRIPT.to_string(),
"sh".to_string(),
public_key.to_string(),
keys_path,
],
},
risk_level: RiskLevel::High,
reboot_required: false,
rollback_available: false,
}
}