diff options
| author | Andrew Guschin <guschin@altlinux.org> | 2026-10-30 03:10:41 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin@altlinux.org> | 2026-10-30 03:10:41 +0400 |
| commit | d608ffeeda1a479c9dc0e5f6ad269ba07a510d7f (patch) | |
| tree | 3824ec9da5ca0adac913cc47e3e20054c3dc843a /src/authentication.rs | |
| parent | 40cf3276cdc74bf6f1795990ed600891a637d1fe (diff) | |
Implement Linux proxy controller, subscription state, and CLI/TUI
Diffstat (limited to 'src/authentication.rs')
| -rw-r--r-- | src/authentication.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/authentication.rs b/src/authentication.rs new file mode 100644 index 0000000..5312792 --- /dev/null +++ b/src/authentication.rs @@ -0,0 +1,52 @@ +use anyhow::{Context, Result}; +use std::{ + io::Read, + os::fd::AsRawFd, + process::{Child, Command, Stdio}, + time::Duration, +}; + +pub struct TerminalAgent(Option<Child>); +impl TerminalAgent { + pub fn start(interactive: bool) -> Result<Self> { + if !interactive || unsafe { libc::geteuid() } == 0 { + return Ok(Self(None)); + } + let (mut reader, writer) = std::os::unix::net::UnixStream::pair()?; + reader.set_read_timeout(Some(Duration::from_secs(5)))?; + let fd = writer.as_raw_fd(); + // SAFETY: fd belongs to writer and remains open until after spawning the agent. + unsafe { + libc::fcntl(fd, libc::F_SETFD, 0); + } + let mut child = Command::new("/usr/bin/pkttyagent") + .args([ + "--process", + &std::process::id().to_string(), + "--notify-fd", + &fd.to_string(), + "--fallback", + ]) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + .context("Could not start terminal polkit agent; install polkit")?; + drop(writer); + let mut buffer = [0u8; 1]; + if let Err(error) = reader.read(&mut buffer) { + let _ = child.kill(); + let _ = child.wait(); + return Err(error).context("Terminal authentication agent did not become ready"); + } + Ok(Self(Some(child))) + } +} +impl Drop for TerminalAgent { + fn drop(&mut self) { + if let Some(child) = &mut self.0 { + let _ = child.kill(); + let _ = child.wait(); + } + } +} |