diff options
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 |