diff --git a/.gitignore b/.gitignore index e197849..ae3dc9d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target/ .DS_Store .idea/ *.iml +site_counter.db diff --git a/Cargo.lock b/Cargo.lock index 1b8907f..41f2781 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,9 +5,11 @@ dependencies = [ "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "bcrypt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "ring-pwhash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -56,6 +58,11 @@ name = "bitflags" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "blake2-rfc" version = "0.2.17" @@ -123,6 +130,28 @@ name = "libc" version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libsqlite3-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "linked-hash-map" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lru-cache" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nix" version = "0.5.1" @@ -140,6 +169,11 @@ dependencies = [ "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pkg-config" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rand" version = "0.3.15" @@ -206,6 +240,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rusqlite" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rust-crypto" version = "0.2.36" @@ -290,6 +335,11 @@ name = "untrusted" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vcpkg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vec_map" version = "0.8.0" @@ -312,6 +362,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bcrypt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "feed84d558481ece6e7b867df7b9d42c17c6b14220a045ee545382f4386987a9" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum blake2-rfc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6a476f32fef3402f1161f89d0d39822809627754a126f8441ff2a9d45e2d59" "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f" "checksum constant_time_eq 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "07dcb7959f0f6f1cf662f9a7ff389bcb919924d99ac41cf31f10d611d8721323" @@ -322,8 +373,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" +"checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c" +"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" +"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" "checksum num_cpus 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e416ba127a4bb3ff398cb19546a8d0414f73352efe2857f4060d36f5fe5983a" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" "checksum rayon-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd1e76f8ee0322fbbeb0c43a07e1757fcf8ff06bb0ff92da017625882ddc04dd" @@ -331,6 +386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ring 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "24293de46bac74c9b9c05b40ff8496bbc8b9ae242a9b89f754e1154a43bc7c4c" "checksum ring-pwhash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad6f03e64c7f6c71e92431fa8ab953952d70743b86882809b44a5e2f9759ae74" "checksum rpassword 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72556b202b5b38d0b69b0fdced60cf92dec7e37640c98eb9d7baf5bd86dc8e1a" +"checksum rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaf393ccdac5580092a4d8eb2edffbffe9a8c4484c62d8a0fcac99bc3718566" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustyline 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "00b06ac9c8e8e3e83b33d175d39a9f7b6c2c930c82990593719c8e48788ae2d9" @@ -342,6 +398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b65243989ef6aacd9c0d6bd2b822765c3361d8ed352185a6f3a41f3a718c673" +"checksum vcpkg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df74ff70e2ced9607f67e06640f89a6a6374b459b51bdef290a5cfa657fe4fcc" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index 50ed112..c5ed218 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,8 @@ rpassword = "0.4" ring = "0.9" ring-pwhash = "0.2" rustyline = "1.0" +rusqlite = "0.12.0" +libsqlite3-sys = "0.8.0" [badges] travis-ci = { repository = "lispyclouds/mpw-rs" } diff --git a/src/arg_parse/mod.rs b/src/arg_parse/mod.rs index 13cae89..7e81699 100644 --- a/src/arg_parse/mod.rs +++ b/src/arg_parse/mod.rs @@ -16,12 +16,14 @@ extern crate clap; // along with Master Password. If not, see . mod helpers; +mod store; use std::process; use self::clap::{Arg, App}; use common::{SiteVariant, SiteType}; use benchmark::mpw_bench; +#[derive(Debug)] pub struct MpwOptions { pub site: String, pub user: String, @@ -111,6 +113,11 @@ pub fn get_opts() -> MpwOptions { .long("benchmark") .help("Benchmarks this program") .takes_value(false)) + .arg(Arg::with_name("save") + .short("s") + .long("save") + .help("Saves the current counter value for the site") + .takes_value(false)) .get_matches(); if matches.is_present("benchmark") { @@ -131,7 +138,7 @@ pub fn get_opts() -> MpwOptions { let user = match helpers::read_opt(&matches, "user", "MP_FULLNAME") { Some(val) => val.to_string(), None => { - match helpers::raw_input("Site Name: ") { + match helpers::raw_input("Full Name: ") { Some(val) => val, None => panic!("Can't read STDIN"), } @@ -171,7 +178,7 @@ pub fn get_opts() -> MpwOptions { None => String::new(), }; - MpwOptions { + let mpw_options = MpwOptions { site: site, user: user, variant: variant.unwrap(), @@ -179,5 +186,12 @@ pub fn get_opts() -> MpwOptions { counter: counter, algo: algo, context: context, + }; + + if matches.is_present("save") { + store::save_to_sql_lite(mpw_options) + } + else { + mpw_options } } diff --git a/src/arg_parse/store.rs b/src/arg_parse/store.rs new file mode 100644 index 0000000..0b6cdaf --- /dev/null +++ b/src/arg_parse/store.rs @@ -0,0 +1,61 @@ +extern crate rusqlite; + +use self::rusqlite::Connection; +use arg_parse::MpwOptions; +use self::rusqlite::{Result}; + + +pub fn save_to_sql_lite(mpw_options: MpwOptions) -> MpwOptions { + let conn = Connection::open("site_counter.db").unwrap(); + conn.execute("CREATE TABLE IF NOT EXISTS mpwOptions (\ + site TEXT NOT NULL,\ + user TEXT NOT NULL,\ + variant INTEGER,\ + template INTEGER,\ + counter INTEGER,\ + algo TEXT NOT NULL,\ + context TEXT NOT NULL\ + )", &[]).unwrap(); + + let variant = mpw_options.variant.clone() as i32; + let template = mpw_options.template.clone() as i32; + let counter = mpw_options.counter as i32; + let mut updated_counter = counter; + + let does_exist: Result = conn.query_row("SELECT counter FROM mpwOptions \ + WHERE site = ? and user = ? and variant = ? and template = ?\ + and algo = ? and context = ?", &[&mpw_options.site, &mpw_options.user, &variant, &template, + &mpw_options.algo, &mpw_options.context], |r| r.get(0)); + + let test: bool = match does_exist { + Ok(_) => true, + _ => false, + }; + + if !test { + conn.execute("INSERT INTO mpwOptions \ + (site,user,variant,template,counter,algo,context)\ + VALUES (?1,?2,?3,?4,?5,?6,?7)", + &[&mpw_options.site, &mpw_options.user, &variant, &template, + &counter, &mpw_options.algo, &mpw_options.context]).unwrap(); + } else { + updated_counter = does_exist.unwrap() + 1; + println!("Current Site Counter is: {}",updated_counter); + conn.execute("UPDATE mpwOptions SET counter = ?\ + WHERE site = ? and user = ? \ + and variant = ? and template = ? \ + and algo = ? and context = ?", + &[&updated_counter, &mpw_options.site, &mpw_options.user, &variant, &template, + &mpw_options.algo, &mpw_options.context]).unwrap(); + } + + MpwOptions { + site: mpw_options.site, + user: mpw_options.user, + variant: mpw_options.variant, + template: mpw_options.template, + counter: updated_counter, + algo: mpw_options.algo, + context: mpw_options.context, + } +} \ No newline at end of file diff --git a/src/common/mod.rs b/src/common/mod.rs index 98dd98c..89553ac 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -22,6 +22,8 @@ use self::argon2rs::{Variant, Argon2}; pub const KEY_LENGTH: usize = 64_usize; #[derive(PartialEq, Eq)] +#[derive(Debug)] +#[derive(Clone)] pub enum SiteVariant { Password, Login, @@ -40,6 +42,8 @@ impl SiteVariant { } #[derive(PartialEq, Eq)] +#[derive(Debug)] +#[derive(Clone)] pub enum SiteType { Maximum, Long,