gardesk/garcard / a32a010

Browse files

Add temp-list authorization introspection

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
a32a010a7a3922bacebde2d23a0ffc9a64c0ad84
Parents
9559b3f
Tree
c9a3529

4 changed files

StatusFile+-
M garcard-ipc/src/lib.rs 1 0
M garcard/src/agent.rs 37 0
M garcard/src/daemon.rs 13 1
M garcardctl/src/main.rs 2 0
garcard-ipc/src/lib.rsmodified
@@ -21,6 +21,7 @@ pub enum Command {
2121
     Status,
2222
     Version,
2323
     AuthSummary,
24
+    TempList,
2425
     Quit,
2526
 }
2627
 
garcard/src/agent.rsmodified
@@ -9,6 +9,7 @@ use std::path::PathBuf;
99
 use std::sync::atomic::{AtomicBool, Ordering};
1010
 use std::sync::{Arc, Condvar, Mutex};
1111
 use std::thread;
12
+use std::time::{SystemTime, UNIX_EPOCH};
1213
 use zbus::blocking::{Connection, Proxy};
1314
 use zbus::fdo;
1415
 use zbus::zvariant::{OwnedObjectPath, OwnedValue, Str};
@@ -56,6 +57,15 @@ pub struct PolkitBackendConfig {
5657
 type Subject = (String, HashMap<String, OwnedValue>);
5758
 type Details = HashMap<String, String>;
5859
 type TemporaryAuthorization = (String, String, Subject, u64, u64);
60
+
61
+#[derive(Debug, Clone, serde::Serialize)]
62
+pub struct TemporaryAuthorizationRecord {
63
+    pub authorization_id: String,
64
+    pub action_id: String,
65
+    pub obtained_at_unix: u64,
66
+    pub expires_at_unix: u64,
67
+    pub expires_in_secs: u64,
68
+}
5969
 const DEFAULT_AUTH_MAX_ATTEMPTS: usize = 3;
6070
 const DEFAULT_IDENTITY_SELECTION_ATTEMPTS: usize = 3;
6171
 const DEFAULT_RETENTION_SELECTION_ATTEMPTS: usize = 3;
@@ -659,6 +669,33 @@ fn helper_outcome_label(outcome: HelperOutcome) -> &'static str {
659669
     }
660670
 }
661671
 
672
+pub fn enumerate_temporary_authorizations() -> Result<Vec<TemporaryAuthorizationRecord>> {
673
+    let connection = Connection::system().context("failed to connect to system bus")?;
674
+    let subject = build_subject();
675
+    let proxy = PolkitAgent::proxy(&connection)?;
676
+    let authorizations: Vec<TemporaryAuthorization> =
677
+        proxy.call("EnumerateTemporaryAuthorizations", &subject)?;
678
+    let now_unix = SystemTime::now()
679
+        .duration_since(UNIX_EPOCH)
680
+        .map(|duration| duration.as_secs())
681
+        .unwrap_or(0);
682
+
683
+    let mut entries = Vec::with_capacity(authorizations.len());
684
+    for (authorization_id, action_id, _subject, obtained_at_unix, expires_at_unix) in authorizations
685
+    {
686
+        let expires_in_secs = expires_at_unix.saturating_sub(now_unix);
687
+        entries.push(TemporaryAuthorizationRecord {
688
+            authorization_id,
689
+            action_id,
690
+            obtained_at_unix,
691
+            expires_at_unix,
692
+            expires_in_secs,
693
+        });
694
+    }
695
+    entries.sort_by(|left, right| left.action_id.cmp(&right.action_id));
696
+    Ok(entries)
697
+}
698
+
662699
 fn revoke_temporary_authorizations_for_action(action_id: &str) -> Result<usize> {
663700
     let connection = Connection::system().context("failed to connect to system bus")?;
664701
     let subject = build_subject();
garcard/src/daemon.rsmodified
@@ -1,4 +1,7 @@
1
-use crate::agent::{AuthAgentBackend, PolkitAgent, PolkitBackendConfig, StubPolkitAgent};
1
+use crate::agent::{
2
+    AuthAgentBackend, PolkitAgent, PolkitBackendConfig, StubPolkitAgent,
3
+    enumerate_temporary_authorizations,
4
+};
25
 use crate::config::{AgentBackendMode, Config};
36
 use crate::state::{AuthState, RuntimeState};
47
 use anyhow::{Context, Result};
@@ -286,6 +289,15 @@ fn dispatch(
286289
         Command::Status => Response::ok_with_data(state.status()),
287290
         Command::Version => Response::ok_with_data(state.version()),
288291
         Command::AuthSummary => Response::ok_with_data(state.auth_summary()),
292
+        Command::TempList => match enumerate_temporary_authorizations() {
293
+            Ok(authorizations) => {
294
+                Response::ok_with_data(json!({ "authorizations": authorizations }))
295
+            }
296
+            Err(err) => Response::err(format!(
297
+                "failed to enumerate temporary authorizations: {}",
298
+                err
299
+            )),
300
+        },
289301
         Command::Quit => {
290302
             if shutdown_tx.send(()).is_err() {
291303
                 Response::err("daemon shutdown channel unavailable")
garcardctl/src/main.rsmodified
@@ -17,6 +17,7 @@ enum Commands {
1717
     Status,
1818
     Version,
1919
     AuthSummary,
20
+    TempList,
2021
     Quit,
2122
 }
2223
 
@@ -47,6 +48,7 @@ fn to_protocol_command(command: Commands) -> Command {
4748
         Commands::Status => Command::Status,
4849
         Commands::Version => Command::Version,
4950
         Commands::AuthSummary => Command::AuthSummary,
51
+        Commands::TempList => Command::TempList,
5052
         Commands::Quit => Command::Quit,
5153
     }
5254
 }