From: Wietse Z Venema Date: Wed, 5 Aug 2026 05:00:00 +0000 (-0500) Subject: postfix-3.12-20260805 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fpostfix.git postfix-3.12-20260805 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index f30d0ad8e..8d9cfd50b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -31865,6 +31865,24 @@ Apologies for any names omitted. client remained in the "accept this message" state, skipping Milter policy enforcement for the second message. +20260805 + + Isolation: stamp Postfix SMTP server TLS session tickets + with their master.cf service name. With this, an SMTP server + defined in master.cf will no longer accept tickets issued + by a different SMTP server defined in the same master.cf + file. Fix by OpenAI security. File: tls_server.c. + + Bug (defect introduced: Postfix 3.4, date: 20180805): SMTP + server command history memory exhaustion with a large number + of very small BDAT requests. Reported by OpenAI security. + File: smtpd.c. + + Bug (defect introduced: Postfix 3.4, date: 20180303): the + MySQL client setting "tls_verify_cert = yes" had no effect + with Oracle MySQL 8 and later. Report and fix by OpenAI + Security. File: dict_mysql.c. + TODO Reorganize PTEST_LIB, PMOCK_LIB, TESTLIB, TESTLIBS, etc. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 7fc52ce1c..5b06a6a19 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -18037,7 +18037,11 @@ requirements.

The maximal number of lines in the Postfix SMTP server command history -before it is flushed upon receipt of EHLO, RSET, or end of DATA. +before it is flushed upon receipt of EHLO, RSET, or end of DATA. With +Postfix ≥ 3.4 releases after 20260805, the history is flushed +whenever it reaches the threshold. The notify_classes parameter +controls what command history may be reported in postmaster +notification email.

diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 6ccde017c..e82fa36f4 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -12373,7 +12373,11 @@ requirements. This feature is available in Postfix >= 3.10. .SH smtpd_history_flush_threshold (default: 100) The maximal number of lines in the Postfix SMTP server command history -before it is flushed upon receipt of EHLO, RSET, or end of DATA. +before it is flushed upon receipt of EHLO, RSET, or end of DATA. With +Postfix >= 3.4 releases after 20260805, the history is flushed +whenever it reaches the threshold. The notify_classes parameter +controls what command history may be reported in postmaster +notification email. .SH smtpd_junk_command_limit (default: normal: 100, overload: 1) The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote SMTP client can send before the Postfix SMTP server starts to diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index bdb60a923..9659b335a 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -6270,7 +6270,11 @@ smtpd_helo_restrictions = permit_mynetworks, reject_unknown_helo_hostname

The maximal number of lines in the Postfix SMTP server command history -before it is flushed upon receipt of EHLO, RSET, or end of DATA. +before it is flushed upon receipt of EHLO, RSET, or end of DATA. With +Postfix ≥ 3.4 releases after 20260805, the history is flushed +whenever it reaches the threshold. The notify_classes parameter +controls what command history may be reported in postmaster +notification email.

%PARAM smtpd_noop_commands diff --git a/postfix/proto/stop b/postfix/proto/stop index 671e3d6d2..8fc534cc4 100644 --- a/postfix/proto/stop +++ b/postfix/proto/stop @@ -1733,3 +1733,5 @@ optimizers resloop tokenized fortra +OpenAI +stateful diff --git a/postfix/proto/stop.double-history b/postfix/proto/stop.double-history index a42ef13ec..81e5e74c6 100644 --- a/postfix/proto/stop.double-history +++ b/postfix/proto/stop.double-history @@ -267,3 +267,5 @@ proto proto stop proto stop double cc support File smtpd smtpd c sendmail sendmail c postqueue postqueue c + OpenAI Security File smtpd smtpd c + by OpenAI Security File smtpd smtpd c diff --git a/postfix/proto/stop.spell-cc b/postfix/proto/stop.spell-cc index b6e5f5a8c..bee6c3842 100644 --- a/postfix/proto/stop.spell-cc +++ b/postfix/proto/stop.spell-cc @@ -1997,3 +1997,5 @@ jk unitext esmtpargs uncoded +desynchronization +xffffffff diff --git a/postfix/src/global/dict_mysql.c b/postfix/src/global/dict_mysql.c index 482e6180d..10cd35ed8 100644 --- a/postfix/src/global/dict_mysql.c +++ b/postfix/src/global/dict_mysql.c @@ -118,7 +118,8 @@ #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 50023 #define DICT_MYSQL_SSL_VERIFY_SERVER_CERT MYSQL_OPT_SSL_VERIFY_SERVER_CERT #elif MYSQL_VERSION_ID >= 80000 -#define DICT_MYSQL_SSL_VERIFY_SERVER_CERT MYSQL_OPT_SSL_MODE +/* 202607 OpenAI: MYSQL_OPT_SSL_MODE is an enum, not a bool. */ +#define DICT_MYSQL_SSL_MODE MYSQL_OPT_SSL_MODE #endif /* @@ -172,7 +173,7 @@ typedef struct { char *tls_CAfile; char *tls_CApath; char *tls_ciphers; -#if defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) +#if defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) || defined(DICT_MYSQL_SSL_MODE) int tls_verify_cert; #endif int require_result_set; @@ -602,6 +603,11 @@ static int plmysql_query(DICT_MYSQL *dict_mysql, */ static void plmysql_connect_single(DICT_MYSQL *dict_mysql, HOST *host) { +#if defined(DICT_MYSQL_SSL_MODE) + enum mysql_ssl_mode ssl_mode; + +#endif + if ((host->db = mysql_init(NULL)) == NULL) msg_fatal("dict_mysql: insufficient memory"); if (dict_mysql->option_file) @@ -629,7 +635,19 @@ static void plmysql_connect_single(DICT_MYSQL *dict_mysql, HOST *host) dict_mysql->tls_CAfile, dict_mysql->tls_CApath, dict_mysql->tls_ciphers); #endif -#if defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) +#if defined(DICT_MYSQL_SSL_MODE) + if (dict_mysql->tls_verify_cert != -1) { + /* MYSQL_OPT_SSL_MODE enum values are not Boolean values. */ + ssl_mode = dict_mysql->tls_verify_cert ? SSL_MODE_VERIFY_IDENTITY : + SSL_MODE_PREFERRED; + if (mysql_options(host->db, DICT_MYSQL_SSL_MODE, &ssl_mode) != 0) { + msg_warn("dict_mysql: could not set TLS mode for host %s: %s", + host->hostname, mysql_error(host->db)); + plmysql_down_host(host, dict_mysql->retry_interval); + return; + } + } +#elif defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) if (dict_mysql->tls_verify_cert != -1) mysql_options(host->db, DICT_MYSQL_SSL_VERIFY_SERVER_CERT, &dict_mysql->tls_verify_cert); @@ -705,7 +723,7 @@ static void mysql_parse_config(DICT_MYSQL *dict_mysql, const char *mysqlcf) dict_mysql->tls_CAfile = cfg_get_str(p, "tls_CAfile", NULL, 0, 0); dict_mysql->tls_CApath = cfg_get_str(p, "tls_CApath", NULL, 0, 0); dict_mysql->tls_ciphers = cfg_get_str(p, "tls_ciphers", NULL, 0, 0); -#if defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) +#if defined(DICT_MYSQL_SSL_VERIFY_SERVER_CERT) || defined(DICT_MYSQL_SSL_MODE) dict_mysql->tls_verify_cert = cfg_get_bool(p, "tls_verify_cert", -1); #endif dict_mysql->require_result_set = cfg_get_bool(p, "require_result_set", 1); diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 3267bc3b9..585b82df6 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 "20260804" +#define MAIL_RELEASE_DATE "20260805" #define MAIL_VERSION_NUMBER "3.12" #ifdef SNAPSHOT diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 56b947e9f..c8519a72b 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -6116,6 +6116,8 @@ static void smtpd_proto(SMTPD_STATE *state) for (;;) { if (state->flags & SMTPD_FLAG_HANGUP) break; + /* Flush the command history if it becomes large. */ + chat_reset(state, var_smtpd_hist_thrsh); smtp_stream_setup(state->client, var_smtpd_tmout, var_smtpd_req_deadline, 0); if (state->error_count >= var_smtpd_hard_erlim) { diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c index 30b7ddfb0..e4c1d3c6d 100644 --- a/postfix/src/tls/tls_server.c +++ b/postfix/src/tls/tls_server.c @@ -819,6 +819,11 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) const char *cipher_list; TLS_APPL_STATE *app_ctx = props->ctx; int log_mask; + /* 202607 OpenAI: isolate session tickets by master.cf service name. */ + EVP_MD_CTX *sessid_ctx_md = 0; + unsigned char sessid_ctx[EVP_MAX_MD_SIZE]; + unsigned int sessid_ctx_len; + static const char sessid_ctx_label[] = "Postfix/TLS serverid"; /* * Convert user loglevel to internal logmask. @@ -876,6 +881,29 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props) TLScontext->stream = props->stream; TLScontext->mdalg = props->mdalg; + /* + * The serverid already partitions stateful sessions in the tlsmgr + * session cache. Apply the same partition to stateless sessions; all + * services in one Postfix instance share the tlsmgr ticket keys. + */ + if (tls_digest_byname(LN_sha256, &sessid_ctx_md) == 0 + || EVP_DigestUpdate(sessid_ctx_md, sessid_ctx_label, + sizeof(sessid_ctx_label)) != 1 + || EVP_DigestUpdate(sessid_ctx_md, props->serverid, + strlen(props->serverid) + 1) != 1 + || EVP_DigestFinal_ex(sessid_ctx_md, sessid_ctx, &sessid_ctx_len) != 1 + || sessid_ctx_len > SSL_MAX_SID_CTX_LENGTH + || SSL_set_session_id_context(TLScontext->con, sessid_ctx, + sessid_ctx_len) != 1) { + msg_warn("Could not set TLS session ID context"); + tls_print_errors(); + if (sessid_ctx_md) + EVP_MD_CTX_destroy(sessid_ctx_md); + tls_free_context(TLScontext); + return (0); + } + EVP_MD_CTX_destroy(sessid_ctx_md); + if (!SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)) { msg_warn("Could not set application data for 'TLScontext->con'"); tls_print_errors();