gardesk/garcard / 18ebea4

Browse files

Prefer session user for helper auth

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
18ebea40bbd216b351b5d97c393014a8bb874344
Parents
5ad012e
Tree
f0cdfeb

2 changed files

StatusFile+-
M garcard/src/agent.rs 50 8
M garcard/src/polkit_helper.rs 19 15
garcard/src/agent.rsmodified
@@ -200,6 +200,7 @@ impl PolkitRuntime {
200200
                 action_id = %active.action_id,
201201
                 icon_name = %active.icon_name,
202202
                 detail_count = active.detail_count,
203
+                username = %active.username,
203204
                 "Processing polkit auth request"
204205
             );
205206
 
@@ -317,24 +318,45 @@ impl PolkitRuntime {
317318
 }
318319
 
319320
 fn resolve_identity_username(identities: &[Subject]) -> Option<String> {
321
+    let current = current_username();
322
+    if let Some(current_name) = current.as_deref() {
323
+        for (kind, details) in identities {
324
+            if kind != "unix-user" {
325
+                continue;
326
+            }
327
+
328
+            if let Some(name) = identity_name(details) {
329
+                if name == current_name {
330
+                    return Some(name);
331
+                }
332
+            }
333
+        }
334
+    }
335
+
320336
     for (kind, details) in identities {
321337
         if kind != "unix-user" {
322338
             continue;
323339
         }
324340
 
325
-        if let Some(value) = details.get("name") {
326
-            if let Ok(name) = <&str>::try_from(value) {
327
-                return Some(name.to_string());
328
-            }
341
+        if let Some(name) = identity_name(details) {
342
+            return Some(name);
329343
         }
344
+    }
330345
 
331
-        if let Some(uid) = details.get("uid").and_then(parse_uid) {
332
-            if let Some(name) = username_for_uid(uid) {
333
-                return Some(name);
334
-            }
346
+    None
347
+}
348
+
349
+fn identity_name(details: &HashMap<String, OwnedValue>) -> Option<String> {
350
+    if let Some(value) = details.get("name") {
351
+        if let Ok(name) = <&str>::try_from(value) {
352
+            return Some(name.to_string());
335353
         }
336354
     }
337355
 
356
+    if let Some(uid) = details.get("uid").and_then(parse_uid) {
357
+        return username_for_uid(uid);
358
+    }
359
+
338360
     None
339361
 }
340362
 
@@ -826,4 +848,24 @@ mod tests {
826848
         let resolved = resolve_identity_username(&identities);
827849
         assert_eq!(resolved, current_username());
828850
     }
851
+
852
+    #[test]
853
+    fn resolve_identity_username_prefers_current_user_name() {
854
+        let mut first = HashMap::new();
855
+        first.insert("uid".to_string(), OwnedValue::from(0_u32));
856
+
857
+        let mut second = HashMap::new();
858
+        second.insert(
859
+            "uid".to_string(),
860
+            OwnedValue::from(nix::unistd::geteuid().as_raw()),
861
+        );
862
+
863
+        let identities = vec![
864
+            ("unix-user".to_string(), first),
865
+            ("unix-user".to_string(), second),
866
+        ];
867
+
868
+        let resolved = resolve_identity_username(&identities);
869
+        assert_eq!(resolved, current_username());
870
+    }
829871
 }
garcard/src/polkit_helper.rsmodified
@@ -99,6 +99,10 @@ impl HelperSocketClient {
9999
             if bytes == 0 {
100100
                 anyhow::bail!("helper closed connection unexpectedly");
101101
             }
102
+            tracing::debug!(
103
+                helper_line = %line.trim_end_matches('\n').trim_end_matches('\r'),
104
+                "Received helper protocol line"
105
+            );
102106
 
103107
             let event = match parse_helper_line(&line) {
104108
                 Ok(event) => event,
@@ -211,17 +215,14 @@ pub fn parse_helper_line(raw: &str) -> Result<HelperEvent> {
211215
         return Ok(HelperEvent::Info(message.to_string()));
212216
     }
213217
 
214
-    // Some helper builds emit plain-text diagnostics instead of PAM_* protocol
215
-    // lines. Classify known auth failures so callers can present proper retry UX
216
-    // without treating successful paths as generic errors.
217
-    let lower = line.to_ascii_lowercase();
218
-    if lower.contains("pam_authenticate failed")
219
-        || lower.contains("authentication failure")
220
-        || lower.contains("no session for cookie")
221
-    {
222
-        return Ok(HelperEvent::Failure);
223
-    }
224218
     if line.starts_with("polkit-agent-helper-1:") {
219
+        let lower = line.to_ascii_lowercase();
220
+        if lower.contains("pam_authenticate failed")
221
+            || lower.contains("authentication failure")
222
+            || lower.contains("no session for cookie")
223
+        {
224
+            return Ok(HelperEvent::Error(line.to_string()));
225
+        }
225226
         return Ok(HelperEvent::Info(line.to_string()));
226227
     }
227228
 
@@ -325,18 +326,21 @@ mod tests {
325326
     }
326327
 
327328
     #[test]
328
-    fn parse_helper_line_maps_plaintext_failure_diagnostics() {
329
+    fn parse_helper_line_maps_plaintext_failure_diagnostics_to_error() {
329330
         assert_eq!(
330331
             parse_helper_line(
331332
                 "polkit-agent-helper-1: pam_authenticate failed: Authentication failure"
332333
             )
333
-            .expect("maps failure"),
334
-            HelperEvent::Failure
334
+            .expect("maps error"),
335
+            HelperEvent::Error(
336
+                "polkit-agent-helper-1: pam_authenticate failed: Authentication failure"
337
+                    .to_string()
338
+            )
335339
         );
336340
         assert_eq!(
337341
             parse_helper_line("polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie")
338
-                .expect("maps cookie failure"),
339
-            HelperEvent::Failure
342
+                .expect("maps cookie error"),
343
+            HelperEvent::Error("polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie".to_string())
340344
         );
341345
     }
342346