1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#[doc(inline)]
pub use super::constants::KeyType;
use std::iter::FromIterator;

/// A key or key/value token which set parameters on the way the
/// given public key is used by OpenSSH.
///
/// Inner slashes or double-quotes must be escaped.
///
/// ```
/// use authorized_keys::openssh::v2::KeyOption;
///
/// let simple_option: KeyOption = ("no-agent-forwarding".to_owned(), None);
/// let value_option: KeyOption = ("command".to_owned(), Some("echo \\\"Hello, world!\\\"".to_owned()));
/// ```
pub type KeyOption = (String, Option<String>);
/// A list of `KeyOption` structs, suitable for placement in front of an
/// `AuthorizedKey`.
pub type KeyOptions = Vec<KeyOption>;

/// Represents a public key for authorization
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct PublicKey {
    /// Type of key (e.g. `ssh-rsa` -> `AuthorizedKeyType::SshRsa`)
    pub key_type: KeyType,
    /// Public key data, base64 encoded
    pub encoded_key: String,
}

impl PublicKey {
    /// Create a representation of a public key
    pub fn new(key_type: KeyType, encoded_key: String) -> Self {
        Self {
            key_type,
            encoded_key,
        }
    }
}

/// Represents the format of a key in an OpenSSH v2 `authorized_keys`
/// file.
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct KeyAuthorization {
    /// Options applied to the key
    pub options: KeyOptions,
    /// Public key type and data
    pub key: PublicKey,
    /// Comments written at the end of the `authorized_keys` line
    pub comments: String,
}

/// Represents a valid line in an `authorized_keys` file.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum KeysFileLine {
    /// A comment line: begins with a "#", or is only whitespace.
    Comment(String),
    /// An authorized key line.
    Key(KeyAuthorization),
}

/// Represents an `authorized_keys` file.
#[derive(Debug, Default, Clone)]
pub struct KeysFile {
    /// Lines of the `authorized_keys` file
    pub lines: Vec<KeysFileLine>,
}

impl FromIterator<KeysFileLine> for KeysFile {
    fn from_iter<I: IntoIterator<Item = KeysFileLine>>(i: I) -> Self {
        Self {
            lines: i.into_iter().collect::<Vec<_>>(),
        }
    }
}

impl IntoIterator for KeysFile {
    type Item = KeysFileLine;
    type IntoIter = ::std::vec::IntoIter<KeysFileLine>;

    fn into_iter(self) -> Self::IntoIter {
        self.lines.into_iter()
    }
}