From 366bfc313d84c5eb39896a3cd0a2d344740969f2 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sun, 16 Sep 2018 12:29:32 +0100 Subject: Assorted changes --- Cargo.lock | 38 ++++++++++++++++++++++++++--------- lockchain-core/src/init.rs | 21 ++++++++++++++++--- lockchain-core/src/traits.rs | 2 +- lockchain-core/src/users/userstore.rs | 17 ++++++++++------ lockchain-files/Cargo.toml | 2 +- lockchain-files/examples/create.rs | 32 ++++++++++++++++------------- lockchain-files/src/config.rs | 34 ++++++++++++++++++------------- lockchain-files/src/create.rs | 33 ++++++++++++++++++------------ lockchain-files/src/fs/mod.rs | 15 ++++++++++---- lockchain-files/src/fs/primitive.rs | 9 +++++++-- lockchain-files/src/lib.rs | 19 ++++-------------- 11 files changed, 139 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5508ee..c98cbf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -896,6 +896,11 @@ name = "linked-hash-map" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "linked-hash-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lock_api" version = "0.1.3" @@ -965,7 +970,7 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_yaml 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1542,6 +1547,17 @@ dependencies = [ "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_yaml" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sha1" version = "0.6.0" @@ -1908,14 +1924,6 @@ dependencies = [ "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "toml" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "trust-dns-proto" version = "0.3.3" @@ -2155,6 +2163,14 @@ name = "xdg" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "yaml-rust" +version = "0.4.2" +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)", +] + [metadata] "checksum actix 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7f0b2daad36916ccd2b162dbc5a04a74df642a29391b1a341c8ee3e82026cb16" "checksum actix-web 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "cebfb353ebcae66f93c190b80ef12b8c82557413856e3e65dbaab662a48ec72d" @@ -2257,6 +2273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazycell 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e26d4c411b39f0afcf2ba6fe502be90e6c9b299c952dbd86124782520a13cffd" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" +"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum lockchain-core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d34acd8a5040484e911a589ad050c1f7f75ea171445f86a1062a46ec3d8157" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" @@ -2324,6 +2341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)" = "0fb622d85245add5327d4f08b2d24fd51fa5d35fe1bba19ee79a1f211e9ac0ff" "checksum serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "59790990c5115d16027f00913e2e66de23a51f70422e549d2ad68c8c5f268f1c" "checksum serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aaed41d9fb1e2f587201b863356590c90c1157495d811430a0c0325fe8169650" +"checksum serde_yaml 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d58de5bf17f1e4ef9f12e774e00b2f11bd68579cff2d5918b6f79bf6f5270dd" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" @@ -2360,7 +2378,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c" "checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" "checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89" -"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum trust-dns-proto 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cbbddb93547eeee847367d8f59b68002294a7b4df31c143fbee4109ce0c61a04" "checksum trust-dns-resolver 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0a0c9d4f8dd56481209c5ae1a8965ed022461d352c81fb92466ec9d846929e" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" @@ -2394,3 +2411,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" +"checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" diff --git a/lockchain-core/src/init.rs b/lockchain-core/src/init.rs index 1880599..410974a 100644 --- a/lockchain-core/src/init.rs +++ b/lockchain-core/src/init.rs @@ -2,16 +2,31 @@ use errors::VaultError; use traits::{Body, Vault}; /// Describes the internal permission layout of a vault +/// +/// --- +/// +/// **Important Note** Because lockchain-core doesn't make assumptions about +/// about the existence of a cryptographic layer, the `UserStore` that +/// handles these secrets assumes they are **not** secret! +/// +/// This means that only already encrypted keys should be given to the +/// generator type, because they will be written to disk **as is** by +/// certain backends! +/// +/// It is in the responsibility of the library user to make sure that all +/// cryptographic operations are handled on the client side. Clear-text +/// keys that are given to a generator +/// should be considered **fully compromised** #[derive(Debug, Serialize, Deserialize, Clone)] pub enum VaultType { /// Create an all-powerful root user which can access everything Administrated { - /// Set a root password - secret: String, + /// + secret: Vec, }, /// Similar to `Administrated` /// but only allows a single-user for a vault - SoloUser { username: String, secret: String }, + SoloUser { username: String, secret: Vec }, } /// A shared initialisation generator for vaults diff --git a/lockchain-core/src/traits.rs b/lockchain-core/src/traits.rs index 13fc1b3..9cd77b0 100644 --- a/lockchain-core/src/traits.rs +++ b/lockchain-core/src/traits.rs @@ -188,7 +188,7 @@ where /// Auto-implement this trait to serialise types to json pub trait AutoEncoder: Serialize + DeserializeOwned { fn encode(&self) -> Result { - serde_json::to_string_pretty(self) + serde_json::to_string(self) } fn decode(s: &str) -> Result { diff --git a/lockchain-core/src/users/userstore.rs b/lockchain-core/src/users/userstore.rs index 5355cdb..51d78a8 100644 --- a/lockchain-core/src/users/userstore.rs +++ b/lockchain-core/src/users/userstore.rs @@ -1,7 +1,6 @@ //! Merging `KeyStore` and `Userstore` into the same concept use super::rights::Access; -use crypto::Key; use std::collections::HashMap; use traits::AutoEncoder; @@ -18,7 +17,7 @@ pub struct UserStore { #[derive(Serialize, Deserialize)] pub struct StoreUser { name: String, - keys: HashMap, + keys: HashMap>, } impl AutoEncoder for UserStore {} @@ -34,7 +33,7 @@ impl UserStore { } } /// Adds a new user to the store, with a root-key - pub fn add_user(&mut self, name: String, key: Key) { + pub fn add_user(&mut self, name: String, key: Vec) { let mut user = StoreUser { name: name.clone(), keys: HashMap::new(), @@ -47,7 +46,7 @@ impl UserStore { self.store.remove(name); } /// Add a key to an existing user - pub fn add_key(&mut self, user: String, k: Key, access: Access) { + pub fn add_key(&mut self, user: String, k: Vec, access: Access) { if !self.store.contains_key(&user) { return; } @@ -55,7 +54,13 @@ impl UserStore { self.store.get_mut(&user).unwrap().keys.insert(access, k); } - pub fn get_key(&self, user: String, access: Access) -> Option<&Key> { - self.store.get(&user).map_or(None, |u| u.keys.get(&access)) + pub fn get_root_key(&self, user: &str) -> Option<&Vec> { + self.store + .get(user) + .map_or(None, |u| u.keys.get(&Access::Root)) + } + + pub fn get_key(&self, user: &str, access: Access) -> Option<&Vec> { + self.store.get(user).map_or(None, |u| u.keys.get(&access)) } } diff --git a/lockchain-files/Cargo.toml b/lockchain-files/Cargo.toml index a4b5086..11bad30 100644 --- a/lockchain-files/Cargo.toml +++ b/lockchain-files/Cargo.toml @@ -15,6 +15,6 @@ vault-version = "0.1" [dependencies] lockchain-core = { version = "0.9.1-alpha.0", path = "../lockchain-core" } semver = "0.9.0" -toml = "0.4" +serde_yaml = "0.8" serde = "1.0" serde_derive = "1.0" \ No newline at end of file diff --git a/lockchain-files/examples/create.rs b/lockchain-files/examples/create.rs index 27d4ff9..2018b7f 100644 --- a/lockchain-files/examples/create.rs +++ b/lockchain-files/examples/create.rs @@ -4,23 +4,27 @@ extern crate lockchain_files as files; use files::FileVault; use lcc::traits::Vault; use lcc::users::User; -use lcc::{EncryptedBody, Generator, Payload, Record, VaultType}; +use lcc::{ + crypto::{Key, KeyType}, + EncryptedBody, Generator, Payload, Record, VaultType, +}; use std::env; fn main() { - - // if env::args().len() == 3 { - // let path = env::args().nth(1).unwrap(); - // let name = env::args().nth(2).unwrap(); - - // let mut vault: FileVault = Generator::new() - // .path(name, path) - // .user_type(VaultType::SoloUser { - // username: "spacekookie".into(), - // secret: "foobar3264".into(), - // }).finalise() - // .unwrap(); - // vault.sync(); + if env::args().len() == 3 { + let path = env::args().nth(1).unwrap(); + let name = env::args().nth(2).unwrap(); + + let key = Key::from_pw(KeyType::Aes256, "foobar3264", "spacekookie"); + + let mut vault: FileVault = Generator::new() + .path(name, path) + .user_type(VaultType::SoloUser { + username: "spacekookie".into(), + secret: key.as_slice().to_vec(), + }).finalise() + .unwrap(); + } // let vault: FileVault = FileVault::new(&name, &path); diff --git a/lockchain-files/src/config.rs b/lockchain-files/src/config.rs index 6d67d7d..1d71605 100644 --- a/lockchain-files/src/config.rs +++ b/lockchain-files/src/config.rs @@ -8,10 +8,10 @@ use std::{ }; use semver::Version; -use toml; +use serde_yaml; use utils::FileToString; -use lcc::{errors::VaultError, Generator, VaultType}; +use lcc::{errors::VaultError, VaultType}; /// A set of errors around `lockchain-files` configs #[derive(Debug)] @@ -43,21 +43,27 @@ impl Error for ConfigError {} pub struct VaultConfig { /// A semver conforming version string pub version: String, - pub vault_type: VaultType, + pub vault_type: ConfigType, pub created_at: SystemTime, pub modified_at: SystemTime, } -impl VaultConfig { - pub fn new(gen: &Generator) -> Result { - let vt = gen - .user_type - .as_ref() - .ok_or(VaultError::IncompleteGenerator)?; +#[derive(Debug, Serialize, Deserialize)] +pub enum ConfigType { + SoloUser, + Administrated, + Unmanaged, +} +impl VaultConfig { + pub fn new(vt: &VaultType) -> Result { Ok(Self { version: "0.1".into(), - vault_type: vt.clone(), + vault_type: match vt { + &VaultType::SoloUser { .. } => ConfigType::SoloUser, + &VaultType::Administrated { .. } => ConfigType::Administrated, + _ => ConfigType::Unmanaged, + }, created_at: SystemTime::now(), modified_at: SystemTime::now(), }) @@ -65,9 +71,9 @@ impl VaultConfig { pub fn save(&self, vault: &PathBuf) -> Result<(), io::Error> { let mut cfg_path = vault.clone(); - cfg_path.push("config.toml"); + cfg_path.push("vault.cfg"); - let t = toml::to_string(self).unwrap(); + let t = serde_yaml::to_string(self).unwrap(); let mut f = OO::new().create(true).write(true).open(cfg_path)?; f.write_all(t.as_bytes())?; Ok(()) @@ -76,11 +82,11 @@ impl VaultConfig { /// Attempts to load a configuration – returning detailed errors pub fn load(vault: &PathBuf) -> Result { let mut cfg_path = vault.clone(); - cfg_path.push("config.toml"); + cfg_path.push("vault.cfg"); let cfg: VaultConfig = match File::open(cfg_path.as_path()) { Ok(mut f) => match f.get_string() { - Ok(s) => match toml::from_str(&s) { + Ok(s) => match serde_yaml::from_str(&s) { Ok(c) => c, Err(_) => return Err(ConfigError::ConfigCorrupted), }, diff --git a/lockchain-files/src/create.rs b/lockchain-files/src/create.rs index e35c449..af84a83 100644 --- a/lockchain-files/src/create.rs +++ b/lockchain-files/src/create.rs @@ -18,40 +18,47 @@ impl FileVault { /// A small utility to create a new file vault pub(crate) fn create(gen: Generator) -> Result { let (name, location) = Self::get_path(&gen)?; + let vault_type = gen + .user_type + .as_ref() + .ok_or(VaultError::IncompleteGenerator)?; let fs = Filesystem::new(location, name); fs.scaffold().map_err(|_| VaultError::FailedCreation)?; - let config = VaultConfig::new(&gen)?; + let config = VaultConfig::new(&vault_type)?; let mut users = UserStore::new(); /* At this point we'll have to create some user */ use self::VaultType::*; - match &config.vault_type { - SoloUser { username, secret } => users.add_user( - username.clone(), - Key::from_pw(KeyType::Aes256, &secret, &username), - ), - Administrated { secret } => users.add_user( - "Admin".into(), - Key::from_pw(KeyType::Aes256, &secret, "admin"), - ), + match vault_type { + SoloUser { username, secret } => users.add_user(username.clone(), secret.clone()), + Administrated { secret } => users.add_user("Admin".into(), secret.clone()), } let mut me = Self { config, fs, users, - ..Default::default() + records: HashMap::new(), + headers: HashMap::new(), + metadata: HashMap::new(), }; - /* Make sure to sync all made changes after the scaffold */ + /* Make sure to sync all changes made after scaffold */ me.sync(); Ok(me) } fn get_path(gen: &Generator) -> Result<(&str, &str), VaultError> { - Err(VaultError::IncompleteGenerator) + match gen { + &Generator { + name: Some(ref n), + location: Some(ref l), + .. + } => Ok((&n, &l)), + _ => Err(VaultError::IncompleteGenerator), + } } } diff --git a/lockchain-files/src/fs/mod.rs b/lockchain-files/src/fs/mod.rs index 7820925..9f2bfe2 100644 --- a/lockchain-files/src/fs/mod.rs +++ b/lockchain-files/src/fs/mod.rs @@ -9,21 +9,22 @@ //! which will return either `Ok(())` or the first error in the list //! of operations. -use lcc::traits::{Body, AutoEncoder}; +use lcc::traits::{AutoEncoder, Body}; use std::collections::HashMap; use std::error::Error; use std::io::{self, Write}; use std::{ - fs::{self, File, OpenOptions as OO}, + fs::{self, File, OpenOptions}, path::PathBuf, }; use utils::FileToString; use FileVault; -pub mod primitive; +mod primitive; use self::primitive::*; +use userstore::DiskMirror; #[derive(Debug)] pub struct Filesystem { @@ -87,8 +88,14 @@ impl Filesystem { pub fn sync_vault(&self, vault: &FileVault) -> Result<(), io::Error> { vault.config.save(&self.root)?; + primitive::write_file( + FileType::Metadata, + &self.root, + "userstore", + vault.users.to_disk(), + )?; - unimplemented!() + Ok(()) } /// Respond to a sync request diff --git a/lockchain-files/src/fs/primitive.rs b/lockchain-files/src/fs/primitive.rs index d567a28..f97cd49 100644 --- a/lockchain-files/src/fs/primitive.rs +++ b/lockchain-files/src/fs/primitive.rs @@ -47,7 +47,12 @@ fn type_path(tt: FileType, root: &PathBuf) -> PathBuf { path } -pub(crate) fn write_file(tt: FileType, root: PathBuf, name: &str, contents: Vec) -> Result<()> { +pub(crate) fn write_file( + tt: FileType, + root: &PathBuf, + name: &str, + contents: Vec, +) -> Result<()> { let file_name = format!("{}.{}", name, file_ending!(&tt)); let mut path = type_path(tt, &root); path.push(file_name); @@ -58,7 +63,7 @@ pub(crate) fn write_file(tt: FileType, root: PathBuf, name: &str, contents: Vec< Ok(()) } -pub(crate) fn read_file(tt: FileType, root: PathBuf, name: &str) -> Result> { +pub(crate) fn read_file(tt: FileType, root: &PathBuf, name: &str) -> Result> { let file_name = format!("{}.{}", name, file_ending!(&tt)); let mut path = type_path(tt, &root); path.push(file_name); diff --git a/lockchain-files/src/lib.rs b/lockchain-files/src/lib.rs index 1c88964..8332448 100644 --- a/lockchain-files/src/lib.rs +++ b/lockchain-files/src/lib.rs @@ -8,10 +8,10 @@ extern crate lockchain_core as lcc; extern crate semver; -extern crate toml; #[macro_use] extern crate serde_derive; +extern crate serde_yaml; extern crate serde; use lcc::traits::{Body, LoadRecord, Vault}; @@ -21,7 +21,6 @@ use lcc::{ Generator, Header, MetaDomain, Payload, Record, VaultMetadata, }; use std::collections::HashMap; -use std::default::Default; mod config; mod create; @@ -74,18 +73,6 @@ pub struct FileVault { metadata: HashMap, } -impl Default for FileVault { - #[allow(unconditional_recursion)] - fn default() -> Self { - Self { - records: HashMap::new(), - headers: HashMap::new(), - metadata: HashMap::new(), - ..Default::default() - } - } -} - impl LoadRecord for FileVault {} impl Vault for FileVault { @@ -159,13 +146,15 @@ impl Vault for FileVault { } fn sync(&mut self) { + self.fs.sync_vault(&self).unwrap(); + // self.fs // .sync::>(&self.records, FileType::Record) // .unwrap(); // self.fs // .sync::(&self.metadata, FileType::Metadata) // .unwrap(); - unimplemented!() + // unimplemented!() } fn get_record(&self, name: &str) -> Option<&Record> { -- cgit v1.2.3