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