pub struct LoginLimiter { /* private fields */ }Expand description
Fixed-window failed-login counter, keyed by client address.
In-process on purpose: it protects a listener that defaults to loopback and holds a handful of accounts, and a database-backed counter would add a write to the very path being flooded.
Implementations§
Source§impl LoginLimiter
impl LoginLimiter
pub fn new(max_attempts: u32, window_seconds: u64) -> Self
Sourcepub fn rebuilt(&self, max_attempts: u32, window_seconds: u64) -> Self
pub fn rebuilt(&self, max_attempts: u32, window_seconds: u64) -> Self
The same counters under new limits.
A configuration reload rebuilds the admin router, and with it every value
AdminState derives from [admin] — which for this type would mean
starting from an empty map. That is a security regression, not a cosmetic
one: a reload in the middle of a brute-force attempt would clear the
attacker’s backoff, and admin.login_* is exactly the sort of key an
operator edits because they are being flooded.
Carrying the whole limiter across instead would be the other error,
leaving login_max_attempts and login_window_seconds silently stale.
So the counters move and the limits do not.
Sourcepub fn check(&self, client: Option<IpAddr>) -> Result<(), u64>
pub fn check(&self, client: Option<IpAddr>) -> Result<(), u64>
Whether this address may attempt a login now. Err carries the seconds
left in the window.
Called before the password hash runs: 600 000 iterations is a denial-of-service lever, so a limited caller must not pay it — nor make the server pay it.
Sourcepub fn record_failure(&self, client: Option<IpAddr>)
pub fn record_failure(&self, client: Option<IpAddr>)
Records a failed attempt.
Sourcepub fn record_success(&self, client: Option<IpAddr>)
pub fn record_success(&self, client: Option<IpAddr>)
Clears an address’s counter after a successful login, so one operator fumbling their password does not spend the window for the next.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for LoginLimiter
impl RefUnwindSafe for LoginLimiter
impl Send for LoginLimiter
impl Sync for LoginLimiter
impl Unpin for LoginLimiter
impl UnsafeUnpin for LoginLimiter
impl UnwindSafe for LoginLimiter
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more