From: Jeremy Harris Date: Sat, 6 Aug 2016 13:04:45 +0000 (+0100) Subject: Merge branch 'CHUNKING' X-Git-Tag: exim-4_88_RC1~52 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/44bc8f0c2f3576b46bd6df1b818cb29eaf84df5b?hp=2d14f39731e88a6d6bb9f1b5c56f497eb12198c4 Merge branch 'CHUNKING' --- diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 6302f5185..d18dd0ce1 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" @@ -19883,12 +19898,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. @@ -31555,7 +31575,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, @@ -31682,6 +31702,11 @@ spam bar is 50 characters. A multiline text table, containing the full SpamAssassin report for the message. Useful for inclusion in headers or reject messages. This variable is only usable in a DATA-time ACL. +.new +Beware that SpamAssassin may return non-ASCII characters, especially +when running in country-specific locales, which are not legal +unencoded in headers. +.wen .vitem &$spam_action$& For SpamAssassin either 'reject' or 'no action' depending on the @@ -35419,6 +35444,7 @@ picked out by the distinctive two-character flags that immediately follow the timestamp. The flags are: .display &`<=`& message arrival +&`(=`& message fakereject &`=>`& normal message delivery &`->`& additional address in same delivery &`>>`& cutthrough message delivery @@ -38091,7 +38117,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 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 0fe63f123..11b25f875 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -55,6 +55,19 @@ 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 Fix logging of errors under PIPELINING. Previously the log line giving + the relevant preceding SMTP command did not note the pipelining mode. + +JH/15 Fix counting of empty lines in $body_linecount and $message_linecount. + Previously they were not counted. + +JH/16 DANE: treat a TLSA lookup response having all non-TLSA RRs, the same + as one having no matching records. Previously we deferred the message + that needed the lookup. + +JH/17 Fakereject: previously logged as a norml message arrival "<="; now + distinguished as "(=". + Exim version 4.87 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 9e2be8372..719bedf31 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -26,7 +26,9 @@ Version 4.88 the queue to be used for a message. A $queue_name variable gives visibility. - 6. The CHUNKING ESMTP extension from RFC 3030. May give some slight + 6. New expansion operators base32/base32d. + + 7. The CHUNKING ESMTP extension from RFC 3030. May give some slight performance increase and network load decrease. Main config option chunking_advertise_hosts, and smtp transport option hosts_try_chunking for control. diff --git a/src/src/deliver.c b/src/src/deliver.c index a8d740cde..eae675753 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -836,6 +836,184 @@ router_name = transport_name = NULL; +/******************************************************************************/ + + +/************************************************* +* Generate local prt for logging * +*************************************************/ + +/* This function is a subroutine for use in string_log_address() below. + +Arguments: + addr the address being logged + yield the current dynamic buffer pointer + sizeptr points to current size + ptrptr points to current insert pointer + +Returns: the new value of the buffer pointer +*/ + +static uschar * +string_get_localpart(address_item *addr, uschar *yield, int *sizeptr, + int *ptrptr) +{ +uschar * s; + +s = addr->prefix; +if (testflag(addr, af_include_affixes) && s) + { +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + yield = string_cat(yield, sizeptr, ptrptr, s); + } + +s = addr->local_part; +#ifdef SUPPORT_I18N +if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif +yield = string_cat(yield, sizeptr, ptrptr, s); + +s = addr->suffix; +if (testflag(addr, af_include_affixes) && s) + { +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + yield = string_cat(yield, sizeptr, ptrptr, s); + } + +return yield; +} + + +/************************************************* +* Generate log address list * +*************************************************/ + +/* This function generates a list consisting of an address and its parents, for +use in logging lines. For saved onetime aliased addresses, the onetime parent +field is used. If the address was delivered by a transport with rcpt_include_ +affixes set, the af_include_affixes bit will be set in the address. In that +case, we include the affixes here too. + +Arguments: + str points to start of growing string, or NULL + size points to current allocation for string + ptr points to offset for append point; updated on exit + addr bottom (ultimate) address + all_parents if TRUE, include all parents + success TRUE for successful delivery + +Returns: a growable string in dynamic store +*/ + +static uschar * +string_log_address(uschar * str, int * size, int * ptr, + address_item *addr, BOOL all_parents, BOOL success) +{ +BOOL add_topaddr = TRUE; +address_item *topaddr; + +/* Find the ultimate parent */ + +for (topaddr = addr; topaddr->parent; topaddr = topaddr->parent) ; + +/* We start with just the local part for pipe, file, and reply deliveries, and +for successful local deliveries from routers that have the log_as_local flag +set. File deliveries from filters can be specified as non-absolute paths in +cases where the transport is goin to complete the path. If there is an error +before this happens (expansion failure) the local part will not be updated, and +so won't necessarily look like a path. Add extra text for this case. */ + +if ( testflag(addr, af_pfr) + || ( success + && addr->router && addr->router->log_as_local + && addr->transport && addr->transport->info->local + ) ) + { + if (testflag(addr, af_file) && addr->local_part[0] != '/') + str = string_catn(str, size, ptr, CUS"save ", 5); + str = string_get_localpart(addr, str, size, ptr); + } + +/* Other deliveries start with the full address. It we have split it into local +part and domain, use those fields. Some early failures can happen before the +splitting is done; in those cases use the original field. */ + +else + { + uschar * cmp = str + *ptr; + + if (addr->local_part) + { + const uschar * s; + str = string_get_localpart(addr, str, size, ptr); + str = string_catn(str, size, ptr, US"@", 1); + s = addr->domain; +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + str = string_cat(str, size, ptr, s); + } + else + str = string_cat(str, size, ptr, addr->address); + + /* If the address we are going to print is the same as the top address, + and all parents are not being included, don't add on the top address. First + of all, do a caseless comparison; if this succeeds, do a caseful comparison + on the local parts. */ + + str[*ptr] = 0; + if ( strcmpic(cmp, topaddr->address) == 0 + && Ustrncmp(cmp, topaddr->address, Ustrchr(cmp, '@') - cmp) == 0 + && !addr->onetime_parent + && (!all_parents || !addr->parent || addr->parent == topaddr) + ) + add_topaddr = FALSE; + } + +/* If all parents are requested, or this is a local pipe/file/reply, and +there is at least one intermediate parent, show it in brackets, and continue +with all of them if all are wanted. */ + +if ( (all_parents || testflag(addr, af_pfr)) + && addr->parent + && addr->parent != topaddr) + { + uschar *s = US" ("; + address_item *addr2; + for (addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent) + { + str = string_catn(str, size, ptr, s, 2); + str = string_cat (str, size, ptr, addr2->address); + if (!all_parents) break; + s = US", "; + } + str = string_catn(str, size, ptr, US")", 1); + } + +/* Add the top address if it is required */ + +if (add_topaddr) + str = string_append(str, size, ptr, 3, + US" <", + addr->onetime_parent ? addr->onetime_parent : topaddr->address, + US">"); + +return str; +} + + +/******************************************************************************/ + + + /* If msg is NULL this is a delivery log and logchar is used. Otherwise this is a nonstandard call; no two-character delivery flag is written but sender-host and sender are prefixed and "msg" is inserted in the log line. @@ -846,11 +1024,10 @@ Arguments: void delivery_log(int flags, address_item * addr, int logchar, uschar * msg) { -uschar *log_address; int size = 256; /* Used for a temporary, */ int ptr = 0; /* expanding buffer, for */ -uschar *s; /* building log lines; */ -void *reset_point; /* released afterwards. */ +uschar * s; /* building log lines; */ +void * reset_point; /* released afterwards. */ /* Log the delivery on the main log. We use an extensible string to build up the log line, and reset the store afterwards. Remote deliveries should always @@ -864,14 +1041,14 @@ pointer to a single host item in their host list, for use by the transport. */ s = reset_point = store_get(size); -log_address = string_log_address(addr, LOGGING(all_parents), TRUE); if (msg) - s = string_append(s, &size, &ptr, 3, host_and_ident(TRUE), US" ", log_address); + s = string_append(s, &size, &ptr, 2, host_and_ident(TRUE), US" "); else { s[ptr++] = logchar; - s = string_append(s, &size, &ptr, 2, US"> ", log_address); + s = string_catn(s, &size, &ptr, US"> ", 2); } +s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), TRUE); if (LOGGING(sender_on_delivery) || msg) s = string_append(s, &size, &ptr, 3, US" F=<", @@ -1017,6 +1194,163 @@ return; +static void +deferral_log(address_item * addr, uschar * now, + int logflags, uschar * driver_name, uschar * driver_kind) +{ +int size = 256; /* Used for a temporary, */ +int ptr = 0; /* expanding buffer, for */ +uschar * s; /* building log lines; */ +void * reset_point; /* released afterwards. */ + +uschar ss[32]; + +/* Build up the line that is used for both the message log and the main +log. */ + +s = reset_point = store_get(size); + +/* Create the address string for logging. Must not do this earlier, because +an OK result may be changed to FAIL when a pipe returns text. */ + +s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), FALSE); + +if (*queue_name) + s = string_append(s, &size, &ptr, 2, US" Q=", queue_name); + +/* Either driver_name contains something and driver_kind contains +" router" or " transport" (note the leading space), or driver_name is +a null string and driver_kind contains "routing" without the leading +space, if all routing has been deferred. When a domain has been held, +so nothing has been done at all, both variables contain null strings. */ + +if (driver_name) + { + if (driver_kind[1] == 't' && addr->router) + s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name); + Ustrcpy(ss, " ?="); + ss[1] = toupper(driver_kind[1]); + s = string_append(s, &size, &ptr, 2, ss, driver_name); + } +else if (driver_kind) + s = string_append(s, &size, &ptr, 2, US" ", driver_kind); + +/*XXX need an s+s+p sprintf */ +sprintf(CS ss, " defer (%d)", addr->basic_errno); +s = string_cat(s, &size, &ptr, ss); + +if (addr->basic_errno > 0) + s = string_append(s, &size, &ptr, 2, US": ", + US strerror(addr->basic_errno)); + +if (addr->host_used) + { + s = string_append(s, &size, &ptr, 5, + US" H=", addr->host_used->name, + US" [", addr->host_used->address, US"]"); + if (LOGGING(outgoing_port)) + { + int port = addr->host_used->port; + s = string_append(s, &size, &ptr, 2, + US":", port == PORT_NONE ? US"25" : string_sprintf("%d", port)); + } + } + +if (addr->message) + s = string_append(s, &size, &ptr, 2, US": ", addr->message); + +s[ptr] = 0; + +/* Log the deferment in the message log, but don't clutter it +up with retry-time defers after the first delivery attempt. */ + +if (deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE) + deliver_msglog("%s %s\n", now, s); + +/* Write the main log and reset the store. +For errors of the type "retry time not reached" (also remotes skipped +on queue run), logging is controlled by L_retry_defer. Note that this kind +of error number is negative, and all the retry ones are less than any +others. */ + + +log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags, + "== %s", s); + +store_reset(reset_point); +return; +} + + + +static void +failure_log(address_item * addr, uschar * driver_kind, uschar * now) +{ +int size = 256; /* Used for a temporary, */ +int ptr = 0; /* expanding buffer, for */ +uschar * s; /* building log lines; */ +void * reset_point; /* released afterwards. */ + +/* Build up the log line for the message and main logs */ + +s = reset_point = store_get(size); + +/* Create the address string for logging. Must not do this earlier, because +an OK result may be changed to FAIL when a pipe returns text. */ + +s = string_log_address(s, &size, &ptr, addr, LOGGING(all_parents), FALSE); + +if (LOGGING(sender_on_delivery)) + s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">"); + +if (*queue_name) + s = string_append(s, &size, &ptr, 2, US" Q=", queue_name); + +/* Return path may not be set if no delivery actually happened */ + +if (used_return_path && LOGGING(return_path_on_delivery)) + s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">"); + +if (addr->router) + s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name); +if (addr->transport) + s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name); + +if (addr->host_used) + s = d_hostlog(s, &size, &ptr, addr); + +#ifdef SUPPORT_TLS +s = d_tlslog(s, &size, &ptr, addr); +#endif + +if (addr->basic_errno > 0) + s = string_append(s, &size, &ptr, 2, US": ", US strerror(addr->basic_errno)); + +if (addr->message) + s = string_append(s, &size, &ptr, 2, US": ", addr->message); + +s[ptr] = 0; + +/* Do the logging. For the message log, "routing failed" for those cases, +just to make it clearer. */ + +if (driver_kind) + deliver_msglog("%s %s failed for %s\n", now, driver_kind, s); +else + deliver_msglog("%s %s\n", now, s); + +log_write(0, LOG_MAIN, "** %s", s); + +#ifndef DISABLE_EVENT +msg_event_raise(US"msg:fail:delivery", addr); +#endif + +store_reset(reset_point); +return; +} + + + /************************************************* * Actions at the end of handling an address * *************************************************/ @@ -1042,12 +1376,6 @@ post_process_one(address_item *addr, int result, int logflags, int driver_type, uschar *now = tod_stamp(tod_log); uschar *driver_kind = NULL; uschar *driver_name = NULL; -uschar *log_address; - -int size = 256; /* Used for a temporary, */ -int ptr = 0; /* expanding buffer, for */ -uschar *s; /* building log lines; */ -void *reset_point; /* released afterwards. */ DEBUG(D_deliver) debug_printf("post-process %s (%d)\n", addr->address, result); @@ -1253,85 +1581,7 @@ else if (result == DEFER || result == PANIC) log or the main log for SMTP defers. */ if (!queue_2stage || addr->basic_errno != 0) - { - uschar ss[32]; - - /* For errors of the type "retry time not reached" (also remotes skipped - on queue run), logging is controlled by L_retry_defer. Note that this kind - of error number is negative, and all the retry ones are less than any - others. */ - - unsigned int use_log_selector = addr->basic_errno <= ERRNO_RETRY_BASE - ? L_retry_defer : 0; - - /* Build up the line that is used for both the message log and the main - log. */ - - s = reset_point = store_get(size); - - /* Create the address string for logging. Must not do this earlier, because - an OK result may be changed to FAIL when a pipe returns text. */ - - log_address = string_log_address(addr, LOGGING(all_parents), result == OK); - - s = string_cat(s, &size, &ptr, log_address); - - if (*queue_name) - s = string_append(s, &size, &ptr, 2, US" Q=", queue_name); - - /* Either driver_name contains something and driver_kind contains - " router" or " transport" (note the leading space), or driver_name is - a null string and driver_kind contains "routing" without the leading - space, if all routing has been deferred. When a domain has been held, - so nothing has been done at all, both variables contain null strings. */ - - if (driver_name) - { - if (driver_kind[1] == 't' && addr->router) - s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name); - Ustrcpy(ss, " ?="); - ss[1] = toupper(driver_kind[1]); - s = string_append(s, &size, &ptr, 2, ss, driver_name); - } - else if (driver_kind) - s = string_append(s, &size, &ptr, 2, US" ", driver_kind); - - sprintf(CS ss, " defer (%d)", addr->basic_errno); - s = string_cat(s, &size, &ptr, ss); - - if (addr->basic_errno > 0) - s = string_append(s, &size, &ptr, 2, US": ", - US strerror(addr->basic_errno)); - - if (addr->host_used) - { - s = string_append(s, &size, &ptr, 5, - US" H=", addr->host_used->name, - US" [", addr->host_used->address, US"]"); - if (LOGGING(outgoing_port)) - { - int port = addr->host_used->port; - s = string_append(s, &size, &ptr, 2, - US":", port == PORT_NONE ? US"25" : string_sprintf("%d", port)); - } - } - - if (addr->message) - s = string_append(s, &size, &ptr, 2, US": ", addr->message); - - s[ptr] = 0; - - /* Log the deferment in the message log, but don't clutter it - up with retry-time defers after the first delivery attempt. */ - - if (deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE) - deliver_msglog("%s %s\n", now, s); - - /* Write the main log and reset the store */ - - log_write(use_log_selector, logflags, "== %s", s); - store_reset(reset_point); - } + deferral_log(addr, now, logflags, driver_name, driver_kind); } @@ -1386,64 +1636,7 @@ else addr_failed = addr; } - /* Build up the log line for the message and main logs */ - - s = reset_point = store_get(size); - - /* Create the address string for logging. Must not do this earlier, because - an OK result may be changed to FAIL when a pipe returns text. */ - - log_address = string_log_address(addr, LOGGING(all_parents), result == OK); - - s = string_cat(s, &size, &ptr, log_address); - - if (LOGGING(sender_on_delivery)) - s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">"); - - if (*queue_name) - s = string_append(s, &size, &ptr, 2, US" Q=", queue_name); - - /* Return path may not be set if no delivery actually happened */ - - if (used_return_path && LOGGING(return_path_on_delivery)) - s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">"); - - if (addr->router) - s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name); - if (addr->transport) - s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name); - - if (addr->host_used) - s = d_hostlog(s, &size, &ptr, addr); - -#ifdef SUPPORT_TLS - s = d_tlslog(s, &size, &ptr, addr); -#endif - - if (addr->basic_errno > 0) - s = string_append(s, &size, &ptr, 2, US": ", - US strerror(addr->basic_errno)); - - if (addr->message) - s = string_append(s, &size, &ptr, 2, US": ", addr->message); - - s[ptr] = 0; - - /* Do the logging. For the message log, "routing failed" for those cases, - just to make it clearer. */ - - if (driver_name) - deliver_msglog("%s %s\n", now, s); - else - deliver_msglog("%s %s failed for %s\n", now, driver_kind, s); - - log_write(0, LOG_MAIN, "** %s", s); - -#ifndef DISABLE_EVENT - msg_event_raise(US"msg:fail:delivery", addr); -#endif - - store_reset(reset_point); + failure_log(addr, driver_name ? NULL : driver_kind, now); } /* Ensure logging is turned on again in all cases */ diff --git a/src/src/dkim.c b/src/src/dkim.c index a09ec7eca..f09d438d5 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? */ } @@ -98,10 +98,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; } @@ -113,6 +119,7 @@ pdkim_signature *sig = NULL; int dkim_signers_size = 0; int dkim_signers_ptr = 0; dkim_signers = NULL; +int rc; store_pool = POOL_PERM; @@ -137,8 +144,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) { @@ -481,8 +492,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. */ @@ -519,8 +529,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 */ @@ -531,8 +540,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) @@ -553,8 +561,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 */ @@ -564,8 +571,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 @@ -587,25 +593,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, @@ -616,27 +620,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"); @@ -654,11 +650,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 8d47a0da1..8745a399c 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -438,7 +438,6 @@ extern int string_is_ip_address(const uschar *, int *); #ifdef SUPPORT_I18N extern BOOL string_is_utf8(const uschar *); #endif -extern uschar *string_log_address(address_item *, BOOL, BOOL); extern uschar *string_nextinlist(const uschar **, int *, uschar *, int); extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3); extern const uschar *string_printing2(const uschar *, BOOL); diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index a0f022685..f468d232b 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -115,28 +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"; - case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR"; - case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION"; - default: return "PDKIM_VERIFY_UNKNOWN"; +switch(ext_status) + { + case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY"; + case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE"; + case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE"; + case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE"; + case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD"; + case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT: return "PDKIM_VERIFY_INVALID_PUBKEY_IMPORT"; + case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR: return "PDKIM_VERIFY_INVALID_SIGNATURE_ERROR"; + case PDKIM_VERIFY_INVALID_DKIM_VERSION: return "PDKIM_VERIFY_INVALID_DKIM_VERSION"; + default: return "PDKIM_VERIFY_UNKNOWN"; + } +} + +const char * +pdkim_errstr(int status) +{ +switch(status) + { + case PDKIM_OK: return "OK"; + case PDKIM_FAIL: return "FAIL"; + case PDKIM_ERR_RSA_PRIVKEY: return "RSA_PRIVKEY"; + case PDKIM_ERR_RSA_SIGNING: return "RSA SIGNING"; + case PDKIM_ERR_LONG_LINE: return "RSA_LONG_LINE"; + case PDKIM_ERR_BUFFER_TOO_SMALL: return "BUFFER_TOO_SMALL"; + case PDKIM_SIGN_PRIVKEY_WRAP: return "PRIVKEY_WRAP"; + case PDKIM_SIGN_PRIVKEY_B64D: return "PRIVKEY_B64D"; + default: return "(unknown)"; } } diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index 0803ea0b0..5d0157e63 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -304,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/receive.c b/src/src/receive.c index 3b048252d..6a8ce8841 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -3820,9 +3820,10 @@ size = 256; sptr = 0; s = store_get(size); -s = string_append(s, &size, &sptr, 2, US"<= ", - (sender_address[0] == 0)? US"<>" : sender_address); -if (message_reference != NULL) +s = string_append(s, &size, &sptr, 2, + fake_response == FAIL ? US"(= " : US"<= ", + sender_address[0] == 0 ? US"<>" : sender_address); +if (message_reference) s = string_append(s, &size, &sptr, 2, US" R=", message_reference); s = add_host_info_for_log(s, &size, &sptr); @@ -3832,7 +3833,7 @@ if (LOGGING(tls_cipher) && tls_in.cipher) s = string_append(s, &size, &sptr, 2, US" X=", tls_in.cipher); if (LOGGING(tls_certificate_verified) && tls_in.cipher) s = string_append(s, &size, &sptr, 2, US" CV=", - tls_in.certificate_verified? "yes":"no"); + tls_in.certificate_verified ? "yes":"no"); if (LOGGING(tls_peerdn) && tls_in.peerdn) s = string_append(s, &size, &sptr, 3, US" DN=\"", string_printing(tls_in.peerdn), US"\""); @@ -3844,10 +3845,10 @@ if (LOGGING(tls_sni) && tls_in.sni) if (sender_host_authenticated) { s = string_append(s, &size, &sptr, 2, US" A=", sender_host_authenticated); - if (authenticated_id != NULL) + if (authenticated_id) { s = string_append(s, &size, &sptr, 2, US":", authenticated_id); - if (LOGGING(smtp_mailauth) && authenticated_sender != NULL) + if (LOGGING(smtp_mailauth) && authenticated_sender) s = string_append(s, &size, &sptr, 2, US":", authenticated_sender); } } @@ -3886,7 +3887,7 @@ any characters except " \ and CR and so in particular it can contain NL! Therefore, make sure we use a printing-characters only version for the log. Also, allow for domain literals in the message id. */ -if (msgid_header != NULL) +if (msgid_header) { uschar *old_id; BOOL save_allow_domain_literals = allow_domain_literals; @@ -3969,7 +3970,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); } } @@ -4089,7 +4092,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; @@ -4145,15 +4150,15 @@ if (smtp_input) if (!smtp_batched_input) { - if (smtp_reply == NULL) + if (!smtp_reply) { if (fake_response != OK) - smtp_respond((fake_response == DEFER)? US"450" : US"550", 3, TRUE, - fake_response_text); + smtp_respond(fake_response == DEFER ? US"450" : US"550", + 3, TRUE, fake_response_text); /* An OK response is required; use "message" text if present. */ - else if (user_msg != NULL) + else if (user_msg) { uschar *code = US"250"; int len = 3; @@ -4207,7 +4212,8 @@ if (smtp_input) nothing on success. The function moan_smtp_batch() does not return - it exits from the program with a non-zero return code. */ - else if (smtp_reply != NULL) moan_smtp_batch(NULL, "%s", smtp_reply); + else if (smtp_reply) + moan_smtp_batch(NULL, "%s", smtp_reply); } @@ -4216,7 +4222,7 @@ file has already been unlinked, and the header file was never written to disk. We must now indicate that nothing was received, to prevent a delivery from starting. */ -if (blackholed_by != NULL) +if (blackholed_by) { const uschar *detail = local_scan_data ? string_printing(local_scan_data) diff --git a/src/src/string.c b/src/src/string.c index 963948f77..ad074e37e 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1544,177 +1544,6 @@ return (eno == EACCES)? -#ifndef COMPILE_UTILITY -/************************************************* -* Generate local prt for logging * -*************************************************/ - -/* This function is a subroutine for use in string_log_address() below. - -Arguments: - addr the address being logged - yield the current dynamic buffer pointer - sizeptr points to current size - ptrptr points to current insert pointer - -Returns: the new value of the buffer pointer -*/ - -static uschar * -string_get_localpart(address_item *addr, uschar *yield, int *sizeptr, - int *ptrptr) -{ -uschar * s; - -s = addr->prefix; -if (testflag(addr, af_include_affixes) && s) - { -#ifdef SUPPORT_I18N - if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif - yield = string_cat(yield, sizeptr, ptrptr, s); - } - -s = addr->local_part; -#ifdef SUPPORT_I18N -if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif -yield = string_cat(yield, sizeptr, ptrptr, s); - -s = addr->suffix; -if (testflag(addr, af_include_affixes) && s) - { -#ifdef SUPPORT_I18N - if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif - yield = string_cat(yield, sizeptr, ptrptr, s); - } - -return yield; -} - - -/************************************************* -* Generate log address list * -*************************************************/ - -/* This function generates a list consisting of an address and its parents, for -use in logging lines. For saved onetime aliased addresses, the onetime parent -field is used. If the address was delivered by a transport with rcpt_include_ -affixes set, the af_include_affixes bit will be set in the address. In that -case, we include the affixes here too. - -Arguments: - addr bottom (ultimate) address - all_parents if TRUE, include all parents - success TRUE for successful delivery - -Returns: a string in dynamic store -*/ - -uschar * -string_log_address(address_item *addr, BOOL all_parents, BOOL success) -{ -int size = 64; -int ptr = 0; -BOOL add_topaddr = TRUE; -uschar *yield = store_get(size); -address_item *topaddr; - -/* Find the ultimate parent */ - -for (topaddr = addr; topaddr->parent != NULL; topaddr = topaddr->parent); - -/* We start with just the local part for pipe, file, and reply deliveries, and -for successful local deliveries from routers that have the log_as_local flag -set. File deliveries from filters can be specified as non-absolute paths in -cases where the transport is goin to complete the path. If there is an error -before this happens (expansion failure) the local part will not be updated, and -so won't necessarily look like a path. Add extra text for this case. */ - -if (testflag(addr, af_pfr) || - (success && - addr->router != NULL && addr->router->log_as_local && - addr->transport != NULL && addr->transport->info->local)) - { - if (testflag(addr, af_file) && addr->local_part[0] != '/') - yield = string_catn(yield, &size, &ptr, CUS"save ", 5); - yield = string_get_localpart(addr, yield, &size, &ptr); - } - -/* Other deliveries start with the full address. It we have split it into local -part and domain, use those fields. Some early failures can happen before the -splitting is done; in those cases use the original field. */ - -else - { - if (addr->local_part != NULL) - { - const uschar * s; - yield = string_get_localpart(addr, yield, &size, &ptr); - yield = string_catn(yield, &size, &ptr, US"@", 1); - s = addr->domain; -#ifdef SUPPORT_I18N - if (testflag(addr, af_utf8_downcvt)) - s = string_localpart_utf8_to_alabel(s, NULL); -#endif - yield = string_cat(yield, &size, &ptr, s); - } - else - yield = string_cat(yield, &size, &ptr, addr->address); - yield[ptr] = 0; - - /* If the address we are going to print is the same as the top address, - and all parents are not being included, don't add on the top address. First - of all, do a caseless comparison; if this succeeds, do a caseful comparison - on the local parts. */ - - if (strcmpic(yield, topaddr->address) == 0 && - Ustrncmp(yield, topaddr->address, Ustrchr(yield, '@') - yield) == 0 && - addr->onetime_parent == NULL && - (!all_parents || addr->parent == NULL || addr->parent == topaddr)) - add_topaddr = FALSE; - } - -/* If all parents are requested, or this is a local pipe/file/reply, and -there is at least one intermediate parent, show it in brackets, and continue -with all of them if all are wanted. */ - -if ((all_parents || testflag(addr, af_pfr)) && - addr->parent != NULL && - addr->parent != topaddr) - { - uschar *s = US" ("; - address_item *addr2; - for (addr2 = addr->parent; addr2 != topaddr; addr2 = addr2->parent) - { - yield = string_catn(yield, &size, &ptr, s, 2); - yield = string_cat (yield, &size, &ptr, addr2->address); - if (!all_parents) break; - s = US", "; - } - yield = string_catn(yield, &size, &ptr, US")", 1); - } - -/* Add the top address if it is required */ - -if (add_topaddr) - { - yield = string_catn(yield, &size, &ptr, US" <", 2); - - yield = string_cat(yield, &size, &ptr, - addr->onetime_parent ? addr->onetime_parent : topaddr->address); - - yield = string_catn(yield, &size, &ptr, US">", 1); - } - -yield[ptr] = 0; /* string_cat() leaves space */ -return yield; -} -#endif /* COMPILE_UTILITY */ #ifndef COMPILE_UTILITY diff --git a/src/src/transport.c b/src/src/transport.c index 88d925e39..a68c22f29 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -616,13 +616,8 @@ Arguments: addr (chain of) addresses (for extra headers), or NULL; only the first address is used fd file descriptor to write the message to + tctx transport context sendfn function for output (transport or verify) - wck_flags - use_crlf turn NL into CR LF - use_bdat callback before chunk flush - rewrite_rules chain of header rewriting rules - rewrite_existflags flags for the rewriting rules - chunk_cb transport callback function for data-chunk commands Returns: TRUE on success; FALSE on failure. */ @@ -1228,6 +1223,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 diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 25e493433..52b2b913f 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1223,7 +1223,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: @@ -2483,7 +2484,7 @@ else | (tblock->headers_only ? topt_no_body : 0) | (tblock->return_path_add ? topt_add_return_path : 0) | (tblock->delivery_date_add ? topt_add_delivery_date : 0) - | (tblock->envelope_to_add ? topt_add_envelope_to : 0), + | (tblock->envelope_to_add ? topt_add_envelope_to : 0) }; /* If using CHUNKING we need a callback from the generic transport diff --git a/test/log/0555 b/test/log/0555 index e223bd466..29d71cd21 100644 --- a/test/log/0555 +++ b/test/log/0555 @@ -1,2 +1,2 @@ -1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 (= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss diff --git a/test/log/4010 b/test/log/4010 index 1ab5847e6..c1176fee6 100644 --- a/test/log/4010 +++ b/test/log/4010 @@ -1,6 +1,6 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex 1999-03-02 09:44:33 10HmaX-0005vi-00 => userx R=r1 T=t1 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 (= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex 1999-03-02 09:44:33 10HmaY-0005vi-00 => userx R=r1 T=t1 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed 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/0555 b/test/scripts/0000-Basic/0555 index 947f1692d..c35113603 100644 --- a/test/scripts/0000-Basic/0555 +++ b/test/scripts/0000-Basic/0555 @@ -1,4 +1,4 @@ -# Long lines for fakedefer/fakereject +# Long response lines for fakedefer/fakereject exim -bs mail from:<> rcpt to: 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/0393 b/test/stderr/0393 index 673d9e6f9..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: fd_write=10 fd_read=11 +process pppp running as transport filter: fd_write=9 fd_read=10 writing data block fd=dddd size=sss timeout=0 process pppp writing to transport filter copying from the filter 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 ) -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/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 ) -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 f455075d1..fe3ed4429 100644 --- a/test/stderr/5410 +++ b/test/stderr/5410 @@ -18,8 +18,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 @@ -69,8 +69,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: * @@ -88,8 +88,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: * @@ -134,8 +134,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) @@ -154,8 +154,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) @@ -172,8 +172,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) @@ -188,8 +188,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>) @@ -197,8 +197,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}} @@ -206,8 +218,8 @@ considering: (envelope-from <$sender_address>) result: (envelope-from ) -condition: def:received_for - result: true + condition: def:received_for + result: true considering: for $received_for}} expanding: @@ -264,8 +276,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 @@ -315,8 +327,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: * @@ -349,8 +361,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) @@ -369,8 +381,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) @@ -387,8 +399,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) @@ -403,8 +415,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>) @@ -412,8 +424,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}} @@ -421,8 +445,8 @@ considering: (envelope-from <$sender_address>) result: (envelope-from ) -condition: def:received_for - result: true + condition: def:received_for + result: true considering: for $received_for}} expanding: @@ -479,8 +503,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 @@ -530,8 +554,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: * @@ -564,8 +588,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) @@ -584,8 +608,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) @@ -602,8 +626,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) @@ -618,8 +642,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>) @@ -627,8 +651,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}} @@ -636,8 +672,8 @@ considering: (envelope-from <$sender_address>) result: (envelope-from ) -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 9117875ef..623b99864 100644 --- a/test/stderr/5420 +++ b/test/stderr/5420 @@ -18,8 +18,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 @@ -69,8 +69,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: * @@ -88,8 +88,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 ) -condition: def:received_for - result: true + condition: def:received_for + result: true considering: for $received_for}} expanding: @@ -263,8 +275,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 @@ -314,8 +326,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: * @@ -348,8 +360,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) @@ -368,8 +380,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) @@ -386,8 +398,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) @@ -402,8 +414,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>) @@ -411,8 +423,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}} @@ -420,8 +444,8 @@ considering: (envelope-from <$sender_address>) result: (envelope-from ) -condition: def:received_for - result: true + condition: def:received_for + result: true considering: for $received_for}} expanding: @@ -478,8 +502,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 @@ -529,8 +553,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: * @@ -563,8 +587,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) @@ -583,8 +607,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) @@ -601,8 +625,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) @@ -617,8 +641,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>) @@ -626,8 +650,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}} @@ -635,8 +671,8 @@ considering: (envelope-from <$sender_address>) result: (envelope-from ) -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 +> base32: 31 <7> +> base32: 32 +> base32: 42 +> 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.