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