use std::io::{self, Read, Write};
use std::sync::Arc;
use std::string::FromUtf8Error;
use std::net::Shutdown;
use flypto::x25519::X25519;
use flypto::hkdf_sha256::HkdfSha256;
use flypto::aes::AES;
use flypto::argon2::Argon2Hash;
use crate::spmg::pin::entry::PinEntry;
use base64::{encode, decode};
use std::os::unix::net::UnixStream;
use libeipc::EIPC_Client;
use rand::RngCore;
use crate::config::Config;
pub struct EIPC_Auth {
pub eipc_client: EIPC_Client,
config: Arc<Config>,
}
impl EIPC_Auth {
pub fn new(path: &str, config: Arc<Config>) -> Self {
let mut x25519 = X25519::new();
let eipc_client = EIPC_Client::new(path, config.hkdf_salt.clone());
EIPC_Auth {
eipc_client,
config
}
}
pub fn auth_command(&mut self, cmd_handle: impl Fn(&str) -> String) -> io::Result<String> {
let mut enc_key = self.eipc_client.send_event("get-cached", "").unwrap();
if enc_key == "NONE" {
match PinEntry::prompt("Please enter a password to unlock spmg") {
Ok(pin) => {
let url_enc_pwd = pin;
let lock_pwd = Some(
urlencoding::decode(&url_enc_pwd).unwrap()
);
let dkey = Argon2Hash::derive_key(&lock_pwd.unwrap(), &self.config.argon_salt);
enc_key = encode(dkey);
}
Err(error) => {
return Err(error);
}
}
}
let mut command = cmd_handle(&enc_key);
let mut cmd_res = self.eipc_client.send_event(&command, "").unwrap();
if cmd_res == "ERR NOLOCK" {
eprintln!("Lock file does not exist!");
}
while cmd_res == "ERR UNAUTH" {
let url_enc_pwd = PinEntry::prompt("Please enter a password to unlock spmg").unwrap();
let lock_pwd = Some(
urlencoding::decode(&url_enc_pwd).unwrap()
);
enc_key = encode(Argon2Hash::derive_key(&lock_pwd.unwrap(), &self.config.argon_salt));
command = cmd_handle(&enc_key);
cmd_res = self.eipc_client.send_event(&command, "").unwrap();
}
Ok(cmd_res)
}
}