]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: delay_until can optionally now have +<max random secs> suffix.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Jun 2016 20:56:18 +0000 (23:56 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Jun 2016 20:56:18 +0000 (23:56 +0300)
src/auth/auth-request.c

index 072622d7c1e9b89dd038ae411335c6c529181bec..3b32b405dcdf8fec98a610c6782fc65a426552fe 100644 (file)
@@ -1691,10 +1691,24 @@ void auth_request_set_field(struct auth_request *request,
                request->failed = TRUE;
        } else if (strcmp(name, "delay_until") == 0) {
                time_t timestamp;
+               unsigned int extra_secs = 0;
+               const char *p;
 
+               p = strchr(value, '+');
+               if (p != NULL) {
+                       value = t_strdup_until(value, p++);
+                       if (str_to_uint(p, &extra_secs) < 0) {
+                               auth_request_log_error(request, AUTH_SUBSYS_DB,
+                                       "Invalid delay_until randomness number '%s'", p);
+                               request->failed = TRUE;
+                       } else {
+                               extra_secs = rand() % extra_secs;
+                       }
+               }
                if (str_to_time(value, &timestamp) < 0) {
                        auth_request_log_error(request, AUTH_SUBSYS_DB,
                                "Invalid delay_until timestamp '%s'", value);
+                       request->failed = TRUE;
                } else if (timestamp <= ioloop_time) {
                        /* no more delays */
                } else if (timestamp - ioloop_time > AUTH_REQUEST_MAX_DELAY_SECS) {
@@ -1702,6 +1716,10 @@ void auth_request_set_field(struct auth_request *request,
                                "delay_until timestamp %s is too much in the future, failing", value);
                        request->failed = TRUE;
                } else {
+                       /* add randomness, but not too much of it */
+                       timestamp += extra_secs;
+                       if (timestamp - ioloop_time > AUTH_REQUEST_MAX_DELAY_SECS)
+                               timestamp = ioloop_time + AUTH_REQUEST_MAX_DELAY_SECS;
                        request->delay_until = timestamp;
                }
        } else if (strcmp(name, "allow_real_nets") == 0) {