dovecot-2.2: Added a "session ID" string for imap/pop3 connectio...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 20 03:26:26 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/5bbcf636bbeb
changeset: 14302:5bbcf636bbeb
user: Timo Sirainen <tss at iki.fi>
date: Wed Mar 07 13:36:34 2012 +0200
description:
Added a "session ID" string for imap/pop3 connections, available in %{session} variable.
The session ID passes through Dovecot IMAP/POP3 proxying to backend server.
The same session ID is can be reused after a long time (currently a bit
under 9 years).
diffstat:
src/imap-login/client.c | 4 +++
src/imap-login/imap-proxy.c | 2 +
src/imap/imap-client.c | 6 ++++-
src/imap/imap-client.h | 4 ++-
src/imap/main.c | 4 ++-
src/lib-master/master-login.c | 16 +++++++++++++-
src/lib-master/master-login.h | 3 ++
src/lib-storage/mail-storage-service.c | 2 +
src/lib-storage/mail-storage-service.h | 1 +
src/login-common/client-common.c | 39 ++++++++++++++++++++++++++++++++++
src/login-common/client-common.h | 6 ++++-
src/login-common/sasl-server.c | 6 ++++-
src/pop3-login/client.c | 3 ++
src/pop3-login/pop3-proxy.c | 5 ++-
src/pop3/main.c | 4 ++-
src/pop3/pop3-client.c | 7 +++++-
src/pop3/pop3-client.h | 4 ++-
17 files changed, 105 insertions(+), 11 deletions(-)
diffs (truncated from 445 to 300 lines):
diff -r 49b832c5de0e -r 5bbcf636bbeb src/imap-login/client.c
--- a/src/imap-login/client.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/imap-login/client.c Wed Mar 07 13:36:34 2012 +0200
@@ -111,6 +111,10 @@
(void)net_addr2ip(value, &client->common.local_ip);
else if (strcasecmp(key, "x-connected-port") == 0)
client->common.local_port = atoi(value);
+ else if (strcasecmp(key, "x-session-id") == 0) {
+ client->common.session_id =
+ p_strdup(client->common.pool, value);
+ }
args += 2;
}
}
diff -r 49b832c5de0e -r 5bbcf636bbeb src/imap-login/imap-proxy.c
--- a/src/imap-login/imap-proxy.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/imap-login/imap-proxy.c Wed Mar 07 13:36:34 2012 +0200
@@ -30,10 +30,12 @@
static void proxy_write_id(struct imap_client *client, string_t *str)
{
str_printfa(str, "I ID ("
+ "\"x-session-id\" \"%s\" "
"\"x-originating-ip\" \"%s\" "
"\"x-originating-port\" \"%u\" "
"\"x-connected-ip\" \"%s\" "
"\"x-connected-port\" \"%u\")\r\n",
+ client_get_session_id(&client->common),
net_ip2addr(&client->common.ip),
client->common.remote_port,
net_ip2addr(&client->common.local_ip),
diff -r 49b832c5de0e -r 5bbcf636bbeb src/imap/imap-client.c
--- a/src/imap/imap-client.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/imap/imap-client.c Wed Mar 07 13:36:34 2012 +0200
@@ -32,7 +32,8 @@
client_destroy(client, "Disconnected for inactivity");
}
-struct client *client_create(int fd_in, int fd_out, struct mail_user *user,
+struct client *client_create(int fd_in, int fd_out, const char *session_id,
+ struct mail_user *user,
struct mail_storage_service_user *service_user,
const struct imap_settings *set)
{
@@ -49,6 +50,7 @@
client->pool = pool;
client->set = set;
client->service_user = service_user;
+ client->session_id = p_strdup(pool, session_id);
client->fd_in = fd_in;
client->fd_out = fd_out;
client->input = i_stream_create_fd(fd_in,
@@ -143,6 +145,7 @@
static struct var_expand_table static_tab[] = {
{ 'i', NULL, "input" },
{ 'o', NULL, "output" },
+ { '\0', NULL, "session" },
{ '\0', NULL, NULL }
};
struct var_expand_table *tab;
@@ -153,6 +156,7 @@
tab[0].value = dec2str(i_stream_get_absolute_offset(client->input));
tab[1].value = dec2str(client->output->offset);
+ tab[2].value = client->session_id;
str = t_str_new(128);
var_expand(str, client->set->imap_logout_format, tab);
diff -r 49b832c5de0e -r 5bbcf636bbeb src/imap/imap-client.h
--- a/src/imap/imap-client.h Wed Mar 07 13:32:40 2012 +0200
+++ b/src/imap/imap-client.h Wed Mar 07 13:36:34 2012 +0200
@@ -99,6 +99,7 @@
struct client {
struct client *prev, *next;
+ const char *session_id;
int fd_in, fd_out;
struct io *io;
struct istream *input;
@@ -170,7 +171,8 @@
/* Create new client with specified input/output handles. socket specifies
if the handle is a socket. */
-struct client *client_create(int fd_in, int fd_out, struct mail_user *user,
+struct client *client_create(int fd_in, int fd_out, const char *session_id,
+ struct mail_user *user,
struct mail_storage_service_user *service_user,
const struct imap_settings *set);
void client_destroy(struct client *client, const char *reason);
diff -r 49b832c5de0e -r 5bbcf636bbeb src/imap/main.c
--- a/src/imap/main.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/imap/main.c Wed Mar 07 13:36:34 2012 +0200
@@ -208,7 +208,8 @@
if (set->verbose_proctitle)
verbose_proctitle = TRUE;
- client = client_create(fd_in, fd_out, mail_user, user, set);
+ client = client_create(fd_in, fd_out, login_client->session_id,
+ mail_user, user, set);
T_BEGIN {
client_add_input(client, input_buf);
} T_END;
@@ -261,6 +262,7 @@
input.remote_ip = client->auth_req.remote_ip;
input.username = username;
input.userdb_fields = extra_fields;
+ input.session_id = client->session_id;
buffer_create_const_data(&input_buf, client->data,
client->auth_req.data_size);
diff -r 49b832c5de0e -r 5bbcf636bbeb src/lib-master/master-login.c
--- a/src/lib-master/master-login.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/lib-master/master-login.c Wed Mar 07 13:36:34 2012 +0200
@@ -392,6 +392,7 @@
struct master_login_client *client;
struct master_login *login = conn->login;
unsigned char data[MASTER_AUTH_MAX_DATA_SIZE];
+ unsigned int i, session_len = 0;
int ret, client_fd;
ret = master_login_conn_read_request(conn, &req, data, &client_fd);
@@ -408,12 +409,25 @@
}
fd_close_on_exec(client_fd, TRUE);
+ /* extract the session ID from the request data */
+ for (i = 0; i < req.data_size; i++) {
+ if (data[i] == '\0') {
+ session_len = i++;
+ break;
+ }
+ }
+ if (session_len >= sizeof(client->session_id)) {
+ i_error("login client: Session ID too long");
+ session_len = 0;
+ }
+
/* @UNSAFE: we have a request. do userdb lookup for it. */
client = i_malloc(sizeof(struct master_login_client) + req.data_size);
client->conn = conn;
client->fd = client_fd;
client->auth_req = req;
- memcpy(client->data, data, req.data_size);
+ memcpy(client->session_id, data, session_len);
+ memcpy(client->data, data+i, req.data_size-i);
conn->refcount++;
master_login_auth_request(login->auth, &req,
diff -r 49b832c5de0e -r 5bbcf636bbeb src/lib-master/master-login.h
--- a/src/lib-master/master-login.h Wed Mar 07 13:32:40 2012 +0200
+++ b/src/lib-master/master-login.h Wed Mar 07 13:36:34 2012 +0200
@@ -4,12 +4,15 @@
#include "master-auth.h"
#define MASTER_POSTLOGIN_TIMEOUT_DEFAULT 60
+/* base64(<IPv6><port><48bit timestamp>) + NUL */
+#define LOGIN_MAX_SESSION_ID_LEN 33
struct master_login_client {
struct master_login_connection *conn;
int fd;
struct master_auth_request auth_req;
+ char session_id[LOGIN_MAX_SESSION_ID_LEN];
unsigned char data[FLEXIBLE_ARRAY_MEMBER];
};
diff -r 49b832c5de0e -r 5bbcf636bbeb src/lib-storage/mail-storage-service.c
--- a/src/lib-storage/mail-storage-service.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/lib-storage/mail-storage-service.c Wed Mar 07 13:36:34 2012 +0200
@@ -374,6 +374,7 @@
{ 'p', NULL, "pid" },
{ 'i', NULL, "uid" },
{ '\0', NULL, "gid" },
+ { '\0', NULL, "session" },
{ '\0', NULL, NULL }
};
struct var_expand_table *tab;
@@ -391,6 +392,7 @@
tab[6].value = my_pid;
tab[7].value = dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
+ tab[9].value = input->session_id;
return tab;
}
diff -r 49b832c5de0e -r 5bbcf636bbeb src/lib-storage/mail-storage-service.h
--- a/src/lib-storage/mail-storage-service.h Wed Mar 07 13:32:40 2012 +0200
+++ b/src/lib-storage/mail-storage-service.h Wed Mar 07 13:36:34 2012 +0200
@@ -40,6 +40,7 @@
const char *module;
const char *service;
const char *username;
+ const char *session_id;
struct ip_addr local_ip, remote_ip;
unsigned int local_port, remote_port;
diff -r 49b832c5de0e -r 5bbcf636bbeb src/login-common/client-common.c
--- a/src/login-common/client-common.c Wed Mar 07 13:32:40 2012 +0200
+++ b/src/login-common/client-common.c Wed Mar 07 13:36:34 2012 +0200
@@ -7,7 +7,9 @@
#include "ostream.h"
#include "iostream-rawlog.h"
#include "process-title.h"
+#include "buffer.h"
#include "str.h"
+#include "base64.h"
#include "str-sanitize.h"
#include "safe-memset.h"
#include "var-expand.h"
@@ -376,6 +378,41 @@
return clients_count;
}
+const char *client_get_session_id(struct client *client)
+{
+ buffer_t *buf, *base64_buf;
+ struct timeval tv;
+ uint64_t timestamp;
+ unsigned int i;
+
+ if (client->session_id != NULL)
+ return client->session_id;
+
+ buf = buffer_create_dynamic(pool_datastack_create(), 24);
+ base64_buf = buffer_create_dynamic(pool_datastack_create(), 24*2);
+
+ if (gettimeofday(&tv, NULL) < 0)
+ i_fatal("gettimeofday(): %m");
+ timestamp = tv.tv_usec + (long long)tv.tv_sec * 1000ULL*1000ULL;
+
+ /* add lowest 48 bits of the timestamp. this gives us a bit less than
+ 9 years until it wraps */
+ for (i = 0; i < 48; i += 8)
+ buffer_append_c(buf, (timestamp >> i) & 0xff);
+
+ buffer_append_c(buf, client->remote_port & 0xff);
+ buffer_append_c(buf, (client->remote_port >> 16) & 0xff);
+#ifdef HAVE_IPV6
+ if (IPADDR_IS_V6(&client->ip))
+ buffer_append(buf, &client->ip.u.ip6, sizeof(client->ip.u.ip6));
+ else
+#endif
+ buffer_append(buf, &client->ip.u.ip4, sizeof(client->ip.u.ip4));
+ base64_encode(buf->data, buf->used, base64_buf);
+ client->session_id = p_strdup(client->pool, str_c(base64_buf));
+ return client->session_id;
+}
+
static struct var_expand_table login_var_expand_empty_tab[] = {
{ 'u', NULL, "user" },
{ 'n', NULL, "username" },
@@ -391,6 +428,7 @@
{ 'c', NULL, "secured" },
{ 'k', NULL, "ssl_security" },
{ 'e', NULL, "mail_pid" },
+ { '\0', NULL, "session" },
{ '\0', NULL, NULL }
};
@@ -439,6 +477,7 @@
}
tab[13].value = client->mail_pid == 0 ? "" :
dec2str(client->mail_pid);
+ tab[14].value = client_get_session_id(client);
return tab;
}
diff -r 49b832c5de0e -r 5bbcf636bbeb src/login-common/client-common.h
--- a/src/login-common/client-common.h Wed Mar 07 13:32:40 2012 +0200
+++ b/src/login-common/client-common.h Wed Mar 07 13:36:34 2012 +0200
@@ -4,6 +4,7 @@
#include "network.h"
#include "login-proxy.h"
#include "sasl-server.h"
+#include "master-login.h" /* for LOGIN_MAX_SESSION_ID_LEN */
#define LOGIN_MAX_MASTER_PREFIX_LEN 128
@@ -14,7 +15,8 @@
POP3: Max. length of a command line (spec says 512 would be enough)
*/
#define LOGIN_MAX_INBUF_SIZE \
- (MASTER_AUTH_MAX_DATA_SIZE - LOGIN_MAX_MASTER_PREFIX_LEN)
+ (MASTER_AUTH_MAX_DATA_SIZE - LOGIN_MAX_MASTER_PREFIX_LEN - \
+ LOGIN_MAX_SESSION_ID_LEN)
/* max. size of output buffer. if it gets full, the client is disconnected.
SASL authentication gives the largest output. */
#define LOGIN_MAX_OUTBUF_SIZE 4096
@@ -89,6 +91,7 @@
unsigned int local_port, remote_port;
struct ssl_proxy *ssl_proxy;
const struct login_settings *set;
+ const char *session_id;
int fd;
struct istream *input;
@@ -163,6 +166,7 @@
const char *client_get_extra_disconnect_reason(struct client *client);
bool client_is_trusted(struct client *client);
void client_auth_failed(struct client *client);
More information about the dovecot-cvs
mailing list