diff options
| author | tv <tv@krebsco.de> | 2026-11-09 15:38:41 +0000 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-09 18:20:59 +0100 |
| commit | e59be7214b1fc1998f76a34f7e4429ee4259494c (patch) | |
| tree | 9754fa4d80f5afce3cbf6d8225b986f99bf402c3 /src | |
| parent | 2b7aaf12fc0fa288560072766ad6d8d39e5e37ed (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')
| -rw-r--r-- | src/access/sshsig.rs | 19 |
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. |
