X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fverify.c;h=1555838acecda3c5abbebea7d232af4691f1a2cf;hb=ca5c132adacf024c8140446b7cb402dd923bc4c3;hp=b957c709b7f0ae0cc79429563efbc738bbb9044d;hpb=c5db348c5e29e93e51389fa0079f829967c5da82;p=exim.git diff --git a/src/src/verify.c b/src/src/verify.c index b957c709b..1555838ac 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2017 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with verifying things. The original code for callout @@ -388,18 +388,21 @@ if (addr->transport == cutthrough.addr.transport) host_af = Ustrchr(host->address, ':') ? AF_INET6 : AF_INET; - if (!smtp_get_interface(tf->interface, host_af, addr, &interface, - US"callout") || - !smtp_get_port(tf->port, addr, &port, US"callout")) + if ( !smtp_get_interface(tf->interface, host_af, addr, &interface, + US"callout") + || !smtp_get_port(tf->port, addr, &port, US"callout") + ) log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address, addr->message); + smtp_port_for_connect(host, port); + if ( ( interface == cutthrough.interface || ( interface && cutthrough.interface && Ustrcmp(interface, cutthrough.interface) == 0 ) ) - && port == cutthrough.host.port + && host->port == cutthrough.host.port ) { uschar * resp = NULL; @@ -818,7 +821,7 @@ tls_retry_connection: debug_printf_indent("problem after random/rset/mfrom; reopen conn\n"); random_local_part = NULL; #ifdef SUPPORT_TLS - tls_close(FALSE, TRUE); + tls_close(FALSE, TLS_SHUTDOWN_NOWAIT); #endif HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n"); (void)close(sx.inblock.sock); @@ -1023,6 +1026,20 @@ no_conn: here is where we want to leave the conn open. Ditto for a lazy-close verify. */ + if (cutthrough.delivery) + { + if (addr->transport->filter_command) + { + cutthrough.delivery= FALSE; + HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n"); + } + if (ob->dkim.dkim_domain || ob->arc_sign) + { + cutthrough.delivery= FALSE; + HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM or ARC signing\n"); + } + } + if ( (cutthrough.delivery || options & vopt_callout_hold) && rcpt_count == 1 && done @@ -1085,7 +1102,7 @@ no_conn: if (sx.inblock.sock >= 0) { #ifdef SUPPORT_TLS - tls_close(FALSE, TRUE); + tls_close(FALSE, TLS_SHUTDOWN_NOWAIT); #endif HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n"); (void)close(sx.inblock.sock); @@ -1380,12 +1397,13 @@ if(fd >= 0) _cutthrough_puts(US"QUIT\r\n", 6); /* avoid recursion */ _cutthrough_flush_send(); cutthrough.fd = -1; /* avoid recursion via read timeout */ + cutthrough.nrcpt = 0; /* permit re-cutthrough on subsequent message */ /* Wait a short time for response, and discard it */ cutthrough_response(fd, '2', NULL, 1); #ifdef SUPPORT_TLS - tls_close(FALSE, TRUE); + tls_close(FALSE, TLS_SHUTDOWN_NOWAIT); #endif HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n"); (void)close(fd); @@ -1845,7 +1863,7 @@ while (addr_new) additional host items being inserted into the chain. Hence we must save the next host first. */ - flags = HOST_FIND_BY_A; + flags = HOST_FIND_BY_A | HOST_FIND_BY_AAAA; if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS; @@ -2165,7 +2183,7 @@ return yield; *************************************************/ /* This function checks those header lines that contain addresses, and verifies -that all the addresses therein are syntactially correct. +that all the addresses therein are 5322-syntactially correct. Arguments: msgptr where to put an error message @@ -2181,7 +2199,7 @@ header_line *h; uschar *colon, *s; int yield = OK; -for (h = header_list; h != NULL && yield == OK; h = h->next) +for (h = header_list; h && yield == OK; h = h->next) { if (h->type != htype_from && h->type != htype_reply_to && @@ -2200,7 +2218,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next) parse_allow_group = TRUE; - while (*s != 0) + while (*s) { uschar *ss = parse_find_address_end(s, FALSE); uschar *recipient, *errmess; @@ -2217,7 +2235,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next) /* Permit an unqualified address only if the message is local, or if the sending host is configured to be permitted to send them. */ - if (recipient != NULL && domain == 0) + if (recipient && !domain) { if (h->type == htype_from || h->type == htype_sender) { @@ -2233,7 +2251,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next) /* It's an error if no address could be extracted, except for the special case of an empty address. */ - if (recipient == NULL && Ustrcmp(errmess, "empty address") != 0) + if (!recipient && Ustrcmp(errmess, "empty address") != 0) { uschar *verb = US"is"; uschar *t = ss; @@ -2271,7 +2289,7 @@ for (h = header_list; h != NULL && yield == OK; h = h->next) /* Advance to the next address */ - s = ss + (terminator? 1:0); + s = ss + (terminator ? 1 : 0); while (isspace(*s)) s++; } /* Next address */ @@ -3072,7 +3090,7 @@ if (isquery) /* Not a query-style lookup; must ensure the host name is present, and then we do a check on the name and all its aliases. */ -if (sender_host_name == NULL) +if (!sender_host_name) { HDEBUG(D_host_lookup) debug_printf("sender host name required, to match against %s\n", ss); @@ -3087,8 +3105,7 @@ if (sender_host_name == NULL) /* Match on the sender host name, using the general matching function */ -switch(match_check_string(sender_host_name, ss, -1, TRUE, TRUE, TRUE, - valueptr)) +switch(match_check_string(sender_host_name, ss, -1, TRUE, TRUE, TRUE, valueptr)) { case OK: return OK; case DEFER: return DEFER; @@ -3097,14 +3114,12 @@ switch(match_check_string(sender_host_name, ss, -1, TRUE, TRUE, TRUE, /* If there are aliases, try matching on them. */ aliases = sender_host_aliases; -while (*aliases != NULL) - { +while (*aliases) switch(match_check_string(*aliases++, ss, -1, TRUE, TRUE, TRUE, valueptr)) { case OK: return OK; case DEFER: return DEFER; } - } return FAIL; } @@ -3403,25 +3418,23 @@ else for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); rr; rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) - { if (rr->type == T_A) { dns_address *da = dns_address_from_rr(&dnsa, rr); if (da) { *addrp = da; - while (da->next != NULL) da = da->next; - addrp = &(da->next); + while (da->next) da = da->next; + addrp = &da->next; if (ttl > rr->ttl) ttl = rr->ttl; } } - } /* If we didn't find any A records, change the return code. This can happen when there is a CNAME record but there are no A records for what it points to. */ - if (cb->rhs == NULL) cb->rc = DNS_NODATA; + if (!cb->rhs) cb->rc = DNS_NODATA; } cb->expiry = time(NULL)+ttl; @@ -3443,7 +3456,7 @@ if (cb->rc == DNS_SUCCEED) records. For A6 records (currently not expected to be used) there may be multiple addresses from a single record. */ - for (da = cb->rhs->next; da != NULL; da = da->next) + for (da = cb->rhs->next; da; da = da->next) addlist = string_sprintf("%s, %s", addlist, da->address); HDEBUG(D_dnsbl) debug_printf("DNS lookup for %s succeeded (yielding %s)\n", @@ -3452,9 +3465,9 @@ if (cb->rc == DNS_SUCCEED) /* Address list check; this can be either for equality, or via a bitmask. In the latter case, all the bits must match. */ - if (iplist != NULL) + if (iplist) { - for (da = cb->rhs; da != NULL; da = da->next) + for (da = cb->rhs; da; da = da->next) { int ipsep = ','; uschar ip[46]; @@ -3464,12 +3477,11 @@ if (cb->rc == DNS_SUCCEED) /* Handle exact matching */ if (!bitmask) - { - while ((res = string_nextinlist(&ptr, &ipsep, ip, sizeof(ip))) != NULL) - { - if (Ustrcmp(CS da->address, ip) == 0) break; - } - } + { + while ((res = string_nextinlist(&ptr, &ipsep, ip, sizeof(ip)))) + if (Ustrcmp(CS da->address, ip) == 0) + break; + } /* Handle bitmask matching */ @@ -3489,7 +3501,7 @@ if (cb->rc == DNS_SUCCEED) /* Scan the returned addresses, skipping any that are IPv6 */ - while ((res = string_nextinlist(&ptr, &ipsep, ip, sizeof(ip))) != NULL) + while ((res = string_nextinlist(&ptr, &ipsep, ip, sizeof(ip)))) { if (host_aton(ip, address) != 1) continue; if ((address[0] & mask) == address[0]) break; @@ -3522,17 +3534,13 @@ if (cb->rc == DNS_SUCCEED) switch(match_type) { case 0: - res = US"was no match"; - break; + res = US"was no match"; break; case MT_NOT: - res = US"was an exclude match"; - break; + res = US"was an exclude match"; break; case MT_ALL: - res = US"was an IP address that did not match"; - break; + res = US"was an IP address that did not match"; break; case MT_NOT|MT_ALL: - res = US"were no IP addresses that did not match"; - break; + res = US"were no IP addresses that did not match"; break; } debug_printf("=> but we are not accepting this block class because\n"); debug_printf("=> there %s for %s%c%s\n", @@ -3564,15 +3572,15 @@ if (cb->rc == DNS_SUCCEED) { dns_record *rr; for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); - rr != NULL; + rr; rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == T_TXT) break; - if (rr != NULL) + if (rr) { int len = (rr->data)[0]; if (len > 511) len = 127; store_pool = POOL_PERM; - cb->text = string_sprintf("%.*s", len, (const uschar *)(rr->data+1)); + cb->text = string_sprintf("%.*s", len, CUS (rr->data+1)); store_pool = old_pool; } }