X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_in.c;h=8e9b93ab39becb029e42667b79dd346ded61539e;hb=7716610b7633eef29e598fb6728e3f7cba2c9aed;hp=eb032bb52ee2ee7d8ead36faa4a0cd53fdc024f1;hpb=36771878fa93a04ecf5bdd71ad3c3c380a16aa03;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index eb032bb52..8e9b93ab3 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -593,6 +593,11 @@ if (n > 0) } +/* Forward declarations */ +static inline void bdat_push_receive_functions(void); +static inline void bdat_pop_receive_functions(void); + + /* Get a byte from the smtp input, in CHUNKING mode. Handle ack of the previous BDAT chunk and getting new ones when we run out. Uses the underlying smtp_getc or tls_getc both for that and for getting the @@ -771,7 +776,7 @@ if (chunking_state != CHUNKING_LAST) } -void +static inline void bdat_push_receive_functions(void) { /* push the current receive_* function on the "stack", and @@ -789,16 +794,25 @@ else } receive_getc = bdat_getc; +receive_getbuf = bdat_getbuf; receive_ungetc = bdat_ungetc; } -void +static inline void bdat_pop_receive_functions(void) { +if (lwr_receive_getc == NULL) + { + DEBUG(D_receive) debug_printf("chunking double-pop receive functions\n"); + return; + } 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; + +lwr_receive_getc = NULL; +lwr_receive_getbuf = NULL; +lwr_receive_ungetc = NULL; } /************************************************* @@ -817,6 +831,9 @@ Returns: the character int smtp_ungetc(int ch) { +if (smtp_inptr <= smtp_inbuffer) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "buffer underflow in smtp_ungetc"); + *--smtp_inptr = ch; return ch; } @@ -826,6 +843,7 @@ int bdat_ungetc(int ch) { chunking_data_left++; +bdat_push_receive_functions(); /* we're not done yet, calling push is safe, because it checks the state before pushing anything */ return lwr_receive_ungetc(ch); } @@ -1989,30 +2007,35 @@ static BOOL 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'; +uschar *v; +if (Ustrlen(smtp_cmd_data) <= 0) return FALSE; +v = smtp_cmd_data + Ustrlen(smtp_cmd_data) - 1; +while (v > smtp_cmd_data && isspace(*v)) v--; +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 == '"') && (v > smtp_cmd_data + 1)) - do v--; while (*v != '"' && v > smtp_cmd_data+1); + if (*v == '"') + { + do v--; while (v > smtp_cmd_data && *v != '"'); + if (v <= smtp_cmd_data) return FALSE; + } v--; } +if (v <= smtp_cmd_data) return FALSE; n = v; if (*v == '=') { - while(isalpha(n[-1])) n--; + while (n > smtp_cmd_data && isalpha(n[-1])) n--; /* RFC says SP, but TAB seen in wild and other major MTAs accept it */ - if (!isspace(n[-1])) return FALSE; + if (n <= smtp_cmd_data || !isspace(n[-1])) return FALSE; n[-1] = 0; } else { n++; - if (v == smtp_cmd_data) return FALSE; } *v++ = 0; *name = n; @@ -2228,9 +2251,11 @@ while (done <= 0) /* Apply SMTP rewrite */ - raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)? - rewrite_one(smtp_cmd_data, rewrite_smtp|rewrite_smtp_sender, NULL, FALSE, - US"", global_rewrite_rules) : smtp_cmd_data; + raw_sender = rewrite_existflags & rewrite_smtp + /* deconst ok as smtp_cmd_data was not const */ + ? US rewrite_one(smtp_cmd_data, rewrite_smtp|rewrite_smtp_sender, NULL, + FALSE, US"", global_rewrite_rules) + : smtp_cmd_data; /* Extract the address; the TRUE flag allows <> as valid */ @@ -2250,7 +2275,8 @@ while (done <= 0) && sender_address[0] != 0 && sender_address[0] != '@') if (f.allow_unqualified_sender) { - sender_address = rewrite_address_qualify(sender_address, FALSE); + /* deconst ok as sender_address was not const */ + sender_address = US rewrite_address_qualify(sender_address, FALSE); DEBUG(D_receive) debug_printf("unqualified address %s accepted " "and rewritten\n", raw_sender); } @@ -2289,7 +2315,8 @@ while (done <= 0) recipient address */ recipient = rewrite_existflags & rewrite_smtp - ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", + /* deconst ok as smtp_cmd_data was not const */ + ? US rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", global_rewrite_rules) : smtp_cmd_data; @@ -2308,7 +2335,8 @@ while (done <= 0) { DEBUG(D_receive) debug_printf("unqualified address %s accepted\n", recipient); - recipient = rewrite_address_qualify(recipient, TRUE); + /* deconst ok as recipient was not const */ + recipient = US rewrite_address_qualify(recipient, TRUE); } /* The function moan_smtp_batch() does not return. */ else @@ -2550,7 +2578,9 @@ 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; +lwr_receive_getc = NULL; +lwr_receive_getbuf = NULL; +lwr_receive_ungetc = NULL; smtp_inptr = smtp_inend = smtp_inbuffer; smtp_had_eof = smtp_had_error = 0; @@ -3836,7 +3866,8 @@ if (f.allow_unqualified_recipient || strcmpic(*recipient, US"postmaster") == 0) DEBUG(D_receive) debug_printf("unqualified address %s accepted\n", *recipient); rd = Ustrlen(recipient) + 1; - *recipient = rewrite_address_qualify(*recipient, TRUE); + /* deconst ok as *recipient was not const */ + *recipient = US rewrite_address_qualify(*recipient, TRUE); return rd; } smtp_printf("501 %s: recipient address must contain a domain\r\n", FALSE, @@ -4887,7 +4918,8 @@ while (done <= 0) TRUE flag allows "<>" as a sender address. */ raw_sender = rewrite_existflags & rewrite_smtp - ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", + /* deconst ok as smtp_cmd_data was not const */ + ? US rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", global_rewrite_rules) : smtp_cmd_data; @@ -4949,7 +4981,8 @@ while (done <= 0) if (f.allow_unqualified_sender) { sender_domain = Ustrlen(sender_address) + 1; - sender_address = rewrite_address_qualify(sender_address, FALSE); + /* deconst ok as sender_address was not const */ + sender_address = US rewrite_address_qualify(sender_address, FALSE); DEBUG(D_receive) debug_printf("unqualified address %s accepted\n", raw_sender); } @@ -5019,6 +5052,10 @@ while (done <= 0) case RCPT_CMD: HAD(SCH_RCPT); + /* We got really to many recipients. A check against configured + limits is done later */ + if (rcpt_count < 0 || rcpt_count >= INT_MAX/2) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Too many recipients: %d", rcpt_count); rcpt_count++; was_rcpt = fl.rcpt_in_progress = TRUE; @@ -5141,7 +5178,8 @@ while (done <= 0) as a recipient address */ recipient = rewrite_existflags & rewrite_smtp - ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", + /* deconst ok as smtp_cmd_data was not const */ + ? US rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", global_rewrite_rules) : smtp_cmd_data; @@ -5174,7 +5212,7 @@ while (done <= 0) /* Check maximum allowed */ - if (rcpt_count > recipients_max && recipients_max > 0) + if (rcpt_count+1 < 0 || rcpt_count > recipients_max && recipients_max > 0) { if (recipients_max_reject) { @@ -5319,7 +5357,7 @@ while (done <= 0) DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n", (int)chunking_state, chunking_data_left); - f.bdat_readers_wanted = TRUE; + f.bdat_readers_wanted = TRUE; /* FIXME: redundant vs chunking_state? */ f.dot_ends = FALSE; goto DATA_BDAT; @@ -5328,7 +5366,7 @@ while (done <= 0) case DATA_CMD: HAD(SCH_DATA); f.dot_ends = TRUE; - f.bdat_readers_wanted = FALSE + f.bdat_readers_wanted = FALSE; DATA_BDAT: /* Common code for DATA and BDAT */ #ifndef DISABLE_PIPE_CONNECT @@ -5369,6 +5407,12 @@ while (done <= 0) sender_address = NULL; /* This will allow a new MAIL without RSET */ sender_address_unrewritten = NULL; smtp_printf("554 Too many recipients\r\n", FALSE); + + if (chunking_state > CHUNKING_OFFERED) + { + bdat_push_receive_functions(); + bdat_flush_data(); + } break; } @@ -5399,9 +5443,6 @@ while (done <= 0) } } - if (f.bdat_readers_wanted) - bdat_push_receive_functions(); - if (user_msg) smtp_user_msg(US"354", user_msg); else @@ -5409,6 +5450,9 @@ while (done <= 0) "354 Enter message, ending with \".\" on a line by itself\r\n", FALSE); } + if (f.bdat_readers_wanted) + bdat_push_receive_functions(); + #ifdef TCP_QUICKACK if (smtp_in) /* all ACKs needed to ramp window up for bulk data */ (void) setsockopt(fileno(smtp_in), IPPROTO_TCP, TCP_QUICKACK,