X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/48ed62d9a68c4e44c9fbaa6e300f88401bb32d65..da80c2a8ed49427334af613c00df65ae301cacdd:/src/src/smtp_in.c diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 6c66a5634..500000be4 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/smtp_in.c,v 1.61 2007/08/22 14:20:28 ph10 Exp $ */ +/* $Cambridge: exim/src/src/smtp_in.c,v 1.67 2010/06/12 15:21:26 jetmore Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2007 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for handling an incoming SMTP call. */ @@ -31,6 +31,7 @@ including that header, and restore its value afterwards. */ int allow_severity = LOG_INFO; int deny_severity = LOG_NOTICE; +uschar *tcp_wrappers_name; #endif @@ -48,7 +49,7 @@ the data can be quite long. */ /* Structure for SMTP command list */ typedef struct { - char *name; + const char *name; int len; short int cmd; short int has_arg; @@ -264,6 +265,9 @@ if (smtp_inptr >= smtp_inend) else smtp_had_eof = 1; return EOF; } +#ifndef DISABLE_DKIM + dkim_exim_verify_feed(smtp_inbuffer, rc); +#endif smtp_inend = smtp_inbuffer + rc; smtp_inptr = smtp_inbuffer; } @@ -372,30 +376,44 @@ Returns: nothing */ void -smtp_printf(char *format, ...) +smtp_printf(const char *format, ...) { va_list ap; +va_start(ap, format); +smtp_vprintf(format, ap); +va_end(ap); +} + +/* This is split off so that verify.c:respond_printf() can, in effect, call +smtp_printf(), bearing in mind that in C a vararg function can't directly +call another vararg function, only a function which accepts a va_list. */ + +void +smtp_vprintf(const char *format, va_list ap) +{ +BOOL yield; + +yield = string_vformat(big_buffer, big_buffer_size, format, ap); + DEBUG(D_receive) { - uschar *cr, *end; - va_start(ap, format); - (void) string_vformat(big_buffer, big_buffer_size, format, ap); - va_end(ap); - end = big_buffer + Ustrlen(big_buffer); - while ((cr = Ustrchr(big_buffer, '\r')) != NULL) /* lose CRs */ - memmove(cr, cr + 1, (end--) - cr); - debug_printf("SMTP>> %s", big_buffer); + void *reset_point = store_get(0); + uschar *msg_copy, *cr, *end; + msg_copy = string_copy(big_buffer); + end = msg_copy + Ustrlen(msg_copy); + while ((cr = Ustrchr(msg_copy, '\r')) != NULL) /* lose CRs */ + memmove(cr, cr + 1, (end--) - cr); + debug_printf("SMTP>> %s", msg_copy); + store_reset(reset_point); } -va_start(ap, format); -if (!string_vformat(big_buffer, big_buffer_size, format, ap)) +if (!yield) { log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()"); smtp_closedown(US"Unexpected error"); exim_exit(EXIT_FAILURE); } -va_end(ap); /* If this is the first output for a (non-batch) RCPT command, see if all RCPTs have had the same. Note: this code is also present in smtp_respond(). It would @@ -1022,8 +1040,10 @@ authenticated_sender = NULL; bmi_run = 0; bmi_verdicts = NULL; #endif -#ifdef EXPERIMENTAL_DOMAINKEYS -dk_do_verify = 0; +#ifndef DISABLE_DKIM +dkim_signers = NULL; +dkim_disable_verify = FALSE; +dkim_collect_input = FALSE; #endif #ifdef EXPERIMENTAL_SPF spf_header_comment = NULL; @@ -1672,7 +1692,14 @@ if (!sender_host_unknown) #ifdef USE_TCP_WRAPPERS errno = 0; - if (!hosts_ctl("exim", + tcp_wrappers_name = expand_string(tcp_wrappers_daemon_name); + if (tcp_wrappers_name == NULL) + { + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Expansion of \"%s\" " + "(tcp_wrappers_name) failed: %s", string_printing(tcp_wrappers_name), + expand_string_message); + } + if (!hosts_ctl(tcp_wrappers_name, (sender_host_name == NULL)? STRING_UNKNOWN : CS sender_host_name, (sender_host_address == NULL)? STRING_UNKNOWN : CS sender_host_address, (sender_ident == NULL)? STRING_UNKNOWN : CS sender_ident)) @@ -3817,6 +3844,23 @@ while (done <= 0) toomany = FALSE; cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = FALSE; + /* There's an attack where more data is read in past the STARTTLS command + before TLS is negotiated, then assumed to be part of the secure session + when used afterwards; we use segregated input buffers, so are not + vulnerable, but we want to note when it happens and, for sheer paranoia, + ensure that the buffer is "wiped". + Pipelining sync checks will normally have protected us too, unless disabled + by configuration. */ + + if (receive_smtp_buffered()) + { + DEBUG(D_any) + debug_printf("Non-empty input buffer after STARTTLS; naive attack?"); + if (tls_active < 0) + smtp_inend = smtp_inptr = smtp_inbuffer; + /* and if TLS is already active, tls_server_start() should fail */ + } + /* 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, and that's what happens by default. However, in order to work round YAEB,