summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt34
-rw-r--r--doc/doc-txt/ChangeLog12
-rw-r--r--doc/doc-txt/NewStuff2
-rw-r--r--src/src/deliver.c30
-rw-r--r--src/src/dkim.c101
-rw-r--r--src/src/expand.c171
-rw-r--r--src/src/functions.h13
-rw-r--r--src/src/pdkim/pdkim.c92
-rw-r--r--src/src/pdkim/pdkim.h17
-rw-r--r--src/src/queue.c2
-rw-r--r--src/src/receive.c11
-rw-r--r--src/src/structs.h21
-rw-r--r--src/src/transport.c308
-rw-r--r--src/src/transports/appendfile.c11
-rw-r--r--src/src/transports/autoreply.c20
-rw-r--r--src/src/transports/lmtp.c11
-rw-r--r--src/src/transports/pipe.c17
-rw-r--r--src/src/transports/smtp.c151
-rw-r--r--src/src/transports/smtp.h7
-rw-r--r--src/src/verify.c11
-rw-r--r--test/log/021744
-rw-r--r--test/log/02182
-rw-r--r--test/log/032216
-rw-r--r--test/log/04958
-rw-r--r--test/log/04976
-rw-r--r--test/log/05526
-rw-r--r--test/scripts/0000-Basic/000214
-rw-r--r--test/scripts/0000-Basic/021716
-rw-r--r--test/stderr/000220
-rw-r--r--test/stderr/00924
-rw-r--r--test/stderr/02182
-rw-r--r--test/stderr/03932
-rw-r--r--test/stderr/040244
-rw-r--r--test/stderr/04954
-rw-r--r--test/stderr/054444
-rw-r--r--test/stderr/45042
-rw-r--r--test/stderr/5410136
-rw-r--r--test/stderr/5420136
-rw-r--r--test/stdout/000214
-rw-r--r--test/stdout/021730
40 files changed, 942 insertions, 650 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 152bcb238..7bd5b7f9d 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -10090,6 +10090,21 @@ Last:user@example.com
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"
@@ -19873,12 +19888,17 @@ list1: :include:/opt/lists/list1
.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.
@@ -31524,7 +31544,7 @@ condition defers.
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,
@@ -38059,7 +38079,7 @@ senders).
.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
@@ -38116,7 +38136,7 @@ used.
.section "Verifying DKIM signatures in incoming mail" "SECID514"
.cindex "DKIM" "verification"
-Verification of DKIM signatures in incoming email is implemented via the
+Verification of DKIM signatures in SMTP incoming email is implemented via the
&%acl_smtp_dkim%& ACL. By default, this ACL is called once for each
syntactically(!) correct signature in the incoming message.
A missing ACL definition defaults to accept.
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 454d34311..11b25f875 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -55,7 +55,17 @@ JH/13 Cutthrough: expand transport dkim_domain option when testing for dkim
empty is permissible (obviously it should depend only on data available
when the cutthrough connection is made).
-JH/14 Fakereject: previously logged as a norml message arrival "<="; now
+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 "(=".
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 2a776b730..587dc6508 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -26,6 +26,8 @@ Version 4.88
the queue to be used for a message. A $queue_name variable gives
visibility.
+ 6. New expansion operators base32/base32d.
+
Version 4.87
------------
diff --git a/src/src/deliver.c b/src/src/deliver.c
index f99aa1819..202f7a400 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -6906,8 +6906,8 @@ if (addr_senddsn)
{
FILE *f = fdopen(fd, "wb");
/* header only as required by RFC. only failure DSN needs to honor RET=FULL */
- int topt = topt_add_return_path | topt_no_body;
uschar * bound;
+ transport_ctx tctx;
DEBUG(D_deliver)
debug_printf("sending error message to: %s\n", sender_address);
@@ -6986,7 +6986,10 @@ if (addr_senddsn)
return_path = sender_address; /* In case not previously set */
/* Write the original email out */
- transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
+
+ bzero(&tctx, sizeof(tctx));
+ tctx.options = topt_add_return_path | topt_no_body;
+ transport_write_message(fileno(f), &tctx, 0);
fflush(f);
fprintf(f,"\n--%s--\n", bound);
@@ -7441,8 +7444,18 @@ wording. */
fflush(f);
transport_filter_argv = NULL; /* Just in case */
return_path = sender_address; /* In case not previously set */
- transport_write_message(NULL, fileno(f), topt,
- 0, dsnnotifyhdr, NULL, NULL, NULL, NULL, 0);
+ { /* Dummy transport for headers add */
+ transport_ctx * tctx =
+ store_get(sizeof(*tctx) + sizeof(transport_instance));
+ transport_instance * tb = (transport_instance *)(tctx+1);
+
+ bzero(tctx, sizeof(*tctx)+sizeof(*tb));
+ tctx->tblock = tb;
+ tctx->options = topt;
+ tb->add_headers = dsnnotifyhdr;
+
+ transport_write_message(fileno(f), tctx, 0);
+ }
fflush(f);
/* we never add the final text. close the file */
@@ -7758,7 +7771,9 @@ else if (addr_defer != (address_item *)(+1))
FILE *wmf = NULL;
FILE *f = fdopen(fd, "wb");
uschar * bound;
- int topt;
+ transport_ctx tctx;
+
+ bzero(&tctx, sizeof(tctx));
if (warn_message_file)
if (!(wmf = Ufopen(warn_message_file, "rb")))
@@ -7905,11 +7920,12 @@ else if (addr_defer != (address_item *)(+1))
fflush(f);
/* header only as required by RFC. only failure DSN needs to honor RET=FULL */
- topt = topt_add_return_path | topt_no_body;
+ tctx.options = topt_add_return_path | topt_no_body;
transport_filter_argv = NULL; /* Just in case */
return_path = sender_address; /* In case not previously set */
+
/* Write the original email out */
- transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
+ transport_write_message(fileno(f), &tctx, 0);
fflush(f);
fprintf(f,"\n--%s--\n", bound);
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 4e20f14f2..e027a23b3 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -28,7 +28,7 @@ dns_record *rr;
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 */
@@ -51,12 +51,12 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
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? */
}
@@ -95,10 +95,16 @@ store_pool = dkim_verify_oldpool;
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;
}
@@ -110,6 +116,7 @@ pdkim_signature *sig = NULL;
int dkim_signers_size = 0;
int dkim_signers_ptr = 0;
dkim_signers = NULL;
+int rc;
store_pool = POOL_PERM;
@@ -134,8 +141,12 @@ dkim_collect_input = FALSE;
/* 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)
{
@@ -148,10 +159,12 @@ for (sig = dkim_signatures; sig; sig = sig->next)
string_sprintf("d=%s s=%s c=%s/%s a=%s b=%d ",
sig->domain,
sig->selector,
- sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
- sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
- sig->algo == PDKIM_ALGO_RSA_SHA256 ? "rsa-sha256" : "rsa-sha1",
- sig->sigdata.len * 8
+ sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ sig->algo == PDKIM_ALGO_RSA_SHA256
+ ? "rsa-sha256"
+ : sig->algo == PDKIM_ALGO_RSA_SHA1 ? "rsa-sha1" : "err",
+ (int)sig->sigdata.len > -1 ? sig->sigdata.len * 8 : 0
),
sig->identity ? string_sprintf("i=%s ", sig->identity) : US"",
@@ -186,6 +199,16 @@ for (sig = dkim_signatures; sig; sig = sig->next)
"syntax error in public key record]");
break;
+ case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "signature tag missing or invalid]");
+ break;
+
+ case PDKIM_VERIFY_INVALID_DKIM_VERSION:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "unsupported DKIM version]");
+ break;
+
default:
logmsg = string_append(logmsg, &size, &ptr, 1,
"unspecified problem]");
@@ -466,8 +489,7 @@ if (!(dkim_domain = expand_cstring(dkim_domain)))
/* 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. */
@@ -504,8 +526,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
{
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 */
@@ -516,8 +537,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
/* 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)
@@ -538,8 +558,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
{
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 */
@@ -549,8 +568,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
{
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
@@ -572,25 +590,23 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
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,
@@ -601,27 +617,19 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
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");
@@ -639,11 +647,18 @@ else
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
diff --git a/src/src/expand.c b/src/src/expand.c
index a0b36f7e2..0fba96278 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -199,6 +199,8 @@ enum {
static uschar *op_table_main[] = {
US"address",
US"addresses",
+ US"base32",
+ US"base32d",
US"base62",
US"base62d",
US"base64",
@@ -242,6 +244,8 @@ static uschar *op_table_main[] = {
enum {
EOP_ADDRESS = nelem(op_table_underscore),
EOP_ADDRESSES,
+ EOP_BASE32,
+ EOP_BASE32D,
EOP_BASE62,
EOP_BASE62D,
EOP_BASE64,
@@ -838,6 +842,9 @@ static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
}
+
+static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567";
+
/*************************************************
* Binary chop search on a table *
*************************************************/
@@ -4105,8 +4112,9 @@ while (*s != 0)
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;
@@ -5166,79 +5174,81 @@ while (*s != 0)
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. */
@@ -6256,6 +6266,47 @@ while (*s != 0)
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;
diff --git a/src/src/functions.h b/src/src/functions.h
index ebbdc55e2..4909d9f61 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -144,9 +144,8 @@ extern uschar *deliver_get_sender_address (uschar *id);
extern BOOL directory_make(const uschar *, const uschar *, int, BOOL);
#ifndef DISABLE_DKIM
-extern BOOL dkim_transport_write_message(address_item *, int, int,
- int, uschar *, uschar *, uschar *, uschar *, rewrite_rule *,
- int, uschar *, uschar *, uschar *, uschar *, uschar *, uschar *);
+extern BOOL dkim_transport_write_message(int, transport_ctx *,
+ struct ob_dkim *);
#endif
extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
extern int dns_basic_lookup(dns_answer *, const uschar *, int);
@@ -468,10 +467,10 @@ extern BOOL transport_set_up_command(const uschar ***, uschar *,
extern void transport_update_waiting(host_item *, uschar *);
extern BOOL transport_write_block(int, uschar *, int);
extern BOOL transport_write_string(int, const char *, ...);
-extern BOOL transport_headers_send(address_item *, int, uschar *, uschar *,
- BOOL (*)(int, uschar *, int, BOOL), BOOL, rewrite_rule *, int);
-extern BOOL transport_write_message(address_item *, int, int, int, uschar *,
- uschar *, uschar *, uschar *, rewrite_rule *, int);
+extern BOOL transport_headers_send(address_item *, int, transport_instance *,
+ BOOL (*)(int, uschar *, int, BOOL),
+ BOOL);
+extern BOOL transport_write_message(int, transport_ctx *, int);
extern void tree_add_duplicate(uschar *, address_item *);
extern void tree_add_nonrecipient(uschar *);
extern void tree_add_unusable(host_item *);
diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c
index 29277baeb..f468d232b 100644
--- a/src/src/pdkim/pdkim.c
+++ b/src/src/pdkim/pdkim.c
@@ -115,26 +115,47 @@ pdkim_combined_canon_entry pdkim_combined_canons[] = {
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";
- 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)";
}
}
@@ -407,6 +428,10 @@ sig = store_get(sizeof(pdkim_signature));
memset(sig, 0, sizeof(pdkim_signature));
sig->bodylength = -1;
+/* Set so invalid/missing data error display is accurate */
+sig->algo = -1;
+sig->version = 0;
+
q = sig->rawsig_no_b_val = store_get(Ustrlen(raw_hdr)+1);
for (p = raw_hdr; ; p++)
@@ -476,8 +501,8 @@ for (p = raw_hdr; ; p++)
case 'v':
/* We only support version 1, and that is currently the
only version there is. */
- if (Ustrcmp(cur_val, PDKIM_SIGNATURE_VERSION) == 0)
- sig->version = 1;
+ sig->version =
+ Ustrcmp(cur_val, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1;
break;
case 'a':
for (i = 0; pdkim_algos[i]; i++)
@@ -542,10 +567,6 @@ NEXT_CHAR:
*q++ = c;
}
-/* Make sure the most important bits are there. */
-if (!sig->version)
- return NULL;
-
*q = '\0';
/* Chomp raw header. The final newline must not be added to the signature. */
while (--q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
@@ -1475,6 +1496,37 @@ while (sig)
uschar *dns_txt_name, *dns_txt_reply;
+ /* Make sure we have all required signature tags */
+ if (!( sig->domain && *sig->domain
+ && sig->selector && *sig->selector
+ && sig->headernames && *sig->headernames
+ && sig->bodyhash.data
+ && sig->sigdata.data
+ && sig->algo > -1
+ && sig->version
+ ) )
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_SIGNATURE_ERROR;
+
+ DEBUG(D_acl) debug_printf(
+ " Error in DKIM-Signature header: tags missing or invalid\n"
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ goto NEXT_VERIFY;
+ }
+
+ /* Make sure sig uses supported DKIM version (only v1) */
+ if (sig->version != 1)
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_DKIM_VERSION;
+
+ DEBUG(D_acl) debug_printf(
+ " Error in DKIM-Signature header: unsupported DKIM version\n"
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ goto NEXT_VERIFY;
+ }
+
/* Fetch public key for signing domain, from DNS */
dns_txt_name = string_sprintf("%s._domainkey.%s.",
diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h
index ba984c1d9..5d0157e63 100644
--- a/src/src/pdkim/pdkim.h
+++ b/src/src/pdkim/pdkim.h
@@ -49,12 +49,14 @@
#define PDKIM_VERIFY_FAIL 2
#define PDKIM_VERIFY_PASS 3
-#define PDKIM_VERIFY_FAIL_BODY 1
-#define PDKIM_VERIFY_FAIL_MESSAGE 2
-#define PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE 3
-#define PDKIM_VERIFY_INVALID_BUFFER_SIZE 4
-#define PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD 5
-#define PDKIM_VERIFY_INVALID_PUBKEY_IMPORT 6
+#define PDKIM_VERIFY_FAIL_BODY 1
+#define PDKIM_VERIFY_FAIL_MESSAGE 2
+#define PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE 3
+#define PDKIM_VERIFY_INVALID_BUFFER_SIZE 4
+#define PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD 5
+#define PDKIM_VERIFY_INVALID_PUBKEY_IMPORT 6
+#define PDKIM_VERIFY_INVALID_SIGNATURE_ERROR 7
+#define PDKIM_VERIFY_INVALID_DKIM_VERSION 8
/* -------------------------------------------------------------------------- */
/* Some parameter values */
@@ -302,6 +304,9 @@ int pdkim_feed_finish (pdkim_ctx *, pdkim_signature **);
DLLEXPORT
void pdkim_free_ctx (pdkim_ctx *);
+
+const char * pdkim_errstr(int);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/src/queue.c b/src/src/queue.c
index 1b7b9f74c..7648f47ca 100644
--- a/src/src/queue.c
+++ b/src/src/queue.c
@@ -1145,7 +1145,7 @@ switch(action)
case MSG_SHOW_COPY:
deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE);
deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE);
- transport_write_message(NULL, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0);
+ transport_write_message(1, NULL, 0);
break;
diff --git a/src/src/receive.c b/src/src/receive.c
index d17cf9b83..32154792e 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -682,7 +682,8 @@ while ((ch = (receive_getc)()) != EOF)
case 1: /* After written "\n" */
if (ch == '.') { ch_state = 3; continue; }
if (ch == '\r') { ch_state = 2; continue; }
- if (ch != '\n') ch_state = 0; else linelength = -1;
+ if (ch == '\n') { body_linecount++; linelength = -1; }
+ else ch_state = 0;
break;
case 2:
@@ -3894,7 +3895,9 @@ if (message_logs && blackholed_by == NULL)
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);
}
}
@@ -4014,7 +4017,9 @@ if(!smtp_reply)
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;
diff --git a/src/src/structs.h b/src/src/structs.h
index 78f5a8087..6666c52ca 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -218,6 +218,17 @@ typedef struct transport_info {
} transport_info;
+/* Structure for information about a delivery-in-progress */
+
+typedef struct transport_context {
+ transport_instance * tblock;
+ struct address_item * addr;
+ uschar * check_string;
+ uschar * escape_string;
+ int options; /* topt_* */
+} transport_ctx;
+
+
typedef struct {
uschar *request;
@@ -826,4 +837,14 @@ typedef struct acl_block {
/* smtp transport calc outbound_ip */
typedef BOOL (*oicf) (uschar *message_id, void *data);
+/* DKIM information for transport */
+struct ob_dkim {
+ uschar *dkim_domain;
+ uschar *dkim_private_key;
+ uschar *dkim_selector;
+ uschar *dkim_canon;
+ uschar *dkim_sign_headers;
+ uschar *dkim_strict;
+} dkim;
+
/* End of structs.h */
diff --git a/src/src/transport.c b/src/src/transport.c
index e1e6dcebf..8e0a80240 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -369,7 +369,7 @@ write_chunk(int fd, uschar *chunk, int len, BOOL use_crlf)
{
uschar *start = chunk;
uschar *end = chunk + len;
-register uschar *ptr;
+uschar *ptr;
int mlen = DELIVER_OUT_BUFFER_SIZE - nl_escape_length - 2;
/* The assumption is made that the check string will never stretch over move
@@ -408,7 +408,7 @@ possible. */
for (ptr = start; ptr < end; ptr++)
{
- register int ch;
+ int ch;
/* Flush the buffer if it has reached the threshold - we want to leave enough
room for the next uschar, plus a possible extra CR for an LF, plus the escape
@@ -560,8 +560,7 @@ struct aci *ppp;
/* Do nothing if we have already handled this address. If not, remember it
so that we don't handle it again. */
-for (ppp = *pdlist; ppp != NULL; ppp = ppp->next)
- { if (p == ppp->ptr) return TRUE; }
+for (ppp = *pdlist; ppp; ppp = ppp->next) if (p == ppp->ptr) return TRUE;
ppp = store_get(sizeof(struct aci));
ppp->next = *pdlist;
@@ -573,19 +572,17 @@ ppp->ptr = p;
for (pp = p;; pp = pp->parent)
{
address_item *dup;
- for (dup = addr_duplicate; dup != NULL; dup = dup->next)
- {
- if (dup->dupof != pp) continue; /* Not a dup of our address */
- if (!write_env_to(dup, pplist, pdlist, first, fd, use_crlf)) return FALSE;
- }
- if (pp->parent == NULL) break;
+ for (dup = addr_duplicate; dup; dup = dup->next)
+ if (dup->dupof == pp) /* a dup of our address */
+ if (!write_env_to(dup, pplist, pdlist, first, fd, use_crlf))
+ return FALSE;
+ if (!pp->parent) break;
}
/* Check to see if we have already output the progenitor. */
-for (ppp = *pplist; ppp != NULL; ppp = ppp->next)
- { if (pp == ppp->ptr) break; }
-if (ppp != NULL) return TRUE;
+for (ppp = *pplist; ppp; ppp = ppp->next) if (pp == ppp->ptr) break;
+if (ppp) return TRUE;
/* Remember what we have output, and output it. */
@@ -619,11 +616,12 @@ Arguments:
Returns: TRUE on success; FALSE on failure.
*/
BOOL
-transport_headers_send(address_item *addr, int fd, uschar *add_headers, uschar *remove_headers,
+transport_headers_send(address_item *addr, int fd, transport_instance * tblock,
BOOL (*sendfn)(int fd, uschar * s, int len, BOOL use_crlf),
- BOOL use_crlf, rewrite_rule *rewrite_rules, int rewrite_existflags)
+ BOOL use_crlf)
{
header_line *h;
+const uschar *list;
/* Then the message's headers. Don't write any that are flagged as "old";
that means they were rewritten, or are a record of envelope rewriting, or
@@ -632,13 +630,12 @@ match any entries therein. It is a colon-sep list; expand the items
separately and squash any empty ones.
Then check addr->prop.remove_headers too, provided that addr is not NULL. */
-for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
+for (h = header_list; h; h = h->next) if (h->type != htype_old)
{
int i;
- const uschar *list = remove_headers;
-
BOOL include_header = TRUE;
+ list = tblock ? tblock->remove_headers : NULL;
for (i = 0; i < 2; i++) /* For remove_headers && addr->prop.remove_headers */
{
if (list)
@@ -661,9 +658,9 @@ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
while (*ss == ' ' || *ss == '\t') ss++;
if (*ss == ':') break;
}
- if (s != NULL) { include_header = FALSE; break; }
+ if (s) { include_header = FALSE; break; }
}
- if (addr != NULL) list = addr->prop.remove_headers;
+ if (addr) list = addr->prop.remove_headers;
}
/* If this header is to be output, try to rewrite it if there are rewriting
@@ -671,12 +668,13 @@ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
if (include_header)
{
- if (rewrite_rules)
+ if (tblock && tblock->rewrite_rules)
{
void *reset_point = store_get(0);
header_line *hh;
- if ((hh = rewrite_header(h, NULL, NULL, rewrite_rules, rewrite_existflags, FALSE)))
+ if ((hh = rewrite_header(h, NULL, NULL, tblock->rewrite_rules,
+ tblock->rewrite_existflags, FALSE)))
{
if (!sendfn(fd, hh->text, hh->slen, use_crlf)) return FALSE;
store_reset(reset_point);
@@ -714,8 +712,7 @@ if (addr)
header_line *hprev = addr->prop.extra_headers;
header_line *hnext;
for (i = 0; i < 2; i++)
- {
- for (h = hprev, hprev = NULL; h != NULL; h = hnext)
+ for (h = hprev, hprev = NULL; h; h = hnext)
{
hnext = h->next;
h->next = hprev;
@@ -727,7 +724,6 @@ if (addr)
debug_printf("added header line(s):\n%s---\n", h->text);
}
}
- }
}
/* If a string containing additional headers exists it is a newline-sep
@@ -737,18 +733,13 @@ up any other headers. An empty string or a forced expansion failure are
noops. An added header string from a transport may not end with a newline;
add one if it does not. */
-if (add_headers)
+if (tblock && (list = CUS tblock->add_headers))
{
int sep = '\n';
uschar * s;
- while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0)))
- if (!(s = expand_string(s)))
- {
- if (!expand_string_forcedfail)
- { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
- }
- else
+ while ((s = string_nextinlist(&list, &sep, NULL, 0)))
+ if ((s = expand_string(s)))
{
int len = Ustrlen(s);
if (len > 0)
@@ -764,6 +755,8 @@ if (add_headers)
}
}
}
+ else if (!expand_string_forcedfail)
+ { errno = ERRNO_CHHEADER_FAIL; return FALSE; }
}
/* Separate headers from body with a blank line */
@@ -801,30 +794,32 @@ can include timeouts for certain transports, which are requested by setting
transport_write_timeout non-zero.
Arguments:
- addr (chain of) addresses (for extra headers), or NULL;
- only the first address is used
fd file descriptor to write the message to
- options bit-wise options:
- add_return_path if TRUE, add a "return-path" header
- add_envelope_to if TRUE, add a "envelope-to" header
- add_delivery_date if TRUE, add a "delivery-date" header
- use_crlf if TRUE, turn NL into CR LF
- end_dot if TRUE, send a terminating "." line at the end
- no_headers if TRUE, omit the headers
- no_body if TRUE, omit the body
- size_limit if > 0, this is a limit to the size of message written;
- it is used when returning messages to their senders,
- and is approximate rather than exact, owing to chunk
- buffering
- add_headers a string containing one or more headers to add; it is
- expanded, and must be in correct RFC 822 format as
- it is transmitted verbatim; NULL => no additions,
- and so does empty string or forced expansion fail
- remove_headers a colon-separated list of headers to remove, or NULL
- check_string a string to check for at the start of lines, or NULL
- escape_string a string to insert in front of any check string
- rewrite_rules chain of header rewriting rules
- rewrite_existflags flags for the rewriting rules
+ tctx
+ addr (chain of) addresses (for extra headers), or NULL;
+ only the first address is used
+ tblock optional transport instance block (NULL signifies NULL/0):
+ add_headers a string containing one or more headers to add; it is
+ expanded, and must be in correct RFC 822 format as
+ it is transmitted verbatim; NULL => no additions,
+ and so does empty string or forced expansion fail
+ remove_headers a colon-separated list of headers to remove, or NULL
+ rewrite_rules chain of header rewriting rules
+ rewrite_existflags flags for the rewriting rules
+ options bit-wise options:
+ add_return_path if TRUE, add a "return-path" header
+ add_envelope_to if TRUE, add a "envelope-to" header
+ add_delivery_date if TRUE, add a "delivery-date" header
+ use_crlf if TRUE, turn NL into CR LF
+ end_dot if TRUE, send a terminating "." line at the end
+ no_headers if TRUE, omit the headers
+ no_body if TRUE, omit the body
+ size_limit if > 0, this is a limit to the size of message written;
+ it is used when returning messages to their senders,
+ and is approximate rather than exact, owing to chunk
+ buffering
+ check_string a string to check for at the start of lines, or NULL
+ escape_string a string to insert in front of any check string
Returns: TRUE on success; FALSE (with errno) on failure.
In addition, the global variable transport_count
@@ -832,13 +827,11 @@ Returns: TRUE on success; FALSE (with errno) on failure.
*/
static BOOL
-internal_transport_write_message(address_item *addr, int fd, int options,
- int size_limit, uschar *add_headers, uschar *remove_headers, uschar *check_string,
- uschar *escape_string, rewrite_rule *rewrite_rules, int rewrite_existflags)
+internal_transport_write_message(int fd, transport_ctx * tctx, int size_limit)
{
int written = 0;
int len;
-BOOL use_crlf = (options & topt_use_crlf) != 0;
+BOOL use_crlf = (tctx->options & topt_use_crlf) != 0;
/* Initialize pointer in output buffer. */
@@ -847,39 +840,41 @@ chunk_ptr = deliver_out_buffer;
/* Set up the data for start-of-line data checking and escaping */
nl_partial_match = -1;
-if (check_string != NULL && escape_string != NULL)
+if (tctx->check_string && tctx->escape_string)
{
- nl_check = check_string;
+ nl_check = tctx->check_string;
nl_check_length = Ustrlen(nl_check);
- nl_escape = escape_string;
+ nl_escape = tctx->escape_string;
nl_escape_length = Ustrlen(nl_escape);
}
-else nl_check_length = nl_escape_length = 0;
+else
+ nl_check_length = nl_escape_length = 0;
/* Whether the escaping mechanism is applied to headers or not is controlled by
an option (set for SMTP, not otherwise). Negate the length if not wanted till
after the headers. */
-if ((options & topt_escape_headers) == 0) nl_check_length = -nl_check_length;
+if (!(tctx->options & topt_escape_headers))
+ nl_check_length = -nl_check_length;
/* Write the headers if required, including any that have to be added. If there
are header rewriting rules, apply them. */
-if ((options & topt_no_headers) == 0)
+if (!(tctx->options & topt_no_headers))
{
/* Add return-path: if requested. */
- if ((options & topt_add_return_path) != 0)
+ if (tctx->options & topt_add_return_path)
{
uschar buffer[ADDRESS_MAXLENGTH + 20];
- sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
+ int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH,
return_path);
- if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE;
+ if (!write_chunk(fd, buffer, n, use_crlf)) return FALSE;
}
/* Add envelope-to: if requested */
- if ((options & topt_add_envelope_to) != 0)
+ if (tctx->options & topt_add_envelope_to)
{
BOOL first = TRUE;
address_item *p;
@@ -893,10 +888,9 @@ if ((options & topt_no_headers) == 0)
anchors for lists of addresses already handled; they have to be defined at
this level becuase write_env_to() calls itself recursively. */
- for (p = addr; p != NULL; p = p->next)
- {
- if (!write_env_to(p, &plist, &dlist, &first, fd, use_crlf)) return FALSE;
- }
+ for (p = tctx->addr; p; p = p->next)
+ if (!write_env_to(p, &plist, &dlist, &first, fd, use_crlf))
+ return FALSE;
/* Add a final newline and reset the store used for tracking duplicates */
@@ -906,11 +900,11 @@ if ((options & topt_no_headers) == 0)
/* Add delivery-date: if requested. */
- if ((options & topt_add_delivery_date) != 0)
+ if (tctx->options & topt_add_delivery_date)
{
uschar buffer[100];
- sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
- if (!write_chunk(fd, buffer, Ustrlen(buffer), use_crlf)) return FALSE;
+ int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
+ if (!write_chunk(fd, buffer, n, use_crlf)) return FALSE;
}
/* Then the message's headers. Don't write any that are flagged as "old";
@@ -918,8 +912,8 @@ if ((options & topt_no_headers) == 0)
were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
match any entries therein. Then check addr->prop.remove_headers too, provided that
addr is not NULL. */
- if (!transport_headers_send(addr, fd, add_headers, remove_headers, &write_chunk,
- use_crlf, rewrite_rules, rewrite_existflags))
+
+ if (!transport_headers_send(tctx->addr, fd, tctx->tblock, &write_chunk, use_crlf))
return FALSE;
}
@@ -929,7 +923,7 @@ negative in cases where it isn't to apply to the headers). Then ensure the body
is positioned at the start of its file (following the message id), then write
it, applying the size limit if required. */
-if ((options & topt_no_body) == 0)
+if (!(tctx->options & topt_no_body))
{
nl_check_length = abs(nl_check_length);
nl_partial_match = 0;
@@ -961,7 +955,7 @@ nl_check_length = nl_escape_length = 0;
/* If requested, add a terminating "." line (SMTP output). */
-if ((options & topt_end_dot) != 0 && !write_chunk(fd, US".\n", 2, use_crlf))
+if (tctx->options & topt_end_dot && !write_chunk(fd, US".\n", 2, use_crlf))
return FALSE;
/* Write out any remaining data in the buffer before returning. */
@@ -986,46 +980,29 @@ return (len = chunk_ptr - deliver_out_buffer) <= 0 ||
signing the file, send the signed message down the original fd (or TLS fd).
Arguments:
- as for internal_transport_write_message() above, with additional arguments:
- uschar *dkim_private_key DKIM: The private key to use (filename or
- plain data)
- uschar *dkim_domain DKIM: The domain to use
- uschar *dkim_selector DKIM: The selector to use.
- uschar *dkim_canon DKIM: The canonalization scheme to use,
- "simple" or "relaxed"
- uschar *dkim_strict DKIM: What to do if signing fails:
- 1/true => throw error
- 0/false => send anyway
- uschar *dkim_sign_headers DKIM: List of headers that should be included
- in signature generation
+ as for internal_transport_write_message() above, with additional arguments
+ for DKIM.
Returns: TRUE on success; FALSE (with errno) for any failure
*/
BOOL
-dkim_transport_write_message(address_item *addr, int fd, int options,
- int size_limit, uschar *add_headers, uschar *remove_headers,
- uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules,
- int rewrite_existflags, uschar *dkim_private_key, uschar *dkim_domain,
- uschar *dkim_selector, uschar *dkim_canon, uschar *dkim_strict, uschar *dkim_sign_headers
- )
+dkim_transport_write_message(int out_fd, transport_ctx * tctx,
+ struct ob_dkim * dkim)
{
int dkim_fd;
int save_errno = 0;
BOOL rc;
uschar * dkim_spool_name;
-char sbuf[2048];
int sread = 0;
int wwritten = 0;
uschar *dkim_signature = NULL;
+off_t k_file_size;
/* If we can't sign, just call the original function. */
-if (!(dkim_private_key && dkim_domain && dkim_selector))
- return transport_write_message(addr, fd, options,
- size_limit, add_headers, remove_headers,
- check_string, escape_string, rewrite_rules,
- rewrite_existflags);
+if (!(dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector))
+ return transport_write_message(out_fd, tctx, 0);
dkim_spool_name = spool_fname(US"input", message_subdir, message_id,
string_sprintf("-%d-K", (int)getpid()));
@@ -1038,12 +1015,9 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0)
goto CLEANUP;
}
-/* Call original function to write the -K file */
+/* Call original function to write the -K file; does the CRLF expansion */
-rc = transport_write_message(addr, dkim_fd, options,
- size_limit, add_headers, remove_headers,
- check_string, escape_string, rewrite_rules,
- rewrite_existflags);
+rc = transport_write_message(dkim_fd, tctx, 0);
/* Save error state. We must clean up before returning. */
if (!rc)
@@ -1052,24 +1026,24 @@ if (!rc)
goto CLEANUP;
}
-if (dkim_private_key && dkim_domain && dkim_selector)
+if (dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector)
{
/* Rewind file and feed it to the goats^W DKIM lib */
lseek(dkim_fd, 0, SEEK_SET);
dkim_signature = dkim_exim_sign(dkim_fd,
- dkim_private_key,
- dkim_domain,
- dkim_selector,
- dkim_canon,
- dkim_sign_headers);
+ dkim->dkim_private_key,
+ dkim->dkim_domain,
+ dkim->dkim_selector,
+ dkim->dkim_canon,
+ dkim->dkim_sign_headers);
if (!dkim_signature)
{
- if (dkim_strict)
+ if (dkim->dkim_strict)
{
- uschar *dkim_strict_result = expand_string(dkim_strict);
+ uschar *dkim_strict_result = expand_string(dkim->dkim_strict);
if (dkim_strict_result)
- if ( (strcmpic(dkim_strict,US"1") == 0) ||
- (strcmpic(dkim_strict,US"true") == 0) )
+ if ( (strcmpic(dkim->dkim_strict,US"1") == 0) ||
+ (strcmpic(dkim->dkim_strict,US"true") == 0) )
{
/* Set errno to something halfway meaningful */
save_errno = EACCES;
@@ -1080,20 +1054,21 @@ if (dkim_private_key && dkim_domain && dkim_selector)
}
}
}
- else
+
+ if (dkim_signature)
{
int siglen = Ustrlen(dkim_signature);
while(siglen > 0)
{
#ifdef SUPPORT_TLS
- wwritten = tls_out.active == fd
- ? tls_write(FALSE, dkim_signature, siglen)
- : write(fd, dkim_signature, siglen);
+ wwritten = tls_out.active == out_fd
+ ? tls_write(FALSE, dkim_signature, siglen)
+ : write(out_fd, dkim_signature, siglen);
#else
- wwritten = write(fd, dkim_signature, siglen);
+ wwritten = write(out_fd, dkim_signature, siglen);
#endif
if (wwritten == -1)
- {
+ {
/* error, bail out */
save_errno = errno;
rc = FALSE;
@@ -1110,17 +1085,18 @@ if (dkim_private_key && dkim_domain && dkim_selector)
to the socket. However only if we don't use TLS,
as then there's another layer of indirection
before the data finally hits the socket. */
-if (tls_out.active != fd)
+if (tls_out.active != out_fd)
{
- off_t size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */
ssize_t copied = 0;
off_t offset = 0;
+ k_file_size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */
+
/* Rewind file */
lseek(dkim_fd, 0, SEEK_SET);
- while(copied >= 0 && offset < size)
- copied = sendfile(fd, dkim_fd, &offset, size - offset);
+ while(copied >= 0 && offset < k_file_size)
+ copied = sendfile(out_fd, dkim_fd, &offset, k_file_size - offset);
if (copied < 0)
{
save_errno = errno;
@@ -1136,19 +1112,19 @@ else
lseek(dkim_fd, 0, SEEK_SET);
/* Send file down the original fd */
- while((sread = read(dkim_fd, sbuf, 2048)) > 0)
+ while((sread = read(dkim_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0)
{
- char *p = sbuf;
+ char *p = deliver_out_buffer;
/* write the chunk */
while (sread)
{
#ifdef SUPPORT_TLS
- wwritten = tls_out.active == fd
+ wwritten = tls_out.active == out_fd
? tls_write(FALSE, US p, sread)
- : write(fd, p, sread);
+ : write(out_fd, p, sread);
#else
- wwritten = write(fd, p, sread);
+ wwritten = write(out_fd, p, sread);
#endif
if (wwritten == -1)
{
@@ -1191,6 +1167,7 @@ set up a filtering process, fork another process to call the internal function
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
@@ -1198,16 +1175,16 @@ Returns: TRUE on success; FALSE (with errno) for any failure
*/
BOOL
-transport_write_message(address_item *addr, int fd, int options,
- int size_limit, uschar *add_headers, uschar *remove_headers,
- uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules,
- int rewrite_existflags)
+transport_write_message(int fd, transport_ctx * tctx, int size_limit)
{
BOOL use_crlf;
BOOL last_filter_was_NL = TRUE;
int rc, len, yield, fd_read, fd_write, save_errno;
int pfd[2] = {-1, -1};
pid_t filter_pid, write_pid;
+static transport_ctx dummy_tctx = { NULL, NULL, NULL, NULL, 0 };
+
+if (!tctx) tctx = &dummy_tctx;
transport_filter_timed_out = FALSE;
@@ -1218,22 +1195,20 @@ if ( !transport_filter_argv
|| !*transport_filter_argv
|| !**transport_filter_argv
)
- return internal_transport_write_message(addr, fd, options, size_limit,
- add_headers, remove_headers, check_string, escape_string,
- rewrite_rules, rewrite_existflags);
+ return internal_transport_write_message(fd, tctx, size_limit);
/* Otherwise the message must be written to a filter process and read back
before being written to the incoming fd. First set up the special processing to
be done during the copying. */
-use_crlf = (options & topt_use_crlf) != 0;
+use_crlf = (tctx->options & topt_use_crlf) != 0;
nl_partial_match = -1;
-if (check_string != NULL && escape_string != NULL)
+if (tctx->check_string && tctx->escape_string)
{
- nl_check = check_string;
+ nl_check = tctx->check_string;
nl_check_length = Ustrlen(nl_check);
- nl_escape = escape_string;
+ nl_escape = tctx->escape_string;
nl_escape_length = Ustrlen(nl_escape);
}
else nl_check_length = nl_escape_length = 0;
@@ -1257,7 +1232,7 @@ filter_pid = child_open(USS transport_filter_argv, NULL, 077,
if (filter_pid < 0) goto TIDY_UP; /* errno set */
DEBUG(D_transport)
- debug_printf("process %d running as transport filter: write=%d read=%d\n",
+ debug_printf("process %d running as transport filter: fd_write=%d fd_read=%d\n",
(int)filter_pid, fd_write, fd_read);
/* Fork subprocess to write the message to the filter, and return the result
@@ -1271,16 +1246,18 @@ if ((write_pid = fork()) == 0)
(void)close(fd_read);
(void)close(pfd[pipe_read]);
nl_check_length = nl_escape_length = 0;
- rc = internal_transport_write_message(addr, fd_write,
- (options & ~(topt_use_crlf | topt_end_dot)),
- size_limit, add_headers, remove_headers, NULL, NULL,
- rewrite_rules, rewrite_existflags);
+
+ tctx->check_string = tctx->escape_string = NULL;
+ tctx->options &= ~(topt_use_crlf | topt_end_dot);
+
+ rc = internal_transport_write_message(fd_write, tctx, size_limit);
+
save_errno = errno;
if ( write(pfd[pipe_write], (void *)&rc, sizeof(BOOL))
!= sizeof(BOOL)
|| write(pfd[pipe_write], (void *)&save_errno, sizeof(int))
!= sizeof(int)
- || write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int))
+ || write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int))
!= sizeof(int)
)
rc = FALSE; /* compiler quietening */
@@ -1377,7 +1354,7 @@ if (filter_pid > 0 && (rc = child_close(filter_pid, 30)) != 0 && yield)
{
yield = FALSE;
save_errno = ERRNO_FILTER_FAIL;
- addr->more_errno = rc;
+ tctx->addr->more_errno = rc;
DEBUG(D_transport) debug_printf("filter process returned %d\n", rc);
}
@@ -1398,7 +1375,7 @@ if (write_pid > 0)
if (!ok)
{
dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int));
- dummy = read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int));
+ dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int));
yield = FALSE;
}
}
@@ -1406,7 +1383,7 @@ if (write_pid > 0)
{
yield = FALSE;
save_errno = ERRNO_FILTER_FAIL;
- addr->more_errno = rc;
+ tctx->addr->more_errno = rc;
DEBUG(D_transport) debug_printf("writing process returned %d\n", rc);
}
}
@@ -1420,28 +1397,27 @@ filter was not NL, insert a NL to make the SMTP protocol work. */
if (yield)
{
nl_check_length = nl_escape_length = 0;
- if ((options & topt_end_dot) != 0 && (last_filter_was_NL?
- !write_chunk(fd, US".\n", 2, use_crlf) :
- !write_chunk(fd, US"\n.\n", 3, use_crlf)))
- {
+ if ( tctx->options & topt_end_dot
+ && ( last_filter_was_NL
+ ? !write_chunk(fd, US".\n", 2, use_crlf)
+ : !write_chunk(fd, US"\n.\n", 3, use_crlf)
+ ) )
yield = FALSE;
- }
/* Write out any remaining data in the buffer. */
else
- {
- yield = (len = chunk_ptr - deliver_out_buffer) <= 0 ||
- transport_write_block(fd, deliver_out_buffer, len);
- }
+ yield = (len = chunk_ptr - deliver_out_buffer) <= 0
+ || transport_write_block(fd, deliver_out_buffer, len);
}
-else errno = save_errno; /* From some earlier error */
+else
+ errno = save_errno; /* From some earlier error */
DEBUG(D_transport)
{
debug_printf("end of filtering transport writing: yield=%d\n", yield);
if (!yield)
- debug_printf("errno=%d more_errno=%d\n", errno, addr->more_errno);
+ debug_printf("errno=%d more_errno=%d\n", errno, tctx->addr->more_errno);
}
return yield;
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 5dc4ee9b5..c9d150525 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -2874,9 +2874,14 @@ at initialization time. */
if (yield == OK)
{
- if (!transport_write_message(addr, fd, ob->options, 0, tblock->add_headers,
- tblock->remove_headers, ob->check_string, ob->escape_string,
- tblock->rewrite_rules, tblock->rewrite_existflags))
+ transport_ctx tctx = {
+ tblock,
+ addr,
+ ob->check_string,
+ ob->escape_string,
+ ob->options
+ };
+ if (!transport_write_message(fd, &tctx, 0))
yield = DEFER;
}
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index 54f9ef4de..36a68b92c 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -691,6 +691,17 @@ if (return_message)
US"------ This is a copy of the body of the message, without the headers.\n"
:
US"------ This is a copy of the message, including all the headers.\n";
+ transport_ctx tctx = {
+ tblock,
+ addr,
+ NULL,
+ NULL,
+ (tblock->body_only ? topt_no_headers : 0) |
+ (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)
+ };
if (bounce_return_size_limit > 0 && !tblock->headers_only)
{
@@ -710,14 +721,7 @@ if (return_message)
fflush(f);
transport_count = 0;
- transport_write_message(addr, fileno(f),
- (tblock->body_only? topt_no_headers : 0) |
- (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),
- bounce_return_size_limit, tblock->add_headers, tblock->remove_headers,
- NULL, NULL, tblock->rewrite_rules, tblock->rewrite_existflags);
+ transport_write_message(fileno(f), &tctx, bounce_return_size_limit);
}
/* End the message and wait for the child process to end; no timeout. */
diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c
index bca597893..9624ece6a 100644
--- a/src/src/transports/lmtp.c
+++ b/src/src/transports/lmtp.c
@@ -609,6 +609,13 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
if (send_data)
{
BOOL ok;
+ transport_ctx tctx = {
+ tblock,
+ addrlist,
+ US".",
+ US"..",
+ ob->options
+ };
if (!lmtp_write_command(fd_in, "DATA\r\n")) goto WRITE_FAILED;
if (!lmtp_read_response(out, buffer, sizeof(buffer), '3', timeout))
@@ -628,9 +635,7 @@ if (send_data)
debug_printf(" LMTP>> writing message and terminating \".\"\n");
transport_count = 0;
- ok = transport_write_message(addrlist, fd_in, ob->options, 0,
- tblock->add_headers, tblock->remove_headers, US".", US"..",
- tblock->rewrite_rules, tblock->rewrite_existflags);
+ ok = transport_write_message(fd_in, &tctx, 0);
/* Failure can either be some kind of I/O disaster (including timeout),
or the failure of a transport filter or the expansion of added headers. */
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index db522e54b..e3d01974a 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -555,6 +555,13 @@ uschar *envp[50];
const uschar *envlist = ob->environment;
uschar *cmd, *ss;
uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n";
+transport_ctx tctx = {
+ tblock,
+ addr,
+ ob->check_string,
+ ob->escape_string,
+ ob->options /* set at initialization time */
+};
DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
@@ -842,23 +849,19 @@ if (ob->use_bsmtp)
if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol))
goto END_WRITE;
- for (a = addr; a != NULL; a = a->next)
- {
+ for (a = addr; a; a = a->next)
if (!transport_write_string(fd_in,
"RCPT TO:<%s>%s",
transport_rcpt_address(a, tblock->rcpt_include_affixes),
eol))
goto END_WRITE;
- }
if (!transport_write_string(fd_in, "DATA%s", eol)) goto END_WRITE;
}
-/* Now the actual message - the options were set at initialization time */
+/* Now the actual message */
-if (!transport_write_message(addr, fd_in, ob->options, 0, tblock->add_headers,
- tblock->remove_headers, ob->check_string, ob->escape_string,
- tblock->rewrite_rules, tblock->rewrite_existflags))
+if (!transport_write_message(fd_in, &tctx, 0))
goto END_WRITE;
/* Now any configured suffix */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 3d12988e8..bbfef0632 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -44,17 +44,17 @@ optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, delay_after_cutoff) },
#ifndef DISABLE_DKIM
{ "dkim_canon", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_canon) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_canon) },
{ "dkim_domain", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_domain) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
{ "dkim_private_key", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_private_key) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
{ "dkim_selector", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_selector) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_selector) },
{ "dkim_sign_headers", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_sign_headers) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_sign_headers) },
{ "dkim_strict", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dkim_strict) },
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_strict) },
#endif
{ "dns_qualify_single", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
@@ -256,12 +256,12 @@ smtp_transport_options_block smtp_transport_option_defaults = {
US"*" /* tls_verify_cert_hostnames */
#endif
#ifndef DISABLE_DKIM
- ,NULL, /* dkim_canon */
- NULL, /* dkim_domain */
- NULL, /* dkim_private_key */
- NULL, /* dkim_selector */
- NULL, /* dkim_sign_headers */
- NULL /* dkim_strict */
+ , {NULL, /* dkim_canon */
+ NULL, /* dkim_domain */
+ NULL, /* dkim_private_key */
+ NULL, /* dkim_selector */
+ NULL, /* dkim_sign_headers */
+ NULL} /* dkim_strict */
#endif
};
@@ -279,6 +279,7 @@ static uschar *rf_names[] = { US"NEVER", US"SUCCESS", US"FAILURE", US"DELAY" };
static uschar *smtp_command; /* Points to last cmd for error messages */
static uschar *mail_command; /* Points to MAIL cmd for error messages */
static BOOL update_waiting; /* TRUE to update the "wait" database */
+static BOOL pipelining_active; /* current transaction is in pipe mode */
/*************************************************
@@ -507,13 +508,7 @@ static BOOL
check_response(host_item *host, int *errno_value, int more_errno,
uschar *buffer, int *yield, uschar **message, BOOL *pass_message)
{
-uschar *pl = US"";
-
-if (smtp_use_pipelining &&
- (Ustrcmp(smtp_command, "MAIL") == 0 ||
- Ustrcmp(smtp_command, "RCPT") == 0 ||
- Ustrcmp(smtp_command, "DATA") == 0))
- pl = US"pipelined ";
+uschar * pl = pipelining_active ? US"pipelined " : US"";
*yield = '4'; /* Default setting is to give a temporary error */
@@ -1222,7 +1217,8 @@ switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname))
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:
@@ -1315,40 +1311,40 @@ uschar
ehlo_response(uschar * buf, size_t bsize, uschar checks)
{
#ifdef SUPPORT_TLS
-if (checks & PEER_OFFERED_TLS)
- if (pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_TLS;
+if ( checks & PEER_OFFERED_TLS
+ && pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_TLS;
#endif
- if ( checks & PEER_OFFERED_IGNQ
- && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_IGNQ;
+if ( checks & PEER_OFFERED_IGNQ
+ && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_IGNQ;
#ifndef DISABLE_PRDR
- if ( checks & PEER_OFFERED_PRDR
- && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PRDR;
+if ( checks & PEER_OFFERED_PRDR
+ && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PRDR;
#endif
#ifdef SUPPORT_I18N
- if ( checks & PEER_OFFERED_UTF8
- && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_UTF8;
+if ( checks & PEER_OFFERED_UTF8
+ && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_UTF8;
#endif
- if ( checks & PEER_OFFERED_DSN
- && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_DSN;
+if ( checks & PEER_OFFERED_DSN
+ && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_DSN;
- if ( checks & PEER_OFFERED_PIPE
- && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
- PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_PIPE;
+if ( checks & PEER_OFFERED_PIPE
+ && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
+ PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_PIPE;
- if ( checks & PEER_OFFERED_SIZE
- && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
- checks &= ~PEER_OFFERED_SIZE;
+if ( checks & PEER_OFFERED_SIZE
+ && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_SIZE;
return checks;
}
@@ -1709,13 +1705,7 @@ goto SEND_QUIT;
if (esmtp || lmtp)
peer_offered = ehlo_response(buffer, Ustrlen(buffer),
- PEER_OFFERED_TLS
- | 0 /* IGNQ checked later */
- | 0 /* PRDR checked later */
- | 0 /* UTF8 checked later */
- | 0 /* DSN checked later */
- | 0 /* PIPE checked later */
- | 0 /* SIZE checked later */
+ PEER_OFFERED_TLS /* others checked later */
);
/* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
@@ -1977,6 +1967,7 @@ if (continue_hostname == NULL
case FAIL: goto RESPONSE_FAILED;
}
}
+pipelining_active = smtp_use_pipelining;
/* The setting up of the SMTP call is now complete. Any subsequent errors are
message-specific. */
@@ -2099,13 +2090,11 @@ if (smtp_use_dsn && !dsn_all_lasthop)
{
if (dsn_ret == dsn_ret_hdrs)
{
- Ustrcpy(p, " RET=HDRS");
- while (*p) p++;
+ Ustrcpy(p, " RET=HDRS"); p += 9;
}
else if (dsn_ret == dsn_ret_full)
{
- Ustrcpy(p, " RET=FULL");
- while (*p) p++;
+ Ustrcpy(p, " RET=FULL"); p += 9;
}
if (dsn_envid != NULL)
{
@@ -2198,7 +2187,7 @@ the PENDING_DEFER status, because only one attempt is ever made, and we know
that max_rcpt will be large, so all addresses will be done at once. */
for (addr = first_addr;
- address_count < max_rcpt && addr != NULL;
+ addr && address_count < max_rcpt;
addr = addr->next)
{
int count;
@@ -2210,14 +2199,14 @@ for (addr = first_addr;
if (addr->transport_return != PENDING_DEFER) continue;
address_count++;
- no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next != NULL);
+ no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next);
/* Add any DSN flags to the rcpt command and add to the sent string */
p = buffer;
*p = 0;
- if (smtp_use_dsn && (addr->dsn_flags & rf_dsnlasthop) != 1)
+ if (smtp_use_dsn && !(addr->dsn_flags & rf_dsnlasthop))
{
if ((addr->dsn_flags & rf_dsnflags) != 0)
{
@@ -2235,7 +2224,7 @@ for (addr = first_addr;
}
}
- if (addr->dsn_orcpt != NULL)
+ if (addr->dsn_orcpt)
{
string_format(p, sizeof(buffer) - (p-buffer), " ORCPT=%s",
addr->dsn_orcpt);
@@ -2334,6 +2323,7 @@ if (ok || (smtp_use_pipelining && !mua_wrapper))
case -1: goto END_OFF; /* Timeout on RCPT */
default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */
}
+ pipelining_active = FALSE;
}
/* Save the first address of the next batch. */
@@ -2347,8 +2337,22 @@ for handling the SMTP dot-handling protocol, flagging to apply to headers as
well as body. Set the appropriate timeout value to be used for each chunk.
(Haven't been able to make it work using select() for writing yet.) */
-if (!ok) ok = TRUE; else
+if (!ok)
+ ok = TRUE;
+else
{
+ transport_ctx tctx = {
+ tblock,
+ addrlist,
+ US".", US"..", /* Escaping strings */
+ topt_use_crlf | topt_end_dot | topt_escape_headers
+ | (tblock->body_only ? topt_no_headers : 0)
+ | (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)
+ };
+
sigalrm_seen = FALSE;
transport_write_timeout = ob->data_timeout;
smtp_command = US"sending data block"; /* For error messages */
@@ -2357,32 +2361,9 @@ if (!ok) ok = TRUE; else
transport_count = 0;
#ifndef DISABLE_DKIM
- ok = dkim_transport_write_message(addrlist, inblock.sock,
- topt_use_crlf | topt_end_dot | topt_escape_headers |
- (tblock->body_only? topt_no_headers : 0) |
- (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),
- 0, /* No size limit */
- tblock->add_headers, tblock->remove_headers,
- US".", US"..", /* Escaping strings */
- tblock->rewrite_rules, tblock->rewrite_existflags,
- ob->dkim_private_key, ob->dkim_domain, ob->dkim_selector,
- ob->dkim_canon, ob->dkim_strict, ob->dkim_sign_headers
- );
+ ok = dkim_transport_write_message(inblock.sock, &tctx, &ob->dkim);
#else
- ok = transport_write_message(addrlist, inblock.sock,
- topt_use_crlf | topt_end_dot | topt_escape_headers |
- (tblock->body_only? topt_no_headers : 0) |
- (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),
- 0, /* No size limit */
- tblock->add_headers, tblock->remove_headers,
- US".", US"..", /* Escaping strings */
- tblock->rewrite_rules, tblock->rewrite_existflags);
+ ok = transport_write_message(inblock.sock, &tctx, 0);
#endif
/* transport_write_message() uses write() because it is called from other
@@ -2464,7 +2445,9 @@ if (!ok) ok = TRUE; else
int delivery_time = (int)(time(NULL) - start_delivery_time);
int len;
uschar *conf = NULL;
+
send_rset = FALSE;
+ pipelining_active = FALSE;
/* Set up confirmation if needed - applies only to SMTP */
diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h
index 8583ab468..804b9942f 100644
--- a/src/src/transports/smtp.h
+++ b/src/src/transports/smtp.h
@@ -76,12 +76,7 @@ typedef struct {
uschar *tls_verify_cert_hostnames;
#endif
#ifndef DISABLE_DKIM
- uschar *dkim_domain;
- uschar *dkim_private_key;
- uschar *dkim_selector;
- uschar *dkim_canon;
- uschar *dkim_sign_headers;
- uschar *dkim_strict;
+ struct ob_dkim dkim;
#endif
} smtp_transport_options_block;
diff --git a/src/src/verify.c b/src/src/verify.c
index 3624af0bc..c04b288dc 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -889,14 +889,16 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount.
/* Need proper integration with the proper transport mechanism. */
if (cutthrough.delivery)
{
+#ifndef DISABLE_DKIM
uschar * s;
+#endif
if (addr->transport->filter_command)
{
cutthrough.delivery = FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n");
}
#ifndef DISABLE_DKIM
- else if ((s = ob->dkim_domain) && (s = expand_string(s)) && *s)
+ else if ((s = ob->dkim.dkim_domain) && (s = expand_string(s)) && *s)
{
cutthrough.delivery = FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n");
@@ -1587,11 +1589,8 @@ if(cutthrough.fd < 0)
HDEBUG(D_acl) debug_printf("----------- start cutthrough headers send -----------\n");
if (!transport_headers_send(&cutthrough.addr, cutthrough.fd,
- cutthrough.addr.transport->add_headers,
- cutthrough.addr.transport->remove_headers,
- &cutthrough_write_chunk, TRUE,
- cutthrough.addr.transport->rewrite_rules,
- cutthrough.addr.transport->rewrite_existflags))
+ cutthrough.addr.transport,
+ &cutthrough_write_chunk, TRUE))
return FALSE;
HDEBUG(D_acl) debug_printf("----------- done cutthrough headers send ------------\n");
diff --git a/test/log/0217 b/test/log/0217
index 1328a46db..b3cf93c4b 100644
--- a/test/log/0217
+++ b/test/log/0217
@@ -8,49 +8,49 @@
1999-03-02 09:44:33 10HmaY-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 == a@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO:<b@test.ex>
-1999-03-02 09:44:33 10HmaZ-0005vi-00 == b@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO:<b@test.ex>
-1999-03-02 09:44:33 10HmaZ-0005vi-00 == c@test.ex R=client T=send_to_server defer (dd): Connection timed out: SMTP timeout after RCPT TO:<b@test.ex>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 == e@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO:<f@test.ex>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 == f@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO:<f@test.ex>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 == g@test.ex R=client T=send_to_server defer (dd): Connection timed out: SMTP timeout after RCPT TO:<f@test.ex>
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbA-0005vi-00 == a@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 451 Temp error
-1999-03-02 09:44:33 10HmbA-0005vi-00 == b@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 451 Temp error
+1999-03-02 09:44:33 10HmbA-0005vi-00 == h@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 451 Temp error
+1999-03-02 09:44:33 10HmbA-0005vi-00 == i@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 451 Temp error
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 550 Perm error
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 550 Perm error
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** j@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 550 Perm error
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** k@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 550 Perm error
1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbC-0005vi-00 ** CALLER@test.ex R=bounce: just discard
1999-03-02 09:44:33 10HmbC-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 == a@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<a@test.ex>: 451 Temp error 1
-1999-03-02 09:44:33 10HmbD-0005vi-00 == b@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@test.ex>: 451 Temp error 2
+1999-03-02 09:44:33 10HmbD-0005vi-00 == l@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<l@test.ex>: 451 Temp error 1
+1999-03-02 09:44:33 10HmbD-0005vi-00 == m@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<m@test.ex>: 451 Temp error 2
1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbE-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<a@test.ex>: 551 Perm error 1
-1999-03-02 09:44:33 10HmbE-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@test.ex>: 551 Perm error 2
+1999-03-02 09:44:33 10HmbE-0005vi-00 ** n@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<n@test.ex>: 551 Perm error 1
+1999-03-02 09:44:33 10HmbE-0005vi-00 ** o@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<o@test.ex>: 551 Perm error 2
1999-03-02 09:44:33 10HmbF-0005vi-00 <= <> R=10HmbE-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbF-0005vi-00 ** CALLER@test.ex R=bounce: just discard
1999-03-02 09:44:33 10HmbF-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbG-0005vi-00 == a@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<a@test.ex>: 451 Temp error 1
-1999-03-02 09:44:33 10HmbG-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@test.ex>: 551 Perm error 2
+1999-03-02 09:44:33 10HmbG-0005vi-00 == p@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<p@test.ex>: 451 Temp error 1
+1999-03-02 09:44:33 10HmbG-0005vi-00 ** q@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<q@test.ex>: 551 Perm error 2
1999-03-02 09:44:33 10HmbH-0005vi-00 <= <> R=10HmbG-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbH-0005vi-00 ** CALLER@test.ex R=bounce: just discard
1999-03-02 09:44:33 10HmbH-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbI-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error
-1999-03-02 09:44:33 10HmbI-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error
+1999-03-02 09:44:33 10HmbI-0005vi-00 ** r@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error
+1999-03-02 09:44:33 10HmbI-0005vi-00 ** s@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error
1999-03-02 09:44:33 10HmbJ-0005vi-00 <= <> R=10HmbI-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbJ-0005vi-00 ** CALLER@test.ex R=bounce: just discard
1999-03-02 09:44:33 10HmbJ-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
1999-03-02 09:44:33 10HmbK-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbK-0005vi-00 == a@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error
-1999-03-02 09:44:33 10HmbK-0005vi-00 == b@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error
+1999-03-02 09:44:33 10HmbK-0005vi-00 == t@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error
+1999-03-02 09:44:33 10HmbK-0005vi-00 == u@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error
1999-03-02 09:44:33 10HmbL-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmbL-0005vi-00 == yes@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error
1999-03-02 09:44:33 10HmbL-0005vi-00 ** n00@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<n00@test.ex>: 550 NO
@@ -258,12 +258,12 @@
1999-03-02 09:44:33 10HmbM-0005vi-00 CALLER@test.ex: error ignored
1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
1999-03-02 09:44:33 10HmbN-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<c@test.ex>
-1999-03-02 09:44:33 10HmbN-0005vi-00 == a@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<c@test.ex>
+1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<c@test.ex>
+1999-03-02 09:44:33 10HmbN-0005vi-00 == a@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<c@test.ex>
1999-03-02 09:44:33 10HmbN-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@test.ex>: 550 NO
-1999-03-02 09:44:33 10HmbN-0005vi-00 == c@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<c@test.ex>
-1999-03-02 09:44:33 10HmbN-0005vi-00 == d@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<c@test.ex>
-1999-03-02 09:44:33 10HmbN-0005vi-00 == e@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<c@test.ex>
+1999-03-02 09:44:33 10HmbN-0005vi-00 == c@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<c@test.ex>
+1999-03-02 09:44:33 10HmbN-0005vi-00 == d@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<c@test.ex>
+1999-03-02 09:44:33 10HmbN-0005vi-00 == e@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<c@test.ex>
1999-03-02 09:44:33 10HmbO-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbO-0005vi-00 ** CALLER@test.ex R=bounce: just discard
1999-03-02 09:44:33 10HmbO-0005vi-00 CALLER@test.ex: error ignored
diff --git a/test/log/0218 b/test/log/0218
index 4aac50dab..bdbd4141f 100644
--- a/test/log/0218
+++ b/test/log/0218
@@ -9,7 +9,7 @@
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qq
-1999-03-02 09:44:33 10HmaZ-0005vi-00 ** a@test.ex F=<CALLER@test.ex> R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 550 NO
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** a@test.ex F=<CALLER@test.ex> R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 550 NO
1999-03-02 09:44:33 10HmbB-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmbA-0005vi-00 H=127.0.0.1 [127.0.0.1] Connection refused
diff --git a/test/log/0322 b/test/log/0322
index 0c45cc5d2..f76f0695b 100644
--- a/test/log/0322
+++ b/test/log/0322
@@ -7,26 +7,26 @@
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<x@test.ex>
-1999-03-02 09:44:33 10HmaZ-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<x@test.ex>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<x@test.ex>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<x@test.ex>
1999-03-02 09:44:33 10HmaZ-0005vi-00 ** x@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <CALLER@myhost.test.ex> R=null
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to MAIL FROM:<CALLER@myhost.test.ex>
-1999-03-02 09:44:33 10HmbB-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to MAIL FROM:<CALLER@myhost.test.ex>
+1999-03-02 09:44:33 10HmbB-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined MAIL FROM:<CALLER@myhost.test.ex>
+1999-03-02 09:44:33 10HmbB-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined MAIL FROM:<CALLER@myhost.test.ex>
1999-03-02 09:44:33 10HmbB-0005vi-00 ** x@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@myhost.test.ex> R=null
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<y@test.ex>
-1999-03-02 09:44:33 10HmbD-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<y@test.ex>
-1999-03-02 09:44:33 10HmbD-0005vi-00 == y@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<y@test.ex>
-1999-03-02 09:44:33 10HmbD-0005vi-00 == z@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO:<y@test.ex>
+1999-03-02 09:44:33 10HmbD-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<y@test.ex>
+1999-03-02 09:44:33 10HmbD-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<y@test.ex>
+1999-03-02 09:44:33 10HmbD-0005vi-00 == y@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<y@test.ex>
+1999-03-02 09:44:33 10HmbD-0005vi-00 == z@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO:<y@test.ex>
1999-03-02 09:44:33 10HmbD-0005vi-00 ** z@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmbD-0005vi-00 ** y@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmbD-0005vi-00 ** x@test.ex: retry timeout exceeded
diff --git a/test/log/0495 b/test/log/0495
index 17886a809..d55d67923 100644
--- a/test/log/0495
+++ b/test/log/0495
@@ -12,12 +12,12 @@
1999-03-02 09:44:33 10HmbA-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@x.y>: 550 NOTOK
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbC-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
-1999-03-02 09:44:33 10HmbC-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
+1999-03-02 09:44:33 10HmbC-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
+1999-03-02 09:44:33 10HmbC-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmbD-0005vi-00 => pm@p.q <postmaster@x.y> R=r9 T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK"
diff --git a/test/log/0497 b/test/log/0497
index 9e55e5d29..8d47ac2b5 100644
--- a/test/log/0497
+++ b/test/log/0497
@@ -27,7 +27,7 @@
1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbF-0005vi-00 == userx@x.y R=r1 T=t1 defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 452 temporary error
+1999-03-02 09:44:33 10HmbF-0005vi-00 == userx@x.y R=r1 T=t1 defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 452 temporary error
1999-03-02 09:44:33 10HmbF-0005vi-00 ** userx@x.y: retry timeout exceeded
1999-03-02 09:44:33 10HmbG-0005vi-00 <= <> R=10HmbF-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <CALLER@myhost.test.ex> R=r0
@@ -55,8 +55,8 @@
1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
1999-03-02 09:44:33 10HmbL-0005vi-00 Completed
1999-03-02 09:44:33 10HmbN-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<userx@x.y>
-1999-03-02 09:44:33 10HmbN-0005vi-00 == userx@x.y R=r1 T=t1 defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO:<userx@x.y>
+1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<userx@x.y>
+1999-03-02 09:44:33 10HmbN-0005vi-00 == userx@x.y R=r1 T=t1 defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO:<userx@x.y>
1999-03-02 09:44:33 10HmbN-0005vi-00 ** userx@x.y: retry timeout exceeded
1999-03-02 09:44:33 10HmbO-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbO-0005vi-00 => :blackhole: <CALLER@myhost.test.ex> R=r0
diff --git a/test/log/0552 b/test/log/0552
index d070f9c8c..4ce57b114 100644
--- a/test/log/0552
+++ b/test/log/0552
@@ -1,9 +1,9 @@
1999-03-02 09:44:33 10HmaX-0005vi-00 Accept non-SMTP
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM:<CALLER@myhost.test.ex> SIZE=ssss
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx1@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00"
diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002
index 278a38660..dafcba7f0 100644
--- a/test/scripts/0000-Basic/0002
+++ b/test/scripts/0000-Basic/0002
@@ -179,6 +179,20 @@ hex2b64:${hex2b64:1a2b3c4d5e6g}
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.
diff --git a/test/scripts/0000-Basic/0217 b/test/scripts/0000-Basic/0217
index c47ae5c9e..a74be606f 100644
--- a/test/scripts/0000-Basic/0217
+++ b/test/scripts/0000-Basic/0217
@@ -36,7 +36,7 @@ RCPT TO
250 OK
*sleep 2
****
-exim -odi a b c
+exim -odi e f g
.
****
# Temp error on MAIL
@@ -56,7 +56,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi h i
.
****
# Perm error on MAIL
@@ -76,7 +76,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi j k
.
****
# All get temp errors
@@ -96,7 +96,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi l m
.
****
# All get perm errors
@@ -116,7 +116,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi n o
.
****
# Mixed temp and perm
@@ -136,7 +136,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi p q
.
****
# Perm error on DATA after good recipients
@@ -156,7 +156,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi r s
.
****
# Temp error on DATA after good recipients
@@ -176,7 +176,7 @@ DATA
QUIT
250 OK
****
-exim -odi a b
+exim -odi t u
.
****
# Temp error on DATA after good recipients, but in first block of a
diff --git a/test/stderr/0002 b/test/stderr/0002
index 19ed3479a..317b4bd0a 100644
--- a/test/stderr/0002
+++ b/test/stderr/0002
@@ -11,8 +11,8 @@ considering: abcd}{\N^([ab]+)(\w+)$\N}{$2$1}fail}
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
@@ -25,8 +25,8 @@ considering: wxyz}{\N^([ab]+)(\w+)$\N}{$2$1}fail}
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:
@@ -41,8 +41,8 @@ considering: 1}{1}{yes}{${lookup{xx}lsearch{/non/exist}}}}
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
@@ -69,8 +69,8 @@ considering: a.b.c}{yes}{no}}
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
@@ -147,8 +147,8 @@ considering: black}{white}{$sender_host_name}{No}}
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:
diff --git a/test/stderr/0092 b/test/stderr/0092
index e763efc0f..197256b81 100644
--- a/test/stderr/0092
+++ b/test/stderr/0092
@@ -57,8 +57,8 @@ considering: V4NET.0.0.1} {$sender_host_address} {2} {30}}s
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
diff --git a/test/stderr/0218 b/test/stderr/0218
index fe4ee2df9..f9f1d6849 100644
--- a/test/stderr/0218
+++ b/test/stderr/0218
@@ -93,7 +93,7 @@ Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP>> QUIT
SMTP(close)>>
LOG: MAIN
- ** a@test.ex F=<CALLER@test.ex> R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@test.ex>: 550 NO
+ ** a@test.ex F=<CALLER@test.ex> R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@test.ex>: 550 NO
Exim version x.yz ....
configuration file is TESTSUITE/test-config
trusted user
diff --git a/test/stderr/0393 b/test/stderr/0393
index c40aa6f52..941e8f89c 100644
--- a/test/stderr/0393
+++ b/test/stderr/0393
@@ -27,7 +27,7 @@ lock file created
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: write=dddd read=dddd
+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
diff --git a/test/stderr/0402 b/test/stderr/0402
index 9f95393f3..24a4fcd4d 100644
--- a/test/stderr/0402
+++ b/test/stderr/0402
@@ -49,8 +49,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -69,8 +69,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -87,8 +87,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -103,8 +103,8 @@ condition: def:sender_helo_name
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>)
@@ -112,8 +112,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -121,8 +133,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@test.ex>)
-condition: def:received_for
- result: false
+ condition: def:received_for
+ result: false
scanning:
for $received_for}}
expanding:
@@ -465,8 +477,8 @@ mailbox TESTSUITE/test-mail/junk is locked
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
@@ -520,8 +532,8 @@ mailbox TESTSUITE/test-mail/junk is locked
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
diff --git a/test/stderr/0495 b/test/stderr/0495
index b00cfd572..bfe9f6218 100644
--- a/test/stderr/0495
+++ b/test/stderr/0495
@@ -1,7 +1,7 @@
Delivery failed: Connection refused
Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<b@x.y>: 550 NOTOK
-Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
-Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
+Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 550 BAD MAIL
+Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:<CALLER@myhost.test.ex>: 450 TEMPORARY MAIL FAIL
routing file@x.y yielded a local delivery
routing fail@x.y yielded a failed delivery: forcible fail message
routing defer@x.y yielded a deferred delivery: forcible defer message
diff --git a/test/stderr/0544 b/test/stderr/0544
index a95583ab7..f950e456c 100644
--- a/test/stderr/0544
+++ b/test/stderr/0544
@@ -11,8 +11,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -31,8 +31,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -49,8 +49,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -65,8 +65,8 @@ condition: def:sender_helo_name
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>)
@@ -74,8 +74,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -83,8 +95,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@test.ex>)
-condition: def:received_for
- result: false
+ condition: def:received_for
+ result: false
scanning:
for $received_for}}
expanding:
@@ -138,8 +150,8 @@ considering: $h_auto-submitted:}{(?i)auto-generated|auto-replied} }} {no}{yes}}
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
@@ -169,8 +181,8 @@ considering: +dlist}}
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
diff --git a/test/stderr/4504 b/test/stderr/4504
new file mode 100644
index 000000000..045fadc9b
--- /dev/null
+++ b/test/stderr/4504
@@ -0,0 +1,2 @@
+
+******** SERVER ********
diff --git a/test/stderr/5410 b/test/stderr/5410
index 41f6bab6f..837941d17 100644
--- a/test/stderr/5410
+++ b/test/stderr/5410
@@ -17,8 +17,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -68,8 +68,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: false
+ condition: eq {$address_data}{usery}
+ result: false
scanning: *}{:}}
expanding: *
result: *
@@ -87,8 +87,8 @@ considering: $address_data}{userz}{*}{:}}
considering: userz}{*}{:}}
expanding: userz
result: userz
-condition: eq {$address_data}{userz}
- result: false
+ condition: eq {$address_data}{userz}
+ result: false
scanning: *}{:}}
expanding: *
result: *
@@ -133,8 +133,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -153,8 +153,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -171,8 +171,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -187,8 +187,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -196,8 +196,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -205,8 +217,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
@@ -262,8 +274,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -313,8 +325,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
@@ -347,8 +359,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -367,8 +379,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -385,8 +397,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -401,8 +413,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -410,8 +422,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -419,8 +443,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
@@ -476,8 +500,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -527,8 +551,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
@@ -561,8 +585,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -581,8 +605,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -599,8 +623,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -615,8 +639,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -624,8 +648,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -633,8 +669,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
diff --git a/test/stderr/5420 b/test/stderr/5420
index 2cac1a73f..a1d4d3267 100644
--- a/test/stderr/5420
+++ b/test/stderr/5420
@@ -17,8 +17,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -68,8 +68,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: false
+ condition: eq {$address_data}{usery}
+ result: false
scanning: *}{:}}
expanding: *
result: *
@@ -87,8 +87,8 @@ considering: $address_data}{userz}{*}{:}}
considering: userz}{*}{:}}
expanding: userz
result: userz
-condition: eq {$address_data}{userz}
- result: false
+ condition: eq {$address_data}{userz}
+ result: false
scanning: *}{:}}
expanding: *
result: *
@@ -132,8 +132,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -152,8 +152,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -170,8 +170,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -186,8 +186,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -195,8 +195,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -204,8 +216,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
@@ -261,8 +273,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -312,8 +324,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
@@ -346,8 +358,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -366,8 +378,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -384,8 +396,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -400,8 +412,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -409,8 +421,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -418,8 +442,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
@@ -475,8 +499,8 @@ considering: SERVER}{server}{queue}{cutthrough}}
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
@@ -526,8 +550,8 @@ considering: $address_data}{usery}{*}{:}}
considering: usery}{*}{:}}
expanding: usery
result: usery
-condition: eq {$address_data}{usery}
- result: true
+ condition: eq {$address_data}{usery}
+ result: true
considering: *}{:}}
expanding: *
result: *
@@ -560,8 +584,8 @@ considering: Received: ${if def:sender_rcvhost {from $sender_rcvhost
${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)
@@ -580,8 +604,8 @@ considering: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${i
${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)
@@ -598,8 +622,8 @@ considering: $sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name
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)
@@ -614,8 +638,8 @@ considering: (helo=$sender_helo_name)
}}
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>)
@@ -623,8 +647,20 @@ considering: with $received_protocol}} ${if def:tls_cipher {($tls_cipher)
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}}
@@ -632,8 +668,8 @@ considering: (envelope-from <$sender_address>)
result: (envelope-from <CALLER@myhost.test.ex>)
-condition: def:received_for
- result: true
+ condition: def:received_for
+ result: true
considering:
for $received_for}}
expanding:
diff --git a/test/stdout/0002 b/test/stdout/0002
index 0bbd4c754..a19cc526c 100644
--- a/test/stdout/0002
+++ b/test/stdout/0002
@@ -169,6 +169,20 @@
> 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.
diff --git a/test/stdout/0217 b/test/stdout/0217
index 8633a43ee..f08a3fab6 100644
--- a/test/stdout/0217
+++ b/test/stdout/0217
@@ -36,7 +36,7 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<e@test.ex>
250 OK
*sleep 2
End of script
@@ -48,9 +48,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
451 Temp error
-RCPT TO:<a@test.ex>
+RCPT TO:<h@test.ex>
503 No sender given
-RCPT TO:<b@test.ex>
+RCPT TO:<i@test.ex>
503 No sender given
DATA
503 No envelope
@@ -65,9 +65,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
550 Perm error
-RCPT TO:<a@test.ex>
+RCPT TO:<j@test.ex>
503 No sender given
-RCPT TO:<b@test.ex>
+RCPT TO:<k@test.ex>
503 No sender given
DATA
503 No envelope
@@ -82,9 +82,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<l@test.ex>
451 Temp error 1
-RCPT TO:<b@test.ex>
+RCPT TO:<m@test.ex>
451 Temp error 2
DATA
503 No recipients
@@ -99,9 +99,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<n@test.ex>
551 Perm error 1
-RCPT TO:<b@test.ex>
+RCPT TO:<o@test.ex>
551 Perm error 2
DATA
503 No recipients
@@ -116,9 +116,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<p@test.ex>
451 Temp error 1
-RCPT TO:<b@test.ex>
+RCPT TO:<q@test.ex>
551 Perm error 2
DATA
503 No recipients
@@ -133,9 +133,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<r@test.ex>
250 OK
-RCPT TO:<b@test.ex>
+RCPT TO:<s@test.ex>
250 OK
DATA
503 Sorry perm data error
@@ -150,9 +150,9 @@ EHLO myhost.test.ex
250 PIPELINING
MAIL FROM:<CALLER@test.ex>
250 OK
-RCPT TO:<a@test.ex>
+RCPT TO:<t@test.ex>
250 OK
-RCPT TO:<b@test.ex>
+RCPT TO:<u@test.ex>
250 OK
DATA
403 Sorry temp data error