lox_cli/src/bin/lox_client.rs

127 lines
4.2 KiB
Rust

// 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<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() {
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
let lox_auth_pubkeys_filename = "lox_auth_pubkeys.json";
let lox_auth_pubkeys: Vec<IssuerPubKey> = 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;
}
}
}