diff options
author | Lars Wirzenius <liw@liw.fi> | 2022-12-15 09:48:59 +0000 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2022-12-15 09:48:59 +0000 |
commit | 60c9d8b2fe557d560248f805d90708145f322ace (patch) | |
tree | 71fdd2324ba2743e2e97148e1bfb1dd8030ecb9f | |
parent | 99010c5eeb45e3626656b22f3c7a1bca663cf260 (diff) | |
parent | 4d4053b01c0a7cdc5a1c4155524a2479ab41488f (diff) | |
download | sshca-60c9d8b2fe557d560248f805d90708145f322ace.tar.gz |
Merge branch 'liw/regen-temp' into 'main'
feat: regenerate --temporary
See merge request larswirzenius/sshca!61
-rw-r--r-- | Cargo.lock | 87 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | build.rs | 2 | ||||
-rw-r--r-- | src/cmd/host.rs | 18 | ||||
-rw-r--r-- | src/util.rs | 8 | ||||
-rw-r--r-- | sshca.md | 34 | ||||
-rw-r--r-- | sshca.subplot | 2 |
7 files changed, 69 insertions, 86 deletions
@@ -123,7 +123,7 @@ dependencies = [ "once_cell", "strsim", "termcolor", - "textwrap 0.15.0", + "textwrap", ] [[package]] @@ -237,25 +237,12 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime 1.3.0", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "env_logger" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", - "humantime 2.1.0", + "humantime", "log", "regex", "termcolor", @@ -454,15 +441,6 @@ checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" [[package]] name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - -[[package]] -name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" @@ -717,16 +695,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger 0.7.1", - "log", -] - -[[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -772,12 +740,6 @@ dependencies = [ ] [[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] name = "quote" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -910,15 +872,15 @@ dependencies = [ [[package]] name = "roadmap" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c460d89fa2561bd4eb9f6db252b79b1520dcdd807b2fe75d34c2056d58e39433" +checksum = "3f0c08002dd427499194cef0e292cfd515281777d5b9cc4c638028d2d3aebda4" dependencies = [ "anyhow", "clap", "serde", "serde_yaml", - "textwrap 0.14.2", + "textwrap", "thiserror", ] @@ -966,9 +928,9 @@ dependencies = [ [[package]] name = "serde-aux" -version = "3.0.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93abf9799c576f004252b2a05168d58527fb7c54de12e94b4d12fe3475ffad24" +checksum = "c599b3fd89a75e0c18d6d2be693ddb12cccaf771db4ff9e39097104808a014c0" dependencies = [ "serde", "serde_json", @@ -998,9 +960,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", "ryu", @@ -1063,7 +1025,7 @@ dependencies = [ "anyhow", "clap", "directories-next", - "env_logger 0.9.0", + "env_logger", "fehler", "log", "serde", @@ -1093,14 +1055,14 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subplot" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c826f5e83eb04e7d35ba6e22d0d9a085866933350872d6e515aa0a7f2a4149d" +checksum = "95cfa682b7da7d48f97d2042c5e21f025cf68035544876c2de7bd007779424d9" dependencies = [ "anyhow", "base64", "clap", - "env_logger 0.9.0", + "env_logger", "file_diff", "git-testament", "lazy_static", @@ -1108,7 +1070,6 @@ dependencies = [ "pandoc", "pandoc_ast", "pikchr", - "pretty_env_logger", "pulldown-cmark", "regex", "roadmap", @@ -1126,9 +1087,9 @@ dependencies = [ [[package]] name = "subplot-build" -version = "0.4.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07b0f49a5ba78bae9db8fde58e94ae1bd508d883ff77c07c227c98da6d38ca2" +checksum = "14c3c09032b72b9229c6d48f3b842ec439de982915295a6854289bc66e8c274a" dependencies = [ "subplot", "tempfile", @@ -1137,9 +1098,9 @@ dependencies = [ [[package]] name = "subplotlib" -version = "0.4.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d1fff7b1ad8b0c44466dfd11a5986f1e08bf317af82450ab6d06bc44f7f51" +checksum = "56e32651107dcf191149190cfe54f41751bb8c4c93021f39435b95aecff6739b" dependencies = [ "base64", "fehler", @@ -1160,9 +1121,9 @@ dependencies = [ [[package]] name = "subplotlib-derive" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5264ca1d43fab97c844a8053c9f6da34c41fc659a52214c85002537651cb83" +checksum = "0c12aaed6f70026bf2c60985e145c8a8309413d8fd34751eacd6b018e272901d" dependencies = [ "fehler", "proc-macro2", @@ -1237,9 +1198,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" dependencies = [ "smawk", "unicode-linebreak", @@ -1247,12 +1208,6 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - -[[package]] name = "thiserror" version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,13 +15,13 @@ log = "0.4.14" serde = { version = "1.0.127", features = ["derive"] } serde_json = "1.0.85" serde_yaml = "0.8.17" -subplotlib = "0.4.1" +subplotlib = "0.6.0" tempfile = "3.2.0" thiserror = "1.0.26" time = { version = "0.3.17", features = ["macros", "formatting"] } [build-dependencies] -subplot-build = "0.4.0" +subplot-build = "0.6.0" [dev-dependencies] fehler = "1.0.0" @@ -1,3 +1,3 @@ fn main() { - subplot_build::codegen("sshca.md").expect("failed to generate code with Subplot"); + subplot_build::codegen("sshca.subplot").expect("failed to generate code with Subplot"); } diff --git a/src/cmd/host.rs b/src/cmd/host.rs index c508137..2896fe3 100644 --- a/src/cmd/host.rs +++ b/src/cmd/host.rs @@ -7,7 +7,7 @@ use crate::error::CAError; use crate::info::{self, Info, SafeHost}; use crate::key::{KeyKind, KeyPair, PublicKey, SshKey}; use crate::store::{KeyStore, KeyStoreError}; -use crate::util::read_as_string; +use crate::util::{format_timestamp, read_as_string}; use clap::{ArgAction, Parser}; use std::fs::File; @@ -322,8 +322,7 @@ impl Runnable for Generate { if self.temporary { let now = std::time::SystemTime::now(); if let Some(valid_until) = time::OffsetDateTime::from(now).checked_add(SHORT_TIME) { - let format = format_description!("[year]:[month]:[day]T[hour]:[minute]:[second]"); - let valid_until = valid_until.format(&format).map_err(CAError::TimeFormat)?; + let valid_until = format_timestamp(valid_until)?; host.set_valid_until(valid_until); } else { return Err(CAError::ShortTime); @@ -340,6 +339,10 @@ pub struct Regenerate { /// Name of host. hostname: String, + /// Make the generated host key short-lived. + #[clap(long)] + temporary: bool, + /// All the principals for this host. Defaults to HOSTNAME if none /// given. #[clap(short, long = "principal", action = ArgAction::Append)] @@ -354,6 +357,15 @@ impl Runnable for Regenerate { } let pair = KeyPair::generate(KeyKind::Ed25519).map_err(CAError::KeyError)?; host.set_keys(pair.public().clone(), pair.private().clone()); + if self.temporary { + let now = std::time::SystemTime::now(); + if let Some(valid_until) = time::OffsetDateTime::from(now).checked_add(SHORT_TIME) { + let valid_until = format_timestamp(valid_until)?; + host.set_valid_until(valid_until); + } else { + return Err(CAError::ShortTime); + }; + } Ok(()) } else { Err(CAError::KeyStoreError(KeyStoreError::UnknownHost( diff --git a/src/util.rs b/src/util.rs index a772ad0..3d50240 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,6 +5,8 @@ use std::fs::{File, Permissions}; use std::io::Write; use std::os::unix::fs::PermissionsExt; use std::path::Path; +use time::OffsetDateTime; +use time::macros::format_description; pub(crate) fn read<P: AsRef<Path>>(filename: P) -> Result<Vec<u8>, CAError> { let filename = filename.as_ref(); @@ -33,3 +35,9 @@ pub fn write_string<P: AsRef<Path>>(filename: P, s: &str) -> Result<(), CAError> pub(crate) fn prompt_token() { eprintln!("You may need to touch the security token button now"); } + +pub(crate) fn format_timestamp(valid_until: OffsetDateTime) -> Result<String, CAError> { + let format = format_description!("[year]:[month]:[day]T[hour]:[minute]:[second]"); + let valid_until = valid_until.format(&format).map_err(CAError::TimeFormat)?; + Ok(valid_until) +} @@ -1,16 +1,3 @@ ---- -title: "sshca—tool to manage SSH CA certificates" -author: Lars Wirzenius -documentclass: report -bindings: -- subplot/sshca.yaml -- lib/files.yaml -- lib/runcmd.yaml -impls: - rust: - - subplot/sshca.rs -... - # Introduction The `sshca` tool helps manage an SSH Certificate Authority (CA) and @@ -607,6 +594,27 @@ when I run sshca host private-key myhost then stdout contains "-----BEGIN OPENSSH PRIVATE KEY-----" ~~~ +### Re-generate a temporary host key + +_Requirement: we can generate a new short-lived host key for an +existing host that already has a private key._ + +Justification: when a host key is generated for installing a new host, +it should be replaced soon. The `sshca` tool should allow marking the +installation host key as short-lived, so that it can't be used for +long. + +~~~scenario +given an installed sshca +given file .config/sshca/config.yaml from config.yaml + +when I run sshca host generate myhost +when I run sshca host regenerate --temporary myhost + +when I try to run sshca host public-key --now=3000-01-01T00:00:00 myhost +then command fails +~~~ + ### Export host public and private keys _Requirement: It must be possible to export a host's public key, and diff --git a/sshca.subplot b/sshca.subplot index 8c97877..1c2dab3 100644 --- a/sshca.subplot +++ b/sshca.subplot @@ -1,4 +1,4 @@ -title: "sshca—tool to manage SSH CA certificates" +title: "sshca: tool to manage SSH CA certificates" authors: - Lars Wirzenius documentclass: report |