summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-12-15 09:48:59 +0000
committerLars Wirzenius <liw@liw.fi>2022-12-15 09:48:59 +0000
commit60c9d8b2fe557d560248f805d90708145f322ace (patch)
tree71fdd2324ba2743e2e97148e1bfb1dd8030ecb9f
parent99010c5eeb45e3626656b22f3c7a1bca663cf260 (diff)
parent4d4053b01c0a7cdc5a1c4155524a2479ab41488f (diff)
downloadsshca-60c9d8b2fe557d560248f805d90708145f322ace.tar.gz
Merge branch 'liw/regen-temp' into 'main'
feat: regenerate --temporary See merge request larswirzenius/sshca!61
-rw-r--r--Cargo.lock87
-rw-r--r--Cargo.toml4
-rw-r--r--build.rs2
-rw-r--r--src/cmd/host.rs18
-rw-r--r--src/util.rs8
-rw-r--r--sshca.md34
-rw-r--r--sshca.subplot2
7 files changed, 69 insertions, 86 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fe43418..5201211 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index f0f199b..84bbee5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/build.rs b/build.rs
index 02db75a..17d240e 100644
--- a/build.rs
+++ b/build.rs
@@ -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)
+}
diff --git a/sshca.md b/sshca.md
index c5c05fd..e7f4867 100644
--- a/sshca.md
+++ b/sshca.md
@@ -1,16 +1,3 @@
----
-title: "sshca&mdash;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&mdash;tool to manage SSH CA certificates"
+title: "sshca: tool to manage SSH CA certificates"
authors:
- Lars Wirzenius
documentclass: report