Download | Plain Text | No Line Numbers
- diff -Naur dovecot-2.2.21.orig/src/anvil/anvil-connection.c dovecot-2.2.21/src/anvil/anvil-connection.c
- --- dovecot-2.2.21.orig/src/anvil/anvil-connection.c 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/anvil/anvil-connection.c 2016-02-17 02:28:07.713478699 +0100
- @@ -109,18 +109,26 @@
- o_stream_nsend_str(conn->output,
- t_strdup_printf("%u %s\n", value, dec2str(stamp)));
- } else if (strcmp(cmd, "PENALTY-INC") == 0) {
- - if (args[0] == NULL || args[1] == NULL || args[2] == NULL) {
- + if (args[0] == NULL || args[1] == NULL) {
- *error_r = "PENALTY-INC: Not enough parameters";
- return -1;
- }
- - if (str_to_uint(args[1], &checksum) < 0 ||
- - str_to_uint(args[2], &value) < 0 ||
- - value > PENALTY_MAX_VALUE ||
- - (value == 0 && checksum != 0)) {
- + if (str_to_uint(args[1], &checksum) < 0) {
- *error_r = "PENALTY-INC: Invalid parameters";
- return -1;
- }
- - penalty_inc(penalty, args[0], checksum, value);
- + penalty_inc(penalty, args[0], checksum);
- + } else if (strcmp(cmd, "PENALTY-SET") == 0) {
- + if (args[0] == NULL) {
- + *error_r = "PENALTY-INC: Not enough parameters";
- + return -1;
- + }
- + if (str_to_uint(args[1], &value) < 0 ||
- + value > PENALTY_MAX_VALUE) {
- + *error_r = "PENALTY-SET: Invalid parameters";
- + return -1;
- + }
- + penalty_set(penalty, args[0], value);
- } else if (strcmp(cmd, "PENALTY-SET-EXPIRE-SECS") == 0) {
- if (args[0] == NULL || str_to_uint(args[0], &value) < 0) {
- *error_r = "PENALTY-SET-EXPIRE-SECS: "
- @@ -128,6 +136,14 @@
- return -1;
- }
- penalty_set_expire_secs(penalty, value);
- + } else if (strcmp(cmd, "PENALTY-SET-MAX-PENALTY") == 0) {
- + if (args[0] == NULL || str_to_uint(args[0], &value) < 0 ||
- + value > PENALTY_MAX_VALUE) {
- + *error_r = "PENALTY-SET-MAX-PENALTY: "
- + "Invalid parameters";
- + return -1;
- + }
- + penalty_set_max_penalty(penalty, value);
- } else if (strcmp(cmd, "PENALTY-DUMP") == 0) {
- penalty_dump(penalty, conn->output);
- } else {
- diff -Naur dovecot-2.2.21.orig/src/anvil/penalty.c dovecot-2.2.21/src/anvil/penalty.c
- --- dovecot-2.2.21.orig/src/anvil/penalty.c 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/anvil/penalty.c 2016-02-17 02:28:07.723478869 +0100
- @@ -16,6 +16,7 @@
- #include <time.h>
-
- #define PENALTY_DEFAULT_EXPIRE_SECS (60*60)
- +#define PENALTY_DEFAULT_MAX_PENALTY 100
- #define PENALTY_CHECKSUM_SAVE_COUNT
- #define CHECKSUM_VALUE_COUNT 2
- #define CHECKSUM_VALUE_PTR_COUNT 10
- @@ -46,6 +47,7 @@
- struct penalty_rec *oldest, *newest;
-
- unsigned int expire_secs;
- + unsigned int max_penalty:16;
- struct timeout *to;
- };
-
- @@ -56,6 +58,7 @@
- penalty = i_new(struct penalty, 1);
- hash_table_create(&penalty->hash, default_pool, 0, str_hash, strcmp);
- penalty->expire_secs = PENALTY_DEFAULT_EXPIRE_SECS;
- + penalty->max_penalty = PENALTY_DEFAULT_MAX_PENALTY;
- return penalty;
- }
-
- @@ -88,6 +91,11 @@
- penalty->expire_secs = expire_secs;
- }
-
- +void penalty_set_max_penalty(struct penalty *penalty, unsigned int max_penalty)
- +{
- + penalty->max_penalty = max_penalty;
- +}
- +
- static bool
- penalty_bump_checksum(struct penalty_rec *rec, unsigned int checksum)
- {
- @@ -183,51 +191,84 @@
- }
- }
-
- -void penalty_inc(struct penalty *penalty, const char *ident,
- - unsigned int checksum, unsigned int value)
- +static void penalty_update_times(struct penalty *penalty,
- + struct penalty_rec *rec)
- {
- - struct penalty_rec *rec;
- time_t diff;
-
- - i_assert(value > 0 || checksum == 0);
- - i_assert(value <= INT_MAX);
- + diff = ioloop_time - rec->last_penalty;
- + if (diff >= (1 << LAST_UPDATE_BITS)) {
- + rec->last_update = (1 << LAST_UPDATE_BITS) - 1;
- + rec->last_penalty = ioloop_time - rec->last_update;
- + } else {
- + rec->last_update = diff;
- + }
- +
- + if (penalty->to == NULL) {
- + penalty->to = timeout_add(penalty->expire_secs * 1000,
- + penalty_timeout, penalty);
- + }
- +}
- +
- +void penalty_inc(struct penalty *penalty, const char *ident,
- + unsigned int checksum)
- +{
- + struct penalty_rec *rec;
- + unsigned int new_penalty;
-
- rec = hash_table_lookup(penalty->hash, ident);
- if (rec == NULL) {
- rec = i_new(struct penalty_rec, 1);
- rec->ident = i_strdup(ident);
- + rec->penalty = 1;
- + rec->last_penalty = ioloop_time;
- hash_table_insert(penalty->hash, rec->ident, rec);
- + if (checksum != 0)
- + penalty_add_checksum(rec, checksum);
- } else {
- DLLIST2_REMOVE(&penalty->oldest, &penalty->newest, rec);
- - }
-
- - if (checksum == 0) {
- - rec->penalty = value;
- - rec->last_penalty = ioloop_time;
- - } else {
- - if (penalty_bump_checksum(rec, checksum))
- - rec->penalty = value - 1;
- - else {
- - penalty_add_checksum(rec, checksum);
- - rec->penalty = value;
- + new_penalty = rec->penalty;
- + if (checksum == 0) {
- + new_penalty++;
- rec->last_penalty = ioloop_time;
- + } else {
- + if (!penalty_bump_checksum(rec, checksum)) {
- + penalty_add_checksum(rec, checksum);
- + new_penalty++;
- + rec->last_penalty = ioloop_time;
- + }
- }
- + rec->penalty = (new_penalty < penalty->max_penalty) ?
- + new_penalty : penalty->max_penalty;
- }
-
- - diff = ioloop_time - rec->last_penalty;
- - if (diff >= (1 << LAST_UPDATE_BITS)) {
- - rec->last_update = (1 << LAST_UPDATE_BITS) - 1;
- - rec->last_penalty = ioloop_time - rec->last_update;
- + penalty_update_times(penalty, rec);
- + DLLIST2_APPEND(&penalty->oldest, &penalty->newest, rec);
- +}
- +
- +void penalty_set(struct penalty *penalty, const char *ident,
- + unsigned int value)
- +{
- + struct penalty_rec *rec;
- +
- + rec = hash_table_lookup(penalty->hash, ident);
- + if (rec == NULL) {
- + if (value == 0)
- + return;
- + rec = i_new(struct penalty_rec, 1);
- + rec->ident = i_strdup(ident);
- + hash_table_insert(penalty->hash, rec->ident, rec);
- } else {
- - rec->last_update = diff;
- + DLLIST2_REMOVE(&penalty->oldest, &penalty->newest, rec);
- }
-
- - DLLIST2_APPEND(&penalty->oldest, &penalty->newest, rec);
- + rec->penalty = (value < penalty->max_penalty) ? value :
- + penalty->max_penalty;
- + rec->last_penalty = ioloop_time;
-
- - if (penalty->to == NULL) {
- - penalty->to = timeout_add(penalty->expire_secs * 1000,
- - penalty_timeout, penalty);
- - }
- + penalty_update_times(penalty, rec);
- + DLLIST2_APPEND(&penalty->oldest, &penalty->newest, rec);
- }
-
- bool penalty_has_checksum(struct penalty *penalty, const char *ident,
- diff -Naur dovecot-2.2.21.orig/src/anvil/penalty.h dovecot-2.2.21/src/anvil/penalty.h
- --- dovecot-2.2.21.orig/src/anvil/penalty.h 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/anvil/penalty.h 2016-02-17 02:28:07.724478886 +0100
- @@ -7,13 +7,14 @@
- void penalty_deinit(struct penalty **penalty);
-
- void penalty_set_expire_secs(struct penalty *penalty, unsigned int expire_secs);
- +void penalty_set_max_penalty(struct penalty *penalty, unsigned int max_penalty);
-
- unsigned int penalty_get(struct penalty *penalty, const char *ident,
- time_t *last_penalty_r);
- -/* if checksum is non-zero and it already exists for ident, the value
- - is set to "value-1", otherwise it's set to "value". */
- void penalty_inc(struct penalty *penalty, const char *ident,
- - unsigned int checksum, unsigned int value);
- + unsigned int checksum);
- +void penalty_set(struct penalty *penalty, const char *ident,
- + unsigned int value);
-
- bool penalty_has_checksum(struct penalty *penalty, const char *ident,
- unsigned int checksum);
- diff -Naur dovecot-2.2.21.orig/src/anvil/test-penalty.c dovecot-2.2.21/src/anvil/test-penalty.c
- --- dovecot-2.2.21.orig/src/anvil/test-penalty.c 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/anvil/test-penalty.c 2016-02-17 02:28:07.724478886 +0100
- @@ -18,9 +18,10 @@
- penalty = penalty_init();
-
- test_assert(penalty_get(penalty, "foo", &t) == 0);
- + penalty_set(penalty, "foo", 5);
- for (i = 1; i <= 10; i++) {
- ioloop_time = 12345678 + i;
- - penalty_inc(penalty, "foo", i, 5+i);
- + penalty_inc(penalty, "foo", i);
-
- for (j = I_MIN(1, i-1); j <= i; j++) {
- test_assert(penalty_get(penalty, "foo", &t) == 5+i);
- @@ -31,20 +32,20 @@
- test_assert(t == (time_t)(12345678 + i));
- test_assert(!penalty_has_checksum(penalty, "foo", j));
- }
- - test_assert(penalty_get(penalty, "foo2", &t) == 0);
-
- /* overflows checksum array */
- ioloop_time = 12345678 + i;
- - penalty_inc(penalty, "foo", i, 5 + i);
- - penalty_inc(penalty, "foo", i, 5 + i);
- - penalty_inc(penalty, "foo", 0, 5 + i);
- + penalty_set(penalty, "foo", 5+i);
- + penalty_inc(penalty, "foo", i);
- + penalty_inc(penalty, "foo", i);
- + penalty_inc(penalty, "foo", 0);
-
- - test_assert(penalty_get(penalty, "foo", &t) == 5+i);
- + test_assert(penalty_get(penalty, "foo", &t) == 5+2+i);
- test_assert(t == (time_t)(12345678 + i));
- test_assert(!penalty_has_checksum(penalty, "foo", 1));
-
- for (j = 2; j <= i; j++) {
- - test_assert(penalty_get(penalty, "foo", &t) == 5+i);
- + test_assert(penalty_get(penalty, "foo", &t) == 5+2+i);
- test_assert(t == (time_t)(12345678 + i));
- test_assert(penalty_has_checksum(penalty, "foo", i));
- }
- diff -Naur dovecot-2.2.21.orig/src/auth/auth-penalty.c dovecot-2.2.21/src/auth/auth-penalty.c
- --- dovecot-2.2.21.orig/src/auth/auth-penalty.c 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/auth/auth-penalty.c 2016-02-17 02:28:14.849599750 +0100
- @@ -39,6 +39,8 @@
- else {
- anvil_client_cmd(penalty->client, t_strdup_printf(
- "PENALTY-SET-EXPIRE-SECS\t%u", AUTH_PENALTY_TIMEOUT));
- + anvil_client_cmd(penalty->client, t_strdup_printf(
- + "PENALTY-SET-MAX-PENALTY\t%u", AUTH_PENALTY_MAX_PENALTY));
- }
- return penalty;
- }
- @@ -149,7 +151,7 @@
- auth_request->user);
- }
-
- -void auth_penalty_update(struct auth_penalty *penalty,
- +void auth_penalty_set(struct auth_penalty *penalty,
- struct auth_request *auth_request, unsigned int value)
- {
- const char *ident;
- @@ -158,18 +160,29 @@
- if (penalty->disabled || ident == NULL || auth_request->no_penalty)
- return;
-
- - if (value > AUTH_PENALTY_MAX_PENALTY) {
- - /* even if the actual value doesn't change, the last_change
- - timestamp does. */
- - value = AUTH_PENALTY_MAX_PENALTY;
- - }
- + T_BEGIN {
- + const char *cmd;
- +
- + cmd = t_strdup_printf("PENALTY-SET\t%s\t%u", ident, value);
- + anvil_client_cmd(penalty->client, cmd);
- + } T_END;
- +}
- +
- +void auth_penalty_inc(struct auth_penalty *penalty,
- + struct auth_request *auth_request)
- +{
- + const char *ident;
- +
- + ident = auth_penalty_get_ident(auth_request);
- + if (penalty->disabled || ident == NULL || auth_request->no_penalty)
- + return;
- +
- T_BEGIN {
- const char *cmd;
- unsigned int checksum;
-
- - checksum = value == 0 ? 0 : get_userpass_checksum(auth_request);
- - cmd = t_strdup_printf("PENALTY-INC\t%s\t%u\t%u",
- - ident, checksum, value);
- + checksum = get_userpass_checksum(auth_request);
- + cmd = t_strdup_printf("PENALTY-INC\t%s\t%u", ident, checksum);
- anvil_client_cmd(penalty->client, cmd);
- } T_END;
- }
- diff -Naur dovecot-2.2.21.orig/src/auth/auth-penalty.h dovecot-2.2.21/src/auth/auth-penalty.h
- --- dovecot-2.2.21.orig/src/auth/auth-penalty.h 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/auth/auth-penalty.h 2016-02-17 02:29:25.160792445 +0100
- @@ -22,7 +22,9 @@
- void auth_penalty_lookup(struct auth_penalty *penalty,
- struct auth_request *auth_request,
- auth_penalty_callback_t *callback);
- -void auth_penalty_update(struct auth_penalty *penalty,
- +void auth_penalty_set(struct auth_penalty *penalty,
- struct auth_request *auth_request, unsigned int value);
- +void auth_penalty_inc(struct auth_penalty *penalty,
- + struct auth_request *auth_request);
-
- #endif
- diff -Naur dovecot-2.2.21.orig/src/auth/auth-request-handler.c dovecot-2.2.21/src/auth/auth-request-handler.c
- --- dovecot-2.2.21.orig/src/auth/auth-request-handler.c 2015-12-09 16:39:10.000000000 +0100
- +++ dovecot-2.2.21/src/auth/auth-request-handler.c 2016-02-17 02:28:14.857599885 +0100
- @@ -228,8 +228,7 @@
- handler->refcount++;
-
- if (auth_penalty != NULL) {
- - auth_penalty_update(auth_penalty, request,
- - request->last_penalty + 1);
- + auth_penalty_inc(auth_penalty, request);
- }
-
- auth_request_refresh_last_access(request);
- @@ -249,7 +248,7 @@
-
- if (request->last_penalty != 0 && auth_penalty != NULL) {
- /* reset penalty */
- - auth_penalty_update(auth_penalty, request, 0);
- + auth_penalty_set(auth_penalty, request, 0);
- }
-
- /* sanitize these fields, since the login code currently assumes they
-