BOFHCHECKHELO is too big restriction (I have many false positives), so
I decided to write a patch and add two new options for esmtpd end
esmtpd-ssl:
REJECTNONFQDNHELO set to 1 rejects all non fqdn HELOs, such as HELO sdfwew
REJECTUNKNOWNHELO set to 1 rejects all non resolvable to A or MX HELOs,
such as HELO there.is.no.such.name
The patch (to the latest available tar.gz, but compiles with some earlier
versions) is attached.
If it will be accepted and some more options (related to HELO checking)
will be needed, I can add them.
I will be thankful for any feedback.
Regards,
--
Grzegorz Janoszka
diff -urN courier-0.45.6.20040618-orig/courier/module.esmtp/esmtpd-ssl.dist.in
courier-0.45.6.20040618/courier/module.esmtp/esmtpd-ssl.dist.in
--- courier-0.45.6.20040618-orig/courier/module.esmtp/esmtpd-ssl.dist.in Sat
Apr 24 21:56:19 2004
+++ courier-0.45.6.20040618/courier/module.esmtp/esmtpd-ssl.dist.in Tue Jul 6
16:11:46 2004
@@ -44,6 +44,18 @@
BOFHNOVRFY=0
+##NAME: REJECTNONFQDNHELO:0
+#
+# Set REJECTNONFQDNHELO to 1 to reject all non fqdn HELOs
+
+REJECTNONFQDNHELO=1
+
+##NAME: REJECTUNKNOWNHELO:0
+#
+# Set REJECTUNKNOWNHELO to 1 to reject all non resolvable to A or MX HELOs
+
+REJECTUNKNOWNHELO=1
+
##NAME: NOADDMSGID:0
#
# The following environment variables keep Courier from adding
diff -urN courier-0.45.6.20040618-orig/courier/module.esmtp/esmtpd.dist.in
courier-0.45.6.20040618/courier/module.esmtp/esmtpd.dist.in
--- courier-0.45.6.20040618-orig/courier/module.esmtp/esmtpd.dist.in Tue May 11
02:48:14 2004
+++ courier-0.45.6.20040618/courier/module.esmtp/esmtpd.dist.in Tue Jul 6 16:11:29
2004
@@ -51,6 +51,18 @@
BOFHNOVRFY=0
+##NAME: REJECTNONFQDNHELO:0
+#
+# Set REJECTNONFQDNHELO to 1 to reject all non fqdn HELOs
+
+REJECTNONFQDNHELO=1
+
+##NAME: REJECTUNKNOWNHELO:0
+#
+# Set REJECTUNKNOWNHELO to 1 to reject all non resolvable to A or MX HELOs
+
+REJECTUNKNOWNHELO=1
+
##NAME: NOADDMSGID:0
#
# The following environment variables keep Courier from adding
diff -urN courier-0.45.6.20040618-orig/courier/submit.C
courier-0.45.6.20040618/courier/submit.C
--- courier-0.45.6.20040618-orig/courier/submit.C Sun Jun 6 18:04:34 2004
+++ courier-0.45.6.20040618/courier/submit.C Tue Jul 6 16:00:08 2004
@@ -504,8 +504,7 @@
const char *tcpremoteip=getenv("TCPREMOTEIP");
- if ((q=getenv("BOFHCHECKHELO")) != 0 && atoi(q) &&
- strcmp(module->name, "esmtp") == 0 && receivedfrommta &&
+ if (strcmp(module->name, "esmtp") == 0 && receivedfrommta &&
strncmp(receivedfrommta, "dns; ", 5) == 0 && tcpremoteip &&
getenv("RELAYCLIENT") == NULL)
{
@@ -519,81 +518,134 @@
memcpy(sbuf, receivedfrommta+5, s-receivedfrommta-5);
sbuf[s-receivedfrommta-5]=0;
- /*
- ** If HELO/EHLO does not match the IP address, query the MX
- ** records.
- */
- struct rfc1035_mxlist *mxlist, *mxp;
- int checked_a=0;
-
- if (ipcmp(sbuf, tcpremoteip)) switch
(rfc1035_mxlist_create(&rfc1035_default_resolver,
- sbuf,
&mxlist))
+ // Original code for checking HELO:
+ if ((q=getenv("BOFHCHECKHELO")) != 0 && atoi(q))
{
- case RFC1035_MX_OK:
-
- for (mxp=mxlist; mxp; mxp=mxp->next)
+ /*
+ ** If HELO/EHLO does not match the IP address,
+ ** query the MX records.
+ */
+ struct rfc1035_mxlist *mxlist, *mxp;
+ int checked_a=0;
+
+ if (ipcmp(sbuf, tcpremoteip))
+ switch
(rfc1035_mxlist_create(&rfc1035_default_resolver,
+ sbuf, &mxlist))
{
- RFC1035_ADDR addr;
- char buf[RFC1035_NTOABUFSIZE];
-
- if (rfc1035_sockaddrip(&mxp->address,
- sizeof(mxp->address),
- &addr))
- continue;
-
- rfc1035_ntoa(&addr, buf);
- if (ipcmp(buf, tcpremoteip) == 0)
- break;
+ case RFC1035_MX_OK:
- if (mxp->priority == -1)
- checked_a=1;
+ for (mxp=mxlist; mxp; mxp=mxp->next)
+ {
+ RFC1035_ADDR addr;
+ char buf[RFC1035_NTOABUFSIZE];
- }
- if (mxp)
- {
- rfc1035_mxlist_free(mxlist);
- free(sbuf);
- break;
- }
- rfc1035_mxlist_free(mxlist);
+ if (rfc1035_sockaddrip(&mxp->address,
+ sizeof(mxp->address),
+ &addr))
+ continue;
+
+ rfc1035_ntoa(&addr, buf);
+ if (ipcmp(buf, tcpremoteip) == 0)
+ break;
- if (!checked_a) /* No need to recheck A records */
- {
- int rc=checka(sbuf);
+ if (mxp->priority == -1)
+ checked_a=1;
- if (rc == 0)
+ }
+ if (mxp)
{
+ rfc1035_mxlist_free(mxlist);
free(sbuf);
break;
}
+ rfc1035_mxlist_free(mxlist);
- if (rc > 0) /* temp failure */
+ if (!checked_a) /* No need to recheck A records */
{
- cout << "417 DNS lookup on HELO "
- << sbuf
- << " failed. Try again later."
- << endl << flush;
- free(sbuf);
- return 1;
+ int rc=checka(sbuf);
+
+ if (rc == 0)
+ {
+ free(sbuf);
+ break;
+ }
+
+ if (rc > 0) /* temp failure */
+ {
+ cout << "417 DNS lookup on HELO "
+ << sbuf
+ << " failed. Try again later."
+ << endl << flush;
+ free(sbuf);
+ return 1;
+ }
}
+
+ cout << "517 HELO " << sbuf
+ << " does not match " <<
+ tcpremoteip << endl;
+ free(sbuf);
+ return 1;
+
+ case RFC1035_MX_HARDERR:
+ cout << "517 HELO " << sbuf <<
+ " does not exist." << endl;
+ return 1;
+ case RFC1035_MX_BADDNS:
+ cout << "517 RFC 1035 violation: recursive CNAME
records for " << sbuf << "." << endl;
+ return 1;
+ default:
+ cout << "417 DNS lookup on HELO " << sbuf <<
+ " failed. Try again later." <<
+ endl << flush;
+ return 1;
+ }
+ }
+
+ if ((q=getenv("REJECTNONFQDNHELO")) != 0 && atoi(q))
+ {
+ /*
+ ** Reject mail if HELO/EHLO sent is not fqdn nor IP
+ */
+
+ if(!strchr(sbuf, '.'))
+ {
+ cout << "517 HELO " << sbuf <<
+ " is not fully qualified domain name." << endl;
+ return 1;
}
- cout << "517 HELO " << sbuf
- << " does not match " << tcpremoteip << endl;
- free(sbuf);
- return 1;
-
- case RFC1035_MX_HARDERR:
- cout << "517 HELO " << sbuf << " does not exist." << endl;
- return 1;
- case RFC1035_MX_BADDNS:
- cout << "517 RFC 1035 violation: recursive CNAME records for "
<< sbuf << "." << endl;
- return 1;
- default:
- cout << "417 DNS lookup on HELO " << sbuf <<
- " failed. Try again later." << endl << flush;
- return 1;
}
+
+ if ((q=getenv("REJECTUNKNOWNHELO")) != 0 && atoi(q))
+ {
+ /*
+ ** Reject mail if HELO/EHLO sent is not resolvable
+ */
+
+ struct rfc1035_mxlist *mxlist;
+
+ if (ipcmp(sbuf, tcpremoteip))
+ switch
(rfc1035_mxlist_create(&rfc1035_default_resolver,
+ sbuf, &mxlist))
+ {
+ case RFC1035_MX_OK:
+ break;
+ case RFC1035_MX_HARDERR:
+ cout << "517 HELO " << sbuf <<
+ " does not exist." << endl;
+ return 1;
+ case RFC1035_MX_BADDNS:
+ cout << "517 RFC 1035 violation: recursive CNAME
records for " << sbuf << "." << endl;
+ return 1;
+ default:
+ cout << "417 DNS lookup on HELO " << sbuf <<
+ " failed. Try again later." <<
+ endl << flush;
+ return 1;
+ }
+ }
+
}
buf.ReleaseBuffer(-1);