dovecot-2.2: imap-hibernate: Use sockets' st_dev and st_ino to v...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 31 20:48:03 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/55cab04ef2af
changeset: 19052:55cab04ef2af
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 31 23:46:05 2015 +0300
description:
imap-hibernate: Use sockets' st_dev and st_ino to verify that the passed fd is correct.
diffstat:
src/imap-hibernate/imap-client.c | 16 ++++-----
src/imap-hibernate/imap-client.h | 4 +-
src/imap-hibernate/imap-hibernate-client.c | 21 ++++++++---
src/imap/imap-client-hibernate.c | 13 ++++---
src/imap/imap-master-client.c | 51 ++++++++++++++++++-----------
5 files changed, 62 insertions(+), 43 deletions(-)
diffs (235 lines):
diff -r 9dd0f155731c -r 55cab04ef2af src/imap-hibernate/imap-client.c
--- a/src/imap-hibernate/imap-client.c Mon Aug 31 23:25:12 2015 +0300
+++ b/src/imap-hibernate/imap-client.c Mon Aug 31 23:46:05 2015 +0300
@@ -117,10 +117,12 @@
str_append(str, "\tuserdb_fields=");
str_append_tabescaped(str, state->userdb_fields);
}
- if (state->peer_ip.family != 0)
- str_printfa(str, "\tpeer_ip=%s", net_ip2addr(&state->peer_ip));
- if (state->peer_port != 0)
- str_printfa(str, "\tpeer_port=%u", state->peer_port);
+ if (major(state->peer_dev) != 0 || minor(state->peer_dev) != 0) {
+ str_printfa(str, "\tpeer_dev_major=%u\tpeer_dev_minor=%u",
+ major(state->peer_dev), minor(state->peer_dev));
+ }
+ if (state->peer_ino != 0)
+ str_printfa(str, "\tpeer_ino=%llu", (unsigned long long)state->peer_ino);
if (state->state_size > 0) {
str_append(str, "\tstate=");
base64_encode(state->state, state->state_size, str);
@@ -411,15 +413,11 @@
client->fd = fd;
client->input = i_stream_create_fd(fd, IMAP_MAX_INBUF, FALSE);
+ client->state = *state;
client->state.username = p_strdup(pool, state->username);
client->state.session_id = p_strdup(pool, state->session_id);
client->state.userdb_fields = p_strdup(pool, state->userdb_fields);
client->state.stats = p_strdup(pool, state->stats);
- client->state.local_ip = state->local_ip;
- client->state.remote_ip = state->remote_ip;
- client->state.imap_idle_notify_interval =
- state->imap_idle_notify_interval;
- client->state.idle_cmd = state->idle_cmd;
if (state->state_size > 0) {
client->state.state = statebuf = p_malloc(pool, state->state_size);
diff -r 9dd0f155731c -r 55cab04ef2af src/imap-hibernate/imap-client.h
--- a/src/imap-hibernate/imap-client.h Mon Aug 31 23:25:12 2015 +0300
+++ b/src/imap-hibernate/imap-client.h Mon Aug 31 23:46:05 2015 +0300
@@ -13,8 +13,8 @@
uid_t uid;
gid_t gid;
- struct ip_addr peer_ip;
- in_port_t peer_port;
+ dev_t peer_dev;
+ ino_t peer_ino;
const unsigned char *state;
size_t state_size;
diff -r 9dd0f155731c -r 55cab04ef2af src/imap-hibernate/imap-hibernate-client.c
--- a/src/imap-hibernate/imap-hibernate-client.c Mon Aug 31 23:25:12 2015 +0300
+++ b/src/imap-hibernate/imap-hibernate-client.c Mon Aug 31 23:46:05 2015 +0300
@@ -44,6 +44,7 @@
const char **error_r)
{
const char *key, *value;
+ unsigned int peer_dev_major = 0, peer_dev_minor = 0;
memset(state_r, 0, sizeof(*state_r));
if (args[0] == NULL) {
@@ -77,16 +78,22 @@
"Invalid rip value: %s", value);
return -1;
}
- } else if (strcmp(key, "peer_ip") == 0) {
- if (net_addr2ip(value, &state_r->peer_ip) < 0) {
+ } else if (strcmp(key, "peer_dev_major") == 0) {
+ if (str_to_uint(value, &peer_dev_major) < 0) {
*error_r = t_strdup_printf(
- "Invalid peer_ip value: %s", value);
+ "Invalid peer_dev_major value: %s", value);
return -1;
}
- } else if (strcmp(key, "peer_port") == 0) {
- if (net_str2port(value, &state_r->peer_port) < 0) {
+ } else if (strcmp(key, "peer_dev_minor") == 0) {
+ if (str_to_uint(value, &peer_dev_minor) < 0) {
*error_r = t_strdup_printf(
- "Invalid peer_port value: %s", value);
+ "Invalid peer_dev_minor value: %s", value);
+ return -1;
+ }
+ } else if (strcmp(key, "peer_ino") == 0) {
+ if (str_to_ino(value, &state_r->peer_ino) < 0) {
+ *error_r = t_strdup_printf(
+ "Invalid peer_ino value: %s", value);
return -1;
}
} else if (strcmp(key, "uid") == 0) {
@@ -131,6 +138,8 @@
state_r->state_size = state_buf->used;
}
}
+ if (peer_dev_major != 0 || peer_dev_minor != 0)
+ state_r->peer_dev = makedev(peer_dev_major, peer_dev_minor);
return 0;
}
diff -r 9dd0f155731c -r 55cab04ef2af src/imap/imap-client-hibernate.c
--- a/src/imap/imap-client-hibernate.c Mon Aug 31 23:25:12 2015 +0300
+++ b/src/imap/imap-client-hibernate.c Mon Aug 31 23:46:05 2015 +0300
@@ -13,6 +13,8 @@
#include "imap-state.h"
#include "imap-client.h"
+#include <sys/stat.h>
+
#define IMAP_HIBERNATE_SOCKET_NAME "imap-hibernate"
#define IMAP_HIBERNATE_SEND_TIMEOUT_SECS 10
#define IMAP_HIBERNATE_HANDSHAKE "VERSION\timap-hibernate\t1\t0\n"
@@ -41,18 +43,17 @@
static void imap_hibernate_write_cmd(struct client *client, string_t *cmd,
const buffer_t *state, int fd_notify)
{
- struct ip_addr peer_ip;
- in_port_t peer_port;
+ struct stat peer_st;
str_append_tabescaped(cmd, client->user->username);
str_append_c(cmd, '\t');
str_append_tabescaped(cmd, client->user->set->mail_log_prefix);
str_printfa(cmd, "\tidle_notify_interval=%u",
client->set->imap_idle_notify_interval);
- if (net_getpeername(client->fd_in, &peer_ip, &peer_port) == 0 &&
- peer_port != 0) {
- str_printfa(cmd, "\tpeer_ip=%s\tpeer_port=%u",
- net_ip2addr(&peer_ip), peer_port);
+ if (fstat(client->fd_in, &peer_st) == 0) {
+ str_printfa(cmd, "\tpeer_dev_major=%u\tpeer_dev_minor=%u\tpeer_ino=%llu",
+ major(peer_st.st_dev), minor(peer_st.st_dev),
+ (unsigned long long)peer_st.st_ino);
}
if (client->session_id != NULL) {
diff -r 9dd0f155731c -r 55cab04ef2af src/imap/imap-master-client.c
--- a/src/imap/imap-master-client.c Mon Aug 31 23:25:12 2015 +0300
+++ b/src/imap/imap-master-client.c Mon Aug 31 23:46:05 2015 +0300
@@ -27,8 +27,8 @@
/* IMAP connection state */
buffer_t *state;
- struct ip_addr peer_ip;
- in_port_t peer_port;
+ dev_t peer_dev;
+ ino_t peer_ino;
bool state_import_bad_idle_done;
bool state_import_idle_continue;
@@ -53,6 +53,7 @@
const char **error_r)
{
const char *key, *value;
+ unsigned int peer_dev_major = 0, peer_dev_minor = 0;
memset(input_r, 0, sizeof(*input_r));
memset(master_input_r, 0, sizeof(*master_input_r));
@@ -91,16 +92,22 @@
"Invalid rip value: %s", value);
return -1;
}
- } else if (strcmp(key, "peer_ip") == 0) {
- if (net_addr2ip(value, &master_input_r->peer_ip) < 0) {
+ } else if (strcmp(key, "peer_dev_major") == 0) {
+ if (str_to_uint(value, &peer_dev_major) < 0) {
*error_r = t_strdup_printf(
- "Invalid peer_ip value: %s", value);
+ "Invalid peer_dev_major value: %s", value);
return -1;
}
- } else if (strcmp(key, "peer_port") == 0) {
- if (net_str2port(value, &master_input_r->peer_port) < 0) {
+ } else if (strcmp(key, "peer_dev_minor") == 0) {
+ if (str_to_uint(value, &peer_dev_minor) < 0) {
*error_r = t_strdup_printf(
- "Invalid peer_port value: %s", value);
+ "Invalid peer_dev_minor value: %s", value);
+ return -1;
+ }
+ } else if (strcmp(key, "peer_ino") == 0) {
+ if (str_to_ino(value, &master_input_r->peer_ino) < 0) {
+ *error_r = t_strdup_printf(
+ "Invalid peer_ino value: %s", value);
return -1;
}
} else if (strcmp(key, "session") == 0) {
@@ -135,31 +142,35 @@
master_input_r->state_import_idle_continue = TRUE;
}
}
+ if (peer_dev_major != 0 || peer_dev_minor != 0) {
+ master_input_r->peer_dev =
+ makedev(peer_dev_major, peer_dev_minor);
+ }
return 0;
}
static int imap_master_client_verify(const struct imap_master_input *master_input,
int fd_client, const char **error_r)
{
- struct ip_addr peer_ip;
- in_port_t peer_port;
+ struct stat peer_st;
- if (master_input->peer_port == 0)
+ if (master_input->peer_ino == 0)
return 0;
/* make sure we have the right fd */
- if (net_getpeername(fd_client, &peer_ip, &peer_port) < 0) {
- *error_r = t_strdup_printf("net_getpeername() failed: %m");
+ if (fstat(fd_client, &peer_st) < 0) {
+ *error_r = t_strdup_printf("fstat(peer) failed: %m");
return -1;
}
- if (!net_ip_compare(&peer_ip, &master_input->peer_ip) ||
- peer_port != master_input->peer_port) {
+ if (peer_st.st_ino != master_input->peer_ino ||
+ !CMP_DEV_T(peer_st.st_dev, master_input->peer_dev)) {
*error_r = t_strdup_printf(
- "BUG: Expected peer_ip=%s peer_port=%u doesn't match "
- "client fd's actual ip=%s port=%u",
- net_ip2addr(&master_input->peer_ip),
- master_input->peer_port,
- net_ip2addr(&peer_ip), peer_port);
+ "BUG: Expected peer device=%u,%u inode=%s doesn't match "
+ "client fd's actual device=%u,%u inode=%s",
+ major(peer_st.st_dev), minor(peer_st.st_dev), dec2str(peer_st.st_ino),
+ major(master_input->peer_dev),
+ minor(master_input->peer_dev),
+ dec2str(master_input->peer_ino));
return -1;
}
return 0;
More information about the dovecot-cvs
mailing list