From df750dd4e0da4104b1c50d99b72c789a28f51b5a Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Sun, 6 Nov 2022 23:37:16 +0800
Subject: [PATCH] Move version writing to ident

---
 src/conn.rs    |  2 +-
 src/ident.rs   | 19 +++++++++++++++++--
 src/traffic.rs | 16 +++++-----------
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/conn.rs b/src/conn.rs
index 3041308..b2830a9 100644
--- a/src/conn.rs
+++ b/src/conn.rs
@@ -122,7 +122,7 @@ impl Conn {
         debug!("progress conn state {:?}", self.state);
         match self.state {
             ConnState::SendIdent => {
-                s.send_version(ident::OUR_VERSION)?;
+                s.send_version()?;
                 self.kex.send_kexinit(&self.algo_conf, s)?;
                 // TODO: first_follows would have a second packet here
                 self.state = ConnState::ReceiveIdent
diff --git a/src/ident.rs b/src/ident.rs
index b19364b..c7852a8 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -1,8 +1,8 @@
 use crate::error::{Error,TrapBug};
 
-pub(crate) const OUR_VERSION: &[u8] = "SSH-2.0-SunsetSSH".as_bytes();
+pub(crate) const OUR_VERSION: &[u8] = b"SSH-2.0-SunsetSSH-0.1";
 
-const SSH_PREFIX: &[u8] = "SSH-2.0-".as_bytes();
+pub(crate) const SSH_PREFIX: &[u8] = b"SSH-2.0-";
 
 // RFC4253 4.2 says max length 255 incl CR LF.
 // TODO find what's in the wild
@@ -12,6 +12,21 @@ const MAX_LINES: usize = 50;
 pub const CR: u8 = 0x0d;
 pub const LF: u8 = 0x0a;
 
+pub(crate) fn write_version(buf: &mut [u8]) -> Result<usize> {
+
+    let total_len = OUR_VERSION.len() + 2;
+    if total_len > buf.len() {
+        return Err(Error::NoRoom);
+    }
+
+    let (d, b) = buf.split_at_mut(OUR_VERSION.len());
+    d.copy_from_slice(OUR_VERSION);
+    b[0] = CR;
+    b[1] = LF;
+
+    return Ok(total_len)
+}
+
 /// Parses and stores the remove SSH version string
 pub struct RemoteVersion {
     storage: [u8; MAX_REMOTE_VERSION_LEN],
diff --git a/src/traffic.rs b/src/traffic.rs
index e412876..f480b80 100644
--- a/src/traffic.rs
+++ b/src/traffic.rs
@@ -334,19 +334,13 @@ impl<'a> TrafOut<'a> {
         }
     }
 
-    pub fn send_version(&mut self, buf: &[u8]) -> Result<(), Error> {
+    pub fn send_version(&mut self) -> Result<(), Error> {
         if !matches!(self.state, TxState::Idle) {
             return Err(Error::bug());
         }
 
-        if buf.len() + 2 > self.buf.len() {
-            return Err(Error::NoRoom);
-        }
-
-        self.buf[..buf.len()].copy_from_slice(buf);
-        self.buf[buf.len()] = ident::CR;
-        self.buf[buf.len()+1] = ident::LF;
-        self.state = TxState::Write { idx: 0, len: buf.len() + 2 };
+        let len = ident::write_version(&mut self.buf)?;
+        self.state = TxState::Write { idx: 0, len };
         Ok(())
     }
 
@@ -400,8 +394,8 @@ impl<'s, 'a> TrafSend<'s, 'a> {
         self.keys.rekey(keys)
     }
 
-    pub fn send_version(&mut self, buf: &[u8]) -> Result<(), Error> {
-        self.out.send_version(buf)
+    pub fn send_version(&mut self) -> Result<(), Error> {
+        self.out.send_version()
     }
 
     pub fn can_output(&self) -> bool {
-- 
GitLab