1/*	$OpenBSD: mta_session.c,v 1.151 2024/01/20 09:01:03 claudio Exp $	*/
2
3/*
4 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
6 * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
7 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/stat.h>
23
24#include <ctype.h>
25#include <errno.h>
26#include <inttypes.h>
27#include <stdlib.h>
28#include <string.h>
29#include <time.h>
30#include <tls.h>
31#include <unistd.h>
32
33#include "smtpd.h"
34#include "log.h"
35
36#define MAX_TRYBEFOREDISABLE	10
37
38#define MTA_HIWAT		65535
39
40enum mta_state {
41	MTA_INIT,
42	MTA_BANNER,
43	MTA_EHLO,
44	MTA_HELO,
45	MTA_LHLO,
46	MTA_STARTTLS,
47	MTA_AUTH,
48	MTA_AUTH_PLAIN,
49	MTA_AUTH_LOGIN,
50	MTA_AUTH_LOGIN_USER,
51	MTA_AUTH_LOGIN_PASS,
52	MTA_READY,
53	MTA_MAIL,
54	MTA_RCPT,
55	MTA_DATA,
56	MTA_BODY,
57	MTA_EOM,
58	MTA_LMTP_EOM,
59	MTA_RSET,
60	MTA_QUIT,
61};
62
63#define MTA_FORCE_ANYSSL	0x0001
64#define MTA_FORCE_SMTPS		0x0002
65#define MTA_FORCE_TLS     	0x0004
66#define MTA_FORCE_PLAIN		0x0008
67#define MTA_WANT_SECURE		0x0010
68#define MTA_DOWNGRADE_PLAIN    	0x0080
69
70#define MTA_TLS			0x0100
71#define MTA_TLS_VERIFIED	0x0200
72
73#define MTA_FREE		0x0400
74#define MTA_LMTP		0x0800
75#define MTA_WAIT		0x1000
76#define MTA_HANGON		0x2000
77#define MTA_RECONN		0x4000
78
79#define MTA_EXT_STARTTLS	0x01
80#define MTA_EXT_PIPELINING	0x02
81#define MTA_EXT_AUTH		0x04
82#define MTA_EXT_AUTH_PLAIN     	0x08
83#define MTA_EXT_AUTH_LOGIN     	0x10
84#define MTA_EXT_SIZE     	0x20
85
86struct mta_session {
87	uint64_t		 id;
88	struct mta_relay	*relay;
89	struct mta_route	*route;
90	char			*helo;
91	char			*mxname;
92
93	char			*username;
94
95	int			 flags;
96
97	int			 attempt;
98	int			 use_smtps;
99	int			 use_starttls;
100	int			 use_smtp_tls;
101	int			 ready;
102
103	struct event		 ev;
104	struct io		*io;
105	int			 ext;
106
107	size_t			 ext_size;
108
109	size_t			 msgtried;
110	size_t			 msgcount;
111	size_t			 rcptcount;
112	int			 hangon;
113
114	enum mta_state		 state;
115	struct mta_task		*task;
116	struct mta_envelope	*currevp;
117	FILE			*datafp;
118	size_t			 datalen;
119
120	size_t			 failures;
121
122	char			 replybuf[2048];
123};
124
125static void mta_session_init(void);
126static void mta_start(int fd, short ev, void *arg);
127static void mta_io(struct io *, int, void *);
128static void mta_free(struct mta_session *);
129static void mta_getnameinfo_cb(void *, int, const char *, const char *);
130static void mta_on_ptr(void *, void *, void *);
131static void mta_on_timeout(struct runq *, void *);
132static void mta_connect(struct mta_session *);
133static void mta_enter_state(struct mta_session *, int);
134static void mta_flush_task(struct mta_session *, int, const char *, size_t, int);
135static void mta_error(struct mta_session *, const char *, ...)
136    __attribute__((__format__ (printf, 2, 3)));
137static void mta_send(struct mta_session *, char *, ...)
138    __attribute__((__format__ (printf, 2, 3)));
139static ssize_t mta_queue_data(struct mta_session *);
140static void mta_response(struct mta_session *, char *);
141static const char * mta_strstate(int);
142static void mta_tls_init(struct mta_session *);
143static void mta_tls_started(struct mta_session *);
144static struct mta_session *mta_tree_pop(struct tree *, uint64_t);
145static const char * dsn_strret(enum dsn_ret);
146static const char * dsn_strnotify(uint8_t);
147
148void mta_hoststat_update(const char *, const char *);
149void mta_hoststat_reschedule(const char *);
150void mta_hoststat_cache(const char *, uint64_t);
151void mta_hoststat_uncache(const char *, uint64_t);
152
153
154static void mta_filter_begin(struct mta_session *);
155static void mta_filter_end(struct mta_session *);
156static void mta_connected(struct mta_session *);
157static void mta_disconnected(struct mta_session *);
158
159static void mta_report_link_connect(struct mta_session *, const char *, int,
160    const struct sockaddr_storage *,
161    const struct sockaddr_storage *);
162static void mta_report_link_greeting(struct mta_session *, const char *);
163static void mta_report_link_identify(struct mta_session *, const char *, const char *);
164static void mta_report_link_tls(struct mta_session *, const char *);
165static void mta_report_link_disconnect(struct mta_session *);
166static void mta_report_link_auth(struct mta_session *, const char *, const char *);
167static void mta_report_tx_reset(struct mta_session *, uint32_t);
168static void mta_report_tx_begin(struct mta_session *, uint32_t);
169static void mta_report_tx_mail(struct mta_session *, uint32_t, const char *, int);
170static void mta_report_tx_rcpt(struct mta_session *, uint32_t, const char *, int);
171static void mta_report_tx_envelope(struct mta_session *, uint32_t, uint64_t);
172static void mta_report_tx_data(struct mta_session *, uint32_t, int);
173static void mta_report_tx_commit(struct mta_session *, uint32_t, size_t);
174static void mta_report_tx_rollback(struct mta_session *, uint32_t);
175static void mta_report_protocol_client(struct mta_session *, const char *);
176static void mta_report_protocol_server(struct mta_session *, const char *);
177#if 0
178static void mta_report_filter_response(struct mta_session *, int, int, const char *);
179#endif
180static void mta_report_timeout(struct mta_session *);
181
182
183static struct tree wait_helo;
184static struct tree wait_ptr;
185static struct tree wait_fd;
186static struct tree wait_tls_init;
187static struct tree wait_tls_verify;
188
189static struct runq *hangon;
190
191#define	SESSION_FILTERED(s) \
192	((s)->relay->dispatcher->u.remote.filtername)
193
194static void
195mta_session_init(void)
196{
197	static int init = 0;
198
199	if (!init) {
200		tree_init(&wait_helo);
201		tree_init(&wait_ptr);
202		tree_init(&wait_fd);
203		tree_init(&wait_tls_init);
204		tree_init(&wait_tls_verify);
205		runq_init(&hangon, mta_on_timeout);
206		init = 1;
207	}
208}
209
210void
211mta_session(struct mta_relay *relay, struct mta_route *route, const char *mxname)
212{
213	struct mta_session	*s;
214	struct timeval		 tv;
215
216	mta_session_init();
217
218	s = xcalloc(1, sizeof *s);
219	s->id = generate_uid();
220	s->relay = relay;
221	s->route = route;
222	s->mxname = xstrdup(mxname);
223
224	mta_filter_begin(s);
225
226	if (relay->flags & RELAY_LMTP)
227		s->flags |= MTA_LMTP;
228	switch (relay->tls) {
229	case RELAY_TLS_SMTPS:
230		s->flags |= MTA_FORCE_SMTPS;
231		s->flags |= MTA_WANT_SECURE;
232		break;
233	case RELAY_TLS_STARTTLS:
234		s->flags |= MTA_FORCE_TLS;
235		s->flags |= MTA_WANT_SECURE;
236		break;
237	case RELAY_TLS_OPPORTUNISTIC:
238		/* do not force anything, try tls then smtp */
239		break;
240	case RELAY_TLS_NO:
241		s->flags |= MTA_FORCE_PLAIN;
242		break;
243	default:
244		fatalx("bad value for relay->tls: %d", relay->tls);
245	}
246
247	log_debug("debug: mta: %p: spawned for relay %s", s,
248	    mta_relay_to_text(relay));
249	stat_increment("mta.session", 1);
250
251	if (route->dst->ptrname || route->dst->lastptrquery) {
252		/* We want to delay the connection since to always notify
253		 * the relay asynchronously.
254		 */
255		tv.tv_sec = 0;
256		tv.tv_usec = 0;
257		evtimer_set(&s->ev, mta_start, s);
258		evtimer_add(&s->ev, &tv);
259	} else if (waitq_wait(&route->dst->ptrname, mta_on_ptr, s)) {
260		resolver_getnameinfo(s->route->dst->sa, NI_NUMERICSERV,
261		    mta_getnameinfo_cb, s);
262	}
263}
264
265void
266mta_session_imsg(struct mproc *p, struct imsg *imsg)
267{
268	struct mta_session	*s;
269	struct msg		 m;
270	uint64_t		 reqid;
271	const char		*name;
272	int			 status, fd;
273	struct stat		 sb;
274
275	switch (imsg->hdr.type) {
276
277	case IMSG_MTA_OPEN_MESSAGE:
278		m_msg(&m, imsg);
279		m_get_id(&m, &reqid);
280		m_end(&m);
281
282		fd = imsg_get_fd(imsg);
283		s = mta_tree_pop(&wait_fd, reqid);
284		if (s == NULL) {
285			if (fd != -1)
286				close(fd);
287			return;
288		}
289
290		if (fd == -1) {
291			log_debug("debug: mta: failed to obtain msg fd");
292			mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
293			    "Could not get message fd", 0, 0);
294			mta_enter_state(s, MTA_READY);
295			return;
296		}
297
298		if ((s->ext & MTA_EXT_SIZE) && s->ext_size != 0) {
299			if (fstat(fd, &sb) == -1) {
300				log_debug("debug: mta: failed to stat msg fd");
301				mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
302				    "Could not stat message fd", 0, 0);
303				mta_enter_state(s, MTA_READY);
304				close(fd);
305				return;
306			}
307			if (sb.st_size > (off_t)s->ext_size) {
308				log_debug("debug: mta: message too large for peer");
309				mta_flush_task(s, IMSG_MTA_DELIVERY_PERMFAIL,
310				    "message too large for peer", 0, 0);
311				mta_enter_state(s, MTA_READY);
312				close(fd);
313				return;
314			}
315		}
316
317		s->datafp = fdopen(fd, "r");
318		if (s->datafp == NULL)
319			fatal("mta: fdopen");
320
321		mta_enter_state(s, MTA_MAIL);
322		return;
323
324	case IMSG_MTA_LOOKUP_HELO:
325		m_msg(&m, imsg);
326		m_get_id(&m, &reqid);
327		m_get_int(&m, &status);
328		if (status == LKA_OK)
329			m_get_string(&m, &name);
330		m_end(&m);
331
332		s = mta_tree_pop(&wait_helo, reqid);
333		if (s == NULL)
334			return;
335
336		if (status == LKA_OK) {
337			s->helo = xstrdup(name);
338			mta_connect(s);
339		} else {
340			mta_source_error(s->relay, s->route,
341			    "Failed to retrieve helo string");
342			mta_free(s);
343		}
344		return;
345
346	default:
347		fatalx("mta_session_imsg: unexpected %s imsg",
348		    imsg_to_str(imsg->hdr.type));
349	}
350}
351
352static struct mta_session *
353mta_tree_pop(struct tree *wait, uint64_t reqid)
354{
355	struct mta_session *s;
356
357	s = tree_xpop(wait, reqid);
358	if (s->flags & MTA_FREE) {
359		log_debug("debug: mta: %p: zombie session", s);
360		mta_free(s);
361		return (NULL);
362	}
363	s->flags &= ~MTA_WAIT;
364
365	return (s);
366}
367
368static void
369mta_free(struct mta_session *s)
370{
371	struct mta_relay *relay;
372	struct mta_route *route;
373
374	log_debug("debug: mta: %p: session done", s);
375
376	mta_disconnected(s);
377
378	if (s->ready)
379		s->relay->nconn_ready -= 1;
380
381	if (s->flags & MTA_HANGON) {
382		log_debug("debug: mta: %p: cancelling hangon timer", s);
383		runq_cancel(hangon, s);
384	}
385
386	if (s->io)
387		io_free(s->io);
388
389	if (s->task)
390		fatalx("current task should have been deleted already");
391	if (s->datafp) {
392		fclose(s->datafp);
393		s->datalen = 0;
394	}
395	free(s->helo);
396
397	relay = s->relay;
398	route = s->route;
399	free(s->username);
400	free(s->mxname);
401	free(s);
402	stat_decrement("mta.session", 1);
403	mta_route_collect(relay, route);
404}
405
406static void
407mta_getnameinfo_cb(void *arg, int gaierrno, const char *host, const char *serv)
408{
409	struct mta_session *s = arg;
410	struct mta_host *h;
411
412	h = s->route->dst;
413	h->lastptrquery = time(NULL);
414	if (host)
415		h->ptrname = xstrdup(host);
416	waitq_run(&h->ptrname, h->ptrname);
417}
418
419static void
420mta_on_timeout(struct runq *runq, void *arg)
421{
422	struct mta_session *s = arg;
423
424	log_debug("mta: timeout for session hangon");
425
426	s->flags &= ~MTA_HANGON;
427	s->hangon++;
428
429	mta_enter_state(s, MTA_READY);
430}
431
432static void
433mta_on_ptr(void *tag, void *arg, void *data)
434{
435	struct mta_session *s = arg;
436
437	mta_connect(s);
438}
439
440static void
441mta_start(int fd, short ev, void *arg)
442{
443	struct mta_session *s = arg;
444
445	mta_connect(s);
446}
447
448static void
449mta_connect(struct mta_session *s)
450{
451	struct sockaddr_storage	 ss;
452	struct sockaddr		*sa;
453	int			 portno;
454	const char		*schema;
455
456	if (s->helo == NULL) {
457		if (s->relay->helotable && s->route->src->sa) {
458			m_create(p_lka, IMSG_MTA_LOOKUP_HELO, 0, 0, -1);
459			m_add_id(p_lka, s->id);
460			m_add_string(p_lka, s->relay->helotable);
461			m_add_sockaddr(p_lka, s->route->src->sa);
462			m_close(p_lka);
463			tree_xset(&wait_helo, s->id, s);
464			s->flags |= MTA_WAIT;
465			return;
466		}
467		else if (s->relay->heloname)
468			s->helo = xstrdup(s->relay->heloname);
469		else
470			s->helo = xstrdup(env->sc_hostname);
471	}
472
473	if (s->io) {
474		io_free(s->io);
475		s->io = NULL;
476	}
477
478	s->use_smtps = s->use_starttls = s->use_smtp_tls = 0;
479
480	switch (s->attempt) {
481	case 0:
482		if (s->flags & MTA_FORCE_SMTPS)
483			s->use_smtps = 1;	/* smtps */
484		else if (s->flags & (MTA_FORCE_TLS|MTA_FORCE_ANYSSL))
485			s->use_starttls = 1;	/* tls, tls+smtps */
486		else if (!(s->flags & MTA_FORCE_PLAIN))
487			s->use_smtp_tls = 1;
488		break;
489	case 1:
490		if (s->flags & MTA_FORCE_ANYSSL) {
491			s->use_smtps = 1;	/* tls+smtps */
492			break;
493		}
494		else if (s->flags & MTA_DOWNGRADE_PLAIN) {
495			/* smtp, with tls failure */
496			break;
497		}
498	default:
499		mta_free(s);
500		return;
501	}
502	portno = s->use_smtps ? 465 : 25;
503
504	/* Override with relay-specified port */
505	if (s->relay->port)
506		portno = s->relay->port;
507
508	memmove(&ss, s->route->dst->sa, s->route->dst->sa->sa_len);
509	sa = (struct sockaddr *)&ss;
510
511	if (sa->sa_family == AF_INET)
512		((struct sockaddr_in *)sa)->sin_port = htons(portno);
513	else if (sa->sa_family == AF_INET6)
514		((struct sockaddr_in6 *)sa)->sin6_port = htons(portno);
515
516	s->attempt += 1;
517	if (s->use_smtp_tls)
518		schema = "smtp://";
519	else if (s->use_starttls)
520		schema = "smtp+tls://";
521	else if (s->use_smtps)
522		schema = "smtps://";
523	else if (s->flags & MTA_LMTP)
524		schema = "lmtp://";
525	else
526		schema = "smtp+notls://";
527
528	log_info("%016"PRIx64" mta "
529	    "connecting address=%s%s:%d host=%s",
530	    s->id, schema, sa_to_text(s->route->dst->sa),
531	    portno, s->route->dst->ptrname);
532
533	mta_enter_state(s, MTA_INIT);
534	s->io = io_new();
535	io_set_callback(s->io, mta_io, s);
536	io_set_timeout(s->io, 300000);
537	if (io_connect(s->io, sa, s->route->src->sa) == -1) {
538		/*
539		 * This error is most likely a "no route",
540		 * so there is no need to try again.
541		 */
542		log_debug("debug: mta: io_connect failed: %s", io_error(s->io));
543		if (errno == EADDRNOTAVAIL)
544			mta_source_error(s->relay, s->route, io_error(s->io));
545		else
546			mta_error(s, "Connection failed: %s", io_error(s->io));
547		mta_free(s);
548	}
549}
550
551static void
552mta_enter_state(struct mta_session *s, int newstate)
553{
554	struct mta_envelope	 *e;
555	size_t			 envid_sz;
556	int			 oldstate;
557	ssize_t			 q;
558	char			 ibuf[LINE_MAX];
559	char			 obuf[LINE_MAX];
560	int			 offset;
561	const char     		*srs_sender;
562
563again:
564	oldstate = s->state;
565
566	log_trace(TRACE_MTA, "mta: %p: %s -> %s", s,
567	    mta_strstate(oldstate),
568	    mta_strstate(newstate));
569
570	s->state = newstate;
571
572	memset(s->replybuf, 0, sizeof s->replybuf);
573
574	/* don't try this at home! */
575#define mta_enter_state(_s, _st) do { newstate = _st; goto again; } while (0)
576
577	switch (s->state) {
578	case MTA_INIT:
579	case MTA_BANNER:
580		break;
581
582	case MTA_EHLO:
583		s->ext = 0;
584		mta_send(s, "EHLO %s", s->helo);
585		mta_report_link_identify(s, "EHLO", s->helo);
586		break;
587
588	case MTA_HELO:
589		s->ext = 0;
590		mta_send(s, "HELO %s", s->helo);
591		mta_report_link_identify(s, "HELO", s->helo);
592		break;
593
594	case MTA_LHLO:
595		s->ext = 0;
596		mta_send(s, "LHLO %s", s->helo);
597		mta_report_link_identify(s, "LHLO", s->helo);
598		break;
599
600	case MTA_STARTTLS:
601		if (s->flags & MTA_DOWNGRADE_PLAIN)
602			mta_enter_state(s, MTA_AUTH);
603		if (s->flags & MTA_TLS) /* already started */
604			mta_enter_state(s, MTA_AUTH);
605		else if ((s->ext & MTA_EXT_STARTTLS) == 0) {
606			if (s->flags & MTA_FORCE_TLS || s->flags & MTA_WANT_SECURE) {
607				mta_error(s, "TLS required but not supported by remote host");
608				s->flags |= MTA_RECONN;
609			}
610			else
611				/* server doesn't support starttls, do not use it */
612				mta_enter_state(s, MTA_AUTH);
613		}
614		else
615			mta_send(s, "STARTTLS");
616		break;
617
618	case MTA_AUTH:
619		if (s->relay->secret && s->flags & MTA_TLS) {
620			if (s->ext & MTA_EXT_AUTH) {
621				if (s->ext & MTA_EXT_AUTH_PLAIN) {
622					mta_enter_state(s, MTA_AUTH_PLAIN);
623					break;
624				}
625				if (s->ext & MTA_EXT_AUTH_LOGIN) {
626					mta_enter_state(s, MTA_AUTH_LOGIN);
627					break;
628				}
629				log_debug("debug: mta: %p: no supported AUTH method on session", s);
630				mta_error(s, "no supported AUTH method");
631			}
632			else {
633				log_debug("debug: mta: %p: AUTH not advertised on session", s);
634				mta_error(s, "AUTH not advertised");
635			}
636		}
637		else if (s->relay->secret) {
638			log_debug("debug: mta: %p: not using AUTH on non-TLS "
639			    "session", s);
640			mta_error(s, "Refuse to AUTH over unsecure channel");
641			mta_connect(s);
642		} else {
643			mta_enter_state(s, MTA_READY);
644		}
645		break;
646
647	case MTA_AUTH_PLAIN:
648		memset(ibuf, 0, sizeof ibuf);
649		if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
650				  sizeof(ibuf)-1) == -1) {
651			log_debug("debug: mta: %p: credentials too large on session", s);
652			mta_error(s, "Credentials too large");
653			break;
654		}
655		s->username = xstrdup(ibuf+1);
656		mta_send(s, "AUTH PLAIN %s", s->relay->secret);
657		break;
658
659	case MTA_AUTH_LOGIN:
660		mta_send(s, "AUTH LOGIN");
661		break;
662
663	case MTA_AUTH_LOGIN_USER:
664		memset(ibuf, 0, sizeof ibuf);
665		if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
666				  sizeof(ibuf)-1) == -1) {
667			log_debug("debug: mta: %p: credentials too large on session", s);
668			mta_error(s, "Credentials too large");
669			break;
670		}
671		s->username = xstrdup(ibuf+1);
672
673		memset(obuf, 0, sizeof obuf);
674		base64_encode((unsigned char *)ibuf + 1, strlen(ibuf + 1), obuf, sizeof obuf);
675		mta_send(s, "%s", obuf);
676
677		memset(ibuf, 0, sizeof ibuf);
678		memset(obuf, 0, sizeof obuf);
679		break;
680
681	case MTA_AUTH_LOGIN_PASS:
682		memset(ibuf, 0, sizeof ibuf);
683		if (base64_decode(s->relay->secret, (unsigned char *)ibuf,
684				  sizeof(ibuf)-1) == -1) {
685			log_debug("debug: mta: %p: credentials too large on session", s);
686			mta_error(s, "Credentials too large");
687			break;
688		}
689
690		offset = strlen(ibuf+1)+2;
691		memset(obuf, 0, sizeof obuf);
692		base64_encode((unsigned char *)ibuf + offset, strlen(ibuf + offset), obuf, sizeof obuf);
693		mta_send(s, "%s", obuf);
694
695		memset(ibuf, 0, sizeof ibuf);
696		memset(obuf, 0, sizeof obuf);
697		break;
698
699	case MTA_READY:
700		/* Ready to send a new mail */
701		if (s->ready == 0) {
702			s->ready = 1;
703			s->relay->nconn_ready += 1;
704			mta_route_ok(s->relay, s->route);
705		}
706
707		if (s->msgtried >= MAX_TRYBEFOREDISABLE) {
708			log_info("%016"PRIx64" mta host-rejects-all-mails",
709			    s->id);
710			mta_route_down(s->relay, s->route);
711			mta_enter_state(s, MTA_QUIT);
712			break;
713		}
714
715		if (s->msgcount >= s->relay->limits->max_mail_per_session) {
716			log_debug("debug: mta: "
717			    "%p: cannot send more message to relay %s", s,
718			    mta_relay_to_text(s->relay));
719			mta_enter_state(s, MTA_QUIT);
720			break;
721		}
722
723		/*
724		 * When downgrading from opportunistic TLS, clear flag and
725		 * possibly reuse the same task (forbidden in other cases).
726		 */
727		if (s->flags & MTA_DOWNGRADE_PLAIN)
728			s->flags &= ~MTA_DOWNGRADE_PLAIN;
729		else if (s->task)
730			fatalx("task should be NULL at this point");
731
732		if (s->task == NULL)
733			s->task = mta_route_next_task(s->relay, s->route);
734		if (s->task == NULL) {
735			log_debug("debug: mta: %p: no task for relay %s",
736			    s, mta_relay_to_text(s->relay));
737
738			if (s->relay->nconn > 1 ||
739			    s->hangon >= s->relay->limits->sessdelay_keepalive) {
740				mta_enter_state(s, MTA_QUIT);
741				break;
742			}
743
744			log_debug("mta: debug: last connection: hanging on for %llds",
745			    (long long)(s->relay->limits->sessdelay_keepalive -
746			    s->hangon));
747			s->flags |= MTA_HANGON;
748			runq_schedule(hangon, 1, s);
749			break;
750		}
751
752		log_debug("debug: mta: %p: handling next task for relay %s", s,
753			    mta_relay_to_text(s->relay));
754
755		stat_increment("mta.task.running", 1);
756
757		m_create(p_queue, IMSG_MTA_OPEN_MESSAGE, 0, 0, -1);
758		m_add_id(p_queue, s->id);
759		m_add_msgid(p_queue, s->task->msgid);
760		m_close(p_queue);
761
762		tree_xset(&wait_fd, s->id, s);
763		s->flags |= MTA_WAIT;
764		break;
765
766	case MTA_MAIL:
767		s->currevp = TAILQ_FIRST(&s->task->envelopes);
768
769		e = s->currevp;
770		s->hangon = 0;
771		s->msgtried++;
772		envid_sz = strlen(e->dsn_envid);
773
774		/* SRS-encode if requested for the relay action, AND we're not
775		 * bouncing, AND we have an RCPT which means we are forwarded,
776		 * AND the RCPT has a '@' just for sanity check (will always).
777		 */
778		if (env->sc_srs_key != NULL &&
779		    s->relay->srs &&
780		    strchr(s->task->sender, '@') &&
781		    e->rcpt &&
782		    strchr(e->rcpt, '@')) {
783			/* encode and replace task sender with new SRS-sender */
784			srs_sender = srs_encode(s->task->sender,
785			    strchr(e->rcpt, '@') + 1);
786			if (srs_sender) {
787				free(s->task->sender);
788				s->task->sender = xstrdup(srs_sender);
789			}
790		}
791
792		if (s->ext & MTA_EXT_DSN) {
793			mta_send(s, "MAIL FROM:<%s>%s%s%s%s",
794			    s->task->sender,
795			    e->dsn_ret ? " RET=" : "",
796			    e->dsn_ret ? dsn_strret(e->dsn_ret) : "",
797			    envid_sz ? " ENVID=" : "",
798			    envid_sz ? e->dsn_envid : "");
799		} else
800			mta_send(s, "MAIL FROM:<%s>", s->task->sender);
801		break;
802
803	case MTA_RCPT:
804		if (s->currevp == NULL)
805			s->currevp = TAILQ_FIRST(&s->task->envelopes);
806
807		e = s->currevp;
808		if (s->ext & MTA_EXT_DSN) {
809			mta_send(s, "RCPT TO:<%s>%s%s%s%s",
810			    e->dest,
811			    e->dsn_notify ? " NOTIFY=" : "",
812			    e->dsn_notify ? dsn_strnotify(e->dsn_notify) : "",
813			    e->dsn_orcpt ? " ORCPT=" : "",
814			    e->dsn_orcpt ? e->dsn_orcpt : "");
815		} else
816			mta_send(s, "RCPT TO:<%s>", e->dest);
817
818		mta_report_tx_envelope(s, s->task->msgid, e->id);
819		s->rcptcount++;
820		break;
821
822	case MTA_DATA:
823		fseek(s->datafp, 0, SEEK_SET);
824		mta_send(s, "DATA");
825		break;
826
827	case MTA_BODY:
828		if (s->datafp == NULL) {
829			log_trace(TRACE_MTA, "mta: %p: end-of-file", s);
830			mta_enter_state(s, MTA_EOM);
831			break;
832		}
833
834		if ((q = mta_queue_data(s)) == -1) {
835			s->flags |= MTA_FREE;
836			break;
837		}
838		if (q == 0) {
839			mta_enter_state(s, MTA_BODY);
840			break;
841		}
842
843		log_trace(TRACE_MTA, "mta: %p: >>> [...%zd bytes...]", s, q);
844		break;
845
846	case MTA_EOM:
847		mta_send(s, ".");
848		break;
849
850	case MTA_LMTP_EOM:
851		/* LMTP reports status of each delivery, so enable read */
852		io_set_read(s->io);
853		break;
854
855	case MTA_RSET:
856		if (s->datafp) {
857			fclose(s->datafp);
858			s->datafp = NULL;
859			s->datalen = 0;
860		}
861		mta_send(s, "RSET");
862		break;
863
864	case MTA_QUIT:
865		mta_send(s, "QUIT");
866		break;
867
868	default:
869		fatalx("mta_enter_state: unknown state");
870	}
871#undef mta_enter_state
872}
873
874/*
875 * Handle a response to an SMTP command
876 */
877static void
878mta_response(struct mta_session *s, char *line)
879{
880	struct mta_envelope	*e;
881	struct sockaddr_storage	 ss;
882	struct sockaddr		*sa;
883	const char		*domain;
884	char			*pbuf;
885	socklen_t		 sa_len;
886	char			 buf[LINE_MAX];
887	int			 delivery;
888
889	switch (s->state) {
890
891	case MTA_BANNER:
892		if (line[0] != '2') {
893			mta_error(s, "BANNER rejected: %s", line);
894			s->flags |= MTA_FREE;
895			return;
896		}
897
898		pbuf = "";
899		if (strlen(line) > 4) {
900			(void)strlcpy(buf, line + 4, sizeof buf);
901			if ((pbuf = strchr(buf, ' ')))
902				*pbuf = '\0';
903			pbuf = valid_domainpart(buf) ? buf : "";
904		}
905		mta_report_link_greeting(s, pbuf);
906
907		if (s->flags & MTA_LMTP)
908			mta_enter_state(s, MTA_LHLO);
909		else
910			mta_enter_state(s, MTA_EHLO);
911		break;
912
913	case MTA_EHLO:
914		if (line[0] != '2') {
915			/* rejected at ehlo state */
916			if ((s->relay->flags & RELAY_AUTH) ||
917			    (s->flags & MTA_WANT_SECURE)) {
918				mta_error(s, "EHLO rejected: %s", line);
919				s->flags |= MTA_FREE;
920				return;
921			}
922			mta_enter_state(s, MTA_HELO);
923			return;
924		}
925		if (!(s->flags & MTA_FORCE_PLAIN))
926			mta_enter_state(s, MTA_STARTTLS);
927		else
928			mta_enter_state(s, MTA_READY);
929		break;
930
931	case MTA_HELO:
932		if (line[0] != '2') {
933			mta_error(s, "HELO rejected: %s", line);
934			s->flags |= MTA_FREE;
935			return;
936		}
937		mta_enter_state(s, MTA_READY);
938		break;
939
940	case MTA_LHLO:
941		if (line[0] != '2') {
942			mta_error(s, "LHLO rejected: %s", line);
943			s->flags |= MTA_FREE;
944			return;
945		}
946		mta_enter_state(s, MTA_READY);
947		break;
948
949	case MTA_STARTTLS:
950		if (line[0] != '2') {
951			if (!(s->flags & MTA_WANT_SECURE)) {
952				mta_enter_state(s, MTA_AUTH);
953				return;
954			}
955			/* XXX mark that the MX doesn't support STARTTLS */
956			mta_error(s, "STARTTLS rejected: %s", line);
957			s->flags |= MTA_FREE;
958			return;
959		}
960
961		mta_tls_init(s);
962		break;
963
964	case MTA_AUTH_PLAIN:
965		if (line[0] != '2') {
966			mta_error(s, "AUTH rejected: %s", line);
967			mta_report_link_auth(s, s->username, "fail");
968			s->flags |= MTA_FREE;
969			return;
970		}
971		mta_report_link_auth(s, s->username, "pass");
972		mta_enter_state(s, MTA_READY);
973		break;
974
975	case MTA_AUTH_LOGIN:
976		if (strncmp(line, "334 ", 4) != 0) {
977			mta_error(s, "AUTH rejected: %s", line);
978			mta_report_link_auth(s, s->username, "fail");
979			s->flags |= MTA_FREE;
980			return;
981		}
982		mta_enter_state(s, MTA_AUTH_LOGIN_USER);
983		break;
984
985	case MTA_AUTH_LOGIN_USER:
986		if (strncmp(line, "334 ", 4) != 0) {
987			mta_error(s, "AUTH rejected: %s", line);
988			mta_report_link_auth(s, s->username, "fail");
989			s->flags |= MTA_FREE;
990			return;
991		}
992		mta_enter_state(s, MTA_AUTH_LOGIN_PASS);
993		break;
994
995	case MTA_AUTH_LOGIN_PASS:
996		if (line[0] != '2') {
997			mta_error(s, "AUTH rejected: %s", line);
998			mta_report_link_auth(s, s->username, "fail");
999			s->flags |= MTA_FREE;
1000			return;
1001		}
1002		mta_report_link_auth(s, s->username, "pass");
1003		mta_enter_state(s, MTA_READY);
1004		break;
1005
1006	case MTA_MAIL:
1007		if (line[0] != '2') {
1008			if (line[0] == '5')
1009				delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1010			else
1011				delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1012
1013			mta_flush_task(s, delivery, line, 0, 0);
1014			mta_enter_state(s, MTA_RSET);
1015			return;
1016		}
1017		mta_report_tx_begin(s, s->task->msgid);
1018		mta_report_tx_mail(s, s->task->msgid, s->task->sender, 1);
1019		mta_enter_state(s, MTA_RCPT);
1020		break;
1021
1022	case MTA_RCPT:
1023		e = s->currevp;
1024
1025		/* remove envelope from hosttat cache if there */
1026		if ((domain = strchr(e->dest, '@')) != NULL) {
1027			domain++;
1028			mta_hoststat_uncache(domain, e->id);
1029		}
1030
1031		s->currevp = TAILQ_NEXT(s->currevp, entry);
1032		if (line[0] == '2') {
1033			s->failures = 0;
1034			/*
1035			 * this host is up, reschedule envelopes that
1036			 * were cached for reschedule.
1037			 */
1038			if (domain)
1039				mta_hoststat_reschedule(domain);
1040		}
1041		else {
1042			mta_report_tx_rollback(s, s->task->msgid);
1043			mta_report_tx_reset(s, s->task->msgid);
1044			if (line[0] == '5')
1045				delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1046			else
1047				delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1048			s->failures++;
1049
1050			/* remove failed envelope from task list */
1051			TAILQ_REMOVE(&s->task->envelopes, e, entry);
1052			stat_decrement("mta.envelope", 1);
1053
1054			/* log right away */
1055			(void)snprintf(buf, sizeof(buf), "%s",
1056			    mta_host_to_text(s->route->dst));
1057
1058			e->session = s->id;
1059			/* XXX */
1060			/*
1061			 * getsockname() can only fail with ENOBUFS here
1062			 * best effort, don't log source ...
1063			 */
1064			sa_len = sizeof(ss);
1065			sa = (struct sockaddr *)&ss;
1066			if (getsockname(io_fileno(s->io), sa, &sa_len) == -1)
1067				mta_delivery_log(e, NULL, buf, delivery, line);
1068			else
1069				mta_delivery_log(e, sa_to_text(sa),
1070				    buf, delivery, line);
1071
1072			if (domain)
1073				mta_hoststat_update(domain, e->status);
1074			mta_delivery_notify(e);
1075
1076			if (s->relay->limits->max_failures_per_session &&
1077			    s->failures == s->relay->limits->max_failures_per_session) {
1078					mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
1079					    "Too many consecutive errors, closing connection", 0, 1);
1080					mta_enter_state(s, MTA_QUIT);
1081					break;
1082				}
1083
1084			/*
1085			 * if no more envelopes, flush failed queue
1086			 */
1087			if (TAILQ_EMPTY(&s->task->envelopes)) {
1088				mta_flush_task(s, IMSG_MTA_DELIVERY_OK,
1089				    "No envelope", 0, 0);
1090				mta_enter_state(s, MTA_RSET);
1091				break;
1092			}
1093		}
1094
1095		switch (line[0]) {
1096		case '2':
1097			mta_report_tx_rcpt(s,
1098			    s->task->msgid, e->dest, 1);
1099			break;
1100		case '4':
1101			mta_report_tx_rcpt(s,
1102			    s->task->msgid, e->dest, -1);
1103			break;
1104		case '5':
1105			mta_report_tx_rcpt(s,
1106			    s->task->msgid, e->dest, 0);
1107			break;
1108		}
1109
1110		if (s->currevp == NULL)
1111			mta_enter_state(s, MTA_DATA);
1112		else
1113			mta_enter_state(s, MTA_RCPT);
1114		break;
1115
1116	case MTA_DATA:
1117		if (line[0] == '2' || line[0] == '3') {
1118			mta_report_tx_data(s, s->task->msgid, 1);
1119			mta_enter_state(s, MTA_BODY);
1120			break;
1121		}
1122
1123		if (line[0] == '5')
1124			delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1125		else
1126			delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1127		mta_report_tx_data(s, s->task->msgid,
1128		    delivery == IMSG_MTA_DELIVERY_TEMPFAIL ? -1 : 0);
1129		mta_report_tx_rollback(s, s->task->msgid);
1130		mta_report_tx_reset(s, s->task->msgid);
1131		mta_flush_task(s, delivery, line, 0, 0);
1132		mta_enter_state(s, MTA_RSET);
1133		break;
1134
1135	case MTA_LMTP_EOM:
1136	case MTA_EOM:
1137		if (line[0] == '2') {
1138			delivery = IMSG_MTA_DELIVERY_OK;
1139			s->msgtried = 0;
1140			s->msgcount++;
1141		}
1142		else if (line[0] == '5')
1143			delivery = IMSG_MTA_DELIVERY_PERMFAIL;
1144		else
1145			delivery = IMSG_MTA_DELIVERY_TEMPFAIL;
1146		if (delivery != IMSG_MTA_DELIVERY_OK) {
1147			mta_report_tx_rollback(s, s->task->msgid);
1148			mta_report_tx_reset(s, s->task->msgid);
1149		}
1150		else {
1151			mta_report_tx_commit(s, s->task->msgid, s->datalen);
1152			mta_report_tx_reset(s, s->task->msgid);
1153		}
1154		mta_flush_task(s, delivery, line, (s->flags & MTA_LMTP) ? 1 : 0, 0);
1155		if (s->task) {
1156			s->rcptcount--;
1157			mta_enter_state(s, MTA_LMTP_EOM);
1158		} else {
1159			s->rcptcount = 0;
1160			if (s->relay->limits->sessdelay_transaction) {
1161				log_debug("debug: mta: waiting for %llds before next transaction",
1162				    (long long)s->relay->limits->sessdelay_transaction);
1163				s->hangon = s->relay->limits->sessdelay_transaction -1;
1164				s->flags |= MTA_HANGON;
1165				runq_schedule(hangon,
1166				    s->relay->limits->sessdelay_transaction, s);
1167			}
1168			else
1169				mta_enter_state(s, MTA_READY);
1170		}
1171		break;
1172
1173	case MTA_RSET:
1174		s->rcptcount = 0;
1175
1176		if (s->task) {
1177			mta_report_tx_rollback(s, s->task->msgid);
1178			mta_report_tx_reset(s, s->task->msgid);
1179		}
1180		if (s->relay->limits->sessdelay_transaction) {
1181			log_debug("debug: mta: waiting for %llds after reset",
1182			    (long long)s->relay->limits->sessdelay_transaction);
1183			s->hangon = s->relay->limits->sessdelay_transaction -1;
1184			s->flags |= MTA_HANGON;
1185			runq_schedule(hangon,
1186			    s->relay->limits->sessdelay_transaction, s);
1187		}
1188		else
1189			mta_enter_state(s, MTA_READY);
1190		break;
1191
1192	default:
1193		fatalx("mta_response() bad state");
1194	}
1195}
1196
1197static void
1198mta_io(struct io *io, int evt, void *arg)
1199{
1200	struct mta_session	*s = arg;
1201	char			*line, *msg, *p;
1202	size_t			 len;
1203	const char		*error;
1204	int			 cont;
1205
1206	log_trace(TRACE_IO, "mta: %p: %s %s", s, io_strevent(evt),
1207	    io_strio(io));
1208
1209	switch (evt) {
1210
1211	case IO_CONNECTED:
1212		mta_connected(s);
1213
1214		if (s->use_smtps) {
1215			io_set_write(io);
1216			mta_tls_init(s);
1217			if (s->flags & MTA_FREE)
1218				mta_free(s);
1219		}
1220		else {
1221			mta_enter_state(s, MTA_BANNER);
1222			io_set_read(io);
1223		}
1224		break;
1225
1226	case IO_TLSREADY:
1227		log_info("%016"PRIx64" mta tls ciphers=%s",
1228		    s->id, tls_to_text(io_tls(s->io)));
1229		s->flags |= MTA_TLS;
1230		if (s->relay->dispatcher->u.remote.tls_verify)
1231			s->flags |= MTA_TLS_VERIFIED;
1232
1233		mta_tls_started(s);
1234		mta_report_link_tls(s,
1235		    tls_to_text(io_tls(s->io)));
1236		break;
1237
1238	case IO_DATAIN:
1239	    nextline:
1240		line = io_getline(s->io, &len);
1241		if (line == NULL) {
1242			if (io_datalen(s->io) >= LINE_MAX) {
1243				mta_error(s, "Input too long");
1244				mta_free(s);
1245			}
1246			return;
1247		}
1248
1249		/* Strip trailing '\r' */
1250		if (len && line[len - 1] == '\r')
1251			line[--len] = '\0';
1252
1253		log_trace(TRACE_MTA, "mta: %p: <<< %s", s, line);
1254		mta_report_protocol_server(s, line);
1255
1256		if ((error = parse_smtp_response(line, len, &msg, &cont))) {
1257			mta_error(s, "Bad response: %s", error);
1258			mta_free(s);
1259			return;
1260		}
1261
1262		/* read extensions */
1263		if (s->state == MTA_EHLO) {
1264			if (strcmp(msg, "STARTTLS") == 0)
1265				s->ext |= MTA_EXT_STARTTLS;
1266			else if (strncmp(msg, "AUTH ", 5) == 0) {
1267                                s->ext |= MTA_EXT_AUTH;
1268                                if ((p = strstr(msg, " PLAIN")) &&
1269				    (*(p+6) == '\0' || *(p+6) == ' '))
1270                                        s->ext |= MTA_EXT_AUTH_PLAIN;
1271                                if ((p = strstr(msg, " LOGIN")) &&
1272				    (*(p+6) == '\0' || *(p+6) == ' '))
1273                                        s->ext |= MTA_EXT_AUTH_LOGIN;
1274			}
1275			else if (strcmp(msg, "PIPELINING") == 0)
1276				s->ext |= MTA_EXT_PIPELINING;
1277			else if (strcmp(msg, "DSN") == 0)
1278				s->ext |= MTA_EXT_DSN;
1279			else if (strncmp(msg, "SIZE ", 5) == 0) {
1280				s->ext_size = strtonum(msg+5, 0, UINT32_MAX, &error);
1281				if (error == NULL)
1282					s->ext |= MTA_EXT_SIZE;
1283			}
1284		}
1285
1286		/* continuation reply, we parse out the repeating statuses and ESC */
1287		if (cont) {
1288			if (s->replybuf[0] == '\0')
1289				(void)strlcat(s->replybuf, line, sizeof s->replybuf);
1290			else if (len > 4) {
1291				p = line + 4;
1292				if (isdigit((unsigned char)p[0]) && p[1] == '.' &&
1293				    isdigit((unsigned char)p[2]) && p[3] == '.' &&
1294				    isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5]))
1295					p += 5;
1296				(void)strlcat(s->replybuf, p, sizeof s->replybuf);
1297			}
1298			goto nextline;
1299		}
1300
1301		/* last line of a reply, check if we're on a continuation to parse out status and ESC.
1302		 * if we overflow reply buffer or are not on continuation, log entire last line.
1303		 */
1304		if (s->replybuf[0] == '\0')
1305			(void)strlcat(s->replybuf, line, sizeof s->replybuf);
1306		else if (len > 4) {
1307			p = line + 4;
1308			if (isdigit((unsigned char)p[0]) && p[1] == '.' &&
1309			    isdigit((unsigned char)p[2]) && p[3] == '.' &&
1310			    isdigit((unsigned char)p[4]) && isspace((unsigned char)p[5]))
1311				p += 5;
1312			if (strlcat(s->replybuf, p, sizeof s->replybuf) >= sizeof s->replybuf)
1313				(void)strlcpy(s->replybuf, line, sizeof s->replybuf);
1314		}
1315
1316		if (s->state == MTA_QUIT) {
1317			log_info("%016"PRIx64" mta disconnected reason=quit messages=%zu",
1318			    s->id, s->msgcount);
1319			mta_free(s);
1320			return;
1321		}
1322		io_set_write(io);
1323		mta_response(s, s->replybuf);
1324		if (s->flags & MTA_FREE) {
1325			mta_free(s);
1326			return;
1327		}
1328		if (s->flags & MTA_RECONN) {
1329			s->flags &= ~MTA_RECONN;
1330			mta_connect(s);
1331			return;
1332		}
1333
1334		if (io_datalen(s->io)) {
1335			log_debug("debug: mta: remaining data in input buffer");
1336			mta_error(s, "Remote host sent too much data");
1337			if (s->flags & MTA_WAIT)
1338				s->flags |= MTA_FREE;
1339			else
1340				mta_free(s);
1341		}
1342		break;
1343
1344	case IO_LOWAT:
1345		if (s->state == MTA_BODY) {
1346			mta_enter_state(s, MTA_BODY);
1347			if (s->flags & MTA_FREE) {
1348				mta_free(s);
1349				return;
1350			}
1351		}
1352
1353		if (io_queued(s->io) == 0)
1354			io_set_read(io);
1355		break;
1356
1357	case IO_TIMEOUT:
1358		log_debug("debug: mta: %p: connection timeout", s);
1359		mta_error(s, "Connection timeout");
1360		mta_report_timeout(s);
1361		if (!s->ready)
1362			mta_connect(s);
1363		else
1364			mta_free(s);
1365		break;
1366
1367	case IO_ERROR:
1368		log_debug("debug: mta: %p: IO error: %s", s, io_error(io));
1369
1370		if (s->state == MTA_STARTTLS && s->use_smtp_tls) {
1371			/* error in non-strict SSL negotiation, downgrade to plain */
1372			log_info("smtp-out: Error on session %016"PRIx64
1373			    ": opportunistic TLS failed, "
1374			    "downgrading to plain", s->id);
1375			s->flags &= ~MTA_TLS;
1376			s->flags |= MTA_DOWNGRADE_PLAIN;
1377			mta_connect(s);
1378			break;
1379		}
1380
1381		mta_error(s, "IO Error: %s", io_error(io));
1382		mta_free(s);
1383		break;
1384
1385	case IO_DISCONNECTED:
1386		log_debug("debug: mta: %p: disconnected in state %s",
1387		    s, mta_strstate(s->state));
1388		mta_error(s, "Connection closed unexpectedly");
1389		if (!s->ready)
1390			mta_connect(s);
1391		else
1392			mta_free(s);
1393		break;
1394
1395	default:
1396		fatalx("mta_io() bad event");
1397	}
1398}
1399
1400static void
1401mta_send(struct mta_session *s, char *fmt, ...)
1402{
1403	va_list  ap;
1404	char	*p;
1405	int	 len;
1406
1407	va_start(ap, fmt);
1408	if ((len = vasprintf(&p, fmt, ap)) == -1)
1409		fatal("mta: vasprintf");
1410	va_end(ap);
1411
1412	log_trace(TRACE_MTA, "mta: %p: >>> %s", s, p);
1413
1414	if (strncasecmp(p, "AUTH PLAIN ", 11) == 0)
1415		mta_report_protocol_client(s, "AUTH PLAIN ********");
1416	else if (s->state == MTA_AUTH_LOGIN_USER || s->state == MTA_AUTH_LOGIN_PASS)
1417		mta_report_protocol_client(s, "********");
1418	else
1419		mta_report_protocol_client(s, p);
1420
1421	io_xprintf(s->io, "%s\r\n", p);
1422
1423	free(p);
1424}
1425
1426/*
1427 * Queue some data into the input buffer
1428 */
1429static ssize_t
1430mta_queue_data(struct mta_session *s)
1431{
1432	char	*ln = NULL;
1433	size_t	 sz = 0, q;
1434	ssize_t	 len;
1435
1436	q = io_queued(s->io);
1437
1438	while (io_queued(s->io) < MTA_HIWAT) {
1439		if ((len = getline(&ln, &sz, s->datafp)) == -1)
1440			break;
1441		if (ln[len - 1] == '\n')
1442			ln[len - 1] = '\0';
1443		s->datalen += io_xprintf(s->io, "%s%s\r\n", *ln == '.' ? "." : "", ln);
1444	}
1445
1446	free(ln);
1447	if (ferror(s->datafp)) {
1448		mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL,
1449		    "Error reading content file", 0, 0);
1450		return (-1);
1451	}
1452
1453	if (feof(s->datafp)) {
1454		fclose(s->datafp);
1455		s->datafp = NULL;
1456	}
1457
1458	return (io_queued(s->io) - q);
1459}
1460
1461static void
1462mta_flush_task(struct mta_session *s, int delivery, const char *error, size_t count,
1463	int cache)
1464{
1465	struct mta_envelope	*e;
1466	char			 relay[LINE_MAX];
1467	size_t			 n;
1468	struct sockaddr_storage	 ss;
1469	struct sockaddr		*sa;
1470	socklen_t		 sa_len;
1471	const char		*domain;
1472
1473	(void)snprintf(relay, sizeof relay, "%s", mta_host_to_text(s->route->dst));
1474	n = 0;
1475	while ((e = TAILQ_FIRST(&s->task->envelopes))) {
1476
1477		if (count && n == count) {
1478			stat_decrement("mta.envelope", n);
1479			return;
1480		}
1481
1482		TAILQ_REMOVE(&s->task->envelopes, e, entry);
1483
1484		/* we're about to log, associate session to envelope */
1485		e->session = s->id;
1486		e->ext = s->ext;
1487
1488		/* XXX */
1489		/*
1490		 * getsockname() can only fail with ENOBUFS here
1491		 * best effort, don't log source ...
1492		 */
1493		sa = (struct sockaddr *)&ss;
1494		sa_len = sizeof(ss);
1495		if (getsockname(io_fileno(s->io), sa, &sa_len) == -1)
1496			mta_delivery_log(e, NULL, relay, delivery, error);
1497		else
1498			mta_delivery_log(e, sa_to_text(sa),
1499			    relay, delivery, error);
1500
1501		mta_delivery_notify(e);
1502
1503		domain = strchr(e->dest, '@');
1504		if (domain) {
1505			domain++;
1506			mta_hoststat_update(domain, error);
1507			if (cache)
1508				mta_hoststat_cache(domain, e->id);
1509		}
1510
1511		n++;
1512	}
1513
1514	free(s->task->sender);
1515	free(s->task);
1516	s->task = NULL;
1517
1518	if (s->datafp) {
1519		fclose(s->datafp);
1520		s->datafp = NULL;
1521	}
1522
1523	stat_decrement("mta.envelope", n);
1524	stat_decrement("mta.task.running", 1);
1525	stat_decrement("mta.task", 1);
1526}
1527
1528static void
1529mta_error(struct mta_session *s, const char *fmt, ...)
1530{
1531	va_list  ap;
1532	char	*error;
1533	int	 len;
1534
1535	va_start(ap, fmt);
1536	if ((len = vasprintf(&error, fmt, ap)) == -1)
1537		fatal("mta: vasprintf");
1538	va_end(ap);
1539
1540	if (s->msgcount)
1541		log_info("smtp-out: Error on session %016"PRIx64
1542		    " after %zu message%s sent: %s", s->id, s->msgcount,
1543		    (s->msgcount > 1) ? "s" : "", error);
1544	else
1545		log_info("%016"PRIx64" mta error reason=%s",
1546		    s->id, error);
1547
1548	/*
1549	 * If not connected yet, and the error is not local, just ignore it
1550	 * and try to reconnect.
1551	 */
1552	if (s->state == MTA_INIT &&
1553	    (errno == ETIMEDOUT || errno == ECONNREFUSED)) {
1554		log_debug("debug: mta: not reporting route error yet");
1555		free(error);
1556		return;
1557	}
1558
1559	mta_route_error(s->relay, s->route);
1560
1561	if (s->task)
1562		mta_flush_task(s, IMSG_MTA_DELIVERY_TEMPFAIL, error, 0, 0);
1563
1564	free(error);
1565}
1566
1567static void
1568mta_tls_init(struct mta_session *s)
1569{
1570	struct dispatcher_remote *remote;
1571	struct tls *tls;
1572
1573	if ((tls = tls_client()) == NULL) {
1574		log_info("%016"PRIx64" mta closing reason=tls-failure", s->id);
1575		s->flags |= MTA_FREE;
1576		return;
1577	}
1578
1579	remote = &s->relay->dispatcher->u.remote;
1580	if ((s->flags & MTA_WANT_SECURE) && !remote->tls_required) {
1581		/* If TLS not explicitly configured, use implicit config. */
1582		remote->tls_required = 1;
1583		remote->tls_verify = 1;
1584		tls_config_verify(remote->tls_config);
1585	}
1586	if (tls_configure(tls, remote->tls_config) == -1) {
1587		log_info("%016"PRIx64" mta closing reason=tls-failure", s->id);
1588		tls_free(tls);
1589		s->flags |= MTA_FREE;
1590		return;
1591	}
1592
1593	if (io_connect_tls(s->io, tls, s->mxname) == -1) {
1594		log_info("%016"PRIx64" mta closing reason=tls-connect-failed", s->id);
1595		tls_free(tls);
1596		s->flags |= MTA_FREE;
1597	}
1598}
1599
1600static void
1601mta_tls_started(struct mta_session *s)
1602{
1603	if (tls_peer_cert_provided(io_tls(s->io))) {
1604		log_info("%016"PRIx64" mta "
1605		    "cert-check result=\"%s\" fingerprint=\"%s\"",
1606		    s->id,
1607		    (s->flags & MTA_TLS_VERIFIED) ? "valid" : "unverified",
1608		    tls_peer_cert_hash(io_tls(s->io)));
1609	}
1610	else {
1611		log_info("%016"PRIx64" smtp "
1612		    "cert-check result=\"no certificate presented\"",
1613		    s->id);
1614	}
1615
1616	if (s->use_smtps) {
1617		mta_enter_state(s, MTA_BANNER);
1618		io_set_read(s->io);
1619	}
1620	else
1621		mta_enter_state(s, MTA_EHLO);
1622}
1623
1624static const char *
1625dsn_strret(enum dsn_ret ret)
1626{
1627	if (ret == DSN_RETHDRS)
1628		return "HDRS";
1629	else if (ret == DSN_RETFULL)
1630		return "FULL";
1631	else {
1632		log_debug("mta: invalid ret %d", ret);
1633		return "???";
1634	}
1635}
1636
1637static const char *
1638dsn_strnotify(uint8_t arg)
1639{
1640	static char	buf[32];
1641	size_t		sz;
1642
1643	buf[0] = '\0';
1644	if (arg & DSN_SUCCESS)
1645		(void)strlcat(buf, "SUCCESS,", sizeof(buf));
1646
1647	if (arg & DSN_FAILURE)
1648		(void)strlcat(buf, "FAILURE,", sizeof(buf));
1649
1650	if (arg & DSN_DELAY)
1651		(void)strlcat(buf, "DELAY,", sizeof(buf));
1652
1653	if (arg & DSN_NEVER)
1654		(void)strlcat(buf, "NEVER,", sizeof(buf));
1655
1656	/* trim trailing comma */
1657	sz = strlen(buf);
1658	if (sz)
1659		buf[sz - 1] = '\0';
1660
1661	return (buf);
1662}
1663
1664#define CASE(x) case x : return #x
1665
1666static const char *
1667mta_strstate(int state)
1668{
1669	switch (state) {
1670	CASE(MTA_INIT);
1671	CASE(MTA_BANNER);
1672	CASE(MTA_EHLO);
1673	CASE(MTA_HELO);
1674	CASE(MTA_STARTTLS);
1675	CASE(MTA_AUTH);
1676	CASE(MTA_AUTH_PLAIN);
1677	CASE(MTA_AUTH_LOGIN);
1678	CASE(MTA_AUTH_LOGIN_USER);
1679	CASE(MTA_AUTH_LOGIN_PASS);
1680	CASE(MTA_READY);
1681	CASE(MTA_MAIL);
1682	CASE(MTA_RCPT);
1683	CASE(MTA_DATA);
1684	CASE(MTA_BODY);
1685	CASE(MTA_EOM);
1686	CASE(MTA_LMTP_EOM);
1687	CASE(MTA_RSET);
1688	CASE(MTA_QUIT);
1689	default:
1690		return "MTA_???";
1691	}
1692}
1693
1694static void
1695mta_filter_begin(struct mta_session *s)
1696{
1697	if (!SESSION_FILTERED(s))
1698		return;
1699
1700	m_create(p_lka, IMSG_FILTER_SMTP_BEGIN, 0, 0, -1);
1701	m_add_id(p_lka, s->id);
1702	m_add_string(p_lka, s->relay->dispatcher->u.remote.filtername);
1703	m_close(p_lka);
1704}
1705
1706static void
1707mta_filter_end(struct mta_session *s)
1708{
1709	if (!SESSION_FILTERED(s))
1710		return;
1711
1712	m_create(p_lka, IMSG_FILTER_SMTP_END, 0, 0, -1);
1713	m_add_id(p_lka, s->id);
1714	m_close(p_lka);
1715}
1716
1717static void
1718mta_connected(struct mta_session *s)
1719{
1720	struct sockaddr_storage sa_src;
1721	struct sockaddr_storage sa_dest;
1722	int sa_len;
1723
1724	log_info("%016"PRIx64" mta connected", s->id);
1725
1726	sa_len = sizeof sa_src;
1727	if (getsockname(io_fileno(s->io),
1728	    (struct sockaddr *)&sa_src, &sa_len) == -1)
1729		bzero(&sa_src, sizeof sa_src);
1730	sa_len = sizeof sa_dest;
1731	if (getpeername(io_fileno(s->io),
1732	    (struct sockaddr *)&sa_dest, &sa_len) == -1)
1733		bzero(&sa_dest, sizeof sa_dest);
1734
1735	mta_report_link_connect(s,
1736	    s->route->dst->ptrname, 1,
1737	    &sa_src,
1738	    &sa_dest);
1739}
1740
1741static void
1742mta_disconnected(struct mta_session *s)
1743{
1744	mta_report_link_disconnect(s);
1745	mta_filter_end(s);
1746}
1747
1748
1749static void
1750mta_report_link_connect(struct mta_session *s, const char *rdns, int fcrdns,
1751    const struct sockaddr_storage *ss_src,
1752    const struct sockaddr_storage *ss_dest)
1753{
1754	if (! SESSION_FILTERED(s))
1755		return;
1756
1757	report_smtp_link_connect("smtp-out", s->id, rdns, fcrdns, ss_src, ss_dest);
1758}
1759
1760static void
1761mta_report_link_greeting(struct mta_session *s,
1762    const char *domain)
1763{
1764	if (! SESSION_FILTERED(s))
1765		return;
1766
1767	report_smtp_link_greeting("smtp-out", s->id, domain);
1768}
1769
1770static void
1771mta_report_link_identify(struct mta_session *s, const char *method, const char *identity)
1772{
1773	if (! SESSION_FILTERED(s))
1774		return;
1775
1776	report_smtp_link_identify("smtp-out", s->id, method, identity);
1777}
1778
1779static void
1780mta_report_link_tls(struct mta_session *s, const char *ssl)
1781{
1782	if (! SESSION_FILTERED(s))
1783		return;
1784
1785	report_smtp_link_tls("smtp-out", s->id, ssl);
1786}
1787
1788static void
1789mta_report_link_disconnect(struct mta_session *s)
1790{
1791	if (! SESSION_FILTERED(s))
1792		return;
1793
1794	report_smtp_link_disconnect("smtp-out", s->id);
1795}
1796
1797static void
1798mta_report_link_auth(struct mta_session *s, const char *user, const char *result)
1799{
1800	if (! SESSION_FILTERED(s))
1801		return;
1802
1803	report_smtp_link_auth("smtp-out", s->id, user, result);
1804}
1805
1806static void
1807mta_report_tx_reset(struct mta_session *s, uint32_t msgid)
1808{
1809	if (! SESSION_FILTERED(s))
1810		return;
1811
1812	report_smtp_tx_reset("smtp-out", s->id, msgid);
1813}
1814
1815static void
1816mta_report_tx_begin(struct mta_session *s, uint32_t msgid)
1817{
1818	if (! SESSION_FILTERED(s))
1819		return;
1820
1821	report_smtp_tx_begin("smtp-out", s->id, msgid);
1822}
1823
1824static void
1825mta_report_tx_mail(struct mta_session *s, uint32_t msgid, const char *address, int ok)
1826{
1827	if (! SESSION_FILTERED(s))
1828		return;
1829
1830	report_smtp_tx_mail("smtp-out", s->id, msgid, address, ok);
1831}
1832
1833static void
1834mta_report_tx_rcpt(struct mta_session *s, uint32_t msgid, const char *address, int ok)
1835{
1836	if (! SESSION_FILTERED(s))
1837		return;
1838
1839	report_smtp_tx_rcpt("smtp-out", s->id, msgid, address, ok);
1840}
1841
1842static void
1843mta_report_tx_envelope(struct mta_session *s, uint32_t msgid, uint64_t evpid)
1844{
1845	if (! SESSION_FILTERED(s))
1846		return;
1847
1848	report_smtp_tx_envelope("smtp-out", s->id, msgid, evpid);
1849}
1850
1851static void
1852mta_report_tx_data(struct mta_session *s, uint32_t msgid, int ok)
1853{
1854	if (! SESSION_FILTERED(s))
1855		return;
1856
1857	report_smtp_tx_data("smtp-out", s->id, msgid, ok);
1858}
1859
1860static void
1861mta_report_tx_commit(struct mta_session *s, uint32_t msgid, size_t msgsz)
1862{
1863	if (! SESSION_FILTERED(s))
1864		return;
1865
1866	report_smtp_tx_commit("smtp-out", s->id, msgid, msgsz);
1867}
1868
1869static void
1870mta_report_tx_rollback(struct mta_session *s, uint32_t msgid)
1871{
1872	if (! SESSION_FILTERED(s))
1873		return;
1874
1875	report_smtp_tx_rollback("smtp-out", s->id, msgid);
1876}
1877
1878static void
1879mta_report_protocol_client(struct mta_session *s, const char *command)
1880{
1881	if (! SESSION_FILTERED(s))
1882		return;
1883
1884	report_smtp_protocol_client("smtp-out", s->id, command);
1885}
1886
1887static void
1888mta_report_protocol_server(struct mta_session *s, const char *response)
1889{
1890	if (! SESSION_FILTERED(s))
1891		return;
1892
1893	report_smtp_protocol_server("smtp-out", s->id, response);
1894}
1895
1896#if 0
1897static void
1898mta_report_filter_response(struct mta_session *s, int phase, int response, const char *param)
1899{
1900	if (! SESSION_FILTERED(s))
1901		return;
1902
1903	report_smtp_filter_response("smtp-out", s->id, phase, response, param);
1904}
1905#endif
1906
1907static void
1908mta_report_timeout(struct mta_session *s)
1909{
1910	if (! SESSION_FILTERED(s))
1911		return;
1912
1913	report_smtp_timeout("smtp-out", s->id);
1914}
1915