Add WASI SSH CLI and in-process Git SSH transport
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
//! One noninteractive SSH command with host-mediated authentication.
|
||||
use clap::Parser;
|
||||
use std::{
|
||||
io::{self, Read, Write},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
#[arg(short = 'p', default_value_t = 22)]
|
||||
port: u16,
|
||||
#[arg(short = 'l')]
|
||||
user: Option<String>,
|
||||
#[arg(short = 'o')]
|
||||
options: Vec<String>,
|
||||
host: String,
|
||||
#[arg(required = true, trailing_var_arg = true)]
|
||||
command: Vec<String>,
|
||||
}
|
||||
fn run(args: Args) -> io::Result<u32> {
|
||||
let mut accept_new = false;
|
||||
for option in args.options {
|
||||
match option.as_str() {
|
||||
"StrictHostKeyChecking=accept-new" => accept_new = true,
|
||||
"StrictHostKeyChecking=yes" => accept_new = false,
|
||||
_ => return Err(io::Error::other("unsupported SSH option")),
|
||||
}
|
||||
}
|
||||
let (user, host) = match args.host.split_once('@') {
|
||||
Some((user, host)) => (Some(user), host),
|
||||
None => (args.user.as_deref(), args.host.as_str()),
|
||||
};
|
||||
let session = sausage_ssh::identity::connect(host, args.port, user, accept_new)?;
|
||||
let mut input = Vec::new();
|
||||
io::stdin().read_to_end(&mut input)?;
|
||||
let output = session.execute_input(
|
||||
args.command.join(" ").as_bytes(),
|
||||
&input,
|
||||
usize::MAX,
|
||||
Instant::now() + Duration::from_secs(300),
|
||||
)?;
|
||||
io::stdout().write_all(&output.stdout)?;
|
||||
io::stderr().write_all(&output.stderr)?;
|
||||
Ok(output.exit_code.unwrap_or(255))
|
||||
}
|
||||
fn main() {
|
||||
let status = match run(Args::parse()) {
|
||||
Ok(status) => status,
|
||||
Err(error) => {
|
||||
eprintln!("{error}");
|
||||
255
|
||||
}
|
||||
};
|
||||
std::process::exit(status.min(255) as i32);
|
||||
}
|
||||
Reference in New Issue
Block a user