From f098fdc99de724f53f7f129b6a5bde50b73fd797 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Sun, 2 Dec 2018 13:52:23 +0100 Subject: request slowdown on login failure --- src/main.rs | 6 +++--- src/request_handler/handler_login.rs | 25 +++++++++++++++++++++++++ src/request_handler/mod.rs | 4 +++- src/request_handler/views.rs | 9 +++++++-- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index a025e69..6cdf77a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,4 @@ -#![feature(test)] -#![feature(duration_as_u128)] - +#![feature(test,integer_atomics,duration_as_u128)] use std::sync::Arc; use std::thread; use std::sync::atomic; @@ -50,6 +48,7 @@ pub struct ApplicationState { cookie_store: CookieStore, cookie_max_age: Duration, debug: bool, + request_slowdown: Arc, } #[derive(Debug, StructOpt)] @@ -72,6 +71,7 @@ fn main() { cookie_store: CookieStore::new(), cookie_max_age: Duration::days(1), debug: opt.debug, + request_slowdown: Arc::new(atomic::AtomicU64::new(0)), }; let server_shutdown_condvar = Arc::new(atomic::AtomicBool::new(false)); diff --git a/src/request_handler/handler_login.rs b/src/request_handler/handler_login.rs index aa93e96..ac0c37e 100644 --- a/src/request_handler/handler_login.rs +++ b/src/request_handler/handler_login.rs @@ -1,5 +1,9 @@ +use std::ops::Add; use std::io; use std::borrow::Cow; +use std::time; +use std::thread; +use std::sync::atomic; use tokio::prelude::*; @@ -36,6 +40,18 @@ fn test_secrets(secrets: &Vec<&str>, token: &String) -> bool { pub(in super) fn POST<'a>(header_infos: &HeaderExtract, state: &ApplicationState, req: &Request) -> Response { +let wait_until = state.request_slowdown.load(atomic::Ordering::Acquire); + let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_secs(); + + let slept = if wait_until > now { + let time = wait_until - now; + warn!("Sleep {}s", time); + thread::sleep(time::Duration::from_secs(time)); + time + } else { + 0 + }; + let mut token = None; let mut redirect = None; for (key, val) in form_urlencoded::parse(req.body()) { @@ -67,6 +83,15 @@ pub(in super) fn POST<'a>(header_infos: &HeaderExtract, state: &ApplicationState .header(SET_COOKIE, cookie.to_string()) .body(views::login_auth_success(&redirect)).unwrap() } else { + let current_wait = state.request_slowdown.load(atomic::Ordering::Acquire); + let wait_until = time::SystemTime::now() + .add(time::Duration::from_secs(8)) + .duration_since(time::UNIX_EPOCH).unwrap() + .as_secs(); + // if this request was already delayed then we double-delay + let wait_until = wait_until.max(current_wait + 8 + slept); + state.request_slowdown.store(wait_until, atomic::Ordering::Release); + Response::builder() .set_defaults() .body(views::login_auth_fail()).unwrap() diff --git a/src/request_handler/mod.rs b/src/request_handler/mod.rs index 6812bb4..ec62ba3 100644 --- a/src/request_handler/mod.rs +++ b/src/request_handler/mod.rs @@ -1,5 +1,6 @@ #![allow(warnings)] +use std::sync::atomic; use std::cell::Cell; use std::collections::HashMap; use std::io; @@ -121,7 +122,8 @@ fn info<'a>(request_handler: &RequestHandler, state: &super::ApplicationState, let valid_cookies: Vec<(String, String)> = state.cookie_store.reader .map_into(|k, v| (k.to_string(), ftime(v[0] as i64))); - views::info_debug(path_rest, valid_cookies) + views::info_debug(path_rest, valid_cookies, + state.request_slowdown.load(atomic::Ordering::Acquire)) } else { views::info(path_rest) }; diff --git a/src/request_handler/views.rs b/src/request_handler/views.rs index bdd7999..d2de163 100644 --- a/src/request_handler/views.rs +++ b/src/request_handler/views.rs @@ -17,7 +17,7 @@ fn render_base_template(title: &'static str, page_body: Box) -> Strin }).into_string().unwrap() } -pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String)>) -> String { +pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String)>, wait_until: u64) -> String { let path = path_rest.to_string(); render_base_template("Info (debug)", box_html! { h1(id = "heading") { @@ -32,7 +32,7 @@ pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String th: "Cookie value"; th: "Valid until"; } - tbody { + tbody { @ for (name, valid_until) in cookies { tr { td: name; @@ -41,6 +41,11 @@ pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String } } } + h2: "Request Slowdown"; + p { + : "Until: "; + : wait_until; + } }) } -- cgit v1.2.1