commit cf86900
uint
·
2026-03-12 16:37:41 +0000 UTC
parent 363bc86
add auth_delay
6 files changed,
+74,
-0
+6,
-0
1@@ -38,6 +38,12 @@ Credentials are provided using the
2 header.
3 .Pp
4 If no users are configured, authentication is disabled.
5+.Pp
6+If
7+.Ic auth_delay
8+is configured in
9+.Xr parados.conf 5 ,
10+unauthorized responses may be intentionally delayed.
11 .Sh ENDPOINTS
12 .Bl -tag -width Ds
13 .It Pa /ping
+18,
-0
1@@ -123,6 +123,23 @@ Example:
2 .Bd -literal -offset indent
3 max_clients=64
4 .Ed
5+.It Ic auth_delay
6+Delay (in ms) before returning
7+.Dv 401 Unauthorized
8+responses.
9+.Pp
10+This can slow down brute force login attempts.
11+.Pp
12+Valid values are non-negative integers 0..
13+.Dv INT_MAX .
14+A value of
15+.Cm 0
16+disables the delay.
17+.Pp
18+Example:
19+.Bd -literal -offset indent
20+auth_delay=250
21+.Ed
22 .El
23 .Sh AUTHENTICATION
24 Authentication entries are specified using repeated groups
25@@ -192,6 +209,7 @@ server_addr=127.0.0.1
26 server_port=8088
27 verbose_log=true
28 cors_origin=
29+auth_delay=0
30 .Ed
31 .Pp
32 Two users with separate access:
+5,
-0
1@@ -58,6 +58,11 @@ max_clients=64
2
3 # *Authentication*
4
5+# Delay (in ms) before returning 401 Unauthorized.
6+# Can help slow down brute force login attempts.
7+# 0 disables delay.
8+auth_delay=250
9+
10 # Each entry consists of one `user`, `pass`, and (multiple) `allow` directives.
11 # Multiple users are permitted.
12 #
+22,
-0
1@@ -1,3 +1,4 @@
2+#include <limits.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6@@ -20,6 +21,7 @@ bool verbose_log = true;
7 char cors_origin[1024] = "";
8 int http_io_timeout = 5;
9 int max_clients = 64;
10+int auth_delay = 250;
11
12 static int load_path(const char* path)
13 {
14@@ -155,6 +157,23 @@ static int set_kv(const char* k, const char* v)
15 return 0;
16 }
17
18+ if (strcmp(k, "auth_delay") == 0) {
19+ char* end = NULL;
20+ long n = strtol(v, &end, 10);
21+
22+ if (end == v || *end != '\0') {
23+ LOG(true, "CONF", "Config Error %s invalid integer '%s'", k, v);
24+ return -1;
25+ }
26+ if (n < 0 || n > INT_MAX) {
27+ LOG(true, "CONF", "Config Error auth_delay out of bounds (0..%d)", INT_MAX);
28+ return -1;
29+ }
30+
31+ auth_delay = (int)n;
32+ return 0;
33+ }
34+
35 /* auth */
36 if (strcmp(k, "user") == 0) {
37 int r = users_push(v);
38@@ -227,6 +246,7 @@ log:
39 char port[8];
40 char tmo[16];
41 char maxc[16];
42+ char adly[16];
43
44 LOG(true, "CONF", "Config File %s", path);
45 LOG(true, "CONF", "Media Directory %s", media_dir);
46@@ -239,6 +259,8 @@ log:
47 LOG(true, "CONF", "HTTP IO Timeout %s", tmo);
48 snprintf(maxc, sizeof(maxc), "%d", max_clients);
49 LOG(true, "CONF", "Max Clients %s", maxc);
50+ snprintf(adly, sizeof(adly), "%d", auth_delay);
51+ LOG(true, "CONF", "Auth Delay %s (ms)", adly);
52
53 return;
54 }
+22,
-0
1@@ -21,6 +21,7 @@
2 #include "users.h"
3 #include "util.h"
4
5+static void auth_delay_sleep(void);
6 static int cors_build(char* out, size_t outsz, const char* hdr, int preflight);
7 static const struct item* find_item(uint64_t id);
8 static int item_path_for_id(char out[4096], uint64_t id, const struct user* u);
9@@ -39,6 +40,25 @@ static int stream_file(int c, const struct item* it, const char* hdr, int head_o
10 extern struct library lib;
11 extern mtx_t lib_lock;
12
13+static void auth_delay_sleep(void)
14+{
15+ if (auth_delay <= 0)
16+ return;
17+
18+ struct timespec req;
19+ struct timespec rem;
20+
21+ /* convert ms to timespec */
22+ req.tv_sec = auth_delay / 1000;
23+ req.tv_nsec = (long)(auth_delay % 1000) * 1000000L;
24+
25+ while (nanosleep(&req, &rem) < 0) {
26+ if (errno != EINTR)
27+ break;
28+ req = rem;
29+ }
30+}
31+
32 static int cors_origin_allowed(const char* origin)
33 {
34 if (cors_origin[0] == '\0')
35@@ -430,6 +450,8 @@ static void reply_unauth(int c, const char* hdr, int send_body)
36 const char* body = "unauthorized\n";
37 size_t blen = strlen(body);
38
39+ auth_delay_sleep();
40+
41 reply(
42 c, hdr,
43 "HTTP/1.1 401 Unauthorized\r\n",
+1,
-0
1@@ -10,6 +10,7 @@ extern bool verbose_log;
2 extern int server_port;
3 extern int http_io_timeout;
4 extern int max_clients;
5+extern int auth_delay;
6
7 /*
8 Load configuration and populate global settings