Mercurial > dovecot > core-2.2
changeset 10256:ba3574ed9f74 HEAD
lmtp: Add Received: header, with a session ID. Log the session ID also.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 05 Nov 2009 17:27:46 -0500 |
parents | b2925a5d9cf7 |
children | 597f969a9870 |
files | src/lib-lda/mail-deliver.c src/lib-lda/mail-deliver.h src/lmtp/client.c src/lmtp/client.h src/lmtp/commands.c |
diffstat | 5 files changed, 105 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-lda/mail-deliver.c Thu Nov 05 17:03:47 2009 -0500 +++ b/src/lib-lda/mail-deliver.c Thu Nov 05 17:27:46 2009 -0500 @@ -66,6 +66,8 @@ msg = t_strdup_vprintf(fmt, args); str = t_str_new(256); + if (ctx->session_id != NULL) + str_printfa(str, "%s: ", ctx->session_id); var_expand(str, ctx->set->deliver_log_format, get_log_var_expand_table(ctx, msg)); i_info("%s", str_c(str));
--- a/src/lib-lda/mail-deliver.h Thu Nov 05 17:03:47 2009 -0500 +++ b/src/lib-lda/mail-deliver.h Thu Nov 05 17:27:46 2009 -0500 @@ -10,6 +10,8 @@ struct duplicate_context *dup_ctx; + /* Session ID, used as log line prefix if non-NULL. */ + const char *session_id; /* Mail to save */ struct mail *src_mail; /* Envelope sender, if known. */
--- a/src/lmtp/client.c Thu Nov 05 17:03:47 2009 -0500 +++ b/src/lmtp/client.c Thu Nov 05 17:27:46 2009 -0500 @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "base64.h" #include "str.h" #include "llist.h" #include "istream.h" @@ -165,6 +166,18 @@ client->lmtp_set = sets[2]; } +static void client_generate_session_id(struct client *client) +{ + uint8_t guid[MAIL_GUID_128_SIZE]; + string_t *id = t_str_new(30); + + mail_generate_guid_128(guid); + base64_encode(guid, sizeof(guid), id); + i_assert(str_c(id)[str_len(id)-2] == '='); + str_truncate(id, str_len(id)-2); /* drop trailing "==" */ + client->state.session_id = p_strdup(client->state_pool, str_c(id)); +} + struct client *client_create(int fd_in, int fd_out, const struct master_service_connection *conn) { @@ -196,6 +209,7 @@ client->state.mail_data_fd = -1; client_read_settings(client); client_raw_user_create(client); + client_generate_session_id(client); DLLIST_PREPEND(&clients, client); clients_count++; @@ -288,6 +302,8 @@ memset(&client->state, 0, sizeof(client->state)); p_clear(client->state_pool); client->state.mail_data_fd = -1; + + client_generate_session_id(client); } void client_send_line(struct client *client, const char *fmt, ...)
--- a/src/lmtp/client.h Thu Nov 05 17:03:47 2009 -0500 +++ b/src/lmtp/client.h Thu Nov 05 17:27:46 2009 -0500 @@ -11,6 +11,8 @@ }; struct client_state { + const char *lhlo; + const char *session_id; const char *mail_from; ARRAY_DEFINE(rcpt_to, struct mail_recipient); unsigned int rcpt_idx; @@ -22,6 +24,7 @@ buffer_t *mail_data; int mail_data_fd; struct ostream *mail_data_output; + const char *received_line; struct mailbox *raw_box; struct mailbox_transaction_context *raw_trans;
--- a/src/lmtp/commands.c Thu Nov 05 17:03:47 2009 -0500 +++ b/src/lmtp/commands.c Thu Nov 05 17:27:46 2009 -0500 @@ -6,10 +6,13 @@ #include "str.h" #include "strescape.h" #include "istream.h" +#include "istream-concat.h" #include "ostream.h" #include "istream-dot.h" #include "safe-mkstemp.h" #include "master-service.h" +#include "rfc822-parser.h" +#include "message-date.h" #include "auth-master.h" #include "mail-storage-service.h" #include "index/raw/raw-storage.h" @@ -28,13 +31,43 @@ #define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30) -int cmd_lhlo(struct client *client, const char *args ATTR_UNUSED) +int cmd_lhlo(struct client *client, const char *args) { + struct rfc822_parser_context parser; + string_t *domain = t_str_new(128); + const char *p; + int ret; + + if (*args == '\0') { + client_send_line(client, "501 Missing hostname"); + return 0; + } + + /* domain / address-literal */ + rfc822_parser_init(&parser, (const unsigned char *)args, strlen(args), + NULL); + if (*args != '[') + ret = rfc822_parse_dot_atom(&parser, domain); + else { + for (p = args+1; *p != ']'; p++) { + if (*p == '\\' || *p == '[') + break; + } + if (strcmp(p, "]") != 0) + ret = -1; + } + if (ret < 0) { + str_truncate(domain, 0); + str_append(domain, "invalid"); + } + client_state_reset(client); client_send_line(client, "250-%s", client->my_domain); client_send_line(client, "250-8BITMIME"); client_send_line(client, "250-ENHANCEDSTATUSCODES"); client_send_line(client, "250 PIPELINING"); + + client->state.lhlo = p_strdup(client->state_pool, str_c(domain)); return 0; } @@ -382,6 +415,7 @@ memset(&dctx, 0, sizeof(dctx)); dctx.pool = pool_alloconly_create("mail delivery", 1024); dctx.set = sets[1]; + dctx.session_id = client->state.session_id; dctx.src_mail = src_mail; dctx.src_envelope_sender = client->state.mail_from; dctx.dest_user = client->state.dest_user; @@ -395,7 +429,8 @@ i_assert(client->state.first_saved_mail == NULL); client->state.first_saved_mail = dctx.dest_mail; } - client_send_line(client, "250 2.0.0 <%s> Saved", rcpt->name); + client_send_line(client, "250 2.0.0 <%s> %s Saved", + rcpt->name, client->state.session_id); ret = 0; } else if (storage == NULL) { /* This shouldn't happen */ @@ -452,18 +487,29 @@ static struct istream *client_get_input(struct client *client) { - struct istream *input; + struct client_state *state = &client->state; + struct istream *cinput, *inputs[3]; + + inputs[0] = i_stream_create_from_data(state->received_line, + strlen(state->received_line)); - if (client->state.mail_data_output != NULL) { - o_stream_unref(&client->state.mail_data_output); - input = i_stream_create_fd(client->state.mail_data_fd, - MAIL_READ_FULL_BLOCK_SIZE, FALSE); - i_stream_set_init_buffer_size(input, MAIL_READ_FULL_BLOCK_SIZE); + if (state->mail_data_output != NULL) { + o_stream_unref(&state->mail_data_output); + inputs[1] = i_stream_create_fd(state->mail_data_fd, + MAIL_READ_FULL_BLOCK_SIZE, + FALSE); + i_stream_set_init_buffer_size(inputs[1], + MAIL_READ_FULL_BLOCK_SIZE); } else { - input = i_stream_create_from_data(client->state.mail_data->data, - client->state.mail_data->used); + inputs[1] = i_stream_create_from_data(state->mail_data->data, + state->mail_data->used); } - return input; + inputs[2] = NULL; + + cinput = i_stream_create_concat(inputs); + i_stream_unref(&inputs[0]); + i_stream_unref(&inputs[1]); + return cinput; } static int client_open_raw_mail(struct client *client, struct istream *input) @@ -557,6 +603,28 @@ client_input_data_finish(client); } +static const char *client_get_received_line(struct client *client) +{ + string_t *str = t_str_new(200); + const char *host; + + str_printfa(str, "Received: from %s", client->state.lhlo); + if ((host = net_ip2addr(&client->remote_ip)) != NULL) + str_printfa(str, " ([%s])", host); + str_printfa(str, "\r\n\tby %s ("PACKAGE_NAME") with LMTP id %s", + client->my_domain, client->state.session_id); + + str_append(str, "\r\n\t"); + if (array_count(&client->state.rcpt_to) == 1) { + const struct mail_recipient *rcpt = + array_idx(&client->state.rcpt_to, 0); + + str_printfa(str, "for <%s>", rcpt->name); + } + str_printfa(str, "; %s\r\n", message_date_create(ioloop_time)); + return str_c(str); +} + static bool client_input_data_write(struct client *client) { struct istream *input; @@ -564,6 +632,9 @@ i_stream_destroy(&client->dot_input); + client->state.received_line = + p_strdup(client->state_pool, client_get_received_line(client)); + input = client_get_input(client); client_input_data_write_local(client, input); if (client->proxy != NULL) {