call,
)}
}
+
+//---------- mgmtchannel-proxy ----------
+
+mod mgmtchannel_proxy {
+ use super::*;
+
+ #[derive(Default,Debug)]
+ struct Args {
+ restrict: Option<sshkeys::KeySpec>,
+ }
+
+ fn subargs(sa: &mut Args) -> ArgumentParser {
+ use argparse::*;
+ let mut ap = ArgumentParser::new();
+ ap.refer(&mut sa.restrict).metavar("ID:NONCE")
+ .add_option(&["--restrict-ssh"],StoreOption,
+ "restrict to access available to registred OpenSSH key \
+ (used in runes generated by server for authorized_keys)");
+ ap
+ }
+
+ #[throws(AE)]
+ fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) {
+ let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
+ let mut conn = connect(&ma)?;
+
+ if let Some(ref restrict) = args.restrict {
+ conn.cmd(&MC::SetRestrictedSshScope { key: restrict.clone() })
+ .context("specify authorisation")?;
+ }
+
+ let Conn { chan: MgmtChannel { read, write, .. }, .. } = conn;
+ let mut read = read.into_stream()?;
+ let mut write = write.into_stream()?;
+
+ let tcmds = thread::spawn(move || {
+ io::copy(&mut io::stdin(), &mut write)
+ .context("copy commands")
+ .unwrap_or_else(|e| e.end_process(8));
+ });
+ let tresps = thread::spawn(move || {
+ io::copy(&mut read, &mut io::stdout())
+ .context("copy responses")
+ .unwrap_or_else(|e| e.end_process(8));
+ });
+ tcmds.join().expect("collect commands copy");
+ tresps.join().expect("collect responses copy");
+ }
+
+ inventory::submit!{Subcommand(
+ "mgmtchannel-proxy",
+ "connect to management channel and copy raw message data back and forth",
+ call,
+ )}
+}