diff -Naur dovecot-2.2.21.orig/src/anvil/anvil-settings.c dovecot-2.2.21/src/anvil/anvil-settings.c
--- dovecot-2.2.21.orig/src/anvil/anvil-settings.c	2015-12-09 16:39:10.000000000 +0100
+++ dovecot-2.2.21/src/anvil/anvil-settings.c	2016-02-18 23:28:19.237600327 +0100
@@ -4,6 +4,7 @@
 #include "buffer.h"
 #include "settings-parser.h"
 #include "service-settings.h"
+#include "anvil-settings.h"
 
 #include <stddef.h>
 
@@ -48,3 +49,30 @@
 
 	.process_limit_1 = TRUE
 };
+
+#undef DEF
+#define DEF(type, name) \
+	{ type, #name, offsetof(struct anvil_settings, name), NULL }
+
+static const struct setting_define anvil_setting_defines[] = {
+	DEF(SET_STR, login_trusted_networks),
+
+	SETTING_DEFINE_LIST_END
+};
+
+const struct anvil_settings anvil_default_settings = {
+	.login_trusted_networks = ""
+};
+
+const struct setting_parser_info anvil_setting_parser_info = {
+	.module_name = "anvil",
+	.defines = anvil_setting_defines,
+	.defaults = &anvil_default_settings,
+
+	.type_offset = (size_t)-1,
+	.struct_size = sizeof(struct anvil_settings),
+
+	.parent_offset = (size_t)-1,
+};
+
+const struct anvil_settings *anvil_settings;
diff -Naur dovecot-2.2.21.orig/src/anvil/anvil-settings.h dovecot-2.2.21/src/anvil/anvil-settings.h
--- dovecot-2.2.21.orig/src/anvil/anvil-settings.h	1970-01-01 01:00:00.000000000 +0100
+++ dovecot-2.2.21/src/anvil/anvil-settings.h	2016-02-18 23:32:24.208396222 +0100
@@ -0,0 +1,11 @@
+#ifndef ANVIL_SETTINGS_H
+#define ANVIL_SETTINGS_H
+
+struct anvil_settings {
+	const char *login_trusted_networks;
+};
+
+extern const struct setting_parser_info anvil_setting_parser_info;
+extern const struct anvil_settings *anvil_settings;
+
+#endif
diff -Naur dovecot-2.2.21.orig/src/anvil/main.c dovecot-2.2.21/src/anvil/main.c
--- dovecot-2.2.21.orig/src/anvil/main.c	2015-12-09 16:39:10.000000000 +0100
+++ dovecot-2.2.21/src/anvil/main.c	2016-02-19 00:40:51.814859086 +0100
@@ -12,6 +12,7 @@
 #include "connect-limit.h"
 #include "penalty.h"
 #include "anvil-connection.h"
+#include "anvil-settings.h"
 
 #include <unistd.h>
 
@@ -54,6 +55,10 @@
 {
 	const enum master_service_flags service_flags =
 		MASTER_SERVICE_FLAG_UPDATE_PROCTITLE;
+	const struct setting_parser_info *set_roots[] = {
+		&anvil_setting_parser_info,
+		NULL
+	};
 	const char *error;
 
 	master_service = master_service_init("anvil", service_flags,
@@ -61,7 +66,7 @@
 	if (master_getopt(master_service) > 0)
 		return FATAL_DEFAULT;
 	if (master_service_settings_read_simple(master_service,
-						NULL, &error) < 0)
+						set_roots, &error) < 0)
 		i_fatal("Error reading configuration: %s", error);
 	master_service_init_log(master_service, "anvil: ");
 
@@ -72,8 +77,10 @@
 	/* delay dying until all of our clients are gone */
 	master_service_set_die_with_master(master_service, FALSE);
 
+	anvil_settings = master_service_settings_get_others(master_service)[0];
+
 	connect_limit = connect_limit_init();
-	penalty = penalty_init();
+	penalty = penalty_init(anvil_settings->login_trusted_networks);
 	log_fdpass_io = io_add(MASTER_ANVIL_LOG_FDPASS_FD, IO_READ,
 			       log_fdpass_input, (void *)NULL);
 	master_service_init_finish(master_service);
diff -Naur dovecot-2.2.21.orig/src/anvil/Makefile.am dovecot-2.2.21/src/anvil/Makefile.am
--- dovecot-2.2.21.orig/src/anvil/Makefile.am	2015-12-09 16:39:10.000000000 +0100
+++ dovecot-2.2.21/src/anvil/Makefile.am	2016-02-18 21:03:52.574719133 +0100
@@ -22,6 +22,7 @@
 
 noinst_HEADERS = \
 	anvil-connection.h \
+	anvil-settings.h \
 	common.h \
 	connect-limit.h \
 	penalty.h
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	2016-02-19 00:59:45.455171729 +0100
+++ dovecot-2.2.21/src/anvil/penalty.c	2016-02-19 00:49:45.569197589 +0100
@@ -11,6 +11,7 @@
 #include "strescape.h"
 #include "llist.h"
 #include "ostream.h"
+#include "net.h"
 #include "penalty.h"
 
 #include <time.h>
@@ -48,10 +49,11 @@
 
 	unsigned int expire_secs;
 	unsigned int max_penalty:16;
+	const char *const *login_trusted_networks;
 	struct timeout *to;
 };
 
-struct penalty *penalty_init(void)
+struct penalty *penalty_init(const char *login_trusted_networks)
 {
 	struct penalty *penalty;
 
@@ -59,6 +61,8 @@
 	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;
+	penalty->login_trusted_networks = (login_trusted_networks != NULL) ?
+		t_strsplit_spaces(login_trusted_networks, ", ") : NULL;
 	return penalty;
 }
 
@@ -210,12 +214,39 @@
 	}
 }
 
+static bool penalty_ident_is_trusted(struct penalty *penalty,
+				     const char *ident)
+{
+	const char *const *net;
+	struct ip_addr net_ip;
+	unsigned int bits;
+	struct ip_addr ip;
+
+	(void)net_addr2ip(ident, &ip);
+
+	net = penalty->login_trusted_networks;
+	for (; *net != NULL; net++) {
+		if (net_parse_range(*net, &net_ip, &bits) < 0) {
+			i_error("login_trusted_networks: "
+				"Invalid network '%s'", *net);
+			break;
+		}
+
+		if (net_is_in_network(&ip, &net_ip, bits))
+			return TRUE;
+	}
+	return FALSE;
+}
+
 void penalty_inc(struct penalty *penalty, const char *ident,
 		 unsigned int checksum)
 {
 	struct penalty_rec *rec;
 	unsigned int new_penalty;
 
+	if (penalty_ident_is_trusted(penalty, ident))
+		return;
+
 	rec = hash_table_lookup(penalty->hash, ident);
 	if (rec == NULL) {
 		rec = i_new(struct penalty_rec, 1);
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	2016-02-19 00:59:45.456171724 +0100
+++ dovecot-2.2.21/src/anvil/penalty.h	2016-02-19 00:40:46.629884972 +0100
@@ -3,7 +3,7 @@
 
 #define PENALTY_MAX_VALUE ((1 << 16)-1)
 
-struct penalty *penalty_init(void);
+struct penalty *penalty_init(const char *login_trusted_networks);
 void penalty_deinit(struct penalty **penalty);
 
 void penalty_set_expire_secs(struct penalty *penalty, unsigned int expire_secs);
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-18 23:28:19.237600327 +0100
@@ -15,7 +15,7 @@
 	test_begin("penalty");
 
 	ioloop = io_loop_create();
-	penalty = penalty_init();
+	penalty = penalty_init(NULL);
 
 	test_assert(penalty_get(penalty, "foo", &t) == 0);
 	penalty_set(penalty, "foo", 5);
diff -Naur dovecot-2.2.21.orig/src/config/all-settings.c dovecot-2.2.21/src/config/all-settings.c
--- dovecot-2.2.21.orig/src/config/all-settings.c	2015-12-09 16:56:14.000000000 +0100
+++ dovecot-2.2.21/src/config/all-settings.c	2016-02-19 01:01:16.935709156 +0100
@@ -1489,6 +1489,11 @@
 	const char *const *realms_arr;
 	const struct ip_addr *proxy_self_ips;
 };
+/* ../../src/anvil/anvil-settings.h */
+extern const struct setting_parser_info anvil_setting_parser_info;
+struct anvil_settings {
+	const char *login_trusted_networks;
+};
 /* ../../src/util/tcpwrap-settings.c */
 #ifdef HAVE_LIBWRAP
 struct service_settings tcpwrap_service_settings = {
@@ -4264,6 +4269,27 @@
 
 	.process_limit_1 = TRUE
 };
+#undef DEF
+#define DEF(type, name) \
+	{ type, #name, offsetof(struct anvil_settings, name), NULL }
+static const struct setting_define anvil_setting_defines[] = {
+	DEF(SET_STR, login_trusted_networks),
+
+	SETTING_DEFINE_LIST_END
+};
+const struct anvil_settings anvil_default_settings = {
+	.login_trusted_networks = ""
+};
+const struct setting_parser_info anvil_setting_parser_info = {
+	.module_name = "anvil",
+	.defines = anvil_setting_defines,
+	.defaults = &anvil_default_settings,
+
+	.type_offset = (size_t)-1,
+	.struct_size = sizeof(struct anvil_settings),
+
+	.parent_offset = (size_t)-1,
+};
 static struct service_settings *config_all_services[] = {
 #ifdef HAVE_LIBWRAP
 	&tcpwrap_service_settings,
@@ -4327,6 +4353,7 @@
 	&pop3_login_setting_parser_info, 
 	&replicator_setting_parser_info, 
 	&imap_urlauth_login_setting_parser_info, 
+	&anvil_setting_parser_info, 
 	NULL
 };
 const struct setting_parser_info *const *all_roots = all_default_roots;
