bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
0ed36079905646682119839c2fbbbcd98444bd3dTimo Sirainen/* The idea behind checksums is that the same username+password doesn't
0ed36079905646682119839c2fbbbcd98444bd3dTimo Sirainen increase the penalty, because it's most likely a user with a misconfigured
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen /* ordered by last_update */
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen unsigned int last_update:LAST_UPDATE_BITS; /* last_penalty + n */
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen /* we use value up to two different checksums.
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen after that switch to pointer. */
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen /* ident => penalty_rec */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen HASH_TABLE(char *, struct penalty_rec *) hash;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&penalty->hash, default_pool, 0, str_hash, strcmp);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen penalty->expire_secs = PENALTY_DEFAULT_EXPIRE_SECS;
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainenstatic void penalty_rec_free(struct penalty *penalty, struct penalty_rec *rec)
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen DLLIST2_REMOVE(&penalty->oldest, &penalty->newest, rec);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainenvoid penalty_set_expire_secs(struct penalty *penalty, unsigned int expire_secs)
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenpenalty_bump_checksum(struct penalty_rec *rec, unsigned int checksum)
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen for (i = 0; i < count; i++) {
7f29b324658de9e42e75af45e2a198f3ba300031Timo Sirainen sizeof(checksums[0]) * i);
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenstatic void penalty_add_checksum(struct penalty_rec *rec, unsigned int checksum)
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen if (rec->checksum.value[CHECKSUM_VALUE_COUNT-1] == 0) {
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen memcpy(rec->checksum.value + 1, rec->checksum.value,
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen /* switch to using a pointer */
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen checksums = i_new(unsigned int, CHECKSUM_VALUE_PTR_COUNT);
4633993e0e102636ba923e327138069a04a5304dTimo Sirainen memmove(rec->checksum.value_ptr + 1, rec->checksum.value_ptr,
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainenunsigned int penalty_get(struct penalty *penalty, const char *ident,
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen rec = hash_table_lookup(penalty->hash, ident);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainenstatic void penalty_timeout(struct penalty *penalty)
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen expire_time = ioloop_time - penalty->expire_secs;
5e0d4b90ef697b8ccc2889eeb6035b27b50baff5Timo Sirainen rec_last_update = rec->last_penalty + rec->last_update;
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenvoid penalty_inc(struct penalty *penalty, const char *ident,
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen rec = hash_table_lookup(penalty->hash, ident);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen hash_table_insert(penalty->hash, rec->ident, rec);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen DLLIST2_REMOVE(&penalty->oldest, &penalty->newest, rec);
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen rec->last_update = (1 << LAST_UPDATE_BITS) - 1;
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen rec->last_penalty = ioloop_time - rec->last_update;
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen DLLIST2_APPEND(&penalty->oldest, &penalty->newest, rec);
7e7cdca78e6a67757188406c8de9db42fcd17881Timo Sirainen penalty->to = timeout_add(penalty->expire_secs * 1000,
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenbool penalty_has_checksum(struct penalty *penalty, const char *ident,
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen rec = hash_table_lookup(penalty->hash, ident);
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen for (i = 0; i < count; i++) {
8825740187b8aaca9c39c4fd6a0b79d480eb143fTimo Sirainenvoid penalty_dump(struct penalty *penalty, struct ostream *output)
8825740187b8aaca9c39c4fd6a0b79d480eb143fTimo Sirainen for (rec = penalty->oldest; rec != NULL; rec = rec->next) {