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