Refactored key-management a lot.

This commit is contained in:
Revertron
2021-02-15 23:09:30 +01:00
parent 4c4493f797
commit 364a969a53
9 changed files with 126 additions and 118 deletions
+69 -30
View File
@@ -1,8 +1,9 @@
#![windows_subsystem = "windows"]
extern crate web_view;
extern crate tinyfiledialogs as tfd;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, Ordering, AtomicUsize};
use std::thread;
use rand::RngCore;
@@ -27,7 +28,10 @@ fn main() {
println!("ALFIS 0.1.0");
let settings = Settings::load(SETTINGS_FILENAME).expect("Error loading settings");
let keystore: Keystore = match Keystore::from_file(&settings.key_file, "") {
None => { generate_key(KEYSTORE_DIFFICULTY, Arc::new(AtomicBool::new(true))).expect("Could not load or generate keypair") }
None => {
println!("Generated temporary keystore. Please, generate full-privileged keys.");
Keystore::new()
}
Some(keystore) => { keystore }
};
let blockchain: Blockchain = Blockchain::new(&settings);
@@ -81,36 +85,66 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
Loaded => {
web_view.eval("showMiningIndicator(false);").expect("Error evaluating!");
let handle = web_view.handle();
let context_copy = context.clone();
let mut c = context.lock().unwrap();
c.bus.register(move |_uuid, e| {
println!("Got event from bus {:?}", &e);
let visible = match e {
Event::MinerStarted => { true }
Event::KeyGeneratorStarted => { true }
Event::MinerStopped => { false }
Event::KeyGeneratorStopped => { false }
_ => { false }
let eval = match e {
Event::KeyCreated { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::KeyLoaded { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::KeySaved { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::MinerStarted => { format!("showMiningIndicator({});", true) }
Event::KeyGeneratorStarted => { format!("showMiningIndicator({});", true) }
Event::MinerStopped => { format!("showMiningIndicator({});", false) }
Event::KeyGeneratorStopped => { format!("showMiningIndicator({});", false) }
_ => { String::new() }
};
handle.dispatch(move |web_view| {
web_view.eval(&format!("showMiningIndicator({});", visible)).expect("Error evaluating!");
return WVResult::Ok(());
}).expect("Error dispatching!");
if !eval.is_empty() {
println!("Evaluating {}", &eval);
handle.dispatch(move |web_view| {
web_view.eval(&eval.replace("\\", "\\\\")).expect("Error evaluating!");
return WVResult::Ok(());
}).expect("Error dispatching!");
}
true
});
}
LoadKey { name, pass } => {
match Keystore::from_file(&name, &pass) {
None => {
println!("Error loading keystore '{}'!", &name);
},
Some(keystore) => {
let mut c = context.lock().unwrap();
c.set_keystore(keystore);
LoadKey {} => {
let result = tfd::open_file_dialog("Open keys file", "", Some((&["*.key"], "*.key")));
match result {
None => {}
Some(file_name) => {
match Keystore::from_file(&file_name, "") {
None => {
println!("Error loading keystore '{}'!", &file_name);
},
Some(keystore) => {
println!("Loaded keystore with key: {:?}", &keystore.get_public());
let mut c = context.lock().unwrap();
c.bus.post(Event::KeyLoaded {path: keystore.get_path().to_owned(), public: keystore.get_public().to_string()});
c.set_keystore(keystore);
}
}
}
}
},
CreateKey { name, pass } => {
create_key(context.clone(), &name, &pass);
CreateKey {} => {
create_key(context.clone());
}
SaveKey {} => {
let result = tfd::save_file_dialog_with_filter("Save keys file", "", &["*.key"], "Key files (*.key)");
match result {
None => {}
Some(new_path) => {
let mut c = context.lock().unwrap();
let path = new_path.clone();
let public = c.keystore.get_public().to_string();
c.keystore.save(&new_path, "");
println!("Key file saved to {}", &path);
c.bus.post(Event::KeySaved {path, public });
}
}
}
CheckDomain { name} => {
let c = context.lock().unwrap();
@@ -170,28 +204,32 @@ fn create_transaction<S: Into<String>>(keystore: &Keystore, name: S, method: S,
transaction
}
fn create_key(context: Arc<Mutex<Context>>, filename: &str, password: &str) {
fn create_key(context: Arc<Mutex<Context>>) {
let mining = Arc::new(AtomicBool::new(true));
let miners_count = Arc::new(AtomicUsize::new(0));
{ context.lock().unwrap().bus.post(Event::KeyGeneratorStarted); }
for _ in 0..num_cpus::get() {
let context = context.clone();
let filename= filename.to_owned();
let password= password.to_owned();
let mining = mining.clone();
let miners_count = miners_count.clone();
thread::spawn(move || {
miners_count.fetch_add(1, Ordering::Relaxed);
match generate_key(KEYSTORE_DIFFICULTY, mining.clone()) {
None => {
println!("Keystore mining finished");
context.lock().unwrap().bus.post(Event::KeyGeneratorStopped);
}
Some(keystore) => {
println!("Key mined successfully: {:?}", &keystore.get_public());
let mut c = context.lock().unwrap();
mining.store(false,Ordering::Relaxed);
keystore.save(&filename, &password);
c.bus.post(Event::KeyCreated {path: keystore.get_path().to_owned(), public: keystore.get_public().to_string()});
c.set_keystore(keystore);
c.bus.post(Event::KeyGeneratorStopped);
}
}
let miners = miners_count.fetch_sub(1, Ordering::Relaxed) - 1;
if miners == 0 {
context.lock().unwrap().bus.post(Event::KeyGeneratorStopped);
}
});
}
context.lock().unwrap().bus.register(move |_uuid, e| {
@@ -222,8 +260,9 @@ fn generate_key(difficulty: usize, mining: Arc<AtomicBool>) -> Option<Keystore>
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
Loaded,
LoadKey{name: String, pass: String},
CreateKey{name: String, pass: String},
LoadKey{},
CreateKey{},
SaveKey{},
CheckDomain{name: String},
CreateDomain{name: String, records: String, tags: String},
ChangeDomain{name: String, records: String, tags: String},