// This seems like probably not the best way to do this, but it works. #[path = "../client_lib.rs"] mod client_lib; use client_lib::*; use curve25519_dalek::scalar::Scalar; use getopts::Options; use lox::bridge_table::BridgeLine; use lox::IssuerPubKey; use serde::Serialize; use std::env::args; use std::fs::File; use std::io::Write; use std::path::Path; // Prints the argument details for this program fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [options]", program); print!("{}", opts.usage(&brief)); } // Helper function to save serializable objects to files fn save_object(obj: T, filename: &str) { let mut outfile = File::create(filename).expect(&("Failed to create ".to_string() + filename)); write!(outfile, "{}", serde_json::to_string(&obj).unwrap()) .expect(&("Failed to write to ".to_string() + filename)); } #[tokio::main] async fn main() { let args: Vec = args().collect(); let mut opts = Options::new(); opts.optflag("h", "help", "print this help menu"); opts.optflag("L", "level-up", "increase trust level"); opts.optflag("N", "new-lox-cred", "get a new Lox Credential"); opts.optopt( "", "server", "Lox Auth server address [http://localhost:8001]", "ADDR", ); let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(f) => { panic!("{}", f.to_string()) } }; if matches.opt_present("h") { print_usage(&args[0], opts); return; } let server_addr = if matches.opt_present("server") { matches.opt_str("server").unwrap() } else { "http://localhost:8001".to_string() }; // Get Lox Authority public keys // TODO: Make this filename configurable let lox_auth_pubkeys_filename = "lox_auth_pubkeys.json"; let lox_auth_pubkeys: Vec = if Path::new(lox_auth_pubkeys_filename).exists() { // read in file let lox_auth_pubkeys_infile = File::open(lox_auth_pubkeys_filename).unwrap(); serde_json::from_reader(lox_auth_pubkeys_infile).unwrap() } else { // download from Lox Auth let pubkeys = get_lox_auth_keys(&server_addr).await; // save to file for next time save_object(&pubkeys, &lox_auth_pubkeys_filename); pubkeys }; // Get Lox Credential and BridgeLine let lox_cred_filename = "lox_cred.json"; let bridgeline_filename = "bridgeline.json"; let (lox_cred, bridgeline) = if matches.opt_present("N") || !Path::new(lox_cred_filename).exists() || !Path::new(bridgeline_filename).exists() { // get new Lox Credential let open_invite = get_open_invitation(&server_addr).await; let (cred, bl) = get_lox_credential(&server_addr, &open_invite, get_lox_pub(&lox_auth_pubkeys)).await; // save to files for next time save_object(&cred, &lox_cred_filename); save_object(&bl, &bridgeline_filename); (cred, bl) } else { // Read existing Lox Credential and BridgeLine from files let cred = serde_json::from_reader(File::open(lox_cred_filename).unwrap()).unwrap(); let bl = serde_json::from_reader(File::open(bridgeline_filename).unwrap()).unwrap(); (cred, bl) }; if matches.opt_present("L") { // If trust level is 0, do trust promotion, otherwise level up. if lox_cred.trust_level == Scalar::zero() { let migration_cred = trust_promotion(&server_addr, &lox_cred, get_lox_pub(&lox_auth_pubkeys)).await; let cred = trust_migration( &server_addr, &lox_cred, &migration_cred, get_lox_pub(&lox_auth_pubkeys), get_migration_pub(&lox_auth_pubkeys), ) .await; } else { let encbuckets = get_reachability_credential(&server_addr).await; let cred = level_up( &server_addr, &lox_cred, &encbuckets, get_lox_pub(&lox_auth_pubkeys), get_reachability_pub(&lox_auth_pubkeys), ) .await; } } }