aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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.