dovecot-2.0-sslstream: lmtp: Add Received: header, with a sessio...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 02:56:01 EET 2010
details: http://hg.dovecot.org/dovecot-2.0-sslstream/rev/ba3574ed9f74
changeset: 10257:ba3574ed9f74
user: Timo Sirainen <tss at iki.fi>
date: Thu Nov 05 17:27:46 2009 -0500
description:
lmtp: Add Received: header, with a session ID. Log the session ID also.
diffstat:
5 files changed, 108 insertions(+), 14 deletions(-)
src/lib-lda/mail-deliver.c | 2
src/lib-lda/mail-deliver.h | 2
src/lmtp/client.c | 16 +++++++
src/lmtp/client.h | 3 +
src/lmtp/commands.c | 99 +++++++++++++++++++++++++++++++++++++-------
diffs (251 lines):
diff -r b2925a5d9cf7 -r ba3574ed9f74 src/lib-lda/mail-deliver.c
--- 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 @@ void mail_deliver_log(struct mail_delive
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));
diff -r b2925a5d9cf7 -r ba3574ed9f74 src/lib-lda/mail-deliver.h
--- 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 mail_deliver_context {
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. */
diff -r b2925a5d9cf7 -r ba3574ed9f74 src/lmtp/client.c
--- 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 @@ static void client_read_settings(struct
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 @@ struct client *client_create(int fd_in,
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 @@ void client_state_reset(struct client *c
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, ...)
diff -r b2925a5d9cf7 -r ba3574ed9f74 src/lmtp/client.h
--- 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 mail_recipient {
};
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 @@ struct client_state {
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;
diff -r b2925a5d9cf7 -r ba3574ed9f74 src/lmtp/commands.c
--- 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 @@ client_deliver(struct client *client, co
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 @@ client_deliver(struct client *client, co
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 void client_rcpt_fail_all(struct
static struct istream *client_get_input(struct client *client)
{
- struct istream *input;
-
- 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);
+ 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 (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);
- }
- return input;
+ inputs[1] = i_stream_create_from_data(state->mail_data->data,
+ state->mail_data->used);
+ }
+ 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,12 +603,37 @@ static void client_proxy_finish(void *co
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;
bool ret = TRUE;
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);
More information about the dovecot-cvs
mailing list