X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f358d5e0ef3cb10a0a6d107f70e9e0442087f6f2..fc362fc531e0ffc898c784e09f097327f5814289:/src/src/transports/smtp.c diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 92df8fa2d..9554652ca 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1366,6 +1366,7 @@ BOOL prdr_offered = FALSE; BOOL prdr_active; #endif #ifdef EXPERIMENTAL_INTERNATIONAL +BOOL utf8_needed = FALSE; BOOL utf8_offered = FALSE; #endif BOOL dsn_all_lasthop = TRUE; @@ -1387,7 +1388,6 @@ uschar *p; uschar buffer[4096]; uschar inbuffer[4096]; uschar outbuffer[4096]; -address_item * current_address; suppress_tls = suppress_tls; /* stop compiler warning when no TLS support */ @@ -1486,6 +1486,19 @@ if (continue_hostname == NULL) delayed till here so that $sending_interface and $sending_port are set. */ helo_data = expand_string(ob->helo_data); +#ifdef EXPERIMENTAL_INTERNATIONAL + if (helo_data) + { + uschar * errstr = NULL; + if ((helo_data = string_domain_utf8_to_alabel(helo_data, &errstr)), errstr) + { + errstr = string_sprintf("failed to expand helo_data: %s", errstr); + set_errno(addrlist, ERRNO_EXPANDFAIL, errstr, DEFER, FALSE, NULL); + yield = DEFER; + goto SEND_QUIT; + } + } +#endif /* The first thing is to wait for an initial OK response. The dreaded "goto" is nevertheless a reasonably clean way of programming this kind of logic, @@ -1629,10 +1642,17 @@ goto SEND_QUIT; #endif #ifdef EXPERIMENTAL_INTERNATIONAL - utf8_offered = esmtp - && addrlist->p.utf8 - && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0, - PCRE_EOPT, NULL, 0) >= 0; + if (addrlist->prop.utf8_msg) + { + utf8_needed = !addrlist->prop.utf8_downcvt + && !addrlist->prop.utf8_downcvt_maybe; + DEBUG(D_transport) if (!utf8_needed) debug_printf("utf8: %s downconvert\n", + addrlist->prop.utf8_downcvt ? "mandatory" : "optional"); + + utf8_offered = esmtp + && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0, + PCRE_EOPT, NULL, 0) >= 0; + } #endif } @@ -1849,10 +1869,10 @@ if (continue_hostname == NULL #endif #ifdef EXPERIMENTAL_INTERNATIONAL - utf8_offered = esmtp - && addrlist->p.utf8 - && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0, - PCRE_EOPT, NULL, 0) >= 0; + if (addrlist->prop.utf8_msg) + utf8_offered = esmtp + && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0, + PCRE_EOPT, NULL, 0) >= 0; #endif /* Note if the server supports DSN */ @@ -1883,7 +1903,7 @@ setting_up = FALSE; #ifdef EXPERIMENTAL_INTERNATIONAL /* If this is an international message we need the host to speak SMTPUTF8 */ -if (addrlist->p.utf8 && !utf8_offered) +if (utf8_needed && !utf8_offered) { errno = ERRNO_UTF8_FWD; goto RESPONSE_FAILED; @@ -1967,7 +1987,7 @@ if (prdr_offered) #endif #ifdef EXPERIMENTAL_INTERNATIONAL -if (addrlist->p.utf8) +if (addrlist->prop.utf8_msg && !addrlist->prop.utf8_downcvt && utf8_offered) sprintf(CS p, " SMTPUTF8"), p += 9; #endif @@ -2024,8 +2044,31 @@ buffer. */ pending_MAIL = TRUE; /* The block starts with MAIL */ -rc = smtp_write_command(&outblock, smtp_use_pipelining, - "MAIL FROM:<%s>%s\r\n", return_path, buffer); + { + uschar * s = return_path; +#ifdef EXPERIMENTAL_INTERNATIONAL + uschar * errstr = NULL; + + /* If we must downconvert, do the from-address here. Remember we had to + for the to-addresses (done below), and also (ugly) for re-doing when building + the delivery log line. */ + + if (addrlist->prop.utf8_msg && (addrlist->prop.utf8_downcvt || !utf8_offered)) + { + if (s = string_address_utf8_to_alabel(return_path, &errstr), errstr) + { + set_errno(addrlist, ERRNO_EXPANDFAIL, errstr, DEFER, FALSE, NULL); + yield = ERROR; + goto SEND_QUIT; + } + setflag(addrlist, af_utf8_downcvt); + } +#endif + + rc = smtp_write_command(&outblock, smtp_use_pipelining, + "MAIL FROM:<%s>%s\r\n", s, buffer); + } + mail_command = string_copy(big_buffer); /* Save for later error message */ switch(rc) @@ -2067,6 +2110,7 @@ for (addr = first_addr; { int count; BOOL no_flush; + uschar * rcpt_addr; addr->dsn_aware = smtp_use_dsn ? dsn_support_yes : dsn_support_no; @@ -2111,8 +2155,24 @@ for (addr = first_addr; yield as OK, because this error can often mean that there is a problem with just one address, so we don't want to delay the host. */ + rcpt_addr = transport_rcpt_address(addr, tblock->rcpt_include_affixes); + +#ifdef EXPERIMENTAL_INTERNATIONAL + { + uschar * dummy_errstr; + if ( testflag(addrlist, af_utf8_downcvt) + && (rcpt_addr = string_address_utf8_to_alabel(rcpt_addr, &dummy_errstr), + dummy_errstr + ) ) + { + errno = ERRNO_EXPANDFAIL; + goto SEND_FAILED; + } + } +#endif + count = smtp_write_command(&outblock, no_flush, "RCPT TO:<%s>%s%s\r\n", - transport_rcpt_address(addr, tblock->rcpt_include_affixes), igquotstr, buffer); + rcpt_addr, igquotstr, buffer); if (count < 0) goto SEND_FAILED; if (count > 0)