SMTP session reuse bugfix
Claus Assmann <[email protected]> Tue, 1 Mar 2016 06:56:21 -0800 (PST)
| Newsgroups | gmane.mail.sendmail.announce |
|---|---|
| Message-ID | <[email protected]> |
--mojUlQ0s9EVzWg2t
Content-Type: multipart/mixed; boundary="RnlQjJ0d97Da+TV1"
Content-Disposition: inline
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
If sendmail tried to reuse an SMTP session which had already been
closed by the server, then the connection cache could have invalid
information about the session. One possible consequence was that
STARTTLS was not used even if offered.
The problem can be fixed by either:
- applying the attached patch (for 8.15.2), also available at
ftp://ftp.sendmail.org/pub/sendmail/8.15.2.mci.p0
ftp://ftp.sendmail.org/pub/sendmail/8.15.2.mci.p0.sig
- or disabling the connection cache:
define(`confMCI_CACHE_SIZE', `0')
The problem can be mitigated by setting at least one of these options:
- using a very short timeout:
define(`confMCI_CACHE_TIMEOUT', `5s')
- sorting the queue by hosts:
define(`confQUEUE_SORT_ORDER', `Host')
To apply this patch, cd to the source code directory, then rebuild
and reinstall sendmail.
cd sendmail-8.15.2
patch < 8.15.2.mci.p0
Note: This issue is fixed in sendmail snapshot 8.16.0.16 (or newer)
for those who would like to test upcoming releases.
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="8.15.2.mci.p1"
Content-Transfer-Encoding: quoted-printable
diff -ru sendmail-/deliver.c sendmail/deliver.c
--- sendmail-/deliver.c 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/deliver.c 2016-02-29 06:02:06.000000000 -0800
@@ -6274,8 +6274,7 @@
tlslogerr(LOG_WARNING, "client");
}
=20
- SSL_free(clt_ssl);
- clt_ssl =3D NULL;
+ SM_SSL_FREE(clt_ssl);
return EX_SOFTWARE;
}
mci->mci_ssl =3D clt_ssl;
@@ -6287,8 +6286,7 @@
return EX_OK;
=20
/* failure */
- SSL_free(clt_ssl);
- clt_ssl =3D NULL;
+ SM_SSL_FREE(clt_ssl);
return EX_SOFTWARE;
}
/*
@@ -6309,7 +6307,7 @@
=20
if (!bitset(MCIF_TLSACT, mci->mci_flags))
return EX_OK;
- r =3D endtls(mci->mci_ssl, "client");
+ r =3D endtls(&mci->mci_ssl, "client");
mci->mci_flags &=3D ~MCIF_TLSACT;
return r;
}
diff -ru sendmail-/macro.c sendmail/macro.c
--- sendmail-/macro.c 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/macro.c 2016-02-29 06:02:06.000000000 -0800
@@ -362,6 +362,33 @@
}
=20
/*
+** MACTABCLEAR -- clear entire macro table
+**
+** Parameters:
+** mac -- Macro table.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** clears entire mac structure including rpool pointer!
+*/
+
+void
+mactabclear(mac)
+ MACROS_T *mac;
+{
+ int i;
+
+ if (mac->mac_rpool =3D=3D NULL)
+ {
+ for (i =3D 0; i < MAXMACROID; i++)
+ SM_FREE_CLR(mac->mac_table[i]);
+ }
+ memset((char *) mac, '\0', sizeof(*mac));
+}
+
+/*
** MACDEFINE -- bind a macro name to a value
**
** Set a macro to a value, with fancy storage management.
diff -ru sendmail-/mci.c sendmail/mci.c
--- sendmail-/mci.c 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/mci.c 2016-02-29 06:02:06.000000000 -0800
@@ -25,6 +25,7 @@
int, bool));
static bool mci_load_persistent __P((MCI *));
static void mci_uncache __P((MCI **, bool));
+static void mci_clear __P((MCI *));
static int mci_lock_host_statfile __P((MCI *));
static int mci_read_persistent __P((SM_FILE_T *, MCI *));
=20
@@ -253,6 +254,7 @@
SM_FREE_CLR(mci->mci_status);
SM_FREE_CLR(mci->mci_rstatus);
SM_FREE_CLR(mci->mci_heloname);
+ mci_clear(mci);
if (mci->mci_rpool !=3D NULL)
{
sm_rpool_free(mci->mci_rpool);
@@ -315,6 +317,41 @@
}
=20
/*
+** MCI_CLEAR -- clear mci
+**
+** Parameters:
+** mci -- the connection to clear.
+**
+** Returns:
+** none.
+*/
+
+static void
+mci_clear(mci)
+ MCI *mci;
+{
+ if (mci =3D=3D NULL)
+ return;
+
+ mci->mci_maxsize =3D 0;
+ mci->mci_min_by =3D 0;
+ mci->mci_deliveries =3D 0;
+#if SASL
+ if (bitset(MCIF_AUTHACT, mci->mci_flags))
+ sasl_dispose(&mci->mci_conn);
+#endif
+#if STARTTLS
+ if (bitset(MCIF_TLSACT, mci->mci_flags) && mci->mci_ssl !=3D NULL)
+ SM_SSL_FREE(mci->mci_ssl);
+#endif
+
+ /* which flags to preserve? */
+ mci->mci_flags &=3D MCIF_CACHED;
+ mactabclear(&mci->mci_macro);
+}
+
+
+/*
** MCI_GET -- get information about a particular host
**
** Parameters:
@@ -419,6 +456,7 @@
mci->mci_errno =3D 0;
mci->mci_exitstat =3D EX_OK;
}
+ mci_clear(mci);
}
=20
return mci;
diff -ru sendmail-/sendmail.h sendmail/sendmail.h
--- sendmail-/sendmail.h 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/sendmail.h 2016-02-29 06:02:06.000000000 -0800
@@ -1186,6 +1186,7 @@
#define macid(name) macid_parse(name, NULL)
extern char *macname __P((int));
extern char *macvalue __P((int, ENVELOPE *));
+extern void mactabclear __P((MACROS_T *));
extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char=
*, char *, ADDRESS *, char **));
extern int rscap __P((char *, char *, char *, ENVELOPE *, char ***, char *=
, int));
extern void setclass __P((int, char *));
@@ -2002,7 +2003,15 @@
extern void setclttls __P((bool));
extern bool initsrvtls __P((bool));
extern int tls_get_info __P((SSL *, bool, char *, MACROS_T *, bool));
-extern int endtls __P((SSL *, char *));
+#define SM_SSL_FREE(ssl) \
+ do { \
+ if (ssl !=3D NULL) \
+ { \
+ SSL_free(ssl); \
+ ssl =3D NULL; \
+ } \
+ } while (0)
+extern int endtls __P((SSL **, char *));
extern void tlslogerr __P((int, const char *));
=20
=20
diff -ru sendmail-/srvrsmtp.c sendmail/srvrsmtp.c
--- sendmail-/srvrsmtp.c 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/srvrsmtp.c 2016-02-29 06:02:06.000000000 -0800
@@ -2122,8 +2122,7 @@
if (get_tls_se_options(e, srv_ssl, true) !=3D 0)
{
message("454 4.3.3 TLS not available: error setting options");
- SSL_free(srv_ssl);
- srv_ssl =3D NULL;
+ SM_SSL_FREE(srv_ssl);
goto tls_done;
}
=20
@@ -2145,8 +2144,7 @@
SSL_set_wfd(srv_ssl, wfd) <=3D 0)
{
message("454 4.3.3 TLS not available: error set fd");
- SSL_free(srv_ssl);
- srv_ssl =3D NULL;
+ SM_SSL_FREE(srv_ssl);
goto tls_done;
}
if (!smtps)
@@ -2188,8 +2186,7 @@
tlslogerr(LOG_WARNING, "server");
}
tls_ok_srv =3D false;
- SSL_free(srv_ssl);
- srv_ssl =3D NULL;
+ SM_SSL_FREE(srv_ssl);
=20
/*
** according to the next draft of
@@ -3416,7 +3413,7 @@
/* shutdown TLS connection */
if (tls_active)
{
- (void) endtls(srv_ssl, "server");
+ (void) endtls(&srv_ssl, "server");
tls_active =3D false;
}
#endif /* STARTTLS */
diff -ru sendmail-/tls.c sendmail/tls.c
--- sendmail-/tls.c 2016-02-29 06:01:55.000000000 -0800
+++ sendmail/tls.c 2016-02-29 06:02:06.000000000 -0800
@@ -1624,7 +1624,7 @@
** ENDTLS -- shutdown secure connection
**
** Parameters:
-** ssl -- SSL connection information.
+** pssl -- pointer to TLS session context
** side -- server/client (for logging).
**
** Returns:
@@ -1632,12 +1632,16 @@
*/
=20
int
-endtls(ssl, side)
- SSL *ssl;
+endtls(pssl, side)
+ SSL **pssl;
char *side;
{
int ret =3D EX_OK;
+ SSL *ssl;
=20
+ SM_REQUIRE(pssl !=3D NULL);
+ ret =3D EX_OK;
+ ssl =3D *pssl;
if (ssl !=3D NULL)
{
int r;
@@ -1703,8 +1707,7 @@
ret =3D EX_SOFTWARE;
}
# endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x=
0090602fL */
- SSL_free(ssl);
- ssl =3D NULL;
+ SM_SSL_FREE(*pssl);
}
return ret;
}
--RnlQjJ0d97Da+TV1--
--mojUlQ0s9EVzWg2t
Content-Type: application/pgp-signature; name="signature.asc"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAEBAgAGBQJW1QssAAoJEG1M0ZQp+wPekqYIAKhU5UPudbWXqEAn9yc76Qmk
af1eIpcMk2eFKkh7VYsOhRFMl/fPrmQfoz7DzTGDKyNuOyEtTflTpSmYGMQhTFhM
V8KTf0MYULagv3raQlcd38rhUbQ3vO6negfAgJeEpRbme3qevLV3il+phv5sYU67
wGO/75IMayaoME0SJvC0iGM9XcU7BDUjEncZDeobUDfsE0ndPZONAlTtHB202mvA
LGF3CdG5vlMoqvtVtoYYB6Gh1zqeHrzakB1rIKqmgOgFtVnFQVFS7A7rbrIRXnSf
XktNn3bq6oEKL3xOCFz30CMwSeovLmADK/wDg72g6BN/W+/ERZjh+esFsv/EaB8=
=h1F/
-----END PGP SIGNATURE-----
--mojUlQ0s9EVzWg2t--