|
@@ -3,16 +3,61 @@
|
|
|
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<T: Serialize>(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() {
|
|
|
- // TODO: Do proper argument handling
|
|
|
- let server_addr = args().nth(1).unwrap(); // must include http://
|
|
|
+ let args: Vec<String> = 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
|
|
@@ -26,51 +71,56 @@ async fn main() {
|
|
|
// download from Lox Auth
|
|
|
let pubkeys = get_lox_auth_keys(&server_addr).await;
|
|
|
// save to file for next time
|
|
|
- let mut lox_auth_pubkeys_outfile = File::create(lox_auth_pubkeys_filename)
|
|
|
- .expect("Failed to create lox_auth pubkeys file");
|
|
|
- write!(
|
|
|
- lox_auth_pubkeys_outfile,
|
|
|
- "{}",
|
|
|
- serde_json::to_string(&pubkeys).unwrap()
|
|
|
- )
|
|
|
- .expect("Failed to write to lox_auth pubkeys file");
|
|
|
+ save_object(&pubkeys, &lox_auth_pubkeys_filename);
|
|
|
pubkeys
|
|
|
};
|
|
|
|
|
|
// Get Lox Credential and BridgeLine
|
|
|
- // TODO: Make these filenames configurable
|
|
|
let lox_cred_filename = "lox_cred.json";
|
|
|
let bridgeline_filename = "bridgeline.json";
|
|
|
- let (lox_cred, bridgeline) = if Path::new(lox_cred_filename).exists()
|
|
|
- && Path::new(bridgeline_filename).exists()
|
|
|
+ let (lox_cred, bridgeline) = if matches.opt_present("N")
|
|
|
+ || !Path::new(lox_cred_filename).exists()
|
|
|
+ || !Path::new(bridgeline_filename).exists()
|
|
|
{
|
|
|
- let lox_cred_infile = File::open(lox_cred_filename).unwrap();
|
|
|
- let lox_cred = serde_json::from_reader(lox_cred_infile).unwrap();
|
|
|
- let bridgeline_infile = File::open(bridgeline_filename).unwrap();
|
|
|
- let bridgeline = serde_json::from_reader(bridgeline_infile).unwrap();
|
|
|
- (lox_cred, bridgeline)
|
|
|
- } else {
|
|
|
- // get new credential based on an open invite
|
|
|
+ // get new Lox Credential
|
|
|
let open_invite = get_open_invitation(&server_addr).await;
|
|
|
- let (cred, bridgeline) =
|
|
|
+ let (cred, bl) =
|
|
|
get_lox_credential(&server_addr, &open_invite, get_lox_pub(&lox_auth_pubkeys)).await;
|
|
|
+
|
|
|
// save to files for next time
|
|
|
- let mut lox_cred_outfile =
|
|
|
- File::create(lox_cred_filename).expect("Failed to create lox credential file");
|
|
|
- write!(
|
|
|
- lox_cred_outfile,
|
|
|
- "{}",
|
|
|
- serde_json::to_string(&cred).unwrap()
|
|
|
- )
|
|
|
- .expect("Failed to write to lox credential file");
|
|
|
- let mut bridgeline_outfile =
|
|
|
- File::create(bridgeline_filename).expect("Failed to create bridgeline file");
|
|
|
- write!(
|
|
|
- bridgeline_outfile,
|
|
|
- "{}",
|
|
|
- serde_json::to_string(&bridgeline).unwrap()
|
|
|
- )
|
|
|
- .expect("Failed to write to bridgeline file");
|
|
|
- (cred, bridgeline)
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|