31#include "timeoutconn.h"
38#define MAX_SIZE 200000000
39#define HUGESMTPTEXT 5000
45#define SMTP_TIMEOUT 1200
47#define WHO "qmail-smtpam"
89void out(
char *s) {
if (buffer_puts(buffer_1small,s) == -1)
_exit(111); }
90void zero() {
if (buffer_put(buffer_1small,
"\0",1) == -1)
_exit(111); }
96 for (i = 0; i <
sa->len; ++i) {
98 if (ch < 33) ch =
'?';
99 if (ch > 126) ch =
'?';
100 if (buffer_put(buffer_1small,&ch,1) == -1)
_exit(111);
106 out(
"Zinvalid ipaddr in control/domainips (#4.3.0)\n");
111 out(
"ZOut of memory. (#4.3.0)\n");
116 out(
"ZSystem resources temporarily unavailable. (#4.3.0)\n");
121 out(
"ZCan't bind to local ip address: ");
128 out(
"ZSorry, I wasn't able to establish an SMTP connection. (#4.4.1)\n");
133 out(
"ZCNAME lookup failed temporarily for: ");
140 out(
"ZSorry, I couldn't find any host named: ");
147 out(
"ZUnable to switch to home directory. (#4.3.0)\n");
152 out(
"ZUnable to read control files. (#4.3.0)\n");
157 out(
"Dqmail-smtpam was invoked improperly. (#5.3.5)\n");
162 out(
"DSorry, I couldn't find any host named: ");
178 if (buffer_put(buffer_1small,
ipaddr,len) == -1)
_exit(0);
185 out(
"ZConnected to ");
187 out(
" but connection died. ");
222 buffer_get(&
bi,ch,1);
240 if (ch !=
'-')
break;
241 while (ch !=
'\n')
get(&ch);
246 while (ch !=
'\n')
get(&ch);
255 out(
"Remote host said: ");
263void quit(
char *prepend,
char *append)
265 buffer_putsflush(&
bo,
"QUIT\r\n");
333 if (case_startb(
smtptext.s + i + 4,8,
"STARTTLS"))
return 1;
334 }
while ((i += str_chr(
smtptext.s + i,
'\n') + 1) &&
343 STACK_OF(X509) *certs;
346 cert = SSL_get_peer_certificate(
ssl);
347 if (!cert) {
flagtls = 100;
return; }
349 if ((certs = SSL_get_peer_cert_chain(
ssl)) == NULL) {
350 certs = sk_X509_new_null();
351 sk_X509_push(certs,cert);
393 if (ncerts) sk_X509_free(certs);
402 if (ch[i++] > 127)
return 1;
412 buffer_puts(&
bo,
"EHLO ");
414 buffer_puts(&
bo,
"\r\n");
418 buffer_puts(&
bo,
"HELO ");
420 buffer_puts(&
bo,
"\r\n");
423 if (
code >= 500)
quit(
"DConnected to",
" but my name was rejected");
424 if (
code != 250)
quit(
"ZConnected to",
" but my name was rejected");
430 buffer_puts(&
bo,
"STARTTLS\r\n");
438 quit(
"ZConnected to",
" but STARTTLS was rejected");
451 if (
code >= 500)
quit(
"DConnected to ",
" but sender was rejected");
452 if (
code >= 400)
quit(
"ZConnected to ",
" but sender was probably greylisted");
465 buffer_puts(&
bo,
"MAIL FROM:<>");
467 buffer_puts(&
bo,
" SMTPUTF8");
468 buffer_puts(&
bo,
"\r\n");
471 if (
code >= 500)
quit(
"DConnected to ",
" but sender was rejected");
472 if (
code >= 400)
quit(
"ZConnected to ",
" but sender was rejected");
474 buffer_puts(&
bo,
"RCPT TO:<");
476 buffer_puts(&
bo,
">\r\n");
508int main(
int argc,
char *
const *argv)
510 static ipalloc ip = {0};
511 stralloc netif = {0};
540 j = str_chr(localip,
'%');
541 if (localip[
j] !=
'%')
j = 0;
542 k = str_chr(localip,
'|');
543 if (localip[
k] !=
'|')
k = 0;
613 while ((r == -1) && (errno == EINTR));
614 if (r == -1)
_exit(111);
632 default:
if (ip.len <= 0)
perm_dns();
636 i = str_chr(localip,
':');
637 if (localip[i] ==
':') ip6flag = 1;
641 for (i = 0; i < ip.len; ++i) {
642 if (ip6flag == -1 && ip.ix[i].af == AF_INET6)
continue;
643 if (ip6flag == 1 && ip.ix[i].af == AF_INET)
continue;
644 if (
tcpto(&ip.ix[i]))
continue;
646 smtpfd = socket(ip.ix[i].af,SOCK_STREAM,0);
651 j = str_chr(localip,
':');
652 if (
j && localip[
j] ==
':') {
654 ifidx = socket_getifidx(netif.s);
662 if (ip.ix[i].af == AF_INET6)
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
int control_readint(unsigned long *i, char *fn)
int control_rldef(stralloc *sa, char *fn, int flagme, char *def)
int control_readfile(stralloc *sa, char *fn, int flagme)
int stralloc_copys(stralloc *, char const *)
int dns_ip(ipalloc *ia, stralloc *sa)
void p(char *, char *, int, int, int)
GEN_ALLOC_readyplus(prioq, struct prioq_elt, p, len, a, i, n, x, 100, prioq_readyplus)
ssize_t saferead(int fd, char *buf, int len)
struct constmap maproutes
char frombuf[BUFFER_SMALL]
struct constmap mapdomainips
GEN_ALLOC_typedef(GEN_ALLOC_readyplus(saa, GEN_ALLOC_readyplus(stralloc, GEN_ALLOC_readyplus(sa, GEN_ALLOC_readyplus(len, GEN_ALLOC_readyplus(a)
struct constmap maptlsdestinations
void quit(char *prepend, char *append)
unsigned long verifydepth
void outsafe(stralloc *sa)
struct constmap mapdomaincerts
char outbuf[BUFSIZE_LINE]
unsigned long timeoutconnect
ssize_t safewrite(int fd, char *buf, int len)
int utf8flag(unsigned char *ch, int len)
void tcpto_err(struct ip_mx *, int)
int tcpto(struct ip_mx *)
void temp_tlscipher(void)
void temp_tlsdigest(void)
void temp_tlspeerverify()
void temp_tlsamissing(void)
void temp_tlsainvalid(void)
void temp_tlscertfp(void)
void temp_invaliddigest(void)
int tlsa_check(const STACK_OF(X509) *, const stralloc, const unsigned long)
int tls_destination(const stralloc)
tls_destination
int tls_fingerprint(X509 *, const char *, const int)
int tls_checkpeer(SSL *, X509 *, const stralloc, const int, const int)
int tls_timeoutconn(int t, int rfd, int wfd, SSL *tls)
int ssl_ciphers(SSL_CTX *, const char *)
SSL * ssl_new(SSL_CTX *, int)
int ssl_ca(SSL_CTX *, const char *, const char *, int)