git.lucas.co / cce-authenticator
login authentication (PAM + fingerprint)
git clone https://git.lucas.co/cce-authenticator.git

commitf0a945534144b39b69a9e20483886a8f4ee9ad4f
parenta3537ce136
authorLucas Galante <[email protected]>
date2026-06-07 22:15
Allow simulation mode in Polkit agent if CCE_AUTH_SIMULATE is set

 src/main.rs | 118 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 62 insertions(+), 56 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index f6d74df..9ca0b9e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -80,6 +80,7 @@ struct AuthenticatorApp {
     polkit_mode: bool,
     helper_stdin: Option<std::process::ChildStdin>,
     shared_child: Option<Arc<Mutex<Option<std::process::Child>>>>,
+    sender: calloop::channel::Sender<AppMessage>,
 }
 
 impl Application for AuthenticatorApp {
@@ -110,67 +111,71 @@ impl Application for AuthenticatorApp {
         
         if let Some(ref req) = *active_req {
             status_msg = req.message.clone();
-            simulate_mode = false;
+            if std::env::var("CCE_AUTH_SIMULATE").is_err() {
+                simulate_mode = false;
+            }
             
-            // Spawn polkit-agent-helper-1
-            match std::process::Command::new("/usr/lib/polkit-1/polkit-agent-helper-1")
-                .arg(&req.username)
-                .arg(&req.cookie)
-                .stdin(std::process::Stdio::piped())
-                .stdout(std::process::Stdio::piped())
-                .stderr(std::process::Stdio::inherit())
-                .spawn()
-            {
-                Ok(mut child) => {
-                    let stdin = child.stdin.take();
-                    let stdout = child.stdout.take();
-                    helper_stdin = stdin;
-                    
-                    let child_arc = Arc::new(Mutex::new(Some(child)));
-                    shared_child = Some(child_arc.clone());
-                    
-                    if let Some(stdout) = stdout {
-                        let sender_clone = sender.clone();
-                        std::thread::spawn(move || {
-                            use std::io::BufRead;
-                            let reader = std::io::BufReader::new(stdout);
-                            for line in reader.lines() {
-                                if let Ok(line) = line {
-                                    if line.starts_with("PAM_PROMPT_ECHO_OFF ") {
-                                        let prompt = line["PAM_PROMPT_ECHO_OFF ".len()..].to_string();
-                                        let _ = sender_clone.send(AppMessage::PromptReceived(prompt, false));
-                                    } else if line.starts_with("PAM_PROMPT_ECHO_ON ") {
-                                        let prompt = line["PAM_PROMPT_ECHO_ON ".len()..].to_string();
-                                        let _ = sender_clone.send(AppMessage::PromptReceived(prompt, true));
-                                    } else if line.starts_with("PAM_ERROR_MSG ") {
-                                        let msg = line["PAM_ERROR_MSG ".len()..].to_string();
-                                        let _ = sender_clone.send(AppMessage::StatusReceived(msg, true));
-                                    } else if line.starts_with("PAM_TEXT_INFO ") {
-                                        let msg = line["PAM_TEXT_INFO ".len()..].to_string();
-                                        let _ = sender_clone.send(AppMessage::StatusReceived(msg, false));
+            if !simulate_mode {
+                // Spawn polkit-agent-helper-1
+                match std::process::Command::new("/usr/lib/polkit-1/polkit-agent-helper-1")
+                    .arg(&req.username)
+                    .arg(&req.cookie)
+                    .stdin(std::process::Stdio::piped())
+                    .stdout(std::process::Stdio::piped())
+                    .stderr(std::process::Stdio::inherit())
+                    .spawn()
+                {
+                    Ok(mut child) => {
+                        let stdin = child.stdin.take();
+                        let stdout = child.stdout.take();
+                        helper_stdin = stdin;
+                        
+                        let child_arc = Arc::new(Mutex::new(Some(child)));
+                        shared_child = Some(child_arc.clone());
+                        
+                        if let Some(stdout) = stdout {
+                            let sender_clone = sender.clone();
+                            std::thread::spawn(move || {
+                                use std::io::BufRead;
+                                let reader = std::io::BufReader::new(stdout);
+                                for line in reader.lines() {
+                                    if let Ok(line) = line {
+                                        if line.starts_with("PAM_PROMPT_ECHO_OFF ") {
+                                            let prompt = line["PAM_PROMPT_ECHO_OFF ".len()..].to_string();
+                                            let _ = sender_clone.send(AppMessage::PromptReceived(prompt, false));
+                                        } else if line.starts_with("PAM_PROMPT_ECHO_ON ") {
+                                            let prompt = line["PAM_PROMPT_ECHO_ON ".len()..].to_string();
+                                            let _ = sender_clone.send(AppMessage::PromptReceived(prompt, true));
+                                        } else if line.starts_with("PAM_ERROR_MSG ") {
+                                            let msg = line["PAM_ERROR_MSG ".len()..].to_string();
+                                            let _ = sender_clone.send(AppMessage::StatusReceived(msg, true));
+                                        } else if line.starts_with("PAM_TEXT_INFO ") {
+                                            let msg = line["PAM_TEXT_INFO ".len()..].to_string();
+                                            let _ = sender_clone.send(AppMessage::StatusReceived(msg, false));
+                                        }
                                     }
                                 }
-                            }
-                            
-                            // Wait for child helper to exit
-                            let mut lock = child_arc.lock().unwrap();
-                            if let Some(mut child) = lock.take() {
-                                drop(lock);
-                                let exit_status = child.wait();
-                                match exit_status {
-                                    Ok(status) if status.success() => {
-                                        let _ = sender_clone.send(AppMessage::AuthDone(AuthResult::Success));
-                                    }
-                                    _ => {
-                                        let _ = sender_clone.send(AppMessage::AuthDone(AuthResult::Failure("Authentication failed".to_string())));
+                                
+                                // Wait for child helper to exit
+                                let mut lock = child_arc.lock().unwrap();
+                                if let Some(mut child) = lock.take() {
+                                    drop(lock);
+                                    let exit_status = child.wait();
+                                    match exit_status {
+                                        Ok(status) if status.success() => {
+                                            let _ = sender_clone.send(AppMessage::AuthDone(AuthResult::Success));
+                                        }
+                                        _ => {
+                                            let _ = sender_clone.send(AppMessage::AuthDone(AuthResult::Failure("Authentication failed".to_string())));
+                                        }
                                     }
                                 }
-                            }
-                        });
+                            });
+                        }
+                    }
+                    Err(e) => {
+                        status_msg = format!("Failed to spawn helper: {}", e);
                     }
-                }
-                Err(e) => {
-                    status_msg = format!("Failed to spawn helper: {}", e);
                 }
             }
         }
@@ -207,6 +212,7 @@ impl Application for AuthenticatorApp {
             polkit_mode,
             helper_stdin,
             shared_child,
+            sender: sender.clone(),
         };
         
         let tx = app.tx_auth.clone();
@@ -371,7 +377,7 @@ impl Application for AuthenticatorApp {
 
     fn tick(&mut self, dt: f32, needs_rebuild: &mut bool) {
         while let Ok(res) = self.rx_auth.try_recv() {
-            self.update(AppMessage::AuthDone(res), needs_rebuild, &mut false);
+            let _ = self.sender.send(AppMessage::AuthDone(res));
         }
         
         if self.fingerprint_active {