master
Avril 4 years ago
parent 41ae60efeb
commit ea431f4190
Signed by: flanchan
GPG Key ID: 284488987C31F630

19
Cargo.lock generated

@ -209,7 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cfc491baaffd7cbd6acc02ebd23564760d83a2c17e1a47e6a04a8d5a86e7fb5" checksum = "2cfc491baaffd7cbd6acc02ebd23564760d83a2c17e1a47e6a04a8d5a86e7fb5"
dependencies = [ dependencies = [
"crc", "crc",
"getrandom", "getrandom 0.1.15",
"hex-literal", "hex-literal",
"hmac", "hmac",
"libc", "libc",
@ -228,9 +228,11 @@ dependencies = [
"color-eyre", "color-eyre",
"cryptohelpers", "cryptohelpers",
"futures", "futures",
"getrandom 0.2.0",
"lazy_static", "lazy_static",
"log", "log",
"pretty_env_logger", "pretty_env_logger",
"rand 0.7.3",
"serde", "serde",
"tokio", "tokio",
"uuid", "uuid",
@ -468,6 +470,17 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "getrandom"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4"
dependencies = [
"cfg-if 0.1.10",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.23.0" version = "0.23.0"
@ -1052,7 +1065,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.1.15",
"libc", "libc",
"rand_chacha 0.2.2", "rand_chacha 0.2.2",
"rand_core 0.5.1", "rand_core 0.5.1",
@ -1100,7 +1113,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.1.15",
] ]
[[package]] [[package]]

@ -23,9 +23,11 @@ client = []
color-eyre = {version = "0.5", default-features=false} color-eyre = {version = "0.5", default-features=false}
cryptohelpers = {version = "1.5.1", features= ["sha256", "rsa", "serde"]} cryptohelpers = {version = "1.5.1", features= ["sha256", "rsa", "serde"]}
futures = "0.3.8" futures = "0.3.8"
getrandom = "0.2.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
log = "0.4.11" log = "0.4.11"
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
rand = "0.7.3"
serde = {version = "1.0", features = ["derive"]} serde = {version = "1.0", features = ["derive"]}
tokio = {version = "0.2", features = ["full"]} tokio = {version = "0.2", features = ["full"]}
uuid = {version = "0.8.1", features = ["v4","serde"]} uuid = {version = "0.8.1", features = ["v4","serde"]}

@ -0,0 +1,32 @@
//! Extensions
use super::*;
pub trait Tuple2MapExt<T>
{
fn map<F, U>(self, fun: F) -> (U, U)
where F: FnMut(T) -> U;
}
impl<T> Tuple2MapExt<T> for (T,T)
{
fn map<F, U>(self, mut fun: F) -> (U, U)
where F: FnMut(T) -> U
{
(fun(self.0), fun(self.1))
}
}
pub trait JitterExt<T>
{
/// Produce a random value between `self.0` and `self.1` inclusive
fn jitter(self) -> T;
}
impl<T> JitterExt<T> for (T, T)
where T: rand::distributions::uniform::SampleUniform
{
fn jitter(self) -> T
{
util::jitter(self.0, self.1)
}
}

@ -16,6 +16,7 @@ use futures::{
prelude::*, prelude::*,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use getrandom::getrandom;
use serde::{ use serde::{
Serialize, Serialize,
Deserialize, Deserialize,
@ -30,6 +31,10 @@ fn install() -> eyre::Result<()>
Ok(()) Ok(())
} }
mod ext;
use ext::*;
mod util;
mod args; mod args;
#[cfg(feature="server")] mod server; #[cfg(feature="server")] mod server;

@ -12,29 +12,54 @@ impl str::FromStr for Sha256Hash
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct AuthRequest pub struct AuthRequest
{ {
id: uuid::Uuid, id: uuid::Uuid,
sign_this: [u8; 32], sign_this: [u8; 32],
salt: [u8; 16], salt: [u8; 16],
passwd_is_allowed: bool, passwd_is_allowed: bool,
ttl_ms: u64
}
impl AuthRequest
{
/// Create a new auth request
pub fn new(cfg: &settings::Settings) -> Self
{
let mut empty = Self {
id: uuid::Uuid::new_v4(),
sign_this: [0; 32],
salt: [0;16],
passwd_is_allowed: cfg.allow_passwd_auth,
ttl_ms: cfg.auth_req_ttl_millis.jitter(),
};
getrandom(&mut empty.sign_this[..]).expect("fatal rng");
getrandom(&mut empty.salt[..]).expect("fatal rng");
empty
}
} }
pub async fn auth_req(who: source::IpAddr, state: Arc<state::State>) -> Result<AuthRequest, Infallible> pub async fn auth_req(who: source::IpAddr, state: Arc<state::State>) -> Result<AuthRequest, Infallible>
{ {
let req = AuthRequest::new(state.cfg());
trace!("{:?} auth req", who);
todo!() // TODO: Add `req` into `state` somehow for later.
// TODO: Use `DelayQueue` to remove `req.id` from the hashmap after `ttl` expires.
Ok(req)
} }
pub async fn auth_key(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, num: usize, body: Bytes) -> Result<(), Infallible> pub async fn auth_key(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, num: usize, body: Bytes) -> Result<(), Infallible>
{ {
trace!("{:?} auth resp key <{}>:{}", who, req_id, num);
Ok(()) Ok(())
} }
pub async fn auth_pass(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, passhash: sha256::Sha256Hash) -> Result<(), Infallible> pub async fn auth_pass(who: source::IpAddr, state: Arc<state::State>, req_id: uuid::Uuid, passhash: sha256::Sha256Hash) -> Result<(), Infallible>
{ {
trace!("{:?} auth resp pass <{}>: \"{}\"", who, req_id, passhash);
Ok(()) Ok(())
} }

@ -74,7 +74,7 @@ pub async fn main(state: server::state::ServerState, cfg: settings::Settings) ->
.and(warp::path::end()) .and(warp::path::end())
.and_then(auth::auth_pass).boxed() .and_then(auth::auth_pass).boxed()
} else { } else {
pw_path.and_then(|_addr, _state, _hash| async move {Err(warp::reject::reject())}).boxed() pw_path.and_then(|_addr, _state, _hash| async move {Err(warp::reject::not_found())}).boxed()
} }
}; };

@ -17,9 +17,13 @@ pub struct Settings
pub max_key_sigs_per_auth_response: usize, pub max_key_sigs_per_auth_response: usize,
/// How long is an auth request ID is valid. /// How long is an auth request ID is valid.
pub auth_req_ttl_millis: u64, ///
/// A random value between these two bounds is selected
pub auth_req_ttl_millis: (u64, u64),
/// How long is an authentication token valid for an action. /// How long is an authentication token valid for an action.
pub auth_token_ttl_millis: u64, ///
/// A random value between these two bounds is selected
pub auth_token_ttl_millis: (u64, u64),
} }
impl Default for Settings impl Default for Settings
@ -34,8 +38,8 @@ impl Default for Settings
allow_passwd_auth: true, allow_passwd_auth: true,
max_key_sigs_per_auth_response: 16, max_key_sigs_per_auth_response: 16,
auth_req_ttl_millis: 5000, //5 s auth_req_ttl_millis: (4000, 6000), //4s - 6s
auth_token_ttl_millis: 60 * 2000, //2 m auth_token_ttl_millis: (1500, 2500).map(|x| x * 60), // 1.5m - 2.5m
} }
} }
} }

@ -15,6 +15,7 @@ pub struct State
impl State impl State
{ {
/// Create state from a backend state and server settings
pub fn new(backend: server::state::ServerState, settings: settings::Settings) -> Self pub fn new(backend: server::state::ServerState, settings: settings::Settings) -> Self
{ {
Self { Self {
@ -23,6 +24,7 @@ impl State
} }
} }
/// The web server settings
pub fn cfg(&self) -> &settings::Settings pub fn cfg(&self) -> &settings::Settings
{ {
&self.settings &self.settings

@ -0,0 +1,14 @@
//! Utils
/// Get a random value between these two inclusive
pub fn jitter<T>(min: T, max: T) -> T
where T: rand::distributions::uniform::SampleUniform
{
use rand::Rng;
let mut thread = rand::thread_rng();
let dist = rand::distributions::Uniform::new_inclusive(min, max);
thread.sample(dist)
}
Loading…
Cancel
Save