Add checkblockage test with changes to lox_context
This commit is contained in:
parent
e7db9e7151
commit
e1f7cda652
|
@ -9,48 +9,8 @@ use lox::{
|
|||
BridgeAuth, BridgeDb, IssuerPubKey,
|
||||
};
|
||||
use lox_utils;
|
||||
use rand::RngCore;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// 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<Mutex<BridgeDb>>,
|
||||
|
@ -129,7 +89,7 @@ impl LoxServerContext {
|
|||
#[cfg(test)]
|
||||
/// For testing only: manually advance the day by the given number
|
||||
/// of days.
|
||||
pub fn advance_days_TEST(&self, num: u16) {
|
||||
pub 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());
|
||||
|
@ -191,26 +151,6 @@ impl LoxServerContext {
|
|||
|
||||
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()
|
||||
}
|
||||
|
||||
|
@ -287,7 +227,6 @@ pub fn verify_and_send_redeem_invite(request: Bytes, context: LoxServerContext)
|
|||
|
||||
pub fn verify_and_send_check_blockage(request: Bytes, context: LoxServerContext) -> Response<Body> {
|
||||
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)
|
||||
|
|
|
@ -8,7 +8,6 @@ pub async fn handle(
|
|||
cloned_context: LoxServerContext,
|
||||
req: Request<Body>,
|
||||
) -> Result<Response<Body>, Infallible> {
|
||||
println!("Request: {:?}", req);
|
||||
match req.method() {
|
||||
&Method::OPTIONS => Ok(Response::builder()
|
||||
.header("Access-Control-Allow-Origin", HeaderValue::from_static("*"))
|
||||
|
@ -77,8 +76,13 @@ mod tests {
|
|||
|
||||
use chrono::{Duration, Utc};
|
||||
use julianday::JulianDay;
|
||||
use lox::{cred::BucketReachability, proto, BridgeAuth, BridgeDb};
|
||||
use lox::{
|
||||
bridge_table::{self, BridgeLine},
|
||||
cred::BucketReachability,
|
||||
proto, BridgeAuth, BridgeDb,
|
||||
};
|
||||
use lox_utils;
|
||||
use rand::RngCore;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
trait LoxClient {
|
||||
|
@ -91,6 +95,8 @@ mod tests {
|
|||
fn levelup(&self, request: proto::level_up::Request) -> Request<Body>;
|
||||
fn issueinvite(&self, request: proto::issue_invite::Request) -> Request<Body>;
|
||||
fn redeeminvite(&self, request: proto::redeem_invite::Request) -> Request<Body>;
|
||||
fn checkblockage(&self, request: proto::check_blockage::Request) -> Request<Body>;
|
||||
fn blockagemigration(&self, request: proto::blockage_migration::Request) -> Request<Body>;
|
||||
}
|
||||
|
||||
struct LoxClientMock {}
|
||||
|
@ -166,7 +172,6 @@ mod tests {
|
|||
req
|
||||
}
|
||||
|
||||
|
||||
fn issueinvite(&self, request: proto::issue_invite::Request) -> Request<Body> {
|
||||
let req_str = serde_json::to_string(&request).unwrap();
|
||||
let req = Request::builder()
|
||||
|
@ -188,6 +193,28 @@ mod tests {
|
|||
.unwrap();
|
||||
req
|
||||
}
|
||||
|
||||
fn checkblockage(&self, request: proto::check_blockage::Request) -> Request<Body> {
|
||||
let req_str = serde_json::to_string(&request).unwrap();
|
||||
let req = Request::builder()
|
||||
.header("Content-Type", "application/json")
|
||||
.method("POST")
|
||||
.uri("http://localhost/checkblockage")
|
||||
.body(Body::from(req_str))
|
||||
.unwrap();
|
||||
req
|
||||
}
|
||||
|
||||
fn blockagemigration(&self, request: proto::blockage_migration::Request) -> Request<Body> {
|
||||
let req_str = serde_json::to_string(&request).unwrap();
|
||||
let req = Request::builder()
|
||||
.header("Content-Type", "application/json")
|
||||
.method("POST")
|
||||
.uri("http://localhost/blockagemigration")
|
||||
.body(Body::from(req_str))
|
||||
.unwrap();
|
||||
req
|
||||
}
|
||||
}
|
||||
|
||||
struct TestHarness {
|
||||
|
@ -201,21 +228,13 @@ mod tests {
|
|||
|
||||
// Make 3 x num_buckets open invitation bridges, in sets of 3
|
||||
for _ in 0..5 {
|
||||
let bucket = [
|
||||
lox_context::random(),
|
||||
lox_context::random(),
|
||||
lox_context::random(),
|
||||
];
|
||||
let bucket = [random(), random(), random()];
|
||||
lox_auth.add_openinv_bridges(bucket, &mut bridgedb);
|
||||
}
|
||||
|
||||
// Add hot_spare more hot spare buckets
|
||||
for _ in 0..5 {
|
||||
let bucket = [
|
||||
lox_context::random(),
|
||||
lox_context::random(),
|
||||
lox_context::random(),
|
||||
];
|
||||
let bucket = [random(), random(), random()];
|
||||
lox_auth.add_spare_bucket(bucket);
|
||||
}
|
||||
// Create the encrypted bridge table
|
||||
|
@ -230,8 +249,65 @@ mod tests {
|
|||
}
|
||||
|
||||
fn advance_days(&mut self, days: u16) {
|
||||
self.context.advance_days_TEST(days)
|
||||
self.context.advance_days_test(days)
|
||||
}
|
||||
|
||||
fn simulate_blocking(&mut self, cred: lox::cred::Lox) -> (lox::cred::Lox, u32, [u8; 16]) {
|
||||
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
|
||||
let mut bdb = self.context.db.lock().unwrap();
|
||||
let mut lox_auth = self.context.ba.lock().unwrap();
|
||||
let encbuckets = lox_auth.enc_bridge_table();
|
||||
let bucket =
|
||||
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize])
|
||||
.unwrap();
|
||||
assert!(bucket.1.is_some());
|
||||
// Block two of our bridges
|
||||
lox_auth.bridge_unreachable(&bucket.0[0], &mut bdb);
|
||||
lox_auth.bridge_unreachable(&bucket.0[2], &mut bdb);
|
||||
|
||||
(cred, id, key)
|
||||
}
|
||||
|
||||
fn prep_next_day(&mut self, id: u32, key: [u8; 16]) {
|
||||
let mut lox_auth = self.context.ba.lock().unwrap();
|
||||
let encbuckets2 = lox_auth.enc_bridge_table();
|
||||
let bucket2 =
|
||||
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets2[id as usize])
|
||||
.unwrap();
|
||||
// We should no longer have a Bridge Reachability credential
|
||||
assert!(bucket2.1.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// This should only be used for testing, use today in production
|
||||
|
@ -379,10 +455,7 @@ mod tests {
|
|||
test_today(31 + 14),
|
||||
) {
|
||||
Ok(level_up_result) => level_up_result,
|
||||
Err(e) => panic!(
|
||||
"Error: Proof error from level up {:?}",
|
||||
e.to_string()
|
||||
),
|
||||
Err(e) => panic!("Error: Proof error from level up {:?}", e.to_string()),
|
||||
};
|
||||
let level_up_request = lc.levelup(level_up_result.0);
|
||||
let level_up_response = handle(th.context.clone(), level_up_request).await.unwrap();
|
||||
|
@ -421,8 +494,9 @@ mod tests {
|
|||
),
|
||||
};
|
||||
let issue_invite_request = lc.issueinvite(issue_invite_result.0);
|
||||
let issue_invite_response = handle(th.context.clone(), issue_invite_request).await.unwrap();
|
||||
println!("Server response?: {:?}", issue_invite_response);
|
||||
let issue_invite_response = handle(th.context.clone(), issue_invite_request)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(issue_invite_response.status(), StatusCode::OK);
|
||||
|
||||
// Test Redeem Invite
|
||||
|
@ -443,16 +517,12 @@ mod tests {
|
|||
test_today(31 + 14),
|
||||
) {
|
||||
Ok(new_invite) => new_invite,
|
||||
Err(e) => panic!(
|
||||
"Error: Proof error from level up {:?}",
|
||||
e.to_string()
|
||||
),
|
||||
Err(e) => panic!("Error: Proof error from level up {:?}", e.to_string()),
|
||||
};
|
||||
let new_redeem_invite_request = lc.redeeminvite(new_invite.0);
|
||||
let new_redeem_invite_response = handle(th.context.clone(), new_redeem_invite_request)
|
||||
.await
|
||||
.unwrap();
|
||||
println!("Server response?: {:?}", new_redeem_invite_response);
|
||||
assert_eq!(new_redeem_invite_response.status(), StatusCode::OK);
|
||||
let redeemed_cred_resp = body_to_string(new_redeem_invite_response).await;
|
||||
let redeemed_cred_resp_obj = serde_json::from_str(&redeemed_cred_resp).unwrap();
|
||||
|
@ -469,5 +539,84 @@ mod tests {
|
|||
),
|
||||
};
|
||||
|
||||
//Test Check Blockage
|
||||
th.advance_days(28); // First advance most recent credential to level 3
|
||||
let new_reachability_request = lc.reachability();
|
||||
let new_reachability_response = handle(th.context.clone(), new_reachability_request)
|
||||
.await
|
||||
.unwrap();
|
||||
let encrypted_table = body_to_string(new_reachability_response).await;
|
||||
let reachability_cred: BucketReachability =
|
||||
lox_utils::generate_reachability_cred(&issue_invite_cred.0, encrypted_table);
|
||||
let level_three_request = match proto::level_up::request(
|
||||
&issue_invite_cred.0,
|
||||
&reachability_cred,
|
||||
&pubkeys_obj.lox_pub,
|
||||
&pubkeys_obj.reachability_pub,
|
||||
test_today(31 + 14 + 28),
|
||||
) {
|
||||
Ok(level_three_request) => level_three_request,
|
||||
Err(e) => panic!("Error: Proof error from level up to 3 {:?}", e.to_string()),
|
||||
};
|
||||
let level_three_req = lc.levelup(level_three_request.0);
|
||||
let level_three_response = handle(th.context.clone(), level_three_req).await.unwrap();
|
||||
assert_eq!(level_three_response.status(), StatusCode::OK);
|
||||
let levelup_resp = body_to_string(level_three_response).await;
|
||||
let levelup_response_obj = serde_json::from_str(&levelup_resp).unwrap();
|
||||
let level_three_cred = match lox::proto::level_up::handle_response(
|
||||
level_three_request.1,
|
||||
levelup_response_obj,
|
||||
&pubkeys_obj.lox_pub,
|
||||
) {
|
||||
Ok(level_three_cred) => level_three_cred,
|
||||
Err(e) => panic!("Error: Level two credential error {:?}", e.to_string()),
|
||||
};
|
||||
// Simulate blocking event
|
||||
let passed_level_three_cred = th.simulate_blocking(level_three_cred);
|
||||
th.advance_days(1);
|
||||
th.prep_next_day(passed_level_three_cred.1, passed_level_three_cred.2);
|
||||
|
||||
let migration_cred_request = match proto::check_blockage::request(
|
||||
&passed_level_three_cred.0,
|
||||
&pubkeys_obj.lox_pub,
|
||||
) {
|
||||
Ok(migration_cred_request) => migration_cred_request,
|
||||
Err(e) => panic!("Error: Proof error from level up to 3 {:?}", e.to_string()),
|
||||
};
|
||||
let migration_cred_req = lc.checkblockage(migration_cred_request.0);
|
||||
let migration_cred_response = handle(th.context.clone(), migration_cred_req)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(migration_cred_response.status(), StatusCode::OK);
|
||||
|
||||
// Test Blockage Migration
|
||||
let migration_resp = body_to_string(migration_cred_response).await;
|
||||
let migration_response_obj = serde_json::from_str(&migration_resp).unwrap();
|
||||
let mig_cred = match lox::proto::check_blockage::handle_response(
|
||||
migration_cred_request.1,
|
||||
migration_response_obj,
|
||||
) {
|
||||
Ok(mig_cred) => mig_cred,
|
||||
Err(e) => panic!("Error: Migration token error {:?}", e.to_string()),
|
||||
};
|
||||
let migration_result = match proto::blockage_migration::request(
|
||||
&passed_level_three_cred.0,
|
||||
&mig_cred,
|
||||
&pubkeys_obj.lox_pub,
|
||||
&pubkeys_obj.migration_pub,
|
||||
) {
|
||||
Ok(migration_result) => migration_result,
|
||||
Err(e) => panic!(
|
||||
"Error: Proof error from trust migration {:?}",
|
||||
e.to_string()
|
||||
),
|
||||
};
|
||||
let blockagemig_request = lc.blockagemigration(migration_result.0);
|
||||
let blockagemig_response = handle(th.context.clone(), blockagemig_request)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(blockagemig_response.status(), StatusCode::OK);
|
||||
|
||||
// Test Level up
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue