Browse Source

add time to ping hash

master
Jonathan Cobb 4 years ago
parent
commit
fc137ea007
2 changed files with 49 additions and 10 deletions
  1. +25
    -7
      src/ping.rs
  2. +24
    -3
      src/proxy.rs

+ 25
- 7
src/ping.rs View File

@@ -7,6 +7,7 @@
extern crate rand; extern crate rand;


use std::sync::Arc; use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};


use rand::Rng; use rand::Rng;
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
@@ -17,32 +18,49 @@ use sha2::{Sha256, Digest};


#[derive(Debug, Deserialize, Serialize, Clone)] #[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Ping { pub struct Ping {
time : u128,
salt : String, salt : String,
hash : String hash : String
} }


const MAX_PING_AGE: i64 = 30000;
const MIN_PING_AGE: i64 = -5000;

impl Ping { impl Ping {
pub fn new (auth_token : Arc<String>) -> Ping { pub fn new (auth_token : Arc<String>) -> Ping {
let salt = rand::thread_rng() let salt = rand::thread_rng()
.sample_iter(&Alphanumeric) .sample_iter(&Alphanumeric)
.take(30)
.take(50)
.collect::<String>(); .collect::<String>();
let hash = hash_token_with_salt(auth_token, &salt);
Ping { salt, hash }
let time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let hash = hash_token_with_salt(auth_token, time, &salt);
Ping { time, salt, hash }
} }


pub fn verify(&self, auth_token : Arc<String>) -> bool { pub fn verify(&self, auth_token : Arc<String>) -> bool {
let hash = hash_token_with_salt(auth_token, &self.salt);
eprintln!("Ping.verify: INFO: comparing provided hash={} with calculated hash={}", self.hash, hash);
self.hash.eq(&hash)
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis();
let age : i64 = (now - self.time) as i64;
return if age > MAX_PING_AGE {
eprintln!("Ping.verify: ERROR: ping was too old");
false
} else if age < MIN_PING_AGE {
eprintln!("Ping.verify: ERROR: ping was too young");
false
} else {
let hash = hash_token_with_salt(auth_token, self.time, &self.salt);
eprintln!("Ping.verify: INFO: comparing provided hash={} with calculated hash={}", self.hash, hash);
self.hash.eq(&hash)
}
} }


} }


fn hash_token_with_salt(auth_token: Arc<String>, salt: &String) -> String {
fn hash_token_with_salt(auth_token: Arc<String>, time : u128, salt: &String) -> String {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(salt.as_bytes()); hasher.update(salt.as_bytes());
hasher.update(b":"); hasher.update(b":");
hasher.update(time.to_string());
hasher.update(b":");
hasher.update(auth_token.to_string()); hasher.update(auth_token.to_string());
let digest = hasher.finalize(); let digest = hasher.finalize();
let hash = hex::encode(digest); let hash = hex::encode(digest);


+ 24
- 3
src/proxy.rs View File

@@ -82,6 +82,8 @@ pub async fn start_proxy (dns1_ip : &str,
eprintln!("start_proxy: INFO Proxy await result: {:?}", result); eprintln!("start_proxy: INFO Proxy await result: {:?}", result);
} }


const HEADER_FLEX_AUTH: &'static str = "X-Bubble-Flex-Auth";

async fn proxy(client: Client<HttpsConnector<HttpConnector<CacheResolver>>>, async fn proxy(client: Client<HttpsConnector<HttpConnector<CacheResolver>>>,
gateway: Arc<String>, gateway: Arc<String>,
resolver: Arc<TokioAsyncResolver>, resolver: Arc<TokioAsyncResolver>,
@@ -97,8 +99,8 @@ async fn proxy(client: Client<HttpsConnector<HttpConnector<CacheResolver>>>,
let ping : Ping = serde_json::from_str(body.as_str()).unwrap(); let ping : Ping = serde_json::from_str(body.as_str()).unwrap();
eprintln!("proxy: INFO: received body: {:?}", ping); eprintln!("proxy: INFO: received body: {:?}", ping);
if !ping.verify(auth_token.clone()) { if !ping.verify(auth_token.clone()) {
eprintln!("proxy: INFO: ping hash not valid");
bad_request("ping hash not valid")
eprintln!("proxy: ERROR: invalid ping hash");
bad_request("invalid ping hash")
} else { } else {
let pong = Ping::new(auth_token.clone()); let pong = Ping::new(auth_token.clone());
let pong_json = serde_json::to_string(&pong).unwrap(); let pong_json = serde_json::to_string(&pong).unwrap();
@@ -106,9 +108,28 @@ async fn proxy(client: Client<HttpsConnector<HttpConnector<CacheResolver>>>,
} }
} else { } else {
eprintln!("proxy: ERROR: no host"); eprintln!("proxy: ERROR: no host");
bad_request("No host!")
bad_request("No host")
} }
} }

let headers = req.headers();
let flex_auth_header = headers.get(HEADER_FLEX_AUTH);
if flex_auth_header.is_none() {
eprintln!("proxy: ERROR: no auth");
return bad_request("No auth");
}
let flex_auth = flex_auth_header.unwrap().to_str();
if flex_auth.is_err() {
eprintln!("proxy: ERROR: auth not found");
return bad_request("auth not found");
}

let auth : Ping = serde_json::from_str(flex_auth.unwrap().to_string().as_str()).unwrap();
if !auth.verify(auth_token.clone()) {
eprintln!("proxy: ERROR: invalid auth");
return bad_request("invalid auth");
}

let host = host.unwrap(); let host = host.unwrap();
let ip_string = resolve_with_cache(host, &resolver, resolver_cache).await; let ip_string = resolve_with_cache(host, &resolver, resolver_cache).await;
eprintln!("proxy: INFO req(host {} resolved to: {}): {:?}", host, ip_string, req); eprintln!("proxy: INFO req(host {} resolved to: {}): {:?}", host, ip_string, req);


Loading…
Cancel
Save