tupas/smtp: fix TLS connections (#163) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit de43b1629d008aa6cdf4f6beb2b06e3859616a3e
 (DIR) parent 9c38253d1d8bae2f821d30fb8216783d2eb76f87
 (HTM) Author: Zach Scott <ethhics@gmail.com>
       Date:   Wed, 14 Nov 2018 05:24:07 +0000
       
       upas/smtp: fix TLS connections (#163)
       
       Both `upas/nfs` and `upas/smtp` call the currently broken `tlsClient()`
       from libsec. This commit copies a fix from upas/nfs into upas/smtp.
       
       In `imapdial()`, upas/nfs replaces a process call for tlsClient with
       `stunnel3` when not on Plan 9. upas/smtp calls tlsClient directly
       as a function, so imapdial was copied into mxdial.c as `smtpdial()`,
       and tlsClient+dial replaced with a call to smtpdial.
       Diffstat:
         M src/cmd/upas/smtp/mxdial.c          |      48 +++++++++++++++++++++++++++++++
         M src/cmd/upas/smtp/smtp.c            |       1 +
       
       2 files changed, 49 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/upas/smtp/mxdial.c b/src/cmd/upas/smtp/mxdial.c
       t@@ -2,6 +2,7 @@
        #include <ndb.h>
        #include "smtp.h"        /* to publish dial_string_parse */
        #include <ip.h>
       +#include <thread.h>
        
        enum
        {
       t@@ -27,6 +28,45 @@ static int        callmx(DS*, char*, char*);
        static void expand_meta(DS *ds);
        extern int        cistrcmp(char*, char*);
        
       +/* Taken from imapdial, replaces tlsclient call with stunnel */
       +static int
       +smtpdial(char *server)
       +{
       +        int p[2];
       +        int fd[3];
       +        char *tmp;
       +        char *fpath;
       +
       +        if(pipe(p) < 0)
       +                return -1;
       +        fd[0] = dup(p[0], -1);
       +        fd[1] = dup(p[0], -1);
       +        fd[2] = dup(2, -1);
       +#ifdef PLAN9PORT
       +        tmp = smprint("%s:587", server);
       +        fpath = searchpath("stunnel3");
       +        if (!fpath) {
       +                werrstr("stunnel not found. it is required for tls support.");
       +                return -1;
       +        }
       +        if(threadspawnl(fd, fpath, "stunnel", "-n", "smtp" , "-c", "-r", tmp, nil) < 0) {
       +#else
       +        tmp = smprint("tcp!%s!587", server);
       +        if(threadspawnl(fd, "/bin/tlsclient", "tlsclient", tmp, nil) < 0){
       +#endif
       +                free(tmp);
       +                close(p[0]);
       +                close(p[1]);
       +                close(fd[0]);
       +                close(fd[1]);
       +                close(fd[2]);
       +                return -1;
       +        }
       +        free(tmp);
       +        close(p[0]);
       +        return p[1];
       +}
       +
        int
        mxdial(char *addr, char *ddomain, char *gdomain)
        {
       t@@ -100,13 +140,21 @@ callmx(DS *ds, char *dest, char *domain)
                }
                /* dial each one in turn */
                for(i = 0; i < nmx; i++){
       +#ifdef PLAN9PORT
       +                snprint(addr, sizeof(addr), "%s", mx[i].host);
       +#else
                        snprint(addr, sizeof(addr), "%s!%s!%s", ds->proto,
                                mx[i].host, ds->service);
       +#endif
                        if(debug)
                                fprint(2, "mxdial trying %s (%d)\n", addr, i);
                        atnotify(timeout, 1);
                        alarm(10*1000);
       +#ifdef PLAN9PORT
       +                fd = smtpdial(addr);
       +#else
                        fd = dial(addr, 0, 0, 0);
       +#endif
                        alarm(0);
                        atnotify(timeout, 0);
                        if(fd >= 0)
 (DIR) diff --git a/src/cmd/upas/smtp/smtp.c b/src/cmd/upas/smtp/smtp.c
       t@@ -467,6 +467,7 @@ hello(char *me, int encrypted)
                        }
        
                ehlo = 1;
       +        encrypted = 1;
          Again:
                if(ehlo)
                        dBprint("EHLO %s\r\n", me);