From d2bd91e0feb4b7030c9f2e52ce1768680c70fa64 Mon Sep 17 00:00:00 2001 From: onyinyang Date: Tue, 4 Apr 2023 19:34:35 -0400 Subject: [PATCH] Update bridgeline sizes to match lox library --- crates/lox-distributor/Cargo.toml | 2 +- crates/lox-distributor/src/lox_context.rs | 277 ++++++++++++++++++ crates/lox-distributor/src/main.rs | 340 +++------------------- 3 files changed, 321 insertions(+), 298 deletions(-) create mode 100644 crates/lox-distributor/src/lox_context.rs diff --git a/crates/lox-distributor/Cargo.toml b/crates/lox-distributor/Cargo.toml index 7b41d7f..334f891 100644 --- a/crates/lox-distributor/Cargo.toml +++ b/crates/lox-distributor/Cargo.toml @@ -17,4 +17,4 @@ serde_with = "1.9.1" serde_json = "1.0.87" lox = { git = "https://gitlab.torproject.org/onyinyang/lox.git"} -rdsys_backend = { git = "https://gitlab.torproject.org/cohosh/rdsys-backend-api.git"} +rdsys_backend = { git = "https://gitlab.torproject.org/onyinyang/rdsys-backend-api.git"} diff --git a/crates/lox-distributor/src/lox_context.rs b/crates/lox-distributor/src/lox_context.rs new file mode 100644 index 0000000..212b754 --- /dev/null +++ b/crates/lox-distributor/src/lox_context.rs @@ -0,0 +1,277 @@ + +use hyper::{ + body::Bytes, + header::HeaderValue, + Body, Response, +}; + +use lox::{ + BridgeAuth, BridgeDb, OPENINV_LENGTH, + bridge_table::{BridgeLine, ENC_BUCKET_BYTES}, + proto::{ + blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite, + redeem_invite, trust_promotion, + }, + IssuerPubKey, +}; +use rand::RngCore; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use std::{ + sync::{Arc, Mutex}, +}; + + +#[serde_as] +#[derive(Serialize, Deserialize)] +pub struct Invite { + #[serde_as(as = "[_; OPENINV_LENGTH]")] + invite: [u8; OPENINV_LENGTH], +} + +#[serde_as] +#[derive(Serialize, Deserialize)] +pub struct EncBridgeTable { + #[serde_as(as = "Vec<[_; ENC_BUCKET_BYTES]>")] + etable: Vec<[u8; ENC_BUCKET_BYTES]>, +} + +/// Create a random BridgeLine for testing ONLY. Do not use in production! +/// This was copied directly from lox/src/bridge_table.rs in order +/// to easily initialize a bridgedb/lox_auth with structurally +/// correct buckets to be used for Lox requests/verifications/responses. +/// In production, existing bridges should be translated into this format +/// in a private function and sorted into buckets (3 bridges/bucket is suggested +/// but experience may suggest something else) in some intelligent way. + +pub fn random() -> BridgeLine { + let mut rng = rand::thread_rng(); + let mut res: BridgeLine = BridgeLine::default(); + // Pick a random 4-byte address + let mut addr: [u8; 4] = [0; 4]; + rng.fill_bytes(&mut addr); + // If the leading byte is 224 or more, that's not a valid IPv4 + // address. Choose an IPv6 address instead (but don't worry too + // much about it being well formed). + if addr[0] >= 224 { + rng.fill_bytes(&mut res.addr); + } else { + // Store an IPv4 address as a v4-mapped IPv6 address + res.addr[10] = 255; + res.addr[11] = 255; + res.addr[12..16].copy_from_slice(&addr); + }; + let ports: [u16; 4] = [443, 4433, 8080, 43079]; + let portidx = (rng.next_u32() % 4) as usize; + res.port = ports[portidx]; + res.uid_fingerprint = rng.next_u64(); + let mut cert: [u8; 52] = [0; 52]; + rng.fill_bytes(&mut cert); + let infostr: String = format!( + "obfs4 cert={}, iat-mode=0", + base64::encode_config(cert, base64::STANDARD_NO_PAD) + ); + res.info[..infostr.len()].copy_from_slice(infostr.as_bytes()); + res +} + +#[derive(Clone)] +pub struct LoxServerContext { + pub db: Arc>, + pub ba: Arc>, +} + +impl LoxServerContext { + pub fn add_openinv_bucket(&self, bucket: [BridgeLine; 3]) { + let mut ba_obj = self.ba.lock().unwrap(); + let mut db_obj = self.db.lock().unwrap(); + ba_obj.add_openinv_bridges(bucket, &mut db_obj); + } + + pub fn add_unreachable(&self, bridgeline: BridgeLine) -> bool { + let mut ba_obj = self.ba.lock().unwrap(); + let mut db_obj = self.db.lock().unwrap(); + ba_obj.bridge_unreachable(&bridgeline, &mut db_obj) + } + + pub fn update_bridge(&self, bridgeline: BridgeLine) -> bool { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.bridge_update(&bridgeline) + } + + fn advance_days_TEST(&self, num: u16) { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.advance_days(num); // FOR TESTING ONLY + println!("Today's date according to server: {}", ba_obj.today()); + } + + pub fn encrypt_table(&self) -> Vec<[u8; ENC_BUCKET_BYTES]> { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.enc_bridge_table().clone() + } + + fn pubkeys(&self) -> Vec { + let ba_obj = self.ba.lock().unwrap(); + // vector of public keys (to serialize) + vec![ + ba_obj.lox_pub.clone(), + ba_obj.migration_pub.clone(), + ba_obj.migrationkey_pub.clone(), + ba_obj.reachability_pub.clone(), + ba_obj.invitation_pub.clone(), + ] + } + + fn gen_invite(&self) -> Invite { + let obj = self.db.lock().unwrap(); + Invite { + invite: obj.invite(), + } + } + + fn open_inv(&self, req: open_invite::Request) -> open_invite::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_open_invite(req).unwrap() + } + + fn trust_promo(&self, req: trust_promotion::Request) -> trust_promotion::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_trust_promotion(req).unwrap() + } + + fn trust_migration(&self, req: migration::Request) -> migration::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_migration(req).unwrap() + } + + fn level_up(&self, req: level_up::Request) -> level_up::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_level_up(req).unwrap() + } + + fn issue_invite(&self, req: issue_invite::Request) -> issue_invite::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_issue_invite(req).unwrap() + } + + fn redeem_invite(&self, req: redeem_invite::Request) -> redeem_invite::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_redeem_invite(req).unwrap() + } + + fn check_blockage(&self, req: check_blockage::Request) -> check_blockage::Response { + let mut ba_obj = self.ba.lock().unwrap(); + // Created 5 buckets initially, so we will add 5 hot spares (for migration) and + // block all of the existing buckets to trigger migration table propagation + // FOR TESTING ONLY, ADD 5 NEW Buckets + for _ in 0..5 { + let bucket = [random(), random(), random()]; + ba_obj.add_spare_bucket(bucket); + } + ba_obj.enc_bridge_table(); + + // FOR TESTING ONLY, BLOCK ALL BRIDGES + let mut db_obj = self.db.lock().unwrap(); + for index in 0..5 { + let b0 = ba_obj.bridge_table.buckets[index][0]; + let b1 = ba_obj.bridge_table.buckets[index][1]; + let b2 = ba_obj.bridge_table.buckets[index][2]; + ba_obj.bridge_unreachable(&b0, &mut db_obj); + ba_obj.bridge_unreachable(&b1, &mut db_obj); + ba_obj.bridge_unreachable(&b2, &mut db_obj); + } + ba_obj.enc_bridge_table(); + ba_obj.handle_check_blockage(req).unwrap() + } + + fn blockage_migration(&self, req: blockage_migration::Request) -> blockage_migration::Response { + let mut ba_obj = self.ba.lock().unwrap(); + ba_obj.handle_blockage_migration(req).unwrap() + } +} + +// Generate and return an open invitation token +pub fn generate_invite(context: LoxServerContext) -> Response { + let invite = context.gen_invite(); + let token = serde_json::to_string(&invite).unwrap(); + prepare_header(token) +} + +// Return the serialized encrypted bridge table +pub fn send_reachability_cred(context: LoxServerContext) -> Response { + context.advance_days_TEST(85); // FOR TESTING ONLY + let enc_table = context.encrypt_table(); + let etable = EncBridgeTable { etable: enc_table }; + prepare_header(serde_json::to_string(&etable).unwrap()) +} + +// Return the serialized pubkeys for the Bridge Authority +pub fn send_keys(context: LoxServerContext) -> Response { + let pubkeys = context.pubkeys(); + prepare_header(serde_json::to_string(&pubkeys).unwrap()) +} + +pub fn verify_and_send_open_cred(request: Bytes, context: LoxServerContext) -> Response { + let req: open_invite::Request = serde_json::from_slice(&request).unwrap(); + let response = context.open_inv(req); + let open_invite_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(open_invite_resp_str) +} + +pub fn verify_and_send_trust_promo(request: Bytes, context: LoxServerContext) -> Response { + let req: trust_promotion::Request = serde_json::from_slice(&request).unwrap(); + context.advance_days_TEST(31); // FOR TESTING ONLY + let response = context.trust_promo(req); + let trust_promo_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(trust_promo_resp_str) +} + +pub fn verify_and_send_trust_migration(request: Bytes, context: LoxServerContext) -> Response { + let req: migration::Request = serde_json::from_slice(&request).unwrap(); + let response = context.trust_migration(req); + let resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(resp_str) +} + +pub fn verify_and_send_level_up(request: Bytes, context: LoxServerContext) -> Response { + let req: level_up::Request = serde_json::from_slice(&request).unwrap(); + let response = context.level_up(req); + let level_up_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(level_up_resp_str) +} + +pub fn verify_and_send_issue_invite(request: Bytes, context: LoxServerContext) -> Response { + let req: issue_invite::Request = serde_json::from_slice(&request).unwrap(); + let response = context.issue_invite(req); + let issue_invite_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(issue_invite_resp_str) +} + +pub fn verify_and_send_redeem_invite(request: Bytes, context: LoxServerContext) -> Response { + let req: redeem_invite::Request = serde_json::from_slice(&request).unwrap(); + let response = context.redeem_invite(req); + let redeem_invite_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(redeem_invite_resp_str) +} + +pub fn verify_and_send_check_blockage(request: Bytes, context: LoxServerContext) -> Response { + let req: check_blockage::Request = serde_json::from_slice(&request).unwrap(); + + let response = context.check_blockage(req); + let check_blockage_resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(check_blockage_resp_str) +} + +pub fn verify_and_send_blockage_migration(request: Bytes, context: LoxServerContext) -> Response { + let req: blockage_migration::Request = serde_json::from_slice(&request).unwrap(); + let response = context.blockage_migration(req); + let resp_str = serde_json::to_string(&response).unwrap(); + prepare_header(resp_str) +} + +fn prepare_header(response: String) -> Response { + let mut resp = Response::new(Body::from(response)); + resp.headers_mut() + .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*")); + resp +} \ No newline at end of file diff --git a/crates/lox-distributor/src/main.rs b/crates/lox-distributor/src/main.rs index 91d3abb..5b66f61 100644 --- a/crates/lox-distributor/src/main.rs +++ b/crates/lox-distributor/src/main.rs @@ -2,25 +2,17 @@ use futures::future; use futures::StreamExt; use hyper::{ body, - body::Bytes, header::HeaderValue, server::conn::AddrStream, service::{make_service_fn, service_fn}, Body, Method, Request, Response, Server, StatusCode, }; -use lox::bridge_table::{BridgeLine, BRIDGE_BYTES, ENC_BUCKET_BYTES}; -use lox::{ - proto::{ - blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite, - redeem_invite, trust_promotion, - }, - IssuerPubKey, -}; -use lox::{BridgeAuth, BridgeDb, OPENINV_LENGTH}; -use rand::RngCore; +use lox::bridge_table::{BridgeLine, BRIDGE_BYTES}; + +use lox::{BridgeAuth, BridgeDb}; + use rdsys_backend::{proto::ResourceDiff, start_stream}; -use serde::{Deserialize, Serialize}; -use serde_with::serde_as; +use serde::{Deserialize}; use std::{ convert::Infallible, env, @@ -31,191 +23,15 @@ use std::{ time::Duration, }; +mod lox_context; +use lox_context::LoxServerContext; + use tokio::{ signal, spawn, sync::{broadcast, mpsc, oneshot}, time::sleep, }; -#[serde_as] -#[derive(Serialize, Deserialize)] -pub struct Invite { - #[serde_as(as = "[_; OPENINV_LENGTH]")] - invite: [u8; OPENINV_LENGTH], -} - -#[serde_as] -#[derive(Serialize, Deserialize)] -pub struct EncBridgeTable { - #[serde_as(as = "Vec<[_; ENC_BUCKET_BYTES]>")] - etable: Vec<[u8; ENC_BUCKET_BYTES]>, -} - -#[derive(Debug, Deserialize)] -struct ResourceInfo { - endpoint: String, - name: String, - token: String, - types: Vec, -} -// Populate Bridgedb from rdsys - -/// Create a random BridgeLine for testing ONLY. Do not use in production! -/// This was copied directly from lox/src/bridge_table.rs in order -/// to easily initialize a bridgedb/lox_auth with structurally -/// correct buckets to be used for Lox requests/verifications/responses. -/// In production, existing bridges should be translated into this format -/// in a private function and sorted into buckets (3 bridges/bucket is suggested -/// but experience may suggest something else) in some intelligent way. - -pub fn random() -> BridgeLine { - let mut rng = rand::thread_rng(); - let mut res: BridgeLine = BridgeLine::default(); - // Pick a random 4-byte address - let mut addr: [u8; 4] = [0; 4]; - rng.fill_bytes(&mut addr); - // If the leading byte is 224 or more, that's not a valid IPv4 - // address. Choose an IPv6 address instead (but don't worry too - // much about it being well formed). - if addr[0] >= 224 { - rng.fill_bytes(&mut res.addr); - } else { - // Store an IPv4 address as a v4-mapped IPv6 address - res.addr[10] = 255; - res.addr[11] = 255; - res.addr[12..16].copy_from_slice(&addr); - }; - let ports: [u16; 4] = [443, 4433, 8080, 43079]; - let portidx = (rng.next_u32() % 4) as usize; - res.port = ports[portidx]; - let mut fingerprint: [u8; 20] = [0; 20]; - let mut cert: [u8; 52] = [0; 52]; - rng.fill_bytes(&mut fingerprint); - rng.fill_bytes(&mut cert); - let infostr: String = format!( - "obfs4 {} cert={} iat-mode=0", - hex_fmt::HexFmt(fingerprint), - base64::encode_config(cert, base64::STANDARD_NO_PAD) - ); - res.info[..infostr.len()].copy_from_slice(infostr.as_bytes()); - res -} - -#[derive(Clone)] -struct LoxServerContext { - db: Arc>, - ba: Arc>, -} - -impl LoxServerContext { - fn add_openinv_bucket(&self, bucket: [BridgeLine; 3]) { - let mut ba_obj = self.ba.lock().unwrap(); - let mut db_obj = self.db.lock().unwrap(); - ba_obj.add_openinv_bridges(bucket, &mut db_obj); - } - - fn add_unreachable(&self, bridgeline: BridgeLine) -> bool { - let mut ba_obj = self.ba.lock().unwrap(); - let mut db_obj = self.db.lock().unwrap(); - ba_obj.bridge_unreachable(&bridgeline, &mut db_obj) - } - - fn update_bridge(&self, bridgeline: BridgeLine) -> bool { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.bridge_update(&bridgeline) - } - - fn advance_days_TEST(&self, num: u16) { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.advance_days(num); // FOR TESTING ONLY - println!("Today's date according to server: {}", ba_obj.today()); - } - - fn encrypt_table(&self) -> Vec<[u8; ENC_BUCKET_BYTES]> { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.enc_bridge_table().clone() - } - - fn pubkeys(&self) -> Vec { - let ba_obj = self.ba.lock().unwrap(); - // vector of public keys (to serialize) - vec![ - ba_obj.lox_pub.clone(), - ba_obj.migration_pub.clone(), - ba_obj.migrationkey_pub.clone(), - ba_obj.reachability_pub.clone(), - ba_obj.invitation_pub.clone(), - ] - } - - fn gen_invite(&self) -> Invite { - let obj = self.db.lock().unwrap(); - Invite { - invite: obj.invite(), - } - } - - fn open_inv(&self, req: open_invite::Request) -> open_invite::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_open_invite(req).unwrap() - } - - fn trust_promo(&self, req: trust_promotion::Request) -> trust_promotion::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_trust_promotion(req).unwrap() - } - - fn trust_migration(&self, req: migration::Request) -> migration::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_migration(req).unwrap() - } - - fn level_up(&self, req: level_up::Request) -> level_up::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_level_up(req).unwrap() - } - - fn issue_invite(&self, req: issue_invite::Request) -> issue_invite::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_issue_invite(req).unwrap() - } - - fn redeem_invite(&self, req: redeem_invite::Request) -> redeem_invite::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_redeem_invite(req).unwrap() - } - - fn check_blockage(&self, req: check_blockage::Request) -> check_blockage::Response { - let mut ba_obj = self.ba.lock().unwrap(); - // Created 5 buckets initially, so we will add 5 hot spares (for migration) and - // block all of the existing buckets to trigger migration table propagation - // FOR TESTING ONLY, ADD 5 NEW Buckets - for _ in 0..5 { - let bucket = [random(), random(), random()]; - ba_obj.add_spare_bucket(bucket); - } - ba_obj.enc_bridge_table(); - - // FOR TESTING ONLY, BLOCK ALL BRIDGES - let mut db_obj = self.db.lock().unwrap(); - for index in 0..5 { - let b0 = ba_obj.bridge_table.buckets[index][0]; - let b1 = ba_obj.bridge_table.buckets[index][1]; - let b2 = ba_obj.bridge_table.buckets[index][2]; - ba_obj.bridge_unreachable(&b0, &mut db_obj); - ba_obj.bridge_unreachable(&b1, &mut db_obj); - ba_obj.bridge_unreachable(&b2, &mut db_obj); - } - ba_obj.enc_bridge_table(); - ba_obj.handle_check_blockage(req).unwrap() - } - - fn blockage_migration(&self, req: blockage_migration::Request) -> blockage_migration::Response { - let mut ba_obj = self.ba.lock().unwrap(); - ba_obj.handle_blockage_migration(req).unwrap() - } -} - // Lox Request handling logic for each Lox request/protocol async fn handle( cloned_context: LoxServerContext, @@ -231,43 +47,43 @@ async fn handle( .body(Body::from("Allow POST")) .unwrap()), _ => match (req.method(), req.uri().path()) { - (&Method::POST, "/invite") => Ok::<_, Infallible>(generate_invite(cloned_context)), + (&Method::POST, "/invite") => Ok::<_, Infallible>(lox_context::generate_invite(cloned_context)), (&Method::POST, "/reachability") => { - Ok::<_, Infallible>(send_reachability_cred(cloned_context)) + Ok::<_, Infallible>(lox_context::send_reachability_cred(cloned_context)) } - (&Method::POST, "/pubkeys") => Ok::<_, Infallible>(send_keys(cloned_context)), + (&Method::POST, "/pubkeys") => Ok::<_, Infallible>(lox_context::send_keys(cloned_context)), (&Method::POST, "/openreq") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_open_cred(bytes, cloned_context) + lox_context::verify_and_send_open_cred(bytes, cloned_context) }), (&Method::POST, "/trustpromo") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_trust_promo(bytes, cloned_context) + lox_context::verify_and_send_trust_promo(bytes, cloned_context) }), (&Method::POST, "/trustmig") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_trust_migration(bytes, cloned_context) + lox_context::verify_and_send_trust_migration(bytes, cloned_context) }), (&Method::POST, "/levelup") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_level_up(bytes, cloned_context) + lox_context::verify_and_send_level_up(bytes, cloned_context) }), (&Method::POST, "/issueinvite") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_issue_invite(bytes, cloned_context) + lox_context::verify_and_send_issue_invite(bytes, cloned_context) }), (&Method::POST, "/redeem") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_redeem_invite(bytes, cloned_context) + lox_context::verify_and_send_redeem_invite(bytes, cloned_context) }), (&Method::POST, "/checkblockage") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); // TEST ONLY: Block all existing bridges and add new ones for migration - verify_and_send_check_blockage(bytes, cloned_context) + lox_context::verify_and_send_check_blockage(bytes, cloned_context) }), (&Method::POST, "/blockagemigration") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); - verify_and_send_blockage_migration(bytes, cloned_context) + lox_context::verify_and_send_blockage_migration(bytes, cloned_context) }), _ => { // Return 404 not found response. @@ -280,92 +96,6 @@ async fn handle( } } -// Generate and return an open invitation token -fn generate_invite(context: LoxServerContext) -> Response { - let invite = context.gen_invite(); - let token = serde_json::to_string(&invite).unwrap(); - prepare_header(token) -} - -// Return the serialized encrypted bridge table -fn send_reachability_cred(context: LoxServerContext) -> Response { - context.advance_days_TEST(85); // FOR TESTING ONLY - let enc_table = context.encrypt_table(); - let etable = EncBridgeTable { etable: enc_table }; - prepare_header(serde_json::to_string(&etable).unwrap()) -} - -// Return the serialized pubkeys for the Bridge Authority -fn send_keys(context: LoxServerContext) -> Response { - let pubkeys = context.pubkeys(); - prepare_header(serde_json::to_string(&pubkeys).unwrap()) -} - -fn verify_and_send_open_cred(request: Bytes, context: LoxServerContext) -> Response { - let req: open_invite::Request = serde_json::from_slice(&request).unwrap(); - let response = context.open_inv(req); - let open_invite_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(open_invite_resp_str) -} - -fn verify_and_send_trust_promo(request: Bytes, context: LoxServerContext) -> Response { - let req: trust_promotion::Request = serde_json::from_slice(&request).unwrap(); - context.advance_days_TEST(31); // FOR TESTING ONLY - let response = context.trust_promo(req); - let trust_promo_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(trust_promo_resp_str) -} - -fn verify_and_send_trust_migration(request: Bytes, context: LoxServerContext) -> Response { - let req: migration::Request = serde_json::from_slice(&request).unwrap(); - let response = context.trust_migration(req); - let resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(resp_str) -} - -fn verify_and_send_level_up(request: Bytes, context: LoxServerContext) -> Response { - let req: level_up::Request = serde_json::from_slice(&request).unwrap(); - let response = context.level_up(req); - let level_up_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(level_up_resp_str) -} - -fn verify_and_send_issue_invite(request: Bytes, context: LoxServerContext) -> Response { - let req: issue_invite::Request = serde_json::from_slice(&request).unwrap(); - let response = context.issue_invite(req); - let issue_invite_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(issue_invite_resp_str) -} - -fn verify_and_send_redeem_invite(request: Bytes, context: LoxServerContext) -> Response { - let req: redeem_invite::Request = serde_json::from_slice(&request).unwrap(); - let response = context.redeem_invite(req); - let redeem_invite_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(redeem_invite_resp_str) -} - -fn verify_and_send_check_blockage(request: Bytes, context: LoxServerContext) -> Response { - let req: check_blockage::Request = serde_json::from_slice(&request).unwrap(); - - let response = context.check_blockage(req); - let check_blockage_resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(check_blockage_resp_str) -} - -fn verify_and_send_blockage_migration(request: Bytes, context: LoxServerContext) -> Response { - let req: blockage_migration::Request = serde_json::from_slice(&request).unwrap(); - let response = context.blockage_migration(req); - let resp_str = serde_json::to_string(&response).unwrap(); - prepare_header(resp_str) -} - -fn prepare_header(response: String) -> Response { - let mut resp = Response::new(Body::from(response)); - resp.headers_mut() - .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*")); - resp -} - async fn shutdown_signal() { tokio::signal::ctrl_c() .await @@ -373,6 +103,16 @@ async fn shutdown_signal() { println!("Shut down Lox Server"); } + +#[derive(Debug, Deserialize)] +struct ResourceInfo { + endpoint: String, + name: String, + token: String, + types: Vec, +} +// Populate Bridgedb from rdsys + // Rdsys sender creates a ResourceStream with the api_endpoint, resource token and type specified // in the config.json file. // TODO: ensure this stream gracefully shutdowns on the ctrl_c command. @@ -439,7 +179,7 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { let bridgedb = BridgeDb::new(); let lox_auth = BridgeAuth::new(bridgedb.pubkey); - let context = LoxServerContext { + let context = lox_context::LoxServerContext { db: Arc::new(Mutex::new(bridgedb)), ba: Arc::new(Mutex::new(lox_auth)), }; @@ -459,11 +199,13 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { ]; let mut count = 0; for resource in pt.1 { + let test = resource.get_uid().unwrap(); let mut ip_bytes: [u8; 16] = [0; 16]; ip_bytes[..resource.address.len()] .copy_from_slice(resource.address.as_bytes()); + let resource_uid = resource.get_uid().expect("Unable to get Fingerprint UID of resource"); let infostr: String = format!( - "type={} blocked_in={:?} protocol={} fingerprint={} or_addresses={:?} distribution={} flags={:?} params={:?}", + "type={} blocked_in={:?} protocol={} fingerprint={:?} or_addresses={:?} distribution={} flags={:?} params={:?}", resource.r#type, resource.blocked_in, resource.protocol, @@ -473,15 +215,15 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { resource.flags, resource.params, ); - let mut info_bytes: [u8; BRIDGE_BYTES - 18] = [0; BRIDGE_BYTES - 18]; + let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26]; info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes()); let bridgeline = BridgeLine { addr: ip_bytes, port: resource.port, + uid_fingerprint: resource_uid, info: info_bytes, }; - println!("Now it's a bridgeline: {:?}", bridgeline); if count < 2 { bucket[count] = bridgeline; @@ -505,8 +247,9 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { let mut ip_bytes: [u8; 16] = [0; 16]; ip_bytes[..resource.address.len()] .copy_from_slice(resource.address.as_bytes()); + let resource_uid = resource.get_uid().expect("Unable to get Fingerprint UID of resource"); let infostr: String = format!( - "type={} blocked_in={:?} protocol={} fingerprint={} or_addresses={:?} distribution={} flags={:?} params={:?}", + "type={} blocked_in={:?} protocol={} fingerprint= {:?} or_addresses={:?} distribution={} flags={:?} params={:?}", resource.r#type, resource.blocked_in, resource.protocol, @@ -516,12 +259,13 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { resource.flags, resource.params, ); - let mut info_bytes: [u8; BRIDGE_BYTES - 18] = [0; BRIDGE_BYTES - 18]; + let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26]; info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes()); let bridgeline = BridgeLine { addr: ip_bytes, port: resource.port, + uid_fingerprint: resource_uid, info: info_bytes, }; @@ -543,8 +287,9 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { let mut ip_bytes: [u8; 16] = [0; 16]; ip_bytes[..resource.address.len()] .copy_from_slice(resource.address.as_bytes()); + let resource_uid = resource.get_uid().expect("Unable to get Fingerprint UID of resource"); let infostr: String = format!( - "type={} blocked_in={:?} protocol={} fingerprint={} or_addresses={:?} distribution={} flags={:?} params={:?}", + "type={} blocked_in={:?} protocol={} fingerprint={:?} or_addresses={:?} distribution={} flags={:?} params={:?}", resource.r#type, resource.blocked_in, resource.protocol, @@ -554,12 +299,13 @@ async fn context_manager(mut context_rx: mpsc::Receiver) { resource.flags, resource.params, ); - let mut info_bytes: [u8; BRIDGE_BYTES - 18] = [0; BRIDGE_BYTES - 18]; + let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26]; info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes()); let bridgeline = BridgeLine { addr: ip_bytes, port: resource.port, + uid_fingerprint: resource_uid, info: info_bytes, };