switch to invokes instead of emits
This commit is contained in:
@ -2,6 +2,7 @@ use netstat2::{AddressFamilyFlags, ProtocolFlags, ProtocolSocketInfo};
|
||||
use sysinfo::{System, SystemExt, Pid, ProcessExt};
|
||||
|
||||
use crate::errors::*;
|
||||
use crate::ipc::Client;
|
||||
|
||||
|
||||
fn get_associated_pids(local_port: u16) -> Result<Vec<u32>, netstat2::error::Error> {
|
||||
@ -22,8 +23,6 @@ fn get_associated_pids(local_port: u16) -> Result<Vec<u32>, netstat2::error::Err
|
||||
&& proto_info.local_addr == std::net::Ipv4Addr::LOCALHOST
|
||||
&& proto_info.remote_addr == std::net::Ipv4Addr::LOCALHOST
|
||||
{
|
||||
println!("PIDs associated with socket: {:?}", &sock_info.associated_pids);
|
||||
println!("Scanned {i} sockets");
|
||||
return Ok(sock_info.associated_pids)
|
||||
}
|
||||
}
|
||||
@ -31,16 +30,22 @@ fn get_associated_pids(local_port: u16) -> Result<Vec<u32>, netstat2::error::Err
|
||||
}
|
||||
|
||||
|
||||
pub fn get_client_info(local_port: u16) -> Result<(), ClientInfoError> {
|
||||
// Theoretically, on some systems, multiple processes can share a socket. We have to
|
||||
// account for this even though 99% of the time there will be only one.
|
||||
pub fn get_clients(local_port: u16) -> Result<Vec<Client>, ClientInfoError> {
|
||||
let mut clients = Vec::new();
|
||||
let mut sys = System::new();
|
||||
for p in get_associated_pids(local_port)? {
|
||||
let pid = Pid::from(p as i32);
|
||||
sys.refresh_process(pid);
|
||||
let proc = sys.process(pid)
|
||||
.ok_or(ClientInfoError::PidNotFound)?;
|
||||
let path = proc.exe().to_string_lossy();
|
||||
println!("exe for requesting process: {path}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
let client = Client {
|
||||
pid: p,
|
||||
exe: proc.exe().to_string_lossy().into_owned(),
|
||||
};
|
||||
clients.push(client);
|
||||
}
|
||||
Ok(clients)
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ pub enum RequestError {
|
||||
MalformedHttpRequest,
|
||||
RequestTooLarge,
|
||||
NoCredentials(GetCredentialsError),
|
||||
ClientInfo(ClientInfoError),
|
||||
}
|
||||
impl From<tokio::io::Error> for RequestError {
|
||||
fn from(e: std::io::Error) -> RequestError {
|
||||
@ -73,6 +74,11 @@ impl From<GetCredentialsError> for RequestError {
|
||||
RequestError::NoCredentials(e)
|
||||
}
|
||||
}
|
||||
impl From<ClientInfoError> for RequestError {
|
||||
fn from(e: ClientInfoError) -> RequestError {
|
||||
RequestError::ClientInfo(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RequestError {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
|
||||
@ -84,6 +90,8 @@ impl Display for RequestError {
|
||||
RequestTooLarge => write!(f, "HTTP request too large"),
|
||||
NoCredentials(GetCredentialsError::Locked) => write!(f, "Recieved go-ahead but app is locked"),
|
||||
NoCredentials(GetCredentialsError::Empty) => write!(f, "Received go-ahead but no credentials are known"),
|
||||
ClientInfo(ClientInfoError::PidNotFound) => write!(f, "Could not resolve PID of client process."),
|
||||
ClientInfo(ClientInfoError::NetstatError(e)) => write!(f, "Error getting client socket details: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,17 @@ use tauri::State;
|
||||
use crate::state::{AppState, Session};
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Client {
|
||||
pub pid: u32,
|
||||
pub exe: String,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Request {
|
||||
pub id: u64,
|
||||
pub clients: Vec<Client>,
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +49,7 @@ pub async fn unlock(passphrase: String, app_state: State<'_, AppState>) -> Resul
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
pub fn session_status(app_state: State<'_, AppState>) -> String {
|
||||
pub fn get_session_status(app_state: State<'_, AppState>) -> String {
|
||||
let session = app_state.session.read().unwrap();
|
||||
match *session {
|
||||
Session::Locked(_) => "locked".into(),
|
||||
|
@ -21,7 +21,11 @@ fn main() {
|
||||
|
||||
tauri::Builder::default()
|
||||
.manage(initial_state)
|
||||
.invoke_handler(tauri::generate_handler![ipc::unlock, ipc::respond])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
ipc::unlock,
|
||||
ipc::respond,
|
||||
ipc::get_session_status,
|
||||
])
|
||||
.setup(|app| {
|
||||
let addr = std::net::SocketAddrV4::from_str("127.0.0.1:12345").unwrap();
|
||||
tauri::async_runtime::spawn(server::serve(addr, app.handle()));
|
||||
|
@ -6,6 +6,7 @@ use tokio::sync::oneshot;
|
||||
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
use crate::clientinfo;
|
||||
use crate::errors::RequestError;
|
||||
use crate::ipc::{Request, Approval};
|
||||
|
||||
@ -46,12 +47,15 @@ async fn handle(mut stream: TcpStream, app_handle: AppHandle) -> Result<(), Requ
|
||||
let app_state = app_handle.state::<crate::state::AppState>();
|
||||
let request_id = app_state.register_request(chan_send);
|
||||
|
||||
if let std::net::SocketAddr::V4(addr) = stream.peer_addr()? {
|
||||
crate::clientinfo::get_client_info(addr.port());
|
||||
}
|
||||
let peer_addr = match stream.peer_addr()? {
|
||||
std::net::SocketAddr::V4(addr) => addr,
|
||||
_ => unreachable!(), // we only listen on IPv4
|
||||
};
|
||||
let clients = clientinfo::get_clients(peer_addr.port())?;
|
||||
|
||||
// Do we want to panic if this fails? Does that mean the frontend is dead?
|
||||
app_handle.emit_all("credentials-request", Request {id: request_id}).unwrap();
|
||||
let req = Request {id: request_id, clients};
|
||||
app_handle.emit_all("credentials-request", req).unwrap();
|
||||
|
||||
let mut buf = [0; 8192]; // it's what tokio's BufReader uses
|
||||
let mut n = 0;
|
||||
|
Reference in New Issue
Block a user