nmh-workers
[Top] [All Lists]

[Nmh-workers] Alternative method for supporting TLS and latest patch set

2010-01-31 03:29:27
I decided to play with DeleGate, <http://www.delegate.org/delegate/>,
to see if it can be used a proxy so nmh can submit to MTAs that
require SSL/TLS and authentication.

It tooks some reading thru the docs, but I did get it to work.
Delegate runs as a real proxy server with protocol awareness,
so nmh using smtp mode can be used with it.  To get complete,
expected functionality, modifications to nmh was required, mainly
with whom.c so it can support the -port option so address
verification can work.

As for DeleGate, I start it as follows:

  delegated -P20025 +=$HOME/delegate/conf/gmail.conf

This says to listen for client requests on port 20025 and
to read additional configuration parameters from gmail.conf
(you can specify all parameters on command-line, but that gets
kind of ugly).  In my gmail.conf file, I have something
like the following:

  UMASK=002
  SERVER=smtp://smtp.gmail.com:587
  STLS=fsv
  AUTHORIZER=-list{localuser:MD5:964ba203464913531aa73b9f774b58f7}
  MYAUTH=username(_at_)gmail(_dot_)com:pass:smtp

[I changed username/password info to bogus values in this message]

The AUTHORIZER parameter is not required, but if specified, client
must (SASL) authenticate to the proxy.  This may be handy so other
users on they system cannot hijack your remote account.  [NOTE:
DeleGate actually supports multi-user access and authentication.
It is quite the swiss-army knife.]

The MYAUTH specifies the username/password to use for authenticating
to the remote server (smtp.gmail.com).

What follows is the latest diffs against nmh source.  They include
my previous changes supporting SASL when 'mts: sendmail' is specified
in mts.conf along with changes to whom so address checks will
work when non-25 port is used.

I can commit the changes into CVS, but would prefer feedback if
such changes are appropriate.

Index: etc/Makefile.in
===================================================================
RCS file: /sources/nmh/nmh/etc/Makefile.in,v
retrieving revision 1.16
diff -u -r1.16 Makefile.in
--- etc/Makefile.in     4 Mar 2006 22:14:18 -0000       1.16
+++ etc/Makefile.in     31 Jan 2010 09:06:13 -0000
@@ -100,18 +100,12 @@
        for path in $$INSTALL_FILES; do \
          file=`basename $$path`; \
          echo "Installing $$file..."; \
-         if [ -f $(DESTDIR)$(etcdir)/$$file ]; then \
-           mv $(DESTDIR)$(etcdir)/$$file $(DESTDIR)$(etcdir)/$$file.prev; \
-           $(INSTALL_DATA) $$path $(DESTDIR)$(etcdir)/$$file; \
-           if diff $(DESTDIR)$(etcdir)/$$file.prev $(DESTDIR)$(etcdir)/$$file; 
then \
-             rm $(DESTDIR)$(etcdir)/$$file.prev; \
+         if [ -f "$(DESTDIR)$(etcdir)/$$file" ]; then \
+           if cmp -s "$$path" "$(DESTDIR)$(etcdir)/$$file"; then \
+             echo "$(DESTDIR)$(etcdir)/$$file unchanged, skipped"; \
            else \
-             echo; \
-             echo "  Previous version of $$file saved as $$file.prev due\c";\
-             echo   " to diffs."; \
-             echo "  Please merge any local config changes into the new\c"; \
-             echo   " $$file."; \
-             echo; \
+             $(INSTALL_DATA) "$$path" "$(DESTDIR)$(etcdir)/$$file.dist"; \
+             echo "INFO: $(DESTDIR)$(etcdir)/$$file installed with .dist 
extension"; \
            fi; \
          else \
            $(INSTALL_DATA) $$path $(DESTDIR)$(etcdir)/$$file; \
Index: mts/smtp/smtp.c
===================================================================
RCS file: /sources/nmh/nmh/mts/smtp/smtp.c,v
retrieving revision 1.28
diff -u -r1.28 smtp.c
--- mts/smtp/smtp.c     21 Dec 2009 17:18:04 -0000      1.28
+++ mts/smtp/smtp.c     31 Jan 2010 09:06:14 -0000
@@ -128,7 +128,8 @@
  */
 static int smtp_init (char *, char *, char *, int, int, int, int, int, int,
                      char *, char *);
-static int sendmail_init (char *, char *, int, int, int, int, int);
+static int sendmail_init (char *, char *, int, int, int, int, int, int,
+                          char *, char *);
 
 static int rclient (char *, char *);
 static int sm_ierror (char *fmt, ...);
@@ -165,13 +166,13 @@
                          debug, onex, queued, sasl, saslmech, user);
     else
        return sendmail_init (client, server, watch, verbose,
-                             debug, onex, queued);
+                              debug, onex, queued, sasl, saslmech, user);
 }
 
 static int
 smtp_init (char *client, char *server, char *port, int watch, int verbose,
-          int debug, int onex, int queued, int sasl, char *saslmech,
-          char *user)
+          int debug, int onex, int queued,
+           int sasl, char *saslmech, char *user)
 {
 #ifdef CYRUS_SASL
     char *server_mechs;
@@ -299,8 +300,12 @@
 
 int
 sendmail_init (char *client, char *server, int watch, int verbose,
-               int debug, int onex, int queued)
+               int debug, int onex, int queued,
+               int sasl, char *saslmech, char *user)
 {
+#ifdef CYRUS_SASL
+    char *server_mechs;
+#endif /* CYRUS_SASL */
     int i, result, vecp;
     int pdi[2], pdo[2];
     char *vec[15];
@@ -426,6 +431,35 @@
                }
            }
 
+#ifdef CYRUS_SASL
+    /*
+     * If the user asked for SASL, then check to see if the SMTP server
+     * supports it.  Otherwise, error out (because the SMTP server
+     * might have been spoofed; we don't want to just silently not
+     * do authentication
+     */
+
+    if (sasl) {
+       if (! (server_mechs = EHLOset("AUTH"))) {
+           sm_end(NOTOK);
+           return sm_ierror("SMTP server does not support SASL");
+       }
+
+       if (saslmech && stringdex(saslmech, server_mechs) == -1) {
+           sm_end(NOTOK);
+           return sm_ierror("Requested SASL mech \"%s\" is not in the "
+                            "list of supported mechanisms:\n%s",
+                            saslmech, server_mechs);
+       }
+
+       if (sm_auth_sasl(user, saslmech ? saslmech : server_mechs,
+                        server) != RP_OK) {
+           sm_end(NOTOK);
+           return NOTOK;
+       }
+    }
+#endif /* CYRUS_SASL */
+
 #ifndef ZMAILER
            if (onex)
                smtalk (SM_HELO, "ONEX");
Index: sbr/mts.c
===================================================================
RCS file: /sources/nmh/nmh/sbr/mts.c,v
retrieving revision 1.6
diff -u -r1.6 mts.c
--- sbr/mts.c   16 Jan 2009 02:28:55 -0000      1.6
+++ sbr/mts.c   31 Jan 2010 09:06:14 -0000
@@ -33,6 +33,9 @@
  */
 static char *tailor_value (unsigned char *);
 static void getuserinfo (void);
+static const char *get_mtsconf_pathname(void);
+static const char *get_mtsuserconf_pathname(void);
+static void mts_read_conf_file (FILE *fp);
 
 /*
  * *mmdfldir and *uucpldir are the maildrop directories.  If maildrops
@@ -172,36 +175,22 @@
 void
 mts_init (char *name)
 {
-    unsigned char *bp;
-    char *cp, buffer[BUFSIZ];
-    struct bind *b;
+    const char *cp;
     FILE *fp;
     static int inited = 0;
 
-    if (inited++ || (fp = fopen (mtsconf, "r")) == NULL)
+    if (inited++ || (fp = fopen (get_mtsconf_pathname(), "r")) == NULL)
        return;
+    mts_read_conf_file(fp);
+    fclose (fp);
 
-    while (fgets (buffer, sizeof(buffer), fp)) {
-       if (!(cp = strchr(buffer, '\n')))
-           break;
-       *cp = 0;
-       if (*buffer == '#' || *buffer == '\0')
-           continue;
-       if (!(bp = strchr(buffer, ':')))
-           break;
-       *bp++ = 0;
-       while (isspace (*bp))
-           *bp++ = 0;
-
-       for (b = binds; b->keyword; b++)
-           if (!strcmp (buffer, b->keyword))
-               break;
-       if (b->keyword && (cp = tailor_value (bp)))
-           *b->value = cp;
+    cp = get_mtsuserconf_pathname();
+    if (cp != NULL &&
+            ((fp = fopen (get_mtsuserconf_pathname(), "r")) != NULL)) {
+        mts_read_conf_file(fp);
+        fclose (fp);
     }
 
-    fclose (fp);
-
     Everyone = atoi (everyone);
 
     if (strstr(masquerade, "draft_from") != NULL)
@@ -529,3 +518,50 @@
 
     return;
 }
+
+static const char*
+get_mtsconf_pathname (void)
+{
+    const char *cp = getenv ( "MHMTSCONF ");
+    if (cp != NULL && *cp != '\0') {
+        return cp;
+    }
+    return mtsconf;
+}
+
+static const char*
+get_mtsuserconf_pathname (void)
+{
+    const char *cp = getenv ( "MHMTSUSERCONF" );
+    if (cp != NULL && *cp != '\0') {
+        return cp;
+    }
+    return NULL;
+}
+
+static void
+mts_read_conf_file (FILE *fp)
+{
+    unsigned char *bp;
+    char *cp, buffer[BUFSIZ];
+    struct bind *b;
+
+    while (fgets (buffer, sizeof(buffer), fp)) {
+       if (!(cp = strchr(buffer, '\n')))
+           break;
+       *cp = 0;
+       if (*buffer == '#' || *buffer == '\0')
+           continue;
+       if (!(bp = strchr(buffer, ':')))
+           break;
+       *bp++ = 0;
+       while (isspace (*bp))
+           *bp++ = 0;
+
+       for (b = binds; b->keyword; b++)
+           if (!strcmp (buffer, b->keyword))
+               break;
+       if (b->keyword && (cp = tailor_value (bp)))
+           *b->value = cp;
+    }
+}
Index: uip/whom.c
===================================================================
RCS file: /sources/nmh/nmh/uip/whom.c,v
retrieving revision 1.4
diff -u -r1.4 whom.c
--- uip/whom.c  2 Jul 2002 22:09:15 -0000       1.4
+++ uip/whom.c  31 Jan 2010 09:06:14 -0000
@@ -13,6 +13,12 @@
 #include <h/signals.h>
 #include <signal.h>
 
+#ifndef CYRUS_SASL
+# define SASLminc(a) (a)
+#else /* CYRUS_SASL */
+# define SASLminc(a)  0
+#endif /* CYRUS_SASL */
+
 static struct swit switches[] = {
 #define        ALIASW              0
     { "alias aliasfile", 0 },
@@ -38,6 +44,14 @@
     { "server host", -6 },
 #define        SNOOPSW            11
     { "snoop", -5 },
+#define SASLSW             12
+    { "sasl", SASLminc(4) },
+#define SASLMECHSW         13
+    { "saslmech mechanism", SASLminc(-5) },
+#define USERSW             14
+    { "user username", SASLminc(-4) },
+#define PORTSW            15
+    { "port server port name/number", 4 },
     { NULL, 0 }
 };
 
@@ -88,6 +102,7 @@
                case CHKSW: 
                case NOCHKSW: 
                case SNOOPSW:
+               case SASLSW:
                    vec[vecp++] = --cp;
                    continue;
 
@@ -117,6 +132,9 @@
                case ALIASW: 
                case CLIESW: 
                case SERVSW: 
+               case USERSW:
+               case PORTSW:
+               case SASLMECHSW:
                    vec[vecp++] = --cp;
                    if (!(cp = *argp++) || *cp == '-')
                        adios (NULL, "missing argument to %s", argp[-2]);


_______________________________________________
Nmh-workers mailing list
Nmh-workers(_at_)nongnu(_dot_)org
http://lists.nongnu.org/mailman/listinfo/nmh-workers

<Prev in Thread] Current Thread [Next in Thread>
  • [Nmh-workers] Alternative method for supporting TLS and latest patch set, Earl Hood <=