xref: /openbsd/usr.sbin/smtpd/smtp_session.c (revision 264ca280)
1 /*	$OpenBSD: smtp_session.c,v 1.285 2016/07/29 08:53:07 giovanni Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
5  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6  * Copyright (c) 2008-2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
7  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/tree.h>
25 #include <sys/socket.h>
26 #include <sys/uio.h>
27 
28 #include <netinet/in.h>
29 
30 #include <ctype.h>
31 #include <errno.h>
32 #include <event.h>
33 #include <imsg.h>
34 #include <limits.h>
35 #include <inttypes.h>
36 #include <openssl/ssl.h>
37 #include <resolv.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <vis.h>
43 
44 #include "smtpd.h"
45 #include "log.h"
46 #include "ssl.h"
47 
48 #define	DATA_HIWAT			65535
49 #define	APPEND_DOMAIN_BUFFER_SIZE	4096
50 
51 enum smtp_phase {
52 	PHASE_INIT = 0,
53 	PHASE_SETUP,
54 	PHASE_TRANSACTION
55 };
56 
57 enum smtp_state {
58 	STATE_NEW = 0,
59 	STATE_CONNECTED,
60 	STATE_TLS,
61 	STATE_HELO,
62 	STATE_AUTH_INIT,
63 	STATE_AUTH_USERNAME,
64 	STATE_AUTH_PASSWORD,
65 	STATE_AUTH_FINALIZE,
66 	STATE_BODY,
67 	STATE_QUIT,
68 };
69 
70 enum session_flags {
71 	SF_EHLO			= 0x0001,
72 	SF_8BITMIME		= 0x0002,
73 	SF_SECURE		= 0x0004,
74 	SF_AUTHENTICATED	= 0x0008,
75 	SF_BOUNCE		= 0x0010,
76 	SF_VERIFIED		= 0x0020,
77 	SF_BADINPUT		= 0x0080,
78 	SF_FILTERCONN		= 0x0100,
79 	SF_FILTERDATA		= 0x0200,
80 	SF_FILTERTX		= 0x0400,
81 };
82 
83 enum message_flags {
84 	MF_QUEUE_ENVELOPE_FAIL	= 0x00001,
85 	MF_ERROR_SIZE		= 0x01000,
86 	MF_ERROR_IO		= 0x02000,
87 	MF_ERROR_LOOP		= 0x04000,
88 	MF_ERROR_MALFORMED     	= 0x08000,
89 	MF_ERROR_RESOURCES     	= 0x10000,
90 };
91 #define MF_ERROR	(MF_ERROR_SIZE | MF_ERROR_IO | MF_ERROR_LOOP | MF_ERROR_MALFORMED | MF_ERROR_RESOURCES)
92 
93 enum smtp_command {
94 	CMD_HELO = 0,
95 	CMD_EHLO,
96 	CMD_STARTTLS,
97 	CMD_AUTH,
98 	CMD_MAIL_FROM,
99 	CMD_RCPT_TO,
100 	CMD_DATA,
101 	CMD_RSET,
102 	CMD_QUIT,
103 	CMD_HELP,
104 	CMD_WIZ,
105 	CMD_NOOP,
106 };
107 
108 struct smtp_rcpt {
109 	TAILQ_ENTRY(smtp_rcpt)	 entry;
110  	struct mailaddr		 maddr;
111 	size_t			 destcount;
112 };
113 
114 struct smtp_tx {
115 	struct smtp_session	*session;
116 	uint32_t		 msgid;
117 
118 	struct envelope		 evp;
119 	size_t			 rcptcount;
120 	size_t			 destcount;
121 	TAILQ_HEAD(, smtp_rcpt)	 rcpts;
122 
123 	size_t			 datain;
124 	size_t			 odatalen;
125 	struct iobuf		 obuf;
126 	struct io		 oev;
127 	int			 hdrdone;
128 	int			 rcvcount;
129 	int			 dataeom;
130 
131 	int			 msgflags;
132 	int			 msgcode;
133 
134 	int			 skiphdr;
135 	struct rfc2822_parser	 rfc2822_parser;
136 };
137 
138 struct smtp_session {
139 	uint64_t		 id;
140 	struct iobuf		 iobuf;
141 	struct io		 io;
142 	struct listener		*listener;
143 	void			*ssl_ctx;
144 	struct sockaddr_storage	 ss;
145 	char			 hostname[HOST_NAME_MAX+1];
146 	char			 smtpname[HOST_NAME_MAX+1];
147 
148 	int			 flags;
149 	int			 phase;
150 	enum smtp_state		 state;
151 
152 	char			 helo[LINE_MAX];
153 	char			 cmd[LINE_MAX];
154 	char			 username[SMTPD_MAXMAILADDRSIZE];
155 
156 	size_t			 mailcount;
157 	struct event		 pause;
158 
159 	struct smtp_tx		*tx;
160 };
161 
162 #define ADVERTISE_TLS(s) \
163 	((s)->listener->flags & F_STARTTLS && !((s)->flags & SF_SECURE))
164 
165 #define ADVERTISE_AUTH(s) \
166 	((s)->listener->flags & F_AUTH && (s)->flags & SF_SECURE && \
167 	 !((s)->flags & SF_AUTHENTICATED))
168 
169 #define ADVERTISE_EXT_DSN(s) \
170 	((s)->listener->flags & F_EXT_DSN)
171 
172 static int smtp_mailaddr(struct mailaddr *, char *, int, char **, const char *);
173 static void smtp_session_init(void);
174 static int smtp_lookup_servername(struct smtp_session *);
175 static void smtp_connected(struct smtp_session *);
176 static void smtp_send_banner(struct smtp_session *);
177 static void smtp_io(struct io *, int);
178 static void smtp_data_io(struct io *, int);
179 static void smtp_data_io_done(struct smtp_session *);
180 static void smtp_enter_state(struct smtp_session *, int);
181 static void smtp_reply(struct smtp_session *, char *, ...);
182 static void smtp_command(struct smtp_session *, char *);
183 static int smtp_parse_mail_args(struct smtp_session *, char *);
184 static int smtp_parse_rcpt_args(struct smtp_session *, char *);
185 static void smtp_rfc4954_auth_plain(struct smtp_session *, char *);
186 static void smtp_rfc4954_auth_login(struct smtp_session *, char *);
187 static void smtp_message_end(struct smtp_session *);
188 static int smtp_message_printf(struct smtp_session *, const char *, ...);
189 static void smtp_free(struct smtp_session *, const char *);
190 static const char *smtp_strstate(int);
191 static int smtp_verify_certificate(struct smtp_session *);
192 static uint8_t dsn_notify_str_to_uint8(const char *);
193 static void smtp_auth_failure_pause(struct smtp_session *);
194 static void smtp_auth_failure_resume(int, short, void *);
195 
196 static int  smtp_tx(struct smtp_session *);
197 static void smtp_tx_free(struct smtp_tx *);
198 
199 static void smtp_queue_create_message(struct smtp_session *);
200 static void smtp_queue_open_message(struct smtp_session *);
201 static void smtp_queue_commit(struct smtp_session *);
202 static void smtp_queue_rollback(struct smtp_session *);
203 
204 static void smtp_filter_connect(struct smtp_session *, struct sockaddr *);
205 static void smtp_filter_rset(struct smtp_session *);
206 static void smtp_filter_disconnect(struct smtp_session *);
207 static void smtp_filter_tx_begin(struct smtp_session *);
208 static void smtp_filter_tx_commit(struct smtp_session *);
209 static void smtp_filter_tx_rollback(struct smtp_session *);
210 static void smtp_filter_eom(struct smtp_session *);
211 static void smtp_filter_helo(struct smtp_session *);
212 static void smtp_filter_mail(struct smtp_session *);
213 static void smtp_filter_rcpt(struct smtp_session *);
214 static void smtp_filter_data(struct smtp_session *);
215 static void smtp_filter_dataline(struct smtp_session *, const char *);
216 
217 static struct { int code; const char *cmd; } commands[] = {
218 	{ CMD_HELO,		"HELO" },
219 	{ CMD_EHLO,		"EHLO" },
220 	{ CMD_STARTTLS,		"STARTTLS" },
221 	{ CMD_AUTH,		"AUTH" },
222 	{ CMD_MAIL_FROM,	"MAIL FROM" },
223 	{ CMD_RCPT_TO,		"RCPT TO" },
224 	{ CMD_DATA,		"DATA" },
225 	{ CMD_RSET,		"RSET" },
226 	{ CMD_QUIT,		"QUIT" },
227 	{ CMD_HELP,		"HELP" },
228 	{ CMD_WIZ,		"WIZ" },
229 	{ CMD_NOOP,		"NOOP" },
230 	{ -1, NULL },
231 };
232 
233 static struct tree wait_lka_ptr;
234 static struct tree wait_lka_helo;
235 static struct tree wait_lka_mail;
236 static struct tree wait_lka_rcpt;
237 static struct tree wait_filter;
238 static struct tree wait_filter_data;
239 static struct tree wait_parent_auth;
240 static struct tree wait_queue_msg;
241 static struct tree wait_queue_fd;
242 static struct tree wait_queue_commit;
243 static struct tree wait_ssl_init;
244 static struct tree wait_ssl_verify;
245 
246 static void
247 header_default_callback(const struct rfc2822_header *hdr, void *arg)
248 {
249 	struct smtp_session    *s = arg;
250 	struct rfc2822_line    *l;
251 
252 	if (smtp_message_printf(s, "%s:", hdr->name) == -1)
253 		return;
254 
255 	TAILQ_FOREACH(l, &hdr->lines, next)
256 		if (smtp_message_printf(s, "%s\n", l->buffer) == -1)
257 			return;
258 }
259 
260 static void
261 dataline_callback(const char *line, void *arg)
262 {
263 	struct smtp_session	*s = arg;
264 
265 	smtp_message_printf(s, "%s\n", line);
266 }
267 
268 static void
269 header_bcc_callback(const struct rfc2822_header *hdr, void *arg)
270 {
271 }
272 
273 static void
274 header_append_domain_buffer(char *buffer, char *domain, size_t len)
275 {
276 	size_t	i;
277 	int	escape, quote, comment, bracket;
278 	int	has_domain, has_bracket, has_group;
279 	int	pos_bracket, pos_component, pos_insert;
280 	char	copy[APPEND_DOMAIN_BUFFER_SIZE];
281 
282 	i = 0;
283 	escape = quote = comment = bracket = 0;
284 	has_domain = has_bracket = has_group = 0;
285 	pos_bracket = pos_insert = pos_component = 0;
286 	for (i = 0; buffer[i]; ++i) {
287 		if (buffer[i] == '(' && !escape && !quote)
288 			comment++;
289 		if (buffer[i] == '"' && !escape && !comment)
290 			quote = !quote;
291 		if (buffer[i] == ')' && !escape && !quote && comment)
292 			comment--;
293 		if (buffer[i] == '\\' && !escape && !comment && !quote)
294 			escape = 1;
295 		else
296 			escape = 0;
297 		if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) {
298 			bracket++;
299 			has_bracket = 1;
300 		}
301 		if (buffer[i] == '>' && !escape && !comment && !quote && bracket) {
302 			bracket--;
303 			pos_bracket = i;
304 		}
305 		if (buffer[i] == '@' && !escape && !comment && !quote)
306 			has_domain = 1;
307 		if (buffer[i] == ':' && !escape && !comment && !quote)
308 			has_group = 1;
309 
310 		/* update insert point if not in comment and not on a whitespace */
311 		if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i]))
312 			pos_component = i;
313 	}
314 
315 	/* parse error, do not attempt to modify */
316 	if (escape || quote || comment || bracket)
317 		return;
318 
319 	/* domain already present, no need to modify */
320 	if (has_domain)
321 		return;
322 
323 	/* address is group, skip */
324 	if (has_group)
325 		return;
326 
327 	/* there's an address between brackets, just append domain */
328 	if (has_bracket) {
329 		pos_bracket--;
330 		while (isspace((unsigned char)buffer[pos_bracket]))
331 			pos_bracket--;
332 		if (buffer[pos_bracket] == '<')
333 			return;
334 		pos_insert = pos_bracket + 1;
335 	}
336 	else {
337 		/* otherwise append address to last component */
338 		pos_insert = pos_component + 1;
339 
340 		/* empty address */
341                 if (buffer[pos_component] == '\0' ||
342 		    isspace((unsigned char)buffer[pos_component]))
343                         return;
344 	}
345 
346 	if (snprintf(copy, sizeof copy, "%.*s@%s%s",
347 		(int)pos_insert, buffer,
348 		domain,
349 		buffer+pos_insert) >= (int)sizeof copy)
350 		return;
351 
352 	memcpy(buffer, copy, len);
353 }
354 
355 static void
356 header_domain_append_callback(const struct rfc2822_header *hdr, void *arg)
357 {
358 	struct smtp_session    *s = arg;
359 	struct rfc2822_line    *l;
360 	size_t			i, j;
361 	int			escape, quote, comment, skip;
362 	char			buffer[APPEND_DOMAIN_BUFFER_SIZE];
363 
364 	if (smtp_message_printf(s, "%s:", hdr->name) == -1)
365 		return;
366 
367 	i = j = 0;
368 	escape = quote = comment = skip = 0;
369 	memset(buffer, 0, sizeof buffer);
370 
371 	TAILQ_FOREACH(l, &hdr->lines, next) {
372 		for (i = 0; i < strlen(l->buffer); ++i) {
373 			if (l->buffer[i] == '(' && !escape && !quote)
374 				comment++;
375 			if (l->buffer[i] == '"' && !escape && !comment)
376 				quote = !quote;
377 			if (l->buffer[i] == ')' && !escape && !quote && comment)
378 				comment--;
379 			if (l->buffer[i] == '\\' && !escape && !comment && !quote)
380 				escape = 1;
381 			else
382 				escape = 0;
383 
384 			/* found a separator, buffer contains a full address */
385 			if (l->buffer[i] == ',' && !escape && !quote && !comment) {
386 				if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer)
387 					header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
388 				if (smtp_message_printf(s, "%s,", buffer) == -1)
389 					return;
390 				j = 0;
391 				skip = 0;
392 				memset(buffer, 0, sizeof buffer);
393 			}
394 			else {
395 				if (skip) {
396 					if (smtp_message_printf(s, "%c",
397 					    l->buffer[i]) == -1)
398 						return;
399 				}
400 				else {
401 					buffer[j++] = l->buffer[i];
402 					if (j == sizeof (buffer) - 1) {
403 						if (smtp_message_printf(s, "%s",
404 						    buffer) != -1)
405 							return;
406 						skip = 1;
407 						j = 0;
408 						memset(buffer, 0, sizeof buffer);
409 					}
410 				}
411 			}
412 		}
413 		if (skip) {
414 			if (smtp_message_printf(s, "\n") == -1)
415 				return;
416 		}
417 		else {
418 			buffer[j++] = '\n';
419 			if (j == sizeof (buffer) - 1) {
420 				if (smtp_message_printf(s, "%s", buffer) == -1)
421 					return;
422 				skip = 1;
423 				j = 0;
424 				memset(buffer, 0, sizeof buffer);
425 			}
426 		}
427 	}
428 
429 	/* end of header, if buffer is not empty we'll process it */
430 	if (buffer[0]) {
431 		if (j + strlen(s->listener->hostname) + 1 < sizeof buffer)
432 			header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
433 		smtp_message_printf(s, "%s", buffer);
434 	}
435 }
436 
437 static void
438 header_address_rewrite_buffer(char *buffer, const char *address, size_t len)
439 {
440 	size_t	i;
441 	int	address_len;
442 	int	escape, quote, comment, bracket;
443 	int	has_bracket, has_group;
444 	int	pos_bracket_beg, pos_bracket_end, pos_component_beg, pos_component_end;
445 	int	insert_beg, insert_end;
446 	char	copy[APPEND_DOMAIN_BUFFER_SIZE];
447 
448 	escape = quote = comment = bracket = 0;
449 	has_bracket = has_group = 0;
450 	pos_bracket_beg = pos_bracket_end = pos_component_beg = pos_component_end = 0;
451 	for (i = 0; buffer[i]; ++i) {
452 		if (buffer[i] == '(' && !escape && !quote)
453 			comment++;
454 		if (buffer[i] == '"' && !escape && !comment)
455 			quote = !quote;
456 		if (buffer[i] == ')' && !escape && !quote && comment)
457 			comment--;
458 		if (buffer[i] == '\\' && !escape && !comment && !quote)
459 			escape = 1;
460 		else
461 			escape = 0;
462 		if (buffer[i] == '<' && !escape && !comment && !quote && !bracket) {
463 			bracket++;
464 			has_bracket = 1;
465 			pos_bracket_beg = i+1;
466 		}
467 		if (buffer[i] == '>' && !escape && !comment && !quote && bracket) {
468 			bracket--;
469 			pos_bracket_end = i;
470 		}
471 		if (buffer[i] == ':' && !escape && !comment && !quote)
472 			has_group = 1;
473 
474 		/* update insert point if not in comment and not on a whitespace */
475 		if (!comment && buffer[i] != ')' && !isspace((unsigned char)buffer[i]))
476 			pos_component_end = i;
477 	}
478 
479 	/* parse error, do not attempt to modify */
480 	if (escape || quote || comment || bracket)
481 		return;
482 
483 	/* address is group, skip */
484 	if (has_group)
485 		return;
486 
487 	/* there's an address between brackets, just replace everything brackets */
488 	if (has_bracket) {
489 		insert_beg = pos_bracket_beg;
490 		insert_end = pos_bracket_end;
491 	}
492 	else {
493 		if (pos_component_end == 0)
494 			pos_component_beg = 0;
495 		else {
496 			for (pos_component_beg = pos_component_end; pos_component_beg >= 0; --pos_component_beg)
497 				if (buffer[pos_component_beg] == ')' || isspace(buffer[pos_component_beg]))
498 					break;
499 			pos_component_beg += 1;
500 			pos_component_end += 1;
501 		}
502 		insert_beg = pos_component_beg;
503 		insert_end = pos_component_end;
504 	}
505 
506 	/* check that masquerade won' t overflow */
507 	address_len = strlen(address);
508 	if (strlen(buffer) - (insert_end - insert_beg) + address_len >= len)
509 		return;
510 
511 	(void)strlcpy(copy, buffer, sizeof copy);
512 	(void)strlcpy(copy+insert_beg, address, sizeof (copy) - insert_beg);
513 	(void)strlcat(copy, buffer+insert_end, sizeof (copy));
514 	memcpy(buffer, copy, len);
515 }
516 
517 static void
518 header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
519 {
520 	struct smtp_session    *s = arg;
521 	struct rfc2822_line    *l;
522 	size_t			i, j;
523 	int			escape, quote, comment, skip;
524 	char			buffer[APPEND_DOMAIN_BUFFER_SIZE];
525 
526 	if (smtp_message_printf(s, "%s:", hdr->name) == -1)
527 		return;
528 
529 	j = 0;
530 	escape = quote = comment = skip = 0;
531 	memset(buffer, 0, sizeof buffer);
532 
533 	TAILQ_FOREACH(l, &hdr->lines, next) {
534 		for (i = 0; i < strlen(l->buffer); ++i) {
535 			if (l->buffer[i] == '(' && !escape && !quote)
536 				comment++;
537 			if (l->buffer[i] == '"' && !escape && !comment)
538 				quote = !quote;
539 			if (l->buffer[i] == ')' && !escape && !quote && comment)
540 				comment--;
541 			if (l->buffer[i] == '\\' && !escape && !comment && !quote)
542 				escape = 1;
543 			else
544 				escape = 0;
545 
546 			/* found a separator, buffer contains a full address */
547 			if (l->buffer[i] == ',' && !escape && !quote && !comment) {
548 				if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer) {
549 					header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
550 					header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender),
551 					    sizeof buffer);
552 				}
553 				if (smtp_message_printf(s, "%s,", buffer) == -1)
554 					return;
555 				j = 0;
556 				skip = 0;
557 				memset(buffer, 0, sizeof buffer);
558 			}
559 			else {
560 				if (skip) {
561 					if (smtp_message_printf(s, "%c", l->buffer[i]) == -1)
562 						return;
563 				}
564 				else {
565 					buffer[j++] = l->buffer[i];
566 					if (j == sizeof (buffer) - 1) {
567 						if (smtp_message_printf(s, "%s", buffer) == -1)
568 							return;
569 						skip = 1;
570 						j = 0;
571 						memset(buffer, 0, sizeof buffer);
572 					}
573 				}
574 			}
575 		}
576 		if (skip) {
577 			if (smtp_message_printf(s, "\n") == -1)
578 				return;
579 		}
580 		else {
581 			buffer[j++] = '\n';
582 			if (j == sizeof (buffer) - 1) {
583 				if (smtp_message_printf(s, "%s", buffer) == -1)
584 					return;
585 				skip = 1;
586 				j = 0;
587 				memset(buffer, 0, sizeof buffer);
588 			}
589 		}
590 	}
591 
592 	/* end of header, if buffer is not empty we'll process it */
593 	if (buffer[0]) {
594 		if (j + strlen(s->listener->hostname) + 1 < sizeof buffer) {
595 			header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
596 			header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender),
597 			    sizeof buffer);
598 		}
599 		smtp_message_printf(s, "%s", buffer);
600 	}
601 }
602 
603 static void
604 header_missing_callback(const char *header, void *arg)
605 {
606 	struct smtp_session	*s = arg;
607 
608 	if (strcasecmp(header, "message-id") == 0)
609 		smtp_message_printf(s, "Message-Id: <%016"PRIx64"@%s>\n",
610 		    generate_uid(), s->listener->hostname);
611 
612 	if (strcasecmp(header, "date") == 0)
613 		smtp_message_printf(s, "Date: %s\n", time_to_text(time(NULL)));
614 }
615 
616 static void
617 smtp_session_init(void)
618 {
619 	static int	init = 0;
620 
621 	if (!init) {
622 		tree_init(&wait_lka_ptr);
623 		tree_init(&wait_lka_helo);
624 		tree_init(&wait_lka_mail);
625 		tree_init(&wait_lka_rcpt);
626 		tree_init(&wait_filter);
627 		tree_init(&wait_filter_data);
628 		tree_init(&wait_parent_auth);
629 		tree_init(&wait_queue_msg);
630 		tree_init(&wait_queue_fd);
631 		tree_init(&wait_queue_commit);
632 		tree_init(&wait_ssl_init);
633 		tree_init(&wait_ssl_verify);
634 		init = 1;
635 	}
636 }
637 
638 int
639 smtp_session(struct listener *listener, int sock,
640     const struct sockaddr_storage *ss, const char *hostname)
641 {
642 	struct smtp_session	*s;
643 
644 	log_debug("debug: smtp: new client on listener: %p", listener);
645 
646 	smtp_session_init();
647 
648 	if ((s = calloc(1, sizeof(*s))) == NULL)
649 		return (-1);
650 
651 	if (iobuf_init(&s->iobuf, LINE_MAX, LINE_MAX) == -1) {
652 		free(s);
653 		return (-1);
654 	}
655 
656 	s->id = generate_uid();
657 	s->listener = listener;
658 	memmove(&s->ss, ss, sizeof(*ss));
659 	io_init(&s->io, sock, s, smtp_io, &s->iobuf);
660 	io_set_timeout(&s->io, SMTPD_SESSION_TIMEOUT * 1000);
661 	io_set_write(&s->io);
662 
663 	s->state = STATE_NEW;
664 	s->phase = PHASE_INIT;
665 
666 	(void)strlcpy(s->smtpname, listener->hostname, sizeof(s->smtpname));
667 
668 	log_trace(TRACE_SMTP, "smtp: %p: connected to listener %p "
669 	    "[hostname=%s, port=%d, tag=%s]", s, listener,
670 	    listener->hostname, ntohs(listener->port), listener->tag);
671 
672 	/* For local enqueueing, the hostname is already set */
673 	if (hostname) {
674 		s->flags |= SF_AUTHENTICATED;
675 		/* A bit of a hack */
676 		if (!strcmp(hostname, "localhost"))
677 			s->flags |= SF_BOUNCE;
678 		(void)strlcpy(s->hostname, hostname, sizeof(s->hostname));
679 		if (smtp_lookup_servername(s))
680 			smtp_connected(s);
681 	} else {
682 		m_create(p_lka,  IMSG_SMTP_DNS_PTR, 0, 0, -1);
683 		m_add_id(p_lka, s->id);
684 		m_add_sockaddr(p_lka, (struct sockaddr *)&s->ss);
685 		m_close(p_lka);
686 		tree_xset(&wait_lka_ptr, s->id, s);
687 	}
688 
689 	/* session may have been freed by now */
690 
691 	return (0);
692 }
693 
694 void
695 smtp_session_imsg(struct mproc *p, struct imsg *imsg)
696 {
697 	struct ca_cert_resp_msg       	*resp_ca_cert;
698 	struct ca_vrfy_resp_msg       	*resp_ca_vrfy;
699 	struct smtp_session		*s;
700 	struct smtp_rcpt		*rcpt;
701 	void				*ssl;
702 	char				 user[LOGIN_NAME_MAX];
703 	struct msg			 m;
704 	const char			*line, *helo;
705 	uint64_t			 reqid, evpid;
706 	uint32_t			 msgid;
707 	int				 status, success, dnserror;
708 	void				*ssl_ctx;
709 
710 	switch (imsg->hdr.type) {
711 	case IMSG_SMTP_DNS_PTR:
712 		m_msg(&m, imsg);
713 		m_get_id(&m, &reqid);
714 		m_get_int(&m, &dnserror);
715 		if (dnserror)
716 			line = "<unknown>";
717 		else
718 			m_get_string(&m, &line);
719 		m_end(&m);
720 		s = tree_xpop(&wait_lka_ptr, reqid);
721 		(void)strlcpy(s->hostname, line, sizeof s->hostname);
722 		if (smtp_lookup_servername(s))
723 			smtp_connected(s);
724 		return;
725 
726 	case IMSG_SMTP_CHECK_SENDER:
727 		m_msg(&m, imsg);
728 		m_get_id(&m, &reqid);
729 		m_get_int(&m, &status);
730 		m_end(&m);
731 		s = tree_xpop(&wait_lka_mail, reqid);
732 		switch (status) {
733 		case LKA_OK:
734 			smtp_queue_create_message(s);
735 
736 			/* sender check passed, override From callback if masquerading */
737 			if (s->listener->flags & F_MASQUERADE)
738 				rfc2822_header_callback(&s->tx->rfc2822_parser, "from",
739 				    header_masquerade_callback, s);
740 			break;
741 
742 		case LKA_PERMFAIL:
743 			smtp_filter_tx_rollback(s);
744 			smtp_tx_free(s->tx);
745 			smtp_reply(s, "%d %s", 530, "Sender rejected");
746 			io_reload(&s->io);
747 			break;
748 		case LKA_TEMPFAIL:
749 			smtp_filter_tx_rollback(s);
750 			smtp_tx_free(s->tx);
751 			smtp_reply(s, "421 %s: Temporary Error",
752 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
753 			io_reload(&s->io);
754 			break;
755 		}
756 		return;
757 
758 	case IMSG_SMTP_EXPAND_RCPT:
759 		m_msg(&m, imsg);
760 		m_get_id(&m, &reqid);
761 		m_get_int(&m, &status);
762 		m_get_string(&m, &line);
763 		m_end(&m);
764 		s = tree_xpop(&wait_lka_rcpt, reqid);
765 		switch (status) {
766 		case LKA_OK:
767 			fatalx("unexpected ok");
768 		case LKA_PERMFAIL:
769 			smtp_reply(s, "%s", line);
770 			break;
771 		case LKA_TEMPFAIL:
772 			smtp_reply(s, "%s", line);
773 		}
774 		io_reload(&s->io);
775 		return;
776 
777 	case IMSG_SMTP_LOOKUP_HELO:
778 		m_msg(&m, imsg);
779 		m_get_id(&m, &reqid);
780 		s = tree_xpop(&wait_lka_helo, reqid);
781 		m_get_int(&m, &status);
782 		if (status == LKA_OK) {
783 			m_get_string(&m, &helo);
784 			(void)strlcpy(s->smtpname, helo, sizeof(s->smtpname));
785 		}
786 		m_end(&m);
787 		smtp_connected(s);
788 		return;
789 
790 	case IMSG_SMTP_MESSAGE_CREATE:
791 		m_msg(&m, imsg);
792 		m_get_id(&m, &reqid);
793 		m_get_int(&m, &success);
794 		s = tree_xpop(&wait_queue_msg, reqid);
795 		if (success) {
796 			m_get_msgid(&m, &msgid);
797 			s->tx->msgid = msgid;
798 			s->tx->evp.id = msgid_to_evpid(msgid);
799 			s->tx->rcptcount = 0;
800 			s->phase = PHASE_TRANSACTION;
801 			smtp_reply(s, "250 %s: Ok",
802 			    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
803 		} else {
804 			smtp_filter_tx_rollback(s);
805 			smtp_tx_free(s->tx);
806 			smtp_reply(s, "421 %s: Temporary Error",
807 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
808 			smtp_enter_state(s, STATE_QUIT);
809 		}
810 		m_end(&m);
811 		io_reload(&s->io);
812 		return;
813 
814 	case IMSG_SMTP_MESSAGE_OPEN:
815 		m_msg(&m, imsg);
816 		m_get_id(&m, &reqid);
817 		m_get_int(&m, &success);
818 		m_end(&m);
819 
820 		s = tree_xpop(&wait_queue_fd, reqid);
821 		if (!success || imsg->fd == -1) {
822 			if (imsg->fd != -1)
823 				close(imsg->fd);
824 			smtp_reply(s, "421 %s: Temporary Error",
825 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
826 			smtp_enter_state(s, STATE_QUIT);
827 			io_reload(&s->io);
828 			return;
829 		}
830 
831 		log_debug("smtp: %p: fd %d from queue", s, imsg->fd);
832 
833 		tree_xset(&wait_filter, s->id, s);
834 		filter_build_fd_chain(s->id, imsg->fd);
835 		return;
836 
837 	case IMSG_QUEUE_ENVELOPE_SUBMIT:
838 		m_msg(&m, imsg);
839 		m_get_id(&m, &reqid);
840 		m_get_int(&m, &success);
841 		s = tree_xget(&wait_lka_rcpt, reqid);
842 		if (success) {
843 			m_get_evpid(&m, &evpid);
844 			s->tx->destcount++;
845 		}
846 		else
847 			s->tx->msgflags |= MF_QUEUE_ENVELOPE_FAIL;
848 		m_end(&m);
849 		return;
850 
851 	case IMSG_QUEUE_ENVELOPE_COMMIT:
852 		m_msg(&m, imsg);
853 		m_get_id(&m, &reqid);
854 		m_get_int(&m, &success);
855 		m_end(&m);
856 		if (!success)
857 			fatalx("commit evp failed: not supposed to happen");
858 		s = tree_xpop(&wait_lka_rcpt, reqid);
859 		if (s->tx->msgflags & MF_QUEUE_ENVELOPE_FAIL) {
860 			/*
861 			 * If an envelope failed, we can't cancel the last
862 			 * RCPT only so we must cancel the whole transaction
863 			 * and close the connection.
864 			 */
865 			smtp_reply(s, "421 %s: Temporary failure",
866 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
867 			smtp_enter_state(s, STATE_QUIT);
868 		}
869 		else {
870 			rcpt = xcalloc(1, sizeof(*rcpt), "smtp_rcpt");
871 			rcpt->destcount = s->tx->destcount;
872 			rcpt->maddr = s->tx->evp.rcpt;
873 			TAILQ_INSERT_TAIL(&s->tx->rcpts, rcpt, entry);
874 
875 			s->tx->destcount = 0;
876 			s->tx->rcptcount++;
877 			smtp_reply(s, "250 %s %s: Recipient ok",
878 			    esc_code(ESC_STATUS_OK, ESC_DESTINATION_ADDRESS_VALID),
879 			    esc_description(ESC_DESTINATION_ADDRESS_VALID));
880 		}
881 		io_reload(&s->io);
882 		return;
883 
884 	case IMSG_SMTP_MESSAGE_COMMIT:
885 		m_msg(&m, imsg);
886 		m_get_id(&m, &reqid);
887 		m_get_int(&m, &success);
888 		m_end(&m);
889 		s = tree_xpop(&wait_queue_commit, reqid);
890 		if (!success) {
891 			smtp_filter_tx_rollback(s);
892 			smtp_tx_free(s->tx);
893 			smtp_reply(s, "421 %s: Temporary failure",
894 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
895 			smtp_enter_state(s, STATE_QUIT);
896 			io_reload(&s->io);
897 			return;
898 		}
899 
900 		smtp_filter_tx_commit(s);
901 		smtp_reply(s, "250 %s: %08x Message accepted for delivery",
902 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS),
903 		    s->tx->msgid);
904 
905 		TAILQ_FOREACH(rcpt, &s->tx->rcpts, entry) {
906 			log_info("%016"PRIx64" smtp event=message msgid=%08x "
907 			    "from=<%s%s%s> to=<%s%s%s> size=%zu ndest=%zu proto=%s",
908 			    s->id,
909 			    s->tx->msgid,
910 			    s->tx->evp.sender.user,
911 			    s->tx->evp.sender.user[0] == '\0' ? "" : "@",
912 			    s->tx->evp.sender.domain,
913 			    rcpt->maddr.user,
914 			    rcpt->maddr.user[0] == '\0' ? "" : "@",
915 			    rcpt->maddr.domain,
916 			    s->tx->odatalen,
917 			    rcpt->destcount,
918 			    s->flags & SF_EHLO ? "ESMTP" : "SMTP");
919 		}
920 		smtp_tx_free(s->tx);
921 		s->mailcount++;
922 		s->phase = PHASE_SETUP;
923 		smtp_enter_state(s, STATE_HELO);
924 		io_reload(&s->io);
925 		return;
926 
927 	case IMSG_SMTP_AUTHENTICATE:
928 		m_msg(&m, imsg);
929 		m_get_id(&m, &reqid);
930 		m_get_int(&m, &success);
931 		m_end(&m);
932 
933 		s = tree_xpop(&wait_parent_auth, reqid);
934 		strnvis(user, s->username, sizeof user, VIS_WHITE | VIS_SAFE);
935 		if (success == LKA_OK) {
936 			log_info("%016"PRIx64" smtp "
937 			    "event=authentication user=%s address=%s "
938 			    "host=%s result=ok",
939 			    s->id, user, ss_to_text(&s->ss), s->hostname);
940 			s->flags |= SF_AUTHENTICATED;
941 			smtp_reply(s, "235 %s: Authentication succeeded",
942 			    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
943 		}
944 		else if (success == LKA_PERMFAIL) {
945 			log_info("%016"PRIx64" smtp "
946 			    "event=authentication user=%s address=%s "
947 			    "host=%s result=permfail",
948 			    s->id, user, ss_to_text(&s->ss), s->hostname);
949 			smtp_auth_failure_pause(s);
950 			return;
951 		}
952 		else if (success == LKA_TEMPFAIL) {
953 			log_info("%016"PRIx64" smtp "
954 			    "event=authentication user=%s address=%s "
955 			    "host=%s result=tempfail",
956 			    s->id, user, ss_to_text(&s->ss), s->hostname);
957 			smtp_reply(s, "421 %s: Temporary failure",
958 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
959 		}
960 		else
961 			fatalx("bad lka response");
962 
963 		smtp_enter_state(s, STATE_HELO);
964 		io_reload(&s->io);
965 		return;
966 
967 	case IMSG_SMTP_TLS_INIT:
968 		resp_ca_cert = imsg->data;
969 		s = tree_xpop(&wait_ssl_init, resp_ca_cert->reqid);
970 
971 		if (resp_ca_cert->status == CA_FAIL) {
972 			log_info("%016"PRIx64" smtp event=closed reason=ca-failure",
973 			    s->id);
974 			smtp_free(s, "CA failure");
975 			return;
976 		}
977 
978 		resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "smtp:ca_cert");
979 		resp_ca_cert->cert = xstrdup((char *)imsg->data +
980 		    sizeof *resp_ca_cert, "smtp:ca_cert");
981 		ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name);
982 		ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY);
983 		io_set_read(&s->io);
984 		io_start_tls(&s->io, ssl);
985 
986 		explicit_bzero(resp_ca_cert->cert, resp_ca_cert->cert_len);
987 		free(resp_ca_cert->cert);
988 		free(resp_ca_cert);
989 		return;
990 
991 	case IMSG_SMTP_TLS_VERIFY:
992 		resp_ca_vrfy = imsg->data;
993 		s = tree_xpop(&wait_ssl_verify, resp_ca_vrfy->reqid);
994 
995 		if (resp_ca_vrfy->status == CA_OK)
996 			s->flags |= SF_VERIFIED;
997 		else if (s->listener->flags & F_TLS_VERIFY) {
998 			log_info("%016"PRIx64" smtp "
999 			    "event=closed reason=cert-check-failed",
1000 			    s->id);
1001 			smtp_free(s, "SSL certificate check failed");
1002 			return;
1003 		}
1004 		smtp_io(&s->io, IO_TLSVERIFIED);
1005 		io_resume(&s->io, IO_PAUSE_IN);
1006 		return;
1007 	}
1008 
1009 	log_warnx("smtp_session_imsg: unexpected %s imsg",
1010 	    imsg_to_str(imsg->hdr.type));
1011 	fatalx(NULL);
1012 }
1013 
1014 void
1015 smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
1016     const char *line)
1017 {
1018 	struct smtp_session	*s;
1019 	struct ca_cert_req_msg	 req_ca_cert;
1020 
1021 	s = tree_xpop(&wait_filter, id);
1022 
1023 	if (status == FILTER_CLOSE) {
1024 		code = code ? code : 421;
1025 		line = line ? line : "Temporary failure";
1026 		smtp_reply(s, "%d %s", code, line);
1027 		smtp_enter_state(s, STATE_QUIT);
1028 		io_reload(&s->io);
1029 		return;
1030 	}
1031 
1032 	switch (query) {
1033 
1034 	case QUERY_CONNECT:
1035 		if (status != FILTER_OK) {
1036 			log_info("%016"PRIx64" smtp "
1037 			    "event=closed reason=filter-reject",
1038 			    s->id);
1039 			smtp_free(s, "rejected by filter");
1040 			return;
1041 		}
1042 
1043 		if (s->listener->flags & F_SMTPS) {
1044 			req_ca_cert.reqid = s->id;
1045 			if (s->listener->pki_name[0]) {
1046 				(void)strlcpy(req_ca_cert.name, s->listener->pki_name,
1047 				    sizeof req_ca_cert.name);
1048 				req_ca_cert.fallback = 0;
1049 			}
1050 			else {
1051 				(void)strlcpy(req_ca_cert.name, s->smtpname,
1052 				    sizeof req_ca_cert.name);
1053 				req_ca_cert.fallback = 1;
1054 			}
1055 			m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1,
1056 			    &req_ca_cert, sizeof(req_ca_cert));
1057 			tree_xset(&wait_ssl_init, s->id, s);
1058 			return;
1059 		}
1060 		smtp_send_banner(s);
1061 		return;
1062 
1063 	case QUERY_HELO:
1064 		if (status != FILTER_OK) {
1065 			code = code ? code : 530;
1066 			line = line ? line : "Hello rejected";
1067 			smtp_reply(s, "%d %s", code, line);
1068 			io_reload(&s->io);
1069 			return;
1070 		}
1071 
1072 		smtp_enter_state(s, STATE_HELO);
1073 		smtp_reply(s, "250%c%s Hello %s [%s], pleased to meet you",
1074 		    (s->flags & SF_EHLO) ? '-' : ' ',
1075 		    s->smtpname,
1076 		    s->helo,
1077 		    ss_to_text(&s->ss));
1078 
1079 		if (s->flags & SF_EHLO) {
1080 			smtp_reply(s, "250-8BITMIME");
1081 			smtp_reply(s, "250-ENHANCEDSTATUSCODES");
1082 			smtp_reply(s, "250-SIZE %zu", env->sc_maxsize);
1083 			if (ADVERTISE_EXT_DSN(s))
1084 				smtp_reply(s, "250-DSN");
1085 			if (ADVERTISE_TLS(s))
1086 				smtp_reply(s, "250-STARTTLS");
1087 			if (ADVERTISE_AUTH(s))
1088 				smtp_reply(s, "250-AUTH PLAIN LOGIN");
1089 			smtp_reply(s, "250 HELP");
1090 		}
1091 		s->phase = PHASE_SETUP;
1092 		io_reload(&s->io);
1093 		return;
1094 
1095 	case QUERY_MAIL:
1096 		if (status != FILTER_OK) {
1097 			smtp_filter_tx_rollback(s);
1098 			smtp_tx_free(s->tx);
1099 			code = code ? code : 530;
1100 			line = line ? line : "Sender rejected";
1101 			smtp_reply(s, "%d %s", code, line);
1102 			io_reload(&s->io);
1103 			return;
1104 		}
1105 
1106 		/* only check sendertable if defined and user has authenticated */
1107 		if (s->flags & SF_AUTHENTICATED && s->listener->sendertable[0]) {
1108 			m_create(p_lka, IMSG_SMTP_CHECK_SENDER, 0, 0, -1);
1109 			m_add_id(p_lka, s->id);
1110 			m_add_string(p_lka, s->listener->sendertable);
1111 			m_add_string(p_lka, s->username);
1112 			m_add_mailaddr(p_lka, &s->tx->evp.sender);
1113 			m_close(p_lka);
1114 			tree_xset(&wait_lka_mail, s->id, s);
1115 		}
1116 		else
1117 			smtp_queue_create_message(s);
1118 		return;
1119 
1120 	case QUERY_RCPT:
1121 		if (status != FILTER_OK) {
1122 			code = code ? code : 530;
1123 			line = line ? line : "Recipient rejected";
1124 			smtp_reply(s, "%d %s", code, line);
1125 			io_reload(&s->io);
1126 			return;
1127 		}
1128 
1129 		m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1);
1130 		m_add_id(p_lka, s->id);
1131 		m_add_envelope(p_lka, &s->tx->evp);
1132 		m_close(p_lka);
1133 		tree_xset(&wait_lka_rcpt, s->id, s);
1134 		return;
1135 
1136 	case QUERY_DATA:
1137 		if (status != FILTER_OK) {
1138 			code = code ? code : 530;
1139 			line = line ? line : "Message rejected";
1140 			smtp_reply(s, "%d %s", code, line);
1141 			io_reload(&s->io);
1142 			return;
1143 		}
1144 		smtp_queue_open_message(s);
1145 		return;
1146 
1147 	case QUERY_EOM:
1148 		if (status != FILTER_OK) {
1149 			tree_pop(&wait_filter_data, s->id);
1150 			smtp_filter_tx_rollback(s);
1151 			smtp_queue_rollback(s);
1152 			smtp_tx_free(s->tx);
1153 			code = code ? code : 530;
1154 			line = line ? line : "Message rejected";
1155 			smtp_reply(s, "%d %s", code, line);
1156 			smtp_enter_state(s, STATE_HELO);
1157 			io_reload(&s->io);
1158 			return;
1159 		}
1160 		smtp_message_end(s);
1161 		return;
1162 
1163 	default:
1164 		log_warn("smtp: bad mfa query type %d", query);
1165 	}
1166 }
1167 
1168 void
1169 smtp_filter_fd(uint64_t id, int fd)
1170 {
1171 	struct smtp_session	*s;
1172 	X509			*x;
1173 
1174 	s = tree_xpop(&wait_filter, id);
1175 
1176 	log_debug("smtp: %p: fd %d from filter", s, fd);
1177 
1178 	if (fd == -1) {
1179 		smtp_reply(s, "421 %s: Temporary Error",
1180 		    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1181 		smtp_enter_state(s, STATE_QUIT);
1182 		io_reload(&s->io);
1183 		return;
1184 	}
1185 
1186 	iobuf_init(&s->tx->obuf, 0, 0);
1187 	io_set_nonblocking(fd);
1188 	io_init(&s->tx->oev, fd, s, smtp_data_io, &s->tx->obuf);
1189 
1190 	iobuf_fqueue(&s->tx->obuf, "Received: ");
1191 	if (!(s->listener->flags & F_MASK_SOURCE)) {
1192 		iobuf_fqueue(&s->tx->obuf, "from %s (%s [%s])",
1193 		    s->helo,
1194 		    s->hostname,
1195 		    ss_to_text(&s->ss));
1196 	}
1197 	iobuf_fqueue(&s->tx->obuf, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
1198 	    s->smtpname,
1199 	    SMTPD_NAME,
1200 	    s->flags & SF_EHLO ? "E" : "",
1201 	    s->flags & SF_SECURE ? "S" : "",
1202 	    s->flags & SF_AUTHENTICATED ? "A" : "",
1203 	    s->tx->msgid);
1204 
1205 	if (s->flags & SF_SECURE) {
1206 		x = SSL_get_peer_certificate(s->io.ssl);
1207 		iobuf_fqueue(&s->tx->obuf,
1208 		    " (%s:%s:%d:%s)",
1209 		    SSL_get_version(s->io.ssl),
1210 		    SSL_get_cipher_name(s->io.ssl),
1211 		    SSL_get_cipher_bits(s->io.ssl, NULL),
1212 		    (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO"));
1213 		if (x)
1214 			X509_free(x);
1215 
1216 		if (s->listener->flags & F_RECEIVEDAUTH) {
1217 			iobuf_fqueue(&s->tx->obuf, " auth=%s", s->username[0] ? "yes" : "no");
1218 			if (s->username[0])
1219 				iobuf_fqueue(&s->tx->obuf, " user=%s", s->username);
1220 		}
1221 	}
1222 
1223 	if (s->tx->rcptcount == 1) {
1224 		iobuf_fqueue(&s->tx->obuf, "\n\tfor <%s@%s>",
1225 		    s->tx->evp.rcpt.user,
1226 		    s->tx->evp.rcpt.domain);
1227 	}
1228 
1229 	iobuf_fqueue(&s->tx->obuf, ";\n\t%s\n", time_to_text(time(NULL)));
1230 
1231 	s->tx->odatalen = iobuf_queued(&s->tx->obuf);
1232 
1233 	io_set_write(&s->tx->oev);
1234 
1235 	smtp_enter_state(s, STATE_BODY);
1236 	smtp_reply(s, "354 Enter mail, end with \".\""
1237 	    " on a line by itself");
1238 
1239 	tree_xset(&wait_filter_data, s->id, s);
1240 	io_reload(&s->io);
1241 }
1242 
1243 static void
1244 smtp_io(struct io *io, int evt)
1245 {
1246 	struct ca_cert_req_msg	req_ca_cert;
1247 	struct smtp_session    *s = io->arg;
1248 	char		       *line;
1249 	size_t			len;
1250 	X509		       *x;
1251 
1252 	log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt),
1253 	    io_strio(io));
1254 
1255 	switch (evt) {
1256 
1257 	case IO_TLSREADY:
1258 		log_info("%016"PRIx64" smtp event=starttls ciphers=\"%s\"",
1259 		    s->id, ssl_to_text(s->io.ssl));
1260 
1261 		s->flags |= SF_SECURE;
1262 		s->phase = PHASE_INIT;
1263 
1264 		if (smtp_verify_certificate(s)) {
1265 			io_pause(&s->io, IO_PAUSE_IN);
1266 			break;
1267 		}
1268 
1269 		if (s->listener->flags & F_TLS_VERIFY) {
1270 			log_info("%016"PRIx64" smtp "
1271 			    "event=closed reason=no-client-cert",
1272 			    s->id);
1273 			smtp_free(s, "client did not present certificate");
1274 			return;
1275 		}
1276 
1277 		/* No verification required, cascade */
1278 
1279 	case IO_TLSVERIFIED:
1280 		x = SSL_get_peer_certificate(s->io.ssl);
1281 		if (x) {
1282 			log_info("%016"PRIx64" smtp "
1283 			    "event=client-cert-check result=\"%s\"",
1284 			    s->id,
1285 			    (s->flags & SF_VERIFIED) ? "success" : "failure");
1286 			X509_free(x);
1287 		}
1288 
1289 		if (s->listener->flags & F_SMTPS) {
1290 			stat_increment("smtp.smtps", 1);
1291 			io_set_write(&s->io);
1292 			smtp_send_banner(s);
1293 		}
1294 		else {
1295 			stat_increment("smtp.tls", 1);
1296 			smtp_enter_state(s, STATE_HELO);
1297 		}
1298 		break;
1299 
1300 	case IO_DATAIN:
1301 	    nextline:
1302 		line = iobuf_getline(&s->iobuf, &len);
1303 		if ((line == NULL && iobuf_len(&s->iobuf) >= LINE_MAX) ||
1304 		    (line && len >= LINE_MAX)) {
1305 			s->flags |= SF_BADINPUT;
1306 			smtp_reply(s, "500 %s: Line too long",
1307 			    esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS));
1308 			smtp_enter_state(s, STATE_QUIT);
1309 			io_set_write(io);
1310 			return;
1311 		}
1312 
1313 		/* No complete line received */
1314 		if (line == NULL) {
1315 			iobuf_normalize(&s->iobuf);
1316 			return;
1317 		}
1318 
1319 		/* Message body */
1320 		if (s->state == STATE_BODY && strcmp(line, ".")) {
1321 			smtp_filter_dataline(s, line);
1322 			goto nextline;
1323 		}
1324 
1325 		/* Pipelining not supported */
1326 		if (iobuf_len(&s->iobuf)) {
1327 			s->flags |= SF_BADINPUT;
1328 			smtp_reply(s, "500 %s %s: Pipelining not supported",
1329 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1330 			    esc_description(ESC_INVALID_COMMAND));
1331 			smtp_enter_state(s, STATE_QUIT);
1332 			io_set_write(io);
1333 			return;
1334 		}
1335 
1336 		/* End of body */
1337 		if (s->state == STATE_BODY) {
1338 			log_trace(TRACE_SMTP, "<<< [EOM]");
1339 
1340 			rfc2822_parser_flush(&s->tx->rfc2822_parser);
1341 
1342 			iobuf_normalize(&s->iobuf);
1343 			io_set_write(io);
1344 
1345 			s->tx->dataeom = 1;
1346 			if (iobuf_queued(&s->tx->obuf) == 0)
1347 				smtp_data_io_done(s);
1348 			return;
1349 		}
1350 
1351 		/* Must be a command */
1352 		(void)strlcpy(s->cmd, line, sizeof s->cmd);
1353 		io_set_write(io);
1354 		smtp_command(s, line);
1355 		iobuf_normalize(&s->iobuf);
1356 		break;
1357 
1358 	case IO_LOWAT:
1359 		if (s->state == STATE_QUIT) {
1360 			log_info("%016"PRIx64" smtp event=closed reason=quit",
1361 			    s->id);
1362 			smtp_free(s, "done");
1363 			break;
1364 		}
1365 
1366 		/* Wait for the client to start tls */
1367 		if (s->state == STATE_TLS) {
1368 			req_ca_cert.reqid = s->id;
1369 
1370 			if (s->listener->pki_name[0]) {
1371 				(void)strlcpy(req_ca_cert.name, s->listener->pki_name,
1372 				    sizeof req_ca_cert.name);
1373 				req_ca_cert.fallback = 0;
1374 			}
1375 			else {
1376 				(void)strlcpy(req_ca_cert.name, s->smtpname,
1377 				    sizeof req_ca_cert.name);
1378 				req_ca_cert.fallback = 1;
1379 			}
1380 			m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1,
1381 			    &req_ca_cert, sizeof(req_ca_cert));
1382 			tree_xset(&wait_ssl_init, s->id, s);
1383 			break;
1384 		}
1385 
1386 		io_set_read(io);
1387 		break;
1388 
1389 	case IO_TIMEOUT:
1390 		log_info("%016"PRIx64" smtp event=closed reason=timeout",
1391 		    s->id);
1392 		smtp_free(s, "timeout");
1393 		break;
1394 
1395 	case IO_DISCONNECTED:
1396 		log_info("%016"PRIx64" smtp event=closed reason=disconnect",
1397 		    s->id);
1398 		smtp_free(s, "disconnected");
1399 		break;
1400 
1401 	case IO_ERROR:
1402 		log_info("%016"PRIx64" smtp event=closed reason=\"io-error: %s\"",
1403 		    s->id, io->error);
1404 		smtp_free(s, "IO error");
1405 		break;
1406 
1407 	default:
1408 		fatalx("smtp_io()");
1409 	}
1410 }
1411 
1412 static int
1413 smtp_tx(struct smtp_session *s)
1414 {
1415 	struct smtp_tx *tx;
1416 
1417 	tx = calloc(1, sizeof(*tx));
1418 	if (tx == NULL)
1419 		return 0;
1420 
1421 	TAILQ_INIT(&tx->rcpts);
1422 	io_init(&tx->oev, -1, s, NULL, NULL); /* initialise 'sock', but not to 0 */
1423 
1424 	s->tx = tx;
1425 	tx->session = s;
1426 
1427 	/* setup the envelope */
1428 	s->tx->evp.ss = s->ss;
1429 	(void)strlcpy(s->tx->evp.tag, s->listener->tag, sizeof(s->tx->evp.tag));
1430 	(void)strlcpy(s->tx->evp.smtpname, s->smtpname, sizeof(s->tx->evp.smtpname));
1431 	(void)strlcpy(s->tx->evp.hostname, s->hostname, sizeof s->tx->evp.hostname);
1432 	(void)strlcpy(s->tx->evp.helo, s->helo, sizeof s->tx->evp.helo);
1433 
1434 	if (s->flags & SF_BOUNCE)
1435 		s->tx->evp.flags |= EF_BOUNCE;
1436 	if (s->flags & SF_AUTHENTICATED)
1437 		s->tx->evp.flags |= EF_AUTHENTICATED;
1438 
1439 	/* Setup parser and callbacks */
1440 	rfc2822_parser_init(&tx->rfc2822_parser);
1441 	rfc2822_header_default_callback(&tx->rfc2822_parser,
1442 	    header_default_callback, s);
1443 	rfc2822_header_callback(&tx->rfc2822_parser, "bcc",
1444 	    header_bcc_callback, s);
1445 	rfc2822_header_callback(&tx->rfc2822_parser, "from",
1446 	    header_domain_append_callback, s);
1447 	rfc2822_header_callback(&tx->rfc2822_parser, "to",
1448 	    header_domain_append_callback, s);
1449 	rfc2822_header_callback(&tx->rfc2822_parser, "cc",
1450 	    header_domain_append_callback, s);
1451 	rfc2822_body_callback(&tx->rfc2822_parser,
1452 	    dataline_callback, s);
1453 
1454 	if (s->listener->local || s->listener->port == 587) {
1455 		rfc2822_missing_header_callback(&tx->rfc2822_parser, "date",
1456 		    header_missing_callback, s);
1457 		rfc2822_missing_header_callback(&tx->rfc2822_parser, "message-id",
1458 		    header_missing_callback, s);
1459 	}
1460 
1461 	return 1;
1462 }
1463 
1464 static void
1465 smtp_tx_free(struct smtp_tx *tx)
1466 {
1467 	struct smtp_rcpt *rcpt;
1468 
1469 	rfc2822_parser_release(&tx->rfc2822_parser);
1470 
1471 	while ((rcpt = TAILQ_FIRST(&tx->rcpts))) {
1472 		TAILQ_REMOVE(&tx->rcpts, rcpt, entry);
1473 		free(rcpt);
1474 	}
1475 
1476 	tx->session->tx = NULL;
1477 
1478 	free(tx);
1479 }
1480 
1481 static void
1482 smtp_data_io(struct io *io, int evt)
1483 {
1484 	struct smtp_session    *s = io->arg;
1485 
1486 	log_trace(TRACE_IO, "smtp: %p (data): %s %s", s, io_strevent(evt),
1487 	    io_strio(io));
1488 
1489 	switch (evt) {
1490 	case IO_TIMEOUT:
1491 	case IO_DISCONNECTED:
1492 	case IO_ERROR:
1493 		log_debug("debug: smtp: %p: io error on mfa", s);
1494 		io_clear(&s->tx->oev);
1495 		iobuf_clear(&s->tx->obuf);
1496 		s->tx->msgflags |= MF_ERROR_IO;
1497 		if (s->io.flags & IO_PAUSE_IN) {
1498 			log_debug("debug: smtp: %p: resuming session after mfa error", s);
1499 			io_resume(&s->io, IO_PAUSE_IN);
1500 		}
1501 		break;
1502 
1503 	case IO_LOWAT:
1504 		if (s->tx->dataeom && iobuf_queued(&s->tx->obuf) == 0) {
1505 			smtp_data_io_done(s);
1506 		} else if (s->io.flags & IO_PAUSE_IN) {
1507 			log_debug("debug: smtp: %p: filter congestion over: resuming session", s);
1508 			io_resume(&s->io, IO_PAUSE_IN);
1509 		}
1510 		break;
1511 
1512 	default:
1513 		fatalx("smtp_data_io()");
1514 	}
1515 }
1516 
1517 static void
1518 smtp_data_io_done(struct smtp_session *s)
1519 {
1520 	log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->tx->odatalen);
1521 	io_clear(&s->tx->oev);
1522 	iobuf_clear(&s->tx->obuf);
1523 
1524 	if (s->tx->msgflags & MF_ERROR) {
1525 
1526 		tree_pop(&wait_filter_data, s->id);
1527 
1528 		smtp_filter_tx_rollback(s);
1529 		smtp_queue_rollback(s);
1530 
1531 		if (s->tx->msgflags & MF_ERROR_SIZE)
1532 			smtp_reply(s, "554 Message too big");
1533 		else if (s->tx->msgflags & MF_ERROR_LOOP)
1534 			smtp_reply(s, "500 %s %s: Loop detected",
1535 				esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED),
1536 				esc_description(ESC_ROUTING_LOOP_DETECTED));
1537                 else if (s->tx->msgflags & MF_ERROR_RESOURCES)
1538                         smtp_reply(s, "421 %s: Temporary Error",
1539                             esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1540                 else if (s->tx->msgflags & MF_ERROR_MALFORMED)
1541                         smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant",
1542                             esc_code(ESC_STATUS_PERMFAIL,
1543 				ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED),
1544                             esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED));
1545 		else if (s->tx->msgflags)
1546 			smtp_reply(s, "421 Internal server error");
1547 		smtp_tx_free(s->tx);
1548 		smtp_enter_state(s, STATE_HELO);
1549 		io_reload(&s->io);
1550 	}
1551 	else {
1552 		smtp_filter_eom(s);
1553 	}
1554 }
1555 
1556 static void
1557 smtp_command(struct smtp_session *s, char *line)
1558 {
1559 	char			       *args, *eom, *method;
1560 	int				cmd, i;
1561 
1562 	log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line);
1563 
1564 	/*
1565 	 * These states are special.
1566 	 */
1567 	if (s->state == STATE_AUTH_INIT) {
1568 		smtp_rfc4954_auth_plain(s, line);
1569 		return;
1570 	}
1571 	if (s->state == STATE_AUTH_USERNAME || s->state == STATE_AUTH_PASSWORD) {
1572 		smtp_rfc4954_auth_login(s, line);
1573 		return;
1574 	}
1575 
1576 	/*
1577 	 * Unlike other commands, "mail from" and "rcpt to" contain a
1578 	 * space in the command name.
1579 	 */
1580 	if (strncasecmp("mail from:", line, 10) == 0 ||
1581 	    strncasecmp("rcpt to:", line, 8) == 0)
1582 		args = strchr(line, ':');
1583 	else
1584 		args = strchr(line, ' ');
1585 
1586 	if (args) {
1587 		*args++ = '\0';
1588 		while (isspace((unsigned char)*args))
1589 			args++;
1590 	}
1591 
1592 	cmd = -1;
1593 	for (i = 0; commands[i].code != -1; i++)
1594 		if (!strcasecmp(line, commands[i].cmd)) {
1595 			cmd = commands[i].code;
1596 			break;
1597 		}
1598 
1599 	switch (cmd) {
1600 	/*
1601 	 * INIT
1602 	 */
1603 	case CMD_HELO:
1604 	case CMD_EHLO:
1605 		if (s->phase != PHASE_INIT) {
1606 			smtp_reply(s, "503 %s %s: Already identified",
1607 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1608 			    esc_description(ESC_INVALID_COMMAND));
1609 			break;
1610 		}
1611 
1612 		if (args == NULL) {
1613 			smtp_reply(s, "501 %s %s: %s requires domain name",
1614 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1615 			    esc_description(ESC_INVALID_COMMAND),
1616 			    (cmd == CMD_HELO) ? "HELO" : "EHLO");
1617 
1618 			break;
1619 		}
1620 
1621 		if (!valid_domainpart(args)) {
1622 			smtp_reply(s, "501 %s %s: Invalid domain name",
1623 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1624 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1625 			break;
1626 		}
1627 		(void)strlcpy(s->helo, args, sizeof(s->helo));
1628 		s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED | SF_FILTERCONN;
1629 		if (cmd == CMD_EHLO) {
1630 			s->flags |= SF_EHLO;
1631 			s->flags |= SF_8BITMIME;
1632 		}
1633 
1634 		smtp_filter_helo(s);
1635 		break;
1636 	/*
1637 	 * SETUP
1638 	 */
1639 	case CMD_STARTTLS:
1640 		if (s->phase != PHASE_SETUP) {
1641 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1642 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1643 			    esc_description(ESC_INVALID_COMMAND));
1644 			break;
1645 		}
1646 
1647 		if (!(s->listener->flags & F_STARTTLS)) {
1648 			smtp_reply(s, "503 %s %s: Command not supported",
1649 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1650 			    esc_description(ESC_INVALID_COMMAND));
1651 			break;
1652 		}
1653 
1654 		if (s->flags & SF_SECURE) {
1655 			smtp_reply(s, "503 %s %s: Channel already secured",
1656 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1657 			    esc_description(ESC_INVALID_COMMAND));
1658 			break;
1659 		}
1660 		if (args != NULL) {
1661 			smtp_reply(s, "501 %s %s: No parameters allowed",
1662 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1663 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1664 			break;
1665 		}
1666 		smtp_reply(s, "220 %s: Ready to start TLS",
1667 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1668 		smtp_enter_state(s, STATE_TLS);
1669 		break;
1670 
1671 	case CMD_AUTH:
1672 		if (s->phase != PHASE_SETUP) {
1673 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1674 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1675 			    esc_description(ESC_INVALID_COMMAND));
1676 			break;
1677 		}
1678 
1679 		if (s->flags & SF_AUTHENTICATED) {
1680 			smtp_reply(s, "503 %s %s: Already authenticated",
1681 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1682 			    esc_description(ESC_INVALID_COMMAND));
1683 			break;
1684 		}
1685 
1686 		if (!ADVERTISE_AUTH(s)) {
1687 			smtp_reply(s, "503 %s %s: Command not supported",
1688 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1689 			    esc_description(ESC_INVALID_COMMAND));
1690 			break;
1691 		}
1692 
1693 		if (args == NULL) {
1694 			smtp_reply(s, "501 %s %s: No parameters given",
1695 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1696 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1697 			break;
1698 		}
1699 
1700 		method = args;
1701 		eom = strchr(args, ' ');
1702 		if (eom == NULL)
1703 			eom = strchr(args, '\t');
1704 		if (eom != NULL)
1705 			*eom++ = '\0';
1706 		if (strcasecmp(method, "PLAIN") == 0)
1707 			smtp_rfc4954_auth_plain(s, eom);
1708 		else if (strcasecmp(method, "LOGIN") == 0)
1709 			smtp_rfc4954_auth_login(s, eom);
1710 		else
1711 			smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported",
1712 			    esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED),
1713 			    esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED),
1714 			    method);
1715 		break;
1716 
1717 	case CMD_MAIL_FROM:
1718 		if (s->phase != PHASE_SETUP) {
1719 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1720 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1721 			    esc_description(ESC_INVALID_COMMAND));
1722 
1723 			break;
1724 		}
1725 
1726 		if (s->listener->flags & F_STARTTLS_REQUIRE &&
1727 		    !(s->flags & SF_SECURE)) {
1728 			smtp_reply(s,
1729 			    "530 %s %s: Must issue a STARTTLS command first",
1730 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1731 			    esc_description(ESC_INVALID_COMMAND));
1732 			break;
1733 		}
1734 
1735 		if (s->listener->flags & F_AUTH_REQUIRE &&
1736 		    !(s->flags & SF_AUTHENTICATED)) {
1737 			smtp_reply(s,
1738 			    "530 %s %s: Must issue an AUTH command first",
1739 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1740 			    esc_description(ESC_INVALID_COMMAND));
1741 			break;
1742 		}
1743 
1744 		if (s->mailcount >= env->sc_session_max_mails) {
1745 			/* we can pretend we had too many recipients */
1746 			smtp_reply(s, "452 %s %s: Too many messages sent",
1747 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS),
1748 			    esc_description(ESC_TOO_MANY_RECIPIENTS));
1749 			break;
1750 		}
1751 
1752 		if (!smtp_tx(s)) {
1753 			smtp_reply(s, "421 %s: Temporary Error",
1754 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1755 			smtp_enter_state(s, STATE_QUIT);
1756 			break;
1757 		}
1758 
1759 		if (smtp_mailaddr(&s->tx->evp.sender, args, 1, &args,
1760 			s->smtpname) == 0) {
1761 			smtp_tx_free(s->tx);
1762 			smtp_reply(s, "553 %s: Sender address syntax error",
1763 			    esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS));
1764 			break;
1765 		}
1766 		if (args && smtp_parse_mail_args(s, args) == -1) {
1767 			smtp_tx_free(s->tx);
1768 			break;
1769 		}
1770 
1771 		smtp_filter_tx_begin(s);
1772 		smtp_filter_mail(s);
1773 		break;
1774 	/*
1775 	 * TRANSACTION
1776 	 */
1777 	case CMD_RCPT_TO:
1778 		if (s->phase != PHASE_TRANSACTION) {
1779 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1780 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1781 			    esc_description(ESC_INVALID_COMMAND));
1782 			break;
1783 		}
1784 
1785 		if (s->tx->rcptcount >= env->sc_session_max_rcpt) {
1786 			smtp_reply(s, "451 %s %s: Too many recipients",
1787 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS),
1788 			    esc_description(ESC_TOO_MANY_RECIPIENTS));
1789 			break;
1790 		}
1791 
1792 		if (smtp_mailaddr(&s->tx->evp.rcpt, args, 0, &args,
1793 		    s->smtpname) == 0) {
1794 			smtp_reply(s,
1795 			    "501 %s: Recipient address syntax error",
1796 			    esc_code(ESC_STATUS_PERMFAIL, ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX));
1797 			break;
1798 		}
1799 		if (args && smtp_parse_rcpt_args(s, args) == -1)
1800 			break;
1801 
1802 		smtp_filter_rcpt(s);
1803 		break;
1804 
1805 	case CMD_RSET:
1806 		if (s->phase != PHASE_TRANSACTION && s->phase != PHASE_SETUP) {
1807 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1808 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1809 			    esc_description(ESC_INVALID_COMMAND));
1810 			break;
1811 		}
1812 
1813 		if (s->tx) {
1814 			smtp_filter_tx_rollback(s);
1815 			if (s->tx->msgid)
1816 				smtp_queue_rollback(s);
1817 			smtp_tx_free(s->tx);
1818 		}
1819 
1820 		smtp_filter_rset(s);
1821 
1822 		s->phase = PHASE_SETUP;
1823 		smtp_reply(s, "250 %s: Reset state",
1824 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1825 		break;
1826 
1827 	case CMD_DATA:
1828 		if (s->phase != PHASE_TRANSACTION) {
1829 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1830 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1831 			    esc_description(ESC_INVALID_COMMAND));
1832 			break;
1833 		}
1834 		if (s->tx->rcptcount == 0) {
1835 			smtp_reply(s, "503 %s %s: No recipient specified",
1836 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1837 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1838 			break;
1839 		}
1840 
1841 		smtp_filter_data(s);
1842 		break;
1843 	/*
1844 	 * ANY
1845 	 */
1846 	case CMD_QUIT:
1847 		smtp_reply(s, "221 %s: Bye",
1848 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1849 		smtp_enter_state(s, STATE_QUIT);
1850 		break;
1851 
1852 	case CMD_NOOP:
1853 		smtp_reply(s, "250 %s: Ok",
1854 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1855 		break;
1856 
1857 	case CMD_HELP:
1858 		smtp_reply(s, "214- This is " SMTPD_NAME);
1859 		smtp_reply(s, "214- To report bugs in the implementation, "
1860 		    "please contact bugs@openbsd.org");
1861 		smtp_reply(s, "214- with full details");
1862 		smtp_reply(s, "214 %s: End of HELP info",
1863 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1864 		break;
1865 
1866 	case CMD_WIZ:
1867 		smtp_reply(s, "500 %s %s: this feature is not supported yet ;-)",
1868 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1869 			    esc_description(ESC_INVALID_COMMAND));
1870 		break;
1871 
1872 	default:
1873 		smtp_reply(s, "500 %s %s: Command unrecognized",
1874 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1875 			    esc_description(ESC_INVALID_COMMAND));
1876 		break;
1877 	}
1878 }
1879 
1880 static void
1881 smtp_rfc4954_auth_plain(struct smtp_session *s, char *arg)
1882 {
1883 	char		 buf[1024], *user, *pass;
1884 	int		 len;
1885 
1886 	switch (s->state) {
1887 	case STATE_HELO:
1888 		if (arg == NULL) {
1889 			smtp_enter_state(s, STATE_AUTH_INIT);
1890 			smtp_reply(s, "334 ");
1891 			return;
1892 		}
1893 		smtp_enter_state(s, STATE_AUTH_INIT);
1894 		/* FALLTHROUGH */
1895 
1896 	case STATE_AUTH_INIT:
1897 		/* String is not NUL terminated, leave room. */
1898 		if ((len = base64_decode(arg, (unsigned char *)buf,
1899 			    sizeof(buf) - 1)) == -1)
1900 			goto abort;
1901 		/* buf is a byte string, NUL terminate. */
1902 		buf[len] = '\0';
1903 
1904 		/*
1905 		 * Skip "foo" in "foo\0user\0pass", if present.
1906 		 */
1907 		user = memchr(buf, '\0', len);
1908 		if (user == NULL || user >= buf + len - 2)
1909 			goto abort;
1910 		user++; /* skip NUL */
1911 		if (strlcpy(s->username, user, sizeof(s->username))
1912 		    >= sizeof(s->username))
1913 			goto abort;
1914 
1915 		pass = memchr(user, '\0', len - (user - buf));
1916 		if (pass == NULL || pass >= buf + len - 2)
1917 			goto abort;
1918 		pass++; /* skip NUL */
1919 
1920 		m_create(p_lka,  IMSG_SMTP_AUTHENTICATE, 0, 0, -1);
1921 		m_add_id(p_lka, s->id);
1922 		m_add_string(p_lka, s->listener->authtable);
1923 		m_add_string(p_lka, user);
1924 		m_add_string(p_lka, pass);
1925 		m_close(p_lka);
1926 		tree_xset(&wait_parent_auth, s->id, s);
1927 		return;
1928 
1929 	default:
1930 		fatal("smtp_rfc4954_auth_plain: unknown state");
1931 	}
1932 
1933 abort:
1934 	smtp_reply(s, "501 %s %s: Syntax error",
1935 	    esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR),
1936 	    esc_description(ESC_SYNTAX_ERROR));
1937 	smtp_enter_state(s, STATE_HELO);
1938 }
1939 
1940 static void
1941 smtp_rfc4954_auth_login(struct smtp_session *s, char *arg)
1942 {
1943 	char		buf[LINE_MAX];
1944 
1945 	switch (s->state) {
1946 	case STATE_HELO:
1947 		smtp_enter_state(s, STATE_AUTH_USERNAME);
1948 		smtp_reply(s, "334 VXNlcm5hbWU6");
1949 		return;
1950 
1951 	case STATE_AUTH_USERNAME:
1952 		memset(s->username, 0, sizeof(s->username));
1953 		if (base64_decode(arg, (unsigned char *)s->username,
1954 				  sizeof(s->username) - 1) == -1)
1955 			goto abort;
1956 
1957 		smtp_enter_state(s, STATE_AUTH_PASSWORD);
1958 		smtp_reply(s, "334 UGFzc3dvcmQ6");
1959 		return;
1960 
1961 	case STATE_AUTH_PASSWORD:
1962 		memset(buf, 0, sizeof(buf));
1963 		if (base64_decode(arg, (unsigned char *)buf,
1964 				  sizeof(buf)-1) == -1)
1965 			goto abort;
1966 
1967 		m_create(p_lka,  IMSG_SMTP_AUTHENTICATE, 0, 0, -1);
1968 		m_add_id(p_lka, s->id);
1969 		m_add_string(p_lka, s->listener->authtable);
1970 		m_add_string(p_lka, s->username);
1971 		m_add_string(p_lka, buf);
1972 		m_close(p_lka);
1973 		tree_xset(&wait_parent_auth, s->id, s);
1974 		return;
1975 
1976 	default:
1977 		fatal("smtp_rfc4954_auth_login: unknown state");
1978 	}
1979 
1980 abort:
1981 	smtp_reply(s, "501 %s %s: Syntax error",
1982 	    esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR),
1983 	    esc_description(ESC_SYNTAX_ERROR));
1984 	smtp_enter_state(s, STATE_HELO);
1985 }
1986 
1987 static uint8_t
1988 dsn_notify_str_to_uint8(const char *arg)
1989 {
1990 	if (strcasecmp(arg, "SUCCESS") == 0)
1991 		return DSN_SUCCESS;
1992 	else if (strcasecmp(arg, "FAILURE") == 0)
1993 		return DSN_FAILURE;
1994 	else if (strcasecmp(arg, "DELAY") == 0)
1995 		return DSN_DELAY;
1996 	else if (strcasecmp(arg, "NEVER") == 0)
1997 		return DSN_NEVER;
1998 
1999 	return (0);
2000 }
2001 
2002 static int
2003 smtp_parse_rcpt_args(struct smtp_session *s, char *args)
2004 {
2005 	char 	*b, *p;
2006 	uint8_t flag;
2007 
2008 	while ((b = strsep(&args, " "))) {
2009 		if (*b == '\0')
2010 			continue;
2011 
2012 		if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "NOTIFY=", 7) == 0) {
2013 			b += 7;
2014 			while ((p = strsep(&b, ","))) {
2015 				if (*p == '\0')
2016 					continue;
2017 
2018 				if ((flag = dsn_notify_str_to_uint8(p)) == 0)
2019 					continue;
2020 
2021 				s->tx->evp.dsn_notify |= flag;
2022 			}
2023 			if (s->tx->evp.dsn_notify & DSN_NEVER &&
2024 			    s->tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE |
2025 			    DSN_DELAY)) {
2026 				smtp_reply(s,
2027 				    "553 NOTIFY option NEVER cannot be \
2028 				    combined with other options");
2029 				return (-1);
2030 			}
2031 		} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ORCPT=", 6) == 0) {
2032 			b += 6;
2033 			if (!text_to_mailaddr(&s->tx->evp.dsn_orcpt, b)) {
2034 				smtp_reply(s, "553 ORCPT address syntax error");
2035 				return (-1);
2036 			}
2037 		} else {
2038 			smtp_reply(s, "503 Unsupported option %s", b);
2039 			return (-1);
2040 		}
2041 	}
2042 
2043 	return (0);
2044 }
2045 
2046 static int
2047 smtp_parse_mail_args(struct smtp_session *s, char *args)
2048 {
2049 	char *b;
2050 
2051 	while ((b = strsep(&args, " "))) {
2052 		if (*b == '\0')
2053 			continue;
2054 
2055 		if (strncasecmp(b, "AUTH=", 5) == 0)
2056 			log_debug("debug: smtp: AUTH in MAIL FROM command");
2057 		else if (strncasecmp(b, "SIZE=", 5) == 0)
2058 			log_debug("debug: smtp: SIZE in MAIL FROM command");
2059 		else if (strcasecmp(b, "BODY=7BIT") == 0)
2060 			/* XXX only for this transaction */
2061 			s->flags &= ~SF_8BITMIME;
2062 		else if (strcasecmp(b, "BODY=8BITMIME") == 0)
2063 			;
2064 		else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "RET=", 4) == 0) {
2065 			b += 4;
2066 			if (strcasecmp(b, "HDRS") == 0)
2067 				s->tx->evp.dsn_ret = DSN_RETHDRS;
2068 			else if (strcasecmp(b, "FULL") == 0)
2069 				s->tx->evp.dsn_ret = DSN_RETFULL;
2070 		} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ENVID=", 6) == 0) {
2071 			b += 6;
2072 			if (strlcpy(s->tx->evp.dsn_envid, b, sizeof(s->tx->evp.dsn_envid))
2073 			    >= sizeof(s->tx->evp.dsn_envid)) {
2074 				smtp_reply(s, "503 %s %s: option too large, truncated: %s",
2075 				    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
2076 				    esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b);
2077 				return (-1);
2078 			}
2079 		} else {
2080 			smtp_reply(s, "503 %s %s: Unsupported option %s",
2081 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
2082 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b);
2083 			return (-1);
2084 		}
2085 	}
2086 
2087 	return (0);
2088 }
2089 
2090 static int
2091 smtp_lookup_servername(struct smtp_session *s)
2092 {
2093 	struct sockaddr		*sa;
2094 	socklen_t		 sa_len;
2095 	struct sockaddr_storage	 ss;
2096 
2097 	if (s->listener->hostnametable[0]) {
2098 		sa_len = sizeof(ss);
2099 		sa = (struct sockaddr *)&ss;
2100 		if (getsockname(s->io.sock, sa, &sa_len) == -1) {
2101 			log_warn("warn: getsockname()");
2102 		}
2103 		else {
2104 			m_create(p_lka, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1);
2105 			m_add_id(p_lka, s->id);
2106 			m_add_string(p_lka, s->listener->hostnametable);
2107 			m_add_sockaddr(p_lka, sa);
2108 			m_close(p_lka);
2109 			tree_xset(&wait_lka_helo, s->id, s);
2110 			return 0;
2111 		}
2112 	}
2113 	return 1;
2114 }
2115 
2116 static void
2117 smtp_connected(struct smtp_session *s)
2118 {
2119 	struct sockaddr_storage	ss;
2120 	socklen_t		sl;
2121 
2122 	smtp_enter_state(s, STATE_CONNECTED);
2123 
2124 	log_info("%016"PRIx64" smtp event=connected address=%s host=%s",
2125 	    s->id, ss_to_text(&s->ss), s->hostname);
2126 
2127 	sl = sizeof(ss);
2128 	if (getsockname(s->io.sock, (struct sockaddr*)&ss, &sl) == -1) {
2129 		smtp_free(s, strerror(errno));
2130 		return;
2131 	}
2132 
2133 	s->flags |= SF_FILTERCONN;
2134 	smtp_filter_connect(s, (struct sockaddr *)&ss);
2135 }
2136 
2137 static void
2138 smtp_send_banner(struct smtp_session *s)
2139 {
2140 	smtp_reply(s, "220 %s ESMTP %s", s->smtpname, SMTPD_NAME);
2141 	io_reload(&s->io);
2142 }
2143 
2144 void
2145 smtp_enter_state(struct smtp_session *s, int newstate)
2146 {
2147 	log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s,
2148 	    smtp_strstate(s->state),
2149 	    smtp_strstate(newstate));
2150 
2151 	s->state = newstate;
2152 }
2153 
2154 static void
2155 smtp_message_end(struct smtp_session *s)
2156 {
2157 	log_debug("debug: %p: end of message, msgflags=0x%04x", s, s->tx->msgflags);
2158 
2159 	tree_xpop(&wait_filter_data, s->id);
2160 
2161 	s->phase = PHASE_SETUP;
2162 
2163 	if (s->tx->msgflags & MF_ERROR) {
2164 		smtp_filter_tx_rollback(s);
2165 		smtp_queue_rollback(s);
2166 		if (s->tx->msgflags & MF_ERROR_SIZE)
2167 			smtp_reply(s, "554 %s %s: Transaction failed, message too big",
2168 			    esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM),
2169 			    esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM));
2170 		else
2171 			smtp_reply(s, "%d Message rejected", s->tx->msgcode);
2172 		smtp_tx_free(s->tx);
2173 		smtp_enter_state(s, STATE_HELO);
2174 		return;
2175 	}
2176 
2177 	smtp_queue_commit(s);
2178 }
2179 
2180 static int
2181 smtp_message_printf(struct smtp_session *s, const char *fmt, ...)
2182 {
2183 	va_list	ap;
2184 	int	len;
2185 
2186 	if (s->tx->msgflags & MF_ERROR)
2187 		return -1;
2188 
2189 	va_start(ap, fmt);
2190 	len = iobuf_vfqueue(&s->tx->obuf, fmt, ap);
2191 	va_end(ap);
2192 
2193 	if (len < 0) {
2194 		log_warn("smtp-in: session %016"PRIx64": vfprintf", s->id);
2195 		s->tx->msgflags |= MF_ERROR_IO;
2196 	}
2197 	else
2198 		s->tx->odatalen += len;
2199 
2200 	return len;
2201 }
2202 
2203 static void
2204 smtp_reply(struct smtp_session *s, char *fmt, ...)
2205 {
2206 	va_list	 ap;
2207 	int	 n;
2208 	char	 buf[LINE_MAX], tmp[LINE_MAX];
2209 
2210 	va_start(ap, fmt);
2211 	n = vsnprintf(buf, sizeof buf, fmt, ap);
2212 	va_end(ap);
2213 	if (n == -1 || n >= LINE_MAX)
2214 		fatalx("smtp_reply: line too long");
2215 	if (n < 4)
2216 		fatalx("smtp_reply: response too short");
2217 
2218 	log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf);
2219 
2220 	iobuf_xfqueue(&s->iobuf, "smtp_reply", "%s\r\n", buf);
2221 
2222 	switch (buf[0]) {
2223 	case '5':
2224 	case '4':
2225 		if (s->flags & SF_BADINPUT) {
2226 			log_info("%016"PRIx64" smtp "
2227 			    "event=bad-input result=\"%.*s\"",
2228 			    s->id, n, buf);
2229 		}
2230 		else if (s->state == STATE_AUTH_INIT) {
2231 			log_info("smtp-in: Failed command on session %016"PRIx64
2232 			    ": \"AUTH PLAIN (...)\" => %.*s", s->id, n, buf);
2233 		}
2234 		else if (s->state == STATE_AUTH_USERNAME) {
2235 			log_info("smtp-in: Failed command on session %016"PRIx64
2236 			    ": \"AUTH LOGIN (username)\" => %.*s", s->id, n, buf);
2237 		}
2238 		else if (s->state == STATE_AUTH_PASSWORD) {
2239 			log_info("smtp-in: Failed command on session %016"PRIx64
2240 			    ": \"AUTH LOGIN (password)\" => %.*s", s->id, n, buf);
2241 		}
2242 		else {
2243 			strnvis(tmp, s->cmd, sizeof tmp, VIS_SAFE | VIS_CSTYLE);
2244 			log_info("%016"PRIx64" smtp "
2245 			    "event=failed-command command=\"%s\" result=\"%.*s\"",
2246 			    s->id, tmp, n, buf);
2247 		}
2248 		break;
2249 	}
2250 }
2251 
2252 static void
2253 smtp_free(struct smtp_session *s, const char * reason)
2254 {
2255 	log_debug("debug: smtp: %p: deleting session: %s", s, reason);
2256 
2257 	tree_pop(&wait_filter_data, s->id);
2258 
2259 	if (s->tx) {
2260 		if (s->tx->msgid) {
2261 			smtp_queue_rollback(s);
2262 			io_clear(&s->tx->oev);
2263 			iobuf_clear(&s->tx->obuf);
2264 		}
2265 		smtp_filter_tx_rollback(s);
2266 		smtp_tx_free(s->tx);
2267 	}
2268 
2269 	if (s->flags & SF_FILTERCONN)
2270 		smtp_filter_disconnect(s);
2271 
2272 	if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS)
2273 		stat_decrement("smtp.smtps", 1);
2274 	if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS)
2275 		stat_decrement("smtp.tls", 1);
2276 
2277 	io_clear(&s->io);
2278 	iobuf_clear(&s->iobuf);
2279 	free(s);
2280 
2281 	smtp_collect();
2282 }
2283 
2284 static int
2285 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2286     const char *domain)
2287 {
2288 	char   *p, *e;
2289 
2290 	if (line == NULL)
2291 		return (0);
2292 
2293 	if (*line != '<')
2294 		return (0);
2295 
2296 	e = strchr(line, '>');
2297 	if (e == NULL)
2298 		return (0);
2299 	*e++ = '\0';
2300 	while (*e == ' ')
2301 		e++;
2302 	*args = e;
2303 
2304 	if (!text_to_mailaddr(maddr, line + 1))
2305 		return (0);
2306 
2307 	p = strchr(maddr->user, ':');
2308 	if (p != NULL) {
2309 		p++;
2310 		memmove(maddr->user, p, strlen(p) + 1);
2311 	}
2312 
2313 	if (!valid_localpart(maddr->user) ||
2314 	    !valid_domainpart(maddr->domain)) {
2315 		/* accept empty return-path in MAIL FROM, required for bounces */
2316 		if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0')
2317 			return (1);
2318 
2319 		/* no user-part, reject */
2320 		if (maddr->user[0] == '\0')
2321 			return (0);
2322 
2323 		/* no domain, local user */
2324 		if (maddr->domain[0] == '\0') {
2325 			(void)strlcpy(maddr->domain, domain,
2326 			    sizeof(maddr->domain));
2327 			return (1);
2328 		}
2329 		return (0);
2330 	}
2331 
2332 	return (1);
2333 }
2334 
2335 static int
2336 smtp_verify_certificate(struct smtp_session *s)
2337 {
2338 #define MAX_CERTS	16
2339 #define MAX_CERT_LEN	(MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(req_ca_vrfy)))
2340 	struct ca_vrfy_req_msg	req_ca_vrfy;
2341 	struct iovec		iov[2];
2342 	X509		       *x;
2343 	STACK_OF(X509)	       *xchain;
2344 	const char	       *name;
2345 	unsigned char	       *cert_der[MAX_CERTS];
2346 	int			cert_len[MAX_CERTS];
2347 	int			i, cert_count, res;
2348 
2349 	res = 0;
2350 	memset(cert_der, 0, sizeof(cert_der));
2351 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2352 
2353 	/* Send the client certificate */
2354 	if (s->listener->ca_name[0]) {
2355 		name = s->listener->ca_name;
2356 		req_ca_vrfy.fallback = 0;
2357 	}
2358 	else {
2359 		name = s->smtpname;
2360 		req_ca_vrfy.fallback = 1;
2361 	}
2362 
2363 	if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name)
2364 	    >= sizeof req_ca_vrfy.name)
2365 		return 0;
2366 
2367 	x = SSL_get_peer_certificate(s->io.ssl);
2368 	if (x == NULL)
2369 		return 0;
2370 	xchain = SSL_get_peer_cert_chain(s->io.ssl);
2371 
2372 	/*
2373 	 * Client provided a certificate and possibly a certificate chain.
2374 	 * SMTP can't verify because it does not have the information that
2375 	 * it needs, instead it will pass the certificate and chain to the
2376 	 * lookup process and wait for a reply.
2377 	 *
2378 	 */
2379 
2380 	cert_len[0] = i2d_X509(x, &cert_der[0]);
2381 	X509_free(x);
2382 
2383 	if (cert_len[0] < 0) {
2384 		log_warnx("warn: failed to encode certificate");
2385 		goto end;
2386 	}
2387 	log_debug("debug: certificate 0: len=%d", cert_len[0]);
2388 	if (cert_len[0] > (int)MAX_CERT_LEN) {
2389 		log_warnx("warn: certificate too long");
2390 		goto end;
2391 	}
2392 
2393 	if (xchain) {
2394 		cert_count = sk_X509_num(xchain);
2395 		log_debug("debug: certificate chain len: %d", cert_count);
2396 		if (cert_count >= MAX_CERTS) {
2397 			log_warnx("warn: certificate chain too long");
2398 			goto end;
2399 		}
2400 	}
2401 	else
2402 		cert_count = 0;
2403 
2404 	for (i = 0; i < cert_count; ++i) {
2405 		x = sk_X509_value(xchain, i);
2406 		cert_len[i+1] = i2d_X509(x, &cert_der[i+1]);
2407 		if (cert_len[i+1] < 0) {
2408 			log_warnx("warn: failed to encode certificate");
2409 			goto end;
2410 		}
2411 		log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]);
2412 		if (cert_len[i+1] > (int)MAX_CERT_LEN) {
2413 			log_warnx("warn: certificate too long");
2414 			goto end;
2415 		}
2416 	}
2417 
2418 	tree_xset(&wait_ssl_verify, s->id, s);
2419 
2420 	/* Send the client certificate */
2421 	req_ca_vrfy.reqid = s->id;
2422 	req_ca_vrfy.cert_len = cert_len[0];
2423 	req_ca_vrfy.n_chain = cert_count;
2424 	iov[0].iov_base = &req_ca_vrfy;
2425 	iov[0].iov_len = sizeof(req_ca_vrfy);
2426 	iov[1].iov_base = cert_der[0];
2427 	iov[1].iov_len = cert_len[0];
2428 	m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CERT, 0, 0, -1,
2429 	    iov, nitems(iov));
2430 
2431 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2432 	req_ca_vrfy.reqid = s->id;
2433 
2434 	/* Send the chain, one cert at a time */
2435 	for (i = 0; i < cert_count; ++i) {
2436 		req_ca_vrfy.cert_len = cert_len[i+1];
2437 		iov[1].iov_base = cert_der[i+1];
2438 		iov[1].iov_len  = cert_len[i+1];
2439 		m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CHAIN, 0, 0, -1,
2440 		    iov, nitems(iov));
2441 	}
2442 
2443 	/* Tell lookup process that it can start verifying, we're done */
2444 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2445 	req_ca_vrfy.reqid = s->id;
2446 	m_compose(p_lka, IMSG_SMTP_TLS_VERIFY, 0, 0, -1,
2447 	    &req_ca_vrfy, sizeof req_ca_vrfy);
2448 
2449 	res = 1;
2450 
2451     end:
2452 	for (i = 0; i < MAX_CERTS; ++i)
2453 		free(cert_der[i]);
2454 
2455 	return res;
2456 }
2457 
2458 static void
2459 smtp_auth_failure_resume(int fd, short event, void *p)
2460 {
2461 	struct smtp_session *s = p;
2462 
2463 	smtp_reply(s, "535 Authentication failed");
2464 	smtp_enter_state(s, STATE_HELO);
2465 	io_reload(&s->io);
2466 }
2467 
2468 static void
2469 smtp_auth_failure_pause(struct smtp_session *s)
2470 {
2471 	struct timeval	tv;
2472 
2473 	tv.tv_sec = 0;
2474 	tv.tv_usec = arc4random_uniform(1000000);
2475 	log_trace(TRACE_SMTP, "smtp: timing-attack protection triggered, "
2476 	    "will defer answer for %lu microseconds", tv.tv_usec);
2477 	evtimer_set(&s->pause, smtp_auth_failure_resume, s);
2478 	evtimer_add(&s->pause, &tv);
2479 }
2480 
2481 static void
2482 smtp_queue_create_message(struct smtp_session *s)
2483 {
2484 	m_create(p_queue, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1);
2485 	m_add_id(p_queue, s->id);
2486 	m_close(p_queue);
2487 	tree_xset(&wait_queue_msg, s->id, s);
2488 }
2489 
2490 static void
2491 smtp_queue_open_message(struct smtp_session *s)
2492 {
2493 	m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1);
2494 	m_add_id(p_queue, s->id);
2495 	m_add_msgid(p_queue, s->tx->msgid);
2496 	m_close(p_queue);
2497 	tree_xset(&wait_queue_fd, s->id, s);
2498 }
2499 
2500 static void
2501 smtp_queue_commit(struct smtp_session *s)
2502 {
2503 	m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
2504 	m_add_id(p_queue, s->id);
2505 	m_add_msgid(p_queue, s->tx->msgid);
2506 	m_close(p_queue);
2507 	tree_xset(&wait_queue_commit, s->id, s);
2508 }
2509 
2510 static void
2511 smtp_queue_rollback(struct smtp_session *s)
2512 {
2513 	m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1);
2514 	m_add_msgid(p_queue, s->tx->msgid);
2515 	m_close(p_queue);
2516 }
2517 
2518 static void
2519 smtp_filter_rset(struct smtp_session *s)
2520 {
2521 	filter_event(s->id, EVENT_RESET);
2522 }
2523 
2524 static void
2525 smtp_filter_tx_begin(struct smtp_session *s)
2526 {
2527 	s->flags |= SF_FILTERTX;
2528 	filter_event(s->id, EVENT_TX_BEGIN);
2529 }
2530 
2531 static void
2532 smtp_filter_tx_commit(struct smtp_session *s)
2533 {
2534 	s->flags &= ~SF_FILTERTX;
2535 	filter_event(s->id, EVENT_TX_COMMIT);
2536 }
2537 
2538 static void
2539 smtp_filter_tx_rollback(struct smtp_session *s)
2540 {
2541 	s->flags &= ~SF_FILTERTX;
2542 	filter_event(s->id, EVENT_TX_ROLLBACK);
2543 }
2544 
2545 static void
2546 smtp_filter_disconnect(struct smtp_session *s)
2547 {
2548 	filter_event(s->id, EVENT_DISCONNECT);
2549 }
2550 
2551 static void
2552 smtp_filter_connect(struct smtp_session *s, struct sockaddr *sa)
2553 {
2554 	char	*filter;
2555 
2556 	tree_xset(&wait_filter, s->id, s);
2557 
2558 	filter = s->listener->filter[0] ? s->listener->filter : NULL;
2559 
2560 	filter_connect(s->id, sa, (struct sockaddr *)&s->ss, s->hostname, filter);
2561 }
2562 
2563 static void
2564 smtp_filter_eom(struct smtp_session *s)
2565 {
2566 	tree_xset(&wait_filter, s->id, s);
2567 	filter_eom(s->id, QUERY_EOM, s->tx->odatalen);
2568 }
2569 
2570 static void
2571 smtp_filter_helo(struct smtp_session *s)
2572 {
2573 	tree_xset(&wait_filter, s->id, s);
2574 	filter_line(s->id, QUERY_HELO, s->helo);
2575 }
2576 
2577 static void
2578 smtp_filter_mail(struct smtp_session *s)
2579 {
2580 	tree_xset(&wait_filter, s->id, s);
2581 	filter_mailaddr(s->id, QUERY_MAIL, &s->tx->evp.sender);
2582 }
2583 
2584 static void
2585 smtp_filter_rcpt(struct smtp_session *s)
2586 {
2587 	tree_xset(&wait_filter, s->id, s);
2588 	filter_mailaddr(s->id, QUERY_RCPT, &s->tx->evp.rcpt);
2589 }
2590 
2591 static void
2592 smtp_filter_data(struct smtp_session *s)
2593 {
2594 	tree_xset(&wait_filter, s->id, s);
2595 	filter_line(s->id, QUERY_DATA, NULL);
2596 }
2597 
2598 static void
2599 smtp_filter_dataline(struct smtp_session *s, const char *line)
2600 {
2601 	int	ret;
2602 
2603 	log_trace(TRACE_SMTP, "<<< [MSG] %s", line);
2604 
2605 	/* ignore data line if an error flag is set */
2606 	if (s->tx->msgflags & MF_ERROR)
2607 		return;
2608 
2609 	/* escape lines starting with a '.' */
2610 	if (line[0] == '.')
2611 		line += 1;
2612 
2613 	/* account for newline */
2614 	s->tx->datain += strlen(line) + 1;
2615 	if (s->tx->datain > env->sc_maxsize) {
2616 		s->tx->msgflags |= MF_ERROR_SIZE;
2617 		return;
2618 	}
2619 
2620 	if (!s->tx->hdrdone) {
2621 
2622 		/* folded header that must be skipped */
2623 		if (isspace((unsigned char)line[0]) && s->tx->skiphdr)
2624 			return;
2625 		s->tx->skiphdr = 0;
2626 
2627 		/* BCC should be stripped from headers */
2628 		if (strncasecmp("bcc:", line, 4) == 0) {
2629 			s->tx->skiphdr = 1;
2630 			return;
2631 		}
2632 
2633 		/* check for loop */
2634 		if (strncasecmp("Received: ", line, 10) == 0)
2635 			s->tx->rcvcount++;
2636 		if (s->tx->rcvcount == MAX_HOPS_COUNT) {
2637 			s->tx->msgflags |= MF_ERROR_LOOP;
2638 			log_warnx("warn: loop detected");
2639 			return;
2640 		}
2641 
2642 		if (line[0] == '\0')
2643 			s->tx->hdrdone = 1;
2644 	}
2645 
2646 	ret = rfc2822_parser_feed(&s->tx->rfc2822_parser, line);
2647 	if (ret == -1) {
2648 		s->tx->msgflags |= MF_ERROR_RESOURCES;
2649 		return;
2650 	}
2651 
2652 	if (ret == 0) {
2653 		s->tx->msgflags |= MF_ERROR_MALFORMED;
2654 		return;
2655 	}
2656 
2657 	if (iobuf_queued(&s->tx->obuf) > DATA_HIWAT && !(s->io.flags & IO_PAUSE_IN)) {
2658 		log_debug("debug: smtp: %p: filter congestion over: pausing session", s);
2659 		io_pause(&s->io, IO_PAUSE_IN);
2660 	}
2661 	io_reload(&s->tx->oev);
2662 }
2663 
2664 #define CASE(x) case x : return #x
2665 
2666 const char *
2667 smtp_strstate(int state)
2668 {
2669 	static char	buf[32];
2670 
2671 	switch (state) {
2672 	CASE(STATE_NEW);
2673 	CASE(STATE_CONNECTED);
2674 	CASE(STATE_TLS);
2675 	CASE(STATE_HELO);
2676 	CASE(STATE_AUTH_INIT);
2677 	CASE(STATE_AUTH_USERNAME);
2678 	CASE(STATE_AUTH_PASSWORD);
2679 	CASE(STATE_AUTH_FINALIZE);
2680 	CASE(STATE_BODY);
2681 	CASE(STATE_QUIT);
2682 	default:
2683 		(void)snprintf(buf, sizeof(buf), "STATE_??? (%d)", state);
2684 		return (buf);
2685 	}
2686 }
2687