1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
10 /* Functions for sending messages to sender or to mailmaster. */
17 /*************************************************
18 * Write From: line for DSN *
19 *************************************************/
21 /* This function is called to write the From: line in automatically generated
22 messages - bounces, warnings, etc. It expands a configuration item in order to
23 get the text. If the expansion fails, a panic is logged and the default value
24 for the option is used.
26 Argument: the FILE to write to
31 moan_write_from(FILE *f)
33 uschar * s = expand_string(dsn_from);
36 log_write(0, LOG_MAIN|LOG_PANIC,
37 "Failed to expand dsn_from (using default): %s", expand_string_message);
38 s = expand_string(US DEFAULT_DSN_FROM);
40 fprintf(f, "From: %s\n", s);
45 /*************************************************
46 * Write References: line for DSN *
47 *************************************************/
49 /* Generate a References: header if there is in the header_list
50 at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
52 Arguments: f the FILE to write to
53 message_id optional already-found message-id, or NULL
59 moan_write_references(FILE * fp, uschar * message_id)
64 for (h = header_list; h; h = h->next)
65 if (h->type == htype_id)
67 message_id = Ustrchr(h->text, ':') + 1;
68 Uskip_whitespace(&message_id);
71 for (h = header_list; h; h = h->next)
72 if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
76 for (h = header_list; h; h = h->next)
77 if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
80 /* We limit the total length of references. Although there is no fixed
81 limit, some systems do not like headers growing beyond recognition.
82 Keep the first message ID for the thread root and the last few for
83 the position inside the thread, up to a maximum of 12 altogether.
84 Also apply the max line length limit from RFC 2822 2.1.1
86 XXX preferably we would get any limit from the outbound transport,
87 passed in here for a limit value.
92 unsigned use = fprintf(fp, "References:");
93 if (message_id) use += Ustrlen(message_id) + 1;
98 uschar * referenced_ids[12];
99 int reference_count = 0;
101 s = Ustrchr(h->text, ':') + 1;
102 f.parse_allow_group = FALSE;
103 while (*s && (s = parse_message_id(s, &id, &error)))
105 unsigned this = Ustrlen(id);
106 if ( reference_count == nelem(referenced_ids)
107 || use + this + reference_count > 998
110 if (reference_count > 1)
112 /* drop position 1 and shuffle down */
113 use -= Ustrlen(referenced_ids + 1);
114 memmove(referenced_ids + 1, referenced_ids + 2,
115 sizeof(referenced_ids) - 2*sizeof(*referenced_ids));
118 referenced_ids[reference_count - 1] = id;
122 referenced_ids[reference_count++] = id;
126 for (int i = 0; i < reference_count; ++i)
127 fprintf(fp, " %s", referenced_ids[i]);
130 /* The message id will have a newline on the end of it. */
132 if (message_id) fprintf(fp, " %s", message_id);
133 else fprintf(fp, "\n");
139 /*************************************************
140 * Send error message *
141 *************************************************/
143 /* This function sends an error message by opening a pipe to a new process
144 running Exim, and writing a message to it using the "-t" option. This is not
145 used for delivery failures, which have their own code for handing failed
149 recipient addressee for the message
150 ident identifies the type of error
151 eblock chain of error_blocks containing data about the error
152 headers the message's headers
153 message_file FILE containing the body of the message
154 firstline contains first line of file, if it was read to check for
155 "From ", but it turned out not to be
157 Returns: TRUE if message successfully sent
161 moan_send_message(uschar *recipient, int ident, error_block *eblock,
162 header_line *headers, FILE *message_file, uschar *firstline)
168 int size_limit = bounce_return_size_limit;
175 /* For DMARC if there is a specific sender set, expand the variable for the
176 header From: and grab the address from that for the envelope FROM. */
178 if ( ident == ERRMESS_DMARC_FORENSIC
179 && dmarc_forensic_sender
180 && (s = expand_string(dmarc_forensic_sender))
182 && (s2 = expand_string(string_sprintf("${address:%s}", s)))
185 pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
186 US"moan_send_message");
190 pid = child_open_exim(&fd, US"moan_send_message");
194 pid = child_open_exim(&fd, US"moan_send_message");
199 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
203 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
205 /* Creation of child succeeded */
207 fp = fdopen(fd, "wb");
208 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
209 fprintf(fp, "Auto-Submitted: auto-replied\n");
213 fprintf(fp, "From: %s\n", s);
218 fprintf(fp, "To: %s\n", recipient);
219 moan_write_references(fp, NULL);
223 case ERRMESS_BADARGADDRESS:
225 "Subject: Mail failure - malformed recipient address\n\n");
227 "A message that you sent contained a recipient address that was incorrectly\n"
229 fprintf(fp, " %s %s\n", eblock->text1, eblock->text2);
230 count = Ustrlen(eblock->text1);
231 if (count > 0 && eblock->text1[count-1] == '.')
233 "\nRecipient addresses must not end with a '.' character.\n");
235 "\nThe message has not been delivered to any recipients.\n");
238 case ERRMESS_BADNOADDRESS:
239 case ERRMESS_BADADDRESS:
241 "Subject: Mail failure - malformed recipient address\n\n");
243 "A message that you sent contained one or more recipient addresses that were\n"
244 "incorrectly constructed:\n\n");
248 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
250 eblock = eblock->next;
253 fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
254 "\nThese addresses have been ignored. ");
256 fprintf(fp, (ident == ERRMESS_BADADDRESS)?
257 "The other addresses in the message were\n"
258 "syntactically valid and have been passed on for an attempt at delivery.\n" :
260 "There were no other addresses in your\n"
261 "message, and so no attempt at delivery was possible.\n");
264 case ERRMESS_IGADDRESS:
265 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
267 "A message that you sent using the -t command line option contained no\n"
268 "addresses that were not also on the command line, and were therefore\n"
269 "suppressed. This left no recipient addresses, and so no delivery could\n"
273 case ERRMESS_NOADDRESS:
274 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
276 "A message that you sent contained no recipient addresses, and therefore no\n"
277 "delivery could be attempted.\n");
281 fprintf(fp, "Subject: Mail failure - system failure\n\n");
283 "A system failure was encountered while processing a message that you sent,\n"
284 "so it has not been possible to deliver it. The error was:\n\n%s\n",
288 case ERRMESS_VLONGHEADER:
289 fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
291 "A message that you sent contained a header section that was excessively\n"
292 "long and could not be handled by the mail transmission software. The\n"
293 "message has not been delivered to any recipients.\n");
296 case ERRMESS_VLONGHDRLINE:
297 fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
299 "A message that you sent contained a header line that was excessively\n"
300 "long and could not be handled by the mail transmission software. The\n"
301 "message has not been delivered to any recipients.\n");
305 fprintf(fp, "Subject: Mail failure - message too big\n\n");
307 "A message that you sent was longer than the maximum size allowed on this\n"
308 "system. It was not delivered to any recipients.\n");
311 case ERRMESS_TOOMANYRECIP:
312 fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
314 "A message that you sent contained more recipients than allowed on this\n"
315 "system. It was not delivered to any recipients.\n");
318 case ERRMESS_LOCAL_SCAN:
319 case ERRMESS_LOCAL_ACL:
320 fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
322 "A message that you sent was rejected by the local scanning code that\n"
323 "checks incoming messages on this system.");
325 fprintf(fp, " The following error was given:\n\n %s", eblock->text1);
330 case ERRMESS_DMARC_FORENSIC:
331 bounce_return_message = TRUE;
332 bounce_return_body = FALSE;
333 fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
334 eblock ? eblock->text2 : US"Unknown",
335 sender_host_address);
337 "A message claiming to be from you has failed the published DMARC\n"
338 "policy for your domain.\n\n");
341 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
343 eblock = eblock->next;
349 fprintf(fp, "Subject: Mail failure\n\n");
351 "A message that you sent has caused the error routine to be entered with\n"
352 "an unknown error number (%d).\n", ident);
356 /* Now, if configured, copy the message; first the headers and then the rest of
357 the input if available, up to the configured limit, if the option for including
358 message bodies in bounces is set. */
360 if (bounce_return_message)
362 if (bounce_return_body)
365 "------ This is a copy of your message, including all the headers.");
366 if (size_limit == 0 || size_limit > thismessage_size_limit)
367 size_limit = thismessage_size_limit;
368 if (size_limit > 0 && size_limit < message_size)
378 "------ No more than %d%s characters of the body are included.\n\n",
381 else fprintf(fp, " ------\n\n");
386 "------ This is a copy of the headers that were received before the "
387 "error\n was detected.\n\n");
390 /* If the error occurred before the Received: header was created, its text
391 field will still be NULL; just omit such a header line. */
395 if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
396 headers = headers->next;
399 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
402 /* After early detection of an error, the message file may be STDIN,
403 in which case we might have to terminate on a line containing just "."
404 as well as on EOF. We may already have the first line in memory. */
406 if (bounce_return_body && message_file)
408 BOOL enddot = f.dot_ends && message_file == stdin;
409 uschar * buf = store_get(bounce_return_linesize_limit+2, GET_TAINTED);
411 if (firstline) fprintf(fp, "%s", CS firstline);
413 while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
417 if (enddot && *buf == '.' && buf[1] == '\n')
424 if (buf[len-1] != '\n')
425 { /* eat rest of partial line */
427 while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
430 if (size_limit > 0 && len > size_limit - written)
432 buf[size_limit - written] = '\0';
441 /* Overkill, but use exact test in case future code gets inserted */
442 else if (bounce_return_body && message_file == NULL)
444 /*XXX limit line length here? */
445 /* This doesn't print newlines, disable until can parse and fix
446 * output to be legible. */
447 fprintf(fp, "%s", expand_string(US"$message_body"));
451 /* Close the file, which should send an EOF to the child process
452 that is receiving the message. Wait for it to finish, without a timeout. */
455 status = child_close(pid, 0); /* Waits for child to close */
458 uschar *msg = US"Child mail process returned status";
460 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
463 log_write(0, LOG_MAIN, "%s %d", msg, status);
472 /*************************************************
473 * Send message to sender *
474 *************************************************/
476 /* This function is called when errors are detected during the receipt of a
477 message. Delivery failures are handled separately in deliver.c.
479 If there is a valid sender_address, and the failing message is not a local
480 error message, then this function calls moan_send_message to send a message to
481 that person. If the sender's address is null, then an error has occurred with a
482 message that was generated by a mailer daemon. All we can do is to write
483 information to log files. The same action is taken if local_error_message is
484 set - this can happen for non null-senders in certain configurations where exim
485 doesn't run setuid root.
488 ident identifies the particular error
489 eblock chain of error_blocks containing data about the error
490 headers message's headers (chain)
491 message_file a FILE where the body of the message can be read
492 check_sender if TRUE, read the first line of the file for a possible
493 "From " sender (if a trusted caller)
495 Returns: FALSE if there is no sender_address to send to;
496 else the return from moan_send_message()
500 moan_to_sender(int ident, error_block *eblock, header_line *headers,
501 FILE *message_file, BOOL check_sender)
503 uschar *firstline = NULL;
504 uschar *msg = US"Error while reading message with no usable sender address";
506 if (message_reference)
507 msg = string_sprintf("%s (R=%s)", msg, message_reference);
509 /* Find the sender from a From line if permitted and possible */
511 if (check_sender && message_file && f.trusted_caller &&
512 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
514 uschar *new_sender = NULL;
515 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
516 new_sender = expand_string(uucp_from_sender);
517 if (new_sender) sender_address = new_sender;
518 else firstline = big_buffer;
521 /* If viable sender address, send a message */
523 if (sender_address && sender_address[0] && !f.local_error_message)
524 return moan_send_message(sender_address, ident, eblock, headers,
525 message_file, firstline);
527 /* Otherwise, we can only log */
531 case ERRMESS_BADARGADDRESS:
532 case ERRMESS_BADNOADDRESS:
533 case ERRMESS_BADADDRESS:
534 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
535 "%s - %s", msg, eblock->text1, eblock->text2);
538 case ERRMESS_IGADDRESS:
539 case ERRMESS_NOADDRESS:
540 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
543 /* This error has already been logged. */
547 case ERRMESS_VLONGHEADER:
548 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
549 "(more than %d characters)", msg, header_maxsize);
552 case ERRMESS_VLONGHDRLINE:
553 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
554 "(more than %d characters)", msg, header_line_maxsize);
558 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
559 thismessage_size_limit);
562 case ERRMESS_TOOMANYRECIP:
563 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
567 case ERRMESS_LOCAL_SCAN:
568 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
571 case ERRMESS_LOCAL_ACL:
572 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
576 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
586 /*************************************************
587 * Send message to someone *
588 *************************************************/
590 /* This is called when exim is configured to tell someone (often the
591 mailmaster) about some incident.
594 who address to send mail to
595 addr chain of deferred addresses whose details are to be included
596 subject subject text for the message
597 format a printf() format for the body of the message
598 ... arguments for the format
604 moan_tell_someone(uschar *who, address_item *addr,
605 const uschar *subject, const char *format, ...)
610 int pid = child_open_exim(&fd, US"moan_tell_someone");
614 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
619 f = fdopen(fd, "wb");
620 fprintf(f, "Auto-Submitted: auto-replied\n");
622 fprintf(f, "To: %s\n", who);
623 moan_write_references(f, NULL);
624 fprintf(f, "Subject: %s\n\n", subject);
625 va_start(ap, format);
626 vfprintf(f, format, ap);
631 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
632 for (; addr; addr = addr->next)
634 uschar * parent = addr->parent ? addr->parent->address : NULL;
635 fprintf(f, " %s", addr->address);
636 if (parent) fprintf(f, " <%s>", parent);
637 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
638 if (addr->message) fprintf(f, ": %s", addr->message);
644 child_close(pid, 0); /* Waits for child to close; no timeout */
649 /*************************************************
650 * Handle SMTP batch error *
651 *************************************************/
653 /* This is called when something goes wrong in batched (-bS) SMTP input.
654 Information is written to stdout and/or stderr, and Exim exits with a non-zero
655 completion code. BSMTP is almost always called by some other program, so it is
656 up to that program to interpret the return code and do something with the error
657 information, and also to preserve the batch input file for human analysis.
659 Formerly, Exim used to attempt to continue after some errors, but this strategy
660 has been abandoned as it can lead to loss of messages.
663 cmd_buffer the command causing the error, or NULL
664 format a printf() format
665 ... arguments for the format
667 Returns: does not return; exits from the program
668 exit code = 1 if some messages were accepted
669 exit code = 2 if no messages were accepted
673 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
676 int yield = (receive_messagecount > 0)? 1 : 2;
678 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
680 /* On stdout, write stuff that a program could parse fairly easily. */
682 va_start(ap, format);
683 vfprintf(stdout, format, ap);
686 fprintf(stdout, "\nTransaction started in line %d\n",
687 bsmtp_transaction_linecount);
688 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
689 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
691 /* On stderr, write stuff for human consumption */
694 "An error was detected while processing a file of BSMTP input.\n"
695 "The error message was:\n\n ");
697 va_start(ap, format);
698 vfprintf(stderr, format, ap);
702 "\n\nThe SMTP transaction started in line %d.\n"
703 "The error was detected in line %d.\n",
704 bsmtp_transaction_linecount, receive_linecount);
706 if (cmd_buffer != NULL)
708 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
712 fprintf(stderr, "%d previous message%s successfully processed.\n",
713 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
715 fprintf(stderr, "The rest of the batch was abandoned.\n");
723 /*************************************************
724 * Check for error copies *
725 *************************************************/
727 /* This function is passed the recipient of an error message, and must check
728 the error_copies string to see whether there is an additional recipient list to
729 which errors for this recipient must be bcc'd. The incoming recipient is always
732 Argument: recipient address
733 Returns: additional recipient list or NULL
737 moan_check_errorcopy(uschar *recipient)
739 uschar *item, *localpart, *domain;
740 const uschar *listptr = errors_copy;
741 uschar *yield = NULL;
745 if (errors_copy == NULL) return NULL;
747 /* Set up pointer to the local part and domain, and compute the
748 length of the local part. */
750 localpart = recipient;
751 domain = Ustrrchr(recipient, '@');
752 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
753 llen = domain++ - recipient;
755 /* Scan through the configured items */
757 while ((item = string_nextinlist(&listptr, &sep, NULL, 0)))
759 const uschar *newaddress = item;
760 const uschar *pattern = string_dequote(&newaddress);
762 /* If no new address found, just skip this item. */
764 while (isspace(*newaddress)) newaddress++;
765 if (*newaddress == 0) continue;
767 /* We now have an item to match as an address in item, and the additional
768 address in newaddress. If the pattern matches, expand the new address string
769 and return it. During expansion, make local part and domain available for
770 insertion. This requires a copy to be made; we can't just temporarily
771 terminate it, as the whole address is required for $0. */
773 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
776 deliver_localpart = string_copyn(localpart, llen);
777 deliver_domain = domain;
778 yield = expand_string_copy(newaddress);
779 deliver_domain = deliver_localpart = NULL;
781 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
782 "errors_copy: %s", newaddress, expand_string_message);
787 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
788 (yield == NULL)? US"NULL" : yield);
796 /************************************************
797 * Handle skipped syntax errors *
798 ************************************************/
800 /* This function is called by the redirect router when it has skipped over one
801 or more syntax errors in the list of addresses. If there is an address to mail
802 to, send a message, and always write the information to the log. In the case of
803 a filter file, a "syntax error" might actually be something else, such as the
804 inability to open a log file. Thus, the wording of the error message is
808 rname the router name
809 eblock chain of error blocks
810 syntax_errors_to address to send mail to, or NULL
811 some TRUE if some addresses were generated; FALSE if none were
812 custom custom message text
814 Returns: FALSE if string expansion failed; TRUE otherwise
818 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
819 uschar *syntax_errors_to, BOOL some, uschar *custom)
825 for (error_block * e = eblock; e; e = e->next)
826 if (e->text2 != NULL)
827 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
828 rname, e->text1, e->text2);
830 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
833 if (!syntax_errors_to) return TRUE;
835 if (!(s = expand_string(syntax_errors_to)))
837 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
838 syntax_errors_to, expand_string_message);
842 /* If we can't create a process to send the message, just forget about
845 pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
849 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
854 f = fdopen(fd, "wb");
855 fprintf(f, "Auto-Submitted: auto-replied\n");
857 fprintf(f, "To: %s\n", s);
858 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
859 moan_write_references(f, NULL);
863 if (!(t = expand_string(custom)))
865 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
866 custom, expand_string_message);
869 fprintf(f, "%s\n\n", t);
872 fprintf(f, "The %s router encountered the following error(s):\n\n",
875 for (error_block * e = eblock; e; e = e->next)
877 fprintf(f, " %s", e->text1);
878 if (e->text2 != NULL)
879 fprintf(f, " in the address\n \"%s\"", e->text2);
884 fprintf(f, "Other addresses were processed normally.\n");
886 fprintf(f, "No valid addresses were generated.\n");
889 child_close(pid, 0); /* Waits for child to close; no timeout */