diff --git a/postfix/.indent.pro b/postfix/.indent.pro index c15aa6353..0e9462f19 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -404,5 +404,4 @@ -Tssl_comp_stack_t -Ttime_t -Ttlsa_filter --Tx509_extension_stack_t -Tx509_stack_t diff --git a/postfix/HISTORY b/postfix/HISTORY index ec3762e54..5b06aab4f 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -21989,3 +21989,24 @@ Apologies for any names omitted. warnings, and skip the failing pattern as in dict_regexp.c. Also, fixed the error text when running into the matcher's backtracking limit. File: util/dict_pcre.c. + +20151017 + + Feature: smtpd_client_auth_rate_limit enforces a rate + limit on the number of AUTH commands per client IP address. + mantools/postlink, proto/postconf.proto, anvil/anvil.c, + global/anvil_clnt.c, global/anvil_clnt.h, global/mail_params.h, + smtpd/smtpd.c. + +20151018 + + Added RFC 7672 (SMTP security via opportunistic DANE TLS) + and RFC 7505 ("Null MX" No Service Resource Record) to the + lists of supported RFCs in manpages. Viktor Dukhovni. Files: + smtp/smtp.c, smtpd/smtpd.c. + +20151031 + + Bitrot: OpenSSL API cleanups. Viktor Dukhovni. Files: + .indent.pro, tls/tls.h, tls/tls_dane.c, tls/tls_fprint.c, + tls/tls_misc.c, tls/tls_server.c, tls/tls_verify.c. diff --git a/postfix/README_FILES/TUNING_README b/postfix/README_FILES/TUNING_README index b7a3f3a3d..c1176617a 100644 --- a/postfix/README_FILES/TUNING_README +++ b/postfix/README_FILES/TUNING_README @@ -173,6 +173,10 @@ the smtpd(8) server against abuse by out-of-control clients. The maximum number of new TLS sessions (without using the TLS session cache) that an SMTP client may negotiate in the time interval specified with anvil_rate_time_unit (default: 60s). + smtpd_client_auth_rate_limit (default: no limit) + The maximum number of AUTH commands that an SMTP client may send in the + time interval specified with anvil_rate_time_unit (default: 60s). + Available in Postfix 3.1 and later. smtpd_client_event_limit_exceptions (default: $mynetworks) SMTP clients that are excluded from connection and rate limits specified above. diff --git a/postfix/html/TUNING_README.html b/postfix/html/TUNING_README.html index a851a225d..9a378d03c 100644 --- a/postfix/html/TUNING_README.html +++ b/postfix/html/TUNING_README.html @@ -267,6 +267,11 @@ the TLS session cache) that an SMTP client may negotiate in the time interval specified with anvil_rate_time_unit (default: 60s). +
+The maximal number of AUTH commands that any client is allowed to +send to this service per time unit, regardless of whether or not +Postfix actually accepts those commands. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +
+ ++By default, there is no limit on the number AUTH commands that a +client may send. +
+ ++To disable this feature, specify a limit of 0. +
+ ++WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +
+ ++This feature is available in Postfix 3.1 and later. +
+ ++The maximal number of AUTH commands that any client is allowed to +send to this service per time unit, regardless of whether or not +Postfix actually accepts those commands. The time unit is specified +with the anvil_rate_time_unit configuration parameter. +
+ ++By default, there is no limit on the number AUTH commands that a +client may send. +
+ ++To disable this feature, specify a limit of 0. +
+ ++WARNING: The purpose of this feature is to limit abuse. It must +not be used to regulate legitimate mail traffic. +
+ ++This feature is available in Postfix 3.1 and later. +
+ %PARAM smtpd_client_restrictions
diff --git a/postfix/src/anvil/anvil.c b/postfix/src/anvil/anvil.c
index ffc40d872..0b536539c 100644
--- a/postfix/src/anvil/anvil.c
+++ b/postfix/src/anvil/anvil.c
@@ -130,6 +130,25 @@
/* \fBstatus=0\fR
/* \fBrate=\fInumber\fR
/* .fi
+/* AUTH RATE CONTROL
+/* .ad
+/* .fi
+/* To register an AUTH request send the following request
+/* to the \fBanvil\fR(8) server:
+/*
+/* .nf
+/* \fBrequest=auth\fR
+/* \fBident=\fIstring\fR
+/* .fi
+/*
+/* The \fBanvil\fR(8) server answers with the number of auth
+/* requests per unit time for the (service, client) combination
+/* specified with \fBident\fR:
+/*
+/* .nf
+/* \fBstatus=0\fR
+/* \fBrate=\fInumber\fR
+/* .fi
/* SECURITY
/* .ad
/* .fi
@@ -288,6 +307,7 @@ typedef struct {
int mail; /* message rate */
int rcpt; /* recipient rate */
int ntls; /* new TLS session rate */
+ int auth; /* AUTH request rate */
time_t start; /* time of first rate sample */
} ANVIL_REMOTE;
@@ -318,6 +338,7 @@ typedef struct {
(remote)->mail = 0; \
(remote)->rcpt = 0; \
(remote)->ntls = 0; \
+ (remote)->auth = 0; \
(remote)->start = event_time(); \
} while(0)
@@ -337,6 +358,7 @@ typedef struct {
(remote)->mail = 0; \
(remote)->rcpt = 0; \
(remote)->ntls = 0; \
+ (remote)->auth = 0; \
(remote)->start = _start; \
} while(0)
@@ -365,6 +387,8 @@ typedef struct {
#define ANVIL_REMOTE_INCR_NTLS(remote) ANVIL_REMOTE_INCR_RATE((remote), ntls)
+#define ANVIL_REMOTE_INCR_AUTH(remote) ANVIL_REMOTE_INCR_RATE((remote), auth)
+
/* Drop connection from (service, client) state. */
#define ANVIL_REMOTE_DROP_ONE(remote) \
@@ -441,6 +465,7 @@ static ANVIL_MAX max_conn_rate; /* peak connection rate */
static ANVIL_MAX max_mail_rate; /* peak message rate */
static ANVIL_MAX max_rcpt_rate; /* peak recipient rate */
static ANVIL_MAX max_ntls_rate; /* peak new TLS session rate */
+static ANVIL_MAX max_auth_rate; /* peak AUTH request rate */
static int max_cache_size; /* peak cache size */
static time_t max_cache_time; /* time of peak size */
@@ -531,6 +556,7 @@ static void anvil_remote_lookup(VSTREAM *client_stream, const char *ident)
SEND_ATTR_INT(ANVIL_ATTR_MAIL, 0),
SEND_ATTR_INT(ANVIL_ATTR_RCPT, 0),
SEND_ATTR_INT(ANVIL_ATTR_NTLS, 0),
+ SEND_ATTR_INT(ANVIL_ATTR_AUTH, 0),
ATTR_TYPE_END);
} else {
@@ -547,6 +573,7 @@ static void anvil_remote_lookup(VSTREAM *client_stream, const char *ident)
SEND_ATTR_INT(ANVIL_ATTR_MAIL, anvil_remote->mail),
SEND_ATTR_INT(ANVIL_ATTR_RCPT, anvil_remote->rcpt),
SEND_ATTR_INT(ANVIL_ATTR_NTLS, anvil_remote->ntls),
+ SEND_ATTR_INT(ANVIL_ATTR_AUTH, anvil_remote->auth),
ATTR_TYPE_END);
}
}
@@ -689,6 +716,35 @@ static void anvil_remote_rcpt(VSTREAM *client_stream, const char *ident)
ANVIL_MAX_UPDATE(max_rcpt_rate, anvil_remote->rcpt, anvil_remote->ident);
}
+/* anvil_remote_auth - register auth request event */
+
+static void anvil_remote_auth(VSTREAM *client_stream, const char *ident)
+{
+ ANVIL_REMOTE *anvil_remote;
+
+ /*
+ * Be prepared for "postfix reload" after "connect".
+ */
+ if ((anvil_remote =
+ (ANVIL_REMOTE *) htable_find(anvil_remote_map, ident)) == 0)
+ anvil_remote = anvil_remote_conn_update(client_stream, ident);
+
+ /*
+ * Update recipient address rate and respond to local server.
+ */
+ ANVIL_REMOTE_INCR_AUTH(anvil_remote);
+ attr_print_plain(client_stream, ATTR_FLAG_NONE,
+ SEND_ATTR_INT(ANVIL_ATTR_STATUS, ANVIL_STAT_OK),
+ SEND_ATTR_INT(ANVIL_ATTR_RATE, anvil_remote->auth),
+ ATTR_TYPE_END);
+
+ /*
+ * Update peak statistics.
+ */
+ if (anvil_remote->auth > max_auth_rate.value)
+ ANVIL_MAX_UPDATE(max_auth_rate, anvil_remote->auth, anvil_remote->ident);
+}
+
/* anvil_remote_newtls - register newtls event */
static void anvil_remote_newtls(VSTREAM *client_stream, const char *ident)
@@ -826,6 +882,7 @@ static void anvil_status_dump(char *unused_name, char **unused_argv)
ANVIL_MAX_RATE_REPORT(max_mail_rate, "message");
ANVIL_MAX_RATE_REPORT(max_rcpt_rate, "recipient");
ANVIL_MAX_RATE_REPORT(max_ntls_rate, "newtls");
+ ANVIL_MAX_RATE_REPORT(max_auth_rate, "auth");
if (max_cache_size > 0) {
msg_info("statistics: max cache size %d at %.15s",
@@ -855,6 +912,7 @@ static void anvil_service(VSTREAM *client_stream, char *unused_service, char **a
ANVIL_REQ_NTLS, anvil_remote_newtls,
ANVIL_REQ_DISC, anvil_remote_disconnect,
ANVIL_REQ_NTLS_STAT, anvil_remote_newtls_stat,
+ ANVIL_REQ_AUTH, anvil_remote_auth,
ANVIL_REQ_LOOKUP, anvil_remote_lookup,
0, 0,
};
diff --git a/postfix/src/global/anvil_clnt.c b/postfix/src/global/anvil_clnt.c
index 34d3c0f31..a681ca14c 100644
--- a/postfix/src/global/anvil_clnt.c
+++ b/postfix/src/global/anvil_clnt.c
@@ -43,13 +43,19 @@
/* const char *addr;
/* int *newtls;
/*
+/* int anvil_clnt_auth(anvil_clnt, service, addr, auths)
+/* ANVIL_CLNT *anvil_clnt;
+/* const char *service;
+/* const char *addr;
+/* int *auths;
+/*
/* int anvil_clnt_disconnect(anvil_clnt, service, addr)
/* ANVIL_CLNT *anvil_clnt;
/* const char *service;
/* const char *addr;
/*
-/* int anvil_clnt_lookup(anvil_clnt, service, addr,
-/* count, rate, msgs, rcpts)
+/* int anvil_clnt_lookup(anvil_clnt, service, addr, count,
+/* rate, msgs, rcpts, ntls, auths)
/* ANVIL_CLNT *anvil_clnt;
/* const char *service;
/* const char *addr;
@@ -57,6 +63,8 @@
/* int *rate;
/* int *msgs;
/* int *rcpts;
+/* int *ntls;
+/* int *auths;
/* DESCRIPTION
/* anvil_clnt_create() instantiates a local anvil service
/* client endpoint.
@@ -80,6 +88,9 @@
/* anvil_clnt_newtls_stat() returns the current newtls request
/* rate for the specified remote client.
/*
+/* anvil_clnt_auth() registers an AUTH event and returns the
+/* current AUTH event rate for the specified remote client.
+/*
/* anvil_clnt_disconnect() informs the anvil server that a remote
/* client has disconnected.
/*
@@ -111,6 +122,9 @@
/* .IP newtls
/* Pointer to storage for the current "new TLS session" rate
/* for this remote client.
+/* .IP auths
+/* Pointer to storage for the current AUTH event rate for this
+/* remote client.
/* DIAGNOSTICS
/* The update and status query routines return
/* ANVIL_STAT_OK in case of success, ANVIL_STAT_FAIL otherwise
@@ -181,7 +195,7 @@ void anvil_clnt_free(ANVIL_CLNT *anvil_clnt)
int anvil_clnt_lookup(ANVIL_CLNT *anvil_clnt, const char *service,
const char *addr, int *count, int *rate,
- int *msgs, int *rcpts, int *newtls)
+ int *msgs, int *rcpts, int *newtls, int *auths)
{
char *ident = ANVIL_IDENT(service, addr);
int status;
@@ -198,7 +212,8 @@ int anvil_clnt_lookup(ANVIL_CLNT *anvil_clnt, const char *service,
RECV_ATTR_INT(ANVIL_ATTR_MAIL, msgs),
RECV_ATTR_INT(ANVIL_ATTR_RCPT, rcpts),
RECV_ATTR_INT(ANVIL_ATTR_NTLS, newtls),
- ATTR_TYPE_END) != 6)
+ RECV_ATTR_INT(ANVIL_ATTR_AUTH, auths),
+ ATTR_TYPE_END) != 7)
status = ANVIL_STAT_FAIL;
else if (status != ANVIL_STAT_OK)
status = ANVIL_STAT_FAIL;
@@ -327,6 +342,30 @@ int anvil_clnt_newtls_stat(ANVIL_CLNT *anvil_clnt, const char *service,
return (status);
}
+/* anvil_clnt_auth - heads-up and status query */
+
+int anvil_clnt_auth(ANVIL_CLNT *anvil_clnt, const char *service,
+ const char *addr, int *auths)
+{
+ char *ident = ANVIL_IDENT(service, addr);
+ int status;
+
+ if (attr_clnt_request((ATTR_CLNT *) anvil_clnt,
+ ATTR_FLAG_NONE, /* Query attributes. */
+ SEND_ATTR_STR(ANVIL_ATTR_REQ, ANVIL_REQ_AUTH),
+ SEND_ATTR_STR(ANVIL_ATTR_IDENT, ident),
+ ATTR_TYPE_END,
+ ATTR_FLAG_MISSING, /* Reply attributes. */
+ RECV_ATTR_INT(ANVIL_ATTR_STATUS, &status),
+ RECV_ATTR_INT(ANVIL_ATTR_RATE, auths),
+ ATTR_TYPE_END) != 2)
+ status = ANVIL_STAT_FAIL;
+ else if (status != ANVIL_STAT_OK)
+ status = ANVIL_STAT_FAIL;
+ myfree(ident);
+ return (status);
+}
+
/* anvil_clnt_disconnect - heads-up only */
int anvil_clnt_disconnect(ANVIL_CLNT *anvil_clnt, const char *service,
@@ -371,6 +410,7 @@ static void usage(void)
ANVIL_REQ_RCPT " service addr | "
ANVIL_REQ_NTLS " service addr | "
ANVIL_REQ_NTLS_STAT " service addr | "
+ ANVIL_REQ_AUTH " service addr | "
ANVIL_REQ_LOOKUP " service addr\n");
}
@@ -387,6 +427,7 @@ int main(int unused_argc, char **argv)
int msgs;
int rcpts;
int newtls;
+ int auths;
ANVIL_CLNT *anvil;
msg_vstream_init(argv[0], VSTREAM_ERR);
@@ -432,6 +473,11 @@ int main(int unused_argc, char **argv)
msg_warn("error!");
else
vstream_printf("rate=%d\n", newtls);
+ } else if (strncmp(cmd, ANVIL_REQ_AUTH, cmd_len) == 0) {
+ if (anvil_clnt_auth(anvil, service, addr, &auths) != ANVIL_STAT_OK)
+ msg_warn("error!");
+ else
+ vstream_printf("rate=%d\n", auths);
} else if (strncmp(cmd, ANVIL_REQ_NTLS_STAT, cmd_len) == 0) {
if (anvil_clnt_newtls_stat(anvil, service, addr, &newtls) != ANVIL_STAT_OK)
msg_warn("error!");
@@ -443,12 +489,13 @@ int main(int unused_argc, char **argv)
else
vstream_printf("OK\n");
} else if (strncmp(cmd, ANVIL_REQ_LOOKUP, cmd_len) == 0) {
- if (anvil_clnt_lookup(anvil, service, addr, &count, &rate,
- &msgs, &rcpts, &newtls) != ANVIL_STAT_OK)
+ if (anvil_clnt_lookup(anvil, service, addr, &count, &rate, &msgs,
+ &rcpts, &newtls, &auths) != ANVIL_STAT_OK)
msg_warn("error!");
else
- vstream_printf("count=%d, rate=%d msgs=%d rcpts=%d newtls=%d\n",
- count, rate, msgs, rcpts, newtls);
+ vstream_printf("count=%d, rate=%d msgs=%d rcpts=%d newtls=%d "
+ "auths=%d\n", count, rate, msgs, rcpts, newtls,
+ auths);
} else {
vstream_printf("bad command: \"%s\"\n", cmd);
usage();
diff --git a/postfix/src/global/anvil_clnt.h b/postfix/src/global/anvil_clnt.h
index 0e48a42dd..f95b64800 100644
--- a/postfix/src/global/anvil_clnt.h
+++ b/postfix/src/global/anvil_clnt.h
@@ -34,6 +34,7 @@
#define ANVIL_REQ_RCPT "recipient"
#define ANVIL_REQ_NTLS "newtls"
#define ANVIL_REQ_NTLS_STAT "newtls_status"
+#define ANVIL_REQ_AUTH "auth"
#define ANVIL_REQ_LOOKUP "lookup"
#define ANVIL_ATTR_IDENT "ident"
#define ANVIL_ATTR_COUNT "count"
@@ -41,6 +42,7 @@
#define ANVIL_ATTR_MAIL "mail"
#define ANVIL_ATTR_RCPT "rcpt"
#define ANVIL_ATTR_NTLS "newtls"
+#define ANVIL_ATTR_AUTH "auth"
#define ANVIL_ATTR_STATUS "status"
#define ANVIL_STAT_OK 0
@@ -57,7 +59,8 @@ extern int anvil_clnt_mail(ANVIL_CLNT *, const char *, const char *, int *);
extern int anvil_clnt_rcpt(ANVIL_CLNT *, const char *, const char *, int *);
extern int anvil_clnt_newtls(ANVIL_CLNT *, const char *, const char *, int *);
extern int anvil_clnt_newtls_stat(ANVIL_CLNT *, const char *, const char *, int *);
-extern int anvil_clnt_lookup(ANVIL_CLNT *, const char *, const char *, int *, int *, int *, int *, int *);
+extern int anvil_clnt_auth(ANVIL_CLNT *, const char *, const char *, int *);
+extern int anvil_clnt_lookup(ANVIL_CLNT *, const char *, const char *, int *, int *, int *, int *, int *, int *);
extern int anvil_clnt_disconnect(ANVIL_CLNT *, const char *, const char *);
extern void anvil_clnt_free(ANVIL_CLNT *);
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index b4dbc21bb..91c7f126e 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -2996,6 +2996,10 @@ extern int var_smtpd_crcpt_limit;
#define DEF_SMTPD_CNTLS_LIMIT 0
extern int var_smtpd_cntls_limit;
+#define VAR_SMTPD_CAUTH_LIMIT "smtpd_client_auth_rate_limit"
+#define DEF_SMTPD_CAUTH_LIMIT 0
+extern int var_smtpd_cauth_limit;
+
#define VAR_SMTPD_HOGGERS "smtpd_client_event_limit_exceptions"
#define DEF_SMTPD_HOGGERS "${smtpd_client_connection_limit_exceptions:$" VAR_MYNETWORKS "}"
extern char *var_smtpd_hoggers;
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 0a84fd808..d2c85a7a5 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20151011"
+#define MAIL_RELEASE_DATE "20151031"
#define MAIL_VERSION_NUMBER "3.1"
#ifdef SNAPSHOT
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index 192e8b2ea..6ca453749 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -98,6 +98,7 @@
/* RFC 5321 (SMTP protocol)
/* RFC 6531 (Internationalized SMTP)
/* RFC 6533 (Internationalized Delivery Status Notifications)
+/* RFC 7672 (SMTP security via opportunistic DANE TLS)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* Corrupted message files are marked so that the queue manager can
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 14bdc693c..7111808cc 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -55,6 +55,7 @@
/* RFC 5321 (SMTP protocol)
/* RFC 6531 (Internationalized SMTP)
/* RFC 6533 (Internationalized Delivery Status Notifications)
+/* RFC 7505 ("Null MX" No Service Resource Record)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/*
@@ -297,7 +298,7 @@
/* features depends on the SASL server implementation that is selected
/* with \fBsmtpd_sasl_type\fR.
/* .IP "\fBsmtpd_sender_login_maps (empty)\fR"
-/* Optional lookup table with the SASL login names that own sender
+/* Optional lookup table with the SASL login names that own the sender
/* (MAIL FROM) addresses.
/* .PP
/* Available in Postfix version 2.1 and later:
@@ -699,6 +700,12 @@
/* time limit per read or write system call, to a time limit to send
/* or receive a complete record (an SMTP command line, SMTP response
/* line, SMTP message content line, or TLS protocol message).
+/* .PP
+/* Available in Postfix version 3.1 and later:
+/* .IP "\fBsmtpd_client_auth_rate_limit (0)\fR"
+/* The maximal number of AUTH commands that any client is allowed to
+/* send to this service per time unit, regardless of whether or not
+/* Postfix actually accepts those commands.
/* TARPIT CONTROLS
/* .ad
/* .fi
@@ -1292,6 +1299,7 @@ int var_smtpd_cconn_limit;
int var_smtpd_cmail_limit;
int var_smtpd_crcpt_limit;
int var_smtpd_cntls_limit;
+int var_smtpd_cauth_limit;
char *var_smtpd_hoggers;
char *var_local_rwr_clients;
char *var_smtpd_ehlo_dis_words;
@@ -1897,6 +1905,32 @@ static void helo_reset(SMTPD_STATE *state)
}
}
+/* smtpd_sasl_auth_cmd_wrapper - smtpd_sasl_auth_cmd front-end */
+
+static int smtpd_sasl_auth_cmd_wrapper(SMTPD_STATE *state, int argc,
+ SMTPD_TOKEN *argv)
+{
+ int rate;
+
+ if (SMTPD_STAND_ALONE(state) == 0
+ && !xclient_allowed
+ && anvil_clnt
+ && var_smtpd_cauth_limit > 0
+ && !namadr_list_match(hogger_list, state->name, state->addr)
+ && anvil_clnt_auth(anvil_clnt, state->service, state->addr,
+ &rate) == ANVIL_STAT_OK
+ && rate > var_smtpd_cauth_limit) {
+ state->error_mask |= MAIL_ERROR_POLICY;
+ msg_warn("AUTH command rate limit exceeded: %d from %s for service %s",
+ rate, state->namaddr, state->service);
+ smtpd_chat_reply(state,
+ "450 4.7.1 Error: too many AUTH commands from %s",
+ state->addr);
+ return (-1);
+ }
+ return (smtpd_sasl_auth_cmd(state, argc, argv));
+}
+
/* mail_open_stream - open mail queue file or IPC stream */
static int mail_open_stream(SMTPD_STATE *state)
@@ -4713,7 +4747,7 @@ static SMTPD_CMD smtpd_cmd_table[] = {
{SMTPD_CMD_STARTTLS, unimpl_cmd, SMTPD_CMD_FLAG_PRE_TLS,},
#endif
#ifdef USE_SASL_AUTH
- {SMTPD_CMD_AUTH, smtpd_sasl_auth_cmd,},
+ {SMTPD_CMD_AUTH, smtpd_sasl_auth_cmd_wrapper,},
#else
{SMTPD_CMD_AUTH, unimpl_cmd,},
#endif
@@ -5577,7 +5611,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
*/
if (var_smtpd_crate_limit || var_smtpd_cconn_limit
|| var_smtpd_cmail_limit || var_smtpd_crcpt_limit
- || var_smtpd_cntls_limit)
+ || var_smtpd_cntls_limit || var_smtpd_cauth_limit)
anvil_clnt = anvil_clnt_create();
}
@@ -5625,6 +5659,7 @@ int main(int argc, char **argv)
VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 0, 0,
VAR_SMTPD_CRCPT_LIMIT, DEF_SMTPD_CRCPT_LIMIT, &var_smtpd_crcpt_limit, 0, 0,
VAR_SMTPD_CNTLS_LIMIT, DEF_SMTPD_CNTLS_LIMIT, &var_smtpd_cntls_limit, 0, 0,
+ VAR_SMTPD_CAUTH_LIMIT, DEF_SMTPD_CAUTH_LIMIT, &var_smtpd_cauth_limit, 0, 0,
#ifdef USE_TLS
VAR_SMTPD_TLS_CCERT_VD, DEF_SMTPD_TLS_CCERT_VD, &var_smtpd_tls_ccert_vd, 0, 0,
#endif
diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h
index 8efb03830..c5a6d4eb8 100644
--- a/postfix/src/tls/tls.h
+++ b/postfix/src/tls/tls.h
@@ -73,17 +73,27 @@ extern const NAME_CODE tls_level_table[];
#include