Skip to main content

stackforge_core/layer/ssh/
builder.rs

1//! SSH layer builder.
2//!
3//! Provides a minimal builder for SSH version exchange messages.
4//! Full SSH binary packet construction is not supported since SSH
5//! requires encryption context for most operations.
6
7/// Builder for SSH layer data.
8///
9/// Currently supports building SSH version exchange messages.
10/// Binary SSH packets require encryption and are not constructable.
11#[derive(Debug, Clone)]
12pub struct SshBuilder {
13    /// Version string (e.g., "OpenSSH_9.2p1")
14    version: String,
15}
16
17impl Default for SshBuilder {
18    fn default() -> Self {
19        Self {
20            version: "stackforge".to_string(),
21        }
22    }
23}
24
25impl SshBuilder {
26    /// Create a new SSH builder with default version string.
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    /// Create an SSH version exchange message.
32    ///
33    /// Generates `SSH-2.0-{version}\r\n`.
34    pub fn version_exchange(version: &str) -> Self {
35        Self {
36            version: version.to_string(),
37        }
38    }
39
40    /// Set the version string.
41    pub fn version(mut self, version: &str) -> Self {
42        self.version = version.to_string();
43        self
44    }
45
46    /// Get the header size (the full version exchange message length).
47    pub fn header_size(&self) -> usize {
48        // "SSH-2.0-" + version + "\r\n"
49        8 + self.version.len() + 2
50    }
51
52    /// Build the SSH version exchange into bytes.
53    pub fn build(&self) -> Vec<u8> {
54        format!("SSH-2.0-{}\r\n", self.version).into_bytes()
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn test_version_exchange_build() {
64        let builder = SshBuilder::version_exchange("OpenSSH_9.2p1");
65        let bytes = builder.build();
66        assert_eq!(bytes, b"SSH-2.0-OpenSSH_9.2p1\r\n");
67    }
68
69    #[test]
70    fn test_default_version() {
71        let builder = SshBuilder::new();
72        let bytes = builder.build();
73        assert_eq!(bytes, b"SSH-2.0-stackforge\r\n");
74    }
75
76    #[test]
77    fn test_header_size() {
78        let builder = SshBuilder::version_exchange("test");
79        assert_eq!(builder.header_size(), builder.build().len());
80    }
81}