aboutsummaryrefslogtreecommitdiffstats
path: root/src/access
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 15:38:41 +0000
committertv <tv@krebsco.de>2026-11-09 18:20:59 +0100
commite59be7214b1fc1998f76a34f7e4429ee4259494c (patch)
tree9754fa4d80f5afce3cbf6d8225b986f99bf402c3 /src/access
parent2b7aaf12fc0fa288560072766ad6d8d39e5e37ed (diff)
access: a key's comment 256 bytes at most
Review 4, 1250's note: a key's comment was kept as given, unbounded but by the request limit (2 MiB), in protocol data every node holds and the dashboard shows. It says whose and where the key is: at most 256 bytes now (`sshsig::MAX_COMMENT`), a longer one refused with the key.
Diffstat (limited to 'src/access')
-rw-r--r--src/access/sshsig.rs19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/access/sshsig.rs b/src/access/sshsig.rs
index 799cb87..e25d8a7 100644
--- a/src/access/sshsig.rs
+++ b/src/access/sshsig.rs
@@ -22,6 +22,10 @@ const END: &str = "-----END SSH SIGNATURE-----";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct PublicKey(pub(crate) [u8; 32]);
+/// A key's comment kept at most, in bytes (`PublicKey::kept_line`): what says whose and
+/// where the key is, not a place for text.
+pub(crate) const MAX_COMMENT: usize = 256;
+
impl PublicKey {
/// From an `authorized_keys` line: `ssh-ed25519 <base64> [comment]`.
pub(crate) fn parse(line: &str) -> Result<Self, String> {
@@ -70,11 +74,20 @@ impl PublicKey {
/// made one). The comment is for whoever reads it: the key alone checks a signature.
pub(crate) fn kept_line(line: &str) -> Result<String, String> {
let key = Self::parse(line)?;
- let comment: Vec<&str> = line.split_whitespace().skip(2).collect();
+ let comment = line
+ .split_whitespace()
+ .skip(2)
+ .collect::<Vec<&str>>()
+ .join(" ");
+ if comment.len() > MAX_COMMENT {
+ return Err(format!(
+ "the key's comment is longer than {MAX_COMMENT} bytes"
+ ));
+ }
Ok(if comment.is_empty() {
key.line()
} else {
- format!("{} {}", key.line(), comment.join(" "))
+ format!("{} {comment}", key.line())
})
}
@@ -263,6 +276,8 @@ DNg4vBWp1j1gLRiBMOF+gwYNegDg==
assert_eq!(commented, format!("{} alice@laptop 2026", key.line()));
assert_eq!(PublicKey::parse(&commented), Ok(key));
assert_eq!(PublicKey::kept_line(&key.line()), Ok(key.line()));
+ let long = format!("{} {}", key.line(), "x".repeat(MAX_COMMENT + 1));
+ assert!(PublicKey::kept_line(&long).is_err());
}
/// What `sign` makes checks, and reads as `ssh-keygen` writes it.