-/* $Cambridge: exim/src/src/receive.c,v 1.46 2009/06/10 07:34:04 tom Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.55 2010/06/05 11:13:30 pdp Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for receiving a message and setting up spool files. */
header_line *my_headerlist;
uschar *user_msg, *log_msg;
int mime_part_count_buffer = -1;
-int rc;
+int rc = OK;
memset(CS rfc822_file_path,0,2048);
DO_MIME_ACL:
/* make sure the eml mbox file is spooled up */
-mbox_file = spool_mbox(&mbox_size);
+mbox_file = spool_mbox(&mbox_size, NULL);
if (mbox_file == NULL) {
/* error while spooling */
log_write(0, LOG_MAIN|LOG_PANIC,
"acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
Uunlink(spool_name);
unspool_mbox();
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
+#endif
smtp_respond(US"451", 3, TRUE, US"temporary local problem");
message_id[0] = 0; /* Indicate no message accepted */
*smtp_reply_ptr = US""; /* Indicate reply already sent */
{
Uunlink(spool_name);
unspool_mbox();
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
+#endif
if (smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0)
*smtp_yield_ptr = FALSE; /* No more messsages after dropped connection */
*smtp_reply_ptr = US""; /* Indicate reply already sent */
BOOL
receive_msg(BOOL extract_recip)
{
-int i, rc;
+int i;
+int rc = FAIL;
int msg_size = 0;
int process_info_len = Ustrlen(process_info);
int error_rc = (error_handling == ERRORS_SENDER)?
}
}
- /* Add the header line */
+ /* Add the header line
+ * Resent-* headers are prepended, per RFC 5322 3.6.6. Non-Resent-* are
+ * appended, to preserve classical expectations of header ordering. */
- header_add(htype_id, "%sMessage-Id: <%s%s%s@%s>\n", resent_prefix,
- message_id_external, (*id_text == 0)? "" : ".", id_text, id_domain);
+ header_add_at_position(!resents_exist, NULL, FALSE, htype_id,
+ "%sMessage-Id: <%s%s%s@%s>\n", resent_prefix, message_id_external,
+ (*id_text == 0)? "" : ".", id_text, id_domain);
}
/* If we are to log recipients, keep a copy of the raw ones before any possible
/* If there is no date header, generate one if the message originates locally
(i.e. not over TCP/IP) and suppress_local_fixups is not set, or if the
submission mode flag is set. Messages without Date: are not valid, but it seems
-to be more confusing if Exim adds one to all remotely-originated messages. */
+to be more confusing if Exim adds one to all remotely-originated messages.
+As per Message-Id, we prepend if resending, else append.
+*/
if (!date_header_exists &&
((sender_host_address == NULL && !suppress_local_fixups)
|| submission_mode))
- header_add(htype_other, "%sDate: %s\n", resent_prefix, tod_stamp(tod_full));
+ header_add_at_position(!resents_exist, NULL, FALSE, htype_other,
+ "%sDate: %s\n", resent_prefix, tod_stamp(tod_full));
search_tidyup(); /* Free any cached resources */
int sep = 0;
uschar *ptr = dkim_verify_signers_expanded;
uschar *item = NULL;
+ uschar *seen_items = NULL;
+ int seen_items_size = 0;
+ int seen_items_offset = 0;
uschar itembuf[256];
+ /* Default to OK when no items are present */
+ rc = OK;
while ((item = string_nextinlist(&ptr, &sep,
itembuf,
sizeof(itembuf))) != NULL)
{
+ /* Prevent running ACL for an empty item */
+ if (!item || (item[0] == '\0')) continue;
+ /* Only run ACL once for each domain or identity, no matter how often it
+ appears in the expanded list. */
+ if (seen_items != NULL)
+ {
+ uschar *seen_item = NULL;
+ uschar seen_item_buf[256];
+ uschar *seen_items_list = seen_items;
+ int seen_this_item = 0;
+
+ while ((seen_item = string_nextinlist(&seen_items_list, &sep,
+ seen_item_buf,
+ sizeof(seen_item_buf))) != NULL)
+ {
+ if (Ustrcmp(seen_item,item) == 0)
+ {
+ seen_this_item = 1;
+ break;
+ }
+ }
+
+ if (seen_this_item > 0)
+ {
+ DEBUG(D_receive)
+ debug_printf("acl_smtp_dkim: skipping signer %s, already seen\n", item);
+ continue;
+ }
+
+ seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,":");
+ }
+
+ seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,item);
+ seen_items[seen_items_offset] = '\0';
+
+ DEBUG(D_receive)
+ debug_printf("calling acl_smtp_dkim for dkim_cur_signer=%s\n", item);
+
dkim_exim_acl_setup(item);
rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, &user_msg, &log_msg);
- if (rc != OK) break;
+
+ if (rc != OK)
+ {
+ DEBUG(D_receive)
+ debug_printf("acl_smtp_dkim: acl_check returned %d on %s, skipping remaining items\n", rc, item);
+ break;
+ }
}
add_acl_headers(US"DKIM");
if (rc == DISCARD)
Uunlink(spool_name);
#ifdef WITH_CONTENT_SCAN
unspool_mbox();
+#endif
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
#endif
if (smtp_handle_acl_fail(ACL_WHERE_DATA, rc, user_msg, log_msg) != 0)
smtp_yield = FALSE; /* No more messsages after dropped connection */
Uunlink(spool_name);
#ifdef WITH_CONTENT_SCAN
unspool_mbox();
+#endif
+#ifdef EXPERIMENTAL_DCC
+ dcc_ok = 0;
#endif
/* The ACL can specify where rejections are to be logged, possibly
nowhere. The default is main and reject logs. */