1 /* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "llist.h"
5 #include "array.h"
6 #include "str.h"
7 #include "ioloop.h"
8 #include "istream.h"
9 #include "ostream.h"
10 #include "iostream.h"
11 #include "connection.h"
12 #include "iostream-rawlog.h"
13 #include "iostream-ssl.h"
14 #include "master-service.h"
15 #include "master-service-ssl.h"
16 
17 #include "smtp-syntax.h"
18 #include "smtp-reply-parser.h"
19 #include "smtp-command-parser.h"
20 #include "smtp-server-private.h"
21 
22 const char *const smtp_server_state_names[] = {
23 	"GREETING",
24 	"XCLIENT",
25 	"HELO",
26 	"STARTTLS",
27 	"AUTH",
28 	"READY",
29 	"MAIL FROM",
30 	"RCPT TO",
31 	"DATA"
32 };
33 
34 /*
35  * Connection
36  */
37 
38 static void smtp_server_connection_input(struct connection *_conn);
39 static int smtp_server_connection_output(struct smtp_server_connection *conn);
40 static void
41 smtp_server_connection_disconnect(struct smtp_server_connection *conn,
42 				  const char *reason) ATTR_NULL(2);
43 
44 static void
smtp_server_connection_update_stats(struct smtp_server_connection * conn)45 smtp_server_connection_update_stats(struct smtp_server_connection *conn)
46 {
47 	if (conn->conn.input != NULL)
48 		conn->stats.input = conn->conn.input->v_offset;
49 	if (conn->conn.output != NULL)
50 		conn->stats.output = conn->conn.output->offset;
51 }
52 
53 const struct smtp_server_stats *
smtp_server_connection_get_stats(struct smtp_server_connection * conn)54 smtp_server_connection_get_stats(struct smtp_server_connection *conn)
55 {
56 	smtp_server_connection_update_stats(conn);
57 	return &conn->stats;
58 }
59 
60 static bool
smtp_server_connection_check_pipeline(struct smtp_server_connection * conn)61 smtp_server_connection_check_pipeline(struct smtp_server_connection *conn)
62 {
63 	unsigned int pipeline = conn->command_queue_count;
64 
65 	if (conn->command_queue_tail != NULL) {
66 		i_assert(pipeline > 0);
67 		if (conn->command_queue_tail->state ==
68 		    SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY)
69 			pipeline--;
70 	}
71 
72 	if (pipeline >= conn->set.max_pipelined_commands) {
73 		e_debug(conn->event, "Command pipeline is full "
74 			"(pipelined commands %u > limit %u)",
75 			pipeline, conn->set.max_pipelined_commands);
76 		return FALSE;
77 	}
78 	return TRUE;
79 }
80 
smtp_server_connection_input_halt(struct smtp_server_connection * conn)81 void smtp_server_connection_input_halt(struct smtp_server_connection *conn)
82 {
83 	connection_input_halt(&conn->conn);
84 }
85 
smtp_server_connection_input_resume(struct smtp_server_connection * conn)86 void smtp_server_connection_input_resume(struct smtp_server_connection *conn)
87 {
88 	struct smtp_server_command *cmd;
89 	bool cmd_locked = FALSE;
90 
91 	if (conn->conn.io == NULL) {
92 		/* Only resume when we actually can */
93 		if (conn->input_locked || conn->input_broken ||
94 			conn->disconnected)
95 			return;
96 		if (!smtp_server_connection_check_pipeline(conn))
97 			return;
98 
99 		/* Is queued command still blocking input? */
100 		cmd = conn->command_queue_head;
101 		while (cmd != NULL) {
102 			if (cmd->input_locked) {
103 				cmd_locked = TRUE;
104 				break;
105 			}
106 			cmd = cmd->next;
107 		}
108 		if (cmd_locked)
109 			return;
110 
111 		/* Restore input handler */
112 		connection_input_resume(&conn->conn);
113 	}
114 
115 	if (conn->conn.io != NULL &&
116 		i_stream_have_bytes_left(conn->conn.input)) {
117 		io_set_pending(conn->conn.io);
118 	}
119 }
120 
smtp_server_connection_input_lock(struct smtp_server_connection * conn)121 void smtp_server_connection_input_lock(struct smtp_server_connection *conn)
122 {
123 	conn->input_locked = TRUE;
124 	smtp_server_connection_input_halt(conn);
125 }
126 
smtp_server_connection_input_unlock(struct smtp_server_connection * conn)127 void smtp_server_connection_input_unlock(struct smtp_server_connection *conn)
128 {
129 	conn->input_locked = FALSE;
130 	smtp_server_connection_input_resume(conn);
131 }
132 
133 #undef smtp_server_connection_input_capture
smtp_server_connection_input_capture(struct smtp_server_connection * conn,smtp_server_input_callback_t * callback,void * context)134 void smtp_server_connection_input_capture(struct smtp_server_connection *conn,
135 	smtp_server_input_callback_t *callback, void *context)
136 {
137 	i_assert(!conn->input_broken && !conn->disconnected);
138 	connection_input_halt(&conn->conn);
139 	conn->conn.io = io_add_istream(conn->conn.input, *callback, context);
140 }
141 
142 static void
smtp_server_connection_update_rawlog(struct smtp_server_connection * conn)143 smtp_server_connection_update_rawlog(struct smtp_server_connection *conn)
144 {
145 	struct stat st;
146 
147 	if (conn->set.rawlog_dir == NULL)
148 		return;
149 
150 	if (!conn->rawlog_checked) {
151 		conn->rawlog_checked = TRUE;
152 		if (stat(conn->set.rawlog_dir, &st) == 0)
153 			conn->rawlog_enabled = TRUE;
154 	}
155 	if (conn->rawlog_enabled) {
156 		iostream_rawlog_create(conn->set.rawlog_dir,
157 				       &conn->conn.input, &conn->conn.output);
158 	}
159 }
160 
161 static void
smtp_server_connection_streams_changed(struct smtp_server_connection * conn)162 smtp_server_connection_streams_changed(struct smtp_server_connection *conn)
163 {
164 	smtp_server_connection_update_rawlog(conn);
165 	smtp_command_parser_set_stream(conn->smtp_parser, conn->conn.input);
166 
167 	o_stream_set_flush_callback(conn->conn.output,
168 		smtp_server_connection_output, conn);
169 	o_stream_set_flush_pending(conn->conn.output, TRUE);
170 }
171 
smtp_server_connection_set_streams(struct smtp_server_connection * conn,struct istream * input,struct ostream * output)172 void smtp_server_connection_set_streams(struct smtp_server_connection *conn,
173 					struct istream *input,
174 					struct ostream *output)
175 {
176 	struct istream *old_input = conn->conn.input;
177 	struct ostream *old_output = conn->conn.output;
178 
179 	i_assert(conn->created_from_streams);
180 
181 	conn->conn.input = input;
182 	i_stream_ref(conn->conn.input);
183 
184 	conn->conn.output = output;
185 	o_stream_ref(conn->conn.output);
186 	o_stream_set_no_error_handling(conn->conn.output, TRUE);
187 
188 	i_stream_unref(&old_input);
189 	o_stream_unref(&old_output);
190 
191 	smtp_server_connection_streams_changed(conn);
192 }
193 
smtp_server_connection_set_ssl_streams(struct smtp_server_connection * conn,struct istream * input,struct ostream * output)194 void smtp_server_connection_set_ssl_streams(struct smtp_server_connection *conn,
195 					    struct istream *input,
196 					    struct ostream *output)
197 {
198 	conn->ssl_secured = TRUE;
199 	conn->set.capabilities &= ENUM_NEGATE(SMTP_CAPABILITY_STARTTLS);
200 
201 	smtp_server_connection_set_streams(conn, input, output);
202 }
203 
204 static void
smtp_server_connection_idle_timeout(struct smtp_server_connection * conn)205 smtp_server_connection_idle_timeout(struct smtp_server_connection *conn)
206 {
207 	smtp_server_connection_terminate(
208 		&conn, "4.4.2", "Disconnected for inactivity");
209 }
210 
smtp_server_connection_timeout_stop(struct smtp_server_connection * conn)211 void smtp_server_connection_timeout_stop(struct smtp_server_connection *conn)
212 {
213 	if (conn->to_idle != NULL) {
214 		e_debug(conn->event, "Timeout stop");
215 
216 		timeout_remove(&conn->to_idle);
217 	}
218 }
219 
smtp_server_connection_timeout_start(struct smtp_server_connection * conn)220 void smtp_server_connection_timeout_start(struct smtp_server_connection *conn)
221 {
222 	if (conn->disconnected)
223 		return;
224 
225 	if (conn->to_idle == NULL &&
226 		conn->set.max_client_idle_time_msecs > 0) {
227 		e_debug(conn->event, "Timeout start");
228 
229 		conn->to_idle = timeout_add(
230 			conn->set.max_client_idle_time_msecs,
231 			smtp_server_connection_idle_timeout, conn);
232 	}
233 }
234 
smtp_server_connection_timeout_reset(struct smtp_server_connection * conn)235 void smtp_server_connection_timeout_reset(struct smtp_server_connection *conn)
236 {
237 	if (conn->to_idle != NULL)
238 		timeout_reset(conn->to_idle);
239 }
240 
241 static void
smtp_server_connection_timeout_update(struct smtp_server_connection * conn)242 smtp_server_connection_timeout_update(struct smtp_server_connection *conn)
243 {
244 	struct smtp_server_command *cmd = conn->command_queue_head;
245 
246 	if (cmd == NULL) {
247 		smtp_server_connection_timeout_start(conn);
248 		return;
249 	}
250 
251 	switch (cmd->state) {
252 	case SMTP_SERVER_COMMAND_STATE_NEW:
253 		smtp_server_connection_timeout_start(conn);
254 		break;
255 	case SMTP_SERVER_COMMAND_STATE_PROCESSING:
256 		if (cmd->input_captured) {
257 			/* Command updates timeout internally */
258 			return;
259 		}
260 		smtp_server_connection_timeout_stop(conn);
261 		break;
262 	case SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY:
263 	case SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY:
264 		smtp_server_connection_timeout_stop(conn);
265 		break;
266 	case SMTP_SERVER_COMMAND_STATE_FINISHED:
267 	case SMTP_SERVER_COMMAND_STATE_ABORTED:
268 		i_unreached();
269 	}
270 }
271 
smtp_server_connection_ready(struct smtp_server_connection * conn)272 static void smtp_server_connection_ready(struct smtp_server_connection *conn)
273 {
274 	conn->raw_input = conn->conn.input;
275 	conn->raw_output = conn->conn.output;
276 
277 	smtp_server_connection_update_rawlog(conn);
278 
279 	conn->smtp_parser = smtp_command_parser_init(conn->conn.input,
280 						     &conn->set.command_limits);
281 	o_stream_set_flush_callback(conn->conn.output,
282 				    smtp_server_connection_output, conn);
283 
284 	o_stream_cork(conn->conn.output);
285 	if (conn->authenticated) {
286 		/* RFC 4954, Section 4:
287 		   Should the client successfully complete the exchange, the
288 		   SMTP server issues a 235 reply. */
289 		smtp_server_connection_send_line(
290 			conn, "235 2.7.0 Logged in.");
291 	} else {
292 		smtp_server_connection_send_line(
293 			conn, "220 %s %s", conn->set.hostname,
294 			conn->set.login_greeting);
295 	}
296 	if (!conn->corked)
297 		o_stream_uncork(conn->conn.output);
298 }
299 
smtp_server_connection_destroy(struct connection * _conn)300 static void smtp_server_connection_destroy(struct connection *_conn)
301 {
302 	struct smtp_server_connection *conn =
303 		(struct smtp_server_connection *)_conn;
304 
305 	smtp_server_connection_disconnect(conn, NULL);
306 	smtp_server_connection_unref(&conn);
307 }
308 
309 static bool
smtp_server_connection_handle_command(struct smtp_server_connection * conn,const char * cmd_name,const char * cmd_params)310 smtp_server_connection_handle_command(struct smtp_server_connection *conn,
311 	const char *cmd_name, const char *cmd_params)
312 {
313 	struct smtp_server_connection *tmp_conn = conn;
314 	struct smtp_server_command *cmd;
315 	bool finished;
316 
317 	cmd = smtp_server_command_new(tmp_conn, cmd_name);
318 
319 	smtp_server_command_ref(cmd);
320 
321 	smtp_server_connection_ref(tmp_conn);
322 	smtp_server_command_execute(cmd, cmd_params);
323 	if (!smtp_server_connection_unref(&tmp_conn)) {
324 		/* The command start callback managed to get this connection
325 		   destroyed */
326 		smtp_server_command_unref(&cmd);
327 		return FALSE;
328 	}
329 
330 	if (conn->command_queue_head == cmd)
331 		(void)smtp_server_command_next_to_reply(&cmd);
332 
333 	smtp_server_connection_timeout_update(conn);
334 
335 	finished = !cmd->input_locked;
336 	return (!smtp_server_command_unref(&cmd) || finished);
337 }
338 
339 static int
smtp_server_connection_init_ssl_ctx(struct smtp_server_connection * conn,const char ** error_r)340 smtp_server_connection_init_ssl_ctx(struct smtp_server_connection *conn,
341 				    const char **error_r)
342 {
343 	struct smtp_server *server = conn->server;
344 	const char *error;
345 
346 	if (conn->ssl_ctx != NULL || conn->set.ssl == NULL)
347 		return 0;
348 	if (conn->set.ssl == server->set.ssl) {
349 		if (smtp_server_init_ssl_ctx(server, error_r) < 0)
350 			return -1;
351 		conn->ssl_ctx = server->ssl_ctx;
352 		ssl_iostream_context_ref(conn->ssl_ctx);
353 		return 0;
354 	}
355 
356 	if (ssl_iostream_server_context_cache_get(conn->set.ssl, &conn->ssl_ctx,
357 						  &error) < 0) {
358 		*error_r = t_strdup_printf(
359 			"Couldn't initialize SSL context: %s", error);
360 		return -1;
361 	}
362 	return 0;
363 }
364 
smtp_server_connection_ssl_init(struct smtp_server_connection * conn)365 int smtp_server_connection_ssl_init(struct smtp_server_connection *conn)
366 {
367 	const char *error;
368 	int ret;
369 
370 	if (smtp_server_connection_init_ssl_ctx(conn, &error) < 0) {
371 		e_error(conn->event, "Couldn't initialize SSL: %s", error);
372 		return -1;
373 	}
374 
375 	e_debug(conn->event, "Starting SSL handshake");
376 
377 	if (conn->raw_input != conn->conn.input) {
378 		/* Recreate rawlog after STARTTLS */
379 		i_stream_ref(conn->raw_input);
380 		o_stream_ref(conn->raw_output);
381 		i_stream_destroy(&conn->conn.input);
382 		o_stream_destroy(&conn->conn.output);
383 		conn->conn.input = conn->raw_input;
384 		conn->conn.output = conn->raw_output;
385 	}
386 
387 	smtp_server_connection_input_halt(conn);
388 	if (conn->ssl_ctx == NULL) {
389 		ret = master_service_ssl_init(
390 			master_service, &conn->conn.input, &conn->conn.output,
391 			&conn->ssl_iostream, &error);
392 	} else {
393 		ret = io_stream_create_ssl_server(
394 			conn->ssl_ctx, conn->set.ssl,
395 			&conn->conn.input, &conn->conn.output,
396 			&conn->ssl_iostream, &error);
397 	}
398 	if (ret < 0) {
399 		e_error(conn->event,
400 			"Couldn't initialize SSL server for %s: %s",
401 			conn->conn.name, error);
402 		return -1;
403 	}
404 	smtp_server_connection_input_resume(conn);
405 
406 	conn->ssl_secured = TRUE;
407 	conn->set.capabilities &= ENUM_NEGATE(SMTP_CAPABILITY_STARTTLS);
408 
409 	if (conn->ssl_start)
410 		smtp_server_connection_ready(conn);
411 	else
412 		smtp_server_connection_streams_changed(conn);
413 	return 0;
414 }
415 
416 static void
smtp_server_connection_handle_input(struct smtp_server_connection * conn)417 smtp_server_connection_handle_input(struct smtp_server_connection *conn)
418 {
419 	struct smtp_server_command *pending_command;
420 	enum smtp_command_parse_error error_code;
421 	const char *cmd_name, *cmd_params, *error;
422 	int ret;
423 
424 	/* Check whether we are continuing a command */
425 	pending_command = NULL;
426 	if (conn->command_queue_tail != NULL) {
427 		pending_command =
428 			((conn->command_queue_tail->state ==
429 			  SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY) ?
430 			 conn->command_queue_tail : NULL);
431 	}
432 
433 	smtp_server_connection_timeout_reset(conn);
434 
435 	/* Parse commands */
436 	ret = 1;
437 	while (!conn->closing && !conn->input_locked && ret != 0) {
438 		while ((ret = smtp_command_parse_next(
439 			conn->smtp_parser, &cmd_name, &cmd_params,
440 			&error_code, &error)) > 0) {
441 
442 			if (pending_command != NULL) {
443 				/* Previous command is now fully read and ready
444 				   to reply */
445 				smtp_server_command_ready_to_reply(pending_command);
446 				pending_command = NULL;
447 			}
448 
449 			e_debug(conn->event, "Received new command: %s %s",
450 				cmd_name, cmd_params);
451 
452 			conn->stats.command_count++;
453 
454 			/* Handle command (cmd may be destroyed after this) */
455 			if (!smtp_server_connection_handle_command(conn,
456 				cmd_name, cmd_params))
457 				return;
458 
459 			if (conn->disconnected)
460 				return;
461 			/* Last command locked the input; stop trying to read
462 			   more. */
463 			if (conn->input_locked)
464 				break;
465 			/* Client indicated it will close after this command;
466 			   stop trying to read more. */
467 			if (conn->closing)
468 				break;
469 
470 			if (!smtp_server_connection_check_pipeline(conn)) {
471 				smtp_server_connection_input_halt(conn);
472 				return;
473 			}
474 
475 			if (conn->command_queue_tail != NULL) {
476 				pending_command =
477 					((conn->command_queue_tail->state ==
478 					  SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY) ?
479 					 conn->command_queue_tail : NULL);
480 			}
481 		}
482 
483 		if (ret < 0 && conn->conn.input->eof) {
484 			const char *error =
485 				i_stream_get_disconnect_reason(conn->conn.input);
486 			e_debug(conn->event, "Remote closed connection: %s",
487 				error);
488 
489 			if (conn->command_queue_head == NULL ||
490 			    conn->command_queue_head->state <
491 			    SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY) {
492 				/* No pending commands or unfinished
493 				   command; close */
494 				smtp_server_connection_close(&conn, error);
495 			} else {
496 				/* A command is still processing;
497 				   only drop input io for now */
498 				conn->input_broken = TRUE;
499 				smtp_server_connection_input_halt(conn);
500 			}
501 			return;
502 		}
503 
504 		if (ret < 0) {
505 			struct smtp_server_command *cmd;
506 
507 			e_debug(conn->event,
508 				"Client sent invalid command: %s", error);
509 
510 			switch (error_code) {
511 			case SMTP_COMMAND_PARSE_ERROR_BROKEN_COMMAND:
512 				conn->input_broken = TRUE;
513 				/* fall through */
514 			case SMTP_COMMAND_PARSE_ERROR_BAD_COMMAND:
515 				cmd = smtp_server_command_new_invalid(conn);
516 				smtp_server_command_fail(
517 					cmd, 500, "5.5.2",
518 					"Invalid command syntax");
519 				break;
520 			case SMTP_COMMAND_PARSE_ERROR_LINE_TOO_LONG:
521 				cmd = smtp_server_command_new_invalid(conn);
522 				smtp_server_command_fail(
523 					cmd, 500, "5.5.2", "Line too long");
524 				break;
525 			case SMTP_COMMAND_PARSE_ERROR_DATA_TOO_LARGE:
526 				/* Command data size exceeds the absolute limit;
527 				   i.e. beyond which we don't even want to skip
528 				   data anymore. The command error is usually
529 				   already submitted by the application and sent
530 				   to the client. */
531 				smtp_server_connection_close(&conn,
532 					"Command data size exceeds absolute limit");
533 				return;
534 			case SMTP_COMMAND_PARSE_ERROR_BROKEN_STREAM:
535 				smtp_server_connection_close(&conn, error);
536 				return;
537 			default:
538 				i_unreached();
539 			}
540 		}
541 
542 		if (conn->disconnected)
543 			return;
544 		if (conn->input_broken || conn->closing) {
545 			smtp_server_connection_input_halt(conn);
546 			return;
547 		}
548 
549 		if (ret == 0 && pending_command != NULL &&
550 		    !smtp_command_parser_pending_data(conn->smtp_parser)) {
551 			/* Previous command is now fully read and ready to
552 			   reply */
553 			smtp_server_command_ready_to_reply(pending_command);
554 		}
555 	}
556 }
557 
smtp_server_connection_input(struct connection * _conn)558 static void smtp_server_connection_input(struct connection *_conn)
559 {
560 	struct smtp_server_connection *conn =
561 		(struct smtp_server_connection *)_conn;
562 
563 	i_assert(!conn->input_broken);
564 
565 	if (conn->handling_input)
566 		return;
567 
568 	smtp_server_connection_timeout_reset(conn);
569 
570 	if (conn->ssl_start && conn->ssl_iostream == NULL) {
571 		if (smtp_server_connection_ssl_init(conn) < 0) {
572 			smtp_server_connection_close(&conn,
573 				"SSL Initialization failed");
574 			return;
575 		}
576 		if (conn->halted) {
577 			smtp_server_connection_input_lock(conn);
578 			return;
579 		}
580 	}
581 	i_assert(!conn->halted);
582 
583 
584 	if (!smtp_server_connection_check_pipeline(conn)) {
585 		smtp_server_connection_input_halt(conn);
586 		return;
587 	}
588 
589 	smtp_server_connection_ref(conn);
590 	conn->handling_input = TRUE;
591 	if (conn->callbacks != NULL &&
592 	    conn->callbacks->conn_cmd_input_pre != NULL)
593 		conn->callbacks->conn_cmd_input_pre(conn->context);
594 	smtp_server_connection_handle_input(conn);
595 	if (conn->callbacks != NULL &&
596 	    conn->callbacks->conn_cmd_input_post != NULL)
597 		conn->callbacks->conn_cmd_input_post(conn->context);
598 	conn->handling_input = FALSE;
599 	smtp_server_connection_unref(&conn);
600 }
601 
smtp_server_connection_pending_command_data(struct smtp_server_connection * conn)602 bool smtp_server_connection_pending_command_data(
603 	struct smtp_server_connection *conn)
604 {
605 	if (conn->smtp_parser == NULL)
606 		return FALSE;
607 	return smtp_command_parser_pending_data(conn->smtp_parser);
608 }
609 
610 /*
611  * Command reply handling
612  */
613 
smtp_server_connection_handle_output_error(struct smtp_server_connection * conn)614 void smtp_server_connection_handle_output_error(
615 	struct smtp_server_connection *conn)
616 {
617 	smtp_server_connection_close(&conn,
618 		o_stream_get_disconnect_reason(conn->conn.output));
619 }
620 
621 static bool
smtp_server_connection_next_reply(struct smtp_server_connection * conn)622 smtp_server_connection_next_reply(struct smtp_server_connection *conn)
623 {
624 	struct smtp_server_command *cmd;
625 	unsigned int i;
626 
627 	cmd = conn->command_queue_head;
628 	if (cmd == NULL) {
629 		/* No commands pending */
630 		e_debug(conn->event, "No more commands pending");
631 		return FALSE;
632 	}
633 
634 	if (!smtp_server_command_next_to_reply(&cmd))
635 		return FALSE;
636 	if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY)
637 		return FALSE;
638 
639 	i_assert(cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY &&
640 		 array_is_created(&cmd->replies));
641 
642 	if (!smtp_server_command_completed(&cmd))
643 		return TRUE;
644 
645 	/* Send command replies */
646 	// FIXME: handle LMTP DATA command with enormous number of recipients;
647 	// i.e. don't keep filling output stream with replies indefinitely.
648 	for (i = 0; i < cmd->replies_expected; i++) {
649 		struct smtp_server_reply *reply;
650 
651 		reply = array_idx_modifiable(&cmd->replies, i);
652 
653 		if (!reply->submitted) {
654 			i_assert(!reply->sent);
655 			cmd->state = SMTP_SERVER_COMMAND_STATE_PROCESSING;
656 			break;
657 		}
658 		if (smtp_server_reply_send(reply) < 0)
659 			return FALSE;
660 	}
661 	if (cmd->state == SMTP_SERVER_COMMAND_STATE_PROCESSING)
662 		return FALSE;
663 
664 	smtp_server_command_finished(cmd);
665 	return TRUE;
666 }
667 
smtp_server_connection_cork(struct smtp_server_connection * conn)668 void smtp_server_connection_cork(struct smtp_server_connection *conn)
669 {
670 	conn->corked = TRUE;
671 	if (conn->conn.output != NULL)
672 		o_stream_cork(conn->conn.output);
673 }
674 
smtp_server_connection_uncork(struct smtp_server_connection * conn)675 void smtp_server_connection_uncork(struct smtp_server_connection *conn)
676 {
677 	conn->corked = FALSE;
678 	if (conn->conn.output != NULL) {
679 		if (o_stream_uncork_flush(conn->conn.output) < 0) {
680 			smtp_server_connection_handle_output_error(conn);
681 			return;
682 		}
683 		smtp_server_connection_trigger_output(conn);
684 	}
685 }
686 
687 static void
smtp_server_connection_send_replies(struct smtp_server_connection * conn)688 smtp_server_connection_send_replies(struct smtp_server_connection *conn)
689 {
690 	/* Send more replies until no more replies remain, the output
691 	   blocks again, or the connection is closed */
692 	while (!conn->disconnected && smtp_server_connection_next_reply(conn));
693 
694 	smtp_server_connection_timeout_update(conn);
695 
696 	/* Accept more commands if possible */
697 	smtp_server_connection_input_resume(conn);
698 }
699 
smtp_server_connection_flush(struct smtp_server_connection * conn)700 int smtp_server_connection_flush(struct smtp_server_connection *conn)
701 {
702 	struct ostream *output = conn->conn.output;
703 	int ret;
704 
705 	if ((ret = o_stream_flush(output)) <= 0) {
706 		if (ret < 0)
707 			smtp_server_connection_handle_output_error(conn);
708 		return ret;
709 	}
710 	return 1;
711 }
712 
smtp_server_connection_output(struct smtp_server_connection * conn)713 static int smtp_server_connection_output(struct smtp_server_connection *conn)
714 {
715 	int ret;
716 
717 	e_debug(conn->event, "Sending replies");
718 
719 	smtp_server_connection_ref(conn);
720 	o_stream_cork(conn->conn.output);
721 	ret = smtp_server_connection_flush(conn);
722 	if (ret > 0) {
723 		smtp_server_connection_timeout_reset(conn);
724 		smtp_server_connection_send_replies(conn);
725 	}
726 	if (ret >= 0 && !conn->corked && conn->conn.output != NULL)
727 		ret = o_stream_uncork_flush(conn->conn.output);
728 	if (conn->conn.output != NULL && conn->conn.output->closed) {
729 		smtp_server_connection_handle_output_error(conn);
730 		ret = -1;
731 	}
732 	smtp_server_connection_unref(&conn);
733 	return ret;
734 }
735 
smtp_server_connection_trigger_output(struct smtp_server_connection * conn)736 void smtp_server_connection_trigger_output(struct smtp_server_connection *conn)
737 {
738 	if (conn->conn.output != NULL) {
739 		e_debug(conn->event, "Trigger output");
740 		o_stream_set_flush_pending(conn->conn.output, TRUE);
741 	}
742 }
743 
744 /*
745  *
746  */
747 
748 static struct connection_settings smtp_server_connection_set = {
749 	.input_max_size = SIZE_MAX,
750 	.output_max_size = SIZE_MAX,
751 	.client = FALSE,
752 	.log_connection_id = TRUE,
753 };
754 
755 static const struct connection_vfuncs smtp_server_connection_vfuncs = {
756 	.destroy = smtp_server_connection_destroy,
757 	.input = smtp_server_connection_input,
758 };
759 
smtp_server_connection_list_init(void)760 struct connection_list *smtp_server_connection_list_init(void)
761 {
762 	return connection_list_init(&smtp_server_connection_set,
763 				    &smtp_server_connection_vfuncs);
764 }
765 
766 static struct event *
smtp_server_connection_event_create(struct smtp_server * server,const struct smtp_server_settings * set)767 smtp_server_connection_event_create(struct smtp_server *server,
768 				    const struct smtp_server_settings *set)
769 {
770 	struct event *conn_event;
771 
772 	if (set != NULL && set->event_parent != NULL) {
773 		conn_event = event_create(set->event_parent);
774 		smtp_server_event_init(server, conn_event);
775 	} else
776 		conn_event = event_create(server->event);
777 	event_set_append_log_prefix(conn_event, t_strdup_printf(
778 		"%s-server: ", smtp_protocol_name(server->set.protocol)));
779 	event_set_forced_debug(conn_event, (set != NULL && set->debug));
780 
781 	return conn_event;
782 }
783 
784 static struct smtp_server_connection * ATTR_NULL(5, 6)
smtp_server_connection_alloc(struct smtp_server * server,const struct smtp_server_settings * set,int fd_in,int fd_out,const struct smtp_server_callbacks * callbacks,void * context)785 smtp_server_connection_alloc(struct smtp_server *server,
786 			     const struct smtp_server_settings *set,
787 			     int fd_in, int fd_out,
788 			     const struct smtp_server_callbacks *callbacks,
789 			     void *context)
790 {
791 	struct smtp_server_connection *conn;
792 	pool_t pool;
793 
794 	pool = pool_alloconly_create("smtp server", 1024);
795 	conn = p_new(pool, struct smtp_server_connection, 1);
796 	conn->pool = pool;
797 	conn->refcount = 1;
798 	conn->server = server;
799 	conn->callbacks = callbacks;
800 	conn->context = context;
801 
802 	/* Merge settings with global server settings */
803 	conn->set = server->set;
804 	if (set != NULL) {
805 		conn->set.protocol = server->set.protocol;
806 		if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
807 			conn->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
808 
809 		if (set->ssl != NULL)
810 			conn->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
811 
812 		if (set->hostname != NULL && *set->hostname != '\0')
813 			conn->set.hostname = p_strdup(pool, set->hostname);
814 		if (set->login_greeting != NULL &&
815 			*set->login_greeting != '\0') {
816 			conn->set.login_greeting =
817 				p_strdup(pool, set->login_greeting);
818 		}
819 		if (set->capabilities != 0)
820 			conn->set.capabilities = set->capabilities;
821 		conn->set.workarounds |= set->workarounds;
822 
823 		if (set->max_client_idle_time_msecs > 0) {
824 			conn->set.max_client_idle_time_msecs =
825 				set->max_client_idle_time_msecs;
826 		}
827 		if (set->max_pipelined_commands > 0) {
828 			conn->set.max_pipelined_commands =
829 				set->max_pipelined_commands;
830 		}
831 		if (set->max_bad_commands > 0) {
832 			conn->set.max_bad_commands = set->max_bad_commands;
833 		}
834 		if (set->max_recipients > 0)
835 			conn->set.max_recipients = set->max_recipients;
836 		smtp_command_limits_merge(&conn->set.command_limits,
837 					  &set->command_limits);
838 
839 		conn->set.max_message_size = set->max_message_size;
840 		if (set->max_message_size == 0 ||
841 		    set->max_message_size == UOFF_T_MAX) {
842 			conn->set.command_limits.max_data_size = UOFF_T_MAX;
843 		} else if (conn->set.command_limits.max_data_size != 0) {
844 			/* Explicit limit given */
845 		} else if (set->max_message_size >
846 			(UOFF_T_MAX - SMTP_SERVER_DEFAULT_MAX_SIZE_EXCESS_LIMIT)) {
847 			/* Very high limit */
848 			conn->set.command_limits.max_data_size = UOFF_T_MAX;
849 		} else {
850 			/* Absolute maximum before connection is closed in DATA
851 			   command */
852 			conn->set.command_limits.max_data_size =
853 				set->max_message_size +
854 					SMTP_SERVER_DEFAULT_MAX_SIZE_EXCESS_LIMIT;
855 		}
856 
857 		if (set->mail_param_extensions != NULL) {
858 			conn->set.mail_param_extensions =
859 				p_strarray_dup(pool, set->mail_param_extensions);
860 		}
861 		if (set->rcpt_param_extensions != NULL) {
862 			conn->set.rcpt_param_extensions =
863 				p_strarray_dup(pool, set->rcpt_param_extensions);
864 		}
865 		if (set->xclient_extensions != NULL) {
866 			conn->set.xclient_extensions =
867 				p_strarray_dup(pool, set->xclient_extensions);
868 		}
869 
870 		if (set->socket_send_buffer_size > 0) {
871 			conn->set.socket_send_buffer_size =
872 				set->socket_send_buffer_size;
873 		}
874 		if (set->socket_recv_buffer_size > 0) {
875 			conn->set.socket_recv_buffer_size =
876 				set->socket_recv_buffer_size;
877 		}
878 
879 		conn->set.tls_required =
880 			conn->set.tls_required || set->tls_required;
881 		conn->set.auth_optional =
882 			conn->set.auth_optional || set->auth_optional;
883 		conn->set.mail_path_allow_broken =
884 			conn->set.mail_path_allow_broken ||
885 				set->mail_path_allow_broken;
886 		conn->set.rcpt_domain_optional =
887 			conn->set.rcpt_domain_optional ||
888 				set->rcpt_domain_optional;
889 		conn->set.debug = conn->set.debug || set->debug;
890 	}
891 
892 	if (set != NULL && set->mail_param_extensions != NULL) {
893 		const char *const *extp;
894 
895 		p_array_init(&conn->mail_param_extensions, pool,
896 			     str_array_length(set->mail_param_extensions) + 8);
897 		for (extp = set->mail_param_extensions; *extp != NULL; extp++) {
898 			const char *ext = p_strdup(pool, *extp);
899 			array_push_back(&conn->mail_param_extensions, &ext);
900 		}
901 		array_append_zero(&conn->mail_param_extensions);
902 	}
903 	if (set != NULL && set->rcpt_param_extensions != NULL) {
904 		const char *const *extp;
905 
906 		p_array_init(&conn->rcpt_param_extensions, pool,
907 			     str_array_length(set->rcpt_param_extensions) + 8);
908 		for (extp = set->rcpt_param_extensions; *extp != NULL; extp++) {
909 			const char *ext = p_strdup(pool, *extp);
910 			array_push_back(&conn->rcpt_param_extensions, &ext);
911 		}
912 		array_append_zero(&conn->rcpt_param_extensions);
913 	}
914 
915 	net_set_nonblock(fd_in, TRUE);
916 	if (fd_in != fd_out)
917 		net_set_nonblock(fd_out, TRUE);
918 	(void)net_set_tcp_nodelay(fd_out, TRUE);
919 
920 	set = &conn->set;
921 	if (set->socket_send_buffer_size > 0 &&
922 	    net_set_send_buffer_size(fd_out,
923 			             set->socket_send_buffer_size) < 0) {
924 		e_error(conn->event,
925 			"net_set_send_buffer_size(%zu) failed: %m",
926 			set->socket_send_buffer_size);
927 	}
928 	if (set->socket_recv_buffer_size > 0 &&
929 	    net_set_recv_buffer_size(fd_in,
930 				     set->socket_recv_buffer_size) < 0) {
931 		e_error(conn->event,
932 			"net_set_recv_buffer_size(%zu) failed: %m",
933 			set->socket_recv_buffer_size);
934 	}
935 
936 	return conn;
937 }
938 
939 struct smtp_server_connection *
smtp_server_connection_create(struct smtp_server * server,int fd_in,int fd_out,const struct ip_addr * remote_ip,in_port_t remote_port,bool ssl_start,const struct smtp_server_settings * set,const struct smtp_server_callbacks * callbacks,void * context)940 smtp_server_connection_create(
941 	struct smtp_server *server, int fd_in, int fd_out,
942 	const struct ip_addr *remote_ip, in_port_t remote_port,
943 	bool ssl_start, const struct smtp_server_settings *set,
944 	const struct smtp_server_callbacks *callbacks, void *context)
945 {
946 	struct smtp_server_connection *conn;
947 	struct event *conn_event;
948 
949 	conn = smtp_server_connection_alloc(server, set, fd_in, fd_out,
950 					    callbacks, context);
951 	conn_event = smtp_server_connection_event_create(server, set);
952 	conn->conn.event_parent = conn_event;
953 	connection_init_server_ip(server->conn_list, &conn->conn, NULL,
954 				  fd_in, fd_out, remote_ip, remote_port);
955 	conn->event = conn->conn.event;
956 	event_unref(&conn_event);
957 
958 	conn->ssl_start = ssl_start;
959 	if (ssl_start)
960 		conn->set.capabilities &= ENUM_NEGATE(SMTP_CAPABILITY_STARTTLS);
961 
962 	/* Halt input until started */
963 	smtp_server_connection_halt(conn);
964 
965 	e_debug(conn->event, "Connection created");
966 
967 	return conn;
968 }
969 
970 struct smtp_server_connection *
smtp_server_connection_create_from_streams(struct smtp_server * server,struct istream * input,struct ostream * output,const struct ip_addr * remote_ip,in_port_t remote_port,const struct smtp_server_settings * set,const struct smtp_server_callbacks * callbacks,void * context)971 smtp_server_connection_create_from_streams(
972 	struct smtp_server *server,
973 	struct istream *input, struct ostream *output,
974 	const struct ip_addr *remote_ip, in_port_t remote_port,
975 	const struct smtp_server_settings *set,
976 	const struct smtp_server_callbacks *callbacks, void *context)
977 {
978 	struct smtp_server_connection *conn;
979 	struct event *conn_event;
980 	int fd_in, fd_out;
981 
982 	fd_in = i_stream_get_fd(input);
983 	fd_out = o_stream_get_fd(output);
984 	i_assert(fd_in >= 0);
985 	i_assert(fd_out >= 0);
986 
987 	conn = smtp_server_connection_alloc(server, set, fd_in, fd_out,
988 					    callbacks, context);
989 	if (remote_ip != NULL && remote_ip->family != 0)
990 		conn->conn.remote_ip = *remote_ip;
991 	if (remote_port != 0)
992 		conn->conn.remote_port = remote_port;
993 	conn_event = smtp_server_connection_event_create(server, set);
994 	conn->conn.event_parent = conn_event;
995 	connection_init_from_streams(server->conn_list,	&conn->conn, NULL,
996 				     input, output);
997 	conn->created_from_streams = TRUE;
998 	conn->event = conn->conn.event;
999 	event_unref(&conn_event);
1000 
1001 	/* Halt input until started */
1002 	smtp_server_connection_halt(conn);
1003 
1004 	e_debug(conn->event, "Connection created");
1005 
1006 	return conn;
1007 }
1008 
smtp_server_connection_ref(struct smtp_server_connection * conn)1009 void smtp_server_connection_ref(struct smtp_server_connection *conn)
1010 {
1011 	conn->refcount++;
1012 }
1013 
1014 static const char *
smtp_server_connection_get_disconnect_reason(struct smtp_server_connection * conn)1015 smtp_server_connection_get_disconnect_reason(
1016 	struct smtp_server_connection *conn)
1017 {
1018 	const char *err;
1019 
1020 	if (conn->ssl_iostream != NULL &&
1021 	    !ssl_iostream_is_handshaked(conn->ssl_iostream)) {
1022 		err = ssl_iostream_get_last_error(conn->ssl_iostream);
1023 		if (err != NULL) {
1024 			return t_strdup_printf(
1025 				"TLS handshaking failed: %s", err);
1026 		}
1027 	}
1028 
1029 	return io_stream_get_disconnect_reason(conn->conn.input,
1030 					       conn->conn.output);
1031 }
1032 
1033 static void
smtp_server_connection_disconnect(struct smtp_server_connection * conn,const char * reason)1034 smtp_server_connection_disconnect(struct smtp_server_connection *conn,
1035 				  const char *reason)
1036 {
1037 	struct smtp_server_command *cmd, *cmd_next;
1038 
1039 	if (conn->disconnected)
1040 		return;
1041 	conn->disconnected = TRUE;
1042 
1043 	if (reason == NULL)
1044 		reason = smtp_server_connection_get_disconnect_reason(conn);
1045 	else
1046 		reason = t_str_oneline(reason);
1047 
1048 	cmd = conn->command_queue_head;
1049 	if (cmd != NULL && cmd->reg != NULL) {
1050 		/* Unfinished command - include it in the reason string */
1051 		reason = t_strdup_printf("%s (unfinished %s command)",
1052 			reason, cmd->reg->name);
1053 	}
1054 	if (!conn->set.no_state_in_reason) {
1055 		reason = t_strdup_printf("%s (state=%s)", reason,
1056 			smtp_server_state_names[conn->state.state]);
1057 	}
1058 
1059 	e_debug(conn->event, "Disconnected: %s", reason);
1060 
1061 	/* Preserve statistics */
1062 	smtp_server_connection_update_stats(conn);
1063 
1064 	/* Drop transaction */
1065 	smtp_server_connection_reset_state(conn);
1066 
1067 	/* Clear command queue */
1068 	cmd = conn->command_queue_head;
1069 	while (cmd != NULL) {
1070 		cmd_next = cmd->next;
1071 		smtp_server_command_abort(&cmd);
1072 		cmd = cmd_next;
1073 	}
1074 
1075 	smtp_server_connection_timeout_stop(conn);
1076 	if (conn->conn.output != NULL)
1077 		o_stream_uncork(conn->conn.output);
1078 	if (conn->smtp_parser != NULL)
1079 		smtp_command_parser_deinit(&conn->smtp_parser);
1080 	ssl_iostream_destroy(&conn->ssl_iostream);
1081 	if (conn->ssl_ctx != NULL)
1082 		ssl_iostream_context_unref(&conn->ssl_ctx);
1083 
1084 	if (conn->callbacks != NULL &&
1085 	    conn->callbacks->conn_disconnect != NULL) {
1086 		/* The callback may close the fd, so remove IO before that */
1087 		io_remove(&conn->conn.io);
1088 		conn->callbacks->conn_disconnect(conn->context, reason);
1089 	}
1090 
1091 	if (!conn->created_from_streams)
1092 		connection_disconnect(&conn->conn);
1093 	else {
1094 		conn->conn.fd_in = conn->conn.fd_out = -1;
1095 		io_remove(&conn->conn.io);
1096 		i_stream_unref(&conn->conn.input);
1097 		o_stream_unref(&conn->conn.output);
1098 	}
1099 }
1100 
smtp_server_connection_unref(struct smtp_server_connection ** _conn)1101 bool smtp_server_connection_unref(struct smtp_server_connection **_conn)
1102 {
1103 	struct smtp_server_connection *conn = *_conn;
1104 
1105 	*_conn = NULL;
1106 
1107 	i_assert(conn->refcount > 0);
1108 	if (--conn->refcount > 0)
1109 		return TRUE;
1110 
1111 	smtp_server_connection_disconnect(conn, NULL);
1112 
1113 	e_debug(conn->event, "Connection destroy");
1114 
1115 	if (conn->callbacks != NULL && conn->callbacks->conn_free != NULL)
1116 		conn->callbacks->conn_free(conn->context);
1117 
1118 	connection_deinit(&conn->conn);
1119 
1120 	i_free(conn->proxy_helo);
1121 	i_free(conn->helo_domain);
1122 	i_free(conn->username);
1123 	event_unref(&conn->next_trans_event);
1124 	pool_unref(&conn->pool);
1125 	return FALSE;
1126 }
1127 
smtp_server_connection_send_line(struct smtp_server_connection * conn,const char * fmt,...)1128 void smtp_server_connection_send_line(struct smtp_server_connection *conn,
1129 				      const char *fmt, ...)
1130 {
1131 	va_list args;
1132 
1133 	va_start(args, fmt);
1134 
1135 	T_BEGIN {
1136 		string_t *str;
1137 
1138 		str = t_str_new(256);
1139 		str_vprintfa(str, fmt, args);
1140 
1141 		e_debug(conn->event, "Sent: %s", str_c(str));
1142 
1143 		str_append(str, "\r\n");
1144 		o_stream_nsend(conn->conn.output, str_data(str), str_len(str));
1145 	} T_END;
1146 	va_end(args);
1147 }
1148 
smtp_server_connection_reply_lines(struct smtp_server_connection * conn,unsigned int status,const char * enh_code,const char * const * text_lines)1149 void smtp_server_connection_reply_lines(struct smtp_server_connection *conn,
1150 				        unsigned int status,
1151 					const char *enh_code,
1152 					const char *const *text_lines)
1153 {
1154 	struct smtp_reply reply;
1155 
1156 	i_zero(&reply);
1157 	reply.status = status;
1158 	reply.text_lines = text_lines;
1159 
1160 	if (!smtp_reply_parse_enhanced_code(
1161 		enh_code, &reply.enhanced_code, NULL))
1162 		reply.enhanced_code = SMTP_REPLY_ENH_CODE(status / 100, 0, 0);
1163 
1164 	T_BEGIN {
1165 		string_t *str;
1166 
1167 		e_debug(conn->event, "Sent: %s", smtp_reply_log(&reply));
1168 
1169 		str = t_str_new(256);
1170 		smtp_reply_write(str, &reply);
1171 		o_stream_nsend(conn->conn.output, str_data(str), str_len(str));
1172 	} T_END;
1173 }
1174 
smtp_server_connection_reply_immediate(struct smtp_server_connection * conn,unsigned int status,const char * fmt,...)1175 void smtp_server_connection_reply_immediate(
1176 	struct smtp_server_connection *conn,
1177 	unsigned int status, const char *fmt, ...)
1178 {
1179 	va_list args;
1180 
1181 	va_start(args, fmt);
1182 	T_BEGIN {
1183 		string_t *str;
1184 
1185 		str = t_str_new(256);
1186 		str_printfa(str, "%03u ", status);
1187 		str_vprintfa(str, fmt, args);
1188 
1189 		e_debug(conn->event, "Sent: %s", str_c(str));
1190 
1191 		str_append(str, "\r\n");
1192 		o_stream_nsend(conn->conn.output, str_data(str), str_len(str));
1193 	} T_END;
1194 	va_end(args);
1195 
1196 	/* Send immediately */
1197 	if (o_stream_is_corked(conn->conn.output)) {
1198 		o_stream_uncork(conn->conn.output);
1199 		o_stream_cork(conn->conn.output);
1200 	}
1201 }
1202 
smtp_server_connection_login(struct smtp_server_connection * conn,const char * username,const char * helo,const unsigned char * pdata,unsigned int pdata_len,bool ssl_secured)1203 void smtp_server_connection_login(struct smtp_server_connection *conn,
1204 				  const char *username, const char *helo,
1205 				  const unsigned char *pdata,
1206 				  unsigned int pdata_len, bool ssl_secured)
1207 {
1208 	i_assert(!conn->started);
1209 
1210 	conn->set.capabilities &= ENUM_NEGATE(SMTP_CAPABILITY_STARTTLS);
1211 	i_free(conn->username);
1212 	conn->username = i_strdup(username);
1213 	if (helo != NULL && *helo != '\0') {
1214 		i_free(conn->helo_domain);
1215 		conn->helo_domain = i_strdup(helo);
1216 		conn->helo.domain = conn->helo_domain;
1217 		conn->helo.domain_valid = TRUE;
1218 	}
1219 	conn->authenticated = TRUE;
1220 	conn->ssl_secured = ssl_secured;
1221 
1222 	if (pdata_len > 0) {
1223 		if (!i_stream_add_data(conn->conn.input, pdata, pdata_len))
1224 			i_panic("Couldn't add client input to stream");
1225 	}
1226 }
1227 
smtp_server_connection_start_pending(struct smtp_server_connection * conn)1228 void smtp_server_connection_start_pending(struct smtp_server_connection *conn)
1229 {
1230 	i_assert(!conn->started);
1231 	conn->started = TRUE;
1232 
1233 	conn->raw_input = conn->conn.input;
1234 	conn->raw_output = conn->conn.output;
1235 
1236 	if (!conn->ssl_start)
1237 		smtp_server_connection_ready(conn);
1238 	else if (conn->ssl_iostream == NULL)
1239 		smtp_server_connection_input_unlock(conn);
1240 }
1241 
smtp_server_connection_start(struct smtp_server_connection * conn)1242 void smtp_server_connection_start(struct smtp_server_connection *conn)
1243 {
1244 	smtp_server_connection_start_pending(conn);
1245 	smtp_server_connection_resume(conn);
1246 }
1247 
smtp_server_connection_abort(struct smtp_server_connection ** _conn,unsigned int status,const char * enh_code,const char * reason)1248 void smtp_server_connection_abort(struct smtp_server_connection **_conn,
1249 				  unsigned int status, const char *enh_code,
1250 				  const char *reason)
1251 {
1252 	struct smtp_server_connection *conn = *_conn;
1253 	const char **reason_lines;
1254 
1255 	if (conn == NULL)
1256 		return;
1257 	*_conn = NULL;
1258 
1259 	i_assert(!conn->started);
1260 	conn->started = TRUE;
1261 
1262 	if (conn->authenticated) {
1263 		reason_lines = t_strsplit_spaces(reason, "\r\n");
1264 		smtp_server_connection_reply_lines(
1265 			conn, status, enh_code, reason_lines);
1266 		smtp_server_connection_terminate(
1267 			&conn, "4.3.2", "Shutting down due to fatal error");
1268 	} else {
1269 		smtp_server_connection_terminate(&conn, enh_code, reason);
1270 	}
1271 }
1272 
smtp_server_connection_halt(struct smtp_server_connection * conn)1273 void smtp_server_connection_halt(struct smtp_server_connection *conn)
1274 {
1275 	conn->halted = TRUE;
1276 	smtp_server_connection_timeout_stop(conn);
1277 	if (!conn->started || !conn->ssl_start || conn->ssl_iostream != NULL)
1278 		smtp_server_connection_input_lock(conn);
1279 }
1280 
smtp_server_connection_resume(struct smtp_server_connection * conn)1281 void smtp_server_connection_resume(struct smtp_server_connection *conn)
1282 {
1283 	smtp_server_connection_input_unlock(conn);
1284 	smtp_server_connection_timeout_update(conn);
1285 	conn->halted = FALSE;
1286 }
1287 
smtp_server_connection_close(struct smtp_server_connection ** _conn,const char * reason)1288 void smtp_server_connection_close(struct smtp_server_connection **_conn,
1289 				  const char *reason)
1290 {
1291 	struct smtp_server_connection *conn = *_conn;
1292 
1293 	*_conn = NULL;
1294 
1295 	if (conn->closed)
1296 		return;
1297 	conn->closed = TRUE;
1298 
1299 	smtp_server_connection_disconnect(conn, reason);
1300 	smtp_server_connection_unref(&conn);
1301 }
1302 
smtp_server_connection_terminate(struct smtp_server_connection ** _conn,const char * enh_code,const char * reason)1303 void smtp_server_connection_terminate(struct smtp_server_connection **_conn,
1304 				      const char *enh_code, const char *reason)
1305 {
1306 	struct smtp_server_connection *conn = *_conn;
1307 	const char **reason_lines;
1308 
1309 	*_conn = NULL;
1310 
1311 	if (conn->closed)
1312 		return;
1313 
1314 	i_assert(enh_code[0] == '4' && enh_code[1] == '.');
1315 
1316 	T_BEGIN {
1317 		/* Add hostname prefix */
1318 		reason_lines = t_strsplit_spaces(reason, "\r\n");
1319 		reason_lines[0] = t_strconcat(conn->set.hostname, " ",
1320 					      reason_lines[0], NULL);
1321 
1322 		smtp_server_connection_reply_lines(conn, 421, enh_code,
1323 						   reason_lines);
1324 
1325 		smtp_server_connection_close(&conn, reason);
1326 	} T_END;
1327 }
1328 
1329 struct smtp_server_helo_data *
smtp_server_connection_get_helo_data(struct smtp_server_connection * conn)1330 smtp_server_connection_get_helo_data(struct smtp_server_connection *conn)
1331 {
1332 	return &conn->helo;
1333 }
1334 
1335 enum smtp_server_state
smtp_server_connection_get_state(struct smtp_server_connection * conn,const char ** args_r)1336 smtp_server_connection_get_state(struct smtp_server_connection *conn,
1337 				 const char **args_r)
1338 {
1339 	if (args_r != NULL)
1340 		*args_r = conn->state.args;
1341 	return conn->state.state;
1342 }
1343 
smtp_server_connection_set_state(struct smtp_server_connection * conn,enum smtp_server_state state,const char * args)1344 void smtp_server_connection_set_state(struct smtp_server_connection *conn,
1345 				      enum smtp_server_state state,
1346 				      const char *args)
1347 {
1348 	bool changed = FALSE;
1349 
1350 	if (conn->state.state != state) {
1351 		conn->state.state = state;
1352 		changed = TRUE;
1353 	}
1354 	if (null_strcmp(args, conn->state.args) != 0) {
1355 		i_free(conn->state.args);
1356 		conn->state.args = i_strdup(args);
1357 		changed = TRUE;
1358 	}
1359 
1360 	if (changed && conn->callbacks != NULL &&
1361 	    conn->callbacks->conn_state_changed != NULL)
1362 		conn->callbacks->conn_state_changed(conn->context, state, args);
1363 }
1364 
1365 const char *
smtp_server_connection_get_security_string(struct smtp_server_connection * conn)1366 smtp_server_connection_get_security_string(struct smtp_server_connection *conn)
1367 {
1368 	if (conn->ssl_iostream == NULL)
1369 		return NULL;
1370 	return ssl_iostream_get_security_string(conn->ssl_iostream);
1371 }
1372 
smtp_server_connection_reset_state(struct smtp_server_connection * conn)1373 void smtp_server_connection_reset_state(struct smtp_server_connection *conn)
1374 {
1375 	e_debug(conn->event, "Connection state reset");
1376 
1377 	i_free(conn->state.args);
1378 
1379 	if (conn->state.trans != NULL)
1380 		smtp_server_transaction_free(&conn->state.trans);
1381 
1382 	/* RFC 3030, Section 2:
1383 	   The RSET command, when issued after the first BDAT and before the
1384 	   BDAT LAST, clears all segments sent during that transaction and resets
1385 	   the session.
1386 	 */
1387 	i_stream_destroy(&conn->state.data_input);
1388 	i_stream_destroy(&conn->state.data_chain_input);
1389 	conn->state.data_chain = NULL;
1390 
1391 	/* Reset state */
1392 	i_zero(&conn->state);
1393 	smtp_server_connection_set_state(conn, SMTP_SERVER_STATE_READY, NULL);
1394 }
1395 
smtp_server_connection_clear(struct smtp_server_connection * conn)1396 void smtp_server_connection_clear(struct smtp_server_connection *conn)
1397 {
1398 	e_debug(conn->event, "Connection clear");
1399 
1400 	i_free(conn->helo_domain);
1401 	i_zero(&conn->helo);
1402 	smtp_server_connection_reset_state(conn);
1403 }
1404 
smtp_server_connection_set_capabilities(struct smtp_server_connection * conn,enum smtp_capability capabilities)1405 void smtp_server_connection_set_capabilities(
1406 	struct smtp_server_connection *conn, enum smtp_capability capabilities)
1407 {
1408 	conn->set.capabilities = capabilities;
1409 }
1410 
smtp_server_connection_add_extra_capability(struct smtp_server_connection * conn,const struct smtp_capability_extra * cap)1411 void smtp_server_connection_add_extra_capability(
1412 	struct smtp_server_connection *conn,
1413 	const struct smtp_capability_extra *cap)
1414 {
1415 	const struct smtp_capability_extra *cap_idx;
1416 	struct smtp_capability_extra cap_new;
1417 	unsigned int insert_idx;
1418 	pool_t pool = conn->pool;
1419 
1420 	/* Avoid committing protocol errors */
1421 	i_assert(smtp_ehlo_keyword_is_valid(cap->name));
1422 	i_assert(smtp_ehlo_params_are_valid(cap->params));
1423 
1424 	/* Cannot override standard capabiltiies */
1425 	i_assert(smtp_capability_find_by_name(cap->name)
1426 		 == SMTP_CAPABILITY_NONE);
1427 
1428 	if (!array_is_created(&conn->extra_capabilities))
1429 		p_array_init(&conn->extra_capabilities, pool, 4);
1430 
1431 	/* Keep array sorted */
1432 	insert_idx = array_count(&conn->extra_capabilities);
1433 	array_foreach(&conn->extra_capabilities, cap_idx) {
1434 		int cmp = strcasecmp(cap_idx->name, cap->name);
1435 
1436 		/* Prohibit duplicates */
1437 		i_assert(cmp != 0);
1438 
1439 		if (cmp > 0) {
1440 			insert_idx = array_foreach_idx(
1441 				&conn->extra_capabilities, cap_idx);
1442 			break;
1443 		}
1444 	}
1445 
1446 	i_zero(&cap_new);
1447 	cap_new.name = p_strdup(pool, cap->name);
1448 	if (cap->params != NULL)
1449 		cap_new.params = p_strarray_dup(pool, cap->params);
1450 
1451 	array_insert(&conn->extra_capabilities, insert_idx, &cap_new, 1);
1452 }
1453 
smtp_server_connection_get_context(struct smtp_server_connection * conn)1454 void *smtp_server_connection_get_context(struct smtp_server_connection *conn)
1455 {
1456 	return conn->context;
1457 }
1458 
smtp_server_connection_is_ssl_secured(struct smtp_server_connection * conn)1459 bool smtp_server_connection_is_ssl_secured(struct smtp_server_connection *conn)
1460 {
1461 	return conn->ssl_secured;
1462 }
1463 
smtp_server_connection_is_trusted(struct smtp_server_connection * conn)1464 bool smtp_server_connection_is_trusted(struct smtp_server_connection *conn)
1465 {
1466 	if (conn->callbacks == NULL || conn->callbacks->conn_is_trusted == NULL)
1467 		return FALSE;
1468 	return conn->callbacks->conn_is_trusted(conn->context);
1469 }
1470 
1471 enum smtp_protocol
smtp_server_connection_get_protocol(struct smtp_server_connection * conn)1472 smtp_server_connection_get_protocol(struct smtp_server_connection *conn)
1473 {
1474 	return conn->set.protocol;
1475 }
1476 
1477 const char *
smtp_server_connection_get_protocol_name(struct smtp_server_connection * conn)1478 smtp_server_connection_get_protocol_name(struct smtp_server_connection *conn)
1479 {
1480 	string_t *pname = t_str_new(16);
1481 
1482 	switch (conn->set.protocol) {
1483 	case SMTP_PROTOCOL_SMTP:
1484 		if (conn->helo.old_smtp)
1485 			str_append(pname, "SMTP");
1486 		else
1487 			str_append(pname, "ESMTP");
1488 		break;
1489 	case SMTP_PROTOCOL_LMTP:
1490 		str_append(pname, "LMTP");
1491 		break;
1492 	default:
1493 		i_unreached();
1494 	}
1495 	if (conn->ssl_secured)
1496 		str_append_c(pname, 'S');
1497 	if (conn->authenticated)
1498 		str_append_c(pname, 'A');
1499 	return str_c(pname);
1500 }
1501 
1502 struct smtp_server_transaction *
smtp_server_connection_get_transaction(struct smtp_server_connection * conn)1503 smtp_server_connection_get_transaction(struct smtp_server_connection *conn)
1504 {
1505 	return conn->state.trans;
1506 }
1507 
1508 const char *
smtp_server_connection_get_transaction_id(struct smtp_server_connection * conn)1509 smtp_server_connection_get_transaction_id(struct smtp_server_connection *conn)
1510 {
1511 	if (conn->state.trans == NULL)
1512 		return NULL;
1513 	return conn->state.trans->id;
1514 }
1515 
smtp_server_connection_get_proxy_data(struct smtp_server_connection * conn,struct smtp_proxy_data * proxy_data)1516 void smtp_server_connection_get_proxy_data(struct smtp_server_connection *conn,
1517 					   struct smtp_proxy_data *proxy_data)
1518 {
1519 	i_zero(proxy_data);
1520 	proxy_data->source_ip = conn->conn.remote_ip;
1521 	proxy_data->source_port = conn->conn.remote_port;
1522 	if (conn->proxy_helo != NULL)
1523 		proxy_data->helo = conn->proxy_helo;
1524 	else if (conn->helo.domain_valid)
1525 		proxy_data->helo = conn->helo.domain;
1526 	proxy_data->login = conn->username;
1527 
1528 	if (conn->proxy_proto != SMTP_PROXY_PROTOCOL_UNKNOWN)
1529 		proxy_data->proto = conn->proxy_proto;
1530 	else if (conn->set.protocol == SMTP_PROTOCOL_LMTP)
1531 		proxy_data->proto = SMTP_PROXY_PROTOCOL_LMTP;
1532 	else if (conn->helo.old_smtp)
1533 		proxy_data->proto = SMTP_PROXY_PROTOCOL_SMTP;
1534 	else
1535 		proxy_data->proto = SMTP_PROXY_PROTOCOL_ESMTP;
1536 
1537 	proxy_data->ttl_plus_1 = conn->proxy_ttl_plus_1;
1538 	proxy_data->timeout_secs = conn->proxy_timeout_secs;
1539 }
1540 
smtp_server_connection_set_proxy_data(struct smtp_server_connection * conn,const struct smtp_proxy_data * proxy_data)1541 void smtp_server_connection_set_proxy_data(
1542 	struct smtp_server_connection *conn,
1543 	const struct smtp_proxy_data *proxy_data)
1544 {
1545 	if (proxy_data->source_ip.family != 0)
1546 		conn->conn.remote_ip = proxy_data->source_ip;
1547 	if (proxy_data->source_port != 0)
1548 		conn->conn.remote_port = proxy_data->source_port;
1549 	if (proxy_data->helo != NULL) {
1550 		i_free(conn->helo_domain);
1551 		conn->helo_domain = i_strdup(proxy_data->helo);
1552 		conn->helo.domain = conn->helo_domain;
1553 		conn->helo.domain_valid = TRUE;
1554 		if (conn->helo.domain_valid) {
1555 			i_free(conn->proxy_helo);
1556 			conn->proxy_helo = i_strdup(proxy_data->helo);
1557 		}
1558 	}
1559 	if (proxy_data->login != NULL) {
1560 		i_free(conn->username);
1561 		conn->username = i_strdup(proxy_data->login);
1562 	}
1563 	if (proxy_data->proto != SMTP_PROXY_PROTOCOL_UNKNOWN)
1564 		conn->proxy_proto = proxy_data->proto;
1565 
1566 	if (proxy_data->ttl_plus_1 > 0)
1567 		conn->proxy_ttl_plus_1 = proxy_data->ttl_plus_1;
1568 	if (conn->proxy_timeout_secs > 0)
1569 		conn->proxy_timeout_secs = proxy_data->timeout_secs;
1570 
1571 	if (conn->callbacks != NULL &&
1572 	    conn->callbacks->conn_proxy_data_updated != NULL) {
1573 		struct smtp_proxy_data full_data;
1574 
1575 		smtp_server_connection_get_proxy_data(conn, &full_data);
1576 
1577 		conn->callbacks->
1578 			conn_proxy_data_updated(conn->context, &full_data);
1579 	}
1580 }
1581 
smtp_server_connection_register_mail_param(struct smtp_server_connection * conn,const char * param)1582 void smtp_server_connection_register_mail_param(
1583 	struct smtp_server_connection *conn, const char *param)
1584 {
1585 	param = p_strdup(conn->pool, param);
1586 
1587 	if (!array_is_created(&conn->mail_param_extensions)) {
1588 		p_array_init(&conn->mail_param_extensions, conn->pool, 8);
1589 		array_push_back(&conn->mail_param_extensions, &param);
1590 	} else {
1591 		unsigned int count = array_count(&conn->mail_param_extensions);
1592 
1593 		i_assert(count > 0);
1594 		array_idx_set(&conn->mail_param_extensions,
1595 			      count - 1, &param);
1596 	}
1597 	array_append_zero(&conn->mail_param_extensions);
1598 }
1599 
smtp_server_connection_register_rcpt_param(struct smtp_server_connection * conn,const char * param)1600 void smtp_server_connection_register_rcpt_param(
1601 	struct smtp_server_connection *conn, const char *param)
1602 {
1603 	param = p_strdup(conn->pool, param);
1604 
1605 	if (!array_is_created(&conn->rcpt_param_extensions)) {
1606 		p_array_init(&conn->rcpt_param_extensions, conn->pool, 8);
1607 		array_push_back(&conn->rcpt_param_extensions, &param);
1608 	} else {
1609 		unsigned int count = array_count(&conn->rcpt_param_extensions);
1610 
1611 		i_assert(count > 0);
1612 		array_idx_set(&conn->rcpt_param_extensions,
1613 			      count - 1, &param);
1614 	}
1615 	array_append_zero(&conn->rcpt_param_extensions);
1616 }
1617 
smtp_server_connection_switch_ioloop(struct smtp_server_connection * conn)1618 void smtp_server_connection_switch_ioloop(struct smtp_server_connection *conn)
1619 {
1620 	if (conn->to_idle != NULL)
1621 		conn->to_idle = io_loop_move_timeout(&conn->to_idle);
1622 	connection_switch_ioloop(&conn->conn);
1623 }
1624