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);

Reply via email to