Fixed some bugs and added colored output

This commit is contained in:
Arkaprabha Chakraborty
2023-01-31 05:56:23 +05:30
parent 4203e91e74
commit c4cd7e608f

View File

@@ -1,9 +1,11 @@
// Program: rustcm-cli (0.1.0-alpha) // Program: rustcm-cli (0.1.1-alpha)
// License: GNU GPL version 3 // License: GNU GPL version 3
// Author: Arkaprabha Chakraborty // Author: Arkaprabha Chakraborty
// Edited: 31-01-23
// //
// Copyright (C) 2023 Arkaprabha Chakraborty // Copyright (C) 2023 Arkaprabha Chakraborty
use colored::Colorize;
use orion::{aead, kdf}; use orion::{aead, kdf};
use passterm::read_password; use passterm::read_password;
use std::env::args; use std::env::args;
@@ -13,12 +15,12 @@ use std::io::{stdout, Read, Write};
use std::process::exit; use std::process::exit;
const PROGRAM_NAME: &str = "rustcm-cli"; const PROGRAM_NAME: &str = "rustcm-cli";
const PROGRAM_VERSION: &str = "0.1.0-alpha"; const PROGRAM_VERSION: &str = "0.1.1-alpha";
pub fn get_password(prompt: &str) -> String { pub fn get_password(prompt: &str) -> String {
print!("{}", prompt); print!("{}", prompt);
into_match(stdout().flush(), "Error: Could not flush date to stdout"); into_match(stdout().flush(), "{} Could not flush date to stdout");
let password = into_match(read_password(), "Error: Could not read the password"); let password = into_match(read_password(), "{} Could not read the password");
println!(); println!();
password password
@@ -28,11 +30,11 @@ pub fn encrypt(plaintext: String, secret_key: orion::kdf::SecretKey) -> Vec<u8>
let plaintext = plaintext.into_bytes(); let plaintext = plaintext.into_bytes();
match aead::seal(&secret_key, &plaintext) { match aead::seal(&secret_key, &plaintext) {
Ok(temp) => { Ok(temp) => {
println!("Success: Data was encrypted"); println!("{} Data was encrypted", "Success:".bright_green());
temp temp
} }
Err(_) => { Err(_) => {
eprintln!("Error: Could not encrypt the data"); eprintln!("{} Could not encrypt the data", "Error:".bright_red());
exit(0); exit(0);
} }
} }
@@ -41,15 +43,15 @@ pub fn encrypt(plaintext: String, secret_key: orion::kdf::SecretKey) -> Vec<u8>
pub fn get_secret_key(salt_bytes: [u8; 32], password: String) -> orion::kdf::SecretKey { pub fn get_secret_key(salt_bytes: [u8; 32], password: String) -> orion::kdf::SecretKey {
let password = into_match( let password = into_match(
kdf::Password::from_slice(password.as_bytes()), kdf::Password::from_slice(password.as_bytes()),
"Error: Could not create the password", "{} Could not create the password",
); );
let salt = into_match( let salt = into_match(
kdf::Salt::from_slice(&salt_bytes), kdf::Salt::from_slice(&salt_bytes),
"Error: Could not create the salt", "{} Could not create the salt",
); );
into_match( into_match(
kdf::derive_key(&password, &salt, 3, 8, 32), kdf::derive_key(&password, &salt, 3, 8, 32),
"Error: Could not generate the secret key", "{} Could not generate the secret key",
) )
} }
@@ -58,7 +60,10 @@ pub fn get_salt_bytes() -> [u8; 32] {
match orion::util::secure_rand_bytes(&mut salt_bytes) { match orion::util::secure_rand_bytes(&mut salt_bytes) {
Ok(_) => (), Ok(_) => (),
Err(_) => { Err(_) => {
eprintln!("Error: Could not generate the random bytes for the salt"); eprintln!(
"{} Could not generate the random bytes for the salt",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
@@ -81,49 +86,46 @@ pub fn into_match<T, E>(res: Result<T, E>, estr: &str) -> T {
pub fn get_salt(salt_bytes: [u8; 32]) -> orion::kdf::Salt { pub fn get_salt(salt_bytes: [u8; 32]) -> orion::kdf::Salt {
let salt = into_match( let salt = into_match(
kdf::Salt::from_slice(&salt_bytes), kdf::Salt::from_slice(&salt_bytes),
"Error: Could not generate the salt", "{} Could not generate the salt",
); );
salt salt
} }
pub fn write_plain(path: String, plaintext: String) { pub fn write_plain(path: String, plaintext: String) {
let mut file = into_match(File::create(&path), "Error: Could not create {path}"); let mut file = into_match(File::create(&path), "{} Could not create {path}");
into_match( into_match(
file.write(&plaintext.into_bytes()), file.write(&plaintext.into_bytes()),
"Error: Could not write the data to {path}", "{} Could not write the data to {path}",
); );
into_match(file.flush(), "Error: Could not flush data to {path}"); into_match(file.flush(), "{} Could not flush data to {path}");
} }
pub fn write_cipher(path: String, salt_bytes: [u8; 32], ciphertext: Vec<u8>) { pub fn write_cipher(path: String, salt_bytes: [u8; 32], ciphertext: Vec<u8>) {
let mut file = into_match(File::create(&path), "Error: Could not create {path}"); let mut file = into_match(File::create(&path), "{} Could not create {path}");
into_match( into_match(file.write(&salt_bytes), "{} Could write the salt to {path}");
file.write(&salt_bytes),
"Error: Could write the salt to {path}",
);
into_match( into_match(
file.write(&ciphertext), file.write(&ciphertext),
"Error: Could not write the ciphertext to {path}", "{} Could not write the ciphertext to {path}",
); );
into_match(file.flush(), "Error: Could not flush data to {path}"); into_match(file.flush(), "{} Could not flush data to {path}");
} }
pub fn read_plain(path: String) -> String { pub fn read_plain(path: String) -> String {
into_match(read_to_string(&path), "Error: Could not read the {path}") into_match(read_to_string(&path), "{} Could not read the {path}")
} }
pub fn read_cipher(path: String) -> (Vec<u8>, Vec<u8>) { pub fn read_cipher(path: String) -> (Vec<u8>, Vec<u8>) {
let mut file = into_match(File::open(&path), "Error: Could not open {path}"); let mut file = into_match(File::open(&path), "{} Could not open {path}");
let metadata = into_match( let metadata = into_match(
File::metadata(&file), File::metadata(&file),
"Error: Could not read the metadata off of {path}", "{} Could not read the metadata off of {path}",
); );
let mut data: Vec<u8> = vec![0u8; metadata.len() as usize]; let mut data: Vec<u8> = vec![0u8; metadata.len() as usize];
match file.read(&mut data) { match file.read(&mut data) {
Ok(_) => (), Ok(_) => (),
Err(_) => { Err(_) => {
eprintln!("Error: Could not read {path}"); eprintln!("{} Could not read {path}", "Error:".bright_red());
exit(0); exit(0);
} }
}; };
@@ -139,15 +141,24 @@ pub fn read_cipher(path: String) -> (Vec<u8>, Vec<u8>) {
pub fn decrypt(ciphertext: Vec<u8>, secret_key: orion::kdf::SecretKey) -> String { pub fn decrypt(ciphertext: Vec<u8>, secret_key: orion::kdf::SecretKey) -> String {
let plaintext = match aead::open(&secret_key, &ciphertext) { let plaintext = match aead::open(&secret_key, &ciphertext) {
Ok(temp) => { Ok(temp) => {
println!("Success: Data was decrypted"); println!("{} Data was decrypted", "Success".bright_green());
temp temp
} }
Err(_) => { Err(_) => {
eprintln!("Error: Failed to decrypt the file, please check the password"); eprintln!(
"{} Failed to decrypt the file, please check the password",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
String::from_utf8(plaintext).expect("Error: Could not convert to String") match String::from_utf8(plaintext) {
Ok(temp) => temp,
Err(_) => {
eprintln!("{} Could not convert to String", "Error:".bright_red());
exit(0);
}
}
} }
pub fn to_array(v: Vec<u8>) -> [u8; 32] { pub fn to_array(v: Vec<u8>) -> [u8; 32] {
@@ -156,7 +167,8 @@ pub fn to_array(v: Vec<u8>) -> [u8; 32] {
Ok(bytes) => bytes, Ok(bytes) => bytes,
Err(_) => { Err(_) => {
eprintln!( eprintln!(
"Error: Expected a vector of length {} but it was {}", "{} Expected a vector of length {} but it was {}",
"Error:".bright_red(),
32, 32,
v.len() v.len()
); );
@@ -179,31 +191,46 @@ fn main() {
"--help" | "-h" => { "--help" | "-h" => {
match args.next() { match args.next() {
Some(_) => { Some(_) => {
eprintln!("Error: Too many arguments"); eprintln!("{} Too many arguments", "Error:".bright_red());
exit(0); exit(0);
} }
None => (), None => (),
}; };
println!( println!(
"{PROGRAM_NAME} {PROGRAM_VERSION} "{} {}
Rust Simple Text Cipher Machine. Rust Simple Text Cipher Machine.
USAGE: USAGE:
rustcm-cli [COMMAND] {} [COMMAND]
COMMAND: COMMAND:
-h, --help {}, {}
Prints this help message Prints this help message
-v, --version {}, {}
Prints the version information Prints the version information
-e, --encrypt <input-path> <output-path> {}, {} {} {}
Runs the program in encryption mode. Runs the program in encryption mode.
-d, --decrypt <input-path> <output-path> {}, {} {} {}
Runs the program in decryption mode." Runs the program in decryption mode.",
PROGRAM_NAME.bright_yellow(),
PROGRAM_VERSION.bright_blue(),
PROGRAM_NAME.bright_yellow(),
"-h".bright_cyan(),
"--help".bright_cyan(),
"-v".bright_cyan(),
"--version".bright_cyan(),
"-e".bright_cyan(),
"--encrypt".bright_cyan(),
"<path-to-input>".bright_magenta(),
"<path-to-output>".bright_magenta(),
"-d".bright_cyan(),
"--decrypt".bright_cyan(),
"<path-to-input>".bright_magenta(),
"<path-to-output>".bright_magenta(),
); );
exit(0); exit(0);
} }
@@ -211,20 +238,23 @@ COMMAND:
"--version" | "-v" => { "--version" | "-v" => {
match args.next() { match args.next() {
Some(_) => { Some(_) => {
eprintln!("Error: Too many arguments"); eprintln!("{} Too many arguments", "Error:".bright_red());
exit(0); exit(0);
} }
None => (), None => (),
}; };
println!( println!(
"rustcm-cli (0.1.0-alpha) "{} ({})
Copyright (C) 2023 Arkaprabha Chakraborty Copyright (C) 2023 Arkaprabha Chakraborty
License GPLv3: GNU GPL version 3 License GPLv3: GNU GPL version 3
This is free software: you are free to change and redistribute it. This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. There is {}, to the extent permitted by law.
Written by Arkaprabha Chakraborty" Written by Arkaprabha Chakraborty",
PROGRAM_NAME.bright_yellow(),
PROGRAM_VERSION.bright_blue(),
"NO WARRANTY".bright_red()
); );
exit(0); exit(0);
} }
@@ -232,7 +262,10 @@ Written by Arkaprabha Chakraborty"
let path: String = match args.next() { let path: String = match args.next() {
Some(temp) => temp, Some(temp) => temp,
None => { None => {
eprintln!("Error: Was expecting two arguments but received none"); eprintln!(
"{} Was expecting two arguments but received none",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
@@ -240,14 +273,17 @@ Written by Arkaprabha Chakraborty"
let output: String = match args.next() { let output: String = match args.next() {
Some(temp) => temp, Some(temp) => temp,
None => { None => {
eprintln!("Error: Was expecting two arguments but received one"); eprintln!(
"{} Was expecting two arguments but received one",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
match args.next() { match args.next() {
Some(_) => { Some(_) => {
eprintln!("Error: Too many arguments"); eprintln!("{} Too many arguments", "Error:".bright_red());
exit(0); exit(0);
} }
None => (), None => (),
@@ -267,7 +303,10 @@ Written by Arkaprabha Chakraborty"
let path: String = match args.next() { let path: String = match args.next() {
Some(temp) => temp, Some(temp) => temp,
None => { None => {
eprintln!("Error: Was expecting two arguments but received none"); eprintln!(
"{} Was expecting two arguments but received none",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
@@ -275,14 +314,17 @@ Written by Arkaprabha Chakraborty"
let output: String = match args.next() { let output: String = match args.next() {
Some(temp) => temp, Some(temp) => temp,
None => { None => {
eprintln!("Error: Was expecting two arguments but received one"); eprintln!(
"{} Was expecting two arguments but received one",
"Error:".bright_red()
);
exit(0); exit(0);
} }
}; };
match args.next() { match args.next() {
Some(_) => { Some(_) => {
eprintln!("Error: Too many arguments"); eprintln!("{} Too many arguments", "Error:".bright_red());
exit(0); exit(0);
} }
None => (), None => (),
@@ -299,7 +341,7 @@ Written by Arkaprabha Chakraborty"
exit(0); exit(0);
} }
_ => { _ => {
eprintln!("Error: Unrecognized argument"); eprintln!("{} Unrecognized argument", "Error:".bright_red());
exit(0); exit(0);
} }
}; };