extern crate env_logger;
extern crate futures;
extern crate thrussh;
extern crate thrussh_keys;
extern crate tokio;
use anyhow::Context;
use std::sync::Arc;
use thrussh::*;
use thrussh_keys::*;
struct Client {}
impl client::Handler for Client {
type Error = thrussh::Error;
type FutureUnit = futures::future::Ready<Result<(Self, client::Session), Self::Error>>;
type FutureBool = futures::future::Ready<Result<(Self, bool), Self::Error>>;
fn finished_bool(self, b: bool) -> Self::FutureBool {
futures::future::ready(Ok((self, b)))
}
fn finished(self, session: client::Session) -> Self::FutureUnit {
futures::future::ready(Ok((self, session)))
}
fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool {
println!("check_server_key: {:?}", server_public_key);
self.finished_bool(true)
}
}
#[tokio::main]
async fn main() {
env_logger::init();
let config = thrussh::client::Config::default();
let config = Arc::new(config);
let sh = Client {};
let mut agent = thrussh_keys::agent::client::AgentClient::connect_env()
.await
.unwrap();
let mut identities = agent.request_identities().await.unwrap();
let mut session = thrussh::client::connect(config, "127.0.0.1:2200", sh)
.await
.unwrap();
let (_, auth_res) = session
.authenticate_future("pe", identities.pop().unwrap(), agent)
.await;
let auth_res = auth_res.unwrap();
println!("=== auth: {}", auth_res);
let mut channel = session
.channel_open_direct_tcpip("localhost", 8000, "localhost", 3333)
.await
.unwrap();
// let mut channel = session.channel_open_session().await.unwrap();
println!("=== after open channel");
let data = b"GET /les_affames.mkv HTTP/1.1\nUser-Agent: curl/7.68.0\nAccept: */*\nConnection: close\n\n";
channel.data(&data[..]).await.unwrap();
let mut f = std::fs::File::create("les_affames.mkv").unwrap();
while let Some(msg) = channel.wait().await {
use std::io::Write;
match msg {
thrussh::ChannelMsg::Data { ref data } => {
f.write_all(&data).unwrap();
}
thrussh::ChannelMsg::Eof => {
f.flush().unwrap();
break;
}
_ => {}
}
}
session
.disconnect(Disconnect::ByApplication, "", "English")
.await
.unwrap();
let res = session.await.context("session await");
println!("{:#?}", res);
}