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 "safe-memset.h"
7 #include "ioloop.h"
8 #include "net.h"
9 #include "base64.h"
10 #include "istream.h"
11 #include "ostream.h"
12 #include "ostream-dot.h"
13 #include "iostream-rawlog.h"
14 #include "iostream-ssl.h"
15 #include "str.h"
16 #include "dsasl-client.h"
17 #include "dns-lookup.h"
18 #include "smtp-syntax.h"
19 #include "smtp-reply-parser.h"
20 #include "smtp-client-private.h"
21 
22 #include <ctype.h>
23 
24 const char *const smtp_client_connection_state_names[] = {
25 	"disconnected",
26 	"connecting",
27 	"handshaking",
28 	"authenticating",
29 	"ready",
30 	"transaction"
31 };
32 
33 static int
34 smtp_client_connection_ssl_init(struct smtp_client_connection *conn,
35 				const char **error_r);
36 static void
37 smtp_client_connection_handshake(struct smtp_client_connection *conn);
38 static void
39 smtp_client_connection_established(struct smtp_client_connection *conn);
40 static void
41 smtp_client_connection_start_transaction(struct smtp_client_connection *conn);
42 static void
43 smtp_client_connection_connect_next_ip(struct smtp_client_connection *conn);
44 static bool
45 smtp_client_connection_last_ip(struct smtp_client_connection *conn);
46 
47 /*
48  * Capabilities
49  */
50 
51 enum smtp_capability
smtp_client_connection_get_capabilities(struct smtp_client_connection * conn)52 smtp_client_connection_get_capabilities(struct smtp_client_connection *conn)
53 {
54 	return conn->caps.standard;
55 }
56 
smtp_client_connection_get_size_capability(struct smtp_client_connection * conn)57 uoff_t smtp_client_connection_get_size_capability(
58 	struct smtp_client_connection *conn)
59 {
60 	return conn->caps.size;
61 }
62 
63 static const struct smtp_client_capability_extra *
smtp_client_connection_find_extra_capability(struct smtp_client_connection * conn,const char * cap_name)64 smtp_client_connection_find_extra_capability(
65 	struct smtp_client_connection *conn, const char *cap_name)
66 {
67 	const struct smtp_client_capability_extra *cap;
68 
69 	if (!array_is_created(&conn->extra_capabilities))
70 		return NULL;
71 	array_foreach(&conn->extra_capabilities, cap) {
72 		if (strcasecmp(cap->name, cap_name) == 0)
73 			return cap;
74 	}
75 	return NULL;
76 }
77 
smtp_client_connection_accept_extra_capability(struct smtp_client_connection * conn,const struct smtp_client_capability_extra * cap)78 void smtp_client_connection_accept_extra_capability(
79 	struct smtp_client_connection *conn,
80 	const struct smtp_client_capability_extra *cap)
81 {
82 	i_assert(smtp_client_connection_find_extra_capability(conn, cap->name)
83 		 == NULL);
84 
85 	if (!array_is_created(&conn->extra_capabilities))
86 		p_array_init(&conn->extra_capabilities, conn->pool, 8);
87 
88 	struct smtp_client_capability_extra cap_new = {
89 		.name = p_strdup(conn->pool, cap->name),
90 	};
91 
92 	if (cap->mail_param_extensions != NULL) {
93 		cap_new.mail_param_extensions =
94 			p_strarray_dup(conn->pool, cap->mail_param_extensions);
95 	}
96 	if (cap->rcpt_param_extensions != NULL) {
97 		cap_new.rcpt_param_extensions =
98 			p_strarray_dup(conn->pool, cap->rcpt_param_extensions);
99 	}
100 
101 	array_push_back(&conn->extra_capabilities, &cap_new);
102 }
103 
104 const struct smtp_capability_extra *
smtp_client_connection_get_extra_capability(struct smtp_client_connection * conn,const char * name)105 smtp_client_connection_get_extra_capability(struct smtp_client_connection *conn,
106 					    const char *name)
107 {
108 	const struct smtp_capability_extra *cap;
109 
110 	if (!array_is_created(&conn->caps.extra))
111 		return NULL;
112 
113 	array_foreach(&conn->caps.extra, cap) {
114 		if (strcasecmp(cap->name, name) == 0)
115 			return cap;
116 	}
117 
118 	return NULL;
119 }
120 
121 /*
122  *
123  */
124 
125 static void
smtp_client_connection_commands_abort(struct smtp_client_connection * conn)126 smtp_client_connection_commands_abort(struct smtp_client_connection *conn)
127 {
128 	smtp_client_commands_list_abort(conn->cmd_wait_list_head,
129 					conn->cmd_wait_list_count);
130 	smtp_client_commands_list_abort(conn->cmd_send_queue_head,
131 					conn->cmd_send_queue_count);
132 	smtp_client_commands_abort_delayed(conn);
133 }
134 
135 static void
smtp_client_connection_commands_fail_reply(struct smtp_client_connection * conn,const struct smtp_reply * reply)136 smtp_client_connection_commands_fail_reply(struct smtp_client_connection *conn,
137 					   const struct smtp_reply *reply)
138 {
139 	smtp_client_commands_list_fail_reply(conn->cmd_wait_list_head,
140 					     conn->cmd_wait_list_count, reply);
141 	smtp_client_commands_list_fail_reply(conn->cmd_send_queue_head,
142 					     conn->cmd_send_queue_count, reply);
143 	smtp_client_commands_fail_delayed(conn);
144 }
145 
146 static void
smtp_client_connection_commands_fail(struct smtp_client_connection * conn,unsigned int status,const char * error)147 smtp_client_connection_commands_fail(struct smtp_client_connection *conn,
148 				     unsigned int status, const char *error)
149 {
150 	struct smtp_reply reply;
151 
152 	smtp_reply_init(&reply, status, error);
153 	reply.enhanced_code.x = 9;
154 
155 	smtp_client_connection_commands_fail_reply(conn, &reply);
156 }
157 
158 static void
smtp_client_connection_transactions_abort(struct smtp_client_connection * conn)159 smtp_client_connection_transactions_abort(struct smtp_client_connection *conn)
160 {
161 	struct smtp_client_transaction *trans;
162 
163 	trans = conn->transactions_head;
164 	while (trans != NULL) {
165 		struct smtp_client_transaction *trans_next = trans->next;
166 		smtp_client_transaction_abort(trans);
167 		trans = trans_next;
168 	}
169 }
170 
171 static void
smtp_client_connection_transactions_fail_reply(struct smtp_client_connection * conn,const struct smtp_reply * reply)172 smtp_client_connection_transactions_fail_reply(
173 	struct smtp_client_connection *conn, const struct smtp_reply *reply)
174 {
175 	struct smtp_client_transaction *trans;
176 
177 	trans = conn->transactions_head;
178 	while (trans != NULL) {
179 		struct smtp_client_transaction *trans_next = trans->next;
180 		smtp_client_transaction_connection_result(trans, reply);
181 		trans = trans_next;
182 	}
183 }
184 
185 static void
smtp_client_connection_transactions_fail(struct smtp_client_connection * conn,unsigned int status,const char * error)186 smtp_client_connection_transactions_fail(
187 	struct smtp_client_connection *conn,
188 	unsigned int status, const char *error)
189 {
190 	struct smtp_reply reply;
191 
192 	smtp_reply_init(&reply, status, error);
193 	reply.enhanced_code.x = 9;
194 
195 	smtp_client_connection_transactions_fail_reply(conn, &reply);
196 }
197 
198 static void
smtp_client_connection_transactions_drop(struct smtp_client_connection * conn)199 smtp_client_connection_transactions_drop(struct smtp_client_connection *conn)
200 {
201 	struct smtp_client_transaction *trans;
202 
203 	trans = conn->transactions_head;
204 	while (trans != NULL) {
205 		struct smtp_client_transaction *trans_next = trans->next;
206 		smtp_client_transaction_connection_destroyed(trans);
207 		trans = trans_next;
208 	}
209 }
210 
211 static void
smtp_client_connection_login_callback(struct smtp_client_connection * conn,const struct smtp_reply * reply)212 smtp_client_connection_login_callback(struct smtp_client_connection *conn,
213 				      const struct smtp_reply *reply)
214 {
215 	const struct smtp_client_login_callback *cb;
216 	ARRAY(struct smtp_client_login_callback) login_cbs;
217 
218 	if (conn->state_data.login_reply == NULL) {
219 		conn->state_data.login_reply =
220 			smtp_reply_clone(conn->state_pool, reply);
221 	}
222 
223 	if (!array_is_created(&conn->login_callbacks) ||
224 	    array_count(&conn->login_callbacks) == 0)
225 		return;
226 
227 	t_array_init(&login_cbs, array_count(&conn->login_callbacks));
228 	array_copy(&login_cbs.arr, 0, &conn->login_callbacks.arr, 0,
229 		   array_count(&conn->login_callbacks));
230 	array_foreach(&login_cbs, cb) {
231 		i_assert(cb->callback != NULL);
232 		if (conn->closed)
233 			break;
234 		if (cb->callback != NULL)
235 			cb->callback(reply, cb->context);
236 	}
237 	array_clear(&conn->login_callbacks);
238 }
239 
240 static void
smtp_client_connection_login_fail(struct smtp_client_connection * conn,unsigned int status,const char * error)241 smtp_client_connection_login_fail(struct smtp_client_connection *conn,
242 				  unsigned int status, const char *error)
243 {
244 	struct smtp_reply reply;
245 
246 	smtp_reply_init(&reply, status, error);
247 	reply.enhanced_code.x = 9;
248 
249 	smtp_client_connection_login_callback(conn, &reply);
250 }
251 
252 static void
smtp_client_connection_set_state(struct smtp_client_connection * conn,enum smtp_client_connection_state state)253 smtp_client_connection_set_state(struct smtp_client_connection *conn,
254 				 enum smtp_client_connection_state state)
255 {
256 	conn->state = state;
257 }
258 
smtp_client_connection_cork(struct smtp_client_connection * conn)259 void smtp_client_connection_cork(struct smtp_client_connection *conn)
260 {
261 	conn->corked = TRUE;
262 	if (conn->conn.output != NULL)
263 		o_stream_cork(conn->conn.output);
264 }
265 
smtp_client_connection_uncork(struct smtp_client_connection * conn)266 void smtp_client_connection_uncork(struct smtp_client_connection *conn)
267 {
268 	conn->corked = FALSE;
269 	if (conn->conn.output != NULL) {
270 		if (o_stream_uncork_flush(conn->conn.output) < 0) {
271 			smtp_client_connection_handle_output_error(conn);
272 			return;
273 		}
274 		smtp_client_connection_trigger_output(conn);
275 	}
276 }
277 
278 enum smtp_client_connection_state
smtp_client_connection_get_state(struct smtp_client_connection * conn)279 smtp_client_connection_get_state(struct smtp_client_connection *conn)
280 {
281 	return conn->state;
282 }
283 
284 static void
smtp_client_command_timeout(struct smtp_client_connection * conn)285 smtp_client_command_timeout(struct smtp_client_connection *conn)
286 {
287 	smtp_client_connection_ref(conn);
288 
289 	e_error(conn->event, "Command timed out, disconnecting");
290 	smtp_client_connection_fail(conn, SMTP_CLIENT_COMMAND_ERROR_TIMED_OUT,
291 				    "Command timed out");
292 	smtp_client_connection_unref(&conn);
293 }
294 
smtp_client_connection_start_cmd_timeout(struct smtp_client_connection * conn)295 void smtp_client_connection_start_cmd_timeout(
296 	struct smtp_client_connection *conn)
297 {
298 	unsigned int msecs = conn->set.command_timeout_msecs;
299 
300 	if (conn->state < SMTP_CLIENT_CONNECTION_STATE_READY) {
301 		/* pre-login uses connect timeout */
302 		return;
303 	}
304 	if (msecs == 0) {
305 		/* no timeout configured */
306 		timeout_remove(&conn->to_commands);
307 		return;
308 	}
309 	if (conn->cmd_wait_list_head == NULL && !conn->sending_command) {
310 		/* no commands pending */
311 		timeout_remove(&conn->to_commands);
312 		return;
313 	}
314 
315 	e_debug(conn->event, "Start timeout");
316 	if (conn->to_commands == NULL) {
317 		conn->to_commands = timeout_add(
318 			msecs, smtp_client_command_timeout, conn);
319 	}
320 }
321 
smtp_client_connection_update_cmd_timeout(struct smtp_client_connection * conn)322 void smtp_client_connection_update_cmd_timeout(
323 	struct smtp_client_connection *conn)
324 {
325 	unsigned int msecs = conn->set.command_timeout_msecs;
326 
327 	if (conn->state < SMTP_CLIENT_CONNECTION_STATE_READY) {
328 		/* pre-login uses connect timeout */
329 		return;
330 	}
331 	if (msecs == 0) {
332 		/* no timeout configured */
333 		timeout_remove(&conn->to_commands);
334 		return;
335 	}
336 
337 	if (conn->cmd_wait_list_head == NULL && !conn->sending_command) {
338 		if (conn->to_commands != NULL) {
339 			e_debug(conn->event,
340 				"No commands pending; stop timeout");
341 		}
342 		timeout_remove(&conn->to_commands);
343 	} else if (conn->to_commands != NULL)  {
344 		e_debug(conn->event, "Reset timeout");
345 		timeout_reset(conn->to_commands);
346 	} else {
347 		smtp_client_connection_start_cmd_timeout(conn);
348 	}
349 }
350 
351 static void
smtp_client_connection_fail_reply(struct smtp_client_connection * conn,const struct smtp_reply * reply)352 smtp_client_connection_fail_reply(struct smtp_client_connection *conn,
353 				  const struct smtp_reply *reply)
354 {
355 	e_debug(conn->event, "Connection failed: %s", smtp_reply_log(reply));
356 
357 	smtp_client_connection_ref(conn);
358 	conn->failing = TRUE;
359 
360 	smtp_client_connection_disconnect(conn);
361 	smtp_client_connection_login_callback(conn, reply);
362 
363 	smtp_client_connection_transactions_fail_reply(conn, reply);
364 	smtp_client_connection_commands_fail_reply(conn, reply);
365 
366 	conn->failing = FALSE;
367 	smtp_client_connection_unref(&conn);
368 }
369 
smtp_client_connection_fail(struct smtp_client_connection * conn,unsigned int status,const char * error)370 void smtp_client_connection_fail(struct smtp_client_connection *conn,
371 				 unsigned int status, const char *error)
372 {
373 	struct smtp_reply reply;
374 	const char *text_lines[] = {error, NULL};
375 
376 	timeout_remove(&conn->to_connect);
377 
378 	if (status == SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED &&
379 	    !smtp_client_connection_last_ip(conn)) {
380 		conn->to_connect = timeout_add_short(
381 			0, smtp_client_connection_connect_next_ip, conn);
382 		return;
383 	}
384 
385 	i_zero(&reply);
386 	reply.status = status;
387 	reply.text_lines = text_lines;
388 	reply.enhanced_code.x = 9;
389 
390 	smtp_client_connection_fail_reply(conn, &reply);
391 }
392 
393 static void
smtp_client_connection_lost(struct smtp_client_connection * conn,const char * error,const char * user_error)394 smtp_client_connection_lost(struct smtp_client_connection *conn,
395 			    const char *error, const char *user_error)
396 {
397 	if (error != NULL)
398 		error = t_strdup_printf("Connection lost: %s", error);
399 
400 	if (user_error == NULL)
401 		user_error = "Lost connection to remote server";
402 	else {
403 		user_error = t_strdup_printf(
404 			"Lost connection to remote server: %s",
405 			user_error);
406 	}
407 
408 	if (conn->ssl_iostream != NULL) {
409 		const char *sslerr =
410 			ssl_iostream_get_last_error(conn->ssl_iostream);
411 
412 		if (error != NULL && sslerr != NULL) {
413 			error = t_strdup_printf("%s (last SSL error: %s)",
414 						error, sslerr);
415 		} else if (sslerr != NULL) {
416 			error = t_strdup_printf(
417 				"Connection lost (last SSL error: %s)", sslerr);
418 		}
419 		if (ssl_iostream_has_handshake_failed(conn->ssl_iostream)) {
420 			/* This isn't really a "connection lost", but that we
421 			   don't trust the remote's SSL certificate. */
422 			i_assert(error != NULL);
423 			e_error(conn->event, "%s", error);
424 			smtp_client_connection_fail(
425 				conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
426 				user_error);
427 			return;
428 		}
429 	}
430 
431 	if (error != NULL)
432 		e_error(conn->event, "%s", error);
433 	smtp_client_connection_fail(
434 		conn, SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST, user_error);
435 }
436 
smtp_client_connection_handle_output_error(struct smtp_client_connection * conn)437 void smtp_client_connection_handle_output_error(
438 	struct smtp_client_connection *conn)
439 {
440 	struct ostream *output = conn->conn.output;
441 
442 	if (output->stream_errno != EPIPE &&
443 	    output->stream_errno != ECONNRESET) {
444 		smtp_client_connection_lost(
445 			conn,
446 			t_strdup_printf("write(%s) failed: %s",
447 					o_stream_get_name(conn->conn.output),
448 					o_stream_get_error(conn->conn.output)),
449 			"Write failure");
450 	} else {
451 		smtp_client_connection_lost(
452 			conn, "Remote disconnected while writing output",
453 			"Remote closed connection unexpectedly");
454 	}
455 }
456 
stmp_client_connection_ready(struct smtp_client_connection * conn,const struct smtp_reply * reply)457 static void stmp_client_connection_ready(struct smtp_client_connection *conn,
458 					 const struct smtp_reply *reply)
459 {
460 	timeout_remove(&conn->to_connect);
461 
462 	smtp_client_connection_set_state(
463 		conn, SMTP_CLIENT_CONNECTION_STATE_READY);
464 	conn->reset_needed = FALSE;
465 
466 	e_debug(conn->event, "Connection ready");
467 
468 	smtp_client_connection_login_callback(conn, reply);
469 
470 	smtp_client_connection_update_cmd_timeout(conn);
471 
472 	smtp_client_connection_start_transaction(conn);
473 }
474 
475 static void
smtp_client_connection_xclient_cb(const struct smtp_reply * reply,struct smtp_client_connection * conn)476 smtp_client_connection_xclient_cb(const struct smtp_reply *reply,
477 				  struct smtp_client_connection *conn)
478 {
479 	e_debug(conn->event, "Received XCLIENT handshake reply: %s",
480 		smtp_reply_log(reply));
481 
482 	i_assert(conn->xclient_replies_expected > 0);
483 
484 	if (reply->status == 421) {
485 		smtp_client_connection_fail_reply(conn, reply);
486 		return;
487 	}
488 	if (conn->state == SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED)
489 		return;
490 
491 	if (conn->to_connect != NULL)
492 		timeout_reset(conn->to_connect);
493 	if (--conn->xclient_replies_expected == 0)
494 		smtp_client_connection_handshake(conn);
495 }
496 
497 static void
smtp_client_connection_xclient_submit(struct smtp_client_connection * conn,const char * cmdstr)498 smtp_client_connection_xclient_submit(struct smtp_client_connection *conn,
499 				      const char *cmdstr)
500 {
501 	struct smtp_client_command *cmd;
502 	enum smtp_client_command_flags flags;
503 
504 	e_debug(conn->event, "Sending XCLIENT handshake");
505 
506 	flags = SMTP_CLIENT_COMMAND_FLAG_PRELOGIN |
507 		SMTP_CLIENT_COMMAND_FLAG_PRIORITY;
508 
509 	cmd = smtp_client_command_new(conn, flags,
510 				      smtp_client_connection_xclient_cb, conn);
511 	smtp_client_command_write(cmd, cmdstr);
512 	smtp_client_command_submit(cmd);
513 
514 	conn->xclient_replies_expected++;
515 }
516 
517 static void
smtp_client_connection_xclient_add(struct smtp_client_connection * conn,string_t * str,size_t offset,const char * field,const char * value)518 smtp_client_connection_xclient_add(struct smtp_client_connection *conn,
519 				   string_t *str, size_t offset,
520 				   const char *field, const char *value)
521 {
522 	size_t prev_offset = str_len(str);
523 	const char *new_field;
524 
525 	i_assert(prev_offset >= offset);
526 
527 	str_append_c(str, ' ');
528 	str_append(str, field);
529 	str_append_c(str, '=');
530 	smtp_xtext_encode_cstr(str, value);
531 
532 	if (prev_offset == offset ||
533 	    str_len(str) <= SMTP_CLIENT_BASE_LINE_LENGTH_LIMIT)
534 		return;
535 
536 	/* preserve field we just added */
537 	new_field = t_strdup(str_c(str) + prev_offset);
538 
539 	/* revert to previous position */
540 	str_truncate(str, prev_offset);
541 
542 	/* send XCLIENT command */
543 	smtp_client_connection_xclient_submit(conn, str_c(str));
544 
545 	/* start next XCLIENT command with new field */
546 	str_truncate(str, offset);
547 	str_append(str, new_field);
548 }
549 
550 static void ATTR_FORMAT(5, 6)
smtp_client_connection_xclient_addf(struct smtp_client_connection * conn,string_t * str,size_t offset,const char * field,const char * format,...)551 smtp_client_connection_xclient_addf(struct smtp_client_connection *conn,
552 				    string_t *str, size_t offset,
553 				    const char *field, const char *format, ...)
554 {
555 	va_list args;
556 
557 	va_start(args, format);
558 	smtp_client_connection_xclient_add(conn, str, offset, field,
559 					   t_strdup_vprintf(format, args));
560 	va_end(args);
561 }
562 
smtp_client_connection_send_xclient(struct smtp_client_connection * conn)563 void smtp_client_connection_send_xclient(struct smtp_client_connection *conn)
564 {
565 	const struct smtp_proxy_data *xclient = &conn->set.proxy_data;
566 	const char **xclient_args = conn->caps.xclient_args;
567 	size_t offset;
568 	string_t *str;
569 
570 	if (!conn->set.peer_trusted)
571 		return;
572 	if (conn->xclient_sent)
573 		return;
574 	if ((conn->caps.standard & SMTP_CAPABILITY_XCLIENT) == 0 ||
575 	    conn->caps.xclient_args == NULL)
576 		return;
577 
578 	i_assert(conn->xclient_replies_expected == 0);
579 
580 	/* http://www.postfix.org/XCLIENT_README.html:
581 
582 	   The client must not send XCLIENT commands that exceed the 512
583 	   character limit for SMTP commands. To avoid exceeding the limit the
584 	   client should send the information in multiple XCLIENT commands; for
585 	   example, send NAME and ADDR last, after HELO and PROTO. Once ADDR is
586 	   sent, the client is usually no longer authorized to send XCLIENT
587 	   commands.
588 	 */
589 
590 	str = t_str_new(64);
591 	str_append(str, "XCLIENT");
592 	offset = str_len(str);
593 
594 	/* HELO */
595 	if (xclient->helo != NULL &&
596 	    str_array_icase_find(xclient_args, "HELO")) {
597 		smtp_client_connection_xclient_add(conn, str, offset,
598 						   "HELO", xclient->helo);
599 	}
600 
601 	/* PROTO */
602 	if (str_array_icase_find(xclient_args, "PROTO")) {
603 		switch (xclient->proto) {
604 		case SMTP_PROXY_PROTOCOL_SMTP:
605 			smtp_client_connection_xclient_add(conn, str, offset,
606 							   "PROTO", "SMTP");
607 			break;
608 		case SMTP_PROXY_PROTOCOL_ESMTP:
609 			smtp_client_connection_xclient_add(conn, str, offset,
610 							   "PROTO", "ESMTP");
611 			break;
612 		case SMTP_PROXY_PROTOCOL_LMTP:
613 			smtp_client_connection_xclient_add(conn, str, offset,
614 							   "PROTO", "LMTP");
615 			break;
616 		default:
617 			break;
618 		}
619 	}
620 
621 	/* LOGIN */
622 	if (xclient->login != NULL &&
623 	    str_array_icase_find(xclient_args, "LOGIN")) {
624 		smtp_client_connection_xclient_add(conn, str, offset,
625 						   "LOGIN", xclient->login);
626 	}
627 
628 	/* TTL */
629 	if (xclient->ttl_plus_1 > 0 &&
630 	    str_array_icase_find(xclient_args, "TTL")) {
631 		smtp_client_connection_xclient_addf(conn, str, offset,
632 						    "TTL", "%u",
633 						    xclient->ttl_plus_1-1);
634 	}
635 
636 	/* TIMEOUT */
637 	if (xclient->timeout_secs > 0 &&
638 	    str_array_icase_find(xclient_args, "TIMEOUT")) {
639 		smtp_client_connection_xclient_addf(conn, str, offset,
640 						    "TIMEOUT", "%u",
641 						    xclient->timeout_secs);
642 	}
643 
644 	/* PORT */
645 	if (xclient->source_port != 0 &&
646 	    str_array_icase_find(xclient_args, "PORT")) {
647 		smtp_client_connection_xclient_addf(conn, str, offset,
648 						    "PORT", "%u",
649 						    xclient->source_port);
650 	}
651 
652 	/* ADDR */
653 	if (xclient->source_ip.family != 0 &&
654 	    str_array_icase_find(xclient_args, "ADDR")) {
655 		const char *addr = net_ip2addr(&xclient->source_ip);
656 
657 		/* Older versions of Dovecot LMTP don't quite follow Postfix'
658 		   specification of the XCLIENT command regarding IPv6
659 		   addresses: the "IPV6:" prefix is omitted. For now, we
660 		   maintain this deviation for LMTP. Newer versions of Dovecot
661 		   LMTP can work with or without the prefix. */
662 		if (conn->protocol != SMTP_PROTOCOL_LMTP &&
663 			xclient->source_ip.family == AF_INET6)
664 			addr = t_strconcat("IPV6:", addr, NULL);
665 		smtp_client_connection_xclient_add(conn, str, offset,
666 						   "ADDR", addr);
667 	}
668 
669 	/* final XCLIENT command */
670 	if (str_len(str) > offset)
671 		smtp_client_connection_xclient_submit(conn, str_c(str));
672 
673 	conn->xclient_sent = TRUE;
674 }
675 
676 static void
smtp_client_connection_clear_password(struct smtp_client_connection * conn)677 smtp_client_connection_clear_password(struct smtp_client_connection *conn)
678 {
679 	if (conn->set.remember_password)
680 		return;
681 	if (conn->password == NULL)
682 		return;
683 	safe_memset(conn->password, 0, strlen(conn->password));
684 	conn->set.password = NULL;
685 	conn->password = NULL;
686 }
687 
688 static void
smtp_client_connection_auth_cb(const struct smtp_reply * reply,struct smtp_client_connection * conn)689 smtp_client_connection_auth_cb(const struct smtp_reply *reply,
690 			       struct smtp_client_connection *conn)
691 {
692 	if (reply->status == 334) {
693 		const unsigned char *sasl_output;
694 		size_t sasl_output_len, input_len;
695 		buffer_t *buf;
696 		const char *error;
697 
698 		if (reply->text_lines[1] != NULL) {
699 			e_error(conn->event, "Authentication failed: "
700 				"Server returned multi-line reply: %s",
701 				smtp_reply_log(reply));
702 			smtp_client_connection_fail(
703 				conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
704 				"Authentication protocol error");
705 			return;
706 		}
707 
708 		input_len = strlen(reply->text_lines[0]);
709 		buf = buffer_create_dynamic(pool_datastack_create(),
710 			MAX_BASE64_DECODED_SIZE(input_len));
711 		if (base64_decode(reply->text_lines[0], input_len,
712 				  NULL, buf) < 0) {
713 			e_error(conn->event, "Authentication failed: "
714 				"Server sent non-base64 input for AUTH: %s",
715 				reply->text_lines[0]);
716 		} else if (dsasl_client_input(conn->sasl_client,
717 					      buf->data, buf->used,
718 					      &error) < 0) {
719 			e_error(conn->event, "Authentication failed: %s",
720 				error);
721 		} else if (dsasl_client_output(conn->sasl_client, &sasl_output,
722 					       &sasl_output_len, &error) < 0) {
723 			e_error(conn->event, "Authentication failed: %s",
724 				error);
725 		} else {
726 			string_t *smtp_output = t_str_new(
727 				MAX_BASE64_ENCODED_SIZE(sasl_output_len) + 2);
728 			base64_encode(sasl_output, sasl_output_len,
729 				      smtp_output);
730 			str_append(smtp_output, "\r\n");
731 			o_stream_nsend(conn->conn.output, str_data(smtp_output),
732 				       str_len(smtp_output));
733 			return;
734 		}
735 
736 		smtp_client_connection_fail(
737 			conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
738 			"Authentication failed");
739 		return;
740 	}
741 
742 	if ((reply->status / 100) != 2) {
743 		e_error(conn->event, "Authentication failed: %s",
744 			smtp_reply_log(reply));
745 		smtp_client_connection_fail_reply(conn, reply);
746 		return;
747 	}
748 
749 	smtp_client_connection_clear_password(conn);
750 
751 	e_debug(conn->event, "Authenticated successfully");
752 	dsasl_client_free(&conn->sasl_client);
753 
754 	if (conn->to_connect != NULL)
755 		timeout_reset(conn->to_connect);
756 	conn->authenticated = TRUE;
757 	smtp_client_connection_handshake(conn);
758 }
759 
760 static int
smtp_client_connection_get_sasl_mech(struct smtp_client_connection * conn,const struct dsasl_client_mech ** mech_r,const char ** error_r)761 smtp_client_connection_get_sasl_mech(struct smtp_client_connection *conn,
762 				     const struct dsasl_client_mech **mech_r,
763 				     const char **error_r)
764 {
765 	const struct smtp_client_settings *set = &conn->set;
766 	const char *const *mechanisms;
767 
768 	if (set->sasl_mech != NULL) {
769 		const char *mech = dsasl_client_mech_get_name(set->sasl_mech);
770 
771 		if (!str_array_icase_find(conn->caps.auth_mechanisms, mech)) {
772 			*error_r = t_strdup_printf(
773 				"Server doesn't support `%s' SASL mechanism",
774 				mech);
775 			return -1;
776 		}
777 		*mech_r = set->sasl_mech;
778 		return 0;
779 	}
780 	if (set->sasl_mechanisms == NULL ||
781 		set->sasl_mechanisms[0] == '\0') {
782 		*mech_r = &dsasl_client_mech_plain;
783 		return 0;
784 	}
785 
786 	/* find one of the specified SASL mechanisms */
787 	mechanisms = t_strsplit_spaces(set->sasl_mechanisms, ", ");
788 	for (; *mechanisms != NULL; mechanisms++) {
789 		if (str_array_icase_find(conn->caps.auth_mechanisms,
790 					 *mechanisms)) {
791 			*mech_r = dsasl_client_mech_find(*mechanisms);
792 			if (*mech_r != NULL)
793 				return 0;
794 
795 			*error_r = t_strdup_printf(
796 				"Support for SASL mechanism `%s' is missing",
797 				*mechanisms);
798 			return -1;
799 		}
800 	}
801 	*error_r = t_strdup_printf(
802 		"Server doesn't support any of "
803 		"the requested SASL mechanisms: %s", set->sasl_mechanisms);
804 	return -1;
805 }
806 
807 static bool
smtp_client_connection_authenticate(struct smtp_client_connection * conn)808 smtp_client_connection_authenticate(struct smtp_client_connection *conn)
809 {
810 	const struct smtp_client_settings *set = &conn->set;
811 	struct dsasl_client_settings sasl_set;
812 	const struct dsasl_client_mech *sasl_mech = NULL;
813 	struct smtp_client_command *cmd;
814 	const unsigned char *sasl_output;
815 	size_t sasl_output_len;
816 	string_t *sasl_output_base64;
817 	const char *init_resp, *error;
818 
819 	if (set->username == NULL && set->sasl_mech == NULL) {
820 		if (!conn->set.xclient_defer)
821 			smtp_client_connection_send_xclient(conn);
822 		return (conn->xclient_replies_expected == 0);
823 	}
824 
825 	smtp_client_connection_send_xclient(conn);
826 	if (conn->xclient_replies_expected > 0)
827 		return FALSE;
828 	if (conn->authenticated)
829 		return TRUE;
830 
831 	if ((conn->caps.standard & SMTP_CAPABILITY_AUTH) == 0) {
832 		smtp_client_connection_fail(
833 			conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
834 			"Authentication not supported");
835 		return FALSE;
836 	}
837 
838 	if (set->master_user != NULL) {
839 		e_debug(conn->event, "Authenticating as %s for user %s",
840 			set->master_user, set->username);
841 	} else if (set->username == NULL) {
842 		e_debug(conn->event, "Authenticating");
843 	} else {
844 		e_debug(conn->event, "Authenticating as %s", set->username);
845 	}
846 
847 	if (smtp_client_connection_get_sasl_mech(conn, &sasl_mech,
848 						 &error) < 0) {
849 		e_error(conn->event, "Authentication failed: %s", error);
850 		smtp_client_connection_fail(
851 			conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
852 			"Server authentication mechanisms incompatible");
853 		return FALSE;
854 	}
855 
856 	i_zero(&sasl_set);
857 	if (set->master_user == NULL)
858 		sasl_set.authid = set->username;
859 	else {
860 		sasl_set.authid = set->master_user;
861 		sasl_set.authzid = set->username;
862 	}
863 	sasl_set.password = set->password;
864 
865 	conn->sasl_client = dsasl_client_new(sasl_mech, &sasl_set);
866 
867 	if (dsasl_client_output(conn->sasl_client, &sasl_output,
868 				&sasl_output_len, &error) < 0) {
869 		e_error(conn->event,
870 			"Failed to create initial %s SASL reply: %s",
871 			dsasl_client_mech_get_name(sasl_mech), error);
872 		smtp_client_connection_fail(
873 			conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
874 			"Internal authentication failure");
875 		return FALSE;
876 	}
877 
878 	sasl_output_base64 = t_str_new(
879 		MAX_BASE64_ENCODED_SIZE(sasl_output_len));
880 	base64_encode(sasl_output, sasl_output_len, sasl_output_base64);
881 
882 	/* RFC 4954, Section 4:
883 
884 	   If the client is transmitting an initial response of zero
885 	   length, it MUST instead transmit the response as a single
886 	   equals sign ("=").  This indicates that the response is
887 	   present, but contains no data. */
888 	init_resp = (str_len(sasl_output_base64) == 0 ?
889 		     "=" : str_c(sasl_output_base64));
890 
891 	cmd = smtp_client_command_new(conn, SMTP_CLIENT_COMMAND_FLAG_PRELOGIN,
892 				      smtp_client_connection_auth_cb, conn);
893 	smtp_client_command_printf(cmd, "AUTH %s %s",
894 				   dsasl_client_mech_get_name(sasl_mech),
895 				   init_resp);
896 	smtp_client_command_submit(cmd);
897 
898 	smtp_client_connection_set_state(
899 		conn, SMTP_CLIENT_CONNECTION_STATE_AUTHENTICATING);
900 	return FALSE;
901 }
902 
903 static void
smtp_client_connection_starttls_cb(const struct smtp_reply * reply,struct smtp_client_connection * conn)904 smtp_client_connection_starttls_cb(const struct smtp_reply *reply,
905 				   struct smtp_client_connection *conn)
906 {
907 	const char *error;
908 
909 	e_debug(conn->event, "Received STARTTLS reply: %s",
910 		smtp_reply_log(reply));
911 
912 	if ((reply->status / 100) != 2) {
913 		smtp_client_connection_fail_reply(conn, reply);
914 		return;
915 	}
916 
917 	if (smtp_client_connection_ssl_init(conn, &error) < 0) {
918 		smtp_client_connection_fail(
919 			conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED, error);
920 	} else {
921 		if (conn->to_connect != NULL)
922 			timeout_reset(conn->to_connect);
923 		smtp_client_connection_handshake(conn);
924 	}
925 }
926 
927 static bool
smtp_client_connection_starttls(struct smtp_client_connection * conn)928 smtp_client_connection_starttls(struct smtp_client_connection *conn)
929 {
930 	struct smtp_client_command *cmd;
931 
932 	if (conn->ssl_mode == SMTP_CLIENT_SSL_MODE_STARTTLS &&
933 	    conn->ssl_iostream == NULL) {
934 		if ((conn->caps.standard & SMTP_CAPABILITY_STARTTLS) == 0) {
935 			e_error(conn->event, "Requested STARTTLS, "
936 				"but server doesn't support it");
937 			smtp_client_connection_fail(
938 				conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
939 				"STARTTLS not supported");
940 			return FALSE;
941 		}
942 
943 		e_debug(conn->event, "Starting TLS");
944 
945 		cmd = smtp_client_command_new(
946 			conn, SMTP_CLIENT_COMMAND_FLAG_PRELOGIN,
947 			smtp_client_connection_starttls_cb, conn);
948 		smtp_client_command_write(cmd, "STARTTLS");
949 		smtp_client_command_submit(cmd);
950 		return FALSE;
951 	}
952 
953 	return smtp_client_connection_authenticate(conn);
954 }
955 
956 static void
smtp_client_connection_record_param_extensions(struct smtp_client_connection * conn,ARRAY_TYPE (const_string)* arr,const char * const * extensions)957 smtp_client_connection_record_param_extensions(
958 	struct smtp_client_connection *conn, ARRAY_TYPE(const_string) *arr,
959 	const char *const *extensions)
960 {
961 	pool_t pool = conn->cap_pool;
962 
963 	if (extensions == NULL || *extensions == NULL)
964 		return;
965 
966 	if (!array_is_created(arr))
967 		p_array_init(arr, pool, 4);
968 	else {
969 		const char *const *end;
970 
971 		/* Drop end marker */
972 		i_assert(array_count(arr) > 0);
973 		end = array_back(arr);
974 		i_assert(*end == NULL);
975 		array_pop_back(arr);
976 	}
977 
978 	const char *const *new_p;
979 	for (new_p = extensions; *new_p != NULL; new_p++) {
980 		/* Drop duplicates */
981 		if (array_lsearch(arr, new_p, i_strcasecmp_p) != NULL)
982 			continue;
983 
984 		array_push_back(arr, new_p);
985 	}
986 
987 	/* Add new end marker */
988 	array_append_zero(arr);
989 }
990 
991 static void
smtp_client_connection_record_extra_capability(struct smtp_client_connection * conn,const char * cap_name,const char * const * params)992 smtp_client_connection_record_extra_capability(
993 	struct smtp_client_connection *conn, const char *cap_name,
994 	const char *const *params)
995 {
996 	const struct smtp_client_capability_extra *ccap_extra;
997 	struct smtp_capability_extra cap_extra;
998 	pool_t pool = conn->cap_pool;
999 
1000 	ccap_extra = smtp_client_connection_find_extra_capability(
1001 		conn, cap_name);
1002 	if (ccap_extra == NULL)
1003 		return;
1004 	if (smtp_client_connection_get_extra_capability(conn, cap_name) != NULL)
1005 		return;
1006 
1007 	if (!array_is_created(&conn->caps.extra))
1008 		p_array_init(&conn->caps.extra, pool, 4);
1009 
1010 	i_zero(&cap_extra);
1011 	cap_extra.name = p_strdup(pool, ccap_extra->name);
1012 	cap_extra.params = p_strarray_dup(pool, params);
1013 
1014 	array_push_back(&conn->caps.extra, &cap_extra);
1015 
1016 	smtp_client_connection_record_param_extensions(
1017 		conn, &conn->caps.mail_param_extensions,
1018 		ccap_extra->mail_param_extensions);
1019 	smtp_client_connection_record_param_extensions(
1020 		conn, &conn->caps.rcpt_param_extensions,
1021 		ccap_extra->rcpt_param_extensions);
1022 }
1023 
1024 static void
smtp_client_connection_handshake_cb(const struct smtp_reply * reply,struct smtp_client_connection * conn)1025 smtp_client_connection_handshake_cb(const struct smtp_reply *reply,
1026 				    struct smtp_client_connection *conn)
1027 {
1028 	const char *const *lines;
1029 
1030 	e_debug(conn->event, "Received handshake reply");
1031 
1032 	/* check reply status */
1033 	if ((reply->status / 100) != 2) {
1034 		/* RFC 5321, Section 3.2:
1035 		   For a particular connection attempt, if the server returns a
1036 		   "command not recognized" response to EHLO, the client SHOULD
1037 		   be able to fall back and send HELO. */
1038 		if (conn->protocol == SMTP_PROTOCOL_SMTP && !conn->old_smtp &&
1039 		    (reply->status == 500 || reply->status == 502)) {
1040 			/* try HELO */
1041 			conn->old_smtp = TRUE;
1042 			smtp_client_connection_handshake(conn);
1043 			return;
1044 		}
1045 		/* failed */
1046 		smtp_client_connection_fail_reply(conn, reply);
1047 		return;
1048 	}
1049 
1050 	/* reset capabilities */
1051 	p_clear(conn->cap_pool);
1052 	i_zero(&conn->caps);
1053 	conn->caps.standard = conn->set.forced_capabilities;
1054 
1055 	lines = reply->text_lines;
1056 	if (*lines == NULL) {
1057 		smtp_client_connection_fail(
1058 			conn, SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1059 			"Invalid handshake reply");
1060 		return;
1061 	}
1062 
1063 	/* greeting line */
1064 	lines++;
1065 
1066 	/* capability lines */
1067 	while (*lines != NULL) {
1068 		enum smtp_capability cap;
1069 		const char *const *params;
1070 		const char *cap_name, *error;
1071 
1072 		if (smtp_ehlo_line_parse(*lines, &cap_name, &params,
1073 					 &error) <= 0) {
1074 			e_warning(conn->event,
1075 				  "Received invalid EHLO response line: %s",
1076 				  error);
1077 			lines++;
1078 			continue;
1079 		}
1080 
1081 		cap = smtp_capability_find_by_name(cap_name);
1082 		switch (cap) {
1083 		case SMTP_CAPABILITY_AUTH:
1084 			conn->caps.auth_mechanisms =
1085 				p_strarray_dup(conn->cap_pool, params);
1086 			break;
1087 		case SMTP_CAPABILITY_SIZE:
1088 			if (params == NULL || *params == NULL)
1089 				break;
1090 			if (str_to_uoff(*params, &conn->caps.size) < 0) {
1091 				e_warning(conn->event,
1092 					  "Received invalid SIZE capability "
1093 					  "in EHLO response line");
1094 				cap = SMTP_CAPABILITY_NONE;
1095 			}
1096 			break;
1097 		case SMTP_CAPABILITY_XCLIENT:
1098 			conn->caps.xclient_args =
1099 				p_strarray_dup(conn->cap_pool, params);
1100 			break;
1101 		case SMTP_CAPABILITY_NONE:
1102 			smtp_client_connection_record_extra_capability(
1103 				conn, cap_name, params);
1104 			break;
1105 		default:
1106 			break;
1107 		}
1108 
1109 		conn->caps.standard |= cap;
1110 		lines++;
1111 	}
1112 
1113 	e_debug(conn->event, "Received server capabilities");
1114 
1115 	if (conn->to_connect != NULL)
1116 		timeout_reset(conn->to_connect);
1117 	if (smtp_client_connection_starttls(conn)) {
1118 		stmp_client_connection_ready(conn, reply);
1119 	}
1120 }
1121 
1122 static void
smtp_client_connection_handshake(struct smtp_client_connection * conn)1123 smtp_client_connection_handshake(struct smtp_client_connection *conn)
1124 {
1125 	struct smtp_client_command *cmd;
1126 	enum smtp_client_command_flags flags;
1127 	const char *command;
1128 
1129 	flags = SMTP_CLIENT_COMMAND_FLAG_PRELOGIN |
1130 		SMTP_CLIENT_COMMAND_FLAG_PRIORITY;
1131 
1132 	switch (conn->protocol) {
1133 	case SMTP_PROTOCOL_SMTP:
1134 		command = (conn->old_smtp ? "HELO" : "EHLO");
1135 		break;
1136 	case SMTP_PROTOCOL_LMTP:
1137 		command = "LHLO";
1138 		break;
1139 	default:
1140 		i_unreached();
1141 	}
1142 
1143 	e_debug(conn->event, "Sending %s handshake", command);
1144 
1145 	cmd = smtp_client_command_new(
1146 		conn, flags, smtp_client_connection_handshake_cb, conn);
1147 	smtp_client_command_write(cmd, command);
1148 	smtp_client_command_write(cmd, " ");
1149 	smtp_client_command_write(cmd, conn->set.my_hostname);
1150 	smtp_client_command_submit(cmd);
1151 	smtp_client_connection_set_state(
1152 		conn, SMTP_CLIENT_CONNECTION_STATE_HANDSHAKING);
1153 }
1154 
1155 static int
smtp_client_connection_input_reply(struct smtp_client_connection * conn,const struct smtp_reply * reply)1156 smtp_client_connection_input_reply(struct smtp_client_connection *conn,
1157 				   const struct smtp_reply *reply)
1158 {
1159 	int ret;
1160 
1161 	/* initial greeting? */
1162 	if (conn->state == SMTP_CLIENT_CONNECTION_STATE_CONNECTING) {
1163 		e_debug(conn->event, "Received greeting from server: %s",
1164 			smtp_reply_log(reply));
1165 		if (reply->status != 220) {
1166 			if (smtp_reply_is_success(reply)) {
1167 				smtp_client_connection_fail(
1168 					conn,
1169 					SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1170 					"Received inappropriate greeting");
1171 			} else {
1172 				smtp_client_connection_fail_reply(conn, reply);
1173 			}
1174 			return -1;
1175 		}
1176 		smtp_client_connection_handshake(conn);
1177 		return 1;
1178 	}
1179 
1180 	if (reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_CLOSED) {
1181 		smtp_client_connection_fail_reply(conn, reply);
1182 		return -1;
1183 	}
1184 
1185 	/* unexpected reply? */
1186 	if (conn->cmd_wait_list_head == NULL) {
1187 		e_debug(conn->event, "Unexpected reply: %s",
1188 			smtp_reply_log(reply));
1189 		smtp_client_connection_fail(
1190 			conn, SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1191 			"Got unexpected reply");
1192 		return -1;
1193 	}
1194 
1195 	/* replied early? */
1196 	if (conn->cmd_wait_list_head == conn->cmd_streaming &&
1197 	    !conn->cmd_wait_list_head->stream_finished) {
1198 		e_debug(conn->event, "Early reply: %s", smtp_reply_log(reply));
1199 		if (smtp_reply_is_success(reply)) {
1200 			smtp_client_connection_fail(
1201 				conn, SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1202 				"Got early success reply");
1203 			return -1;
1204 		}
1205 	}
1206 
1207 	/* command reply */
1208 	ret = smtp_client_command_input_reply(conn->cmd_wait_list_head, reply);
1209 
1210 	if (conn->state == SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED ||
1211 	    conn->conn.output == NULL)
1212 		return -1;
1213 	return ret;
1214 }
1215 
smtp_client_connection_input(struct connection * _conn)1216 static void smtp_client_connection_input(struct connection *_conn)
1217 {
1218 	struct smtp_client_connection *conn =
1219 		(struct smtp_client_connection *)_conn;
1220 	bool enhanced_codes = ((conn->caps.standard &
1221 				SMTP_CAPABILITY_ENHANCEDSTATUSCODES) != 0);
1222 	struct smtp_reply *reply;
1223 	const char *error = NULL;
1224 	int ret;
1225 
1226 	if (conn->ssl_iostream != NULL &&
1227 	    !ssl_iostream_is_handshaked(conn->ssl_iostream)) {
1228 		/* finish SSL negotiation by reading from input stream */
1229 		while ((ret = i_stream_read(conn->conn.input)) > 0 ||
1230 		       ret == -2) {
1231 			if (ssl_iostream_is_handshaked(conn->ssl_iostream))
1232 				break;
1233 		}
1234 		if (ret < 0) {
1235 			/* failed somehow */
1236 			i_assert(ret != -2);
1237 			e_error(conn->event,
1238 				"SSL handshaking with %s failed: "
1239 				"read(%s) failed: %s", _conn->name,
1240 				i_stream_get_name(conn->conn.input),
1241 				i_stream_get_error(conn->conn.input));
1242 			smtp_client_connection_fail(
1243 				conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1244 				"Failed to connect to remote server");
1245 			return;
1246 		}
1247 
1248 		if (!ssl_iostream_is_handshaked(conn->ssl_iostream)) {
1249 			/* not finished */
1250 			i_assert(ret == 0);
1251 			return;
1252 		}
1253 
1254 		if (conn->to_connect != NULL)
1255 			timeout_reset(conn->to_connect);
1256 	}
1257 
1258 	if (!conn->connect_succeeded) {
1259 		/* just got ready for SMTP handshake */
1260 		smtp_client_connection_established(conn);
1261 	}
1262 
1263 	smtp_client_connection_ref(conn);
1264 	o_stream_cork(conn->conn.output);
1265 	for (;;) {
1266 		if (conn->cmd_wait_list_head != NULL &&
1267 		    conn->cmd_wait_list_head->ehlo) {
1268 			if ((ret = smtp_reply_parse_ehlo(conn->reply_parser,
1269 							 &reply, &error)) <= 0)
1270 				break;
1271 		} else {
1272 			if ((ret = smtp_reply_parse_next(conn->reply_parser,
1273 							 enhanced_codes,
1274 							 &reply, &error)) <= 0)
1275 				break;
1276 		}
1277 
1278 		T_BEGIN {
1279 			ret = smtp_client_connection_input_reply(conn, reply);
1280 		} T_END;
1281 		if (ret < 0) {
1282 			if (conn->conn.output != NULL && !conn->corked)
1283 				o_stream_uncork(conn->conn.output);
1284 			smtp_client_connection_unref(&conn);
1285 			return;
1286 		}
1287 	}
1288 
1289 	if (ret < 0 || (ret == 0 && conn->conn.input->eof)) {
1290 		if (conn->conn.input->stream_errno == ENOBUFS) {
1291 			smtp_client_connection_fail(
1292 				conn, SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1293 				"Command reply line too long");
1294 		} else if (conn->conn.input->stream_errno != 0) {
1295 			smtp_client_connection_lost(
1296 				conn,
1297 				t_strdup_printf(
1298 					"read(%s) failed: %s",
1299 					i_stream_get_name(conn->conn.input),
1300 					i_stream_get_error(conn->conn.input)),
1301 				"Read failure");
1302 		} else if (!i_stream_have_bytes_left(conn->conn.input)) {
1303 			if (conn->sent_quit) {
1304 				smtp_client_connection_lost(
1305 					conn, NULL,
1306 					"Remote closed connection");
1307 			} else {
1308 				smtp_client_connection_lost(
1309 					conn, NULL,
1310 					"Remote closed connection unexpectedly");
1311 			}
1312 		} else {
1313 			i_assert(error != NULL);
1314 			smtp_client_connection_fail(
1315 				conn, SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY,
1316 				t_strdup_printf("Invalid command reply: %s",
1317 						error));
1318 		}
1319 	}
1320 	if (ret >= 0 && conn->conn.output != NULL && !conn->corked) {
1321 		if (o_stream_uncork_flush(conn->conn.output) < 0)
1322 			smtp_client_connection_handle_output_error(conn);
1323 	}
1324 	smtp_client_connection_unref(&conn);
1325 }
1326 
smtp_client_connection_output(struct smtp_client_connection * conn)1327 static int smtp_client_connection_output(struct smtp_client_connection *conn)
1328 {
1329 	int ret;
1330 
1331 	if (conn->to_connect != NULL)
1332 		timeout_reset(conn->to_connect);
1333 
1334 	ret = o_stream_flush(conn->conn.output);
1335 	if (ret <= 0) {
1336 		if (ret < 0)
1337 			smtp_client_connection_handle_output_error(conn);
1338 		return ret;
1339 	}
1340 
1341 	smtp_client_connection_ref(conn);
1342 	o_stream_cork(conn->conn.output);
1343 	if (smtp_client_command_send_more(conn) < 0)
1344 		ret = -1;
1345 	if (ret >= 0 && conn->conn.output != NULL && !conn->corked) {
1346 		if (o_stream_uncork_flush(conn->conn.output) < 0)
1347 			smtp_client_connection_handle_output_error(conn);
1348 	}
1349 	smtp_client_connection_unref(&conn);
1350 	return ret;
1351 }
1352 
smtp_client_connection_trigger_output(struct smtp_client_connection * conn)1353 void smtp_client_connection_trigger_output(struct smtp_client_connection *conn)
1354 {
1355 	if (conn->conn.output != NULL)
1356 		o_stream_set_flush_pending(conn->conn.output, TRUE);
1357 }
1358 
smtp_client_connection_destroy(struct connection * _conn)1359 static void smtp_client_connection_destroy(struct connection *_conn)
1360 {
1361 	struct smtp_client_connection *conn =
1362 		(struct smtp_client_connection *)_conn;
1363 
1364 	switch (_conn->disconnect_reason) {
1365 	case CONNECTION_DISCONNECT_NOT:
1366 		break;
1367 	case CONNECTION_DISCONNECT_DEINIT:
1368 		e_debug(conn->event, "Connection deinit");
1369 		smtp_client_connection_close(&conn);
1370 		break;
1371 	case CONNECTION_DISCONNECT_CONNECT_TIMEOUT:
1372 		e_error(conn->event, "connect(%s) failed: Connection timed out",
1373 			_conn->name);
1374 		smtp_client_connection_fail(
1375 			conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1376 			"Connect timed out");
1377 		break;
1378 	default:
1379 	case CONNECTION_DISCONNECT_CONN_CLOSED:
1380 		if (conn->connect_failed) {
1381 			smtp_client_connection_fail(conn,
1382 				SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1383 				"Failed to connect to remote server");
1384 			break;
1385 		}
1386 		if (_conn->input != NULL && _conn->input->stream_errno != 0) {
1387 			smtp_client_connection_lost(
1388 				conn,
1389 				t_strdup_printf("read(%s) failed: %s",
1390 					i_stream_get_name(conn->conn.input),
1391 					i_stream_get_error(conn->conn.input)),
1392 				"Read failure");
1393 			break;
1394 		}
1395 		smtp_client_connection_lost(
1396 			conn, "Remote disconnected",
1397 			"Remote closed connection unexpectedly");
1398 		break;
1399 	}
1400 }
1401 
1402 static void
smtp_client_connection_established(struct smtp_client_connection * conn)1403 smtp_client_connection_established(struct smtp_client_connection *conn)
1404 {
1405 	i_assert(!conn->connect_succeeded);
1406 	conn->connect_succeeded = TRUE;
1407 
1408 	if (conn->to_connect != NULL)
1409 		timeout_reset(conn->to_connect);
1410 
1411 	/* set flush callback */
1412 	o_stream_set_flush_callback(conn->conn.output,
1413 		smtp_client_connection_output, conn);
1414 }
1415 
1416 static int
smtp_client_connection_ssl_handshaked(const char ** error_r,void * context)1417 smtp_client_connection_ssl_handshaked(const char **error_r, void *context)
1418 {
1419 	struct smtp_client_connection *conn = context;
1420 	const char *error, *host = conn->host;
1421 
1422 	if (ssl_iostream_check_cert_validity(conn->ssl_iostream,
1423 					     host, &error) == 0) {
1424 		e_debug(conn->event, "SSL handshake successful");
1425 	} else if (conn->set.ssl->allow_invalid_cert) {
1426 		e_debug(conn->event, "SSL handshake successful, "
1427 			"ignoring invalid certificate: %s", error);
1428 	} else {
1429 		*error_r = error;
1430 		return -1;
1431 	}
1432 	return 0;
1433 }
1434 
1435 static void
smtp_client_connection_streams_changed(struct smtp_client_connection * conn)1436 smtp_client_connection_streams_changed(struct smtp_client_connection *conn)
1437 {
1438 	struct stat st;
1439 
1440 	if (conn->set.rawlog_dir != NULL &&
1441 	    stat(conn->set.rawlog_dir, &st) == 0) {
1442 		iostream_rawlog_create(conn->set.rawlog_dir,
1443 				       &conn->conn.input, &conn->conn.output);
1444 	}
1445 
1446 	if (conn->reply_parser == NULL) {
1447 		conn->reply_parser = smtp_reply_parser_init(
1448 			conn->conn.input, conn->set.max_reply_size);
1449 	} else {
1450 		smtp_reply_parser_set_stream(conn->reply_parser,
1451 					     conn->conn.input);
1452 	}
1453 
1454 	connection_streams_changed(&conn->conn);
1455 }
1456 
1457 static int
smtp_client_connection_init_ssl_ctx(struct smtp_client_connection * conn,const char ** error_r)1458 smtp_client_connection_init_ssl_ctx(struct smtp_client_connection *conn,
1459 				    const char **error_r)
1460 {
1461 	struct smtp_client *client = conn->client;
1462 	const char *error;
1463 
1464 	if (conn->ssl_ctx != NULL)
1465 		return 0;
1466 
1467 	if (conn->set.ssl == client->set.ssl) {
1468 		if (smtp_client_init_ssl_ctx(client, error_r) < 0)
1469 			return -1;
1470 		conn->ssl_ctx = client->ssl_ctx;
1471 		ssl_iostream_context_ref(conn->ssl_ctx);
1472 		return 0;
1473 	}
1474 
1475 	if (conn->set.ssl == NULL) {
1476 		*error_r =
1477 			"Requested SSL connection, but no SSL settings given";
1478 		return -1;
1479 	}
1480 	if (ssl_iostream_client_context_cache_get(conn->set.ssl, &conn->ssl_ctx,
1481 						  &error) < 0) {
1482 		*error_r = t_strdup_printf(
1483 			"Couldn't initialize SSL context: %s", error);
1484 		return -1;
1485 	}
1486 	return 0;
1487 }
1488 
1489 static int
smtp_client_connection_ssl_init(struct smtp_client_connection * conn,const char ** error_r)1490 smtp_client_connection_ssl_init(struct smtp_client_connection *conn,
1491 				const char **error_r)
1492 {
1493 	const char *error;
1494 
1495 	if (smtp_client_connection_init_ssl_ctx(conn, &error) < 0) {
1496 		*error_r = t_strdup_printf(
1497 			"Failed to initialize SSL: %s", error);
1498 		return -1;
1499 	}
1500 
1501 	e_debug(conn->event, "Starting SSL handshake");
1502 
1503 	if (conn->raw_input != conn->conn.input) {
1504 		/* recreate rawlog after STARTTLS */
1505 		i_stream_ref(conn->raw_input);
1506 		o_stream_ref(conn->raw_output);
1507 		i_stream_destroy(&conn->conn.input);
1508 		o_stream_destroy(&conn->conn.output);
1509 		conn->conn.input = conn->raw_input;
1510 		conn->conn.output = conn->raw_output;
1511 	}
1512 
1513 	connection_input_halt(&conn->conn);
1514 	if (io_stream_create_ssl_client(
1515 		conn->ssl_ctx, conn->host, conn->set.ssl,
1516 		&conn->conn.input, &conn->conn.output,
1517 		&conn->ssl_iostream, &error) < 0) {
1518 		*error_r = t_strdup_printf(
1519 			"Couldn't initialize SSL client for %s: %s",
1520 			conn->conn.name, error);
1521 		return -1;
1522 	}
1523 	connection_input_resume(&conn->conn);
1524 	smtp_client_connection_streams_changed(conn);
1525 
1526 	ssl_iostream_set_handshake_callback(
1527 		conn->ssl_iostream, smtp_client_connection_ssl_handshaked,
1528 		conn);
1529 	if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
1530 		*error_r = t_strdup_printf(
1531 			"SSL handshake to %s failed: %s", conn->conn.name,
1532 			ssl_iostream_get_last_error(conn->ssl_iostream));
1533 		return -1;
1534 	}
1535 
1536 	if (ssl_iostream_is_handshaked(conn->ssl_iostream) &&
1537 	    !conn->connect_succeeded) {
1538 		smtp_client_connection_established(conn);
1539 	} else {
1540 		/* wait for handshake to complete; connection input handler
1541 		   does the rest by reading from the input stream */
1542 		o_stream_set_flush_callback(
1543 			conn->conn.output, smtp_client_connection_output, conn);
1544 	}
1545 	return 0;
1546 }
1547 
1548 static void
smtp_client_connection_connected(struct connection * _conn,bool success)1549 smtp_client_connection_connected(struct connection *_conn, bool success)
1550 {
1551 	struct smtp_client_connection *conn =
1552 		(struct smtp_client_connection *)_conn;
1553 	const struct smtp_client_settings *set = &conn->set;
1554 	const char *error;
1555 
1556 	if (!success) {
1557 		e_error(conn->event, "connect(%s) failed: %m", _conn->name);
1558 		conn->connect_failed = TRUE;
1559 		return;
1560 	}
1561 
1562 	if (conn->set.debug) {
1563 		struct ip_addr local_ip;
1564 		in_port_t local_port;
1565 		int ret;
1566 
1567 		ret = net_getsockname(_conn->fd_in, &local_ip, &local_port);
1568 		i_assert(ret == 0);
1569 		e_debug(conn->event, "Connected to server (from %s:%u)",
1570 			net_ip2addr(&local_ip), local_port);
1571 	}
1572 
1573 	(void)net_set_tcp_nodelay(_conn->fd_out, TRUE);
1574 	if (set->socket_send_buffer_size > 0 &&
1575 	    net_set_send_buffer_size(_conn->fd_out,
1576 				     set->socket_send_buffer_size) < 0) {
1577 		e_error(conn->event,
1578 			"net_set_send_buffer_size(%zu) failed: %m",
1579 			set->socket_send_buffer_size);
1580 	}
1581 	if (set->socket_recv_buffer_size > 0 &&
1582 	    net_set_recv_buffer_size(_conn->fd_in,
1583 				     set->socket_recv_buffer_size) < 0) {
1584 		e_error(conn->event,
1585 			"net_set_recv_buffer_size(%zu) failed: %m",
1586 			set->socket_recv_buffer_size);
1587 	}
1588 
1589 	conn->raw_input = conn->conn.input;
1590 	conn->raw_output = conn->conn.output;
1591 	smtp_client_connection_streams_changed(conn);
1592 
1593 	if (conn->ssl_mode == SMTP_CLIENT_SSL_MODE_IMMEDIATE) {
1594 		if (smtp_client_connection_ssl_init(conn, &error) < 0) {
1595 			e_error(conn->event, "connect(%s) failed: %s",
1596 				_conn->name, error);
1597 			smtp_client_connection_fail(
1598 				conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1599 				"Failed to connect to remote server");
1600 		}
1601 	} else {
1602 		smtp_client_connection_established(conn);
1603 		smtp_client_connection_input(_conn);
1604 	}
1605 }
1606 
1607 static void
smtp_client_connection_connect_timeout(struct smtp_client_connection * conn)1608 smtp_client_connection_connect_timeout(struct smtp_client_connection *conn)
1609 {
1610 	switch (conn->state) {
1611 	case SMTP_CLIENT_CONNECTION_STATE_CONNECTING:
1612 		e_error(conn->event, "connect(%s) failed: "
1613 			"Connection timed out after %u seconds",
1614 			conn->conn.name,
1615 			conn->set.connect_timeout_msecs/1000);
1616 		smtp_client_connection_fail(
1617 			conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1618 			"Connect timed out");
1619 		break;
1620 	case SMTP_CLIENT_CONNECTION_STATE_HANDSHAKING:
1621 		e_error(conn->event,
1622 			"SMTP handshake timed out after %u seconds",
1623 			conn->set.connect_timeout_msecs/1000);
1624 		smtp_client_connection_fail(
1625 			conn, SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1626 			"Handshake timed out");
1627 		break;
1628 	case SMTP_CLIENT_CONNECTION_STATE_AUTHENTICATING:
1629 		e_error(conn->event,
1630 			"Authentication timed out after %u seconds",
1631 			conn->set.connect_timeout_msecs/1000);
1632 		smtp_client_connection_fail(
1633 			conn, SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED,
1634 			"Authentication timed out");
1635 		break;
1636 	default:
1637 		i_unreached();
1638 	}
1639 }
1640 
1641 static void
smtp_client_connection_delayed_connect_error(struct smtp_client_connection * conn)1642 smtp_client_connection_delayed_connect_error(
1643 	struct smtp_client_connection *conn)
1644 {
1645 	e_debug(conn->event, "Delayed connect error");
1646 
1647 	timeout_remove(&conn->to_connect);
1648 	errno = conn->connect_errno;
1649 	smtp_client_connection_connected(&conn->conn, FALSE);
1650 	smtp_client_connection_fail(conn,
1651 		SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED,
1652 		"Failed to connect to remote server");
1653 }
1654 
1655 static void
smtp_client_connection_do_connect(struct smtp_client_connection * conn)1656 smtp_client_connection_do_connect(struct smtp_client_connection *conn)
1657 {
1658 	unsigned int msecs;
1659 
1660 	if (conn->closed || conn->failing)
1661 		return;
1662 
1663 	/* Clear state data */
1664 	i_zero(&conn->state_data);
1665 	p_clear(conn->state_pool);
1666 
1667 	if (connection_client_connect(&conn->conn) < 0) {
1668 		conn->connect_errno = errno;
1669 		e_debug(conn->event, "Connect failed: %m");
1670 		conn->to_connect = timeout_add_short(0,
1671 			smtp_client_connection_delayed_connect_error, conn);
1672 		return;
1673 	}
1674 
1675 	/* don't use connection.h timeout because we want this timeout
1676 	   to include also the SSL handshake */
1677 	msecs = conn->set.connect_timeout_msecs;
1678 	if (msecs == 0)
1679 		msecs = conn->set.command_timeout_msecs;
1680 	i_assert(conn->to_connect == NULL);
1681 	if (msecs > 0) {
1682 		conn->to_connect = timeout_add(
1683 			msecs, smtp_client_connection_connect_timeout, conn);
1684 	}
1685 }
1686 
1687 static bool
smtp_client_connection_last_ip(struct smtp_client_connection * conn)1688 smtp_client_connection_last_ip(struct smtp_client_connection *conn)
1689 {
1690 	i_assert(conn->prev_connect_idx < conn->ips_count);
1691 	return (conn->prev_connect_idx + 1) % conn->ips_count == 0;
1692 }
1693 
1694 static void
smtp_client_connection_connect_next_ip(struct smtp_client_connection * conn)1695 smtp_client_connection_connect_next_ip(struct smtp_client_connection *conn)
1696 {
1697 	const struct ip_addr *ip, *my_ip = &conn->set.my_ip;
1698 
1699 	timeout_remove(&conn->to_connect);
1700 
1701 	conn->prev_connect_idx = (conn->prev_connect_idx+1) % conn->ips_count;
1702 	ip = &conn->ips[conn->prev_connect_idx];
1703 
1704 	if (my_ip->family != 0) {
1705 		e_debug(conn->event, "Connecting to %s:%u (from %s)",
1706 			net_ip2addr(ip), conn->port, net_ip2addr(my_ip));
1707 	} else {
1708 		e_debug(conn->event, "Connecting to %s:%u",
1709 			net_ip2addr(ip), conn->port);
1710 	}
1711 
1712 	connection_init_client_ip_from(conn->client->conn_list, &conn->conn,
1713 				       (conn->host_is_ip ? NULL : conn->host),
1714 				       ip, conn->port, my_ip);
1715 
1716 	smtp_client_connection_do_connect(conn);
1717 }
1718 
1719 static void
smtp_client_connection_connect_unix(struct smtp_client_connection * conn)1720 smtp_client_connection_connect_unix(struct smtp_client_connection *conn)
1721 {
1722 	timeout_remove(&conn->to_connect);
1723 
1724 	e_debug(conn->event, "Connecting to socket %s", conn->path);
1725 
1726 	connection_init_client_unix(conn->client->conn_list, &conn->conn,
1727 				    conn->path);
1728 
1729 	smtp_client_connection_do_connect(conn);
1730 }
1731 
1732 static void
smtp_client_connection_delayed_host_lookup_failure(struct smtp_client_connection * conn)1733 smtp_client_connection_delayed_host_lookup_failure(
1734 	struct smtp_client_connection *conn)
1735 {
1736 	e_debug(conn->event, "Delayed host lookup failure");
1737 
1738 	i_assert(conn->to_connect != NULL);
1739 	timeout_remove(&conn->to_connect);
1740 	smtp_client_connection_fail(
1741 		conn, SMTP_CLIENT_COMMAND_ERROR_HOST_LOOKUP_FAILED,
1742 		"Failed to lookup remote server");
1743 }
1744 
1745 static void
smtp_client_connection_dns_callback(const struct dns_lookup_result * result,struct smtp_client_connection * conn)1746 smtp_client_connection_dns_callback(const struct dns_lookup_result *result,
1747 				    struct smtp_client_connection *conn)
1748 {
1749 	conn->dns_lookup = NULL;
1750 
1751 	if (result->ret != 0) {
1752 		e_error(conn->event, "dns_lookup(%s) failed: %s",
1753 			conn->host, result->error);
1754 		timeout_remove(&conn->to_connect);
1755 		conn->to_connect = timeout_add_short(
1756 			0, smtp_client_connection_delayed_host_lookup_failure,
1757 			conn);
1758 		return;
1759 	}
1760 
1761 	e_debug(conn->event, "DNS lookup successful; got %d IPs",
1762 		result->ips_count);
1763 
1764 	i_assert(result->ips_count > 0);
1765 	conn->ips_count = result->ips_count;
1766 	conn->ips = i_new(struct ip_addr, conn->ips_count);
1767 	memcpy(conn->ips, result->ips, sizeof(*conn->ips) * conn->ips_count);
1768 	conn->prev_connect_idx = conn->ips_count - 1;
1769 
1770 	smtp_client_connection_connect_next_ip(conn);
1771 }
1772 
1773 static void
smtp_client_connection_lookup_ip(struct smtp_client_connection * conn)1774 smtp_client_connection_lookup_ip(struct smtp_client_connection *conn)
1775 {
1776 	struct dns_lookup_settings dns_set;
1777 	struct ip_addr ip, *ips;
1778 	unsigned int ips_count;
1779 	int ret;
1780 
1781 	if (conn->ips_count != 0)
1782 		return;
1783 
1784 	e_debug(conn->event, "Looking up IP address");
1785 
1786 	if (net_addr2ip(conn->host, &ip) == 0) {
1787 		/* IP address */
1788 		conn->ips_count = 1;
1789 		conn->ips = i_new(struct ip_addr, conn->ips_count);
1790 		conn->ips[0] = ip;
1791 		conn->host_is_ip = TRUE;
1792 	} else if (conn->set.dns_client != NULL) {
1793 		e_debug(conn->event, "Performing asynchronous DNS lookup");
1794 		(void)dns_client_lookup(
1795 			conn->set.dns_client, conn->host,
1796 			smtp_client_connection_dns_callback, conn,
1797 			&conn->dns_lookup);
1798 	} else if (conn->set.dns_client_socket_path != NULL) {
1799 		i_zero(&dns_set);
1800 		dns_set.dns_client_socket_path =
1801 			conn->set.dns_client_socket_path;
1802 		dns_set.timeout_msecs = conn->set.connect_timeout_msecs;
1803 		dns_set.event_parent = conn->event;
1804 		e_debug(conn->event, "Performing asynchronous DNS lookup");
1805 		(void)dns_lookup(conn->host, &dns_set,
1806 				 smtp_client_connection_dns_callback, conn,
1807 				 &conn->dns_lookup);
1808 	} else {
1809 		/* no dns-conn, use blocking lookup */
1810 		ret = net_gethostbyname(conn->host, &ips, &ips_count);
1811 		if (ret != 0) {
1812 			e_error(conn->event, "net_gethostbyname(%s) failed: %s",
1813 				conn->host, net_gethosterror(ret));
1814 			timeout_remove(&conn->to_connect);
1815 			conn->to_connect = timeout_add_short(
1816 				0,
1817 				smtp_client_connection_delayed_host_lookup_failure,
1818 				conn);
1819 			return;
1820 		}
1821 
1822 		e_debug(conn->event, "DNS lookup successful; got %d IPs",
1823 			ips_count);
1824 
1825 		conn->ips_count = ips_count;
1826 		conn->ips = i_new(struct ip_addr, ips_count);
1827 		memcpy(conn->ips, ips, ips_count * sizeof(*ips));
1828 	}
1829 }
1830 
1831 static void
smtp_client_connection_already_connected(struct smtp_client_connection * conn)1832 smtp_client_connection_already_connected(struct smtp_client_connection *conn)
1833 {
1834 	i_assert(conn->state_data.login_reply != NULL);
1835 
1836 	timeout_remove(&conn->to_connect);
1837 
1838 	e_debug(conn->event, "Already connected");
1839 
1840 	smtp_client_connection_login_callback(
1841 		conn, conn->state_data.login_reply);
1842 }
1843 
1844 static void
smtp_client_connection_connect_more(struct smtp_client_connection * conn)1845 smtp_client_connection_connect_more(struct smtp_client_connection *conn)
1846 {
1847 	if (!array_is_created(&conn->login_callbacks) ||
1848 	    array_count(&conn->login_callbacks) == 0) {
1849 		/* No login callbacks required */
1850 		return;
1851 	}
1852 	if (conn->state < SMTP_CLIENT_CONNECTION_STATE_READY) {
1853 		/* Login callbacks will be called once the connection succeeds
1854 		   or fails. */
1855 		return;
1856 	}
1857 
1858 	if (array_count(&conn->login_callbacks) > 1) {
1859 		/* Another login callback is already pending */
1860 		i_assert(conn->to_connect != NULL);
1861 		return;
1862 	}
1863 
1864 	/* Schedule immediate login callback */
1865 	i_assert(conn->to_connect == NULL);
1866 	conn->to_connect = timeout_add(
1867 		0, smtp_client_connection_already_connected, conn);
1868 }
1869 
smtp_client_connection_connect(struct smtp_client_connection * conn,smtp_client_command_callback_t login_callback,void * login_context)1870 void smtp_client_connection_connect(
1871 	struct smtp_client_connection *conn,
1872 	smtp_client_command_callback_t login_callback, void *login_context)
1873 {
1874 	struct smtp_client_login_callback *login_cb;
1875 
1876 	if (conn->closed)
1877 		return;
1878 
1879 	if (login_callback != NULL) {
1880 		if (!array_is_created(&conn->login_callbacks))
1881 			i_array_init(&conn->login_callbacks, 4);
1882 
1883 		login_cb = array_append_space(&conn->login_callbacks);
1884 		login_cb->callback = login_callback;
1885 		login_cb->context = login_context;
1886 	}
1887 
1888 	if (conn->state != SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED) {
1889 		/* Already connecting or connected */
1890 		smtp_client_connection_connect_more(conn);
1891 		return;
1892 	}
1893 	if (conn->failing)
1894 		return;
1895 
1896 	e_debug(conn->event, "Disconnected");
1897 
1898 	conn->xclient_replies_expected = 0;
1899 	conn->authenticated = FALSE;
1900 	conn->xclient_sent = FALSE;
1901 	conn->connect_failed = FALSE;
1902 	conn->connect_succeeded = FALSE;
1903 	conn->handshake_failed = FALSE;
1904 	conn->sent_quit = FALSE;
1905 	conn->reset_needed = FALSE;
1906 
1907 	smtp_client_connection_set_state(
1908 		conn, SMTP_CLIENT_CONNECTION_STATE_CONNECTING);
1909 
1910 	if (conn->path == NULL) {
1911 		smtp_client_connection_lookup_ip(conn);
1912 		if (conn->ips_count == 0)
1913 			return;
1914 
1915 		/* always work asynchronously */
1916 		timeout_remove(&conn->to_connect);
1917 		conn->to_connect = timeout_add(
1918 			0, smtp_client_connection_connect_next_ip, conn);
1919 	} else {
1920 		/* always work asynchronously */
1921 		timeout_remove(&conn->to_connect);
1922 		conn->to_connect = timeout_add(
1923 			0, smtp_client_connection_connect_unix, conn);
1924 	}
1925 }
1926 
1927 static const struct connection_settings smtp_client_connection_set = {
1928 	.input_max_size = SIZE_MAX,
1929 	.output_max_size = SIZE_MAX,
1930 	.client = TRUE,
1931 	.delayed_unix_client_connected_callback = TRUE,
1932 	.log_connection_id = TRUE,
1933 };
1934 
1935 static const struct connection_vfuncs smtp_client_connection_vfuncs = {
1936 	.destroy = smtp_client_connection_destroy,
1937 	.input = smtp_client_connection_input,
1938 	.client_connected = smtp_client_connection_connected
1939 };
1940 
smtp_client_connection_list_init(void)1941 struct connection_list *smtp_client_connection_list_init(void)
1942 {
1943 	return connection_list_init(&smtp_client_connection_set,
1944 				    &smtp_client_connection_vfuncs);
1945 }
1946 
smtp_client_connection_disconnect(struct smtp_client_connection * conn)1947 void smtp_client_connection_disconnect(struct smtp_client_connection *conn)
1948 {
1949 	if (conn->state == SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED)
1950 		return;
1951 
1952 	e_debug(conn->event, "Disconnected");
1953 
1954 	smtp_client_connection_clear_password(conn);
1955 
1956 	if (conn->conn.output != NULL && !conn->sent_quit &&
1957 	    !conn->sending_command) {
1958 		/* Close the connection gracefully if possible */
1959 		o_stream_nsend_str(conn->conn.output, "QUIT\r\n");
1960 		o_stream_uncork(conn->conn.output);
1961 	}
1962 
1963 	if (conn->dns_lookup != NULL)
1964 		dns_lookup_abort(&conn->dns_lookup);
1965 	io_remove(&conn->io_cmd_payload);
1966 	timeout_remove(&conn->to_connect);
1967 	timeout_remove(&conn->to_trans);
1968 	timeout_remove(&conn->to_commands);
1969 	timeout_remove(&conn->to_cmd_fail);
1970 
1971 	ssl_iostream_destroy(&conn->ssl_iostream);
1972 	if (conn->ssl_ctx != NULL)
1973 		ssl_iostream_context_unref(&conn->ssl_ctx);
1974 	if (conn->sasl_client != NULL)
1975 		dsasl_client_free(&conn->sasl_client);
1976 
1977 	o_stream_destroy(&conn->dot_output);
1978 
1979 	connection_disconnect(&conn->conn);
1980 
1981 	smtp_client_connection_set_state(
1982 		conn, SMTP_CLIENT_CONNECTION_STATE_DISCONNECTED);
1983 
1984 	if (!conn->failing) {
1985 		smtp_client_connection_login_fail(
1986 			conn, SMTP_CLIENT_COMMAND_ERROR_ABORTED,
1987 			"Disconnected from server");
1988 		smtp_client_connection_transactions_fail(
1989 			conn,  SMTP_CLIENT_COMMAND_ERROR_ABORTED,
1990 			"Disconnected from server");
1991 		smtp_client_connection_commands_fail(
1992 			conn, SMTP_CLIENT_COMMAND_ERROR_ABORTED,
1993 			"Disconnected from server");
1994 	}
1995 	smtp_client_command_unref(&conn->cmd_streaming);
1996 }
1997 
1998 static struct smtp_client_connection *
smtp_client_connection_do_create(struct smtp_client * client,const char * name,enum smtp_protocol protocol,const struct smtp_client_settings * set)1999 smtp_client_connection_do_create(struct smtp_client *client, const char *name,
2000 				 enum smtp_protocol protocol,
2001 				 const struct smtp_client_settings *set)
2002 {
2003 	struct smtp_client_connection *conn;
2004 	struct event *conn_event;
2005 	pool_t pool;
2006 
2007 	pool = pool_alloconly_create("smtp client connection", 2048);
2008 	conn = p_new(pool, struct smtp_client_connection, 1);
2009 	conn->refcount = 1;
2010 	conn->pool = pool;
2011 
2012 	conn->client = client;
2013 	conn->protocol = protocol;
2014 
2015 	conn->set = client->set;
2016 	if (set != NULL) {
2017 		if (set->my_ip.family != 0)
2018 			conn->set.my_ip = set->my_ip;
2019 		if (set->my_hostname != NULL && *set->my_hostname != '\0')
2020 			conn->set.my_hostname = p_strdup(pool, set->my_hostname);
2021 
2022 		conn->set.forced_capabilities |= set->forced_capabilities;
2023 		if (set->extra_capabilities != NULL) {
2024 			conn->set.extra_capabilities =
2025 				p_strarray_dup(pool, set->extra_capabilities);
2026 		}
2027 
2028 		if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
2029 			conn->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
2030 
2031 		if (set->ssl != NULL)
2032 			conn->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
2033 
2034 		if (set->master_user != NULL && *set->master_user != '\0')
2035 			conn->set.master_user = p_strdup_empty(pool, set->master_user);
2036 		if (set->username != NULL && *set->username != '\0')
2037 			conn->set.username = p_strdup_empty(pool, set->username);
2038 		if (set->password != NULL && *set->password != '\0') {
2039 			conn->password = p_strdup(pool, set->password);
2040 			conn->set.password = conn->password;
2041 		}
2042 		if (set->sasl_mech != NULL)
2043 			conn->set.sasl_mech = set->sasl_mech;
2044 		else if (set->sasl_mechanisms != NULL &&
2045 			 *set->sasl_mechanisms != '\0') {
2046 			conn->set.sasl_mechanisms =
2047 				p_strdup(pool, set->sasl_mechanisms);
2048 		}
2049 		conn->set.remember_password = set->remember_password;
2050 
2051 		if (set->command_timeout_msecs > 0)
2052 			conn->set.command_timeout_msecs = set->command_timeout_msecs;
2053 		if (set->connect_timeout_msecs > 0)
2054 			conn->set.connect_timeout_msecs = set->connect_timeout_msecs;
2055 		if (set->max_reply_size > 0)
2056 			conn->set.max_reply_size = set->max_reply_size;
2057 		if (set->max_data_chunk_size > 0)
2058 			conn->set.max_data_chunk_size = set->max_data_chunk_size;
2059 		if (set->max_data_chunk_pipeline > 0)
2060 			conn->set.max_data_chunk_pipeline = set->max_data_chunk_pipeline;
2061 
2062 		if (set->socket_send_buffer_size > 0)
2063 			conn->set.socket_send_buffer_size = set->socket_send_buffer_size;
2064 		if (set->socket_recv_buffer_size > 0)
2065 			conn->set.socket_recv_buffer_size = set->socket_recv_buffer_size;
2066 		conn->set.debug = conn->set.debug || set->debug;
2067 
2068 		smtp_proxy_data_merge(conn->pool, &conn->set.proxy_data,
2069 				      &set->proxy_data);
2070 		conn->set.xclient_defer = set->xclient_defer;
2071 		conn->set.peer_trusted = set->peer_trusted;
2072 
2073 		conn->set.mail_send_broken_path = set->mail_send_broken_path;
2074 	}
2075 
2076 
2077 	if (set != NULL && set->extra_capabilities != NULL) {
2078 		const char *const *extp;
2079 
2080 		p_array_init(&conn->extra_capabilities, pool,
2081 			     str_array_length(set->extra_capabilities) + 8);
2082 		for (extp = set->extra_capabilities; *extp != NULL; extp++) {
2083 			struct smtp_client_capability_extra cap = {
2084 				.name = p_strdup(pool, *extp),
2085 			};
2086 
2087 			array_push_back(&conn->extra_capabilities, &cap);
2088 		}
2089 	}
2090 
2091 	i_assert(conn->set.my_hostname != NULL &&
2092 		*conn->set.my_hostname != '\0');
2093 
2094 	conn->caps.standard = conn->set.forced_capabilities;
2095 	conn->cap_pool = pool_alloconly_create(
2096 		"smtp client connection capabilities", 128);
2097 	conn->state_pool = pool_alloconly_create(
2098 		"smtp client connection state", 256);
2099 
2100 	if (set != NULL && set->event_parent != NULL)
2101 		conn_event = event_create(set->event_parent);
2102 	else
2103 		conn_event = event_create(client->event);
2104 	event_set_append_log_prefix(
2105 		conn_event,
2106 		t_strdup_printf("%s-client: ",
2107 				smtp_protocol_name(conn->protocol)));
2108 	event_add_str(conn_event, "protocol",
2109 		      smtp_protocol_name(conn->protocol));
2110 	event_set_forced_debug(conn_event, (set != NULL && set->debug));
2111 
2112 	conn->conn.event_parent = conn_event;
2113 	connection_init(conn->client->conn_list, &conn->conn, name);
2114 	conn->event = conn->conn.event;
2115 	event_unref(&conn_event);
2116 
2117 	return conn;
2118 }
2119 
2120 struct smtp_client_connection *
smtp_client_connection_create(struct smtp_client * client,enum smtp_protocol protocol,const char * host,in_port_t port,enum smtp_client_connection_ssl_mode ssl_mode,const struct smtp_client_settings * set)2121 smtp_client_connection_create(struct smtp_client *client,
2122 			      enum smtp_protocol protocol,
2123 			      const char *host, in_port_t port,
2124 			      enum smtp_client_connection_ssl_mode ssl_mode,
2125 			      const struct smtp_client_settings *set)
2126 {
2127 	struct smtp_client_connection *conn;
2128 	const char *name = t_strdup_printf("%s:%u", host, port);
2129 
2130 	conn = smtp_client_connection_do_create(client, name, protocol, set);
2131 	conn->host = p_strdup(conn->pool, host);
2132 	conn->port = port;
2133 	conn->ssl_mode = ssl_mode;
2134 
2135 	event_add_str(conn->event, "host", host);
2136 
2137 	e_debug(conn->event, "Connection created");
2138 
2139 	return conn;
2140 }
2141 
2142 struct smtp_client_connection *
smtp_client_connection_create_ip(struct smtp_client * client,enum smtp_protocol protocol,const struct ip_addr * ip,in_port_t port,const char * hostname,enum smtp_client_connection_ssl_mode ssl_mode,const struct smtp_client_settings * set)2143 smtp_client_connection_create_ip(struct smtp_client *client,
2144 				 enum smtp_protocol protocol,
2145 				 const struct ip_addr *ip, in_port_t port,
2146 				 const char *hostname,
2147 				 enum smtp_client_connection_ssl_mode ssl_mode,
2148 				 const struct smtp_client_settings *set)
2149 {
2150 	struct smtp_client_connection *conn;
2151 	bool host_is_ip = FALSE;
2152 
2153 	if (hostname == NULL) {
2154 		hostname = net_ip2addr(ip);
2155 		host_is_ip = TRUE;
2156 	}
2157 
2158 	conn = smtp_client_connection_create(client, protocol, hostname, port,
2159 					     ssl_mode, set);
2160 	conn->ips_count = 1;
2161 	conn->ips = i_new(struct ip_addr, conn->ips_count);
2162 	conn->ips[0] = *ip;
2163 	conn->host_is_ip = host_is_ip;
2164 	return conn;
2165 }
2166 
2167 struct smtp_client_connection *
smtp_client_connection_create_unix(struct smtp_client * client,enum smtp_protocol protocol,const char * path,const struct smtp_client_settings * set)2168 smtp_client_connection_create_unix(struct smtp_client *client,
2169 				   enum smtp_protocol protocol,
2170 				   const char *path,
2171 				   const struct smtp_client_settings *set)
2172 {
2173 	struct smtp_client_connection *conn;
2174 	const char *name = t_strconcat("unix:", path, NULL);
2175 
2176 	conn = smtp_client_connection_do_create(client, name, protocol, set);
2177 	conn->path = p_strdup(conn->pool, path);
2178 
2179 	e_debug(conn->event, "Connection created");
2180 
2181 	return conn;
2182 }
2183 
smtp_client_connection_ref(struct smtp_client_connection * conn)2184 void smtp_client_connection_ref(struct smtp_client_connection *conn)
2185 {
2186 	i_assert(conn->refcount >= 0);
2187 	conn->refcount++;
2188 }
2189 
smtp_client_connection_unref(struct smtp_client_connection ** _conn)2190 void smtp_client_connection_unref(struct smtp_client_connection **_conn)
2191 {
2192 	struct smtp_client_connection *conn = *_conn;
2193 
2194 	*_conn = NULL;
2195 
2196 	i_assert(conn->refcount > 0);
2197 	if (--conn->refcount > 0)
2198 		return;
2199 	if (conn->destroying)
2200 		return;
2201 
2202 	conn->destroying = TRUE;
2203 
2204 	smtp_client_connection_clear_password(conn);
2205 	smtp_client_connection_disconnect(conn);
2206 
2207 	/* could have been created while already disconnected */
2208 	timeout_remove(&conn->to_commands);
2209 	timeout_remove(&conn->to_cmd_fail);
2210 
2211 	e_debug(conn->event, "Destroy");
2212 
2213 	if (conn->reply_parser != NULL)
2214 		smtp_reply_parser_deinit(&conn->reply_parser);
2215 
2216 	smtp_client_connection_login_fail(
2217 		conn, SMTP_CLIENT_COMMAND_ERROR_ABORTED,
2218 		"Connection destroy");
2219 	smtp_client_connection_transactions_fail(
2220 		conn,  SMTP_CLIENT_COMMAND_ERROR_ABORTED,
2221 		"Connection destroy");
2222 	smtp_client_connection_commands_fail(
2223 		conn, SMTP_CLIENT_COMMAND_ERROR_ABORTED,
2224 		"Connection destroy");
2225 	smtp_client_connection_transactions_drop(conn);
2226 
2227 	connection_deinit(&conn->conn);
2228 
2229 	i_free(conn->ips);
2230 	array_free(&conn->login_callbacks);
2231 	pool_unref(&conn->cap_pool);
2232 	pool_unref(&conn->state_pool);
2233 	pool_unref(&conn->pool);
2234 }
2235 
smtp_client_connection_close(struct smtp_client_connection ** _conn)2236 void smtp_client_connection_close(struct smtp_client_connection **_conn)
2237 {
2238 	struct smtp_client_connection *conn = *_conn;
2239 
2240 	*_conn = NULL;
2241 
2242 	if (conn->closed)
2243 		return;
2244 	conn->closed = TRUE;
2245 
2246 	smtp_client_connection_transactions_abort(conn);
2247 	smtp_client_connection_commands_abort(conn);
2248 	smtp_client_connection_disconnect(conn);
2249 
2250 	/* could have been created while already disconnected */
2251 	timeout_remove(&conn->to_commands);
2252 	timeout_remove(&conn->to_cmd_fail);
2253 
2254 	smtp_client_connection_unref(&conn);
2255 }
2256 
smtp_client_connection_update_proxy_data(struct smtp_client_connection * conn,const struct smtp_proxy_data * proxy_data)2257 void smtp_client_connection_update_proxy_data(
2258 	struct smtp_client_connection *conn,
2259 	const struct smtp_proxy_data *proxy_data)
2260 {
2261 	if (conn->xclient_sent)
2262 		return;
2263 
2264 	smtp_proxy_data_merge(conn->pool, &conn->set.proxy_data, proxy_data);
2265 }
2266 
smtp_client_connection_switch_ioloop(struct smtp_client_connection * conn)2267 void smtp_client_connection_switch_ioloop(struct smtp_client_connection *conn)
2268 {
2269 	struct smtp_client_transaction *trans;
2270 
2271 	if (conn->io_cmd_payload != NULL)
2272 		conn->io_cmd_payload = io_loop_move_io(&conn->io_cmd_payload);
2273 	if (conn->to_connect != NULL)
2274 		conn->to_connect = io_loop_move_timeout(&conn->to_connect);
2275 	if (conn->to_trans != NULL)
2276 		conn->to_trans = io_loop_move_timeout(&conn->to_trans);
2277 	if (conn->to_commands != NULL)
2278 		conn->to_commands = io_loop_move_timeout(&conn->to_commands);
2279 	if (conn->to_cmd_fail != NULL)
2280 		conn->to_cmd_fail = io_loop_move_timeout(&conn->to_cmd_fail);
2281 	connection_switch_ioloop(&conn->conn);
2282 
2283 	trans = conn->transactions_head;
2284 	while (trans != NULL) {
2285 		smtp_client_transaction_switch_ioloop(trans);
2286 		trans = trans->next;
2287 	}
2288 }
2289 
2290 static void
smtp_client_connection_rset_dummy_cb(const struct smtp_reply * reply ATTR_UNUSED,struct smtp_client_connection * conn ATTR_UNUSED)2291 smtp_client_connection_rset_dummy_cb(
2292 	const struct smtp_reply *reply ATTR_UNUSED,
2293 	struct smtp_client_connection *conn ATTR_UNUSED)
2294 {
2295 	/* nothing */
2296 }
2297 
2298 static void
smtp_client_connection_reset(struct smtp_client_connection * conn)2299 smtp_client_connection_reset(struct smtp_client_connection *conn)
2300 {
2301 	e_debug(conn->event, "Submitting RSET command");
2302 
2303 	conn->reset_needed = FALSE;
2304 
2305 	(void)smtp_client_command_rset_submit(
2306 		conn, SMTP_CLIENT_COMMAND_FLAG_PRIORITY,
2307 		smtp_client_connection_rset_dummy_cb, conn);
2308 }
2309 
2310 static void
smtp_client_connection_do_start_transaction(struct smtp_client_connection * conn)2311 smtp_client_connection_do_start_transaction(struct smtp_client_connection *conn)
2312 {
2313 	struct smtp_reply reply;
2314 
2315 	timeout_remove(&conn->to_trans);
2316 
2317 	if (conn->state != SMTP_CLIENT_CONNECTION_STATE_TRANSACTION)
2318 		return;
2319 	if (conn->transactions_head == NULL) {
2320 		smtp_client_connection_set_state(
2321 			conn, SMTP_CLIENT_CONNECTION_STATE_READY);
2322 		return;
2323 	}
2324 
2325 	if (conn->reset_needed)
2326 		smtp_client_connection_reset(conn);
2327 
2328 	e_debug(conn->event, "Start next transaction");
2329 
2330 	smtp_reply_init(&reply, 200, "Connection ready");
2331 	smtp_client_transaction_connection_result(
2332 		conn->transactions_head, &reply);
2333 }
2334 
2335 static void
smtp_client_connection_start_transaction(struct smtp_client_connection * conn)2336 smtp_client_connection_start_transaction(struct smtp_client_connection *conn)
2337 {
2338 	if (conn->state != SMTP_CLIENT_CONNECTION_STATE_READY)
2339 		return;
2340 	if (conn->transactions_head == NULL)
2341 		return;
2342 	if (conn->to_trans != NULL)
2343 		return;
2344 
2345 	smtp_client_connection_set_state(
2346 		conn, SMTP_CLIENT_CONNECTION_STATE_TRANSACTION);
2347 	conn->to_trans = timeout_add_short(
2348 		0, smtp_client_connection_do_start_transaction, conn);
2349 }
2350 
smtp_client_connection_add_transaction(struct smtp_client_connection * conn,struct smtp_client_transaction * trans)2351 void smtp_client_connection_add_transaction(
2352 	struct smtp_client_connection *conn,
2353 	struct smtp_client_transaction *trans)
2354 {
2355 	e_debug(conn->event, "Add transaction");
2356 
2357 	DLLIST2_APPEND(&conn->transactions_head, &conn->transactions_tail,
2358 		       trans);
2359 
2360 	smtp_client_connection_connect(conn, NULL, NULL);
2361 	smtp_client_connection_start_transaction(conn);
2362 }
2363 
smtp_client_connection_abort_transaction(struct smtp_client_connection * conn,struct smtp_client_transaction * trans)2364 void smtp_client_connection_abort_transaction(
2365 	struct smtp_client_connection *conn,
2366 	struct smtp_client_transaction *trans)
2367 {
2368 	bool was_first = (trans == conn->transactions_head);
2369 
2370 	e_debug(conn->event, "Abort transaction");
2371 
2372 	DLLIST2_REMOVE(&conn->transactions_head, &conn->transactions_tail,
2373 		       trans);
2374 
2375 	if (!was_first)
2376 		return;
2377 	i_assert(conn->state != SMTP_CLIENT_CONNECTION_STATE_READY);
2378 	if (conn->state != SMTP_CLIENT_CONNECTION_STATE_TRANSACTION)
2379 		return;
2380 
2381 	/* transaction messed up; protocol state needs to be reset for
2382 	   next transaction */
2383 	conn->reset_needed = TRUE;
2384 
2385 	smtp_client_connection_set_state(
2386 		conn, SMTP_CLIENT_CONNECTION_STATE_READY);
2387 	smtp_client_connection_start_transaction(conn);
2388 }
2389 
smtp_client_connection_next_transaction(struct smtp_client_connection * conn,struct smtp_client_transaction * trans)2390 void smtp_client_connection_next_transaction(
2391 	struct smtp_client_connection *conn,
2392 	struct smtp_client_transaction *trans)
2393 {
2394 	e_debug(conn->event, "Initiate next transaction");
2395 
2396 	i_assert(trans == conn->transactions_head);
2397 
2398 	DLLIST2_REMOVE(&conn->transactions_head, &conn->transactions_tail,
2399 		       trans);
2400 
2401 	i_assert(conn->state != SMTP_CLIENT_CONNECTION_STATE_READY);
2402 	if (conn->state != SMTP_CLIENT_CONNECTION_STATE_TRANSACTION)
2403 		return;
2404 
2405 	smtp_client_connection_set_state(
2406 		conn, SMTP_CLIENT_CONNECTION_STATE_READY);
2407 	smtp_client_connection_start_transaction(conn);
2408 }
2409