static uschar *item_table[] = {
US"acl",
+ US"authresults",
US"certextract",
US"dlfunc",
US"env",
enum {
EITEM_ACL,
+ EITEM_AUTHRESULTS,
EITEM_CERTEXTRACT,
EITEM_DLFUNC,
EITEM_ENV,
{ "address_data", vtype_stringptr, &deliver_address_data },
{ "address_file", vtype_stringptr, &address_file },
{ "address_pipe", vtype_stringptr, &address_pipe },
+#ifdef EXPERIMENTAL_ARC
+ { "arc_state", vtype_stringptr, &arc_state },
+ { "arc_state_reason", vtype_stringptr, &arc_state_reason },
+#endif
{ "authenticated_fail_id",vtype_stringptr, &authenticated_fail_id },
{ "authenticated_id", vtype_stringptr, &authenticated_id },
{ "authenticated_sender",vtype_stringptr, &authenticated_sender },
{ "dkim_verify_status", vtype_stringptr, &dkim_verify_status },
#endif
#ifdef EXPERIMENTAL_DMARC
- { "dmarc_ar_header", vtype_stringptr, &dmarc_ar_header },
{ "dmarc_domain_policy", vtype_stringptr, &dmarc_domain_policy },
{ "dmarc_status", vtype_stringptr, &dmarc_status },
{ "dmarc_status_text", vtype_stringptr, &dmarc_status_text },
{ "local_part_data", vtype_stringptr, &deliver_localpart_data },
{ "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix },
{ "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix },
+#ifdef HAVE_LOCAL_SCAN
{ "local_scan_data", vtype_stringptr, &local_scan_data },
+#endif
{ "local_user_gid", vtype_gid, &local_user_gid },
{ "local_user_uid", vtype_uid, &local_user_uid },
{ "localhost_number", vtype_int, &host_number },
{ "spf_header_comment", vtype_stringptr, &spf_header_comment },
{ "spf_received", vtype_stringptr, &spf_received },
{ "spf_result", vtype_stringptr, &spf_result },
+ { "spf_result_guessed", vtype_bool, &spf_result_guessed },
{ "spf_smtp_comment", vtype_stringptr, &spf_smtp_comment },
#endif
{ "spool_directory", vtype_stringptr, &spool_directory },
+/* Append a "local" element to an Autherntication-Results: header
+if this was a non-smtp message.
+*/
+
+static gstring *
+authres_local(gstring * g, const uschar * sysname)
+{
+if (!authentication_local)
+ return g;
+g = string_append(g, 3, US";\n\tlocal=pass (non-smtp, ", sysname, US")");
+if (authenticated_id) g = string_append(g, 2, " u=", authenticated_id);
+return g;
+}
+
+
+/* Append an "iprev" element to an Autherntication-Results: header
+if we have attempted to get the calling host's name.
+*/
+
+static gstring *
+authres_iprev(gstring * g)
+{
+if (sender_host_name)
+ return string_append(g, sender_host_address ? 5 : 3,
+ US";\n\tiprev=pass (", sender_host_name, US")",
+ US" smtp.client-ip=", sender_host_address);
+if (host_lookup_deferred)
+ return string_catn(g, US";\n\tiprev=temperror", 19);
+if (host_lookup_failed)
+ return string_catn(g, US";\n\tiprev=fail", 13);
+return g;
+}
+
+
+
/*************************************************
* Return list of recipients *
*************************************************/
return var_buffer;
case vtype_host_lookup: /* Lookup if not done so */
- if (sender_host_name == NULL && sender_host_address != NULL &&
- !host_lookup_failed && host_name_lookup() == OK)
+ if ( !sender_host_name && sender_host_address
+ && !host_lookup_failed && host_name_lookup() == OK)
host_build_sender_fullhost();
- return (sender_host_name == NULL)? US"" : sender_host_name;
+ return sender_host_name ? sender_host_name : US"";
case vtype_localpart: /* Get local part from address */
s = *((uschar **)(val));
}
}
+ case EITEM_AUTHRESULTS:
+ /* ${authresults {mysystemname}} */
+ {
+ uschar *sub_arg[1];
+
+ switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name,
+ &resetok))
+ {
+ case 1: goto EXPAND_FAILED_CURLY;
+ case 2:
+ case 3: goto EXPAND_FAILED;
+ }
+
+ yield = string_append(yield, 3,
+ US"Authentication-Results: ", sub_arg[0], US"; none");
+ yield->ptr -= 6;
+
+ yield = authres_local(yield, sub_arg[0]);
+ yield = authres_iprev(yield);
+ yield = authres_smtpauth(yield);
+#ifdef SUPPORT_SPF
+ yield = authres_spf(yield);
+#endif
+#ifndef DISABLE_DKIM
+ yield = authres_dkim(yield);
+#endif
+#ifdef EXPERIMENTAL_DMARC
+ yield = authres_dmarc(yield);
+#endif
+#ifdef EXPERIMENTAL_ARC
+ yield = authres_arc(yield);
+#endif
+ continue;
+ }
+
/* Handle conditionals - preserve the values of the numerical expansion
variables in case they get changed by a regular expression match in the
condition. If not, they retain their external settings. At the end
if (ket_ends && *s == 0)
{
- expand_string_message = malformed_header?
- US"missing } at end of string - could be header name not terminated by colon"
- :
- US"missing } at end of string";
+ expand_string_message = malformed_header
+ ? US"missing } at end of string - could be header name not terminated by colon"
+ : US"missing } at end of string";
goto EXPAND_FAILED;
}
}
+/* Read given named file into big_buffer. Use for keying material etc.
+The content will have an ascii NUL appended.
+
+Arguments:
+ filename as it says
+
+Return: pointer to buffer, or NULL on error.
+*/
+
+uschar *
+expand_file_big_buffer(const uschar * filename)
+{
+int fd, off = 0, len;
+
+if ((fd = open(CS filename, O_RDONLY)) < 0)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "unable to open file for reading: %s",
+ filename);
+ return NULL;
+ }
+
+do
+ {
+ if ((len = read(fd, big_buffer + off, big_buffer_size - 2 - off)) < 0)
+ {
+ (void) close(fd);
+ log_write(0, LOG_MAIN|LOG_PANIC, "unable to read file: %s", filename);
+ return NULL;
+ }
+ off += len;
+ }
+while (len > 0);
+
+(void) close(fd);
+big_buffer[off] = '\0';
+return big_buffer;
+}
+
+
/*************************************************
* Error-checking for testsuite *