Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
619 changes: 0 additions & 619 deletions russh/src/tests.rs

This file was deleted.

434 changes: 434 additions & 0 deletions russh/src/tests/channels.rs

Large diffs are not rendered by default.

132 changes: 132 additions & 0 deletions russh/src/tests/compress.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use log::debug;
use rand_core::OsRng;
use russh_cryptovec::CryptoVec;
use ssh_key::PrivateKey;

use crate::keys::PrivateKeyWithHashAlg;
use crate::server::{Msg, Server as _, Session};
use crate::tests::test_init;
use crate::{client, server, Channel, ChannelId, ChannelMsg, Preferred};

#[tokio::test]
async fn compress_local_test() {
test_init();

let client_key = PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap();
let mut config = crate::server::Config::default();
config.preferred = Preferred::COMPRESSED;
config.inactivity_timeout = None; // Some(std::time::Duration::from_secs(3));
config.auth_rejection_time = std::time::Duration::from_secs(3);
config
.keys
.push(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap());
let config = Arc::new(config);
let mut sh = Server {
clients: Arc::new(Mutex::new(HashMap::new())),
id: 0,
};

let socket = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = socket.local_addr().unwrap();

tokio::spawn(async move {
let (socket, _) = socket.accept().await.unwrap();
let server = sh.new_client(socket.peer_addr().ok());
server::run_stream(config, socket, server).await.unwrap();
});

let mut config = client::Config::default();
config.preferred = Preferred::COMPRESSED;
let config = Arc::new(config);

let mut session = client::connect(config, addr, Client {}).await.unwrap();
let authenticated = session
.authenticate_publickey(
std::env::var("USER").unwrap_or("user".to_owned()),
PrivateKeyWithHashAlg::new(
Arc::new(client_key),
session.best_supported_rsa_hash().await.unwrap().flatten(),
),
)
.await
.unwrap()
.success();
assert!(authenticated);
let mut channel = session.channel_open_session().await.unwrap();

let data = &b"Hello, world!"[..];
channel.data(data).await.unwrap();
let msg = channel.wait().await.unwrap();
match msg {
ChannelMsg::Data { data: msg_data } => {
assert_eq!(*data, *msg_data)
}
msg => panic!("Unexpected message {:?}", msg),
}
}

#[derive(Clone)]
struct Server {
clients: Arc<Mutex<HashMap<(usize, ChannelId), server::Handle>>>,
id: usize,
}

impl server::Server for Server {
type Handler = Self;
fn new_client(&mut self, _: Option<std::net::SocketAddr>) -> Self {
let s = self.clone();
self.id += 1;
s
}
}

impl server::Handler for Server {
type Error = crate::Error;

async fn channel_open_session(
&mut self,
channel: Channel<Msg>,
session: &mut Session,
) -> Result<bool, Self::Error> {
{
let mut clients = self.clients.lock().unwrap();
clients.insert((self.id, channel.id()), session.handle());
}
Ok(true)
}
async fn auth_publickey(
&mut self,
_: &str,
_: &crate::keys::ssh_key::PublicKey,
) -> Result<server::Auth, Self::Error> {
debug!("auth_publickey");
Ok(server::Auth::Accept)
}
async fn data(
&mut self,
channel: ChannelId,
data: &[u8],
session: &mut Session,
) -> Result<(), Self::Error> {
debug!("server data = {:?}", std::str::from_utf8(data));
session.data(channel, CryptoVec::from_slice(data))?;
Ok(())
}
}

struct Client {}

impl client::Handler for Client {
type Error = crate::Error;

async fn check_server_key(
&mut self,
_server_public_key: &crate::keys::ssh_key::PublicKey,
) -> Result<bool, Self::Error> {
// println!("check_server_key: {:?}", server_public_key);
Ok(true)
}
}
18 changes: 18 additions & 0 deletions russh/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] // Allow unwraps, expects and panics in the test suite

mod channels;
mod compress;
mod server_kex_junk;
mod test_backpressure;
mod test_crypto;
mod test_data_channels;
mod test_data_stream;
mod test_framework;
mod test_kex;
mod test_tcpip_channels;

pub fn test_init() {
let _ = env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.try_init();
}
51 changes: 51 additions & 0 deletions russh/src/tests/server_kex_junk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::sync::Arc;

use tokio::io::AsyncWriteExt;

use crate::server;
use crate::server::Server as _;
use crate::tests::test_init;

#[tokio::test]
async fn server_kex_junk_test() {
test_init();

let config = server::Config::default();
let config = Arc::new(config);
let mut sh = Server {};

let socket = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = socket.local_addr().unwrap();

tokio::spawn(async move {
let mut client_stream = tokio::net::TcpStream::connect(addr).await.unwrap();
client_stream
.write_all(b"SSH-2.0-Client_1.0\r\n")
.await
.unwrap();
// Unexpected message pre-kex
client_stream.write_all(&[0, 0, 0, 2, 0, 99]).await.unwrap();
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
});

let (socket, _) = socket.accept().await.unwrap();
let server = sh.new_client(socket.peer_addr().ok());
let rs = server::run_stream(config, socket, server).await.unwrap();

// May not panic
assert!(rs.await.is_err());
}

#[derive(Clone)]
struct Server {}

impl server::Server for Server {
type Handler = Self;
fn new_client(&mut self, _: Option<std::net::SocketAddr>) -> Self {
self.clone()
}
}

impl server::Handler for Server {
type Error = crate::Error;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@ use std::sync::Arc;
use futures::FutureExt;
use rand::RngCore;
use rand_core::OsRng;
use russh::keys::PrivateKeyWithHashAlg;
use russh::server::{self, Auth, Msg, Server as _, Session};
use russh::{client, Channel, ChannelMsg};
use ssh_key::PrivateKey;
use tokio::io::AsyncWriteExt;
use tokio::sync::watch;
use tokio::time::sleep;

use crate::keys::PrivateKeyWithHashAlg;
use crate::server::{self, Auth, Msg, Server as _, Session};
use crate::tests::test_init;
use crate::{client, Channel, ChannelMsg};

pub const WINDOW_SIZE: usize = 8 * 2048;
pub const CHANNEL_BUFFER_SIZE: usize = 10;

#[tokio::test]
async fn test_backpressure() -> Result<(), anyhow::Error> {
env_logger::init();
test_init();

let addr = addr();
let data = data();
Expand All @@ -39,7 +41,7 @@ async fn stream(addr: SocketAddr, data: &[u8], tx: watch::Sender<()>) -> Result<
let config = Arc::new(client::Config::default());
let key = Arc::new(PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap());

let mut session = russh::client::connect(config, addr, Client).await?;
let mut session = crate::client::connect(config, addr, Client).await?;
let channel = match session
.authenticate_publickey(
"user",
Expand Down Expand Up @@ -108,15 +110,15 @@ impl Server {
}
}

impl russh::server::Server for Server {
impl crate::server::Server for Server {
type Handler = Self;

fn new_client(&mut self, _: Option<std::net::SocketAddr>) -> Self::Handler {
self.clone()
}
}

impl russh::server::Handler for Server {
impl crate::server::Handler for Server {
type Error = anyhow::Error;

async fn auth_publickey(
Expand Down Expand Up @@ -148,7 +150,7 @@ impl russh::server::Handler for Server {

struct Client;

impl russh::client::Handler for Client {
impl crate::client::Handler for Client {
type Error = anyhow::Error;

async fn check_server_key(&mut self, _: &ssh_key::PublicKey) -> Result<bool, Self::Error> {
Expand Down
Loading
Loading