Package: dovecot-common Version: 1:1.0.13-2 Severity: normal Tags: patch This bug was reported on the dovecot mailing list: http://www.dovecot.org/list/dovecot/2008-March/029578.html Timo provides a fix for this issue.: http://www.dovecot.org/list/dovecot/2008-April/030295.html
I have attached the necessary code changes as patch (`hg diff -r27 -r33`). It also includes some other small fixes and improvements. Regards, Pascal -- System Information: Debian Release: lenny/sid APT prefers testing APT policy: (500, 'testing'), (50, 'unstable') Architecture: amd64 (x86_64) Kernel: Linux 2.6.24-1-amd64 (SMP w/4 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages dovecot-common depends on: ii adduser 3.107 add and remove users and groups ii libc6 2.7-10 GNU C Library: Shared libraries ii libcomerr2 1.40.8-2 common error description library ii libkrb53 1.6.dfsg.3~beta1-4 MIT Kerberos runtime libraries ii libldap-2.4-2 2.4.7-6.2 OpenLDAP libraries ii libmysqlclient15off 5.0.51a-3 MySQL database client library ii libpam-runtime 0.99.7.1-6 Runtime support for the PAM librar ii libpam0g 0.99.7.1-6 Pluggable Authentication Modules l ii libpq5 8.3.1-1 PostgreSQL C client library ii libsqlite3-0 3.5.8-1 SQLite 3 shared library ii libssl0.9.8 0.9.8g-8 SSL shared libraries ii openssl 0.9.8g-8 Secure Socket Layer (SSL) binary a ii ucf 3.006 Update Configuration File: preserv ii zlib1g 1:1.2.3.3.dfsg-12 compression library - runtime dovecot-common recommends no packages. -- no debconf information
diff -r 9137442dd18a -r 5c3ba11994cb src/cmusieve-plugin.c --- a/src/cmusieve-plugin.c Wed Aug 01 15:02:51 2007 +0300 +++ b/src/cmusieve-plugin.c Fri Apr 25 02:54:13 2008 +0300 @@ -27,6 +27,7 @@ /* disabled */ return NULL; } + script_path = home_expand(script_path); if (*script_path != '/' && *script_path != '\0') { /* relative path. change to absolute. */ @@ -35,10 +36,8 @@ } } else { if (home == NULL) { - /* we must have a home directory */ - i_error("userdb(%s) didn't return a home directory or " - "sieve script location, can't find it", - getenv("USER")); + i_error("Per-user script path is unknown. See " + "http://wiki.dovecot.org/LDA/Sieve#location"); return NULL; } diff -r 9137442dd18a -r 5c3ba11994cb src/libsieve/bc_eval.c --- a/src/libsieve/bc_eval.c Wed Aug 01 15:02:51 2007 +0300 +++ b/src/libsieve/bc_eval.c Fri Apr 25 02:54:13 2008 +0300 @@ -124,7 +124,7 @@ if (!strncasecmp(addr, "majordomo", 9)) return 1; - if (strstr(addr, "-request")) + if (strstr(addr, "-request@")) return 1; if (!strncmp(addr, "owner-", 6)) @@ -186,6 +186,17 @@ return found; } + +static char *list_fields[] = { + "list-id", + "list-help", + "list-subscribe", + "list-unsubscribe", + "list-post", + "list-owner", + "list-archive", + NULL +}; /* Determine if we should respond to a vacation message */ static int shouldRespond(void * m, sieve_interp_t *interp, @@ -195,14 +206,28 @@ const char **body; char buf[128]; char *myaddr = NULL; - int l = SIEVE_OK; + int l = SIEVE_OK, j; void *data = NULL, *marker = NULL; char *tmp; int curra, x; char *found=NULL; char *reply_to=NULL; - /* is there an Auto-Submitted keyword other than "no"? */ + /* Implementations SHOULD NOT respond to any message that contains a + "List-Id" [RFC2919], "List-Help", "List-Subscribe", "List- + Unsubscribe", "List-Post", "List-Owner" or "List-Archive" [RFC2369] + header field. */ + for (j = 0; list_fields[j]; j++) { + strcpy(buf, list_fields[j]); + if (interp->getheader(m, buf, &body) == SIEVE_OK) { + l = SIEVE_DONE; + break; + } + } + + /* Implementations SHOULD NOT respond to any message that has an + "Auto-submitted" header field with a value other than "no". + This header field is described in [RFC3834]. */ strcpy(buf, "auto-submitted"); if (interp->getheader(m, buf, &body) == SIEVE_OK) { /* we don't deal with comments, etc. here */ @@ -212,6 +237,7 @@ } /* is there a Precedence keyword of "junk | bulk | list"? */ + /* XXX non-standard header, but worth checking */ strcpy(buf, "precedence"); if (interp->getheader(m, buf, &body) == SIEVE_OK) { /* we don't deal with comments, etc. here */ @@ -282,7 +308,7 @@ if (l == SIEVE_OK) { /* ok, we're willing to respond to the sender. but is this message to me? that is, is my address - in the TO, CC or BCC fields? */ + in the [Resent]-To, [Resent]-Cc or [Resent]-Bcc fields? */ if (strcpy(buf, "to"), interp->getheader(m, buf, &body) == SIEVE_OK) found = look_for_me(myaddr, numaddresses ,bc, i, body); @@ -290,6 +316,15 @@ (interp->getheader(m, buf, &body) == SIEVE_OK))) found = look_for_me(myaddr, numaddresses, bc, i, body); if (!found && (strcpy(buf, "bcc"), + (interp->getheader(m, buf, &body) == SIEVE_OK))) + found = look_for_me(myaddr, numaddresses, bc, i, body); + if (!found && (strcpy(buf, "resent-to"), + (interp->getheader(m, buf, &body) == SIEVE_OK))) + found = look_for_me(myaddr, numaddresses ,bc, i, body); + if (!found && (strcpy(buf, "resent-cc"), + (interp->getheader(m, buf, &body) == SIEVE_OK))) + found = look_for_me(myaddr, numaddresses, bc, i, body); + if (!found && (strcpy(buf, "resent-bcc"), (interp->getheader(m, buf, &body) == SIEVE_OK))) found = look_for_me(myaddr, numaddresses, bc, i, body); if (!found) @@ -1093,10 +1128,7 @@ /* s[0] contains the original subject */ const char *origsubj = s[0]; - while (!strncasecmp(origsubj, "Re: ", 4)) - origsubj += 4; - - snprintf(subject, sizeof(subject), "Re: %s", origsubj); + snprintf(subject, sizeof(subject), "Auto: %s", origsubj); } } else { /* user specified subject */ diff -r 9137442dd18a -r 5c3ba11994cb src/sieve-cmu.c --- a/src/sieve-cmu.c Wed Aug 01 15:02:51 2007 +0300 +++ b/src/sieve-cmu.c Fri Apr 25 02:54:13 2008 +0300 @@ -39,13 +39,69 @@ const char *temp[10]; } sieve_msgdata_t; +static const char *unfold_header(const char *str) +{ + char *new_str; + unsigned int i, j; + + for (i = 0; str[i] != '\0'; i++) { + if (str[i] == '\n') + break; + } + if (str[i] == '\0') + return str; + + /* @UNSAFE */ + new_str = t_malloc(i + strlen(str+i) + 1); + memcpy(new_str, str, i); + for (j = i; str[i] != '\0'; i++) { + if (str[i] == '\n') { + new_str[j++] = ' '; + i++; + i_assert(str[i] == ' ' || str[i] == '\t'); + } else { + new_str[j++] = str[i]; + } + } + new_str[j] = '\0'; + return new_str; +} + +static const char *const * +unfold_multiline_headers(const char *const *headers) +{ + const char **new_headers; + unsigned int i; + + /* see if there are any multiline headers */ + for (i = 0; headers[i] != NULL; i++) { + if (strchr(headers[i], '\n') != NULL) + break; + } + if (headers[i] == NULL) { + /* no multilines */ + return headers; + } + + /* @UNSAFE */ + for (; headers[i] != NULL; i++) ; + new_headers = t_new(const char *, i + 1); + for (i = 0; headers[i] != NULL; i++) + new_headers[i] = unfold_header(headers[i]); + return new_headers; +} + /* gets the header "head" from msg. */ static int getheader(void *v, const char *phead, const char ***body) { sieve_msgdata_t *m = v; + const char *const *headers; if (phead==NULL) return SIEVE_FAIL; - *body = (const char **)mail_get_headers(m->mail, phead); + headers = mail_get_headers(m->mail, phead); + if (headers != NULL) + headers = unfold_multiline_headers(headers); + *body = (const char **)headers; if (*body) { return SIEVE_OK; @@ -346,23 +402,25 @@ static int autorespond(void *ac, void *ic __attr_unused__, void *sc, - void *mc __attr_unused__, + void *mc, const char **errmsg __attr_unused__) { sieve_autorespond_context_t *arc = (sieve_autorespond_context_t *) ac; script_data_t *sd = (script_data_t *) sc; - int ret; + sieve_msgdata_t *md = mc; /* ok, let's see if we've responded before */ - ret = duplicate_check(arc->hash, arc->len, sd->username) ? - SIEVE_DONE : SIEVE_OK; - - if (ret == SIEVE_OK) { - duplicate_mark(arc->hash, arc->len, sd->username, - ioloop_time + arc->days * (24 * 60 * 60)); + if (duplicate_check(arc->hash, arc->len, sd->username)) { + i_info("msgid=%s: discarded duplicate vacation response to <%s>", + md->id == NULL ? "" : str_sanitize(md->id, 80), + str_sanitize(md->return_path, 80)); + return SIEVE_DONE; } - return ret; + duplicate_mark(arc->hash, arc->len, sd->username, + ioloop_time + arc->days * (24 * 60 * 60)); + + return SIEVE_OK; } static int send_response(void *ac, @@ -409,6 +467,9 @@ if (smtp_client_close(smtp_client) == 0) { duplicate_mark(outmsgid, strlen(outmsgid), sdata->username, ioloop_time + DUPLICATE_DEFAULT_KEEP); + i_info("msgid=%s: sent vacation response to <%s>", + md->id == NULL ? "" : str_sanitize(md->id, 80), + str_sanitize(md->return_path, 80)); return SIEVE_OK; } else { *errmsg = "Error sending mail"; @@ -533,7 +594,7 @@ return -1; } } else { - if (st.st_mtime < st2.st_mtime) + if (st.st_mtime <= st2.st_mtime) return 1; }