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