From a8da82a55164442e974cead96a8d1502978acc0a Mon Sep 17 00:00:00 2001 From: David Date: Thu, 26 Aug 2021 02:05:46 -0400 Subject: [PATCH] While preparing to port my netcat/tar shell combo to shoop, I noticed it didn't support non-standard port options (outside of 22), so I sprinkled some in. --- src/connection/mod.rs | 6 +++++- src/lib.rs | 12 +++++++----- src/main.rs | 9 +++++++-- src/ssh.rs | 12 +++++++++--- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/connection/mod.rs b/src/connection/mod.rs index 4188127..5c78cec 100644 --- a/src/connection/mod.rs +++ b/src/connection/mod.rs @@ -93,10 +93,13 @@ pub struct Server { sock: UdtSocket, } +pub type SSHPort = String; + pub struct Client { addr: SocketAddr, sock: UdtSocket, crypto: crypto::Handler, + ssh_port: SSHPort } pub struct ServerConnection { @@ -105,12 +108,13 @@ pub struct ServerConnection { } impl Client { - pub fn new(addr: SocketAddr, key: &[u8]) -> Client { + pub fn new(addr: SocketAddr, key: &[u8], ssh_port: &str) -> Client { let sock = new_udt_socket(); Client { addr: addr, sock: sock, crypto: crypto::Handler::new(key), + ssh_port: ssh_port.to_owned() } } diff --git a/src/lib.rs b/src/lib.rs index a61fa82..cc0989a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub mod progress; use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian}; use colored::*; -use connection::{PortRange, Transceiver}; +use connection::{PortRange, SSHPort, Transceiver}; use log::{Record, Level, Metadata}; use std::net::{SocketAddr, IpAddr}; use std::fs::File; @@ -99,6 +99,7 @@ enum TransferState { pub struct Client { port_range: PortRange, transfer_state: TransferState, + ssh_port: SSHPort } #[derive(Clone, Copy)] @@ -488,7 +489,7 @@ impl Server { impl Client { - pub fn new(source: Target, dest: Target, port_range: PortRange) + pub fn new(source: Target, dest: Target, port_range: PortRange, ssh_port: SSHPort) -> Result { if source.is_local() && dest.is_local() || source.is_remote() && dest.is_remote() { @@ -541,7 +542,8 @@ impl Client { Ok(Client { port_range: port_range, - transfer_state: state + transfer_state: state, + ssh_port: ssh_port }) } @@ -551,7 +553,7 @@ impl Client { panic!("sending unsupported"); } TransferState::Receive((host, path), _) => { - ssh::Connection::new(host, path, &self.port_range) + ssh::Connection::new(host, path, &self.port_range, &self.ssh_port) } }; @@ -627,7 +629,7 @@ impl Client { loop { overprint!(" - opening UDT connection..."); - let mut conn = connection::Client::new(addr, &keybytes); + let mut conn = connection::Client::new(addr, &keybytes, &self.ssh_port); match conn.connect() { Ok(()) => { overprint!(" - connection opened, shakin' hands, makin' frands"); diff --git a/src/main.rs b/src/main.rs index 3f236c7..f9d63ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,9 @@ struct Opt { #[structopt(short = "p", long = "port-range", default_value = "55000-55050")] port_range: String, + #[structopt(short = "P", long = "ssh-port", default_value = "22")] + ssh_port: String, + #[structopt(name = "SOURCE", help = "The source target, ex. \"my.server.com:~/file.bin\"")] source: String, @@ -44,6 +47,8 @@ fn main() { let port_range = PortRange::from(&opt.port_range).unwrap(); + let ssh_port = opt.ssh_port; + ShoopLogger::init(mode, verbosity).expect("Error starting shoop logger."); match mode { @@ -58,8 +63,8 @@ fn main() { ShoopMode::Client => { let source = Target::from(opt.source.clone()); let dest = Target::from(opt.dest.clone()); - - match Client::new(source, dest, port_range) { + + match Client::new(source, dest, port_range, ssh_port) { Ok(mut client) => client.start(opt.force), Err(e) => error!("{}", e), } diff --git a/src/ssh.rs b/src/ssh.rs index c8bc60d..217adb5 100644 --- a/src/ssh.rs +++ b/src/ssh.rs @@ -1,4 +1,4 @@ -use connection::PortRange; +use connection::{PortRange, SSHPort}; use std::collections::HashMap; use std::io; use std::net::SocketAddr; @@ -33,6 +33,7 @@ pub struct Connection { hostname: String, path: PathBuf, port_range: PortRange, + ssh_port: SSHPort } pub struct Response { @@ -70,11 +71,12 @@ impl From for Error { } impl Connection { - pub fn new>(hostname: S, path: PathBuf, port_range: &PortRange) -> Connection { + pub fn new>(hostname: S, path: PathBuf, port_range: &PortRange, ssh_port: &SSHPort) -> Connection { Connection { hostname: hostname.into(), path: path, port_range: port_range.to_owned(), + ssh_port: ssh_port.to_owned() } } @@ -94,7 +96,10 @@ impl Connection { self.path.to_string_lossy(), self.port_range); debug!("👉 ssh {} {}", &self.hostname, cmd); + let mut command = Command::new("ssh"); + command.arg(format!("-p {}", &self.ssh_port)); + for arg in extra_args { command.arg(&arg); } @@ -103,7 +108,8 @@ impl Connection { .output()); if !output.status.success() { - Err(Error::new(ErrorType::SshError, "ssh returned failure exit code")) + let err = String::from_utf8_lossy(&output.stderr); + Err(Error::new(ErrorType::SshError, format!("ssh returned failure exit code: {:?}", err))) } else { Ok(output) }