chiark / gitweb /
sshkeys: Introduce KeySpec
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 19:18:18 +0000 (20:18 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 19:18:18 +0000 (20:18 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/cmdlistener.rs
src/commands.rs
src/sshkeys.rs

index 8d48aee8d5698772f1026782649cfd275942b968..650a1705f711537bc5de0e5441c9a8eff5d187e9 100644 (file)
@@ -55,8 +55,7 @@ type Euid = Result<Uid, ConnectionEuidDiscoverError>;
 enum AuthState {
   None { euid: Euid },
   Superuser { euid: Euid, auth: AuthorisationSuperuser },
-  Ssh { id: sshkeys::Id, nonce: sshkeys::Nonce,
-        auth: Authorisation<(sshkeys::Id, sshkeys::Nonce)>, },
+  Ssh { key: sshkeys::KeySpec, auth: Authorisation<sshkeys::KeySpec> },
 }
 
 #[derive(Debug,Clone)]
@@ -167,12 +166,12 @@ fn execute_and_respond<W>(cs: &mut CommandStreamData, cmd: MgmtCommand,
       }
       Fine
     },
-    MC::SetRestrictedSshScope { id, nonce } => {
+    MC::SetRestrictedSshScope { key } => {
       let good_uid = Some(config().ssh_proxy_uid);
       let auth = cs.authorised_uid(good_uid, Some("SetRestrictedScope"))
         .map_err(|_| ME::AuthorisationError)?;
       let auth = auth.therefore_ok();
-      cs.authstate = AuthState::Ssh { id, nonce, auth };
+      cs.authstate = AuthState::Ssh { key, auth };
       Fine
     },
 
@@ -1773,7 +1772,7 @@ fn do_authorise_scope(cs: &CommandStreamData, ag: &AccountsGuard,
   match &cs.authstate {
     &AuthState::Superuser { auth, .. } => return auth.into(),
 
-    &AuthState::Ssh { id: sshkey_id, ref nonce, auth } => {
+    &AuthState::Ssh { ref key, auth } => {
       let wanted_base_account = AccountName {
         scope: wanted.clone(),
         subaccount: default(),
@@ -1782,7 +1781,7 @@ fn do_authorise_scope(cs: &CommandStreamData, ag: &AccountsGuard,
         if let Ok::<_,AccountNotFound>
           ((record, _acctid)) = ag.lookup(&wanted_base_account);
         if let
-          Some(auth) = record.ssh_keys.check(ag, sshkey_id, &nonce, auth);
+          Some(auth) = record.ssh_keys.check(ag, &key, auth);
         then { return Ok(auth) }
         else { throw!(AuthorisationError("ssh key not authorised".into())); }
       }
index a0e34236fe3628c351215b98bee62a44b5cfa66a..4cece82f4dee14ff95ab1ad223ecdfda827a811f 100644 (file)
@@ -8,7 +8,7 @@ use crate::prelude::*;
 pub enum MgmtCommand {
   Noop,
   SetSuperuser(bool),
-  SetRestrictedSshScope { id: sshkeys::Id, nonce: sshkeys::Nonce },
+  SetRestrictedSshScope { key: sshkeys::KeySpec },
 
   CreateAccount(AccountDetails),
   UpdateAccount(AccountDetails),
index 4d06eabeafc08fde6a9375f293e8a1c7bfa9c238..e1eaca02defc6ad4e1890a3c0c2f7947aaebefaa 100644 (file)
@@ -66,6 +66,12 @@ pub struct ScopeKey {
   comment: Comment,
 }
 
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct KeySpec {
+  id: sshkeys::Id,
+  nonce: sshkeys::Nonce,
+}
+
 mod veneer {
   // openssh_keys's API is a little odd.  We make our own mini-API.
   use crate::prelude::*;
@@ -149,16 +155,16 @@ impl Debug for Nonce {
 }
 
 impl PerScope {
-  pub fn check(&self, ag: &AccountsGuard, id: Id, nonce: &Nonce,
-               auth_in: Authorisation<(Id, Nonce)>)
+  pub fn check(&self, ag: &AccountsGuard, authed_key: &KeySpec,
+               auth_in: Authorisation<KeySpec>)
                -> Option<Authorisation<AccountScope>> {
     let gl = &ag.get().ssh_keys;
     for sk in &self.authorised {
       if_chain!{
         if let Some(sk) = sk;
-        if sk.id == id;
-        if let Some(key) = gl.keys.get(sk.id);
-        if &key.nonce == nonce;
+        if sk.id == authed_key.id;
+        if let Some(want_key) = gl.keys.get(sk.id);
+        if &want_key.nonce == &authed_key.nonce;
         then {
           // We have checked id and nonce, against those allowed
           let auth = auth_in.therefore_ok();