diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2017-01-22 14:05:38 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2017-01-22 14:05:38 +0000 |
commit | 1137f3a6938882cc81a1fcd7dc15530e8fae9e32 (patch) | |
tree | 059a2be620690455e5f431b8fd01c1dae04be216 /src | |
parent | adc426215052297d694fcc08786e87a140171e76 (diff) | |
parent | bd8fbe3606d80e5a3fc02fe71b521146c6938448 (diff) |
Merge branch 'fix-2016-dkim'
Diffstat (limited to 'src')
-rw-r--r-- | src/src/auths/get_data.c | 2 | ||||
-rw-r--r-- | src/src/auths/get_no64_data.c | 2 | ||||
-rw-r--r-- | src/src/dkim.c | 9 | ||||
-rw-r--r-- | src/src/functions.h | 8 | ||||
-rw-r--r-- | src/src/globals.c | 4 | ||||
-rw-r--r-- | src/src/globals.h | 4 | ||||
-rw-r--r-- | src/src/macros.h | 4 | ||||
-rw-r--r-- | src/src/pdkim/pdkim.c | 5 | ||||
-rw-r--r-- | src/src/receive.c | 22 | ||||
-rw-r--r-- | src/src/smtp_in.c | 80 | ||||
-rw-r--r-- | src/src/tls-gnu.c | 8 | ||||
-rw-r--r-- | src/src/tls-openssl.c | 9 |
12 files changed, 91 insertions, 66 deletions
diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index f839a010e..11bc581b9 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -31,7 +31,7 @@ auth_get_data(uschar **aptr, uschar *challenge, int challen) int c; int p = 0; smtp_printf("334 %s\r\n", b64encode(challenge, challen)); -while ((c = receive_getc()) != '\n' && c != EOF) +while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF) { if (p >= big_buffer_size - 1) return BAD64; big_buffer[p++] = c; diff --git a/src/src/auths/get_no64_data.c b/src/src/auths/get_no64_data.c index d3ffe081e..71e71394c 100644 --- a/src/src/auths/get_no64_data.c +++ b/src/src/auths/get_no64_data.c @@ -32,7 +32,7 @@ auth_get_no64_data(uschar **aptr, uschar *challenge) int c; int p = 0; smtp_printf("334 %s\r\n", challenge); -while ((c = receive_getc()) != '\n' && c != EOF) +while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF) { if (p >= big_buffer_size - 1) return BAD64; big_buffer[p++] = c; diff --git a/src/src/dkim.c b/src/src/dkim.c index cc103c289..3573e45e6 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -18,6 +18,7 @@ int dkim_verify_oldpool; pdkim_ctx *dkim_verify_ctx = NULL; pdkim_signature *dkim_signatures = NULL; pdkim_signature *dkim_cur_sig = NULL; +static BOOL dkim_collect_error = FALSE; static int dkim_exim_query_dns_txt(char *name, char *answer) @@ -87,6 +88,7 @@ if (dkim_verify_ctx) dkim_verify_ctx = pdkim_init_verify(&dkim_exim_query_dns_txt, dot_stuffing); dkim_collect_input = !!dkim_verify_ctx; +dkim_collect_error = FALSE; /* Start feed up with any cached data */ receive_get_cache(); @@ -106,6 +108,7 @@ if ( dkim_collect_input { log_write(0, LOG_MAIN, "DKIM: validation error: %.100s", pdkim_errstr(rc)); + dkim_collect_error = TRUE; dkim_collect_input = FALSE; } store_pool = dkim_verify_oldpool; @@ -127,11 +130,7 @@ store_pool = POOL_PERM; dkim_signatures = NULL; -/* If we have arrived here with dkim_collect_input == FALSE, it -means there was a processing error somewhere along the way. -Log the incident and disable further verification. */ - -if (!dkim_collect_input) +if (dkim_collect_error) { log_write(0, LOG_MAIN, "DKIM: Error while running this message through validation," diff --git a/src/src/functions.h b/src/src/functions.h index bba8c446b..9c7dbe671 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -55,7 +55,7 @@ extern int tls_export_cert(uschar *, size_t, void *); extern int tls_feof(void); extern int tls_ferror(void); extern void tls_free_cert(void **); -extern int tls_getc(void); +extern int tls_getc(unsigned); extern void tls_get_cache(void); extern int tls_import_cert(const uschar *, void **); extern int tls_read(BOOL, uschar *, size_t); @@ -101,7 +101,7 @@ extern int auth_xtextdecode(uschar *, uschar **); extern uschar *b64encode(uschar *, int); extern int b64decode(uschar *, uschar **); -extern int bdat_getc(void); +extern int bdat_getc(unsigned); extern void bits_clear(unsigned int *, size_t, int *); extern void bits_set(unsigned int *, size_t, int *); @@ -394,7 +394,7 @@ extern uschar *smtp_get_connection_info(void); extern BOOL smtp_get_interface(uschar *, int, address_item *, uschar **, uschar *); extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *); -extern int smtp_getc(void); +extern int smtp_getc(unsigned); extern void smtp_get_cache(void); extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); extern void smtp_log_no_mail(void); @@ -420,7 +420,7 @@ extern int spool_open_datafile(uschar *); extern int spool_open_temp(uschar *); extern int spool_read_header(uschar *, BOOL, BOOL); extern int spool_write_header(uschar *, int, uschar **); -extern int stdin_getc(void); +extern int stdin_getc(unsigned); extern int stdin_feof(void); extern int stdin_ferror(void); extern int stdin_ungetc(int); diff --git a/src/src/globals.c b/src/src/globals.c index 90e46dff5..bb5acb6fc 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -183,9 +183,9 @@ incoming TCP/IP. The defaults use stdin. We never need these for any stand-alone tests. */ #ifndef STAND_ALONE -int (*lwr_receive_getc)(void) = stdin_getc; +int (*lwr_receive_getc)(unsigned) = stdin_getc; int (*lwr_receive_ungetc)(int) = stdin_ungetc; -int (*receive_getc)(void) = stdin_getc; +int (*receive_getc)(unsigned) = stdin_getc; void (*receive_get_cache)(void)= NULL; int (*receive_ungetc)(int) = stdin_ungetc; int (*receive_feof)(void) = stdin_feof; diff --git a/src/src/globals.h b/src/src/globals.h index 6cd43c08e..62bcb7a98 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -136,9 +136,9 @@ extern uschar *dsn_advertise_hosts; /* host for which TLS is advertised */ /* Input-reading functions for messages, so we can use special ones for incoming TCP/IP. */ -extern int (*lwr_receive_getc)(void); +extern int (*lwr_receive_getc)(unsigned); extern int (*lwr_receive_ungetc)(int); -extern int (*receive_getc)(void); +extern int (*receive_getc)(unsigned); extern void (*receive_get_cache)(void); extern int (*receive_ungetc)(int); extern int (*receive_feof)(void); diff --git a/src/src/macros.h b/src/src/macros.h index 53ffe1b2a..2692714f7 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -968,5 +968,9 @@ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE }; #define PEER_OFFERED_SIZE BIT(6) #define PEER_OFFERED_CHUNKING BIT(7) +/* Argument for *_getc */ + +#define GETC_BUFFER_UNLIMITED UINT_MAX + /* End of macros.h */ diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 1953c4bd6..4309675e6 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -959,6 +959,11 @@ if (ctx->flags & PDKIM_MODE_SIGN) /* DKIM-Signature: headers are added to the verification list */ else { + DEBUG(D_acl) + { + debug_printf("PDKIM >> raw hdr: "); + pdkim_quoteprint(CUS ctx->cur_header, Ustrlen(ctx->cur_header)); + } if (strncasecmp(CCS ctx->cur_header, DKIM_SIGNATURE_HEADERNAME, Ustrlen(DKIM_SIGNATURE_HEADERNAME)) == 0) diff --git a/src/src/receive.c b/src/src/receive.c index 73713aa97..48cdff88c 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -37,7 +37,7 @@ the file. (When SMTP input is occurring, different functions are used by changing the pointer variables.) */ int -stdin_getc(void) +stdin_getc(unsigned lim) { return getc(stdin); } @@ -626,7 +626,7 @@ if (!dot_ends) { register int last_ch = '\n'; - for (; (ch = (receive_getc)()) != EOF; last_ch = ch) + for (; (ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF; last_ch = ch) { if (ch == 0) body_zerocount++; if (last_ch == '\r' && ch != '\n') @@ -668,7 +668,7 @@ if (!dot_ends) ch_state = 1; -while ((ch = (receive_getc)()) != EOF) +while ((ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF) { if (ch == 0) body_zerocount++; switch (ch_state) @@ -786,7 +786,7 @@ int ch_state = 0; int ch; int linelength = 0; -while ((ch = (receive_getc)()) != EOF) +while ((ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF) { if (ch == 0) body_zerocount++; switch (ch_state) @@ -913,7 +913,7 @@ read_message_bdat_smtp(FILE *fout) int ch; int linelength = 0; -for (;;) switch (ch = bdat_getc()) +for (;;) switch (ch = bdat_getc(GETC_BUFFER_UNLIMITED)) { case EOF: return END_EOF; case EOD: return END_DOT; @@ -1682,7 +1682,7 @@ next->text. */ for (;;) { - int ch = (receive_getc)(); + int ch = (receive_getc)(GETC_BUFFER_UNLIMITED); /* If we hit EOF on a SMTP connection, it's an error, since incoming SMTP must have a correct "." terminator. */ @@ -1761,10 +1761,10 @@ for (;;) if (ptr == 0 && ch == '.' && (smtp_input || dot_ends)) { - ch = (receive_getc)(); + ch = (receive_getc)(GETC_BUFFER_UNLIMITED); if (ch == '\r') { - ch = (receive_getc)(); + ch = (receive_getc)(GETC_BUFFER_UNLIMITED); if (ch != '\n') { receive_ungetc(ch); @@ -1795,7 +1795,7 @@ for (;;) if (ch == '\r') { - ch = (receive_getc)(); + ch = (receive_getc)(GETC_BUFFER_UNLIMITED); if (ch == '\n') { if (first_line_ended_crlf == TRUE_UNSET) first_line_ended_crlf = TRUE; @@ -1890,7 +1890,7 @@ for (;;) if (ch != EOF) { - int nextch = (receive_getc)(); + int nextch = (receive_getc)(GETC_BUFFER_UNLIMITED); if (nextch == ' ' || nextch == '\t') { next->text[ptr++] = nextch; @@ -4024,7 +4024,7 @@ if (smtp_input && sender_host_address != NULL && !sender_host_notsocket && if (select(fileno(smtp_in) + 1, &select_check, NULL, NULL, &tv) != 0) { - int c = (receive_getc)(); + int c = (receive_getc)(GETC_BUFFER_UNLIMITED); if (c != EOF) (receive_ungetc)(c); else { smtp_notquit_exit(US"connection-lost", NULL, NULL); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 79a1ee02b..9c647efda 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -44,11 +44,11 @@ The maximum size of a Kerberos ticket under Windows 2003 is 12000 bytes, and we need room to handle large base64-encoded AUTHs for GSSAPI. */ -#define smtp_cmd_buffer_size 16384 +#define SMTP_CMD_BUFFER_SIZE 16384 /* Size of buffer for reading SMTP incoming packets */ -#define in_buffer_size 8192 +#define IN_BUFFER_SIZE 8192 /* Structure for SMTP command list */ @@ -305,7 +305,7 @@ static int smtp_had_error; /* forward declarations */ int bdat_ungetc(int ch); -static int smtp_read_command(BOOL check_sync); +static int smtp_read_command(BOOL check_sync, unsigned buffer_lim); static int synprot_error(int type, int code, uschar *data, uschar *errmess); static void smtp_quit_handler(uschar **, uschar **); static void smtp_rset_handler(void); @@ -352,7 +352,7 @@ tzero.tv_usec = 0; rc = select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tzero); if (rc <= 0) return TRUE; /* Not ready to read */ -rc = smtp_getc(); +rc = smtp_getc(GETC_BUFFER_UNLIMITED); if (rc < 0) return TRUE; /* End of file or error */ smtp_ungetc(rc); @@ -410,12 +410,12 @@ it flushes the output, and refills the buffer, with a timeout. The signal handler is set appropriately by the calling function. This function is not used after a connection has negotiated itself into an TLS/SSL state. -Arguments: none +Arguments: lim Maximum amount to read/buffer Returns: the next character or EOF */ int -smtp_getc(void) +smtp_getc(unsigned lim) { if (smtp_inptr >= smtp_inend) { @@ -423,7 +423,10 @@ if (smtp_inptr >= smtp_inend) if (!smtp_out) return EOF; fflush(smtp_out); if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout); - rc = read(fileno(smtp_in), smtp_inbuffer, in_buffer_size); + + /* Limit amount read, so non-message data is not fed to DKIM */ + + rc = read(fileno(smtp_in), smtp_inbuffer, MIN(IN_BUFFER_SIZE, lim)); save_errno = errno; alarm(0); if (rc <= 0) @@ -471,23 +474,26 @@ to handle the BDAT command/response. Placed here due to the correlation with the above smtp_getc(), which it wraps, and also by the need to do smtp command/response handling. -Arguments: none +Arguments: lim (ignored) Returns: the next character or ERR, EOD or EOF */ int -bdat_getc(void) +bdat_getc(unsigned lim) { uschar * user_msg = NULL; uschar * log_msg; for(;;) { - if (chunking_data_left-- > 0) - return lwr_receive_getc(); + if (chunking_data_left > 0) + return lwr_receive_getc(chunking_data_left--); receive_getc = lwr_receive_getc; receive_ungetc = lwr_receive_ungetc; +#ifndef DISABLE_DKIM + dkim_collect_input = FALSE; +#endif /* Unless PIPELINING was offered, there should be no next command until after we ack that chunk */ @@ -516,21 +522,22 @@ for(;;) return EOD; } - chunking_state = CHUNKING_OFFERED; smtp_printf("250 %u byte chunk received\r\n", chunking_datasize); + chunking_state = CHUNKING_OFFERED; + DEBUG(D_receive) debug_printf("chunking state %d\n", (int)chunking_state); /* Expect another BDAT cmd from input. RFC 3030 says nothing about QUIT, RSET or NOOP but handling them seems obvious */ next_cmd: - switch(smtp_read_command(TRUE)) + switch(smtp_read_command(TRUE, 1)) { default: (void) synprot_error(L_smtp_protocol_error, 503, NULL, US"only BDAT permissible after non-LAST BDAT"); repeat_until_rset: - switch(smtp_read_command(TRUE)) + switch(smtp_read_command(TRUE, 1)) { case QUIT_CMD: smtp_quit_handler(&user_msg, &log_msg); /*FALLTHROUGH */ case EOF_CMD: return EOF; @@ -569,6 +576,8 @@ next_cmd: chunking_state = strcmpic(smtp_cmd_data+n, US"LAST") == 0 ? CHUNKING_LAST : CHUNKING_ACTIVE; chunking_data_left = chunking_datasize; + DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n", + (int)chunking_state, chunking_data_left); if (chunking_datasize == 0) if (chunking_state == CHUNKING_LAST) @@ -582,6 +591,9 @@ next_cmd: receive_getc = bdat_getc; receive_ungetc = bdat_ungetc; +#ifndef DISABLE_DKIM + dkim_collect_input = TRUE; +#endif break; /* to top of main loop */ } } @@ -591,15 +603,18 @@ next_cmd: static void bdat_flush_data(void) { -while (chunking_data_left-- > 0) - if (lwr_receive_getc() < 0) +while (chunking_data_left > 0) + if (lwr_receive_getc(chunking_data_left--) < 0) break; receive_getc = lwr_receive_getc; receive_ungetc = lwr_receive_ungetc; if (chunking_state != CHUNKING_LAST) + { chunking_state = CHUNKING_OFFERED; + DEBUG(D_receive) debug_printf("chunking state %d\n", (int)chunking_state); + } } @@ -1234,13 +1249,14 @@ signal handler that closes down the session on a timeout. Control does not return when it runs. Arguments: - check_sync if TRUE, check synchronization rules if global option is TRUE + check_sync if TRUE, check synchronization rules if global option is TRUE + buffer_lim maximum to buffer in lower layer Returns: a code identifying the command (enumerated above) */ static int -smtp_read_command(BOOL check_sync) +smtp_read_command(BOOL check_sync, unsigned buffer_lim) { int c; int ptr = 0; @@ -1249,9 +1265,9 @@ BOOL hadnull = FALSE; os_non_restarting_signal(SIGALRM, command_timeout_handler); -while ((c = (receive_getc)()) != '\n' && c != EOF) +while ((c = (receive_getc)(buffer_lim)) != '\n' && c != EOF) { - if (ptr >= smtp_cmd_buffer_size) + if (ptr >= SMTP_CMD_BUFFER_SIZE) { os_non_restarting_signal(SIGALRM, sigalrm_handler); return OTHER_CMD; @@ -1391,7 +1407,7 @@ if (smtp_in == NULL || smtp_batched_input) return; receive_swallow_smtp(); smtp_printf("421 %s\r\n", message); -for (;;) switch(smtp_read_command(FALSE)) +for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { case EOF_CMD: return; @@ -1835,7 +1851,7 @@ while (done <= 0) uschar *recipient = NULL; int start, end, sender_domain, recipient_domain; - switch(smtp_read_command(FALSE)) + switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { /* The HELO/EHLO commands set sender_address_helo if they have valid data; otherwise they are ignored, except that they do @@ -2094,12 +2110,12 @@ acl_var_c = NULL; /* Allow for trailing 0 in the command and data buffers. */ -if (!(smtp_cmd_buffer = US malloc(2*smtp_cmd_buffer_size + 2))) +if (!(smtp_cmd_buffer = US malloc(2*SMTP_CMD_BUFFER_SIZE + 2))) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP command buffer"); smtp_cmd_buffer[0] = 0; -smtp_data_buffer = smtp_cmd_buffer + smtp_cmd_buffer_size + 1; +smtp_data_buffer = smtp_cmd_buffer + SMTP_CMD_BUFFER_SIZE + 1; /* For batched input, the protocol setting can be overridden from the command line by a trusted caller. */ @@ -2119,7 +2135,7 @@ else /* Set up the buffer for inputting using direct read() calls, and arrange to call the local functions instead of the standard C ones. */ -if (!(smtp_inbuffer = (uschar *)malloc(in_buffer_size))) +if (!(smtp_inbuffer = (uschar *)malloc(IN_BUFFER_SIZE))) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP input buffer"); receive_getc = smtp_getc; @@ -3567,7 +3583,7 @@ while (done <= 0) US &off, sizeof(off)); #endif - switch(smtp_read_command(TRUE)) + switch(smtp_read_command(TRUE, GETC_BUFFER_UNLIMITED)) { /* The AUTH command is not permitted to occur inside a transaction, and may occur successfully only once per connection. Actually, that isn't quite @@ -4768,14 +4784,14 @@ while (done <= 0) chunking_state = strcmpic(smtp_cmd_data+n, US"LAST") == 0 ? CHUNKING_LAST : CHUNKING_ACTIVE; chunking_data_left = chunking_datasize; + DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n", + (int)chunking_state, chunking_data_left); lwr_receive_getc = receive_getc; lwr_receive_ungetc = receive_ungetc; receive_getc = bdat_getc; receive_ungetc = bdat_ungetc; - DEBUG(D_any) - debug_printf("chunking state %d\n", (int)chunking_state); goto DATA_BDAT; } @@ -4991,7 +5007,7 @@ while (done <= 0) It seems safest to just wipe away the content rather than leave it as a target to jump to. */ - memset(smtp_inbuffer, 0, in_buffer_size); + memset(smtp_inbuffer, 0, IN_BUFFER_SIZE); /* Attempt to start up a TLS session, and if successful, discard all knowledge that was obtained previously. At least, that's what the RFC says, @@ -5045,7 +5061,7 @@ while (done <= 0) set, but we must still reject all incoming commands. */ DEBUG(D_tls) debug_printf("TLS failed to start\n"); - while (done <= 0) switch(smtp_read_command(FALSE)) + while (done <= 0) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { case EOF_CMD: log_write(L_smtp_connection, LOG_MAIN, "%s closed by EOF", @@ -5333,8 +5349,8 @@ while (done <= 0) case BADSYN_CMD: SYNC_FAILURE: - if (smtp_inend >= smtp_inbuffer + in_buffer_size) - smtp_inend = smtp_inbuffer + in_buffer_size - 1; + if (smtp_inend >= smtp_inbuffer + IN_BUFFER_SIZE) + smtp_inend = smtp_inbuffer + IN_BUFFER_SIZE - 1; c = smtp_inend - smtp_inptr; if (c > 150) c = 150; smtp_inptr[c] = 0; diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 9ed548a60..7b16fc811 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2158,12 +2158,12 @@ Only used by the server-side TLS. This feeds DKIM and should be used for all message-body reads. -Arguments: none +Arguments: lim Maximum amount to read/bufffer Returns: the next character or EOF */ int -tls_getc(void) +tls_getc(unsigned lim) { exim_gnutls_state_st *state = &state_server; if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm) @@ -2175,7 +2175,7 @@ if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm) if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout); inbytes = gnutls_record_recv(state->session, state->xfer_buffer, - ssl_xfer_buffer_size); + MIN(ssl_xfer_buffer_size, lim)); alarm(0); /* Timeouts do not get this far; see command_timeout_handler(). @@ -2213,7 +2213,7 @@ if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm) state->tlsp->peercert = NULL; state->tlsp->peerdn = NULL; - return smtp_getc(); + return smtp_getc(lim); } /* Handle genuine errors */ diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index f360f21ae..5a7e92a25 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2360,14 +2360,14 @@ return OK; /* This gets the next byte from the TLS input buffer. If the buffer is empty, it refills the buffer via the SSL reading function. -Arguments: none +Arguments: lim Maximum amount to read/buffer Returns: the next character or EOF Only used by the server-side TLS. */ int -tls_getc(void) +tls_getc(unsigned lim) { if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm) { @@ -2378,7 +2378,8 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm) ssl_xfer_buffer, ssl_xfer_buffer_size); if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout); - inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size); + inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer, + MIN(ssl_xfer_buffer_size, lim)); error = SSL_get_error(server_ssl, inbytes); alarm(0); @@ -2405,7 +2406,7 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm) tls_in.peerdn = NULL; tls_in.sni = NULL; - return smtp_getc(); + return smtp_getc(lim); } /* Handle genuine errors */ |