mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-03-25 07:57:53 +00:00
Compare commits
3 Commits
dependabot
...
feat/lockd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb86fff0e4 | ||
|
|
6b0d804ba3 | ||
|
|
f9b1aeb23e |
@@ -21,8 +21,11 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// hard-defaults, may make configurable in the future if needed,
|
||||||
|
// but for now these are just safety limits to prevent unbounded memory usage
|
||||||
const MaxOAuthPendingSessions = 256
|
const MaxOAuthPendingSessions = 256
|
||||||
const OAuthCleanupCount = 16
|
const OAuthCleanupCount = 16
|
||||||
|
const MaxLoginAttemptRecords = 256
|
||||||
|
|
||||||
type OAuthPendingSession struct {
|
type OAuthPendingSession struct {
|
||||||
State string
|
State string
|
||||||
@@ -43,6 +46,11 @@ type LoginAttempt struct {
|
|||||||
LockedUntil time.Time
|
LockedUntil time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Lockdown struct {
|
||||||
|
Active bool
|
||||||
|
ActiveUntil time.Time
|
||||||
|
}
|
||||||
|
|
||||||
type AuthServiceConfig struct {
|
type AuthServiceConfig struct {
|
||||||
Users []config.User
|
Users []config.User
|
||||||
OauthWhitelist []string
|
OauthWhitelist []string
|
||||||
@@ -69,6 +77,7 @@ type AuthService struct {
|
|||||||
ldap *LdapService
|
ldap *LdapService
|
||||||
queries *repository.Queries
|
queries *repository.Queries
|
||||||
oauthBroker *OAuthBrokerService
|
oauthBroker *OAuthBrokerService
|
||||||
|
lockdown *Lockdown
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, queries *repository.Queries, oauthBroker *OAuthBrokerService) *AuthService {
|
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, queries *repository.Queries, oauthBroker *OAuthBrokerService) *AuthService {
|
||||||
@@ -202,6 +211,11 @@ func (auth *AuthService) IsAccountLocked(identifier string) (bool, int) {
|
|||||||
auth.loginMutex.RLock()
|
auth.loginMutex.RLock()
|
||||||
defer auth.loginMutex.RUnlock()
|
defer auth.loginMutex.RUnlock()
|
||||||
|
|
||||||
|
if auth.lockdown != nil && auth.lockdown.Active {
|
||||||
|
remaining := int(time.Until(auth.lockdown.ActiveUntil).Seconds())
|
||||||
|
return true, remaining
|
||||||
|
}
|
||||||
|
|
||||||
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
||||||
return false, 0
|
return false, 0
|
||||||
}
|
}
|
||||||
@@ -227,6 +241,14 @@ func (auth *AuthService) RecordLoginAttempt(identifier string, success bool) {
|
|||||||
auth.loginMutex.Lock()
|
auth.loginMutex.Lock()
|
||||||
defer auth.loginMutex.Unlock()
|
defer auth.loginMutex.Unlock()
|
||||||
|
|
||||||
|
if len(auth.loginAttempts) >= MaxLoginAttemptRecords {
|
||||||
|
if auth.lockdown != nil && auth.lockdown.Active {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go auth.lockdownMode()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
attempt, exists := auth.loginAttempts[identifier]
|
attempt, exists := auth.loginAttempts[identifier]
|
||||||
if !exists {
|
if !exists {
|
||||||
attempt = &LoginAttempt{}
|
attempt = &LoginAttempt{}
|
||||||
@@ -746,3 +768,31 @@ func (auth *AuthService) ensureOAuthSessionLimit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (auth *AuthService) lockdownMode() {
|
||||||
|
auth.loginMutex.Lock()
|
||||||
|
|
||||||
|
tlog.App.Warn().Msg("Multiple login attempts detected, possibly DDOS attack. Activating temporary lockdown.")
|
||||||
|
|
||||||
|
auth.lockdown = &Lockdown{
|
||||||
|
Active: true,
|
||||||
|
ActiveUntil: time.Now().Add(time.Duration(auth.config.LoginTimeout) * time.Second),
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point all login attemps will also expire so,
|
||||||
|
// we might as well clear them to free up memory
|
||||||
|
auth.loginAttempts = make(map[string]*LoginAttempt)
|
||||||
|
|
||||||
|
timer := time.NewTimer(time.Until(auth.lockdown.ActiveUntil))
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
|
auth.loginMutex.Unlock()
|
||||||
|
|
||||||
|
<-timer.C
|
||||||
|
|
||||||
|
auth.loginMutex.Lock()
|
||||||
|
|
||||||
|
tlog.App.Info().Msg("Lockdown period ended, resuming normal operation")
|
||||||
|
auth.lockdown = nil
|
||||||
|
auth.loginMutex.Unlock()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user