summaryrefslogtreecommitdiff
path: root/src/qmail-smtpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-smtpd.c')
-rw-r--r--src/qmail-smtpd.c1437
1 files changed, 891 insertions, 546 deletions
diff --git a/src/qmail-smtpd.c b/src/qmail-smtpd.c
index f312c11..6d2d0d4 100644
--- a/src/qmail-smtpd.c
+++ b/src/qmail-smtpd.c
@@ -1,93 +1,102 @@
#include <unistd.h>
-#include "wildmat.h"
-#include "buffer.h"
-#include "stralloc.h"
-#include "genalloc.h"
+
#include "alloc.h"
-#include "auto_qmail.h"
-#include "control.h"
-#include "received.h"
+#include "base64.h"
+#include "buffer.h"
+#include "byte.h"
+#include "case.h"
+#include "cdbread.h"
+#include "close.h"
#include "constmap.h"
-#include "logmsg.h"
-#include "ipme.h"
+#include "env.h"
+#include "exit.h"
#include "fd.h"
-#include "ip.h"
-#include "qmail.h"
-#include "str.h"
#include "fmt.h"
+#include "genalloc.h"
+#include "ip.h"
+#include "logmsg.h"
+#include "open.h"
#include "scan.h"
-#include "byte.h"
-#include "case.h"
-#include "env.h"
+#include "sig.h"
+#include "str.h"
+#include "stralloc.h"
+#include "timeout.h"
+#include "wait.h"
+
+#include "auto_qmail.h"
+#include "commands.h"
+#include "control.h"
+#include "dns.h"
+#include "ipme.h"
+#include "mfrules.h"
#include "now.h"
-#include "exit.h"
+#include "qmail.h"
#include "rcpthosts.h"
+#include "received.h"
#include "recipients.h"
-#include "mfrules.h"
-#include "tls_start.h"
#include "smtpdlog.h"
-#include "timeout.h"
-#include "commands.h"
-#include "cdbread.h"
-#include "dns.h"
-#include "wait.h"
-#include "sig.h"
-#include "close.h"
-#include "open.h"
-#include "base64.h"
#include "spf.h"
+#include "tls_start.h"
+#include "wildmat.h"
/** @file qmail-smtpd.c -- authenticating ESMTP/ESMTPS server
@brief requires sslserver or tcpserver */
#define PAM111421
-#define AUTHSLEEP 5
+#define AUTHSLEEP 5
#define PORT_SMTPS "465"
-#define MIMETYPE_LEN 9
-#define LOADER_LEN 5
+#define MIMETYPE_LEN 9
+#define LOADER_LEN 5
#define BASE64MESSAGE "content-transfer-encoding: base64"
-#define FDIN 0
-#define FDOUT 1
-#define FDLOG 2
-#define FDAUTH 3
+#define FDIN 0
+#define FDOUT 1
+#define FDLOG 2
+#define FDAUTH 3
#define BUFFER_SIZE 1024
-#define MAXHOPS 100
+#define MAXHOPS 100
unsigned long databytes = 0;
int timeout = 1200;
int modssl_info();
-ssize_t safewrite(int fd,char *buf,int len)
+ssize_t safewrite(int fd, char *buf, int len)
{
int r;
- r = timeoutwrite(timeout,fd,buf,len);
+ r = timeoutwrite(timeout, fd, buf, len);
if (r <= 0) _exit(1);
return r;
}
-ssize_t saferead(int fd,char *buf,int len)
+ssize_t saferead(int fd, char *buf, int len)
{
int r;
flush();
- r = timeoutread(timeout,fd,buf,len);
- if (r == -1) if (errno == ETIMEDOUT) die_alarm();
+ r = timeoutread(timeout, fd, buf, len);
+ if (r == -1)
+ if (errno == ETIMEDOUT) die_alarm();
if (r <= 0) die_read();
return r;
}
char inbuf[BUFFER_SIZE];
-buffer bi = BUFFER_INIT(saferead,FDIN,inbuf,sizeof(inbuf));
+buffer bi = BUFFER_INIT(saferead, FDIN, inbuf, sizeof(inbuf));
-char outbuf[BUFFER_SIZE/2];
-buffer bo = BUFFER_INIT(safewrite,FDOUT,outbuf,sizeof(outbuf));
+char outbuf[BUFFER_SIZE / 2];
+buffer bo = BUFFER_INIT(safewrite, FDOUT, outbuf, sizeof(outbuf));
char logbuf[256];
-buffer bl = BUFFER_INIT(write,FDLOG,logbuf,sizeof(logbuf));
+buffer bl = BUFFER_INIT(write, FDLOG, logbuf, sizeof(logbuf));
-void flush() { buffer_flush(&bo); } // this triggers writing to STDIO
-void out(char *s) { buffer_puts(&bo,s); }
+void flush()
+{
+ buffer_flush(&bo);
+} // this triggers writing to STDIO
+void out(char *s)
+{
+ buffer_puts(&bo, s);
+}
stralloc sa = {0};
ipalloc ia = {0};
@@ -96,7 +105,7 @@ int bhelocheck(void);
/* this file is too long -------------------------------------- DNS helper */
-int dnsq(char *arg,char type)
+int dnsq(char *arg, char type)
{
unsigned int random;
int at;
@@ -106,26 +115,27 @@ int dnsq(char *arg,char type)
len = str_len(arg);
if (len < 1) return r;
- if (arg[len-1] == ' ') len--; /* trailing blank */
+ if (arg[len - 1] == ' ') len--; /* trailing blank */
if (len < 1) return r;
- at = byte_rchr(arg,len,'@');
+ at = byte_rchr(arg, len, '@');
if (at < len) {
- if (!stralloc_copyb(&sa,arg + at + 1,len - at - 1)) die_nomem();
- } else
- if (!stralloc_copyb(&sa,arg,len)) die_nomem();
+ if (!stralloc_copyb(&sa, arg + at + 1, len - at - 1)) die_nomem();
+ } else if (!stralloc_copyb(&sa, arg, len))
+ die_nomem();
random = now() + (getpid() << 16);
- switch (type) { /* Common for IPv4 and IPv6 */
- case 'A': r = dns_ip(&ia,&sa); break;
- case 'M': r = dns_mxip(&ia,&sa,random); break;
+ switch (type) { /* Common for IPv4 and IPv6 */
+ case 'A': r = dns_ip(&ia, &sa); break;
+ case 'M': r = dns_mxip(&ia, &sa, random); break;
}
switch (r) {
case DNS_ERR: out("451 DNS temporary failure (#4.3.0)\r\n"); return -1;
case DNS_MEM: die_nomem();
- default: if (ia.len) return 0;
+ default:
+ if (ia.len) return 0;
}
return 1;
@@ -137,8 +147,8 @@ static stralloc greeting = {0};
void smtp_greet(char *code)
{
- buffer_puts(&bo,code);
- buffer_put(&bo,greeting.s,greeting.len);
+ buffer_puts(&bo, code);
+ buffer_put(&bo, greeting.s, greeting.len);
}
void smtp_help()
{
@@ -146,7 +156,10 @@ void smtp_help()
}
void smtp_quit()
{
- smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
+ smtp_greet("221 ");
+ out("\r\n");
+ flush();
+ _exit(0);
}
char *remoteip;
@@ -172,33 +185,47 @@ char *badhelocond;
void dohelo(char *helo)
{
- if (!stralloc_copys(&helohost,helo)) die_nomem();
+ if (!stralloc_copys(&helohost, helo)) die_nomem();
if (!stralloc_0(&helohost)) die_nomem();
- fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0;
+ fakehelo = case_diffs(remotehost, helohost.s) ? helohost.s : 0;
if (helocheck) {
if (str_len(helocheck) == 1) {
switch (*helocheck) {
- case '=': flagbadhelo = bhelocheck();
- if (fakehelo) { flagdnshelo = 1; badhelocond = "="; }
- break;
- case 'A': flagbadhelo = bhelocheck();
- if (flagbadhelo == 0) { flagdnshelo = dnsq(helohost.s,'A'); badhelocond = "A"; }
- break;
- case 'M': flagbadhelo = bhelocheck();
- if (flagbadhelo == 0) { flagdnshelo = dnsq(helohost.s,'M'); badhelocond = "M"; }
- break;
- case '.': flagbadhelo = bhelocheck();
- if (!str_len(helo)) flagbadhelo = -2;
- break;
- case '!': if (!str_len(helo)) flagbadhelo = -2;
- break;
+ case '=':
+ flagbadhelo = bhelocheck();
+ if (fakehelo) {
+ flagdnshelo = 1;
+ badhelocond = "=";
+ }
+ break;
+ case 'A':
+ flagbadhelo = bhelocheck();
+ if (flagbadhelo == 0) {
+ flagdnshelo = dnsq(helohost.s, 'A');
+ badhelocond = "A";
+ }
+ break;
+ case 'M':
+ flagbadhelo = bhelocheck();
+ if (flagbadhelo == 0) {
+ flagdnshelo = dnsq(helohost.s, 'M');
+ badhelocond = "M";
+ }
+ break;
+ case '.':
+ flagbadhelo = bhelocheck();
+ if (!str_len(helo)) flagbadhelo = -2;
+ break;
+ case '!':
+ if (!str_len(helo)) flagbadhelo = -2;
+ break;
}
} else {
- flagbadhelo = bhelocheck();
+ flagbadhelo = bhelocheck();
}
if (flagbadhelo == -3) flagbadhelo = 0;
}
- if (!env_put("HELOHOST",helohost.s)) die_nomem();
+ if (!env_put("HELOHOST", helohost.s)) die_nomem();
}
int liphostok = 0;
@@ -208,7 +235,7 @@ int bmfok = 0;
stralloc bmf = {0};
struct constmap mapbmf;
-int brtok= 0;
+int brtok = 0;
stralloc brt = {0};
struct constmap mapbrt;
@@ -220,16 +247,17 @@ static struct cdb cdbm;
static struct cdb cdbl;
static int fdbmt;
-int flagmimetype = 0; /* 1: white; 2: cdb; 3: white+cdb; 4: !relay+white; 6: !relay+white+cdb; -1: found in cdb; -2: found white */
+int flagmimetype =
+ 0; /* 1: white; 2: cdb; 3: white+cdb; 4: !relay+white; 6: !relay+white+cdb; -1: found in cdb; -2: found white */
char *badmimeinit;
static int fdblt;
-int flagloadertype = 0; /* 1: cdb; 2: !relay+cdb; -1: found in cdb */
+int flagloadertype = 0; /* 1: cdb; 2: !relay+cdb; -1: found in cdb */
char *badloaderinit;
static int fdmav;
int flagmav = 0;
-int localmf = 0; /* 1: domainpart->rcpthosts; 2: ->mailformrules; 3: ->remoteinfo; 4: ->DN(Email) */
+int localmf = 0; /* 1: domainpart->rcpthosts; 2: ->mailformrules; 3: ->remoteinfo; 4: ->DN(Email) */
char *localmfcheck;
char *mfdnscheck;
@@ -247,12 +275,14 @@ int greylist = 0;
stralloc pgbind = {0};
char *auth;
-int smtpauth = 0; /* -1:Cert 0:none 1:login/plain 2:cram 3:login/plain/cram 11:must_login/plain 12:must_2 13:must_3 */
+int smtpauth =
+ 0; /* -1:Cert 0:none 1:login/plain 2:cram 3:login/plain/cram 11:must_login/plain 12:must_2 13:must_3 */
int seenauth = 0; /* 1:ESMTPA 2:~CLIENTDN */
stralloc authmethod = {0};
-int starttls = 0; /* -1:TLS 0:none 1:STARTTLS 2:require_STARTTLS 3:relay_if_CLIENTDN 4:require_+_relay_if_CLIENTDN */
-int seentls = 0; /* 1:~STARTTLS 2:~TLS 3:~CLIENTDN */
+int starttls =
+ 0; /* -1:TLS 0:none 1:STARTTLS 2:require_STARTTLS 3:relay_if_CLIENTDN 4:require_+_relay_if_CLIENTDN */
+int seentls = 0; /* 1:~STARTTLS 2:~TLS 3:~CLIENTDN */
char *ucspitls = 0;
char *tlsversion;
char *cipher;
@@ -279,39 +309,47 @@ void setup()
flagip6 = 1; // GCC 10 implicit int declarition if global var
if (control_init() == -1) die_control();
- if (control_rldef(&greeting,"control/smtpgreeting",1,(char *) 0) != 1)
- die_control();
- liphostok = control_rldef(&liphost,"control/localiphost",1,(char *) 0);
+ if (control_rldef(&greeting, "control/smtpgreeting", 1, (char *)0) != 1) die_control();
+ liphostok = control_rldef(&liphost, "control/localiphost", 1, (char *)0);
if (liphostok == -1) die_control();
- if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
+ if (control_readint(&timeout, "control/timeoutsmtpd") == -1) die_control();
if (timeout <= 0) timeout = 1;
if (rcpthosts_init() == -1) die_control();
if (recipients_init() == -1) die_control();
- bmfok = control_readfile(&bmf,"control/badmailfrom",0);
+ bmfok = control_readfile(&bmf, "control/badmailfrom", 0);
if (bmfok == -1) die_control();
if (bmfok)
- if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
+ if (!constmap_init(&mapbmf, bmf.s, bmf.len, 0)) die_nomem();
- brtok = control_readfile(&brt,"control/badrcptto",0);
+ brtok = control_readfile(&brt, "control/badrcptto", 0);
if (brtok == -1) die_control();
if (brtok)
- if (!constmap_init(&mapbrt,brt.s,brt.len,0)) die_nomem();
+ if (!constmap_init(&mapbrt, brt.s, brt.len, 0)) die_nomem();
- if (control_readint(&databytes,"control/databytes") == -1) die_control();
+ if (control_readint(&databytes, "control/databytes") == -1) die_control();
x = env_get("DATABYTES");
- if (x) { scan_ulong(x,&u); databytes = u; }
+ if (x) {
+ scan_ulong(x, &u);
+ databytes = u;
+ }
if (!(databytes + 1)) --databytes;
- if (!stralloc_copys(&protocol,"ESMTP")) die_nomem(); /* RFC 3848 */
- remoteip = env_get("TCP6REMOTEIP"); /* compactified IPv6 */
- if (!remoteip) remoteip = env_get("TCPREMOTEIP"); /* allow other tcpserver/sslserver */
- if (remoteip && (str_chr(remoteip,':') < str_len(remoteip))) {
- if (byte_equal(remoteip,7,V4MAPPREFIX))
- { remoteip = remoteip + 7; flagip6 = 0; }
- } else flagip6 = 0;
- if (!remoteip) { remoteip = "unknown"; flagip6 = -1; }
+ if (!stralloc_copys(&protocol, "ESMTP")) die_nomem(); /* RFC 3848 */
+ remoteip = env_get("TCP6REMOTEIP"); /* compactified IPv6 */
+ if (!remoteip) remoteip = env_get("TCPREMOTEIP"); /* allow other tcpserver/sslserver */
+ if (remoteip && (str_chr(remoteip, ':') < str_len(remoteip))) {
+ if (byte_equal(remoteip, 7, V4MAPPREFIX)) {
+ remoteip = remoteip + 7;
+ flagip6 = 0;
+ }
+ } else
+ flagip6 = 0;
+ if (!remoteip) {
+ remoteip = "unknown";
+ flagip6 = -1;
+ }
local = env_get("TCP6LOCALHOST");
if (!local) local = env_get("TCPLOCALHOST");
if (!local) local = env_get("TCP6LOCALIP");
@@ -327,35 +365,44 @@ void setup()
if (!remoteinfo) remoteinfo = env_get("TCPREMOTEINFO");
relayclient = env_get("RELAYCLIENT");
- if (!case_diffs(localport,PORT_SMTPS)) {
+ if (!case_diffs(localport, PORT_SMTPS)) {
if (!modssl_info()) die_starttls();
starttls = -1;
}
mfdnscheck = env_get("MFDNSCHECK");
x = env_get("MAXRECIPIENTS");
- if (x) { scan_ulong(x,&u); maxrcptcount = u; };
+ if (x) {
+ scan_ulong(x, &u);
+ maxrcptcount = u;
+ };
if (!(maxrcptcount + 1)) --maxrcptcount;
helocheck = env_get("HELOCHECK");
if (helocheck) {
- badhelook = control_readfile(&badhelo,"control/badhelo",0);
+ badhelook = control_readfile(&badhelo, "control/badhelo", 0);
if (badhelook == -1) die_control();
if (badhelook)
- if (!constmap_init(&mapbhlo,badhelo.s,badhelo.len,0)) die_nomem();
+ if (!constmap_init(&mapbhlo, badhelo.s, badhelo.len, 0)) die_nomem();
}
x = env_get("TARPITCOUNT");
- if (x) { scan_ulong(x,&u); tarpitcount = u; };
+ if (x) {
+ scan_ulong(x, &u);
+ tarpitcount = u;
+ };
x = env_get("TARPITDELAY");
- if (x) { scan_ulong(x,&u); tarpitdelay = u; };
+ if (x) {
+ scan_ulong(x, &u);
+ tarpitdelay = u;
+ };
x = env_get("POSTGREY"); // RFC 6647
if (x) {
- if (case_diffs(x,"-")) {
+ if (case_diffs(x, "-")) {
greylist = 1;
- if (!stralloc_copys(&pgbind,x)) die_nomem();
- if (!stralloc_append(&pgbind,"")) die_nomem();
+ if (!stralloc_copys(&pgbind, x)) die_nomem();
+ if (!stralloc_append(&pgbind, "")) die_nomem();
}
}
@@ -365,7 +412,7 @@ void setup()
if (str_len(localmfcheck) == 1 && *localmfcheck == '!') {
localmf = 2;
fdmav = open_read("control/mailfromrules.cdb");
- if (fdmav == -1 ) localmf = 1;
+ if (fdmav == -1) localmf = 1;
}
if (str_len(localmfcheck) == 1 && *localmfcheck == '=') {
localmf = 3;
@@ -386,7 +433,7 @@ void setup()
if (*badmimeinit == '+') flagmimetype = 4;
}
}
- if (fdbmt != -1 ) flagmimetype = flagmimetype + 2;
+ if (fdbmt != -1) flagmimetype = flagmimetype + 2;
}
badloaderinit = env_get("BADLOADERTYPE");
@@ -398,7 +445,7 @@ void setup()
flagloadertype = 1;
if (*badloaderinit == '+') flagloadertype = 2;
fdblt = open_read("control/badloadertypes.cdb");
- if (fdblt == -1 ) flagloadertype = 0;
+ if (fdblt == -1) flagloadertype = 0;
}
}
}
@@ -408,67 +455,69 @@ void setup()
auth = env_get("SMTPAUTH");
if (auth) {
smtpauth = 1;
- if (!case_diffs(auth,"-")) smtpauth = 0;
- if (!case_diffs(auth,"!")) smtpauth = 11;
- if (case_starts(auth,"cram")) smtpauth = 2;
- if (case_starts(auth,"+cram")) smtpauth = 3;
- if (case_starts(auth,"!cram")) smtpauth = 12;
- if (case_starts(auth,"!+cram")) smtpauth = 13;
+ if (!case_diffs(auth, "-")) smtpauth = 0;
+ if (!case_diffs(auth, "!")) smtpauth = 11;
+ if (case_starts(auth, "cram")) smtpauth = 2;
+ if (case_starts(auth, "+cram")) smtpauth = 3;
+ if (case_starts(auth, "!cram")) smtpauth = 12;
+ if (case_starts(auth, "!+cram")) smtpauth = 13;
}
if (!seentls) {
ucspitls = env_get("UCSPITLS");
if (ucspitls) {
starttls = 1;
- if (!case_diffs(ucspitls,"-")) starttls = 0;
- if (!case_diffs(ucspitls,"!")) starttls = 2;
- if (!case_diffs(ucspitls,"?")) starttls = 3;
- if (!case_diffs(ucspitls,"@")) starttls = 4;
+ if (!case_diffs(ucspitls, "-")) starttls = 0;
+ if (!case_diffs(ucspitls, "!")) starttls = 2;
+ if (!case_diffs(ucspitls, "?")) starttls = 3;
+ if (!case_diffs(ucspitls, "@")) starttls = 4;
}
}
delivermailto = env_get("DELIVERTO");
if (delivermailto) {
- if (!stralloc_cats(&mailto,delivermailto)) die_nomem();
- if (!stralloc_cats(&mailto," ")) die_nomem();
+ if (!stralloc_cats(&mailto, delivermailto)) die_nomem();
+ if (!stralloc_cats(&mailto, " ")) die_nomem();
}
rblsmtpd = env_get("RBLSMTPD");
if (rblsmtpd) {
- if (!stralloc_cats(&rblinfo,rblsmtpd)) die_nomem();
+ if (!stralloc_cats(&rblinfo, rblsmtpd)) die_nomem();
if (!stralloc_0(&rblinfo)) die_nomem();
}
x = env_get("SPF");
- if (x) { scan_ulong(x,&u); flagspf = u; }
+ if (x) {
+ scan_ulong(x, &u);
+ flagspf = u;
+ }
if (flagspf < 0 || flagspf > 6) die_control();
if (flagspf) {
- r = control_readline(&spflocalrules,"control/spflocalrules");
+ r = control_readline(&spflocalrules, "control/spflocalrules");
if (r == -1) die_control();
if (!stralloc_0(&spflocalrules)) die_nomem();
- if (control_rldef(&spfexplain,"control/spfexplain",0,SPF_DEFEXP) == -1) die_control();
+ if (control_rldef(&spfexplain, "control/spfexplain", 0, SPF_DEFEXP) == -1) die_control();
if (!stralloc_0(&spfexplain)) die_nomem();
}
x = env_get("UTF8");
if (x) flagutf8 = 1;
- if (!stralloc_copys(&helohost,"")) die_nomem(); // helohost is initially empty
+ if (!stralloc_copys(&helohost, "")) die_nomem(); // helohost is initially empty
if (!stralloc_0(&helohost)) die_nomem();
fakehelo = 0;
-
}
void auth_info(char *method)
{
- if (!env_put("AUTHPROTOCOL",method)) die_nomem();
- if (!env_put("AUTHUSER",remoteinfo)) die_nomem();
- if (!env_unset("TCPREMOTEINFO")) die_read();
- if (!env_put("TCPREMOTEINFO",remoteinfo)) die_nomem();
- if (!env_unset("TCP6REMOTEINFO")) die_read();
- if (!env_put("TCP6REMOTEINFO",remoteinfo)) die_nomem();
-
- if (!stralloc_append(&protocol,"A")) die_nomem();
+ if (!env_put("AUTHPROTOCOL", method)) die_nomem();
+ if (!env_put("AUTHUSER", remoteinfo)) die_nomem();
+ if (!env_unset("TCPREMOTEINFO")) die_read();
+ if (!env_put("TCPREMOTEINFO", remoteinfo)) die_nomem();
+ if (!env_unset("TCP6REMOTEINFO")) die_read();
+ if (!env_put("TCP6REMOTEINFO", remoteinfo)) die_nomem();
+
+ if (!stralloc_append(&protocol, "A")) die_nomem();
}
int modssl_info()
@@ -483,7 +532,8 @@ int modssl_info()
cipherused = env_get("SSL_CIPHER_USEKEYSIZE");
if (!cipherused) cipherused = "unknown";
clientdn = env_get("SSL_CLIENT_S_DN");
- if (!clientdn) clientdn = "none";
+ if (!clientdn)
+ clientdn = "none";
else {
seentls = 3;
seenauth = 2;
@@ -491,26 +541,26 @@ int modssl_info()
relayclient = "";
}
- if (!stralloc_copys(&tlsinfo,tlsversion)) die_nomem();
- if (!stralloc_cats(&tlsinfo,": ")) die_nomem();
- if (!stralloc_cats(&tlsinfo,cipher)) die_nomem();
- if (!stralloc_cats(&tlsinfo," [")) die_nomem();
- if (!stralloc_cats(&tlsinfo,cipherused)) die_nomem();
- if (!stralloc_cats(&tlsinfo,"/")) die_nomem();
- if (!stralloc_cats(&tlsinfo,cipherperm)) die_nomem();
- if (!stralloc_cats(&tlsinfo,"] \n")) die_nomem();
- if (!stralloc_cats(&tlsinfo," DN=")) die_nomem();
- if (!stralloc_cats(&tlsinfo,clientdn)) die_nomem();
+ if (!stralloc_copys(&tlsinfo, tlsversion)) die_nomem();
+ if (!stralloc_cats(&tlsinfo, ": ")) die_nomem();
+ if (!stralloc_cats(&tlsinfo, cipher)) die_nomem();
+ if (!stralloc_cats(&tlsinfo, " [")) die_nomem();
+ if (!stralloc_cats(&tlsinfo, cipherused)) die_nomem();
+ if (!stralloc_cats(&tlsinfo, "/")) die_nomem();
+ if (!stralloc_cats(&tlsinfo, cipherperm)) die_nomem();
+ if (!stralloc_cats(&tlsinfo, "] \n")) die_nomem();
+ if (!stralloc_cats(&tlsinfo, " DN=")) die_nomem();
+ if (!stralloc_cats(&tlsinfo, clientdn)) die_nomem();
if (!stralloc_0(&tlsinfo)) die_nomem();
- if (!stralloc_append(&protocol,"S")) die_nomem();
+ if (!stralloc_append(&protocol, "S")) die_nomem();
if (seentls == 3 && starttls == 4) {
clientcn = env_get("SSL_CLIENT_S_DN_CN");
- remoteinfo = clientcn ? clientcn : clientdn;
+ remoteinfo = clientcn ? clientcn : clientdn;
dnemail = env_get("SSL_CLIENT_S_DN_Email");
if (!dnemail) dnemail = "unknown";
- if (!stralloc_cats(&authmethod,"cert")) die_nomem();
+ if (!stralloc_cats(&authmethod, "cert")) die_nomem();
auth_info(authmethod.s);
}
return 1;
@@ -545,50 +595,52 @@ int addrparse(char *arg)
int flagquoted;
terminator = '>';
- i = str_chr(arg,'<');
+ i = str_chr(arg, '<');
if (arg[i])
arg += i + 1;
else
return 0;
/* strip source route */
- if (*arg == '@') while (*arg) if (*arg++ == ':') break;
+ if (*arg == '@')
+ while (*arg)
+ if (*arg++ == ':') break;
- if (!stralloc_copys(&addr,"")) die_nomem();
+ if (!stralloc_copys(&addr, "")) die_nomem();
flagesc = 0;
flagquoted = 0;
for (i = 0; ch = arg[i]; ++i) { /* copy arg to addr, stripping quotes */
if (flagesc) {
- if (!stralloc_append(&addr,&ch)) die_nomem();
+ if (!stralloc_append(&addr, &ch)) die_nomem();
flagesc = 0;
- }
- else {
+ } else {
if (!flagquoted && (ch == terminator)) break;
switch (ch) {
case '\\': flagesc = 1; break;
- case '"': flagquoted = !flagquoted; break;
- default: if (!stralloc_append(&addr,&ch)) die_nomem();
+ case '"': flagquoted = !flagquoted; break;
+ default:
+ if (!stralloc_append(&addr, &ch)) die_nomem();
}
}
}
/* could check for termination failure here, but why bother? */
- if (!stralloc_append(&addr,"")) die_nomem();
+ if (!stralloc_append(&addr, "")) die_nomem();
if (liphostok) {
- i = byte_rchr(addr.s,addr.len,'@');
+ i = byte_rchr(addr.s, addr.len, '@');
if (i < addr.len) /* if not, partner should go read rfc 821 */
if (addr.s[i + 1] == '[') {
- if (byte_rchr(addr.s + i + 2,addr.len - i - 2,':') < str_len(addr.s)) { /* @[IPv6::] */
- if (!addr.s[i + 1 + ip6_scanbracket(addr.s + i + 1,(char *)&ip6s.d)])
- if (ipme_is6(&ip6s)) {
- addr.len = i + 1;
- if (!stralloc_cat(&addr,&liphost)) die_nomem();
- }
- } else { /* @[IPv4] */
- if (!addr.s[i + 1 + ip4_scanbracket(addr.s + i + 1,(char *)&ip4s.d)])
+ if (byte_rchr(addr.s + i + 2, addr.len - i - 2, ':') < str_len(addr.s)) { /* @[IPv6::] */
+ if (!addr.s[i + 1 + ip6_scanbracket(addr.s + i + 1, (char *)&ip6s.d)])
+ if (ipme_is6(&ip6s)) {
+ addr.len = i + 1;
+ if (!stralloc_cat(&addr, &liphost)) die_nomem();
+ }
+ } else { /* @[IPv4] */
+ if (!addr.s[i + 1 + ip4_scanbracket(addr.s + i + 1, (char *)&ip4s.d)])
if (ipme_is4(&ip4s)) {
addr.len = i + 1;
- if (!stralloc_cat(&addr,&liphost)) die_nomem();
+ if (!stralloc_cat(&addr, &liphost)) die_nomem();
}
}
}
@@ -607,19 +659,19 @@ int bhelocheck()
char subvalue;
if (badhelook && helohost.len > 1) { /* helohost! */
- if (!stralloc_copyb(&eddr,helohost.s,helohost.len - 1)) die_nomem();
- if (!stralloc_append(&eddr,"!")) die_nomem();
+ if (!stralloc_copyb(&eddr, helohost.s, helohost.len - 1)) die_nomem();
+ if (!stralloc_append(&eddr, "!")) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- if (constmap(&mapbhlo,eddr.s,eddr.len - 1)) return -3;
+ if (constmap(&mapbhlo, eddr.s, eddr.len - 1)) return -3;
- if (constmap(&mapbhlo,helohost.s,helohost.len - 1)) return -1;
+ if (constmap(&mapbhlo, helohost.s, helohost.len - 1)) return -1;
i = 0;
for (j = 0; j < badhelo.len; ++j)
if (!badhelo.s[j]) {
subvalue = badhelo.s[i] != '!';
if (!subvalue) i++;
- if ((k != subvalue) && wildmat(helohost.s,badhelo.s + i)) k = subvalue;
+ if ((k != subvalue) && wildmat(helohost.s, badhelo.s + i)) k = subvalue;
i = j + 1;
}
return k;
@@ -639,74 +691,75 @@ int bmfcheck()
if (bmfok && mailfrom.len > 1) {
rlen = str_len(remotehost);
- at = byte_rchr(mailfrom.s,mailfrom.len,'@');
+ at = byte_rchr(mailfrom.s, mailfrom.len, '@');
-/* '?' enhanced address to skip all other tests including MFDNSCHECK */
+ /* '?' enhanced address to skip all other tests including MFDNSCHECK */
- if (!stralloc_copys(&eddr,"?")) die_nomem();
- if (!stralloc_cat(&eddr,&mailfrom)) die_nomem();
- case_lowerb(eddr.s,eddr.len);
- if (constmap(&mapbmf,eddr.s,eddr.len - 1)) return -110;
+ if (!stralloc_copys(&eddr, "?")) die_nomem();
+ if (!stralloc_cat(&eddr, &mailfrom)) die_nomem();
+ case_lowerb(eddr.s, eddr.len);
+ if (constmap(&mapbmf, eddr.s, eddr.len - 1)) return -110;
-/* '+' extended address for none-RELAYCLIENTS */
+ /* '+' extended address for none-RELAYCLIENTS */
if (at && !relayclient) {
- if (!stralloc_copyb(&eddr,mailfrom.s,mailfrom.len - 1)) die_nomem();
- if (!stralloc_append(&eddr,"+")) die_nomem();
+ if (!stralloc_copyb(&eddr, mailfrom.s, mailfrom.len - 1)) die_nomem();
+ if (!stralloc_append(&eddr, "+")) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- case_lowerb(eddr.s,eddr.len);
- if (constmap(&mapbmf,eddr.s + at,eddr.len - at - 1)) return -5;
+ case_lowerb(eddr.s, eddr.len);
+ if (constmap(&mapbmf, eddr.s + at, eddr.len - at - 1)) return -5;
}
-/* '-' extended address from UNKNOWN */
+ /* '-' extended address from UNKNOWN */
- if (at && !case_diffs(remotehost,"unknown")) {
- if (!stralloc_copyb(&eddr,mailfrom.s,mailfrom.len - 1)) die_nomem();
- if (!stralloc_append(&eddr,"-")) die_nomem();
+ if (at && !case_diffs(remotehost, "unknown")) {
+ if (!stralloc_copyb(&eddr, mailfrom.s, mailfrom.len - 1)) die_nomem();
+ if (!stralloc_append(&eddr, "-")) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- case_lowerb(eddr.s,eddr.len);
- if (constmap(&mapbmf,eddr.s + at,eddr.len - at - 1)) return -4;
+ case_lowerb(eddr.s, eddr.len);
+ if (constmap(&mapbmf, eddr.s + at, eddr.len - at - 1)) return -4;
}
-/* '=' extended address for WELLKNOWN senders */
+ /* '=' extended address for WELLKNOWN senders */
- else if (at && rlen >= mailfrom.len - at - 1) {
+ else if (at && rlen >= mailfrom.len - at - 1)
+ {
dlen = mailfrom.len - at - 2;
- if (!stralloc_copyb(&eddr,mailfrom.s,mailfrom.len - 1)) die_nomem();
- if (!stralloc_append(&eddr,"=")) die_nomem();
+ if (!stralloc_copyb(&eddr, mailfrom.s, mailfrom.len - 1)) die_nomem();
+ if (!stralloc_append(&eddr, "=")) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- case_lowerb(eddr.s,eddr.len);
- if (str_diffn(remotehost + rlen - dlen,eddr.s + at + 1,dlen))
- if (constmap(&mapbmf,eddr.s + at,eddr.len - at - 1)) return -3;
+ case_lowerb(eddr.s, eddr.len);
+ if (str_diffn(remotehost + rlen - dlen, eddr.s + at + 1, dlen))
+ if (constmap(&mapbmf, eddr.s + at, eddr.len - at - 1)) return -3;
-/* '~' extended address for MISMATCHED Domains */
+ /* '~' extended address for MISMATCHED Domains */
- if (case_diffrs(remotehost,mailfrom.s + at + 1)) {
+ if (case_diffrs(remotehost, mailfrom.s + at + 1)) {
j = 0;
do {
- if (!stralloc_copys(&eddr,"~")) die_nomem();
- if (!stralloc_cats(&eddr,remotehost + j)) die_nomem();
+ if (!stralloc_copys(&eddr, "~")) die_nomem();
+ if (!stralloc_cats(&eddr, remotehost + j)) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- if (constmap(&mapbmf,eddr.s,eddr.len - 1)) return -2;
- j = byte_chr(remotehost + j,rlen - j,'.') + j + 1;
+ if (constmap(&mapbmf, eddr.s, eddr.len - 1)) return -2;
+ j = byte_chr(remotehost + j, rlen - j, '.') + j + 1;
} while (j > 0 && rlen - j > 0);
}
}
-/* Standard */
+ /* Standard */
- if (constmap(&mapbmf,mailfrom.s,mailfrom.len - 1)) return -1;
+ if (constmap(&mapbmf, mailfrom.s, mailfrom.len - 1)) return -1;
if (at && at < mailfrom.len)
- if (constmap(&mapbmf,mailfrom.s + at,mailfrom.len - at - 1)) return -1;
+ if (constmap(&mapbmf, mailfrom.s + at, mailfrom.len - at - 1)) return -1;
-/* Wildmating */
+ /* Wildmating */
i = k = 0;
for (j = 0; j < bmf.len; ++j) {
if (!bmf.s[j]) {
subvalue = bmf.s[i] != '!';
if (!subvalue) i++;
- if ((k != subvalue) && wildmat(mailfrom.s,bmf.s + i)) k = subvalue;
+ if ((k != subvalue) && wildmat(mailfrom.s, bmf.s + i)) k = subvalue;
i = j + 1;
}
}
@@ -724,20 +777,20 @@ int brtcheck()
char subvalue;
if (brtok) {
- if (constmap(&mapbrt,addr.s,addr.len - 1)) return -2;
+ if (constmap(&mapbrt, addr.s, addr.len - 1)) return -2;
- int at = byte_rchr(addr.s,addr.len,'@');
+ int at = byte_rchr(addr.s, addr.len, '@');
if (at < addr.len)
- if (constmap(&mapbrt,addr.s + at,addr.len - at - j)) return -1;
+ if (constmap(&mapbrt, addr.s + at, addr.len - at - j)) return -1;
-/* '#' enhanced address to consider invalid rcptto addresses for none-relayclients */
+ /* '#' enhanced address to consider invalid rcptto addresses for none-relayclients */
if (!relayclient) {
- if (!stralloc_copys(&eddr,"+")) die_nomem();
- if (!stralloc_cat(&eddr,&addr)) die_nomem();
+ if (!stralloc_copys(&eddr, "+")) die_nomem();
+ if (!stralloc_cat(&eddr, &addr)) die_nomem();
if (!stralloc_0(&eddr)) die_nomem();
- case_lowerb(eddr.s,eddr.len);
- if (constmap(&mapbmf,eddr.s,eddr.len - 1)) return 110;
+ case_lowerb(eddr.s, eddr.len);
+ if (constmap(&mapbmf, eddr.s, eddr.len - 1)) return 110;
}
i = 0;
@@ -745,7 +798,7 @@ int brtcheck()
if (!brt.s[j]) {
subvalue = brt.s[i] != '!';
if (!subvalue) i++;
- if ((k != subvalue) && wildmat(addr.s,brt.s + i)) k = subvalue;
+ if ((k != subvalue) && wildmat(addr.s, brt.s + i)) k = subvalue;
i = j + 1;
}
return k;
@@ -756,7 +809,7 @@ int brtcheck()
int addrallowed(char *arg)
{
int r;
- r = rcpthosts(arg,str_len(arg));
+ r = rcpthosts(arg, str_len(arg));
if (r == -1) die_control();
return r;
}
@@ -764,7 +817,7 @@ int addrallowed(char *arg)
int rcptallowed()
{
int r;
- r = recipients(addr.s,str_len(addr.s));
+ r = recipients(addr.s, str_len(addr.s));
#ifdef PAM111421
if (r == 111) die_recipients();
#endif
@@ -780,24 +833,23 @@ int localaddr(char *mf)
int mflen;
mflen = str_len(mf);
- if (mflen < 1 ) return 0;
+ if (mflen < 1) return 0;
if (localmf == 4) {
- if (!case_diffs(dnemail,mf)) return 2;
+ if (!case_diffs(dnemail, mf)) return 2;
return -4;
}
if (localmf == 3) {
- if (!case_diffs(remoteinfo,mf)) return 2;
+ if (!case_diffs(remoteinfo, mf)) return 2;
return -3;
- }
- else if (localmf == 2)
- return mfrules(fdmav,remoteip,remotehost,remoteinfo,mf);
+ } else if (localmf == 2)
+ return mfrules(fdmav, remoteip, remotehost, remoteinfo, mf);
else {
if (str_len(localmfcheck) > 1) {
- case_lowerb(localmfcheck,str_len(localmfcheck));
- at = byte_rchr(mf,mflen,'@');
+ case_lowerb(localmfcheck, str_len(localmfcheck));
+ at = byte_rchr(mf, mflen, '@');
if (at < mflen)
- if (!str_diffn(localmfcheck,mf + at + 1,mflen - at - 1)) return 2;
+ if (!str_diffn(localmfcheck, mf + at + 1, mflen - at - 1)) return 2;
}
if (addrallowed(mf)) return 3;
return -2;
@@ -808,47 +860,59 @@ int spf_check(int flag6)
{
int r;
- if (mailfrom.len <= 1) { flagspf = 0; return 0; }
+ if (mailfrom.len <= 1) {
+ flagspf = 0;
+ return 0;
+ }
DNS_INIT
- r = spf_query(remoteip,helohost.s,mailfrom.s,local,flag6);
+ r = spf_query(remoteip, helohost.s, mailfrom.s, local, flag6);
if (r == SPF_NOMEM) die_nomem();
if (!stralloc_0(&spfinfo)) die_nomem();
switch (r) {
case SPF_ME:
- case SPF_OK:
- if (!env_put("SPFRESULT","pass")) die_nomem();
+ case SPF_OK:
+ if (!env_put("SPFRESULT", "pass")) die_nomem();
flagspf = 10;
break;
case SPF_LOOP:
- case SPF_ERROR:
+ case SPF_ERROR:
case SPF_SYNTAX:
case SPF_EXHAUST:
- if (!env_put("SPFRESULT","error")) die_nomem();
- if (flagspf < 2) { flagspf = 0; break; }
+ if (!env_put("SPFRESULT", "error")) die_nomem();
+ if (flagspf < 2) {
+ flagspf = 0;
+ break;
+ }
out("451 SPF lookup failure (#4.3.0)\r\n");
return -1;
- case SPF_NONE:
- if (!env_put("SPFRESULT","none")) die_nomem();
+ case SPF_NONE:
+ if (!env_put("SPFRESULT", "none")) die_nomem();
flagspf = 0;
break;
case SPF_UNKNOWN:
- if (!env_put("SPFRESULT","unknown")) die_nomem();
- if (flagspf < 6) break;
- else return 4;
+ if (!env_put("SPFRESULT", "unknown")) die_nomem();
+ if (flagspf < 6)
+ break;
+ else
+ return 4;
case SPF_NEUTRAL:
- if (!env_put("SPFRESULT","neutral")) die_nomem();
- if (flagspf < 5) break;
- else return 3;
+ if (!env_put("SPFRESULT", "neutral")) die_nomem();
+ if (flagspf < 5)
+ break;
+ else
+ return 3;
case SPF_SOFTFAIL:
- if (!env_put("SPFRESULT","softfail")) die_nomem();
- if (flagspf < 4) break;
- else return 2;
+ if (!env_put("SPFRESULT", "softfail")) die_nomem();
+ if (flagspf < 4)
+ break;
+ else
+ return 2;
case SPF_FAIL:
- if (!env_put("SPFRESULT","fail")) die_nomem();
+ if (!env_put("SPFRESULT", "fail")) die_nomem();
if (flagspf < 3) break;
- if (!spf_parse(&spfbounce,spfexpmsg.s,expdomain.s)) die_nomem();
+ if (!spf_parse(&spfbounce, spfexpmsg.s, expdomain.s)) die_nomem();
return 1;
}
@@ -862,32 +926,36 @@ int mailfrom_size(char *arg)
unsigned long r;
unsigned long sizebytes = 0;
- scan_ulong(arg,&r);
+ scan_ulong(arg, &r);
sizebytes = r;
- if (databytes) if (sizebytes > databytes) return 1;
+ if (databytes)
+ if (sizebytes > databytes) return 1;
return 0;
}
-void mailfrom_auth(char *arg,int len)
+void mailfrom_auth(char *arg, int len)
{
- if (!stralloc_copys(&fuser,"")) die_nomem();
- if (case_starts(arg,"<>")) {
- if (!stralloc_cats(&fuser,"unknown")) die_nomem();
+ if (!stralloc_copys(&fuser, "")) die_nomem();
+ if (case_starts(arg, "<>")) {
+ if (!stralloc_cats(&fuser, "unknown")) die_nomem();
} else {
while (len) {
if (*arg == '+') {
- if (case_starts(arg,"+3D")) {
- arg = arg + 2; len = len - 2;
- if (!stralloc_cats(&fuser,"=")) die_nomem();
+ if (case_starts(arg, "+3D")) {
+ arg = arg + 2;
+ len = len - 2;
+ if (!stralloc_cats(&fuser, "=")) die_nomem();
}
- if (case_starts(arg,"+2B")) {
- arg = arg + 2; len = len - 2;
- if (!stralloc_cats(&fuser,"+")) die_nomem();
+ if (case_starts(arg, "+2B")) {
+ arg = arg + 2;
+ len = len - 2;
+ if (!stralloc_cats(&fuser, "+")) die_nomem();
}
} else {
- if (!stralloc_catb(&fuser,arg,1)) die_nomem();
+ if (!stralloc_catb(&fuser, arg, 1)) die_nomem();
}
- arg++; len--;
+ arg++;
+ len--;
}
}
@@ -895,9 +963,9 @@ void mailfrom_auth(char *arg,int len)
if (!remoteinfo) {
remoteinfo = fuser.s;
if (!env_unset("TCPREMOTEINFO")) die_read();
- if (!env_put("TCPREMOTEINFO",remoteinfo)) die_nomem();
+ if (!env_put("TCPREMOTEINFO", remoteinfo)) die_nomem();
if (!env_unset("TCP6REMOTEINFO")) die_read();
- if (!env_put("TCP6REMOTEINFO",remoteinfo)) die_nomem();
+ if (!env_put("TCP6REMOTEINFO", remoteinfo)) die_nomem();
}
}
@@ -906,18 +974,23 @@ void mailfrom_parms(char *arg)
int len;
if ((len = str_len(arg))) {
- if (!stralloc_copys(&mfparms,"")) die_nomem();
- while (len) {
- arg++; len--;
- if (*arg == ' ' || *arg == '\0' ) {
- if (flagutf8) if (case_starts(mfparms.s,"SMTPUTF8")) flagutf8 = 2;
- if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s + 5)) { flagsize = 1; return; }
- if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s + 5,mfparms.len - 5);
- if (!stralloc_copys(&mfparms,"")) die_nomem();
- }
- else
- if (!stralloc_catb(&mfparms,arg,1)) die_nomem();
- }
+ if (!stralloc_copys(&mfparms, "")) die_nomem();
+ while (len) {
+ arg++;
+ len--;
+ if (*arg == ' ' || *arg == '\0') {
+ if (flagutf8)
+ if (case_starts(mfparms.s, "SMTPUTF8")) flagutf8 = 2;
+ if (case_starts(mfparms.s, "SIZE="))
+ if (mailfrom_size(mfparms.s + 5)) {
+ flagsize = 1;
+ return;
+ }
+ if (case_starts(mfparms.s, "AUTH=")) mailfrom_auth(mfparms.s + 5, mfparms.len - 5);
+ if (!stralloc_copys(&mfparms, "")) die_nomem();
+ } else if (!stralloc_catb(&mfparms, arg, 1))
+ die_nomem();
+ }
}
}
@@ -925,8 +998,12 @@ void mailfrom_parms(char *arg)
void smtp_helo(char *arg)
{
- smtp_greet("250 "); out("\r\n"); flush();
- seenmail = 0; rcptcount = 0; seenhelo++;
+ smtp_greet("250 ");
+ out("\r\n");
+ flush();
+ seenmail = 0;
+ rcptcount = 0;
+ seenhelo++;
dohelo(arg);
}
@@ -934,30 +1011,39 @@ void smtp_ehlo(char *arg)
{
char size[FMT_ULONG];
- smtp_greet("250-"); out("\r\n");
+ smtp_greet("250-");
+ out("\r\n");
out("250-PIPELINING\r\n250-8BITMIME\r\n");
if (flagutf8) out("250-SMTPUTF8\r\n");
if (starttls > 0 && !seentls) out("250-STARTTLS\r\n");
-
+
switch (smtpauth) {
- case 1: case 11: out("250-AUTH LOGIN PLAIN\r\n"); break;
- case 2: case 12: out("250-AUTH CRAM-MD5\r\n"); break;
- case 3: case 13: out("250-AUTH LOGIN PLAIN CRAM-MD5\r\n"); break;
+ case 1:
+ case 11: out("250-AUTH LOGIN PLAIN\r\n"); break;
+ case 2:
+ case 12: out("250-AUTH CRAM-MD5\r\n"); break;
+ case 3:
+ case 13: out("250-AUTH LOGIN PLAIN CRAM-MD5\r\n"); break;
}
- size[fmt_ulong(size,(unsigned long) databytes)] = 0;
- out("250 SIZE "); out(size); out("\r\n");
+ size[fmt_ulong(size, (unsigned long)databytes)] = 0;
+ out("250 SIZE ");
+ out(size);
+ out("\r\n");
- seenhelo++; seenmail = 0; rcptcount = 0;
+ seenhelo++;
+ seenmail = 0;
+ rcptcount = 0;
dohelo(arg);
}
void smtp_rset(void)
{
- seenmail = 0; rcptcount = 0; /* RFC 5321: seenauth + seentls stay */
+ seenmail = 0;
+ rcptcount = 0; /* RFC 5321: seenauth + seentls stay */
- if (!stralloc_copys(&mailfrom,"")) die_nomem();
- if (!stralloc_copys(&rcptto,"")) die_nomem();
+ if (!stralloc_copys(&mailfrom, "")) die_nomem();
+ if (!stralloc_copys(&rcptto, "")) die_nomem();
out("250 flushed\r\n");
}
@@ -969,36 +1055,42 @@ void smtp_starttls()
flush();
if (!starttls_init()) die_starttls();
- buffer_init(&bi,saferead,FDIN,inbuf,sizeof(inbuf));
+ buffer_init(&bi, saferead, FDIN, inbuf, sizeof(inbuf));
seentls = 2;
if (!starttls_info()) die_starttls();
if (!modssl_info()) die_starttls();
-/* reset SMTP state */
+ /* reset SMTP state */
- seenhelo = 0; seenmail = 0; rcptcount = 0;
- if (!stralloc_copys(&addr,"")) die_nomem();
- if (!stralloc_copys(&helohost,"")) die_nomem();
- if (!stralloc_copys(&mailfrom,"")) die_nomem();
- if (!stralloc_copys(&rcptto,"")) die_nomem();
+ seenhelo = 0;
+ seenmail = 0;
+ rcptcount = 0;
+ if (!stralloc_copys(&addr, "")) die_nomem();
+ if (!stralloc_copys(&helohost, "")) die_nomem();
+ if (!stralloc_copys(&mailfrom, "")) die_nomem();
+ if (!stralloc_copys(&rcptto, "")) die_nomem();
if (seenauth == 1) seenauth = 0; /* Otherwise Auth by client Cert */
}
void smtp_mail(char *arg)
{
- if (flagutf8) if (!stralloc_cats(&protocol,"UTF8")) die_nomem();
+ if (flagutf8)
+ if (!stralloc_cats(&protocol, "UTF8")) die_nomem();
if (!stralloc_0(&protocol)) die_nomem();
- if ((starttls > 1) && !seentls) {
- err_tlsreq("Reject::TLS::missing",protocol.s,remoteip,remotehost,helohost.s);
+ if ((starttls > 1) && !seentls) {
+ err_tlsreq("Reject::TLS::missing", protocol.s, remoteip, remotehost, helohost.s);
+ return;
+ }
+ if (smtpauth > 10 && !seenauth) {
+ err_authreq("Reject::AUTH::missing", protocol.s, remoteip, remotehost, helohost.s);
return;
}
- if (smtpauth > 10 && !seenauth) {
- err_authreq("Reject::AUTH::missing",protocol.s,remoteip,remotehost,helohost.s);
+ if (!addrparse(arg)) {
+ err_syntax();
return;
}
- if (!addrparse(arg)) { err_syntax(); return; }
flagsize = 0;
rcptcount = 0;
@@ -1006,16 +1098,17 @@ void smtp_mail(char *arg)
seenmail++;
if (relayclient && localmf) {
flagmav = localaddr(addr.s);
- if (flagmav > 0) if (!stralloc_append(&protocol,"M")) die_nomem();
+ if (flagmav > 0)
+ if (!stralloc_append(&protocol, "M")) die_nomem();
}
- if (!stralloc_copys(&rcptto,"")) die_nomem();
- if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
+ if (!stralloc_copys(&rcptto, "")) die_nomem();
+ if (!stralloc_copys(&mailfrom, addr.s)) die_nomem();
if (!stralloc_0(&mailfrom)) die_nomem();
- if (!env_put("MAILFROM",mailfrom.s)) die_nomem();
+ if (!env_put("MAILFROM", mailfrom.s)) die_nomem();
flagaddr = bmfcheck();
- if (flagaddr != -110)
- if (mfdnscheck) flagdnsmf = dnsq(mailfrom.s,'M');
+ if (flagaddr != -110)
+ if (mfdnscheck) flagdnsmf = dnsq(mailfrom.s, 'M');
out("250 ok\r\n");
}
@@ -1027,17 +1120,15 @@ int postgrey_scanner()
int child;
int wstat;
- char *postgrey_scannerarg[] = {"bin/qmail-postgrey",pgbind.s,mailfrom.s,addr.s,remoteip,remotehost,0};
+ char *postgrey_scannerarg[] = {
+ "bin/qmail-postgrey", pgbind.s, mailfrom.s, addr.s, remoteip, remotehost, 0};
switch (child = fork()) {
- case -1:
- return err_forkgl();
- case 0:
- execv(*postgrey_scannerarg,postgrey_scannerarg);
- _exit(1);
+ case -1: return err_forkgl();
+ case 0: execv(*postgrey_scannerarg, postgrey_scannerarg); _exit(1);
}
- wait_pid(&wstat,child);
+ wait_pid(&wstat, child);
if (wait_crashed(wstat)) return err_postgl();
switch (wait_exitcode(wstat)) {
@@ -1049,89 +1140,164 @@ int postgrey_scanner()
void smtp_rcpt(char *arg)
{
char *rcptok = 0;
- if (!seenmail) { err_wantmail(); return; }
- if (!addrparse(arg)) { err_syntax(); return; }
+ if (!seenmail) {
+ err_wantmail();
+ return;
+ }
+ if (!addrparse(arg)) {
+ err_syntax();
+ return;
+ }
rcptcount++;
-/* this file is too long --------------------------------- Split Horizon envelope checks */
+ /* this file is too long --------------------------------- Split Horizon envelope checks */
if (!relayclient) {
- if (!seenhelo && helocheck) /* Helo rejects */
- if (str_len(helocheck) == 1) {
- err_helo("Reject::SNDR::Bad_Helo",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,"0");
- return;
- }
+ if (!seenhelo && helocheck) /* Helo rejects */
+ if (str_len(helocheck) == 1) {
+ err_helo(
+ "Reject::SNDR::Bad_Helo",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ "0");
+ return;
+ }
if (flagbadhelo) {
- switch (flagbadhelo) {
- case -2: badhelocond = "!"; break;
- case -1: badhelocond = "."; break;
- default: badhelocond = "*"; break;
- }
- err_helo("Reject::SNDR::Bad_Helo",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,badhelocond);
- return;
+ switch (flagbadhelo) {
+ case -2: badhelocond = "!"; break;
+ case -1: badhelocond = "."; break;
+ default: badhelocond = "*"; break;
+ }
+ err_helo(
+ "Reject::SNDR::Bad_Helo",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ badhelocond);
+ return;
}
if (flagdnshelo > 0) {
- err_helo("Reject::SNDR::DNS_Helo",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,badhelocond);
+ err_helo(
+ "Reject::SNDR::DNS_Helo",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ badhelocond);
return;
}
- if (flagdnsmf > 0) { /* Mail from rejects */
- err_mfdns("Reject::ORIG::DNS_MF",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ if (flagdnsmf > 0) { /* Mail from rejects */
+ err_mfdns(
+ "Reject::ORIG::DNS_MF", protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
return;
}
-
- if (!addrallowed(addr.s)) { /* Relaying rejects */
- err_nogateway("Reject::SNDR::Invalid_Relay",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+
+ if (!addrallowed(addr.s)) { /* Relaying rejects */
+ err_nogateway(
+ "Reject::SNDR::Invalid_Relay",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
}
-
- if (greylist && (postgrey_scanner() == 1)) { /* Greylisting */
- postgrey("Deferred::SNDR::Grey_Listed",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+
+ if (greylist && (postgrey_scanner() == 1)) { /* Greylisting */
+ postgrey(
+ "Deferred::SNDR::Grey_Listed",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
}
- if (tarpitcount && flagerrcpts >= tarpitcount) { /* Tarpitting et al. */
+ if (tarpitcount && flagerrcpts >= tarpitcount) { /* Tarpitting et al. */
if (tarpitdelay == 999) flagnotorious++;
- err_rcpts("Reject::RCPT::Toomany_Rcptto",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_rcpts(
+ "Reject::RCPT::Toomany_Rcptto",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
}
if (tarpitcount && rcptcount >= tarpitcount)
if (tarpitdelay > 0 && tarpitdelay < 999) sleep(tarpitdelay);
- flagrcpt = rcptallowed(); /* Rcpt to rejects */
+ flagrcpt = rcptallowed(); /* Rcpt to rejects */
if (!flagrcpt) {
- err_recipient("Reject::RCPT::Failed_Rcptto",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_recipient(
+ "Reject::RCPT::Failed_Rcptto",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
flagerrcpts++;
return;
}
- if (flagspf) /* SPF rejects */
+ if (flagspf) /* SPF rejects */
if (spf_check(flagip6) > 0) {
if (!stralloc_0(&spfbounce)) die_nomem(); // spfbounce is 0-terminated in any case
- err_spf("Reject::SPF::Fail",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,spfbounce.s);
+ err_spf(
+ "Reject::SPF::Fail",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ spfbounce.s);
return;
}
}
-/* this file is too long --------------------------------- Local checks */
+ /* this file is too long --------------------------------- Local checks */
- else {
+ else
+ {
if (flagmimetype == 4 || flagmimetype == 6) flagmimetype = 0;
if (flagloadertype == 2) flagloadertype = 0;
if (flagmav < 0) {
- err_mav("Reject::ORIG::Invalid_Mailfrom",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_mav(
+ "Reject::ORIG::Invalid_Mailfrom",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
}
--addr.len;
- if (!stralloc_cats(&addr,relayclient)) die_nomem();
+ if (!stralloc_cats(&addr, relayclient)) die_nomem();
if (!stralloc_0(&addr)) die_nomem();
}
-/* this file is too long --------------------------------- Common checks */
+ /* this file is too long --------------------------------- Common checks */
- if (flagmimetype == 2 || flagmimetype == 3 || flagmimetype == 6) cdb_init(&cdbm,fdbmt);
- if (flagloadertype == 1) cdb_init(&cdbl,fdblt);
+ if (flagmimetype == 2 || flagmimetype == 3 || flagmimetype == 6) cdb_init(&cdbm, fdbmt);
+ if (flagloadertype == 1) cdb_init(&cdbl, fdblt);
if (flagaddr && flagaddr != -110) {
switch (flagaddr) {
@@ -1142,60 +1308,96 @@ void smtp_rcpt(char *arg)
case -5: badmailcond = "+"; break;
default: badmailcond = "*"; break;
}
- err_bmf("Reject::ORIG::Bad_Mailfrom",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,badmailcond);
+ err_bmf(
+ "Reject::ORIG::Bad_Mailfrom",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ badmailcond);
return;
}
-
+
flagrcpt = brtcheck();
if (flagrcpt == 110) {
- err_brt("Reject::RCPT::Invalid_Rcptto",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_brt(
+ "Reject::RCPT::Invalid_Rcptto",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
} else if (flagrcpt > 0) {
- err_brt("Reject::RCPT::Bad_Rcptto",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_brt(
+ "Reject::RCPT::Bad_Rcptto", protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
return;
}
if (flagsize) {
- err_size("Reject::DATA::Invalid_Size",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_size(
+ "Reject::DATA::Invalid_Size", protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
return;
}
if (maxrcptcount && rcptcount > maxrcptcount) {
- err_rcpts("Reject::RCPT::Toomany_Rcptto",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ err_rcpts(
+ "Reject::RCPT::Toomany_Rcptto",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
return;
}
-/* this file is too long --------------------------------- Checks done; mailfrom/recipient accepted */
+ /* this file is too long --------------------------------- Checks done; mailfrom/recipient accepted */
- if (!stralloc_cats(&rcptto,"T")) die_nomem();
- if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
+ if (!stralloc_cats(&rcptto, "T")) die_nomem();
+ if (!stralloc_cats(&rcptto, addr.s)) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
- if (!stralloc_cats(&mailto,addr.s)) die_nomem();
- if (!stralloc_cats(&mailto," ")) die_nomem();
- if (!stralloc_copys(&deliverto,mailto.s)) die_nomem();
+ if (!stralloc_cats(&mailto, addr.s)) die_nomem();
+ if (!stralloc_cats(&mailto, " ")) die_nomem();
+ if (!stralloc_copys(&deliverto, mailto.s)) die_nomem();
if (!stralloc_0(&deliverto)) die_nomem();
- if (!env_put("RCPTTO",deliverto.s)) die_nomem();
+ if (!env_put("RCPTTO", deliverto.s)) die_nomem();
-/* this file is too long --------------------------------- Additional logging */
+ /* this file is too long --------------------------------- Additional logging */
switch (flagrcpt) {
- case 1: rcptok = "Recipients_Cdb"; break;
- case 2: rcptok = "Recipients_Pam"; break;
- case 3: rcptok = "Recipients_Users"; break;
- case 4: rcptok = "Recipients_Wild"; break;
- default: rcptok = "Rcpthosts_Rcptto"; break;
+ case 1: rcptok = "Recipients_Cdb"; break;
+ case 2: rcptok = "Recipients_Pam"; break;
+ case 3: rcptok = "Recipients_Users"; break;
+ case 4: rcptok = "Recipients_Wild"; break;
+ default: rcptok = "Rcpthosts_Rcptto"; break;
}
if (seenauth)
- smtp_loga("Accept::AUTH::",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,remoteinfo,authmethod.s);
+ smtp_loga(
+ "Accept::AUTH::",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ remoteinfo,
+ authmethod.s);
else if (flagmav > 0)
- smtp_logg("Accept::ORIG::Local_Sender",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ smtp_logg(
+ "Accept::ORIG::Local_Sender", protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
else if (relayclient)
- smtp_logg("Accept::SNDR::Relay_Client",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ smtp_logg(
+ "Accept::SNDR::Relay_Client", protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
else if (flagspf == 10)
- smtp_logr("Accept::SPF::",rcptok,protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ smtp_logr("Accept::SPF::", rcptok, protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
else
- smtp_logr("Accept::RCPT::",rcptok,protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
+ smtp_logr(
+ "Accept::RCPT::", rcptok, protocol.s, remoteip, remotehost, helohost.s, mailfrom.s, addr.s);
out("250 ok\r\n");
}
@@ -1209,37 +1411,44 @@ stralloc badmimetype = {0};
stralloc badloadertype = {0};
unsigned int nolines = 0;
-unsigned int flagb64 = 0; /* lineno with BASE64MESSAGE */
-unsigned int flagbase = 0; /* lineno with actual base64 content */
+unsigned int flagb64 = 0; /* lineno with BASE64MESSAGE */
+unsigned int flagbase = 0; /* lineno with actual base64 content */
unsigned int flagblank = 0;
static void queue_put(char *ch)
{
int i;
- if (flagmimetype > 0 || flagloadertype > 0 ) {
+ if (flagmimetype > 0 || flagloadertype > 0) {
if (line.len <= BUFFER_SIZE)
- if (!stralloc_catb(&line,ch,1)) die_nomem(); /* Reassamble chars to line; prepend with 'L' */
+ if (!stralloc_catb(&line, ch, 1)) die_nomem(); /* Reassamble chars to line; prepend with 'L' */
if (*ch == '\n') {
nolines++;
- if (line.len == 2) { flagblank = nolines; flagbase = 0; }
+ if (line.len == 2) {
+ flagblank = nolines;
+ flagbase = 0;
+ }
if (*(line.s + 1) == 'C' || *(line.s + 1) == 'c')
- if (case_startb(line.s + 1,line.len - 2,BASE64MESSAGE)) flagb64 = nolines;
+ if (case_startb(line.s + 1, line.len - 2, BASE64MESSAGE)) flagb64 = nolines;
if (flagb64 && nolines == flagblank + 1 && line.len > MIMETYPE_LEN + 2) flagbase = nolines;
- if (*(line.s + 1) == '-') { flagb64 = 0; flagbase = 0; }
+ if (*(line.s + 1) == '-') {
+ flagb64 = 0;
+ flagbase = 0;
+ }
- if (flagmimetype > 0 && flagbase == nolines) { /* badmimetype */
- if (!stralloc_catb(&base64types,line.s + 1,MIMETYPE_LEN)) die_nomem();
+ if (flagmimetype > 0 && flagbase == nolines) { /* badmimetype */
+ if (!stralloc_catb(&base64types, line.s + 1, MIMETYPE_LEN)) die_nomem();
if (!stralloc_0(&base64types)) die_nomem();
if (flagmimetype == 2 || flagmimetype == 3 || flagmimetype == 6) {
- if (cdb_find(&cdbm,line.s + 1,MIMETYPE_LEN)) {
- cdb_free(&cdbm); close(fdbmt);
- if (!stralloc_copyb(&badmimetype,line.s + 1,MIMETYPE_LEN)) die_nomem();
+ if (cdb_find(&cdbm, line.s + 1, MIMETYPE_LEN)) {
+ cdb_free(&cdbm);
+ close(fdbmt);
+ if (!stralloc_copyb(&badmimetype, line.s + 1, MIMETYPE_LEN)) die_nomem();
if (!stralloc_0(&badmimetype)) die_nomem();
- if (!stralloc_cats(&rcptto,"M")) die_nomem();
+ if (!stralloc_cats(&rcptto, "M")) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
qmail_fail(&qqt);
flagmimetype = -1;
@@ -1250,22 +1459,23 @@ static void queue_put(char *ch)
if (flagbase && line.len > LOADER_LEN + 2) {
if (flagloadertype >= 1 || flagmimetype >= 1) {
for (i = 0; i < line.len - LOADER_LEN; ++i) {
- if (flagloadertype == 1 && *(line.s+i) == *badloaderinit) { /* badloadertype */
- if (cdb_find(&cdbl,line.s + i,LOADER_LEN)) {
- cdb_free(&cdbl); close(fdbmt);
- if (!stralloc_copyb(&badloadertype,line.s + i,LOADER_LEN)) die_nomem();
+ if (flagloadertype == 1 && *(line.s + i) == *badloaderinit) { /* badloadertype */
+ if (cdb_find(&cdbl, line.s + i, LOADER_LEN)) {
+ cdb_free(&cdbl);
+ close(fdbmt);
+ if (!stralloc_copyb(&badloadertype, line.s + i, LOADER_LEN)) die_nomem();
if (!stralloc_0(&badloadertype)) die_nomem();
- if (!stralloc_cats(&rcptto,"L")) die_nomem();
+ if (!stralloc_cats(&rcptto, "L")) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
qmail_fail(&qqt);
flagloadertype = -1;
}
}
if (flagmimetype == 1 || flagmimetype == 3 || flagmimetype == 4) {
- if (*(line.s + i) == ' ' || *(line.s + i) == '\t') { /* white spaces */
- if (!stralloc_copyb(&badmimetype,line.s + i - 2,MIMETYPE_LEN)) die_nomem();
+ if (*(line.s + i) == ' ' || *(line.s + i) == '\t') { /* white spaces */
+ if (!stralloc_copyb(&badmimetype, line.s + i - 2, MIMETYPE_LEN)) die_nomem();
if (!stralloc_0(&badmimetype)) die_nomem();
- if (!stralloc_cats(&rcptto,"M")) die_nomem();
+ if (!stralloc_cats(&rcptto, "M")) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
qmail_fail(&qqt);
flagmimetype = -2;
@@ -1275,14 +1485,13 @@ static void queue_put(char *ch)
}
}
line.len = 0;
- if (!stralloc_copys(&line,"L")) die_nomem();
+ if (!stralloc_copys(&line, "L")) die_nomem();
}
}
if (bytestooverflow)
- if (!--bytestooverflow)
- qmail_fail(&qqt);
- qmail_put(&qqt,ch,1);
+ if (!--bytestooverflow) qmail_fail(&qqt);
+ qmail_put(&qqt, ch, 1);
}
void blast(int *hops)
@@ -1291,7 +1500,7 @@ void blast(int *hops)
int state;
int seencr;
int flaginheader;
- int pos; /* number of bytes since most recent \n, if fih */
+ int pos; /* number of bytes since most recent \n, if fih */
int flagmaybex; /* 1 if this line might match RECEIVED, if fih */
int flagmaybey; /* 1 if this line might match \r\n, if fih */
int flagmaybez; /* 1 if this line might match DELIVERED, if fih */
@@ -1299,52 +1508,90 @@ void blast(int *hops)
state = 1;
*hops = 0;
flaginheader = 1;
- pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; seencr = 0;
+ pos = 0;
+ flagmaybex = flagmaybey = flagmaybez = 1;
+ seencr = 0;
for (;;) {
- buffer_get(&bi,&ch,1);
+ buffer_get(&bi, &ch, 1);
if (ch == '\n') {
- if (seencr == 0) { buffer_seek(&bi,-1); ch = '\r'; }
+ if (seencr == 0) {
+ buffer_seek(&bi, -1);
+ ch = '\r';
+ }
}
- if (ch == '\r') seencr = 1; else seencr = 0;
+ if (ch == '\r')
+ seencr = 1;
+ else
+ seencr = 0;
if (flaginheader) {
if (pos < 9) {
- if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
- if (flagmaybez) if (pos == 8) ++*hops;
+ if (ch != "delivered"[pos])
+ if (ch != "DELIVERED"[pos]) flagmaybez = 0;
+ if (flagmaybez)
+ if (pos == 8) ++*hops;
if (pos < 8)
- if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0;
- if (flagmaybex) if (pos == 7) ++*hops;
- if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
- if (flagmaybey) if (pos == 1) flaginheader = 0;
+ if (ch != "received"[pos])
+ if (ch != "RECEIVED"[pos]) flagmaybex = 0;
+ if (flagmaybex)
+ if (pos == 7) ++*hops;
+ if (pos < 2)
+ if (ch != "\r\n"[pos]) flagmaybey = 0;
+ if (flagmaybey)
+ if (pos == 1) flaginheader = 0;
++pos;
}
- if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
+ if (ch == '\n') {
+ pos = 0;
+ flagmaybex = flagmaybey = flagmaybez = 1;
+ }
}
switch (state) {
case 0:
if (ch == '\n') straynewline();
- if (ch == '\r') { state = 4; continue; }
+ if (ch == '\r') {
+ state = 4;
+ continue;
+ }
break;
case 1: /* \r\n */
if (ch == '\n') straynewline();
- if (ch == '.') { state = 2; continue; }
- if (ch == '\r') { state = 4; continue; }
+ if (ch == '.') {
+ state = 2;
+ continue;
+ }
+ if (ch == '\r') {
+ state = 4;
+ continue;
+ }
state = 0;
break;
case 2: /* \r\n + . */
if (ch == '\n') straynewline();
- if (ch == '\r') { state = 3; continue; }
+ if (ch == '\r') {
+ state = 3;
+ continue;
+ }
state = 0;
break;
case 3: /* \r\n + .\r */
if (ch == '\n') return;
queue_put(".");
queue_put("\r");
- if (ch == '\r') { state = 4; continue; }
+ if (ch == '\r') {
+ state = 4;
+ continue;
+ }
state = 0;
break;
case 4: /* + \r */
- if (ch == '\n') { state = 1; break; }
- if (ch != '\r') { queue_put("\r"); state = 0; }
+ if (ch == '\n') {
+ state = 1;
+ break;
+ }
+ if (ch != '\r') {
+ queue_put("\r");
+ state = 0;
+ }
}
queue_put(&ch);
}
@@ -1357,10 +1604,10 @@ void acceptmessage(unsigned long qp)
datetime_sec when;
when = now();
out("250 ok ");
- accept_buf[fmt_ulong(accept_buf,(unsigned long) when)] = 0;
+ accept_buf[fmt_ulong(accept_buf, (unsigned long)when)] = 0;
out(accept_buf);
out(" qp ");
- accept_buf[fmt_ulong(accept_buf,qp)] = 0;
+ accept_buf[fmt_ulong(accept_buf, qp)] = 0;
out(accept_buf);
out("\r\n");
}
@@ -1371,69 +1618,152 @@ void smtp_data()
unsigned long qp;
char *qqx;
- if (!seenmail) { err_wantmail(); return; }
- if (!rcptto.len) { err_wantrcpt(); return; }
- if (flagnotorious) { err_notorious(); }
+ if (!seenmail) {
+ err_wantmail();
+ return;
+ }
+ if (!rcptto.len) {
+ err_wantrcpt();
+ return;
+ }
+ if (flagnotorious) {
+ err_notorious();
+ }
seenmail = 0;
if (databytes) bytestooverflow = databytes + 1;
- if (!stralloc_copys(&addr,"")) die_nomem();
- if (!stralloc_cats(&addr,rcptto.s + 1)) die_nomem();
+ if (!stralloc_copys(&addr, "")) die_nomem();
+ if (!stralloc_cats(&addr, rcptto.s + 1)) die_nomem();
if (!stralloc_0(&addr)) die_nomem();
- if (qmail_open(&qqt) == -1) { err_qqt(); return; }
+ if (qmail_open(&qqt) == -1) {
+ err_qqt();
+ return;
+ }
qp = qmail_qp(&qqt);
out("354 go ahead\r\n");
- if (flagspf && !relayclient) spfheader(&qqt,spfinfo.s,local,remoteip,helohost.s,mailfrom.s);
- received(&qqt,protocol.s,local,remoteip,remotehost,remoteinfo,fakehelo,tlsinfo.s,rblinfo.s);
+ if (flagspf && !relayclient) spfheader(&qqt, spfinfo.s, local, remoteip, helohost.s, mailfrom.s);
+ received(&qqt, protocol.s, local, remoteip, remotehost, remoteinfo, fakehelo, tlsinfo.s, rblinfo.s);
blast(&hops);
hops = (hops >= MAXHOPS);
if (hops) qmail_fail(&qqt);
if (base64 && base64types.len == 0) {
- if (!stralloc_cats(&rcptto,"Q")) die_nomem();
+ if (!stralloc_cats(&rcptto, "Q")) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
}
- qmail_from(&qqt,mailfrom.s);
- qmail_put(&qqt,rcptto.s,rcptto.len);
+ qmail_from(&qqt, mailfrom.s);
+ qmail_put(&qqt, rcptto.s, rcptto.len);
qqx = qmail_close(&qqt);
- if (!*qqx) { acceptmessage(qp); return; }
- if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; }
+ if (!*qqx) {
+ acceptmessage(qp);
+ return;
+ }
+ if (hops) {
+ out("554 too many hops, this message is looping (#5.4.6)\r\n");
+ return;
+ }
if (databytes)
if (!bytestooverflow) {
- err_size("Reject::DATA::Invalid_Size",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s);
- return;
+ err_size(
+ "Reject::DATA::Invalid_Size",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s);
+ return;
}
if (flagmimetype < 0) {
- err_data("Reject::DATA::Bad_MIME",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,badmimetype.s);
+ err_data(
+ "Reject::DATA::Bad_MIME",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ badmimetype.s);
return;
}
if (flagloadertype < 0) {
- err_data("Reject::DATA::Bad_Loader",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,badloadertype.s);
+ err_data(
+ "Reject::DATA::Bad_Loader",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ badloadertype.s);
return;
}
if (*qqx == 'I') {
- err_data("Reject::DKIM::Signature",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,"fail");
+ err_data(
+ "Reject::DKIM::Signature",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ "fail");
return;
}
if (*qqx == 'S') {
- err_data("Reject::DATA::Spam_Message",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,"spam");
+ err_data(
+ "Reject::DATA::Spam_Message",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ "spam");
return;
}
if (*qqx == 'A') {
- err_data("Reject::DATA::MIME_Attach",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,"MIME");
+ err_data(
+ "Reject::DATA::MIME_Attach",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ "MIME");
return;
}
if (*qqx == 'V') {
if (qhpsi)
- err_data("Reject::DATA::Virus_Infected",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,qhpsi);
+ err_data(
+ "Reject::DATA::Virus_Infected",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ qhpsi);
else
- err_data("Reject::DATA::Virus_Infected",protocol.s,remoteip,remotehost,helohost.s,mailfrom.s,addr.s,"AV scanner");
+ err_data(
+ "Reject::DATA::Virus_Infected",
+ protocol.s,
+ remoteip,
+ remotehost,
+ helohost.s,
+ mailfrom.s,
+ addr.s,
+ "AV scanner");
return;
}
- if (*qqx == 'D') out("554 "); else out("451 ");
+ if (*qqx == 'D')
+ out("554 ");
+ else
+ out("451 ");
out(qqx + 1);
out("\r\n");
}
@@ -1441,33 +1771,34 @@ void smtp_data()
/* this file is too long --------------------------------- SMTP Auth */
char unique[FMT_ULONG + FMT_ULONG + 3];
-static stralloc authin = {0}; /* input from SMTP client */
-static stralloc pass = {0}; /* plain passwd or digest */
-static stralloc resp = {0}; /* b64 response */
-static stralloc chal = {0}; /* CRAM-MD5 plain challenge */
-static stralloc slop = {0}; /* CRAM-MD5 b64 challenge */
+static stralloc authin = {0}; /* input from SMTP client */
+static stralloc pass = {0}; /* plain passwd or digest */
+static stralloc resp = {0}; /* b64 response */
+static stralloc chal = {0}; /* CRAM-MD5 plain challenge */
+static stralloc slop = {0}; /* CRAM-MD5 b64 challenge */
char **childargs;
char authbuf[512];
-buffer ba = BUFFER_INIT(safewrite,FDAUTH,authbuf,sizeof(authbuf));
+buffer ba = BUFFER_INIT(safewrite, FDAUTH, authbuf, sizeof(authbuf));
int authgetl(void)
{
int i;
- if (!stralloc_copys(&authin,"")) die_nomem();
+ if (!stralloc_copys(&authin, "")) die_nomem();
for (;;) {
- if (!stralloc_readyplus(&authin,1)) die_nomem(); /* XXX */
- i = buffer_get(&bi,authin.s + authin.len,1);
+ if (!stralloc_readyplus(&authin, 1)) die_nomem(); /* XXX */
+ i = buffer_get(&bi, authin.s + authin.len, 1);
if (i != 1) die_read();
if (authin.s[authin.len] == '\n') break;
++authin.len;
}
- if (authin.len > 0) if (authin.s[authin.len - 1] == '\r') --authin.len;
+ if (authin.len > 0)
+ if (authin.s[authin.len - 1] == '\r') --authin.len;
authin.s[authin.len] = 0;
if (*authin.s == '*' && *(authin.s + 1) == 0) return err_authabort();
- if (authin.len == 0) return err_authinput();
+ if (authin.len == 0) return err_authinput();
return authin.len;
}
@@ -1480,35 +1811,37 @@ int authenticate(void)
if (!stralloc_0(&user)) die_nomem();
if (!stralloc_0(&pass)) die_nomem();
if (!stralloc_0(&chal)) die_nomem();
- if (!env_put("AUTHUSER",user.s)) die_nomem();
+ if (!env_put("AUTHUSER", user.s)) die_nomem();
if (pipe(pi) == -1) return err_pipe();
switch (child = fork()) {
- case -1:
- return err_fork();
+ case -1: return err_fork();
case 0:
close(pi[1]);
- if (fd_copy(FDAUTH,pi[0]) == -1) return err_pipe();
+ if (fd_copy(FDAUTH, pi[0]) == -1) return err_pipe();
sig_pipedefault();
- execvp(*childargs,childargs);
+ execvp(*childargs, childargs);
_exit(1);
}
close(pi[0]);
- buffer_init(&ba,write,pi[1],authbuf,sizeof(authbuf));
- if (buffer_put(&ba,user.s,user.len) == -1) return err_write();
- if (buffer_put(&ba,pass.s,pass.len) == -1) return err_write();
+ buffer_init(&ba, write, pi[1], authbuf, sizeof(authbuf));
+ if (buffer_put(&ba, user.s, user.len) == -1) return err_write();
+ if (buffer_put(&ba, pass.s, pass.len) == -1) return err_write();
if (smtpauth == 2 || smtpauth == 3 || smtpauth == 12 || smtpauth == 13)
- if (buffer_put(&ba,chal.s,chal.len) == -1) return err_write();
+ if (buffer_put(&ba, chal.s, chal.len) == -1) return err_write();
if (buffer_flush(&ba) == -1) return err_write();
close(pi[1]);
- if (!stralloc_copys(&chal,"")) die_nomem();
- if (!stralloc_copys(&slop,"")) die_nomem();
- byte_zero(authbuf,sizeof(authbuf));
- if (wait_pid(&wstat,child) == -1) return err_child();
+ if (!stralloc_copys(&chal, "")) die_nomem();
+ if (!stralloc_copys(&slop, "")) die_nomem();
+ byte_zero(authbuf, sizeof(authbuf));
+ if (wait_pid(&wstat, child) == -1) return err_child();
if (wait_crashed(wstat)) return err_child();
- if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */
+ if (wait_exitcode(wstat)) {
+ sleep(AUTHSLEEP);
+ return 1;
+ } /* no */
return 0; /* yes */
}
@@ -1518,19 +1851,20 @@ int auth_login(char *arg)
if (smtpauth == 2 || smtpauth == 12) return 1; /* only login/plain */
if (*arg) {
- if ((r = b64decode((unsigned char *)arg,str_len(arg),&user)) == 1) return err_authinput();
- }
- else {
- out("334 VXNlcm5hbWU6\r\n"); flush(); /* Username: */
+ if ((r = b64decode((unsigned char *)arg, str_len(arg), &user)) == 1) return err_authinput();
+ } else {
+ out("334 VXNlcm5hbWU6\r\n");
+ flush(); /* Username: */
if (authgetl() < 0) return -1;
- if ((r = b64decode((unsigned char *)authin.s,authin.len,&user)) == 1) return err_authinput();
+ if ((r = b64decode((unsigned char *)authin.s, authin.len, &user)) == 1) return err_authinput();
}
if (r == -1) die_nomem();
- out("334 UGFzc3dvcmQ6\r\n"); flush(); /* Password: */
+ out("334 UGFzc3dvcmQ6\r\n");
+ flush(); /* Password: */
if (authgetl() < 0) return -1;
- if ((r = b64decode((unsigned char *)authin.s,authin.len,&pass)) == 1) return err_authinput();
+ if ((r = b64decode((unsigned char *)authin.s, authin.len, &pass)) == 1) return err_authinput();
if (r == -1) die_nomem();
if (!user.len || !pass.len) return err_authinput();
@@ -1543,20 +1877,20 @@ int auth_plain(char *arg)
if (smtpauth == 2 || smtpauth == 12) return 1; /* only login/plain */
if (*arg) {
- if ((r = b64decode((unsigned char *)arg,str_len(arg),&resp)) == 1) return err_authinput();
- }
- else {
- out("334 \r\n"); flush();
+ if ((r = b64decode((unsigned char *)arg, str_len(arg), &resp)) == 1) return err_authinput();
+ } else {
+ out("334 \r\n");
+ flush();
if (authgetl() < 0) return -1;
- if ((r = b64decode((unsigned char *)authin.s,authin.len,&resp)) == 1) return err_authinput();
+ if ((r = b64decode((unsigned char *)authin.s, authin.len, &resp)) == 1) return err_authinput();
}
if (r == -1 || !stralloc_0(&resp)) die_nomem();
- while (resp.s[id]) id++; /* "authorize-id\0userid\0passwd\0" */
+ while (resp.s[id]) id++; /* "authorize-id\0userid\0passwd\0" */
if (resp.len > id + 1)
- if (!stralloc_copys(&user,resp.s + id + 1)) die_nomem();
+ if (!stralloc_copys(&user, resp.s + id + 1)) die_nomem();
if (resp.len > id + user.len + 2)
- if (!stralloc_copys(&pass,resp.s + id + user.len + 2)) die_nomem();
+ if (!stralloc_copys(&pass, resp.s + id + user.len + 2)) die_nomem();
if (!user.len || !pass.len) return err_authinput();
return authenticate();
@@ -1568,34 +1902,34 @@ int auth_cram()
char *s;
if (smtpauth == 1 || smtpauth == 11) return 1; /* no challenge if login/plain */
- s = unique; /* generate challenge */
- s += fmt_uint(s,getpid());
+ s = unique; /* generate challenge */
+ s += fmt_uint(s, getpid());
*s++ = '.';
- s += fmt_ulong(s,(unsigned long) now());
+ s += fmt_ulong(s, (unsigned long)now());
*s++ = '@';
*s++ = 0;
- if (!stralloc_copys(&chal,"<")) die_nomem();
- if (!stralloc_cats(&chal,unique)) die_nomem();
- if (!stralloc_cats(&chal,local)) die_nomem();
- if (!stralloc_cats(&chal,">")) die_nomem();
- if (b64encode(&chal,&slop) < 0) die_nomem();
+ if (!stralloc_copys(&chal, "<")) die_nomem();
+ if (!stralloc_cats(&chal, unique)) die_nomem();
+ if (!stralloc_cats(&chal, local)) die_nomem();
+ if (!stralloc_cats(&chal, ">")) die_nomem();
+ if (b64encode(&chal, &slop) < 0) die_nomem();
if (!stralloc_0(&slop)) die_nomem();
- out("334 "); /* "334 base64_challenge \r\n" */
+ out("334 "); /* "334 base64_challenge \r\n" */
out(slop.s);
out("\r\n");
flush();
- if (authgetl() < 0) return -1; /* got response */
- if ((r = b64decode((unsigned char *)authin.s,authin.len,&resp)) == 1) return err_authinput();
+ if (authgetl() < 0) return -1; /* got response */
+ if ((r = b64decode((unsigned char *)authin.s, authin.len, &resp)) == 1) return err_authinput();
if (r == -1 || !stralloc_0(&resp)) die_nomem();
- i = str_rchr(resp.s,' ');
+ i = str_rchr(resp.s, ' ');
s = resp.s + i;
while (*s == ' ') ++s;
resp.s[i] = 0;
- if (!stralloc_copys(&user,resp.s)) die_nomem();/* userid */
- if (!stralloc_copys(&pass,s)) die_nomem(); /* digest */
+ if (!stralloc_copys(&user, resp.s)) die_nomem(); /* userid */
+ if (!stralloc_copys(&pass, s)) die_nomem(); /* digest */
if (!user.len || !pass.len) return err_authinput();
return authenticate();
@@ -1605,10 +1939,10 @@ struct authcmd {
char *text;
int (*fun)();
} authcmds[] = {
- { "login", auth_login }
-, { "plain", auth_plain }
-, { "cram-md5", auth_cram }
-, { 0, err_noauth }
+ { "login", auth_login},
+ { "plain", auth_plain},
+ {"cram-md5", auth_cram},
+ { 0, err_noauth}
};
void smtp_auth(char *arg)
@@ -1618,49 +1952,60 @@ void smtp_auth(char *arg)
/* prevent users to expose userid + password over unencrypted connection */
- if ((starttls > 1) && !seentls) {
- if (!stralloc_append(&protocol,"A")) die_nomem();
+ if ((starttls > 1) && !seentls) {
+ if (!stralloc_append(&protocol, "A")) die_nomem();
if (!stralloc_0(&protocol)) die_nomem();
- err_authsetup("Reject::TLS::required",protocol.s,remoteip,remotehost,helohost.s);
+ err_authsetup("Reject::TLS::required", protocol.s, remoteip, remotehost, helohost.s);
return;
}
- if ((starttls > 1) && !seenhelo) {
- if (!stralloc_append(&protocol,"A")) die_nomem();
+ if ((starttls > 1) && !seenhelo) {
+ if (!stralloc_append(&protocol, "A")) die_nomem();
if (!stralloc_0(&protocol)) die_nomem();
- err_tlsreq("Reject::AUTH::invalid",protocol.s,remoteip,remotehost,helohost.s);
+ err_tlsreq("Reject::AUTH::invalid", protocol.s, remoteip, remotehost, helohost.s);
return;
}
- if (!smtpauth) { out("503 auth not available (#5.3.3)\r\n"); flush(); _exit(0); }
+ if (!smtpauth) {
+ out("503 auth not available (#5.3.3)\r\n");
+ flush();
+ _exit(0);
+ }
if (smtpauth && !*childargs) {
- err_authsetup("Reject::AUTH::invalid",protocol.s,remoteip,remotehost,helohost.s);
- flush(); _exit(1);
+ err_authsetup("Reject::AUTH::invalid", protocol.s, remoteip, remotehost, helohost.s);
+ flush();
+ _exit(1);
+ }
+ if (seenauth) {
+ err_authd();
+ return;
+ }
+ if (seenmail) {
+ err_authmail();
+ return;
}
- if (seenauth) { err_authd(); return; }
- if (seenmail) { err_authmail(); return; }
- if (!stralloc_copys(&user,"")) die_nomem();
- if (!stralloc_copys(&pass,"")) die_nomem();
- if (!stralloc_copys(&resp,"")) die_nomem();
- if (!stralloc_copys(&chal,"")) die_nomem(); /* only needed for CRAM-MD5 */
+ if (!stralloc_copys(&user, "")) die_nomem();
+ if (!stralloc_copys(&pass, "")) die_nomem();
+ if (!stralloc_copys(&resp, "")) die_nomem();
+ if (!stralloc_copys(&chal, "")) die_nomem(); /* only needed for CRAM-MD5 */
- i = str_chr(cmd,' '); /* get AUTH type */
+ i = str_chr(cmd, ' '); /* get AUTH type */
arg = cmd + i;
while (*arg == ' ') ++arg;
cmd[i] = 0;
for (i = 0; authcmds[i].text; ++i)
- if (case_equals(authcmds[i].text,cmd)) break;
+ if (case_equals(authcmds[i].text, cmd)) break;
- if (!authcmds[i].text) { /* invalid auth cmd */
- if (!stralloc_append(&protocol,"A")) die_nomem();
+ if (!authcmds[i].text) { /* invalid auth cmd */
+ if (!stralloc_append(&protocol, "A")) die_nomem();
if (!stralloc_0(&protocol)) die_nomem();
- err_authinvalid("Reject::AUTH::Method",protocol.s,remoteip,remotehost,helohost.s);
+ err_authinvalid("Reject::AUTH::Method", protocol.s, remoteip, remotehost, helohost.s);
return;
}
- if (!stralloc_copys(&authmethod,authcmds[i].text)) die_nomem();
+ if (!stralloc_copys(&authmethod, authcmds[i].text)) die_nomem();
if (!stralloc_0(&authmethod)) die_nomem();
switch (authcmds[i].fun(arg)) {
@@ -1672,9 +2017,9 @@ void smtp_auth(char *arg)
out("235 ok, go ahead (#2.0.0)\r\n");
break;
case 1:
- if (!stralloc_append(&protocol,"A")) die_nomem();
+ if (!stralloc_append(&protocol, "A")) die_nomem();
if (!stralloc_0(&protocol)) die_nomem();
- err_authfail("Reject::AUTH::",protocol.s,remoteip,remotehost,helohost.s,user.s,authmethod.s);
+ err_authfail("Reject::AUTH::", protocol.s, remoteip, remotehost, helohost.s, user.s, authmethod.s);
return;
}
}
@@ -1682,20 +2027,20 @@ void smtp_auth(char *arg)
/* this file is too long --------------------------------- GO ON */
struct commands smtpcommands[] = {
- { "rcpt", smtp_rcpt, 0 }
-, { "mail", smtp_mail, 0 }
-, { "data", smtp_data, flush }
-, { "auth", smtp_auth, flush }
-, { "quit", smtp_quit, flush }
-, { "helo", smtp_helo, flush }
-, { "ehlo", smtp_ehlo, flush }
-, { "rset", smtp_rset, flush }
-, { "help", smtp_help, flush }
-, { "noop", err_noop, flush }
-, { "vrfy", err_vrfy, flush }
-, { "starttls", smtp_starttls, flush }
-, { 0, err_unimpl, flush }
-} ;
+ { "rcpt", smtp_rcpt, 0},
+ { "mail", smtp_mail, 0},
+ { "data", smtp_data, flush},
+ { "auth", smtp_auth, flush},
+ { "quit", smtp_quit, flush},
+ { "helo", smtp_helo, flush},
+ { "ehlo", smtp_ehlo, flush},
+ { "rset", smtp_rset, flush},
+ { "help", smtp_help, flush},
+ { "noop", err_noop, flush},
+ { "vrfy", err_vrfy, flush},
+ {"starttls", smtp_starttls, flush},
+ { 0, err_unimpl, flush}
+};
int main(int argc, char **argv)
{
@@ -1708,7 +2053,7 @@ int main(int argc, char **argv)
smtp_greet("220 ");
out(" ESMTP\r\n");
flush();
- if (commands(&bi,&smtpcommands) == 0) die_read();
+ if (commands(&bi, &smtpcommands) == 0) die_read();
die_nomem();
return 0;