]> diplodocus.org Git - nmh/blobdiff - mts/smtp/smtp.c
m_gmprot.c: Move interface to own file.
[nmh] / mts / smtp / smtp.c
index c7d95073fccbc8ec976babbbba28af8976ebb77c..8270b343a4796f7c8891a005a3e28269f50e0cfd 100644 (file)
@@ -5,12 +5,15 @@
  * complete copyright information.
  */
 
  * complete copyright information.
  */
 
-#include <h/mh.h>
+#include "h/mh.h"
+#include "sbr/r1bindex.h"
+#include "sbr/client.h"
+#include "sbr/error.h"
 #include "smtp.h"
 #include "smtp.h"
-#include <h/mts.h>
-#include <h/signals.h>
-#include <h/utils.h>
-#include <h/netsec.h>
+#include "h/mts.h"
+#include "h/signals.h"
+#include "h/utils.h"
+#include "h/netsec.h"
 
 #include <sys/socket.h>
 #include "sbr/base64.h"
 
 #include <sys/socket.h>
 #include "sbr/base64.h"
@@ -68,7 +71,7 @@ static int smhear (void);
 static char *EHLOset (char *) PURE;
 static int sm_sasl_callback(enum sasl_message_type, unsigned const char *,
                            unsigned int, unsigned char **, unsigned int *,
 static char *EHLOset (char *) PURE;
 static int sm_sasl_callback(enum sasl_message_type, unsigned const char *,
                            unsigned int, unsigned char **, unsigned int *,
-                           char **);
+                           void *, char **);
 
 int
 sm_init (char *client, char *server, char *port, int watch, int verbose,
 
 int
 sm_init (char *client, char *server, char *port, int watch, int verbose,
@@ -133,7 +136,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose,
 
     if (sasl) {
        if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
 
     if (sasl) {
        if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
-                                  &errstr) != OK)
+                                  NULL, &errstr) != OK)
            return sm_nerror(errstr);
     }
 
            return sm_nerror(errstr);
     }
 
@@ -295,7 +298,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl,
 
     if (sasl) {
        if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
 
     if (sasl) {
        if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback,
-                                  &errstr) != OK)
+                                  NULL, &errstr) != OK)
            return sm_nerror(errstr);
     }
 
            return sm_nerror(errstr);
     }
 
@@ -529,10 +532,14 @@ sm_waend (void)
 int
 sm_wtxt (char *buffer, int len)
 {
 int
 sm_wtxt (char *buffer, int len)
 {
-    int result;
+    int result, snoopstate;
+
+    if ((snoopstate = netsec_get_snoop(nsc)))
+       netsec_set_snoop(nsc, 0);
 
     result = sm_wstream (buffer, len);
 
 
     result = sm_wstream (buffer, len);
 
+    netsec_set_snoop(nsc, snoopstate);
     return result == NOTOK ? RP_BHST : RP_OK;
 }
 
     return result == NOTOK ? RP_BHST : RP_OK;
 }
 
@@ -540,9 +547,30 @@ sm_wtxt (char *buffer, int len)
 int
 sm_wtend (void)
 {
 int
 sm_wtend (void)
 {
+    int snoopstate;
+
+    if ((snoopstate = netsec_get_snoop(nsc)))
+       netsec_set_snoop(nsc, 0);
+
     if (sm_wstream(NULL, 0) == NOTOK)
        return RP_BHST;
 
     if (sm_wstream(NULL, 0) == NOTOK)
        return RP_BHST;
 
+    /*
+     * Because snoop output now happens at flush time, if we are using snoop
+     * we force an extra flush here.  While this introduces some extra network
+     * traffic, we're only doing it when snoop is in effect so I think it's
+     * reasonable.
+     */
+
+    if (snoopstate) {
+       char *errstr;
+       if (netsec_flush(nsc, &errstr) != OK) {
+           sm_nerror(errstr);
+           return RP_BHST;
+       }
+       netsec_set_snoop(nsc, snoopstate);
+    }
+
     switch (smtalk (SM_DOT + 3 * sm_addrs, ".")) {
        case 250: 
        case 251: 
     switch (smtalk (SM_DOT + 3 * sm_addrs, ".")) {
        case 250: 
        case 251: 
@@ -760,7 +788,7 @@ smhear (void)
     char **ehlo = EHLOkeys, *buffer;
 
     if (doingEHLO) {
     char **ehlo = EHLOkeys, *buffer;
 
     if (doingEHLO) {
-       static int at_least_once = 0;
+       static bool at_least_once;
 
        if (at_least_once) {
            char *ep;
 
        if (at_least_once) {
            char *ep;
@@ -770,7 +798,7 @@ smhear (void)
                free (ep);
            }
        } else {
                free (ep);
            }
        } else {
-           at_least_once = 1;
+           at_least_once = true;
        }
 
        ehlo = EHLOkeys;
        }
 
        ehlo = EHLOkeys;
@@ -947,11 +975,12 @@ EHLOset (char *s)
 static int
 sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
                 unsigned int indatalen, unsigned char **outdata,
 static int
 sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
                 unsigned int indatalen, unsigned char **outdata,
-                unsigned int *outdatalen, char **errstr)
+                unsigned int *outdatalen, void *context, char **errstr)
 {
     int rc, snoopoffset;
     char *mech, *line;
     size_t len;
 {
     int rc, snoopoffset;
     char *mech, *line;
     size_t len;
+    NMH_UNUSED(context);
 
     switch (mtype) {
     case NETSEC_SASL_START:
 
     switch (mtype) {
     case NETSEC_SASL_START:
@@ -974,15 +1003,19 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
            snoopoffset = 6 + strlen(mech);
            rc = netsec_printf(nsc, errstr, "AUTH %s %s\r\n", mech, b64data);
            free(b64data);
            snoopoffset = 6 + strlen(mech);
            rc = netsec_printf(nsc, errstr, "AUTH %s %s\r\n", mech, b64data);
            free(b64data);
-           netsec_set_snoop_callback(nsc, NULL, NULL);
        } else {
            rc = netsec_printf(nsc, errstr, "AUTH %s\r\n", mech);
        }
 
        } else {
            rc = netsec_printf(nsc, errstr, "AUTH %s\r\n", mech);
        }
 
-       if (rc != OK)
+       if (rc != OK) {
+           netsec_set_snoop_callback(nsc, NULL, NULL);
            return NOTOK;
            return NOTOK;
+       }
+
+       rc = netsec_flush(nsc, errstr);
+       netsec_set_snoop_callback(nsc, NULL, NULL);
 
 
-       if (netsec_flush(nsc, errstr) != OK)
+       if (rc != OK)
            return NOTOK;
 
        break;
            return NOTOK;
 
        break;
@@ -1036,14 +1069,16 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
            writeBase64raw(indata, indatalen, b64data);
            netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, NULL);
            rc = netsec_printf(nsc, errstr, "%s\r\n", b64data);
            writeBase64raw(indata, indatalen, b64data);
            netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, NULL);
            rc = netsec_printf(nsc, errstr, "%s\r\n", b64data);
-           netsec_set_snoop_callback(nsc, NULL, NULL);
            free(b64data);
        }
 
        if (rc != OK)
            return NOTOK;
 
            free(b64data);
        }
 
        if (rc != OK)
            return NOTOK;
 
-       if (netsec_flush(nsc, errstr) != OK)
+       rc = netsec_flush(nsc, errstr);
+       netsec_set_snoop_callback(nsc, NULL, NULL);
+
+       if (rc != OK)
            return NOTOK;
        break;
 
            return NOTOK;
        break;