X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/1cf47989a0376c3f7156c214c1d509d372e4262b..36771878fa93a04ecf5bdd71ad3c3c380a16aa03:/src/src/smtp_in.c diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 5888b8037..eb032bb52 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -624,9 +624,7 @@ for(;;) if (chunking_data_left > 0) return lwr_receive_getc(chunking_data_left--); - receive_getc = lwr_receive_getc; - receive_getbuf = lwr_receive_getbuf; - receive_ungetc = lwr_receive_ungetc; + bdat_pop_receive_functions(); #ifndef DISABLE_DKIM dkim_save = dkim_collect_input; dkim_collect_input = 0; @@ -730,9 +728,7 @@ next_cmd: goto repeat_until_rset; } - receive_getc = bdat_getc; - receive_getbuf = bdat_getbuf; /* r~getbuf is never actually used */ - receive_ungetc = bdat_ungetc; + bdat_push_receive_functions(); #ifndef DISABLE_DKIM dkim_collect_input = dkim_save; #endif @@ -765,9 +761,7 @@ while (chunking_data_left) if (!bdat_getbuf(&n)) break; } -receive_getc = lwr_receive_getc; -receive_getbuf = lwr_receive_getbuf; -receive_ungetc = lwr_receive_ungetc; +bdat_pop_receive_functions(); if (chunking_state != CHUNKING_LAST) { @@ -777,7 +771,35 @@ if (chunking_state != CHUNKING_LAST) } +void +bdat_push_receive_functions(void) +{ +/* push the current receive_* function on the "stack", and +replace them by bdat_getc(), which in turn will use the lwr_receive_* +functions to do the dirty work. */ +if (lwr_receive_getc == NULL) + { + lwr_receive_getc = receive_getc; + lwr_receive_getbuf = receive_getbuf; + lwr_receive_ungetc = receive_ungetc; + } +else + { + DEBUG(D_receive) debug_printf("chunking double-push receive functions\n"); + } + +receive_getc = bdat_getc; +receive_ungetc = bdat_ungetc; +} +void +bdat_pop_receive_functions(void) +{ +receive_getc = lwr_receive_getc; +receive_getbuf = lwr_receive_getbuf; +receive_ungetc = lwr_receive_ungetc; +lwr_receive_getc = lwr_receive_getbuf = lwr_receive_ungetc = NULL; +} /************************************************* * SMTP version of ungetc() * @@ -1969,12 +1991,13 @@ extract_option(uschar **name, uschar **value) uschar *n; uschar *v = smtp_cmd_data + Ustrlen(smtp_cmd_data) - 1; while (isspace(*v)) v--; -v[1] = 0; +v[1] = '\0'; while (v > smtp_cmd_data && *v != '=' && !isspace(*v)) { /* Take care to not stop at a space embedded in a quoted local-part */ - if (*v == '"') do v--; while (*v != '"' && v > smtp_cmd_data+1); + if ((*v == '"') && (v > smtp_cmd_data + 1)) + do v--; while (*v != '"' && v > smtp_cmd_data+1); v--; } @@ -2527,6 +2550,7 @@ receive_ungetc = smtp_ungetc; receive_feof = smtp_feof; receive_ferror = smtp_ferror; receive_smtp_buffered = smtp_buffered; +lwr_receive_getc = lwr_receive_getbuf = lwr_receive_ungetc = NULL; smtp_inptr = smtp_inend = smtp_inbuffer; smtp_had_eof = smtp_had_error = 0; @@ -3847,9 +3871,18 @@ if (*user_msgp) else smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); -#ifndef DISABLE_TLS +#ifdef SERVERSIDE_CLOSE_NOWAIT +# ifndef DISABLE_TLS +tls_close(NULL, TLS_SHUTDOWN_NOWAIT); +# endif + +log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", + smtp_get_connection_info()); +#else + +# ifndef DISABLE_TLS tls_close(NULL, TLS_SHUTDOWN_WAIT); -#endif +# endif log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", smtp_get_connection_info()); @@ -3866,6 +3899,7 @@ The socket should become readble (though with no data) */ FD_SET(fd, &fds); (void) select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &t_limit); } +#endif /*!DAEMON_CLOSE_NOWAIT*/ } @@ -3943,6 +3977,14 @@ cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE; cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE; #endif +if (lwr_receive_getc != NULL) + { + /* This should have already happened, but if we've gotten confused, + force a reset here. */ + DEBUG(D_receive) debug_printf("WARNING: smtp_setup_msg had to restore receive functions to lowers\n"); + bdat_pop_receive_functions(); + } + /* Set the local signal handler for SIGTERM - it tries to end off tidily */ had_command_sigterm = 0; @@ -4336,6 +4378,19 @@ while (done <= 0) g = string_catn(g, US"-SIZE\r\n", 7); } +#ifdef EXPERIMENTAL_ESMTP_LIMITS + if ( (mailmax > 0 || recipients_max) + && verify_check_host(&limits_advertise_hosts) == OK) + { + g = string_fmt_append(g, "%.3s-LIMITS", smtp_code); + if (mailmax > 0) + g = string_fmt_append(g, " MAILMAX=%d", mailmax); + if (recipients_max) + g = string_fmt_append(g, " RCPTMAX=%d", recipients_max); + g = string_catn(g, US"\r\n", 2); + } +#endif + /* Exim does not do protocol conversion or data conversion. It is 8-bit clean; if it has an 8-bit character in its hand, it just sends it. It cannot therefore specify 8BITMIME and remain consistent with the RFCs. @@ -5264,16 +5319,7 @@ while (done <= 0) DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n", (int)chunking_state, chunking_data_left); - /* push the current receive_* function on the "stack", and - replace them by bdat_getc(), which in turn will use the lwr_receive_* - functions to do the dirty work. */ - lwr_receive_getc = receive_getc; - lwr_receive_getbuf = receive_getbuf; - lwr_receive_ungetc = receive_ungetc; - - receive_getc = bdat_getc; - receive_ungetc = bdat_ungetc; - + f.bdat_readers_wanted = TRUE; f.dot_ends = FALSE; goto DATA_BDAT; @@ -5282,6 +5328,7 @@ while (done <= 0) case DATA_CMD: HAD(SCH_DATA); f.dot_ends = TRUE; + f.bdat_readers_wanted = FALSE DATA_BDAT: /* Common code for DATA and BDAT */ #ifndef DISABLE_PIPE_CONNECT @@ -5310,7 +5357,10 @@ while (done <= 0) : US"valid RCPT command must precede BDAT"); if (chunking_state > CHUNKING_OFFERED) + { + bdat_push_receive_functions(); bdat_flush_data(); + } break; } @@ -5349,6 +5399,9 @@ while (done <= 0) } } + if (f.bdat_readers_wanted) + bdat_push_receive_functions(); + if (user_msg) smtp_user_msg(US"354", user_msg); else