chiark / gitweb /
otter cli: provide set-list-keys
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 31 May 2021 00:15:11 +0000 (01:15 +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
src/sshkeys.rs

index b2d65347f53189d9f95086fd28d56dce95aa1eb5..a502385144b76a5f7acc30b546d949633ec4093c 100644 (file)
@@ -2032,3 +2032,65 @@ mod set_ssh_keys {
     call,
   )}
 }
+
+//---------- list-ssh-keys ----------
+
+mod list_ssh_keys {
+  use super::*;
+
+  type Args = NoArgs;
+
+  #[throws(AE)]
+  fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) {
+    let _args = parse_args::<Args,_>(args, &noargs, &ok_id, None);
+    let mut conn = connect(&ma)?;
+
+    use sshkeys::*;
+
+    let mut out = BufWriter::new(io::stdout());
+
+    // find the one we're using now
+
+    let using = {
+      use MgmtResponse::ThisConnAuthBy as TCAB;
+      use MgmtThisConnAuthBy as MTCAB;
+      match conn.cmd(&MC::ThisConnAuthBy).context("find current auth")? {
+        TCAB(MTCAB::Ssh { key }) => Some(key),
+        TCAB(_) => None,
+        _ => throw!(anyhow!("unexpected response to ThisConnAuthBy")),
+      }
+    };
+
+    // obtain current set
+
+    for (_index, mkr) in match conn.cmd(&MC::SshListKeys)
+      .context("list existing keys")?
+    {
+      MR::SshKeys(report) => report,
+      _ => throw!(anyhow!("unexpected response to SshListKeys")),
+    }
+      .into_iter().enumerate()
+    {
+      let s = mkr.to_string();
+      use unicode_width::UnicodeWidthChar;
+      if s.chars().any(|c| c.width() == None /* control char */) {
+        write!(&mut out, "# FUNKY! # {:?}", &s)?;
+      } else {
+        write!(&mut out, "{}", &s)?;
+      }
+
+      if Some(&mkr.key) == using.as_ref() {
+        write!(&mut out, "# <- this connection!")?;
+      }
+      writeln!(&mut out, "")?;
+    }
+
+    out.flush()?;
+  }
+
+  inventory::submit!{Subcommand(
+    "list-ssh-keys",
+    "set SSH keys for remote management access authentication",
+    call,
+  )}
+}
index cc1069b8ba9422a22001e030e3b19c1bc4a7cba8..4fcef54e1b6d84b3be56979986869962978fefcd 100644 (file)
@@ -110,6 +110,10 @@ mod veneer {
     fn from(e: OpenSSHKeyError) -> Self { KeyError::BadData(e.to_string()) }
   }
 
+  impl Display for Comment {
+    #[throws(fmt::Error)]
+    fn fmt(&self, f: &mut fmt::Formatter) { write!(f, "{}", &self.0)? }
+  }
   impl Display for PubData {
     #[throws(fmt::Error)]
     fn fmt(&self, f: &mut fmt::Formatter) { write!(f, "{}", &self.0)? }
@@ -208,6 +212,23 @@ pub struct MgmtKeyReport {
   pub problem: Option<KeyError>,
 }
 
+impl Display for KeySpec {
+  #[throws(fmt::Error)]
+  fn fmt(&self, f: &mut fmt::Formatter) {
+    write!(f, "{}:{}", self.id, &self.nonce)?;
+  }
+}
+
+impl Display for MgmtKeyReport {
+  #[throws(fmt::Error)]
+  fn fmt(&self, f: &mut fmt::Formatter) {
+    if let Some(problem) = &self.problem {
+      write!(f, "# PROBLEM {} # ", &problem)?;
+    }
+    write!(f, "{} {} # {}", &self.data, &self.comment, &self.key)?;
+  }
+}
+
 macro_rules! def_pskeys_get {
   ($trait:ident, $f:ident, $get:ident, $($mut:tt)?) => {
     #[ext(name=$trait)]