From: Timo Sirainen Date: Sun, 4 Apr 2010 21:18:41 +0000 (+0300) Subject: dsync: Verify that msg-get and msg-copy reply has the correct UID. X-Git-Tag: 2.0.beta5~243 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5072d572aefaefc1714bae26f48362ed2e41fa91;p=thirdparty%2Fdovecot%2Fcore.git dsync: Verify that msg-get and msg-copy reply has the correct UID. --HG-- branch : HEAD --- diff --git a/src/dsync/dsync-proxy-client.c b/src/dsync/dsync-proxy-client.c index 249748d642..591981392c 100644 --- a/src/dsync/dsync-proxy-client.c +++ b/src/dsync/dsync-proxy-client.c @@ -27,6 +27,7 @@ enum proxy_client_request_type { struct proxy_client_request { enum proxy_client_request_type type; + uint32_t uid; union { dsync_worker_msg_callback_t *get; dsync_worker_copy_callback_t *copy; @@ -137,10 +138,31 @@ proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker) } static bool -proxy_client_worker_next_copy(const struct proxy_client_request *request, +proxy_client_worker_next_copy(struct proxy_client_dsync_worker *worker, + const struct proxy_client_request *request, const char *line) { - request->callback.copy(*line == '1', request->context); + uint32_t uid; + bool success; + + if (line[0] == '1' && line[1] == '\t') + success = TRUE; + else if (line[0] == '0' && line[1] == '\t') + success = FALSE; + else { + i_error("msg-copy returned invalid input: %s", line); + proxy_client_fail(worker); + return FALSE; + } + uid = strtoul(line + 2, NULL, 10); + if (uid != request->uid) { + i_error("msg-copy returned invalid uid: %u != %u", + uid, request->uid); + proxy_client_fail(worker); + return FALSE; + } + + request->callback.copy(success, request->context); return TRUE; } @@ -167,6 +189,13 @@ proxy_client_worker_next_msg_get(struct proxy_client_dsync_worker *worker, uid = strtoul(t_strcut(line, '\t'), NULL, 10); line = p + 1; + if (uid != request->uid) { + i_error("msg-get returned invalid uid: %u != %u", + uid, request->uid); + proxy_client_fail(worker); + return FALSE; + } + if (dsync_proxy_msg_static_import(worker->msg_get_pool, line, &worker->msg_get_data, &error) < 0) { @@ -230,7 +259,7 @@ proxy_client_worker_next_reply(struct proxy_client_dsync_worker *worker, switch (request.type) { case PROXY_CLIENT_REQUEST_TYPE_COPY: - ret = proxy_client_worker_next_copy(&request, line); + ret = proxy_client_worker_next_copy(worker, &request, line); break; case PROXY_CLIENT_REQUEST_TYPE_GET: ret = proxy_client_worker_next_msg_get(worker, &request, line); @@ -847,6 +876,7 @@ proxy_client_worker_msg_copy(struct dsync_worker *_worker, request.type = PROXY_CLIENT_REQUEST_TYPE_COPY; request.callback.copy = callback; request.context = context; + request.uid = src_uid; aqueue_append(worker->request_queue, &request); } @@ -960,6 +990,7 @@ proxy_client_worker_msg_get(struct dsync_worker *_worker, request.type = PROXY_CLIENT_REQUEST_TYPE_GET; request.callback.get = callback; request.context = context; + request.uid = uid; aqueue_append(worker->request_queue, &request); } diff --git a/src/dsync/dsync-proxy-server-cmd.c b/src/dsync/dsync-proxy-server-cmd.c index 88755e5f0b..7df73e56c8 100644 --- a/src/dsync/dsync-proxy-server-cmd.c +++ b/src/dsync/dsync-proxy-server-cmd.c @@ -364,8 +364,12 @@ cmd_msg_expunge(struct dsync_proxy_server *server, const char *const *args) static void copy_callback(bool success, void *context) { struct dsync_proxy_server *server = context; + const char *reply; + + i_assert(server->copy_uid != 0); - o_stream_send(server->output, success ? "1\n" : "0\n", 2); + reply = t_strdup_printf("%d\t%u\n", success ? 1 : 0, server->copy_uid); + o_stream_send_str(server->output, reply); } static int @@ -390,8 +394,10 @@ cmd_msg_copy(struct dsync_proxy_server *server, const char *const *args) args + 2, &msg, &error) < 0) i_error("Invalid message input: %s", error); + server->copy_uid = src_uid; dsync_worker_msg_copy(server->worker, &src_mailbox_guid, src_uid, &msg, copy_callback, server); + server->copy_uid = 0; return 1; } @@ -459,6 +465,8 @@ cmd_msg_get_callback(enum dsync_msg_get_result result, struct dsync_proxy_server *server = context; string_t *str; + i_assert(server->get_uid != 0); + switch (result) { case DSYNC_MSG_GET_RESULT_SUCCESS: break; @@ -507,7 +515,10 @@ cmd_msg_get(struct dsync_proxy_server *server, const char *const *args) dsync_worker_msg_get(server->worker, &mailbox_guid, uid, cmd_msg_get_callback, server); } - return server->get_input == NULL ? 1 : 0; + if (server->get_input != NULL) + return 0; + server->get_uid = 0; + return 1; } static void cmd_finish_callback(bool success, void *context) diff --git a/src/dsync/dsync-proxy-server.h b/src/dsync/dsync-proxy-server.h index 727ca33532..44a48b00f6 100644 --- a/src/dsync/dsync-proxy-server.h +++ b/src/dsync/dsync-proxy-server.h @@ -28,7 +28,7 @@ struct dsync_proxy_server { struct istream *get_input; bool get_input_last_lf; - uint32_t get_uid; + uint32_t get_uid, copy_uid; unsigned int handshake_received:1; unsigned int subs_sending_unsubscriptions:1; diff --git a/src/dsync/dsync-worker-local.c b/src/dsync/dsync-worker-local.c index f120b58eec..3a51b7da6c 100644 --- a/src/dsync/dsync-worker-local.c +++ b/src/dsync/dsync-worker-local.c @@ -485,7 +485,6 @@ local_worker_mailbox_iter_next(struct dsync_worker_mailbox_iter *_iter, if (info == NULL) return iter_next_deleted(iter, worker, dsync_box_r); - storage_name = mail_namespace_get_storage_name(info->ns, info->name); dsync_box_r->name = info->name; dsync_box_r->name_sep = info->ns->sep;