user@example.com
.endd
+.new
+.vitem &*${base32:*&<&'digits'&>&*}*&
+.cindex "&%base32%& expansion item"
+.cindex "expansion" "conversion to base 32"
+The string must consist entirely of decimal digits. The number is converted to
+base 32 and output as a (empty, for zero) string of characters.
+Only lowercase letters are used.
+
+.vitem &*${base32d:*&<&'base-32&~digits'&>&*}*&
+.cindex "&%base32d%& expansion item"
+.cindex "expansion" "conversion to base 32"
+The string must consist entirely of base-32 digits.
+The number is converted to decimal and output as a string.
+.wen
+
.vitem &*${base62:*&<&'digits'&>&*}*&
.cindex "&%base62%& expansion item"
.cindex "expansion" "conversion to base 62"
.endd
.next
.cindex "address redirection" "to black hole"
-Sometimes you want to throw away mail to a particular local part. Making the
-&%data%& option expand to an empty string does not work, because that causes
-the router to decline. Instead, the alias item
+.cindex "delivery" "discard"
+.cindex "delivery" "blackhole"
.cindex "black hole"
.cindex "abandoning mail"
-&':blackhole:'& can be used. It does what its name implies. No delivery is
+Sometimes you want to throw away mail to a particular local part. Making the
+&%data%& option expand to an empty string does not work, because that causes
+the router to decline. Instead, the alias item
+.code
+:blackhole:
+.endd
+can be used. It does what its name implies. No delivery is
done, and no error message is generated. This has the same effect as specifying
&_/dev/null_& as a destination, but it can be independently disabled.
Unix and TCP socket specifications may be mixed in any order.
Each element of the list is a list itself, space-separated by default
-and changeable in the usual way.
+and changeable in the usual way; take care to not double the separator.
For TCP socket specifications a host name or IP (v4 or v6, but
subject to list-separator quoting rules) address can be used,
A multiline text table, containing the full SpamAssassin report for the
message. Useful for inclusion in headers or reject messages.
This variable is only usable in a DATA-time ACL.
+.new
+Beware that SpamAssassin may return non-ASCII characters, especially
+when running in country-specific locales, which are not legal
+unencoded in headers.
+.wen
.vitem &$spam_action$&
For SpamAssassin either 'reject' or 'no action' depending on the
timestamp. The flags are:
.display
&`<=`& message arrival
+&`(=`& message fakereject
&`=>`& normal message delivery
&`->`& additional address in same delivery
&`>>`& cutthrough message delivery
.section "Signing outgoing messages" "SECDKIMSIGN"
.cindex "DKIM" "signing"
-Signing is implemented by setting private options on the SMTP transport.
+Signing is enabled by setting private options on the SMTP transport.
These options take (expandable) strings as arguments.
.option dkim_domain smtp string&!! unset
empty is permissible (obviously it should depend only on data available
when the cutthrough connection is made).
+JH/14 Fix logging of errors under PIPELINING. Previously the log line giving
+ the relevant preceding SMTP command did not note the pipelining mode.
+
+JH/15 Fix counting of empty lines in $body_linecount and $message_linecount.
+ Previously they were not counted.
+
+JH/16 DANE: treat a TLSA lookup response having all non-TLSA RRs, the same
+ as one having no matching records. Previously we deferred the message
+ that needed the lookup.
+
+JH/17 Fakereject: previously logged as a norml message arrival "<="; now
+ distinguished as "(=".
+
Exim version 4.87
-----------------
the queue to be used for a message. A $queue_name variable gives
visibility.
- 6. The CHUNKING ESMTP extension from RFC 3030. May give some slight
+ 6. New expansion operators base32/base32d.
+
+ 7. The CHUNKING ESMTP extension from RFC 3030. May give some slight
performance increase and network load decrease. Main config option
chunking_advertise_hosts, and smtp transport option hosts_try_chunking
for control.
+/******************************************************************************/
+
+
+/*************************************************
+* Generate local prt for logging *
+*************************************************/
+
+/* This function is a subroutine for use in string_log_address() below.
+
+Arguments:
+ addr the address being logged
+ yield the current dynamic buffer pointer
+ sizeptr points to current size
+ ptrptr points to current insert pointer
+
+Returns: the new value of the buffer pointer
+*/
+
+static uschar *
+string_get_localpart(address_item *addr, uschar *yield, int *sizeptr,
+ int *ptrptr)
+{
+uschar * s;
+
+s = addr->prefix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s);
+ }
+
+s = addr->local_part;
+#ifdef SUPPORT_I18N
+if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+yield = string_cat(yield, sizeptr, ptrptr, s);
+
+s = addr->suffix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s);
+ }
+
+return yield;
+}
+
+
+/*************************************************
+* Generate log address list *
+*************************************************/
+
+/* This function generates a list consisting of an address and its parents, for
+use in logging lines. For saved onetime aliased addresses, the onetime parent
+field is used. If the address was delivered by a transport with rcpt_include_
+affixes set, the af_include_affixes bit will be set in the address. In that
+case, we include the affixes here too.
+
+Arguments:
+ str points to start of growing string, or NULL
+ size points to current allocation for string
+ ptr points to offset for append point; updated on exit
+ addr bottom (ultimate) address
+ all_parents if TRUE, include all parents
+ success TRUE for successful delivery
+
+Returns: a growable string in dynamic store
+*/
+
+static uschar *
+string_log_address(uschar * str, int * size, int * ptr,
+ address_item *addr, BOOL all_parents, BOOL success)
+{
+BOOL add_topaddr = TRUE;
+address_item *topaddr;
+
+/* Find the ultimate parent */
+
+for (topaddr = addr; topaddr->parent; topaddr = topaddr->parent) ;
+
+/* We start with just the local part for pipe, file, and reply deliveries, and
+for successful local deliveries from routers that have the log_as_local flag
+set. File deliveries from filters can be specified as non-absolute paths in
+cases where the transport is goin to complete the path. If there is an error
+before this happens (expansion failure) the local part will not be updated, and
+so won't necessarily look like a path. Add extra text for this case. */
+
+if ( testflag(addr, af_pfr)
+ || ( success
+ && addr->router && addr->router->log_as_local
+ && addr->transport && addr->transport->info->local
+ ) )
+ {
+ if (testflag(addr, af_file) && addr->local_part[0] != '/')
+ str = string_catn(str, size, ptr, CUS"save ", 5);
+ str = string_get_localpart(addr, str, size, ptr);
+ }
+
+/* Other deliveries start with the full address. It we have split it into local
+part and domain, use those fields. Some early failures can happen before the
+splitting is done; in those cases use the original field. */
+
+else
+ {
+ uschar * cmp = str + *ptr;
+
+ if (addr->local_part)
+ {
+ const uschar * s;
+ str = string_get_localpart(addr, str, size, ptr);
+ str = string_catn(str, size, ptr, US"@", 1);
+ s = addr->domain;
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ str = string_cat(str, size, ptr, s);
+ }
+ else
+ str = string_cat(str, size, ptr, addr->address);
+
+ /* If the address we are going to print is the same as the top address,
+ and all parents are not being included, don't add on the top address. First
+ of all, do a caseless comparison; if this succeeds, do a caseful comparison
+ on the local parts. */
+
+ str[*ptr] = 0;
+ if ( strcmpic(cmp, topaddr->address) == 0
+ && Ustrncmp(cmp, topaddr->address, Ustrchr(cmp, '@') - cmp) == 0
+ && !addr->onetime_parent
+ && (!all_parents || !addr->parent || addr->parent == topaddr)
+ )
+ add_topaddr = FALSE;
+ }
+
+/* If all parents are requested, or this is a local pipe/file/reply, and
+there is at least one intermediate parent, show it in brackets, and continue
+with all of them if all are wanted. */
+
+if ( (all_parents || testflag(addr, af_pfr))
+ && addr->parent
+ && addr->parent != topaddr)
+ {
+ uschar *s = US" (";
+ address_item *addr2;
+ for (addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent)
+ {
+ str = string_catn(str, size, ptr, s, 2);
+ str = string_cat (str, size, ptr, addr2->address);
+ if (!all_parents) break;
+ s = US", ";
+ }
+ str = string_catn(str, size, ptr, US")", 1);
+ }
+
+/* Add the top address if it is required */
+
+if (add_topaddr)
+ str = string_append(str, size, ptr, 3,
+ US" <",
+ addr->onetime_parent ? addr->onetime_parent : topaddr->address,
+ US">");
+
+return str;
+}
+
+
+/******************************************************************************/
+
+
+
/* If msg is NULL this is a delivery log and logchar is used. Otherwise
this is a nonstandard call; no two-character delivery flag is written
but sender-host and sender are prefixed and "msg" is inserted in the log line.
void
delivery_log(int flags, address_item * addr, int logchar, uschar * msg)
{
-uschar *log_address;
int size = 256; /* Used for a temporary, */
int ptr = 0; /* expanding buffer, for */
-uschar *s; /* building log lines; */
-void *reset_point; /* released afterwards. */
+uschar * s; /* building log lines; */
+void * reset_point; /* released afterwards. */
/* Log the delivery on the main log. We use an extensible string to build up
the log line, and reset the store afterwards. Remote deliveries should always
s = reset_point = store_get(size);
-log_address = string_log_address(addr, LOGGING(all_parents), TRUE);
if (msg)
- s = string_append(s, &size, &ptr, 3, host_and_ident(TRUE), US" ", log_address);
+ s = string_append(s, &size, &ptr, 2, host_and_ident(TRUE), US" ");
else
{
s[ptr++] = logchar;
- s = string_append(s, &size, &ptr, 2, US"> ", log_address);
+ s = string_catn(s, &size, &ptr, US"> ", 2);
}
+s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), TRUE);
if (LOGGING(sender_on_delivery) || msg)
s = string_append(s, &size, &ptr, 3, US" F=<",
+static void
+deferral_log(address_item * addr, uschar * now,
+ int logflags, uschar * driver_name, uschar * driver_kind)
+{
+int size = 256; /* Used for a temporary, */
+int ptr = 0; /* expanding buffer, for */
+uschar * s; /* building log lines; */
+void * reset_point; /* released afterwards. */
+
+uschar ss[32];
+
+/* Build up the line that is used for both the message log and the main
+log. */
+
+s = reset_point = store_get(size);
+
+/* Create the address string for logging. Must not do this earlier, because
+an OK result may be changed to FAIL when a pipe returns text. */
+
+s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), FALSE);
+
+if (*queue_name)
+ s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
+
+/* Either driver_name contains something and driver_kind contains
+" router" or " transport" (note the leading space), or driver_name is
+a null string and driver_kind contains "routing" without the leading
+space, if all routing has been deferred. When a domain has been held,
+so nothing has been done at all, both variables contain null strings. */
+
+if (driver_name)
+ {
+ if (driver_kind[1] == 't' && addr->router)
+ s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
+ Ustrcpy(ss, " ?=");
+ ss[1] = toupper(driver_kind[1]);
+ s = string_append(s, &size, &ptr, 2, ss, driver_name);
+ }
+else if (driver_kind)
+ s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
+
+/*XXX need an s+s+p sprintf */
+sprintf(CS ss, " defer (%d)", addr->basic_errno);
+s = string_cat(s, &size, &ptr, ss);
+
+if (addr->basic_errno > 0)
+ s = string_append(s, &size, &ptr, 2, US": ",
+ US strerror(addr->basic_errno));
+
+if (addr->host_used)
+ {
+ s = string_append(s, &size, &ptr, 5,
+ US" H=", addr->host_used->name,
+ US" [", addr->host_used->address, US"]");
+ if (LOGGING(outgoing_port))
+ {
+ int port = addr->host_used->port;
+ s = string_append(s, &size, &ptr, 2,
+ US":", port == PORT_NONE ? US"25" : string_sprintf("%d", port));
+ }
+ }
+
+if (addr->message)
+ s = string_append(s, &size, &ptr, 2, US": ", addr->message);
+
+s[ptr] = 0;
+
+/* Log the deferment in the message log, but don't clutter it
+up with retry-time defers after the first delivery attempt. */
+
+if (deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE)
+ deliver_msglog("%s %s\n", now, s);
+
+/* Write the main log and reset the store.
+For errors of the type "retry time not reached" (also remotes skipped
+on queue run), logging is controlled by L_retry_defer. Note that this kind
+of error number is negative, and all the retry ones are less than any
+others. */
+
+
+log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags,
+ "== %s", s);
+
+store_reset(reset_point);
+return;
+}
+
+
+
+static void
+failure_log(address_item * addr, uschar * driver_kind, uschar * now)
+{
+int size = 256; /* Used for a temporary, */
+int ptr = 0; /* expanding buffer, for */
+uschar * s; /* building log lines; */
+void * reset_point; /* released afterwards. */
+
+/* Build up the log line for the message and main logs */
+
+s = reset_point = store_get(size);
+
+/* Create the address string for logging. Must not do this earlier, because
+an OK result may be changed to FAIL when a pipe returns text. */
+
+s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), FALSE);
+
+if (LOGGING(sender_on_delivery))
+ s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
+
+if (*queue_name)
+ s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
+
+/* Return path may not be set if no delivery actually happened */
+
+if (used_return_path && LOGGING(return_path_on_delivery))
+ s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
+
+if (addr->router)
+ s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
+if (addr->transport)
+ s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name);
+
+if (addr->host_used)
+ s = d_hostlog(s, &size, &ptr, addr);
+
+#ifdef SUPPORT_TLS
+s = d_tlslog(s, &size, &ptr, addr);
+#endif
+
+if (addr->basic_errno > 0)
+ s = string_append(s, &size, &ptr, 2, US": ", US strerror(addr->basic_errno));
+
+if (addr->message)
+ s = string_append(s, &size, &ptr, 2, US": ", addr->message);
+
+s[ptr] = 0;
+
+/* Do the logging. For the message log, "routing failed" for those cases,
+just to make it clearer. */
+
+if (driver_kind)
+ deliver_msglog("%s %s failed for %s\n", now, driver_kind, s);
+else
+ deliver_msglog("%s %s\n", now, s);
+
+log_write(0, LOG_MAIN, "** %s", s);
+
+#ifndef DISABLE_EVENT
+msg_event_raise(US"msg:fail:delivery", addr);
+#endif
+
+store_reset(reset_point);
+return;
+}
+
+
+
/*************************************************
* Actions at the end of handling an address *
*************************************************/
uschar *now = tod_stamp(tod_log);
uschar *driver_kind = NULL;
uschar *driver_name = NULL;
-uschar *log_address;
-
-int size = 256; /* Used for a temporary, */
-int ptr = 0; /* expanding buffer, for */
-uschar *s; /* building log lines; */
-void *reset_point; /* released afterwards. */
DEBUG(D_deliver) debug_printf("post-process %s (%d)\n", addr->address, result);
log or the main log for SMTP defers. */
if (!queue_2stage || addr->basic_errno != 0)
- {
- uschar ss[32];
-
- /* For errors of the type "retry time not reached" (also remotes skipped
- on queue run), logging is controlled by L_retry_defer. Note that this kind
- of error number is negative, and all the retry ones are less than any
- others. */
-
- unsigned int use_log_selector = addr->basic_errno <= ERRNO_RETRY_BASE
- ? L_retry_defer : 0;
-
- /* Build up the line that is used for both the message log and the main
- log. */
-
- s = reset_point = store_get(size);
-
- /* Create the address string for logging. Must not do this earlier, because
- an OK result may be changed to FAIL when a pipe returns text. */
-
- log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
-
- s = string_cat(s, &size, &ptr, log_address);
-
- if (*queue_name)
- s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
-
- /* Either driver_name contains something and driver_kind contains
- " router" or " transport" (note the leading space), or driver_name is
- a null string and driver_kind contains "routing" without the leading
- space, if all routing has been deferred. When a domain has been held,
- so nothing has been done at all, both variables contain null strings. */
-
- if (driver_name)
- {
- if (driver_kind[1] == 't' && addr->router)
- s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
- Ustrcpy(ss, " ?=");
- ss[1] = toupper(driver_kind[1]);
- s = string_append(s, &size, &ptr, 2, ss, driver_name);
- }
- else if (driver_kind)
- s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
-
- sprintf(CS ss, " defer (%d)", addr->basic_errno);
- s = string_cat(s, &size, &ptr, ss);
-
- if (addr->basic_errno > 0)
- s = string_append(s, &size, &ptr, 2, US": ",
- US strerror(addr->basic_errno));
-
- if (addr->host_used)
- {
- s = string_append(s, &size, &ptr, 5,
- US" H=", addr->host_used->name,
- US" [", addr->host_used->address, US"]");
- if (LOGGING(outgoing_port))
- {
- int port = addr->host_used->port;
- s = string_append(s, &size, &ptr, 2,
- US":", port == PORT_NONE ? US"25" : string_sprintf("%d", port));
- }
- }
-
- if (addr->message)
- s = string_append(s, &size, &ptr, 2, US": ", addr->message);
-
- s[ptr] = 0;
-
- /* Log the deferment in the message log, but don't clutter it
- up with retry-time defers after the first delivery attempt. */
-
- if (deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE)
- deliver_msglog("%s %s\n", now, s);
-
- /* Write the main log and reset the store */
-
- log_write(use_log_selector, logflags, "== %s", s);
- store_reset(reset_point);
- }
+ deferral_log(addr, now, logflags, driver_name, driver_kind);
}
addr_failed = addr;
}
- /* Build up the log line for the message and main logs */
-
- s = reset_point = store_get(size);
-
- /* Create the address string for logging. Must not do this earlier, because
- an OK result may be changed to FAIL when a pipe returns text. */
-
- log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
-
- s = string_cat(s, &size, &ptr, log_address);
-
- if (LOGGING(sender_on_delivery))
- s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
-
- if (*queue_name)
- s = string_append(s, &size, &ptr, 2, US" Q=", queue_name);
-
- /* Return path may not be set if no delivery actually happened */
-
- if (used_return_path && LOGGING(return_path_on_delivery))
- s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
-
- if (addr->router)
- s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
- if (addr->transport)
- s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name);
-
- if (addr->host_used)
- s = d_hostlog(s, &size, &ptr, addr);
-
-#ifdef SUPPORT_TLS
- s = d_tlslog(s, &size, &ptr, addr);
-#endif
-
- if (addr->basic_errno > 0)
- s = string_append(s, &size, &ptr, 2, US": ",
- US strerror(addr->basic_errno));
-
- if (addr->message)
- s = string_append(s, &size, &ptr, 2, US": ", addr->message);
-
- s[ptr] = 0;
-
- /* Do the logging. For the message log, "routing failed" for those cases,
- just to make it clearer. */
-
- if (driver_name)
- deliver_msglog("%s %s\n", now, s);
- else
- deliver_msglog("%s %s failed for %s\n", now, driver_kind, s);
-
- log_write(0, LOG_MAIN, "** %s", s);
-
-#ifndef DISABLE_EVENT
- msg_event_raise(US"msg:fail:delivery", addr);
-#endif
-
- store_reset(reset_point);
+ failure_log(addr, driver_name ? NULL : driver_kind, now);
}
/* Ensure logging is turned on again in all cases */
lookup_dnssec_authenticated = NULL;
if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
- return PDKIM_FAIL;
+ return PDKIM_FAIL; /*XXX better error detail? logging? */
/* Search for TXT record */
rr_offset += len;
answer_offset += len;
if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN)
- return PDKIM_FAIL;
+ return PDKIM_FAIL; /*XXX better error detail? logging? */
}
return PDKIM_OK;
}
-return PDKIM_FAIL;
+return PDKIM_FAIL; /*XXX better error detail? logging? */
}
void
dkim_exim_verify_feed(uschar * data, int len)
{
+int rc;
+
store_pool = POOL_PERM;
if ( dkim_collect_input
- && pdkim_feed(dkim_verify_ctx, (char *)data, len) != PDKIM_OK)
+ && (rc = pdkim_feed(dkim_verify_ctx, (char *)data, len)) != PDKIM_OK)
+ {
+ log_write(0, LOG_MAIN,
+ "DKIM: validation error: %.100s", pdkim_errstr(rc));
dkim_collect_input = FALSE;
+ }
store_pool = dkim_verify_oldpool;
}
int dkim_signers_size = 0;
int dkim_signers_ptr = 0;
dkim_signers = NULL;
+int rc;
store_pool = POOL_PERM;
/* Finish DKIM operation and fetch link to signatures chain */
-if (pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures) != PDKIM_OK)
+if ((rc = pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures)) != PDKIM_OK)
+ {
+ log_write(0, LOG_MAIN,
+ "DKIM: validation error: %.100s", pdkim_errstr(rc));
goto out;
+ }
for (sig = dkim_signatures; sig; sig = sig->next)
{
/* expansion error, do not send message. */
log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
"dkim_domain: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
/* Set $dkim_domain expansion variable to each unique domain in list. */
{
log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
"dkim_selector: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
/* Get canonicalization to use */
/* expansion error, do not send message. */
log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
"dkim_canon: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
if (Ustrcmp(dkim_canon_expanded, "relaxed") == 0)
{
log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
"dkim_sign_headers: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
/* else pass NULL, which means default header list */
{
log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
"dkim_private_key: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
if ( Ustrlen(dkim_private_key_expanded) == 0
log_write(0, LOG_MAIN | LOG_PANIC, "unable to open "
"private key file for reading: %s",
dkim_private_key_expanded);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
if (read(privkey_fd, big_buffer, big_buffer_size - 2) < 0)
{
log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s",
dkim_private_key_expanded);
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
(void) close(privkey_fd);
dkim_private_key_expanded = big_buffer;
}
- ctx = pdkim_init_sign( (char *) dkim_signing_domain,
- (char *) dkim_signing_selector,
- (char *) dkim_private_key_expanded,
+ ctx = pdkim_init_sign( CS dkim_signing_domain,
+ CS dkim_signing_selector,
+ CS dkim_private_key_expanded,
PDKIM_ALGO_RSA_SHA256);
pdkim_set_optional(ctx,
(char *) dkim_sign_headers_expanded,
lseek(dkim_fd, 0, SEEK_SET);
while ((sread = read(dkim_fd, &buf, 4096)) > 0)
- if (pdkim_feed(ctx, buf, sread) != PDKIM_OK)
- {
- rc = NULL;
- goto CLEANUP;
- }
+ if ((pdkim_rc = pdkim_feed(ctx, buf, sread)) != PDKIM_OK)
+ goto pk_bad;
/* Handle failed read above. */
if (sread == -1)
{
debug_printf("DKIM: Error reading -K file.\n");
save_errno = errno;
- rc = NULL;
- goto CLEANUP;
+ goto bad;
}
if ((pdkim_rc = pdkim_feed_finish(ctx, &signature)) != PDKIM_OK)
- {
- log_write(0, LOG_MAIN|LOG_PANIC, "DKIM: signing failed (RC %d)", pdkim_rc);
- rc = NULL;
- goto CLEANUP;
- }
+ goto pk_bad;
sigbuf = string_append(sigbuf, &sigsize, &sigptr, 2,
US signature->signature_header, US"\r\n");
rc = US"";
CLEANUP:
-if (ctx)
- pdkim_free_ctx(ctx);
-store_pool = old_pool;
-errno = save_errno;
-return rc;
+ if (ctx)
+ pdkim_free_ctx(ctx);
+ store_pool = old_pool;
+ errno = save_errno;
+ return rc;
+
+pk_bad:
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "DKIM: signing failed: %.100s", pdkim_errstr(pdkim_rc));
+bad:
+ rc = NULL;
+ goto CLEANUP;
}
#endif
static uschar *op_table_main[] = {
US"address",
US"addresses",
+ US"base32",
+ US"base32d",
US"base62",
US"base62d",
US"base64",
enum {
EOP_ADDRESS = nelem(op_table_underscore),
EOP_ADDRESSES,
+ EOP_BASE32,
+ EOP_BASE32D,
EOP_BASE62,
EOP_BASE62D,
EOP_BASE64,
}
+
+static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567";
+
/*************************************************
* Binary chop search on a table *
*************************************************/
if (next_s == NULL) goto EXPAND_FAILED; /* message already set */
DEBUG(D_expand)
- debug_printf("condition: %.*s\n result: %s\n", (int)(next_s - s), s,
- cond? "true" : "false");
+ debug_printf(" condition: %.*s\n result: %s\n",
+ (int)(next_s - s), s,
+ cond ? "true" : "false");
s = next_s;
case 3: goto EXPAND_FAILED;
}
- if (Ustrcmp(sub[0], "md5") == 0)
- {
- type = HMAC_MD5;
- use_base = &md5_base;
- hashlen = 16;
- hashblocklen = 64;
- }
- else if (Ustrcmp(sub[0], "sha1") == 0)
- {
- type = HMAC_SHA1;
- use_base = &sha1_ctx;
- hashlen = 20;
- hashblocklen = 64;
- }
- else
- {
- expand_string_message =
- string_sprintf("hmac algorithm \"%s\" is not recognised", sub[0]);
- goto EXPAND_FAILED;
- }
+ if (!skipping)
+ {
+ if (Ustrcmp(sub[0], "md5") == 0)
+ {
+ type = HMAC_MD5;
+ use_base = &md5_base;
+ hashlen = 16;
+ hashblocklen = 64;
+ }
+ else if (Ustrcmp(sub[0], "sha1") == 0)
+ {
+ type = HMAC_SHA1;
+ use_base = &sha1_ctx;
+ hashlen = 20;
+ hashblocklen = 64;
+ }
+ else
+ {
+ expand_string_message =
+ string_sprintf("hmac algorithm \"%s\" is not recognised", sub[0]);
+ goto EXPAND_FAILED;
+ }
- keyptr = sub[1];
- keylen = Ustrlen(keyptr);
+ keyptr = sub[1];
+ keylen = Ustrlen(keyptr);
- /* If the key is longer than the hash block length, then hash the key
- first */
+ /* If the key is longer than the hash block length, then hash the key
+ first */
- if (keylen > hashblocklen)
- {
- chash_start(type, use_base);
- chash_end(type, use_base, keyptr, keylen, keyhash);
- keyptr = keyhash;
- keylen = hashlen;
- }
+ if (keylen > hashblocklen)
+ {
+ chash_start(type, use_base);
+ chash_end(type, use_base, keyptr, keylen, keyhash);
+ keyptr = keyhash;
+ keylen = hashlen;
+ }
- /* Now make the inner and outer key values */
+ /* Now make the inner and outer key values */
- memset(innerkey, 0x36, hashblocklen);
- memset(outerkey, 0x5c, hashblocklen);
+ memset(innerkey, 0x36, hashblocklen);
+ memset(outerkey, 0x5c, hashblocklen);
- for (i = 0; i < keylen; i++)
- {
- innerkey[i] ^= keyptr[i];
- outerkey[i] ^= keyptr[i];
- }
+ for (i = 0; i < keylen; i++)
+ {
+ innerkey[i] ^= keyptr[i];
+ outerkey[i] ^= keyptr[i];
+ }
- /* Now do the hashes */
+ /* Now do the hashes */
- chash_start(type, use_base);
- chash_mid(type, use_base, innerkey);
- chash_end(type, use_base, sub[2], Ustrlen(sub[2]), innerhash);
+ chash_start(type, use_base);
+ chash_mid(type, use_base, innerkey);
+ chash_end(type, use_base, sub[2], Ustrlen(sub[2]), innerhash);
- chash_start(type, use_base);
- chash_mid(type, use_base, outerkey);
- chash_end(type, use_base, innerhash, hashlen, finalhash);
+ chash_start(type, use_base);
+ chash_mid(type, use_base, outerkey);
+ chash_end(type, use_base, innerhash, hashlen, finalhash);
- /* Encode the final hash as a hex string */
+ /* Encode the final hash as a hex string */
- p = finalhash_hex;
- for (i = 0; i < hashlen; i++)
- {
- *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
- *p++ = hex_digits[finalhash[i] & 0x0f];
- }
+ p = finalhash_hex;
+ for (i = 0; i < hashlen; i++)
+ {
+ *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
+ *p++ = hex_digits[finalhash[i] & 0x0f];
+ }
- DEBUG(D_any) debug_printf("HMAC[%s](%.*s,%.*s)=%.*s\n", sub[0],
- (int)keylen, keyptr, Ustrlen(sub[2]), sub[2], hashlen*2, finalhash_hex);
+ DEBUG(D_any) debug_printf("HMAC[%s](%.*s,%s)=%.*s\n",
+ sub[0], (int)keylen, keyptr, sub[2], hashlen*2, finalhash_hex);
- yield = string_catn(yield, &size, &ptr, finalhash_hex, hashlen*2);
+ yield = string_catn(yield, &size, &ptr, finalhash_hex, hashlen*2);
+ }
+ continue;
}
- continue;
-
/* Handle global substitution for "sg" - like Perl's s/xxx/yyy/g operator.
We have to save the numerical variables and restore them afterwards. */
switch(c)
{
+ case EOP_BASE32:
+ {
+ uschar *t;
+ unsigned long int n = Ustrtoul(sub, &t, 10);
+ uschar * s = NULL;
+ int sz = 0, i = 0;
+
+ if (*t != 0)
+ {
+ expand_string_message = string_sprintf("argument for base32 "
+ "operator is \"%s\", which is not a decimal number", sub);
+ goto EXPAND_FAILED;
+ }
+ for ( ; n; n >>= 5)
+ s = string_catn(s, &sz, &i, &base32_chars[n & 0x1f], 1);
+
+ while (i > 0) yield = string_catn(yield, &size, &ptr, &s[--i], 1);
+ continue;
+ }
+
+ case EOP_BASE32D:
+ {
+ uschar *tt = sub;
+ unsigned long int n = 0;
+ uschar * s;
+ while (*tt)
+ {
+ uschar * t = Ustrchr(base32_chars, *tt++);
+ if (t == NULL)
+ {
+ expand_string_message = string_sprintf("argument for base32d "
+ "operator is \"%s\", which is not a base 32 number", sub);
+ goto EXPAND_FAILED;
+ }
+ n = n * 32 + (t - base32_chars);
+ }
+ s = string_sprintf("%ld", n);
+ yield = string_cat(yield, &size, &ptr, s);
+ continue;
+ }
+
case EOP_BASE62:
{
uschar *t;
#ifdef SUPPORT_I18N
extern BOOL string_is_utf8(const uschar *);
#endif
-extern uschar *string_log_address(address_item *, BOOL, BOOL);
extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3);
extern const uschar *string_printing2(const uschar *, BOOL);
const char *
pdkim_verify_status_str(int status)
{
- switch(status) {
- case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
- case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
- case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
- case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
- default: return "PDKIM_VERIFY_UNKNOWN";
+switch(status)
+ {
+ case PDKIM_VERIFY_NONE: return "PDKIM_VERIFY_NONE";
+ case PDKIM_VERIFY_INVALID: return "PDKIM_VERIFY_INVALID";
+ case PDKIM_VERIFY_FAIL: return "PDKIM_VERIFY_FAIL";
+ case PDKIM_VERIFY_PASS: return "PDKIM_VERIFY_PASS";
+ default: return "PDKIM_VERIFY_UNKNOWN";
}
}
const char *
pdkim_verify_ext_status_str(int ext_status)
{
- switch(ext_status) {
- case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
- case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
- case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
- case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
- case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
- case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
- case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
- case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
- default: return "PDKIM_VERIFY_UNKNOWN";
+switch(ext_status)
+ {
+ case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
+ case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
+ case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
+ case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
+ case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
+ case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT";
+ case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR";
+ case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION";
+ default: return "PDKIM_VERIFY_UNKNOWN";
+ }
+}
+
+const char *
+pdkim_errstr(int status)
+{
+switch(status)
+ {
+ case PDKIM_OK: return "OK";
+ case PDKIM_FAIL: return "FAIL";
+ case PDKIM_ERR_RSA_PRIVKEY: return "RSA_PRIVKEY";
+ case PDKIM_ERR_RSA_SIGNING: return "RSA SIGNING";
+ case PDKIM_ERR_LONG_LINE: return "RSA_LONG_LINE";
+ case PDKIM_ERR_BUFFER_TOO_SMALL: return "BUFFER_TOO_SMALL";
+ case PDKIM_SIGN_PRIVKEY_WRAP: return "PRIVKEY_WRAP";
+ case PDKIM_SIGN_PRIVKEY_B64D: return "PRIVKEY_B64D";
+ default: return "(unknown)";
}
}
DLLEXPORT
void pdkim_free_ctx (pdkim_ctx *);
+
+const char * pdkim_errstr(int);
+
#ifdef __cplusplus
}
#endif
sptr = 0;
s = store_get(size);
-s = string_append(s, &size, &sptr, 2, US"<= ",
- (sender_address[0] == 0)? US"<>" : sender_address);
-if (message_reference != NULL)
+s = string_append(s, &size, &sptr, 2,
+ fake_response == FAIL ? US"(= " : US"<= ",
+ sender_address[0] == 0 ? US"<>" : sender_address);
+if (message_reference)
s = string_append(s, &size, &sptr, 2, US" R=", message_reference);
s = add_host_info_for_log(s, &size, &sptr);
s = string_append(s, &size, &sptr, 2, US" X=", tls_in.cipher);
if (LOGGING(tls_certificate_verified) && tls_in.cipher)
s = string_append(s, &size, &sptr, 2, US" CV=",
- tls_in.certificate_verified? "yes":"no");
+ tls_in.certificate_verified ? "yes":"no");
if (LOGGING(tls_peerdn) && tls_in.peerdn)
s = string_append(s, &size, &sptr, 3, US" DN=\"",
string_printing(tls_in.peerdn), US"\"");
if (sender_host_authenticated)
{
s = string_append(s, &size, &sptr, 2, US" A=", sender_host_authenticated);
- if (authenticated_id != NULL)
+ if (authenticated_id)
{
s = string_append(s, &size, &sptr, 2, US":", authenticated_id);
- if (LOGGING(smtp_mailauth) && authenticated_sender != NULL)
+ if (LOGGING(smtp_mailauth) && authenticated_sender)
s = string_append(s, &size, &sptr, 2, US":", authenticated_sender);
}
}
Therefore, make sure we use a printing-characters only version for the log.
Also, allow for domain literals in the message id. */
-if (msgid_header != NULL)
+if (msgid_header)
{
uschar *old_id;
BOOL save_allow_domain_literals = allow_domain_literals;
if (deliver_freeze) fprintf(message_log, "%s frozen by %s\n", now,
frozen_by);
if (queue_only_policy) fprintf(message_log,
- "%s no immediate delivery: queued by %s\n", now, queued_by);
+ "%s no immediate delivery: queued%s%s by %s\n", now,
+ *queue_name ? " in " : "", *queue_name ? CS queue_name : "",
+ queued_by);
(void)fclose(message_log);
}
}
if (deliver_freeze) log_write(0, LOG_MAIN, "frozen by %s", frozen_by);
if (queue_only_policy) log_write(L_delay_delivery, LOG_MAIN,
- "no immediate delivery: queued by %s", queued_by);
+ "no immediate delivery: queued%s%s by %s",
+ *queue_name ? " in " : "", *queue_name ? CS queue_name : "",
+ queued_by);
}
receive_call_bombout = FALSE;
if (!smtp_batched_input)
{
- if (smtp_reply == NULL)
+ if (!smtp_reply)
{
if (fake_response != OK)
- smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE,
- fake_response_text);
+ smtp_respond(fake_response == DEFER ? US"450" : US"550",
+ 3, TRUE, fake_response_text);
/* An OK response is required; use "message" text if present. */
- else if (user_msg != NULL)
+ else if (user_msg)
{
uschar *code = US"250";
int len = 3;
nothing on success. The function moan_smtp_batch() does not return -
it exits from the program with a non-zero return code. */
- else if (smtp_reply != NULL) moan_smtp_batch(NULL, "%s", smtp_reply);
+ else if (smtp_reply)
+ moan_smtp_batch(NULL, "%s", smtp_reply);
}
We must now indicate that nothing was received, to prevent a delivery from
starting. */
-if (blackholed_by != NULL)
+if (blackholed_by)
{
const uschar *detail = local_scan_data
? string_printing(local_scan_data)
-#ifndef COMPILE_UTILITY
-/*************************************************
-* Generate local prt for logging *
-*************************************************/
-
-/* This function is a subroutine for use in string_log_address() below.
-
-Arguments:
- addr the address being logged
- yield the current dynamic buffer pointer
- sizeptr points to current size
- ptrptr points to current insert pointer
-
-Returns: the new value of the buffer pointer
-*/
-
-static uschar *
-string_get_localpart(address_item *addr, uschar *yield, int *sizeptr,
- int *ptrptr)
-{
-uschar * s;
-
-s = addr->prefix;
-if (testflag(addr, af_include_affixes) && s)
- {
-#ifdef SUPPORT_I18N
- if (testflag(addr, af_utf8_downcvt))
- s = string_localpart_utf8_to_alabel(s, NULL);
-#endif
- yield = string_cat(yield, sizeptr, ptrptr, s);
- }
-
-s = addr->local_part;
-#ifdef SUPPORT_I18N
-if (testflag(addr, af_utf8_downcvt))
- s = string_localpart_utf8_to_alabel(s, NULL);
-#endif
-yield = string_cat(yield, sizeptr, ptrptr, s);
-
-s = addr->suffix;
-if (testflag(addr, af_include_affixes) && s)
- {
-#ifdef SUPPORT_I18N
- if (testflag(addr, af_utf8_downcvt))
- s = string_localpart_utf8_to_alabel(s, NULL);
-#endif
- yield = string_cat(yield, sizeptr, ptrptr, s);
- }
-
-return yield;
-}
-
-
-/*************************************************
-* Generate log address list *
-*************************************************/
-
-/* This function generates a list consisting of an address and its parents, for
-use in logging lines. For saved onetime aliased addresses, the onetime parent
-field is used. If the address was delivered by a transport with rcpt_include_
-affixes set, the af_include_affixes bit will be set in the address. In that
-case, we include the affixes here too.
-
-Arguments:
- addr bottom (ultimate) address
- all_parents if TRUE, include all parents
- success TRUE for successful delivery
-
-Returns: a string in dynamic store
-*/
-
-uschar *
-string_log_address(address_item *addr, BOOL all_parents, BOOL success)
-{
-int size = 64;
-int ptr = 0;
-BOOL add_topaddr = TRUE;
-uschar *yield = store_get(size);
-address_item *topaddr;
-
-/* Find the ultimate parent */
-
-for (topaddr = addr; topaddr->parent != NULL; topaddr = topaddr->parent);
-
-/* We start with just the local part for pipe, file, and reply deliveries, and
-for successful local deliveries from routers that have the log_as_local flag
-set. File deliveries from filters can be specified as non-absolute paths in
-cases where the transport is goin to complete the path. If there is an error
-before this happens (expansion failure) the local part will not be updated, and
-so won't necessarily look like a path. Add extra text for this case. */
-
-if (testflag(addr, af_pfr) ||
- (success &&
- addr->router != NULL && addr->router->log_as_local &&
- addr->transport != NULL && addr->transport->info->local))
- {
- if (testflag(addr, af_file) && addr->local_part[0] != '/')
- yield = string_catn(yield, &size, &ptr, CUS"save ", 5);
- yield = string_get_localpart(addr, yield, &size, &ptr);
- }
-
-/* Other deliveries start with the full address. It we have split it into local
-part and domain, use those fields. Some early failures can happen before the
-splitting is done; in those cases use the original field. */
-
-else
- {
- if (addr->local_part != NULL)
- {
- const uschar * s;
- yield = string_get_localpart(addr, yield, &size, &ptr);
- yield = string_catn(yield, &size, &ptr, US"@", 1);
- s = addr->domain;
-#ifdef SUPPORT_I18N
- if (testflag(addr, af_utf8_downcvt))
- s = string_localpart_utf8_to_alabel(s, NULL);
-#endif
- yield = string_cat(yield, &size, &ptr, s);
- }
- else
- yield = string_cat(yield, &size, &ptr, addr->address);
- yield[ptr] = 0;
-
- /* If the address we are going to print is the same as the top address,
- and all parents are not being included, don't add on the top address. First
- of all, do a caseless comparison; if this succeeds, do a caseful comparison
- on the local parts. */
-
- if (strcmpic(yield, topaddr->address) == 0 &&
- Ustrncmp(yield, topaddr->address, Ustrchr(yield, '@') - yield) == 0 &&
- addr->onetime_parent == NULL &&
- (!all_parents || addr->parent == NULL || addr->parent == topaddr))
- add_topaddr = FALSE;
- }
-
-/* If all parents are requested, or this is a local pipe/file/reply, and
-there is at least one intermediate parent, show it in brackets, and continue
-with all of them if all are wanted. */
-
-if ((all_parents || testflag(addr, af_pfr)) &&
- addr->parent != NULL &&
- addr->parent != topaddr)
- {
- uschar *s = US" (";
- address_item *addr2;
- for (addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent)
- {
- yield = string_catn(yield, &size, &ptr, s, 2);
- yield = string_cat (yield, &size, &ptr, addr2->address);
- if (!all_parents) break;
- s = US", ";
- }
- yield = string_catn(yield, &size, &ptr, US")", 1);
- }
-
-/* Add the top address if it is required */
-
-if (add_topaddr)
- {
- yield = string_catn(yield, &size, &ptr, US" <", 2);
-
- yield = string_cat(yield, &size, &ptr,
- addr->onetime_parent ? addr->onetime_parent : topaddr->address);
-
- yield = string_catn(yield, &size, &ptr, US">", 1);
- }
-
-yield[ptr] = 0; /* string_cat() leaves space */
-return yield;
-}
-#endif /* COMPILE_UTILITY */
#ifndef COMPILE_UTILITY
addr (chain of) addresses (for extra headers), or NULL;
only the first address is used
fd file descriptor to write the message to
+ tctx transport context
sendfn function for output (transport or verify)
- wck_flags
- use_crlf turn NL into CR LF
- use_bdat callback before chunk flush
- rewrite_rules chain of header rewriting rules
- rewrite_existflags flags for the rewriting rules
- chunk_cb transport callback function for data-chunk commands
Returns: TRUE on success; FALSE on failure.
*/
to write to the filter, and in this process just suck from the filter and write
down the given fd. At the end, tidy up the pipes and the processes.
+XXX
Arguments: as for internal_transport_write_message() above
Returns: TRUE on success; FALSE (with errno) for any failure
case DNS_AGAIN:
return DEFER; /* just defer this TLS'd conn */
- case DNS_NOMATCH:
+ case DNS_NODATA: /* no TLSA RR for this lookup */
+ case DNS_NOMATCH: /* no records at all for this lookup */
return dane_required ? FAIL : FAIL_FORCED;
default:
| (tblock->headers_only ? topt_no_body : 0)
| (tblock->return_path_add ? topt_add_return_path : 0)
| (tblock->delivery_date_add ? topt_add_delivery_date : 0)
- | (tblock->envelope_to_add ? topt_add_envelope_to : 0),
+ | (tblock->envelope_to_add ? topt_add_envelope_to : 0)
};
/* If using CHUNKING we need a callback from the generic transport
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 (= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 (= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
hex2b64:${hex2b64:${md5:the quick brown fox}}
hex2b64:${hex2b64:${sha1:the quick brown fox}}
+base32: 0 <${base32:0}>
+base32: 1 <${base32:1}>
+base32: 31 <${base32:31}>
+base32: 32 <${base32:32}>
+base32: 42 <${base32:42}>
+base32 error: 0x1 ${base32:0x1}
+
+base32d: 0 ${base32d:${base32:0}}
+base32d: 1 ${base32d:${base32:1}}
+base32d: 31 ${base32d:${base32:31}}
+base32d: 32 ${base32d:${base32:32}}
+base32d: 42 ${base32d:${base32:42}}
+base32d error: ABC ${base32d:ABC}
+
The base62 operator is actually a base36 operator in the Darwin and Cygwin
environments. Write cunning tests that produce the same output in both cases,
while doing a reasonable check.
-# Long lines for fakedefer/fakereject
+# Long response lines for fakedefer/fakereject
exim -bs
mail from:<>
rcpt to:<userx@test.ex>
considering: \N^([ab]+)(\w+)$\N}{$2$1}fail}
expanding: \N^([ab]+)(\w+)$\N
result: ^([ab]+)(\w+)$
-condition: match{abcd}{\N^([ab]+)(\w+)$\N}
- result: true
+ condition: match{abcd}{\N^([ab]+)(\w+)$\N}
+ result: true
considering: $2$1}fail}
expanding: $2$1
result: cdab
considering: \N^([ab]+)(\w+)$\N}{$2$1}fail}
expanding: \N^([ab]+)(\w+)$\N
result: ^([ab]+)(\w+)$
-condition: match{wxyz}{\N^([ab]+)(\w+)$\N}
- result: false
+ condition: match{wxyz}{\N^([ab]+)(\w+)$\N}
+ result: false
scanning: $2$1}fail}
expanding: $2$1
result:
considering: 1}{yes}{${lookup{xx}lsearch{/non/exist}}}}
expanding: 1
result: 1
-condition: eq {1}{1}
- result: true
+ condition: eq {1}{1}
+ result: true
considering: yes}{${lookup{xx}lsearch{/non/exist}}}}
expanding: yes
result: yes
result: a.b.c
LOG: MAIN PANIC
no @ found in the subject of an address list match: subject="a.b.c" pattern="a.b.c"
-condition: match_address{a.b.c}{a.b.c}
- result: false
+ condition: match_address{a.b.c}{a.b.c}
+ result: false
scanning: yes}{no}}
expanding: yes
result: yes
considering: white}{$sender_host_name}{No}}
expanding: white
result: white
-condition: eq{black}{white}
- result: false
+ condition: eq{black}{white}
+ result: false
scanning: $sender_host_name}{No}}
expanding: $sender_host_name
result:
considering: $sender_host_address} {2} {30}}s
expanding: $sender_host_address
result: V4NET.0.0.1
-condition: eq {V4NET.0.0.1} {$sender_host_address}
- result: true
+ condition: eq {V4NET.0.0.1} {$sender_host_address}
+ result: true
considering: 2} {30}}s
expanding: 2
result: 2
mailbox TESTSUITE/test-mail/userx is locked
writing to file TESTSUITE/test-mail/userx
writing data block fd=dddd size=sss timeout=0
-process pppp running as transport filter: fd_write=10 fd_read=11
+process pppp running as transport filter: fd_write=9 fd_read=10
writing data block fd=dddd size=sss timeout=0
process pppp writing to transport filter
copying from the filter
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: false
+ condition: def:sender_helo_name
+ result: false
scanning: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
expanding: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}
result: from CALLER
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@test.ex>)
-condition: def:received_for
- result: false
+ condition: def:received_for
+ result: false
scanning:
for $received_for}}
expanding:
writing to file TESTSUITE/test-mail/junk
considering: From ${if def:return_path{$return_path}{MAILER-DAEMON}} ${tod_bsdinbox}
-condition: def:return_path
- result: true
+ condition: def:return_path
+ result: true
considering: $return_path}{MAILER-DAEMON}} ${tod_bsdinbox}
expanding: $return_path
writing to file TESTSUITE/test-mail/junk
considering: From ${if def:return_path{$return_path}{MAILER-DAEMON}} ${tod_bsdinbox}
-condition: def:return_path
- result: true
+ condition: def:return_path
+ result: true
considering: $return_path}{MAILER-DAEMON}} ${tod_bsdinbox}
expanding: $return_path
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: false
+ condition: def:sender_helo_name
+ result: false
scanning: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
expanding: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}
result: from CALLER
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@test.ex>)
-condition: def:received_for
- result: false
+ condition: def:received_for
+ result: false
scanning:
for $received_for}}
expanding:
considering: (?i)auto-generated|auto-replied} }} {no}{yes}}
expanding: (?i)auto-generated|auto-replied
result: (?i)auto-generated|auto-replied
-condition: or {{ !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }{ match{$h_precedence:}{(?i)bulk|list|junk} }{ match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }}
- result: false
+ condition: or {{ !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }{ match{$h_precedence:}{(?i)bulk|list|junk} }{ match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }}
+ result: false
scanning: no}{yes}}
expanding: no
result: no
considering: $domain
expanding: $domain
result: ehlo.domain
-condition: match_domain {$sender_helo_name}{+dlist}
- result: true
+ condition: match_domain {$sender_helo_name}{+dlist}
+ result: true
expanding: ${if match_domain {$sender_helo_name}{+dlist}}
result: true
considering: domain=$domain/sender_domain=$sender_address_domain
--- /dev/null
+
+******** SERVER ********
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: false
+ condition: eq {$address_data}{usery}
+ result: false
scanning: *}{:}}
expanding: *
result: *
considering: userz}{*}{:}}
expanding: userz
result: userz
-condition: eq {$address_data}{userz}
- result: false
+ condition: eq {$address_data}{userz}
+ result: false
scanning: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: false
+ condition: eq {$address_data}{usery}
+ result: false
scanning: *}{:}}
expanding: *
result: *
considering: userz}{*}{:}}
expanding: userz
result: userz
-condition: eq {$address_data}{userz}
- result: false
+ condition: eq {$address_data}{userz}
+ result: false
scanning: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
considering: server}{queue}{cutthrough}}
expanding: server
result: server
-condition: eq {SERVER}{server}
- result: false
+ condition: eq {SERVER}{server}
+ result: false
scanning: queue}{cutthrough}}
expanding: queue
result: queue
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_rcvhost
- result: false
+ condition: def:sender_rcvhost
+ result: false
scanning: from $sender_rcvhost
}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
${if def:sender_address {(envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
-condition: def:sender_ident
- result: true
+ condition: def:sender_ident
+ result: true
considering: from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
result: CALLER
expanding: from ${quote_local_part:$sender_ident}
result: from CALLER
-condition: def:sender_helo_name
- result: true
+ condition: def:sender_helo_name
+ result: true
considering: (helo=$sender_helo_name)
}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
}}
result: from CALLER (helo=myhost.test.ex)
-condition: def:received_protocol
- result: true
+ condition: def:received_protocol
+ result: true
considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
}}(Exim $version_number)
${if def:sender_address {(envelope-from <$sender_address>)
for $received_for}}
expanding: with $received_protocol
result: with local-esmtp
-condition: def:sender_address
- result: true
+ condition: def:tls_cipher
+ result: false
+ scanning: ($tls_cipher)
+ }}(Exim $version_number)
+ ${if def:sender_address {(envelope-from <$sender_address>)
+ }}id $message_exim_id${if def:received_for {
+ for $received_for}}
+ expanding: ($tls_cipher)
+
+ result: ()
+
+ skipping: result is not used
+ condition: def:sender_address
+ result: true
considering: (envelope-from <$sender_address>)
}}id $message_exim_id${if def:received_for {
for $received_for}}
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
> hex2b64:MPPJPkZDbetYunCBao7BJA==
> hex2b64:ztcfpyNSMb7Tg/rP3EHE3cwi7PE=
>
+> base32: 0 <>
+> base32: 1 <b>
+> base32: 31 <7>
+> base32: 32 <ba>
+> base32: 42 <bk>
+> Failed: argument for base32 operator is "0x1", which is not a decimal number
+>
+> base32d: 0 0
+> base32d: 1 1
+> base32d: 31 31
+> base32d: 32 32
+> base32d: 42 42
+> Failed: argument for base32d operator is "ABC", which is not a base 32 number
+>
> The base62 operator is actually a base36 operator in the Darwin and Cygwin
> environments. Write cunning tests that produce the same output in both cases,
> while doing a reasonable check.