From dovecot at dovecot.org Mon Jul 2 05:14:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 05:14:36 +0300 Subject: dovecot-2.2: lib-storage: Fixed STATUS_FIRST_UNSEEN_SEQ lookup w... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c0ff628352d5 changeset: 14703:c0ff628352d5 user: Timo Sirainen date: Mon Jul 02 05:14:02 2012 +0300 description: lib-storage: Fixed STATUS_FIRST_UNSEEN_SEQ lookup with private flags index. diffstat: src/lib-storage/index/index-status.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 3d3689c2c81d -r c0ff628352d5 src/lib-storage/index/index-status.c --- a/src/lib-storage/index/index-status.c Sat Jun 30 22:27:34 2012 +0300 +++ b/src/lib-storage/index/index-status.c Mon Jul 02 05:14:02 2012 +0300 @@ -87,8 +87,14 @@ } if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) { - mail_index_lookup_first(box->view, 0, MAIL_SEEN, - &status_r->first_unseen_seq); + if (hdr_pvt == NULL || + (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { + mail_index_lookup_first(box->view, 0, MAIL_SEEN, + &status_r->first_unseen_seq); + } else { + mail_index_lookup_first(box->view_pvt, 0, MAIL_SEEN, + &status_r->first_unseen_seq); + } } if ((items & STATUS_LAST_CACHED_SEQ) != 0) get_last_cached_seq(box, &status_r->last_cached_seq); From dovecot at dovecot.org Mon Jul 2 05:14:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 05:14:36 +0300 Subject: dovecot-2.2: lib-storage: Fixed searching message flags with pri... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/04c89bb18bdd changeset: 14704:04c89bb18bdd user: Timo Sirainen date: Mon Jul 02 05:14:22 2012 +0300 description: lib-storage: Fixed searching message flags with private flags index. diffstat: src/lib-storage/index/index-search-private.h | 2 + src/lib-storage/index/index-search.c | 57 +++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 10 deletions(-) diffs (129 lines): diff -r c0ff628352d5 -r 04c89bb18bdd src/lib-storage/index/index-search-private.h --- a/src/lib-storage/index/index-search-private.h Mon Jul 02 05:14:02 2012 +0300 +++ b/src/lib-storage/index/index-search-private.h Mon Jul 02 05:14:22 2012 +0300 @@ -10,6 +10,8 @@ struct mail_index_view *view; struct mailbox *box; + uint32_t pvt_uid, pvt_seq; + enum mail_fetch_field extra_wanted_fields; struct mailbox_header_lookup_ctx *extra_wanted_headers; diff -r c0ff628352d5 -r 04c89bb18bdd src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Mon Jul 02 05:14:02 2012 +0300 +++ b/src/lib-storage/index/index-search.c Mon Jul 02 05:14:22 2012 +0300 @@ -148,12 +148,29 @@ return 1; } +static bool +index_search_get_pvt(struct index_search_context *ctx, uint32_t uid) +{ + if (ctx->pvt_uid == uid) + return ctx->pvt_seq != 0; + ctx->pvt_uid = uid; + ctx->pvt_seq = uid; + + if (ctx->box->view_pvt == NULL) { + /* no private view (set by view syncing) -> no private flags */ + return FALSE; + } + + return mail_index_lookup_seq(ctx->mail_ctx.transaction->view_pvt, + uid, &ctx->pvt_seq); +} + /* Returns >0 = matched, 0 = not matched, -1 = unknown */ static int search_arg_match_index(struct index_search_context *ctx, struct mail_search_arg *arg, const struct mail_index_record *rec) { - enum mail_flags flags; + enum mail_flags flags, pvt_flags_mask; uint64_t modseq; int ret; @@ -168,6 +185,13 @@ if ((arg->value.flags & MAIL_RECENT) != 0 && index_mailbox_is_recent(ctx->box, rec->uid)) flags |= MAIL_RECENT; + if (index_search_get_pvt(ctx, rec->uid)) { + pvt_flags_mask = mailbox_get_private_flags_mask(ctx->box); + flags &= ~pvt_flags_mask; + rec = mail_index_lookup(ctx->mail_ctx.transaction->view_pvt, + ctx->pvt_seq); + flags |= rec->flags & pvt_flags_mask; + } return (flags & arg->value.flags) == arg->value.flags; case SEARCH_KEYWORDS: T_BEGIN { @@ -870,9 +894,21 @@ struct mail_search_arg *args, uint32_t *seq1, uint32_t *seq2) { - const struct mail_index_header *hdr; + const struct mail_index_header *hdr_seen, *hdr_del, *hdr_pvt; + enum mail_flags pvt_flags_mask; - hdr = mail_index_get_header(ctx->view); + hdr_seen = hdr_del = mail_index_get_header(ctx->view); + + if (ctx->box->view_pvt != NULL) { + pvt_flags_mask = mailbox_get_private_flags_mask(ctx->box); + index_transaction_init_pvt(ctx->mail_ctx.transaction); + hdr_pvt = mail_index_get_header(ctx->mail_ctx.transaction->view_pvt); + if ((pvt_flags_mask & MAIL_SEEN) != 0) + hdr_seen = hdr_pvt; + if ((pvt_flags_mask & MAIL_DELETED) != 0) + hdr_del = hdr_pvt; + } + for (; args != NULL; args = args->next) { if (args->type != SEARCH_FLAGS) { if (args->type == SEARCH_ALL) { @@ -883,10 +919,11 @@ } if ((args->value.flags & MAIL_SEEN) != 0) { /* SEEN with 0 seen? */ - if (!args->match_not && hdr->seen_messages_count == 0) + if (!args->match_not && hdr_seen->seen_messages_count == 0) return FALSE; - if (hdr->seen_messages_count == hdr->messages_count) { + if (hdr_seen->seen_messages_count == + hdr_seen->messages_count) { /* UNSEEN with all seen? */ if (args->match_not) return FALSE; @@ -896,17 +933,17 @@ } else if (args->match_not) { /* UNSEEN with lowwater limiting */ search_limit_lowwater(ctx, - hdr->first_unseen_uid_lowwater, seq1); + hdr_seen->first_unseen_uid_lowwater, seq1); } } if ((args->value.flags & MAIL_DELETED) != 0) { /* DELETED with 0 deleted? */ if (!args->match_not && - hdr->deleted_messages_count == 0) + hdr_del->deleted_messages_count == 0) return FALSE; - if (hdr->deleted_messages_count == - hdr->messages_count) { + if (hdr_del->deleted_messages_count == + hdr_del->messages_count) { /* UNDELETED with all deleted? */ if (args->match_not) return FALSE; @@ -916,7 +953,7 @@ } else if (!args->match_not) { /* DELETED with lowwater limiting */ search_limit_lowwater(ctx, - hdr->first_deleted_uid_lowwater, seq1); + hdr_del->first_deleted_uid_lowwater, seq1); } } } From dovecot at dovecot.org Mon Jul 2 08:06:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 08:06:27 +0300 Subject: dovecot-2.1: config: Fixed IPv6 address handling for parsing v1.... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/e009aaf19934 changeset: 14585:e009aaf19934 user: Timo Sirainen date: Mon Jul 02 08:06:19 2012 +0300 description: config: Fixed IPv6 address handling for parsing v1.x style listen/ssl_listen settings. diffstat: src/config/old-set-parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 6b08977c4b75 -r e009aaf19934 src/config/old-set-parser.c --- a/src/config/old-set-parser.c Fri Jun 29 08:05:08 2012 +0300 +++ b/src/config/old-set-parser.c Mon Jul 02 08:06:19 2012 +0300 @@ -305,7 +305,7 @@ return TRUE; } p = strrchr(value, ':'); - if (p != NULL) { + if (p != NULL && listen_has_port(value)) { obsolete(ctx, "%s=..:port has been replaced by service { inet_listener { port } }", key); value = t_strdup_until(value, p++); if (config_filter_match(&old_section->filter, &imap_filter)) { From dovecot at dovecot.org Mon Jul 2 08:09:14 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 08:09:14 +0300 Subject: dovecot-2.0: config: Fixed IPv6 address handling for parsing v1.... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/ac6fec6057e6 changeset: 13104:ac6fec6057e6 user: Timo Sirainen date: Mon Jul 02 08:06:19 2012 +0300 description: config: Fixed IPv6 address handling for parsing v1.x style listen/ssl_listen settings. diffstat: src/config/old-set-parser.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2440e656ed9f -r ac6fec6057e6 src/config/old-set-parser.c --- a/src/config/old-set-parser.c Sun Jun 24 01:03:52 2012 +0300 +++ b/src/config/old-set-parser.c Mon Jul 02 08:06:19 2012 +0300 @@ -299,7 +299,7 @@ return TRUE; } p = strrchr(value, ':'); - if (p != NULL) { + if (p != NULL && listen_has_port(value)) { obsolete(ctx, "%s=..:port has been replaced by service { inet_listener { port } }", key); value = t_strdup_until(value, p++); if (config_filter_match(&old_section->filter, &imap_filter)) { From dovecot at dovecot.org Mon Jul 2 10:05:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 10:05:58 +0300 Subject: dovecot-2.1: lmtp proxy: Reset timeout each time receiving a rep... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/27dccff46fe9 changeset: 14586:27dccff46fe9 user: Timo Sirainen date: Mon Jul 02 10:05:46 2012 +0300 description: lmtp proxy: Reset timeout each time receiving a reply lin for DATA. This avoids timing out when there are a lot of RCPT TOs. diffstat: src/lmtp/lmtp-proxy.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r e009aaf19934 -r 27dccff46fe9 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Mon Jul 02 08:06:19 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jul 02 10:05:46 2012 +0300 @@ -229,6 +229,9 @@ i_assert(!rcpt->rcpt_to_failed); i_assert(rcpt->reply != NULL); + /* reset timeout in case there are a lot of RCPT TOs */ + timeout_reset(conn->to); + rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; From dovecot at dovecot.org Mon Jul 2 10:09:21 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 10:09:21 +0300 Subject: dovecot-2.1: lmtp: Don't idle-timeout LMTP client while proxying... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8a97daa8aff6 changeset: 14587:8a97daa8aff6 user: Timo Sirainen date: Mon Jul 02 10:09:15 2012 +0300 description: lmtp: Don't idle-timeout LMTP client while proxying waits for DATA replies. diffstat: src/lmtp/commands.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diffs (13 lines): diff -r 27dccff46fe9 -r 8a97daa8aff6 src/lmtp/commands.c --- a/src/lmtp/commands.c Mon Jul 02 10:05:46 2012 +0300 +++ b/src/lmtp/commands.c Mon Jul 02 10:09:15 2012 +0300 @@ -771,6 +771,9 @@ struct istream *input; bool ret = TRUE; + /* stop handling client input until saving/proxying is finished */ + if (client->to_idle != NULL) + timeout_remove(&client->to_idle); io_remove(&client->io); i_stream_destroy(&client->dot_input); From dovecot at dovecot.org Mon Jul 2 10:13:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 10:13:10 +0300 Subject: dovecot-2.1: lmtp: Fixed previous change to make sure it doesn't... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/569588ff7ef0 changeset: 14588:569588ff7ef0 user: Timo Sirainen date: Mon Jul 02 10:12:59 2012 +0300 description: lmtp: Fixed previous change to make sure it doesn't crash on error handling. diffstat: src/lmtp/lmtp-proxy.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 8a97daa8aff6 -r 569588ff7ef0 src/lmtp/lmtp-proxy.c --- a/src/lmtp/lmtp-proxy.c Mon Jul 02 10:09:15 2012 +0300 +++ b/src/lmtp/lmtp-proxy.c Mon Jul 02 10:12:59 2012 +0300 @@ -230,7 +230,8 @@ i_assert(rcpt->reply != NULL); /* reset timeout in case there are a lot of RCPT TOs */ - timeout_reset(conn->to); + if (conn->to != NULL) + timeout_reset(conn->to); rcpt->reply = p_strdup(conn->proxy->pool, reply); rcpt->data_reply_received = TRUE; From dovecot at dovecot.org Mon Jul 2 14:54:47 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 02 Jul 2012 14:54:47 +0300 Subject: dovecot-2.1: imap: Mailbox names in STATUS replies were sent as ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a698fccd37c3 changeset: 14589:a698fccd37c3 user: Timo Sirainen date: Mon Jul 02 14:54:33 2012 +0300 description: imap: Mailbox names in STATUS replies were sent as UTF-8 instead of mUTF-7. diffstat: src/imap/cmd-list.c | 10 ++++++---- src/imap/cmd-status.c | 5 +++-- src/imap/imap-status.c | 4 ++-- src/imap/imap-status.h | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diffs (96 lines): diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/cmd-list.c Mon Jul 02 14:54:33 2012 +0300 @@ -364,8 +364,9 @@ client_send_line(ctx->cmd->client, str_c(str)); } -static void list_send_status(struct cmd_list_context *ctx, const char *name, - enum mailbox_info_flags flags) +static void +list_send_status(struct cmd_list_context *ctx, const char *name, + const char *mutf7_name, enum mailbox_info_flags flags) { struct imap_status_result result; struct mail_namespace *ns; @@ -391,7 +392,8 @@ return; } - imap_status_send(ctx->cmd->client, name, &ctx->status_items, &result); + imap_status_send(ctx->cmd->client, mutf7_name, + &ctx->status_items, &result); } static bool list_has_empty_prefix_ns(struct mail_user *user) @@ -481,7 +483,7 @@ ret = client_send_line(ctx->cmd->client, str_c(str)); if (ctx->used_status) T_BEGIN { - list_send_status(ctx, name, flags); + list_send_status(ctx, name, str_c(mutf7_name), flags); } T_END; if (ret == 0) { /* buffer is full, continue later */ diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/cmd-status.c --- a/src/imap/cmd-status.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/cmd-status.c Mon Jul 02 14:54:33 2012 +0300 @@ -13,7 +13,7 @@ struct imap_status_items items; struct imap_status_result result; struct mail_namespace *ns; - const char *mailbox, *error; + const char *mailbox, *orig_mailbox, *error; bool selected_mailbox; /* */ @@ -30,6 +30,7 @@ if (imap_status_parse_items(cmd, list_args, &items) < 0) return TRUE; + orig_mailbox = mailbox; ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) return TRUE; @@ -42,7 +43,7 @@ return TRUE; } - imap_status_send(client, mailbox, &items, &result); + imap_status_send(client, orig_mailbox, &items, &result); if (!selected_mailbox) client_send_tagline(cmd, "OK Status completed."); else { diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/imap-status.c --- a/src/imap/imap-status.c Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/imap-status.c Mon Jul 02 14:54:33 2012 +0300 @@ -96,7 +96,7 @@ return ret; } -void imap_status_send(struct client *client, const char *mailbox, +void imap_status_send(struct client *client, const char *mailbox_mutf7, const struct imap_status_items *items, const struct imap_status_result *result) { @@ -106,7 +106,7 @@ str = t_str_new(128); str_append(str, "* STATUS "); - imap_quote_append_string(str, mailbox, FALSE); + imap_quote_append_string(str, mailbox_mutf7, FALSE); str_append(str, " ("); prefix_len = str_len(str); diff -r 569588ff7ef0 -r a698fccd37c3 src/imap/imap-status.h --- a/src/imap/imap-status.h Mon Jul 02 10:12:59 2012 +0300 +++ b/src/imap/imap-status.h Mon Jul 02 14:54:33 2012 +0300 @@ -18,7 +18,7 @@ struct mail_namespace *ns, const char *mailbox, const struct imap_status_items *items, struct imap_status_result *result_r, const char **error_r); -void imap_status_send(struct client *client, const char *mailbox, +void imap_status_send(struct client *client, const char *mailbox_mutf7, const struct imap_status_items *items, const struct imap_status_result *result); From dovecot at dovecot.org Tue Jul 3 01:06:30 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 01:06:30 +0300 Subject: dovecot-2.1: imap-acl: MYRIGHTS command used UTF-8 instead of mU... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/880af3c78df9 changeset: 14590:880af3c78df9 user: Timo Sirainen date: Tue Jul 03 01:06:10 2012 +0300 description: imap-acl: MYRIGHTS command used UTF-8 instead of mUTF-7 encoding for mailbox name. diffstat: src/plugins/imap-acl/imap-acl-plugin.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (27 lines): diff -r a698fccd37c3 -r 880af3c78df9 src/plugins/imap-acl/imap-acl-plugin.c --- a/src/plugins/imap-acl/imap-acl-plugin.c Mon Jul 02 14:54:33 2012 +0300 +++ b/src/plugins/imap-acl/imap-acl-plugin.c Tue Jul 03 01:06:10 2012 +0300 @@ -309,12 +309,13 @@ { struct mail_namespace *ns; struct mailbox *box; - const char *mailbox; + const char *mailbox, *orig_mailbox; const char *const *rights; string_t *str; if (!client_read_string_args(cmd, 1, &mailbox)) return FALSE; + orig_mailbox = mailbox; if (ACL_USER_CONTEXT(cmd->client->user) == NULL) { client_send_command_error(cmd, "ACLs disabled."); @@ -346,7 +347,7 @@ str = t_str_new(128); str_append(str, "* MYRIGHTS "); - imap_quote_append_string(str, mailbox, FALSE); + imap_quote_append_string(str, orig_mailbox, FALSE); str_append_c(str,' '); imap_acl_write_rights_list(str, rights); From dovecot at dovecot.org Tue Jul 3 01:06:30 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 01:06:30 +0300 Subject: dovecot-2.1: imap-quota: GETQUOTAROOT command used UTF-8 instead... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/90270c054e1f changeset: 14591:90270c054e1f user: Timo Sirainen date: Tue Jul 03 01:06:24 2012 +0300 description: imap-quota: GETQUOTAROOT command used UTF-8 instead of mUTF-7 encoding for mailbox name. diffstat: src/plugins/imap-quota/imap-quota-plugin.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (27 lines): diff -r 880af3c78df9 -r 90270c054e1f src/plugins/imap-quota/imap-quota-plugin.c --- a/src/plugins/imap-quota/imap-quota-plugin.c Tue Jul 03 01:06:10 2012 +0300 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Tue Jul 03 01:06:24 2012 +0300 @@ -74,12 +74,13 @@ struct mailbox *box; struct quota_root_iter *iter; struct quota_root *root; - const char *mailbox, *name; + const char *mailbox, *orig_mailbox, *name; string_t *quotaroot_reply, *quota_reply; /* */ if (!client_read_string_args(cmd, 1, &mailbox)) return FALSE; + orig_mailbox = mailbox; ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) @@ -101,7 +102,7 @@ quotaroot_reply = t_str_new(128); quota_reply = t_str_new(256); str_append(quotaroot_reply, "* QUOTAROOT "); - imap_quote_append_string(quotaroot_reply, mailbox, FALSE); + imap_quote_append_string(quotaroot_reply, orig_mailbox, FALSE); iter = quota_root_iter_init(box); while ((root = quota_root_iter_next(iter)) != NULL) { From dovecot at dovecot.org Tue Jul 3 01:56:34 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 01:56:34 +0300 Subject: dovecot-2.1: layout=fs, mail_shared_explicit_inbox=no: Fixed lis... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a6d59207d9d6 changeset: 14592:a6d59207d9d6 user: Timo Sirainen date: Tue Jul 03 01:52:00 2012 +0300 description: layout=fs, mail_shared_explicit_inbox=no: Fixed listing nonexistent mailboxes in root. diffstat: src/lib-storage/list/mailbox-list-fs-iter.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-) diffs (26 lines): diff -r 90270c054e1f -r a6d59207d9d6 src/lib-storage/list/mailbox-list-fs-iter.c --- a/src/lib-storage/list/mailbox-list-fs-iter.c Tue Jul 03 01:06:24 2012 +0300 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Tue Jul 03 01:52:00 2012 +0300 @@ -404,10 +404,18 @@ we just want to see its contents (not the INBOX's children). */ root = ""; - } else if (*prefix_vname == '\0') { - /* we need to handle "" explicitly here, because getting - storage name with mail_shared_explicit_inbox=no - would return root=INBOX. */ + } else if ((ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0 && + ns->type == NAMESPACE_SHARED && + !ctx->ctx.list->mail_set->mail_shared_explicit_inbox && + (prefix_vname[0] == '\0' || + (strncmp(ns->prefix, prefix_vname, ns->prefix_len-1) == 0 && + prefix_vname[ns->prefix_len-1] == '\0'))) { + /* we need to handle ns prefix explicitly here, because + getting storage name with + mail_shared_explicit_inbox=no would return + root=INBOX. (e.g. LIST "" shared/user/box has to + return the box when it doesn't exist but + shared/user/box/child exists) */ root = ""; } else { root = mailbox_list_get_storage_name(ctx->ctx.list, From dovecot at dovecot.org Tue Jul 3 03:01:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 03:01:40 +0300 Subject: dovecot-2.1: doveadm server: Keep config socket open while running. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/668173038ada changeset: 14593:668173038ada user: Timo Sirainen date: Tue Jul 03 02:59:53 2012 +0300 description: doveadm server: Keep config socket open while running. diffstat: src/doveadm/main.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (17 lines): diff -r a6d59207d9d6 -r 668173038ada src/doveadm/main.c --- a/src/doveadm/main.c Tue Jul 03 01:52:00 2012 +0300 +++ b/src/doveadm/main.c Tue Jul 03 02:59:53 2012 +0300 @@ -68,9 +68,12 @@ &doveadm_setting_parser_info, NULL }; + enum master_service_flags service_flags = + MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN; const char *error; - master_service = master_service_init("doveadm", 0, &argc, &argv, NULL); + master_service = master_service_init("doveadm", service_flags, + &argc, &argv, NULL); if (master_getopt(master_service) > 0) return FATAL_DEFAULT; From dovecot at dovecot.org Tue Jul 3 03:28:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 03:28:10 +0300 Subject: dovecot-2.1: lib-sql db cache: Reaching max_unused_connections c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/955e741ef46a changeset: 14594:955e741ef46a user: Timo Sirainen date: Tue Jul 03 03:27:52 2012 +0300 description: lib-sql db cache: Reaching max_unused_connections caused a crash later. diffstat: src/lib-sql/sql-db-cache.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 668173038ada -r 955e741ef46a src/lib-sql/sql-db-cache.c --- a/src/lib-sql/sql-db-cache.c Tue Jul 03 02:59:53 2012 +0300 +++ b/src/lib-sql/sql-db-cache.c Tue Jul 03 03:27:52 2012 +0300 @@ -75,6 +75,7 @@ db = cache->unused_tail; ctx = SQL_DB_CACHE_CONTEXT(db); sql_db_cache_unlink(ctx); + hash_table_remove(cache->dbs, ctx->key); i_free(ctx->key); ctx->orig_deinit(db); From dovecot at dovecot.org Tue Jul 3 04:23:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 04:23:39 +0300 Subject: dovecot-2.1: lmtp: Added lmtp_address_translate setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f1509d8eb2c1 changeset: 14595:f1509d8eb2c1 user: Timo Sirainen date: Tue Jul 03 04:23:03 2012 +0300 description: lmtp: Added lmtp_address_translate setting. The idea is that if you need userdb lookup to be done with a special kind of a username like user:domain at extrainfo, you can set lmtp_address_translate=%n:%d@ which translates the address to user at domain after the userdb lookup is done. diffstat: src/lmtp/commands.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lmtp/lmtp-settings.c | 4 ++- src/lmtp/lmtp-settings.h | 1 + 3 files changed, 69 insertions(+), 1 deletions(-) diffs (114 lines): diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/commands.c --- a/src/lmtp/commands.c Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/commands.c Tue Jul 03 04:23:03 2012 +0300 @@ -380,6 +380,69 @@ } } +static void lmtp_address_translate(struct client *client, const char **address) +{ + const char *transpos = client->lmtp_set->lmtp_address_translate; + const char *p, *nextstr, *addrpos = *address; + unsigned int len; + string_t *username, *domain, *dest = NULL; + + if (*transpos == '\0') + return; + + username = t_str_new(64); + domain = t_str_new(64); + + /* check that string matches up to the first '%' */ + p = strchr(transpos, '%'); + if (p == NULL) + len = strlen(transpos); + else + len = p-transpos; + if (strncmp(transpos, addrpos, len) != 0) + return; + transpos += len; + addrpos += len; + + while (*transpos != '\0') { + switch (transpos[1]) { + case 'n': + case 'u': + dest = username; + break; + case 'd': + dest = domain; + break; + default: + return; + } + transpos += 2; + + /* find where the next string starts */ + if (*transpos == '\0') { + str_append(dest, addrpos); + break; + } + p = strchr(transpos, '%'); + if (p == NULL) + nextstr = transpos; + else + nextstr = t_strdup_until(transpos, p); + p = strstr(addrpos, nextstr); + if (p == NULL) + return; + str_append_n(dest, addrpos, p-addrpos); + + len = strlen(nextstr); + transpos += len; + addrpos = p + len; + } + str_append_c(username, '@'); + if (domain != NULL) + str_append_str(username, domain); + *address = str_c(username); +} + int cmd_rcpt(struct client *client, const char *args) { struct mail_recipient rcpt; @@ -449,6 +512,8 @@ return 0; } + lmtp_address_translate(client, &address); + rcpt.address = p_strdup(client->state_pool, address); rcpt.detail = p_strdup(client->state_pool, detail); array_append(&client->state.rcpt_to, &rcpt, 1); diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/lmtp-settings.c --- a/src/lmtp/lmtp-settings.c Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/lmtp-settings.c Tue Jul 03 04:23:03 2012 +0300 @@ -60,6 +60,7 @@ DEF(SET_BOOL, lmtp_proxy), DEF(SET_BOOL, lmtp_save_to_detail_mailbox), DEF(SET_STR_VARS, login_greeting), + DEF(SET_STR, lmtp_address_translate), SETTING_DEFINE_LIST_END }; @@ -67,7 +68,8 @@ static const struct lmtp_settings lmtp_default_settings = { .lmtp_proxy = FALSE, .lmtp_save_to_detail_mailbox = FALSE, - .login_greeting = PACKAGE_NAME" ready." + .login_greeting = PACKAGE_NAME" ready.", + .lmtp_address_translate = "" }; static const struct setting_parser_info *lmtp_setting_dependencies[] = { diff -r 955e741ef46a -r f1509d8eb2c1 src/lmtp/lmtp-settings.h --- a/src/lmtp/lmtp-settings.h Tue Jul 03 03:27:52 2012 +0300 +++ b/src/lmtp/lmtp-settings.h Tue Jul 03 04:23:03 2012 +0300 @@ -8,6 +8,7 @@ bool lmtp_proxy; bool lmtp_save_to_detail_mailbox; const char *login_greeting; + const char *lmtp_address_translate; }; extern const struct setting_parser_info lmtp_setting_parser_info; From dovecot at dovecot.org Tue Jul 3 05:22:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 05:22:10 +0300 Subject: dovecot-2.1: Released v2.1.8. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7e5f36fd989d changeset: 14596:7e5f36fd989d user: Timo Sirainen date: Tue Jul 03 05:15:04 2012 +0300 description: Released v2.1.8. diffstat: NEWS | 15 +++++++++++++++ configure.in | 2 +- 2 files changed, 16 insertions(+), 1 deletions(-) diffs (32 lines): diff -r f1509d8eb2c1 -r 7e5f36fd989d NEWS --- a/NEWS Tue Jul 03 04:23:03 2012 +0300 +++ b/NEWS Tue Jul 03 05:15:04 2012 +0300 @@ -1,3 +1,18 @@ +v2.1.8 2012-07-03 Timo Sirainen + + + pop3c: Added pop3c_master_user setting. + - imap: Mailbox names were accidentally sent as UTF-8 instead of mUTF-7 + in previous v2.1.x releases for STATUS, MYRIGHTS and GETQUOTAROOT + commands. + - lmtp proxy: Don't timeout connections too early when mail has a lot + of RCPT TOs. + - director: Don't crash if the director is working alone. + - shared mailboxes: Avoid doing "@domain" userdb lookups. + - doveadm: Fixed crash with proxying some commands. + - fts-squat: Fixed handling multiple SEARCH parameters. + - imapc: Fixed a crash when message had more than 8 keywords. + - imapc: Don't crash on APPEND/COPY if server doesn't support UIDPLUS. + v2.1.7 2012-05-29 Timo Sirainen * LDAP: Compatibility fix for v2.0: ldap: If attributes contain diff -r f1509d8eb2c1 -r 7e5f36fd989d configure.in --- a/configure.in Tue Jul 03 04:23:03 2012 +0300 +++ b/configure.in Tue Jul 03 05:15:04 2012 +0300 @@ -1,5 +1,5 @@ AC_PREREQ([2.59]) -AC_INIT([Dovecot],[2.1.7],[dovecot at dovecot.org]) +AC_INIT([Dovecot],[2.1.8],[dovecot at dovecot.org]) AC_CONFIG_SRCDIR([src]) AM_INIT_AUTOMAKE([foreign]) From dovecot at dovecot.org Tue Jul 3 05:22:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 05:22:10 +0300 Subject: dovecot-2.1: Added tag 2.1.8 for changeset 7e5f36fd989d Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/7e0c247ef1e4 changeset: 14597:7e0c247ef1e4 user: Timo Sirainen date: Tue Jul 03 05:15:04 2012 +0300 description: Added tag 2.1.8 for changeset 7e5f36fd989d diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7e5f36fd989d -r 7e0c247ef1e4 .hgtags --- a/.hgtags Tue Jul 03 05:15:04 2012 +0300 +++ b/.hgtags Tue Jul 03 05:15:04 2012 +0300 @@ -84,3 +84,4 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 2.1.5 7c249e2a82a9cd33ae15ead6443c3499e16da623 2.1.6 c92fb8b928f69ca01681a2c2976304b7e4bc3afc 2.1.7 +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 2.1.8 From dovecot at dovecot.org Tue Jul 3 05:22:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 03 Jul 2012 05:22:10 +0300 Subject: dovecot-2.1: Added signature for changeset 7e5f36fd989d Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c1a97e799b43 changeset: 14598:c1a97e799b43 user: Timo Sirainen date: Tue Jul 03 05:15:14 2012 +0300 description: Added signature for changeset 7e5f36fd989d diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 7e0c247ef1e4 -r c1a97e799b43 .hgsigs --- a/.hgsigs Tue Jul 03 05:15:04 2012 +0300 +++ b/.hgsigs Tue Jul 03 05:15:14 2012 +0300 @@ -47,3 +47,4 @@ 469cee314d9c54d2d7101ec9e38579fdc9610eaf 0 iEYEABECAAYFAk+VWqkACgkQyUhSUUBVislnXACfVjPqMmPUvYtXQXwqff0h7N76mZUAn02lPeUCyuyr1TF9e1hGM/sKgmko 7c249e2a82a9cd33ae15ead6443c3499e16da623 0 iEYEABECAAYFAk+nX2sACgkQyUhSUUBVisn7uwCbBD3boxBOGEJ8OYsIJ57n5Cr09FAAoIvhxL6EHRB15AMOw4sPaALJ3/bB c92fb8b928f69ca01681a2c2976304b7e4bc3afc 0 iEYEABECAAYFAk/FIeIACgkQyUhSUUBVisk4IgCfUiXVXntqzPjJcALYRpqw4Zc7a/0An3HKWwgb6PBCbmvxBfTezNkqjqVK +7e5f36fd989d27a2fb48250adbab8fa54ddb6083 0 iEYEABECAAYFAk/yVakACgkQyUhSUUBVismekwCfSEVQjd6fwdChjd53LSt03b4UWKoAoIxd/IjLatTISlHm44iiQwzRKByo From dovecot at dovecot.org Wed Jul 4 10:58:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 04 Jul 2012 10:58:52 +0300 Subject: dovecot-2.1: auth: Added CACHE-FLUSH command to flush some/all u... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/007bf0047ab0 changeset: 14599:007bf0047ab0 user: Timo Sirainen date: Wed Jul 04 10:56:53 2012 +0300 description: auth: Added CACHE-FLUSH command to flush some/all users from auth cache. diffstat: src/auth/auth-cache.c | 228 +++++++++++++++++++++++++++---------- src/auth/auth-cache.h | 6 +- src/auth/auth-master-connection.c | 27 ++++ src/auth/auth-request.h | 4 + src/auth/auth.c | 9 + src/auth/test-auth-cache.c | 18 ++- 6 files changed, 226 insertions(+), 66 deletions(-) diffs (truncated from 491 to 300 lines): diff -r c1a97e799b43 -r 007bf0047ab0 src/auth/auth-cache.c --- a/src/auth/auth-cache.c Tue Jul 03 05:15:14 2012 +0300 +++ b/src/auth/auth-cache.c Wed Jul 04 10:56:53 2012 +0300 @@ -23,36 +23,72 @@ unsigned long long pos_size, neg_size; }; -static const struct var_expand_table * -auth_request_var_expand_tab_find(const char *key, unsigned int size) +static bool +auth_request_var_expand_tab_find(const char *key, unsigned int size, + unsigned int *idx_r) { const struct var_expand_table *tab = auth_request_var_expand_static_tab; unsigned int i; for (i = 0; tab[i].key != '\0' || tab[i].long_key != NULL; i++) { if (size == 1) { - if (key[0] == tab[i].key) - return &tab[i]; + if (key[0] == tab[i].key) { + *idx_r = i; + return TRUE; + } } else if (tab[i].long_key != NULL) { if (strncmp(key, tab[i].long_key, size) == 0 && - tab[i].long_key[size] == '\0') - return &tab[i]; + tab[i].long_key[size] == '\0') { + *idx_r = i; + return TRUE; + } } } - return NULL; + return FALSE; +} + +static void +auth_cache_key_add_var(string_t *str, const char *data, unsigned int len) +{ + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (len == 1) + str_append_c(str, data[0]); + else { + str_append_c(str, '{'); + str_append_n(str, data, len); + str_append_c(str, '}'); + } +} + +static void auth_cache_key_add_tab_idx(string_t *str, unsigned int i) +{ + const struct var_expand_table *tab = + &auth_request_var_expand_static_tab[i]; + + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append_c(str, '%'); + if (tab->key != '\0') + str_append_c(str, tab->key); + else { + str_append_c(str, '{'); + str_append(str, tab->long_key); + str_append_c(str, '}'); + } } char *auth_cache_parse_key(pool_t pool, const char *query) { - const struct var_expand_table *tab; string_t *str; - bool key_seen[100]; - unsigned int idx, size, tab_idx; - bool add_key; + bool key_seen[AUTH_REQUEST_VAR_TAB_COUNT]; + const char *extra_vars; + unsigned int i, idx, size, tab_idx; memset(key_seen, 0, sizeof(key_seen)); - str = str_new(pool, 32); + str = t_str_new(32); for (; *query != '\0'; ) { if (*query != '%') { query++; @@ -66,34 +102,45 @@ } query += idx; - tab = auth_request_var_expand_tab_find(query, size); - if (tab == NULL) { + if (!auth_request_var_expand_tab_find(query, size, &tab_idx)) { /* just add the key. it would be nice to prevent duplicates here as well, but that's just too much trouble and probably very rare. */ - add_key = TRUE; + auth_cache_key_add_var(str, query, size); } else { - tab_idx = tab - auth_request_var_expand_static_tab; i_assert(tab_idx < N_ELEMENTS(key_seen)); - /* @UNSAFE */ - add_key = !key_seen[tab_idx]; key_seen[tab_idx] = TRUE; } - if (add_key) { - if (str_len(str) != 0) - str_append_c(str, '\t'); - str_append_c(str, '%'); - if (size == 1) - str_append_c(str, query[0]); - else { - str_append_c(str, '{'); - str_append_n(str, query, size); - str_append_c(str, '}'); - } - } query += size; } - return str_free_without_data(&str); + + if (key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] && + key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX]) { + /* %n and %d both used -> replace with %u */ + key_seen[AUTH_REQUEST_VAR_TAB_USER_IDX] = TRUE; + key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] = FALSE; + key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX] = FALSE; + } + + /* we rely on these being at the beginning */ + i_assert(AUTH_REQUEST_VAR_TAB_USER_IDX == 0); + i_assert(AUTH_REQUEST_VAR_TAB_USERNAME_IDX == 1); + i_assert(AUTH_REQUEST_VAR_TAB_DOMAIN_IDX == 2); + + extra_vars = t_strdup(str_c(str)); + str_truncate(str, 0); + for (i = 0; i < N_ELEMENTS(key_seen); i++) { + if (key_seen[i]) + auth_cache_key_add_tab_idx(str, i); + } + + if (*extra_vars != '\0') { + if (str_len(str) > 0) + str_append_c(str, '\t'); + str_append(str, extra_vars); + } + + return p_strdup(pool, str_c(str)); } static void @@ -142,8 +189,8 @@ { struct auth_cache *cache = context; - i_info("SIGHUP received, clearing cache"); - auth_cache_clear(cache); + i_info("SIGHUP received, %u cache entries flushed", + auth_cache_clear(cache)); } static void sig_auth_cache_stats(const siginfo_t *si ATTR_UNUSED, void *context) @@ -200,11 +247,69 @@ i_free(cache); } -void auth_cache_clear(struct auth_cache *cache) +unsigned int auth_cache_clear(struct auth_cache *cache) { + unsigned int ret = hash_table_count(cache->hash); + while (cache->tail != NULL) auth_cache_node_destroy(cache, cache->tail); hash_table_clear(cache->hash, FALSE); + return ret; +} + +static bool auth_cache_node_is_user(struct auth_cache_node *node, + const char *username) +{ + const char *data = node->data; + unsigned int username_len; + + /* The cache nodes begin with "P"/"U", passdb/userdb ID, "/" and + then usually followed by the username. It's too much trouble to + keep track of all the cache keys, so we'll just match it as if it + was the username. If e.g. '%n' is used in the cache key instead of + '%u', it means that cache entries can be removed only when @domain + isn't in the username parameter. */ + if (*data != 'P' && *data != 'U') + return FALSE; + data++; + + while (*data >= '0' && *data <= '9') + data++; + if (*data != '/') + return FALSE; + data++; + + username_len = strlen(username); + return strncmp(data, username, username_len) == 0 && + (data[username_len] == '\t' || data[username_len] == '\0'); +} + +static bool auth_cache_node_is_one_of_users(struct auth_cache_node *node, + const char *const *usernames) +{ + unsigned int i; + + for (i = 0; usernames[i] != NULL; i++) { + if (auth_cache_node_is_user(node, usernames[i])) + return TRUE; + } + return FALSE; +} + +unsigned int auth_cache_clear_users(struct auth_cache *cache, + const char *const *usernames) +{ + struct auth_cache_node *node, *next; + unsigned int ret = 0; + + for (node = cache->tail; node != NULL; node = next) { + next = node->next; + if (auth_cache_node_is_one_of_users(node, usernames)) { + auth_cache_node_destroy(cache, cache->tail); + ret++; + } + } + return ret; } static const char * @@ -216,12 +321,27 @@ return str_tabescape(string); } +static const char * +auth_request_expand_cache_key(const struct auth_request *request, + const char *key) +{ + string_t *str; + + /* Uniquely identify the request's passdb/userdb with the P/U prefix + and by "%!", which expands to the passdb/userdb ID number. */ + key = t_strconcat(request->userdb_lookup ? "U" : "P", "%!/", key, NULL); + + str = t_str_new(256); + var_expand(str, key, + auth_request_get_var_expand_table(request, auth_cache_escape)); + return str_c(str); +} + const char * auth_cache_lookup(struct auth_cache *cache, const struct auth_request *request, const char *key, struct auth_cache_node **node_r, bool *expired_r, bool *neg_expired_r) { - string_t *str; struct auth_cache_node *node; const char *value; unsigned int ttl_secs; @@ -230,13 +350,8 @@ *expired_r = FALSE; *neg_expired_r = FALSE; - /* %! is prepended automatically. it contains the passdb ID number. */ - str = t_str_new(256); - var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", - "%!/", key, NULL), - auth_request_get_var_expand_table(request, auth_cache_escape)); - - node = hash_table_lookup(cache->hash, str_c(str)); + key = auth_request_expand_cache_key(request, key); + node = hash_table_lookup(cache->hash, key); if (node == NULL) { cache->miss_count++; return NULL; @@ -269,9 +384,8 @@ void auth_cache_insert(struct auth_cache *cache, struct auth_request *request, const char *key, const char *value, bool last_success) { - string_t *str; struct auth_cache_node *node; - size_t data_size, alloc_size, value_len = strlen(value); + size_t data_size, alloc_size, key_len, value_len = strlen(value); char *current_username; if (*value == '\0' && cache->neg_ttl_secs == 0) { @@ -286,15 +400,12 @@ request->requested_login_user == NULL) request->user = t_strdup_noconst(request->translated_username); - /* %! is prepended automatically. it contains the db ID number. */ - str = t_str_new(256); - var_expand(str, t_strconcat(request->userdb_lookup ? "U" : "P", - "%!/", key, NULL), - auth_request_get_var_expand_table(request, auth_cache_escape)); From dovecot at dovecot.org Wed Jul 4 10:58:52 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 04 Jul 2012 10:58:52 +0300 Subject: dovecot-2.1: doveadm: Added "auth cache flush" command. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1093c74f54af changeset: 14600:1093c74f54af user: Timo Sirainen date: Wed Jul 04 10:57:40 2012 +0300 description: doveadm: Added "auth cache flush" command. diffstat: src/doveadm/doveadm-auth.c | 82 +++++++++++++++++++++++++++++++++++++++------ src/doveadm/doveadm.c | 3 +- src/doveadm/doveadm.h | 3 +- src/lib-auth/auth-master.c | 43 ++++++++++++++++++++++++ src/lib-auth/auth-master.h | 4 ++ 5 files changed, 120 insertions(+), 15 deletions(-) diffs (247 lines): diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm-auth.c Wed Jul 04 10:57:40 2012 +0300 @@ -27,6 +27,8 @@ bool success; }; +static void auth_cmd_help(doveadm_command_t *cmd); + static int cmd_user_input(const char *auth_socket_path, const struct authtest_input *input, const char *show_field) @@ -214,12 +216,52 @@ auth_master_deinit(&conn); } +static void cmd_auth_cache_flush(int argc, char *argv[]) +{ + const char *auth_socket_path = NULL; + struct auth_master_connection *conn; + unsigned int count; + int c; + + while ((c = getopt(argc, argv, "a:")) > 0) { + switch (c) { + case 'a': + auth_socket_path = optarg; + break; + default: + auth_cmd_help(cmd_auth_cache_flush); + } + } + argv += optind; + + if (auth_socket_path == NULL) { + auth_socket_path = t_strconcat(doveadm_settings->base_dir, + "/auth-master", NULL); + } + + conn = auth_master_init(auth_socket_path, 0); + if (auth_master_cache_flush(conn, (void *)argv, &count) < 0) { + i_error("Cache flush failed"); + doveadm_exit_code = EX_TEMPFAIL; + } else { + printf("%u cache entries flushed\n", count); + } + auth_master_deinit(&conn); +} + static void cmd_auth(int argc, char *argv[]) { const char *auth_socket_path = NULL; struct authtest_input input; int c; + if (null_strcmp(argv[1], "cache") == 0 && + null_strcmp(argv[2], "flush") == 0) { + /* kludgy: handle "doveadm auth cache" command instead */ + cmd_auth_cache_flush(argc-2, argv+2); + return; + } + memset(&input, 0, sizeof(input)); input.info.service = "doveadm"; @@ -232,12 +274,12 @@ auth_user_info_parse(&input.info, optarg); break; default: - help(&doveadm_cmd_auth); + auth_cmd_help(cmd_auth); } } if (optind == argc) - help(&doveadm_cmd_auth); + auth_cmd_help(cmd_auth); input.username = argv[optind++]; input.password = argv[optind] != NULL ? argv[optind++] : @@ -331,12 +373,12 @@ auth_user_info_parse(&input.info, optarg); break; default: - help(&doveadm_cmd_user); + auth_cmd_help(cmd_user); } } if (optind == argc) - help(&doveadm_cmd_user); + auth_cmd_help(cmd_user); have_wildcards = FALSE; for (i = optind; argv[i] != NULL; i++) { @@ -380,12 +422,30 @@ mail_storage_service_deinit(&storage_service); } -struct doveadm_cmd doveadm_cmd_auth = { - cmd_auth, "auth", - "[-a ] [-x ] []" +struct doveadm_cmd doveadm_cmd_auth[] = { + { cmd_auth, "auth", + "[-a ] [-x ] []" }, + { cmd_auth_cache_flush, "auth cache flush", + "[-a ] []" }, + { cmd_user, "user", + "[-a ] [-x ] [-f field] [-m] [...]" } }; -struct doveadm_cmd doveadm_cmd_user = { - cmd_user, "user", - "[-a ] [-x ] [-f field] [-m] [...]" -}; +static void auth_cmd_help(doveadm_command_t *cmd) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_auth); i++) { + if (doveadm_cmd_auth[i].cmd == cmd) + help(&doveadm_cmd_auth[i]); + } + i_unreached(); +} + +void doveadm_register_auth_commands(void) +{ + unsigned int i; + + for (i = 0; i < N_ELEMENTS(doveadm_cmd_auth); i++) + doveadm_register_cmd(&doveadm_cmd_auth[i]); +} diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm.c --- a/src/doveadm/doveadm.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm.c Wed Jul 04 10:57:40 2012 +0300 @@ -271,8 +271,6 @@ &doveadm_cmd_config, &doveadm_cmd_stop, &doveadm_cmd_reload, - &doveadm_cmd_auth, - &doveadm_cmd_user, &doveadm_cmd_dump, &doveadm_cmd_pw, &doveadm_cmd_who, @@ -342,6 +340,7 @@ quick_init = TRUE; } else { quick_init = FALSE; + doveadm_register_auth_commands(); doveadm_register_director_commands(); doveadm_register_instance_commands(); doveadm_register_mount_commands(); diff -r 007bf0047ab0 -r 1093c74f54af src/doveadm/doveadm.h --- a/src/doveadm/doveadm.h Wed Jul 04 10:56:53 2012 +0300 +++ b/src/doveadm/doveadm.h Wed Jul 04 10:57:40 2012 +0300 @@ -22,8 +22,6 @@ extern struct doveadm_cmd doveadm_cmd_stop; extern struct doveadm_cmd doveadm_cmd_reload; -extern struct doveadm_cmd doveadm_cmd_auth; -extern struct doveadm_cmd doveadm_cmd_user; extern struct doveadm_cmd doveadm_cmd_dump; extern struct doveadm_cmd doveadm_cmd_pw; extern struct doveadm_cmd doveadm_cmd_who; @@ -41,6 +39,7 @@ void help(const struct doveadm_cmd *cmd) ATTR_NORETURN; void doveadm_master_send_signal(int signo); +void doveadm_register_auth_commands(void); void doveadm_register_director_commands(void); void doveadm_register_proxy_commands(void); void doveadm_register_log_commands(void); diff -r 007bf0047ab0 -r 1093c74f54af src/lib-auth/auth-master.c --- a/src/lib-auth/auth-master.c Wed Jul 04 10:56:53 2012 +0300 +++ b/src/lib-auth/auth-master.c Wed Jul 04 10:57:40 2012 +0300 @@ -9,6 +9,7 @@ #include "istream.h" #include "ostream.h" #include "str.h" +#include "strescape.h" #include "master-interface.h" #include "auth-master.h" @@ -564,6 +565,48 @@ } static bool +auth_cache_flush_reply_callback(const char *cmd, const char *const *args, + void *context) +{ + unsigned int *countp = context; + + if (strcmp(cmd, "OK") != 0) + *countp = -1U; + else if (args[0] == NULL || str_to_uint(args[0], countp) < 0) + *countp = -1U; + + io_loop_stop(current_ioloop); + return TRUE; +} + +int auth_master_cache_flush(struct auth_master_connection *conn, + const char *const *users, unsigned int *count_r) +{ + string_t *str; + + *count_r = -1U; + + conn->reply_callback = auth_cache_flush_reply_callback; + conn->reply_context = count_r; + + str = t_str_new(128); + str_printfa(str, "CACHE-FLUSH\t%u", auth_master_next_request_id(conn)); + if (users != NULL) { + for (; *users != NULL; users++) { + str_append_c(str, '\t'); + str_tabescape_write(str, *users); + } + } + str_append_c(str, '\n'); + + conn->prefix = "auth cache flush"; + (void)auth_master_run_cmd(conn, str_c(str)); + conn->prefix = DEFAULT_USERDB_LOOKUP_PREFIX; + + return *count_r == -1U ? -1 : 0; +} + +static bool auth_user_list_reply_callback(const char *cmd, const char *const *args, void *context) { diff -r 007bf0047ab0 -r 1093c74f54af src/lib-auth/auth-master.h --- a/src/lib-auth/auth-master.h Wed Jul 04 10:56:53 2012 +0300 +++ b/src/lib-auth/auth-master.h Wed Jul 04 10:57:40 2012 +0300 @@ -38,6 +38,10 @@ int auth_master_pass_lookup(struct auth_master_connection *conn, const char *user, const struct auth_user_info *info, pool_t pool, const char *const **fields_r); +/* Flush authentication cache for everyone (users=NULL) or only for specified + users. Returns number of users flushed from cache. */ +int auth_master_cache_flush(struct auth_master_connection *conn, + const char *const *users, unsigned int *count_r); /* Parse userdb extra fields into auth_user_reply structure. */ void auth_user_fields_parse(const char *const *fields, pool_t pool, From dovecot at dovecot.org Wed Jul 4 11:19:55 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 04 Jul 2012 11:19:55 +0300 Subject: dovecot-2.2: lib-master: i_close_fd() change caused environment ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/5d3bc8a98e46 changeset: 14705:5d3bc8a98e46 user: Timo Sirainen date: Wed Jul 04 11:19:44 2012 +0300 description: lib-master: i_close_fd() change caused environment variables to be used as settings. diffstat: src/lib-master/master-service-settings.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diffs (25 lines): diff -r 04c89bb18bdd -r 5d3bc8a98e46 src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c Mon Jul 02 05:14:22 2012 +0300 +++ b/src/lib-master/master-service-settings.c Wed Jul 04 11:19:44 2012 +0300 @@ -337,6 +337,7 @@ unsigned int i; int ret, fd = -1; time_t now, timeout; + bool use_environment; memset(output_r, 0, sizeof(*output_r)); @@ -415,9 +416,12 @@ service->config_fd = fd; else i_close_fd(&fd); + use_environment = FALSE; + } else { + use_environment = TRUE; } - if (fd == -1 || service->keep_environment) { + if (use_environment || service->keep_environment) { if (settings_parse_environ(parser) < 0) { *error_r = settings_parser_get_error(parser); return -1; From dovecot at dovecot.org Wed Jul 4 12:37:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 04 Jul 2012 12:37:16 +0300 Subject: dovecot-2.2: lib-storage: Don't try to sync private index files ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e59dfda2a02f changeset: 14706:e59dfda2a02f user: Timo Sirainen date: Wed Jul 04 12:37:02 2012 +0300 description: lib-storage: Don't try to sync private index files if syncing already failed. This fixes a crash when opening a mailbox failed. diffstat: src/lib-storage/index/index-sync.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (21 lines): diff -r 5d3bc8a98e46 -r e59dfda2a02f src/lib-storage/index/index-sync.c --- a/src/lib-storage/index/index-sync.c Wed Jul 04 11:19:44 2012 +0300 +++ b/src/lib-storage/index/index-sync.c Wed Jul 04 12:37:02 2012 +0300 @@ -184,14 +184,14 @@ ctx->ctx.box = box; ctx->ctx.flags = flags; - /* sync private index if needed */ - (void)index_storage_mailbox_sync_pvt(box); - if (failed) { ctx->failed = TRUE; return &ctx->ctx; } + /* sync private index if needed */ + (void)index_storage_mailbox_sync_pvt(box); + if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES; From dovecot at dovecot.org Wed Jul 4 13:14:09 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 04 Jul 2012 13:14:09 +0300 Subject: dovecot-2.2: lib-storage: Private index needs to be synced also ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dfd3f9135017 changeset: 14707:dfd3f9135017 user: Timo Sirainen date: Wed Jul 04 13:13:56 2012 +0300 description: lib-storage: Private index needs to be synced also when messages have been expunged. diffstat: src/lib-storage/index/index-sync-pvt.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diffs (15 lines): diff -r e59dfda2a02f -r dfd3f9135017 src/lib-storage/index/index-sync-pvt.c --- a/src/lib-storage/index/index-sync-pvt.c Wed Jul 04 12:37:02 2012 +0300 +++ b/src/lib-storage/index/index-sync-pvt.c Wed Jul 04 13:13:56 2012 +0300 @@ -132,8 +132,9 @@ return 0; } hdr_pvt = mail_index_get_header(box->view_pvt); - if (hdr_pvt->next_uid == hdr_shared->next_uid) { - /* no new mails, don't bother syncing */ + if (hdr_pvt->next_uid == hdr_shared->next_uid && + hdr_pvt->messages_count == hdr_shared->messages_count) { + /* no new or expunged mails, don't bother syncing */ mail_index_view_close(&view_shared); return 0; } From dovecot at dovecot.org Thu Jul 5 10:52:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Jul 2012 10:52:11 +0300 Subject: dovecot-2.2: imap: Fixed crashes on some FETCH commands Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2ab4aa784474 changeset: 14708:2ab4aa784474 user: Timo Sirainen date: Thu Jul 05 10:51:42 2012 +0300 description: imap: Fixed crashes on some FETCH commands diffstat: src/lib-imap-storage/imap-msgpart.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (20 lines): diff -r dfd3f9135017 -r 2ab4aa784474 src/lib-imap-storage/imap-msgpart.c --- a/src/lib-imap-storage/imap-msgpart.c Wed Jul 04 13:13:56 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart.c Thu Jul 05 10:51:42 2012 +0300 @@ -55,6 +55,7 @@ msgpart->pool = pool; msgpart->partial_size = (uoff_t)-1; msgpart->fetch_type = fetch_type; + msgpart->section_number = ""; if (fetch_type == FETCH_HEADER || fetch_type == FETCH_FULL) msgpart->wanted_fields |= MAIL_FETCH_STREAM_HEADER; if (fetch_type == FETCH_BODY || fetch_type == FETCH_FULL) @@ -190,7 +191,7 @@ bool next_digit; int ret; - pool = pool_alloconly_create("imap msgpart", 512); + pool = pool_alloconly_create("imap msgpart", 1024); msgpart = *msgpart_r = p_new(pool, struct imap_msgpart, 1); msgpart->pool = pool; msgpart->partial_size = (uoff_t)-1; From dovecot at dovecot.org Thu Jul 5 16:08:16 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Jul 2012 16:08:16 +0300 Subject: dovecot-2.2: lib-storage: Fixed searching message flags on mailb... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/e9e1b97c78c7 changeset: 14709:e9e1b97c78c7 user: Timo Sirainen date: Thu Jul 05 16:08:07 2012 +0300 description: lib-storage: Fixed searching message flags on mailboxes without private index. diffstat: src/lib-storage/index/index-search.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (20 lines): diff -r 2ab4aa784474 -r e9e1b97c78c7 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Thu Jul 05 10:51:42 2012 +0300 +++ b/src/lib-storage/index/index-search.c Thu Jul 05 16:08:07 2012 +0300 @@ -153,14 +153,14 @@ { if (ctx->pvt_uid == uid) return ctx->pvt_seq != 0; - ctx->pvt_uid = uid; - ctx->pvt_seq = uid; if (ctx->box->view_pvt == NULL) { /* no private view (set by view syncing) -> no private flags */ return FALSE; } + ctx->pvt_uid = uid; + ctx->pvt_seq = uid; return mail_index_lookup_seq(ctx->mail_ctx.transaction->view_pvt, uid, &ctx->pvt_seq); } From dovecot at dovecot.org Thu Jul 5 16:11:08 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Thu, 05 Jul 2012 16:11:08 +0300 Subject: dovecot-2.2: lib-storage: Minor code cleanup Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/94fd1ec48e81 changeset: 14710:94fd1ec48e81 user: Timo Sirainen date: Thu Jul 05 16:11:00 2012 +0300 description: lib-storage: Minor code cleanup diffstat: src/lib-storage/index/index-search.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r e9e1b97c78c7 -r 94fd1ec48e81 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Thu Jul 05 16:08:07 2012 +0300 +++ b/src/lib-storage/index/index-search.c Thu Jul 05 16:11:00 2012 +0300 @@ -160,7 +160,6 @@ } ctx->pvt_uid = uid; - ctx->pvt_seq = uid; return mail_index_lookup_seq(ctx->mail_ctx.transaction->view_pvt, uid, &ctx->pvt_seq); } From dovecot at dovecot.org Sat Jul 7 05:51:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 07 Jul 2012 05:51:48 +0300 Subject: dovecot-2.1: pop3: Fixed assert crash when doing UIDL on empty m... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ea18b2ddb67b changeset: 14601:ea18b2ddb67b user: Timo Sirainen date: Sat Jul 07 05:51:37 2012 +0300 description: pop3: Fixed assert crash when doing UIDL on empty mailbox on some setups. diffstat: src/pop3/pop3-commands.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 1093c74f54af -r ea18b2ddb67b src/pop3/pop3-commands.c --- a/src/pop3/pop3-commands.c Wed Jul 04 10:57:40 2012 +0300 +++ b/src/pop3/pop3-commands.c Sat Jul 07 05:51:37 2012 +0300 @@ -759,7 +759,7 @@ str_hash, (hash_cmp_callback_t *)strcmp); client->uidl_pool = pool_alloconly_create("message uidls", 1024); client->message_uidls = p_new(client->uidl_pool, const char *, - client->messages_count); + client->messages_count+1); str = t_str_new(128); msgnum = 0; while (mailbox_search_next(search_ctx, &mail)) { From dovecot at dovecot.org Sat Jul 7 14:38:04 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 07 Jul 2012 14:38:04 +0300 Subject: dovecot-2.1: file_preallocate() returned wrong value on success ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4b0095f19181 changeset: 14602:4b0095f19181 user: Timo Sirainen date: Sat Jul 07 14:37:54 2012 +0300 description: file_preallocate() returned wrong value on success with OSX. diffstat: src/lib/file-set-size.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ea18b2ddb67b -r 4b0095f19181 src/lib/file-set-size.c --- a/src/lib/file-set-size.c Sat Jul 07 05:51:37 2012 +0300 +++ b/src/lib/file-set-size.c Sat Jul 07 14:37:54 2012 +0300 @@ -100,7 +100,7 @@ fs.fst_bytesalloc = 0; if (fcntl(fd, F_PREALLOCATE, &fs) < 0) return -1; - return 0; + return fs.fst_bytesalloc > 0 ? 1 : 0; #else return 0; #endif From dovecot at dovecot.org Sat Jul 7 14:40:07 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 07 Jul 2012 14:40:07 +0300 Subject: dovecot-2.1: doveadm auth cache flush usage string updated Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b3e1111e7f49 changeset: 14603:b3e1111e7f49 user: Timo Sirainen date: Wed Jul 04 11:02:58 2012 +0300 description: doveadm auth cache flush usage string updated diffstat: src/doveadm/doveadm-auth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4b0095f19181 -r b3e1111e7f49 src/doveadm/doveadm-auth.c --- a/src/doveadm/doveadm-auth.c Sat Jul 07 14:37:54 2012 +0300 +++ b/src/doveadm/doveadm-auth.c Wed Jul 04 11:02:58 2012 +0300 @@ -426,7 +426,7 @@ { cmd_auth, "auth", "[-a ] [-x ] []" }, { cmd_auth_cache_flush, "auth cache flush", - "[-a ] []" }, + "[-a ] [ [...]]" }, { cmd_user, "user", "[-a ] [-x ] [-f field] [-m] [...]" } }; From dovecot at dovecot.org Sat Jul 7 16:28:10 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 07 Jul 2012 16:28:10 +0300 Subject: dovecot-2.1: pop3c: Don't get size of TOP output and cache it as... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/8ef2b31b125f changeset: 14604:8ef2b31b125f user: Timo Sirainen date: Sat Jul 07 16:27:59 2012 +0300 description: pop3c: Don't get size of TOP output and cache it as message's virtual size. diffstat: src/lib-storage/index/pop3c/pop3c-mail.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diffs (28 lines): diff -r b3e1111e7f49 -r 8ef2b31b125f src/lib-storage/index/pop3c/pop3c-mail.c --- a/src/lib-storage/index/pop3c/pop3c-mail.c Wed Jul 04 11:02:58 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-mail.c Sat Jul 07 16:27:59 2012 +0300 @@ -110,10 +110,12 @@ if (mail->data.stream == NULL) { capa = pop3c_client_get_capabilities(mbox->client); - if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) + if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) { cmd = t_strdup_printf("RETR %u\r\n", _mail->seq); - else + get_body = TRUE; + } else { cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq); + } if (pop3c_client_cmd_stream(mbox->client, cmd, &input, &error) < 0) { mail_storage_set_error(mbox->box.storage, @@ -130,7 +132,8 @@ } } i_stream_set_name(mail->data.stream, t_strcut(cmd, '\r')); - pop3c_mail_cache_size(mail); + if (get_body) + pop3c_mail_cache_size(mail); } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); } From dovecot at dovecot.org Sun Jul 8 09:01:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 09:01:11 +0300 Subject: dovecot-2.1: Added a simple JSON parser for parsing an object. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/01cdca5817f2 changeset: 14605:01cdca5817f2 user: Timo Sirainen date: Sun Jul 08 07:37:28 2012 +0300 description: Added a simple JSON parser for parsing an object. diffstat: src/lib/Makefile.am | 2 + src/lib/json-parser.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/json-parser.h | 22 ++++ 3 files changed, 296 insertions(+), 0 deletions(-) diffs (truncated from 321 to 300 lines): diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/Makefile.am --- a/src/lib/Makefile.am Sat Jul 07 16:27:59 2012 +0300 +++ b/src/lib/Makefile.am Sun Jul 08 07:37:28 2012 +0300 @@ -74,6 +74,7 @@ ioloop-select.c \ ioloop-epoll.c \ ioloop-kqueue.c \ + json-parser.c \ lib.c \ lib-signals.c \ md4.c \ @@ -183,6 +184,7 @@ ioloop-iolist.h \ ioloop-private.h \ ioloop-notify-fd.h \ + json-parser.h \ lib.h \ lib-signals.h \ llist.h \ diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/json-parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/json-parser.c Sun Jul 08 07:37:28 2012 +0300 @@ -0,0 +1,272 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "hex-dec.h" +#include "unichar.h" +#include "json-parser.h" + +enum json_state { + JSON_STATE_ROOT = 0, + JSON_STATE_OBJECT_KEY, + JSON_STATE_OBJECT_COLON, + JSON_STATE_OBJECT_VALUE, + JSON_STATE_OBJECT_VALUE_NEXT, + JSON_STATE_DONE +}; + +struct json_parser { + const unsigned char *data, *end; + const char *error; + string_t *value; + + enum json_state state; +}; + +struct json_parser * +json_parser_init(const unsigned char *data, unsigned int len) +{ + struct json_parser *parser; + + parser = i_new(struct json_parser, 1); + parser->data = data; + parser->end = data + len; + parser->value = str_new(default_pool, 128); + return parser; +} + +int json_parser_deinit(struct json_parser **_parser, const char **error_r) +{ + struct json_parser *parser = *_parser; + + *_parser = NULL; + + if (parser->error == NULL && parser->data == parser->end && + parser->state != JSON_STATE_ROOT && + parser->state != JSON_STATE_DONE) + parser->error = "Missing '}'"; + + *error_r = parser->error; + str_free(&parser->value); + i_free(parser); + return *error_r != NULL ? -1 : 0; +} + +static bool json_parse_whitespace(struct json_parser *parser) +{ + for (; parser->data != parser->end; parser->data++) { + switch (*parser->data) { + case ' ': + case '\t': + case '\r': + case '\n': + break; + default: + return TRUE; + } + } + return FALSE; +} + +static int json_parse_string(struct json_parser *parser, const char **value_r) +{ + const unsigned char *p; + + if (*parser->data != '"') + return -1; + + str_truncate(parser->value, 0); + for (p = parser->data + 1; p < parser->end; p++) { + if (*p == '"') { + parser->data = p + 1; + *value_r = str_c(parser->value); + return 0; + } + if (*p != '\\') + str_append_c(parser->value, *p); + else { + switch (*++p) { + case '"': + case '\\': + case '/': + str_append_c(parser->value, *p); + break; + case 'b': + str_append_c(parser->value, '\b'); + break; + case 'f': + str_append_c(parser->value, '\f'); + break; + case 'n': + str_append_c(parser->value, '\n'); + break; + case 'r': + str_append_c(parser->value, '\r'); + break; + case 't': + str_append_c(parser->value, '\t'); + break; + case 'u': + if (parser->end - p < 4) + return -1; + uni_ucs4_to_utf8_c(hex2dec(p, 4), + parser->value); + p += 3; + break; + default: + return -1; + } + } + } + return -1; +} + +static int +json_parse_digits(struct json_parser *parser, const unsigned char **_p) +{ + const unsigned char *p = *_p; + + if (p >= parser->end || *p < '0' || *p > '9') + return -1; + + for (; p < parser->end && *p >= '0' && *p <= '9'; p++) + str_append_c(parser->value, *p++); + *_p = p; + return 0; +} + +static int json_parse_int(struct json_parser *parser, const unsigned char **_p) +{ + const unsigned char *p = *_p; + + if (*p == '-') { + str_append_c(parser->value, *p++); + if (p == parser->end) + return -1; + } + if (*p == '0') + str_append_c(parser->value, *p++); + else { + if (json_parse_digits(parser, &p) < 0) + return -1; + } + *_p = p; + return 0; +} + +static int json_parse_number(struct json_parser *parser, const char **value_r) +{ + const unsigned char *p = parser->data; + + str_truncate(parser->value, 0); + if (json_parse_int(parser, &p) < 0) + return -1; + if (p < parser->end && *p == '.') { + /* frac */ + str_append_c(parser->value, *p++); + if (json_parse_digits(parser, &p) < 0) + return -1; + } + if (p < parser->end && (*p == 'e' || *p == 'E')) { + /* exp */ + str_append_c(parser->value, *p++); + if (p == parser->end) + return -1; + if (*p == '+' || *p == '-') + str_append_c(parser->value, *p++); + if (json_parse_digits(parser, &p) < 0) + return -1; + } + *value_r = str_c(parser->value); + return 0; +} + +static int json_parse_atom(struct json_parser *parser, const char *atom) +{ + unsigned int len = strlen(atom); + + if (parser->end - parser->data < len) + return -1; + if (memcmp(parser->data, atom, len) != 0) + return -1; + parser->data += len; + return 0; +} + +bool json_parse_next(struct json_parser *parser, enum json_type *type_r, + const char **value_r) +{ + *value_r = NULL; + + if (!json_parse_whitespace(parser) || parser->error != NULL) + return FALSE; + + switch (parser->state) { + case JSON_STATE_ROOT: + if (*parser->data == '{') { + parser->data++; + parser->state = JSON_STATE_OBJECT_KEY; + return json_parse_next(parser, type_r, value_r); + } + /* fall through */ + case JSON_STATE_OBJECT_VALUE: + if (json_parse_string(parser, value_r) == 0) + *type_r = JSON_TYPE_STRING; + else if (json_parse_number(parser, value_r) == 0) + *type_r = JSON_TYPE_NUMBER; + else if (json_parse_atom(parser, "true") == 0) { + *type_r = JSON_TYPE_TRUE; + *value_r = "true"; + } else if (json_parse_atom(parser, "false") == 0) { + *type_r = JSON_TYPE_FALSE; + *value_r = "false"; + } else if (json_parse_atom(parser, "null") == 0) { + *type_r = JSON_TYPE_NULL; + *value_r = NULL; + } else if (*parser->data == '[') { + parser->error = "Arrays not supported"; + return FALSE; + } else if (*parser->data == '{') { + parser->error = "Nested objects not supported"; + return FALSE; + } else { + parser->error = "Invalid data as value"; + return FALSE; + } + parser->state = parser->state == JSON_STATE_ROOT ? + JSON_STATE_DONE : + JSON_STATE_OBJECT_VALUE_NEXT; + break; + case JSON_STATE_OBJECT_KEY: + *type_r = JSON_TYPE_OBJECT_KEY; + if (json_parse_string(parser, value_r) < 0) { + parser->error = "Expected string as object key"; + return FALSE; + } + parser->state = JSON_STATE_OBJECT_COLON; + break; + case JSON_STATE_OBJECT_COLON: + if (*parser->data != ':') { + parser->error = "Expected ':' after key"; + return FALSE; + } + parser->data++; + parser->state = JSON_STATE_OBJECT_VALUE; + return json_parse_next(parser, type_r, value_r); + case JSON_STATE_OBJECT_VALUE_NEXT: + if (*parser->data == ',') + parser->state = JSON_STATE_OBJECT_KEY; + else if (*parser->data == '}') + parser->state = JSON_STATE_DONE; + else { + parser->error = "Expected ',' or '}' after object value"; + return FALSE; + } + parser->data++; + return json_parse_next(parser, type_r, value_r); + case JSON_STATE_DONE: + parser->error = "Unexpected data at the end"; + return FALSE; + } + return TRUE; +} diff -r 8ef2b31b125f -r 01cdca5817f2 src/lib/json-parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/json-parser.h Sun Jul 08 07:37:28 2012 +0300 @@ -0,0 +1,22 @@ +#ifndef JSON_PARSER_H From dovecot at dovecot.org Sun Jul 8 09:01:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 09:01:11 +0300 Subject: dovecot-2.1: auth: Added "dict" passdb/userdb. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/523c19238a8b changeset: 14606:523c19238a8b user: Timo Sirainen date: Sun Jul 08 07:45:17 2012 +0300 description: auth: Added "dict" passdb/userdb. diffstat: doc/example-config/conf.d/auth-dict.conf.ext | 16 ++ doc/example-config/dovecot-dict-auth.conf.ext | 22 ++ src/auth/Makefile.am | 5 + src/auth/db-dict.c | 177 ++++++++++++++++++++++ src/auth/db-dict.h | 37 ++++ src/auth/main.c | 3 + src/auth/passdb-dict.c | 197 ++++++++++++++++++++++++ src/auth/passdb.c | 2 + src/auth/userdb-dict.c | 207 ++++++++++++++++++++++++++ src/auth/userdb.c | 2 + 10 files changed, 668 insertions(+), 0 deletions(-) diffs (truncated from 788 to 300 lines): diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/conf.d/auth-dict.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/conf.d/auth-dict.conf.ext Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,16 @@ +# Authentication via dict backend. Included from auth.conf. +# +# + +passdb { + driver = dict + + # Path for dict configuration file, see + # example-config/dovecot-dict-auth.conf.ext + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} + +userdb { + driver = dict + args = /etc/dovecot/dovecot-dict-auth.conf.ext +} diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/dovecot-dict-auth.conf.ext --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/example-config/dovecot-dict-auth.conf.ext Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,22 @@ +# Dictionary URI +#uri = + +# Key for passdb lookups +password_key = dovecot/passdb/%u + +# Key for userdb lookups +user_key = dovecot/userdb/%u + +# How to parse the value for key=value pairs. Currently we support only JSON +# format with { "key": "value", ... } object. +#value_format = json + +# Username iteration prefix. Keys under this are assumed to contain usernames. +iterate_prefix = dovecot/userdb/ + +# Should iteration be disabled for this userdb? If this userdb acts only as a +# cache there's no reason to try to iterate the (partial & duplicate) users. +#iterate_disable = no + +# Default password scheme +default_pass_scheme = MD5 diff -r 01cdca5817f2 -r 523c19238a8b src/auth/Makefile.am --- a/src/auth/Makefile.am Sun Jul 08 07:37:28 2012 +0300 +++ b/src/auth/Makefile.am Sun Jul 08 07:45:17 2012 +0300 @@ -25,6 +25,7 @@ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-auth \ -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-dict \ -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-sql \ -I$(top_srcdir)/src/lib-settings \ @@ -73,6 +74,7 @@ auth-worker-client.c \ auth-worker-server.c \ db-checkpassword.c \ + db-dict.c \ db-sql.c \ db-passwd-file.c \ main.c \ @@ -96,6 +98,7 @@ passdb-bsdauth.c \ passdb-cache.c \ passdb-checkpassword.c \ + passdb-dict.c \ passdb-passwd.c \ passdb-passwd-file.c \ passdb-pam.c \ @@ -108,6 +111,7 @@ userdb.c \ userdb-blocking.c \ userdb-checkpassword.c \ + userdb-dict.c \ userdb-nss.c \ userdb-passwd.c \ userdb-passwd-file.c \ @@ -134,6 +138,7 @@ auth-stream.h \ auth-worker-client.h \ auth-worker-server.h \ + db-dict.h \ db-ldap.h \ db-sql.h \ db-passwd-file.h \ diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/db-dict.c Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,177 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "auth-common.h" + +#include "settings.h" +#include "dict.h" +#include "json-parser.h" +#include "str.h" +#include "auth-request.h" +#include "auth-worker-client.h" +#include "db-dict.h" + +#include +#include + +#define DEF_STR(name) DEF_STRUCT_STR(name, db_dict_settings) +#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, db_dict_settings) + +static struct setting_def setting_defs[] = { + DEF_STR(uri), + DEF_STR(password_key), + DEF_STR(user_key), + DEF_STR(iterate_prefix), + DEF_STR(value_format), + DEF_BOOL(iterate_disable), + DEF_STR(default_pass_scheme), + + { 0, NULL, 0 } +}; + +static struct db_dict_settings default_dict_settings = { + .uri = NULL, + .password_key = "", + .user_key = "", + .iterate_prefix = "", + .iterate_disable = FALSE, + .value_format = "json", + .default_pass_scheme = "MD5" +}; + +static struct dict_connection *connections = NULL; + +static struct dict_connection *dict_conn_find(const char *config_path) +{ + struct dict_connection *conn; + + for (conn = connections; conn != NULL; conn = conn->next) { + if (strcmp(conn->config_path, config_path) == 0) + return conn; + } + + return NULL; +} + +static const char *parse_setting(const char *key, const char *value, + struct dict_connection *conn) +{ + return parse_setting_from_defs(conn->pool, setting_defs, + &conn->set, key, value); +} + +struct dict_connection *db_dict_init(const char *config_path) +{ + struct dict_connection *conn; + pool_t pool; + + conn = dict_conn_find(config_path); + if (conn != NULL) { + conn->refcount++; + return conn; + } + + if (*config_path == '\0') + i_fatal("dict: Configuration file path not given"); + + pool = pool_alloconly_create("dict_connection", 1024); + conn = p_new(pool, struct dict_connection, 1); + conn->pool = pool; + + conn->refcount = 1; + + conn->config_path = p_strdup(pool, config_path); + conn->set = default_dict_settings; + if (!settings_read(config_path, NULL, parse_setting, + null_settings_section_callback, conn)) + exit(FATAL_DEFAULT); + + if (conn->set.uri == NULL) + i_fatal("dict %s: Empty uri setting", config_path); + if (strcmp(conn->set.value_format, "json") != 0) { + i_fatal("dict %s: Unsupported value_format %s in ", + config_path, conn->set.value_format); + } + conn->dict = dict_init(conn->set.uri, DICT_DATA_TYPE_STRING, "", + global_auth_settings->base_dir); + + conn->next = connections; + connections = conn; + return conn; +} + +void db_dict_unref(struct dict_connection **_conn) +{ + struct dict_connection *conn = *_conn; + + *_conn = NULL; + if (--conn->refcount > 0) + return; + + dict_deinit(&conn->dict); + pool_unref(&conn->pool); +} + +struct db_dict_value_iter { + struct json_parser *parser; + string_t *key; + const char *error; +}; + +struct db_dict_value_iter * +db_dict_value_iter_init(struct dict_connection *conn, const char *value) +{ + struct db_dict_value_iter *iter; + + i_assert(strcmp(conn->set.value_format, "json") == 0); + + /* hardcoded for now for JSON value. make it more modular when other + value types are supported. */ + iter = i_new(struct db_dict_value_iter, 1); + iter->key = str_new(default_pool, 64); + iter->parser = json_parser_init((const void *)value, strlen(value)); + return iter; +} + +bool db_dict_value_iter_next(struct db_dict_value_iter *iter, + const char **key_r, const char **value_r) +{ + enum json_type type; + const char *value; + + if (!json_parse_next(iter->parser, &type, &value)) + return FALSE; + if (type != JSON_TYPE_OBJECT_KEY) { + iter->error = "Object expected"; + return FALSE; + } + if (*value == '\0') { + iter->error = "Empty object key"; + return FALSE; + } + str_truncate(iter->key, 0); + str_append(iter->key, value); + + if (!json_parse_next(iter->parser, &type, &value)) { + iter->error = "Missing value"; + return FALSE; + } + *key_r = str_c(iter->key); + *value_r = value; + return TRUE; +} + +int db_dict_value_iter_deinit(struct db_dict_value_iter **_iter, + const char **error_r) +{ + struct db_dict_value_iter *iter = *_iter; + + *_iter = NULL; + + *error_r = iter->error; + if (json_parser_deinit(&iter->parser, &iter->error) < 0 && + *error_r == NULL) + *error_r = iter->error; + str_free(&iter->key); + i_free(iter); + return *error_r != NULL ? -1 : 0; +} diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/db-dict.h Sun Jul 08 07:45:17 2012 +0300 @@ -0,0 +1,37 @@ +#ifndef DB_DICT_H +#define DB_DICT_H + +#include "sql-api.h" + +struct db_dict_settings { + const char *uri; + const char *password_key; + const char *user_key; + const char *iterate_prefix; + bool iterate_disable; + const char *value_format; + const char *default_pass_scheme; +}; + +struct dict_connection { + struct dict_connection *next; + + pool_t pool; + int refcount; + + char *config_path; + struct db_dict_settings set; + struct dict *dict; +}; + From dovecot at dovecot.org Sun Jul 8 09:01:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 09:01:11 +0300 Subject: dovecot-2.1: Added "connection" API for handling client/server c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/43b841891c77 changeset: 14607:43b841891c77 user: Timo Sirainen date: Sun Jul 08 08:59:52 2012 +0300 description: Added "connection" API for handling client/server connections more easily. diffstat: src/lib/Makefile.am | 2 + src/lib/connection.c | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/connection.h | 118 +++++++++++++++++ 3 files changed, 461 insertions(+), 0 deletions(-) diffs (truncated from 486 to 300 lines): diff -r 523c19238a8b -r 43b841891c77 src/lib/Makefile.am --- a/src/lib/Makefile.am Sun Jul 08 07:45:17 2012 +0300 +++ b/src/lib/Makefile.am Sun Jul 08 08:59:52 2012 +0300 @@ -22,6 +22,7 @@ child-wait.c \ close-keep-errno.c \ compat.c \ + connection.c \ crc32.c \ data-stack.c \ eacces-error.c \ @@ -140,6 +141,7 @@ child-wait.h \ close-keep-errno.h \ compat.h \ + connection.h \ crc32.h \ data-stack.h \ eacces-error.h \ diff -r 523c19238a8b -r 43b841891c77 src/lib/connection.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/connection.c Sun Jul 08 08:59:52 2012 +0300 @@ -0,0 +1,341 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "istream.h" +#include "ostream.h" +#include "network.h" +#include "strescape.h" +#include "llist.h" +#include "connection.h" + +#include + +static void connection_idle_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_IDLE_TIMEOUT; + conn->list->v.destroy(conn); +} + +static void connection_connect_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_CONNECT_TIMEOUT; + conn->list->v.destroy(conn); +} + +void connection_input_default(struct connection *conn) +{ + const char *line; + struct istream *input; + int ret = 0; + + switch (connection_input_read(conn)) { + case -1: + case 0: + return; + case 1: + break; + default: + i_unreached(); + } + + input = conn->input; + i_stream_ref(input); + while (!input->closed && (line = i_stream_next_line(input)) != NULL) { + T_BEGIN { + ret = conn->list->v.input_line(conn, line); + } T_END; + if (ret <= 0) + break; + } + if (ret < 0 && !input->closed) { + conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT; + conn->list->v.destroy(conn); + } + i_stream_unref(&input); +} + +int connection_verify_version(struct connection *conn, + const char *const *args) +{ + unsigned int recv_major_version; + + /* VERSION service_name major version minor version */ + if (str_array_length(args) != 4 || + strcmp(args[0], "VERSION") != 0 || + str_to_uint(args[2], &recv_major_version) < 0 || + str_to_uint(args[3], &conn->minor_version) < 0) { + i_error("%s didn't reply with a valid VERSION line", + conn->name); + return -1; + } + + if (strcmp(args[1], conn->list->set.service_name_in) != 0) { + i_error("%s: Connected to wrong socket type. " + "We want '%s', but received '%s'", conn->name, + conn->list->set.service_name_in, args[1]); + return -1; + } + + if (recv_major_version != conn->list->set.major_version) { + i_error("%s: Socket supports major version %u, " + "but we support only %u (mixed old and new binaries?)", + conn->name, recv_major_version, + conn->list->set.major_version); + return -1; + } + return 0; +} + +int connection_input_line_default(struct connection *conn, const char *line) +{ + const char *const *args; + + args = t_strsplit_tabescaped(line); + if (!conn->version_received) { + if (connection_verify_version(conn, args) < 0) + return -1; + conn->version_received = TRUE; + } + + return conn->list->v.input_args(conn, args); +} + +static void connection_init_streams(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + + i_assert(conn->input == NULL); + i_assert(conn->output == NULL); + i_assert(conn->to == NULL); + + conn->version_received = set->major_version == 0; + + if (set->input_max_size != 0) { + conn->input = i_stream_create_fd(conn->fd_in, + set->input_max_size, FALSE); + } + if (set->output_max_size != 0) { + conn->output = o_stream_create_fd(conn->fd_out, + set->output_max_size, FALSE); + } + if (set->input_idle_timeout_secs != 0) { + conn->to = timeout_add(set->input_idle_timeout_secs*1000, + connection_idle_timeout, conn); + } + if (set->major_version != 0) { + o_stream_send_str(conn->output, t_strdup_printf( + "VERSION\t%s\t%u\t%u\n", set->service_name_out, + set->major_version, set->minor_version)); + } +} + +static void connection_init_io(struct connection *conn) +{ + i_assert(conn->io == NULL); + conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); +} + +void connection_init_server(struct connection_list *list, + struct connection *conn, const char *name, + int fd_in, int fd_out) +{ + i_assert(name != NULL); + i_assert(!list->set.client); + + conn->list = list; + conn->name = i_strdup(name); + conn->fd_in = fd_in; + conn->fd_out = fd_out; + connection_init_io(conn); + connection_init_streams(conn); + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_ip(struct connection_list *list, + struct connection *conn, + const struct ip_addr *ip, unsigned int port) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup_printf("%s:%u", net_ip2addr(ip), port); + + conn->ip = *ip; + conn->port = port; + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_unix(struct connection_list *list, + struct connection *conn, const char *path) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup(path); + + DLLIST_PREPEND(&list->connections, conn); +} + +static void connection_connected(struct connection *conn) +{ + io_remove(&conn->io); + if (conn->to != NULL) + timeout_remove(&conn->to); + + connection_init_io(conn); +} + +int connection_client_connect(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + int fd; + + i_assert(conn->list->set.client); + i_assert(conn->fd_in == -1); + + if (conn->port != 0) + fd = net_connect_ip(&conn->ip, conn->port, NULL); + else + fd = net_connect_unix(conn->name); + if (fd == -1) + return -1; + conn->fd_in = conn->fd_out = fd; + + if (conn->port != 0) { + conn->io = io_add(conn->fd_out, IO_WRITE, + connection_connected, conn); + if (set->client_connect_timeout_msecs != 0) { + conn->to = timeout_add(set->client_connect_timeout_msecs, + connection_connect_timeout, conn); + } + } else { + connection_init_io(conn); + } + connection_init_streams(conn); + return 0; +} + +void connection_disconnect(struct connection *conn) +{ + if (conn->to != NULL) + timeout_remove(&conn->to); + if (conn->io != NULL) + io_remove(&conn->io); + if (conn->input != NULL) + i_stream_destroy(&conn->input); + if (conn->output != NULL) + o_stream_destroy(&conn->output); + if (conn->fd_in != -1) { + if (close(conn->fd_in) < 0) + i_error("close(%s) failed: %m", conn->name); + if (conn->fd_in != conn->fd_out) + i_error("close(%s/out) failed: %m", conn->name); + conn->fd_in = conn->fd_out = -1; + } +} + +void connection_deinit(struct connection *conn) +{ + DLLIST_REMOVE(&conn->list->connections, conn); + + connection_disconnect(conn); + i_free(conn->name); +} + +int connection_input_read(struct connection *conn) +{ + conn->last_input = ioloop_time; + if (conn->to != NULL) + timeout_reset(conn->to); + + switch (i_stream_read(conn->input)) { + case -2: + /* buffer full */ + switch (conn->list->set.input_full_behavior) { + case CONNECTION_BEHAVIOR_DESTROY: + conn->disconnect_reason = + CONNECTION_DISCONNECT_BUFFER_FULL; + conn->list->v.destroy(conn); + return -1; + case CONNECTION_BEHAVIOR_ALLOW: + return -2; + } + case -1: + /* disconnected */ + conn->disconnect_reason = + CONNECTION_DISCONNECT_CONN_CLOSED; + conn->list->v.destroy(conn); + return -1; + case 0: + /* nothing new read */ + return 0; + default: From dovecot at dovecot.org Sun Jul 8 09:01:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 09:01:11 +0300 Subject: dovecot-2.1: lib-dict: Added initial version of Redis support. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/211fbc872ed4 changeset: 14608:211fbc872ed4 user: Timo Sirainen date: Sun Jul 08 09:00:57 2012 +0300 description: lib-dict: Added initial version of Redis support. The code is a bit ugly and doesn't handle anything except key lookups. diffstat: src/lib-dict/Makefile.am | 3 +- src/lib-dict/dict-private.h | 3 +- src/lib-dict/dict-redis.c | 250 ++++++++++++++++++++++++++++++++++++++++++++ src/lib-dict/dict.c | 2 + src/lib-dict/test-dict.c | 1 + 5 files changed, 257 insertions(+), 2 deletions(-) diffs (truncated from 309 to 300 lines): diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/Makefile.am Sun Jul 08 09:00:57 2012 +0300 @@ -13,7 +13,8 @@ base_sources = \ dict.c \ dict-client.c \ - dict-file.c + dict-file.c \ + dict-redis.c libdict_la_SOURCES = \ $(base_sources) diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict-private.h --- a/src/lib-dict/dict-private.h Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/dict-private.h Sun Jul 08 09:00:57 2012 +0300 @@ -51,7 +51,8 @@ unsigned int changed:1; }; +extern struct dict dict_driver_client; extern struct dict dict_driver_file; -extern struct dict dict_driver_client; +extern struct dict dict_driver_redis; #endif diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict-redis.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-redis.c Sun Jul 08 09:00:57 2012 +0300 @@ -0,0 +1,250 @@ +/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING redis */ + +#include "lib.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "connection.h" +#include "dict-private.h" + +#define REDIS_DEFAULT_PORT 6379 +#define REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) + +struct redis_connection { + struct connection conn; + struct redis_dict *dict; + + string_t *last_reply; + unsigned int bytes_left; + bool value_not_found; + bool value_received; +}; + +struct redis_dict { + struct dict dict; + struct ip_addr ip; + unsigned int port; + unsigned int timeout_msecs; + + struct ioloop *ioloop; + struct redis_connection conn; +}; + +struct redis_dict_iterate_context { + struct dict_iterate_context ctx; + struct redis_connection *conn; +}; + +static struct connection_list *redis_connections; + +static void redis_conn_destroy(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + + connection_disconnect(_conn); + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static void redis_conn_input(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + const unsigned char *data; + size_t size; + const char *line; + + switch (i_stream_read(_conn->input)) { + case 0: + return; + case -1: + redis_conn_destroy(_conn); + return; + default: + break; + } + + if (conn->bytes_left == 0) { + /* read the size first */ + line = i_stream_next_line(_conn->input); + if (line == NULL) + return; + if (strcmp(line, "$-1") == 0) { + conn->value_received = TRUE; + conn->value_not_found = TRUE; + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + return; + } + if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { + i_error("redis: Unexpected input (wanted $size): %s", + line); + redis_conn_destroy(_conn); + return; + } + conn->bytes_left += 2; /* include trailing CRLF */ + } + + data = i_stream_get_data(_conn->input, &size); + if (size > conn->bytes_left) + size = conn->bytes_left; + str_append_n(conn->last_reply, data, size); + + conn->bytes_left -= size; + i_stream_skip(_conn->input, size); + + if (conn->bytes_left == 0) { + /* drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + } +} + +static const struct connection_settings redis_conn_set = { + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1, + .client = TRUE +}; + +static const struct connection_vfuncs redis_conn_vfuncs = { + .destroy = redis_conn_destroy, + .input = redis_conn_input +}; + +static struct dict * +redis_dict_init(struct dict *driver, const char *uri, + enum dict_data_type value_type ATTR_UNUSED, + const char *username ATTR_UNUSED, + const char *base_dir ATTR_UNUSED) +{ + struct redis_dict *dict; + const char *const *args; + + if (redis_connections == NULL) { + redis_connections = + connection_list_init(&redis_conn_set, + &redis_conn_vfuncs); + } + + dict = i_new(struct redis_dict, 1); + if (net_addr2ip("127.0.0.1", &dict->ip) < 0) + i_unreached(); + dict->port = REDIS_DEFAULT_PORT; + dict->timeout_msecs = REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS; + + args = t_strsplit(uri, ":"); + for (; *args != NULL; args++) { + if (strncmp(*args, "host=", 5) == 0) { + if (net_addr2ip(*args+5, &dict->ip) < 0) + i_error("Invalid IP: %s", *args+5); + } else if (strncmp(*args, "port=", 5) == 0) { + if (str_to_uint(*args+5, &dict->port) < 0) + i_error("Invalid port: %s", *args+5); + } else if (strncmp(*args, "timeout_msecs=", 14) == 0) { + if (str_to_uint(*args+14, &dict->timeout_msecs) < 0) + i_error("Invalid timeout_msecs: %s", *args+14); + } else { + i_error("Unknown parameter: %s", *args); + } + } + connection_init_client_ip(redis_connections, &dict->conn.conn, + &dict->ip, dict->port); + + dict->dict = *driver; + dict->conn.last_reply = str_new(default_pool, 256); + dict->conn.dict = dict; + return &dict->dict; +} + +static void redis_dict_deinit(struct dict *_dict) +{ + struct redis_dict *dict = (struct redis_dict *)_dict; + + connection_deinit(&dict->conn.conn); + str_free(&dict->conn.last_reply); + i_free(dict); + + if (redis_connections->connections == NULL) + connection_list_deinit(&redis_connections); +} + +static void redis_dict_lookup_timeout(struct redis_dict *dict) +{ + i_error("redis: Lookup timed out in %u secs", dict->timeout_msecs); + io_loop_stop(dict->ioloop); +} + +static int redis_dict_lookup(struct dict *_dict, pool_t pool, + const char *key, const char **value_r) +{ + struct redis_dict *dict = (struct redis_dict *)_dict; + struct timeout *to; + const char *cmd; + struct ioloop *prev_ioloop = current_ioloop; + + if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) + key += strlen(DICT_PATH_SHARED); + else { + i_error("redis: Only shared key lookups supported for now"); + return -1; + } + + dict->conn.value_received = FALSE; + dict->conn.value_not_found = FALSE; + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + if (dict->conn.conn.fd_in == -1 && + connection_client_connect(&dict->conn.conn) < 0) { + i_error("redis: Couldn't connect to %s:%u", + net_ip2addr(&dict->ip), dict->port); + } else { + to = timeout_add(dict->timeout_msecs, + redis_dict_lookup_timeout, dict); + cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", + (int)strlen(key), key); + o_stream_send_str(dict->conn.conn.output, cmd); + + str_truncate(dict->conn.last_reply, 0); + io_loop_run(dict->ioloop); + timeout_remove(&to); + } + + current_ioloop = prev_ioloop; + connection_switch_ioloop(&dict->conn.conn); + current_ioloop = dict->ioloop; + io_loop_destroy(&dict->ioloop); + + if (!dict->conn.value_received) { + /* we failed in some way. make sure we disconnect since the + connection state isn't known anymore */ + redis_conn_destroy(&dict->conn.conn); + return -1; + } + if (dict->conn.value_not_found) + return 0; + + *value_r = p_strdup(pool, str_c(dict->conn.last_reply)); + return 1; +} + +struct dict dict_driver_redis = { + .name = "redis", + { + redis_dict_init, + redis_dict_deinit, + NULL, + redis_dict_lookup, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + } +}; diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/dict.c --- a/src/lib-dict/dict.c Sun Jul 08 08:59:52 2012 +0300 +++ b/src/lib-dict/dict.c Sun Jul 08 09:00:57 2012 +0300 @@ -55,12 +55,14 @@ { dict_driver_register(&dict_driver_client); dict_driver_register(&dict_driver_file); + dict_driver_register(&dict_driver_redis); } void dict_drivers_unregister_builtin(void) { dict_driver_unregister(&dict_driver_client); dict_driver_unregister(&dict_driver_file); + dict_driver_unregister(&dict_driver_redis); } struct dict *dict_init(const char *uri, enum dict_data_type value_type, diff -r 43b841891c77 -r 211fbc872ed4 src/lib-dict/test-dict.c --- a/src/lib-dict/test-dict.c Sun Jul 08 08:59:52 2012 +0300 From dovecot at dovecot.org Sun Jul 8 09:18:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 09:18:56 +0300 Subject: dovecot-2.1: redis: Fixed connection handling. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/64725ff9c297 changeset: 14609:64725ff9c297 user: Timo Sirainen date: Sun Jul 08 09:18:46 2012 +0300 description: redis: Fixed connection handling. diffstat: src/lib-dict/dict-redis.c | 44 ++++++++++++++++++++++++++++++++------------ src/lib/connection.c | 16 ++++++---------- src/lib/connection.h | 1 + 3 files changed, 39 insertions(+), 22 deletions(-) diffs (163 lines): diff -r 211fbc872ed4 -r 64725ff9c297 src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib-dict/dict-redis.c Sun Jul 08 09:18:46 2012 +0300 @@ -28,11 +28,7 @@ struct ioloop *ioloop; struct redis_connection conn; -}; - -struct redis_dict_iterate_context { - struct dict_iterate_context ctx; - struct redis_connection *conn; + bool connected; }; static struct connection_list *redis_connections; @@ -41,6 +37,7 @@ { struct redis_connection *conn = (struct redis_connection *)_conn; + conn->dict->connected = FALSE; connection_disconnect(_conn); if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); @@ -101,6 +98,20 @@ } } +static void redis_conn_connected(struct connection *_conn) +{ + struct redis_connection *conn = (struct redis_connection *)_conn; + + if ((errno = net_geterror(_conn->fd_in)) != 0) { + i_error("redis: connect(%s, %u) failed: %m", + net_ip2addr(&conn->dict->ip), conn->dict->port); + } else { + conn->dict->connected = TRUE; + } + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + static const struct connection_settings redis_conn_set = { .input_max_size = (size_t)-1, .output_max_size = (size_t)-1, @@ -109,7 +120,8 @@ static const struct connection_vfuncs redis_conn_vfuncs = { .destroy = redis_conn_destroy, - .input = redis_conn_input + .input = redis_conn_input, + .connected = redis_conn_connected }; static struct dict * @@ -171,7 +183,8 @@ static void redis_dict_lookup_timeout(struct redis_dict *dict) { - i_error("redis: Lookup timed out in %u secs", dict->timeout_msecs); + i_error("redis: Lookup timed out in %u.%03u secs", + dict->timeout_msecs/1000, dict->timeout_msecs%1000); io_loop_stop(dict->ioloop); } @@ -203,12 +216,19 @@ } else { to = timeout_add(dict->timeout_msecs, redis_dict_lookup_timeout, dict); - cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", - (int)strlen(key), key); - o_stream_send_str(dict->conn.conn.output, cmd); + if (!dict->connected) { + /* wait for connection */ + io_loop_run(dict->ioloop); + } - str_truncate(dict->conn.last_reply, 0); - io_loop_run(dict->ioloop); + if (dict->connected) { + cmd = t_strdup_printf("*2\r\n$3\r\nGET\r\n$%d\r\n%s\r\n", + (int)strlen(key), key); + o_stream_send_str(dict->conn.conn.output, cmd); + + str_truncate(dict->conn.last_reply, 0); + io_loop_run(dict->ioloop); + } timeout_remove(&to); } diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.c --- a/src/lib/connection.c Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib/connection.c Sun Jul 08 09:18:46 2012 +0300 @@ -105,6 +105,7 @@ { const struct connection_settings *set = &conn->list->set; + i_assert(conn->io == NULL); i_assert(conn->input == NULL); i_assert(conn->output == NULL); i_assert(conn->to == NULL); @@ -119,6 +120,7 @@ conn->output = o_stream_create_fd(conn->fd_out, set->output_max_size, FALSE); } + conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { conn->to = timeout_add(set->input_idle_timeout_secs*1000, connection_idle_timeout, conn); @@ -128,12 +130,8 @@ "VERSION\t%s\t%u\t%u\n", set->service_name_out, set->major_version, set->minor_version)); } -} - -static void connection_init_io(struct connection *conn) -{ - i_assert(conn->io == NULL); - conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); + if (conn->list->v.connected != NULL) + conn->list->v.connected(conn); } void connection_init_server(struct connection_list *list, @@ -147,7 +145,6 @@ conn->name = i_strdup(name); conn->fd_in = fd_in; conn->fd_out = fd_out; - connection_init_io(conn); connection_init_streams(conn); DLLIST_PREPEND(&list->connections, conn); @@ -187,7 +184,7 @@ if (conn->to != NULL) timeout_remove(&conn->to); - connection_init_io(conn); + connection_init_streams(conn); } int connection_client_connect(struct connection *conn) @@ -214,9 +211,8 @@ connection_connect_timeout, conn); } } else { - connection_init_io(conn); + connection_init_streams(conn); } - connection_init_streams(conn); return 0; } diff -r 211fbc872ed4 -r 64725ff9c297 src/lib/connection.h --- a/src/lib/connection.h Sun Jul 08 09:00:57 2012 +0300 +++ b/src/lib/connection.h Sun Jul 08 09:18:46 2012 +0300 @@ -27,6 +27,7 @@ struct connection_vfuncs { void (*destroy)(struct connection *conn); + void (*connected)(struct connection *conn); /* implement one of the input*() methods. They return 0 = ok, -1 = error, disconnect the client */ From dovecot at dovecot.org Sun Jul 8 10:29:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sun, 08 Jul 2012 10:29:02 +0300 Subject: dovecot-2.1: pop3c: pop3c_master_user setting broke down non-mas... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5b0c88c43929 changeset: 14610:5b0c88c43929 user: Timo Sirainen date: Sun Jul 08 10:28:38 2012 +0300 description: pop3c: pop3c_master_user setting broke down non-master logins. diffstat: src/lib-storage/index/pop3c/pop3c-client.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 64725ff9c297 -r 5b0c88c43929 src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Sun Jul 08 09:18:46 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Sun Jul 08 10:28:38 2012 +0300 @@ -84,7 +84,7 @@ client->set.debug = set->debug; client->set.host = p_strdup(pool, set->host); client->set.port = set->port; - client->set.master_user = p_strdup(pool, set->master_user); + client->set.master_user = p_strdup_empty(pool, set->master_user); client->set.username = p_strdup(pool, set->username); client->set.password = p_strdup(pool, set->password); client->set.dns_client_socket_path = From dovecot at dovecot.org Wed Jul 11 10:32:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Jul 2012 10:32:27 +0300 Subject: dovecot-2.1: Debian names libtextcat as libexttextcat. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/558e4205c429 changeset: 14611:558e4205c429 user: Timo Sirainen date: Wed Jul 11 09:32:18 2012 +0200 description: Debian names libtextcat as libexttextcat. Patch by Stephan Bosch. diffstat: configure.in | 6 ++++++ src/plugins/fts-lucene/Makefile.am | 4 ++++ src/plugins/fts-lucene/lucene-wrapper.cc | 4 ++++ 3 files changed, 14 insertions(+), 0 deletions(-) diffs (51 lines): diff -r 5b0c88c43929 -r 558e4205c429 configure.in --- a/configure.in Sun Jul 08 10:28:38 2012 +0300 +++ b/configure.in Wed Jul 11 09:32:18 2012 +0200 @@ -2665,6 +2665,11 @@ AC_CHECK_LIB(textcat, special_textcat_Init, [ have_lucene_textcat=yes AC_DEFINE(HAVE_LUCENE_TEXTCAT,, Define if you want textcat support for CLucene) + ], [ + AC_CHECK_LIB(exttextcat, special_textcat_Init, [ + have_lucene_exttextcat=yes + AC_DEFINE(HAVE_LUCENE_EXTTEXTCAT,, Define if you want textcat (Debian version) support for CLucene) + ]) ]) ], [ if test $want_stemmer = yes; then @@ -2677,6 +2682,7 @@ fi AM_CONDITIONAL(BUILD_LUCENE_STEMMER, test "$have_lucene_stemmer" = "yes") AM_CONDITIONAL(BUILD_LUCENE_TEXTCAT, test "$have_lucene_textcat" = "yes") +AM_CONDITIONAL(BUILD_LUCENE_EXTTEXTCAT, test "$have_lucene_exttextcat" = "yes") if test $have_lucene = no; then not_fts="$not_fts lucene" diff -r 5b0c88c43929 -r 558e4205c429 src/plugins/fts-lucene/Makefile.am --- a/src/plugins/fts-lucene/Makefile.am Sun Jul 08 10:28:38 2012 +0300 +++ b/src/plugins/fts-lucene/Makefile.am Wed Jul 11 09:32:18 2012 +0200 @@ -21,6 +21,10 @@ endif if BUILD_LUCENE_TEXTCAT TEXTCAT_LIBS = -ltextcat +else +if BUILD_LUCENE_EXTTEXTCAT +TEXTCAT_LIBS = -lexttextcat +endif endif lib21_fts_lucene_plugin_la_LIBADD = \ diff -r 5b0c88c43929 -r 558e4205c429 src/plugins/fts-lucene/lucene-wrapper.cc --- a/src/plugins/fts-lucene/lucene-wrapper.cc Sun Jul 08 10:28:38 2012 +0300 +++ b/src/plugins/fts-lucene/lucene-wrapper.cc Wed Jul 11 09:32:18 2012 +0200 @@ -18,6 +18,10 @@ #include #ifdef HAVE_LUCENE_TEXTCAT # include +#else +#ifdef HAVE_LUCENE_EXTTEXTCAT +# include +#endif #endif }; #include From dovecot at dovecot.org Wed Jul 11 20:15:13 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 11 Jul 2012 20:15:13 +0300 Subject: dovecot-2.1: mail-log: Log mailbox names with UTF-8 everywhere (... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b4cd382b6606 changeset: 14612:b4cd382b6606 user: Timo Sirainen date: Wed Jul 11 19:15:03 2012 +0200 description: mail-log: Log mailbox names with UTF-8 everywhere (instead of mUTF-7) diffstat: src/plugins/mail-log/mail-log-plugin.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diffs (41 lines): diff -r 558e4205c429 -r b4cd382b6606 src/plugins/mail-log/mail-log-plugin.c --- a/src/plugins/mail-log/mail-log-plugin.c Wed Jul 11 09:32:18 2012 +0200 +++ b/src/plugins/mail-log/mail-log-plugin.c Wed Jul 11 19:15:03 2012 +0200 @@ -363,7 +363,7 @@ const char *desc; desc = t_strdup_printf("copy from %s", - str_sanitize(mailbox_get_name(src->box), + str_sanitize(mailbox_get_vname(src->box), MAILBOX_NAME_LOG_LEN)); mail_log_append_mail_message(ctx, dst, MAIL_LOG_EVENT_COPY, desc); @@ -466,7 +466,7 @@ return; i_info("Mailbox created: %s", - str_sanitize(box->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN)); } static void @@ -478,7 +478,7 @@ return; i_info("Mailbox deleted: %s", - str_sanitize(box->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(box), MAILBOX_NAME_LOG_LEN)); } static void @@ -491,8 +491,8 @@ return; i_info("Mailbox renamed: %s -> %s", - str_sanitize(src->name, MAILBOX_NAME_LOG_LEN), - str_sanitize(dest->name, MAILBOX_NAME_LOG_LEN)); + str_sanitize(mailbox_get_vname(src), MAILBOX_NAME_LOG_LEN), + str_sanitize(mailbox_get_vname(dest), MAILBOX_NAME_LOG_LEN)); } static const struct notify_vfuncs mail_log_vfuncs = { From pigeonhole at rename-it.nl Fri Jul 13 00:40:59 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 12 Jul 2012 23:40:59 +0200 Subject: dovecot-2.2-pigeonhole: Adjusted to Dovecot API changes. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/f9b7eb9a567e changeset: 1631:f9b7eb9a567e user: Stephan Bosch date: Thu Jul 12 23:40:52 2012 +0200 description: Adjusted to Dovecot API changes. diffstat: src/lib-managesieve/managesieve-parser.c | 2 +- src/lib-sieve-tool/mail-raw.c | 3 +-- src/lib-sieve/edit-mail.c | 8 +++----- 3 files changed, 5 insertions(+), 8 deletions(-) diffs (50 lines): diff -r 258d83f111b9 -r f9b7eb9a567e src/lib-managesieve/managesieve-parser.c --- a/src/lib-managesieve/managesieve-parser.c Sun May 20 12:16:43 2012 +0200 +++ b/src/lib-managesieve/managesieve-parser.c Thu Jul 12 23:40:52 2012 +0200 @@ -648,7 +648,7 @@ } /* Allocate buffer space */ - if (!i_stream_get_buffer_space(stream, size, NULL)) + if (!i_stream_try_alloc(stream, size, NULL)) return -2; /* Parse quoted string content */ diff -r 258d83f111b9 -r f9b7eb9a567e src/lib-sieve-tool/mail-raw.c --- a/src/lib-sieve-tool/mail-raw.c Sun May 20 12:16:43 2012 +0200 +++ b/src/lib-sieve-tool/mail-raw.c Thu Jul 12 23:40:52 2012 +0200 @@ -9,7 +9,6 @@ #include "str-sanitize.h" #include "strescape.h" #include "safe-mkstemp.h" -#include "close-keep-errno.h" #include "mkdir-parents.h" #include "abspath.h" #include "message-address.h" @@ -88,7 +87,7 @@ if (unlink(str_c(path)) < 0) { /* shouldn't happen.. */ i_error("unlink(%s) failed: %m", str_c(path)); - close_keep_errno(fd); + i_close_fd(&fd); return -1; } diff -r 258d83f111b9 -r f9b7eb9a567e src/lib-sieve/edit-mail.c --- a/src/lib-sieve/edit-mail.c Sun May 20 12:16:43 2012 +0200 +++ b/src/lib-sieve/edit-mail.c Thu Jul 12 23:40:52 2012 +0200 @@ -534,11 +534,9 @@ /* hdr_data is already unfolded */ /* Decode MIME encoded-words. */ - if ( message_header_decode_utf8 - ((const unsigned char *)hdr_data, hdr_data_len, str, FALSE)) - return i_strdup(str_c(str)); - - return i_strndup(hdr_data, hdr_data_len); + message_header_decode_utf8 + ((const unsigned char *)hdr_data, hdr_data_len, str, FALSE); + return i_strdup(str_c(str)); } static int edit_mail_headers_parse From pigeonhole at rename-it.nl Fri Jul 13 00:58:03 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Thu, 12 Jul 2012 23:58:03 +0200 Subject: dovecot-2.1-pigeonhole: ManageSieve: fixed segfault bug triggere... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/6ceeb6421231 changeset: 1626:6ceeb6421231 user: Stephan Bosch date: Thu Jul 12 23:57:50 2012 +0200 description: ManageSieve: fixed segfault bug triggered by CHECKSCRIPT command. diffstat: src/lib-sievestorage/sieve-storage-save.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diffs (30 lines): diff -r 602d93069d3a -r 6ceeb6421231 src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Sat May 26 00:16:35 2012 +0200 +++ b/src/lib-sievestorage/sieve-storage-save.c Thu Jul 12 23:57:50 2012 +0200 @@ -318,19 +318,20 @@ bool sieve_storage_save_will_activate (struct sieve_save_context *ctx) { - const char *scriptname; - int ret = 0; + bool result = FALSE; - T_BEGIN { + if ( ctx->scriptname != NULL ) T_BEGIN { + const char *scriptname; + int ret; + ret = sieve_storage_get_active_scriptfile(ctx->storage, &scriptname); - if ( ret > 0 ) { /* Is the requested script active? */ - ret = ( strcmp(ctx->scriptname, scriptname) == 0 ? 1 : 0 ); + result = ( strcmp(ctx->scriptname, scriptname) == 0 ); } } T_END; - return ret; + return result; } int sieve_storage_save_commit(struct sieve_save_context **ctx) From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: Merged changes from Dovecot v2.1. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d6ccbf5136bd changeset: 1636:d6ccbf5136bd user: Stephan Bosch date: Fri Jul 13 00:57:00 2012 +0200 description: Merged changes from Dovecot v2.1. diffstat: .hgsigs | 1 + .hgtags | 1 + NEWS | 28 ++++++++++++++++++++++++++++ src/lib-sievestorage/sieve-storage-save.c | 13 +++++++------ 4 files changed, 37 insertions(+), 6 deletions(-) diffs (81 lines): diff -r f9b7eb9a567e -r d6ccbf5136bd .hgsigs --- a/.hgsigs Thu Jul 12 23:40:52 2012 +0200 +++ b/.hgsigs Fri Jul 13 00:57:00 2012 +0200 @@ -4,3 +4,4 @@ 0d071eaa6d5e2a9f524c94ddf1686f1b3091f604 0 iQEcBAABAgAGBQJOb8BjAAoJEATWKx49+7T0cAcH/3coc1MhQj8zUdC+NB3N8eUkQ3AF3QQgSfP9uXs9BhvPw70Ts9MLJiO54RhhYf/k9VxptzWk7MPJF47v4NEEKHkjDDMXtPbVOxHjNa2Ny8EAuWe4dv5X0faAlH4Ks58enDchCmunX1DgQtC1f+gHqVtvTpGAROFPqkBe5RGOJ0jQd+2hTTlf1BpLl44fiBdYd6350haX0KjDGNthX9ETVc3bnbdIiXSy7DPnn0ELhvTbgkl4Zu1tA778IJy/JjsCPb2YueX7LsksvxcSZHqv80Zd3JJhs5a3ZeHijN6twpe7VZD9FO+jPOKA1rr/HYwCv0KweKgmwVHCdaT+Mq4OLPc= 873baa85e2202f45a9c14fa21cccedc60f3715bc 0 iQEcBAABAgAGBQJOx9MCAAoJEATWKx49+7T09aUIANIKsuzM3bGhtGJ/UPIwzpOu39lEGCmHah6dMa+bDOoCZhuhASDdTuvRKXTfGC57GMu+NzBK6I7heFiPD3E4VTI4xOCK1azJ9G4SsiDEkQThucXqWBKDjPB0RgOEf6iefAkslXIU3cprJgattwpeXbUKiHjBhoYJFJ5j/GTx1B62ndvaTfMu1zF5UppiyRG1rQD7FLY4f6kANzSI2jOOCBs4UFH7ZKhafO1AeQfLNDvxdDczZafPZxrCIF+5JCNvQ6Xue/JrvRZQ0V9sxLQat7clUJ6I6Ejl5u5l1LF+VscWldfaQKwDdOktCVux84YGH8+XqXaukMiEg6j4hceAYIM= fe7bd7ee6c2e33e38515cbeca7642135db8dea4b 0 iQEcBAABAgAGBQJPPXAPAAoJEATWKx49+7T0iqMH/3e+RKKmryOz5pak0cvdPcS/D9O9xl2l6SuoE2okTq/WOrDtZ1xDg0afg7t27D9mDfUY1hiSFS4ekN3WP620Gcb9wlL3FC+rLEYmiE8iSfZvsH+FeLa7n8NB+XdnAsXE1WdLQp5CSKEh3sXIod7Q04PL0uv/rimGS9jOGcAufW3y9QAYd+DVorPS4lV5Kz8qIqY9r/0lLqhJN1ukIJtClVkFanRljd+SfoHFFOSWbQjCKNxlOSWFhwJji7Mp091A1+N6JoZe4IMIlajMsM2Ypp726Y2LA/du+uRVFjKgta65eP9tfdrmVCJtrjIjvikowD5Zl80GuVRI5j44aQ7rJ3A= +e9ed5d5cef4b3b27ac5d980b3e4aeadaabeeeae2 0 iQEcBAABAgAGBQJPwAS+AAoJEATWKx49+7T0ngIH/R+teyHN4Pdv4bFTkder85rxy4bzPDzlV9gGlhuKuRBtI8F7CKKWLEP/ESPdtZbMmsNj9k104q2U9pgUfkYrVKL4lrk3hlz44o8Smpwp/xrxyNY8/OuBof0LvyXjp7unHAvvAWFiEmeTpJMmSu77xE8wsEqZowHi8/Igh3lrQ3U129VP1xWr1mvnvQdMQk9TTMK3T38H9kUrz2CRdOWjJbxAA4rLyozGLqWUeSKepUcwAGANd35k8pNLYiONlGU8NZsQyzS2dfOl0TeolgqZn+UkmM9FZFFnD40WU8zPft0nK4g8cFZGObX4fsPyK03EAnR7BXd1BKdmr7jdppAnSvQ= diff -r f9b7eb9a567e -r d6ccbf5136bd .hgtags --- a/.hgtags Thu Jul 12 23:40:52 2012 +0200 +++ b/.hgtags Fri Jul 13 00:57:00 2012 +0200 @@ -10,3 +10,4 @@ 0d071eaa6d5e2a9f524c94ddf1686f1b3091f604 0.2.4 873baa85e2202f45a9c14fa21cccedc60f3715bc 0.2.5 fe7bd7ee6c2e33e38515cbeca7642135db8dea4b 0.3.0 +e9ed5d5cef4b3b27ac5d980b3e4aeadaabeeeae2 0.3.1 diff -r f9b7eb9a567e -r d6ccbf5136bd NEWS --- a/NEWS Thu Jul 12 23:40:52 2012 +0200 +++ b/NEWS Fri Jul 13 00:57:00 2012 +0200 @@ -1,3 +1,31 @@ +v0.3.1 25-05-2012 Stephan Bosch + + * Added support for retrieving Sieve scripts from dict lookup. This means that + Sieve scripts can now be downloaded from a database. Compiled script + binaries are still put on disk somewhere if used. The INSTALL documentation + is updated with information on this new feature and the + (backwards-compatible) changes to the configuration. Note that his feature + is currently not supported for sieve_before/sieve_after or script management + through ManageSieve. + + Incorporated the sieve_duplicate plugin into main Pigeonhole tree as a + normal extension (vnd.dovecot.duplicate). This Dovecot-specific extension + adds the ability to check for duplicate deliveries based on message ID. + Specification can be found in: doc/rfc/spec-bosch-sieve-duplicate.txt + + Added support for specifying multiple sieve_before and sieve_after paths. + This adds much more flexibility to the multiscript configuration. One + application is to have user-specific Sieve scripts outside the user's + normal control through ManageSieve. + + Added a "session ID" string for managesieve connections, available in + %{session} variable (analogous to Dovecot change). + - Fixed several small issues, including a few potential segfault bugs, based + on static source code analysis. + - ManageSieve: changed use of EPROTO error to EIO in ManageSieve string stream + implementation because it is apparently not known in BSD. + - Gave stamp.h.in (needed for autotools) some content to prevent it from + disappearing in patch files. + - Fixed bug that caused a SunStudio CC compile failure (reported by Piotr + Tarnowski). + v0.3.0 16-02-2012 Stephan Bosch * Renamed sieve_global_path setting to sieve_default for clarity. Old name is diff -r f9b7eb9a567e -r d6ccbf5136bd src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Thu Jul 12 23:40:52 2012 +0200 +++ b/src/lib-sievestorage/sieve-storage-save.c Fri Jul 13 00:57:00 2012 +0200 @@ -318,19 +318,20 @@ bool sieve_storage_save_will_activate (struct sieve_save_context *ctx) { - const char *scriptname; - int ret = 0; + bool result = FALSE; - T_BEGIN { + if ( ctx->scriptname != NULL ) T_BEGIN { + const char *scriptname; + int ret; + ret = sieve_storage_get_active_scriptfile(ctx->storage, &scriptname); - if ( ret > 0 ) { /* Is the requested script active? */ - ret = ( strcmp(ctx->scriptname, scriptname) == 0 ? 1 : 0 ); + result = ( strcmp(ctx->scriptname, scriptname) == 0 ); } } T_END; - return ret; + return result; } int sieve_storage_save_commit(struct sieve_save_context **ctx) From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: Added signature for changeset e9ed5d5cef4b Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/602d93069d3a changeset: 1634:602d93069d3a user: Stephan Bosch date: Sat May 26 00:16:35 2012 +0200 description: Added signature for changeset e9ed5d5cef4b diffstat: .hgsigs | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r 396e429dc550 -r 602d93069d3a .hgsigs --- a/.hgsigs Sat May 26 00:14:18 2012 +0200 +++ b/.hgsigs Sat May 26 00:16:35 2012 +0200 @@ -4,3 +4,4 @@ 0d071eaa6d5e2a9f524c94ddf1686f1b3091f604 0 iQEcBAABAgAGBQJOb8BjAAoJEATWKx49+7T0cAcH/3coc1MhQj8zUdC+NB3N8eUkQ3AF3QQgSfP9uXs9BhvPw70Ts9MLJiO54RhhYf/k9VxptzWk7MPJF47v4NEEKHkjDDMXtPbVOxHjNa2Ny8EAuWe4dv5X0faAlH4Ks58enDchCmunX1DgQtC1f+gHqVtvTpGAROFPqkBe5RGOJ0jQd+2hTTlf1BpLl44fiBdYd6350haX0KjDGNthX9ETVc3bnbdIiXSy7DPnn0ELhvTbgkl4Zu1tA778IJy/JjsCPb2YueX7LsksvxcSZHqv80Zd3JJhs5a3ZeHijN6twpe7VZD9FO+jPOKA1rr/HYwCv0KweKgmwVHCdaT+Mq4OLPc= 873baa85e2202f45a9c14fa21cccedc60f3715bc 0 iQEcBAABAgAGBQJOx9MCAAoJEATWKx49+7T09aUIANIKsuzM3bGhtGJ/UPIwzpOu39lEGCmHah6dMa+bDOoCZhuhASDdTuvRKXTfGC57GMu+NzBK6I7heFiPD3E4VTI4xOCK1azJ9G4SsiDEkQThucXqWBKDjPB0RgOEf6iefAkslXIU3cprJgattwpeXbUKiHjBhoYJFJ5j/GTx1B62ndvaTfMu1zF5UppiyRG1rQD7FLY4f6kANzSI2jOOCBs4UFH7ZKhafO1AeQfLNDvxdDczZafPZxrCIF+5JCNvQ6Xue/JrvRZQ0V9sxLQat7clUJ6I6Ejl5u5l1LF+VscWldfaQKwDdOktCVux84YGH8+XqXaukMiEg6j4hceAYIM= fe7bd7ee6c2e33e38515cbeca7642135db8dea4b 0 iQEcBAABAgAGBQJPPXAPAAoJEATWKx49+7T0iqMH/3e+RKKmryOz5pak0cvdPcS/D9O9xl2l6SuoE2okTq/WOrDtZ1xDg0afg7t27D9mDfUY1hiSFS4ekN3WP620Gcb9wlL3FC+rLEYmiE8iSfZvsH+FeLa7n8NB+XdnAsXE1WdLQp5CSKEh3sXIod7Q04PL0uv/rimGS9jOGcAufW3y9QAYd+DVorPS4lV5Kz8qIqY9r/0lLqhJN1ukIJtClVkFanRljd+SfoHFFOSWbQjCKNxlOSWFhwJji7Mp091A1+N6JoZe4IMIlajMsM2Ypp726Y2LA/du+uRVFjKgta65eP9tfdrmVCJtrjIjvikowD5Zl80GuVRI5j44aQ7rJ3A= +e9ed5d5cef4b3b27ac5d980b3e4aeadaabeeeae2 0 iQEcBAABAgAGBQJPwAS+AAoJEATWKx49+7T0ngIH/R+teyHN4Pdv4bFTkder85rxy4bzPDzlV9gGlhuKuRBtI8F7CKKWLEP/ESPdtZbMmsNj9k104q2U9pgUfkYrVKL4lrk3hlz44o8Smpwp/xrxyNY8/OuBof0LvyXjp7unHAvvAWFiEmeTpJMmSu77xE8wsEqZowHi8/Igh3lrQ3U129VP1xWr1mvnvQdMQk9TTMK3T38H9kUrz2CRdOWjJbxAA4rLyozGLqWUeSKepUcwAGANd35k8pNLYiONlGU8NZsQyzS2dfOl0TeolgqZn+UkmM9FZFFnD40WU8zPft0nK4g8cFZGObX4fsPyK03EAnR7BXd1BKdmr7jdppAnSvQ= From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: ManageSieve: fixed segfault caused by Do... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a1668b71e657 changeset: 1637:a1668b71e657 user: Stephan Bosch date: Fri Jul 13 10:06:46 2012 +0200 description: ManageSieve: fixed segfault caused by Dovecot API change. diffstat: src/lib-managesieve/managesieve-parser.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r d6ccbf5136bd -r a1668b71e657 src/lib-managesieve/managesieve-parser.c --- a/src/lib-managesieve/managesieve-parser.c Fri Jul 13 00:57:00 2012 +0200 +++ b/src/lib-managesieve/managesieve-parser.c Fri Jul 13 10:06:46 2012 +0200 @@ -620,7 +620,7 @@ struct quoted_string_istream *qsstream = (struct quoted_string_istream *)stream; const unsigned char *data; - size_t i, dest, size; + size_t i, dest, size, avail; ssize_t ret = 0; bool slash; @@ -648,7 +648,7 @@ } /* Allocate buffer space */ - if (!i_stream_try_alloc(stream, size, NULL)) + if (!i_stream_try_alloc(stream, size, &avail)) return -2; /* Parse quoted string content */ From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: ManageSieve: fixed segfault bug triggere... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/6ceeb6421231 changeset: 1635:6ceeb6421231 user: Stephan Bosch date: Thu Jul 12 23:57:50 2012 +0200 description: ManageSieve: fixed segfault bug triggered by CHECKSCRIPT command. diffstat: src/lib-sievestorage/sieve-storage-save.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diffs (30 lines): diff -r 602d93069d3a -r 6ceeb6421231 src/lib-sievestorage/sieve-storage-save.c --- a/src/lib-sievestorage/sieve-storage-save.c Sat May 26 00:16:35 2012 +0200 +++ b/src/lib-sievestorage/sieve-storage-save.c Thu Jul 12 23:57:50 2012 +0200 @@ -318,19 +318,20 @@ bool sieve_storage_save_will_activate (struct sieve_save_context *ctx) { - const char *scriptname; - int ret = 0; + bool result = FALSE; - T_BEGIN { + if ( ctx->scriptname != NULL ) T_BEGIN { + const char *scriptname; + int ret; + ret = sieve_storage_get_active_scriptfile(ctx->storage, &scriptname); - if ( ret > 0 ) { /* Is the requested script active? */ - ret = ( strcmp(ctx->scriptname, scriptname) == 0 ? 1 : 0 ); + result = ( strcmp(ctx->scriptname, scriptname) == 0 ); } } T_END; - return ret; + return result; } int sieve_storage_save_commit(struct sieve_save_context **ctx) From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: Added tag 0.3.1 for changeset e9ed5d5cef4b Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/396e429dc550 changeset: 1633:396e429dc550 user: Stephan Bosch date: Sat May 26 00:14:18 2012 +0200 description: Added tag 0.3.1 for changeset e9ed5d5cef4b diffstat: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (8 lines): diff -r e9ed5d5cef4b -r 396e429dc550 .hgtags --- a/.hgtags Sat May 26 00:14:05 2012 +0200 +++ b/.hgtags Sat May 26 00:14:18 2012 +0200 @@ -10,3 +10,4 @@ 0d071eaa6d5e2a9f524c94ddf1686f1b3091f604 0.2.4 873baa85e2202f45a9c14fa21cccedc60f3715bc 0.2.5 fe7bd7ee6c2e33e38515cbeca7642135db8dea4b 0.3.0 +e9ed5d5cef4b3b27ac5d980b3e4aeadaabeeeae2 0.3.1 From pigeonhole at rename-it.nl Fri Jul 13 11:06:55 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Fri, 13 Jul 2012 10:06:55 +0200 Subject: dovecot-2.2-pigeonhole: Released v0.3.1 for Dovecot v2.1.6. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e9ed5d5cef4b changeset: 1632:e9ed5d5cef4b user: Stephan Bosch date: Sat May 26 00:14:05 2012 +0200 description: Released v0.3.1 for Dovecot v2.1.6. diffstat: NEWS | 28 ++++++++++++++++++++++++++++ configure.in | 2 +- 2 files changed, 29 insertions(+), 1 deletions(-) diffs (44 lines): diff -r 12bcfe5e748a -r e9ed5d5cef4b NEWS --- a/NEWS Fri May 11 02:54:42 2012 +0200 +++ b/NEWS Sat May 26 00:14:05 2012 +0200 @@ -1,3 +1,31 @@ +v0.3.1 25-05-2012 Stephan Bosch + + * Added support for retrieving Sieve scripts from dict lookup. This means that + Sieve scripts can now be downloaded from a database. Compiled script + binaries are still put on disk somewhere if used. The INSTALL documentation + is updated with information on this new feature and the + (backwards-compatible) changes to the configuration. Note that his feature + is currently not supported for sieve_before/sieve_after or script management + through ManageSieve. + + Incorporated the sieve_duplicate plugin into main Pigeonhole tree as a + normal extension (vnd.dovecot.duplicate). This Dovecot-specific extension + adds the ability to check for duplicate deliveries based on message ID. + Specification can be found in: doc/rfc/spec-bosch-sieve-duplicate.txt + + Added support for specifying multiple sieve_before and sieve_after paths. + This adds much more flexibility to the multiscript configuration. One + application is to have user-specific Sieve scripts outside the user's + normal control through ManageSieve. + + Added a "session ID" string for managesieve connections, available in + %{session} variable (analogous to Dovecot change). + - Fixed several small issues, including a few potential segfault bugs, based + on static source code analysis. + - ManageSieve: changed use of EPROTO error to EIO in ManageSieve string stream + implementation because it is apparently not known in BSD. + - Gave stamp.h.in (needed for autotools) some content to prevent it from + disappearing in patch files. + - Fixed bug that caused a SunStudio CC compile failure (reported by Piotr + Tarnowski). + v0.3.0 16-02-2012 Stephan Bosch * Renamed sieve_global_path setting to sieve_default for clarity. Old name is diff -r 12bcfe5e748a -r e9ed5d5cef4b configure.in --- a/configure.in Fri May 11 02:54:42 2012 +0200 +++ b/configure.in Sat May 26 00:14:05 2012 +0200 @@ -1,4 +1,4 @@ -AC_INIT([Pigeonhole], [0.3.0], [dovecot at dovecot.org], [dovecot-2.1-pigeonhole]) +AC_INIT([Pigeonhole], [0.3.1], [dovecot at dovecot.org], [dovecot-2.1-pigeonhole]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) From dovecot at dovecot.org Mon Jul 16 16:49:21 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 16:49:21 +0300 Subject: dovecot-2.1: login: If ssl_key parsing fails, log the reason. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5bbdfee113a5 changeset: 14613:5bbdfee113a5 user: Timo Sirainen date: Mon Jul 16 16:49:16 2012 +0300 description: login: If ssl_key parsing fails, log the reason. diffstat: src/login-common/ssl-proxy-openssl.c | 28 +++++++++++++++------------- 1 files changed, 15 insertions(+), 13 deletions(-) diffs (49 lines): diff -r b4cd382b6606 -r 5bbdfee113a5 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Wed Jul 11 19:15:03 2012 +0200 +++ b/src/login-common/ssl-proxy-openssl.c Mon Jul 16 16:49:16 2012 +0300 @@ -1026,6 +1026,17 @@ } } +static const char *ssl_key_load_error(void) +{ + unsigned long err = ERR_peek_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_X509 && + ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) + return "Key is for a different cert than ssl_cert"; + else + return ssl_last_error(); +} + static EVP_PKEY * ssl_proxy_load_key(const char *key, const char *password) { @@ -1040,23 +1051,14 @@ dup_password = t_strdup_noconst(password); pkey = PEM_read_bio_PrivateKey(bio, NULL, pem_password_callback, dup_password); - if (pkey == NULL) - i_fatal("Couldn't parse private ssl_key"); + if (pkey == NULL) { + i_fatal("Couldn't parse private ssl_key: %s", + ssl_key_load_error()); + } BIO_free(bio); return pkey; } -static const char *ssl_key_load_error(void) -{ - unsigned long err = ERR_peek_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_X509 && - ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH) - return "Key is for a different cert than ssl_cert"; - else - return ssl_last_error(); -} - static void ssl_proxy_ctx_use_key(SSL_CTX *ctx, const struct login_settings *set) { EVP_PKEY *pkey; From dovecot at dovecot.org Mon Jul 16 16:59:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 16:59:56 +0300 Subject: dovecot-2.2: lib-storage: Search crashfix. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4fb231804670 changeset: 14711:4fb231804670 user: Timo Sirainen date: Mon Jul 16 16:59:51 2012 +0300 description: lib-storage: Search crashfix. diffstat: src/lib-storage/index/index-search.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diffs (20 lines): diff -r 94fd1ec48e81 -r 4fb231804670 src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Thu Jul 05 16:11:00 2012 +0300 +++ b/src/lib-storage/index/index-search.c Mon Jul 16 16:59:51 2012 +0300 @@ -151,14 +151,13 @@ static bool index_search_get_pvt(struct index_search_context *ctx, uint32_t uid) { - if (ctx->pvt_uid == uid) - return ctx->pvt_seq != 0; - if (ctx->box->view_pvt == NULL) { /* no private view (set by view syncing) -> no private flags */ return FALSE; } + if (ctx->pvt_uid == uid) + return ctx->pvt_seq != 0; ctx->pvt_uid = uid; return mail_index_lookup_seq(ctx->mail_ctx.transaction->view_pvt, uid, &ctx->pvt_seq); From dovecot at dovecot.org Mon Jul 16 17:40:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 17:40:56 +0300 Subject: dovecot-2.1: lib-storage: %h variable didn't necessarily expand ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/abaafe4cc439 changeset: 14614:abaafe4cc439 user: Timo Sirainen date: Mon Jul 16 17:40:45 2012 +0300 description: lib-storage: %h variable didn't necessarily expand correctly for shared users' settings. diffstat: src/lib-storage/mail-user.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diffs (14 lines): diff -r 5bbdfee113a5 -r abaafe4cc439 src/lib-storage/mail-user.c --- a/src/lib-storage/mail-user.c Mon Jul 16 16:49:16 2012 +0300 +++ b/src/lib-storage/mail-user.c Mon Jul 16 17:40:45 2012 +0300 @@ -201,7 +201,9 @@ }; struct var_expand_table *tab; - if (user->var_expand_table != NULL) + /* use a cached table, unless home directory has been set afterwards */ + if (user->var_expand_table != NULL && + user->var_expand_table[4].value == user->_home) return user->var_expand_table; tab = p_malloc(user->pool, sizeof(static_tab)); From dovecot at dovecot.org Mon Jul 16 18:00:42 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 18:00:42 +0300 Subject: dovecot-2.1: quota: ns=PREFIX setting was ignored when accessing... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/30b0d6b1c581 changeset: 14615:30b0d6b1c581 user: Timo Sirainen date: Mon Jul 16 18:00:21 2012 +0300 description: quota: ns=PREFIX setting was ignored when accessing other users' shared mailboxes. diffstat: src/plugins/quota/quota-private.h | 5 ++++- src/plugins/quota/quota.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diffs (27 lines): diff -r abaafe4cc439 -r 30b0d6b1c581 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Mon Jul 16 17:40:45 2012 +0300 +++ b/src/plugins/quota/quota-private.h Mon Jul 16 18:00:21 2012 +0300 @@ -101,7 +101,10 @@ /* this quota root applies only to this namespace. it may also be a public namespace without an owner. */ struct mail_namespace *ns; - /* this is set in quota init(), because namespaces aren't known yet */ + /* this is set in quota init(), because namespaces aren't known yet. + when accessing shared users the ns_prefix may be non-NULL but + ns=NULL, so when checking if quota root applies only to a specific + namespace use the ns_prefix!=NULL check. */ const char *ns_prefix; /* initially the same as set->default_rule.*_limit, but some backends diff -r abaafe4cc439 -r 30b0d6b1c581 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Mon Jul 16 17:40:45 2012 +0300 +++ b/src/plugins/quota/quota.c Mon Jul 16 18:00:21 2012 +0300 @@ -769,7 +769,7 @@ (storage->class_flags & MAIL_STORAGE_CLASS_FLAG_NOQUOTA) != 0) return FALSE; - if (root->ns != NULL) { + if (root->ns_prefix != NULL) { if (root->ns != ns) return FALSE; } else { From dovecot at dovecot.org Mon Jul 16 18:25:00 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 18:25:00 +0300 Subject: dovecot-2.2: master: Create missing /var/lib/dovecot/ with world... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/744a1037ce86 changeset: 14712:744a1037ce86 user: Timo Sirainen date: Mon Jul 16 18:24:53 2012 +0300 description: master: Create missing /var/lib/dovecot/ with world-read-exec permissions. There's really nothing secret in the directory and in some setups this change had to be done manually anyway. diffstat: src/master/master-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 4fb231804670 -r 744a1037ce86 src/master/master-settings.c --- a/src/master/master-settings.c Mon Jul 16 16:59:51 2012 +0300 +++ b/src/master/master-settings.c Mon Jul 16 18:24:53 2012 +0300 @@ -731,7 +731,7 @@ } /* Make sure our permanent state directory exists */ - if (mkdir_parents(PKG_STATEDIR, 0750) < 0 && errno != EEXIST) + if (mkdir_parents(PKG_STATEDIR, 0755) < 0 && errno != EEXIST) i_fatal("mkdir(%s) failed: %m", PKG_STATEDIR); login_dir = t_strconcat(set->base_dir, "/login", NULL); From dovecot at dovecot.org Mon Jul 16 20:42:02 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 20:42:02 +0300 Subject: dovecot-2.2: imap: Updated MOVE implementation. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/76fe255ba921 changeset: 14713:76fe255ba921 user: Timo Sirainen date: Mon Jul 16 20:41:51 2012 +0300 description: imap: Updated MOVE implementation. diffstat: src/imap/cmd-copy.c | 19 ++++++++++++++----- src/imap/imap-commands.c | 3 ++- src/imap/imap-commands.h | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diffs (68 lines): diff -r 744a1037ce86 -r 76fe255ba921 src/imap/cmd-copy.c --- a/src/imap/cmd-copy.c Mon Jul 16 18:24:53 2012 +0300 +++ b/src/imap/cmd-copy.c Mon Jul 16 20:41:51 2012 +0300 @@ -137,16 +137,25 @@ str_append(msg, move ? "OK Move completed." : "OK Copy completed."); pool_unref(&changes.pool); + } else if (move) { + i_assert(copy_count == seq_range_count(&changes.saved_uids)); + + str_printfa(msg, "* OK [COPYUID %u %s", + changes.uid_validity, src_uidset); + imap_write_seq_range(msg, &changes.saved_uids); + str_append(msg, "] Moved UIDs."); + client_send_line(client, str_c(msg)); + + str_truncate(msg, 0); + str_append(msg, "OK Move completed."); + pool_unref(&changes.pool); } else { i_assert(copy_count == seq_range_count(&changes.saved_uids)); str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity, src_uidset); imap_write_seq_range(msg, &changes.saved_uids); - if (move) - str_append(msg, "] Move completed."); - else - str_append(msg, "] Copy completed."); + str_append(msg, "] Copy completed."); pool_unref(&changes.pool); } @@ -183,7 +192,7 @@ return cmd_copy_full(cmd, FALSE); } -bool cmd_uid_move(struct client_command_context *cmd) +bool cmd_move(struct client_command_context *cmd) { return cmd_copy_full(cmd, TRUE); } diff -r 744a1037ce86 -r 76fe255ba921 src/imap/imap-commands.c --- a/src/imap/imap-commands.c Mon Jul 16 18:24:53 2012 +0300 +++ b/src/imap/imap-commands.c Mon Jul 16 20:41:51 2012 +0300 @@ -56,8 +56,9 @@ { "SORT", cmd_sort, COMMAND_FLAG_USES_SEQS }, { "THREAD", cmd_thread, COMMAND_FLAG_USES_SEQS }, { "UID EXPUNGE", cmd_uid_expunge, COMMAND_FLAG_BREAKS_SEQS }, - { "UID MOVE", cmd_uid_move, COMMAND_FLAG_USES_SEQS | + { "MOVE", cmd_move, COMMAND_FLAG_USES_SEQS | COMMAND_FLAG_BREAKS_SEQS }, + { "UID MOVE", cmd_move, COMMAND_FLAG_BREAKS_SEQS }, { "UID SORT", cmd_sort, COMMAND_FLAG_BREAKS_SEQS }, { "UID THREAD", cmd_thread, COMMAND_FLAG_BREAKS_SEQS }, { "UNSELECT", cmd_unselect, COMMAND_FLAG_BREAKS_MAILBOX }, diff -r 744a1037ce86 -r 76fe255ba921 src/imap/imap-commands.h --- a/src/imap/imap-commands.h Mon Jul 16 18:24:53 2012 +0300 +++ b/src/imap/imap-commands.h Mon Jul 16 20:41:51 2012 +0300 @@ -110,7 +110,7 @@ bool cmd_sort(struct client_command_context *cmd); bool cmd_thread(struct client_command_context *cmd); bool cmd_uid_expunge(struct client_command_context *cmd); -bool cmd_uid_move(struct client_command_context *cmd); +bool cmd_move(struct client_command_context *cmd); bool cmd_unselect(struct client_command_context *cmd); bool cmd_x_cancel(struct client_command_context *cmd); From pigeonhole at rename-it.nl Mon Jul 16 22:37:27 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 16 Jul 2012 21:37:27 +0200 Subject: dovecot-2.1-pigeonhole: Example config: disabled default section... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/e6d102e6f0fc changeset: 1627:e6d102e6f0fc user: Stephan Bosch date: Mon Jul 16 21:36:23 2012 +0200 description: Example config: disabled default sections for managesieve and managesieve-login services. This currently breaks uninstall when the settings plugins are removed and 20-managesieve.conf remains in conf.d directory. These sections only need to be active in the config file when settings for the services themselves need to be disabled. diffstat: doc/example-config/conf.d/20-managesieve.conf | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (28 lines): diff -r 6ceeb6421231 -r e6d102e6f0fc doc/example-config/conf.d/20-managesieve.conf --- a/doc/example-config/conf.d/20-managesieve.conf Thu Jul 12 23:57:50 2012 +0200 +++ b/doc/example-config/conf.d/20-managesieve.conf Mon Jul 16 21:36:23 2012 +0200 @@ -7,7 +7,7 @@ # Service definitions -service managesieve-login { +#service managesieve-login { #inet_listener sieve { # port = 4190 #} @@ -26,12 +26,12 @@ # If you set service_count=0, you probably need to grow this. #vsz_limit = 64M -} +#} -service managesieve { +#service managesieve { # Max. number of ManageSieve processes (connections) #process_count = 1024 -} +#} # Service configuration From dovecot at dovecot.org Mon Jul 16 23:15:31 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 16 Jul 2012 23:15:31 +0300 Subject: dovecot-2.1: doveconf: When looking up specific settings, ignore... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/892ab0a8ab9c changeset: 14616:892ab0a8ab9c user: Timo Sirainen date: Mon Jul 16 23:15:19 2012 +0300 description: doveconf: When looking up specific settings, ignore errors found by check functions. diffstat: src/config/doveconf.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diffs (24 lines): diff -r 30b0d6b1c581 -r 892ab0a8ab9c src/config/doveconf.c --- a/src/config/doveconf.c Mon Jul 16 18:00:21 2012 +0300 +++ b/src/config/doveconf.c Mon Jul 16 23:15:19 2012 +0300 @@ -451,7 +451,7 @@ unsigned int len; bool dump_section = FALSE; - ctx = config_dump_human_init("", scope, TRUE); + ctx = config_dump_human_init("", scope, FALSE); config_export_by_filter(ctx->export_ctx, filter); if (config_export_finish(&ctx->export_ctx) < 0) return -1; @@ -693,6 +693,11 @@ ret2 = config_export_finish(&ctx); } else if (setting_name_filters != NULL) { ret2 = 0; + /* ignore settings-check failures in configuration. this allows + using doveconf to lookup settings for things like install or + uninstall scripts where the configuration might + (temporarily) not be fully usable */ + ret = 0; for (i = 0; setting_name_filters[i] != NULL; i++) { if (config_dump_one(&filter, hide_key, scope, setting_name_filters[i]) < 0) From dovecot at dovecot.org Tue Jul 17 14:57:56 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 14:57:56 +0300 Subject: dovecot-2.1: master: "/X is no longer mounted" warning now point... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/9366cfaefdaa changeset: 14617:9366cfaefdaa user: Timo Sirainen date: Tue Jul 17 14:57:44 2012 +0300 description: master: "/X is no longer mounted" warning now points to wiki page. diffstat: src/master/main.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (13 lines): diff -r 892ab0a8ab9c -r 9366cfaefdaa src/master/main.c --- a/src/master/main.c Mon Jul 16 23:15:19 2012 +0300 +++ b/src/master/main.c Tue Jul 17 14:57:44 2012 +0300 @@ -299,8 +299,7 @@ while ((rec = mountpoint_list_iter_next(iter)) != NULL) { if (MOUNTPOINT_WRONGLY_NOT_MOUNTED(rec)) { i_warning("%s is no longer mounted. " - "If this is intentional, " - "remove it with doveadm mount", + "See http://wiki2.dovecot.org/Mountpoints", rec->mount_path); } } From dovecot at dovecot.org Tue Jul 17 15:10:48 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:10:48 +0300 Subject: dovecot-2.1: lib-mail: mail_user_hash() has now a faster code pa... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/5ad46e104c07 changeset: 14618:5ad46e104c07 user: Timo Sirainen date: Tue Jul 17 15:10:35 2012 +0300 description: lib-mail: mail_user_hash() has now a faster code path for format=%Lu diffstat: src/lib-mail/mail-user-hash.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diffs (16 lines): diff -r 9366cfaefdaa -r 5ad46e104c07 src/lib-mail/mail-user-hash.c --- a/src/lib-mail/mail-user-hash.c Tue Jul 17 14:57:44 2012 +0300 +++ b/src/lib-mail/mail-user-hash.c Tue Jul 17 15:10:35 2012 +0300 @@ -21,6 +21,12 @@ if (strcmp(format, "%u") == 0) { /* fast path */ md5_get_digest(username, strlen(username), md5); + } else if (strcmp(format, "%Lu") == 0) { + /* almost as fast path */ + T_BEGIN { + md5_get_digest(t_str_lcase(username), + strlen(username), md5); + } T_END; } else T_BEGIN { string_t *str = t_str_new(128); From dovecot at dovecot.org Tue Jul 17 15:14:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:14:27 +0300 Subject: dovecot-2.1: example-config: Added director_username_hash setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0722a06a0d9f changeset: 14619:0722a06a0d9f user: Timo Sirainen date: Tue Jul 17 15:13:21 2012 +0300 description: example-config: Added director_username_hash setting. diffstat: doc/example-config/conf.d/10-director.conf | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (15 lines): diff -r 5ad46e104c07 -r 0722a06a0d9f doc/example-config/conf.d/10-director.conf --- a/doc/example-config/conf.d/10-director.conf Tue Jul 17 15:10:35 2012 +0300 +++ b/doc/example-config/conf.d/10-director.conf Tue Jul 17 15:13:21 2012 +0300 @@ -25,6 +25,11 @@ # If you enable this, you'll also need to add inet_listener for the port. #director_doveadm_port = 0 +# How the username is translated before being hashed. Useful values include +# %Ln if user can log in with or without @domain, %Ld if mailboxes are shared +# within domain. +#director_username_hash = %Lu + # To enable director service, uncomment the modes and assign a port. service director { unix_listener login/director { From dovecot at dovecot.org Tue Jul 17 15:14:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:14:27 +0300 Subject: dovecot-2.1: director: Changed director_username_hash setting's ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/36c3d44a5ba3 changeset: 14620:36c3d44a5ba3 user: Timo Sirainen date: Tue Jul 17 15:14:21 2012 +0300 description: director: Changed director_username_hash setting's default from %u to %Lu This allows potential trouble when username isn't always lowercased. diffstat: src/director/director-settings.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0722a06a0d9f -r 36c3d44a5ba3 src/director/director-settings.c --- a/src/director/director-settings.c Tue Jul 17 15:13:21 2012 +0300 +++ b/src/director/director-settings.c Tue Jul 17 15:14:21 2012 +0300 @@ -80,7 +80,7 @@ .director_servers = "", .director_mail_servers = "", - .director_username_hash = "%u", + .director_username_hash = "%Lu", .director_user_expire = 60*15, .director_doveadm_port = 0 }; From dovecot at dovecot.org Tue Jul 17 15:21:37 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:21:37 +0300 Subject: dovecot-2.1: lib-master: Updated default mountpoint ignore prefi... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/77b52599e883 changeset: 14621:77b52599e883 user: Timo Sirainen date: Tue Jul 17 15:21:32 2012 +0300 description: lib-master: Updated default mountpoint ignore prefix list. diffstat: src/lib-master/mountpoint-list.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (12 lines): diff -r 36c3d44a5ba3 -r 77b52599e883 src/lib-master/mountpoint-list.c --- a/src/lib-master/mountpoint-list.c Tue Jul 17 15:14:21 2012 +0300 +++ b/src/lib-master/mountpoint-list.c Tue Jul 17 15:21:32 2012 +0300 @@ -55,6 +55,8 @@ "/media", "/sys", "/proc", + "/var/run", + "/run", NULL }; From dovecot at dovecot.org Tue Jul 17 15:28:43 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:28:43 +0300 Subject: dovecot-2.1: login: Don't allow STARTTLS if ssl=no in client's s... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/258c2e231357 changeset: 14622:258c2e231357 user: Timo Sirainen date: Tue Jul 17 15:28:24 2012 +0300 description: login: Don't allow STARTTLS if ssl=no in client's settings, even if ssl=yes globally. diffstat: src/imap-login/client.c | 2 +- src/login-common/client-common.c | 7 ++++++- src/login-common/client-common.h | 1 + src/pop3-login/client-authenticate.c | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diffs (59 lines): diff -r 77b52599e883 -r 258c2e231357 src/imap-login/client.c --- a/src/imap-login/client.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/imap-login/client.c Tue Jul 17 15:28:24 2012 +0300 @@ -62,7 +62,7 @@ str_append(cap_str, imap_client->set->imap_capability + 1); } - if (ssl_initialized && !client->tls) + if (client_is_tls_enabled(client) && !client->tls) str_append(cap_str, " STARTTLS"); if (client->set->disable_plaintext_auth && !client->secured) str_append(cap_str, " LOGINDISABLED"); diff -r 77b52599e883 -r 258c2e231357 src/login-common/client-common.c --- a/src/login-common/client-common.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/login-common/client-common.c Tue Jul 17 15:28:24 2012 +0300 @@ -346,7 +346,7 @@ return; } - if (!ssl_initialized) { + if (!client_is_tls_enabled(client)) { client_send_line(client, CLIENT_CMD_REPLY_BAD, "TLS support isn't enabled."); return; @@ -591,6 +591,11 @@ return FALSE; } +bool client_is_tls_enabled(struct client *client) +{ + return ssl_initialized && strcmp(client->set->ssl, "no") != 0; +} + const char *client_get_extra_disconnect_reason(struct client *client) { unsigned int auth_secs = client->auth_first_started == 0 ? 0 : diff -r 77b52599e883 -r 258c2e231357 src/login-common/client-common.h --- a/src/login-common/client-common.h Tue Jul 17 15:21:32 2012 +0300 +++ b/src/login-common/client-common.h Tue Jul 17 15:28:24 2012 +0300 @@ -168,6 +168,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); +bool client_is_tls_enabled(struct client *client); const char *client_get_session_id(struct client *client); bool client_read(struct client *client); diff -r 77b52599e883 -r 258c2e231357 src/pop3-login/client-authenticate.c --- a/src/pop3-login/client-authenticate.c Tue Jul 17 15:21:32 2012 +0300 +++ b/src/pop3-login/client-authenticate.c Tue Jul 17 15:28:24 2012 +0300 @@ -33,7 +33,7 @@ str_append(str, "+OK\r\n"); str_append(str, capability_string); - if (ssl_initialized && !client->common.tls) + if (client_is_tls_enabled(&client->common) && !client->common.tls) str_append(str, "STLS\r\n"); if (!client->common.set->disable_plaintext_auth || client->common.secured) From dovecot at dovecot.org Tue Jul 17 15:31:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:31:11 +0300 Subject: dovecot-2.1: doc: Install mkcert.sh, dovecot-openssl.cnf and sol... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/d01a06d821cf changeset: 14623:d01a06d821cf user: Timo Sirainen date: Tue Jul 17 15:31:03 2012 +0300 description: doc: Install mkcert.sh, dovecot-openssl.cnf and solr-schema.xml files. diffstat: doc/Makefile.am | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (23 lines): diff -r 258c2e231357 -r d01a06d821cf doc/Makefile.am --- a/doc/Makefile.am Tue Jul 17 15:28:24 2012 +0300 +++ b/doc/Makefile.am Tue Jul 17 15:31:03 2012 +0300 @@ -7,7 +7,10 @@ docfiles = \ documentation.txt \ securecoding.txt \ - thread-refs.txt + thread-refs.txt \ + mkcert.sh \ + dovecot-openssl.cnf \ + solr-schema.xml if BUILD_DOCS doc_DATA = $(docfiles) @@ -15,7 +18,4 @@ EXTRA_DIST = \ dovecot-initd.sh \ - mkcert.sh \ - dovecot-openssl.cnf \ - solr-schema.xml \ $(docfiles) From dovecot at dovecot.org Tue Jul 17 15:44:49 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 15:44:49 +0300 Subject: dovecot-2.1: config: Fixed error reporting when reloading settin... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/56ef4e70b1a9 changeset: 14624:56ef4e70b1a9 user: Timo Sirainen date: Tue Jul 17 15:44:36 2012 +0300 description: config: Fixed error reporting when reloading settings for master process fails. diffstat: src/config/config-connection.c | 2 +- src/lib-settings/settings-parser.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diffs (24 lines): diff -r d01a06d821cf -r 56ef4e70b1a9 src/config/config-connection.c --- a/src/config/config-connection.c Tue Jul 17 15:31:03 2012 +0300 +++ b/src/config/config-connection.c Tue Jul 17 15:44:36 2012 +0300 @@ -100,7 +100,7 @@ path = master_service_get_config_path(master_service); if (config_parse_file(path, TRUE, "", &error) <= 0) { o_stream_send_str(conn->output, - t_strconcat("ERROR ", error, "\n", NULL)); + t_strconcat("\nERROR ", error, "\n", NULL)); config_connection_destroy(conn); return -1; } diff -r d01a06d821cf -r 56ef4e70b1a9 src/lib-settings/settings-parser.c --- a/src/lib-settings/settings-parser.c Tue Jul 17 15:31:03 2012 +0300 +++ b/src/lib-settings/settings-parser.c Tue Jul 17 15:44:36 2012 +0300 @@ -945,6 +945,8 @@ switch (ret) { case -1: + if (ctx->error != NULL) + break; if (input->stream_errno != 0) { ctx->error = p_strdup_printf(ctx->parser_pool, "read() failed: %m"); From dovecot at dovecot.org Tue Jul 17 16:04:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 16:04:06 +0300 Subject: dovecot-2.2: quota: Support for fs hard limit Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/cdba6fec5ddf changeset: 14714:cdba6fec5ddf user: Jan Friesse date: Tue Jul 17 16:03:43 2012 +0300 description: quota: Support for fs hard limit Support for hard limit is implemented for NFS, but sadly not for other filesystems. If softlimit is not set (it's 0), hardlimit should be used. --- src/plugins/quota/quota-fs.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-) diffstat: src/plugins/quota/quota-fs.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-) diffs (84 lines): diff -r 76fe255ba921 -r cdba6fec5ddf src/plugins/quota/quota-fs.c --- a/src/plugins/quota/quota-fs.c Mon Jul 16 20:41:51 2012 +0300 +++ b/src/plugins/quota/quota-fs.c Tue Jul 17 16:03:43 2012 +0300 @@ -566,9 +566,15 @@ /* values always returned in 512 byte blocks */ *value_r = xdqblk.d_bcount * 512; *limit_r = xdqblk.d_blk_softlimit * 512; + if (*limit_r == 0) { + *limit_r = xdqblk.d_blk_hardlimit * 512; + } } else { *value_r = xdqblk.d_icount; *limit_r = xdqblk.d_ino_softlimit; + if (*limit_r == 0) { + *limit_r = xdqblk.d_ino_hardlimit; + } } } else #endif @@ -600,9 +606,15 @@ *value_r = dqblk.dqb_curblocks; #endif *limit_r = dqblk.dqb_bsoftlimit * 1024; + if (*limit_r == 0) { + *limit_r = dqblk.dqb_bhardlimit * 1024; + } } else { *value_r = dqblk.dqb_curinodes; *limit_r = dqblk.dqb_isoftlimit; + if (*limit_r == 0) { + *limit_r = dqblk.dqb_ihardlimit; + } } } return 1; @@ -633,9 +645,15 @@ if (bytes) { *value_r = (uint64_t)dqblk.dqb_curblocks * DEV_BSIZE; *limit_r = (uint64_t)dqblk.dqb_bsoftlimit * DEV_BSIZE; + if (*limit_r == 0) { + *limit_r = (uint64_t)dqblk.dqb_bhardlimit * DEV_BSIZE; + } } else { *value_r = dqblk.dqb_curinodes; *limit_r = dqblk.dqb_isoftlimit; + if (*limit_r == 0) { + *limit_r = dqblk.dqb_ihardlimit; + } } return 1; } @@ -664,9 +682,16 @@ root->mount->block_size; *limit_r = (uint64_t)dqblk.dqb_bsoftlimit * root->mount->block_size; + if (*limit_r == 0) { + *limit_r = (uint64_t)dqblk.dqb_bhardlimit * + root->mount->block_size; + } } else { *value_r = dqblk.dqb_curfiles; *limit_r = dqblk.dqb_fsoftlimit; + if (*limit_r == 0) { + *limit_r = dqblk.dqb_fhardlimit; + } } return 1; } @@ -693,9 +718,15 @@ if (bytes) { *value_r = (uint64_t)dqblk.dqb_curblocks * DEV_BSIZE; *limit_r = (uint64_t)dqblk.dqb_bsoftlimit * DEV_BSIZE; + if (*limit_r == 0) { + *limit_r = (uint64_t)dqblk.dqb_bhardlimit * DEV_BSIZE; + } } else { *value_r = dqblk.dqb_curfiles; *limit_r = dqblk.dqb_fsoftlimit; + if (*limit_r == 0) { + *limit_r = dqblk.dqb_fhardlimit; + } } return 1; } From dovecot at dovecot.org Tue Jul 17 16:20:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 16:20:36 +0300 Subject: dovecot-2.1: auth: GSSAPI RFC compliancy fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ced6a796f56d changeset: 14625:ced6a796f56d user: Timo Sirainen date: Tue Jul 17 16:17:40 2012 +0300 description: auth: GSSAPI RFC compliancy fixes. Patch by Ben Morrow: The first problem is that, because of the way the client invokes libsasl, it sends a GSSAPI request which does not ask for mutual authentication. This means that on the server gss_accept_sec_context returns GSS_S_COMPLETE with a zero-length output token. Dovecot currently sends this to the client as a zero-length continuation response, but this is incorrect according to RFC 4752: what it ought to do instead is proceed straight to the security layer negotiations, and send a gss_wrap packet. The second is that Cyrus sends an empty authz identity; that is, the security layer negotiation packet, when gss_unwrapped, is exactly 4 bytes long. Dovecot objects to this, but in RFC 4422 this is explicitly allowed, and means the authz identity is identical to the authn identity. diffstat: src/auth/mech-gssapi.c | 58 +++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 46 insertions(+), 12 deletions(-) diffs (96 lines): diff -r 56ef4e70b1a9 -r ced6a796f56d src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Tue Jul 17 15:44:36 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:17:40 2012 +0300 @@ -78,6 +78,9 @@ static gss_OID_desc mech_gssapi_krb5_oid = { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; +static int +mech_gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf); + static void mech_gssapi_log_error(struct auth_request *request, OM_uint32 status_value, int status_type, const char *description) @@ -214,6 +217,21 @@ return name; } +static gss_name_t +duplicate_name(struct auth_request *request, gss_name_t old) +{ + OM_uint32 major_status, minor_status; + gss_name_t new; + + major_status = gss_duplicate_name(&minor_status, old, &new); + if (GSS_ERROR(major_status)) { + mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE, + "gss_duplicate_name"); + return GSS_C_NO_NAME; + } + return new; +} + static bool data_has_nuls(const void *data, unsigned int len) { const unsigned char *c = data; @@ -328,9 +346,15 @@ } if (ret == 0) { - auth_request_handler_reply_continue(auth_request, - output_token.value, - output_token.length); + if (output_token.length > 0) { + auth_request_handler_reply_continue(auth_request, + output_token.value, + output_token.length); + } else { + /* If there is no output token, go straight to wrap, + which is expecting an empty input token. */ + ret = mech_gssapi_wrap(request, output_token); + } } (void)gss_release_buffer(&minor_status, &output_token); return ret; @@ -510,22 +534,32 @@ /* outbuf[0] contains bitmask for selected security layer, outbuf[1..3] contains maximum output_message size */ - if (outbuf.length <= 4) { + if (outbuf.length < 4) { auth_request_log_error(auth_request, "gssapi", "Invalid response length"); return -1; } - name = (unsigned char *)outbuf.value + 4; - name_len = outbuf.length - 4; - if (data_has_nuls(name, name_len)) { - auth_request_log_info(auth_request, "gssapi", - "authz_name has NULs"); - return -1; + if (outbuf.length > 4) { + name = (unsigned char *)outbuf.value + 4; + name_len = outbuf.length - 4; + + if (data_has_nuls(name, name_len)) { + auth_request_log_info(auth_request, "gssapi", + "authz_name has NULs"); + return -1; + } + + login_user = p_strndup(auth_request->pool, name, name_len); + request->authz_name = import_name(auth_request, name, name_len); + } else { + request->authz_name = duplicate_name(auth_request, + request->authn_name); + if (get_display_name(auth_request, request->authz_name, + NULL, &login_user) < 0) + return -1; } - login_user = p_strndup(auth_request->pool, name, name_len); - request->authz_name = import_name(auth_request, name, name_len); if (request->authz_name == GSS_C_NO_NAME) { auth_request_log_info(auth_request, "gssapi", "no authz_name"); return -1; From dovecot at dovecot.org Tue Jul 17 16:20:36 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 16:20:36 +0300 Subject: dovecot-2.1: auth: Fixed error handling in GSSAPI when __gss_use... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/35ae9569de5a changeset: 14626:35ae9569de5a user: Timo Sirainen date: Tue Jul 17 16:20:20 2012 +0300 description: auth: Fixed error handling in GSSAPI when __gss_userok() was used. An invalid username would have been treated as successful and auth process probably would have crashed. diffstat: src/auth/mech-gssapi.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r ced6a796f56d -r 35ae9569de5a src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Tue Jul 17 16:17:40 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:20:20 2012 +0300 @@ -416,8 +416,8 @@ bool ret = FALSE; /* Parse out the principal's username */ - if (!get_display_name(&request->auth_request, name, &name_type, - &princ_display_name) < 0) + if (get_display_name(&request->auth_request, name, &name_type, + &princ_display_name) < 0) return FALSE; if (!mech_gssapi_oid_cmp(name_type, GSS_KRB5_NT_PRINCIPAL_NAME) && From dovecot at dovecot.org Tue Jul 17 16:21:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 16:21:54 +0300 Subject: dovecot-2.0: auth: Fixed error handling in GSSAPI when __gss_use... Message-ID: details: http://hg.dovecot.org/dovecot-2.0/rev/13b8b90bed3e changeset: 13105:13b8b90bed3e user: Timo Sirainen date: Tue Jul 17 16:20:20 2012 +0300 description: auth: Fixed error handling in GSSAPI when __gss_userok() was used. An invalid username would have been treated as successful and auth process probably would have crashed. diffstat: src/auth/mech-gssapi.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r ac6fec6057e6 -r 13b8b90bed3e src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Mon Jul 02 08:06:19 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:20:20 2012 +0300 @@ -392,8 +392,8 @@ bool ret = FALSE; /* Parse out the principal's username */ - if (!get_display_name(&request->auth_request, name, &name_type, - &princ_display_name) < 0) + if (get_display_name(&request->auth_request, name, &name_type, + &princ_display_name) < 0) return FALSE; if (!mech_gssapi_oid_cmp(name_type, GSS_KRB5_NT_PRINCIPAL_NAME) && From dovecot at dovecot.org Tue Jul 17 16:22:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 17 Jul 2012 16:22:11 +0300 Subject: dovecot-1.2: auth: Fixed error handling in GSSAPI when __gss_use... Message-ID: details: http://hg.dovecot.org/dovecot-1.2/rev/6862d534e5b1 changeset: 9656:6862d534e5b1 user: Timo Sirainen date: Tue Jul 17 16:20:20 2012 +0300 description: auth: Fixed error handling in GSSAPI when __gss_userok() was used. An invalid username would have been treated as successful and auth process probably would have crashed. diffstat: src/auth/mech-gssapi.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r a56eb5db0d87 -r 6862d534e5b1 src/auth/mech-gssapi.c --- a/src/auth/mech-gssapi.c Wed Jun 20 02:21:54 2012 +0300 +++ b/src/auth/mech-gssapi.c Tue Jul 17 16:20:20 2012 +0300 @@ -392,8 +392,8 @@ bool ret = FALSE; /* Parse out the principal's username */ - if (!get_display_name(&request->auth_request, name, &name_type, - &princ_display_name) < 0) + if (get_display_name(&request->auth_request, name, &name_type, + &princ_display_name) < 0) return FALSE; if (!mech_gssapi_oid_cmp(name_type, GSS_KRB5_NT_PRINCIPAL_NAME) && From dovecot at dovecot.org Mon Jul 23 14:23:54 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 23 Jul 2012 14:23:54 +0300 Subject: dovecot-2.1: quota: Added quota_ignore_save_errors plugin setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a946a37af082 changeset: 14627:a946a37af082 user: Timo Sirainen date: Mon Jul 23 14:23:32 2012 +0300 description: quota: Added quota_ignore_save_errors plugin setting. If mail is being saved but current quota usage lookup fails with internal error, save the mail anyway instead of failing. diffstat: src/plugins/quota/quota-private.h | 1 + src/plugins/quota/quota-storage.c | 5 +++-- src/plugins/quota/quota.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diffs (45 lines): diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota-private.h --- a/src/plugins/quota/quota-private.h Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota-private.h Mon Jul 23 14:23:32 2012 +0300 @@ -25,6 +25,7 @@ uoff_t size, bool *too_large_r); const char *quota_exceeded_msg; + unsigned int ignore_save_errors:1; unsigned int debug:1; }; diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota-storage.c --- a/src/plugins/quota/quota-storage.c Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota-storage.c Mon Jul 23 14:23:32 2012 +0300 @@ -147,7 +147,7 @@ } else { mail_storage_set_critical(t->box->storage, "Internal quota calculation error"); - return -1; + return qt->quota->set->ignore_save_errors ? 0 : -1; } } @@ -204,7 +204,8 @@ } else if (ret < 0) { mail_storage_set_critical(t->box->storage, "Internal quota calculation error"); - return -1; + if (!qt->quota->set->ignore_save_errors) + return -1; } } diff -r 35ae9569de5a -r a946a37af082 src/plugins/quota/quota.c --- a/src/plugins/quota/quota.c Tue Jul 17 16:20:20 2012 +0300 +++ b/src/plugins/quota/quota.c Mon Jul 23 14:23:32 2012 +0300 @@ -195,6 +195,8 @@ quota_set->debug = user->mail_debug; quota_set->quota_exceeded_msg = mail_user_plugin_getenv(user, "quota_exceeded_message"); + quota_set->ignore_save_errors = + mail_user_plugin_getenv(user, "quota_ignore_save_errors") != NULL; if (quota_set->quota_exceeded_msg == NULL) quota_set->quota_exceeded_msg = DEFAULT_QUOTA_EXCEEDED_MSG; From dovecot at dovecot.org Mon Jul 23 17:24:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 23 Jul 2012 17:24:26 +0300 Subject: dovecot-2.1: lib-dict: Allow backends to have iteration methods ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/522e03dd4268 changeset: 14628:522e03dd4268 user: Timo Sirainen date: Mon Jul 23 17:23:37 2012 +0300 description: lib-dict: Allow backends to have iteration methods as NULL if they don't support it. diffstat: src/lib-dict/dict.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diffs (42 lines): diff -r a946a37af082 -r 522e03dd4268 src/lib-dict/dict.c --- a/src/lib-dict/dict.c Mon Jul 23 14:23:32 2012 +0300 +++ b/src/lib-dict/dict.c Mon Jul 23 17:23:37 2012 +0300 @@ -7,6 +7,7 @@ #include "dict-private.h" static ARRAY_DEFINE(dict_drivers, struct dict *); +static struct dict_iterate_context dict_iter_unsupported; static struct dict *dict_driver_lookup(const char *name) { @@ -136,13 +137,19 @@ i_assert(paths[0] != NULL); for (i = 0; paths[i] != NULL; i++) i_assert(dict_key_prefix_is_valid(paths[i])); + if (dict->v.iterate_init == NULL) { + /* not supported by backend */ + i_error("%s: dict iteration not supported", dict->name); + return &dict_iter_unsupported; + } return dict->v.iterate_init(dict, paths, flags); } bool dict_iterate(struct dict_iterate_context *ctx, const char **key_r, const char **value_r) { - return ctx->dict->v.iterate(ctx, key_r, value_r); + return ctx == &dict_iter_unsupported ? FALSE : + ctx->dict->v.iterate(ctx, key_r, value_r); } int dict_iterate_deinit(struct dict_iterate_context **_ctx) @@ -150,7 +157,8 @@ struct dict_iterate_context *ctx = *_ctx; *_ctx = NULL; - return ctx->dict->v.iterate_deinit(ctx); + return ctx == &dict_iter_unsupported ? -1 : + ctx->dict->v.iterate_deinit(ctx); } struct dict_transaction_context *dict_transaction_begin(struct dict *dict) From dovecot at dovecot.org Mon Jul 23 17:24:26 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 23 Jul 2012 17:24:26 +0300 Subject: dovecot-2.1: redis dict: Added support for set/unset/atomic_inc. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/54e2556f87ea changeset: 14629:54e2556f87ea user: Timo Sirainen date: Mon Jul 23 17:24:13 2012 +0300 description: redis dict: Added support for set/unset/atomic_inc. This allows using Redis as dict quota backend. diffstat: src/lib-dict/dict-redis.c | 504 +++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 451 insertions(+), 53 deletions(-) diffs (truncated from 632 to 300 lines): diff -r 522e03dd4268 -r 54e2556f87ea src/lib-dict/dict-redis.c --- a/src/lib-dict/dict-redis.c Mon Jul 23 17:23:37 2012 +0300 +++ b/src/lib-dict/dict-redis.c Mon Jul 23 17:24:13 2012 +0300 @@ -1,6 +1,7 @@ /* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING redis */ #include "lib.h" +#include "array.h" #include "str.h" #include "istream.h" #include "ostream.h" @@ -9,6 +10,20 @@ #define REDIS_DEFAULT_PORT 6379 #define REDIS_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) +#define DICT_USERNAME_SEPARATOR '/' + +enum redis_input_state { + /* expecting $-1 / $ followed by GET reply */ + REDIS_INPUT_STATE_GET, + /* expecting +QUEUED */ + REDIS_INPUT_STATE_MULTI, + /* expecting +OK reply for DISCARD */ + REDIS_INPUT_STATE_DISCARD, + /* expecting * */ + REDIS_INPUT_STATE_EXEC, + /* expecting EXEC reply */ + REDIS_INPUT_STATE_EXEC_REPLY +}; struct redis_connection { struct connection conn; @@ -20,35 +35,208 @@ bool value_received; }; +struct redis_dict_reply { + unsigned int reply_count; + dict_transaction_commit_callback_t *callback; + void *context; +}; + struct redis_dict { struct dict dict; struct ip_addr ip; + char *username, *key_prefix; unsigned int port; unsigned int timeout_msecs; struct ioloop *ioloop; struct redis_connection conn; + + ARRAY_DEFINE(input_states, enum redis_input_state); + ARRAY_DEFINE(replies, struct redis_dict_reply); + bool connected; + bool transaction_open; +}; + +struct redis_dict_transaction_context { + struct dict_transaction_context ctx; + unsigned int cmd_count; + bool failed; }; static struct connection_list *redis_connections; +static void +redis_input_state_add(struct redis_dict *dict, enum redis_input_state state) +{ + array_append(&dict->input_states, &state, 1); +} + +static void redis_input_state_remove(struct redis_dict *dict) +{ + array_delete(&dict->input_states, 0, 1); +} + static void redis_conn_destroy(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; + const struct redis_dict_reply *reply; conn->dict->connected = FALSE; connection_disconnect(_conn); + + array_foreach(&conn->dict->replies, reply) { + if (reply->callback != NULL) + reply->callback(-1, reply->context); + } + array_clear(&conn->dict->replies); + array_clear(&conn->dict->input_states); + if (conn->dict->ioloop != NULL) io_loop_stop(conn->dict->ioloop); } +static void redis_wait(struct redis_dict *dict) +{ + struct ioloop *prev_ioloop = current_ioloop; + + i_assert(dict->ioloop == NULL); + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + do { + io_loop_run(dict->ioloop); + } while (array_count(&dict->input_states) > 0); + + current_ioloop = prev_ioloop; + connection_switch_ioloop(&dict->conn.conn); + current_ioloop = dict->ioloop; + io_loop_destroy(&dict->ioloop); +} + +static void redis_input_get(struct redis_connection *conn) +{ + const unsigned char *data; + size_t size; + const char *line; + + if (conn->bytes_left == 0) { + /* read the size first */ + line = i_stream_next_line(conn->conn.input); + if (line == NULL) + return; + if (strcmp(line, "$-1") == 0) { + conn->value_received = TRUE; + conn->value_not_found = TRUE; + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + return; + } + if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { + i_error("redis: Unexpected input (wanted $size): %s", + line); + redis_conn_destroy(&conn->conn); + return; + } + conn->bytes_left += 2; /* include trailing CRLF */ + } + + data = i_stream_get_data(conn->conn.input, &size); + if (size > conn->bytes_left) + size = conn->bytes_left; + str_append_n(conn->last_reply, data, size); + + conn->bytes_left -= size; + i_stream_skip(conn->conn.input, size); + + if (conn->bytes_left == 0) { + /* reply fully read - drop trailing CRLF */ + conn->value_received = TRUE; + str_truncate(conn->last_reply, str_len(conn->last_reply)-2); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + redis_input_state_remove(conn->dict); + } +} + +static int redis_conn_input_more(struct redis_connection *conn) +{ + struct redis_dict *dict = conn->dict; + struct redis_dict_reply *reply; + const enum redis_input_state *states; + enum redis_input_state state; + unsigned int count, num_replies; + const char *line; + + states = array_get(&dict->input_states, &count); + if (count == 0) { + line = i_stream_next_line(conn->conn.input); + if (line == NULL) line = ""; + i_error("redis: Unexpected input (expected nothing): %s", + line); + return -1; + } + state = states[0]; + if (state == REDIS_INPUT_STATE_GET) { + redis_input_get(conn); + return 1; + } + + line = i_stream_next_line(conn->conn.input); + if (line == NULL) + return 0; + + redis_input_state_remove(dict); + switch (state) { + case REDIS_INPUT_STATE_GET: + i_unreached(); + case REDIS_INPUT_STATE_MULTI: + case REDIS_INPUT_STATE_DISCARD: + if (line[0] != '+') + break; + return 1; + case REDIS_INPUT_STATE_EXEC: + if (line[0] != '*' || str_to_uint(line+1, &num_replies) < 0) + break; + + reply = array_idx_modifiable(&dict->replies, 0); + i_assert(reply->reply_count > 0); + if (reply->reply_count != num_replies) { + i_error("redis: EXEC expected %u replies, not %u", + reply->reply_count, num_replies); + return -1; + } + return 1; + case REDIS_INPUT_STATE_EXEC_REPLY: + if (*line != '+' && *line != ':') + break; + /* success, just ignore the actual reply */ + reply = array_idx_modifiable(&dict->replies, 0); + i_assert(reply->reply_count > 0); + if (--reply->reply_count == 0) { + if (reply->callback != NULL) + reply->callback(1, reply->context); + array_delete(&dict->replies, 0, 1); + /* if we're running in a dict-ioloop, we're handling a + synchronous commit and need to stop now */ + if (array_count(&dict->replies) == 0 && + conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + } + return 1; + } + i_error("redis: Unexpected input (state=%d): %s", state, line); + return -1; +} + static void redis_conn_input(struct connection *_conn) { struct redis_connection *conn = (struct redis_connection *)_conn; - const unsigned char *data; size_t size; - const char *line; + int ret; switch (i_stream_read(_conn->input)) { case 0: @@ -60,42 +248,13 @@ break; } - if (conn->bytes_left == 0) { - /* read the size first */ - line = i_stream_next_line(_conn->input); - if (line == NULL) - return; - if (strcmp(line, "$-1") == 0) { - conn->value_received = TRUE; - conn->value_not_found = TRUE; - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - return; - } - if (line[0] != '$' || str_to_uint(line+1, &conn->bytes_left) < 0) { - i_error("redis: Unexpected input (wanted $size): %s", - line); - redis_conn_destroy(_conn); - return; - } - conn->bytes_left += 2; /* include trailing CRLF */ + while ((ret = redis_conn_input_more(conn)) > 0) { + i_stream_get_data(_conn->input, &size); + if (size == 0) + break; } - - data = i_stream_get_data(_conn->input, &size); - if (size > conn->bytes_left) - size = conn->bytes_left; - str_append_n(conn->last_reply, data, size); - - conn->bytes_left -= size; - i_stream_skip(_conn->input, size); - - if (conn->bytes_left == 0) { - /* drop trailing CRLF */ - conn->value_received = TRUE; - str_truncate(conn->last_reply, str_len(conn->last_reply)-2); - if (conn->dict->ioloop != NULL) - io_loop_stop(conn->dict->ioloop); - } + if (ret < 0) + redis_conn_destroy(_conn); } static void redis_conn_connected(struct connection *_conn) @@ -124,10 +283,30 @@ .connected = redis_conn_connected }; +static const char *redis_escape_username(const char *username) +{ + const char *p; + string_t *str = t_str_new(64); From dovecot at dovecot.org Mon Jul 23 21:44:07 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 23 Jul 2012 21:44:07 +0300 Subject: dovecot-2.1: lib-dict: Added memcached backend using its binary ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b6df5871632a changeset: 14630:b6df5871632a user: Timo Sirainen date: Mon Jul 23 21:43:39 2012 +0300 description: lib-dict: Added memcached backend using its binary protocol. diffstat: src/lib-dict/Makefile.am | 1 + src/lib-dict/dict-memcached.c | 376 ++++++++++++++++++++++++++++++++++++++++++ src/lib-dict/dict-private.h | 1 + src/lib-dict/dict.c | 2 + src/lib-dict/test-dict.c | 1 + 5 files changed, 381 insertions(+), 0 deletions(-) diffs (truncated from 432 to 300 lines): diff -r 54e2556f87ea -r b6df5871632a src/lib-dict/Makefile.am --- a/src/lib-dict/Makefile.am Mon Jul 23 17:24:13 2012 +0300 +++ b/src/lib-dict/Makefile.am Mon Jul 23 21:43:39 2012 +0300 @@ -14,6 +14,7 @@ dict.c \ dict-client.c \ dict-file.c \ + dict-memcached.c \ dict-redis.c libdict_la_SOURCES = \ diff -r 54e2556f87ea -r b6df5871632a src/lib-dict/dict-memcached.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-dict/dict-memcached.c Mon Jul 23 21:43:39 2012 +0300 @@ -0,0 +1,376 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING memcached */ + +#include "lib.h" +#include "array.h" +#include "str.h" +#include "istream.h" +#include "ostream.h" +#include "connection.h" +#include "dict-private.h" + +#define MEMCACHED_DEFAULT_PORT 11211 +#define MEMCACHED_DEFAULT_LOOKUP_TIMEOUT_MSECS (1000*30) + +/* we need only very limited memcached functionality, so just define the binary + protocol ourself instead requiring protocol_binary.h */ +#define MEMCACHED_REQUEST_HDR_MAGIC 0x80 +#define MEMCACHED_REPLY_HDR_MAGIC 0x81 + +#define MEMCACHED_REQUEST_HDR_LENGTH 24 +#define MEMCACHED_REPLY_HDR_LENGTH 24 + +#define MEMCACHED_CMD_GET 0x00 + +#define MEMCACHED_DATA_TYPE_RAW 0x00 + +enum memcached_response { + MEMCACHED_RESPONSE_OK = 0x0000, + MEMCACHED_RESPONSE_NOTFOUND = 0x0001, + MEMCACHED_RESPONSE_INTERNALERROR= 0x0084, + MEMCACHED_RESPONSE_BUSY = 0x0085, + MEMCACHED_RESPONSE_TEMPFAILURE = 0x0086 +}; + +struct memcached_connection { + struct connection conn; + struct memcached_dict *dict; + + buffer_t *cmd; + struct { + const unsigned char *value; + unsigned int value_len; + enum memcached_response status; + bool reply_received; + } reply; +}; + +struct memcached_dict { + struct dict dict; + struct ip_addr ip; + char *key_prefix; + unsigned int port; + unsigned int timeout_msecs; + + struct ioloop *ioloop; + struct memcached_connection conn; + + bool connected; +}; + +static struct connection_list *memcached_connections; + +static void memcached_conn_destroy(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + conn->dict->connected = FALSE; + connection_disconnect(_conn); + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static int memcached_input_get(struct memcached_connection *conn) +{ + const unsigned char *data; + size_t size; + uint32_t body_len, value_pos; + uint16_t key_len, key_pos, status; + uint8_t extras_len, data_type; + + data = i_stream_get_data(conn->conn.input, &size); + if (size < MEMCACHED_REPLY_HDR_LENGTH) + return 0; + + if (data[0] != MEMCACHED_REPLY_HDR_MAGIC) { + i_error("memcached: Invalid reply magic: %u != %u", + data[0], MEMCACHED_REPLY_HDR_MAGIC); + return -1; + } + memcpy(&body_len, data+8, 4); body_len = ntohl(body_len); + body_len += MEMCACHED_REPLY_HDR_LENGTH; + if (size < body_len) { + /* we haven't read the whole response yet */ + return 0; + } + + memcpy(&key_len, data+2, 2); key_len = ntohs(key_len); + extras_len = data[4]; + data_type = data[5]; + memcpy(&status, data+6, 2); status = ntohs(status); + if (data_type != MEMCACHED_DATA_TYPE_RAW) { + i_error("memcached: Unsupported data type: %u != %u", + data[0], MEMCACHED_DATA_TYPE_RAW); + return -1; + } + + key_pos = MEMCACHED_REPLY_HDR_LENGTH + extras_len; + value_pos = key_pos + key_len; + if (value_pos > body_len) { + i_error("memcached: Invalid key/extras lengths"); + return -1; + } + conn->reply.value = data + value_pos; + conn->reply.value_len = body_len - value_pos; + conn->reply.status = status; + + i_stream_skip(conn->conn.input, body_len); + conn->reply.reply_received = TRUE; + + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); + return 1; +} + +static void memcached_conn_input(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + switch (i_stream_read(_conn->input)) { + case 0: + return; + case -1: + memcached_conn_destroy(_conn); + return; + default: + break; + } + + if (memcached_input_get(conn) < 0) + memcached_conn_destroy(_conn); +} + +static void memcached_conn_connected(struct connection *_conn) +{ + struct memcached_connection *conn = (struct memcached_connection *)_conn; + + if ((errno = net_geterror(_conn->fd_in)) != 0) { + i_error("memcached: connect(%s, %u) failed: %m", + net_ip2addr(&conn->dict->ip), conn->dict->port); + } else { + conn->dict->connected = TRUE; + } + if (conn->dict->ioloop != NULL) + io_loop_stop(conn->dict->ioloop); +} + +static const struct connection_settings memcached_conn_set = { + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1, + .client = TRUE +}; + +static const struct connection_vfuncs memcached_conn_vfuncs = { + .destroy = memcached_conn_destroy, + .input = memcached_conn_input, + .connected = memcached_conn_connected +}; + +static struct dict * +memcached_dict_init(struct dict *driver, const char *uri, + enum dict_data_type value_type ATTR_UNUSED, + const char *username ATTR_UNUSED, + const char *base_dir ATTR_UNUSED) +{ + struct memcached_dict *dict; + const char *const *args; + + if (memcached_connections == NULL) { + memcached_connections = + connection_list_init(&memcached_conn_set, + &memcached_conn_vfuncs); + } + + dict = i_new(struct memcached_dict, 1); + if (net_addr2ip("127.0.0.1", &dict->ip) < 0) + i_unreached(); + dict->port = MEMCACHED_DEFAULT_PORT; + dict->timeout_msecs = MEMCACHED_DEFAULT_LOOKUP_TIMEOUT_MSECS; + dict->key_prefix = i_strdup(""); + + args = t_strsplit(uri, ":"); + for (; *args != NULL; args++) { + if (strncmp(*args, "host=", 5) == 0) { + if (net_addr2ip(*args+5, &dict->ip) < 0) + i_error("Invalid IP: %s", *args+5); + } else if (strncmp(*args, "port=", 5) == 0) { + if (str_to_uint(*args+5, &dict->port) < 0) + i_error("Invalid port: %s", *args+5); + } else if (strncmp(*args, "prefix=", 7) == 0) { + i_free(dict->key_prefix); + dict->key_prefix = i_strdup(*args + 7); + } else if (strncmp(*args, "timeout_msecs=", 14) == 0) { + if (str_to_uint(*args+14, &dict->timeout_msecs) < 0) + i_error("Invalid timeout_msecs: %s", *args+14); + } else { + i_error("Unknown parameter: %s", *args); + } + } + connection_init_client_ip(memcached_connections, &dict->conn.conn, + &dict->ip, dict->port); + + dict->dict = *driver; + dict->conn.cmd = buffer_create_dynamic(default_pool, 256); + dict->conn.dict = dict; + return &dict->dict; +} + +static void memcached_dict_deinit(struct dict *_dict) +{ + struct memcached_dict *dict = (struct memcached_dict *)_dict; + + connection_deinit(&dict->conn.conn); + buffer_free(&dict->conn.cmd); + i_free(dict->key_prefix); + i_free(dict); + + if (memcached_connections->connections == NULL) + connection_list_deinit(&memcached_connections); +} + +static void memcached_dict_lookup_timeout(struct memcached_dict *dict) +{ + i_error("memcached: Lookup timed out in %u.%03u secs", + dict->timeout_msecs/1000, dict->timeout_msecs%1000); + io_loop_stop(dict->ioloop); +} + +static void memcached_add_header(buffer_t *buf, unsigned int key_len) +{ + uint32_t body_len = htonl(key_len); + + i_assert(key_len <= 0xffff); + + buffer_append_c(buf, MEMCACHED_REQUEST_HDR_MAGIC); + buffer_append_c(buf, MEMCACHED_CMD_GET); + buffer_append_c(buf, (key_len >> 8) & 0xff); + buffer_append_c(buf, key_len & 0xff); + buffer_append_c(buf, 0); /* extras length */ + buffer_append_c(buf, MEMCACHED_DATA_TYPE_RAW); + buffer_append_zero(buf, 2); /* vbucket id - we probably don't care? */ + buffer_append(buf, &body_len, sizeof(body_len)); + buffer_append_zero(buf, 4+8); /* opaque + cas */ + i_assert(buf->used == MEMCACHED_REQUEST_HDR_LENGTH); +} + +static int +memcached_dict_lookup_real(struct memcached_dict *dict, pool_t pool, + const char *key, const char **value_r) +{ + struct ioloop *prev_ioloop = current_ioloop; + struct timeout *to; + unsigned int key_len; + + if (strncmp(key, DICT_PATH_SHARED, strlen(DICT_PATH_SHARED)) == 0) + key += strlen(DICT_PATH_SHARED); + else { + i_error("memcached: Only shared keys supported currently"); + return -1; + } + if (*dict->key_prefix != '\0') + key = t_strconcat(dict->key_prefix, key, NULL); + key_len = strlen(key); + if (key_len > 0xffff) { + i_error("memcached: Key is too long (%u bytes): %s", + key_len, key); + return -1; + } + + i_assert(dict->ioloop == NULL); + + dict->ioloop = io_loop_create(); + connection_switch_ioloop(&dict->conn.conn); + + if (dict->conn.conn.fd_in == -1 && + connection_client_connect(&dict->conn.conn) < 0) { From pigeonhole at rename-it.nl Wed Jul 25 10:08:18 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Wed, 25 Jul 2012 09:08:18 +0200 Subject: dovecot-2.1-pigeonhole: Editheader: name of added header is now ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/b614a99f40f1 changeset: 1628:b614a99f40f1 user: Stephan Bosch date: Wed Jul 25 09:08:11 2012 +0200 description: Editheader: name of added header is now first sanitized to have capital letters where conventional. diffstat: src/lib-sieve/plugins/editheader/cmd-addheader.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (12 lines): diff -r e6d102e6f0fc -r b614a99f40f1 src/lib-sieve/plugins/editheader/cmd-addheader.c --- a/src/lib-sieve/plugins/editheader/cmd-addheader.c Mon Jul 16 21:36:23 2012 +0200 +++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c Wed Jul 25 09:08:11 2012 +0200 @@ -304,7 +304,6 @@ str_sanitize(str_c(field_name), 80), str_sanitize(str_c(value), 80)); edmail = sieve_message_edit(renv->msgctx); - edit_mail_header_add(edmail, str_c(field_name), str_c(value), last); - + edit_mail_header_add(edmail, rfc2822_header_field_name_sanitize(str_c(field_name)), str_c(value), last); return SIEVE_EXEC_OK; } From dovecot at dovecot.org Wed Jul 25 15:39:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 25 Jul 2012 15:39:29 +0300 Subject: dovecot-2.1: pop3c: If POP3 server doesn't support CAPA command,... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4b505b1c4c5b changeset: 14631:4b505b1c4c5b user: Timo Sirainen date: Wed Jul 25 15:39:14 2012 +0300 description: pop3c: If POP3 server doesn't support CAPA command, try to use UIDL anyway. diffstat: src/lib-storage/index/pop3c/pop3c-client.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) diffs (19 lines): diff -r b6df5871632a -r 4b505b1c4c5b src/lib-storage/index/pop3c/pop3c-client.c --- a/src/lib-storage/index/pop3c/pop3c-client.c Mon Jul 23 21:43:39 2012 +0300 +++ b/src/lib-storage/index/pop3c/pop3c-client.c Wed Jul 25 15:39:14 2012 +0300 @@ -348,8 +348,13 @@ client->state = POP3C_CLIENT_STATE_CAPA; break; case POP3C_CLIENT_STATE_CAPA: - if (strncasecmp(line, "-ERR", 4) == 0 || - strcmp(line, ".") == 0) { + if (strncasecmp(line, "-ERR", 4) == 0) { + /* CAPA command not supported. some commands still + support UIDL though. */ + client->capabilities |= POP3C_CAPABILITY_UIDL; + pop3c_client_login_finished(client); + break; + } else if (strcmp(line, ".") == 0) { pop3c_client_login_finished(client); break; } From dovecot at dovecot.org Wed Jul 25 19:31:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 25 Jul 2012 19:31:15 +0300 Subject: dovecot-2.2: istream-attachment-extractor: Fixed read() returnin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d95ff676d358 changeset: 14715:d95ff676d358 user: Timo Sirainen date: Wed Jul 25 19:30:55 2012 +0300 description: istream-attachment-extractor: Fixed read() returning EOF too early. diffstat: src/lib-mail/istream-attachment-extractor.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diffs (49 lines): diff -r cdba6fec5ddf -r d95ff676d358 src/lib-mail/istream-attachment-extractor.c --- a/src/lib-mail/istream-attachment-extractor.c Tue Jul 17 16:03:43 2012 +0300 +++ b/src/lib-mail/istream-attachment-extractor.c Wed Jul 25 19:30:55 2012 +0300 @@ -535,6 +535,7 @@ if (part->part_buf != NULL) { stream_add_data(astream, part->part_buf->data, part->part_buf->used); + ret = part->part_buf->used > 0 ? 1 : 0; } break; case MAIL_ATTACHMENT_STATE_YES: @@ -553,19 +554,27 @@ struct istream_private *stream = &astream->istream; struct message_block block; size_t old_size, new_size; + int ret; *retry_r = FALSE; if (stream->pos - stream->skip >= stream->max_buffer_size) return -2; + old_size = stream->pos - stream->skip; switch (message_parser_parse_next_block(astream->parser, &block)) { case -1: /* done / error */ + ret = astream_end_of_part(astream); + if (ret > 0) { + /* final data */ + new_size = stream->pos - stream->skip; + return new_size - old_size; + } stream->istream.eof = TRUE; stream->istream.stream_errno = stream->parent->stream_errno; - if (astream_end_of_part(astream) < 0) + if (ret < 0) stream->istream.stream_errno = EIO; astream->cur_part = NULL; return -1; @@ -576,8 +585,6 @@ break; } - old_size = stream->pos - stream->skip; - if (block.part != astream->cur_part && astream->cur_part != NULL) { /* end of a MIME part */ if (astream_end_of_part(astream) < 0) { From dovecot at dovecot.org Wed Jul 25 19:31:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Wed, 25 Jul 2012 19:31:15 +0300 Subject: dovecot-2.2: Comment update. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aedc3650b5cf changeset: 14716:aedc3650b5cf user: Timo Sirainen date: Wed Jul 25 19:30:59 2012 +0300 description: Comment update. diffstat: src/lib-mail/istream-attachment-connector.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r d95ff676d358 -r aedc3650b5cf src/lib-mail/istream-attachment-connector.h --- a/src/lib-mail/istream-attachment-connector.h Wed Jul 25 19:30:55 2012 +0300 +++ b/src/lib-mail/istream-attachment-connector.h Wed Jul 25 19:30:59 2012 +0300 @@ -11,7 +11,8 @@ non-zero, the input is base64-encoded with the given settings. The (resulting base64-encoded) input must have exactly encoded_size bytes. - Returns 0 if the input was ok, -1 if we've already reached msg_size */ + Returns 0 if the input was ok, -1 if we've already reached msg_size or + attachment offsets/sizes aren't valid. */ int istream_attachment_connector_add(struct istream_attachment_connector *conn, struct istream *decoded_input, uoff_t start_offset, uoff_t encoded_size, From dovecot at dovecot.org Sat Jul 28 15:34:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 15:34:40 +0300 Subject: dovecot-2.2: i_stream_read(): Added assert to make sure EOF isn'... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2a12a8f589c4 changeset: 14717:2a12a8f589c4 user: Timo Sirainen date: Wed Jul 25 19:31:28 2012 +0300 description: i_stream_read(): Added assert to make sure EOF isn't returned too early. diffstat: src/lib/istream.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r aedc3650b5cf -r 2a12a8f589c4 src/lib/istream.c --- a/src/lib/istream.c Wed Jul 25 19:30:59 2012 +0300 +++ b/src/lib/istream.c Wed Jul 25 19:31:28 2012 +0300 @@ -140,6 +140,7 @@ errno = stream->stream_errno; } else { i_assert(stream->eof); + i_assert(old_size == _stream->pos - _stream->skip); } break; case 0: From dovecot at dovecot.org Sat Jul 28 15:34:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 15:34:40 +0300 Subject: dovecot-2.2: imap: MOVE command's COPYUID reply was missing a space Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1ee54bb2fa5a changeset: 14718:1ee54bb2fa5a user: Timo Sirainen date: Sat Jul 28 15:34:28 2012 +0300 description: imap: MOVE command's COPYUID reply was missing a space diffstat: src/imap/cmd-copy.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 2a12a8f589c4 -r 1ee54bb2fa5a src/imap/cmd-copy.c --- a/src/imap/cmd-copy.c Wed Jul 25 19:31:28 2012 +0300 +++ b/src/imap/cmd-copy.c Sat Jul 28 15:34:28 2012 +0300 @@ -140,7 +140,7 @@ } else if (move) { i_assert(copy_count == seq_range_count(&changes.saved_uids)); - str_printfa(msg, "* OK [COPYUID %u %s", + str_printfa(msg, "* OK [COPYUID %u %s ", changes.uid_validity, src_uidset); imap_write_seq_range(msg, &changes.saved_uids); str_append(msg, "] Moved UIDs."); From dovecot at dovecot.org Sat Jul 28 16:29:37 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 16:29:37 +0300 Subject: dovecot-2.2: config: Added support for plugins to contain multip... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/eee77416e137 changeset: 14719:eee77416e137 user: Timo Sirainen date: Sat Jul 28 16:29:22 2012 +0300 description: config: Added support for plugins to contain multiple service settings. For example: const struct service_settings *foo_settings_service_settings_array[] = { &foo1_settings_service_settings, &foo2_settings_service_settings, NULL }; diffstat: src/config/config-parser.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diffs (25 lines): diff -r 1ee54bb2fa5a -r eee77416e137 src/config/config-parser.c --- a/src/config/config-parser.c Sat Jul 28 15:34:28 2012 +0300 +++ b/src/config/config-parser.c Sat Jul 28 16:29:22 2012 +0300 @@ -997,10 +997,17 @@ array_append(&new_roots, &roots[i], 1); } - service_set = module_get_symbol_quiet(m, - t_strdup_printf("%s_service_settings", m->name)); - if (service_set != NULL) - array_append(&new_services, &service_set, 1); + services = module_get_symbol_quiet(m, + t_strdup_printf("%s_service_settings_array", m->name)); + if (services != NULL) { + for (count = 0; services[count] != NULL; count++) ; + array_append(&new_services, services, count); + } else { + service_set = module_get_symbol_quiet(m, + t_strdup_printf("%s_service_settings", m->name)); + if (service_set != NULL) + array_append(&new_services, &service_set, 1); + } } if (array_count(&new_roots) > 0) { /* modules added new settings. add the defaults and start From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Added ssl_iostream_destroy() to d... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/ff479f84022f changeset: 14720:ff479f84022f user: Timo Sirainen date: Sat Jul 28 17:32:14 2012 +0300 description: lib-ssl-iostream: Added ssl_iostream_destroy() to do a clean SSL shutdown. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 13 +++++++++++++ src/lib-ssl-iostream/iostream-ssl-none.c | 4 ++++ src/lib-ssl-iostream/iostream-ssl.h | 2 ++ 3 files changed, 19 insertions(+), 0 deletions(-) diffs (49 lines): diff -r eee77416e137 -r ff479f84022f src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 16:29:22 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:32:14 2012 +0300 @@ -252,6 +252,19 @@ ssl_iostream_free(ssl_io); } +void ssl_iostream_destroy(struct ssl_iostream **_ssl_io) +{ + struct ssl_iostream *ssl_io = *_ssl_io; + + *_ssl_io = NULL; + + (void)SSL_shutdown(ssl_io->ssl); + (void)ssl_iostream_more(ssl_io); + (void)o_stream_flush(ssl_io->plain_output); + + ssl_iostream_unref(&ssl_io); +} + static bool ssl_iostream_bio_output(struct ssl_iostream *ssl_io) { size_t bytes, max_bytes; diff -r eee77416e137 -r ff479f84022f src/lib-ssl-iostream/iostream-ssl-none.c --- a/src/lib-ssl-iostream/iostream-ssl-none.c Sat Jul 28 16:29:22 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-ssl-none.c Sat Jul 28 17:32:14 2012 +0300 @@ -18,6 +18,10 @@ { } +void ssl_iostream_destroy(struct ssl_iostream **ssl_io ATTR_UNUSED) +{ +} + int ssl_iostream_handshake(struct ssl_iostream *ssl_io ATTR_UNUSED) { return -1; diff -r eee77416e137 -r ff479f84022f src/lib-ssl-iostream/iostream-ssl.h --- a/src/lib-ssl-iostream/iostream-ssl.h Sat Jul 28 16:29:22 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-ssl.h Sat Jul 28 17:32:14 2012 +0300 @@ -24,6 +24,8 @@ struct ssl_iostream **iostream_r); /* returned input and output streams must also be unreferenced */ void ssl_iostream_unref(struct ssl_iostream **ssl_io); +/* shutdown SSL connection and unreference ssl iostream */ +void ssl_iostream_destroy(struct ssl_iostream **ssl_io); int ssl_iostream_handshake(struct ssl_iostream *ssl_io); void ssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io, From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Inherit output stream's error han... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c4bef64d28ac changeset: 14721:c4bef64d28ac user: Timo Sirainen date: Sat Jul 28 17:33:45 2012 +0300 description: lib-ssl-iostream: Inherit output stream's error handling from parent. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diffs (22 lines): diff -r ff479f84022f -r c4bef64d28ac src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:32:14 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:33:45 2012 +0300 @@ -2,7 +2,7 @@ #include "lib.h" #include "istream.h" -#include "ostream.h" +#include "ostream-private.h" #include "iostream-openssl.h" #include @@ -223,6 +223,9 @@ *input = i_stream_create_ssl(ssl_io); *output = o_stream_create_ssl(ssl_io); + if (ssl_io->plain_output->real_stream->error_handling_disabled) + o_stream_set_no_error_handling(*output, TRUE); + ssl_io->ssl_output = *output; *iostream_r = ssl_io; return 0; From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Name SSL iostreams based on paren... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/76d492963638 changeset: 14722:76d492963638 user: Timo Sirainen date: Sat Jul 28 17:34:11 2012 +0300 description: lib-ssl-iostream: Name SSL iostreams based on parent streams. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r c4bef64d28ac -r 76d492963638 src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:33:45 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:34:11 2012 +0300 @@ -222,6 +222,10 @@ *input = i_stream_create_ssl(ssl_io); *output = o_stream_create_ssl(ssl_io); + i_stream_set_name(*input, t_strconcat("SSL ", + i_stream_get_name(ssl_io->plain_input), NULL)); + o_stream_set_name(*output, t_strconcat("SSL ", + o_stream_get_name(ssl_io->plain_output), NULL)); if (ssl_io->plain_output->real_stream->error_handling_disabled) o_stream_set_no_error_handling(*output, TRUE); From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-ssl-iostream: Added protocols setting. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/69626d2ce3f0 changeset: 14723:69626d2ce3f0 user: Timo Sirainen date: Sat Jul 28 17:36:27 2012 +0300 description: lib-ssl-iostream: Added protocols setting. diffstat: src/lib-ssl-iostream/iostream-openssl-context.c | 52 +++++++++++++++++++++++++ src/lib-ssl-iostream/iostream-openssl.c | 7 ++- src/lib-ssl-iostream/iostream-openssl.h | 3 + src/lib-ssl-iostream/iostream-ssl.h | 11 ++-- 4 files changed, 67 insertions(+), 6 deletions(-) diffs (134 lines): diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl-context.c --- a/src/lib-ssl-iostream/iostream-openssl-context.c Sat Jul 28 17:34:11 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl-context.c Sat Jul 28 17:36:27 2012 +0300 @@ -278,6 +278,7 @@ struct ssl_iostream_settings *new_set; new_set = p_new(pool, struct ssl_iostream_settings, 1); + new_set->protocols = p_strdup(pool, old_set->protocols); new_set->cipher_list = p_strdup(pool, old_set->cipher_list); new_set->cert = p_strdup(pool, old_set->cert); new_set->key = p_strdup(pool, old_set->key); @@ -287,6 +288,55 @@ return new_set; } +enum { + DOVECOT_SSL_PROTO_SSLv2 = 0x01, + DOVECOT_SSL_PROTO_SSLv3 = 0x02, + DOVECOT_SSL_PROTO_TLSv1 = 0x04, + DOVECOT_SSL_PROTO_ALL = 0x07 +}; + +int openssl_get_protocol_options(const char *protocols) +{ + const char *const *tmp; + int proto, op = 0, include = 0, exclude = 0; + bool neg; + + tmp = t_strsplit_spaces(protocols, " "); + for (; *tmp != NULL; tmp++) { + const char *name = *tmp; + + if (*name != '!') + neg = FALSE; + else { + name++; + neg = TRUE; + } + if (strcasecmp(name, SSL_TXT_SSLV2) == 0) + proto = DOVECOT_SSL_PROTO_SSLv2; + else if (strcasecmp(name, SSL_TXT_SSLV3) == 0) + proto = DOVECOT_SSL_PROTO_SSLv3; + else if (strcasecmp(name, SSL_TXT_TLSV1) == 0) + proto = DOVECOT_SSL_PROTO_TLSv1; + else { + i_fatal("Invalid ssl_protocols setting: " + "Unknown protocol '%s'", name); + } + if (neg) + exclude |= proto; + else + include |= proto; + } + if (include != 0) { + /* exclude everything, except those that are included + (and let excludes still override those) */ + exclude |= DOVECOT_SSL_PROTO_ALL & ~include; + } + if ((exclude & DOVECOT_SSL_PROTO_SSLv2) != 0) op |= SSL_OP_NO_SSLv2; + if ((exclude & DOVECOT_SSL_PROTO_SSLv3) != 0) op |= SSL_OP_NO_SSLv3; + if ((exclude & DOVECOT_SSL_PROTO_TLSv1) != 0) op |= SSL_OP_NO_TLSv1; + return op; +} + static int ssl_iostream_context_set(struct ssl_iostream_context *ctx, const struct ssl_iostream_settings *set) @@ -302,6 +352,8 @@ ssl_iostream_error()); return -1; } + SSL_CTX_set_options(ctx->ssl_ctx, + openssl_get_protocol_options(ctx->set->protocols)); if (set->cert != NULL && ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) < 0) { diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:34:11 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 17:36:27 2012 +0300 @@ -133,8 +133,13 @@ ssl_iostream_error()); } return -1; + } + if (set->protocols != NULL) { + SSL_clear_options(ssl_io->ssl, OPENSSL_ALL_PROTOCOL_OPTIONS); + SSL_set_options(ssl_io->ssl, + openssl_get_protocol_options(set->protocols)); + } - } if (set->cert != NULL && strcmp(ctx_set->cert, set->cert) != 0) { if (ssl_iostream_use_certificate(ssl_io, set->cert) < 0) return -1; diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-openssl.h --- a/src/lib-ssl-iostream/iostream-openssl.h Sat Jul 28 17:34:11 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.h Sat Jul 28 17:36:27 2012 +0300 @@ -61,6 +61,9 @@ const char *key_source, EVP_PKEY **pkey_r); const char *ssl_iostream_get_use_certificate_error(const char *cert); int openssl_cert_match_name(SSL *ssl, const char *verify_name); +int openssl_get_protocol_options(const char *protocols); +#define OPENSSL_ALL_PROTOCOL_OPTIONS \ + (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1) /* Sync plain_input/plain_output streams with BIOs. Returns TRUE if at least one byte was read/written. */ diff -r 76d492963638 -r 69626d2ce3f0 src/lib-ssl-iostream/iostream-ssl.h --- a/src/lib-ssl-iostream/iostream-ssl.h Sat Jul 28 17:34:11 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-ssl.h Sat Jul 28 17:36:27 2012 +0300 @@ -5,17 +5,18 @@ struct ssl_iostream_context; struct ssl_iostream_settings { + const char *protocols; const char *cipher_list; - const char *ca, *ca_dir; + const char *ca, *ca_dir; /* context-only */ const char *cert; const char *key; const char *key_password; const char *cert_username_field; - const char *crypto_device; + const char *crypto_device; /* context-only */ - bool verbose, verbose_invalid_cert; - bool verify_remote_cert; - bool require_valid_cert; + bool verbose, verbose_invalid_cert; /* stream-only */ + bool verify_remote_cert; /* neither/both */ + bool require_valid_cert; /* stream-only */ }; int io_stream_create_ssl(struct ssl_iostream_context *ctx, const char *source, From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: ssl-params: Create also base_dir/ssl-params socket. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/3671877fb692 changeset: 14725:3671877fb692 user: Timo Sirainen date: Sat Jul 28 17:37:19 2012 +0300 description: ssl-params: Create also base_dir/ssl-params socket. diffstat: src/ssl-params/ssl-params-settings.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 16862a69e22c -r 3671877fb692 src/ssl-params/ssl-params-settings.c --- a/src/ssl-params/ssl-params-settings.c Sat Jul 28 17:36:53 2012 +0300 +++ b/src/ssl-params/ssl-params-settings.c Sat Jul 28 17:37:19 2012 +0300 @@ -13,6 +13,7 @@ /* */ static struct file_listener_settings ssl_params_unix_listeners_array[] = { + { "ssl-params", 0666, "", "" }, { "login/ssl-params", 0666, "", "" } }; static struct file_listener_settings *ssl_params_unix_listeners[] = { From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: login: Use lib-ssl-iostream code to handle ssl_prot... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/16862a69e22c changeset: 14724:16862a69e22c user: Timo Sirainen date: Sat Jul 28 17:36:53 2012 +0300 description: login: Use lib-ssl-iostream code to handle ssl_protocols setting. diffstat: src/login-common/ssl-proxy-openssl.c | 53 +----------------------------------- 1 files changed, 1 insertions(+), 52 deletions(-) diffs (70 lines): diff -r 69626d2ce3f0 -r 16862a69e22c src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Jul 28 17:36:27 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Jul 28 17:36:53 2012 +0300 @@ -1149,57 +1149,6 @@ } #endif -enum { - DOVECOT_SSL_PROTO_SSLv2 = 0x01, - DOVECOT_SSL_PROTO_SSLv3 = 0x02, - DOVECOT_SSL_PROTO_TLSv1 = 0x04, - DOVECOT_SSL_PROTO_ALL = 0x07 -}; - -static void -ssl_proxy_ctx_set_protocols(struct ssl_server_context *ssl_ctx, - const char *protocols) -{ - const char *const *tmp; - int proto, op = 0, include = 0, exclude = 0; - bool neg; - - tmp = t_strsplit_spaces(protocols, " "); - for (; *tmp != NULL; tmp++) { - const char *name = *tmp; - - if (*name != '!') - neg = FALSE; - else { - name++; - neg = TRUE; - } - if (strcasecmp(name, SSL_TXT_SSLV2) == 0) - proto = DOVECOT_SSL_PROTO_SSLv2; - else if (strcasecmp(name, SSL_TXT_SSLV3) == 0) - proto = DOVECOT_SSL_PROTO_SSLv3; - else if (strcasecmp(name, SSL_TXT_TLSV1) == 0) - proto = DOVECOT_SSL_PROTO_TLSv1; - else { - i_fatal("Invalid ssl_protocols setting: " - "Unknown protocol '%s'", name); - } - if (neg) - exclude |= proto; - else - include |= proto; - } - if (include != 0) { - /* exclude everything, except those that are included - (and let excludes still override those) */ - exclude |= DOVECOT_SSL_PROTO_ALL & ~include; - } - if ((exclude & DOVECOT_SSL_PROTO_SSLv2) != 0) op |= SSL_OP_NO_SSLv2; - if ((exclude & DOVECOT_SSL_PROTO_SSLv3) != 0) op |= SSL_OP_NO_SSLv3; - if ((exclude & DOVECOT_SSL_PROTO_TLSv1) != 0) op |= SSL_OP_NO_TLSv1; - SSL_CTX_set_options(ssl_ctx->ctx, op); -} - static struct ssl_server_context * ssl_server_context_init(const struct login_settings *set) { @@ -1227,7 +1176,7 @@ i_fatal("Can't set cipher list to '%s': %s", ctx->cipher_list, ssl_last_error()); } - ssl_proxy_ctx_set_protocols(ctx, ctx->protocols); + SSL_CTX_set_options(ssl_ctx, openssl_get_protocol_options(ctx->protocols)); if (ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->cert) != 1) { i_fatal("Can't load ssl_cert: %s", From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-master: Added and used MASTER_SERVICE_INTERNAL_... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/2199fd0d1682 changeset: 14726:2199fd0d1682 user: Timo Sirainen date: Sat Jul 28 17:45:47 2012 +0300 description: lib-master: Added and used MASTER_SERVICE_INTERNAL_SET_PARSERS macro. diffstat: src/auth/auth-settings.c | 2 +- src/lib-master/master-service-settings.c | 3 ++- src/lib-master/master-service-settings.h | 4 ++++ src/lib-storage/mail-storage-service.c | 9 +++++---- src/lmtp/lmtp-settings.c | 3 ++- src/login-common/login-settings.c | 3 ++- 6 files changed, 16 insertions(+), 8 deletions(-) diffs (105 lines): diff -r 3671877fb692 -r 2199fd0d1682 src/auth/auth-settings.c --- a/src/auth/auth-settings.c Sat Jul 28 17:37:19 2012 +0300 +++ b/src/auth/auth-settings.c Sat Jul 28 17:45:47 2012 +0300 @@ -406,7 +406,7 @@ if (!settings_parser_check(set_parser, pool, &error)) i_unreached(); - set = settings_parser_get_list(set_parser)[1]; + set = settings_parser_get_list(set_parser)[MASTER_SERVICE_INTERNAL_SET_PARSERS]; settings_parser_deinit(&set_parser); return set; } diff -r 3671877fb692 -r 2199fd0d1682 src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c Sat Jul 28 17:37:19 2012 +0300 +++ b/src/lib-master/master-service-settings.c Sat Jul 28 17:45:47 2012 +0300 @@ -491,7 +491,8 @@ void **master_service_settings_get_others(struct master_service *service) { - return settings_parser_get_list(service->set_parser) + 1; + return settings_parser_get_list(service->set_parser) + + MASTER_SERVICE_INTERNAL_SET_PARSERS; } struct setting_parser_context * diff -r 3671877fb692 -r 2199fd0d1682 src/lib-master/master-service-settings.h --- a/src/lib-master/master-service-settings.h Sat Jul 28 17:37:19 2012 +0300 +++ b/src/lib-master/master-service-settings.h Sat Jul 28 17:45:47 2012 +0300 @@ -3,6 +3,10 @@ #include "network.h" +/* Number of settings roots used by lib-master internally. Typically you should + use master_service_settings_get_others() to avoid knowing about this. */ +#define MASTER_SERVICE_INTERNAL_SET_PARSERS 1 + struct setting_parser_info; struct master_service; diff -r 3671877fb692 -r 2199fd0d1682 src/lib-storage/mail-storage-service.c --- a/src/lib-storage/mail-storage-service.c Sat Jul 28 17:37:19 2012 +0300 +++ b/src/lib-storage/mail-storage-service.c Sat Jul 28 17:45:47 2012 +0300 @@ -970,7 +970,7 @@ master_service_init_log(ctx->service, t_strconcat(ctx->service->name, ": ", NULL)); } - user_set = settings_parser_get_list(set_parser)[1]; + user_set = settings_parser_get_list(set_parser)[MASTER_SERVICE_INTERNAL_SET_PARSERS]; if (ctx->conn == NULL) mail_storage_service_first_init(ctx, user_info, user_set); @@ -1004,7 +1004,7 @@ if (!settings_parser_check(user->set_parser, user_pool, &error)) i_panic("settings_parser_check() failed: %s", error); - user->user_set = settings_parser_get_list(user->set_parser)[1]; + user->user_set = settings_parser_get_list(user->set_parser)[MASTER_SERVICE_INTERNAL_SET_PARSERS]; user->gid_source = "mail_gid setting"; user->uid_source = "mail_uid setting"; @@ -1195,7 +1195,7 @@ &user_info, &set_parser, &error) < 0) i_fatal("%s", error); - user_set = settings_parser_get_list(set_parser)[1]; + user_set = settings_parser_get_list(set_parser)[MASTER_SERVICE_INTERNAL_SET_PARSERS]; mail_storage_service_first_init(ctx, user_info, user_set); pool_unref(&temp_pool); @@ -1246,7 +1246,8 @@ void **mail_storage_service_user_get_set(struct mail_storage_service_user *user) { - return settings_parser_get_list(user->set_parser) + 1; + return settings_parser_get_list(user->set_parser) + + MASTER_SERVICE_INTERNAL_SET_PARSERS; } const struct mail_storage_service_input * diff -r 3671877fb692 -r 2199fd0d1682 src/lmtp/lmtp-settings.c --- a/src/lmtp/lmtp-settings.c Sat Jul 28 17:37:19 2012 +0300 +++ b/src/lmtp/lmtp-settings.c Sat Jul 28 17:45:47 2012 +0300 @@ -97,7 +97,8 @@ { void **sets; - sets = settings_parser_get_list(set_parser) + 1; + sets = settings_parser_get_list(set_parser) + + MASTER_SERVICE_INTERNAL_SET_PARSERS; *lda_set_r = settings_dup(&lda_setting_parser_info, sets[1], pool); *lmtp_set_r = settings_dup(&lmtp_setting_parser_info, sets[2], pool); } diff -r 3671877fb692 -r 2199fd0d1682 src/login-common/login-settings.c --- a/src/login-common/login-settings.c Sat Jul 28 17:37:19 2012 +0300 +++ b/src/login-common/login-settings.c Sat Jul 28 17:45:47 2012 +0300 @@ -227,7 +227,8 @@ &parser, &error) < 0) i_fatal("Error reading configuration: %s", error); - cache_sets = settings_parser_get_list(parser) + 1; + cache_sets = settings_parser_get_list(parser) + + MASTER_SERVICE_INTERNAL_SET_PARSERS; for (count = 0; input.roots[count] != NULL; count++) ; i_assert(cache_sets[count] == NULL); sets = p_new(pool, void *, count + 1); From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: lib-master: Added base_dir to master_service_settings. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d4b95346c08a changeset: 14727:d4b95346c08a user: Timo Sirainen date: Sat Jul 28 17:47:34 2012 +0300 description: lib-master: Added base_dir to master_service_settings. diffstat: src/lib-master/master-service-settings.c | 2 ++ src/lib-master/master-service-settings.h | 1 + 2 files changed, 3 insertions(+), 0 deletions(-) diffs (30 lines): diff -r 2199fd0d1682 -r d4b95346c08a src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c Sat Jul 28 17:45:47 2012 +0300 +++ b/src/lib-master/master-service-settings.c Sat Jul 28 17:47:34 2012 +0300 @@ -33,6 +33,7 @@ master_service_settings_check(void *_set, pool_t pool, const char **error_r); static const struct setting_define master_service_setting_defines[] = { + DEF(SET_STR, base_dir), DEF(SET_STR, log_path), DEF(SET_STR, info_log_path), DEF(SET_STR, debug_log_path), @@ -47,6 +48,7 @@ }; static const struct master_service_settings master_service_default_settings = { + .base_dir = PKG_RUNDIR, .log_path = "syslog", .info_log_path = "", .debug_log_path = "", diff -r 2199fd0d1682 -r d4b95346c08a src/lib-master/master-service-settings.h --- a/src/lib-master/master-service-settings.h Sat Jul 28 17:45:47 2012 +0300 +++ b/src/lib-master/master-service-settings.h Sat Jul 28 17:47:34 2012 +0300 @@ -11,6 +11,7 @@ struct master_service; struct master_service_settings { + const char *base_dir; const char *log_path; const char *info_log_path; const char *debug_log_path; From dovecot at dovecot.org Sat Jul 28 17:56:05 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:05 +0300 Subject: dovecot-2.2: Moved ssl_* settings from login-common to lib-master. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/983c6ff12cc9 changeset: 14728:983c6ff12cc9 user: Timo Sirainen date: Sat Jul 28 17:54:19 2012 +0300 description: Moved ssl_* settings from login-common to lib-master. This allows creating other SSL servers more easily. diffstat: src/config/config-parser.c | 4 +- src/lib-master/Makefile.am | 2 + src/lib-master/master-service-private.h | 5 + src/lib-master/master-service-settings.c | 3 + src/lib-master/master-service-settings.h | 2 +- src/lib-master/master-service-ssl-settings.c | 101 ++++++++++++++++++++++++++ src/lib-master/master-service-ssl-settings.h | 26 ++++++ src/lib-master/master-service.c | 13 +++ src/login-common/client-common-auth.c | 3 +- src/login-common/client-common.c | 8 +- src/login-common/client-common.h | 5 +- src/login-common/login-common.h | 1 + src/login-common/login-proxy.c | 1 + src/login-common/login-settings.c | 103 ++++++-------------------- src/login-common/login-settings.h | 14 +-- src/login-common/main.c | 18 +++- src/login-common/ssl-proxy-openssl.c | 101 +++++++++++++++---------- src/login-common/ssl-proxy.c | 6 +- src/login-common/ssl-proxy.h | 7 +- src/master/service-process.c | 1 + 20 files changed, 279 insertions(+), 145 deletions(-) diffs (truncated from 993 to 300 lines): diff -r d4b95346c08a -r 983c6ff12cc9 src/config/config-parser.c --- a/src/config/config-parser.c Sat Jul 28 17:47:34 2012 +0300 +++ b/src/config/config-parser.c Sat Jul 28 17:54:19 2012 +0300 @@ -11,6 +11,7 @@ #include "service-settings.h" #include "master-service.h" #include "master-service-settings.h" +#include "master-service-ssl-settings.h" #include "all-settings.h" #include "old-set-parser.h" #include "config-request.h" @@ -1056,7 +1057,8 @@ if (strcmp(root->module_name, module) == 0) return TRUE; - if (root == &master_service_setting_parser_info) { + if (root == &master_service_setting_parser_info || + root == &master_service_ssl_setting_parser_info) { /* everyone wants master service settings */ return TRUE; } diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/Makefile.am --- a/src/lib-master/Makefile.am Sat Jul 28 17:47:34 2012 +0300 +++ b/src/lib-master/Makefile.am Sat Jul 28 17:54:19 2012 +0300 @@ -21,6 +21,7 @@ master-service.c \ master-service-settings.c \ master-service-settings-cache.c \ + master-service-ssl-settings.c \ mountpoint-list.c \ syslog-util.c @@ -37,6 +38,7 @@ master-service-private.h \ master-service-settings.h \ master-service-settings-cache.h \ + master-service-ssl-settings.h \ service-settings.h \ mountpoint-list.h \ syslog-util.h diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service-private.h --- a/src/lib-master/master-service-private.h Sat Jul 28 17:47:34 2012 +0300 +++ b/src/lib-master/master-service-private.h Sat Jul 28 17:54:19 2012 +0300 @@ -59,6 +59,9 @@ const struct master_service_settings *set; struct setting_parser_context *set_parser; + struct ssl_iostream_context *ssl_ctx; + time_t ssl_params_last_refresh; + unsigned int killed:1; unsigned int stopping:1; unsigned int keep_environment:1; @@ -67,6 +70,7 @@ unsigned int die_with_master:1; unsigned int call_avail_overflow:1; unsigned int config_path_is_default:1; + unsigned int ssl_ctx_initialized:1; }; void master_service_io_listeners_add(struct master_service *service); @@ -74,5 +78,6 @@ void master_service_close_config_fd(struct master_service *service); void master_service_io_listeners_remove(struct master_service *service); +void master_service_ssl_io_listeners_remove(struct master_service *service); #endif diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service-settings.c --- a/src/lib-master/master-service-settings.c Sat Jul 28 17:47:34 2012 +0300 +++ b/src/lib-master/master-service-settings.c Sat Jul 28 17:54:19 2012 +0300 @@ -11,6 +11,7 @@ #include "execv-const.h" #include "settings-parser.h" #include "master-service-private.h" +#include "master-service-ssl-settings.h" #include "master-service-settings.h" #include @@ -368,6 +369,8 @@ p_array_init(&all_roots, service->set_pool, 8); tmp_root = &master_service_setting_parser_info; array_append(&all_roots, &tmp_root, 1); + tmp_root = &master_service_ssl_setting_parser_info; + array_append(&all_roots, &tmp_root, 1); if (input->roots != NULL) { for (i = 0; input->roots[i] != NULL; i++) array_append(&all_roots, &input->roots[i], 1); diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service-settings.h --- a/src/lib-master/master-service-settings.h Sat Jul 28 17:47:34 2012 +0300 +++ b/src/lib-master/master-service-settings.h Sat Jul 28 17:54:19 2012 +0300 @@ -5,7 +5,7 @@ /* Number of settings roots used by lib-master internally. Typically you should use master_service_settings_get_others() to avoid knowing about this. */ -#define MASTER_SERVICE_INTERNAL_SET_PARSERS 1 +#define MASTER_SERVICE_INTERNAL_SET_PARSERS 2 struct setting_parser_info; struct master_service; diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service-ssl-settings.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/master-service-ssl-settings.c Sat Jul 28 17:54:19 2012 +0300 @@ -0,0 +1,101 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "settings-parser.h" +#include "master-service-private.h" +#include "master-service-ssl-settings.h" + +#include + +#undef DEF +#define DEF(type, name) \ + { type, #name, offsetof(struct master_service_ssl_settings, name), NULL } + +static bool +master_service_ssl_settings_check(void *_set, pool_t pool, const char **error_r); + +static const struct setting_define master_service_ssl_setting_defines[] = { + DEF(SET_ENUM, ssl), + DEF(SET_STR, ssl_ca), + DEF(SET_STR, ssl_cert), + DEF(SET_STR, ssl_key), + DEF(SET_STR, ssl_key_password), + DEF(SET_STR, ssl_cipher_list), + DEF(SET_STR, ssl_protocols), + DEF(SET_STR, ssl_cert_username_field), + DEF(SET_STR, ssl_crypto_device), + DEF(SET_BOOL, ssl_verify_client_cert), + DEF(SET_BOOL, ssl_require_crl), + DEF(SET_BOOL, verbose_ssl), + + SETTING_DEFINE_LIST_END +}; + +static const struct master_service_ssl_settings master_service_ssl_default_settings = { + .ssl = "yes:no:required", + .ssl_ca = "", + .ssl_cert = "", + .ssl_key = "", + .ssl_key_password = "", + .ssl_cipher_list = "ALL:!LOW:!SSLv2:!EXP:!aNULL", + .ssl_protocols = "!SSLv2", + .ssl_cert_username_field = "commonName", + .ssl_crypto_device = "", + .ssl_verify_client_cert = FALSE, + .ssl_require_crl = TRUE, + .verbose_ssl = FALSE +}; + +const struct setting_parser_info master_service_ssl_setting_parser_info = { + .module_name = "master", + .defines = master_service_ssl_setting_defines, + .defaults = &master_service_ssl_default_settings, + + .type_offset = (size_t)-1, + .struct_size = sizeof(struct master_service_ssl_settings), + + .parent_offset = (size_t)-1, + .check_func = master_service_ssl_settings_check +}; + +/* */ +static bool +master_service_ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED, + const char **error_r) +{ + struct master_service_ssl_settings *set = _set; + + if (strcmp(set->ssl, "no") == 0) { + /* disabled */ + return TRUE; + } +#ifndef HAVE_SSL + *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s", + set->ssl); + return FALSE; +#else + if (*set->ssl_cert == '\0') { + *error_r = "ssl enabled, but ssl_cert not set"; + return FALSE; + } + if (*set->ssl_key == '\0') { + *error_r = "ssl enabled, but ssl_key not set"; + return FALSE; + } + if (set->ssl_verify_client_cert && *set->ssl_ca == '\0') { + *error_r = "ssl_verify_client_cert set, but ssl_ca not"; + return FALSE; + } + return TRUE; +#endif +} +/* */ + +const struct master_service_ssl_settings * +master_service_ssl_settings_get(struct master_service *service) +{ + void **sets; + + sets = settings_parser_get_list(service->set_parser); + return sets[1]; +} diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service-ssl-settings.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/master-service-ssl-settings.h Sat Jul 28 17:54:19 2012 +0300 @@ -0,0 +1,26 @@ +#ifndef MASTER_SERVICE_SSL_SETTINGS_H +#define MASTER_SERVICE_SSL_SETTINGS_H + +struct master_service; + +struct master_service_ssl_settings { + const char *ssl; + const char *ssl_ca; + const char *ssl_cert; + const char *ssl_key; + const char *ssl_key_password; + const char *ssl_cipher_list; + const char *ssl_protocols; + const char *ssl_cert_username_field; + const char *ssl_crypto_device; + bool ssl_verify_client_cert; + bool ssl_require_crl; + bool verbose_ssl; +}; + +extern const struct setting_parser_info master_service_ssl_setting_parser_info; + +const struct master_service_ssl_settings * +master_service_ssl_settings_get(struct master_service *service); + +#endif diff -r d4b95346c08a -r 983c6ff12cc9 src/lib-master/master-service.c --- a/src/lib-master/master-service.c Sat Jul 28 17:47:34 2012 +0300 +++ b/src/lib-master/master-service.c Sat Jul 28 17:54:19 2012 +0300 @@ -869,6 +869,19 @@ } } +void master_service_ssl_io_listeners_remove(struct master_service *service) +{ + unsigned int i; + + if (service->listeners != NULL) { + for (i = 0; i < service->socket_count; i++) { + if (service->listeners[i].io != NULL && + service->listeners[i].ssl) + io_remove(&service->listeners[i].io); + } + } +} + static void master_service_io_listeners_close(struct master_service *service) { unsigned int i; diff -r d4b95346c08a -r 983c6ff12cc9 src/login-common/client-common-auth.c --- a/src/login-common/client-common-auth.c Sat Jul 28 17:47:34 2012 +0300 +++ b/src/login-common/client-common-auth.c Sat Jul 28 17:54:19 2012 +0300 @@ -9,6 +9,7 @@ #include "time-util.h" #include "login-proxy.h" #include "auth-client.h" +#include "master-service-ssl-settings.h" #include "client-common.h" #include @@ -580,7 +581,7 @@ int client_auth_begin(struct client *client, const char *mech_name, const char *init_resp) { - if (!client->secured && strcmp(client->set->ssl, "required") == 0) { + if (!client->secured && strcmp(client->ssl_set->ssl, "required") == 0) { if (client->set->auth_verbose) { client_log(client, "Login failed: " "SSL required for authentication"); diff -r d4b95346c08a -r 983c6ff12cc9 src/login-common/client-common.c --- a/src/login-common/client-common.c Sat Jul 28 17:47:34 2012 +0300 +++ b/src/login-common/client-common.c Sat Jul 28 17:54:19 2012 +0300 @@ -100,7 +100,9 @@ struct client * client_create(int fd, bool ssl, pool_t pool, - const struct login_settings *set, void **other_sets, + const struct login_settings *set, + const struct master_service_ssl_settings *ssl_set, + void **other_sets, const struct ip_addr *local_ip, const struct ip_addr *remote_ip) { struct client *client; @@ -119,6 +121,7 @@ client->pool = pool; client->set = set; + client->ssl_set = ssl_set; client->local_ip = *local_ip; client->ip = *remote_ip; client->fd = fd; From dovecot at dovecot.org Sat Jul 28 17:56:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 17:56:06 +0300 Subject: dovecot-2.2: Added libdovecot-ssl for creating SSL servers more ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/0de6b238d6eb changeset: 14729:0de6b238d6eb user: Timo Sirainen date: Sat Jul 28 17:55:46 2012 +0300 description: Added libdovecot-ssl for creating SSL servers more easily using lib-ssl-iostream. diffstat: Makefile.am | 1 + configure.in | 3 + dovecot-config.in.in | 4 +- dovecot.m4 | 4 +- src/Makefile.am | 4 +- src/lib-dovecot/Makefile.am | 13 +++- src/lib-master/Makefile.am | 7 +- src/lib-master/master-service-ssl.c | 138 ++++++++++++++++++++++++++++++++++++ src/lib-master/master-service-ssl.h | 15 +++ 9 files changed, 182 insertions(+), 7 deletions(-) diffs (truncated from 319 to 300 lines): diff -r 983c6ff12cc9 -r 0de6b238d6eb Makefile.am --- a/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -65,6 +65,7 @@ -e "s|^\(LIBDOVECOT\)=.*$$|\1='-L$(pkglibdir) -ldovecot'|" \ -e "s|^\(LIBDOVECOT_LOGIN\)=.*$$|\1=-ldovecot-login|" \ -e "s|^\(LIBDOVECOT_SQL\)=.*$$|\1=-ldovecot-sql|" \ + -e "s|^\(LIBDOVECOT_SSL\)=.*$$|\1=-ldovecot-ssl|" \ -e "s|^\(LIBDOVECOT_LDA\)=.*$$|\1=-ldovecot-lda|" \ -e "s|^\(LIBDOVECOT_STORAGE\)=.*$$|\1=-ldovecot-storage|" \ -e "s|^\(LIBDOVECOT_INCLUDE\)=.*$$|\1=-I$(pkgincludedir)|" \ diff -r 983c6ff12cc9 -r 0de6b238d6eb configure.in --- a/configure.in Sat Jul 28 17:54:19 2012 +0300 +++ b/configure.in Sat Jul 28 17:55:46 2012 +0300 @@ -2514,6 +2514,7 @@ LIBDOVECOT="$LIBDOVECOT_DEPS" LIBDOVECOT_STORAGE_DEPS='$(top_builddir)/src/lib-storage/libdovecot-storage.la $(top_builddir)/src/lib-imap-storage/libimap-storage.la' LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/libdovecot-login.la' + LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/libdovecot-lda.la' else LIBDOVECOT_DEPS='$(top_builddir)/src/lib-master/libmaster.la $(top_builddir)/src/lib-settings/libsettings.la $(top_builddir)/src/lib-dict/libdict.la $(top_builddir)/src/lib-dns/libdns.la $(top_builddir)/src/lib-fs/libfs.la $(top_builddir)/src/lib-imap/libimap.la $(top_builddir)/src/lib-mail/libmail.la $(top_builddir)/src/lib-auth/libauth.la $(top_builddir)/src/lib-charset/libcharset.la $(top_builddir)/src/lib/liblib.la' @@ -2522,6 +2523,7 @@ LIBDOVECOT_STORAGE_FIRST='$(top_builddir)/src/lib-storage/libstorage_service.la $(top_builddir)/src/lib-storage/register/libstorage_register.la' LIBDOVECOT_STORAGE_DEPS="$LIBDOVECOT_STORAGE_FIRST $LINKED_STORAGE_LIBS $LIBDOVECOT_STORAGE_LAST" LIBDOVECOT_LOGIN='$(top_builddir)/src/login-common/liblogin.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' + LIBDOVECOT_SSL='$(top_builddir)/src/lib-master/libmaster_ssl.la $(top_builddir)/src/lib-ssl-iostream/libssl_iostream.la' LIBDOVECOT_LDA='$(top_builddir)/src/lib-lda/liblda.la' fi LIBDOVECOT_STORAGE="$LIBDOVECOT_STORAGE_DEPS $LINKED_STORAGE_LDADD" @@ -2532,6 +2534,7 @@ AC_SUBST(LIBDOVECOT_STORAGE_DEPS) AC_SUBST(LIBDOVECOT_LOGIN) AC_SUBST(LIBDOVECOT_SQL) +AC_SUBST(LIBDOVECOT_SSL) AC_SUBST(LIBDOVECOT_LDA) dnl ** diff -r 983c6ff12cc9 -r 0de6b238d6eb dovecot-config.in.in --- a/dovecot-config.in.in Sat Jul 28 17:54:19 2012 +0300 +++ b/dovecot-config.in.in Sat Jul 28 17:55:46 2012 +0300 @@ -6,16 +6,18 @@ LIBDOVECOT="@LIBDOVECOT@ @MODULE_LIBS@" LIBDOVECOT_LOGIN="@LIBDOVECOT_LOGIN@ @SSL_LIBS@" LIBDOVECOT_SQL="@LIBDOVECOT_SQL@" +LIBDOVECOT_SSL="@LIBDOVECOT_SSL@" LIBDOVECOT_LDA="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE="@LIBDOVECOT_STORAGE@" LIBDOVECOT_DEPS="@LIBDOVECOT_DEPS@" LIBDOVECOT_LOGIN_DEPS="@LIBDOVECOT_LOGIN@" LIBDOVECOT_SQL_DEPS="@LIBDOVECOT_SQL@" +LIBDOVECOT_SSL_DEPS="@LIBDOVECOT_SSL@" LIBDOVECOT_LDA_DEPS="@LIBDOVECOT_LDA@" LIBDOVECOT_STORAGE_DEPS="@LIBDOVECOT_STORAGE_DEPS@" -LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-settings" +LIBDOVECOT_INCLUDE="-I$(incdir) -I$(incdir)/src/lib -I$(incdir)/src/lib-dict -I$(incdir)/src/lib-dns -I$(incdir)/src/lib-mail -I$(incdir)/src/lib-imap -I$(incdir)/src/lib-fs -I$(incdir)/src/lib-charset -I$(incdir)/src/lib-auth -I$(incdir)/src/lib-master -I$(incdir)/src/lib-ssl-iostream -I$(incdir)/src/lib-settings" LIBDOVECOT_LDA_INCLUDE="-I$(incdir)/src/lib-lda -I$(incdir)/src/lda" LIBDOVECOT_STORAGE_INCLUDE="-I$(incdir)/src/lib-index -I$(incdir)/src/lib-storage -I$(incdir)/src/lib-storage/index -I$(incdir)/src/lib-storage/index/raw" LIBDOVECOT_LOGIN_INCLUDE="-I$(incdir)/src/login-common" diff -r 983c6ff12cc9 -r 0de6b238d6eb dovecot.m4 --- a/dovecot.m4 Sat Jul 28 17:54:19 2012 +0300 +++ b/dovecot.m4 Sat Jul 28 17:55:46 2012 +0300 @@ -60,8 +60,8 @@ eval `grep '^LIBDOVECOT[[A-Z_]]*=' "$dovecotdir"/dovecot-config` AX_SUBST_L([dovecotdir], [dovecot_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir]) AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS]) - AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) - AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) + AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) + AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE]) DC_PLUGIN_DEPS diff -r 983c6ff12cc9 -r 0de6b238d6eb src/Makefile.am --- a/src/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -9,12 +9,12 @@ lib-imap-storage \ lib-master \ lib-dict \ - lib-settings + lib-settings \ + lib-ssl-iostream SUBDIRS = \ lib-test \ $(LIBDOVECOT_SUBDIRS) \ - lib-ssl-iostream \ lib-imap-client \ lib-dovecot \ lib-index \ diff -r 983c6ff12cc9 -r 0de6b238d6eb src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/lib-dovecot/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -10,15 +10,26 @@ ../lib-master/libmaster.la \ ../lib/liblib.la -pkglib_LTLIBRARIES = libdovecot.la +ssl_libs = \ + ../lib-master/libmaster_ssl.la + ../lib-ssl-iostream/libssl_iostream.la + +pkglib_LTLIBRARIES = libdovecot.la libdovecot-ssl.la libdovecot_la_SOURCES = +libdovecot_ssl_la_SOURCES = libdovecot_la_LIBADD = \ $(libs) \ $(MODULE_LIBS) \ $(LTLIBICONV) +libdovecot_ssl_la_LIBADD = \ + $(ssl_libs) \ + $(SSL_LIBS) + libdovecot_la_DEPENDENCIES = $(libs) +libdovecot_ssl_la_DEPENDENCIES = $(ssl_libs) libdovecot_la_LDFLAGS = -export-dynamic +libdovecot_ssl_la_LDFLAGS = -export-dynamic diff -r 983c6ff12cc9 -r 0de6b238d6eb src/lib-master/Makefile.am --- a/src/lib-master/Makefile.am Sat Jul 28 17:54:19 2012 +0300 +++ b/src/lib-master/Makefile.am Sat Jul 28 17:55:46 2012 +0300 @@ -1,10 +1,11 @@ pkgsysconfdir = $(sysconfdir)/dovecot -noinst_LTLIBRARIES = libmaster.la +noinst_LTLIBRARIES = libmaster.la libmaster_ssl.la AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-settings \ + -I$(top_srcdir)/src/lib-ssl-iostream \ -DPKG_RUNDIR=\""$(rundir)"\" \ -DPKG_STATEDIR=\""$(statedir)"\" \ -DSYSCONFDIR=\""$(pkgsysconfdir)"\" \ @@ -25,6 +26,9 @@ mountpoint-list.c \ syslog-util.c +libmaster_ssl_la_SOURCES = \ + master-service-ssl.c + headers = \ anvil-client.h \ ipc-client.h \ @@ -38,6 +42,7 @@ master-service-private.h \ master-service-settings.h \ master-service-settings-cache.h \ + master-service-ssl.h \ master-service-ssl-settings.h \ service-settings.h \ mountpoint-list.h \ diff -r 983c6ff12cc9 -r 0de6b238d6eb src/lib-master/master-service-ssl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-master/master-service-ssl.c Sat Jul 28 17:55:46 2012 +0300 @@ -0,0 +1,138 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "buffer.h" +#include "iostream-ssl.h" +#include "master-service-private.h" +#include "master-service-settings.h" +#include "master-service-ssl-settings.h" +#include "master-service-ssl.h" + +#include + +/* Check every 30 minutes if parameters file has been updated */ +#define SSL_PARAMS_CHECK_INTERVAL (60*30) + +#define SSL_PARAMETERS_PATH "ssl-params" + +static int ssl_refresh_parameters(struct master_service *service) +{ +#define BUF_APPEND_SIZE 1024 + const char *path; + buffer_t *buf; + void *data; + ssize_t ret; + int fd; + + if (ioloop_time == 0 || + service->ssl_params_last_refresh > ioloop_time - SSL_PARAMS_CHECK_INTERVAL) + return 0; + service->ssl_params_last_refresh = ioloop_time; + + path = t_strdup_printf("%s/"SSL_PARAMETERS_PATH, service->set->base_dir); + fd = net_connect_unix(path); + if (fd == -1) { + i_error("connect(%s) failed: %m", path); + return -1; + } + net_set_nonblock(fd, FALSE); + + buf = buffer_create_dynamic(default_pool, BUF_APPEND_SIZE*2); + for (;;) { + data = buffer_append_space_unsafe(buf, BUF_APPEND_SIZE); + ret = read(fd, data, BUF_APPEND_SIZE); + buffer_set_used_size(buf, buf->used - BUF_APPEND_SIZE + + (ret < 0 ? 0 : ret)); + if (ret <= 0) + break; + } + if (ret < 0) + i_error("read(%s) failed: %m", path); + else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) { + i_error("Corrupted SSL parameters file: " + PKG_STATEDIR"/ssl-parameters.dat - disabling SSL %u", (int)buf->used); + ret = -1; + } + i_close_fd(&fd); + buffer_free(&buf); + return ret < 0 ? -1 : 0; +} + +int master_service_ssl_init(struct master_service *service, + struct istream **input, struct ostream **output, + struct ssl_iostream **ssl_iostream_r) +{ + const struct master_service_ssl_settings *set; + struct ssl_iostream_settings ssl_set; + + i_assert(service->ssl_ctx_initialized); + + if (service->ssl_ctx == NULL) + return -1; + + (void)ssl_refresh_parameters(service); + + set = master_service_ssl_settings_get(service); + + memset(&ssl_set, 0, sizeof(ssl_set)); + ssl_set.verbose = set->verbose_ssl; + ssl_set.verify_remote_cert = set->ssl_verify_client_cert; + + return io_stream_create_ssl(service->ssl_ctx, service->name, &ssl_set, + input, output, ssl_iostream_r); +} + +bool master_service_ssl_is_enabled(struct master_service *service) +{ + return service->ssl_ctx != NULL; +} + +void master_service_ssl_ctx_init(struct master_service *service) +{ + const struct master_service_ssl_settings *set; + struct ssl_iostream_settings ssl_set; + + if (service->ssl_ctx_initialized) + return; + service->ssl_ctx_initialized = TRUE; + + /* must be called after master_service_init_finish() so that if + initialization fails we can close the SSL listeners */ + i_assert(service->listeners != NULL); + + set = master_service_ssl_settings_get(service); + + memset(&ssl_set, 0, sizeof(ssl_set)); + ssl_set.protocols = set->ssl_protocols; + ssl_set.cipher_list = set->ssl_cipher_list; + ssl_set.ca = set->ssl_ca; + ssl_set.cert = set->ssl_cert; + ssl_set.key = set->ssl_key; + ssl_set.key_password = set->ssl_key_password; + ssl_set.cert_username_field = set->ssl_cert_username_field; + ssl_set.crypto_device = set->ssl_crypto_device; + + ssl_set.verbose = set->verbose_ssl; + ssl_set.verify_remote_cert = set->ssl_verify_client_cert; + + if (ssl_iostream_context_init_server(service->name, &ssl_set, + &service->ssl_ctx) < 0) { + i_error("SSL context initialization failed, disabling SSL"); + master_service_ssl_io_listeners_remove(service); + return; + } + if (ssl_refresh_parameters(service) < 0) { + i_error("Couldn't initialize SSL parameters, disabling SSL"); + ssl_iostream_context_deinit(&service->ssl_ctx); + master_service_ssl_io_listeners_remove(service); + return; + } +} + +void master_service_ssl_ctx_deinit(struct master_service *service) +{ + if (service->ssl_ctx != NULL) + ssl_iostream_context_deinit(&service->ssl_ctx); + service->ssl_ctx_initialized = FALSE; +} From dovecot at dovecot.org Sat Jul 28 18:03:35 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 18:03:35 +0300 Subject: dovecot-2.2: dovecot.m4: Updates from Pigeonhole Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/73ce16df6b16 changeset: 14730:73ce16df6b16 user: Timo Sirainen date: Sat Jul 28 18:03:25 2012 +0300 description: dovecot.m4: Updates from Pigeonhole diffstat: dovecot.m4 | 29 +++++++++++++++++++++++++++-- 1 files changed, 27 insertions(+), 2 deletions(-) diffs (55 lines): diff -r 0de6b238d6eb -r 73ce16df6b16 dovecot.m4 --- a/dovecot.m4 Sat Jul 28 17:55:46 2012 +0300 +++ b/dovecot.m4 Sat Jul 28 18:03:25 2012 +0300 @@ -6,7 +6,7 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 4 +# serial 6 AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, @@ -46,6 +46,16 @@ ] ) + AC_ARG_WITH(dovecot-install-dirs, + [AC_HELP_STRING([--with-dovecot-install-dirs], + [Use install directories configured for Dovecot (default)])], + if test x$withval = xno; then + use_install_dirs=no + else + use_install_dirs=yes + fi, + use_install_dirs=yes) + AC_MSG_CHECKING([for dovecot-config in "$dovecotdir"]) if test -f "$dovecotdir/dovecot-config"; then AC_MSG_RESULT([$dovecotdir/dovecot-config]) @@ -56,9 +66,24 @@ AC_MSG_ERROR([dovecot-config not found]) fi + old=`pwd` + cd $dovecotdir + abs_dovecotdir=`pwd` + cd $old + DISTCHECK_CONFIGURE_FLAGS="--with-dovecot=$abs_dovecotdir --without-dovecot-install-dirs" + eval `grep -i '^dovecot_[[a-z_]]*=' "$dovecotdir"/dovecot-config` eval `grep '^LIBDOVECOT[[A-Z_]]*=' "$dovecotdir"/dovecot-config` - AX_SUBST_L([dovecotdir], [dovecot_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir]) + + if test "$use_install_dirs" = "no"; then + dovecot_pkgincludedir='$(pkgincludedir)' + dovecot_pkglibdir='$(pkglibdir)' + dovecot_pkglibexecdir='$(libexecdir)/dovecot' + dovecot_docdir='$(docdir)' + dovecot_moduledir='$(moduledir)' + fi + + AX_SUBST_L([DISTCHECK_CONFIGURE_FLAGS], [dovecotdir], [dovecot_moduledir], [dovecot_pkgincludedir], [dovecot_pkglibexecdir], [dovecot_pkglibdir], [dovecot_docdir]) AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS]) AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) From dovecot at dovecot.org Sat Jul 28 19:33:47 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 19:33:47 +0300 Subject: dovecot-2.1: lib-charset: Removed unnecessary buffer size increa... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/cbd2b321a68f changeset: 14632:cbd2b321a68f user: Timo Sirainen date: Sat Jul 28 19:33:14 2012 +0300 description: lib-charset: Removed unnecessary buffer size increases, which only caused out-of-memory errors. diffstat: src/lib-charset/charset-iconv.c | 13 +------------ 1 files changed, 1 insertions(+), 12 deletions(-) diffs (31 lines): diff -r 4b505b1c4c5b -r cbd2b321a68f src/lib-charset/charset-iconv.c --- a/src/lib-charset/charset-iconv.c Wed Jul 25 15:39:14 2012 +0300 +++ b/src/lib-charset/charset-iconv.c Sat Jul 28 19:33:14 2012 +0300 @@ -120,9 +120,8 @@ charset_to_utf8(struct charset_translation *t, const unsigned char *src, size_t *src_size, buffer_t *dest) { - bool dtcase = (t->flags & CHARSET_FLAG_DECOMP_TITLECASE) != 0; enum charset_result result; - size_t pos, used, size, prev_pos = 0, prev_used = 0; + size_t pos, size; size_t prev_invalid_pos = (size_t)-1; bool ret; @@ -141,16 +140,6 @@ prev_invalid_pos = dest->used; } pos++; - } else if (!dtcase) { - /* force buffer to grow */ - used = dest->used; - size = buffer_get_size(dest) - used + 1; - (void)buffer_append_space_unsafe(dest, size); - buffer_set_used_size(dest, used); - } else { - i_assert(dest->used != prev_used || pos != prev_pos); - prev_pos = pos; - prev_used = dest->used; } } From dovecot at dovecot.org Sat Jul 28 19:56:15 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 19:56:15 +0300 Subject: dovecot-2.1: verbose_ssl=yes: Log debug messages with debug leve... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/eec5e1f03fff changeset: 14633:eec5e1f03fff user: Timo Sirainen date: Sat Jul 28 19:56:07 2012 +0300 description: verbose_ssl=yes: Log debug messages with debug level instead of as warnings. diffstat: src/lib-ssl-iostream/iostream-openssl.c | 6 +++--- src/login-common/ssl-proxy-openssl.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diffs (32 lines): diff -r cbd2b321a68f -r eec5e1f03fff src/lib-ssl-iostream/iostream-openssl.c --- a/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 19:33:14 2012 +0300 +++ b/src/lib-ssl-iostream/iostream-openssl.c Sat Jul 28 19:56:07 2012 +0300 @@ -24,9 +24,9 @@ i_warning("%s: SSL failed: where=0x%x: %s", ssl_io->source, where, SSL_state_string_long(ssl)); } else { - i_warning("%s: SSL: where=0x%x, ret=%d: %s", - ssl_io->source, where, ret, - SSL_state_string_long(ssl)); + i_debug("%s: SSL: where=0x%x, ret=%d: %s", + ssl_io->source, where, ret, + SSL_state_string_long(ssl)); } } diff -r cbd2b321a68f -r eec5e1f03fff src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:33:14 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:56:07 2012 +0300 @@ -846,9 +846,9 @@ where, SSL_state_string_long(ssl), net_ip2addr(&proxy->ip)); } else { - i_warning("SSL: where=0x%x, ret=%d: %s [%s]", - where, ret, SSL_state_string_long(ssl), - net_ip2addr(&proxy->ip)); + i_info("SSL: where=0x%x, ret=%d: %s [%s]", + where, ret, SSL_state_string_long(ssl), + net_ip2addr(&proxy->ip)); } } From dovecot at dovecot.org Sat Jul 28 19:57:17 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 19:57:17 +0300 Subject: dovecot-2.1: verbose_ssl=yes: Log debug messages with debug leve... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/4ddb9117a178 changeset: 14634:4ddb9117a178 user: Timo Sirainen date: Sat Jul 28 19:57:10 2012 +0300 description: verbose_ssl=yes: Log debug messages with debug level instead of as info... diffstat: src/login-common/ssl-proxy-openssl.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (16 lines): diff -r eec5e1f03fff -r 4ddb9117a178 src/login-common/ssl-proxy-openssl.c --- a/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:56:07 2012 +0300 +++ b/src/login-common/ssl-proxy-openssl.c Sat Jul 28 19:57:10 2012 +0300 @@ -846,9 +846,9 @@ where, SSL_state_string_long(ssl), net_ip2addr(&proxy->ip)); } else { - i_info("SSL: where=0x%x, ret=%d: %s [%s]", - where, ret, SSL_state_string_long(ssl), - net_ip2addr(&proxy->ip)); + i_debug("SSL: where=0x%x, ret=%d: %s [%s]", + where, ret, SSL_state_string_long(ssl), + net_ip2addr(&proxy->ip)); } } From dovecot at dovecot.org Sat Jul 28 20:00:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 20:00:39 +0300 Subject: dovecot-2.1: fts-lucene: Fixed handling non-lowercase SEARCH HEA... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/77f2510bb009 changeset: 14635:77f2510bb009 user: Timo Sirainen date: Sat Jul 28 20:00:32 2012 +0300 description: fts-lucene: Fixed handling non-lowercase SEARCH HEADER FROM/TO/SUBJECT/CC/BCC Based on patch by Matthew Powell. diffstat: src/plugins/fts-lucene/lucene-wrapper.cc | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 4ddb9117a178 -r 77f2510bb009 src/plugins/fts-lucene/lucene-wrapper.cc --- a/src/plugins/fts-lucene/lucene-wrapper.cc Sat Jul 28 19:57:10 2012 +0300 +++ b/src/plugins/fts-lucene/lucene-wrapper.cc Sat Jul 28 20:00:32 2012 +0300 @@ -1098,7 +1098,7 @@ return false; q = lucene_get_query(index, - t_lucene_utf8_to_tchar(index, arg->hdr_field_name, FALSE), + t_lucene_utf8_to_tchar(index, t_str_lcase(arg->hdr_field_name), FALSE), arg); break; default: @@ -1141,7 +1141,7 @@ if (*arg->value.str == '\0') { /* checking potential existence of the header name */ q = lucene_get_query_str(index, _T("hdr"), - arg->hdr_field_name, FALSE); + t_str_lcase(arg->hdr_field_name), FALSE); break; } From dovecot at dovecot.org Sat Jul 28 20:32:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 20:32:12 +0300 Subject: dovecot-2.1: lib-storage: When saving a mail, set date.save to c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/c598f76eeeed changeset: 14637:c598f76eeeed user: Timo Sirainen date: Sat Jul 28 20:31:30 2012 +0300 description: lib-storage: When saving a mail, set date.save to cache immediately. diffstat: src/lib-storage/index/index-mail.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r b13b8267999d -r c598f76eeeed src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Sat Jul 28 20:31:13 2012 +0300 +++ b/src/lib-storage/index/index-mail.c Sat Jul 28 20:31:30 2012 +0300 @@ -731,7 +731,8 @@ uint32_t t; dates[0] = mail->data.received_date; - dates[1] = mail->data.save_date; + dates[1] = mail->mail.mail.saving ? ioloop_time : + mail->data.save_date; for (i = 0; i < N_ELEMENTS(date_fields); i++) { if (dates[i] != (time_t)-1 && From dovecot at dovecot.org Sat Jul 28 20:32:11 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 20:32:11 +0300 Subject: dovecot-2.1: lib-storage: When copying a mail, use a new timesta... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/b13b8267999d changeset: 14636:b13b8267999d user: Timo Sirainen date: Sat Jul 28 20:31:13 2012 +0300 description: lib-storage: When copying a mail, use a new timestamp for date.save instead of preserving it. diffstat: src/lib-storage/index/index-storage.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diffs (30 lines): diff -r 77f2510bb009 -r b13b8267999d src/lib-storage/index/index-storage.c --- a/src/lib-storage/index/index-storage.c Sat Jul 28 20:00:32 2012 +0300 +++ b/src/lib-storage/index/index-storage.c Sat Jul 28 20:31:13 2012 +0300 @@ -625,6 +625,7 @@ struct mailbox_transaction_context *dest_trans = ctx->transaction; const struct mail_cache_field *dest_field; unsigned int src_field_idx, dest_field_idx; + uint32_t t; src_field_idx = mail_cache_register_lookup(src_mail->box->cache, name); i_assert(src_field_idx != -1U); @@ -643,8 +644,16 @@ } buffer_set_used_size(buf, 0); - if (mail_cache_lookup_field(src_mail->transaction->cache_view, buf, - src_mail->seq, src_field_idx) > 0) { + if (strcmp(name, "date.save") == 0) { + /* save date must update when mail is copied */ + t = ioloop_time; + buffer_append(buf, &t, sizeof(t)); + } else { + if (mail_cache_lookup_field(src_mail->transaction->cache_view, buf, + src_mail->seq, src_field_idx) <= 0) + buffer_set_used_size(buf, 0); + } + if (buf->used > 0) { mail_cache_add(dest_trans->cache_trans, dest_seq, dest_field_idx, buf->data, buf->used); } From dovecot at dovecot.org Sat Jul 28 21:55:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Sat, 28 Jul 2012 21:55:29 +0300 Subject: dovecot-2.2: lib-master: Check ssl_cert/ssl_key only when runnin... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/476be9198559 changeset: 14731:476be9198559 user: Timo Sirainen date: Sat Jul 28 21:55:14 2012 +0300 description: lib-master: Check ssl_cert/ssl_key only when running in config/doveconf. Also if Dovecot isn't built with SSL, default to ssl=no diffstat: src/lib-master/master-service-ssl-settings.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diffs (35 lines): diff -r 73ce16df6b16 -r 476be9198559 src/lib-master/master-service-ssl-settings.c --- a/src/lib-master/master-service-ssl-settings.c Sat Jul 28 18:03:25 2012 +0300 +++ b/src/lib-master/master-service-ssl-settings.c Sat Jul 28 21:55:14 2012 +0300 @@ -32,7 +32,11 @@ }; static const struct master_service_ssl_settings master_service_ssl_default_settings = { +#ifdef HAVE_SSL .ssl = "yes:no:required", +#else + .ssl = "no:yes:required", +#endif .ssl_ca = "", .ssl_cert = "", .ssl_key = "", @@ -74,6 +78,11 @@ set->ssl); return FALSE; #else + /* we get called from many different tools, possibly with -O parameter, + and few of those tools care about SSL settings. so don't check + ssl_cert/ssl_key/etc validity here except in doveconf, because it + usually is just an extra annoyance. */ +#ifdef CONFIG if (*set->ssl_cert == '\0') { *error_r = "ssl enabled, but ssl_cert not set"; return FALSE; @@ -82,6 +91,7 @@ *error_r = "ssl enabled, but ssl_key not set"; return FALSE; } +#endif if (set->ssl_verify_client_cert && *set->ssl_ca == '\0') { *error_r = "ssl_verify_client_cert set, but ssl_ca not"; return FALSE; From pigeonhole at rename-it.nl Mon Jul 30 11:14:49 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Mon, 30 Jul 2012 10:14:49 +0200 Subject: dovecot-2.1-pigeonhole: Fixed several Clang compile warnings and... Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/e3ea0270985a changeset: 1629:e3ea0270985a user: Stephan Bosch date: Mon Jul 30 10:14:42 2012 +0200 description: Fixed several Clang compile warnings and a few potential bugs. Patch by Timo Sirainen. diffstat: src/lib-sieve/rfc2822.h | 2 +- src/lib-sieve/sieve-binary-dumper.c | 7 ++- src/lib-sieve/sieve-binary-dumper.h | 6 ++- src/lib-sieve/sieve-error.c | 64 ++++++++++++++++++------------------ src/lib-sieve/sieve-result.h | 3 +- src/lib-sieve/sieve-runtime-trace.c | 6 +- src/lib-sieve/sieve-runtime-trace.h | 20 ++++++----- src/lib-sievestorage/sieve-storage.c | 2 +- src/testsuite/testsuite-log.c | 8 ++-- 9 files changed, 62 insertions(+), 56 deletions(-) diffs (truncated from 498 to 300 lines): diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/rfc2822.h --- a/src/lib-sieve/rfc2822.h Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/rfc2822.h Mon Jul 30 10:14:42 2012 +0200 @@ -33,7 +33,7 @@ int rfc2822_header_field_write (FILE *f, const char *name, const char *body); - + int rfc2822_header_field_printf (FILE *f, const char *name, const char *body_fmt, ...) ATTR_FORMAT(3, 4); diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-binary-dumper.c --- a/src/lib-sieve/sieve-binary-dumper.c Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.c Mon Jul 30 10:14:42 2012 +0200 @@ -222,10 +222,11 @@ size_t offset; data = (const char *) buffer_get_data(blockbuf, &data_size); - + + // FIXME: calculate offset more nicely. sieve_binary_dump_sectionf - (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, - data_size, sblock->offset + 8 /* header size (yuck) */); + (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, + data_size, (unsigned long long int) sblock->offset + 8); line = t_str_new(128); offset = 0; diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-binary-dumper.h --- a/src/lib-sieve/sieve-binary-dumper.h Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.h Mon Jul 30 10:14:42 2012 +0200 @@ -25,9 +25,11 @@ */ void sieve_binary_dumpf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); void sieve_binary_dump_sectionf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); /* * Dumping the binary diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-error.c Mon Jul 30 10:14:42 2012 +0200 @@ -602,7 +602,7 @@ typedef void (*master_log_func_t)(const char *fmt, ...) ATTR_FORMAT(1, 2); -static void sieve_master_vlog +static void ATTR_FORMAT(4, 0) sieve_master_vlog (struct sieve_error_handler *_ehandler, master_log_func_t log_func, const char *location, const char *fmt, va_list args) { @@ -624,7 +624,7 @@ log_func("%s", str_c(str)); } -static void sieve_master_verror +static void ATTR_FORMAT(4, 0) sieve_master_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -632,7 +632,7 @@ sieve_master_vlog(ehandler, i_error, location, fmt, args); } -static void sieve_master_vwarning +static void ATTR_FORMAT(4, 0) sieve_master_vwarning (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -640,7 +640,7 @@ sieve_master_vlog(ehandler, i_warning, location, fmt, args); } -static void sieve_master_vinfo +static void ATTR_FORMAT(4, 0) sieve_master_vinfo (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -648,7 +648,7 @@ sieve_master_vlog(ehandler, i_info, location, fmt, args); } -static void sieve_master_vdebug +static void ATTR_FORMAT(4, 0) sieve_master_vdebug (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -685,7 +685,7 @@ * - Output errors directly to stderror */ -static void sieve_stderr_vmessage +static void ATTR_FORMAT(4, 0) sieve_stderr_vmessage (struct sieve_error_handler *ehandler ATTR_UNUSED, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -695,28 +695,28 @@ fprintf(stderr, "%s: %s: %s.\n", location, prefix, t_strdup_vprintf(fmt, args)); } -static void sieve_stderr_verror +static void ATTR_FORMAT(4, 0) sieve_stderr_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_stderr_vwarning +static void ATTR_FORMAT(4, 0) sieve_stderr_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_stderr_vinfo +static void ATTR_FORMAT(4, 0) sieve_stderr_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_stderr_vdebug +static void ATTR_FORMAT(4, 0) sieve_stderr_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -757,7 +757,7 @@ bool crlf; }; -static void sieve_strbuf_vmessage +static void ATTR_FORMAT(4, 0) sieve_strbuf_vmessage (struct sieve_error_handler *ehandler, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -775,28 +775,28 @@ str_append(handler->errors, ".\r\n"); } -static void sieve_strbuf_verror +static void ATTR_FORMAT(4, 0) sieve_strbuf_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_strbuf_vwarning +static void ATTR_FORMAT(4, 0) sieve_strbuf_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_strbuf_vinfo +static void ATTR_FORMAT(4, 0) sieve_strbuf_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_strbuf_vdebug +static void ATTR_FORMAT(4, 0) sieve_strbuf_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -841,7 +841,7 @@ struct ostream *stream; }; -static void sieve_logfile_vprintf +static void ATTR_FORMAT(4, 0) sieve_logfile_vprintf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, va_list args) { @@ -877,7 +877,7 @@ } } -inline static void sieve_logfile_printf +inline static void ATTR_FORMAT(4, 5) sieve_logfile_printf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, ...) { @@ -985,7 +985,7 @@ } } -static void sieve_logfile_verror +static void ATTR_FORMAT(4, 0) sieve_logfile_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -997,7 +997,7 @@ sieve_logfile_vprintf(handler, location, "error", fmt, args); } -static void sieve_logfile_vwarning +static void ATTR_FORMAT(4, 0) sieve_logfile_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1009,7 +1009,7 @@ sieve_logfile_vprintf(handler, location, "warning", fmt, args); } -static void sieve_logfile_vinfo +static void ATTR_FORMAT(4, 0) sieve_logfile_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1021,7 +1021,7 @@ sieve_logfile_vprintf(handler, location, "info", fmt, args); } -static void sieve_logfile_vdebug +static void ATTR_FORMAT(4, 0) sieve_logfile_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1093,9 +1093,9 @@ const char *prefix; }; -static const char *_prefix_message +static const char *ATTR_FORMAT(3, 0) _prefix_message (struct sieve_prefix_ehandler *ehandler, - const char *location, const char *fmt, va_list args) + const char *location, const char *fmt, va_list args) { string_t *str = t_str_new(256); @@ -1108,7 +1108,7 @@ return str_c(str); } -static void sieve_prefix_verror +static void ATTR_FORMAT(4, 0) sieve_prefix_verror (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1119,7 +1119,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vwarning +static void ATTR_FORMAT(4, 0) sieve_prefix_vwarning (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1130,7 +1130,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vinfo +static void ATTR_FORMAT(4, 0) sieve_prefix_vinfo (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1141,7 +1141,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vdebug +static void ATTR_FORMAT(4, 0) sieve_prefix_vdebug (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1190,7 +1190,7 @@ ARRAY_DEFINE(table, struct var_expand_table); }; -static const char *_expand_message +static const char *ATTR_FORMAT(3, 0) _expand_message (struct sieve_error_handler *_ehandler, const char *location, const char *fmt, va_list args) { @@ -1211,7 +1211,7 @@ return str_c(str); } -static void sieve_varexpand_verror +static void ATTR_FORMAT(4, 0) sieve_varexpand_verror (struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1219,7 +1219,7 @@ From dovecot at dovecot.org Mon Jul 30 15:06:40 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jul 2012 15:06:40 +0300 Subject: dovecot-2.2: dovecot.m4: Export also LIBDOVECOT_IMAP_INCLUDE Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/aab2cca80015 changeset: 14732:aab2cca80015 user: Timo Sirainen date: Mon Jul 30 15:06:29 2012 +0300 description: dovecot.m4: Export also LIBDOVECOT_IMAP_INCLUDE diffstat: dovecot.m4 | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (21 lines): diff -r 476be9198559 -r aab2cca80015 dovecot.m4 --- a/dovecot.m4 Sat Jul 28 21:55:14 2012 +0300 +++ b/dovecot.m4 Mon Jul 30 15:06:29 2012 +0300 @@ -6,7 +6,7 @@ # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 6 +# serial 7 AC_DEFUN([DC_DOVECOT_MODULEDIR],[ AC_ARG_WITH(moduledir, @@ -87,7 +87,7 @@ AX_SUBST_L([DOVECOT_CFLAGS], [DOVECOT_LIBS], [DOVECOT_SSL_LIBS], [DOVECOT_SQL_LIBS]) AX_SUBST_L([LIBDOVECOT], [LIBDOVECOT_LOGIN], [LIBDOVECOT_SQL], [LIBDOVECOT_SSL], [LIBDOVECOT_LDA], [LIBDOVECOT_STORAGE]) AX_SUBST_L([LIBDOVECOT_DEPS], [LIBDOVECOT_LOGIN_DEPS], [LIBDOVECOT_SQL_DEPS], [LIBDOVECOT_SSL_DEPS], [LIBDOVECOT_LDA_DEPS], [LIBDOVECOT_STORAGE_DEPS]) - AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE]) + AX_SUBST_L([LIBDOVECOT_INCLUDE], [LIBDOVECOT_LDA_INCLUDE], [LIBDOVECOT_SERVICE_INCLUDE], [LIBDOVECOT_STORAGE_INCLUDE], [LIBDOVECOT_LOGIN_INCLUDE], [LIBDOVECOT_CONFIG_INCLUDE], [LIBDOVECOT_IMAP_INCLUDE]) DC_PLUGIN_DEPS ]) From dovecot at dovecot.org Mon Jul 30 15:56:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jul 2012 15:56:06 +0300 Subject: dovecot-2.2: Makefile: Fixed libdovecot-ssl to actually contain ... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/d090feb2d9b3 changeset: 14733:d090feb2d9b3 user: Timo Sirainen date: Mon Jul 30 15:55:39 2012 +0300 description: Makefile: Fixed libdovecot-ssl to actually contain libssl-iostream diffstat: src/lib-dovecot/Makefile.am | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r aab2cca80015 -r d090feb2d9b3 src/lib-dovecot/Makefile.am --- a/src/lib-dovecot/Makefile.am Mon Jul 30 15:06:29 2012 +0300 +++ b/src/lib-dovecot/Makefile.am Mon Jul 30 15:55:39 2012 +0300 @@ -11,7 +11,7 @@ ../lib/liblib.la ssl_libs = \ - ../lib-master/libmaster_ssl.la + ../lib-master/libmaster_ssl.la \ ../lib-ssl-iostream/libssl_iostream.la pkglib_LTLIBRARIES = libdovecot.la libdovecot-ssl.la From dovecot at dovecot.org Mon Jul 30 15:56:06 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jul 2012 15:56:06 +0300 Subject: dovecot-2.2: Added "connection" API for handling client/server c... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/dfe6f9a790bc changeset: 14734:dfe6f9a790bc user: Timo Sirainen date: Mon Jul 30 15:56:00 2012 +0300 description: Added "connection" API for handling client/server connections more easily. diffstat: src/lib/Makefile.am | 2 + src/lib/connection.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/connection.h | 120 ++++++++++++++++++ 3 files changed, 460 insertions(+), 0 deletions(-) diffs (truncated from 485 to 300 lines): diff -r d090feb2d9b3 -r dfe6f9a790bc src/lib/Makefile.am --- a/src/lib/Makefile.am Mon Jul 30 15:55:39 2012 +0300 +++ b/src/lib/Makefile.am Mon Jul 30 15:56:00 2012 +0300 @@ -21,6 +21,7 @@ buffer.c \ child-wait.c \ compat.c \ + connection.c \ crc32.c \ data-stack.c \ eacces-error.c \ @@ -141,6 +142,7 @@ buffer.h \ child-wait.h \ compat.h \ + connection.h \ crc32.h \ data-stack.h \ eacces-error.h \ diff -r d090feb2d9b3 -r dfe6f9a790bc src/lib/connection.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/connection.c Mon Jul 30 15:56:00 2012 +0300 @@ -0,0 +1,338 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "istream.h" +#include "ostream.h" +#include "network.h" +#include "strescape.h" +#include "llist.h" +#include "connection.h" + +#include + +static void connection_idle_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_IDLE_TIMEOUT; + conn->list->v.destroy(conn); +} + +static void connection_connect_timeout(struct connection *conn) +{ + conn->disconnect_reason = CONNECTION_DISCONNECT_CONNECT_TIMEOUT; + conn->list->v.destroy(conn); +} + +void connection_input_default(struct connection *conn) +{ + const char *line; + struct istream *input; + int ret = 0; + + switch (connection_input_read(conn)) { + case -1: + case 0: + return; + case 1: + break; + default: + i_unreached(); + } + + input = conn->input; + i_stream_ref(input); + while (!input->closed && (line = i_stream_next_line(input)) != NULL) { + T_BEGIN { + ret = conn->list->v.input_line(conn, line); + } T_END; + if (ret <= 0) + break; + } + if (ret < 0 && !input->closed) { + conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT; + conn->list->v.destroy(conn); + } + i_stream_unref(&input); +} + +int connection_verify_version(struct connection *conn, + const char *const *args) +{ + unsigned int recv_major_version; + + /* VERSION service_name major version minor version */ + if (str_array_length(args) != 4 || + strcmp(args[0], "VERSION") != 0 || + str_to_uint(args[2], &recv_major_version) < 0 || + str_to_uint(args[3], &conn->minor_version) < 0) { + i_error("%s didn't reply with a valid VERSION line", + conn->name); + return -1; + } + + if (strcmp(args[1], conn->list->set.service_name_in) != 0) { + i_error("%s: Connected to wrong socket type. " + "We want '%s', but received '%s'", conn->name, + conn->list->set.service_name_in, args[1]); + return -1; + } + + if (recv_major_version != conn->list->set.major_version) { + i_error("%s: Socket supports major version %u, " + "but we support only %u (mixed old and new binaries?)", + conn->name, recv_major_version, + conn->list->set.major_version); + return -1; + } + return 0; +} + +int connection_input_line_default(struct connection *conn, const char *line) +{ + const char *const *args; + + args = t_strsplit_tabescaped(line); + if (!conn->version_received) { + if (connection_verify_version(conn, args) < 0) + return -1; + conn->version_received = TRUE; + return 1; + } + + return conn->list->v.input_args(conn, args); +} + +static void connection_init_streams(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + + i_assert(conn->io == NULL); + i_assert(conn->input == NULL); + i_assert(conn->output == NULL); + i_assert(conn->to == NULL); + + conn->version_received = set->major_version == 0; + + if (set->input_max_size != 0) { + conn->input = i_stream_create_fd(conn->fd_in, + set->input_max_size, FALSE); + } + if (set->output_max_size != 0) { + conn->output = o_stream_create_fd(conn->fd_out, + set->output_max_size, FALSE); + } + conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); + if (set->input_idle_timeout_secs != 0) { + conn->to = timeout_add(set->input_idle_timeout_secs*1000, + connection_idle_timeout, conn); + } + if (set->major_version != 0 && !set->dont_send_version) { + o_stream_nsend_str(conn->output, t_strdup_printf( + "VERSION\t%s\t%u\t%u\n", set->service_name_out, + set->major_version, set->minor_version)); + } + if (conn->list->v.connected != NULL) + conn->list->v.connected(conn); +} + +void connection_init_server(struct connection_list *list, + struct connection *conn, const char *name, + int fd_in, int fd_out) +{ + i_assert(name != NULL); + i_assert(!list->set.client); + + conn->list = list; + conn->name = i_strdup(name); + conn->fd_in = fd_in; + conn->fd_out = fd_out; + connection_init_streams(conn); + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_ip(struct connection_list *list, + struct connection *conn, + const struct ip_addr *ip, unsigned int port) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup_printf("%s:%u", net_ip2addr(ip), port); + + conn->ip = *ip; + conn->port = port; + + DLLIST_PREPEND(&list->connections, conn); +} + +void connection_init_client_unix(struct connection_list *list, + struct connection *conn, const char *path) +{ + i_assert(list->set.client); + + conn->fd_in = conn->fd_out = -1; + conn->list = list; + conn->name = i_strdup(path); + + DLLIST_PREPEND(&list->connections, conn); +} + +static void connection_connected(struct connection *conn) +{ + io_remove(&conn->io); + if (conn->to != NULL) + timeout_remove(&conn->to); + + connection_init_streams(conn); +} + +int connection_client_connect(struct connection *conn) +{ + const struct connection_settings *set = &conn->list->set; + int fd; + + i_assert(conn->list->set.client); + i_assert(conn->fd_in == -1); + + if (conn->port != 0) + fd = net_connect_ip(&conn->ip, conn->port, NULL); + else + fd = net_connect_unix(conn->name); + if (fd == -1) + return -1; + conn->fd_in = conn->fd_out = fd; + + if (conn->port != 0) { + conn->io = io_add(conn->fd_out, IO_WRITE, + connection_connected, conn); + if (set->client_connect_timeout_msecs != 0) { + conn->to = timeout_add(set->client_connect_timeout_msecs, + connection_connect_timeout, conn); + } + } else { + connection_init_streams(conn); + } + return 0; +} + +void connection_disconnect(struct connection *conn) +{ + if (conn->to != NULL) + timeout_remove(&conn->to); + if (conn->io != NULL) + io_remove(&conn->io); + if (conn->input != NULL) + i_stream_destroy(&conn->input); + if (conn->output != NULL) + o_stream_destroy(&conn->output); + if (conn->fd_in != -1) { + if (close(conn->fd_in) < 0) + i_error("close(%s) failed: %m", conn->name); + if (conn->fd_in != conn->fd_out) + i_error("close(%s/out) failed: %m", conn->name); + conn->fd_in = conn->fd_out = -1; + } +} + +void connection_deinit(struct connection *conn) +{ + DLLIST_REMOVE(&conn->list->connections, conn); + + connection_disconnect(conn); + i_free(conn->name); +} + +int connection_input_read(struct connection *conn) +{ + conn->last_input = ioloop_time; + if (conn->to != NULL) + timeout_reset(conn->to); + + switch (i_stream_read(conn->input)) { + case -2: + /* buffer full */ + switch (conn->list->set.input_full_behavior) { + case CONNECTION_BEHAVIOR_DESTROY: + conn->disconnect_reason = + CONNECTION_DISCONNECT_BUFFER_FULL; + conn->list->v.destroy(conn); + return -1; + case CONNECTION_BEHAVIOR_ALLOW: + return -2; + } + case -1: + /* disconnected */ + conn->disconnect_reason = + CONNECTION_DISCONNECT_CONN_CLOSED; + conn->list->v.destroy(conn); + return -1; + case 0: + /* nothing new read */ + return 0; + default: + /* something was read */ + return 1; + } From dovecot at dovecot.org Mon Jul 30 19:49:55 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Mon, 30 Jul 2012 19:49:55 +0300 Subject: dovecot-2.2: auth: EXTERNAL mechanism didn't use auth_username_*... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1e7c33ce9c16 changeset: 14735:1e7c33ce9c16 user: Timo Sirainen date: Mon Jul 30 19:49:43 2012 +0300 description: auth: EXTERNAL mechanism didn't use auth_username_* settings. diffstat: src/auth/mech-external.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diffs (26 lines): diff -r dfe6f9a790bc -r 1e7c33ce9c16 src/auth/mech-external.c --- a/src/auth/mech-external.c Mon Jul 30 15:56:00 2012 +0300 +++ b/src/auth/mech-external.c Mon Jul 30 19:49:43 2012 +0300 @@ -16,8 +16,20 @@ auth_request_log_info(request, "external", "username not known"); auth_request_fail(request); - } else if (*authzid != '\0' && - !auth_request_set_login_username(request, authzid, &error)) { + return; + } + + /* this call is done simply to put the username through translation + settings */ + if (!auth_request_set_username(request, "", &error)) { + auth_request_log_info(request, "external", + "Invalid username"); + auth_request_fail(request); + return; + } + + if (*authzid != '\0' && + !auth_request_set_login_username(request, authzid, &error)) { /* invalid login username */ auth_request_log_info(request, "plain", "login user: %s", error); From pigeonhole at rename-it.nl Tue Jul 31 02:18:23 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:18:23 +0200 Subject: dovecot-2.1-pigeonhole: Fix linkage with ld.gold. Message-ID: details: http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/c52a0c561311 changeset: 1630:c52a0c561311 user: Stephan Bosch date: Tue Jul 31 01:18:15 2012 +0200 description: Fix linkage with ld.gold. Patch by Eray Aslan. diffstat: src/lib-sieve/Makefile.am | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r e3ea0270985a -r c52a0c561311 src/lib-sieve/Makefile.am --- a/src/lib-sieve/Makefile.am Mon Jul 30 10:14:42 2012 +0200 +++ b/src/lib-sieve/Makefile.am Tue Jul 31 01:18:15 2012 +0200 @@ -70,8 +70,8 @@ $(extdir)/vnd.dovecot/duplicate/libsieve_ext_duplicate.la \ $(unfinished_plugins) -libdovecot_sieve_la_DEPENDENCIES = $(plugins) -libdovecot_sieve_la_LIBADD = $(plugins) +libdovecot_sieve_la_DEPENDENCIES = $(plugins) $(LIBDOVECOT_LDA_DEPS) +libdovecot_sieve_la_LIBADD = $(plugins) $(LIBDOVECOT_LDA) libdovecot_sieve_la_SOURCES = \ rfc2822.c \ From pigeonhole at rename-it.nl Tue Jul 31 02:24:36 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:24:36 +0200 Subject: dovecot-2.2-pigeonhole: Merged changes from Pigeonhole v0.2 tree. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/bea6fcece21e changeset: 1642:bea6fcece21e user: Stephan Bosch date: Tue Jul 31 01:24:28 2012 +0200 description: Merged changes from Pigeonhole v0.2 tree. diffstat: doc/example-config/conf.d/20-managesieve.conf | 8 +- src/lib-sieve/Makefile.am | 4 +- src/lib-sieve/plugins/editheader/cmd-addheader.c | 3 +- src/lib-sieve/rfc2822.h | 4 +- src/lib-sieve/sieve-binary-dumper.c | 7 +- src/lib-sieve/sieve-binary-dumper.h | 6 +- src/lib-sieve/sieve-error.c | 64 ++++++++++++------------ src/lib-sieve/sieve-result.h | 3 +- src/lib-sieve/sieve-runtime-trace.c | 6 +- src/lib-sieve/sieve-runtime-trace.h | 20 ++++--- src/lib-sievestorage/sieve-storage.c | 2 +- src/testsuite/testsuite-log.c | 8 +- 12 files changed, 70 insertions(+), 65 deletions(-) diffs (truncated from 554 to 300 lines): diff -r a1668b71e657 -r bea6fcece21e doc/example-config/conf.d/20-managesieve.conf --- a/doc/example-config/conf.d/20-managesieve.conf Fri Jul 13 10:06:46 2012 +0200 +++ b/doc/example-config/conf.d/20-managesieve.conf Tue Jul 31 01:24:28 2012 +0200 @@ -7,7 +7,7 @@ # Service definitions -service managesieve-login { +#service managesieve-login { #inet_listener sieve { # port = 4190 #} @@ -26,12 +26,12 @@ # If you set service_count=0, you probably need to grow this. #vsz_limit = 64M -} +#} -service managesieve { +#service managesieve { # Max. number of ManageSieve processes (connections) #process_count = 1024 -} +#} # Service configuration diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/Makefile.am --- a/src/lib-sieve/Makefile.am Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/Makefile.am Tue Jul 31 01:24:28 2012 +0200 @@ -70,8 +70,8 @@ $(extdir)/vnd.dovecot/duplicate/libsieve_ext_duplicate.la \ $(unfinished_plugins) -libdovecot_sieve_la_DEPENDENCIES = $(plugins) -libdovecot_sieve_la_LIBADD = $(plugins) +libdovecot_sieve_la_DEPENDENCIES = $(plugins) $(LIBDOVECOT_LDA_DEPS) +libdovecot_sieve_la_LIBADD = $(plugins) $(LIBDOVECOT_LDA) libdovecot_sieve_la_SOURCES = \ rfc2822.c \ diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/plugins/editheader/cmd-addheader.c --- a/src/lib-sieve/plugins/editheader/cmd-addheader.c Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c Tue Jul 31 01:24:28 2012 +0200 @@ -304,7 +304,6 @@ str_sanitize(str_c(field_name), 80), str_sanitize(str_c(value), 80)); edmail = sieve_message_edit(renv->msgctx); - edit_mail_header_add(edmail, str_c(field_name), str_c(value), last); - + edit_mail_header_add(edmail, rfc2822_header_field_name_sanitize(str_c(field_name)), str_c(value), last); return SIEVE_EXEC_OK; } diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/rfc2822.h --- a/src/lib-sieve/rfc2822.h Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/rfc2822.h Tue Jul 31 01:24:28 2012 +0200 @@ -38,8 +38,8 @@ } void rfc2822_header_printf - (string_t *header, const char *name, const char *fmt, ...); + (string_t *header, const char *name, const char *fmt, ...) ATTR_FORMAT(3, 4); void rfc2822_header_utf8_printf - (string_t *header, const char *name, const char *fmt, ...); + (string_t *header, const char *name, const char *fmt, ...) ATTR_FORMAT(3, 4); #endif /* __RFC2822_H */ diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/sieve-binary-dumper.c --- a/src/lib-sieve/sieve-binary-dumper.c Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.c Tue Jul 31 01:24:28 2012 +0200 @@ -222,10 +222,11 @@ size_t offset; data = (const char *) buffer_get_data(blockbuf, &data_size); - + + // FIXME: calculate offset more nicely. sieve_binary_dump_sectionf - (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, - data_size, sblock->offset + 8 /* header size (yuck) */); + (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, + data_size, (unsigned long long int) sblock->offset + 8); line = t_str_new(128); offset = 0; diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/sieve-binary-dumper.h --- a/src/lib-sieve/sieve-binary-dumper.h Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.h Tue Jul 31 01:24:28 2012 +0200 @@ -25,9 +25,11 @@ */ void sieve_binary_dumpf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); void sieve_binary_dump_sectionf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); /* * Dumping the binary diff -r a1668b71e657 -r bea6fcece21e src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Fri Jul 13 10:06:46 2012 +0200 +++ b/src/lib-sieve/sieve-error.c Tue Jul 31 01:24:28 2012 +0200 @@ -602,7 +602,7 @@ typedef void (*master_log_func_t)(const char *fmt, ...) ATTR_FORMAT(1, 2); -static void sieve_master_vlog +static void ATTR_FORMAT(4, 0) sieve_master_vlog (struct sieve_error_handler *_ehandler, master_log_func_t log_func, const char *location, const char *fmt, va_list args) { @@ -624,7 +624,7 @@ log_func("%s", str_c(str)); } -static void sieve_master_verror +static void ATTR_FORMAT(4, 0) sieve_master_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -632,7 +632,7 @@ sieve_master_vlog(ehandler, i_error, location, fmt, args); } -static void sieve_master_vwarning +static void ATTR_FORMAT(4, 0) sieve_master_vwarning (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -640,7 +640,7 @@ sieve_master_vlog(ehandler, i_warning, location, fmt, args); } -static void sieve_master_vinfo +static void ATTR_FORMAT(4, 0) sieve_master_vinfo (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -648,7 +648,7 @@ sieve_master_vlog(ehandler, i_info, location, fmt, args); } -static void sieve_master_vdebug +static void ATTR_FORMAT(4, 0) sieve_master_vdebug (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -685,7 +685,7 @@ * - Output errors directly to stderror */ -static void sieve_stderr_vmessage +static void ATTR_FORMAT(4, 0) sieve_stderr_vmessage (struct sieve_error_handler *ehandler ATTR_UNUSED, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -695,28 +695,28 @@ fprintf(stderr, "%s: %s: %s.\n", location, prefix, t_strdup_vprintf(fmt, args)); } -static void sieve_stderr_verror +static void ATTR_FORMAT(4, 0) sieve_stderr_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_stderr_vwarning +static void ATTR_FORMAT(4, 0) sieve_stderr_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_stderr_vinfo +static void ATTR_FORMAT(4, 0) sieve_stderr_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_stderr_vdebug +static void ATTR_FORMAT(4, 0) sieve_stderr_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -757,7 +757,7 @@ bool crlf; }; -static void sieve_strbuf_vmessage +static void ATTR_FORMAT(4, 0) sieve_strbuf_vmessage (struct sieve_error_handler *ehandler, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -775,28 +775,28 @@ str_append(handler->errors, ".\r\n"); } -static void sieve_strbuf_verror +static void ATTR_FORMAT(4, 0) sieve_strbuf_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_strbuf_vwarning +static void ATTR_FORMAT(4, 0) sieve_strbuf_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_strbuf_vinfo +static void ATTR_FORMAT(4, 0) sieve_strbuf_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_strbuf_vdebug +static void ATTR_FORMAT(4, 0) sieve_strbuf_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -841,7 +841,7 @@ struct ostream *stream; }; -static void sieve_logfile_vprintf +static void ATTR_FORMAT(4, 0) sieve_logfile_vprintf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, va_list args) { @@ -877,7 +877,7 @@ } } -inline static void sieve_logfile_printf +inline static void ATTR_FORMAT(4, 5) sieve_logfile_printf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, ...) { @@ -985,7 +985,7 @@ } } -static void sieve_logfile_verror +static void ATTR_FORMAT(4, 0) sieve_logfile_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -997,7 +997,7 @@ sieve_logfile_vprintf(handler, location, "error", fmt, args); } -static void sieve_logfile_vwarning +static void ATTR_FORMAT(4, 0) sieve_logfile_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1009,7 +1009,7 @@ sieve_logfile_vprintf(handler, location, "warning", fmt, args); } -static void sieve_logfile_vinfo +static void ATTR_FORMAT(4, 0) sieve_logfile_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1021,7 +1021,7 @@ sieve_logfile_vprintf(handler, location, "info", fmt, args); } -static void sieve_logfile_vdebug +static void ATTR_FORMAT(4, 0) sieve_logfile_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1093,9 +1093,9 @@ const char *prefix; }; -static const char *_prefix_message +static const char *ATTR_FORMAT(3, 0) _prefix_message (struct sieve_prefix_ehandler *ehandler, - const char *location, const char *fmt, va_list args) + const char *location, const char *fmt, va_list args) { string_t *str = t_str_new(256); From pigeonhole at rename-it.nl Tue Jul 31 02:24:36 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:24:36 +0200 Subject: dovecot-2.2-pigeonhole: Fixed several Clang compile warnings and... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e3ea0270985a changeset: 1640:e3ea0270985a user: Stephan Bosch date: Mon Jul 30 10:14:42 2012 +0200 description: Fixed several Clang compile warnings and a few potential bugs. Patch by Timo Sirainen. diffstat: src/lib-sieve/rfc2822.h | 2 +- src/lib-sieve/sieve-binary-dumper.c | 7 ++- src/lib-sieve/sieve-binary-dumper.h | 6 ++- src/lib-sieve/sieve-error.c | 64 ++++++++++++++++++------------------ src/lib-sieve/sieve-result.h | 3 +- src/lib-sieve/sieve-runtime-trace.c | 6 +- src/lib-sieve/sieve-runtime-trace.h | 20 ++++++----- src/lib-sievestorage/sieve-storage.c | 2 +- src/testsuite/testsuite-log.c | 8 ++-- 9 files changed, 62 insertions(+), 56 deletions(-) diffs (truncated from 498 to 300 lines): diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/rfc2822.h --- a/src/lib-sieve/rfc2822.h Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/rfc2822.h Mon Jul 30 10:14:42 2012 +0200 @@ -33,7 +33,7 @@ int rfc2822_header_field_write (FILE *f, const char *name, const char *body); - + int rfc2822_header_field_printf (FILE *f, const char *name, const char *body_fmt, ...) ATTR_FORMAT(3, 4); diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-binary-dumper.c --- a/src/lib-sieve/sieve-binary-dumper.c Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.c Mon Jul 30 10:14:42 2012 +0200 @@ -222,10 +222,11 @@ size_t offset; data = (const char *) buffer_get_data(blockbuf, &data_size); - + + // FIXME: calculate offset more nicely. sieve_binary_dump_sectionf - (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, - data_size, sblock->offset + 8 /* header size (yuck) */); + (denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i, + data_size, (unsigned long long int) sblock->offset + 8); line = t_str_new(128); offset = 0; diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-binary-dumper.h --- a/src/lib-sieve/sieve-binary-dumper.h Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-binary-dumper.h Mon Jul 30 10:14:42 2012 +0200 @@ -25,9 +25,11 @@ */ void sieve_binary_dumpf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); void sieve_binary_dump_sectionf - (const struct sieve_dumptime_env *denv, const char *fmt, ...); + (const struct sieve_dumptime_env *denv, const char *fmt, ...) + ATTR_FORMAT(2, 3); /* * Dumping the binary diff -r b614a99f40f1 -r e3ea0270985a src/lib-sieve/sieve-error.c --- a/src/lib-sieve/sieve-error.c Wed Jul 25 09:08:11 2012 +0200 +++ b/src/lib-sieve/sieve-error.c Mon Jul 30 10:14:42 2012 +0200 @@ -602,7 +602,7 @@ typedef void (*master_log_func_t)(const char *fmt, ...) ATTR_FORMAT(1, 2); -static void sieve_master_vlog +static void ATTR_FORMAT(4, 0) sieve_master_vlog (struct sieve_error_handler *_ehandler, master_log_func_t log_func, const char *location, const char *fmt, va_list args) { @@ -624,7 +624,7 @@ log_func("%s", str_c(str)); } -static void sieve_master_verror +static void ATTR_FORMAT(4, 0) sieve_master_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -632,7 +632,7 @@ sieve_master_vlog(ehandler, i_error, location, fmt, args); } -static void sieve_master_vwarning +static void ATTR_FORMAT(4, 0) sieve_master_vwarning (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -640,7 +640,7 @@ sieve_master_vlog(ehandler, i_warning, location, fmt, args); } -static void sieve_master_vinfo +static void ATTR_FORMAT(4, 0) sieve_master_vinfo (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -648,7 +648,7 @@ sieve_master_vlog(ehandler, i_info, location, fmt, args); } -static void sieve_master_vdebug +static void ATTR_FORMAT(4, 0) sieve_master_vdebug (struct sieve_error_handler *ehandler ATTR_UNUSED, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) @@ -685,7 +685,7 @@ * - Output errors directly to stderror */ -static void sieve_stderr_vmessage +static void ATTR_FORMAT(4, 0) sieve_stderr_vmessage (struct sieve_error_handler *ehandler ATTR_UNUSED, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -695,28 +695,28 @@ fprintf(stderr, "%s: %s: %s.\n", location, prefix, t_strdup_vprintf(fmt, args)); } -static void sieve_stderr_verror +static void ATTR_FORMAT(4, 0) sieve_stderr_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_stderr_vwarning +static void ATTR_FORMAT(4, 0) sieve_stderr_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_stderr_vinfo +static void ATTR_FORMAT(4, 0) sieve_stderr_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_stderr_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_stderr_vdebug +static void ATTR_FORMAT(4, 0) sieve_stderr_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -757,7 +757,7 @@ bool crlf; }; -static void sieve_strbuf_vmessage +static void ATTR_FORMAT(4, 0) sieve_strbuf_vmessage (struct sieve_error_handler *ehandler, const char *prefix, const char *location, const char *fmt, va_list args) { @@ -775,28 +775,28 @@ str_append(handler->errors, ".\r\n"); } -static void sieve_strbuf_verror +static void ATTR_FORMAT(4, 0) sieve_strbuf_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "error", location, fmt, args); } -static void sieve_strbuf_vwarning +static void ATTR_FORMAT(4, 0) sieve_strbuf_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "warning", location, fmt, args); } -static void sieve_strbuf_vinfo +static void ATTR_FORMAT(4, 0) sieve_strbuf_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { sieve_strbuf_vmessage(ehandler, "info", location, fmt, args); } -static void sieve_strbuf_vdebug +static void ATTR_FORMAT(4, 0) sieve_strbuf_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -841,7 +841,7 @@ struct ostream *stream; }; -static void sieve_logfile_vprintf +static void ATTR_FORMAT(4, 0) sieve_logfile_vprintf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, va_list args) { @@ -877,7 +877,7 @@ } } -inline static void sieve_logfile_printf +inline static void ATTR_FORMAT(4, 5) sieve_logfile_printf (struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix, const char *fmt, ...) { @@ -985,7 +985,7 @@ } } -static void sieve_logfile_verror +static void ATTR_FORMAT(4, 0) sieve_logfile_verror (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -997,7 +997,7 @@ sieve_logfile_vprintf(handler, location, "error", fmt, args); } -static void sieve_logfile_vwarning +static void ATTR_FORMAT(4, 0) sieve_logfile_vwarning (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1009,7 +1009,7 @@ sieve_logfile_vprintf(handler, location, "warning", fmt, args); } -static void sieve_logfile_vinfo +static void ATTR_FORMAT(4, 0) sieve_logfile_vinfo (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1021,7 +1021,7 @@ sieve_logfile_vprintf(handler, location, "info", fmt, args); } -static void sieve_logfile_vdebug +static void ATTR_FORMAT(4, 0) sieve_logfile_vdebug (struct sieve_error_handler *ehandler, unsigned int flags ATTR_UNUSED, const char *location, const char *fmt, va_list args) { @@ -1093,9 +1093,9 @@ const char *prefix; }; -static const char *_prefix_message +static const char *ATTR_FORMAT(3, 0) _prefix_message (struct sieve_prefix_ehandler *ehandler, - const char *location, const char *fmt, va_list args) + const char *location, const char *fmt, va_list args) { string_t *str = t_str_new(256); @@ -1108,7 +1108,7 @@ return str_c(str); } -static void sieve_prefix_verror +static void ATTR_FORMAT(4, 0) sieve_prefix_verror (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1119,7 +1119,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vwarning +static void ATTR_FORMAT(4, 0) sieve_prefix_vwarning (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1130,7 +1130,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vinfo +static void ATTR_FORMAT(4, 0) sieve_prefix_vinfo (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1141,7 +1141,7 @@ ehandler->location, "%s", _prefix_message(ehandler, location, fmt, args)); } -static void sieve_prefix_vdebug +static void ATTR_FORMAT(4, 0) sieve_prefix_vdebug (struct sieve_error_handler *_ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1190,7 +1190,7 @@ ARRAY_DEFINE(table, struct var_expand_table); }; -static const char *_expand_message +static const char *ATTR_FORMAT(3, 0) _expand_message (struct sieve_error_handler *_ehandler, const char *location, const char *fmt, va_list args) { @@ -1211,7 +1211,7 @@ return str_c(str); } -static void sieve_varexpand_verror +static void ATTR_FORMAT(4, 0) sieve_varexpand_verror (struct sieve_error_handler *ehandler, unsigned int flags, const char *location, const char *fmt, va_list args) { @@ -1219,7 +1219,7 @@ From pigeonhole at rename-it.nl Tue Jul 31 02:24:36 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:24:36 +0200 Subject: dovecot-2.2-pigeonhole: Fix linkage with ld.gold. Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/c52a0c561311 changeset: 1641:c52a0c561311 user: Stephan Bosch date: Tue Jul 31 01:18:15 2012 +0200 description: Fix linkage with ld.gold. Patch by Eray Aslan. diffstat: src/lib-sieve/Makefile.am | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r e3ea0270985a -r c52a0c561311 src/lib-sieve/Makefile.am --- a/src/lib-sieve/Makefile.am Mon Jul 30 10:14:42 2012 +0200 +++ b/src/lib-sieve/Makefile.am Tue Jul 31 01:18:15 2012 +0200 @@ -70,8 +70,8 @@ $(extdir)/vnd.dovecot/duplicate/libsieve_ext_duplicate.la \ $(unfinished_plugins) -libdovecot_sieve_la_DEPENDENCIES = $(plugins) -libdovecot_sieve_la_LIBADD = $(plugins) +libdovecot_sieve_la_DEPENDENCIES = $(plugins) $(LIBDOVECOT_LDA_DEPS) +libdovecot_sieve_la_LIBADD = $(plugins) $(LIBDOVECOT_LDA) libdovecot_sieve_la_SOURCES = \ rfc2822.c \ From pigeonhole at rename-it.nl Tue Jul 31 02:24:36 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:24:36 +0200 Subject: dovecot-2.2-pigeonhole: Example config: disabled default section... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e6d102e6f0fc changeset: 1638:e6d102e6f0fc user: Stephan Bosch date: Mon Jul 16 21:36:23 2012 +0200 description: Example config: disabled default sections for managesieve and managesieve-login services. This currently breaks uninstall when the settings plugins are removed and 20-managesieve.conf remains in conf.d directory. These sections only need to be active in the config file when settings for the services themselves need to be disabled. diffstat: doc/example-config/conf.d/20-managesieve.conf | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (28 lines): diff -r 6ceeb6421231 -r e6d102e6f0fc doc/example-config/conf.d/20-managesieve.conf --- a/doc/example-config/conf.d/20-managesieve.conf Thu Jul 12 23:57:50 2012 +0200 +++ b/doc/example-config/conf.d/20-managesieve.conf Mon Jul 16 21:36:23 2012 +0200 @@ -7,7 +7,7 @@ # Service definitions -service managesieve-login { +#service managesieve-login { #inet_listener sieve { # port = 4190 #} @@ -26,12 +26,12 @@ # If you set service_count=0, you probably need to grow this. #vsz_limit = 64M -} +#} -service managesieve { +#service managesieve { # Max. number of ManageSieve processes (connections) #process_count = 1024 -} +#} # Service configuration From pigeonhole at rename-it.nl Tue Jul 31 02:24:36 2012 From: pigeonhole at rename-it.nl (pigeonhole at rename-it.nl) Date: Tue, 31 Jul 2012 01:24:36 +0200 Subject: dovecot-2.2-pigeonhole: Editheader: name of added header is now ... Message-ID: details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/b614a99f40f1 changeset: 1639:b614a99f40f1 user: Stephan Bosch date: Wed Jul 25 09:08:11 2012 +0200 description: Editheader: name of added header is now first sanitized to have capital letters where conventional. diffstat: src/lib-sieve/plugins/editheader/cmd-addheader.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diffs (12 lines): diff -r e6d102e6f0fc -r b614a99f40f1 src/lib-sieve/plugins/editheader/cmd-addheader.c --- a/src/lib-sieve/plugins/editheader/cmd-addheader.c Mon Jul 16 21:36:23 2012 +0200 +++ b/src/lib-sieve/plugins/editheader/cmd-addheader.c Wed Jul 25 09:08:11 2012 +0200 @@ -304,7 +304,6 @@ str_sanitize(str_c(field_name), 80), str_sanitize(str_c(value), 80)); edmail = sieve_message_edit(renv->msgctx); - edit_mail_header_add(edmail, str_c(field_name), str_c(value), last); - + edit_mail_header_add(edmail, rfc2822_header_field_name_sanitize(str_c(field_name)), str_c(value), last); return SIEVE_EXEC_OK; } From dovecot at dovecot.org Tue Jul 31 02:45:39 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 02:45:39 +0300 Subject: dovecot-2.2: lib-master: Assert-crashfix Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/4d518c1a366c changeset: 14736:4d518c1a366c user: Timo Sirainen date: Tue Jul 31 02:45:23 2012 +0300 description: lib-master: Assert-crashfix diffstat: src/lib-master/master-service-ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 1e7c33ce9c16 -r 4d518c1a366c src/lib-master/master-service-ssl.c --- a/src/lib-master/master-service-ssl.c Mon Jul 30 19:49:43 2012 +0300 +++ b/src/lib-master/master-service-ssl.c Tue Jul 31 02:45:23 2012 +0300 @@ -99,7 +99,7 @@ /* must be called after master_service_init_finish() so that if initialization fails we can close the SSL listeners */ - i_assert(service->listeners != NULL); + i_assert(service->listeners != NULL || service->socket_count == 0); set = master_service_ssl_settings_get(service); From dovecot at dovecot.org Tue Jul 31 02:46:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 02:46:27 +0300 Subject: dovecot-2.2: imap: CATENATE command fixes. Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/1af9d08e67d7 changeset: 14737:1af9d08e67d7 user: Timo Sirainen date: Tue Jul 31 02:46:21 2012 +0300 description: imap: CATENATE command fixes. Patch by Stephan Bosch diffstat: src/imap/cmd-append.c | 25 ++++++++++++------------- src/lib-imap-storage/imap-msgpart-url.c | 11 ++++++----- src/lib/uri-util.c | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diffs (130 lines): diff -r 4d518c1a366c -r 1af9d08e67d7 src/imap/cmd-append.c --- a/src/imap/cmd-append.c Tue Jul 31 02:45:23 2012 +0300 +++ b/src/imap/cmd-append.c Tue Jul 31 02:46:21 2012 +0300 @@ -59,9 +59,9 @@ str_printfa(str, "Disconnected in APPEND (%u msgs, %u secs", ctx->count, secs); - if (ctx->input != NULL) { + if (ctx->litinput != NULL) { str_printfa(str, ", %"PRIuUOFF_T"/%"PRIuUOFF_T" bytes", - ctx->input->v_offset, ctx->literal_size); + ctx->litinput->v_offset, ctx->literal_size); } str_append_c(str, ')'); return str_c(str); @@ -156,8 +156,8 @@ return TRUE; } - (void)i_stream_read(ctx->input); - i_stream_skip(ctx->input, i_stream_get_data_size(ctx->input)); + (void)i_stream_read(ctx->litinput); + i_stream_skip(ctx->litinput, i_stream_get_data_size(ctx->litinput)); if (cmd->client->input->closed) { cmd_append_finish(ctx); @@ -189,7 +189,7 @@ /* we have to read the nonsynced literal so we don't treat the message data as commands. */ - ctx->input = i_stream_create_limit(ctx->client->input, ctx->literal_size); + ctx->litinput = i_stream_create_limit(ctx->client->input, ctx->literal_size); ctx->message_input = TRUE; ctx->cmd->func = cmd_append_continue_cancel; @@ -249,17 +249,16 @@ ctx->cat_msg_size = newsize; /* add this input stream to chain */ i_stream_chain_append(ctx->catchain, input); - input = NULL; /* save by reading the chain stream */ - while (!i_stream_is_eof(ctx->input)) { - ret = i_stream_read(ctx->input); + while (!i_stream_is_eof(input)) { + ret = i_stream_read(input); i_assert(ret != 0); /* we can handle only blocking input here */ if (mailbox_save_continue(ctx->save_ctx) < 0 || ret == -1) break; } - if (ctx->input->stream_errno != 0) { - errno = ctx->input->stream_errno; + if (input->stream_errno != 0) { + errno = input->stream_errno; mail_storage_set_critical(ctx->box->storage, "read(%s) failed: %m (for CATENATE URL %s)", i_stream_get_name(input), caturl); @@ -719,7 +718,7 @@ if (ctx->save_ctx != NULL) { while (ctx->litinput->v_offset != ctx->literal_size) { - ret = i_stream_read(ctx->input); + ret = i_stream_read(ctx->litinput); if (mailbox_save_continue(ctx->save_ctx) < 0) { /* we still have to finish reading the message from client */ @@ -732,8 +731,8 @@ } if (ctx->save_ctx == NULL) { - (void)i_stream_read(ctx->input); - i_stream_skip(ctx->input, i_stream_get_data_size(ctx->input)); + (void)i_stream_read(ctx->litinput); + i_stream_skip(ctx->litinput, i_stream_get_data_size(ctx->litinput)); } if (ctx->litinput->eof || client->input->closed) { diff -r 4d518c1a366c -r 1af9d08e67d7 src/lib-imap-storage/imap-msgpart-url.c --- a/src/lib-imap-storage/imap-msgpart-url.c Tue Jul 31 02:45:23 2012 +0300 +++ b/src/lib-imap-storage/imap-msgpart-url.c Tue Jul 31 02:46:21 2012 +0300 @@ -67,18 +67,18 @@ if (imap_url_parse(urlstr, &base_url, IMAP_URL_PARSE_REQUIRE_RELATIVE, &url, &error) < 0) { *error_r = t_strconcat("Invalid IMAP URL: ", error, NULL); - return -1; + return 0; } if (url->mailbox == NULL) { *error_r = "Mailbox-relative IMAP URL, but no mailbox selected"; - return -1; + return 0; } if (url->uid == 0 || url->search_program != NULL) { *error_r = "Invalid messagepart IMAP URL"; - return -1; + return 0; } *url_r = imap_msgpart_url_create(user, url); - return 0; + return 1; } struct mailbox *imap_msgpart_url_get_mailbox(struct imap_msgpart_url *mpurl) @@ -168,12 +168,13 @@ imap_msgpart_url_open_part(struct imap_msgpart_url *mpurl, struct mail **mail_r, struct imap_msgpart **msgpart_r, const char **error_r) { + const char *section = mpurl->section == NULL ? "" : mpurl->section; int ret; if ((ret = imap_msgpart_url_open_mail(mpurl, mail_r, error_r)) <= 0) return ret; - if (imap_msgpart_parse((*mail_r)->box, mpurl->section, msgpart_r) < 0) { + if (imap_msgpart_parse((*mail_r)->box, section, msgpart_r) < 0) { *error_r = "Invalid section"; return 0; } diff -r 4d518c1a366c -r 1af9d08e67d7 src/lib/uri-util.c --- a/src/lib/uri-util.c Tue Jul 31 02:45:23 2012 +0300 +++ b/src/lib/uri-util.c Tue Jul 31 02:46:21 2012 +0300 @@ -239,7 +239,7 @@ p = (const char *)parser->cur; if (uri_cut_scheme(&p, scheme_r) < 0) - return -1; + return 0; parser->cur = (const unsigned char *)p; return 1; From dovecot at dovecot.org Tue Jul 31 18:35:03 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 18:35:03 +0300 Subject: dovecot-2.1: imap: Fixed LIST handling with reference parameter. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/fac6b994e869 changeset: 14639:fac6b994e869 user: Timo Sirainen date: Tue Jul 31 18:34:53 2012 +0300 description: imap: Fixed LIST handling with reference parameter. For example "LIST shared/ %" failed to list shared/user namespace prefix. diffstat: src/imap/cmd-list.c | 28 +++++++++++++++------------- 1 files changed, 15 insertions(+), 13 deletions(-) diffs (72 lines): diff -r ec5c630012cd -r fac6b994e869 src/imap/cmd-list.c --- a/src/imap/cmd-list.c Tue Jul 31 18:33:45 2012 +0300 +++ b/src/imap/cmd-list.c Tue Jul 31 18:34:53 2012 +0300 @@ -236,17 +236,22 @@ enum imap_match_result match; const char *ns_prefix, *p; bool inboxcase; + unsigned int skip_len; + + skip_len = strlen(ctx->ref); + if (strncmp(ctx->ns->prefix, ctx->ref, skip_len) != 0) + skip_len = 0; inboxcase = strncasecmp(ctx->ns->prefix, "INBOX", 5) == 0 && ctx->ns->prefix[5] == mail_namespace_get_sep(ctx->ns); glob = imap_match_init_multiple(pool_datastack_create(), ctx->patterns, inboxcase, mail_namespace_get_sep(ctx->ns)); - ns_prefix = ctx->ns->prefix; + ns_prefix = ctx->ns->prefix + skip_len; match = imap_match(glob, ns_prefix); if (match == IMAP_MATCH_YES) { - return !ctx->cur_ns_skip_trailing_sep ? ns_prefix : - t_strndup(ns_prefix, strlen(ns_prefix)-1); + return !ctx->cur_ns_skip_trailing_sep ? ctx->ns->prefix : + t_strndup(ctx->ns->prefix, strlen(ctx->ns->prefix)-1); } while ((match & IMAP_MATCH_PARENT) != 0) { @@ -256,7 +261,8 @@ match = imap_match(glob, ns_prefix); } i_assert(match == IMAP_MATCH_YES); - return ns_prefix; + return t_strconcat(t_strndup(ctx->ns->prefix, skip_len), + ns_prefix, NULL); } static void list_reply_append_ns_sep_param(string_t *str, char sep) @@ -510,18 +516,14 @@ skip_namespace_prefix(const char **prefix, const char **pattern, bool inbox_check, char sep) { - size_t pattern_len, prefix_len; + size_t pattern_len, prefix_len, min_len; bool match; prefix_len = strlen(*prefix); pattern_len = strlen(*pattern); + min_len = I_MIN(prefix_len, pattern_len); - if (pattern_len < prefix_len) { - /* eg. namespace prefix = "INBOX.", pattern = "INBOX" */ - return; - } - - match = strncmp(*prefix, *pattern, prefix_len) == 0; + match = strncmp(*prefix, *pattern, min_len) == 0; if (!match && inbox_check) { /* try INBOX check. */ match = prefix_len >= 5 && @@ -533,8 +535,8 @@ } if (match) { - *prefix += prefix_len; - *pattern += prefix_len; + *prefix += min_len; + *pattern += min_len; } } From dovecot at dovecot.org Tue Jul 31 18:35:03 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 18:35:03 +0300 Subject: dovecot-2.1: lib-storage: Avoid creating shared user for an empt... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/ec5c630012cd changeset: 14638:ec5c630012cd user: Timo Sirainen date: Tue Jul 31 18:33:45 2012 +0300 description: lib-storage: Avoid creating shared user for an empty username. diffstat: src/lib-storage/index/shared/shared-list.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r c598f76eeeed -r ec5c630012cd src/lib-storage/index/shared/shared-list.c --- a/src/lib-storage/index/shared/shared-list.c Sat Jul 28 20:31:30 2012 +0300 +++ b/src/lib-storage/index/shared/shared-list.c Tue Jul 31 18:33:45 2012 +0300 @@ -135,7 +135,8 @@ else ns_ref = NULL; - if (ns_ref != NULL && shared_storage_get_namespace(&ns, &ns_ref) == 0) + if (ns_ref != NULL && *ns_ref != '\0' && + shared_storage_get_namespace(&ns, &ns_ref) == 0) return mailbox_list_join_refpattern(ns->list, ref, pattern); /* fallback to default behavior */ From dovecot at dovecot.org Tue Jul 31 19:32:19 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 19:32:19 +0300 Subject: dovecot-2.2: lib-storage: Fixes to handling private message flag... Message-ID: details: http://hg.dovecot.org/dovecot-2.2/rev/c3a781ef0aeb changeset: 14738:c3a781ef0aeb user: Timo Sirainen date: Tue Jul 31 19:32:03 2012 +0300 description: lib-storage: Fixes to handling private message flag indexes. diffstat: src/lib-storage/index/index-search.c | 56 ++++++++++------------ src/lib-storage/index/index-status.c | 81 ++++++++++++++++++++++++++++----- src/lib-storage/index/index-sync-pvt.c | 9 +++ src/lib-storage/index/index-sync.c | 7 +- 4 files changed, 107 insertions(+), 46 deletions(-) diffs (282 lines): diff -r 1af9d08e67d7 -r c3a781ef0aeb src/lib-storage/index/index-search.c --- a/src/lib-storage/index/index-search.c Tue Jul 31 02:46:21 2012 +0300 +++ b/src/lib-storage/index/index-search.c Tue Jul 31 19:32:03 2012 +0300 @@ -151,10 +151,7 @@ static bool index_search_get_pvt(struct index_search_context *ctx, uint32_t uid) { - if (ctx->box->view_pvt == NULL) { - /* no private view (set by view syncing) -> no private flags */ - return FALSE; - } + index_transaction_init_pvt(ctx->mail_ctx.transaction); if (ctx->pvt_uid == uid) return ctx->pvt_seq != 0; @@ -183,12 +180,17 @@ if ((arg->value.flags & MAIL_RECENT) != 0 && index_mailbox_is_recent(ctx->box, rec->uid)) flags |= MAIL_RECENT; - if (index_search_get_pvt(ctx, rec->uid)) { + if (ctx->box->view_pvt == NULL) { + /* no private view (set by view syncing) -> + no private flags */ + } else { pvt_flags_mask = mailbox_get_private_flags_mask(ctx->box); flags &= ~pvt_flags_mask; - rec = mail_index_lookup(ctx->mail_ctx.transaction->view_pvt, - ctx->pvt_seq); - flags |= rec->flags & pvt_flags_mask; + if (index_search_get_pvt(ctx, rec->uid)) { + rec = mail_index_lookup(ctx->mail_ctx.transaction->view_pvt, + ctx->pvt_seq); + flags |= rec->flags & pvt_flags_mask; + } } return (flags & arg->value.flags) == arg->value.flags; case SEARCH_KEYWORDS: @@ -892,20 +894,14 @@ struct mail_search_arg *args, uint32_t *seq1, uint32_t *seq2) { - const struct mail_index_header *hdr_seen, *hdr_del, *hdr_pvt; + const struct mail_index_header *hdr; enum mail_flags pvt_flags_mask; - hdr_seen = hdr_del = mail_index_get_header(ctx->view); - - if (ctx->box->view_pvt != NULL) { - pvt_flags_mask = mailbox_get_private_flags_mask(ctx->box); - index_transaction_init_pvt(ctx->mail_ctx.transaction); - hdr_pvt = mail_index_get_header(ctx->mail_ctx.transaction->view_pvt); - if ((pvt_flags_mask & MAIL_SEEN) != 0) - hdr_seen = hdr_pvt; - if ((pvt_flags_mask & MAIL_DELETED) != 0) - hdr_del = hdr_pvt; - } + hdr = mail_index_get_header(ctx->view); + /* we can't trust that private view's header is fully up to date, + so do this optimization only for non-private flags */ + pvt_flags_mask = ctx->box->view_pvt == NULL ? 0 : + mailbox_get_private_flags_mask(ctx->box); for (; args != NULL; args = args->next) { if (args->type != SEARCH_FLAGS) { @@ -915,13 +911,13 @@ } continue; } - if ((args->value.flags & MAIL_SEEN) != 0) { + if ((args->value.flags & MAIL_SEEN) != 0 && + (pvt_flags_mask & MAIL_SEEN) == 0) { /* SEEN with 0 seen? */ - if (!args->match_not && hdr_seen->seen_messages_count == 0) + if (!args->match_not && hdr->seen_messages_count == 0) return FALSE; - if (hdr_seen->seen_messages_count == - hdr_seen->messages_count) { + if (hdr->seen_messages_count == hdr->messages_count) { /* UNSEEN with all seen? */ if (args->match_not) return FALSE; @@ -931,17 +927,17 @@ } else if (args->match_not) { /* UNSEEN with lowwater limiting */ search_limit_lowwater(ctx, - hdr_seen->first_unseen_uid_lowwater, seq1); + hdr->first_unseen_uid_lowwater, seq1); } } - if ((args->value.flags & MAIL_DELETED) != 0) { + if ((args->value.flags & MAIL_DELETED) != 0 && + (pvt_flags_mask & MAIL_DELETED) == 0) { /* DELETED with 0 deleted? */ if (!args->match_not && - hdr_del->deleted_messages_count == 0) + hdr->deleted_messages_count == 0) return FALSE; - if (hdr_del->deleted_messages_count == - hdr_del->messages_count) { + if (hdr->deleted_messages_count == hdr->messages_count) { /* UNDELETED with all deleted? */ if (args->match_not) return FALSE; @@ -951,7 +947,7 @@ } else if (!args->match_not) { /* DELETED with lowwater limiting */ search_limit_lowwater(ctx, - hdr_del->first_deleted_uid_lowwater, seq1); + hdr->first_deleted_uid_lowwater, seq1); } } } diff -r 1af9d08e67d7 -r c3a781ef0aeb src/lib-storage/index/index-status.c --- a/src/lib-storage/index/index-status.c Tue Jul 31 02:46:21 2012 +0300 +++ b/src/lib-storage/index/index-status.c Tue Jul 31 19:32:03 2012 +0300 @@ -43,18 +43,72 @@ return 0; } +static unsigned int index_storage_count_pvt_unseen(struct mailbox *box) +{ + const struct mail_index_record *pvt_rec; + uint32_t shared_seq, pvt_seq, shared_count, pvt_count; + uint32_t shared_uid; + unsigned int unseen_count = 0; + + /* we can't trust private index to be up to date. we'll need to go + through the shared index and for each existing mail lookup its + private flags. if a mail doesn't exist in private index then its + flags are 0. */ + shared_count = mail_index_view_get_messages_count(box->view); + pvt_count = mail_index_view_get_messages_count(box->view_pvt); + shared_seq = pvt_seq = 1; + while (shared_seq <= shared_count && pvt_seq <= pvt_count) { + mail_index_lookup_uid(box->view, shared_seq, &shared_uid); + pvt_rec = mail_index_lookup(box->view_pvt, pvt_seq); + + if (shared_uid == pvt_rec->uid) { + if ((pvt_rec->flags & MAIL_SEEN) == 0) + unseen_count++; + shared_seq++; pvt_seq++; + } else if (shared_uid < pvt_rec->uid) { + shared_seq++; + } else { + pvt_seq++; + } + } + unseen_count += (shared_count+1) - shared_seq; + return unseen_count; +} + +static uint32_t index_storage_find_first_pvt_unseen_seq(struct mailbox *box) +{ + const struct mail_index_header *pvt_hdr; + const struct mail_index_record *pvt_rec; + uint32_t pvt_seq, pvt_count, shared_seq, seq2; + + pvt_count = mail_index_view_get_messages_count(box->view_pvt); + mail_index_lookup_first(box->view_pvt, 0, MAIL_SEEN, &pvt_seq); + for (; pvt_seq <= pvt_count; pvt_seq++) { + pvt_rec = mail_index_lookup(box->view_pvt, pvt_seq); + if ((pvt_rec->flags & MAIL_SEEN) == 0 && + mail_index_lookup_seq(box->view, pvt_rec->uid, &shared_seq)) + return shared_seq; + } + /* if shared index has any messages that don't exist in private index, + the first of them is the first unseen message */ + pvt_hdr = mail_index_get_header(box->view_pvt); + if (mail_index_lookup_seq_range(box->view, + pvt_hdr->next_uid, (uint32_t)-1, + &shared_seq, &seq2)) + return shared_seq; + return 0; +} + void index_storage_get_open_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r) { - const struct mail_index_header *hdr, *hdr_pvt; + const struct mail_index_header *hdr; memset(status_r, 0, sizeof(struct mailbox_status)); /* we can get most of the status items without any trouble */ hdr = mail_index_get_header(box->view); - hdr_pvt = box->view_pvt == NULL ? NULL : - mail_index_get_header(box->view_pvt); status_r->messages = hdr->messages_count; if ((items & STATUS_RECENT) != 0) { /* make sure recent count is set, in case syncing hasn't @@ -63,13 +117,14 @@ status_r->recent = index_mailbox_get_recent_count(box); i_assert(status_r->recent <= status_r->messages); } - if (hdr_pvt == NULL || - (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { - status_r->unseen = hdr->messages_count - - hdr->seen_messages_count; - } else { - status_r->unseen = hdr_pvt->messages_count - - hdr_pvt->seen_messages_count; + if ((items & STATUS_UNSEEN) != 0) { + if (box->view_pvt == NULL || + (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { + status_r->unseen = hdr->messages_count - + hdr->seen_messages_count; + } else { + status_r->unseen = index_storage_count_pvt_unseen(box); + } } status_r->uidvalidity = hdr->uid_validity; status_r->uidnext = hdr->next_uid; @@ -87,13 +142,13 @@ } if ((items & STATUS_FIRST_UNSEEN_SEQ) != 0) { - if (hdr_pvt == NULL || + if (box->view_pvt == NULL || (mailbox_get_private_flags_mask(box) & MAIL_SEEN) == 0) { mail_index_lookup_first(box->view, 0, MAIL_SEEN, &status_r->first_unseen_seq); } else { - mail_index_lookup_first(box->view_pvt, 0, MAIL_SEEN, - &status_r->first_unseen_seq); + status_r->first_unseen_seq = + index_storage_find_first_pvt_unseen_seq(box); } } if ((items & STATUS_LAST_CACHED_SEQ) != 0) diff -r 1af9d08e67d7 -r c3a781ef0aeb src/lib-storage/index/index-sync-pvt.c --- a/src/lib-storage/index/index-sync-pvt.c Tue Jul 31 02:46:21 2012 +0300 +++ b/src/lib-storage/index/index-sync-pvt.c Tue Jul 31 19:32:03 2012 +0300 @@ -178,6 +178,7 @@ seq_shared = 1; } + uid = 0; for (; seq_shared <= count_shared; seq_shared++) { mail_index_lookup_uid(view_shared, seq_shared, &uid); mail_index_append(trans_pvt, uid, &seq_pvt); @@ -189,6 +190,14 @@ seq_old_pvt, seq_pvt); } } + + if (uid < hdr_shared->next_uid) { + mail_index_update_header(trans_pvt, + offsetof(struct mail_index_header, next_uid), + &hdr_shared->next_uid, + sizeof(hdr_shared->next_uid), FALSE); + } + if ((ret = mail_index_sync_commit(&sync_ctx)) < 0) mail_storage_set_index_error(box); mail_index_view_close(&view_shared); diff -r 1af9d08e67d7 -r c3a781ef0aeb src/lib-storage/index/index-sync.c --- a/src/lib-storage/index/index-sync.c Tue Jul 31 02:46:21 2012 +0300 +++ b/src/lib-storage/index/index-sync.c Tue Jul 31 19:32:03 2012 +0300 @@ -189,9 +189,6 @@ return &ctx->ctx; } - /* sync private index if needed */ - (void)index_storage_mailbox_sync_pvt(box); - if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) sync_flags |= MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES; @@ -394,6 +391,10 @@ if (array_is_created(&ctx->all_flag_update_uids)) array_free(&ctx->all_flag_update_uids); + /* sync private index if needed. do this last to make sure that all + the new messages are added to the private index, so their flags can + be updated. */ + (void)index_storage_mailbox_sync_pvt(_ctx->box); i_free(ctx); return ret; } From dovecot at dovecot.org Tue Jul 31 20:59:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 20:59:29 +0300 Subject: dovecot-2.1: auth: if passwd-file isn't the only userdb, don't c... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/f74557336910 changeset: 14640:f74557336910 user: Timo Sirainen date: Tue Jul 31 20:59:22 2012 +0300 description: auth: if passwd-file isn't the only userdb, don't complain about missing userdb fields diffstat: src/auth/db-passwd-file.c | 18 +++++++++++++++--- src/auth/db-passwd-file.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diffs (65 lines): diff -r fac6b994e869 -r f74557336910 src/auth/db-passwd-file.c --- a/src/auth/db-passwd-file.c Tue Jul 31 18:34:53 2012 +0300 +++ b/src/auth/db-passwd-file.c Tue Jul 31 20:59:22 2012 +0300 @@ -7,6 +7,7 @@ #include "userdb.h" #include "db-passwd-file.h" +#include "array.h" #include "buffer.h" #include "istream.h" #include "hash.h" @@ -90,7 +91,7 @@ } if (*args == NULL) { - if (pw->db->userdb) { + if (pw->db->userdb_warn_missing) { i_error("passwd-file %s: User %s is missing " "userdb info", pw->path, username); } @@ -290,6 +291,15 @@ return NULL; } +static void db_passwd_file_set_userdb(struct db_passwd_file *db) +{ + db->userdb = TRUE; + /* warn about missing userdb fields only when there aren't any other + userdbs. */ + db->userdb_warn_missing = + array_count(&global_auth_settings->userdbs) == 1; +} + struct db_passwd_file * db_passwd_file_init(const char *path, bool userdb, bool debug) { @@ -300,13 +310,15 @@ db = db_passwd_file_find(path); if (db != NULL) { db->refcount++; - db->userdb = TRUE; + if (userdb) + db_passwd_file_set_userdb(db); return db; } db = i_new(struct db_passwd_file, 1); db->refcount = 1; - db->userdb = userdb; + if (userdb) + db_passwd_file_set_userdb(db); db->debug = debug; for (p = path; *p != '\0'; p++) { diff -r fac6b994e869 -r f74557336910 src/auth/db-passwd-file.h --- a/src/auth/db-passwd-file.h Tue Jul 31 18:34:53 2012 +0300 +++ b/src/auth/db-passwd-file.h Tue Jul 31 20:59:22 2012 +0300 @@ -37,6 +37,7 @@ unsigned int vars:1; unsigned int userdb:1; + unsigned int userdb_warn_missing:1; unsigned int debug:1; }; From dovecot at dovecot.org Tue Jul 31 22:03:12 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 22:03:12 +0300 Subject: dovecot-2.1: fts-solr: Log a better error if Solr sends invalid ... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/817b69b2b21f changeset: 14641:817b69b2b21f user: Timo Sirainen date: Tue Jul 31 22:03:00 2012 +0300 description: fts-solr: Log a better error if Solr sends invalid XML input. diffstat: src/plugins/fts-solr/solr-connection.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diffs (25 lines): diff -r f74557336910 -r 817b69b2b21f src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Tue Jul 31 20:59:22 2012 +0300 +++ b/src/plugins/fts-solr/solr-connection.c Tue Jul 31 22:03:00 2012 +0300 @@ -88,7 +88,7 @@ const void *data, size_t size, bool done) { enum XML_Error err; - int line; + int line, col; if (conn->xml_failed) return -1; @@ -99,8 +99,10 @@ err = XML_GetErrorCode(conn->xml_parser); if (err != XML_ERROR_FINISHED) { line = XML_GetCurrentLineNumber(conn->xml_parser); - i_error("fts_solr: Invalid XML input at line %d: %s", - line, XML_ErrorString(err)); + col = XML_GetCurrentColumnNumber(conn->xml_parser); + i_error("fts_solr: Invalid XML input at %d:%d: %s " + "(near: %.*s)", line, col, XML_ErrorString(err), + (int)I_MIN(size, 128), data); conn->xml_failed = TRUE; return -1; } From dovecot at dovecot.org Tue Jul 31 22:30:29 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 22:30:29 +0300 Subject: dovecot-2.1: script: Don't add an empty parameter to executed co... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/1d9d799a2efc changeset: 14642:1d9d799a2efc user: Timo Sirainen date: Tue Jul 31 22:30:19 2012 +0300 description: script: Don't add an empty parameter to executed command line Also fixed an error check diffstat: src/util/script.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (23 lines): diff -r 817b69b2b21f -r 1d9d799a2efc src/util/script.c --- a/src/util/script.c Tue Jul 31 22:03:00 2012 +0300 +++ b/src/util/script.c Tue Jul 31 22:30:19 2012 +0300 @@ -133,8 +133,8 @@ } alarm(0); - /* drop the last LF */ - buffer_set_used_size(input, scanpos-1); + /* drop the last two LFs */ + buffer_set_used_size(input, scanpos-2); args = t_strsplit(str_c(input), "\n"); script_verify_version(*args); args++; @@ -148,7 +148,7 @@ exec_child(conn, args + 1); i_unreached(); } - if (*args == '\0') + if (**args == '\0') i_fatal("empty options"); args++; } From dovecot at dovecot.org Tue Jul 31 22:33:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 22:33:27 +0300 Subject: dovecot-2.1: lib-storage: Improved missing namespace error messa... Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/0abb9b0a54db changeset: 14643:0abb9b0a54db user: Timo Sirainen date: Tue Jul 31 22:33:21 2012 +0300 description: lib-storage: Improved missing namespace error messages. diffstat: src/lib-storage/mail-namespace.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diffs (22 lines): diff -r 1d9d799a2efc -r 0abb9b0a54db src/lib-storage/mail-namespace.c --- a/src/lib-storage/mail-namespace.c Tue Jul 31 22:30:19 2012 +0300 +++ b/src/lib-storage/mail-namespace.c Tue Jul 31 22:33:21 2012 +0300 @@ -249,15 +249,15 @@ return FALSE; } if (list_sep == '\0') { - *error_r = "no list=yes namespaces"; + *error_r = "list=yes namespace missing"; return FALSE; } if (!visible_namespaces) { - *error_r = "no hidden=no namespaces"; + *error_r = "hidden=no namespace missing"; return FALSE; } if (subscriptions_count == 0) { - *error_r = "no subscriptions=yes namespaces"; + *error_r = "subscriptions=yes namespace missing"; return FALSE; } return TRUE; From dovecot at dovecot.org Tue Jul 31 23:02:27 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 23:02:27 +0300 Subject: dovecot-2.1: imapc: Fixed crashes during mailbox close. Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/afa918d1c1eb changeset: 14644:afa918d1c1eb user: Timo Sirainen date: Tue Jul 31 23:02:22 2012 +0300 description: imapc: Fixed crashes during mailbox close. diffstat: src/lib-imap-client/imapc-client.c | 2 +- src/lib-imap-client/imapc-connection.c | 29 +++++++++++++++-------------- src/lib-imap-client/imapc-connection.h | 3 ++- 3 files changed, 18 insertions(+), 16 deletions(-) diffs (104 lines): diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-client.c --- a/src/lib-imap-client/imapc-client.c Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-client.c Tue Jul 31 23:02:22 2012 +0300 @@ -270,7 +270,7 @@ /* reopen the mailbox */ box->reopen_callback(box->reopen_context); } else { - imapc_connection_abort_commands(box->conn, TRUE, FALSE); + imapc_connection_abort_commands(box->conn, NULL, FALSE); } } diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-connection.c --- a/src/lib-imap-client/imapc-connection.c Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.c Tue Jul 31 23:02:22 2012 +0300 @@ -212,6 +212,7 @@ static void imapc_connection_abort_commands_array(ARRAY_TYPE(imapc_command) *cmd_array, ARRAY_TYPE(imapc_command) *dest_array, + struct imapc_client_mailbox *only_box, bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; @@ -221,8 +222,10 @@ cmdp = array_idx(cmd_array, i); cmd = *cmdp; - if (keep_retriable && - (cmd->flags & IMAPC_COMMAND_FLAG_RETRIABLE) != 0) { + if (cmd->box != only_box && only_box != NULL) + i++; + else if (keep_retriable && + (cmd->flags & IMAPC_COMMAND_FLAG_RETRIABLE) != 0) { cmd->send_pos = 0; cmd->wait_for_literal = 0; i++; @@ -234,22 +237,20 @@ } void imapc_connection_abort_commands(struct imapc_connection *conn, - bool disconnected, bool keep_retriable) + struct imapc_client_mailbox *only_box, + bool keep_retriable) { struct imapc_command *const *cmdp, *cmd; ARRAY_TYPE(imapc_command) tmp_array; struct imapc_command_reply reply; t_array_init(&tmp_array, 8); - if (disconnected) { - imapc_connection_abort_commands_array(&conn->cmd_wait_list, - &tmp_array, - keep_retriable); - } - imapc_connection_abort_commands_array(&conn->cmd_send_queue, - &tmp_array, keep_retriable); + imapc_connection_abort_commands_array(&conn->cmd_wait_list, &tmp_array, + only_box, keep_retriable); + imapc_connection_abort_commands_array(&conn->cmd_send_queue, &tmp_array, + only_box, keep_retriable); - if (array_count(&conn->cmd_wait_list) > 0 && disconnected) { + if (array_count(&conn->cmd_wait_list) > 0 && only_box == NULL) { /* need to move all the waiting commands to send queue */ array_append_array(&conn->cmd_wait_list, &conn->cmd_send_queue); @@ -368,13 +369,13 @@ conn->fd = -1; imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); - imapc_connection_abort_commands(conn, TRUE, reconnecting); + imapc_connection_abort_commands(conn, NULL, reconnecting); } static void imapc_connection_set_disconnected(struct imapc_connection *conn) { imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DISCONNECTED); - imapc_connection_abort_commands(conn, TRUE, FALSE); + imapc_connection_abort_commands(conn, NULL, FALSE); } static void imapc_connection_reconnect(struct imapc_connection *conn) @@ -1852,7 +1853,7 @@ conn->selecting_box = NULL; } imapc_connection_send_idle_done(conn); - imapc_connection_abort_commands(conn, FALSE, FALSE); + imapc_connection_abort_commands(conn, box, FALSE); } struct imapc_client_mailbox * diff -r 0abb9b0a54db -r afa918d1c1eb src/lib-imap-client/imapc-connection.h --- a/src/lib-imap-client/imapc-connection.h Tue Jul 31 22:33:21 2012 +0300 +++ b/src/lib-imap-client/imapc-connection.h Tue Jul 31 23:02:22 2012 +0300 @@ -26,7 +26,8 @@ void *login_context); void imapc_connection_disconnect(struct imapc_connection *conn); void imapc_connection_abort_commands(struct imapc_connection *conn, - bool disconnected, bool keep_retriable); + struct imapc_client_mailbox *only_box, + bool keep_retriable); void imapc_connection_ioloop_changed(struct imapc_connection *conn); void imapc_connection_input_pending(struct imapc_connection *conn); From dovecot at dovecot.org Tue Jul 31 23:10:58 2012 From: dovecot at dovecot.org (dovecot at dovecot.org) Date: Tue, 31 Jul 2012 23:10:58 +0300 Subject: dovecot-2.1: fts-solr: Compiler warning fix Message-ID: details: http://hg.dovecot.org/dovecot-2.1/rev/a606e9ff1476 changeset: 14645:a606e9ff1476 user: Timo Sirainen date: Tue Jul 31 23:10:53 2012 +0300 description: fts-solr: Compiler warning fix diffstat: src/plugins/fts-solr/solr-connection.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r afa918d1c1eb -r a606e9ff1476 src/plugins/fts-solr/solr-connection.c --- a/src/plugins/fts-solr/solr-connection.c Tue Jul 31 23:02:22 2012 +0300 +++ b/src/plugins/fts-solr/solr-connection.c Tue Jul 31 23:10:53 2012 +0300 @@ -102,7 +102,7 @@ col = XML_GetCurrentColumnNumber(conn->xml_parser); i_error("fts_solr: Invalid XML input at %d:%d: %s " "(near: %.*s)", line, col, XML_ErrorString(err), - (int)I_MIN(size, 128), data); + (int)I_MIN(size, 128), (const char *)data); conn->xml_failed = TRUE; return -1; }