summaryrefslogtreecommitdiff
path: root/src/spec.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-04-06 20:01:41 +0300
committerLars Wirzenius <liw@liw.fi>2022-04-07 10:13:02 +0300
commit7fb4d37e19469b1bf567dd57cb86ae9f9f9d44c0 (patch)
tree0c145eef6210cc711f054c77f127a8bf9877dc87 /src/spec.rs
parentf5b7ee0ce079e22f37e42c23277ed32aebb41919 (diff)
downloadvmadm-7fb4d37e19469b1bf567dd57cb86ae9f9f9d44c0.tar.gz
feat: add a user_ca_pubkey field to config, spec
With this, there's no need to install an SSH key into root's authorized_keys file. Sponsored-by: author
Diffstat (limited to 'src/spec.rs')
-rw-r--r--src/spec.rs51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/spec.rs b/src/spec.rs
index 150f404..58d7550 100644
--- a/src/spec.rs
+++ b/src/spec.rs
@@ -33,19 +33,32 @@ struct OneVmInputSpecification {
pub autostart: Option<bool>,
pub networks: Option<Vec<String>>,
pub ca_key: Option<PathBuf>,
+ pub user_ca_pubkey: Option<PathBuf>,
}
impl OneVmInputSpecification {
- fn ssh_key_files(
- &self,
- config: &Configuration,
- name: &str,
- ) -> Result<Vec<PathBuf>, SpecificationError> {
- get(
+ fn ssh_key_files(&self, config: &Configuration, name: &str) -> Option<Vec<PathBuf>> {
+ if let Ok(x) = get(
&self.ssh_key_files,
&config.authorized_keys,
SpecificationError::NoAuthorizedKeys(name.to_string()),
- )
+ ) {
+ Some(x)
+ } else {
+ None
+ }
+ }
+
+ fn user_ca_pubkey(&self, config: &Configuration, name: &str) -> Option<PathBuf> {
+ if let Ok(x) = get(
+ &self.user_ca_pubkey,
+ &config.user_ca_pubkey,
+ SpecificationError::NoAuthorizedKeys(name.to_string()),
+ ) {
+ Some(x)
+ } else {
+ None
+ }
}
fn base_image(
@@ -199,6 +212,9 @@ pub struct Specification {
/// Path to CA key for creating host certificate.
pub ca_key: Option<PathBuf>,
+ /// Path to CA publicv key for verifying user certificates.
+ pub user_ca_pubkey: Option<PathBuf>,
+
/// List of networks to which host should be added.
pub networks: Vec<String>,
}
@@ -226,8 +242,8 @@ pub enum SpecificationError {
#[error("No CPU count specified for {0} and no default configured")]
NoCpuCount(String),
- /// No SSH authorized keys specified.
- #[error("No SSH authorized keys specified for {0} and no default configured")]
+ /// No SSH authorized keys or user CA specified.
+ #[error("No SSH authorized keys nor user CA specified for {0} and no default configured")]
NoAuthorizedKeys(String),
/// Error reading specification file.
@@ -289,8 +305,20 @@ impl Specification {
name: &str,
input: &OneVmInputSpecification,
) -> Result<Specification, SpecificationError> {
- let key_filenames = input.ssh_key_files(config, name)?;
- let ssh_keys = ssh_keys(&key_filenames)?;
+ let ssh_keys = if let Some(key_filenames) = input.ssh_key_files(config, name) {
+ ssh_keys(&key_filenames)?
+ } else {
+ vec![]
+ };
+ let user_ca_pubkey = input.user_ca_pubkey(config, name);
+ if ssh_keys.is_empty() && user_ca_pubkey.is_none() {
+ return Err(SpecificationError::NoAuthorizedKeys(name.to_string()));
+ }
+ let user_ca_pubkey = if let Some(filename) = user_ca_pubkey {
+ Some(expand_tilde(&filename)?)
+ } else {
+ None
+ };
let ca_key = if let Some(filename) = &input.ca_key {
Some(expand_tilde(filename)?)
} else {
@@ -326,6 +354,7 @@ impl Specification {
generate_host_certificate: gen_cert,
autostart: input.autostart(config),
ca_key,
+ user_ca_pubkey,
networks,
};