GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/smtpd/smtpd/../smtp_session.c Lines: 0 1219 0.0 %
Date: 2017-11-13 Branches: 0 656 0.0 %

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