From b7d0a83ac40bbcf9831e0ff3102b9a874616d39a Mon Sep 17 00:00:00 2001
From: Bob Mottram <bob@freedombone.net>
Date: Wed, 9 Jun 2021 11:09:28 +0100
Subject: [PATCH] Extra delay between failed login attempts

---
 daemon.py | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/daemon.py b/daemon.py
index 5ac2b315e..4dd7ea4a5 100644
--- a/daemon.py
+++ b/daemon.py
@@ -1370,6 +1370,13 @@ class PubServer(BaseHTTPRequestHandler):
                      debug: bool) -> None:
         """Shows the login screen
         """
+        # ensure that there is a minimum delay between failed login
+        # attempts, to mitigate brute force
+        if int(time.time()) - self.server.lastLoginAttempt < 5:
+            self._503()
+            self.server.POSTbusy = False
+            return
+
         # get the contents of POST containing login credentials
         length = int(self.headers['Content-length'])
         if length > 512:
@@ -1435,6 +1442,7 @@ class PubServer(BaseHTTPRequestHandler):
                                   authHeader, False):
                 print('Login failed: ' + loginNickname)
                 self._clearLoginDetails(loginNickname, callingDomain)
+                self.server.lastLoginAttempt = int(time.time())
                 self.server.POSTbusy = False
                 return
             else:
@@ -15088,6 +15096,7 @@ def runDaemon(city: str,
     httpd.maxQueueLength = 64
     httpd.allowDeletion = allowDeletion
     httpd.lastLoginTime = 0
+    httpd.lastLoginAttempt = 0
     httpd.maxReplies = maxReplies
     httpd.tokens = {}
     httpd.tokensLookup = {}