Implement gen command, to generate samples.
This commit is contained in:
@@ -22,3 +22,4 @@ rpassword = "7.2.0"
|
||||
shlex = "1.1.0"
|
||||
shellexpand = "3.0.0"
|
||||
scopeguard = "1.1.0"
|
||||
rand = "0.8.5"
|
||||
|
||||
+47
-1
@@ -5,10 +5,13 @@ use std::collections::{HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::rc::Rc;
|
||||
use std::cmp::min;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
use crate::parser::command_parser;
|
||||
use crate::password::fix_password_recursion;
|
||||
use crate::password::{Name, PasswordRef};
|
||||
use crate::password::{Name, Password, PasswordRef};
|
||||
use crate::repl::LKEval;
|
||||
use crate::structs::{LKOut, Radix, CORRECT_FILE, DUMP_FILE};
|
||||
use crate::utils::{call_cmd_with_input, get_cmd_args_from_command, get_copy_command_from_env};
|
||||
@@ -409,4 +412,47 @@ impl<'a> LKEval<'a> {
|
||||
Err(e) => out.e(format!("error: failed to write: {}", e.to_string())),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn cmd_gen(&self, out: &LKOut, num: &u32, name: &PasswordRef) {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(r"^.+?(G+|X+)$").unwrap();
|
||||
}
|
||||
let mut rng = thread_rng();
|
||||
let num: usize = (*num).try_into().unwrap();
|
||||
let pwd = name.borrow();
|
||||
let secret = "a".to_string();
|
||||
let mut genpwds: Vec<(PasswordRef, String)> = Vec::new();
|
||||
match RE.captures(pwd.name.as_ref()) {
|
||||
Some(caps) => {
|
||||
let gen = &caps[1];
|
||||
if gen.starts_with("G") {
|
||||
let name = pwd.name.trim_end_matches('G');
|
||||
for num in 1..10_u32.pow(gen.len().try_into().unwrap()) {
|
||||
let npwd = Password::from_password(&pwd);
|
||||
npwd.borrow_mut().name = Rc::new(format!("{}{}", name, num).to_string());
|
||||
let pass = npwd.borrow().encode(&secret);
|
||||
genpwds.push((npwd, pass));
|
||||
}
|
||||
} else {
|
||||
let name = gen.trim_end_matches('X');
|
||||
let num = rng.gen_range(1..10_u32.pow(gen.len().try_into().unwrap()));
|
||||
let npwd = Password::from_password(&pwd);
|
||||
npwd.borrow_mut().name = Rc::new(format!("{}{}", name, num).to_string());
|
||||
let pass = npwd.borrow().encode(&secret);
|
||||
genpwds.push((npwd, pass));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let npwd = Password::from_password(&pwd);
|
||||
let pass = npwd.borrow().encode(&secret);
|
||||
genpwds.push((npwd, pass));
|
||||
}
|
||||
}
|
||||
genpwds.sort_by(|a, b| b.1.len().cmp(&a.1.len()));
|
||||
out.o(format!("{:>30}{:>4} {}", "Name", "Len", "Password"));
|
||||
for num in (genpwds.len()-min(genpwds.len(), num))..genpwds.len() {
|
||||
let (pwd, pass) = (genpwds[num].0.borrow(), genpwds[num].1.to_string());
|
||||
out.o(format!("{:>30}{:>4} {}", pwd.to_string(), pass.len(), pass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -21,6 +21,7 @@ peg::parser! {
|
||||
/ dump_cmd()
|
||||
/ dump_def_cmd()
|
||||
/ enc_cmd()
|
||||
/ gen_cmd()
|
||||
/ pass_cmd()
|
||||
/ unpass_cmd()
|
||||
/ correct_cmd()
|
||||
@@ -51,12 +52,14 @@ peg::parser! {
|
||||
match name { Some(n) => Ok(n), None => Err("failed to parse password description") }
|
||||
}
|
||||
|
||||
rule date() -> NaiveDate = y:$("-"? ['0'..='9']*<1,4>) "-" m:$(['0'..='9']*<1,2>) "-" d:$(['0'..='9']*<1,2>) {?
|
||||
rule ndate() -> NaiveDate = y:$("-"? ['0'..='9']*<1,4>) "-" m:$(['0'..='9']*<1,2>) "-" d:$(['0'..='9']*<1,2>) {?
|
||||
let year: i32 = match y.parse() { Ok(n) => n, Err(_) => return Err("year") };
|
||||
let month: u32 = match m.parse() { Ok(n) => n, Err(_) => return Err("month") };
|
||||
let day: u32 = match d.parse() { Ok(n) => n, Err(_) => return Err("day") };
|
||||
NaiveDate::from_ymd_opt(year, month, day).ok_or("date")
|
||||
}
|
||||
rule cdate() -> NaiveDate = "now" { Local::now().naive_local().date() }
|
||||
rule date() -> NaiveDate = d:(ndate() / cdate()) { d }
|
||||
rule umode() -> Mode = ("U" / "u") m:$("R" / "r" / "N" / "n" / "H" / "h" / "B" / "b") {?
|
||||
match m.to_uppercase().as_str() {
|
||||
"R" => Ok(Mode::RegularUpcase),
|
||||
@@ -88,6 +91,9 @@ peg::parser! {
|
||||
rule source_cmd() -> Command<'input> = "source" _ s:$(([' '..='~'])+) { Command::Source(s.to_string()) }
|
||||
rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".to_string())) }
|
||||
rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) }
|
||||
rule gen_cmd() -> Command<'input> = "gen" n:num()? _ name:name() {
|
||||
Command::Gen(match n { Some(n) => n, None => 10_u32 }, Rc::new(RefCell::new(name)))
|
||||
}
|
||||
rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) }
|
||||
rule mv_cmd() -> Command<'input> = "mv" _ name:word() _ folder:word() { Command::Mv(name, folder) }
|
||||
rule pass_cmd() -> Command<'input> = "pass" _ name:word() { Command::Pass(name) }
|
||||
|
||||
@@ -47,6 +47,19 @@ impl Password {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_password(password: &Password) -> PasswordRef {
|
||||
Rc::new(RefCell::new(Self {
|
||||
parent: password.parent.clone(),
|
||||
prefix: password.prefix.clone(),
|
||||
name: password.name.clone(),
|
||||
length: password.length.clone(),
|
||||
mode: password.mode.clone(),
|
||||
seq: password.seq,
|
||||
date: password.date.clone(),
|
||||
comment: password.comment.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn encode(&self, secret: &str) -> String {
|
||||
let skey = SKey::new(&self.name, self.seq, secret);
|
||||
let (sep, len) = match (&self.length, &self.mode) {
|
||||
|
||||
+2
-3
@@ -106,9 +106,8 @@ impl<'a> LKEval<'a> {
|
||||
}
|
||||
None => out.e(format!("error: password {} not found", name)),
|
||||
},
|
||||
Command::Enc(name) => {
|
||||
self.cmd_enc(&out, name);
|
||||
}
|
||||
Command::Enc(name) => { self.cmd_enc(&out, name); }
|
||||
Command::Gen(num, name) => self.cmd_gen(&out, &num, &name),
|
||||
Command::PasteBuffer(command) => self.cmd_pb(&out, command),
|
||||
Command::Source(script) => self.cmd_source(&out, script),
|
||||
Command::Dump(script) => self.cmd_dump(&out, script),
|
||||
|
||||
+2
-1
@@ -60,6 +60,7 @@ pub enum Command<'a> {
|
||||
Mv(Name, Name),
|
||||
Rm(Name),
|
||||
Enc(Name),
|
||||
Gen(u32, PasswordRef),
|
||||
Pass(Name),
|
||||
UnPass(Name),
|
||||
Correct(Name),
|
||||
@@ -74,7 +75,7 @@ pub enum Command<'a> {
|
||||
Quit,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Mode {
|
||||
Regular,
|
||||
RegularUpcase,
|
||||
|
||||
Reference in New Issue
Block a user