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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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