libspmg 0.2.1

Secure password manager library
Documentation


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)
    }

}