1 /* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lmtp-common.h"
4 #include "base64.h"
5 #include "str.h"
6 #include "llist.h"
7 #include "iostream.h"
8 #include "istream.h"
9 #include "ostream.h"
10 #include "hostpid.h"
11 #include "process-title.h"
12 #include "var-expand.h"
13 #include "module-dir.h"
14 #include "master-service-ssl.h"
15 #include "master-service-settings.h"
16 #include "iostream-ssl.h"
17 #include "mail-namespace.h"
18 #include "mail-storage.h"
19 #include "mail-storage-service.h"
20 #include "raw-storage.h"
21 #include "lda-settings.h"
22 #include "lmtp-local.h"
23 #include "lmtp-proxy.h"
24 #include "lmtp-commands.h"
25 
26 #include <unistd.h>
27 
28 #define CLIENT_IDLE_TIMEOUT_MSECS (1000*60*5)
29 
30 static const struct smtp_server_callbacks lmtp_callbacks;
31 static const struct lmtp_client_vfuncs lmtp_client_vfuncs;
32 
33 struct lmtp_module_register lmtp_module_register = { 0 };
34 
35 static struct client *clients = NULL;
36 static unsigned int clients_count = 0;
37 
38 static bool verbose_proctitle = FALSE;
39 
client_remote_id(struct client * client)40 static const char *client_remote_id(struct client *client)
41 {
42 	const char *addr;
43 
44 	addr = net_ip2addr(&client->remote_ip);
45 	if (addr[0] == '\0')
46 		addr = "local";
47 	return addr;
48 }
49 
refresh_proctitle(void)50 static void refresh_proctitle(void)
51 {
52 	struct client *client;
53 	string_t *title;
54 
55 	if (!verbose_proctitle)
56 		return;
57 
58 	title = t_str_new(128);
59 	str_append_c(title, '[');
60 	switch (clients_count) {
61 	case 0:
62 		str_append(title, "idling");
63 		break;
64 	case 1:
65 		client = clients;
66 		str_append(title, client_remote_id(client));
67 		str_append_c(title, ' ');
68 		str_append(title, smtp_server_state_names[client->state.state]);
69 		if (client->state.args != NULL && *client->state.args != '\0') {
70 			str_append_c(title, ' ');
71 			str_append(title, client->state.args);
72 		}
73 		break;
74 	default:
75 		str_printfa(title, "%u connections", clients_count);
76 		break;
77 	}
78 	str_append_c(title, ']');
79 	process_title_set(str_c(title));
80 }
81 
client_load_modules(struct client * client)82 static void client_load_modules(struct client *client)
83 {
84         struct module_dir_load_settings mod_set;
85 
86         i_zero(&mod_set);
87         mod_set.abi_version = DOVECOT_ABI_VERSION;
88         mod_set.require_init_funcs = TRUE;
89         mod_set.binary_name = "lmtp";
90 
91         /* pre-load all configured mail plugins */
92         mail_storage_service_modules =
93                 module_dir_load_missing(mail_storage_service_modules,
94                                         client->lmtp_set->mail_plugin_dir,
95                                         client->lmtp_set->mail_plugins,
96                                         &mod_set);
97 	module_dir_init(mail_storage_service_modules);
98 }
99 
client_raw_user_create(struct client * client)100 static void client_raw_user_create(struct client *client)
101 {
102 	void **sets;
103 
104 	sets = master_service_settings_get_others(master_service);
105 	client->raw_mail_user =
106 		raw_storage_create_from_set(client->user_set_info, sets[0]);
107 }
108 
client_read_settings(struct client * client,bool ssl)109 static void client_read_settings(struct client *client, bool ssl)
110 {
111 	struct mail_storage_service_input input;
112 	const struct setting_parser_context *set_parser;
113 	struct mail_user_settings *user_set;
114 	struct lmtp_settings *lmtp_set;
115 	struct lda_settings *lda_set;
116 	const char *error;
117 
118 	i_zero(&input);
119 	input.module = input.service = "lmtp";
120 	input.local_ip = client->local_ip;
121 	input.remote_ip = client->remote_ip;
122 	input.local_port = client->local_port;
123 	input.remote_port = client->remote_port;
124 	input.conn_secured = ssl;
125 	input.conn_ssl_secured = ssl;
126 	input.username = "";
127 
128 	if (mail_storage_service_read_settings(storage_service, &input,
129 					       client->pool,
130 					       &client->user_set_info,
131 					       &set_parser, &error) < 0)
132 		i_fatal("%s", error);
133 
134 	lmtp_settings_dup(set_parser, client->pool,
135 			  &user_set, &lmtp_set, &lda_set);
136 	const struct var_expand_table *tab =
137 		mail_storage_service_get_var_expand_table(storage_service, &input);
138 	if (settings_var_expand(&lmtp_setting_parser_info, lmtp_set,
139 				client->pool, tab, &error) <= 0)
140 		i_fatal("Failed to expand settings: %s", error);
141 	client->service_set = master_service_settings_get(master_service);
142 	client->user_set = user_set;
143 	client->lmtp_set = lmtp_set;
144 	client->unexpanded_lda_set = lda_set;
145 }
146 
client_create(int fd_in,int fd_out,const struct master_service_connection * conn)147 struct client *client_create(int fd_in, int fd_out,
148 			     const struct master_service_connection *conn)
149 {
150 	static const char *rcpt_param_extensions[] = {
151 		LMTP_RCPT_FORWARD_PARAMETER, NULL };
152 	static const struct smtp_capability_extra cap_rcpt_forward = {
153 		.name = LMTP_RCPT_FORWARD_CAPABILITY };
154 	enum lmtp_client_workarounds workarounds;
155 	struct smtp_server_settings lmtp_set;
156 	struct client *client;
157 	pool_t pool;
158 
159 	pool = pool_alloconly_create("lmtp client", 2048);
160 	client = p_new(pool, struct client, 1);
161 	client->pool = pool;
162 	client->v = lmtp_client_vfuncs;
163 	client->remote_ip = conn->remote_ip;
164 	client->remote_port = conn->remote_port;
165 	client->local_ip = conn->local_ip;
166 	client->local_port = conn->local_port;
167 	client->real_local_ip = conn->real_local_ip;
168 	client->real_local_port = conn->real_local_port;
169 	client->real_remote_ip = conn->real_remote_ip;
170 	client->real_remote_port = conn->real_remote_port;
171 	client->state_pool = pool_alloconly_create("client state", 4096);
172 
173 	client->event = event_create(NULL);
174 	event_add_category(client->event, &event_category_lmtp);
175 
176 	client_read_settings(client, conn->ssl);
177 	client_raw_user_create(client);
178 	client_load_modules(client);
179 	client->my_domain = client->unexpanded_lda_set->hostname;
180 
181 	if (client->service_set->verbose_proctitle)
182 		verbose_proctitle = TRUE;
183 
184 	p_array_init(&client->module_contexts, client->pool, 5);
185 
186 	i_zero(&lmtp_set);
187 	lmtp_set.capabilities =
188 		SMTP_CAPABILITY_PIPELINING |
189 		SMTP_CAPABILITY_ENHANCEDSTATUSCODES |
190 		SMTP_CAPABILITY_8BITMIME |
191 		SMTP_CAPABILITY_CHUNKING |
192 		SMTP_CAPABILITY_XCLIENT |
193 		SMTP_CAPABILITY__ORCPT;
194 	if (!conn->ssl && master_service_ssl_is_enabled(master_service))
195 		lmtp_set.capabilities |= SMTP_CAPABILITY_STARTTLS;
196 	lmtp_set.hostname = client->unexpanded_lda_set->hostname;
197 	lmtp_set.login_greeting = client->lmtp_set->login_greeting;
198 	lmtp_set.max_message_size = UOFF_T_MAX;
199 	lmtp_set.rcpt_param_extensions = rcpt_param_extensions;
200 	lmtp_set.rcpt_domain_optional = TRUE;
201 	lmtp_set.max_client_idle_time_msecs = CLIENT_IDLE_TIMEOUT_MSECS;
202 	lmtp_set.rawlog_dir = client->lmtp_set->lmtp_rawlog_dir;
203 	lmtp_set.event_parent = client->event;
204 
205 	workarounds = client->lmtp_set->parsed_workarounds;
206 	if ((workarounds & LMTP_WORKAROUND_WHITESPACE_BEFORE_PATH) != 0) {
207 		lmtp_set.workarounds |=
208 			SMTP_SERVER_WORKAROUND_WHITESPACE_BEFORE_PATH;
209 	}
210 	if ((workarounds & LMTP_WORKAROUND_MAILBOX_FOR_PATH) != 0) {
211 		lmtp_set.workarounds |=
212 			SMTP_SERVER_WORKAROUND_MAILBOX_FOR_PATH;
213 	}
214 
215 	client->conn = smtp_server_connection_create(
216 		lmtp_server, fd_in, fd_out,
217 		&conn->remote_ip, conn->remote_port, conn->ssl,
218 		&lmtp_set, &lmtp_callbacks, client);
219 	if (smtp_server_connection_is_trusted(client->conn)) {
220 		smtp_server_connection_add_extra_capability(
221 			client->conn, &cap_rcpt_forward);
222 	}
223 
224 	DLLIST_PREPEND(&clients, client);
225 	clients_count++;
226 
227 	e_info(client->event, "Connect from %s", client_remote_id(client));
228 
229 	if (hook_client_created != NULL)
230 		hook_client_created(&client);
231 
232 	smtp_server_connection_start(client->conn);
233 
234 	refresh_proctitle();
235 	return client;
236 }
237 
client_state_reset(struct client * client)238 void client_state_reset(struct client *client)
239 {
240 	i_free(client->state.args);
241 
242 	if (client->local != NULL)
243 		lmtp_local_deinit(&client->local);
244 	if (client->proxy != NULL)
245 		lmtp_proxy_deinit(&client->proxy);
246 
247 	o_stream_unref(&client->state.mail_data_output);
248 
249 	i_zero(&client->state);
250 	p_clear(client->state_pool);
251 }
252 
client_destroy(struct client ** _client,const char * enh_code,const char * reason)253 void client_destroy(struct client **_client, const char *enh_code,
254 		    const char *reason)
255 {
256 	struct client *client = *_client;
257 
258 	*_client = NULL;
259 
260 	smtp_server_connection_terminate(&client->conn,
261 		(enh_code == NULL ? "4.0.0" : enh_code), reason);
262 }
263 
264 static void
client_default_destroy(struct client * client)265 client_default_destroy(struct client *client)
266 {
267 	if (client->destroyed)
268 		return;
269 	client->destroyed = TRUE;
270 
271 	clients_count--;
272 	DLLIST_REMOVE(&clients, client);
273 
274 	if (client->raw_mail_user != NULL)
275 		mail_user_deinit(&client->raw_mail_user);
276 
277 	client_state_reset(client);
278 	event_unref(&client->event);
279 	pool_unref(&client->state_pool);
280 	pool_unref(&client->pool);
281 
282 	master_service_client_connection_destroyed(master_service);
283 }
284 
285 static void
client_connection_trans_start(void * context,struct smtp_server_transaction * trans)286 client_connection_trans_start(void *context,
287 			      struct smtp_server_transaction *trans)
288 {
289 	struct client *client = context;
290 
291 	client->v.trans_start(client, trans);
292 }
293 
294 static void
client_default_trans_start(struct client * client ATTR_UNUSED,struct smtp_server_transaction * trans ATTR_UNUSED)295 client_default_trans_start(struct client *client ATTR_UNUSED,
296 			   struct smtp_server_transaction *trans ATTR_UNUSED)
297 {
298 	/* nothing */
299 }
300 
301 static void
client_connection_trans_free(void * context,struct smtp_server_transaction * trans)302 client_connection_trans_free(void *context,
303 			     struct smtp_server_transaction *trans)
304 {
305 	struct client *client = (struct client *)context;
306 
307 	client->v.trans_free(client, trans);
308 }
309 
310 static void
client_default_trans_free(struct client * client,struct smtp_server_transaction * trans ATTR_UNUSED)311 client_default_trans_free(struct client *client,
312 			  struct smtp_server_transaction *trans ATTR_UNUSED)
313 {
314 	client_state_reset(client);
315 }
316 
317 static void
client_connection_state_changed(void * context,enum smtp_server_state new_state,const char * new_args)318 client_connection_state_changed(void *context,
319 				enum smtp_server_state new_state,
320 				const char *new_args)
321 {
322 	struct client *client = (struct client *)context;
323 
324 	i_free(client->state.args);
325 
326 	client->state.state = new_state;
327 	client->state.args = i_strdup(new_args);
328 
329 	if (clients_count == 1)
330 		refresh_proctitle();
331 }
332 
client_update_data_state(struct client * client,const char * new_args)333 void client_update_data_state(struct client *client, const char *new_args)
334 {
335 	i_assert(client->state.state == SMTP_SERVER_STATE_DATA);
336 	i_free(client->state.args);
337 	client->state.args = i_strdup(new_args);
338 
339 	if (clients_count == 1)
340 		refresh_proctitle();
341 }
342 
343 static void
client_connection_proxy_data_updated(void * context,const struct smtp_proxy_data * data)344 client_connection_proxy_data_updated(void *context,
345 				     const struct smtp_proxy_data *data)
346 {
347 	struct client *client = (struct client *)context;
348 
349 	client->remote_ip = data->source_ip;
350 	client->remote_port = data->source_port;
351 
352 	if (clients_count == 1)
353 		refresh_proctitle();
354 }
355 
client_connection_disconnect(void * context,const char * reason)356 static void client_connection_disconnect(void *context, const char *reason)
357 {
358 	struct client *client = (struct client *)context;
359 
360 	if (client->disconnected)
361 		return;
362 	client->disconnected = TRUE;
363 
364 	if (reason == NULL)
365 		reason = "Connection closed";
366 	e_info(client->event, "Disconnect from %s: %s",
367 	       client_remote_id(client), reason);
368 }
369 
client_connection_free(void * context)370 static void client_connection_free(void *context)
371 {
372 	struct client *client = (struct client *)context;
373 
374 	client->v.destroy(client);
375 }
376 
client_connection_is_trusted(void * context)377 static bool client_connection_is_trusted(void *context)
378 {
379 	struct client *client = (struct client *)context;
380 	const char *const *net;
381 	struct ip_addr net_ip;
382 	unsigned int bits;
383 
384 	if (client->lmtp_set->login_trusted_networks == NULL)
385 		return FALSE;
386 
387 	net = t_strsplit_spaces(client->lmtp_set->login_trusted_networks, ", ");
388 	for (; *net != NULL; net++) {
389 		if (net_parse_range(*net, &net_ip, &bits) < 0) {
390 			e_error(client->event, "login_trusted_networks: "
391 				"Invalid network '%s'", *net);
392 			break;
393 		}
394 
395 		if (net_is_in_network(&client->real_remote_ip, &net_ip, bits))
396 			return TRUE;
397 	}
398 	return FALSE;
399 }
400 
clients_destroy(void)401 void clients_destroy(void)
402 {
403 	while (clients != NULL) {
404 		struct client *client = clients;
405 		client_destroy(&client, "4.3.2", "Shutting down");
406 	}
407 }
408 
409 static const struct smtp_server_callbacks lmtp_callbacks = {
410 	.conn_cmd_mail = cmd_mail,
411 	.conn_cmd_rcpt = cmd_rcpt,
412 	.conn_cmd_data_begin = cmd_data_begin,
413 	.conn_cmd_data_continue = cmd_data_continue,
414 
415 	.conn_trans_start = client_connection_trans_start,
416 	.conn_trans_free = client_connection_trans_free,
417 
418 	.conn_state_changed = client_connection_state_changed,
419 
420 	.conn_proxy_data_updated = client_connection_proxy_data_updated,
421 
422 	.conn_disconnect = client_connection_disconnect,
423 	.conn_free = client_connection_free,
424 
425 	.conn_is_trusted = client_connection_is_trusted
426 };
427 
428 static const struct lmtp_client_vfuncs lmtp_client_vfuncs = {
429 	.destroy = client_default_destroy,
430 
431 	.trans_start = client_default_trans_start,
432 	.trans_free = client_default_trans_free,
433 
434 	.cmd_mail = client_default_cmd_mail,
435 	.cmd_rcpt = client_default_cmd_rcpt,
436 	.cmd_data = client_default_cmd_data,
437 
438 	.local_deliver = lmtp_local_default_deliver,
439 };
440