chiark / gitweb /
otter cli: Provide mgmtchannel-proxy subcommand
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 20:20:26 +0000 (21:20 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 1 Jun 2021 00:33:18 +0000 (01:33 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/otter.rs

index 828111a5d6363b2eeb607ae694ff2ac18d73b125..89b39d587e46753fcf8e1c3191982beb65f5f41f 100644 (file)
@@ -1816,3 +1816,58 @@ mod list_accounts {
     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,
+  )}
+}