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