From 151274d7540031e391fd1fd9d7eed91a6982d5ca Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 27 May 2019 22:57:40 -0400 Subject: [PATCH] Reading/writing unencrypted db properties and starting work on getting the master key --- Cargo.toml | 1 + src/db.rs | 34 ++++++++++++++++++++++++++++++++++ src/main.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index be65de9..13d4ed3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ log = "0.4.6" pretty_env_logger = "0.3.0" rand = "0.6.5" dirs = "2.0.0" +rust-crypto = "0.2.36" [dependencies.rusqlite] version = "0.18.0" diff --git a/src/db.rs b/src/db.rs index c030ecd..99f2180 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,4 +1,5 @@ use rusqlite::Connection; +use std::error::Error; use std::path::PathBuf; static DB_INIT_QUERY: &'static str = include_str!("init.sql"); @@ -7,6 +8,12 @@ pub struct DbHandle { conn: Connection, } +#[derive(Debug, Clone)] +struct DbProperty { + name: String, + value: Option, +} + impl DbHandle { pub fn new(db_path: &Option) -> DbHandle { let path: PathBuf = db_path @@ -19,4 +26,31 @@ impl DbHandle { tx.commit(); DbHandle { conn: conn } } + + pub fn get_db_property(&self, name: &str) -> Result, Box> { + let mut stmt = self + .conn + .prepare("SELECT name, value FROM props WHERE name=$1") + .unwrap(); + let mut props = stmt.query_map(&[&name], |row| { + Ok(DbProperty { + name: row.get(0)?, + value: row.get(1)?, + }) + })?; + + match props.next() { + Some(prop) => Ok(Some(prop.unwrap().value.unwrap())), + None => Ok(None), + } + } + + pub fn set_db_property(&self, name: &str, value: &str) { + self.conn + .execute( + "INSERT OR REPLACE INTO props (name, value) VALUES ($1, $2)", + &[&name, &value], + ) + .unwrap(); + } } diff --git a/src/main.rs b/src/main.rs index faad663..4b927ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ use docopt::Docopt; use log::debug; +use rand::rngs::OsRng; +use rand::seq::IteratorRandom; +use rand::seq::SliceRandom; use serde::Deserialize; use std::error::Error; @@ -32,6 +35,31 @@ struct Args { arg_spec: Option, } +fn get_master_key(db_conn: &mut db::DbHandle) -> [u8; 32] { + let known_string = db_conn + .get_db_property("known_string") + .unwrap_or_else(|error| { + panic!("There was a problem reading from the db: {:?}", error); + }) + .unwrap_or_else(|| { + println!("No master password set yet, create new one:"); + let mut random = OsRng::new().unwrap(); + let new_known: String = { + let mut new_chars: Vec = "abcdefghijklmnopqrstuvwxyz" + .chars() + .choose_multiple(&mut random, 64); + new_chars.shuffle(&mut random); + new_chars.into_iter().collect() + }; + db_conn.set_db_property("known_string", &new_known); + new_known + }); + + let master_key: [u8; 32] = [0; 32]; + + master_key +} + fn main() -> Result<(), Box> { pretty_env_logger::init(); let args: Args = Docopt::new(USAGE) @@ -46,5 +74,7 @@ fn main() -> Result<(), Box> { let mut db_conn: db::DbHandle = db::DbHandle::new(&args.flag_db); + let master_key: [u8; 32] = get_master_key(&mut db_conn); + Ok(()) }