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

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