diff options
Diffstat (limited to 'src/qmail-smtpam.c')
-rw-r--r-- | src/qmail-smtpam.c | 438 |
1 files changed, 232 insertions, 206 deletions
diff --git a/src/qmail-smtpam.c b/src/qmail-smtpam.c index c0c6550..89105c3 100644 --- a/src/qmail-smtpam.c +++ b/src/qmail-smtpam.c @@ -1,65 +1,67 @@ -#include <sys/types.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <sys/socket.h> #include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/inet.h> +#include <sys/types.h> #include <unistd.h> -#include "sig.h" -#include "genalloc.h" -#include "stralloc.h" + +#include "alloc.h" #include "buffer.h" -#include "scan.h" -#include "case.h" #include "byte.h" +#include "case.h" +#include "constmap.h" #include "error.h" +#include "exit.h" +#include "genalloc.h" +#include "ip.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 "quote.h" -#include "ip.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 "socket_if.h" -#include "ucspissl.h" -#include "timeout.h" -#include "timeoutconn.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 MAX_SIZE 200000000 +#define MAX_SIZE 200000000 #define HUGESMTPTEXT 5000 -#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */ -#define PORT_SMTPS 465 -#define VERIFYDEPTH 1 -#define FDPAM 3 +#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */ +#define PORT_SMTPS 465 +#define VERIFYDEPTH 1 +#define FDPAM 3 #define WHO "qmail-smtpam" /** @file qmail-smtpam.c -- TLS enabled SMTP PAM to check mailbox at remote MX */ -int flagauth = 0; /* 1 = login; 2 = plain; 3 =crammd5 */ -int flagsmtps = 0; /* RFC 8314 - 'implicit TLS' */ -int flagtls = 0; /* -2 = rejected; -1 = not; 0 = no, default; +int flagauth = 0; /* 1 = login; 2 = plain; 3 =crammd5 */ +int flagsmtps = 0; /* RFC 8314 - 'implicit TLS' */ +int flagtls = 0; /* -2 = rejected; -1 = not; 0 = no, default; > 0 see tls_remote.c +10 = SMTPS; +20 = QMTPS; 100 = active TLS connection */ -int flagverify = 0; /* 1 = verify Cert against CA ; -1 = Cert pinning */ +int flagverify = 0; /* 1 = verify Cert against CA ; -1 = Cert pinning */ int flagutf8mail = 0; unsigned long port = PORT_SMTP; -GEN_ALLOC_typedef(saa,stralloc,sa,len,a) -GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus) +GEN_ALLOC_typedef(saa, stralloc, sa, len, a) + GEN_ALLOC_readyplus(saa, stralloc, sa, len, a, i, n, x, 10, saa_readyplus) -stralloc helohost = {0}; + stralloc helohost = {0}; stralloc host = {0}; stralloc ports = {0}; stralloc remotehost = {0}; @@ -83,44 +85,55 @@ struct ip_mx partner; SSL *ssl; SSL_CTX *ctx; -void out(char *s) { if (buffer_puts(buffer_1small,s) == -1) _exit(111); } -void zero() { if (buffer_put(buffer_1small,"\0",1) == -1) _exit(111); } -void zerodie() { zero(); buffer_flush(buffer_1small); _exit(111); } -void outsafe(stralloc *sa) -{ - int i; +void out(char *s) +{ + if (buffer_puts(buffer_1small, s) == -1) _exit(111); +} +void zero() +{ + if (buffer_put(buffer_1small, "\0", 1) == -1) _exit(111); +} +void zerodie() +{ + zero(); + buffer_flush(buffer_1small); + _exit(111); +} +void outsafe(stralloc *sa) +{ + int i; char ch; for (i = 0; i < sa->len; ++i) { - ch = sa->s[i]; - if (ch < 33) ch = '?'; + ch = sa->s[i]; + if (ch < 33) ch = '?'; if (ch > 126) ch = '?'; - if (buffer_put(buffer_1small,&ch,1) == -1) _exit(111); - } + if (buffer_put(buffer_1small, &ch, 1) == -1) _exit(111); + } } -void temp_noip() +void temp_noip() { out("Zinvalid ipaddr in control/domainips (#4.3.0)\n"); zerodie(); } -void temp_nomem() +void temp_nomem() { out("ZOut of memory. (#4.3.0)\n"); zerodie(); } -void temp_oserr() +void temp_oserr() { out("ZSystem resources temporarily unavailable. (#4.3.0)\n"); zerodie(); } -void temp_osip() +void temp_osip() { out("ZCan't bind to local ip address: "); outsafe(&sendip); out(". (#4.3.0)\n"); zerodie(); } -void temp_noconn() +void temp_noconn() { out("ZSorry, I wasn't able to establish an SMTP connection. (#4.4.1)\n"); zerodie(); @@ -132,29 +145,29 @@ void temp_dnscanon() out(". (#4.4.3)\n"); zerodie(); } -void temp_dns() +void temp_dns() { out("ZSorry, I couldn't find any host named: "); outsafe(&host); out(". (#4.1.2)\n"); zerodie(); } -void temp_chdir() +void temp_chdir() { out("ZUnable to switch to home directory. (#4.3.0)\n"); zerodie(); } -void temp_control() +void temp_control() { out("ZUnable to read control files. (#4.3.0)\n"); zerodie(); } -void perm_usage() +void perm_usage() { out("Dqmail-smtpam was invoked improperly. (#5.3.5)\n"); zerodie(); } -void perm_dns() +void perm_dns() { out("DSorry, I couldn't find any host named: "); outsafe(&host); @@ -167,17 +180,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; + 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(buffer_1small,ipaddr,len) == -1) _exit(0); + if (buffer_put(buffer_1small, ipaddr, len) == -1) _exit(0); } int flagcritical = 0; -void dropped() +void dropped() { out("ZConnected to "); outhost(); @@ -191,35 +202,35 @@ 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; - 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; - r = timeoutwrite(timeout,smtpfd,buf,len); + r = timeoutwrite(timeout, smtpfd, buf, len); if (r <= 0) dropped(); return r; } char outbuf[1450]; -buffer bo = BUFFER_INIT(safewrite,-1,outbuf,sizeof(outbuf)); +buffer bo = BUFFER_INIT(safewrite, -1, outbuf, sizeof(outbuf)); char frombuf[128]; -buffer bi = BUFFER_INIT(saferead,-1,frombuf,sizeof(frombuf)); +buffer bi = BUFFER_INIT(saferead, -1, frombuf, sizeof(frombuf)); stralloc smtptext = {0}; void get(char *ch) { - buffer_get(&bi,ch,1); + buffer_get(&bi, 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() @@ -227,11 +238,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; @@ -247,19 +261,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(buffer_1small,smtptext.s,smtptext.len) == -1) _exit(111); - 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(buffer_1small, smtptext.s, smtptext.len) == -1) _exit(111); + 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(); @@ -292,43 +307,42 @@ unsigned long verifydepth = VERIFYDEPTH; void tls_init() { -/* Client CTX */ + /* Client CTX */ ctx = ssl_client(); 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 (!ssl_ca(ctx, cafile.s, cadir.s, (int)verifydepth)) temp_tlsca(); if (ciphers.len) - if (!ssl_ciphers(ctx,ciphers.s)) temp_tlscipher(); + if (!ssl_ciphers(ctx, ciphers.s)) temp_tlscipher(); -/* Set SSL Context */ + /* Set SSL Context */ - ssl = ssl_new(ctx,smtpfd); + ssl = ssl_new(ctx, smtpfd); if (!ssl) temp_tlsctx(); -/* Setup SSL FDs */ + /* Setup SSL FDs */ - if (!tls_conn(ssl,smtpfd)) temp_tlscon(); + 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 < smtptext.len - 8) ) { - if (!str_diffn(smtptext.s + i + 4,"STARTTLS",8)) return 1; } + while ((i += str_chr(smtptext.s + i, '\n') + 1) && (i < smtptext.len - 8)) { + if (!str_diffn(smtptext.s + i + 4, "STARTTLS", 8)) return 1; + } return 0; } @@ -336,37 +350,40 @@ int starttls_peer() void tls_peercheck() { X509 *cert; - + cert = SSL_get_peer_certificate(ssl); - if (!cert) { flagtls = 100; return; } + if (!cert) { + flagtls = 100; + return; + } if (flagverify < 0) { - if (cafile.len) case_lowerb(cafile.s,cafile.len); - switch (tls_fingerprint(cert,cafile.s + 1,cafile.len - 1)) { + if (cafile.len) case_lowerb(cafile.s, cafile.len); + switch (tls_fingerprint(cert, cafile.s + 1, cafile.len - 1)) { case -1: temp_tlspeercert(); case -2: temp_tlsdigest(); case -3: temp_invaliddigest(); - case 1: temp_tlscertfp(); + case 1: temp_tlscertfp(); } } else { - 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 1: flagtls = 101; break; + case 2: flagtls = 102; break; + case 3: flagtls = 103; break; } } if (flagtls < 100) flagtls = 100; - + X509_free(cert); return; } -int utf8flag(unsigned char *ch,int len) +int utf8flag(unsigned char *ch, int len) { int i = 0; while (i < len) @@ -380,25 +397,25 @@ unsigned long code; 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(); - 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"); } } void smtp_starttls() { - buffer_puts(&bo,"STARTTLS\r\n"); + buffer_puts(&bo, "STARTTLS\r\n"); buffer_flush(&bo); if (smtpcode() == 220) { tls_init(); @@ -406,45 +423,44 @@ void smtp_starttls() smtp_greeting(); } else { flagtls = -2; - quit("ZConnected to"," but STARTTLS was rejected"); + quit("ZConnected to", " but STARTTLS was rejected"); } } void smtp() { - if (flagtls > 10 && flagtls < 20) { /* SMTPS */ + if (flagtls > 10 && flagtls < 20) { /* SMTPS */ tls_init(); tls_peercheck(); } 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"); smtp_greeting(); - if (flagutf8mail) buffer_puts(&bo," SMTPUTF8"); + if (flagutf8mail) buffer_puts(&bo, " SMTPUTF8"); - if (flagtls > 0 && flagtls < 10) /* STARTTLS */ + if (flagtls > 0 && flagtls < 10) /* STARTTLS */ if (starttls_peer()) { - smtp_starttls(); + smtp_starttls(); } else if (flagtls > 2) { - temp_tlshost(); + temp_tlshost(); } - buffer_puts(&bo,"MAIL FROM:<>"); - if (flagutf8mail) - buffer_puts(&bo," SMTPUTF8"); - buffer_puts(&bo,"\r\n"); + buffer_puts(&bo, "MAIL FROM:<>"); + if (flagutf8mail) buffer_puts(&bo, " SMTPUTF8"); + buffer_puts(&bo, "\r\n"); buffer_flush(&bo); code = smtpcode(); - if (code >= 500) quit("DConnected to "," but sender was rejected"); - if (code >= 400) quit("ZConnected to "," but sender was rejected"); - - buffer_puts(&bo,"RCPT TO:<"); - buffer_put(&bo,recipient.s,recipient.len); - buffer_puts(&bo,">\r\n"); + if (code >= 500) quit("DConnected to ", " but sender was rejected"); + if (code >= 400) quit("ZConnected to ", " but sender was rejected"); + + buffer_puts(&bo, "RCPT TO:<"); + buffer_put(&bo, recipient.s, recipient.len); + buffer_puts(&bo, ">\r\n"); buffer_flush(&bo); code = smtpcode(); close(smtpfd); @@ -455,28 +471,33 @@ void smtp() 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(&domainips,"control/domainips",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(&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(&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; } - } char up[513]; int uplen; -int main(int argc,char **argv) +int main(int argc, char **argv) { static ipalloc ip = {0}; stralloc netif = {0}; @@ -485,83 +506,88 @@ int main(int argc,char **argv) int p; /* reserved for port */ char *localip = 0; char *tlsdestinfo = 0; - + sig_pipeignore(); if (argc < 2) perm_usage(); if (chdir(auto_qmail) == -1) temp_chdir(); getcontrols(); - - if (!stralloc_copys(&host,argv[1])) temp_nomem(); + + if (!stralloc_copys(&host, argv[1])) temp_nomem(); if (argv[2]) { - if (!stralloc_copys(&ports,argv[2])) temp_nomem(); - if (*ports.s == 's') { ports.s++; flagsmtps = 1; } - scan_ulong(ports.s,&port); + if (!stralloc_copys(&ports, argv[2])) temp_nomem(); + if (*ports.s == 's') { + ports.s++; + flagsmtps = 1; + } + scan_ulong(ports.s, &port); } if (ipme_init() != 1) temp_oserr(); -/* this file is too long -------------------------------------- set domain ip + helohost */ + /* this file is too long -------------------------------------- set domain ip + helohost */ - 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(); 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 -------------------------------------- TLS destinations */ + /* this file is too long -------------------------------------- TLS destinations */ - flagtls = tls_destination((const stralloc) host); // un-terminated + flagtls = tls_destination((const stralloc)host); // un-terminated if (flagtls > 0) { if (tlsdestinfo) { - i = str_chr(tlsdestinfo,'|'); /* ca file or cert fingerprint */ + i = str_chr(tlsdestinfo, '|'); /* ca file 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 */ + 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; + 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] == ';') { - if (tlsdestinfo[i + j + p + 3] == 's') { flagsmtps = 1; p++; } + if (tlsdestinfo[i + j + p + 3] == 's') { + flagsmtps = 1; + p++; + } tlsdestinfo[i + j + p + 2] = 0; - if (p > 0) scan_ulong(tlsdestinfo+i+j + 2,&verifydepth); - scan_ulong(tlsdestinfo+i+j + p + 3,&port); + if (p > 0) scan_ulong(tlsdestinfo + i + j + 2, &verifydepth); + scan_ulong(tlsdestinfo + i + j + p + 3, &port); } } - if (!stralloc_copys(&ciphers,tlsdestinfo + i + 1)) temp_nomem(); + if (!stralloc_copys(&ciphers, tlsdestinfo + i + 1)) temp_nomem(); } - if (!stralloc_copys(&cafile,tlsdestinfo)) temp_nomem(); + 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 */ - if (cafile.len) { + if (cafile.len) { flagverify = 1; 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 = -1; @@ -574,12 +600,11 @@ int main(int argc,char **argv) if (port == PORT_SMTPS || flagsmtps) flagtls = flagtls + 10; } -/* this file is too long -------------------------------------- Setup connection */ + /* this file is too long -------------------------------------- Setup connection */ uplen = 0; for (;;) { - do - r = read(FDPAM,up + uplen,sizeof(up) - uplen); + do r = read(FDPAM, up + uplen, sizeof(up) - uplen); while ((r == -1) && (errno == EINTR)); if (r == -1) _exit(111); if (r == 0) break; @@ -588,44 +613,45 @@ int main(int argc,char **argv) } close(FDPAM); - if (!stralloc_copyb(&recipient,up,uplen)) temp_nomem(); - if (!stralloc_0(&recipient)) temp_nomem(); - if (!stralloc_0(&host)) temp_nomem(); - if (!stralloc_copys(&remotehost,host.s)) temp_nomem(); + if (!stralloc_copyb(&recipient, up, uplen)) temp_nomem(); + if (!stralloc_0(&recipient)) temp_nomem(); + if (!stralloc_0(&host)) temp_nomem(); + if (!stralloc_copys(&remotehost, host.s)) temp_nomem(); - flagutf8mail = utf8flag(recipient.s,recipient.len); + flagutf8mail = utf8flag(recipient.s, recipient.len); - switch (dns_ip(&ip,&remotehost)) { - case DNS_MEM: temp_nomem(); + switch (dns_ip(&ip, &remotehost)) { + case DNS_MEM: temp_nomem(); case DNS_ERR: temp_dns(); case DNS_COM: temp_dnscanon(); - default: if (ip.len <= 0) perm_dns(); + default: + if (ip.len <= 0) perm_dns(); } - smtpfd = socket(ip.ix[i].af,SOCK_STREAM,0); + smtpfd = socket(ip.ix[i].af, SOCK_STREAM, 0); if (smtpfd == -1) temp_oserr(); - - if (localip) { /* set domain ip */ - if (!stralloc_copyb(&sendip,localip,str_len(localip))) temp_nomem(); - j = str_chr(localip,':'); - if (j && localip[j] == ':') { /* IPv6 */ - if (!ip6_scan(localip,ip6)) temp_noip(); - ifidx = socket_getifidx(netif.s); - if (socket_bind6(smtpfd,ip6,0,ifidx) < 0) temp_osip(); - } else { /* IPv4 */ - if (!ip4_scan(localip,ip4)) temp_noip(); - if (socket_bind4(smtpfd,ip4,0) < 0) temp_osip(); - } - } - - r = timeoutconn(smtpfd,&ip.ix[i].addr,(unsigned int) port,timeoutconnect,ifidx); - if (r == 0) { - tcpto_err(&ip.ix[i],0); + + if (localip) { /* set domain ip */ + if (!stralloc_copyb(&sendip, localip, str_len(localip))) temp_nomem(); + j = str_chr(localip, ':'); + if (j && localip[j] == ':') { /* IPv6 */ + if (!ip6_scan(localip, ip6)) temp_noip(); + ifidx = socket_getifidx(netif.s); + if (socket_bind6(smtpfd, ip6, 0, ifidx) < 0) temp_osip(); + } else { /* IPv4 */ + if (!ip4_scan(localip, ip4)) temp_noip(); + if (socket_bind4(smtpfd, ip4, 0) < 0) temp_osip(); + } + } + + r = timeoutconn(smtpfd, &ip.ix[i].addr, (unsigned int)port, timeoutconnect, ifidx); + if (r == 0) { + tcpto_err(&ip.ix[i], 0); partner = ip.ix[i]; smtp(); /* does not return */ } - tcpto_err(&ip.ix[i],errno == ETIMEDOUT); + tcpto_err(&ip.ix[i], errno == ETIMEDOUT); close(smtpfd); - + temp_noconn(); } |