From d796ac2427c8e3c2ad6431e1ae8fe20ac75e5fc8 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Tue, 10 Jan 2017 23:22:28 +0100 Subject: [PATCH] lib-sieve: Fixed handling of mail_get_headers()/mail_get_headers_utf8() result. The situation where no headers are found was not always handled correctly. --- .../plugins/enotify/mailto/ntfy-mailto.c | 34 +++--- src/lib-sieve/plugins/notify/cmd-notify.c | 33 ++--- src/lib-sieve/plugins/vacation/cmd-vacation.c | 115 ++++++++++-------- .../plugins/vnd.dovecot/report/cmd-report.c | 6 +- src/lib-sieve/sieve-message.c | 2 +- 5 files changed, 103 insertions(+), 87 deletions(-) diff --git a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c index ce0e21121..d5afcc9f9 100644 --- a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c @@ -516,7 +516,7 @@ static int ntfy_mailto_send /* Fetch subject from original message */ if ( mail_get_headers_utf8 - (msgdata->mail, "subject", &hsubject) >= 0 ) + (msgdata->mail, "subject", &hsubject) > 0 ) subject = str_sanitize(t_strdup_printf("Notification: %s", hsubject[0]), NTFY_MAILTO_MAX_SUBJECT); else @@ -672,7 +672,7 @@ static int ntfy_mailto_action_execute i_assert( owner_email != NULL ); /* Is the message an automatic reply ? */ - if ( mail_get_headers(mail, "auto-submitted", &hdsp) < 0 ) { + if ( (ret=mail_get_headers(mail, "auto-submitted", &hdsp)) < 0 ) { sieve_enotify_critical(nenv, "mailto notification: " "failed to read `auto-submitted' header field", @@ -683,21 +683,23 @@ static int ntfy_mailto_action_execute } /* Theoretically multiple headers could exist, so lets make sure */ - while ( *hdsp != NULL ) { - if ( strcasecmp(*hdsp, "no") != 0 ) { - const char *from = NULL; - - if ( (nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0 ) - from = sieve_message_get_sender(nenv->msgctx); - from = (from == NULL ? "" : - t_strdup_printf(" from <%s>", str_sanitize(from, 256))); - - sieve_enotify_global_info(nenv, - "not sending notification for auto-submitted message%s", - from); - return 0; + if ( ret > 0 ) { + while ( *hdsp != NULL ) { + if ( strcasecmp(*hdsp, "no") != 0 ) { + const char *from = NULL; + + if ( (nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0 ) + from = sieve_message_get_sender(nenv->msgctx); + from = (from == NULL ? "" : + t_strdup_printf(" from <%s>", str_sanitize(from, 256))); + + sieve_enotify_global_info(nenv, + "not sending notification " + "for auto-submitted message%s", from); + return 0; + } + hdsp++; } - hdsp++; } T_BEGIN { diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c index a964b4a42..e9c667371 100644 --- a/src/lib-sieve/plugins/notify/cmd-notify.c +++ b/src/lib-sieve/plugins/notify/cmd-notify.c @@ -805,30 +805,33 @@ static int act_notify_commit (const struct ext_notify_action *) action->context; const char *const *hdsp; bool result; + int ret; /* Is the message an automatic reply ? */ - if ( mail_get_headers(mail, "auto-submitted", &hdsp) < 0 ) { + if ( (ret=mail_get_headers(mail, "auto-submitted", &hdsp)) < 0 ) { return sieve_result_mail_error(aenv, mail, "notify action: " "failed to read `auto-submitted' header field"); } /* Theoretically multiple headers could exist, so lets make sure */ - while ( *hdsp != NULL ) { - if ( strcasecmp(*hdsp, "no") != 0 ) { - const char *from = NULL; - - if ( (aenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0 ) - from = sieve_message_get_sender(aenv->msgctx); - from = (from == NULL ? "" : - t_strdup_printf(" from <%s>", str_sanitize(from, 256))); - - sieve_result_global_log(aenv, - "not sending notification for auto-submitted message%s", - from); - return SIEVE_EXEC_OK; + if (ret > 0) { + while ( *hdsp != NULL ) { + if ( strcasecmp(*hdsp, "no") != 0 ) { + const char *from = NULL; + + if ( (aenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0 ) + from = sieve_message_get_sender(aenv->msgctx); + from = (from == NULL ? "" : + t_strdup_printf(" from <%s>", str_sanitize(from, 256))); + + sieve_result_global_log(aenv, + "not sending notification for auto-submitted message%s", + from); + return SIEVE_EXEC_OK; + } + hdsp++; } - hdsp++; } T_BEGIN { diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 8681e219d..bccb4a3c3 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -912,13 +912,13 @@ static int act_vacation_send /* Make sure we have a subject for our reply */ if ( ctx->subject == NULL || *(ctx->subject) == '\0' ) { - if ( mail_get_headers_utf8 - (msgdata->mail, "subject", &headers) < 0 ) { + if ( (ret=mail_get_headers_utf8 + (msgdata->mail, "subject", &headers)) < 0 ) { return sieve_result_mail_error(aenv, msgdata->mail, "vacation action: " "failed to read header field `subject'"); } - if ( headers[0] != NULL ) { + if ( ret > 0 && headers[0] != NULL ) { subject = t_strconcat("Auto: ", headers[0], NULL); } else { subject = "Automated reply"; @@ -961,8 +961,8 @@ static int act_vacation_send /* Compose proper in-reply-to and references headers */ - if ( mail_get_headers - (msgdata->mail, "references", &headers) < 0 ) { + if ( (ret=mail_get_headers + (msgdata->mail, "references", &headers)) < 0 ) { return sieve_result_mail_error(aenv, msgdata->mail, "vacation action: " "failed to read header field `references'"); @@ -971,12 +971,13 @@ static int act_vacation_send if ( msgdata->id != NULL ) { rfc2822_header_write(msg, "In-Reply-To", msgdata->id); - if ( headers[0] != NULL ) - rfc2822_header_write - (msg, "References", t_strconcat(headers[0], " ", msgdata->id, NULL)); - else + if ( ret > 0 && headers[0] != NULL ) { + rfc2822_header_write(msg, "References", + t_strconcat(headers[0], " ", msgdata->id, NULL)); + } else { rfc2822_header_write(msg, "References", msgdata->id); - } else if ( headers[0] != NULL ) { + } + } else if ( ret > 0 && headers[0] != NULL ) { rfc2822_header_write(msg, "References", headers[0]); } @@ -1107,16 +1108,17 @@ static int act_vacation_commit /* Are we trying to respond to a mailing list ? */ hdsp = _list_headers; while ( *hdsp != NULL ) { - if ( mail_get_headers(mail, *hdsp, &headers) < 0 ) { + if ( (ret=mail_get_headers(mail, *hdsp, &headers)) < 0 ) { return sieve_result_mail_error(aenv, mail, "vacation action: " "failed to read header field `%s'", *hdsp); } - if ( headers[0] != NULL ) { + if ( ret > 0 && headers[0] != NULL ) { /* Yes, bail out */ sieve_result_global_log(aenv, - "discarding vacation response to mailinglist recipient <%s>", + "discarding vacation response " + "to mailinglist recipient <%s>", str_sanitize(sender, 128)); return SIEVE_EXEC_OK; } @@ -1124,68 +1126,77 @@ static int act_vacation_commit } /* Is the message that we are replying to an automatic reply ? */ - if ( mail_get_headers - (mail, "auto-submitted", &headers) < 0 ) { + if ( (ret=mail_get_headers + (mail, "auto-submitted", &headers)) < 0 ) { return sieve_result_mail_error(aenv, mail, "vacation action: " "failed to read header field `auto-submitted'"); } /* Theoretically multiple headers could exist, so lets make sure */ - hdsp = headers; - while ( *hdsp != NULL ) { - if ( strcasecmp(*hdsp, "no") != 0 ) { - sieve_result_global_log(aenv, - "discarding vacation response to auto-submitted message from <%s>", - str_sanitize(sender, 128)); - return SIEVE_EXEC_OK; + if ( ret > 0 ) { + hdsp = headers; + while ( *hdsp != NULL ) { + if ( strcasecmp(*hdsp, "no") != 0 ) { + sieve_result_global_log(aenv, + "discarding vacation response " + "to auto-submitted message from <%s>", + str_sanitize(sender, 128)); + return SIEVE_EXEC_OK; + } + hdsp++; } - hdsp++; } /* Check for the (non-standard) precedence header */ - if ( mail_get_headers - (mail, "precedence", &headers) < 0 ) { + if ( (ret=mail_get_headers + (mail, "precedence", &headers)) < 0 ) { return sieve_result_mail_error(aenv, mail, "vacation action: " "failed to read header field `precedence'"); } /* Theoretically multiple headers could exist, so lets make sure */ - hdsp = headers; - while ( *hdsp != NULL ) { - if ( strcasecmp(*hdsp, "junk") == 0 || strcasecmp(*hdsp, "bulk") == 0 || - strcasecmp(*hdsp, "list") == 0 ) { - sieve_result_global_log(aenv, - "discarding vacation response to precedence=%s message from <%s>", - *hdsp, str_sanitize(sender, 128)); - return SIEVE_EXEC_OK; + if ( ret > 0 ) { + hdsp = headers; + while ( *hdsp != NULL ) { + if ( strcasecmp(*hdsp, "junk") == 0 || + strcasecmp(*hdsp, "bulk") == 0 || + strcasecmp(*hdsp, "list") == 0 ) { + sieve_result_global_log(aenv, + "discarding vacation response " + "to precedence=%s message from <%s>", + *hdsp, str_sanitize(sender, 128)); + return SIEVE_EXEC_OK; + } + hdsp++; } - hdsp++; } /* Check for the (non-standard) Microsoft X-Auto-Response-Suppress header */ - if ( mail_get_headers - (mail, "x-auto-response-suppress", &headers) < 0 ) { + if ( (ret=mail_get_headers + (mail, "x-auto-response-suppress", &headers)) < 0 ) { return sieve_result_mail_error(aenv, mail, "vacation action: " "failed to read header field `x-auto-response-suppress'"); } /* Theoretically multiple headers could exist, so lets make sure */ - hdsp = headers; - while ( *hdsp != NULL ) { - const char *const *flags = t_strsplit(*hdsp, ","); - while ( *flags != NULL ) { - const char *flag = ph_t_str_trim(*flags, " \t"); - if ( strcasecmp(flag, "All") == 0 || - strcasecmp(flag, "OOF") == 0 ) { - sieve_result_global_log(aenv, - "discarding vacation response to message from <%s> " - "(`%s' flag found in x-auto-response-suppress header)", - str_sanitize(sender, 128), flag); - return SIEVE_EXEC_OK; + if ( ret > 0 ) { + hdsp = headers; + while ( *hdsp != NULL ) { + const char *const *flags = t_strsplit(*hdsp, ","); + while ( *flags != NULL ) { + const char *flag = ph_t_str_trim(*flags, " \t"); + if ( strcasecmp(flag, "All") == 0 || + strcasecmp(flag, "OOF") == 0 ) { + sieve_result_global_log(aenv, + "discarding vacation response to message from <%s> " + "(`%s' flag found in x-auto-response-suppress header)", + str_sanitize(sender, 128), flag); + return SIEVE_EXEC_OK; + } + flags++; } - flags++; + hdsp++; } - hdsp++; } /* Do not reply to system addresses */ @@ -1208,12 +1219,12 @@ static int act_vacation_commit */ hdsp = _my_address_headers; while ( *hdsp != NULL ) { - if ( mail_get_headers(mail, *hdsp, &headers) < 0 ) { + if ( (ret=mail_get_headers(mail, *hdsp, &headers)) < 0 ) { return sieve_result_mail_error(aenv, mail, "vacation action: " "failed to read header field `%s'", *hdsp); } - if ( headers[0] != NULL ) { + if ( ret > 0 && headers[0] != NULL ) { /* Final recipient directly listed in headers? */ if ( _contains_my_address(headers, recipient) ) { diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c index 5909c7e4e..15de6f258 100644 --- a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c +++ b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c @@ -470,13 +470,13 @@ static int act_report_send } /* Make sure we have a subject for our report */ - if ( mail_get_headers_utf8 - (msgdata->mail, "subject", &headers) < 0 ) { + if ( (ret=mail_get_headers_utf8 + (msgdata->mail, "subject", &headers)) < 0 ) { return sieve_result_mail_error(aenv, msgdata->mail, "report action: " "failed to read header field `subject'"); } - if ( headers[0] != NULL ) { + if ( ret > 0 && headers[0] != NULL ) { subject = t_strconcat("Report: ", headers[0], NULL); } else { subject = "Report: (message without subject)"; diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index 592a9257b..ec2e02441 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -625,7 +625,7 @@ static int sieve_message_header_list_next_item return -1; } - if ( hdrlist->headers == NULL || hdrlist->headers[0] == NULL ) { + if ( ret == 0 || hdrlist->headers[0] == NULL ) { /* Try next item when no headers found */ hdrlist->headers = NULL; }