xref: /openbsd-src/usr.sbin/smtpd/smtp_session.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: smtp_session.c,v 1.286 2016/09/03 22:59:06 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 address=%s host=%s "
907 			    "msgid=%08x from=<%s%s%s> to=<%s%s%s> size=%zu ndest=%zu proto=%s",
908 			    s->id,
909 			    ss_to_text(&s->ss), s->hostname,
910 			    s->tx->msgid,
911 			    s->tx->evp.sender.user,
912 			    s->tx->evp.sender.user[0] == '\0' ? "" : "@",
913 			    s->tx->evp.sender.domain,
914 			    rcpt->maddr.user,
915 			    rcpt->maddr.user[0] == '\0' ? "" : "@",
916 			    rcpt->maddr.domain,
917 			    s->tx->odatalen,
918 			    rcpt->destcount,
919 			    s->flags & SF_EHLO ? "ESMTP" : "SMTP");
920 		}
921 		smtp_tx_free(s->tx);
922 		s->mailcount++;
923 		s->phase = PHASE_SETUP;
924 		smtp_enter_state(s, STATE_HELO);
925 		io_reload(&s->io);
926 		return;
927 
928 	case IMSG_SMTP_AUTHENTICATE:
929 		m_msg(&m, imsg);
930 		m_get_id(&m, &reqid);
931 		m_get_int(&m, &success);
932 		m_end(&m);
933 
934 		s = tree_xpop(&wait_parent_auth, reqid);
935 		strnvis(user, s->username, sizeof user, VIS_WHITE | VIS_SAFE);
936 		if (success == LKA_OK) {
937 			log_info("%016"PRIx64" smtp "
938 			    "event=authentication user=%s address=%s "
939 			    "host=%s result=ok",
940 			    s->id, user, ss_to_text(&s->ss), s->hostname);
941 			s->flags |= SF_AUTHENTICATED;
942 			smtp_reply(s, "235 %s: Authentication succeeded",
943 			    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
944 		}
945 		else if (success == LKA_PERMFAIL) {
946 			log_info("%016"PRIx64" smtp "
947 			    "event=authentication user=%s address=%s "
948 			    "host=%s result=permfail",
949 			    s->id, user, ss_to_text(&s->ss), s->hostname);
950 			smtp_auth_failure_pause(s);
951 			return;
952 		}
953 		else if (success == LKA_TEMPFAIL) {
954 			log_info("%016"PRIx64" smtp "
955 			    "event=authentication user=%s address=%s "
956 			    "host=%s result=tempfail",
957 			    s->id, user, ss_to_text(&s->ss), s->hostname);
958 			smtp_reply(s, "421 %s: Temporary failure",
959 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
960 		}
961 		else
962 			fatalx("bad lka response");
963 
964 		smtp_enter_state(s, STATE_HELO);
965 		io_reload(&s->io);
966 		return;
967 
968 	case IMSG_SMTP_TLS_INIT:
969 		resp_ca_cert = imsg->data;
970 		s = tree_xpop(&wait_ssl_init, resp_ca_cert->reqid);
971 
972 		if (resp_ca_cert->status == CA_FAIL) {
973 			log_info("%016"PRIx64" smtp event=closed address=%s host=%s "
974 			    "reason=ca-failure",
975 			    s->id, ss_to_text(&s->ss), s->hostname);
976 			smtp_free(s, "CA failure");
977 			return;
978 		}
979 
980 		resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "smtp:ca_cert");
981 		resp_ca_cert->cert = xstrdup((char *)imsg->data +
982 		    sizeof *resp_ca_cert, "smtp:ca_cert");
983 		ssl_ctx = dict_get(env->sc_ssl_dict, resp_ca_cert->name);
984 		ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY);
985 		io_set_read(&s->io);
986 		io_start_tls(&s->io, ssl);
987 
988 		explicit_bzero(resp_ca_cert->cert, resp_ca_cert->cert_len);
989 		free(resp_ca_cert->cert);
990 		free(resp_ca_cert);
991 		return;
992 
993 	case IMSG_SMTP_TLS_VERIFY:
994 		resp_ca_vrfy = imsg->data;
995 		s = tree_xpop(&wait_ssl_verify, resp_ca_vrfy->reqid);
996 
997 		if (resp_ca_vrfy->status == CA_OK)
998 			s->flags |= SF_VERIFIED;
999 		else if (s->listener->flags & F_TLS_VERIFY) {
1000 			log_info("%016"PRIx64" smtp "
1001 			    "event=closed address=%s host=%s reason=cert-check-failed",
1002 			    s->id, ss_to_text(&s->ss), s->hostname);
1003 			smtp_free(s, "SSL certificate check failed");
1004 			return;
1005 		}
1006 		smtp_io(&s->io, IO_TLSVERIFIED);
1007 		io_resume(&s->io, IO_PAUSE_IN);
1008 		return;
1009 	}
1010 
1011 	log_warnx("smtp_session_imsg: unexpected %s imsg",
1012 	    imsg_to_str(imsg->hdr.type));
1013 	fatalx(NULL);
1014 }
1015 
1016 void
1017 smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
1018     const char *line)
1019 {
1020 	struct smtp_session	*s;
1021 	struct ca_cert_req_msg	 req_ca_cert;
1022 
1023 	s = tree_xpop(&wait_filter, id);
1024 
1025 	if (status == FILTER_CLOSE) {
1026 		code = code ? code : 421;
1027 		line = line ? line : "Temporary failure";
1028 		smtp_reply(s, "%d %s", code, line);
1029 		smtp_enter_state(s, STATE_QUIT);
1030 		io_reload(&s->io);
1031 		return;
1032 	}
1033 
1034 	switch (query) {
1035 
1036 	case QUERY_CONNECT:
1037 		if (status != FILTER_OK) {
1038 			log_info("%016"PRIx64" smtp "
1039 			    "event=closed address=%s host=%s reason=filter-reject",
1040 			    s->id, ss_to_text(&s->ss), s->hostname);
1041 			smtp_free(s, "rejected by filter");
1042 			return;
1043 		}
1044 
1045 		if (s->listener->flags & F_SMTPS) {
1046 			req_ca_cert.reqid = s->id;
1047 			if (s->listener->pki_name[0]) {
1048 				(void)strlcpy(req_ca_cert.name, s->listener->pki_name,
1049 				    sizeof req_ca_cert.name);
1050 				req_ca_cert.fallback = 0;
1051 			}
1052 			else {
1053 				(void)strlcpy(req_ca_cert.name, s->smtpname,
1054 				    sizeof req_ca_cert.name);
1055 				req_ca_cert.fallback = 1;
1056 			}
1057 			m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1,
1058 			    &req_ca_cert, sizeof(req_ca_cert));
1059 			tree_xset(&wait_ssl_init, s->id, s);
1060 			return;
1061 		}
1062 		smtp_send_banner(s);
1063 		return;
1064 
1065 	case QUERY_HELO:
1066 		if (status != FILTER_OK) {
1067 			code = code ? code : 530;
1068 			line = line ? line : "Hello rejected";
1069 			smtp_reply(s, "%d %s", code, line);
1070 			io_reload(&s->io);
1071 			return;
1072 		}
1073 
1074 		smtp_enter_state(s, STATE_HELO);
1075 		smtp_reply(s, "250%c%s Hello %s [%s], pleased to meet you",
1076 		    (s->flags & SF_EHLO) ? '-' : ' ',
1077 		    s->smtpname,
1078 		    s->helo,
1079 		    ss_to_text(&s->ss));
1080 
1081 		if (s->flags & SF_EHLO) {
1082 			smtp_reply(s, "250-8BITMIME");
1083 			smtp_reply(s, "250-ENHANCEDSTATUSCODES");
1084 			smtp_reply(s, "250-SIZE %zu", env->sc_maxsize);
1085 			if (ADVERTISE_EXT_DSN(s))
1086 				smtp_reply(s, "250-DSN");
1087 			if (ADVERTISE_TLS(s))
1088 				smtp_reply(s, "250-STARTTLS");
1089 			if (ADVERTISE_AUTH(s))
1090 				smtp_reply(s, "250-AUTH PLAIN LOGIN");
1091 			smtp_reply(s, "250 HELP");
1092 		}
1093 		s->phase = PHASE_SETUP;
1094 		io_reload(&s->io);
1095 		return;
1096 
1097 	case QUERY_MAIL:
1098 		if (status != FILTER_OK) {
1099 			smtp_filter_tx_rollback(s);
1100 			smtp_tx_free(s->tx);
1101 			code = code ? code : 530;
1102 			line = line ? line : "Sender rejected";
1103 			smtp_reply(s, "%d %s", code, line);
1104 			io_reload(&s->io);
1105 			return;
1106 		}
1107 
1108 		/* only check sendertable if defined and user has authenticated */
1109 		if (s->flags & SF_AUTHENTICATED && s->listener->sendertable[0]) {
1110 			m_create(p_lka, IMSG_SMTP_CHECK_SENDER, 0, 0, -1);
1111 			m_add_id(p_lka, s->id);
1112 			m_add_string(p_lka, s->listener->sendertable);
1113 			m_add_string(p_lka, s->username);
1114 			m_add_mailaddr(p_lka, &s->tx->evp.sender);
1115 			m_close(p_lka);
1116 			tree_xset(&wait_lka_mail, s->id, s);
1117 		}
1118 		else
1119 			smtp_queue_create_message(s);
1120 		return;
1121 
1122 	case QUERY_RCPT:
1123 		if (status != FILTER_OK) {
1124 			code = code ? code : 530;
1125 			line = line ? line : "Recipient rejected";
1126 			smtp_reply(s, "%d %s", code, line);
1127 			io_reload(&s->io);
1128 			return;
1129 		}
1130 
1131 		m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1);
1132 		m_add_id(p_lka, s->id);
1133 		m_add_envelope(p_lka, &s->tx->evp);
1134 		m_close(p_lka);
1135 		tree_xset(&wait_lka_rcpt, s->id, s);
1136 		return;
1137 
1138 	case QUERY_DATA:
1139 		if (status != FILTER_OK) {
1140 			code = code ? code : 530;
1141 			line = line ? line : "Message rejected";
1142 			smtp_reply(s, "%d %s", code, line);
1143 			io_reload(&s->io);
1144 			return;
1145 		}
1146 		smtp_queue_open_message(s);
1147 		return;
1148 
1149 	case QUERY_EOM:
1150 		if (status != FILTER_OK) {
1151 			tree_pop(&wait_filter_data, s->id);
1152 			smtp_filter_tx_rollback(s);
1153 			smtp_queue_rollback(s);
1154 			smtp_tx_free(s->tx);
1155 			code = code ? code : 530;
1156 			line = line ? line : "Message rejected";
1157 			smtp_reply(s, "%d %s", code, line);
1158 			smtp_enter_state(s, STATE_HELO);
1159 			io_reload(&s->io);
1160 			return;
1161 		}
1162 		smtp_message_end(s);
1163 		return;
1164 
1165 	default:
1166 		log_warn("smtp: bad mfa query type %d", query);
1167 	}
1168 }
1169 
1170 void
1171 smtp_filter_fd(uint64_t id, int fd)
1172 {
1173 	struct smtp_session	*s;
1174 	X509			*x;
1175 
1176 	s = tree_xpop(&wait_filter, id);
1177 
1178 	log_debug("smtp: %p: fd %d from filter", s, fd);
1179 
1180 	if (fd == -1) {
1181 		smtp_reply(s, "421 %s: Temporary Error",
1182 		    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1183 		smtp_enter_state(s, STATE_QUIT);
1184 		io_reload(&s->io);
1185 		return;
1186 	}
1187 
1188 	iobuf_init(&s->tx->obuf, 0, 0);
1189 	io_set_nonblocking(fd);
1190 	io_init(&s->tx->oev, fd, s, smtp_data_io, &s->tx->obuf);
1191 
1192 	iobuf_fqueue(&s->tx->obuf, "Received: ");
1193 	if (!(s->listener->flags & F_MASK_SOURCE)) {
1194 		iobuf_fqueue(&s->tx->obuf, "from %s (%s [%s])",
1195 		    s->helo,
1196 		    s->hostname,
1197 		    ss_to_text(&s->ss));
1198 	}
1199 	iobuf_fqueue(&s->tx->obuf, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
1200 	    s->smtpname,
1201 	    SMTPD_NAME,
1202 	    s->flags & SF_EHLO ? "E" : "",
1203 	    s->flags & SF_SECURE ? "S" : "",
1204 	    s->flags & SF_AUTHENTICATED ? "A" : "",
1205 	    s->tx->msgid);
1206 
1207 	if (s->flags & SF_SECURE) {
1208 		x = SSL_get_peer_certificate(s->io.ssl);
1209 		iobuf_fqueue(&s->tx->obuf,
1210 		    " (%s:%s:%d:%s)",
1211 		    SSL_get_version(s->io.ssl),
1212 		    SSL_get_cipher_name(s->io.ssl),
1213 		    SSL_get_cipher_bits(s->io.ssl, NULL),
1214 		    (s->flags & SF_VERIFIED) ? "YES" : (x ? "FAIL" : "NO"));
1215 		if (x)
1216 			X509_free(x);
1217 
1218 		if (s->listener->flags & F_RECEIVEDAUTH) {
1219 			iobuf_fqueue(&s->tx->obuf, " auth=%s", s->username[0] ? "yes" : "no");
1220 			if (s->username[0])
1221 				iobuf_fqueue(&s->tx->obuf, " user=%s", s->username);
1222 		}
1223 	}
1224 
1225 	if (s->tx->rcptcount == 1) {
1226 		iobuf_fqueue(&s->tx->obuf, "\n\tfor <%s@%s>",
1227 		    s->tx->evp.rcpt.user,
1228 		    s->tx->evp.rcpt.domain);
1229 	}
1230 
1231 	iobuf_fqueue(&s->tx->obuf, ";\n\t%s\n", time_to_text(time(NULL)));
1232 
1233 	s->tx->odatalen = iobuf_queued(&s->tx->obuf);
1234 
1235 	io_set_write(&s->tx->oev);
1236 
1237 	smtp_enter_state(s, STATE_BODY);
1238 	smtp_reply(s, "354 Enter mail, end with \".\""
1239 	    " on a line by itself");
1240 
1241 	tree_xset(&wait_filter_data, s->id, s);
1242 	io_reload(&s->io);
1243 }
1244 
1245 static void
1246 smtp_io(struct io *io, int evt)
1247 {
1248 	struct ca_cert_req_msg	req_ca_cert;
1249 	struct smtp_session    *s = io->arg;
1250 	char		       *line;
1251 	size_t			len;
1252 	X509		       *x;
1253 
1254 	log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt),
1255 	    io_strio(io));
1256 
1257 	switch (evt) {
1258 
1259 	case IO_TLSREADY:
1260 		log_info("%016"PRIx64" smtp event=starttls address=%s host=%s ciphers=\"%s\"",
1261 		    s->id, ss_to_text(&s->ss), s->hostname, ssl_to_text(s->io.ssl));
1262 
1263 		s->flags |= SF_SECURE;
1264 		s->phase = PHASE_INIT;
1265 
1266 		if (smtp_verify_certificate(s)) {
1267 			io_pause(&s->io, IO_PAUSE_IN);
1268 			break;
1269 		}
1270 
1271 		if (s->listener->flags & F_TLS_VERIFY) {
1272 			log_info("%016"PRIx64" smtp "
1273 			    "event=closed address=%s host=%s reason=no-client-cert",
1274 			    s->id, ss_to_text(&s->ss), s->hostname);
1275 			smtp_free(s, "client did not present certificate");
1276 			return;
1277 		}
1278 
1279 		/* No verification required, cascade */
1280 
1281 	case IO_TLSVERIFIED:
1282 		x = SSL_get_peer_certificate(s->io.ssl);
1283 		if (x) {
1284 			log_info("%016"PRIx64" smtp "
1285 			    "event=client-cert-check address=%s host=%s result=\"%s\"",
1286 			    s->id, ss_to_text(&s->ss), s->hostname,
1287 			    (s->flags & SF_VERIFIED) ? "success" : "failure");
1288 			X509_free(x);
1289 		}
1290 
1291 		if (s->listener->flags & F_SMTPS) {
1292 			stat_increment("smtp.smtps", 1);
1293 			io_set_write(&s->io);
1294 			smtp_send_banner(s);
1295 		}
1296 		else {
1297 			stat_increment("smtp.tls", 1);
1298 			smtp_enter_state(s, STATE_HELO);
1299 		}
1300 		break;
1301 
1302 	case IO_DATAIN:
1303 	    nextline:
1304 		line = iobuf_getline(&s->iobuf, &len);
1305 		if ((line == NULL && iobuf_len(&s->iobuf) >= LINE_MAX) ||
1306 		    (line && len >= LINE_MAX)) {
1307 			s->flags |= SF_BADINPUT;
1308 			smtp_reply(s, "500 %s: Line too long",
1309 			    esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_STATUS));
1310 			smtp_enter_state(s, STATE_QUIT);
1311 			io_set_write(io);
1312 			return;
1313 		}
1314 
1315 		/* No complete line received */
1316 		if (line == NULL) {
1317 			iobuf_normalize(&s->iobuf);
1318 			return;
1319 		}
1320 
1321 		/* Message body */
1322 		if (s->state == STATE_BODY && strcmp(line, ".")) {
1323 			smtp_filter_dataline(s, line);
1324 			goto nextline;
1325 		}
1326 
1327 		/* Pipelining not supported */
1328 		if (iobuf_len(&s->iobuf)) {
1329 			s->flags |= SF_BADINPUT;
1330 			smtp_reply(s, "500 %s %s: Pipelining not supported",
1331 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1332 			    esc_description(ESC_INVALID_COMMAND));
1333 			smtp_enter_state(s, STATE_QUIT);
1334 			io_set_write(io);
1335 			return;
1336 		}
1337 
1338 		/* End of body */
1339 		if (s->state == STATE_BODY) {
1340 			log_trace(TRACE_SMTP, "<<< [EOM]");
1341 
1342 			rfc2822_parser_flush(&s->tx->rfc2822_parser);
1343 
1344 			iobuf_normalize(&s->iobuf);
1345 			io_set_write(io);
1346 
1347 			s->tx->dataeom = 1;
1348 			if (iobuf_queued(&s->tx->obuf) == 0)
1349 				smtp_data_io_done(s);
1350 			return;
1351 		}
1352 
1353 		/* Must be a command */
1354 		(void)strlcpy(s->cmd, line, sizeof s->cmd);
1355 		io_set_write(io);
1356 		smtp_command(s, line);
1357 		iobuf_normalize(&s->iobuf);
1358 		break;
1359 
1360 	case IO_LOWAT:
1361 		if (s->state == STATE_QUIT) {
1362 			log_info("%016"PRIx64" smtp event=closed address=%s host=%s "
1363 			    "reason=quit",
1364 			    s->id, ss_to_text(&s->ss), s->hostname);
1365 			smtp_free(s, "done");
1366 			break;
1367 		}
1368 
1369 		/* Wait for the client to start tls */
1370 		if (s->state == STATE_TLS) {
1371 			req_ca_cert.reqid = s->id;
1372 
1373 			if (s->listener->pki_name[0]) {
1374 				(void)strlcpy(req_ca_cert.name, s->listener->pki_name,
1375 				    sizeof req_ca_cert.name);
1376 				req_ca_cert.fallback = 0;
1377 			}
1378 			else {
1379 				(void)strlcpy(req_ca_cert.name, s->smtpname,
1380 				    sizeof req_ca_cert.name);
1381 				req_ca_cert.fallback = 1;
1382 			}
1383 			m_compose(p_lka, IMSG_SMTP_TLS_INIT, 0, 0, -1,
1384 			    &req_ca_cert, sizeof(req_ca_cert));
1385 			tree_xset(&wait_ssl_init, s->id, s);
1386 			break;
1387 		}
1388 
1389 		io_set_read(io);
1390 		break;
1391 
1392 	case IO_TIMEOUT:
1393 		log_info("%016"PRIx64" smtp event=closed address=%s host=%s "
1394 		    "reason=timeout",
1395 		    s->id, ss_to_text(&s->ss), s->hostname);
1396 		smtp_free(s, "timeout");
1397 		break;
1398 
1399 	case IO_DISCONNECTED:
1400 		log_info("%016"PRIx64" smtp event=closed address=%s host=%s "
1401 		    "reason=disconnect",
1402 		    s->id, ss_to_text(&s->ss), s->hostname);
1403 		smtp_free(s, "disconnected");
1404 		break;
1405 
1406 	case IO_ERROR:
1407 		log_info("%016"PRIx64" smtp event=closed address=%s host=%s "
1408 		    "reason=\"io-error: %s\"",
1409 		    s->id, ss_to_text(&s->ss), s->hostname, io->error);
1410 		smtp_free(s, "IO error");
1411 		break;
1412 
1413 	default:
1414 		fatalx("smtp_io()");
1415 	}
1416 }
1417 
1418 static int
1419 smtp_tx(struct smtp_session *s)
1420 {
1421 	struct smtp_tx *tx;
1422 
1423 	tx = calloc(1, sizeof(*tx));
1424 	if (tx == NULL)
1425 		return 0;
1426 
1427 	TAILQ_INIT(&tx->rcpts);
1428 	io_init(&tx->oev, -1, s, NULL, NULL); /* initialise 'sock', but not to 0 */
1429 
1430 	s->tx = tx;
1431 	tx->session = s;
1432 
1433 	/* setup the envelope */
1434 	s->tx->evp.ss = s->ss;
1435 	(void)strlcpy(s->tx->evp.tag, s->listener->tag, sizeof(s->tx->evp.tag));
1436 	(void)strlcpy(s->tx->evp.smtpname, s->smtpname, sizeof(s->tx->evp.smtpname));
1437 	(void)strlcpy(s->tx->evp.hostname, s->hostname, sizeof s->tx->evp.hostname);
1438 	(void)strlcpy(s->tx->evp.helo, s->helo, sizeof s->tx->evp.helo);
1439 
1440 	if (s->flags & SF_BOUNCE)
1441 		s->tx->evp.flags |= EF_BOUNCE;
1442 	if (s->flags & SF_AUTHENTICATED)
1443 		s->tx->evp.flags |= EF_AUTHENTICATED;
1444 
1445 	/* Setup parser and callbacks */
1446 	rfc2822_parser_init(&tx->rfc2822_parser);
1447 	rfc2822_header_default_callback(&tx->rfc2822_parser,
1448 	    header_default_callback, s);
1449 	rfc2822_header_callback(&tx->rfc2822_parser, "bcc",
1450 	    header_bcc_callback, s);
1451 	rfc2822_header_callback(&tx->rfc2822_parser, "from",
1452 	    header_domain_append_callback, s);
1453 	rfc2822_header_callback(&tx->rfc2822_parser, "to",
1454 	    header_domain_append_callback, s);
1455 	rfc2822_header_callback(&tx->rfc2822_parser, "cc",
1456 	    header_domain_append_callback, s);
1457 	rfc2822_body_callback(&tx->rfc2822_parser,
1458 	    dataline_callback, s);
1459 
1460 	if (s->listener->local || s->listener->port == 587) {
1461 		rfc2822_missing_header_callback(&tx->rfc2822_parser, "date",
1462 		    header_missing_callback, s);
1463 		rfc2822_missing_header_callback(&tx->rfc2822_parser, "message-id",
1464 		    header_missing_callback, s);
1465 	}
1466 
1467 	return 1;
1468 }
1469 
1470 static void
1471 smtp_tx_free(struct smtp_tx *tx)
1472 {
1473 	struct smtp_rcpt *rcpt;
1474 
1475 	rfc2822_parser_release(&tx->rfc2822_parser);
1476 
1477 	while ((rcpt = TAILQ_FIRST(&tx->rcpts))) {
1478 		TAILQ_REMOVE(&tx->rcpts, rcpt, entry);
1479 		free(rcpt);
1480 	}
1481 
1482 	tx->session->tx = NULL;
1483 
1484 	free(tx);
1485 }
1486 
1487 static void
1488 smtp_data_io(struct io *io, int evt)
1489 {
1490 	struct smtp_session    *s = io->arg;
1491 
1492 	log_trace(TRACE_IO, "smtp: %p (data): %s %s", s, io_strevent(evt),
1493 	    io_strio(io));
1494 
1495 	switch (evt) {
1496 	case IO_TIMEOUT:
1497 	case IO_DISCONNECTED:
1498 	case IO_ERROR:
1499 		log_debug("debug: smtp: %p: io error on mfa", s);
1500 		io_clear(&s->tx->oev);
1501 		iobuf_clear(&s->tx->obuf);
1502 		s->tx->msgflags |= MF_ERROR_IO;
1503 		if (s->io.flags & IO_PAUSE_IN) {
1504 			log_debug("debug: smtp: %p: resuming session after mfa error", s);
1505 			io_resume(&s->io, IO_PAUSE_IN);
1506 		}
1507 		break;
1508 
1509 	case IO_LOWAT:
1510 		if (s->tx->dataeom && iobuf_queued(&s->tx->obuf) == 0) {
1511 			smtp_data_io_done(s);
1512 		} else if (s->io.flags & IO_PAUSE_IN) {
1513 			log_debug("debug: smtp: %p: filter congestion over: resuming session", s);
1514 			io_resume(&s->io, IO_PAUSE_IN);
1515 		}
1516 		break;
1517 
1518 	default:
1519 		fatalx("smtp_data_io()");
1520 	}
1521 }
1522 
1523 static void
1524 smtp_data_io_done(struct smtp_session *s)
1525 {
1526 	log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->tx->odatalen);
1527 	io_clear(&s->tx->oev);
1528 	iobuf_clear(&s->tx->obuf);
1529 
1530 	if (s->tx->msgflags & MF_ERROR) {
1531 
1532 		tree_pop(&wait_filter_data, s->id);
1533 
1534 		smtp_filter_tx_rollback(s);
1535 		smtp_queue_rollback(s);
1536 
1537 		if (s->tx->msgflags & MF_ERROR_SIZE)
1538 			smtp_reply(s, "554 Message too big");
1539 		else if (s->tx->msgflags & MF_ERROR_LOOP)
1540 			smtp_reply(s, "500 %s %s: Loop detected",
1541 				esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED),
1542 				esc_description(ESC_ROUTING_LOOP_DETECTED));
1543                 else if (s->tx->msgflags & MF_ERROR_RESOURCES)
1544                         smtp_reply(s, "421 %s: Temporary Error",
1545                             esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1546                 else if (s->tx->msgflags & MF_ERROR_MALFORMED)
1547                         smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant",
1548                             esc_code(ESC_STATUS_PERMFAIL,
1549 				ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED),
1550                             esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED));
1551 		else if (s->tx->msgflags)
1552 			smtp_reply(s, "421 Internal server error");
1553 		smtp_tx_free(s->tx);
1554 		smtp_enter_state(s, STATE_HELO);
1555 		io_reload(&s->io);
1556 	}
1557 	else {
1558 		smtp_filter_eom(s);
1559 	}
1560 }
1561 
1562 static void
1563 smtp_command(struct smtp_session *s, char *line)
1564 {
1565 	char			       *args, *eom, *method;
1566 	int				cmd, i;
1567 
1568 	log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line);
1569 
1570 	/*
1571 	 * These states are special.
1572 	 */
1573 	if (s->state == STATE_AUTH_INIT) {
1574 		smtp_rfc4954_auth_plain(s, line);
1575 		return;
1576 	}
1577 	if (s->state == STATE_AUTH_USERNAME || s->state == STATE_AUTH_PASSWORD) {
1578 		smtp_rfc4954_auth_login(s, line);
1579 		return;
1580 	}
1581 
1582 	/*
1583 	 * Unlike other commands, "mail from" and "rcpt to" contain a
1584 	 * space in the command name.
1585 	 */
1586 	if (strncasecmp("mail from:", line, 10) == 0 ||
1587 	    strncasecmp("rcpt to:", line, 8) == 0)
1588 		args = strchr(line, ':');
1589 	else
1590 		args = strchr(line, ' ');
1591 
1592 	if (args) {
1593 		*args++ = '\0';
1594 		while (isspace((unsigned char)*args))
1595 			args++;
1596 	}
1597 
1598 	cmd = -1;
1599 	for (i = 0; commands[i].code != -1; i++)
1600 		if (!strcasecmp(line, commands[i].cmd)) {
1601 			cmd = commands[i].code;
1602 			break;
1603 		}
1604 
1605 	switch (cmd) {
1606 	/*
1607 	 * INIT
1608 	 */
1609 	case CMD_HELO:
1610 	case CMD_EHLO:
1611 		if (s->phase != PHASE_INIT) {
1612 			smtp_reply(s, "503 %s %s: Already identified",
1613 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1614 			    esc_description(ESC_INVALID_COMMAND));
1615 			break;
1616 		}
1617 
1618 		if (args == NULL) {
1619 			smtp_reply(s, "501 %s %s: %s requires domain name",
1620 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1621 			    esc_description(ESC_INVALID_COMMAND),
1622 			    (cmd == CMD_HELO) ? "HELO" : "EHLO");
1623 
1624 			break;
1625 		}
1626 
1627 		if (!valid_domainpart(args)) {
1628 			smtp_reply(s, "501 %s %s: Invalid domain name",
1629 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1630 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1631 			break;
1632 		}
1633 		(void)strlcpy(s->helo, args, sizeof(s->helo));
1634 		s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED | SF_FILTERCONN;
1635 		if (cmd == CMD_EHLO) {
1636 			s->flags |= SF_EHLO;
1637 			s->flags |= SF_8BITMIME;
1638 		}
1639 
1640 		smtp_filter_helo(s);
1641 		break;
1642 	/*
1643 	 * SETUP
1644 	 */
1645 	case CMD_STARTTLS:
1646 		if (s->phase != PHASE_SETUP) {
1647 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1648 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1649 			    esc_description(ESC_INVALID_COMMAND));
1650 			break;
1651 		}
1652 
1653 		if (!(s->listener->flags & F_STARTTLS)) {
1654 			smtp_reply(s, "503 %s %s: Command not supported",
1655 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1656 			    esc_description(ESC_INVALID_COMMAND));
1657 			break;
1658 		}
1659 
1660 		if (s->flags & SF_SECURE) {
1661 			smtp_reply(s, "503 %s %s: Channel already secured",
1662 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1663 			    esc_description(ESC_INVALID_COMMAND));
1664 			break;
1665 		}
1666 		if (args != NULL) {
1667 			smtp_reply(s, "501 %s %s: No parameters allowed",
1668 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1669 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1670 			break;
1671 		}
1672 		smtp_reply(s, "220 %s: Ready to start TLS",
1673 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1674 		smtp_enter_state(s, STATE_TLS);
1675 		break;
1676 
1677 	case CMD_AUTH:
1678 		if (s->phase != PHASE_SETUP) {
1679 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1680 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1681 			    esc_description(ESC_INVALID_COMMAND));
1682 			break;
1683 		}
1684 
1685 		if (s->flags & SF_AUTHENTICATED) {
1686 			smtp_reply(s, "503 %s %s: Already authenticated",
1687 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1688 			    esc_description(ESC_INVALID_COMMAND));
1689 			break;
1690 		}
1691 
1692 		if (!ADVERTISE_AUTH(s)) {
1693 			smtp_reply(s, "503 %s %s: Command not supported",
1694 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1695 			    esc_description(ESC_INVALID_COMMAND));
1696 			break;
1697 		}
1698 
1699 		if (args == NULL) {
1700 			smtp_reply(s, "501 %s %s: No parameters given",
1701 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1702 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1703 			break;
1704 		}
1705 
1706 		method = args;
1707 		eom = strchr(args, ' ');
1708 		if (eom == NULL)
1709 			eom = strchr(args, '\t');
1710 		if (eom != NULL)
1711 			*eom++ = '\0';
1712 		if (strcasecmp(method, "PLAIN") == 0)
1713 			smtp_rfc4954_auth_plain(s, eom);
1714 		else if (strcasecmp(method, "LOGIN") == 0)
1715 			smtp_rfc4954_auth_login(s, eom);
1716 		else
1717 			smtp_reply(s, "504 %s %s: AUTH method \"%s\" not supported",
1718 			    esc_code(ESC_STATUS_PERMFAIL, ESC_SECURITY_FEATURES_NOT_SUPPORTED),
1719 			    esc_description(ESC_SECURITY_FEATURES_NOT_SUPPORTED),
1720 			    method);
1721 		break;
1722 
1723 	case CMD_MAIL_FROM:
1724 		if (s->phase != PHASE_SETUP) {
1725 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1726 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1727 			    esc_description(ESC_INVALID_COMMAND));
1728 
1729 			break;
1730 		}
1731 
1732 		if (s->listener->flags & F_STARTTLS_REQUIRE &&
1733 		    !(s->flags & SF_SECURE)) {
1734 			smtp_reply(s,
1735 			    "530 %s %s: Must issue a STARTTLS command first",
1736 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1737 			    esc_description(ESC_INVALID_COMMAND));
1738 			break;
1739 		}
1740 
1741 		if (s->listener->flags & F_AUTH_REQUIRE &&
1742 		    !(s->flags & SF_AUTHENTICATED)) {
1743 			smtp_reply(s,
1744 			    "530 %s %s: Must issue an AUTH command first",
1745 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1746 			    esc_description(ESC_INVALID_COMMAND));
1747 			break;
1748 		}
1749 
1750 		if (s->mailcount >= env->sc_session_max_mails) {
1751 			/* we can pretend we had too many recipients */
1752 			smtp_reply(s, "452 %s %s: Too many messages sent",
1753 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS),
1754 			    esc_description(ESC_TOO_MANY_RECIPIENTS));
1755 			break;
1756 		}
1757 
1758 		if (!smtp_tx(s)) {
1759 			smtp_reply(s, "421 %s: Temporary Error",
1760 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
1761 			smtp_enter_state(s, STATE_QUIT);
1762 			break;
1763 		}
1764 
1765 		if (smtp_mailaddr(&s->tx->evp.sender, args, 1, &args,
1766 			s->smtpname) == 0) {
1767 			smtp_tx_free(s->tx);
1768 			smtp_reply(s, "553 %s: Sender address syntax error",
1769 			    esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS));
1770 			break;
1771 		}
1772 		if (args && smtp_parse_mail_args(s, args) == -1) {
1773 			smtp_tx_free(s->tx);
1774 			break;
1775 		}
1776 
1777 		smtp_filter_tx_begin(s);
1778 		smtp_filter_mail(s);
1779 		break;
1780 	/*
1781 	 * TRANSACTION
1782 	 */
1783 	case CMD_RCPT_TO:
1784 		if (s->phase != PHASE_TRANSACTION) {
1785 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1786 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1787 			    esc_description(ESC_INVALID_COMMAND));
1788 			break;
1789 		}
1790 
1791 		if (s->tx->rcptcount >= env->sc_session_max_rcpt) {
1792 			smtp_reply(s, "451 %s %s: Too many recipients",
1793 			    esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS),
1794 			    esc_description(ESC_TOO_MANY_RECIPIENTS));
1795 			break;
1796 		}
1797 
1798 		if (smtp_mailaddr(&s->tx->evp.rcpt, args, 0, &args,
1799 		    s->smtpname) == 0) {
1800 			smtp_reply(s,
1801 			    "501 %s: Recipient address syntax error",
1802 			    esc_code(ESC_STATUS_PERMFAIL, ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX));
1803 			break;
1804 		}
1805 		if (args && smtp_parse_rcpt_args(s, args) == -1)
1806 			break;
1807 
1808 		smtp_filter_rcpt(s);
1809 		break;
1810 
1811 	case CMD_RSET:
1812 		if (s->phase != PHASE_TRANSACTION && s->phase != PHASE_SETUP) {
1813 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1814 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1815 			    esc_description(ESC_INVALID_COMMAND));
1816 			break;
1817 		}
1818 
1819 		if (s->tx) {
1820 			smtp_filter_tx_rollback(s);
1821 			if (s->tx->msgid)
1822 				smtp_queue_rollback(s);
1823 			smtp_tx_free(s->tx);
1824 		}
1825 
1826 		smtp_filter_rset(s);
1827 
1828 		s->phase = PHASE_SETUP;
1829 		smtp_reply(s, "250 %s: Reset state",
1830 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1831 		break;
1832 
1833 	case CMD_DATA:
1834 		if (s->phase != PHASE_TRANSACTION) {
1835 			smtp_reply(s, "503 %s %s: Command not allowed at this point.",
1836 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1837 			    esc_description(ESC_INVALID_COMMAND));
1838 			break;
1839 		}
1840 		if (s->tx->rcptcount == 0) {
1841 			smtp_reply(s, "503 %s %s: No recipient specified",
1842 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
1843 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
1844 			break;
1845 		}
1846 
1847 		smtp_filter_data(s);
1848 		break;
1849 	/*
1850 	 * ANY
1851 	 */
1852 	case CMD_QUIT:
1853 		smtp_reply(s, "221 %s: Bye",
1854 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1855 		smtp_enter_state(s, STATE_QUIT);
1856 		break;
1857 
1858 	case CMD_NOOP:
1859 		smtp_reply(s, "250 %s: Ok",
1860 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1861 		break;
1862 
1863 	case CMD_HELP:
1864 		smtp_reply(s, "214- This is " SMTPD_NAME);
1865 		smtp_reply(s, "214- To report bugs in the implementation, "
1866 		    "please contact bugs@openbsd.org");
1867 		smtp_reply(s, "214- with full details");
1868 		smtp_reply(s, "214 %s: End of HELP info",
1869 		    esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
1870 		break;
1871 
1872 	case CMD_WIZ:
1873 		smtp_reply(s, "500 %s %s: this feature is not supported yet ;-)",
1874 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1875 			    esc_description(ESC_INVALID_COMMAND));
1876 		break;
1877 
1878 	default:
1879 		smtp_reply(s, "500 %s %s: Command unrecognized",
1880 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND),
1881 			    esc_description(ESC_INVALID_COMMAND));
1882 		break;
1883 	}
1884 }
1885 
1886 static void
1887 smtp_rfc4954_auth_plain(struct smtp_session *s, char *arg)
1888 {
1889 	char		 buf[1024], *user, *pass;
1890 	int		 len;
1891 
1892 	switch (s->state) {
1893 	case STATE_HELO:
1894 		if (arg == NULL) {
1895 			smtp_enter_state(s, STATE_AUTH_INIT);
1896 			smtp_reply(s, "334 ");
1897 			return;
1898 		}
1899 		smtp_enter_state(s, STATE_AUTH_INIT);
1900 		/* FALLTHROUGH */
1901 
1902 	case STATE_AUTH_INIT:
1903 		/* String is not NUL terminated, leave room. */
1904 		if ((len = base64_decode(arg, (unsigned char *)buf,
1905 			    sizeof(buf) - 1)) == -1)
1906 			goto abort;
1907 		/* buf is a byte string, NUL terminate. */
1908 		buf[len] = '\0';
1909 
1910 		/*
1911 		 * Skip "foo" in "foo\0user\0pass", if present.
1912 		 */
1913 		user = memchr(buf, '\0', len);
1914 		if (user == NULL || user >= buf + len - 2)
1915 			goto abort;
1916 		user++; /* skip NUL */
1917 		if (strlcpy(s->username, user, sizeof(s->username))
1918 		    >= sizeof(s->username))
1919 			goto abort;
1920 
1921 		pass = memchr(user, '\0', len - (user - buf));
1922 		if (pass == NULL || pass >= buf + len - 2)
1923 			goto abort;
1924 		pass++; /* skip NUL */
1925 
1926 		m_create(p_lka,  IMSG_SMTP_AUTHENTICATE, 0, 0, -1);
1927 		m_add_id(p_lka, s->id);
1928 		m_add_string(p_lka, s->listener->authtable);
1929 		m_add_string(p_lka, user);
1930 		m_add_string(p_lka, pass);
1931 		m_close(p_lka);
1932 		tree_xset(&wait_parent_auth, s->id, s);
1933 		return;
1934 
1935 	default:
1936 		fatal("smtp_rfc4954_auth_plain: unknown state");
1937 	}
1938 
1939 abort:
1940 	smtp_reply(s, "501 %s %s: Syntax error",
1941 	    esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR),
1942 	    esc_description(ESC_SYNTAX_ERROR));
1943 	smtp_enter_state(s, STATE_HELO);
1944 }
1945 
1946 static void
1947 smtp_rfc4954_auth_login(struct smtp_session *s, char *arg)
1948 {
1949 	char		buf[LINE_MAX];
1950 
1951 	switch (s->state) {
1952 	case STATE_HELO:
1953 		smtp_enter_state(s, STATE_AUTH_USERNAME);
1954 		smtp_reply(s, "334 VXNlcm5hbWU6");
1955 		return;
1956 
1957 	case STATE_AUTH_USERNAME:
1958 		memset(s->username, 0, sizeof(s->username));
1959 		if (base64_decode(arg, (unsigned char *)s->username,
1960 				  sizeof(s->username) - 1) == -1)
1961 			goto abort;
1962 
1963 		smtp_enter_state(s, STATE_AUTH_PASSWORD);
1964 		smtp_reply(s, "334 UGFzc3dvcmQ6");
1965 		return;
1966 
1967 	case STATE_AUTH_PASSWORD:
1968 		memset(buf, 0, sizeof(buf));
1969 		if (base64_decode(arg, (unsigned char *)buf,
1970 				  sizeof(buf)-1) == -1)
1971 			goto abort;
1972 
1973 		m_create(p_lka,  IMSG_SMTP_AUTHENTICATE, 0, 0, -1);
1974 		m_add_id(p_lka, s->id);
1975 		m_add_string(p_lka, s->listener->authtable);
1976 		m_add_string(p_lka, s->username);
1977 		m_add_string(p_lka, buf);
1978 		m_close(p_lka);
1979 		tree_xset(&wait_parent_auth, s->id, s);
1980 		return;
1981 
1982 	default:
1983 		fatal("smtp_rfc4954_auth_login: unknown state");
1984 	}
1985 
1986 abort:
1987 	smtp_reply(s, "501 %s %s: Syntax error",
1988 	    esc_code(ESC_STATUS_PERMFAIL, ESC_SYNTAX_ERROR),
1989 	    esc_description(ESC_SYNTAX_ERROR));
1990 	smtp_enter_state(s, STATE_HELO);
1991 }
1992 
1993 static uint8_t
1994 dsn_notify_str_to_uint8(const char *arg)
1995 {
1996 	if (strcasecmp(arg, "SUCCESS") == 0)
1997 		return DSN_SUCCESS;
1998 	else if (strcasecmp(arg, "FAILURE") == 0)
1999 		return DSN_FAILURE;
2000 	else if (strcasecmp(arg, "DELAY") == 0)
2001 		return DSN_DELAY;
2002 	else if (strcasecmp(arg, "NEVER") == 0)
2003 		return DSN_NEVER;
2004 
2005 	return (0);
2006 }
2007 
2008 static int
2009 smtp_parse_rcpt_args(struct smtp_session *s, char *args)
2010 {
2011 	char 	*b, *p;
2012 	uint8_t flag;
2013 
2014 	while ((b = strsep(&args, " "))) {
2015 		if (*b == '\0')
2016 			continue;
2017 
2018 		if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "NOTIFY=", 7) == 0) {
2019 			b += 7;
2020 			while ((p = strsep(&b, ","))) {
2021 				if (*p == '\0')
2022 					continue;
2023 
2024 				if ((flag = dsn_notify_str_to_uint8(p)) == 0)
2025 					continue;
2026 
2027 				s->tx->evp.dsn_notify |= flag;
2028 			}
2029 			if (s->tx->evp.dsn_notify & DSN_NEVER &&
2030 			    s->tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE |
2031 			    DSN_DELAY)) {
2032 				smtp_reply(s,
2033 				    "553 NOTIFY option NEVER cannot be \
2034 				    combined with other options");
2035 				return (-1);
2036 			}
2037 		} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ORCPT=", 6) == 0) {
2038 			b += 6;
2039 			if (!text_to_mailaddr(&s->tx->evp.dsn_orcpt, b)) {
2040 				smtp_reply(s, "553 ORCPT address syntax error");
2041 				return (-1);
2042 			}
2043 		} else {
2044 			smtp_reply(s, "503 Unsupported option %s", b);
2045 			return (-1);
2046 		}
2047 	}
2048 
2049 	return (0);
2050 }
2051 
2052 static int
2053 smtp_parse_mail_args(struct smtp_session *s, char *args)
2054 {
2055 	char *b;
2056 
2057 	while ((b = strsep(&args, " "))) {
2058 		if (*b == '\0')
2059 			continue;
2060 
2061 		if (strncasecmp(b, "AUTH=", 5) == 0)
2062 			log_debug("debug: smtp: AUTH in MAIL FROM command");
2063 		else if (strncasecmp(b, "SIZE=", 5) == 0)
2064 			log_debug("debug: smtp: SIZE in MAIL FROM command");
2065 		else if (strcasecmp(b, "BODY=7BIT") == 0)
2066 			/* XXX only for this transaction */
2067 			s->flags &= ~SF_8BITMIME;
2068 		else if (strcasecmp(b, "BODY=8BITMIME") == 0)
2069 			;
2070 		else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "RET=", 4) == 0) {
2071 			b += 4;
2072 			if (strcasecmp(b, "HDRS") == 0)
2073 				s->tx->evp.dsn_ret = DSN_RETHDRS;
2074 			else if (strcasecmp(b, "FULL") == 0)
2075 				s->tx->evp.dsn_ret = DSN_RETFULL;
2076 		} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ENVID=", 6) == 0) {
2077 			b += 6;
2078 			if (strlcpy(s->tx->evp.dsn_envid, b, sizeof(s->tx->evp.dsn_envid))
2079 			    >= sizeof(s->tx->evp.dsn_envid)) {
2080 				smtp_reply(s, "503 %s %s: option too large, truncated: %s",
2081 				    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
2082 				    esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b);
2083 				return (-1);
2084 			}
2085 		} else {
2086 			smtp_reply(s, "503 %s %s: Unsupported option %s",
2087 			    esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
2088 			    esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b);
2089 			return (-1);
2090 		}
2091 	}
2092 
2093 	return (0);
2094 }
2095 
2096 static int
2097 smtp_lookup_servername(struct smtp_session *s)
2098 {
2099 	struct sockaddr		*sa;
2100 	socklen_t		 sa_len;
2101 	struct sockaddr_storage	 ss;
2102 
2103 	if (s->listener->hostnametable[0]) {
2104 		sa_len = sizeof(ss);
2105 		sa = (struct sockaddr *)&ss;
2106 		if (getsockname(s->io.sock, sa, &sa_len) == -1) {
2107 			log_warn("warn: getsockname()");
2108 		}
2109 		else {
2110 			m_create(p_lka, IMSG_SMTP_LOOKUP_HELO, 0, 0, -1);
2111 			m_add_id(p_lka, s->id);
2112 			m_add_string(p_lka, s->listener->hostnametable);
2113 			m_add_sockaddr(p_lka, sa);
2114 			m_close(p_lka);
2115 			tree_xset(&wait_lka_helo, s->id, s);
2116 			return 0;
2117 		}
2118 	}
2119 	return 1;
2120 }
2121 
2122 static void
2123 smtp_connected(struct smtp_session *s)
2124 {
2125 	struct sockaddr_storage	ss;
2126 	socklen_t		sl;
2127 
2128 	smtp_enter_state(s, STATE_CONNECTED);
2129 
2130 	log_info("%016"PRIx64" smtp event=connected address=%s host=%s",
2131 	    s->id, ss_to_text(&s->ss), s->hostname);
2132 
2133 	sl = sizeof(ss);
2134 	if (getsockname(s->io.sock, (struct sockaddr*)&ss, &sl) == -1) {
2135 		smtp_free(s, strerror(errno));
2136 		return;
2137 	}
2138 
2139 	s->flags |= SF_FILTERCONN;
2140 	smtp_filter_connect(s, (struct sockaddr *)&ss);
2141 }
2142 
2143 static void
2144 smtp_send_banner(struct smtp_session *s)
2145 {
2146 	smtp_reply(s, "220 %s ESMTP %s", s->smtpname, SMTPD_NAME);
2147 	io_reload(&s->io);
2148 }
2149 
2150 void
2151 smtp_enter_state(struct smtp_session *s, int newstate)
2152 {
2153 	log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s,
2154 	    smtp_strstate(s->state),
2155 	    smtp_strstate(newstate));
2156 
2157 	s->state = newstate;
2158 }
2159 
2160 static void
2161 smtp_message_end(struct smtp_session *s)
2162 {
2163 	log_debug("debug: %p: end of message, msgflags=0x%04x", s, s->tx->msgflags);
2164 
2165 	tree_xpop(&wait_filter_data, s->id);
2166 
2167 	s->phase = PHASE_SETUP;
2168 
2169 	if (s->tx->msgflags & MF_ERROR) {
2170 		smtp_filter_tx_rollback(s);
2171 		smtp_queue_rollback(s);
2172 		if (s->tx->msgflags & MF_ERROR_SIZE)
2173 			smtp_reply(s, "554 %s %s: Transaction failed, message too big",
2174 			    esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM),
2175 			    esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM));
2176 		else
2177 			smtp_reply(s, "%d Message rejected", s->tx->msgcode);
2178 		smtp_tx_free(s->tx);
2179 		smtp_enter_state(s, STATE_HELO);
2180 		return;
2181 	}
2182 
2183 	smtp_queue_commit(s);
2184 }
2185 
2186 static int
2187 smtp_message_printf(struct smtp_session *s, const char *fmt, ...)
2188 {
2189 	va_list	ap;
2190 	int	len;
2191 
2192 	if (s->tx->msgflags & MF_ERROR)
2193 		return -1;
2194 
2195 	va_start(ap, fmt);
2196 	len = iobuf_vfqueue(&s->tx->obuf, fmt, ap);
2197 	va_end(ap);
2198 
2199 	if (len < 0) {
2200 		log_warn("smtp-in: session %016"PRIx64": vfprintf", s->id);
2201 		s->tx->msgflags |= MF_ERROR_IO;
2202 	}
2203 	else
2204 		s->tx->odatalen += len;
2205 
2206 	return len;
2207 }
2208 
2209 static void
2210 smtp_reply(struct smtp_session *s, char *fmt, ...)
2211 {
2212 	va_list	 ap;
2213 	int	 n;
2214 	char	 buf[LINE_MAX], tmp[LINE_MAX];
2215 
2216 	va_start(ap, fmt);
2217 	n = vsnprintf(buf, sizeof buf, fmt, ap);
2218 	va_end(ap);
2219 	if (n == -1 || n >= LINE_MAX)
2220 		fatalx("smtp_reply: line too long");
2221 	if (n < 4)
2222 		fatalx("smtp_reply: response too short");
2223 
2224 	log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf);
2225 
2226 	iobuf_xfqueue(&s->iobuf, "smtp_reply", "%s\r\n", buf);
2227 
2228 	switch (buf[0]) {
2229 	case '5':
2230 	case '4':
2231 		if (s->flags & SF_BADINPUT) {
2232 			log_info("%016"PRIx64" smtp "
2233 			    "event=bad-input address=%s host=%s result=\"%.*s\"",
2234 			    s->id, ss_to_text(&s->ss), s->hostname, n, buf);
2235 		}
2236 		else if (s->state == STATE_AUTH_INIT) {
2237 			log_info("%016"PRIx64" smtp "
2238 			    "event=failed-command address=%s host=%s "
2239 			    "command=\"AUTH PLAIN (...)\" result=\"%.*s\"",
2240 			    s->id, ss_to_text(&s->ss), s->hostname, n, buf);
2241 		}
2242 		else if (s->state == STATE_AUTH_USERNAME) {
2243 			log_info("%016"PRIx64" smtp "
2244 			    "event=failed-command address=%s host=%s "
2245 			    "command=\"AUTH LOGIN (username)\" result=\"%.*s\"",
2246 			    s->id, ss_to_text(&s->ss), s->hostname, n, buf);
2247 		}
2248 		else if (s->state == STATE_AUTH_PASSWORD) {
2249 			log_info("%016"PRIx64" smtp "
2250 			    "event=failed-command address=%s host=%s "
2251 			    "command=\"AUTH LOGIN (password)\" result=\"%.*s\"",
2252 			    s->id, ss_to_text(&s->ss), s->hostname, n, buf);
2253 		}
2254 		else {
2255 			strnvis(tmp, s->cmd, sizeof tmp, VIS_SAFE | VIS_CSTYLE);
2256 			log_info("%016"PRIx64" smtp "
2257 			    "event=failed-command address=%s host=%s command=\"%s\" "
2258 			    "result=\"%.*s\"",
2259 			    s->id, ss_to_text(&s->ss), s->hostname, tmp, n, buf);
2260 		}
2261 		break;
2262 	}
2263 }
2264 
2265 static void
2266 smtp_free(struct smtp_session *s, const char * reason)
2267 {
2268 	log_debug("debug: smtp: %p: deleting session: %s", s, reason);
2269 
2270 	tree_pop(&wait_filter_data, s->id);
2271 
2272 	if (s->tx) {
2273 		if (s->tx->msgid) {
2274 			smtp_queue_rollback(s);
2275 			io_clear(&s->tx->oev);
2276 			iobuf_clear(&s->tx->obuf);
2277 		}
2278 		smtp_filter_tx_rollback(s);
2279 		smtp_tx_free(s->tx);
2280 	}
2281 
2282 	if (s->flags & SF_FILTERCONN)
2283 		smtp_filter_disconnect(s);
2284 
2285 	if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS)
2286 		stat_decrement("smtp.smtps", 1);
2287 	if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS)
2288 		stat_decrement("smtp.tls", 1);
2289 
2290 	io_clear(&s->io);
2291 	iobuf_clear(&s->iobuf);
2292 	free(s);
2293 
2294 	smtp_collect();
2295 }
2296 
2297 static int
2298 smtp_mailaddr(struct mailaddr *maddr, char *line, int mailfrom, char **args,
2299     const char *domain)
2300 {
2301 	char   *p, *e;
2302 
2303 	if (line == NULL)
2304 		return (0);
2305 
2306 	if (*line != '<')
2307 		return (0);
2308 
2309 	e = strchr(line, '>');
2310 	if (e == NULL)
2311 		return (0);
2312 	*e++ = '\0';
2313 	while (*e == ' ')
2314 		e++;
2315 	*args = e;
2316 
2317 	if (!text_to_mailaddr(maddr, line + 1))
2318 		return (0);
2319 
2320 	p = strchr(maddr->user, ':');
2321 	if (p != NULL) {
2322 		p++;
2323 		memmove(maddr->user, p, strlen(p) + 1);
2324 	}
2325 
2326 	if (!valid_localpart(maddr->user) ||
2327 	    !valid_domainpart(maddr->domain)) {
2328 		/* accept empty return-path in MAIL FROM, required for bounces */
2329 		if (mailfrom && maddr->user[0] == '\0' && maddr->domain[0] == '\0')
2330 			return (1);
2331 
2332 		/* no user-part, reject */
2333 		if (maddr->user[0] == '\0')
2334 			return (0);
2335 
2336 		/* no domain, local user */
2337 		if (maddr->domain[0] == '\0') {
2338 			(void)strlcpy(maddr->domain, domain,
2339 			    sizeof(maddr->domain));
2340 			return (1);
2341 		}
2342 		return (0);
2343 	}
2344 
2345 	return (1);
2346 }
2347 
2348 static int
2349 smtp_verify_certificate(struct smtp_session *s)
2350 {
2351 #define MAX_CERTS	16
2352 #define MAX_CERT_LEN	(MAX_IMSGSIZE - (IMSG_HEADER_SIZE + sizeof(req_ca_vrfy)))
2353 	struct ca_vrfy_req_msg	req_ca_vrfy;
2354 	struct iovec		iov[2];
2355 	X509		       *x;
2356 	STACK_OF(X509)	       *xchain;
2357 	const char	       *name;
2358 	unsigned char	       *cert_der[MAX_CERTS];
2359 	int			cert_len[MAX_CERTS];
2360 	int			i, cert_count, res;
2361 
2362 	res = 0;
2363 	memset(cert_der, 0, sizeof(cert_der));
2364 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2365 
2366 	/* Send the client certificate */
2367 	if (s->listener->ca_name[0]) {
2368 		name = s->listener->ca_name;
2369 		req_ca_vrfy.fallback = 0;
2370 	}
2371 	else {
2372 		name = s->smtpname;
2373 		req_ca_vrfy.fallback = 1;
2374 	}
2375 
2376 	if (strlcpy(req_ca_vrfy.name, name, sizeof req_ca_vrfy.name)
2377 	    >= sizeof req_ca_vrfy.name)
2378 		return 0;
2379 
2380 	x = SSL_get_peer_certificate(s->io.ssl);
2381 	if (x == NULL)
2382 		return 0;
2383 	xchain = SSL_get_peer_cert_chain(s->io.ssl);
2384 
2385 	/*
2386 	 * Client provided a certificate and possibly a certificate chain.
2387 	 * SMTP can't verify because it does not have the information that
2388 	 * it needs, instead it will pass the certificate and chain to the
2389 	 * lookup process and wait for a reply.
2390 	 *
2391 	 */
2392 
2393 	cert_len[0] = i2d_X509(x, &cert_der[0]);
2394 	X509_free(x);
2395 
2396 	if (cert_len[0] < 0) {
2397 		log_warnx("warn: failed to encode certificate");
2398 		goto end;
2399 	}
2400 	log_debug("debug: certificate 0: len=%d", cert_len[0]);
2401 	if (cert_len[0] > (int)MAX_CERT_LEN) {
2402 		log_warnx("warn: certificate too long");
2403 		goto end;
2404 	}
2405 
2406 	if (xchain) {
2407 		cert_count = sk_X509_num(xchain);
2408 		log_debug("debug: certificate chain len: %d", cert_count);
2409 		if (cert_count >= MAX_CERTS) {
2410 			log_warnx("warn: certificate chain too long");
2411 			goto end;
2412 		}
2413 	}
2414 	else
2415 		cert_count = 0;
2416 
2417 	for (i = 0; i < cert_count; ++i) {
2418 		x = sk_X509_value(xchain, i);
2419 		cert_len[i+1] = i2d_X509(x, &cert_der[i+1]);
2420 		if (cert_len[i+1] < 0) {
2421 			log_warnx("warn: failed to encode certificate");
2422 			goto end;
2423 		}
2424 		log_debug("debug: certificate %i: len=%d", i+1, cert_len[i+1]);
2425 		if (cert_len[i+1] > (int)MAX_CERT_LEN) {
2426 			log_warnx("warn: certificate too long");
2427 			goto end;
2428 		}
2429 	}
2430 
2431 	tree_xset(&wait_ssl_verify, s->id, s);
2432 
2433 	/* Send the client certificate */
2434 	req_ca_vrfy.reqid = s->id;
2435 	req_ca_vrfy.cert_len = cert_len[0];
2436 	req_ca_vrfy.n_chain = cert_count;
2437 	iov[0].iov_base = &req_ca_vrfy;
2438 	iov[0].iov_len = sizeof(req_ca_vrfy);
2439 	iov[1].iov_base = cert_der[0];
2440 	iov[1].iov_len = cert_len[0];
2441 	m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CERT, 0, 0, -1,
2442 	    iov, nitems(iov));
2443 
2444 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2445 	req_ca_vrfy.reqid = s->id;
2446 
2447 	/* Send the chain, one cert at a time */
2448 	for (i = 0; i < cert_count; ++i) {
2449 		req_ca_vrfy.cert_len = cert_len[i+1];
2450 		iov[1].iov_base = cert_der[i+1];
2451 		iov[1].iov_len  = cert_len[i+1];
2452 		m_composev(p_lka, IMSG_SMTP_TLS_VERIFY_CHAIN, 0, 0, -1,
2453 		    iov, nitems(iov));
2454 	}
2455 
2456 	/* Tell lookup process that it can start verifying, we're done */
2457 	memset(&req_ca_vrfy, 0, sizeof req_ca_vrfy);
2458 	req_ca_vrfy.reqid = s->id;
2459 	m_compose(p_lka, IMSG_SMTP_TLS_VERIFY, 0, 0, -1,
2460 	    &req_ca_vrfy, sizeof req_ca_vrfy);
2461 
2462 	res = 1;
2463 
2464     end:
2465 	for (i = 0; i < MAX_CERTS; ++i)
2466 		free(cert_der[i]);
2467 
2468 	return res;
2469 }
2470 
2471 static void
2472 smtp_auth_failure_resume(int fd, short event, void *p)
2473 {
2474 	struct smtp_session *s = p;
2475 
2476 	smtp_reply(s, "535 Authentication failed");
2477 	smtp_enter_state(s, STATE_HELO);
2478 	io_reload(&s->io);
2479 }
2480 
2481 static void
2482 smtp_auth_failure_pause(struct smtp_session *s)
2483 {
2484 	struct timeval	tv;
2485 
2486 	tv.tv_sec = 0;
2487 	tv.tv_usec = arc4random_uniform(1000000);
2488 	log_trace(TRACE_SMTP, "smtp: timing-attack protection triggered, "
2489 	    "will defer answer for %lu microseconds", tv.tv_usec);
2490 	evtimer_set(&s->pause, smtp_auth_failure_resume, s);
2491 	evtimer_add(&s->pause, &tv);
2492 }
2493 
2494 static void
2495 smtp_queue_create_message(struct smtp_session *s)
2496 {
2497 	m_create(p_queue, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1);
2498 	m_add_id(p_queue, s->id);
2499 	m_close(p_queue);
2500 	tree_xset(&wait_queue_msg, s->id, s);
2501 }
2502 
2503 static void
2504 smtp_queue_open_message(struct smtp_session *s)
2505 {
2506 	m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1);
2507 	m_add_id(p_queue, s->id);
2508 	m_add_msgid(p_queue, s->tx->msgid);
2509 	m_close(p_queue);
2510 	tree_xset(&wait_queue_fd, s->id, s);
2511 }
2512 
2513 static void
2514 smtp_queue_commit(struct smtp_session *s)
2515 {
2516 	m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
2517 	m_add_id(p_queue, s->id);
2518 	m_add_msgid(p_queue, s->tx->msgid);
2519 	m_close(p_queue);
2520 	tree_xset(&wait_queue_commit, s->id, s);
2521 }
2522 
2523 static void
2524 smtp_queue_rollback(struct smtp_session *s)
2525 {
2526 	m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1);
2527 	m_add_msgid(p_queue, s->tx->msgid);
2528 	m_close(p_queue);
2529 }
2530 
2531 static void
2532 smtp_filter_rset(struct smtp_session *s)
2533 {
2534 	filter_event(s->id, EVENT_RESET);
2535 }
2536 
2537 static void
2538 smtp_filter_tx_begin(struct smtp_session *s)
2539 {
2540 	s->flags |= SF_FILTERTX;
2541 	filter_event(s->id, EVENT_TX_BEGIN);
2542 }
2543 
2544 static void
2545 smtp_filter_tx_commit(struct smtp_session *s)
2546 {
2547 	s->flags &= ~SF_FILTERTX;
2548 	filter_event(s->id, EVENT_TX_COMMIT);
2549 }
2550 
2551 static void
2552 smtp_filter_tx_rollback(struct smtp_session *s)
2553 {
2554 	s->flags &= ~SF_FILTERTX;
2555 	filter_event(s->id, EVENT_TX_ROLLBACK);
2556 }
2557 
2558 static void
2559 smtp_filter_disconnect(struct smtp_session *s)
2560 {
2561 	filter_event(s->id, EVENT_DISCONNECT);
2562 }
2563 
2564 static void
2565 smtp_filter_connect(struct smtp_session *s, struct sockaddr *sa)
2566 {
2567 	char	*filter;
2568 
2569 	tree_xset(&wait_filter, s->id, s);
2570 
2571 	filter = s->listener->filter[0] ? s->listener->filter : NULL;
2572 
2573 	filter_connect(s->id, sa, (struct sockaddr *)&s->ss, s->hostname, filter);
2574 }
2575 
2576 static void
2577 smtp_filter_eom(struct smtp_session *s)
2578 {
2579 	tree_xset(&wait_filter, s->id, s);
2580 	filter_eom(s->id, QUERY_EOM, s->tx->odatalen);
2581 }
2582 
2583 static void
2584 smtp_filter_helo(struct smtp_session *s)
2585 {
2586 	tree_xset(&wait_filter, s->id, s);
2587 	filter_line(s->id, QUERY_HELO, s->helo);
2588 }
2589 
2590 static void
2591 smtp_filter_mail(struct smtp_session *s)
2592 {
2593 	tree_xset(&wait_filter, s->id, s);
2594 	filter_mailaddr(s->id, QUERY_MAIL, &s->tx->evp.sender);
2595 }
2596 
2597 static void
2598 smtp_filter_rcpt(struct smtp_session *s)
2599 {
2600 	tree_xset(&wait_filter, s->id, s);
2601 	filter_mailaddr(s->id, QUERY_RCPT, &s->tx->evp.rcpt);
2602 }
2603 
2604 static void
2605 smtp_filter_data(struct smtp_session *s)
2606 {
2607 	tree_xset(&wait_filter, s->id, s);
2608 	filter_line(s->id, QUERY_DATA, NULL);
2609 }
2610 
2611 static void
2612 smtp_filter_dataline(struct smtp_session *s, const char *line)
2613 {
2614 	int	ret;
2615 
2616 	log_trace(TRACE_SMTP, "<<< [MSG] %s", line);
2617 
2618 	/* ignore data line if an error flag is set */
2619 	if (s->tx->msgflags & MF_ERROR)
2620 		return;
2621 
2622 	/* escape lines starting with a '.' */
2623 	if (line[0] == '.')
2624 		line += 1;
2625 
2626 	/* account for newline */
2627 	s->tx->datain += strlen(line) + 1;
2628 	if (s->tx->datain > env->sc_maxsize) {
2629 		s->tx->msgflags |= MF_ERROR_SIZE;
2630 		return;
2631 	}
2632 
2633 	if (!s->tx->hdrdone) {
2634 
2635 		/* folded header that must be skipped */
2636 		if (isspace((unsigned char)line[0]) && s->tx->skiphdr)
2637 			return;
2638 		s->tx->skiphdr = 0;
2639 
2640 		/* BCC should be stripped from headers */
2641 		if (strncasecmp("bcc:", line, 4) == 0) {
2642 			s->tx->skiphdr = 1;
2643 			return;
2644 		}
2645 
2646 		/* check for loop */
2647 		if (strncasecmp("Received: ", line, 10) == 0)
2648 			s->tx->rcvcount++;
2649 		if (s->tx->rcvcount == MAX_HOPS_COUNT) {
2650 			s->tx->msgflags |= MF_ERROR_LOOP;
2651 			log_warnx("warn: loop detected");
2652 			return;
2653 		}
2654 
2655 		if (line[0] == '\0')
2656 			s->tx->hdrdone = 1;
2657 	}
2658 
2659 	ret = rfc2822_parser_feed(&s->tx->rfc2822_parser, line);
2660 	if (ret == -1) {
2661 		s->tx->msgflags |= MF_ERROR_RESOURCES;
2662 		return;
2663 	}
2664 
2665 	if (ret == 0) {
2666 		s->tx->msgflags |= MF_ERROR_MALFORMED;
2667 		return;
2668 	}
2669 
2670 	if (iobuf_queued(&s->tx->obuf) > DATA_HIWAT && !(s->io.flags & IO_PAUSE_IN)) {
2671 		log_debug("debug: smtp: %p: filter congestion over: pausing session", s);
2672 		io_pause(&s->io, IO_PAUSE_IN);
2673 	}
2674 	io_reload(&s->tx->oev);
2675 }
2676 
2677 #define CASE(x) case x : return #x
2678 
2679 const char *
2680 smtp_strstate(int state)
2681 {
2682 	static char	buf[32];
2683 
2684 	switch (state) {
2685 	CASE(STATE_NEW);
2686 	CASE(STATE_CONNECTED);
2687 	CASE(STATE_TLS);
2688 	CASE(STATE_HELO);
2689 	CASE(STATE_AUTH_INIT);
2690 	CASE(STATE_AUTH_USERNAME);
2691 	CASE(STATE_AUTH_PASSWORD);
2692 	CASE(STATE_AUTH_FINALIZE);
2693 	CASE(STATE_BODY);
2694 	CASE(STATE_QUIT);
2695 	default:
2696 		(void)snprintf(buf, sizeof(buf), "STATE_??? (%d)", state);
2697 		return (buf);
2698 	}
2699 }
2700