1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
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. */
87 fprintf(fp, "References:");
92 uschar * referenced_ids[12];
93 int reference_count = 0;
95 s = Ustrchr(h->text, ':') + 1;
96 f.parse_allow_group = FALSE;
97 while (*s && (s = parse_message_id(s, &id, &error)))
98 if (reference_count == nelem(referenced_ids))
100 memmove(referenced_ids + 1, referenced_ids + 2,
101 sizeof(referenced_ids) - 2*sizeof(uschar *));
102 referenced_ids[reference_count - 1] = id;
105 referenced_ids[reference_count++] = id;
107 for (int i = 0; i < reference_count; ++i)
108 fprintf(fp, " %s", referenced_ids[i]);
111 /* The message id will have a newline on the end of it. */
113 if (message_id) fprintf(fp, " %s", message_id);
114 else fprintf(fp, "\n");
120 /*************************************************
121 * Send error message *
122 *************************************************/
124 /* This function sends an error message by opening a pipe to a new process
125 running Exim, and writing a message to it using the "-t" option. This is not
126 used for delivery failures, which have their own code for handing failed
130 recipient addressee for the message
131 ident identifies the type of error
132 eblock chain of error_blocks containing data about the error
133 headers the message's headers
134 message_file FILE containing the body of the message
135 firstline contains first line of file, if it was read to check for
136 "From ", but it turned out not to be
138 Returns: TRUE if message successfully sent
142 moan_send_message(uschar *recipient, int ident, error_block *eblock,
143 header_line *headers, FILE *message_file, uschar *firstline)
149 int size_limit = bounce_return_size_limit;
156 /* For DMARC if there is a specific sender set, expand the variable for the
157 header From: and grab the address from that for the envelope FROM. */
159 if ( ident == ERRMESS_DMARC_FORENSIC
160 && dmarc_forensic_sender
161 && (s = expand_string(dmarc_forensic_sender))
163 && (s2 = expand_string(string_sprintf("${address:%s}", s)))
166 pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
167 US"moan_send_message");
171 pid = child_open_exim(&fd, US"moan_send_message");
175 pid = child_open_exim(&fd, US"moan_send_message");
180 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
184 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
186 /* Creation of child succeeded */
188 fp = fdopen(fd, "wb");
189 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
190 fprintf(fp, "Auto-Submitted: auto-replied\n");
194 fprintf(fp, "From: %s\n", s);
199 fprintf(fp, "To: %s\n", recipient);
200 moan_write_references(fp, NULL);
204 case ERRMESS_BADARGADDRESS:
206 "Subject: Mail failure - malformed recipient address\n\n");
208 "A message that you sent contained a recipient address that was incorrectly\n"
210 fprintf(fp, " %s %s\n", eblock->text1, eblock->text2);
211 count = Ustrlen(eblock->text1);
212 if (count > 0 && eblock->text1[count-1] == '.')
214 "\nRecipient addresses must not end with a '.' character.\n");
216 "\nThe message has not been delivered to any recipients.\n");
219 case ERRMESS_BADNOADDRESS:
220 case ERRMESS_BADADDRESS:
222 "Subject: Mail failure - malformed recipient address\n\n");
224 "A message that you sent contained one or more recipient addresses that were\n"
225 "incorrectly constructed:\n\n");
229 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
231 eblock = eblock->next;
234 fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
235 "\nThese addresses have been ignored. ");
237 fprintf(fp, (ident == ERRMESS_BADADDRESS)?
238 "The other addresses in the message were\n"
239 "syntactically valid and have been passed on for an attempt at delivery.\n" :
241 "There were no other addresses in your\n"
242 "message, and so no attempt at delivery was possible.\n");
245 case ERRMESS_IGADDRESS:
246 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
248 "A message that you sent using the -t command line option contained no\n"
249 "addresses that were not also on the command line, and were therefore\n"
250 "suppressed. This left no recipient addresses, and so no delivery could\n"
254 case ERRMESS_NOADDRESS:
255 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
257 "A message that you sent contained no recipient addresses, and therefore no\n"
258 "delivery could be attempted.\n");
262 fprintf(fp, "Subject: Mail failure - system failure\n\n");
264 "A system failure was encountered while processing a message that you sent,\n"
265 "so it has not been possible to deliver it. The error was:\n\n%s\n",
269 case ERRMESS_VLONGHEADER:
270 fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
272 "A message that you sent contained a header section that was excessively\n"
273 "long and could not be handled by the mail transmission software. The\n"
274 "message has not been delivered to any recipients.\n");
277 case ERRMESS_VLONGHDRLINE:
278 fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
280 "A message that you sent contained a header line that was excessively\n"
281 "long and could not be handled by the mail transmission software. The\n"
282 "message has not been delivered to any recipients.\n");
286 fprintf(fp, "Subject: Mail failure - message too big\n\n");
288 "A message that you sent was longer than the maximum size allowed on this\n"
289 "system. It was not delivered to any recipients.\n");
292 case ERRMESS_TOOMANYRECIP:
293 fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
295 "A message that you sent contained more recipients than allowed on this\n"
296 "system. It was not delivered to any recipients.\n");
299 case ERRMESS_LOCAL_SCAN:
300 case ERRMESS_LOCAL_ACL:
301 fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
303 "A message that you sent was rejected by the local scanning code that\n"
304 "checks incoming messages on this system.");
306 fprintf(fp, " The following error was given:\n\n %s", eblock->text1);
311 case ERRMESS_DMARC_FORENSIC:
312 bounce_return_message = TRUE;
313 bounce_return_body = FALSE;
314 fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
315 eblock ? eblock->text2 : US"Unknown",
316 sender_host_address);
318 "A message claiming to be from you has failed the published DMARC\n"
319 "policy for your domain.\n\n");
322 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
324 eblock = eblock->next;
330 fprintf(fp, "Subject: Mail failure\n\n");
332 "A message that you sent has caused the error routine to be entered with\n"
333 "an unknown error number (%d).\n", ident);
337 /* Now, if configured, copy the message; first the headers and then the rest of
338 the input if available, up to the configured limit, if the option for including
339 message bodies in bounces is set. */
341 if (bounce_return_message)
343 if (bounce_return_body)
346 "------ This is a copy of your message, including all the headers.");
347 if (size_limit == 0 || size_limit > thismessage_size_limit)
348 size_limit = thismessage_size_limit;
349 if (size_limit > 0 && size_limit < message_size)
359 "------ No more than %d%s characters of the body are included.\n\n",
362 else fprintf(fp, " ------\n\n");
367 "------ This is a copy of the headers that were received before the "
368 "error\n was detected.\n\n");
371 /* If the error occurred before the Received: header was created, its text
372 field will still be NULL; just omit such a header line. */
376 if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
377 headers = headers->next;
380 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
383 /* After early detection of an error, the message file may be STDIN,
384 in which case we might have to terminate on a line containing just "."
385 as well as on EOF. We may already have the first line in memory. */
387 if (bounce_return_body && message_file)
389 BOOL enddot = f.dot_ends && message_file == stdin;
390 uschar * buf = store_get(bounce_return_linesize_limit+2, GET_TAINTED);
392 if (firstline) fprintf(fp, "%s", CS firstline);
394 while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
398 if (enddot && *buf == '.' && buf[1] == '\n')
405 if (buf[len-1] != '\n')
406 { /* eat rest of partial line */
408 while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
411 if (size_limit > 0 && len > size_limit - written)
413 buf[size_limit - written] = '\0';
422 /* Overkill, but use exact test in case future code gets inserted */
423 else if (bounce_return_body && message_file == NULL)
425 /*XXX limit line length here? */
426 /* This doesn't print newlines, disable until can parse and fix
427 * output to be legible. */
428 fprintf(fp, "%s", expand_string(US"$message_body"));
432 /* Close the file, which should send an EOF to the child process
433 that is receiving the message. Wait for it to finish, without a timeout. */
436 status = child_close(pid, 0); /* Waits for child to close */
439 uschar *msg = US"Child mail process returned status";
441 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
444 log_write(0, LOG_MAIN, "%s %d", msg, status);
453 /*************************************************
454 * Send message to sender *
455 *************************************************/
457 /* This function is called when errors are detected during the receipt of a
458 message. Delivery failures are handled separately in deliver.c.
460 If there is a valid sender_address, and the failing message is not a local
461 error message, then this function calls moan_send_message to send a message to
462 that person. If the sender's address is null, then an error has occurred with a
463 message that was generated by a mailer daemon. All we can do is to write
464 information to log files. The same action is taken if local_error_message is
465 set - this can happen for non null-senders in certain configurations where exim
466 doesn't run setuid root.
469 ident identifies the particular error
470 eblock chain of error_blocks containing data about the error
471 headers message's headers (chain)
472 message_file a FILE where the body of the message can be read
473 check_sender if TRUE, read the first line of the file for a possible
474 "From " sender (if a trusted caller)
476 Returns: FALSE if there is no sender_address to send to;
477 else the return from moan_send_message()
481 moan_to_sender(int ident, error_block *eblock, header_line *headers,
482 FILE *message_file, BOOL check_sender)
484 uschar *firstline = NULL;
485 uschar *msg = US"Error while reading message with no usable sender address";
487 if (message_reference)
488 msg = string_sprintf("%s (R=%s)", msg, message_reference);
490 /* Find the sender from a From line if permitted and possible */
492 if (check_sender && message_file && f.trusted_caller &&
493 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
495 uschar *new_sender = NULL;
496 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
497 new_sender = expand_string(uucp_from_sender);
498 if (new_sender) sender_address = new_sender;
499 else firstline = big_buffer;
502 /* If viable sender address, send a message */
504 if (sender_address && sender_address[0] && !f.local_error_message)
505 return moan_send_message(sender_address, ident, eblock, headers,
506 message_file, firstline);
508 /* Otherwise, we can only log */
512 case ERRMESS_BADARGADDRESS:
513 case ERRMESS_BADNOADDRESS:
514 case ERRMESS_BADADDRESS:
515 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
516 "%s - %s", msg, eblock->text1, eblock->text2);
519 case ERRMESS_IGADDRESS:
520 case ERRMESS_NOADDRESS:
521 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
524 /* This error has already been logged. */
528 case ERRMESS_VLONGHEADER:
529 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
530 "(more than %d characters)", msg, header_maxsize);
533 case ERRMESS_VLONGHDRLINE:
534 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
535 "(more than %d characters)", msg, header_line_maxsize);
539 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
540 thismessage_size_limit);
543 case ERRMESS_TOOMANYRECIP:
544 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
548 case ERRMESS_LOCAL_SCAN:
549 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
552 case ERRMESS_LOCAL_ACL:
553 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
557 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
567 /*************************************************
568 * Send message to someone *
569 *************************************************/
571 /* This is called when exim is configured to tell someone (often the
572 mailmaster) about some incident.
575 who address to send mail to
576 addr chain of deferred addresses whose details are to be included
577 subject subject text for the message
578 format a printf() format for the body of the message
579 ... arguments for the format
585 moan_tell_someone(uschar *who, address_item *addr,
586 const uschar *subject, const char *format, ...)
591 int pid = child_open_exim(&fd, US"moan_tell_someone");
595 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
600 f = fdopen(fd, "wb");
601 fprintf(f, "Auto-Submitted: auto-replied\n");
603 fprintf(f, "To: %s\n", who);
604 moan_write_references(f, NULL);
605 fprintf(f, "Subject: %s\n\n", subject);
606 va_start(ap, format);
607 vfprintf(f, format, ap);
612 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
613 for (; addr; addr = addr->next)
615 uschar * parent = addr->parent ? addr->parent->address : NULL;
616 fprintf(f, " %s", addr->address);
617 if (parent) fprintf(f, " <%s>", parent);
618 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
619 if (addr->message) fprintf(f, ": %s", addr->message);
625 child_close(pid, 0); /* Waits for child to close; no timeout */
630 /*************************************************
631 * Handle SMTP batch error *
632 *************************************************/
634 /* This is called when something goes wrong in batched (-bS) SMTP input.
635 Information is written to stdout and/or stderr, and Exim exits with a non-zero
636 completion code. BSMTP is almost always called by some other program, so it is
637 up to that program to interpret the return code and do something with the error
638 information, and also to preserve the batch input file for human analysis.
640 Formerly, Exim used to attempt to continue after some errors, but this strategy
641 has been abandoned as it can lead to loss of messages.
644 cmd_buffer the command causing the error, or NULL
645 format a printf() format
646 ... arguments for the format
648 Returns: does not return; exits from the program
649 exit code = 1 if some messages were accepted
650 exit code = 2 if no messages were accepted
654 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
657 int yield = (receive_messagecount > 0)? 1 : 2;
659 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
661 /* On stdout, write stuff that a program could parse fairly easily. */
663 va_start(ap, format);
664 vfprintf(stdout, format, ap);
667 fprintf(stdout, "\nTransaction started in line %d\n",
668 bsmtp_transaction_linecount);
669 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
670 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
672 /* On stderr, write stuff for human consumption */
675 "An error was detected while processing a file of BSMTP input.\n"
676 "The error message was:\n\n ");
678 va_start(ap, format);
679 vfprintf(stderr, format, ap);
683 "\n\nThe SMTP transaction started in line %d.\n"
684 "The error was detected in line %d.\n",
685 bsmtp_transaction_linecount, receive_linecount);
687 if (cmd_buffer != NULL)
689 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
693 fprintf(stderr, "%d previous message%s successfully processed.\n",
694 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
696 fprintf(stderr, "The rest of the batch was abandoned.\n");
704 /*************************************************
705 * Check for error copies *
706 *************************************************/
708 /* This function is passed the recipient of an error message, and must check
709 the error_copies string to see whether there is an additional recipient list to
710 which errors for this recipient must be bcc'd. The incoming recipient is always
713 Argument: recipient address
714 Returns: additional recipient list or NULL
718 moan_check_errorcopy(uschar *recipient)
720 uschar *item, *localpart, *domain;
721 const uschar *listptr = errors_copy;
722 uschar *yield = NULL;
726 if (errors_copy == NULL) return NULL;
728 /* Set up pointer to the local part and domain, and compute the
729 length of the local part. */
731 localpart = recipient;
732 domain = Ustrrchr(recipient, '@');
733 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
734 llen = domain++ - recipient;
736 /* Scan through the configured items */
738 while ((item = string_nextinlist(&listptr, &sep, NULL, 0)))
740 const uschar *newaddress = item;
741 const uschar *pattern = string_dequote(&newaddress);
743 /* If no new address found, just skip this item. */
745 while (isspace(*newaddress)) newaddress++;
746 if (*newaddress == 0) continue;
748 /* We now have an item to match as an address in item, and the additional
749 address in newaddress. If the pattern matches, expand the new address string
750 and return it. During expansion, make local part and domain available for
751 insertion. This requires a copy to be made; we can't just temporarily
752 terminate it, as the whole address is required for $0. */
754 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
757 deliver_localpart = string_copyn(localpart, llen);
758 deliver_domain = domain;
759 yield = expand_string_copy(newaddress);
760 deliver_domain = deliver_localpart = NULL;
762 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
763 "errors_copy: %s", newaddress, expand_string_message);
768 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
769 (yield == NULL)? US"NULL" : yield);
777 /************************************************
778 * Handle skipped syntax errors *
779 ************************************************/
781 /* This function is called by the redirect router when it has skipped over one
782 or more syntax errors in the list of addresses. If there is an address to mail
783 to, send a message, and always write the information to the log. In the case of
784 a filter file, a "syntax error" might actually be something else, such as the
785 inability to open a log file. Thus, the wording of the error message is
789 rname the router name
790 eblock chain of error blocks
791 syntax_errors_to address to send mail to, or NULL
792 some TRUE if some addresses were generated; FALSE if none were
793 custom custom message text
795 Returns: FALSE if string expansion failed; TRUE otherwise
799 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
800 uschar *syntax_errors_to, BOOL some, uschar *custom)
806 for (error_block * e = eblock; e; e = e->next)
807 if (e->text2 != NULL)
808 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
809 rname, e->text1, e->text2);
811 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
814 if (!syntax_errors_to) return TRUE;
816 if (!(s = expand_string(syntax_errors_to)))
818 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
819 syntax_errors_to, expand_string_message);
823 /* If we can't create a process to send the message, just forget about
826 pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
830 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
835 f = fdopen(fd, "wb");
836 fprintf(f, "Auto-Submitted: auto-replied\n");
838 fprintf(f, "To: %s\n", s);
839 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
840 moan_write_references(f, NULL);
844 if (!(t = expand_string(custom)))
846 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
847 custom, expand_string_message);
850 fprintf(f, "%s\n\n", t);
853 fprintf(f, "The %s router encountered the following error(s):\n\n",
856 for (error_block * e = eblock; e; e = e->next)
858 fprintf(f, " %s", e->text1);
859 if (e->text2 != NULL)
860 fprintf(f, " in the address\n \"%s\"", e->text2);
865 fprintf(f, "Other addresses were processed normally.\n");
867 fprintf(f, "No valid addresses were generated.\n");
870 child_close(pid, 0); /* Waits for child to close; no timeout */