summaryrefslogtreecommitdiff
path: root/src/qmail-remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-remote.c')
-rw-r--r--src/qmail-remote.c1275
1 files changed, 671 insertions, 604 deletions
diff --git a/src/qmail-remote.c b/src/qmail-remote.c
index 5ef9465..2a7498c 100644
--- a/src/qmail-remote.c
+++ b/src/qmail-remote.c
@@ -1,76 +1,77 @@
#ifdef IDN2
-#include <idn2.h>
+ #include <idn2.h>
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
-#include "sig.h"
-#include "stralloc.h"
+
+#include "alloc.h"
+#include "base64.h"
#include "buffer.h"
-#include "scan.h"
-#include "case.h"
#include "byte.h"
+#include "case.h"
+#include "constmap.h"
+#include "exit.h"
+#include "fmt.h"
+#include "genalloc.h"
+#include "ip.h"
#include "logmsg.h"
+#include "scan.h"
+#include "sig.h"
+#include "socket_if.h"
+#include "str.h"
+#include "stralloc.h"
+#include "timeout.h"
+#include "timeoutconn.h"
+#include "uint_t.h"
+
#include "auto_qmail.h"
#include "control.h"
#include "dns.h"
-#include "alloc.h"
-#include "genalloc.h"
-#include "quote.h"
-#include "fmt.h"
-#include "ip.h"
+#include "hmac_md5.h"
#include "ipalloc.h"
#include "ipme.h"
-#include "str.h"
#include "now.h"
-#include "exit.h"
-#include "constmap.h"
+#include "quote.h"
#include "tcpto.h"
-#include "timeout.h"
-#include "timeoutconn.h"
-#include "base64.h"
-#include "socket_if.h"
-#include "ucspissl.h"
-#include "hmac_md5.h"
-#include "tls_remote.h"
#include "tls_errors.h"
+#include "tls_remote.h"
#include "tls_timeoutio.h"
-#include "uint_t.h"
+#include "ucspissl.h"
#define WHO "qmail-remote"
-#define MAX_SIZE 200000000
-#define HUGESMTPTEXT 1000 /* RFC 5322; was 5000 chars/line */
-#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */
-#define PORT_QMTP 209
-#define PORT_SMTPS 465
+#define MAX_SIZE 200000000
+#define HUGESMTPTEXT 1000 /* RFC 5322; was 5000 chars/line */
+#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */
+#define PORT_QMTP 209
+#define PORT_SMTPS 465
#define PORT_SUBMISSION 587
-#define PORT_QMTPS 6209
-#define VERIFYDEPTH 1
+#define PORT_QMTPS 6209
+#define VERIFYDEPTH 1
unsigned long port = PORT_SMTP;
/** @file qmail-remote.c -- versatile SMTP(S)/QMTP(S) client */
-int flagauth = 0; /* 1 = login; 2 = plain; 3 = crammd5 */
-int flagsmtps = 0; /* RFC 8314 - 'implicit TLS' */
-int flagtlsdomain = 0; /* 0 = no; 1 = yes; 2 = cert */
-int flagtls = 0; /* flagtls: XYZ
+int flagauth = 0; /* 1 = login; 2 = plain; 3 = crammd5 */
+int flagsmtps = 0; /* RFC 8314 - 'implicit TLS' */
+int flagtlsdomain = 0; /* 0 = no; 1 = yes; 2 = cert */
+int flagtls = 0; /* flagtls: XYZ
(mode) Z: -2 = rejected; -1 = not; 0 = no, default; Z > 0 see tls_remote.c
(prot) Y: 0 = StartTLS; 1 = SMTPS; 2 = QMTPS
(active) X: 1 = running TLS connection (after DNS lookup)
(done) Z: 1: CA chain; 2: Cert wildname; 3: Cert exactname;
4: Cert fingerprint; 5: TLSA record */
-int flagverify = 0; /* 1 = verify Cert against CA; 2 = verify against Dir; 3 = triggerd by TLSA;
- -2 = Cert pinning; -1 = no TLSA validation */
+int flagverify = 0; /* 1 = verify Cert against CA; 2 = verify against Dir; 3 = triggerd by TLSA;
+ -2 = Cert pinning; -1 = no TLSA validation */
int flagutf8 = 0;
-GEN_ALLOC_typedef(saa,stralloc,sa,len,a)
-GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus)
-static stralloc sauninit = {0};
+GEN_ALLOC_typedef(saa, stralloc, sa, len, a) GEN_ALLOC_readyplus(
+ saa, stralloc, sa, len, a, i, n, x, 10, saa_readyplus) static stralloc sauninit = {0};
stralloc helohost = {0};
stralloc eaihost = {0};
@@ -103,22 +104,20 @@ unsigned long msize = 0;
struct ip_mx partner;
SSL *ssl;
-SSL_CTX *ctx;
+SSL_CTX *ctx;
char smallbuf[BUFFER_SMALL];
-buffer bs = BUFFER_INIT(write,1,smallbuf,sizeof(smallbuf));
-
-void out(char *s)
-{
- if (buffer_puts(&bs,s) == -1)
- _exit(0);
- }
-void zero()
-{
- if (buffer_put(&bs,"\0",1) == -1)
- _exit(0);
+buffer bs = BUFFER_INIT(write, 1, smallbuf, sizeof(smallbuf));
+
+void out(char *s)
+{
+ if (buffer_puts(&bs, s) == -1) _exit(0);
+}
+void zero()
+{
+ if (buffer_put(&bs, "\0", 1) == -1) _exit(0);
}
-void zerodie()
+void zerodie()
{
zero();
buffer_flush(&bs);
@@ -126,127 +125,127 @@ void zerodie()
_exit(0);
}
-void outsafe(stralloc *sa)
-{
- int i;
+void outsafe(stralloc *sa)
+{
+ int i;
char ch;
for (i = 0; i < sa->len; ++i) {
- ch = sa->s[i];
+ ch = sa->s[i];
if (ch == 0) continue;
- if (ch < 33) ch = '?';
+ if (ch < 33) ch = '?';
if (ch > 126) ch = '?';
- if (buffer_put(&bs,&ch,1) == -1) _exit(0);
- }
+ if (buffer_put(&bs, &ch, 1) == -1) _exit(0);
+ }
}
-void temp_noip()
-{
- out("ZInvalid ipaddr in control/domainips (#4.3.0)\n");
- zerodie();
+void temp_noip()
+{
+ out("ZInvalid ipaddr in control/domainips (#4.3.0)\n");
+ zerodie();
}
-void temp_nomem()
-{
- out("ZOut of memory. (#4.3.0)\n");
- zerodie();
+void temp_nomem()
+{
+ out("ZOut of memory. (#4.3.0)\n");
+ zerodie();
}
-void temp_oserr()
-{
- out("ZSystem resources temporarily unavailable. (#4.3.0)\n");
- zerodie();
+void temp_oserr()
+{
+ out("ZSystem resources temporarily unavailable. (#4.3.0)\n");
+ zerodie();
}
-void temp_osip()
-{
- out("ZCan't bind to local ip address: ");
- outsafe(&sendip);
+void temp_osip()
+{
+ out("ZCan't bind to local ip address: ");
+ outsafe(&sendip);
out(". (#4.3.0)\n");
- zerodie();
+ zerodie();
}
-void temp_noconn()
-{
+void temp_noconn()
+{
out("ZSorry, I wasn't able to establish an SMTP connection: ");
- outsafe(&canonhost);
+ outsafe(&canonhost);
out(". (#4.3.0)\n");
- zerodie();
+ zerodie();
}
-void temp_qmtpnoc()
-{
+void temp_qmtpnoc()
+{
out("ZSorry, I wasn't able to establish an QMTP connection: ");
- outsafe(&canonhost);
+ outsafe(&canonhost);
out(". (#4.3.1)\n");
- zerodie();
+ zerodie();
}
-void temp_read()
-{
- out("ZUnable to read message. (#4.3.0)\n");
- zerodie();
+void temp_read()
+{
+ out("ZUnable to read message. (#4.3.0)\n");
+ zerodie();
}
-void temp_dnscanon()
-{
- out("ZCNAME lookup failed temporarily for: ");
- outsafe(&canonhost);
+void temp_dnscanon()
+{
+ out("ZCNAME lookup failed temporarily for: ");
+ outsafe(&canonhost);
out(". (#4.4.3)\n");
- zerodie();
+ zerodie();
}
-void temp_dns()
-{
- out("ZSorry, I couldn't find any host named: ");
- outsafe(&host);
- out(". (#4.1.2)\n");
- zerodie();
+void temp_dns()
+{
+ out("ZSorry, I couldn't find any host named: ");
+ outsafe(&host);
+ out(". (#4.1.2)\n");
+ zerodie();
}
-void temp_nomx()
-{
+void temp_nomx()
+{
out("ZSorry, I couldn't find a mail exchanger or IP address for: ");
- outsafe(&host);
- out(". Will try again. (#4.1.2)\n");
- zerodie();
+ outsafe(&host);
+ out(". Will try again. (#4.1.2)\n");
+ zerodie();
}
-void temp_chdir()
-{
- out("ZUnable to switch to home directory. (#4.3.0)\n");
- zerodie();
+void temp_chdir()
+{
+ out("ZUnable to switch to home directory. (#4.3.0)\n");
+ zerodie();
}
-void temp_control()
-{
- out("ZUnable to read control files. (#4.3.0)\n");
- zerodie();
+void temp_control()
+{
+ out("ZUnable to read control files. (#4.3.0)\n");
+ zerodie();
}
-void perm_partialline()
-{
- out("DSMTP cannot transfer messages with partial final lines. (#5.6.2)\n");
- zerodie();
+void perm_partialline()
+{
+ out("DSMTP cannot transfer messages with partial final lines. (#5.6.2)\n");
+ zerodie();
}
-void temp_proto()
-{
- out("ZRecipient did not talk proper QMTP (#4.3.0)\n");
- zerodie();
+void temp_proto()
+{
+ out("ZRecipient did not talk proper QMTP (#4.3.0)\n");
+ zerodie();
}
-void perm_usage()
-{
- out("Dqmail-remote was invoked improperly. (#5.3.5)\n");
- zerodie();
+void perm_usage()
+{
+ out("Dqmail-remote was invoked improperly. (#5.3.5)\n");
+ zerodie();
}
-void perm_dns()
-{
- out("DSorry, I couldn't find any host named: ");
- outsafe(&host);
- out(". (#5.1.2)\n");
- zerodie();
+void perm_dns()
+{
+ out("DSorry, I couldn't find any host named: ");
+ outsafe(&host);
+ out(". (#5.1.2)\n");
+ zerodie();
}
-void perm_nomx()
-{
+void perm_nomx()
+{
out("DSorry, I couldn't find a mail exchanger or IP address for: ");
- outsafe(&host);
- out(". (#5.4.4)\n");
- zerodie();
+ outsafe(&host);
+ out(". (#5.4.4)\n");
+ zerodie();
}
-void perm_ambigmx()
-{
+void perm_ambigmx()
+{
out("DSorry. Although I'm listed as a best-preference MX or A for that host,\n\
it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n");
- zerodie();
+ zerodie();
}
-void err_authprot()
+void err_authprot()
{
out("KNo supported AUTH method found, continuing without authentication.\n");
}
@@ -257,17 +256,15 @@ void outhost()
int len;
switch (partner.af) {
- case AF_INET:
- len = ip4_fmt(ipaddr,(char *)&partner.addr.ip4.d); break;
- case AF_INET6:
- len = ip6_fmt(ipaddr,(char *)&partner.addr.ip6.d); break;
- }
- if (buffer_put(&bs,ipaddr,len) == -1) _exit(0);
+ case AF_INET: len = ip4_fmt(ipaddr, (char *)&partner.addr.ip4.d); break;
+ case AF_INET6: len = ip6_fmt(ipaddr, (char *)&partner.addr.ip6.d); break;
+ }
+ if (buffer_put(&bs, ipaddr, len) == -1) _exit(0);
}
int flagcritical = 0;
-void dropped()
+void dropped()
{
out("ZConnected to ");
outhost();
@@ -281,48 +278,48 @@ int timeoutconnect = 60;
int smtpfd;
int timeout = 1200;
-ssize_t saferead(int fd,char *buf,int len)
+ssize_t saferead(int fd, char *buf, int len)
{
int r;
if (ssl) {
- r = tls_timeoutread(timeout,smtpfd,smtpfd,ssl,buf,len);
+ r = tls_timeoutread(timeout, smtpfd, smtpfd, ssl, buf, len);
if (r < 0) temp_tlserr();
} else {
- r = timeoutread(timeout,smtpfd,buf,len);
+ r = timeoutread(timeout, smtpfd, buf, len);
}
if (r <= 0) dropped();
return r;
}
-ssize_t safewrite(int fd,char *buf,int len)
+ssize_t safewrite(int fd, char *buf, int len)
{
int r;
if (ssl) {
- r = tls_timeoutwrite(timeout,smtpfd,smtpfd,ssl,buf,len);
+ r = tls_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len);
if (r < 0) temp_tlserr();
} else {
- r = timeoutwrite(timeout,smtpfd,buf,len);
+ r = timeoutwrite(timeout, smtpfd, buf, len);
}
if (r <= 0) dropped();
return r;
}
char inbuf[BUFFER_MTUSIZE];
-buffer bi = BUFFER_INIT(read,0,inbuf,sizeof(inbuf));
+buffer bi = BUFFER_INIT(read, 0, inbuf, sizeof(inbuf));
char outbuf[BUFFER_MTUSIZE];
-buffer bo = BUFFER_INIT(safewrite,-1,outbuf,sizeof(outbuf));
+buffer bo = BUFFER_INIT(safewrite, -1, outbuf, sizeof(outbuf));
char frombuf[BUFFER_SMALL];
-buffer bf = BUFFER_INIT(saferead,-1,frombuf,sizeof(frombuf));
+buffer bf = BUFFER_INIT(saferead, -1, frombuf, sizeof(frombuf));
static stralloc smtptext = {0};
static stralloc header = {0};
-
+
void get(char *ch)
{
- buffer_get(&bf,ch,1);
+ buffer_get(&bf, ch, 1);
if (*ch != '\r')
if (smtptext.len < HUGESMTPTEXT)
- if (!stralloc_append(&smtptext,ch)) temp_nomem();
+ if (!stralloc_append(&smtptext, ch)) temp_nomem();
}
unsigned long smtpcode()
@@ -330,11 +327,14 @@ unsigned long smtpcode()
unsigned char ch;
unsigned long code;
- if (!stralloc_copys(&smtptext,"")) temp_nomem();
+ if (!stralloc_copys(&smtptext, "")) temp_nomem();
- get(&ch); code = ch - '0';
- get(&ch); code = code * 10 + (ch - '0');
- get(&ch); code = code * 10 + (ch - '0');
+ get(&ch);
+ code = ch - '0';
+ get(&ch);
+ code = code * 10 + (ch - '0');
+ get(&ch);
+ code = code * 10 + (ch - '0');
for (;;) {
get(&ch);
if (ch != '-') break;
@@ -350,19 +350,20 @@ unsigned long smtpcode()
void outsmtptext()
{
- int i;
- if (smtptext.s) if (smtptext.len) {
- out("Remote host said: ");
- for (i = 0; i < smtptext.len; ++i)
- if (!smtptext.s[i]) smtptext.s[i] = '?';
- if (buffer_put(&bs,smtptext.s,smtptext.len) == -1) _exit(0);
- smtptext.len = 0;
- }
+ int i;
+ if (smtptext.s)
+ if (smtptext.len) {
+ out("Remote host said: ");
+ for (i = 0; i < smtptext.len; ++i)
+ if (!smtptext.s[i]) smtptext.s[i] = '?';
+ if (buffer_put(&bs, smtptext.s, smtptext.len) == -1) _exit(0);
+ smtptext.len = 0;
+ }
}
-void quit(char *prepend,char *append)
+void quit(char *prepend, char *append)
{
- buffer_putsflush(&bo,"QUIT\r\n");
+ buffer_putsflush(&bo, "QUIT\r\n");
/* waiting for remote side is just too ridiculous */
out(prepend);
outhost();
@@ -378,23 +379,22 @@ void blast()
char ch;
for (;;) {
- r = buffer_get(&bi,&ch,1);
+ r = buffer_get(&bi, &ch, 1);
if (r == 0) break;
if (r == -1) temp_read();
- if (ch == '.') buffer_put(&bo,".",1);
+ if (ch == '.') buffer_put(&bo, ".", 1);
while (ch != '\n') {
- if (ch != '\r')
- buffer_put(&bo,&ch,1); // DKIM input
- r = buffer_get(&bi,&ch,1);
+ if (ch != '\r') buffer_put(&bo, &ch, 1); // DKIM input
+ r = buffer_get(&bi, &ch, 1);
if (r == 0) perm_partialline();
if (r == -1) temp_read();
}
- buffer_put(&bo,"\r\n",2);
+ buffer_put(&bo, "\r\n", 2);
}
flagcritical = 1;
- buffer_put(&bo,".\r\n",3);
+ buffer_put(&bo, ".\r\n", 3);
buffer_flush(&bo);
}
@@ -422,47 +422,46 @@ void tls_init()
ssl_errstr();
if (!ctx) temp_tlsctx();
-/* Fetch CA infos for dest */
+ /* Fetch CA infos for dest */
- if (flagverify > 0)
- if (cafile.len || cadir.len)
- if (!ssl_ca(ctx,cafile.s,cadir.s,(int) verifydepth)) temp_tlsca();
+ if (flagverify > 0)
+ if (cafile.len || cadir.len)
+ if (!ssl_ca(ctx, cafile.s, cadir.s, (int)verifydepth)) temp_tlsca();
- if (ciphers.len)
- if (!ssl_ciphers(ctx,ciphers.s)) temp_tlscipher();
+ if (ciphers.len)
+ if (!ssl_ciphers(ctx, ciphers.s)) temp_tlscipher();
-/* Prepare for Certificate Request */
+ /* Prepare for Certificate Request */
- if (flagtlsdomain == 2)
- switch (tls_certkey(ctx,certfile.s,keyfile.s,keypwd.s)) {
- case 0: break;
- case -1: temp_tlscert();
+ if (flagtlsdomain == 2) switch (tls_certkey(ctx, certfile.s, keyfile.s, keypwd.s))
+ {
+ case 0: break;
+ case -1: temp_tlscert();
case -2: temp_tlskey();
- case -3: temp_tlschk();
+ case -3: temp_tlschk();
}
-/* Set SSL Context */
+ /* Set SSL Context */
- ssl = ssl_new(ctx,smtpfd);
+ ssl = ssl_new(ctx, smtpfd);
if (!ssl) temp_tlsctx();
-/* Setup SSL FDs */
-
- if (!tls_conn(ssl,smtpfd)) temp_tlscon();
+ /* Setup SSL FDs */
+
+ if (!tls_conn(ssl, smtpfd)) temp_tlscon();
-/* Go on in none-blocking mode */
+ /* Go on in none-blocking mode */
- if (tls_timeoutconn(timeout,smtpfd,smtpfd,ssl) <= 0)
- temp_tlserr();
+ if (tls_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0) temp_tlserr();
}
int starttls_peer()
{
int i = 0;
- while ((i += str_chr(smtptext.s+i,'\n') + 1) &&
- (i + 8 < smtptext.len) ) {
- if (!str_diffn(smtptext.s + i + 4,"STARTTLS",8)) return 1; }
+ while ((i += str_chr(smtptext.s + i, '\n') + 1) && (i + 8 < smtptext.len)) {
+ if (!str_diffn(smtptext.s + i + 4, "STARTTLS", 8)) return 1;
+ }
return 0;
}
@@ -470,48 +469,61 @@ int starttls_peer()
void tls_peercheck()
{
X509 *cert;
- STACK_OF(X509) *certs;
-
+ STACK_OF(X509) * certs;
+
cert = SSL_get_peer_certificate(ssl);
- if (!cert) { flagtls = 100; return; }
+ if (!cert) {
+ flagtls = 100;
+ return;
+ }
if ((certs = SSL_get_peer_cert_chain(ssl)) == NULL) {
certs = sk_X509_new_null();
sk_X509_push(certs, cert);
}
- if (flagverify == -2) { // fingerprinting is silent
- if (cafile.len) case_lowerb(cafile.s,cafile.len);
- switch (tls_fingerprint(cert,cafile.s + 1,cafile.len - 2)) {
- case -1: temp_tlspeercert();
- case -2: temp_tlsdigest();
- case -3: temp_invaliddigest();
- case 0: temp_tlscertfp();
- case 1: flagtls = 104; break;
+ if (flagverify == -2) { // fingerprinting is silent
+ if (cafile.len) case_lowerb(cafile.s, cafile.len);
+ switch (tls_fingerprint(cert, cafile.s + 1, cafile.len - 2)) {
+ case -1: temp_tlspeercert();
+ case -2: temp_tlsdigest();
+ case -3: temp_invaliddigest();
+ case 0: temp_tlscertfp();
+ case 1: flagtls = 104; break;
}
- }
-
- if (flagverify >= 0) { // TLSA is default
- switch (tlsa_check(certs,remotehost,port)) {
- case -4: temp_tlsamissing(); break; /* FIXME */
- case -3: temp_tlsainvalid(); break;
- case -2: break; // unsupported type; may happen
- case -1: break; // weird TLSA record
- case 0: break; // no TLSA record given
- case 1: case 2: flagtls = 107; flagverify = 3; break; // full certchain available (-PKIX)
- case 3: flagtls = 106; flagverify = 0; break; // TA-CA; verify wont work
- case 4: flagtls = 105; flagverify = 0; break; // Endpoint only
+ }
+
+ if (flagverify >= 0) { // TLSA is default
+ switch (tlsa_check(certs, remotehost, port)) {
+ case -4: temp_tlsamissing(); break; /* FIXME */
+ case -3: temp_tlsainvalid(); break;
+ case -2: break; // unsupported type; may happen
+ case -1: break; // weird TLSA record
+ case 0: break; // no TLSA record given
+ case 1:
+ case 2:
+ flagtls = 107;
+ flagverify = 3;
+ break; // full certchain available (-PKIX)
+ case 3:
+ flagtls = 106;
+ flagverify = 0;
+ break; // TA-CA; verify wont work
+ case 4:
+ flagtls = 105;
+ flagverify = 0;
+ break; // Endpoint only
}
}
if (flagverify > 0) {
- switch (tls_checkpeer(ssl,cert,remotehost,flagtls,flagverify)) {
+ switch (tls_checkpeer(ssl, cert, remotehost, flagtls, flagverify)) {
case -1: temp_tlspeercert();
- case -2: temp_tlspeerverify();
- case -3: temp_tlspeervalid();
- case 1: flagtls = 101; break;
- case 2: flagtls = 102; break;
- case 3: flagtls = 103; break;
+ case -2: temp_tlspeerverify();
+ case -3: temp_tlspeervalid();
+ case 1: flagtls = 101; break;
+ case 2: flagtls = 102; break;
+ case 3: flagtls = 103; break;
}
}
@@ -519,13 +531,13 @@ void tls_peercheck()
X509_free(cert);
X509_free(certs);
-
+
return;
}
/* this file is too long --------------------------------------- smtp UTF8 */
-int utf8string(unsigned char *ch,int len)
+int utf8string(unsigned char *ch, int len)
{
int i = 0;
while (i < len)
@@ -541,31 +553,31 @@ int utf8received()
char ch;
stralloc receivedline = {0};
-/* we consider only our own last written header */
+ /* we consider only our own last written header */
for (;;) {
- r = buffer_get(&bi,&ch,1);
+ r = buffer_get(&bi, &ch, 1);
if (r == 0) break;
if (r == -1) temp_read();
- if (ch == '\r') continue; // DKIM
+ if (ch == '\r') continue; // DKIM
if (ch == '\n') {
- if (!stralloc_append(&header,"\r")) temp_nomem(); /* received.c does not add '\r' */
- if (!stralloc_append(&header,"\n")) temp_nomem();
- if (case_starts(receivedline.s,"Date:")) return 0; /* header to quit asap */
- if (case_starts(receivedline.s,"Received: from")) received++; /* found Received header */
+ if (!stralloc_append(&header, "\r")) temp_nomem(); /* received.c does not add '\r' */
+ if (!stralloc_append(&header, "\n")) temp_nomem();
+ if (case_starts(receivedline.s, "Date:")) return 0; /* header to quit asap */
+ if (case_starts(receivedline.s, "Received: from")) received++; /* found Received header */
if (received) {
- if (case_starts(receivedline.s," by ")) {
- for (i = 6; i < receivedline.len - 6; ++i)
+ if (case_starts(receivedline.s, " by ")) {
+ for (i = 6; i < receivedline.len - 6; ++i)
if (*(receivedline.s + i) == ' ')
- if (case_starts(receivedline.s + i + 1,"with UTF8")) return 1;
+ if (case_starts(receivedline.s + i + 1, "with UTF8")) return 1;
return 0;
- }
+ }
}
- if (!stralloc_copys(&receivedline,"")) temp_nomem();
+ if (!stralloc_copys(&receivedline, "")) temp_nomem();
} else {
- if (!stralloc_append(&header,&ch)) temp_nomem();
- if (!stralloc_catb(&receivedline,&ch,1)) temp_nomem();
+ if (!stralloc_append(&header, &ch)) temp_nomem();
+ if (!stralloc_catb(&receivedline, &ch, 1)) temp_nomem();
}
}
return 0;
@@ -581,60 +593,59 @@ int smtp_size()
int i;
if (smtptext.len > 10)
for (i = 0; i < smtptext.len; ++i) {
- if (case_starts(smtptext.s + i,"SIZE ")) return 1;
- }
- return 0;;
+ if (case_starts(smtptext.s + i, "SIZE ")) return 1;
+ }
+ return 0;
+ ;
}
void smtp_greeting()
{
- buffer_puts(&bo,"EHLO ");
- buffer_put(&bo,helohost.s,helohost.len);
- buffer_puts(&bo,"\r\n");
+ buffer_puts(&bo, "EHLO ");
+ buffer_put(&bo, helohost.s, helohost.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
if (smtpcode() != 250) {
- buffer_puts(&bo,"HELO ");
- buffer_put(&bo,helohost.s,helohost.len);
- buffer_puts(&bo,"\r\n");
+ buffer_puts(&bo, "HELO ");
+ buffer_put(&bo, helohost.s, helohost.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
code = smtpcode();
authsender = 0;
- if (code >= 500) quit("DConnected to "," but my name was rejected");
- if (code != 250) quit("ZConnected to "," but my name was rejected");
+ if (code >= 500) quit("DConnected to ", " but my name was rejected");
+ if (code != 250) quit("ZConnected to ", " but my name was rejected");
}
flagsize = smtp_size();
}
void smtp_starttls()
{
- buffer_puts(&bo,"STARTTLS\r\n");
+ buffer_puts(&bo, "STARTTLS\r\n");
buffer_flush(&bo);
if (smtpcode() == 220) {
tls_init();
tls_peercheck();
smtp_greeting();
- }
- else {
+ } else {
flagtls = -2;
- quit("ZConnected to "," but STARTTLS was rejected");
+ quit("ZConnected to ", " but STARTTLS was rejected");
}
}
void mailfrom()
{
- buffer_puts(&bo,"MAIL FROM:<");
- buffer_put(&bo,sender.s,sender.len);
- buffer_puts(&bo,">");
- if (flagutf8 || utf8received())
- buffer_puts(&bo," SMTPUTF8");
+ buffer_puts(&bo, "MAIL FROM:<");
+ buffer_put(&bo, sender.s, sender.len);
+ buffer_puts(&bo, ">");
+ if (flagutf8 || utf8received()) buffer_puts(&bo, " SMTPUTF8");
if (flagsize && msize) {
- buffer_puts(&bo," SIZE=");
- buffer_puts(&bo,msgsize);
+ buffer_puts(&bo, " SIZE=");
+ buffer_puts(&bo, msgsize);
}
- buffer_puts(&bo,"\r\n");
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
}
@@ -653,22 +664,22 @@ stralloc xuser = {0};
static const char hextab[] = "0123456789abcdef";
-int xtext(stralloc *sa,char *s,int len)
+int xtext(stralloc *sa, char *s, int len)
{
int i;
unsigned char c;
char xch[2];
- if (!stralloc_copys(sa,"")) temp_nomem();
+ if (!stralloc_copys(sa, "")) temp_nomem();
for (i = 0; i < len; i++) {
c = s[i];
if (c < 33 || c > 126 || c == '=' || c == '+') {
xch[0] = hextab[(c >> 4) & 0x0f];
xch[1] = hextab[c & 0x0f];
- if (!stralloc_catb(sa,xch,2)) temp_nomem();
- } else
- if (!stralloc_catb(sa,s + i,1)) temp_nomem();
+ if (!stralloc_catb(sa, xch, 2)) temp_nomem();
+ } else if (!stralloc_catb(sa, s + i, 1))
+ temp_nomem();
}
return sa->len;
@@ -676,73 +687,72 @@ int xtext(stralloc *sa,char *s,int len)
void mailfrom_xtext()
{
- if (!xtext(&xuser,user.s,user.len)) temp_nomem();
- buffer_puts(&bo,"MAIL FROM:<");
- buffer_put(&bo,sender.s,sender.len);
- buffer_puts(&bo,"> AUTH=");
- buffer_put(&bo,xuser.s,xuser.len);
- if (flagutf8 || utf8received())
- buffer_puts(&bo," SMTPUTF8");
+ if (!xtext(&xuser, user.s, user.len)) temp_nomem();
+ buffer_puts(&bo, "MAIL FROM:<");
+ buffer_put(&bo, sender.s, sender.len);
+ buffer_puts(&bo, "> AUTH=");
+ buffer_put(&bo, xuser.s, xuser.len);
+ if (flagutf8 || utf8received()) buffer_puts(&bo, " SMTPUTF8");
if (flagsize && msize) {
- buffer_puts(&bo," SIZE=");
- buffer_puts(&bo,msgsize);
+ buffer_puts(&bo, " SIZE=");
+ buffer_puts(&bo, msgsize);
}
- buffer_puts(&bo,"\r\n");
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
}
-
+
int mailfrom_plain()
{
- buffer_puts(&bo,"AUTH PLAIN\r\n");
+ buffer_puts(&bo, "AUTH PLAIN\r\n");
buffer_flush(&bo);
- if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (AUTH PLAIN)");
+ if (smtpcode() != 334) quit("ZConnected to ", " but authentication was rejected (AUTH PLAIN)");
- if (!stralloc_cats(&plain,"")) temp_nomem(); /* RFC 4616 section 2 */
+ if (!stralloc_cats(&plain, "")) temp_nomem(); /* RFC 4616 section 2 */
if (!stralloc_0(&plain)) temp_nomem();
- if (!stralloc_cat(&plain,&user)) temp_nomem(); /* user-id */
+ if (!stralloc_cat(&plain, &user)) temp_nomem(); /* user-id */
if (!stralloc_0(&plain)) temp_nomem();
- if (!stralloc_cat(&plain,&pass)) temp_nomem(); /* password */
- if (b64encode(&plain,&auth)) quit("ZConnected to "," but unable to base64encode (plain)");
- buffer_put(&bo,auth.s,auth.len);
- buffer_puts(&bo,"\r\n");
+ if (!stralloc_cat(&plain, &pass)) temp_nomem(); /* password */
+ if (b64encode(&plain, &auth)) quit("ZConnected to ", " but unable to base64encode (plain)");
+ buffer_put(&bo, auth.s, auth.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
switch (smtpcode()) {
case 235: mailfrom_xtext(); break;
- case 432: quit("DConnected to "," but password expired");
- case 534: quit("ZConnected to "," but authentication mechamism too weak (plain)");
- default: quit("ZConnected to "," but authentication was rejected (plain)");
+ case 432: quit("DConnected to ", " but password expired");
+ case 534: quit("ZConnected to ", " but authentication mechamism too weak (plain)");
+ default: quit("ZConnected to ", " but authentication was rejected (plain)");
}
return 0;
}
int mailfrom_login()
{
- buffer_puts(&bo,"AUTH LOGIN\r\n");
+ buffer_puts(&bo, "AUTH LOGIN\r\n");
buffer_flush(&bo);
- if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (AUTH LOGIN)");
- if (!stralloc_copys(&auth,"")) temp_nomem();
- if (b64encode(&user,&auth)) quit("ZConnected to "," but unable to base64encode user");
+ if (smtpcode() != 334) quit("ZConnected to ", " but authentication was rejected (AUTH LOGIN)");
+ if (!stralloc_copys(&auth, "")) temp_nomem();
+ if (b64encode(&user, &auth)) quit("ZConnected to ", " but unable to base64encode user");
- buffer_put(&bo,auth.s,auth.len);
- buffer_puts(&bo,"\r\n");
+ buffer_put(&bo, auth.s, auth.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
- if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (username)");
+ if (smtpcode() != 334) quit("ZConnected to ", " but authentication was rejected (username)");
- if (!stralloc_copys(&auth,"")) temp_nomem();
- if (b64encode(&pass,&auth)) quit("ZConnected to "," but unable to base64encode pass");
- buffer_put(&bo,auth.s,auth.len);
- buffer_puts(&bo,"\r\n");
+ if (!stralloc_copys(&auth, "")) temp_nomem();
+ if (b64encode(&pass, &auth)) quit("ZConnected to ", " but unable to base64encode pass");
+ buffer_put(&bo, auth.s, auth.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
switch (smtpcode()) {
case 235: mailfrom_xtext(); break;
- case 432: quit("DConnected to "," but password expired");
- case 534: quit("ZConnected to "," but authentication mechanism is too weak (login)");
- default: quit("ZConnected to "," but authentication was rejected (login)");
+ case 432: quit("DConnected to ", " but password expired");
+ case 534: quit("ZConnected to ", " but authentication mechanism is too weak (login)");
+ default: quit("ZConnected to ", " but authentication was rejected (login)");
}
return 0;
}
@@ -753,41 +763,42 @@ int mailfrom_cram()
unsigned char digest[16];
unsigned char digascii[33];
- buffer_puts(&bo,"AUTH CRAM-MD5\r\n");
+ buffer_puts(&bo, "AUTH CRAM-MD5\r\n");
buffer_flush(&bo);
- if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (AUTH CRAM-MD5)");
- if (str_chr(smtptext.s + 4,' ')) { /* Challenge */
- if (!stralloc_copys(&slop,"")) temp_nomem();
- if (!stralloc_copyb(&slop,smtptext.s + 4,smtptext.len - 5)) temp_nomem();
- if (b64decode(slop.s,slop.len,&chal)) quit("ZConnected to "," but unable to base64decode challenge");
+ if (smtpcode() != 334) quit("ZConnected to ", " but authentication was rejected (AUTH CRAM-MD5)");
+ if (str_chr(smtptext.s + 4, ' ')) { /* Challenge */
+ if (!stralloc_copys(&slop, "")) temp_nomem();
+ if (!stralloc_copyb(&slop, smtptext.s + 4, smtptext.len - 5)) temp_nomem();
+ if (b64decode(slop.s, slop.len, &chal))
+ quit("ZConnected to ", " but unable to base64decode challenge");
}
- hmac_md5((unsigned char *)chal.s,chal.len,pass.s,pass.len,digest);
+ hmac_md5((unsigned char *)chal.s, chal.len, pass.s, pass.len, digest);
- for (j = 0; j < 16; j++) { /* HEX => ASCII */
+ for (j = 0; j < 16; j++) { /* HEX => ASCII */
digascii[2 * j] = hextab[digest[j] >> 4];
digascii[2 * j + 1] = hextab[digest[j] & 0x0f];
}
- digascii[32]=0;
+ digascii[32] = 0;
- if (!stralloc_copys(&slop,"")) temp_nomem();
- if (!stralloc_cat(&slop,&user)) temp_nomem(); /* user-id */
- if (!stralloc_cats(&slop," ")) temp_nomem();
- if (!stralloc_catb(&slop,digascii,32)) temp_nomem(); /* digest */
+ if (!stralloc_copys(&slop, "")) temp_nomem();
+ if (!stralloc_cat(&slop, &user)) temp_nomem(); /* user-id */
+ if (!stralloc_cats(&slop, " ")) temp_nomem();
+ if (!stralloc_catb(&slop, digascii, 32)) temp_nomem(); /* digest */
- if (!stralloc_copys(&auth,"")) temp_nomem();
- if (b64encode(&slop,&auth)) quit("ZConnected to "," but unable to base64encode username+digest");
+ if (!stralloc_copys(&auth, "")) temp_nomem();
+ if (b64encode(&slop, &auth)) quit("ZConnected to ", " but unable to base64encode username+digest");
- buffer_put(&bo,auth.s,auth.len);
- buffer_puts(&bo,"\r\n");
+ buffer_put(&bo, auth.s, auth.len);
+ buffer_puts(&bo, "\r\n");
buffer_flush(&bo);
switch (smtpcode()) {
case 235: mailfrom_xtext(); break;
- case 432: quit("DConnected to "," but password expired");
- case 534: quit("ZConnected to "," but authentication mechamism too weak (cram)");
- default: quit("ZConnected to "," but authentication was rejected (cram)");
+ case 432: quit("DConnected to ", " but password expired");
+ case 534: quit("ZConnected to ", " but authentication mechamism too weak (cram)");
+ default: quit("ZConnected to ", " but authentication was rejected (cram)");
}
return 0;
}
@@ -796,13 +807,13 @@ void smtp_auth()
{
int i;
- if (smtptext.len > 8)
+ if (smtptext.len > 8)
for (i = 4; i < smtptext.len - 5; ++i) {
- if (case_starts(smtptext.s + i,"CRAM"))
+ if (case_starts(smtptext.s + i, "CRAM"))
if (mailfrom_cram() >= 0) return;
- if (case_starts(smtptext.s + i,"LOGIN"))
+ if (case_starts(smtptext.s + i, "LOGIN"))
if (mailfrom_login() >= 0) return;
- if (case_starts(smtptext.s + i,"PLAIN"))
+ if (case_starts(smtptext.s + i, "PLAIN"))
if (mailfrom_plain() >= 0) return;
}
err_authprot();
@@ -816,87 +827,105 @@ void smtp()
int flagbother;
int i;
- if (flagtls > 10 && flagtls < 20) { /* SMTPS */
+ if (flagtls > 10 && flagtls < 20) { /* SMTPS */
tls_init();
- tls_peercheck();
+ tls_peercheck();
}
code = smtpcode();
- if (code >= 500) quit("DConnected to "," but sender was rejected");
- if (code == 421 || code == 450) quit("ZConnected to "," but probably greylisted"); /* RFC 6647 */
- if (code >= 400) quit("ZConnected to "," but sender was rejected");
- if (code != 220) quit("ZConnected to "," but greeting failed");
+ if (code >= 500) quit("DConnected to ", " but sender was rejected");
+ if (code == 421 || code == 450) quit("ZConnected to ", " but probably greylisted"); /* RFC 6647 */
+ if (code >= 400) quit("ZConnected to ", " but sender was rejected");
+ if (code != 220) quit("ZConnected to ", " but greeting failed");
smtp_greeting();
- if (flagtls > 0 && flagtls < 10) { /* STARTTLS */
- if (starttls_peer())
- smtp_starttls();
+ if (flagtls > 0 && flagtls < 10) { /* STARTTLS */
+ if (starttls_peer())
+ smtp_starttls();
else if (flagtls > 3 && flagtls != 9) {
- if (!stralloc_0(&host)) temp_nomem();
- temp_tlshost();
+ if (!stralloc_0(&host)) temp_nomem();
+ temp_tlshost();
}
}
- if (user.len && pass.len) /* AUTH */
+ if (user.len && pass.len) /* AUTH */
smtp_auth();
- else
- mailfrom(); /* Mail From */
+ else
+ mailfrom(); /* Mail From */
code = smtpcode();
- if (code >= 500) quit("DConnected to "," but sender was rejected");
- if (code >= 400) quit("ZConnected to "," but sender was probably greylisted");
+ if (code >= 500) quit("DConnected to ", " but sender was rejected");
+ if (code >= 400) quit("ZConnected to ", " but sender was probably greylisted");
- flagbother = 0; /* Rcpt To */
+ flagbother = 0; /* Rcpt To */
for (i = 0; i < reciplist.len; ++i) {
- buffer_puts(&bo,"RCPT TO:<");
- buffer_put(&bo,reciplist.sa[i].s,reciplist.sa[i].len);
- buffer_puts(&bo,">\r\n");
+ buffer_puts(&bo, "RCPT TO:<");
+ buffer_put(&bo, reciplist.sa[i].s, reciplist.sa[i].len);
+ buffer_puts(&bo, ">\r\n");
buffer_flush(&bo);
- code = smtpcode(); /* Data */
+ code = smtpcode(); /* Data */
if (flagsize) {
- if (code == 552) quit("DConnected to "," but message size is too large");
- if (code == 452) quit("ZConnected to "," however insufficient storage space available");
- }
+ if (code == 552) quit("DConnected to ", " but message size is too large");
+ if (code == 452) quit("ZConnected to ", " however insufficient storage space available");
+ }
if (code == 421 || code == 450) { // Postfix merde ;-)
- out("s"); outhost(); out(" sender is greylisting.\n");
- outsmtptext(); zero();
+ out("s");
+ outhost();
+ out(" sender is greylisting.\n");
+ outsmtptext();
+ zero();
} else if (code >= 500) {
- out("h"); outhost(); out(" does not like recipient.\n");
- outsmtptext(); zero();
+ out("h");
+ outhost();
+ out(" does not like recipient.\n");
+ outsmtptext();
+ zero();
} else if (code >= 400) {
- out("s"); outhost(); out(" does not like recipient.\n");
- outsmtptext(); zero();
+ out("s");
+ outhost();
+ out(" does not like recipient.\n");
+ outsmtptext();
+ zero();
} else {
- out("r"); zero();
+ out("r");
+ zero();
flagbother = 1;
}
}
- if (!flagbother) quit("DGiving up on ","");
+ if (!flagbother) quit("DGiving up on ", "");
- buffer_putsflush(&bo,"DATA\r\n");
+ buffer_putsflush(&bo, "DATA\r\n");
code = smtpcode();
- if (code >= 500) quit("D"," failed on DATA command");
- if (code >= 400) quit("Z"," failed on DATA command");
+ if (code >= 500) quit("D", " failed on DATA command");
+ if (code >= 400) quit("Z", " failed on DATA command");
+
+ buffer_putflush(&bo, header.s, header.len);
- buffer_putflush(&bo,header.s,header.len);
-
blast();
code = smtpcode();
flagcritical = 0;
- if (code >= 500) quit("D"," failed after I sent the message");
- if (code >= 400) quit("Z"," failed after I sent the message");
+ if (code >= 500) quit("D", " failed after I sent the message");
+ if (code >= 400) quit("Z", " failed after I sent the message");
switch (flagtls) { // StartTLS + SMTPS
- case 100: case 110: quit("K"," TLS transmitted message accepted"); break;
- case 101: case 111: quit("K"," TLS (verified CA) transmitted message accepted"); break;
- case 102: case 112: quit("K"," TLS (validated CA+DN*) transmitted message accepted"); break;
- case 103: case 113: quit("K"," TLS (validated CA+DN) transmitted message accepted"); break;
- case 104: case 114: quit("K"," TLS (CERT pinning) transmitted message accepted"); break;
- case 105: case 115: quit("K"," TLS (TLSA EE validated) transmitted message accepted"); break;
- case 106: case 116: quit("K"," TLS (TLSA TA validated) transmitted message accepted"); break;
- case 107: case 117: quit("K"," TLS (TLSA PKIX verified) transmitted message accepted"); break;
- default: quit("K"," accepted message"); break;
+ case 100:
+ case 110: quit("K", " TLS transmitted message accepted"); break;
+ case 101:
+ case 111: quit("K", " TLS (verified CA) transmitted message accepted"); break;
+ case 102:
+ case 112: quit("K", " TLS (validated CA+DN*) transmitted message accepted"); break;
+ case 103:
+ case 113: quit("K", " TLS (validated CA+DN) transmitted message accepted"); break;
+ case 104:
+ case 114: quit("K", " TLS (CERT pinning) transmitted message accepted"); break;
+ case 105:
+ case 115: quit("K", " TLS (TLSA EE validated) transmitted message accepted"); break;
+ case 106:
+ case 116: quit("K", " TLS (TLSA TA validated) transmitted message accepted"); break;
+ case 107:
+ case 117: quit("K", " TLS (TLSA PKIX verified) transmitted message accepted"); break;
+ default: quit("K", " accepted message"); break;
}
}
@@ -914,44 +943,44 @@ void qmtp()
char num[FMT_ULONG];
int flagallok;
- if (qmtpsend == 2) { /* QMTPS */
+ if (qmtpsend == 2) { /* QMTPS */
tls_init();
tls_peercheck();
}
-/* the following code was substantially taken from serialmail's serialqmtp.c */
+ /* the following code was substantially taken from serialmail's serialqmtp.c */
- scan_ulong(msgsize,&len);
- buffer_put(&bo,num,fmt_ulong(num,len + 1));
- buffer_put(&bo,":\n",2);
+ scan_ulong(msgsize, &len);
+ buffer_put(&bo, num, fmt_ulong(num, len + 1));
+ buffer_put(&bo, ":\n", 2);
while (len > 0) {
n = buffer_feed(&bi);
- if (n <= 0) _exit(1); /* wise guy again */
+ if (n <= 0) _exit(1); /* wise guy again */
x = buffer_PEEK(&bi);
- buffer_put(&bo,x,n);
- buffer_SEEK(&bi,n);
+ buffer_put(&bo, x, n);
+ buffer_SEEK(&bi, n);
len -= n;
}
- buffer_put(&bo,",",1);
+ buffer_put(&bo, ",", 1);
len = sender.len;
- buffer_put(&bo,num,fmt_ulong(num,len));
- buffer_put(&bo,":",1);
- buffer_put(&bo,sender.s,sender.len);
- buffer_put(&bo,",",1);
+ buffer_put(&bo, num, fmt_ulong(num, len));
+ buffer_put(&bo, ":", 1);
+ buffer_put(&bo, sender.s, sender.len);
+ buffer_put(&bo, ",", 1);
len = 0;
for (i = 0; i < reciplist.len; ++i)
- len += fmt_ulong(num,reciplist.sa[i].len) + 1 + reciplist.sa[i].len + 1;
- buffer_put(&bo,num,fmt_ulong(num,len));
- buffer_put(&bo,":",1);
+ len += fmt_ulong(num, reciplist.sa[i].len) + 1 + reciplist.sa[i].len + 1;
+ buffer_put(&bo, num, fmt_ulong(num, len));
+ buffer_put(&bo, ":", 1);
for (i = 0; i < reciplist.len; ++i) {
- buffer_put(&bo,num,fmt_ulong(num,reciplist.sa[i].len));
- buffer_put(&bo,":",1);
- buffer_put(&bo,reciplist.sa[i].s,reciplist.sa[i].len);
- buffer_put(&bo,",",1);
+ buffer_put(&bo, num, fmt_ulong(num, reciplist.sa[i].len));
+ buffer_put(&bo, ":", 1);
+ buffer_put(&bo, reciplist.sa[i].s, reciplist.sa[i].len);
+ buffer_put(&bo, ",", 1);
}
- buffer_put(&bo,",",1);
+ buffer_put(&bo, ",", 1);
buffer_flush(&bo);
flagallok = 1;
@@ -966,14 +995,15 @@ void qmtp()
len = 10 * len + (ch - '0');
}
if (!len) temp_proto();
- get(&ch); --len;
+ get(&ch);
+ --len;
if ((ch != 'Z') && (ch != 'D') && (ch != 'K')) temp_proto();
- if (!stralloc_copyb(&smtptext,&ch,1)) temp_proto();
+ if (!stralloc_copyb(&smtptext, &ch, 1)) temp_proto();
if (flagtls == 100) {
- if (!stralloc_cats(&smtptext,"qmtps:")) temp_nomem();
+ if (!stralloc_cats(&smtptext, "qmtps:")) temp_nomem();
} else {
- if (!stralloc_cats(&smtptext,"qmtp:")) temp_nomem();
+ if (!stralloc_cats(&smtptext, "qmtp:")) temp_nomem();
}
while (len > 0) {
@@ -989,22 +1019,26 @@ void qmtp()
if (ch != ',') temp_proto();
smtptext.s[smtptext.len - 1] = '\n';
- if (smtptext.s[0] == 'K') out("r");
+ if (smtptext.s[0] == 'K')
+ out("r");
else if (smtptext.s[0] == 'D') {
out("h");
flagallok = 0;
- }
- else { /* if (smtptext.s[0] == 'Z') */
+ } else { /* if (smtptext.s[0] == 'Z') */
out("s");
flagallok = 0;
}
- if (buffer_put(&bs,smtptext.s + 1,smtptext.len - 1) == -1) temp_qmtpnoc();
+ if (buffer_put(&bs, smtptext.s + 1, smtptext.len - 1) == -1) temp_qmtpnoc();
zero();
}
if (!flagallok) {
- out("DGiving up on "); outhost(); out("\n");
+ out("DGiving up on ");
+ outhost();
+ out("\n");
} else {
- out("KAll received okay by "); outhost(); out("\n");
+ out("KAll received okay by ");
+ outhost();
+ out("\n");
}
zerodie();
}
@@ -1013,86 +1047,108 @@ void qmtp()
/* host has to be canonical [A/AAAA record], box has to be quoted */
-void addrmangle(stralloc *saout,char *address,int *flagalias,int flagcname)
+void addrmangle(stralloc *saout, char *address, int *flagalias, int flagcname)
{
int at;
int r = 0;
stralloc cn = {0};
- *flagalias = flagcname; /* saout + flagalias are output */
- if (!flagutf8)
- flagutf8 = utf8string(address,str_len(address));
+ *flagalias = flagcname; /* saout + flagalias are output */
+ if (!flagutf8) flagutf8 = utf8string(address, str_len(address));
- at = str_rchr(address,'@');
+ at = str_rchr(address, '@');
if (!address[at]) {
- if (!stralloc_copys(saout,address)) temp_nomem();
+ if (!stralloc_copys(saout, address)) temp_nomem();
return;
}
- if (!stralloc_copys(&canonbox,address)) temp_nomem();
+ if (!stralloc_copys(&canonbox, address)) temp_nomem();
canonbox.len = at;
- if (!quote(saout,&canonbox)) temp_nomem(); /* saout = 'inbox' name without quotes ;-) */
- if (!stralloc_cats(saout,"@")) temp_nomem();
+ if (!quote(saout, &canonbox)) temp_nomem(); /* saout = 'inbox' name without quotes ;-) */
+ if (!stralloc_cats(saout, "@")) temp_nomem();
- if (!stralloc_copys(&canonhost,address + at + 1)) temp_nomem();
- if (flagcname) { /* no relayhost */
+ if (!stralloc_copys(&canonhost, address + at + 1)) temp_nomem();
+ if (flagcname) { /* no relayhost */
DNS_INIT
- switch ((r = dns_cname(&cn,&canonhost))) {
- case DNS_MEM: temp_nomem();
+ switch ((r = dns_cname(&cn, &canonhost))) {
+ case DNS_MEM: temp_nomem();
case DNS_SOFT: temp_dnscanon();
case DNS_HARD: ; /* alias loop, not our problem */
- default: if (r > 0) *flagalias = 0;
+ default:
+ if (r > 0) *flagalias = 0;
}
}
- if (!stralloc_cat(saout,&canonhost)) temp_nomem();
+ if (!stralloc_cat(saout, &canonhost)) temp_nomem();
}
void getcontrols()
{
if (control_init() == -1) temp_control();
- if (control_readint(&timeout,"control/timeoutremote") == -1) temp_control();
- if (control_readint(&timeoutconnect,"control/timeoutconnect") == -1)
- temp_control();
- if (control_rldef(&helohost,"control/helohost",1,(char *) 0) != 1)
- temp_control();
- switch (control_readfile(&smtproutes,"control/smtproutes",0)) {
+ if (control_readint(&timeout, "control/timeoutremote") == -1) temp_control();
+ if (control_readint(&timeoutconnect, "control/timeoutconnect") == -1) temp_control();
+ if (control_rldef(&helohost, "control/helohost", 1, (char *)0) != 1) temp_control();
+ switch (control_readfile(&smtproutes, "control/smtproutes", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&mapsmtproutes,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&mapsmtproutes,smtproutes.s,smtproutes.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&mapsmtproutes, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&mapsmtproutes, smtproutes.s, smtproutes.len, 1)) temp_nomem();
+ break;
}
- switch (control_readfile(&domainips,"control/domainips",0)) {
+ switch (control_readfile(&domainips, "control/domainips", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&mapdomainips,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&mapdomainips,domainips.s,domainips.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&mapdomainips, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&mapdomainips, domainips.s, domainips.len, 1)) temp_nomem();
+ break;
}
- switch (control_readfile(&authsenders,"control/authsenders",0)) {
+ switch (control_readfile(&authsenders, "control/authsenders", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&mapauthsenders,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&mapauthsenders,authsenders.s,authsenders.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&mapauthsenders, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&mapauthsenders, authsenders.s, authsenders.len, 1)) temp_nomem();
+ break;
}
- switch (control_readfile(&qmtproutes,"control/qmtproutes",0)) {
+ switch (control_readfile(&qmtproutes, "control/qmtproutes", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&mapqmtproutes,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&mapqmtproutes,qmtproutes.s,qmtproutes.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&mapqmtproutes, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&mapqmtproutes, qmtproutes.s, qmtproutes.len, 1)) temp_nomem();
+ break;
}
- switch (control_readfile(&domaincerts,"control/domaincerts",0)) {
+ switch (control_readfile(&domaincerts, "control/domaincerts", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&mapdomaincerts,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&mapdomaincerts,domaincerts.s,domaincerts.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&mapdomaincerts, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&mapdomaincerts, domaincerts.s, domaincerts.len, 1)) temp_nomem();
+ break;
}
- switch (control_readfile(&tlsdestinations,"control/tlsdestinations",0)) {
+ switch (control_readfile(&tlsdestinations, "control/tlsdestinations", 0)) {
case -1: temp_control();
- case 0: if (!constmap_init(&maptlsdestinations,"",0,1)) temp_nomem(); break;
- case 1: if (!constmap_init(&maptlsdestinations,tlsdestinations.s,tlsdestinations.len,1)) temp_nomem(); break;
+ case 0:
+ if (!constmap_init(&maptlsdestinations, "", 0, 1)) temp_nomem();
+ break;
+ case 1:
+ if (!constmap_init(&maptlsdestinations, tlsdestinations.s, tlsdestinations.len, 1)) temp_nomem();
+ break;
}
}
-int main(int argc,char **argv)
+int main(int argc, char **argv)
{
static ipalloc ip = {0};
stralloc netif = {0};
struct stat st;
- int i, j, k;
+ int i, j, k;
int p; /* reserved for port */
int r; /* reserved for return code */
unsigned long random;
@@ -1109,184 +1165,191 @@ int main(int argc,char **argv)
if (chdir(auto_qmail) == -1) temp_chdir();
getcontrols();
- if (!stralloc_copys(&host,argv[1])) temp_nomem();
+ if (!stralloc_copys(&host, argv[1])) temp_nomem();
authsender = 0;
relayhost = 0;
- addrmangle(&sender,argv[2],&flagalias,0);
+ addrmangle(&sender, argv[2], &flagalias, 0);
if (sender.len > 1) {
- i = str_chr(sender.s,'@');
+ i = str_chr(sender.s, '@');
if (sender.s[i] == '@')
- if (!stralloc_copyb(&senddomain,sender.s + i + 1,sender.len - i - 1)) temp_nomem(); // un-terminated
+ if (!stralloc_copyb(&senddomain, sender.s + i + 1, sender.len - i - 1))
+ temp_nomem(); // un-terminated
}
-/* this file is too long -------------------------------------- set domain ip + helohost */
+ /* this file is too long -------------------------------------- set domain ip + helohost */
localip = 0;
-
+
for (i = 0; i <= senddomain.len; ++i)
- if ((i == 0) || (senddomain.s[i] == '.'))
- if ((localip = constmap(&mapdomainips,senddomain.s + i,senddomain.len - i)))
- break;
+ if ((i == 0) || (senddomain.s[i] == '.'))
+ if ((localip = constmap(&mapdomainips, senddomain.s + i, senddomain.len - i))) break;
- if (!localip)
- localip = constmap(&mapdomainips,"*",1); /* one for all */
+ if (!localip) localip = constmap(&mapdomainips, "*", 1); /* one for all */
if (localip) {
- j = str_chr(localip,'%');
+ j = str_chr(localip, '%');
if (localip[j] != '%') j = 0;
- k = str_chr(localip,'|');
+ k = str_chr(localip, '|');
if (localip[k] != '|') k = 0;
- if (k) { /* helohost */
- if (!stralloc_copys(&helohost,localip + k + 1)) temp_nomem();
+ if (k) { /* helohost */
+ if (!stralloc_copys(&helohost, localip + k + 1)) temp_nomem();
if (!stralloc_0(&helohost)) temp_nomem();
localip[k] = 0;
}
- if (j) { /* IF index */
+ if (j) { /* IF index */
localip[j] = 0;
- if (!stralloc_copys(&netif,localip + j + 1)) temp_nomem();
+ if (!stralloc_copys(&netif, localip + j + 1)) temp_nomem();
if (!stralloc_0(&netif)) temp_nomem();
}
}
-/* this file is too long -------------------------------------- authsender routes */
+ /* this file is too long -------------------------------------- authsender routes */
for (i = 0; i <= sender.len; ++i)
if ((i == 0) || (i == sender.len) || (sender.s[i] == '.') || (sender.s[i] == '@'))
- if ((authsender = constmap(&mapauthsenders,sender.s + i,sender.len - i)))
- break;
+ if ((authsender = constmap(&mapauthsenders, sender.s + i, sender.len - i))) break;
if (authsender && !*authsender) authsender = 0;
if (authsender) {
- i = str_chr(authsender,'|');
+ i = str_chr(authsender, '|');
if (authsender[i] == '|') {
- j = str_chr(authsender + i + 1,'|');
+ j = str_chr(authsender + i + 1, '|');
if (authsender[i + j + 1] == '|') {
authsender[i] = 0;
authsender[i + j + 1] = 0;
- if (!stralloc_copys(&user,"")) temp_nomem();
- if (!stralloc_copys(&user,authsender + i + 1)) temp_nomem();
- if (!stralloc_copys(&pass,"")) temp_nomem();
- if (!stralloc_copys(&pass,authsender + i + j + 2)) temp_nomem();
+ if (!stralloc_copys(&user, "")) temp_nomem();
+ if (!stralloc_copys(&user, authsender + i + 1)) temp_nomem();
+ if (!stralloc_copys(&pass, "")) temp_nomem();
+ if (!stralloc_copys(&pass, authsender + i + j + 2)) temp_nomem();
}
}
- p = str_chr(authsender,';');
+ p = str_chr(authsender, ';');
if (authsender[p] == ';') {
- if (authsender[p + 1] == 's') { flagsmtps = 1, p++; }
- scan_ulong(authsender + p + 1,&port);
+ if (authsender[p + 1] == 's') {
+ flagsmtps = 1, p++;
+ }
+ scan_ulong(authsender + p + 1, &port);
authsender[p] = 0;
}
relayhost = authsender;
- if (!stralloc_copys(&host,authsender)) temp_nomem();
+ if (!stralloc_copys(&host, authsender)) temp_nomem();
}
-/* this file is too long -------------------------------------- standard routes */
+ /* this file is too long -------------------------------------- standard routes */
if (!authsender) {
- if (sender.len == 0) { /* bounce routes */
- if ((relayhost = constmap(&mapqmtproutes,"!@",2))) {
- qmtpsend = 1; port = PORT_QMTP;
+ if (sender.len == 0) { /* bounce routes */
+ if ((relayhost = constmap(&mapqmtproutes, "!@", 2))) {
+ qmtpsend = 1;
+ port = PORT_QMTP;
} else
- relayhost = constmap(&mapsmtproutes,"!@",2);
+ relayhost = constmap(&mapsmtproutes, "!@", 2);
}
if (relayhost && !*relayhost) relayhost = 0;
if (!relayhost) {
- for (i = 0; i <= host.len; ++i) { /* qmtproutes */
+ for (i = 0; i <= host.len; ++i) { /* qmtproutes */
if ((i == 0) || (i == host.len) || (host.s[i] == '.'))
- if ((relayhost = constmap(&mapqmtproutes,host.s + i,host.len - i))) {
- qmtpsend = 1; port = PORT_QMTP;
- break;
- } /* default smtproutes */
- if ((relayhost = constmap(&mapsmtproutes,host.s + i,host.len - i)))
+ if ((relayhost = constmap(&mapqmtproutes, host.s + i, host.len - i))) {
+ qmtpsend = 1;
+ port = PORT_QMTP;
break;
+ } /* default smtproutes */
+ if ((relayhost = constmap(&mapsmtproutes, host.s + i, host.len - i))) break;
}
}
if (relayhost && !*relayhost) relayhost = 0;
- if (relayhost) { /* default smtproutes -- authenticated */
- i = str_chr(relayhost,'|');
+ if (relayhost) { /* default smtproutes -- authenticated */
+ i = str_chr(relayhost, '|');
if (relayhost[i] == '|') {
- j = str_chr(relayhost + i + 1,'|'); // authenticate
+ j = str_chr(relayhost + i + 1, '|'); // authenticate
if (relayhost[i + j + 1] == '|') {
relayhost[i] = 0;
relayhost[i + j + 1] = 0;
- if (!stralloc_copys(&user,"")) temp_nomem();
- if (!stralloc_copys(&user,relayhost + i + 1)) temp_nomem();
- if (!stralloc_copys(&pass,"")) temp_nomem();
- k = str_chr(relayhost + i + j + 2,'|'); // local ip
+ if (!stralloc_copys(&user, "")) temp_nomem();
+ if (!stralloc_copys(&user, relayhost + i + 1)) temp_nomem();
+ if (!stralloc_copys(&pass, "")) temp_nomem();
+ k = str_chr(relayhost + i + j + 2, '|'); // local ip
if (relayhost[i + j + k + 2] == '|') {
relayhost[i + j + k + 2] = 0;
localip = relayhost + i + j + k + 3;
}
- if (!stralloc_copys(&pass,relayhost + i + j + 2)) temp_nomem();
+ if (!stralloc_copys(&pass, relayhost + i + j + 2)) temp_nomem();
}
}
- p = str_chr(relayhost,';');
+ p = str_chr(relayhost, ';');
if (relayhost[p] == ';') {
- if (relayhost[p + 1] == 's') { flagsmtps = 1; p++; } // RFC 8314
- scan_ulong(relayhost + p + 1,&port);
+ if (relayhost[p + 1] == 's') {
+ flagsmtps = 1;
+ p++;
+ } // RFC 8314
+ scan_ulong(relayhost + p + 1, &port);
if (qmtpsend && port == PORT_QMTPS) qmtpsend = 2;
relayhost[p] = 0;
}
- if (!stralloc_copys(&host,relayhost)) temp_nomem();
+ if (!stralloc_copys(&host, relayhost)) temp_nomem();
#ifdef IDN2
} else {
char *asciihost = 0;
if (!stralloc_0(&host)) temp_nomem();
- switch (idn2_lookup_u8(host.s,(uint8_t**)&asciihost,IDN2_NFC_INPUT)) {
+ switch (idn2_lookup_u8(host.s, (uint8_t **)&asciihost, IDN2_NFC_INPUT)) {
case IDN2_OK: break;
case IDN2_MALLOC: temp_nomem();
default: perm_dns();
}
- if (!stralloc_copys(&idnhost,asciihost)) temp_nomem();
+ if (!stralloc_copys(&idnhost, asciihost)) temp_nomem();
#endif
}
}
-/* this file is too long -------------------------------------- TLS destinations */
+ /* this file is too long -------------------------------------- TLS destinations */
- flagtls = tls_destination((const stralloc) host); // host may not be 0-terminated
+ flagtls = tls_destination((const stralloc)host); // host may not be 0-terminated
if (flagtls > 0) {
- if (tlsdestinfo) {
- i = str_chr(tlsdestinfo,'|'); /* ca file/dir or cert fingerprint */
+ if (tlsdestinfo) {
+ i = str_chr(tlsdestinfo, '|'); /* ca file/dir or cert fingerprint */
if (tlsdestinfo[i] == '|') {
tlsdestinfo[i] = 0;
- j = str_chr(tlsdestinfo + i + 1,'|'); /* cipher */
+ j = str_chr(tlsdestinfo + i + 1, '|'); /* cipher */
if (tlsdestinfo[i + j + 1] == '|') {
- tlsdestinfo[i + j + 1] = 0;
- k = str_chr(tlsdestinfo + i + j + 2,'|'); /* cone domain */
+ tlsdestinfo[i + j + 1] = 0;
+ k = str_chr(tlsdestinfo + i + j + 2, '|'); /* cone domain */
if (tlsdestinfo[i + j + k + 2] == '|') {
- tlsdestinfo[i + j + k + 2] = 0;
- if (str_diffn(tlsdestinfo + j + k + 3,canonhost.s,canonhost.len)) flagtls = 0;
+ tlsdestinfo[i + j + k + 2] = 0;
+ if (str_diffn(tlsdestinfo + j + k + 3, canonhost.s, canonhost.len)) flagtls = 0;
}
- p = str_chr(tlsdestinfo + i + j + 2,';'); /* verifydepth;port */
+ p = str_chr(tlsdestinfo + i + j + 2, ';'); /* verifydepth;port */
if (tlsdestinfo[i + j + p + 2] == ';') {
tlsdestinfo[i + j + p + 2] = 0;
- if (p > 0) scan_ulong(tlsdestinfo + i + j + 2,&verifydepth);
- if (tlsdestinfo[i + j + p + 3] == 's') { flagsmtps = 1; p++; } /* RFC 8314 */
- scan_ulong(tlsdestinfo + i + j + p + 3,&port);
+ if (p > 0) scan_ulong(tlsdestinfo + i + j + 2, &verifydepth);
+ if (tlsdestinfo[i + j + p + 3] == 's') {
+ flagsmtps = 1;
+ p++;
+ } /* RFC 8314 */
+ scan_ulong(tlsdestinfo + i + j + p + 3, &port);
}
}
if (j)
- if (!stralloc_copys(&ciphers,tlsdestinfo + i + 1)) temp_nomem();
- }
+ if (!stralloc_copys(&ciphers, tlsdestinfo + i + 1)) temp_nomem();
+ }
/* either ':[=]cafile/cadir' -or- ':;port' */
- if (tlsdestinfo[0] == ';')
- scan_ulong(tlsdestinfo + 1,&port);
- else
- if (!stralloc_copys(&cafile,tlsdestinfo)) temp_nomem();
+ if (tlsdestinfo[0] == ';')
+ scan_ulong(tlsdestinfo + 1, &port);
+ else if (!stralloc_copys(&cafile, tlsdestinfo))
+ temp_nomem();
}
-/* cafile starts with '=' => it is a fingerprint
+ /* cafile starts with '=' => it is a fingerprint
cafile ends with '/' => consider it as cadir
cafile and cadir are now 0-terminated
ciphers are alway 0-terminated if given */
@@ -1296,7 +1359,7 @@ int main(int argc,char **argv)
if (cafile.s[cafile.len] == '/') {
cafile.len = 0;
flagverify = 2;
- if (!stralloc_copys(&cadir,tlsdestinfo)) temp_nomem();
+ if (!stralloc_copys(&cadir, tlsdestinfo)) temp_nomem();
if (!stralloc_0(&cadir)) temp_nomem();
} else {
if (cafile.s[0] == '=') flagverify = -2;
@@ -1305,60 +1368,61 @@ int main(int argc,char **argv)
} else
cafile.len = cadir.len = 0;
- if (ciphers.len > 4) /* otherwise garbage */
- if (!stralloc_0(&ciphers)) temp_nomem();
- else
- ciphers.len = 0;
+ if (ciphers.len > 4) /* otherwise garbage */
+ if (!stralloc_0(&ciphers))
+ temp_nomem();
+ else
+ ciphers.len = 0;
if (port == PORT_SMTPS || flagsmtps) flagtls += 10;
if (port == PORT_QMTPS) flagtls += 20;
}
- if (flagtls == 8) flagverify = -1;
- if (!flagtls && qmtpsend == 2) flagtls = 20; /* QMTPS */
+ if (flagtls == 8) flagverify = -1;
+ if (!flagtls && qmtpsend == 2) flagtls = 20; /* QMTPS */
-/* this file is too long -------------------------------------- Our Certs - per senddomain */
+ /* this file is too long -------------------------------------- Our Certs - per senddomain */
if (flagtls > 0) {
- flagtlsdomain = tls_domaincerts((const stralloc) senddomain); // senddomain un-terminated
+ flagtlsdomain = tls_domaincerts((const stralloc)senddomain); // senddomain un-terminated
if (flagtlsdomain && tlsdomaininfo) {
- i = str_chr(tlsdomaininfo,'|');
+ i = str_chr(tlsdomaininfo, '|');
if (tlsdomaininfo[i] == '|') {
tlsdomaininfo[i] = 0;
- j = str_chr(tlsdomaininfo + i + 1,'|');
+ j = str_chr(tlsdomaininfo + i + 1, '|');
if (tlsdomaininfo[i + j + 1] == '|') {
tlsdomaininfo[i + j + 1] = 0;
- if (!stralloc_copys(&keypwd,"")) temp_nomem();
- if (!stralloc_copys(&keypwd,tlsdomaininfo + i + j + 2)) temp_nomem();
+ if (!stralloc_copys(&keypwd, "")) temp_nomem();
+ if (!stralloc_copys(&keypwd, tlsdomaininfo + i + j + 2)) temp_nomem();
if (!stralloc_0(&keypwd)) temp_nomem();
}
- if (!stralloc_copys(&keyfile,tlsdomaininfo + i + 1)) temp_nomem();
+ if (!stralloc_copys(&keyfile, tlsdomaininfo + i + 1)) temp_nomem();
if (!stralloc_0(&keyfile)) temp_nomem();
}
- if (!stralloc_copys(&certfile,tlsdomaininfo)) temp_nomem();
+ if (!stralloc_copys(&certfile, tlsdomaininfo)) temp_nomem();
if (!stralloc_0(&certfile)) temp_nomem();
flagtlsdomain = 2;
}
}
-/* this file is too long -------------------------------------- work thru reciplist */
+ /* this file is too long -------------------------------------- work thru reciplist */
- if (!saa_readyplus(&reciplist,0)) temp_nomem();
+ if (!saa_readyplus(&reciplist, 0)) temp_nomem();
if (ipme_init() != 1) temp_oserr();
-
+
flagallaliases = 1;
recips = argv + 3;
- if (fstat(0,&st) == -1) quit("Z", " unable to fstat stdin");
+ if (fstat(0, &st) == -1) quit("Z", " unable to fstat stdin");
msize = st.st_size;
- fmt_ulong(msgsize,msize);
+ fmt_ulong(msgsize, msize);
while (*recips) {
- if (!saa_readyplus(&reciplist,1)) temp_nomem();
+ if (!saa_readyplus(&reciplist, 1)) temp_nomem();
reciplist.sa[reciplist.len] = sauninit;
- addrmangle(reciplist.sa + reciplist.len,*recips,&flagalias,!relayhost);
+ addrmangle(reciplist.sa + reciplist.len, *recips, &flagalias, !relayhost);
if (!flagalias) flagallaliases = 0;
++reciplist.len;
++recips;
@@ -1366,91 +1430,94 @@ int main(int argc,char **argv)
random = now() + (getpid() << 16);
#ifdef IDN2
- switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip,&idnhost,random)) {
+ switch (relayhost ? dns_ip(&ip, &host) : dns_mxip(&ip, &idnhost, random)) {
#else
- switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip,&host,random)) {
+ switch (relayhost ? dns_ip(&ip, &host) : dns_mxip(&ip, &host, random)) {
#endif
- case DNS_MEM: temp_nomem();
- case DNS_ERR: temp_dns();
- case DNS_COM: temp_dns();
+ case DNS_MEM: temp_nomem();
+ case DNS_ERR: temp_dns();
+ case DNS_COM: temp_dns();
case DNS_SOFT: temp_dns();
#ifdef DEFERREDBOUNCES
- default: if (!ip.len) temp_nomx();
+ default:
+ if (!ip.len) temp_nomx();
#else
- default: if (!ip.len) perm_nomx();
+ default:
+ if (!ip.len) perm_nomx();
#endif
}
prefme = 100000;
for (i = 0; i < ip.len; ++i)
if (ipme_is(&ip.ix[i]))
- if (ip.ix[i].pref < prefme)
- prefme = ip.ix[i].pref;
-
+ if (ip.ix[i].pref < prefme) prefme = ip.ix[i].pref;
+
if (relayhost) prefme = 300000;
if (flagallaliases) prefme = 500000;
-
+
if (localip) {
- i = str_chr(localip,':');
- if (localip[i] == ':') ip6flag = 1;
- else ip6flag = -1;
+ i = str_chr(localip, ':');
+ if (localip[i] == ':')
+ ip6flag = 1;
+ else
+ ip6flag = -1;
}
- for (i = 0; i < ip.len; ++i) { /* MX with smallest distance */
- if (ip6flag == -1 && ip.ix[i].af == AF_INET6) continue;
- if (ip6flag == 1 && ip.ix[i].af == AF_INET) continue;
+ for (i = 0; i < ip.len; ++i) { /* MX with smallest distance */
+ if (ip6flag == -1 && ip.ix[i].af == AF_INET6) continue;
+ if (ip6flag == 1 && ip.ix[i].af == AF_INET) continue;
if (ip.ix[i].pref < prefme) break;
}
- if (i >= ip.len)
- perm_ambigmx();
+ if (i >= ip.len) perm_ambigmx();
- if (!stralloc_copys(&remotehost,ip.ix[i].mxh)) temp_nomem(); /* take MX hostname for TLSA */
+ if (!stralloc_copys(&remotehost, ip.ix[i].mxh)) temp_nomem(); /* take MX hostname for TLSA */
if (!stralloc_0(&remotehost)) temp_nomem();
for (i = 0; i < ip.len; ++i) {
if (ip.ix[i].pref < prefme) {
- if (ip6flag == -1 && ip.ix[i].af == AF_INET6) continue; /* explicit binding */
- if (ip6flag == 1 && ip.ix[i].af == AF_INET) continue;
+ if (ip6flag == -1 && ip.ix[i].af == AF_INET6) continue; /* explicit binding */
+ if (ip6flag == 1 && ip.ix[i].af == AF_INET) continue;
if (tcpto(&ip.ix[i])) continue;
-
- smtpfd = socket(ip.ix[i].af,SOCK_STREAM,0);
+
+ smtpfd = socket(ip.ix[i].af, SOCK_STREAM, 0);
if (smtpfd == -1) continue;
- if (localip) { /* set domain ip */
- if (!stralloc_copyb(&sendip,localip,str_len(localip))) temp_nomem();
- j = str_chr(localip,':');
- if (localip[j] == ':') {
- if (!ip6_scan(localip,ip6)) temp_noip(); /* IPv6 */
- if (byte_equal(ip.ix[i].addr.ip6.d,16,ip6)) continue;
- ifidx = socket_getifidx(netif.s);
- if (socket_bind6(smtpfd,ip6,0,ifidx) < 0) temp_osip();
- } else {
- if (!ip4_scan(localip,ip4)) temp_noip(); /* IPv4 */
- if (byte_equal(ip.ix[i].addr.ip4.d,4,ip4)) continue;
- if (socket_bind4(smtpfd,ip4,0) < 0) temp_osip();
- }
- }
-
-
- AGAIN:
+ if (localip) { /* set domain ip */
+ if (!stralloc_copyb(&sendip, localip, str_len(localip))) temp_nomem();
+ j = str_chr(localip, ':');
+ if (localip[j] == ':') {
+ if (!ip6_scan(localip, ip6)) temp_noip(); /* IPv6 */
+ if (byte_equal(ip.ix[i].addr.ip6.d, 16, ip6)) continue;
+ ifidx = socket_getifidx(netif.s);
+ if (socket_bind6(smtpfd, ip6, 0, ifidx) < 0) temp_osip();
+ } else {
+ if (!ip4_scan(localip, ip4)) temp_noip(); /* IPv4 */
+ if (byte_equal(ip.ix[i].addr.ip4.d, 4, ip4)) continue;
+ if (socket_bind4(smtpfd, ip4, 0) < 0) temp_osip();
+ }
+ }
+
+
+ AGAIN:
if (ip.ix[i].af == AF_INET6)
- r = timeoutconn6(smtpfd,(char *)&ip.ix[i].addr.ip6.d,(unsigned int) port,timeoutconnect,ifidx);
+ r = timeoutconn6(
+ smtpfd, (char *)&ip.ix[i].addr.ip6.d, (unsigned int)port, timeoutconnect, ifidx);
else
- r = timeoutconn4(smtpfd,(char *)&ip.ix[i].addr.ip4.d,(unsigned int) port,timeoutconnect);
+ r = timeoutconn4(smtpfd, (char *)&ip.ix[i].addr.ip4.d, (unsigned int)port, timeoutconnect);
if (r == 0) {
- tcpto_err(&ip.ix[i],0);
+ tcpto_err(&ip.ix[i], 0);
partner = ip.ix[i];
- if (qmtpsend)
- qmtp();
- else
- smtp(); /* read qmail/THOUGHTS; section 6 */
+ if (qmtpsend)
+ qmtp();
+ else
+ smtp(); /* read qmail/THOUGHTS; section 6 */
}
if (flagtls == 9 && errno == EPROTO) {
- flagtls = 0; goto AGAIN;
+ flagtls = 0;
+ goto AGAIN;
}
- if (errno == ETIMEDOUT || errno == ECONNREFUSED || errno == EPROTO)
- tcpto_err(&ip.ix[i],1);
+ if (errno == ETIMEDOUT || errno == ECONNREFUSED || errno == EPROTO) tcpto_err(&ip.ix[i], 1);
close(smtpfd);
}
}