forked from Morganamilo/paru
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.rs
93 lines (77 loc) · 2.25 KB
/
auth.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use anyhow::{Result, ensure, bail, Context};
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::FromRawFd;
use nix::unistd::pipe;
use crate::config::Config;
use std::process::Command;
use std::cell::RefCell;
#[derive(Debug)]
pub struct Pipe {
pub read: File,
pub write: File,
}
impl Pipe {
fn wait_ok(&mut self) -> Result<()> {
let mut buf = [0; "ok\n".len()];
self.read.read_exact(&mut buf)?;
ensure!(&buf == b"ok\n");
Ok(())
}
}
#[derive(Debug, Default)]
pub struct LazyPipe {
pipe: RefCell<Option<Result<Pipe>>>,
}
impl LazyPipe {
pub fn run(&self, config: &Config) -> Result<()> {
let mut pipe = self.pipe.borrow_mut();
let pipe = pipe.get_or_insert_with(|| spawn_auth(config).context("failed to spawn auth process"));
let pipe = match pipe {
Err(e) => bail!(e.to_string()),
Ok(p) => p,
};
loop {}
pipe.write.write_all(b"something")?;
pipe.wait_ok()?;
Ok(())
}
}
pub fn spawn_auth(config: &Config) -> Result<Pipe> {
let (paru_read, auth_write) = pipe()?;
let (auth_read, paru_write) = pipe()?;
/*Command::new(&config.sudo_bin)
.args(&config.sudo_flags)
.arg(std::env::current_exe()?)
.arg("--authpipe")
.arg(auth_read.to_string())
.arg(auth_write.to_string())
.spawn()?;*/
Command::new(std::env::current_exe()?)
.arg("--authpipe")
.arg(auth_read.to_string())
.arg(auth_write.to_string())
.spawn()?;
loop {}
let read = unsafe { File::from_raw_fd(paru_read) };
let write = unsafe { File::from_raw_fd(paru_write) };
let mut pipe = Pipe { read, write };
pipe.wait_ok().unwrap();
Ok(pipe)
}
pub unsafe fn authpipe(read: &str, write: &str) -> Result<i32> {
let read = read.parse::<i32>()?;
let write = write.parse::<i32>()?;
ensure!(read > 3);
ensure!(write > 3);
println!("read={} write={}", read, write);
ensure!(read != write);
loop {}
let mut read = File::from_raw_fd(read);
let mut write = File::from_raw_fd(write);
loop {
write.write(b"ok\n").context("failed to write ok")?;
write.flush().context("failed to flush")?;
}
Ok(0)
}