1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
diff -pur orig/sendmail-8.14.3/sendmail/milter.c sendmail-8.14.3/sendmail/milter.c
--- orig/sendmail-8.14.3/sendmail/milter.c 2007-06-06 20:26:12.000000000 +0300
+++ sendmail-8.14.3/sendmail/milter.c 2009-08-31 11:49:59.750070622 +0300
@@ -3951,29 +3951,30 @@ milter_connect(hostname, addr, e, state)
milter_per_connection_check(e);
/*
+ * There used to be the following comment here:
+ *
** SMFIR_REPLYCODE can't work with connect due to
** the requirements of SMTP. Therefore, ignore the
** reply code text but keep the state it would reflect.
+ *
+ * However, this is wrong. RFC2821, section 3.9 states, that:
+ *
+ * "An SMTP server MUST NOT intentionally close the connection except:
+ * [...]
+ * - After detecting the need to shut down the SMTP service and
+ * returning a 421 response code. This response code can be issued
+ * after the server receives any command or, if necessary,
+ * asynchronously from command receipt (on the assumption that the
+ * client will receive it after the next command is issued)."
+ *
+ * I see no reason why a milter cannot supply its own textual
+ * explanation in xxfi_connect. So, instead of blindly filtering
+ * out the user-supllied response, I return it to smtp(). The latter
+ * is crafted so that it will graciously abort the connection, if
+ * the response begins with 421, giving the user-supplied textual
+ * message, and will proceed with nullserver otherwise.
+ * --gray
*/
-
- if (*state == SMFIR_REPLYCODE)
- {
- if (response != NULL &&
- *response == '4')
- {
- if (strncmp(response, "421 ", 4) == 0)
- *state = SMFIR_SHUTDOWN;
- else
- *state = SMFIR_TEMPFAIL;
- }
- else
- *state = SMFIR_REJECT;
- if (response != NULL)
- {
- sm_free(response); /* XXX */
- response = NULL;
- }
- }
return response;
}
diff -pur orig/sendmail-8.14.3/sendmail/srvrsmtp.c sendmail-8.14.3/sendmail/srvrsmtp.c
--- orig/sendmail-8.14.3/sendmail/srvrsmtp.c 2008-03-31 19:32:13.000000000 +0300
+++ sendmail-8.14.3/sendmail/srvrsmtp.c 2009-09-23 16:07:56.604677429 +0300
@@ -957,6 +957,8 @@ smtp(nullserver, d_flags, e)
{
char state;
char *response;
+ static char greetcodebuf[4];
+ size_t len;
q = macvalue(macid("{client_name}"), e);
SM_ASSERT(q != NULL || OpMode == MD_SMTP);
@@ -965,7 +967,36 @@ smtp(nullserver, d_flags, e)
response = milter_connect(q, RealHostAddr, e, &state);
switch (state)
{
- case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
+ case SMFIR_REPLYCODE:
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: connect: host=%s, addr=%s, reject=%s",
+ peerhostname,
+ anynet_ntoa(&RealHostAddr),
+ response);
+ len = strlen(response);
+ if (len >= 3) {
+ /* RFC 2821, Section 3.9 */
+ nullserver = newstr(response);
+ if (memcmp(response, "421", 3) == 0) {
+ message(response);
+ /* arrange to ignore send list */
+ e->e_sendqueue = NULL;
+ sm_syslog(LOG_INFO, e->e_id,
+ "host=%s, addr=%s, reject=%s",
+ peerhostname,
+ anynet_ntoa(&RealHostAddr),
+ response);
+ goto doquit;
+ } else {
+ memcpy(greetcodebuf, response, 3);
+ greetcodebuf[3] = 0;
+ greetcode = greetcodebuf;
+ break;
+ }
+ }
+ /* FALL THROUGH */
+
case SMFIR_REJECT:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
|