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,