1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 */
7 /* See the file NOTICE for conditions of use and distribution. */
9 /* Functions for sending messages to sender or to mailmaster. */
16 /*************************************************
17 * Write From: line for DSN *
18 *************************************************/
20 /* This function is called to write the From: line in automatically generated
21 messages - bounces, warnings, etc. It expands a configuration item in order to
22 get the text. If the expansion fails, a panic is logged and the default value
23 for the option is used.
25 Argument: the FILE to write to
30 moan_write_from(FILE *f)
32 uschar * s = expand_string(dsn_from);
35 log_write(0, LOG_MAIN|LOG_PANIC,
36 "Failed to expand dsn_from (using default): %s", expand_string_message);
37 s = expand_string(US DEFAULT_DSN_FROM);
39 fprintf(f, "From: %s\n", s);
44 /*************************************************
45 * Write References: line for DSN *
46 *************************************************/
48 /* Generate a References: header if there is in the header_list
49 at least one of Message-ID:, References:, or In-Reply-To: (see RFC 2822).
51 Arguments: f the FILE to write to
52 message_id optional already-found message-id, or NULL
58 moan_write_references(FILE * fp, uschar * message_id)
63 for (h = header_list; h; h = h->next)
64 if (h->type == htype_id)
66 message_id = Ustrchr(h->text, ':') + 1;
67 Uskip_whitespace(&message_id);
70 for (h = header_list; h; h = h->next)
71 if (h->type != htype_old && strncmpic(US"References:", h->text, 11) == 0)
75 for (h = header_list; h; h = h->next)
76 if (h->type != htype_old && strncmpic(US"In-Reply-To:", h->text, 12) == 0)
79 /* We limit the total length of references. Although there is no fixed
80 limit, some systems do not like headers growing beyond recognition.
81 Keep the first message ID for the thread root and the last few for
82 the position inside the thread, up to a maximum of 12 altogether. */
86 fprintf(fp, "References:");
89 uschar * s, * id, * error;
90 uschar * referenced_ids[12];
91 int reference_count = 0;
93 s = Ustrchr(h->text, ':') + 1;
94 f.parse_allow_group = FALSE;
95 while (*s && (s = parse_message_id(s, &id, &error)))
96 if (reference_count == nelem(referenced_ids))
98 memmove(referenced_ids + 1, referenced_ids + 2,
99 sizeof(referenced_ids) - 2*sizeof(uschar *));
100 referenced_ids[reference_count - 1] = id;
103 referenced_ids[reference_count++] = id;
105 for (int i = 0; i < reference_count; ++i)
106 fprintf(fp, " %s", referenced_ids[i]);
109 /* The message id will have a newline on the end of it. */
111 if (message_id) fprintf(fp, " %s", message_id);
112 else fprintf(fp, "\n");
118 /*************************************************
119 * Send error message *
120 *************************************************/
122 /* This function sends an error message by opening a pipe to a new process
123 running Exim, and writing a message to it using the "-t" option. This is not
124 used for delivery failures, which have their own code for handing failed
128 recipient addressee for the message
129 ident identifies the type of error
130 eblock chain of error_blocks containing data about the error
131 headers the message's headers
132 message_file FILE containing the body of the message
133 firstline contains first line of file, if it was read to check for
134 "From ", but it turned out not to be
136 Returns: TRUE if message successfully sent
140 moan_send_message(uschar *recipient, int ident, error_block *eblock,
141 header_line *headers, FILE *message_file, uschar *firstline)
147 int size_limit = bounce_return_size_limit;
154 /* For DMARC if there is a specific sender set, expand the variable for the
155 header From: and grab the address from that for the envelope FROM. */
157 if ( ident == ERRMESS_DMARC_FORENSIC
158 && dmarc_forensic_sender
159 && (s = expand_string(dmarc_forensic_sender))
161 && (s2 = expand_string(string_sprintf("${address:%s}", s)))
164 pid = child_open_exim2(&fd, s2, bounce_sender_authentication,
165 US"moan_send_message");
169 pid = child_open_exim(&fd, US"moan_send_message");
173 pid = child_open_exim(&fd, US"moan_send_message");
178 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
182 else DEBUG(D_any) debug_printf("Child process %d for sending message\n", pid);
184 /* Creation of child succeeded */
186 fp = fdopen(fd, "wb");
187 if (errors_reply_to) fprintf(fp, "Reply-To: %s\n", errors_reply_to);
188 fprintf(fp, "Auto-Submitted: auto-replied\n");
192 fprintf(fp, "From: %s\n", s);
197 fprintf(fp, "To: %s\n", recipient);
198 moan_write_references(fp, NULL);
202 case ERRMESS_BADARGADDRESS:
204 "Subject: Mail failure - malformed recipient address\n\n");
206 "A message that you sent contained a recipient address that was incorrectly\n"
208 fprintf(fp, " %s %s\n", eblock->text1, eblock->text2);
209 count = Ustrlen(eblock->text1);
210 if (count > 0 && eblock->text1[count-1] == '.')
212 "\nRecipient addresses must not end with a '.' character.\n");
214 "\nThe message has not been delivered to any recipients.\n");
217 case ERRMESS_BADNOADDRESS:
218 case ERRMESS_BADADDRESS:
220 "Subject: Mail failure - malformed recipient address\n\n");
222 "A message that you sent contained one or more recipient addresses that were\n"
223 "incorrectly constructed:\n\n");
227 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
229 eblock = eblock->next;
232 fprintf(fp, (count == 1)? "\nThis address has been ignored. " :
233 "\nThese addresses have been ignored. ");
235 fprintf(fp, (ident == ERRMESS_BADADDRESS)?
236 "The other addresses in the message were\n"
237 "syntactically valid and have been passed on for an attempt at delivery.\n" :
239 "There were no other addresses in your\n"
240 "message, and so no attempt at delivery was possible.\n");
243 case ERRMESS_IGADDRESS:
244 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
246 "A message that you sent using the -t command line option contained no\n"
247 "addresses that were not also on the command line, and were therefore\n"
248 "suppressed. This left no recipient addresses, and so no delivery could\n"
252 case ERRMESS_NOADDRESS:
253 fprintf(fp, "Subject: Mail failure - no recipient addresses\n\n");
255 "A message that you sent contained no recipient addresses, and therefore no\n"
256 "delivery could be attempted.\n");
260 fprintf(fp, "Subject: Mail failure - system failure\n\n");
262 "A system failure was encountered while processing a message that you sent,\n"
263 "so it has not been possible to deliver it. The error was:\n\n%s\n",
267 case ERRMESS_VLONGHEADER:
268 fprintf(fp, "Subject: Mail failure - overlong header section\n\n");
270 "A message that you sent contained a header section that was excessively\n"
271 "long and could not be handled by the mail transmission software. The\n"
272 "message has not been delivered to any recipients.\n");
275 case ERRMESS_VLONGHDRLINE:
276 fprintf(fp, "Subject: Mail failure - overlong header line\n\n");
278 "A message that you sent contained a header line that was excessively\n"
279 "long and could not be handled by the mail transmission software. The\n"
280 "message has not been delivered to any recipients.\n");
284 fprintf(fp, "Subject: Mail failure - message too big\n\n");
286 "A message that you sent was longer than the maximum size allowed on this\n"
287 "system. It was not delivered to any recipients.\n");
290 case ERRMESS_TOOMANYRECIP:
291 fprintf(fp, "Subject: Mail failure - too many recipients\n\n");
293 "A message that you sent contained more recipients than allowed on this\n"
294 "system. It was not delivered to any recipients.\n");
297 case ERRMESS_LOCAL_SCAN:
298 case ERRMESS_LOCAL_ACL:
299 fprintf(fp, "Subject: Mail failure - rejected by local scanning code\n\n");
301 "A message that you sent was rejected by the local scanning code that\n"
302 "checks incoming messages on this system.");
304 fprintf(fp, " The following error was given:\n\n %s", eblock->text1);
309 case ERRMESS_DMARC_FORENSIC:
310 bounce_return_message = TRUE;
311 bounce_return_body = FALSE;
312 fprintf(fp, "Subject: DMARC Forensic Report for %s from IP %s\n\n",
313 eblock ? eblock->text2 : US"Unknown",
314 sender_host_address);
316 "A message claiming to be from you has failed the published DMARC\n"
317 "policy for your domain.\n\n");
320 fprintf(fp, " %s: %s\n", eblock->text1, eblock->text2);
322 eblock = eblock->next;
328 fprintf(fp, "Subject: Mail failure\n\n");
330 "A message that you sent has caused the error routine to be entered with\n"
331 "an unknown error number (%d).\n", ident);
335 /* Now, if configured, copy the message; first the headers and then the rest of
336 the input if available, up to the configured limit, if the option for including
337 message bodies in bounces is set. */
339 if (bounce_return_message)
341 if (bounce_return_body)
344 "------ This is a copy of your message, including all the headers.");
345 if (size_limit == 0 || size_limit > thismessage_size_limit)
346 size_limit = thismessage_size_limit;
347 if (size_limit > 0 && size_limit < message_size)
357 "------ No more than %d%s characters of the body are included.\n\n",
360 else fprintf(fp, " ------\n\n");
365 "------ This is a copy of the headers that were received before the "
366 "error\n was detected.\n\n");
369 /* If the error occurred before the Received: header was created, its text
370 field will still be NULL; just omit such a header line. */
374 if (headers->text != NULL) fprintf(fp, "%s", CS headers->text);
375 headers = headers->next;
378 if (ident != ERRMESS_VLONGHEADER && ident != ERRMESS_VLONGHDRLINE)
381 /* After early detection of an error, the message file may be STDIN,
382 in which case we might have to terminate on a line containing just "."
383 as well as on EOF. We may already have the first line in memory. */
385 if (bounce_return_body && message_file)
387 BOOL enddot = f.dot_ends && message_file == stdin;
388 uschar * buf = store_get(bounce_return_linesize_limit+2, TRUE);
390 if (firstline) fprintf(fp, "%s", CS firstline);
392 while (fgets(CS buf, bounce_return_linesize_limit+2, message_file))
396 if (enddot && *buf == '.' && buf[1] == '\n')
403 if (buf[len-1] != '\n')
404 { /* eat rest of partial line */
406 while ((ch = fgetc(message_file)) != EOF && ch != '\n') ;
409 if (size_limit > 0 && len > size_limit - written)
411 buf[size_limit - written] = '\0';
420 /* Overkill, but use exact test in case future code gets inserted */
421 else if (bounce_return_body && message_file == NULL)
423 /*XXX limit line length here? */
424 /* This doesn't print newlines, disable until can parse and fix
425 * output to be legible. */
426 fprintf(fp, "%s", expand_string(US"$message_body"));
430 /* Close the file, which should send an EOF to the child process
431 that is receiving the message. Wait for it to finish, without a timeout. */
434 status = child_close(pid, 0); /* Waits for child to close */
437 uschar *msg = US"Child mail process returned status";
439 log_write(0, LOG_MAIN, "%s %d: errno=%d: %s", msg, status, errno,
442 log_write(0, LOG_MAIN, "%s %d", msg, status);
451 /*************************************************
452 * Send message to sender *
453 *************************************************/
455 /* This function is called when errors are detected during the receipt of a
456 message. Delivery failures are handled separately in deliver.c.
458 If there is a valid sender_address, and the failing message is not a local
459 error message, then this function calls moan_send_message to send a message to
460 that person. If the sender's address is null, then an error has occurred with a
461 message that was generated by a mailer daemon. All we can do is to write
462 information to log files. The same action is taken if local_error_message is
463 set - this can happen for non null-senders in certain configurations where exim
464 doesn't run setuid root.
467 ident identifies the particular error
468 eblock chain of error_blocks containing data about the error
469 headers message's headers (chain)
470 message_file a FILE where the body of the message can be read
471 check_sender if TRUE, read the first line of the file for a possible
472 "From " sender (if a trusted caller)
474 Returns: FALSE if there is no sender_address to send to;
475 else the return from moan_send_message()
479 moan_to_sender(int ident, error_block *eblock, header_line *headers,
480 FILE *message_file, BOOL check_sender)
482 uschar *firstline = NULL;
483 uschar *msg = US"Error while reading message with no usable sender address";
485 if (message_reference)
486 msg = string_sprintf("%s (R=%s)", msg, message_reference);
488 /* Find the sender from a From line if permitted and possible */
490 if (check_sender && message_file && f.trusted_caller &&
491 Ufgets(big_buffer, BIG_BUFFER_SIZE, message_file) != NULL)
493 uschar *new_sender = NULL;
494 if (regex_match_and_setup(regex_From, big_buffer, 0, -1))
495 new_sender = expand_string(uucp_from_sender);
496 if (new_sender) sender_address = new_sender;
497 else firstline = big_buffer;
500 /* If viable sender address, send a message */
502 if (sender_address && sender_address[0] && !f.local_error_message)
503 return moan_send_message(sender_address, ident, eblock, headers,
504 message_file, firstline);
506 /* Otherwise, we can only log */
510 case ERRMESS_BADARGADDRESS:
511 case ERRMESS_BADNOADDRESS:
512 case ERRMESS_BADADDRESS:
513 log_write(0, LOG_MAIN, "%s: at least one malformed recipient address: "
514 "%s - %s", msg, eblock->text1, eblock->text2);
517 case ERRMESS_IGADDRESS:
518 case ERRMESS_NOADDRESS:
519 log_write(0, LOG_MAIN, "%s: no recipient addresses", msg);
522 /* This error has already been logged. */
526 case ERRMESS_VLONGHEADER:
527 log_write(0, LOG_MAIN, "%s: excessively long message header section read "
528 "(more than %d characters)", msg, header_maxsize);
531 case ERRMESS_VLONGHDRLINE:
532 log_write(0, LOG_MAIN, "%s: excessively long message header line read "
533 "(more than %d characters)", msg, header_line_maxsize);
537 log_write(0, LOG_MAIN, "%s: message too big (limit set to %d)", msg,
538 thismessage_size_limit);
541 case ERRMESS_TOOMANYRECIP:
542 log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
546 case ERRMESS_LOCAL_SCAN:
547 log_write(0, LOG_MAIN, "%s: rejected by local_scan: %s", msg, eblock->text1);
550 case ERRMESS_LOCAL_ACL:
551 log_write(0, LOG_MAIN, "%s: rejected by non-SMTP ACL: %s", msg, eblock->text1);
555 log_write(0, LOG_MAIN|LOG_PANIC, "%s: unknown error number %d", msg,
565 /*************************************************
566 * Send message to someone *
567 *************************************************/
569 /* This is called when exim is configured to tell someone (often the
570 mailmaster) about some incident.
573 who address to send mail to
574 addr chain of deferred addresses whose details are to be included
575 subject subject text for the message
576 format a printf() format for the body of the message
577 ... arguments for the format
583 moan_tell_someone(uschar *who, address_item *addr,
584 const uschar *subject, const char *format, ...)
589 int pid = child_open_exim(&fd, US"moan_tell_someone");
593 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
598 f = fdopen(fd, "wb");
599 fprintf(f, "Auto-Submitted: auto-replied\n");
601 fprintf(f, "To: %s\n", who);
602 moan_write_references(f, NULL);
603 fprintf(f, "Subject: %s\n\n", subject);
604 va_start(ap, format);
605 vfprintf(f, format, ap);
610 fprintf(f, "\nThe following address(es) have yet to be delivered:\n");
611 for (; addr; addr = addr->next)
613 uschar * parent = addr->parent ? addr->parent->address : NULL;
614 fprintf(f, " %s", addr->address);
615 if (parent) fprintf(f, " <%s>", parent);
616 if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno));
617 if (addr->message) fprintf(f, ": %s", addr->message);
623 child_close(pid, 0); /* Waits for child to close; no timeout */
628 /*************************************************
629 * Handle SMTP batch error *
630 *************************************************/
632 /* This is called when something goes wrong in batched (-bS) SMTP input.
633 Information is written to stdout and/or stderr, and Exim exits with a non-zero
634 completion code. BSMTP is almost always called by some other program, so it is
635 up to that program to interpret the return code and do something with the error
636 information, and also to preserve the batch input file for human analysis.
638 Formerly, Exim used to attempt to continue after some errors, but this strategy
639 has been abandoned as it can lead to loss of messages.
642 cmd_buffer the command causing the error, or NULL
643 format a printf() format
644 ... arguments for the format
646 Returns: does not return; exits from the program
647 exit code = 1 if some messages were accepted
648 exit code = 2 if no messages were accepted
652 moan_smtp_batch(uschar *cmd_buffer, const char *format, ...)
655 int yield = (receive_messagecount > 0)? 1 : 2;
657 DEBUG(D_any) debug_printf("Handling error in batched SMTP input\n");
659 /* On stdout, write stuff that a program could parse fairly easily. */
661 va_start(ap, format);
662 vfprintf(stdout, format, ap);
665 fprintf(stdout, "\nTransaction started in line %d\n",
666 bsmtp_transaction_linecount);
667 fprintf(stdout, "Error detected in line %d\n", receive_linecount);
668 if (cmd_buffer != NULL) fprintf(stdout, "%s\n", cmd_buffer);
670 /* On stderr, write stuff for human consumption */
673 "An error was detected while processing a file of BSMTP input.\n"
674 "The error message was:\n\n ");
676 va_start(ap, format);
677 vfprintf(stderr, format, ap);
681 "\n\nThe SMTP transaction started in line %d.\n"
682 "The error was detected in line %d.\n",
683 bsmtp_transaction_linecount, receive_linecount);
685 if (cmd_buffer != NULL)
687 fprintf(stderr, "The SMTP command at fault was:\n\n %s\n\n",
691 fprintf(stderr, "%d previous message%s successfully processed.\n",
692 receive_messagecount, (receive_messagecount == 1)? " was" : "s were");
694 fprintf(stderr, "The rest of the batch was abandoned.\n");
702 /*************************************************
703 * Check for error copies *
704 *************************************************/
706 /* This function is passed the recipient of an error message, and must check
707 the error_copies string to see whether there is an additional recipient list to
708 which errors for this recipient must be bcc'd. The incoming recipient is always
711 Argument: recipient address
712 Returns: additional recipient list or NULL
716 moan_check_errorcopy(uschar *recipient)
718 uschar *item, *localpart, *domain;
719 const uschar *listptr = errors_copy;
720 uschar *yield = NULL;
724 if (errors_copy == NULL) return NULL;
726 /* Set up pointer to the local part and domain, and compute the
727 length of the local part. */
729 localpart = recipient;
730 domain = Ustrrchr(recipient, '@');
731 if (domain == NULL) return NULL; /* should not occur, but avoid crash */
732 llen = domain++ - recipient;
734 /* Scan through the configured items */
736 while ((item = string_nextinlist(&listptr, &sep, NULL, 0)))
738 const uschar *newaddress = item;
739 const uschar *pattern = string_dequote(&newaddress);
741 /* If no new address found, just skip this item. */
743 while (isspace(*newaddress)) newaddress++;
744 if (*newaddress == 0) continue;
746 /* We now have an item to match as an address in item, and the additional
747 address in newaddress. If the pattern matches, expand the new address string
748 and return it. During expansion, make local part and domain available for
749 insertion. This requires a copy to be made; we can't just temporarily
750 terminate it, as the whole address is required for $0. */
752 if (match_address_list(recipient, TRUE, TRUE, &pattern, NULL, 0, UCHAR_MAX+1,
755 deliver_localpart = string_copyn(localpart, llen);
756 deliver_domain = domain;
757 yield = expand_string_copy(newaddress);
758 deliver_domain = deliver_localpart = NULL;
760 log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s when processing "
761 "errors_copy: %s", newaddress, expand_string_message);
766 DEBUG(D_any) debug_printf("errors_copy check returned %s\n",
767 (yield == NULL)? US"NULL" : yield);
775 /************************************************
776 * Handle skipped syntax errors *
777 ************************************************/
779 /* This function is called by the redirect router when it has skipped over one
780 or more syntax errors in the list of addresses. If there is an address to mail
781 to, send a message, and always write the information to the log. In the case of
782 a filter file, a "syntax error" might actually be something else, such as the
783 inability to open a log file. Thus, the wording of the error message is
787 rname the router name
788 eblock chain of error blocks
789 syntax_errors_to address to send mail to, or NULL
790 some TRUE if some addresses were generated; FALSE if none were
791 custom custom message text
793 Returns: FALSE if string expansion failed; TRUE otherwise
797 moan_skipped_syntax_errors(uschar *rname, error_block *eblock,
798 uschar *syntax_errors_to, BOOL some, uschar *custom)
804 for (error_block * e = eblock; e; e = e->next)
805 if (e->text2 != NULL)
806 log_write(0, LOG_MAIN, "%s router: skipped error: %s in \"%s\"",
807 rname, e->text1, e->text2);
809 log_write(0, LOG_MAIN, "%s router: skipped error: %s", rname,
812 if (!syntax_errors_to) return TRUE;
814 if (!(s = expand_string(syntax_errors_to)))
816 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
817 syntax_errors_to, expand_string_message);
821 /* If we can't create a process to send the message, just forget about
824 pid = child_open_exim(&fd, US"moan_skipped_syntax_errors");
828 DEBUG(D_any) debug_printf("Failed to create child to send message: %s\n",
833 f = fdopen(fd, "wb");
834 fprintf(f, "Auto-Submitted: auto-replied\n");
836 fprintf(f, "To: %s\n", s);
837 fprintf(f, "Subject: error(s) in forwarding or filtering\n\n");
838 moan_write_references(f, NULL);
842 if (!(t = expand_string(custom)))
844 log_write(0, LOG_MAIN, "%s router failed to expand %s: %s", rname,
845 custom, expand_string_message);
848 fprintf(f, "%s\n\n", t);
851 fprintf(f, "The %s router encountered the following error(s):\n\n",
854 for (error_block * e = eblock; e; e = e->next)
856 fprintf(f, " %s", e->text1);
857 if (e->text2 != NULL)
858 fprintf(f, " in the address\n \"%s\"", e->text2);
863 fprintf(f, "Other addresses were processed normally.\n");
865 fprintf(f, "No valid addresses were generated.\n");
868 child_close(pid, 0); /* Waits for child to close; no timeout */