mirror of
https://github.com/002Hub/IPass.git
synced 2025-04-19 22:01:21 +02:00
better error handling
Co-authored-by: Alpisc <Alpisc@users.noreply.github.com>
This commit is contained in:
parent
c4d3d09e08
commit
4a1093f495
39
Cargo.lock
generated
39
Cargo.lock
generated
@ -37,6 +37,21 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-no-stdlib"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-stdlib"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
@ -46,6 +61,27 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli"
|
||||||
|
version = "3.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
"brotli-decompressor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli-decompressor"
|
||||||
|
version = "2.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -158,9 +194,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipass"
|
name = "ipass"
|
||||||
version = "0.1.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
|
"brotli",
|
||||||
"hex",
|
"hex",
|
||||||
"home",
|
"home",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ipass"
|
name = "ipass"
|
||||||
version = "0.1.0"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@ -12,3 +12,4 @@ rand = "0.8.5"
|
|||||||
aes-gcm = "0.10.1"
|
aes-gcm = "0.10.1"
|
||||||
sha2 = "0.10.6"
|
sha2 = "0.10.6"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
brotli = "3.3.4"
|
BIN
IPass_logo.png
Normal file
BIN
IPass_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
126
src/main.rs
126
src/main.rs
@ -2,10 +2,11 @@ use std::collections::HashMap;
|
|||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::io::Read;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let version = "0.2.1";
|
let version = option_env!("CARGO_PKG_VERSION").unwrap_or("x.x.x");
|
||||||
println!("IPass v{}\n", version);
|
println!("IPass v{}\n", version);
|
||||||
|
|
||||||
let args = utils::get_args();
|
let args = utils::get_args();
|
||||||
@ -21,12 +22,14 @@ fn main() {
|
|||||||
"list" => list(),
|
"list" => list(),
|
||||||
"add" => add(&args),
|
"add" => add(&args),
|
||||||
"get" => get(&args),
|
"get" => get(&args),
|
||||||
"edit" => edit(&args),
|
"changepw" => changepw(&args),
|
||||||
|
"changeuser" => changeuser(&args),
|
||||||
"remove" => remove(&args),
|
"remove" => remove(&args),
|
||||||
"import" => import(&args),
|
"import" => import(&args),
|
||||||
"export" => export(&args),
|
"export" => export(&args),
|
||||||
"rename" => rename(&args),
|
"rename" => rename(&args),
|
||||||
"version" => version_help(version),
|
"version" => version_help(version),
|
||||||
|
"clear" => clear(),
|
||||||
_ => help_message(&args),
|
_ => help_message(&args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +42,6 @@ fn version_help(version: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn help_message(args: &Vec<String>) {
|
fn help_message(args: &Vec<String>) {
|
||||||
|
|
||||||
let mut help_messages:HashMap<String, String> = HashMap::new();
|
let mut help_messages:HashMap<String, String> = HashMap::new();
|
||||||
help_messages.insert(
|
help_messages.insert(
|
||||||
"list".to_string(),
|
"list".to_string(),
|
||||||
@ -58,8 +60,8 @@ fn help_message(args: &Vec<String>) {
|
|||||||
"tells you this message, takes an optional {command name}".to_string(),
|
"tells you this message, takes an optional {command name}".to_string(),
|
||||||
);
|
);
|
||||||
help_messages.insert(
|
help_messages.insert(
|
||||||
"edit".to_string(),
|
"changepw".to_string(),
|
||||||
"lets you edit an existing entry, given the name and the new password".to_string(),
|
"changes the password of the specified entry".to_string(),
|
||||||
);
|
);
|
||||||
help_messages.insert(
|
help_messages.insert(
|
||||||
"remove".to_string(),
|
"remove".to_string(),
|
||||||
@ -81,12 +83,19 @@ fn help_message(args: &Vec<String>) {
|
|||||||
"version".to_string(),
|
"version".to_string(),
|
||||||
"explains the current version".to_string()
|
"explains the current version".to_string()
|
||||||
);
|
);
|
||||||
|
help_messages.insert(
|
||||||
|
"changeuser".to_string(),
|
||||||
|
"changes the username of the specified entry".to_string(),
|
||||||
|
);
|
||||||
|
help_messages.insert(
|
||||||
|
"clear".to_string(),
|
||||||
|
"clears all entries".to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
if args.len() < 3 {
|
if args.len() < 3 {
|
||||||
println!("You can use the following commands:");
|
println!("You can use the following commands:");
|
||||||
for i in help_messages.keys() {
|
for (cmd, expl) in &help_messages {
|
||||||
println!("\"{i}\"{}- {}"," ".repeat(8-i.len()),help_messages[i]);
|
println!("\"{cmd}\"{}- {expl}"," ".repeat(12-cmd.len()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -110,19 +119,20 @@ fn list() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(args: &Vec<String>) { //TODO: format: [specifier] [email or username] {password}
|
fn add(args: &Vec<String>) {
|
||||||
|
|
||||||
if args.len() < 3 || args.len() > 4 {
|
if args.len() < 4 || args.len() > 5 {
|
||||||
println!("Incorrect usage of \"add\"");
|
println!("Incorrect usage of \"add\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pw: String;
|
let pw: String;
|
||||||
|
let username:String = args[3].to_string();
|
||||||
|
|
||||||
if args.len() > 3 {
|
if args.len() > 4 {
|
||||||
pw = args[3].trim().to_owned();
|
pw = username+";"+args[4].trim();
|
||||||
} else {
|
} else {
|
||||||
let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!\"§$%&/()=?´`²³{[]}\\,.-;:_><|+*#'";
|
let alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!\"$%&/()=?{[]}\\,.-;:_><|+*#'";
|
||||||
let alph_len = alphabet.chars().count();
|
let alph_len = alphabet.chars().count();
|
||||||
let char_set:Vec<char> = alphabet.chars().collect();
|
let char_set:Vec<char> = alphabet.chars().collect();
|
||||||
let mut chars_index: Vec<u8> = vec![0;20];
|
let mut chars_index: Vec<u8> = vec![0;20];
|
||||||
@ -133,7 +143,7 @@ fn add(args: &Vec<String>) { //TODO: format: [specifier] [email or username] {pa
|
|||||||
// println!("{} - {} - {}",index,(index as usize)%(alph_len-1),alph_len);
|
// println!("{} - {} - {}",index,(index as usize)%(alph_len-1),alph_len);
|
||||||
chars += &char_set[(index as usize)%(alph_len-1)].to_string();
|
chars += &char_set[(index as usize)%(alph_len-1)].to_string();
|
||||||
}
|
}
|
||||||
pw = chars;
|
pw = username+";"+chars.as_str();
|
||||||
|
|
||||||
println!("Using auto generated password");
|
println!("Using auto generated password");
|
||||||
// println!("pw: {pw}");
|
// println!("pw: {pw}");
|
||||||
@ -158,16 +168,18 @@ fn get(args: &Vec<String>) {
|
|||||||
let filepath = &(utils::get_ipass_folder()+name+".ipass");
|
let filepath = &(utils::get_ipass_folder()+name+".ipass");
|
||||||
if std::path::Path::new(filepath).exists() {
|
if std::path::Path::new(filepath).exists() {
|
||||||
println!("Getting entry");
|
println!("Getting entry");
|
||||||
println!("{}",utils::get_entry(name));
|
let entry = utils::get_entry(name);
|
||||||
|
let mut data = entry.split(";");
|
||||||
|
println!("Username: '{}' Password: '{}'",data.next().unwrap(),data.next().unwrap());
|
||||||
} else {
|
} else {
|
||||||
println!("No such entry!");
|
println!("No such entry!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit(args: &Vec<String>) {
|
fn changepw(args: &Vec<String>) { //rename func to changepw
|
||||||
if args.len() < 3 {
|
if args.len() < 3 {
|
||||||
println!("Invalid usage of \"edit\"");
|
println!("Invalid usage of \"changepw\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let filepath = &(utils::get_ipass_folder()+&args[2]+".ipass");
|
let filepath = &(utils::get_ipass_folder()+&args[2]+".ipass");
|
||||||
@ -179,8 +191,7 @@ fn edit(args: &Vec<String>) {
|
|||||||
output = args[3].clone();
|
output = args[3].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = std::fs::File::create(format!("{}/{}.ipass",utils::get_ipass_folder(),args[2])).unwrap();
|
utils::edit_password(&args[2], output);
|
||||||
file.write_all(output.replace("\n", "").replace("\r","").as_bytes()).unwrap();
|
|
||||||
|
|
||||||
println!("Changed Password of {}!", args[2]);
|
println!("Changed Password of {}!", args[2]);
|
||||||
} else {
|
} else {
|
||||||
@ -188,6 +199,28 @@ fn edit(args: &Vec<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn changeuser(args: &Vec<String>) {
|
||||||
|
if args.len() < 3 {
|
||||||
|
println!("Invalid usage of \"changeuser\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let filepath = &(utils::get_ipass_folder()+&args[2]+".ipass");
|
||||||
|
if std::path::Path::new(filepath).exists() {
|
||||||
|
let output: String;
|
||||||
|
if args.len() != 4 {
|
||||||
|
output = utils::prompt_answer("Enter new Username: ".to_string());
|
||||||
|
} else {
|
||||||
|
output = args[3].clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
utils::edit_username(&args[2], output);
|
||||||
|
|
||||||
|
println!("Changed Username of {}!", args[2]);
|
||||||
|
} else {
|
||||||
|
println!("No such file!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rename(args: &Vec<String>) { // prog ren old new
|
fn rename(args: &Vec<String>) { // prog ren old new
|
||||||
if args.len() < 4 {
|
if args.len() < 4 {
|
||||||
println!("Invalid usage of \"rename\"");
|
println!("Invalid usage of \"rename\"");
|
||||||
@ -233,7 +266,29 @@ fn import(args: &Vec<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if std::path::Path::new(&(location.clone()+"/export.ipassx")).exists() {
|
if std::path::Path::new(&(location.clone()+"/export.ipassx")).exists() {
|
||||||
let content = &mut std::fs::read_to_string(location.clone()+"/export.ipassx").expect("Should have been able to read the file");
|
let mut reader = brotli::Decompressor::new(
|
||||||
|
std::fs::File::open(location.clone()+"/export.ipassx").unwrap(),
|
||||||
|
4096, // buffer size
|
||||||
|
);
|
||||||
|
let mut content: String = String::new();
|
||||||
|
let mut buf = [0u8; 4096];
|
||||||
|
loop {
|
||||||
|
match reader.read(&mut buf[..]) {
|
||||||
|
Err(e) => {
|
||||||
|
if let std::io::ErrorKind::Interrupted = e.kind() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
panic!("{}", e);
|
||||||
|
}
|
||||||
|
Ok(size) => {
|
||||||
|
if size == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
content += &std::str::from_utf8(&buf[..size]).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let lines = content.lines();
|
let lines = content.lines();
|
||||||
let mut name = "";
|
let mut name = "";
|
||||||
for i in lines {
|
for i in lines {
|
||||||
@ -275,8 +330,19 @@ fn export(args: &Vec<String>) { //TODO: compress data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(mut file) = std::fs::File::create(location.clone()+"/export.ipassx") {
|
|
||||||
file.write_all(collected_data.as_bytes()).unwrap();
|
|
||||||
|
if let Ok(file) = std::fs::File::create(location.clone()+"/export.ipassx") {
|
||||||
|
let mut writer = brotli::CompressorWriter::new(
|
||||||
|
file,
|
||||||
|
4096,
|
||||||
|
11,
|
||||||
|
22);
|
||||||
|
|
||||||
|
match writer.write_all(collected_data.as_bytes()) {
|
||||||
|
Err(e) => panic!("{}", e),
|
||||||
|
Ok(_) => {},
|
||||||
|
}
|
||||||
|
|
||||||
println!("Saved at: '{}/export.ipassx'", location);
|
println!("Saved at: '{}/export.ipassx'", location);
|
||||||
} else {
|
} else {
|
||||||
@ -284,3 +350,19 @@ fn export(args: &Vec<String>) { //TODO: compress data
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear() {
|
||||||
|
if utils::prompt_answer("Are you sure you want to clear everything? [y/N] ".to_string()) != "y" {
|
||||||
|
println!("operation cancelled!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let paths = std::fs::read_dir(utils::get_ipass_folder()).unwrap();
|
||||||
|
|
||||||
|
for path in paths {
|
||||||
|
if let Ok(p) = path {
|
||||||
|
std::fs::remove_file(utils::get_ipass_folder()+"/"+p.file_name().into_string().unwrap().as_str()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Cleared all entries!");
|
||||||
|
}
|
78
src/utils.rs
78
src/utils.rs
@ -10,15 +10,23 @@ pub fn get_args() -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn vecu8_to_string(vec: Vec<u8>) -> String {
|
fn vecu8_to_string(vec: Vec<u8>) -> String {
|
||||||
|
let mut do_print_warning = false;
|
||||||
let mut out: String = String::new();
|
let mut out: String = String::new();
|
||||||
for ind in vec {
|
for ind in vec {
|
||||||
if let Ok(a) = std::str::from_utf8(&[ind]) {
|
if let Ok(a) = std::str::from_utf8(&[ind]) {
|
||||||
out += a;
|
out += a;
|
||||||
} else {
|
} else {
|
||||||
panic!("malformed character");
|
do_print_warning = true;
|
||||||
|
eprintln!("[WARNING] malformed character {}",ind);
|
||||||
|
let mut temp_vec: Vec<u8> = Vec::new();
|
||||||
|
temp_vec.insert(0,ind%128);
|
||||||
|
out += vecu8_to_string(temp_vec).as_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out
|
if do_print_warning {
|
||||||
|
println!("[WARNING] Output may be corrupt");
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt_pass(nonce_arg:String, pass: String,mpw: String) -> String {
|
fn encrypt_pass(nonce_arg:String, pass: String,mpw: String) -> String {
|
||||||
@ -29,13 +37,20 @@ fn encrypt_pass(nonce_arg:String, pass: String,mpw: String) -> String {
|
|||||||
if nonce_arg.len() > 12 {
|
if nonce_arg.len() > 12 {
|
||||||
nonce_argument = nonce_arg[0..12].to_string();
|
nonce_argument = nonce_arg[0..12].to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut nonce_hasher = Sha256::new();
|
||||||
|
nonce_hasher.update(nonce_argument.as_bytes());
|
||||||
|
|
||||||
|
let nonce_final = &nonce_hasher.finalize()[0..12];
|
||||||
|
|
||||||
|
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(mpw.as_bytes());
|
hasher.update(mpw.as_bytes());
|
||||||
|
|
||||||
let master_pw = &hasher.finalize();
|
let master_pw = &hasher.finalize();
|
||||||
|
|
||||||
let cipher = Aes256Gcm::new(master_pw);
|
let cipher = Aes256Gcm::new(master_pw);
|
||||||
let nonce = Nonce::from_slice(nonce_argument.as_bytes()); // 96-bits; unique per message
|
let nonce = Nonce::from_slice(nonce_final); // 96-bits; unique per message
|
||||||
let ciphertext = cipher.encrypt(nonce, pass.as_ref()).unwrap();
|
let ciphertext = cipher.encrypt(nonce, pass.as_ref()).unwrap();
|
||||||
return hex::encode(ciphertext);
|
return hex::encode(ciphertext);
|
||||||
}
|
}
|
||||||
@ -48,15 +63,29 @@ fn decrypt_pass(nonce_arg:String, pass: Vec<u8>,mpw: String) -> String {
|
|||||||
if nonce_arg.len() > 12 {
|
if nonce_arg.len() > 12 {
|
||||||
nonce_argument = nonce_arg[0..12].to_string();
|
nonce_argument = nonce_arg[0..12].to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut nonce_hasher = Sha256::new();
|
||||||
|
nonce_hasher.update(nonce_argument.as_bytes());
|
||||||
|
|
||||||
|
let nonce_final = &nonce_hasher.finalize()[0..12];
|
||||||
|
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(mpw.as_bytes());
|
hasher.update(mpw.as_bytes());
|
||||||
|
|
||||||
let master_pw = &hasher.finalize();
|
let master_pw = &hasher.finalize();
|
||||||
let cipher = Aes256Gcm::new(master_pw);
|
let cipher = Aes256Gcm::new(master_pw);
|
||||||
let nonce = Nonce::from_slice(nonce_argument.as_bytes()); // 96-bits; unique per message
|
let nonce = Nonce::from_slice(nonce_final); // 96-bits; unique per message
|
||||||
|
|
||||||
let plaintext = cipher.decrypt(nonce, pass.as_ref()).unwrap();
|
let plaintext = cipher.decrypt(nonce, pass.as_ref());
|
||||||
return vecu8_to_string(plaintext);
|
match plaintext {
|
||||||
|
Ok(res) => {
|
||||||
|
return vecu8_to_string(res);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("[ERROR] Error decrypting data, check your master password");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_home_folder_str() -> String {
|
pub fn get_home_folder_str() -> String {
|
||||||
@ -82,21 +111,46 @@ pub fn create_entry(name: &String, pw: String) -> bool {
|
|||||||
if std::path::Path::new(&(get_ipass_folder()+name+".ipass")).exists() {
|
if std::path::Path::new(&(get_ipass_folder()+name+".ipass")).exists() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
edit_entry(name, pw);
|
let mpw = ask_for_pw();
|
||||||
|
// println!("{pw}");
|
||||||
|
let pw = encrypt_pass(name.to_owned(), pw,mpw);
|
||||||
|
let mut file = std::fs::File::create(get_ipass_folder()+name+".ipass").unwrap();
|
||||||
|
file.write_all(pw.as_bytes()).unwrap();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_entry(name:&String) -> String {
|
fn read_entry(name:&String,mpw:String) -> String {
|
||||||
let content = &mut std::fs::read_to_string(get_ipass_folder()+name+".ipass").expect("Should have been able to read the file");
|
let content = &mut std::fs::read_to_string(get_ipass_folder()+name+".ipass").expect("Should have been able to read the file");
|
||||||
let mpw = ask_for_pw();
|
|
||||||
return decrypt_pass(name.to_owned(),hex::decode(content).unwrap(),mpw).to_owned();
|
return decrypt_pass(name.to_owned(),hex::decode(content).unwrap(),mpw).to_owned();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_entry(name:&String,mut pw:String) {
|
pub fn get_entry(name:&String) -> String {
|
||||||
let mpw = ask_for_pw();
|
let mpw = ask_for_pw();
|
||||||
pw = encrypt_pass(name.to_owned(), pw,mpw);
|
return read_entry(name,mpw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edit_password(name:&String, password:String) {
|
||||||
|
let mpw = ask_for_pw();
|
||||||
|
let entry = read_entry(name, mpw.clone());
|
||||||
|
// println!("entry: {entry}");
|
||||||
|
let mut parts = entry.split(";");
|
||||||
|
let username = parts.next().unwrap().to_string();
|
||||||
|
let _old_password = parts.next().unwrap();
|
||||||
|
let data = encrypt_pass(name.to_owned(), username+";"+password.as_str(),mpw);
|
||||||
let mut file = std::fs::File::create(get_ipass_folder()+name+".ipass").unwrap();
|
let mut file = std::fs::File::create(get_ipass_folder()+name+".ipass").unwrap();
|
||||||
file.write_all(pw.as_bytes()).unwrap();
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edit_username(name:&String, username: String) {
|
||||||
|
let mpw = ask_for_pw();
|
||||||
|
let entry = read_entry(name, mpw.clone());
|
||||||
|
// println!("entry: {entry}");
|
||||||
|
let mut parts = entry.split(";");
|
||||||
|
let _old_username = parts.next().unwrap();
|
||||||
|
let password = parts.next().unwrap();
|
||||||
|
let data = encrypt_pass(name.to_owned(), username+";"+password,mpw);
|
||||||
|
let mut file = std::fs::File::create(get_ipass_folder()+name+".ipass").unwrap();
|
||||||
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ask_for_pw() -> String {
|
fn ask_for_pw() -> String {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user