diff options
Diffstat (limited to '')
-rw-r--r-- | src/smtp/smtp_addr.c | 13 | ||||
-rw-r--r-- | src/smtpd/smtpd.c | 19 | ||||
-rw-r--r-- | src/smtpd/smtpd_check.c | 10 | ||||
-rw-r--r-- | src/smtpd/smtpd_sasl_glue.c | 10 |
4 files changed, 46 insertions, 6 deletions
diff --git a/src/smtp/smtp_addr.c b/src/smtp/smtp_addr.c index 2b5c126..fa0af4e 100644 --- a/src/smtp/smtp_addr.c +++ b/src/smtp/smtp_addr.c @@ -154,7 +154,7 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt, msg_fatal("host %s: conversion error for address family " "%d: %m", host, res0->ai_addr->sa_family); addr_list = dns_rr_append(addr_list, addr); - if (msg_verbose) + if (msg_verbose && !DNS_RR_IS_TRUNCATED(addr_list)) msg_info("%s: using numerical host %s", myname, host); freeaddrinfo(res0); return (addr_list); @@ -232,6 +232,8 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt, msg_fatal("host %s: conversion error for address family " "%d: %m", host, res0->ai_addr->sa_family); addr_list = dns_rr_append(addr_list, addr); + if (DNS_RR_IS_TRUNCATED(addr_list)) + break; if (msg_verbose) { MAI_HOSTADDR_STR hostaddr_str; @@ -297,6 +299,8 @@ static DNS_RR *smtp_addr_list(DNS_RR *mx_names, DSN_BUF *why) msg_panic("smtp_addr_list: bad resource type: %d", rr->type); addr_list = smtp_addr_one(addr_list, (char *) rr->data, res_opt, rr->pref, why); + if (addr_list && DNS_RR_IS_TRUNCATED(addr_list)) + break; } return (addr_list); } @@ -391,6 +395,13 @@ static DNS_RR *smtp_balance_inet_proto(DNS_RR *addr_list, int misc_flags, */ /* + * Ensure that dns_rr_append() won't interfere with the protocol + * balancing goals. + */ + if (addr_limit > var_dns_rr_list_limit) + addr_limit = var_dns_rr_list_limit; + + /* * Count the number of IPv6 and IPv4 addresses. */ for (v4_count = v6_count = 0, rr = addr_list; rr != 0; rr = rr->next) { diff --git a/src/smtpd/smtpd.c b/src/smtpd/smtpd.c index 4f4aedd..c2aa428 100644 --- a/src/smtpd/smtpd.c +++ b/src/smtpd/smtpd.c @@ -4114,14 +4114,31 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) /* * Read lines from the fragment. The last line may continue in the * next fragment, or in the next chunk. + * + * If smtp_get_noexcept() stopped after var_line_limit bytes and did not + * emit a queue file record, then that means smtp_get_noexcept() + * stopped after CR and hit EOF as it tried to find out if the next + * byte is LF. In that case, read the first byte from the next + * fragment or chunk, and if that first byte is LF, then + * smtp_get_noexcept() strips off the trailing CRLF and returns '\n' + * as it always does after reading a complete line. */ do { + int can_read = var_line_limit - LEN(state->bdat_get_buffer); + if (smtp_get_noexcept(state->bdat_get_buffer, state->bdat_get_stream, - var_line_limit, + can_read > 0 ? can_read : 1, /* Peek one */ SMTP_GET_FLAG_APPEND) == '\n') { /* Stopped at end-of-line. */ curr_rec_type = REC_TYPE_NORM; + } else if (LEN(state->bdat_get_buffer) > var_line_limit) { + /* Undo peeking, and output the buffer as REC_TYPE_CONT. */ + vstream_ungetc(state->bdat_get_stream, + vstring_end(state->bdat_get_buffer)[-1]); + vstring_truncate(state->bdat_get_buffer, + LEN(state->bdat_get_buffer) - 1); + curr_rec_type = REC_TYPE_CONT; } else if (!vstream_feof(state->bdat_get_stream)) { /* Stopped at var_line_limit. */ curr_rec_type = REC_TYPE_CONT; diff --git a/src/smtpd/smtpd_check.c b/src/smtpd/smtpd_check.c index 996a19e..513652d 100644 --- a/src/smtpd/smtpd_check.c +++ b/src/smtpd/smtpd_check.c @@ -2993,6 +2993,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table, struct addrinfo *res; int status; const INET_PROTO_INFO *proto_info; + int server_addr_count = 0; /* * Sanity check. @@ -3144,6 +3145,15 @@ static int check_server_access(SMTPD_STATE *state, const char *table, msg_info("%s: %s host address check: %s", myname, dns_strtype(type), (char *) server->data); for (res = res0; res != 0; res = res->ai_next) { + server_addr_count += 1; + if (server_addr_count > var_dns_rr_list_limit) { + msg_warn("%s: %s server address count limit (%d) exceeded" + " for %s %s -- ignoring the remainder", myname, + dns_strtype(type), var_dns_rr_list_limit, + reply_class, reply_name); + freeaddrinfo(res0); + CHECK_SERVER_RETURN(SMTPD_CHECK_DUNNO); + } if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) { if (msg_verbose) msg_info("skipping address family %d for host %s", diff --git a/src/smtpd/smtpd_sasl_glue.c b/src/smtpd/smtpd_sasl_glue.c index 2dc6aad..d9db7b0 100644 --- a/src/smtpd/smtpd_sasl_glue.c +++ b/src/smtpd/smtpd_sasl_glue.c @@ -340,18 +340,20 @@ int smtpd_sasl_authenticate(SMTPD_STATE *state, } } if (status != XSASL_AUTH_DONE) { + const char *reason = (*STR(state->sasl_reply) ? STR(state->sasl_reply) : + "(reason unavailable)"); + sasl_username = xsasl_server_get_username(state->sasl_server); msg_warn("%s: SASL %.100s authentication failed: %s, sasl_username=%.100s", - state->namaddr, sasl_method, *STR(state->sasl_reply) ? - STR(state->sasl_reply) : "(reason unavailable)", + state->namaddr, sasl_method, reason, sasl_username ? sasl_username : "(unavailable)"); /* RFC 4954 Section 6. */ if (status == XSASL_AUTH_TEMP) smtpd_chat_reply(state, "454 4.7.0 Temporary authentication failure: %s", - STR(state->sasl_reply)); + reason); else smtpd_chat_reply(state, "535 5.7.8 Error: authentication failed: %s", - STR(state->sasl_reply)); + reason); return (-1); } /* RFC 4954 Section 6. */ |