xref: /openbsd-src/usr.sbin/smtpd/smtp_session.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: smtp_session.c,v 1.162 2012/05/08 11:52:57 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.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/param.h>
26 #include <sys/socket.h>
27 
28 #include <netinet/in.h>
29 
30 #include <ctype.h>
31 #include <event.h>
32 #include <imsg.h>
33 #include <resolv.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 
38 #include <openssl/ssl.h>
39 
40 #include "smtpd.h"
41 #include "log.h"
42 
43 void	 ssl_error(const char *);
44 
45 static int session_rfc5321_helo_handler(struct session *, char *);
46 static int session_rfc5321_ehlo_handler(struct session *, char *);
47 static int session_rfc5321_rset_handler(struct session *, char *);
48 static int session_rfc5321_noop_handler(struct session *, char *);
49 static int session_rfc5321_data_handler(struct session *, char *);
50 static int session_rfc5321_mail_handler(struct session *, char *);
51 static int session_rfc5321_rcpt_handler(struct session *, char *);
52 static int session_rfc5321_vrfy_handler(struct session *, char *);
53 static int session_rfc5321_expn_handler(struct session *, char *);
54 static int session_rfc5321_turn_handler(struct session *, char *);
55 static int session_rfc5321_help_handler(struct session *, char *);
56 static int session_rfc5321_quit_handler(struct session *, char *);
57 
58 static int session_rfc1652_mail_handler(struct session *, char *);
59 
60 static int session_rfc3207_stls_handler(struct session *, char *);
61 
62 static int session_rfc4954_auth_handler(struct session *, char *);
63 static void session_rfc4954_auth_plain(struct session *, char *);
64 static void session_rfc4954_auth_login(struct session *, char *);
65 
66 static void session_line(struct session *, char *, size_t);
67 static void session_read_data(struct session *, char *);
68 static void session_command(struct session *, char *);
69 static void session_respond_delayed(int, short, void *);
70 static int session_set_mailaddr(struct mailaddr *, char *);
71 static void session_imsg(struct session *, enum smtp_proc_type,
72     enum imsg_type, u_int32_t, pid_t, int, void *, u_int16_t);
73 
74 static void session_enter_state(struct session *, int);
75 
76 const char *session_strstate(int);
77 
78 struct session_cmd {
79 	char	 *name;
80 	int		(*func)(struct session *, char *);
81 };
82 
83 struct session_cmd rfc5321_cmdtab[] = {
84 	{ "helo",	session_rfc5321_helo_handler },
85 	{ "ehlo",	session_rfc5321_ehlo_handler },
86 	{ "rset",	session_rfc5321_rset_handler },
87 	{ "noop",	session_rfc5321_noop_handler },
88 	{ "data",	session_rfc5321_data_handler },
89 	{ "mail from",	session_rfc5321_mail_handler },
90 	{ "rcpt to",	session_rfc5321_rcpt_handler },
91 	{ "vrfy",	session_rfc5321_vrfy_handler },
92 	{ "expn",	session_rfc5321_expn_handler },
93 	{ "turn",	session_rfc5321_turn_handler },
94 	{ "help",	session_rfc5321_help_handler },
95 	{ "quit",	session_rfc5321_quit_handler }
96 };
97 
98 struct session_cmd rfc1652_cmdtab[] = {
99 	{ "mail from",	session_rfc1652_mail_handler },
100 };
101 
102 struct session_cmd rfc3207_cmdtab[] = {
103 	{ "starttls",	session_rfc3207_stls_handler }
104 };
105 
106 struct session_cmd rfc4954_cmdtab[] = {
107 	{ "auth",	session_rfc4954_auth_handler }
108 };
109 
110 static int
111 session_rfc3207_stls_handler(struct session *s, char *args)
112 {
113 	if (! ADVERTISE_TLS(s))
114 		return 0;
115 
116 	if (s->s_state == S_GREETED) {
117 		session_respond(s, "503 Polite people say HELO first");
118 		return 1;
119 	}
120 
121 	if (s->s_state != S_HELO) {
122 		session_respond(s, "503 TLS not allowed at this stage");
123 		return 1;
124 	}
125 
126 	if (args != NULL) {
127 		session_respond(s, "501 No parameters allowed");
128 		return 1;
129 	}
130 
131 	session_enter_state(s, S_TLS);
132 	session_respond(s, "220 Ready to start TLS");
133 
134 	return 1;
135 }
136 
137 static int
138 session_rfc4954_auth_handler(struct session *s, char *args)
139 {
140 	char	*method;
141 	char	*eom;
142 
143 	if (! ADVERTISE_AUTH(s)) {
144 		if (s->s_flags & F_AUTHENTICATED) {
145 			session_respond(s, "503 Already authenticated");
146 			return 1;
147 		} else
148 			return 0;
149 	}
150 
151 	if (s->s_state == S_GREETED) {
152 		session_respond(s, "503 Polite people say HELO first");
153 		return 1;
154 	}
155 
156 	if (s->s_state != S_HELO) {
157 		session_respond(s, "503 Session already in progress");
158 		return 1;
159 	}
160 
161 	if (args == NULL) {
162 		session_respond(s, "501 No parameters given");
163 		return 1;
164 	}
165 
166 	method = args;
167 	eom = strchr(args, ' ');
168 	if (eom == NULL)
169 		eom = strchr(args, '\t');
170 	if (eom != NULL)
171 		*eom++ = '\0';
172 
173 	if (strcasecmp(method, "PLAIN") == 0)
174 		session_rfc4954_auth_plain(s, eom);
175 	else if (strcasecmp(method, "LOGIN") == 0)
176 		session_rfc4954_auth_login(s, eom);
177 	else
178 		session_respond(s, "504 AUTH method '%s' unsupported", method);
179 
180 	return 1;
181 }
182 
183 static void
184 session_rfc4954_auth_plain(struct session *s, char *arg)
185 {
186 	struct auth	*a = &s->s_auth;
187 	char		 buf[1024], *user, *pass;
188 	int		 len;
189 
190 	switch (s->s_state) {
191 	case S_HELO:
192 		if (arg == NULL) {
193 			session_enter_state(s, S_AUTH_INIT);
194 			session_respond(s, "334 ");
195 			return;
196 		}
197 		session_enter_state(s, S_AUTH_INIT);
198 		/* FALLTHROUGH */
199 
200 	case S_AUTH_INIT:
201 		/* String is not NUL terminated, leave room. */
202 		if ((len = __b64_pton(arg, (unsigned char *)buf, sizeof(buf) - 1)) == -1)
203 			goto abort;
204 		/* buf is a byte string, NUL terminate. */
205 		buf[len] = '\0';
206 
207 		/*
208 		 * Skip "foo" in "foo\0user\0pass", if present.
209 		 */
210 		user = memchr(buf, '\0', len);
211 		if (user == NULL || user >= buf + len - 2)
212 			goto abort;
213 		user++; /* skip NUL */
214 		if (strlcpy(a->user, user, sizeof(a->user)) >= sizeof(a->user))
215 			goto abort;
216 
217 		pass = memchr(user, '\0', len - (user - buf));
218 		if (pass == NULL || pass >= buf + len - 2)
219 			goto abort;
220 		pass++; /* skip NUL */
221 		if (strlcpy(a->pass, pass, sizeof(a->pass)) >= sizeof(a->pass))
222 			goto abort;
223 
224 		session_enter_state(s, S_AUTH_FINALIZE);
225 
226 		a->id = s->s_id;
227 		session_imsg(s, PROC_PARENT, IMSG_PARENT_AUTHENTICATE, 0, 0, -1,
228 		    a, sizeof(*a));
229 
230 		bzero(a->pass, sizeof(a->pass));
231 		return;
232 
233 	default:
234 		fatal("session_rfc4954_auth_plain: unknown state");
235 	}
236 
237 abort:
238 	session_respond(s, "501 Syntax error");
239 	session_enter_state(s, S_HELO);
240 }
241 
242 static void
243 session_rfc4954_auth_login(struct session *s, char *arg)
244 {
245 	struct auth	*a = &s->s_auth;
246 
247 	switch (s->s_state) {
248 	case S_HELO:
249 		session_enter_state(s, S_AUTH_USERNAME);
250 		session_respond(s, "334 VXNlcm5hbWU6");
251 		return;
252 
253 	case S_AUTH_USERNAME:
254 		bzero(a->user, sizeof(a->user));
255 		if (__b64_pton(arg, (unsigned char *)a->user, sizeof(a->user) - 1) == -1)
256 			goto abort;
257 
258 		session_enter_state(s, S_AUTH_PASSWORD);
259 		session_respond(s, "334 UGFzc3dvcmQ6");
260 		return;
261 
262 	case S_AUTH_PASSWORD:
263 		bzero(a->pass, sizeof(a->pass));
264 		if (__b64_pton(arg, (unsigned char *)a->pass, sizeof(a->pass) - 1) == -1)
265 			goto abort;
266 
267 		session_enter_state(s, S_AUTH_FINALIZE);
268 
269 		a->id = s->s_id;
270 		session_imsg(s, PROC_PARENT, IMSG_PARENT_AUTHENTICATE, 0, 0, -1,
271 		    a, sizeof(*a));
272 
273 		bzero(a->pass, sizeof(a->pass));
274 		return;
275 
276 	default:
277 		fatal("session_rfc4954_auth_login: unknown state");
278 	}
279 
280 abort:
281 	session_respond(s, "501 Syntax error");
282 	session_enter_state(s, S_HELO);
283 }
284 
285 static int
286 session_rfc1652_mail_handler(struct session *s, char *args)
287 {
288 	char *body;
289 
290 	if (s->s_state == S_GREETED) {
291 		session_respond(s, "503 5.5.1 Polite people say HELO first");
292 		return 1;
293 	}
294 
295 	for (body = strrchr(args, ' '); body != NULL;
296 		body = strrchr(args, ' ')) {
297 		*body++ = '\0';
298 
299 		if (strncasecmp(body, "AUTH=", 5) == 0) {
300 			log_debug("smtp: AUTH in MAIL FROM command, skipping");
301 			continue;
302 		}
303 
304 		if (strncasecmp(body, "BODY=", 5) == 0) {
305 			log_debug("smtp: BODY in MAIL FROM command");
306 
307 			if (strncasecmp("body=7bit", body, 9) == 0) {
308 				s->s_flags &= ~F_8BITMIME;
309 				continue;
310 			}
311 
312 			else if (strncasecmp("body=8bitmime", body, 13) != 0) {
313 				session_respond(s, "503 5.5.4 Unsupported option %s", body);
314 				return 1;
315 			}
316 		}
317 	}
318 
319 	return session_rfc5321_mail_handler(s, args);
320 }
321 
322 static int
323 session_rfc5321_helo_handler(struct session *s, char *args)
324 {
325 	if (args == NULL) {
326 		session_respond(s, "501 HELO requires domain address");
327 		return 1;
328 	}
329 
330 	if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo))
331 	    >= sizeof(s->s_msg.helo)) {
332 		session_respond(s, "501 Invalid domain name");
333 		return 1;
334 	}
335 
336 	s->s_msg.session_id = s->s_id;
337 	s->s_flags &= F_SECURE|F_AUTHENTICATED;
338 	session_enter_state(s, S_HELO);
339 
340 	session_imsg(s, PROC_MFA, IMSG_MFA_HELO, 0, 0, -1, &s->s_msg,
341 	    sizeof(s->s_msg));
342 	return 1;
343 }
344 
345 static int
346 session_rfc5321_ehlo_handler(struct session *s, char *args)
347 {
348 	if (args == NULL) {
349 		session_respond(s, "501 EHLO requires domain address");
350 		return 1;
351 	}
352 
353 	if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo))
354 	    >= sizeof(s->s_msg.helo)) {
355 		session_respond(s, "501 Invalid domain name");
356 		return 1;
357 	}
358 
359 	s->s_msg.session_id = s->s_id;
360 	s->s_flags &= F_SECURE|F_AUTHENTICATED;
361 	s->s_flags |= F_EHLO;
362 	s->s_flags |= F_8BITMIME;
363 	session_enter_state(s, S_HELO);
364 
365 	session_imsg(s, PROC_MFA, IMSG_MFA_HELO, 0, 0, -1, &s->s_msg,
366 	    sizeof(s->s_msg));
367 	return 1;
368 }
369 
370 static int
371 session_rfc5321_rset_handler(struct session *s, char *args)
372 {
373 	session_enter_state(s, S_RSET);
374 
375 	session_imsg(s, PROC_MFA, IMSG_MFA_RSET, 0, 0, -1, &s->s_msg,
376 	    sizeof(s->s_msg));
377 	return 1;
378 }
379 
380 static int
381 session_rfc5321_noop_handler(struct session *s, char *args)
382 {
383 	session_respond(s, "250 2.0.0 OK");
384 
385 	return 1;
386 }
387 
388 static int
389 session_rfc5321_mail_handler(struct session *s, char *args)
390 {
391 	if (s->s_state == S_GREETED) {
392 		session_respond(s, "503 5.5.1 Polite people say HELO first");
393 		return 1;
394 	}
395 
396 	if (s->s_state != S_HELO) {
397 		session_respond(s, "503 5.5.1 Sender already specified");
398 		return 1;
399 	}
400 
401 	if (! session_set_mailaddr(&s->s_msg.sender, args)) {
402 		/* No need to even transmit to MFA, path is invalid */
403 		session_respond(s, "553 5.1.7 Sender address syntax error");
404 		return 1;
405 	}
406 
407 	s->rcptcount = 0;
408 	s->s_msg.id = 0;
409 
410 	session_enter_state(s, S_MAIL_MFA);
411 	session_imsg(s, PROC_MFA, IMSG_MFA_MAIL, 0, 0, -1, &s->s_msg,
412 	    sizeof(s->s_msg));
413 	return 1;
414 }
415 
416 static int
417 session_rfc5321_rcpt_handler(struct session *s, char *args)
418 {
419 	if (s->s_state == S_GREETED) {
420 		session_respond(s, "503 5.5.1 Polite people say HELO first");
421 		return 1;
422 	}
423 
424 	if (s->s_state == S_HELO) {
425 		session_respond(s, "503 5.5.1 Need MAIL before RCPT");
426 		return 1;
427 	}
428 
429 	if (! session_set_mailaddr(&s->s_msg.rcpt, args)) {
430 		/* No need to even transmit to MFA, path is invalid */
431 		session_respond(s, "553 5.1.3 Recipient address syntax error");
432 		return 1;
433 	}
434 
435 	session_enter_state(s, S_RCPT_MFA);
436 	session_imsg(s, PROC_MFA, IMSG_MFA_RCPT, 0, 0, -1, &s->s_msg,
437 	    sizeof(s->s_msg));
438 	return 1;
439 }
440 
441 static int
442 session_rfc5321_quit_handler(struct session *s, char *args)
443 {
444 	session_enter_state(s, S_QUIT);
445 	session_respond(s, "221 2.0.0 %s Closing connection", env->sc_hostname);
446 /*
447 	session_imsg(s, PROC_MFA, IMSG_MFA_QUIT, 0, 0, -1, &s->s_msg,
448 	    sizeof(s->s_msg));
449 */
450 	return 1;
451 }
452 
453 static int
454 session_rfc5321_data_handler(struct session *s, char *args)
455 {
456 	if (s->s_state == S_GREETED) {
457 		session_respond(s, "503 5.5.1 Polite people say HELO first");
458 		return 1;
459 	}
460 
461 	if (s->s_state == S_HELO) {
462 		session_respond(s, "503 5.5.1 Need MAIL before DATA");
463 		return 1;
464 	}
465 
466 	if (s->s_state == S_MAIL) {
467 		session_respond(s, "503 5.5.1 Need RCPT before DATA");
468 		return 1;
469 	}
470 
471 	session_enter_state(s, S_DATA_QUEUE);
472 
473 	session_imsg(s, PROC_QUEUE, IMSG_QUEUE_MESSAGE_FILE, 0, 0, -1,
474 	    &s->s_msg, sizeof(s->s_msg));
475 
476 	return 1;
477 }
478 
479 static int
480 session_rfc5321_vrfy_handler(struct session *s, char *args)
481 {
482 	session_respond(s, "252 5.5.1 Cannot VRFY; try RCPT to attempt delivery");
483 
484 	return 1;
485 }
486 
487 static int
488 session_rfc5321_expn_handler(struct session *s, char *args)
489 {
490 	session_respond(s, "502 5.5.2 Sorry, we do not allow this operation");
491 
492 	return 1;
493 }
494 
495 static int
496 session_rfc5321_turn_handler(struct session *s, char *args)
497 {
498 	session_respond(s, "502 5.5.2 Sorry, we do not allow this operation");
499 
500 	return 1;
501 }
502 
503 static int
504 session_rfc5321_help_handler(struct session *s, char *args)
505 {
506 	session_respond(s, "214- This is OpenSMTPD");
507 	session_respond(s, "214- To report bugs in the implementation, please "
508 	    "contact bugs@openbsd.org");
509 	session_respond(s, "214- with full details");
510 	session_respond(s, "214 End of HELP info");
511 
512 	return 1;
513 }
514 
515 static void
516 session_enter_state(struct session *s, int newstate)
517 {
518 	log_trace(TRACE_SMTP, "smtp: %p: %s -> %s", s,
519 	    session_strstate(s->s_state),
520 	    session_strstate(newstate));
521 
522 	s->s_state = newstate;
523 }
524 
525 static void
526 session_command(struct session *s, char *cmd)
527 {
528 	char		*ep, *args;
529 	unsigned int	 i;
530 
531 	/*
532 	 * unlike other commands, "mail from" and "rcpt to" contain a
533 	 * space in the command name.
534 	 */
535 	if (strncasecmp("mail from:", cmd, 10) == 0 ||
536 	    strncasecmp("rcpt to:", cmd, 8) == 0)
537 		ep = strchr(cmd, ':');
538 	else
539 		ep = strchr(cmd, ' ');
540 
541 	if (ep != NULL) {
542 		*ep = '\0';
543 		args = ++ep;
544 		while (isspace((int)*args))
545 			args++;
546 	} else
547 		args = NULL;
548 
549 	if (!(s->s_flags & F_EHLO))
550 		goto rfc5321;
551 
552 	/* RFC 1652 - 8BITMIME */
553 	for (i = 0; i < nitems(rfc1652_cmdtab); ++i)
554 		if (strcasecmp(rfc1652_cmdtab[i].name, cmd) == 0)
555 			break;
556 	if (i < nitems(rfc1652_cmdtab)) {
557 		if (rfc1652_cmdtab[i].func(s, args))
558 			return;
559 	}
560 
561 	/* RFC 3207 - STARTTLS */
562 	for (i = 0; i < nitems(rfc3207_cmdtab); ++i)
563 		if (strcasecmp(rfc3207_cmdtab[i].name, cmd) == 0)
564 			break;
565 	if (i < nitems(rfc3207_cmdtab)) {
566 		if (rfc3207_cmdtab[i].func(s, args))
567 			return;
568 	}
569 
570 	/* RFC 4954 - AUTH */
571 	for (i = 0; i < nitems(rfc4954_cmdtab); ++i)
572 		if (strcasecmp(rfc4954_cmdtab[i].name, cmd) == 0)
573 			break;
574 	if (i < nitems(rfc4954_cmdtab)) {
575 		if (rfc4954_cmdtab[i].func(s, args))
576 			return;
577 	}
578 
579 rfc5321:
580 	/* RFC 5321 - SMTP */
581 	for (i = 0; i < nitems(rfc5321_cmdtab); ++i)
582 		if (strcasecmp(rfc5321_cmdtab[i].name, cmd) == 0)
583 			break;
584 	if (i < nitems(rfc5321_cmdtab)) {
585 		if (rfc5321_cmdtab[i].func(s, args))
586 			return;
587 	}
588 
589 	session_respond(s, "500 Command unrecognized");
590 }
591 
592 void
593 session_io(struct io *io, int evt)
594 {
595 	struct session	*s = io->arg;
596 	char		*line;
597 	ssize_t		 len;
598 
599 	log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), io_strio(io));
600 
601 	switch(evt) {
602 
603 	case IO_TLSREADY:
604 		s->s_flags |= F_SECURE;
605 		if (s->s_l->flags & F_SMTPS)
606 			stat_increment(STATS_SMTP_SMTPS);
607 		if (s->s_l->flags & F_STARTTLS)
608 			stat_increment(STATS_SMTP_STARTTLS);
609 		if (s->s_state == S_INIT) {
610 			io_set_write(&s->s_io);
611 			session_respond(s, SMTPD_BANNER, env->sc_hostname);
612 		}
613 		session_enter_state(s, S_GREETED);
614 		break;
615 
616 	case IO_DATAIN:
617 	    nextline:
618 		line = iobuf_getline(&s->s_iobuf, &len);
619 		if ((line == NULL && iobuf_len(&s->s_iobuf) >= SMTP_LINE_MAX) ||
620 		    (line && len >= SMTP_LINE_MAX)) {
621 			session_respond(s, "500 5.0.0 Line too long");
622 			session_enter_state(s, S_QUIT);
623 			io_set_write(io);
624 			return;
625 		}
626 
627 		if (line == NULL) {
628 			iobuf_normalize(&s->s_iobuf);
629 			return;
630 		}
631 
632 		if (s->s_state == S_DATACONTENT && strcmp(line, ".")) {
633 			/* more data to come */
634 			session_line(s, line, len);
635 			goto nextline;
636 		}
637 
638 		/* pipelining not supported */
639 		if (iobuf_len(&s->s_iobuf)) {
640 			session_respond(s, "500 5.0.0 Pipelining not supported");
641 			session_enter_state(s, S_QUIT);
642 			io_set_write(io);
643 			return;
644 		}
645 
646 		session_line(s, line, len);
647 		iobuf_normalize(&s->s_iobuf);
648 		io_set_write(io);
649 		break;
650 
651 	case IO_LOWAT:
652 		if (s->s_state == S_QUIT) {
653 			session_destroy(s, "done");
654 			break;
655 		}
656 
657 		io_set_read(io);
658 
659 		/* wait for the client to start tls */
660 		if (s->s_state == S_TLS) {
661 			ssl_session_init(s);
662 			io_start_tls(io, s->s_ssl);
663 		}
664 		break;
665 
666 	case IO_TIMEOUT:
667 		session_destroy(s, "timeout");
668 		break;
669 
670 	case IO_DISCONNECTED:
671 		session_destroy(s, "disconnected");
672 		break;
673 
674 	case IO_ERROR:
675 		session_destroy(s, "error");
676 		break;
677 
678 	default:
679 		fatal("session_io()");
680 	}
681 }
682 
683 void
684 session_pickup(struct session *s, struct submit_status *ss)
685 {
686 	s->s_flags &= ~F_WAITIMSG;
687 
688 	if ((ss != NULL && ss->code == 421) ||
689 	    (s->s_dstatus & DS_TEMPFAILURE)) {
690 		env->stats->smtp.tempfail++;
691 		session_respond(s, "421 Service temporarily unavailable");
692 		session_enter_state(s, S_QUIT);
693 		io_reload(&s->s_io);
694 		return;
695 	}
696 
697 	switch (s->s_state) {
698 
699 	case S_CONNECTED:
700 		session_enter_state(s, S_INIT);
701 		s->s_msg.session_id = s->s_id;
702 		s->s_msg.ss = s->s_ss;
703 		session_imsg(s, PROC_MFA, IMSG_MFA_CONNECT, 0, 0, -1,
704 			     &s->s_msg, sizeof(s->s_msg));
705 		break;
706 
707 	case S_INIT:
708 		if (ss->code != 250) {
709 			session_destroy(s, "rejected by filter");
710 			return;
711 		}
712 
713 		if (s->s_l->flags & F_SMTPS) {
714 			ssl_session_init(s);
715 			io_set_read(&s->s_io);
716 			io_start_tls(&s->s_io, s->s_ssl);
717 			return;
718 		}
719 
720 		session_respond(s, SMTPD_BANNER, env->sc_hostname);
721 		session_enter_state(s, S_GREETED);
722 		break;
723 
724 	case S_AUTH_FINALIZE:
725 		if (s->s_flags & F_AUTHENTICATED)
726 			session_respond(s, "235 Authentication succeeded");
727 		else
728 			session_respond(s, "535 Authentication failed");
729 		session_enter_state(s, S_HELO);
730 		break;
731 
732 	case S_RSET:
733 		session_respond(s, "250 2.0.0 Reset state");
734 		session_enter_state(s, S_HELO);
735 		break;
736 
737 	case S_HELO:
738 		if (ss->code != 250) {
739 			session_enter_state(s, S_GREETED);
740 			session_respond(s, "%d Helo rejected", ss->code);
741 			break;
742 		}
743 
744 		session_respond(s, "250%c%s Hello %s [%s], pleased to meet you",
745 		    (s->s_flags & F_EHLO) ? '-' : ' ',
746 		    env->sc_hostname, s->s_msg.helo, ss_to_text(&s->s_ss));
747 
748 		if (s->s_flags & F_EHLO) {
749 			/* unconditionnal extensions go first */
750 			session_respond(s, "250-8BITMIME");
751 			session_respond(s, "250-ENHANCEDSTATUSCODES");
752 
753 			/* XXX - we also want to support reading SIZE from MAIL parameters */
754 			session_respond(s, "250-SIZE %zu", env->sc_maxsize);
755 
756 			if (ADVERTISE_TLS(s))
757 				session_respond(s, "250-STARTTLS");
758 
759 			if (ADVERTISE_AUTH(s))
760 				session_respond(s, "250-AUTH PLAIN LOGIN");
761 			session_respond(s, "250 HELP");
762 		}
763 		break;
764 
765 	case S_MAIL_MFA:
766 		if (ss->code != 250) {
767 			session_enter_state(s, S_HELO);
768 			session_respond(s, "%d Sender rejected", ss->code);
769 			break;
770 		}
771 
772 		session_enter_state(s, S_MAIL_QUEUE);
773 		s->s_msg.sender = ss->u.maddr;
774 
775 		session_imsg(s, PROC_QUEUE, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1,
776 		    &s->s_msg, sizeof(s->s_msg));
777 		break;
778 
779 	case S_MAIL_QUEUE:
780 		session_enter_state(s, S_MAIL);
781 		session_respond(s, "%d 2.1.0 Sender ok", ss->code);
782 		break;
783 
784 	case S_RCPT_MFA:
785 		/* recipient was not accepted */
786 		if (ss->code != 250) {
787 			/* We do not have a valid recipient, downgrade state */
788 			if (s->rcptcount == 0)
789 				session_enter_state(s, S_MAIL);
790 			else
791 				session_enter_state(s, S_RCPT);
792 			session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", ss->code,
793 			    s->s_msg.rcpt.user,
794 			    s->s_msg.rcpt.domain);
795 			break;
796 		}
797 
798 		session_enter_state(s, S_RCPT);
799 		s->rcptcount++;
800 		s->s_msg.dest = ss->u.maddr;
801 		session_respond(s, "%d 2.0.0 Recipient ok", ss->code);
802 		break;
803 
804 	case S_DATA_QUEUE:
805 		session_enter_state(s, S_DATACONTENT);
806 		session_respond(s, "354 Enter mail, end with \".\" on a line by"
807 		    " itself");
808 
809 		fprintf(s->datafp, "Received: from %s (%s [%s])\n",
810 		    s->s_msg.helo, s->s_hostname, ss_to_text(&s->s_ss));
811 		fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %08x",
812 		    env->sc_hostname, s->s_flags & F_EHLO ? "E" : "",
813 		    evpid_to_msgid(s->s_msg.id));
814 
815 		if (s->s_flags & F_SECURE) {
816 			fprintf(s->datafp, "\n\t(version=%s cipher=%s bits=%d)",
817 			    SSL_get_cipher_version(s->s_ssl),
818 			    SSL_get_cipher_name(s->s_ssl),
819 			    SSL_get_cipher_bits(s->s_ssl, NULL));
820 		}
821 		if (s->rcptcount == 1)
822 			fprintf(s->datafp, "\n\tfor <%s@%s>; ",
823 			    s->s_msg.rcpt.user,
824 			    s->s_msg.rcpt.domain);
825 		else
826 			fprintf(s->datafp, ";\n\t");
827 
828 		fprintf(s->datafp, "%s\n", time_to_text(time(NULL)));
829 		break;
830 
831 	case S_DATACONTENT:
832 		if (ss->code != 250)
833 			s->s_dstatus |= DS_PERMFAILURE;
834 		session_read_data(s, ss->u.dataline);
835 		break;
836 
837 	case S_DONE:
838 		session_respond(s, "250 2.0.0 %08x Message accepted for delivery",
839 		    evpid_to_msgid(s->s_msg.id));
840 		log_info("%08x: from=<%s%s%s>, size=%ld, nrcpts=%zu, proto=%s, "
841 		    "relay=%s [%s]",
842 		    evpid_to_msgid(s->s_msg.id),
843 		    s->s_msg.sender.user,
844 		    s->s_msg.sender.user[0] == '\0' ? "" : "@",
845 		    s->s_msg.sender.domain,
846 		    s->s_datalen,
847 		    s->rcptcount,
848 		    s->s_flags & F_EHLO ? "ESMTP" : "SMTP",
849 		    s->s_hostname,
850 		    ss_to_text(&s->s_ss));
851 
852 		session_enter_state(s, S_HELO);
853 		s->s_msg.id = 0;
854 		bzero(&s->s_nresp, sizeof(s->s_nresp));
855 		break;
856 
857 	default:
858 		fatal("session_pickup: unknown state");
859 	}
860 
861 	io_reload(&s->s_io);
862 }
863 
864 static void
865 session_line(struct session *s, char *line, size_t len)
866 {
867 	struct submit_status ss;
868 
869 	if (s->s_state != S_DATACONTENT)
870 		log_trace(TRACE_SMTP, "smtp: %p: <<< %s", s, line);
871 
872 	switch (s->s_state) {
873 	case S_AUTH_INIT:
874 		if (s->s_dstatus & DS_TEMPFAILURE)
875 			goto tempfail;
876 		session_rfc4954_auth_plain(s, line);
877 		break;
878 
879 	case S_AUTH_USERNAME:
880 	case S_AUTH_PASSWORD:
881 		if (s->s_dstatus & DS_TEMPFAILURE)
882 			goto tempfail;
883 		session_rfc4954_auth_login(s, line);
884 		break;
885 
886 	case S_GREETED:
887 	case S_HELO:
888 	case S_MAIL:
889 	case S_RCPT:
890 		if (s->s_dstatus & DS_TEMPFAILURE)
891 			goto tempfail;
892 		session_command(s, line);
893 		break;
894 
895 	case S_DATACONTENT:
896 		if (env->filtermask & FILTER_DATALINE) {
897 			bzero(&ss, sizeof(ss));
898 			ss.id = s->s_id;
899 			if (strlcpy(ss.u.dataline, line,
900 				sizeof(ss.u.dataline)) >= sizeof(ss.u.dataline))
901 				fatal("session_line: data truncation");
902 
903 			session_imsg(s, PROC_MFA, IMSG_MFA_DATALINE,
904 			    0, 0, -1, &ss, sizeof(ss));
905 		} else {
906 			/* no filtering */
907 			session_read_data(s, line);
908 		}
909 		break;
910 
911 	default:
912 		log_debug("session_read: %i", s->s_state);
913 		fatalx("session_read: unexpected state");
914 	}
915 
916 	return;
917 
918 tempfail:
919 	session_respond(s, "421 4.0.0 Service temporarily unavailable");
920 	env->stats->smtp.tempfail++;
921 	session_enter_state(s, S_QUIT);
922 }
923 
924 static void
925 session_read_data(struct session *s, char *line)
926 {
927 	size_t datalen;
928 	size_t len;
929 	size_t i;
930 
931 	if (strcmp(line, ".") == 0) {
932 		s->s_datalen = ftell(s->datafp);
933 		if (! safe_fclose(s->datafp))
934 			s->s_dstatus |= DS_TEMPFAILURE;
935 		s->datafp = NULL;
936 
937 		if (s->s_dstatus & DS_PERMFAILURE) {
938 			session_respond(s, "554 5.0.0 Transaction failed");
939 			session_enter_state(s, S_HELO);
940 		} else if (s->s_dstatus & DS_TEMPFAILURE) {
941 			session_respond(s, "421 4.0.0 Temporary failure");
942 			session_enter_state(s, S_QUIT);
943 			env->stats->smtp.tempfail++;
944 		} else {
945 			session_imsg(s, PROC_QUEUE, IMSG_QUEUE_COMMIT_MESSAGE,
946 			    0, 0, -1, &s->s_msg, sizeof(s->s_msg));
947 			session_enter_state(s, S_DONE);
948 		}
949 		return;
950 	}
951 
952 	/* Don't waste resources on message if it's going to bin anyway. */
953 	if (s->s_dstatus & (DS_PERMFAILURE|DS_TEMPFAILURE))
954 		return;
955 
956 	/* "If the first character is a period and there are other characters
957 	 *  on the line, the first character is deleted." [4.5.2]
958 	 */
959 	if (*line == '.')
960 		line++;
961 
962 	len = strlen(line);
963 
964 	/* If size of data overflows a size_t or exceeds max size allowed
965 	 * for a message, set permanent failure.
966 	 */
967 	datalen = ftell(s->datafp);
968 	if (SIZE_MAX - datalen < len + 1 ||
969 	    datalen + len + 1 > env->sc_maxsize) {
970 		s->s_dstatus |= DS_PERMFAILURE;
971 		return;
972 	}
973 
974 	if (! (s->s_flags & F_8BITMIME)) {
975 		for (i = 0; i < len; ++i)
976 			if (line[i] & 0x80)
977 				line[i] = line[i] & 0x7f;
978 	}
979 
980 	if (fprintf(s->datafp, "%s\n", line) != (int)len + 1)
981 		s->s_dstatus |= DS_TEMPFAILURE;
982 }
983 
984 void
985 session_destroy(struct session *s, const char * reason)
986 {
987 	size_t	resume;
988 
989 	log_debug("smtp: %p: deleting session: %s", s, reason);
990 
991 	if (s->s_flags & F_ZOMBIE)
992 		goto finalize;
993 
994 	if (s->datafp != NULL)
995 		fclose(s->datafp);
996 
997 	if (s->s_msg.id != 0 && s->s_state != S_DONE)
998 		imsg_compose_event(env->sc_ievs[PROC_QUEUE],
999 		    IMSG_QUEUE_REMOVE_MESSAGE, 0, 0, -1, &s->s_msg,
1000 		    sizeof(s->s_msg));
1001 
1002 	if (s->s_ssl) {
1003 		if (s->s_l->flags & F_SMTPS)
1004 			if (s->s_flags & F_SECURE)
1005 				stat_decrement(STATS_SMTP_SMTPS);
1006 		if (s->s_l->flags & F_STARTTLS)
1007 			if (s->s_flags & F_SECURE)
1008 				stat_decrement(STATS_SMTP_STARTTLS);
1009 	}
1010 
1011 	event_del(&s->s_ev); /* in case something was scheduled */
1012 	io_clear(&s->s_io);
1013 	iobuf_clear(&s->s_iobuf);
1014 
1015 	/* resume when session count decreases to 95% */
1016 	resume = env->sc_maxconn * 95 / 100;
1017 	if (stat_decrement(STATS_SMTP_SESSION) == resume) {
1018 		log_warnx("re-enabling incoming connections");
1019 		smtp_resume();
1020 	}
1021 
1022 	/* If the session is waiting for an imsg, do not kill it now, since
1023 	 * the id must still be valid.
1024 	 */
1025 	if (s->s_flags & F_WAITIMSG) {
1026 		s->s_flags = F_ZOMBIE;
1027 		return;
1028 	}
1029 
1030     finalize:
1031 	SPLAY_REMOVE(sessiontree, &env->sc_sessions, s);
1032 	bzero(s, sizeof(*s));
1033 	free(s);
1034 }
1035 
1036 int
1037 session_cmp(struct session *s1, struct session *s2)
1038 {
1039 	/*
1040 	 * do not return u_int64_t's
1041 	 */
1042 	if (s1->s_id < s2->s_id)
1043 		return (-1);
1044 
1045 	if (s1->s_id > s2->s_id)
1046 		return (1);
1047 
1048 	return (0);
1049 }
1050 
1051 static int
1052 session_set_mailaddr(struct mailaddr *maddr, char *line)
1053 {
1054 	size_t len;
1055 
1056 	len = strlen(line);
1057 	if (*line != '<' || line[len - 1] != '>')
1058 		return 0;
1059 	line[len - 1] = '\0';
1060 
1061 	return email_to_mailaddr(maddr, line + 1);
1062 }
1063 
1064 void
1065 session_respond(struct session *s, char *fmt, ...)
1066 {
1067 	va_list	 ap;
1068 	int	 n, delay;
1069 	char	 buf[SMTP_LINE_MAX];
1070 
1071 	va_start(ap, fmt);
1072 	n = vsnprintf(buf, sizeof buf, fmt, ap);
1073 	va_end(ap);
1074 	if (n == -1 || n >= SMTP_LINE_MAX)
1075 		fatal("session_respond: line too long");
1076 	if (n < 4)
1077 		fatal("session_respond: response too short");
1078 
1079 	log_trace(TRACE_SMTP, "smtp: %p: >>> %s", s, buf);
1080 
1081 	iobuf_queue(&s->s_iobuf, buf, n);
1082 	iobuf_queue(&s->s_iobuf, "\r\n", 2);
1083 
1084 	/*
1085 	 * Log failures.  Might be annoying in the long term, but it is a good
1086 	 * development aid for now.
1087 	 */
1088 	switch (buf[0]) {
1089 	case '5':
1090 	case '4':
1091 		log_info("%08x: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)",
1092 		    evpid_to_msgid(s->s_msg.id),
1093 		    s->s_msg.sender.user, s->s_msg.sender.domain,
1094 		    s->s_hostname, ss_to_text(&s->s_ss),
1095 		    n, buf);
1096 		break;
1097 	}
1098 
1099 	/* Detect multi-line response. */
1100 	switch (buf[3]) {
1101 	case '-':
1102 		return;
1103 	case ' ':
1104 		break;
1105 	default:
1106 		fatalx("session_respond: invalid response");
1107 	}
1108 
1109 	/*
1110 	 * Deal with request flooding; avoid letting response rate keep up
1111 	 * with incoming request rate.
1112 	 */
1113 	s->s_nresp[s->s_state]++;
1114 
1115 	if (s->s_state == S_RCPT)
1116 		delay = 0;
1117 	else if ((n = s->s_nresp[s->s_state] - FAST_RESPONSES) > 0)
1118 		delay = MIN(1 << (n - 1), MAX_RESPONSE_DELAY);
1119 	else
1120 		delay = 0;
1121 
1122 	if (delay > 0) {
1123 		struct timeval tv = { delay, 0 };
1124 
1125 		io_pause(&s->s_io, IO_PAUSE_OUT);
1126 		env->stats->smtp.delays++;
1127 
1128 		/* in case session_respond is called multiple times */
1129 		evtimer_del(&s->s_ev);
1130 		evtimer_set(&s->s_ev, session_respond_delayed, s);
1131 		evtimer_add(&s->s_ev, &tv);
1132 	}
1133 }
1134 
1135 static void
1136 session_respond_delayed(int fd, short event, void *p)
1137 {
1138 	struct session	*s = p;
1139 
1140 	io_resume(&s->s_io, IO_PAUSE_OUT);
1141 }
1142 
1143 /*
1144  * Send IMSG, waiting for reply safely.
1145  */
1146 static void
1147 session_imsg(struct session *s, enum smtp_proc_type proc, enum imsg_type type,
1148     u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen)
1149 {
1150 	/*
1151 	 * Each outgoing IMSG has a response IMSG associated that must be
1152 	 * waited for before the session can be progressed further.
1153 	 * During the wait period:
1154 	 * 1) session must not be destroyed,
1155 	 * 2) session must not be read from,
1156 	 * 3) session may be written to.
1157 	 */
1158 
1159 	s->s_flags |= F_WAITIMSG;
1160 	imsg_compose_event(env->sc_ievs[proc], type, peerid, pid, fd, data,
1161 	    datalen);
1162 }
1163 
1164 SPLAY_GENERATE(sessiontree, session, s_nodes, session_cmp);
1165 
1166 #define CASE(x) case x : return #x
1167 
1168 const char *
1169 session_strstate(int state)
1170 {
1171 	static char	buf[32];
1172 
1173 	switch (state) {
1174 	CASE(S_NEW);
1175 	CASE(S_CONNECTED);
1176 	CASE(S_INIT);
1177 	CASE(S_GREETED);
1178 	CASE(S_TLS);
1179 	CASE(S_AUTH_INIT);
1180 	CASE(S_AUTH_USERNAME);
1181 	CASE(S_AUTH_PASSWORD);
1182 	CASE(S_AUTH_FINALIZE);
1183 	CASE(S_RSET);
1184 	CASE(S_HELO);
1185 	CASE(S_MAIL_MFA);
1186 	CASE(S_MAIL_QUEUE);
1187 	CASE(S_MAIL);
1188 	CASE(S_RCPT_MFA);
1189 	CASE(S_RCPT);
1190 	CASE(S_DATA);
1191 	CASE(S_DATA_QUEUE);
1192 	CASE(S_DATACONTENT);
1193 	CASE(S_DONE);
1194 	CASE(S_QUIT);
1195 	CASE(S_CLOSE);
1196 	default:
1197 		snprintf(buf, sizeof(buf), "S_??? (%d)", state);
1198 		return buf;
1199 	}
1200 }
1201