From 590b0a382534cb1a209cfafcad8ca0e0c2e5ac7e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Wed, 2 Oct 2019 18:00:44 +0200 Subject: [PATCH] - rel 2; add References header into DSN notifications emails --- dsn-references.patch | 285 +++++++++++++++++++++++++++++++++++++++++++ exim.spec | 6 +- 2 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 dsn-references.patch diff --git a/dsn-references.patch b/dsn-references.patch new file mode 100644 index 0000000..8267e82 --- /dev/null +++ b/dsn-references.patch @@ -0,0 +1,285 @@ +commit d6c829b9a350f61c98196768e3260beb3cbecbfe +Author: Jeremy Harris +Date: Wed Oct 2 14:49:55 2019 +0100 + + DSN: add References: header. Bug 2452 + +diff --git a/src/src/deliver.c b/src/src/deliver.c +index 72751c2dc..7433b5fb2 100644 +--- a/src/src/deliver.c ++++ b/src/src/deliver.c +@@ -7344,7 +7344,7 @@ if (addr_senddsn) + if (pid < 0) /* Creation of child failed */ + { + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to " +- "create child process to send failure message: %s", getpid(), ++ "create child process to send success-dsn message: %s", getpid(), + getppid(), strerror(errno)); + + DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n"); +@@ -7357,7 +7357,7 @@ if (addr_senddsn) + transport_ctx tctx = {{0}}; + + DEBUG(D_deliver) +- debug_printf("sending error message to: %s\n", sender_address); ++ debug_printf("sending success-dsn to: %s\n", sender_address); + + /* build unique id for MIME boundary */ + bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand()); +@@ -7369,8 +7369,11 @@ if (addr_senddsn) + moan_write_from(f); + fprintf(f, "Auto-Submitted: auto-generated\n" + "To: %s\n" +- "Subject: Delivery Status Notification\n" +- "Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n" ++ "Subject: Delivery Status Notification\n", ++ sender_address); ++ moan_write_references(f, NULL); ++ fprintf(f, "Content-Type: multipart/report;" ++ " report-type=delivery-status; boundary=%s\n" + "MIME-Version: 1.0\n\n" + + "--%s\n" +@@ -7378,7 +7381,7 @@ if (addr_senddsn) + + "This message was created automatically by mail delivery software.\n" + " ----- The following addresses had successful delivery notifications -----\n", +- sender_address, bound, bound); ++ bound, bound); + + for (address_item * a = addr_senddsn; a; a = a->next) + fprintf(f, "<%s> (relayed %s)\n\n", +@@ -7607,6 +7610,7 @@ while (addr_failed) + fprintf(fp, "Auto-Submitted: auto-replied\n"); + moan_write_from(fp); + fprintf(fp, "To: %s\n", bounce_recipient); ++ moan_write_references(fp, NULL); + + /* generate boundary string and output MIME-Headers */ + bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand()); +@@ -8192,7 +8196,8 @@ else if (addr_defer != (address_item *)(+1)) + + DEBUG(D_deliver) + { +- debug_printf("time on queue = %s id %s addr %s\n", readconf_printtime(queue_time), message_id, addr_defer->address); ++ debug_printf("time on queue = %s id %s addr %s\n", ++ readconf_printtime(queue_time), message_id, addr_defer->address); + debug_printf("warning counts: required %d done %d\n", count, + warning_count); + } +@@ -8230,6 +8235,7 @@ else if (addr_defer != (address_item *)(+1)) + fprintf(f, "Auto-Submitted: auto-replied\n"); + moan_write_from(f); + fprintf(f, "To: %s\n", recipients); ++ moan_write_references(f, NULL); + + /* generated boundary string and output MIME-Headers */ + bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand()); +diff --git a/src/src/functions.h b/src/src/functions.h +index 31c005773..d99f15465 100644 +--- a/src/src/functions.h ++++ b/src/src/functions.h +@@ -335,6 +335,7 @@ extern void moan_tell_someone(uschar *, address_item *, + const uschar *, const char *, ...) PRINTF_FUNCTION(4,5); + extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL); + extern void moan_write_from(FILE *); ++extern void moan_write_references(FILE *, uschar *); + extern FILE *modefopen(const uschar *, const char *, mode_t); + + extern int open_cutthrough_connection( address_item * addr ); +diff --git a/src/src/moan.c b/src/src/moan.c +index f6cda37f2..31d033c1a 100644 +--- a/src/src/moan.c ++++ b/src/src/moan.c +@@ -28,7 +28,7 @@ Returns: nothing + void + moan_write_from(FILE *f) + { +-uschar *s = expand_string(dsn_from); ++uschar * s = expand_string(dsn_from); + if (!s) + { + log_write(0, LOG_MAIN|LOG_PANIC, +@@ -40,6 +40,80 @@ fprintf(f, "From: %s\n", s); + + + ++/************************************************* ++* Write References: line for DSN * ++*************************************************/ ++ ++/* Generate a References: header if there is in the header_list ++at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822). ++ ++Arguments: f the FILE to write to ++ message_id optional already-found message-id, or NULL ++ ++Returns: nothing ++*/ ++ ++void ++moan_write_references(FILE * fp, uschar * message_id) ++{ ++header_line * h; ++ ++if (!message_id) ++ for (h = header_list; h; h = h->next) ++ if (h->type == htype_id) ++ { ++ message_id = Ustrchr(h->text, ':') + 1; ++ while (isspace(*message_id)) message_id++; ++ } ++ ++for (h = header_list; h; h = h->next) ++ if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0) ++ break; ++ ++if (!h) ++ for (h = header_list; h; h = h->next) ++ if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0) ++ break; ++ ++/* We limit the total length of references. Although there is no fixed ++limit, some systems do not like headers growing beyond recognition. ++Keep the first message ID for the thread root and the last few for ++the position inside the thread, up to a maximum of 12 altogether. */ ++ ++if (h || message_id) ++ { ++ fprintf(fp, "References:"); ++ if (h) ++ { ++ uschar * s, * id, * error; ++ uschar * referenced_ids[12]; ++ int reference_count = 0; ++ ++ s = Ustrchr(h->text, ':') + 1; ++ f.parse_allow_group = FALSE; ++ while (*s && (s = parse_message_id(s, &id, &error))) ++ if (reference_count == nelem(referenced_ids)) ++ { ++ memmove(referenced_ids + 1, referenced_ids + 2, ++ sizeof(referenced_ids) - 2*sizeof(uschar *)); ++ referenced_ids[reference_count - 1] = id; ++ } ++ else ++ referenced_ids[reference_count++] = id; ++ ++ for (int i = 0; i < reference_count; ++i) ++ fprintf(fp, " %s", referenced_ids[i]); ++ } ++ ++ /* The message id will have a newline on the end of it. */ ++ ++ if (message_id) fprintf(fp, " %s", message_id); ++ else fprintf(fp, "\n"); ++ } ++} ++ ++ ++ + /************************************************* + * Send error message * + *************************************************/ +@@ -119,6 +193,7 @@ else + moan_write_from(fp); + + fprintf(fp, "To: %s\n", recipient); ++moan_write_references(fp, NULL); + + switch(ident) + { +@@ -145,7 +220,7 @@ switch(ident) + "A message that you sent contained one or more recipient addresses that were\n" + "incorrectly constructed:\n\n"); + +- while (eblock != NULL) ++ while (eblock) + { + fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2); + count++; +@@ -522,6 +597,7 @@ f = fdopen(fd, "wb"); + fprintf(f, "Auto-Submitted: auto-replied\n"); + moan_write_from(f); + fprintf(f, "To: %s\n", who); ++moan_write_references(f, NULL); + fprintf(f, "Subject: %s\n\n", subject); + va_start(ap, format); + vfprintf(f, format, ap); +@@ -656,8 +732,7 @@ llen = domain++ - recipient; + + /* Scan through the configured items */ + +-while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) +- != NULL) ++while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))) + { + const uschar *newaddress = item; + const uschar *pattern = string_dequote(&newaddress); +@@ -759,6 +834,7 @@ fprintf(f, "Auto-Submitted: auto-replied\n"); + moan_write_from(f); + fprintf(f, "To: %s\n", s); + fprintf(f, "Subject: error(s) in forwarding or filtering\n\n"); ++moan_write_references(f, NULL); + + if (custom) + { +diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c +index 734e65833..1aef02aaf 100644 +--- a/src/src/transports/autoreply.c ++++ b/src/src/transports/autoreply.c +@@ -599,53 +599,7 @@ if (h) + fprintf(fp, "In-Reply-To: %s", message_id); + } + +-/* Generate a References header if there is at least one of Message-ID:, +-References:, or In-Reply-To: (see RFC 2822). */ +- +-for (h = header_list; h; h = h->next) +- if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0) +- break; +- +-if (!h) +- for (h = header_list; h; h = h->next) +- if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0) +- break; +- +-/* We limit the total length of references. Although there is no fixed +-limit, some systems do not like headers growing beyond recognition. +-Keep the first message ID for the thread root and the last few for +-the position inside the thread, up to a maximum of 12 altogether. */ +- +-if (h || message_id) +- { +- fprintf(fp, "References:"); +- if (h) +- { +- uschar *s, *id, *error; +- uschar *referenced_ids[12]; +- int reference_count = 0; +- int i; +- +- s = Ustrchr(h->text, ':') + 1; +- f.parse_allow_group = FALSE; +- while (*s != 0 && (s = parse_message_id(s, &id, &error)) != NULL) +- { +- if (reference_count == nelem(referenced_ids)) +- { +- memmove(referenced_ids + 1, referenced_ids + 2, +- sizeof(referenced_ids) - 2*sizeof(uschar *)); +- referenced_ids[reference_count - 1] = id; +- } +- else referenced_ids[reference_count++] = id; +- } +- for (i = 0; i < reference_count; ++i) fprintf(fp, " %s", referenced_ids[i]); +- } +- +- /* The message id will have a newline on the end of it. */ +- +- if (message_id) fprintf(fp, " %s", message_id); +- else fprintf(fp, "\n"); +- } ++ moan_write_references(fp, message_id); + + /* Add an Auto-Submitted: header */ + diff --git a/exim.spec b/exim.spec index e93ac4e..cd4ba1a 100644 --- a/exim.spec +++ b/exim.spec @@ -25,7 +25,7 @@ Summary(pl.UTF-8): Agent Transferu Poczty Uniwersytetu w Cambridge Summary(pt_BR.UTF-8): Servidor de correio eletrônico exim Name: exim Version: 4.92.3 -Release: 1 +Release: 2 Epoch: 2 License: GPL Group: Networking/Daemons/SMTP @@ -60,7 +60,7 @@ Patch4: %{name}4-Makefile-Default.patch # http://marc.merlins.org/linux/exim/files/sa-exim-cvs/localscan_dlopen_exim_4.20_or_better.patch Patch5: localscan_dlopen_%{name}_4.20_or_better.patch Patch6: exim-bug-1891.patch - +Patch7: dsn-references.patch Patch8: %{name}-spam-timeout.patch Patch20: %{name}4-disableSSLv3.patch @@ -186,7 +186,7 @@ Pliki nagłówkowe dla Exima. %patch4 -p1 %patch5 -p1 %patch6 -p2 - +%patch7 -p2 %patch8 -p1 install %{SOURCE4} exim4.conf -- 2.44.0