From 9f17d6c2e125598c27379ba1d5e7c1b35ffc4a6c Mon Sep 17 00:00:00 2001 From: William Brawner Date: Wed, 27 Jul 2022 21:18:25 -0600 Subject: [PATCH] Add telnet command --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 60d246d..c493a8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,7 @@ name = "gsm-agent" version = "0.1.0" dependencies = [ "minreq", + "telnet", ] [[package]] @@ -148,6 +149,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "telnet" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99f2cc260bea5219955ab4832c9600a41b87101d280939edae6dd10b3c68a4f3" + [[package]] name = "unicode-ident" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index 10555ec..a5e0167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ lto = true [dependencies] minreq = { version = "2.6.0", features = ["https"] } +telnet = "0.2.1" diff --git a/src/main.rs b/src/main.rs index c0a0c62..1533095 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,11 @@ use std::net::TcpListener; use std::net::TcpStream; use std::path::Path; use std::process::Command; +use std::time::Duration; use gsm_agent::ThreadPool; +use telnet::Event; +use telnet::Telnet; fn main() { let listener = TcpListener::bind("127.0.0.1:4762").unwrap(); @@ -68,6 +71,38 @@ where String::from_utf8(Command::new(command).args(args).output().unwrap().stdout).unwrap() } +fn telnet(stream: &mut TcpStream, host: &str, port: &u16) -> Result { + let mut telnet = Telnet::connect((host, *port), 4096)?; + let mut stream_buffer = [0; 4096]; + stream.set_read_timeout(Some(Duration::new(1, 0)))?; + 'main: loop { + match stream.read(&mut stream_buffer) { + Ok(read) => { + match String::from_utf8_lossy(&stream_buffer[0..read]) + .as_ref() + .trim() + { + "quit" => break 'main, + _ => telnet.write(&stream_buffer[0..read]).unwrap(), + }; + } + Err(_) => {} + }; + match telnet.read_timeout(Duration::new(1, 0)) { + Ok(event) => { + if let Event::Data(buffer) = event { + stream.write(&buffer).unwrap(); + } + } + Err(e) => { + println!("telnet read error: {:?}\n", e); + break 'main; + } + } + } + Ok(String::from("Telnet connection closed")) +} + fn handle_connection(mut stream: TcpStream) { loop { let mut buffer = [0; 1024]; @@ -104,6 +139,14 @@ fn handle_connection(mut stream: TcpStream) { "ping" => String::from("pong"), "pwd" => pwd(), "shell" => shell(command_iter.next().unwrap(), command_iter), + "telnet" => { + let host = command_iter.next().unwrap(); + let port = u16::from_str_radix(command_iter.next().unwrap(), 10).unwrap(); + match telnet(&mut stream, host, &port) { + Ok(s) => s, + Err(e) => e.to_string(), + } + } _ => { format!( "unknown command: {:?}",