bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
120ab73a12c9a752d112db80cd467eea514493c6Timo Sirainen/* We don't want IPv6 hosts being able to flood our penalty
120ab73a12c9a752d112db80cd467eea514493c6Timo Sirainen tracking with tons of different IPs. */
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenstruct auth_penalty *auth_penalty_init(const char *path)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen penalty->client = anvil_client_init(path, NULL,
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen if (anvil_client_connect(penalty->client, TRUE) < 0)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen anvil_client_cmd(penalty->client, t_strdup_printf(
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen "PENALTY-SET-EXPIRE-SECS\t%u", AUTH_PENALTY_TIMEOUT));
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenvoid auth_penalty_deinit(struct auth_penalty **_penalty)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenunsigned int auth_penalty_to_secs(unsigned int penalty)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen unsigned int i, secs = AUTH_PENALTY_INIT_SECS;
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen for (i = 0; i < penalty; i++)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen return secs < AUTH_PENALTY_MAX_SECS ? secs : AUTH_PENALTY_MAX_SECS;
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenstatic void auth_penalty_anvil_callback(const char *reply, void *context)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen struct auth_penalty_request *request = context;
e9d9f9071b12a687564c6817f3984cc1cd56d866Timo Sirainen /* internal failure. */
e9d9f9071b12a687564c6817f3984cc1cd56d866Timo Sirainen if (!anvil_client_is_connected(request->client)) {
e9d9f9071b12a687564c6817f3984cc1cd56d866Timo Sirainen /* we probably didn't have permissions to reconnect
e9d9f9071b12a687564c6817f3984cc1cd56d866Timo Sirainen back to anvil. need to restart ourself. */
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen } else if (sscanf(reply, "%u %lu", &penalty, &last_penalty) != 2) {
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen i_error("Invalid PENALTY-GET reply: %s", reply);
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen /* time moved backwards? */
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen /* update penalty. */
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen while (penalty > 0) {
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen request->callback(penalty, request->auth_request);
120ab73a12c9a752d112db80cd467eea514493c6Timo Sirainenstatic const char *
120ab73a12c9a752d112db80cd467eea514493c6Timo Sirainenauth_penalty_get_ident(struct auth_request *auth_request)
120ab73a12c9a752d112db80cd467eea514493c6Timo Sirainen memset(ip.u.ip6.s6_addr + PENALTY_IPV6_MASK_BITS/CHAR_BIT, 0,
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenvoid auth_penalty_lookup(struct auth_penalty *penalty,
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen const char *ident;
d8702d15ee7721ed1fcfc8f00a589970bd6b3598Timo Sirainen if (penalty->disabled || ident == NULL || auth_request->no_penalty) {
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen request = i_new(struct auth_penalty_request, 1);
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenstatic unsigned int
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainenget_userpass_checksum(struct auth_request *auth_request)
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen return auth_request->mech_password == NULL ? 0 :
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen crc32_str_more(crc32_str(auth_request->mech_password),
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainenvoid auth_penalty_update(struct auth_penalty *penalty,
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen struct auth_request *auth_request, unsigned int value)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen const char *ident;
d8702d15ee7721ed1fcfc8f00a589970bd6b3598Timo Sirainen if (penalty->disabled || ident == NULL || auth_request->no_penalty)
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen /* even if the actual value doesn't change, the last_change
e76073ebaf90fa29abfdc364873acf78983949aaTimo Sirainen timestamp does. */
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen checksum = value == 0 ? 0 : get_userpass_checksum(auth_request);
5566faf0b48f0b77b0134f34130bdc7842c844ebTimo Sirainen cmd = t_strdup_printf("PENALTY-INC\t%s\t%u\t%u",