blob: 23190609cfe78a0e47c609bff7e58836df566ea0 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
crate::config::get_config_str,
crate::constants::{SSH_PORT, SSH_PRIV},
crate::target::TargetAddr,
anyhow::{anyhow, Error},
std::collections::HashSet,
std::process::Command,
};
static DEFAULT_SSH_OPTIONS: &'static [&str] = &[
"-o CheckHostIP=no",
"-o StrictHostKeyChecking=no",
"-o UserKnownHostsFile=/dev/null",
"-o ServerAliveInterval=1",
"-o ServerAliveCountMax=10",
"-o LogLevel=ERROR",
];
pub async fn build_ssh_command(
addrs: HashSet<TargetAddr>,
command: Vec<&str>,
) -> Result<Command, Error> {
if command.is_empty() {
return Err(anyhow!("missing SSH command"));
}
let port = get_config_str(SSH_PORT, "").await;
let key = get_config_str(SSH_PRIV, "").await;
let mut c = Command::new("ssh");
if port.len() > 0 {
c.arg("-p").arg(port);
}
if key.len() > 0 {
c.arg("-i").arg(key);
}
let addr = addrs.iter().next().ok_or(anyhow!("no IP's for chosen target"))?;
c.args(DEFAULT_SSH_OPTIONS).arg(format!("{}", addr)).args(&command);
return Ok(c);
}
#[cfg(test)]
mod test {
use {
super::build_ssh_command,
crate::target::TargetAddr,
std::collections::HashSet,
std::net::{IpAddr, Ipv4Addr},
};
#[test]
fn test_empty_command_vec_produces_error() {
hoist::run(async move {
let result = build_ssh_command(HashSet::new(), vec![]).await;
assert!(result.is_err(), "empty command vec should produce an error");
});
}
#[test]
fn test_no_ips_produces_error() {
hoist::run(async move {
let result = build_ssh_command(HashSet::new(), vec!["ls"]).await;
assert!(result.is_err(), "target with no IP's should produce an error");
});
}
#[test]
fn test_valid_inputs() {
hoist::run(async move {
let key_path = std::env::current_exe().unwrap();
let key_path = key_path.to_str().take().unwrap();
std::env::set_var("FUCHSIA_SSH_PORT", "1234");
std::env::set_var("FUCHSIA_SSH_KEY", key_path);
let ip = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1));
let mut addrs = HashSet::new();
addrs.insert(TargetAddr::from((ip, 0)));
let result = build_ssh_command(addrs, vec!["ls"]).await.unwrap();
let dbgstr = format!("{:?}", result);
assert!(dbgstr.contains(&format!("\"-p\" \"1234\" \"-i\" \"{}\"", key_path)), dbgstr);
assert!(dbgstr.contains(&ip.to_string()), dbgstr);
});
}
}