The files themselves didn't make it through the list server. I'll try
with .txt
On 09/06/2024 15:42, John Fawcett via dovecot wrote:
Hi
Just in case this is useful more generally, I'm posting it to the list.
While Dovecot has an access control via allow_nets, it is a user
database field that applies only at the authentication stage to deny
access for the specific user when there is a connection attempt from
an unauthorized ip for that user.
https://doc.dovecot.org/configuration_manual/authentication/allow_nets/
I don't believe there is anything that checks access at connect time
to deny unwanted traffic prior to authentication, for example from
compromised machines, botnets etc. Though failed connection attempts
do not appear to be a significant issue, maybe better to add some
safety net for the future.
The attached patch is proof of concept code that introduces the
parameters rbl_check and rbl_check_timeout (msecs) to the protocol
section. Tested for imap, pop3 and sieve. The following is an example
for sieve.
protocol sieve {
rbl_check = zen.spamhaus.net=127.0.0.4
rbl_check_timeout = 5000
}
If the lookup results in a hit the client is disconnected with a BYE
"Disconnected for policy." message and the logs report:
Jun 09 12:00:56 server.example.com dovecot[977650]:
managesieve-login: Disconnected: Policy (disconnected before auth was
ready, waited 1 secs): user=<>, service=sieve, rip=n.n.n.n, lip=n.n.n.n
The patch also makes the number of pre-login errors and post-login
errors configurable (max_login_command_errors and max_command_errors
respectively) for pop3, imap and sieve protocols .
protocol sieve {
max_command_errors = 1
max_login_command_errors = 1
}
A potential extension to the logic would be "allow_nets" and
"disallow_nets" parameters or maybe something more sophisticated to
allow ips/networks that would otherwise be blocked or deny additional
ips/networks.
John
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/config/all-settings.c
dovecot-2.3.21/src/config/all-settings.c
--- dovecot-2.3.21-orig/src/config/all-settings.c 2023-09-14
15:18:20.000000000 +0200
+++ dovecot-2.3.21/src/config/all-settings.c 2024-06-09 11:31:45.820319492
+0200
@@ -1750,6 +1750,7 @@
struct pop3_settings {
bool verbose_proctitle;
const char *rawlog_dir;
+ unsigned int max_bad_commands;
/* pop3: */
bool pop3_no_flag_updates;
@@ -1849,6 +1850,10 @@
unsigned int mail_max_userip_connections;
+ const char *rbl_check;
+ unsigned int rbl_check_timeout;
+ unsigned int max_login_command_errors;
+
/* generated: */
char *const *log_format_elements_split;
};
@@ -1907,6 +1912,7 @@
struct imap_settings {
bool verbose_proctitle;
const char *rawlog_dir;
+ unsigned int max_command_errors;
/* imap: */
uoff_t imap_max_line_length;
@@ -3277,6 +3283,7 @@
static const struct setting_define pop3_setting_defines[] = {
DEF(BOOL, verbose_proctitle),
DEF(STR_VARS, rawlog_dir),
+ DEF(UINT, max_bad_commands),
DEF(BOOL, pop3_no_flag_updates),
DEF(BOOL, pop3_enable_last),
@@ -3295,6 +3302,7 @@
static const struct pop3_settings pop3_default_settings = {
.verbose_proctitle = FALSE,
.rawlog_dir = "",
+ .max_bad_commands = 20,
.pop3_no_flag_updates = FALSE,
.pop3_enable_last = FALSE,
@@ -4183,6 +4191,10 @@
DEF(UINT, mail_max_userip_connections),
+ DEF(STR, rbl_check),
+ DEF(TIME_MSECS, rbl_check_timeout),
+ DEF(UINT, max_login_command_errors),
+
SETTING_DEFINE_LIST_END
};
static const struct login_settings login_default_settings = {
@@ -4209,7 +4221,11 @@
.auth_debug = FALSE,
.verbose_proctitle = FALSE,
- .mail_max_userip_connections = 10
+ .mail_max_userip_connections = 10,
+
+ .rbl_check = "",
+ .rbl_check_timeout = 10*1000,
+ .max_login_command_errors = 3
};
const struct setting_parser_info login_setting_parser_info = {
.module_name = "login",
@@ -4656,6 +4672,7 @@
static const struct setting_define imap_setting_defines[] = {
DEF(BOOL, verbose_proctitle),
DEF(STR_VARS, rawlog_dir),
+ DEF(UINT, max_command_errors),
DEF(SIZE, imap_max_line_length),
DEF(TIME, imap_idle_notify_interval),
@@ -4677,6 +4694,7 @@
static const struct imap_settings imap_default_settings = {
.verbose_proctitle = FALSE,
.rawlog_dir = "",
+ .max_command_errors = 20,
/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
break large message sets to multiple commands, so we're pretty
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/imap/imap-client.c dovecot-2.3.21/src/imap/imap-client.c
--- dovecot-2.3.21-orig/src/imap/imap-client.c 2023-09-14 15:17:46.000000000
+0200
+++ dovecot-2.3.21/src/imap/imap-client.c 2024-06-09 11:08:27.416859461
+0200
@@ -726,7 +726,7 @@
client_send_tagline(cmd, error);
- if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
+ if (++client->bad_counter >= client->set->max_command_errors) {
client_disconnect_with_error(client,
"Too many invalid IMAP commands.");
}
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/imap/imap-common.h dovecot-2.3.21/src/imap/imap-common.h
--- dovecot-2.3.21-orig/src/imap/imap-common.h 2023-09-14 15:17:46.000000000
+0200
+++ dovecot-2.3.21/src/imap/imap-common.h 2024-06-09 11:08:27.417859463
+0200
@@ -10,9 +10,6 @@
/* Stop buffering more data into output stream after this many bytes */
#define CLIENT_OUTPUT_OPTIMAL_SIZE 2048
-/* Disconnect client when it sends too many bad commands in a row */
-#define CLIENT_MAX_BAD_COMMANDS 20
-
#include "lib.h"
#include "imap-client.h"
#include "imap-settings.h"
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/imap/imap-settings.c
dovecot-2.3.21/src/imap/imap-settings.c
--- dovecot-2.3.21-orig/src/imap/imap-settings.c 2023-09-14
15:17:46.000000000 +0200
+++ dovecot-2.3.21/src/imap/imap-settings.c 2024-06-09 11:08:27.417859463
+0200
@@ -67,6 +67,7 @@
static const struct setting_define imap_setting_defines[] = {
DEF(BOOL, verbose_proctitle),
DEF(STR_VARS, rawlog_dir),
+ DEF(UINT, max_command_errors),
DEF(SIZE, imap_max_line_length),
DEF(TIME, imap_idle_notify_interval),
@@ -89,6 +90,7 @@
static const struct imap_settings imap_default_settings = {
.verbose_proctitle = FALSE,
.rawlog_dir = "",
+ .max_command_errors = 20,
/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
break large message sets to multiple commands, so we're pretty
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/imap/imap-settings.h
dovecot-2.3.21/src/imap/imap-settings.h
--- dovecot-2.3.21-orig/src/imap/imap-settings.h 2023-09-14
15:17:46.000000000 +0200
+++ dovecot-2.3.21/src/imap/imap-settings.h 2024-06-09 11:08:27.417859463
+0200
@@ -22,6 +22,7 @@
struct imap_settings {
bool verbose_proctitle;
const char *rawlog_dir;
+ unsigned int max_command_errors;
/* imap: */
uoff_t imap_max_line_length;
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/imap-login/imap-login-client.c
dovecot-2.3.21/src/imap-login/imap-login-client.c
--- dovecot-2.3.21-orig/src/imap-login/imap-login-client.c 2023-09-14
15:17:46.000000000 +0200
+++ dovecot-2.3.21/src/imap-login/imap-login-client.c 2024-06-09
11:08:27.417859463 +0200
@@ -25,9 +25,6 @@
# error LOGIN_MAX_INBUF_SIZE too short to fit all ID command parameters
#endif
-/* Disconnect client when it sends too many bad commands */
-#define CLIENT_MAX_BAD_COMMANDS 3
-
/* Skip incoming data until newline is found,
returns TRUE if newline was found. */
bool client_skip_line(struct imap_client *client)
@@ -197,7 +194,7 @@
{
if (client->cmd_tag == NULL || *client->cmd_tag == '\0')
client->cmd_tag = "*";
- if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
+ if (++client->common.bad_counter >=
client->common.set->max_login_command_errors) {
client_send_reply(&client->common, IMAP_CMD_REPLY_BYE,
"Too many invalid IMAP commands.");
client_destroy(&client->common, "Too many invalid commands");
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/lib/net.c dovecot-2.3.21/src/lib/net.c
--- dovecot-2.3.21-orig/src/lib/net.c 2023-09-14 15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/lib/net.c 2024-06-09 11:08:27.418859465 +0200
@@ -8,8 +8,10 @@
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
+#include <stdio.h>
#include <sys/un.h>
#include <netinet/tcp.h>
+#include <regex.h>
#if defined(HAVE_UCRED_H)
# include <ucred.h> /* for getpeerucred() */
#elif defined(HAVE_SYS_UCRED_H)
@@ -898,6 +900,60 @@
return addr;
}
+const char *net_ip2raddr(const struct ip_addr *ip)
+{
+ char *raddr = t_malloc_no0(MAX_IP_LEN*2);
+ if (inet_rntop(ip->family, &ip->u.ip6, raddr, MAX_IP_LEN*2) == NULL) {
+ return "";
+ }
+ return raddr;
+}
+
+static const char * inet_rntop4 (const u_char *src, char *dst, socklen_t size)
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+ if ((socklen_t)sprintf(tmp, fmt, src[3], src[2], src[1], src[0]) >=
size) {
+ return (NULL);
+ }
+ return strcpy(dst, tmp);
+}
+
+static const char * inet_rntop6 (const u_char *src, char *dst, socklen_t size)
+{
+ char tmp[MAX_IP_LEN*2], buf[3],*tp;
+ int i;
+ tp = tmp;
+ for (i=15;i>0;i--) {
+ sprintf(buf,"%02x",src[i]);
+ *tp++ = buf[1];
+ *tp++ = '.';
+ *tp++ = buf[0];
+ *tp++ = '.';
+ }
+ sprintf(buf,"%02x",src[0]);
+ *tp++ = buf[1];
+ *tp++ = '.';
+ *tp++ = buf[0];
+ *tp = '\0';
+ if ((socklen_t)(tp - tmp) > size) {
+ return (NULL);
+ }
+ return strcpy(dst, tmp);
+}
+
+const char * inet_rntop (int af, const void *src, char *dst, socklen_t size)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_rntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_rntop6(src, dst, size));
+ default:
+ return (NULL);
+ }
+}
+
static bool net_addr2ip_inet4_fast(const char *addr, struct ip_addr *ip)
{
uint8_t *saddr = (void *)&ip->u.ip4.s_addr;
@@ -1235,3 +1291,34 @@
}
return TRUE;
}
+
+bool net_rbl_match(const char * ip, const char * filter)
+{
+ regex_t regex;
+ int ret;
+
+ /* Compile regular expression */
+ ret = regcomp(®ex, filter, 0);
+ if (ret) {
+ i_error("Could not compile regex");
+ return FALSE;
+ }
+
+ /* Execute regular expression */
+ ret = regexec(®ex, ip, 0, NULL, 0);
+ if (!ret) {
+ regfree(®ex);
+ return TRUE;
+ }
+ else if (ret == REG_NOMATCH) {
+ regfree(®ex);
+ return FALSE;
+ }
+ else {
+ i_error("Regex match failed");
+ return FALSE;
+ }
+}
+
+
+
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/lib/net.h dovecot-2.3.21/src/lib/net.h
--- dovecot-2.3.21-orig/src/lib/net.h 2023-09-14 15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/lib/net.h 2024-06-09 11:08:27.419859467 +0200
@@ -155,6 +155,11 @@
/* Returns ip_addr as string, or "" if ip isn't valid IPv4 or IPv6 address. */
const char *net_ip2addr(const struct ip_addr *ip);
+
+const char *net_ip2raddr(const struct ip_addr *ip);
+
+const char * inet_rntop (int af, const void *src, char *dst, socklen_t size);
+
/* char* -> struct ip_addr translation. */
int net_addr2ip(const char *addr, struct ip_addr *ip);
/* char* -> in_port_t translation */
@@ -196,4 +201,5 @@
bool net_is_in_network(const struct ip_addr *ip, const struct ip_addr *net_ip,
unsigned int bits) ATTR_PURE;
+bool net_rbl_match(const char * ip, const char * filter);
#endif
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/client-common.c
dovecot-2.3.21/src/login-common/client-common.c
--- dovecot-2.3.21-orig/src/login-common/client-common.c 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/login-common/client-common.c 2024-06-09
14:10:29.805269915 +0200
@@ -29,6 +29,7 @@
#include "dsasl-client.h"
#include "login-proxy.h"
#include "client-common.h"
+#include "dns-lookup.h"
struct client *clients = NULL;
struct client *destroyed_clients = NULL;
@@ -232,8 +233,62 @@
return client;
}
+static void
+dns_lookup_callback(const struct dns_lookup_result *result,
+ struct rbl_context * r)
+{
+ const char *user_reason, *destroy_reason;
+ if (result->ret != 0)
+ {
+ i_info("rbl_check negative, cannot resolve': %s",
result->error);
+ client_init_continue(r->client);
+ }
+ else
+ {
+ i_info("rbl_check got %d IPs", result->ips_count);
+ int match = FALSE;
+ for (unsigned int i = 0; i<result->ips_count; i++) {
+ if
(net_rbl_match(net_ip2addr(&result->ips[i]),r->filter)) {
+ match = TRUE;
+ i_info("ip: %s filter %s
match",net_ip2addr(&result->ips[i]),r->filter);
+ } else {
+ i_info("ip: %s filter %s no
match",net_ip2addr(&result->ips[i]),r->filter);
+ }
+ }
+ if (match) {
+ user_reason = "Disconnected for policy.";
+ destroy_reason = "Policy";
+ client_notify_disconnect(r->client,
CLIENT_DISCONNECT_POLICY, user_reason);
+ client_destroy(r->client, destroy_reason);
+ } else {
+ i_info("No match");
+ client_init_continue(r->client);
+ }
+ }
+ free(r->filter);
+ free(r);
+}
+
+void client_init_continue(struct client * client)
+{
+ client->access_checks_done = TRUE;
+ if (auth_client_is_connected(auth_client))
+ client_notify_auth_ready(client);
+ else
+ client_set_auth_waiting(client);
+ login_refresh_proctitle();
+}
+
void client_init(struct client *client, void **other_sets)
{
+ struct dns_lookup_settings dns_set;
+ struct dns_lookup *lookup;
+ char * revip = (char *)
malloc(MAX_IP_LEN*2+strlen(client->set->rbl_check)+1);
+ char * rbl = (char *) malloc(strlen(client->set->rbl_check)+1);
+ char * filter = (char *) malloc(100);
+ char * sep;
+ int rbl_len;
+
if (last_client == NULL)
last_client = client;
client->list_type = CLIENT_LIST_TYPE_ACTIVE;
@@ -247,15 +302,40 @@
hook_login_client_allocated(client);
client->v.create(client, other_sets);
client->create_finished = TRUE;
+ client->access_checks_done = FALSE;
- if (auth_client_is_connected(auth_client))
- client_notify_auth_ready(client);
- else
- client_set_auth_waiting(client);
-
- login_refresh_proctitle();
+ i_debug("listner name %s login remote ip: %s rbl_check:
%s",client->listener_name,net_ip2addr(&client->real_remote_ip),client->set->rbl_check);
+ if (strlen(client->set->rbl_check)>0) {
+ sep = strchr(client->set->rbl_check,'=');
+ if (sep == NULL) {
+ strcpy(rbl,client->set->rbl_check);
+ filter[0] ='\0';
+ } else {
+ rbl_len = sep-client->set->rbl_check;
+ strncpy(rbl,client->set->rbl_check,rbl_len);
+ rbl[rbl_len]='\0';
+ if(*(sep+1) != '\0') {
+ strcpy(filter,sep+1);
+ }
+ }
+ i_zero(&dns_set);
+ dns_set.dns_client_socket_path = DNS_CLIENT_SOCKET_NAME;
+ dns_set.timeout_msecs = client->set->rbl_check_timeout;
+ dns_set.event_parent = client->event;
+
sprintf(revip,"%s.%s",net_ip2raddr(&client->real_remote_ip),rbl);
+ struct rbl_context * r = ( struct rbl_context *)
malloc(sizeof(struct rbl_context));
+ r->client = client;
+ r->filter = filter;
+ i_info("rbl_check: %s",revip);
+ dns_lookup(revip, &dns_set, dns_lookup_callback, r, &lookup);
+ }
+ else {
+ i_info("No rbl check");
+ client_init_continue(client);
+ }
}
+
void client_disconnect(struct client *client, const char *reason,
bool add_disconnected_prefix)
{
@@ -1124,7 +1204,7 @@
void client_notify_auth_ready(struct client *client)
{
- if (!client->notified_auth_ready) {
+ if (client->access_checks_done && !client->notified_auth_ready) {
if (client->v.notify_auth_ready != NULL)
client->v.notify_auth_ready(client);
client->notified_auth_ready = TRUE;
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/client-common.h
dovecot-2.3.21/src/login-common/client-common.h
--- dovecot-2.3.21-orig/src/login-common/client-common.h 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/login-common/client-common.h 2024-06-09
14:09:28.885136093 +0200
@@ -47,7 +47,8 @@
CLIENT_DISCONNECT_TIMEOUT,
CLIENT_DISCONNECT_SYSTEM_SHUTDOWN,
CLIENT_DISCONNECT_RESOURCE_CONSTRAINT,
- CLIENT_DISCONNECT_INTERNAL_ERROR
+ CLIENT_DISCONNECT_INTERNAL_ERROR,
+ CLIENT_DISCONNECT_POLICY
};
enum client_auth_fail_code {
@@ -258,6 +259,7 @@
bool proxy_nopipelining:1;
bool proxy_not_trusted:1;
bool auth_waiting:1;
+ bool access_checks_done:1;
bool notified_auth_ready:1;
bool notified_disconnect:1;
bool fd_proxying:1;
@@ -265,6 +267,12 @@
/* ... */
};
+struct rbl_context {
+ struct client * client;
+ char * filter;
+};
+
+
union login_client_module_context {
struct client_vfuncs super;
struct login_module_register *reg;
@@ -289,6 +297,7 @@
const struct master_service_ssl_settings *ssl_set,
const struct master_service_ssl_server_settings *ssl_server_set);
void client_init(struct client *client, void **other_sets);
+void client_init_continue(struct client *client);
void client_disconnect(struct client *client, const char *reason,
bool add_disconnected_prefix);
void client_destroy(struct client *client, const char *reason);
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/login-settings.c
dovecot-2.3.21/src/login-common/login-settings.c
--- dovecot-2.3.21-orig/src/login-common/login-settings.c 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/login-common/login-settings.c 2024-06-09
11:08:27.424859476 +0200
@@ -45,6 +45,10 @@
DEF(UINT, mail_max_userip_connections),
+ DEF(STR, rbl_check),
+ DEF(TIME_MSECS, rbl_check_timeout),
+ DEF(UINT, max_login_command_errors),
+
SETTING_DEFINE_LIST_END
};
@@ -72,7 +76,11 @@
.auth_debug = FALSE,
.verbose_proctitle = FALSE,
- .mail_max_userip_connections = 10
+ .mail_max_userip_connections = 10,
+
+ .rbl_check = "",
+ .rbl_check_timeout = 10*1000,
+ .max_login_command_errors = 3
};
const struct setting_parser_info login_setting_parser_info = {
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/login-settings.h
dovecot-2.3.21/src/login-common/login-settings.h
--- dovecot-2.3.21-orig/src/login-common/login-settings.h 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/login-common/login-settings.h 2024-06-09
11:08:27.425859478 +0200
@@ -30,6 +30,10 @@
unsigned int mail_max_userip_connections;
+ const char *rbl_check;
+ unsigned int rbl_check_timeout;
+ unsigned int max_login_command_errors;
+
/* generated: */
char *const *log_format_elements_split;
};
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/Makefile.am
dovecot-2.3.21/src/login-common/Makefile.am
--- dovecot-2.3.21-orig/src/login-common/Makefile.am 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/login-common/Makefile.am 2024-06-09 11:08:27.435859495
+0200
@@ -4,6 +4,7 @@
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-auth \
+ -I$(top_srcdir)/src/lib-dns \
-I$(top_srcdir)/src/lib-sasl \
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-ssl-iostream \
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/login-common/Makefile.in
dovecot-2.3.21/src/login-common/Makefile.in
--- dovecot-2.3.21-orig/src/login-common/Makefile.in 2023-09-14
15:17:58.000000000 +0200
+++ dovecot-2.3.21/src/login-common/Makefile.in 2024-06-09 11:08:27.435859495
+0200
@@ -487,6 +487,7 @@
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-auth \
+ -I$(top_srcdir)/src/lib-dns \
-I$(top_srcdir)/src/lib-sasl \
-I$(top_srcdir)/src/lib-master \
-I$(top_srcdir)/src/lib-ssl-iostream \
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/pop3/pop3-client.c dovecot-2.3.21/src/pop3/pop3-client.c
--- dovecot-2.3.21-orig/src/pop3/pop3-client.c 2023-09-14 15:17:47.000000000
+0200
+++ dovecot-2.3.21/src/pop3/pop3-client.c 2024-06-09 11:08:27.425859478
+0200
@@ -27,9 +27,6 @@
/* max. length of input command line (spec says 512) */
#define MAX_INBUF_SIZE 2048
-/* Disconnect client when it sends too many bad commands in a row */
-#define CLIENT_MAX_BAD_COMMANDS 20
-
/* Disconnect client after idling this many milliseconds */
#define CLIENT_IDLE_TIMEOUT_MSECS (10*60*1000)
/* If client starts idling for this many milliseconds, commit the current
@@ -765,7 +762,7 @@
client->waiting_input = TRUE;
break;
}
- } else if (++client->bad_counter > CLIENT_MAX_BAD_COMMANDS) {
+ } else if (++client->bad_counter >
client->set->max_bad_commands) {
client_send_line(client, "-ERR Too many bad commands.");
client_disconnect(client, "Too many bad commands.");
}
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/pop3/pop3-settings.c
dovecot-2.3.21/src/pop3/pop3-settings.c
--- dovecot-2.3.21-orig/src/pop3/pop3-settings.c 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/pop3/pop3-settings.c 2024-06-09 11:08:27.433859492
+0200
@@ -63,6 +63,7 @@
static const struct setting_define pop3_setting_defines[] = {
DEF(BOOL, verbose_proctitle),
DEF(STR_VARS, rawlog_dir),
+ DEF(UINT, max_bad_commands),
DEF(BOOL, pop3_no_flag_updates),
DEF(BOOL, pop3_enable_last),
@@ -82,6 +83,7 @@
static const struct pop3_settings pop3_default_settings = {
.verbose_proctitle = FALSE,
.rawlog_dir = "",
+ .max_bad_commands = 20,
.pop3_no_flag_updates = FALSE,
.pop3_enable_last = FALSE,
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/pop3/pop3-settings.h
dovecot-2.3.21/src/pop3/pop3-settings.h
--- dovecot-2.3.21-orig/src/pop3/pop3-settings.h 2023-09-14
15:17:47.000000000 +0200
+++ dovecot-2.3.21/src/pop3/pop3-settings.h 2024-06-09 11:08:27.434859494
+0200
@@ -17,6 +17,7 @@
struct pop3_settings {
bool verbose_proctitle;
const char *rawlog_dir;
+ unsigned int max_bad_commands;
/* pop3: */
bool pop3_no_flag_updates;
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3.21-orig/src/pop3-login/client.c
dovecot-2.3.21/src/pop3-login/client.c
--- dovecot-2.3.21-orig/src/pop3-login/client.c 2023-09-14 15:17:47.000000000
+0200
+++ dovecot-2.3.21/src/pop3-login/client.c 2024-06-09 11:08:27.434859494
+0200
@@ -20,8 +20,6 @@
#include <ctype.h>
-/* Disconnect client when it sends too many bad commands */
-#define CLIENT_MAX_BAD_COMMANDS 3
#define CLIENT_MAX_CMD_LEN 8
static bool cmd_stls(struct pop3_client *client)
@@ -190,7 +188,7 @@
if (client_command_execute(pop3_client, pop3_client->current_cmd, args))
client->bad_counter = 0;
- else if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
+ else if (++client->bad_counter >=
pop3_client->common.set->max_login_command_errors ) {
client_send_reply(client, POP3_CMD_REPLY_ERROR,
"Too many invalid bad commands.");
client_destroy(client,
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-client.c
dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-client.c
--- dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-client.c
2023-09-14 15:18:26.000000000 +0200
+++ dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-client.c
2024-06-08 12:23:33.448065570 +0200
@@ -412,7 +412,7 @@
client_send_no(client, error);
- if (++client->bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
+ if (++client->bad_counter >= client->set->max_command_errors) {
client_disconnect_with_error(
client, "Too many invalid MANAGESIEVE commands.");
}
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-common.h
dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-common.h
--- dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-common.h
2023-09-14 15:18:26.000000000 +0200
+++ dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-common.h
2024-06-01 10:36:40.167047136 +0200
@@ -12,9 +12,6 @@
/* Stop buffering more data into output stream after this many bytes */
#define CLIENT_OUTPUT_OPTIMAL_SIZE 2048
-/* Disconnect client when it sends too many bad commands in a row */
-#define CLIENT_MAX_BAD_COMMANDS 20
-
#define CRITICAL_MSG \
"Internal error occurred. Refer to server log for more information."
#define CRITICAL_MSG_STAMP CRITICAL_MSG " [%Y-%m-%d %H:%M:%S]"
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-settings.c
dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-settings.c
--- dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-settings.c
2023-09-14 15:18:26.000000000 +0200
+++ dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-settings.c
2024-06-08 12:31:13.488173013 +0200
@@ -63,6 +63,7 @@
DEF(BOOL, mail_debug),
DEF(BOOL, verbose_proctitle),
DEF(STR_VARS, rawlog_dir),
+ DEF(UINT, max_command_errors),
DEF(SIZE, managesieve_max_line_length),
DEF(STR, managesieve_implementation_string),
@@ -70,7 +71,6 @@
DEF(STR, managesieve_logout_format),
DEF(UINT, managesieve_max_compile_errors),
-
SETTING_DEFINE_LIST_END
};
@@ -78,6 +78,7 @@
.mail_debug = FALSE,
.verbose_proctitle = FALSE,
.rawlog_dir = "",
+ .max_command_errors = 20,
/* RFC-2683 recommends at least 8000 bytes. Some clients however don't
break large message sets to multiple commands, so we're pretty
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-settings.h
dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-settings.h
--- dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve/managesieve-settings.h
2023-09-14 15:18:26.000000000 +0200
+++ dovecot-2.3-pigeonhole-0.5.21/src/managesieve/managesieve-settings.h
2024-06-08 12:30:32.487074330 +0200
@@ -13,6 +13,7 @@
bool mail_debug;
bool verbose_proctitle;
const char *rawlog_dir;
+ unsigned int max_command_errors;
/* managesieve: */
uoff_t managesieve_max_line_length;
diff -x '*.log' -x '*.status' -x '*.deps' -x '*.a' -x '*.o' -ur
dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve-login/client.c
dovecot-2.3-pigeonhole-0.5.21/src/managesieve-login/client.c
--- dovecot-2.3-pigeonhole-0.5.21-orig/src/managesieve-login/client.c
2023-09-14 15:18:26.000000000 +0200
+++ dovecot-2.3-pigeonhole-0.5.21/src/managesieve-login/client.c
2024-06-08 12:22:07.446858494 +0200
@@ -23,9 +23,6 @@
#include "managesieve-login-settings.h"
#include "managesieve-proxy.h"
-/* Disconnect client when it sends too many bad commands */
-#define CLIENT_MAX_BAD_COMMANDS 3
-
struct managesieve_command {
const char *name;
int (*func)(struct managesieve_client *client,
@@ -339,7 +336,7 @@
if (ret != 0)
client->cmd_finished = TRUE;
if (ret < 0) {
- if (++client->common.bad_counter >= CLIENT_MAX_BAD_COMMANDS) {
+ if (++client->common.bad_counter >=
client->common.set->max_login_command_errors) {
client_send_bye(&client->common,
"Too many invalid MANAGESIEVE commands.");
client_destroy(&client->common,
_______________________________________________
dovecot mailing list -- dovecot@dovecot.org
To unsubscribe send an email to dovecot-le...@dovecot.org