Skip to content

Commit

Permalink
Improve echoserver example, bump Rust toolchain to 1.81 (#339)
Browse files Browse the repository at this point in the history
While trying out the echoserver, I've added some error handling and made
the session closable with ctrl+c, which might often be what you want. So
I thought upstreaming these changes might be a good thing.

While on it, I took the liberty of bumping the rust toolchain to 1.81,
which does not seem to break anything.

---------

Co-authored-by: Eugene <inbox@null.page>
  • Loading branch information
JuliDi and Eugeny authored Sep 17, 2024
1 parent 6e64af1 commit 73fa3e5
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 14 deletions.
13 changes: 5 additions & 8 deletions russh-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ ocyR
fn test_decode_encode_symmetry(key: &str) {
let original_key_bytes = data_encoding::BASE64_MIME
.decode(
&key.lines()
key.lines()
.filter(|line| !line.starts_with("-----"))
.collect::<Vec<&str>>()
.join("")
Expand Down Expand Up @@ -1013,7 +1013,7 @@ ocyR
sig.extend_ssh_string(&[0]);
sig.extend_ssh_string(&[0]);
let public = key.clone_public_key().unwrap();
assert_eq!(false, public.verify_detached(buf, &sig));
assert!(!public.verify_detached(buf, &sig));
}
}

Expand Down Expand Up @@ -1369,12 +1369,9 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux
let (_, buf) = client.sign_request(&public, buf).await;
let buf = buf?;
let (a, b) = buf.split_at(len);
match key {
key::KeyPair::Ed25519 { .. } => {
let sig = &b[b.len() - 64..];
assert!(public.verify_detached(a, sig));
}
_ => {}
if let key::KeyPair::Ed25519 { .. } = key {
let sig = &b[b.len() - 64..];
assert!(public.verify_detached(a, sig));
}
Ok::<(), Error>(())
})
Expand Down
10 changes: 9 additions & 1 deletion russh/examples/echoserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,14 @@ impl server::Server for Server {
self.id += 1;
s
}
fn handle_session_error(&mut self, _error: <Self::Handler as russh::server::Handler>::Error) {
eprintln!("Session error: {:#?}", _error);
}
}

#[async_trait]
impl server::Handler for Server {
type Error = anyhow::Error;
type Error = russh::Error;

async fn channel_open_session(
&mut self,
Expand Down Expand Up @@ -84,6 +87,11 @@ impl server::Handler for Server {
data: &[u8],
session: &mut Session,
) -> Result<(), Self::Error> {
// Sending Ctrl+C ends the session and disconnects the client
if data == [3] {
return Err(russh::Error::Disconnect);
}

let data = CryptoVec::from(format!("Got data: {}\r\n", String::from_utf8_lossy(data)));
self.post(data.clone()).await;
session.data(channel, data);
Expand Down
2 changes: 2 additions & 0 deletions russh/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ pub struct AuthRequest {
#[derive(Debug)]
pub enum CurrentRequest {
PublicKey {
#[allow(dead_code)]
key: CryptoVec,
#[allow(dead_code)]
algo: CryptoVec,
sent_pk_ok: bool,
},
Expand Down
4 changes: 2 additions & 2 deletions russh/src/cipher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ pub(crate) trait SealingKey {

// Maximum packet length:
// https://tools.ietf.org/html/rfc4253#section-6.1
assert!(packet_length <= std::u32::MAX as usize);
assert!(packet_length <= u32::MAX as usize);
buffer.buffer.push_u32_be(packet_length as u32);

assert!(padding_length <= std::u8::MAX as usize);
assert!(padding_length <= u8::MAX as usize);
buffer.buffer.push(padding_length as u8);
buffer.buffer.extend(payload);
self.fill_padding(buffer.buffer.resize_mut(padding_length));
Expand Down
2 changes: 1 addition & 1 deletion russh/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ impl<H: Handler> Handle<H> {
/// complete Keyboard-Interactive based SSH authentication.
///
/// * `responses` - The responses to each prompt. The number of responses must match the number
/// of prompts. If a prompt has an empty string, then the response should be an empty string.
/// of prompts. If a prompt has an empty string, then the response should be an empty string.
pub async fn authenticate_keyboard_interactive_respond(
&mut self,
responses: Vec<String>,
Expand Down
2 changes: 1 addition & 1 deletion russh/src/sshbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl SshId {
pub(crate) fn as_kex_hash_bytes(&self) -> &[u8] {
match self {
Self::Standard(s) => s.as_bytes(),
Self::Raw(s) => s.trim_end_matches(|c| c == '\n' || c == '\r').as_bytes(),
Self::Raw(s) => s.trim_end_matches(['\n', '\r']).as_bytes(),
}
}

Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[toolchain]
channel = "1.76.0"
channel = "1.81.0"

0 comments on commit 73fa3e5

Please sign in to comment.