1 /* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "net.h"
5 #include "str.h"
6 #include "hash.h"
7 #include "hostpid.h"
8 #include "array.h"
9 #include "ioloop.h"
10 #include "istream.h"
11 #include "ostream.h"
12 #include "connection.h"
13 #include "dns-lookup.h"
14 #include "iostream-rawlog.h"
15 #include "iostream-ssl.h"
16 
17 #include "smtp-server-private.h"
18 
19 static struct event_category event_category_smtp_server = {
20 	.name = "smtp-server"
21 };
22 
23 /*
24  * Server
25  */
26 
smtp_server_init(const struct smtp_server_settings * set)27 struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
28 {
29 	struct smtp_server *server;
30 	pool_t pool;
31 
32 	pool = pool_alloconly_create("smtp server", 1024);
33 	server = p_new(pool, struct smtp_server, 1);
34 	server->pool = pool;
35 	server->set.protocol = set->protocol;
36 	server->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
37 
38 	if (set->ssl != NULL) {
39 		server->set.ssl =
40 			ssl_iostream_settings_dup(server->pool, set->ssl);
41 	}
42 
43 	if (set->hostname != NULL && *set->hostname != '\0')
44 		server->set.hostname = p_strdup(pool, set->hostname);
45 	else
46 		server->set.hostname = p_strdup(pool, my_hostdomain());
47 	if (set->login_greeting != NULL && *set->login_greeting != '\0')
48 		server->set.login_greeting = p_strdup(pool, set->login_greeting);
49 	else
50 		server->set.login_greeting = PACKAGE_NAME" ready.";
51 	if (set->capabilities == 0) {
52 		server->set.capabilities = SMTP_SERVER_DEFAULT_CAPABILITIES;
53 	} else  {
54 		server->set.capabilities = set->capabilities;
55 	}
56 	server->set.workarounds = set->workarounds;
57 	server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs;
58 	server->set.max_pipelined_commands = (set->max_pipelined_commands > 0 ?
59 		set->max_pipelined_commands : 1);
60 	server->set.max_bad_commands = (set->max_bad_commands > 0 ?
61 		set->max_bad_commands : SMTP_SERVER_DEFAULT_MAX_BAD_COMMANDS);
62 	server->set.max_recipients = set->max_recipients;
63 	server->set.command_limits = set->command_limits;
64 	server->set.max_message_size = set->max_message_size;
65 
66 	if (set->mail_param_extensions != NULL) {
67 		server->set.mail_param_extensions =
68 			p_strarray_dup(pool, set->mail_param_extensions);
69 	}
70 	if (set->rcpt_param_extensions != NULL) {
71 		server->set.rcpt_param_extensions =
72 			p_strarray_dup(pool, set->rcpt_param_extensions);
73 	}
74 	if (set->xclient_extensions != NULL) {
75 		server->set.xclient_extensions =
76 			p_strarray_dup(pool, set->xclient_extensions);
77 	}
78 
79 	server->set.socket_send_buffer_size = set->socket_send_buffer_size;
80 	server->set.socket_recv_buffer_size = set->socket_recv_buffer_size;
81 
82 	server->set.tls_required = set->tls_required;
83 	server->set.auth_optional = set->auth_optional;
84 	server->set.rcpt_domain_optional = set->rcpt_domain_optional;
85 	server->set.mail_path_allow_broken = set->mail_path_allow_broken;
86 	server->set.debug = set->debug;
87 	server->set.no_state_in_reason = set->no_state_in_reason;
88 
89 	/* There is no event log prefix added here, since the server itself does
90 	   not log anything. */
91 	server->event = event_create(set->event_parent);
92 	smtp_server_event_init(server, server->event);
93 	event_set_forced_debug(server->event, set->debug);
94 
95 	server->conn_list = smtp_server_connection_list_init();
96 	smtp_server_commands_init(server);
97 	return server;
98 }
99 
smtp_server_event_init(struct smtp_server * server,struct event * event)100 void smtp_server_event_init(struct smtp_server *server, struct event *event)
101 {
102 	event_add_category(event, &event_category_smtp_server);
103 	event_add_str(event, "protocol",
104 		      smtp_protocol_name(server->set.protocol));
105 }
106 
smtp_server_deinit(struct smtp_server ** _server)107 void smtp_server_deinit(struct smtp_server **_server)
108 {
109 	struct smtp_server *server = *_server;
110 
111 	connection_list_deinit(&server->conn_list);
112 
113 	if (server->ssl_ctx != NULL)
114 		ssl_iostream_context_unref(&server->ssl_ctx);
115 	event_unref(&server->event);
116 	pool_unref(&server->pool);
117 	*_server = NULL;
118 }
119 
smtp_server_switch_ioloop(struct smtp_server * server)120 void smtp_server_switch_ioloop(struct smtp_server *server)
121 {
122 	struct connection *_conn = server->conn_list->connections;
123 
124 	/* move connections */
125 	/* FIXME: we wouldn't necessarily need to switch all of them
126 	   immediately, only those that have commands now. but also connections
127 	   that get new commands before ioloop is switched again.. */
128 	for (; _conn != NULL; _conn = _conn->next) {
129 		struct smtp_server_connection *conn =
130 			(struct smtp_server_connection *)_conn;
131 
132 		smtp_server_connection_switch_ioloop(conn);
133 	}
134 }
135 
smtp_server_init_ssl_ctx(struct smtp_server * server,const char ** error_r)136 int smtp_server_init_ssl_ctx(struct smtp_server *server, const char **error_r)
137 {
138 	const char *error;
139 
140 	if (server->ssl_ctx != NULL || server->set.ssl == NULL)
141 		return 0;
142 
143 	if (ssl_iostream_server_context_cache_get(server->set.ssl,
144 		&server->ssl_ctx, &error) < 0) {
145 		*error_r = t_strdup_printf("Couldn't initialize SSL context: %s",
146 					   error);
147 		return -1;
148 	}
149 	return 0;
150 }
151