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

1
Cargo.lock generated

@ -231,6 +231,7 @@ dependencies = [
"lazy_static", "lazy_static",
"log", "log",
"pretty_env_logger", "pretty_env_logger",
"serde",
"tokio", "tokio",
"uuid", "uuid",
"warp", "warp",

@ -26,6 +26,7 @@ futures = "0.3.8"
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"
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"]}
warp = "0.2.5" warp = "0.2.5"

@ -1,5 +1,6 @@
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_imports)]
#[macro_use] extern crate log; #[macro_use] extern crate log;
@ -15,6 +16,10 @@ use futures::{
prelude::*, prelude::*,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use serde::{
Serialize,
Deserialize,
};
fn install() -> eyre::Result<()> fn install() -> eyre::Result<()>
{ {

@ -12,10 +12,19 @@ impl str::FromStr for Sha256Hash
} }
} }
pub async fn auth_req(who: source::IpAddr, state: Arc<state::State>) -> Result<(), Infallible> #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuthRequest
{
id: uuid::Uuid,
sign_this: [u8; 32],
salt: [u8; 16],
passwd_is_allowed: bool,
}
pub async fn auth_req(who: source::IpAddr, state: Arc<state::State>) -> Result<AuthRequest, Infallible>
{ {
Ok(()) todo!()
} }
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>

@ -39,10 +39,14 @@ pub async fn main(state: server::state::ServerState, cfg: settings::Settings) ->
.and(warp::header("X-Forwarded-For")) .and(warp::header("X-Forwarded-For"))
.map(source::extract(cfg.trust_x_forwarded_for)) .map(source::extract(cfg.trust_x_forwarded_for))
.and_then(|req: Result<std::net::IpAddr, _>| async move {req.map_err(warp::reject::custom)}); .and_then(|req: Result<std::net::IpAddr, _>| async move {req.map_err(warp::reject::custom)});
// /auth/req - Request an auth ID and information about how to respond (data to sign / password salt / what is supported, etc)
// /auth/resp/<req_id>/pw/<passwd hash> - Respond to an auth ID with a hashed password, salted with the salt obtained from the req call.
// /auth/resp/<req_id>/si[/<num of sigs in body>] - Respond to an auth ID with one or more signatures of the data to be signed obtained in the auth request. If no number is provided, 1 is assumed.
let auth = { let auth = {
let req = warp::path("req") let req = warp::path("req")
.and(client_ip.clone()).and(state.clone()); //TODO .and(client_ip.clone()).and(state.clone())
.and_then(auth::auth_req);
let resp = { let resp = {
let resp_auth_with_state = warp::post() let resp_auth_with_state = warp::post()
@ -51,7 +55,9 @@ pub async fn main(state: server::state::ServerState, cfg: settings::Settings) ->
let resp_auth_key = resp_auth_with_state.clone() let resp_auth_key = resp_auth_with_state.clone()
.and(warp::path("si") .and(warp::path("si")
.and(warp::path::param().map(|num: usize| std::cmp::max(1, num)) .and(warp::path::param().map(|num: usize| std::cmp::min(std::cmp::max(1,
num),
cfg.max_key_sigs_per_auth_response))
.or(warp::path::end().map(|| 1usize)).unify())) .or(warp::path::end().map(|| 1usize)).unify()))
.and(warp::body::content_length_limit(cfg.max_body_len.0)) .and(warp::body::content_length_limit(cfg.max_body_len.0))
.and(warp::body::bytes()) .and(warp::body::bytes())
@ -59,21 +65,29 @@ pub async fn main(state: server::state::ServerState, cfg: settings::Settings) ->
// -- Paths -- // -- Paths --
let resp_auth_pass = resp_auth_with_state let resp_auth_pass = {
.and(warp::path::param().map(|hash: auth::Sha256Hash| hash.0)) let pw_path = resp_auth_with_state
.and_then(auth::auth_pass); .and(warp::path("pw"));
if cfg.allow_passwd_auth {
pw_path.and(warp::path::param().map(|hash: auth::Sha256Hash| hash.0))
.and(warp::path::end())
.and_then(auth::auth_pass).boxed()
} else {
pw_path.and_then(|_addr, _state, _hash| async move {Err(warp::reject::reject())}).boxed()
}
};
let resp = warp::path("resp") let resp = warp::path("resp")
.and(resp_auth_key .and(resp_auth_key
.or(resp_auth_pass)); .or(resp_auth_pass));
// /resp/<req_id>/pw/<passwd hash> // /resp/<req_id>/pw/<passwd hash>
// /resp/<req_id>/si[/<num of sigs in body>] // /resp/<req_id>/si[/<num of sigs in body>]
resp resp
}; };
warp::path("auth").and(req) warp::path("auth").and(req.or(resp))
}; };
todo!() todo!()

@ -12,6 +12,14 @@ pub struct Settings
/// First is max body len for auth responses, 2nd is for data. /// First is max body len for auth responses, 2nd is for data.
pub max_body_len: (u64, u64), pub max_body_len: (u64, u64),
pub trust_x_forwarded_for: bool, pub trust_x_forwarded_for: bool,
pub allow_passwd_auth: bool,
pub max_key_sigs_per_auth_response: usize,
/// How long is an auth request ID is valid.
pub auth_req_ttl_millis: u64,
/// How long is an authentication token valid for an action.
pub auth_token_ttl_millis: u64,
} }
impl Default for Settings impl Default for Settings
@ -22,6 +30,12 @@ impl Default for Settings
Self { Self {
max_body_len: (DEFAULT_MAX_BODY_LEN_ARESP, DEFAULT_MAX_BODY_LEN), max_body_len: (DEFAULT_MAX_BODY_LEN_ARESP, DEFAULT_MAX_BODY_LEN),
trust_x_forwarded_for: false, trust_x_forwarded_for: false,
allow_passwd_auth: true,
max_key_sigs_per_auth_response: 16,
auth_req_ttl_millis: 5000, //5 s
auth_token_ttl_millis: 60 * 2000, //2 m
} }
} }
} }

Loading…
Cancel
Save