From bd0fda477be8660c8310e35b17ea65564851db9e Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 30 May 2021 12:19:30 +0100 Subject: [PATCH] sshkeys: Rework calling conventions of sshkeys We can't pass this &mut AccountsGuard and &mut PerScope since the latter is inside the former. Signed-off-by: Ian Jackson --- src/accounts.rs | 7 +++++-- src/commands.rs | 1 + src/sshkeys.rs | 49 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/accounts.rs b/src/accounts.rs index e2c56d8d..4a40a06a 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -438,8 +438,11 @@ impl AccountsGuard { fs::rename(&tmp, &main)?; } - pub fn ssh_keys_mut(&mut self) -> &mut sshkeys::Global { - &mut self.0.get_or_insert_with(default).ssh_keys + pub fn get(&self) -> &Accounts { + self.0.as_ref().expect("loaded") + } + pub fn get_mut(&mut self) -> &mut Accounts { + self.0.as_mut().expect("loaded") } } diff --git a/src/commands.rs b/src/commands.rs index c3cc997a..a19bf5fc 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -258,6 +258,7 @@ pub enum MgmtError { #[error("game contains invalid UTF-8")] GameSpecInvalidData, #[error("idle timeout waiting for mgmt command")] IdleTimeout, #[error("upload took too long (timed out)")] UploadTimeout, + #[error("ssh keys are only for main subaccount")] NoSshKeysForSubaccount, #[error("ssh key not found")] SshKeyNotFound, #[error("ssh key id default, ie invalid")] InvalidSshKeyId, #[error("ssh key invalid: {0}")] InvalidSshKey(#[from] sshkeys::KeyError), diff --git a/src/sshkeys.rs b/src/sshkeys.rs index 255dedec..fd45bf7a 100644 --- a/src/sshkeys.rs +++ b/src/sshkeys.rs @@ -172,9 +172,31 @@ pub struct MgmtKeyReport { problem: Option, } +macro_rules! def_pskeys_get { + ($trait:ident, $f:ident, $get:ident, $($mut:tt)?) => { + #[ext(name=$trait)] + impl DenseSlotMap { + #[throws(MgmtError)] + fn $f(& $($mut)? self, acctid: AccountId) -> & $($mut)? PerScope { + let record = self.$get(acctid).ok_or(AccountNotFound)?; + if ! record.account.subaccount.is_empty() { + throw!(ME::NoSshKeysForSubaccount) + } + & $($mut)? record.ssh_keys + } + } + } +} + +def_pskeys_get!{ RecordsExtImm, pskeys_get, get , } +def_pskeys_get!{ RecordsExtMut, pskeys_mut, get_mut, mut } + impl AccountsGuard { - pub fn keys(&mut self, ps: &PerScope) -> Vec { - let gl = self.ssh_keys_mut(); + #[throws(MgmtError)] + pub fn sshkeys_report(&self, acctid: AccountId) -> Vec { + let accounts = self.get(); + let gl = &accounts.ssh_keys; + let ps = &accounts.records.pskeys_get(acctid)?; let dirty_error = if gl.authkeys_dirty { Some(KeyError::Dirty) } else { None }; @@ -195,11 +217,13 @@ impl AccountsGuard { // not a good idea to speicfy a problem, but "whatever" #[throws(ME)] - pub fn add_key(&mut self, ps: &mut PerScope, - new_akl: AuthkeysLine) -> (usize, Id) { + pub fn sshkeys_add(&mut self, acctid: AccountId, + new_akl: AuthkeysLine) -> (usize, Id) { + let accounts = self.get_mut(); + let gl = &mut accounts.ssh_keys; + let ps = accounts.records.pskeys_mut(acctid)?; let (data, comment) = new_akl.parse()?; let fp = data.fingerprint().map_err(KeyError::from)?; - let gl = self.ssh_keys_mut(); let fp = Arc::new(fp); let _ = gl.fps(); let fpe = gl.fps.as_mut().unwrap().entry(fp.clone()); @@ -236,15 +260,17 @@ impl AccountsGuard { // UNSAVED self.save_accounts_now()?; // BROKEN - self.ssh_keys_mut().rewrite_authorized_keys()?; + self.get_mut().ssh_keys.rewrite_authorized_keys()?; // PRESENT (index, id) } #[throws(ME)] - pub fn remove_key(&mut self, ps: &mut PerScope, + pub fn remove_key(&mut self, acctid: AccountId, index: usize, id: Id) { - let gl = self.ssh_keys_mut(); + let accounts = self.get_mut(); + let gl = &mut accounts.ssh_keys; + let ps = accounts.records.pskeys_mut(acctid)?; if id == default() { throw!(ME::InvalidSshKeyId); } @@ -265,7 +291,12 @@ impl AccountsGuard { let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe( || self.save_accounts_now() )); - let gl = self.ssh_keys_mut(); + + // Must re-borrow everything since save_accounts_now needed a + // reference to all of it. + let accounts = self.get_mut(); + let gl = &mut accounts.ssh_keys; + let ps = accounts.records.pskeys_mut(acctid).expect("aargh!"); let key = gl.keys.get_mut(id).expect("aargh!"); if ! matches!(r, Ok(Ok(()))) { -- 2.30.2