commit 51894f20e0c03113b4c4e07898ac5e955b21ec41 Merge: caba96329 f70940c94 Author: Jeremy Harris Date: Sat Nov 4 14:20:45 2023 +0000 Merge branch '4.next' diff --git a/src/src/acl.c b/src/src/acl.c index 578cf32cb..cdf60bbb8 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -203,7 +203,14 @@ static condition_def conditions[] = { [ACLC_DELAY] = { US"delay", TRUE, TRUE, ACL_BIT_NOTQUIT }, #ifndef DISABLE_DKIM [ACLC_DKIM_SIGNER] = { US"dkim_signers", TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM }, - [ACLC_DKIM_STATUS] = { US"dkim_status", TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM }, + [ACLC_DKIM_STATUS] = { US"dkim_status", TRUE, FALSE, + (unsigned int) + ~(ACL_BIT_DKIM | ACL_BIT_DATA | ACL_BIT_MIME +# ifndef DISABLE_PRDR + | ACL_BIT_PRDR +# endif + ), + }, #endif #ifdef SUPPORT_DMARC [ACLC_DMARC_STATUS] = { US"dmarc_status", TRUE, FALSE, (unsigned int) ~ACL_BIT_DATA }, @@ -3764,8 +3771,14 @@ for (; cb; cb = cb->next) break; case ACLC_DKIM_STATUS: - rc = match_isinlist(dkim_verify_status, - &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); + { /* return good for any match */ + const uschar * s = dkim_verify_status ? dkim_verify_status : US"none"; + int sep = 0; + for (uschar * ss; ss = string_nextinlist(&s, &sep, NULL, 0); ) + if ( (rc = match_isinlist(ss, &arg, + 0, NULL, NULL, MCL_STRING, TRUE, NULL)) + == OK) break; + } break; #endif diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index 4c67f17e2..0c9fb37fe 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -77,7 +77,7 @@ auth_get_data(uschar ** aptr, const uschar * challenge, int challen) { int c; int p = 0; -smtp_printf("334 %s\r\n", FALSE, b64encode(challenge, challen)); +smtp_printf("334 %s\r\n", SP_NO_MORE, b64encode(challenge, challen)); while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF) { if (p >= big_buffer_size - 1) return BAD64; diff --git a/src/src/auths/get_no64_data.c b/src/src/auths/get_no64_data.c index e2cadfbc6..ae11ae5dc 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", FALSE, challenge); +smtp_printf("334 %s\r\n", SP_NO_MORE, challenge); while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF) { if (p >= big_buffer_size - 1) return BAD64; diff --git a/src/src/daemon.c b/src/src/daemon.c index 9709845e5..f2183c735 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -128,7 +128,7 @@ never_error(uschar *log_msg, uschar *smtp_msg, int was_errno) uschar *emsg = was_errno <= 0 ? US"" : string_sprintf(": %s", strerror(was_errno)); log_write(0, LOG_MAIN|LOG_PANIC, "%s%s", log_msg, emsg); -if (smtp_out) smtp_printf("421 %s\r\n", FALSE, smtp_msg); +if (smtp_out) smtp_printf("421 %s\r\n", SP_NO_MORE, smtp_msg); } @@ -233,7 +233,7 @@ if (getsockname(accept_socket, (struct sockaddr *)(&interface_sockaddr), { log_write(0, LOG_MAIN | ((errno == ECONNRESET)? 0 : LOG_PANIC), "getsockname() failed: %s", strerror(errno)); - smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n", FALSE); + smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n", SP_NO_MORE); goto ERROR_RETURN; } @@ -263,7 +263,7 @@ if (smtp_accept_max > 0 && smtp_accept_count >= smtp_accept_max) DEBUG(D_any) debug_printf("rejecting SMTP connection: count=%d max=%d\n", smtp_accept_count, smtp_accept_max); smtp_printf("421 Too many concurrent SMTP connections; " - "please try again later.\r\n", FALSE); + "please try again later.\r\n", SP_NO_MORE); log_write(L_connection_reject, LOG_MAIN, "Connection from %Y refused: too many connections", whofrom); @@ -282,7 +282,7 @@ if (smtp_load_reserve >= 0) { DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n", (double)load_average/1000.0); - smtp_printf("421 Too much load; please try again later.\r\n", FALSE); + smtp_printf("421 Too much load; please try again later.\r\n", SP_NO_MORE); log_write(L_connection_reject, LOG_MAIN, "Connection from %Y refused: load average = %.2f", whofrom, (double)load_average/1000.0); @@ -351,7 +351,7 @@ if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host) "IP address: count=%d max=%d\n", host_accept_count, max_for_this_host); smtp_printf("421 Too many concurrent SMTP connections " - "from this IP address; please try again later.\r\n", FALSE); + "from this IP address; please try again later.\r\n", SP_NO_MORE); log_write(L_connection_reject, LOG_MAIN, "Connection from %Y refused: too many connections " "from that IP address", whofrom); @@ -445,7 +445,7 @@ if (pid == 0) "(smtp_active_hostname): %s", raw_active_hostname, expand_string_message); smtp_printf("421 Local configuration error; " - "please try again later.\r\n", FALSE); + "please try again later.\r\n", SP_NO_MORE); mac_smtp_fflush(); search_tidyup(); exim_underbar_exit(EXIT_FAILURE); diff --git a/src/src/macros.h b/src/src/macros.h index 2658b9ab7..969393561 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1159,4 +1159,12 @@ typedef unsigned mcs_flags; #define TSUC_ALLOW_TAINTED_ARGS BIT(1) #define TSUC_ALLOW_RECIPIENTS BIT(2) +/* Flags for smtp_printf */ +#define SP_MORE TRUE +#define SP_NO_MORE FALSE + +/* Flags for smtp_respond */ +#define SR_FINAL TRUE +#define SR_NOT_FINAL FALSE + /* End of macros.h */ diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index 36e559b59..c723ae6c8 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -1868,9 +1868,9 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next) if (*dkim_verify_min_keysizes) { unsigned minbits; - uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype], + const uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype], dkim_verify_min_keysizes); - if (ss && (minbits = atoi(CS ss)) > sig->keybits) + if (ss && (minbits = atoi(CCS ss)) > sig->keybits) { DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u Minima '%s'\n", pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes); diff --git a/src/src/receive.c b/src/src/receive.c index 8a400caf0..8190c5941 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -570,7 +570,7 @@ smtp_user_msg(uschar *code, uschar *user_msg) { int len = 3; smtp_message_code(&code, &len, &user_msg, NULL, TRUE); -smtp_respond(code, len, TRUE, user_msg); +smtp_respond(code, len, SR_FINAL, user_msg); } #endif @@ -1457,7 +1457,7 @@ if (!(mbox_file = spool_mbox(&mbox_size, NULL, &mbox_filename))) #ifdef EXPERIMENTAL_DCC dcc_ok = 0; #endif - smtp_respond(US"451", 3, TRUE, US"temporary local problem"); + smtp_respond(US"451", 3, SR_FINAL, US"temporary local problem"); message_id[0] = 0; /* Indicate no message accepted */ *smtp_reply_ptr = US""; /* Indicate reply already sent */ return FALSE; /* Indicate skip to end of receive function */ @@ -2309,7 +2309,7 @@ OVERSIZE: sender_address, sender_fullhost ? " H=" : "", sender_fullhost ? sender_fullhost : US"", sender_ident ? " U=" : "", sender_ident ? sender_ident : US""); - smtp_printf("552 Message header not CRLF terminated\r\n", FALSE); + smtp_printf("552 Message header not CRLF terminated\r\n", SP_NO_MORE); bdat_flush_data(); smtp_reply = US""; goto TIDYUP; /* Skip to end of function */ @@ -3251,10 +3251,9 @@ if (!ferror(spool_data_file) && !(receive_feof)() && message_ended != END_DOT) { Uunlink(spool_name); /* Lose data file when closed */ cancel_cutthrough_connection(TRUE, US"sender closed connection"); - message_id[0] = 0; /* Indicate no message_accepted */ smtp_reply = handle_lost_connection(US""); smtp_yield = FALSE; - goto TIDYUP; /* Skip to end of function */ + goto NOT_ACCEPTED; /* Skip to end of function */ } break; @@ -3597,7 +3596,7 @@ else int all_pass = OK; int all_fail = FAIL; - smtp_printf("353 PRDR content analysis beginning\r\n", TRUE); + smtp_printf("353 PRDR content analysis beginning\r\n", SP_MORE); /* Loop through recipients, responses must be in same order received */ for (unsigned int c = 0; recipients_count > c; c++) { @@ -3661,7 +3660,7 @@ else /* Check the recipients count again, as the MIME ACL might have changed them. */ - if (acl_smtp_data != NULL && recipients_count > 0) + if (acl_smtp_data && recipients_count > 0) { rc = acl_check(ACL_WHERE_DATA, NULL, acl_smtp_data, &user_msg, &log_msg); add_acl_headers(ACL_WHERE_DATA, US"DATA"); @@ -3922,7 +3921,7 @@ else if (smtp_input) if (!smtp_batched_input) { - smtp_respond(smtp_code, 3, TRUE, errmsg); + smtp_respond(smtp_code, 3, SR_FINAL, errmsg); smtp_reply = US""; /* Indicate reply already sent */ goto NOT_ACCEPTED; /* Skip to end of function */ } @@ -4030,11 +4029,6 @@ else receive_messagecount++; -/* Add data size to written header size. We do not count the initial file name -that is in the file, but we do add one extra for the notional blank line that -precedes the data. This total differs from message_size in that it include the -added Received: header and any other headers that got created locally. */ - if (fflush(spool_data_file)) { errmsg = string_sprintf("Spool write error: %s", strerror(errno)); @@ -4054,8 +4048,13 @@ if (fflush(spool_data_file)) /* Does not return */ } } -fstat(data_fd, &statbuf); +/* Add data size to written header size. We do not count the initial file name +that is in the file, but we do add one extra for the notional blank line that +precedes the data. This total differs from message_size in that it include the +added Received: header and any other headers that got created locally. */ + +fstat(data_fd, &statbuf); msg_size += statbuf.st_size - spool_data_start_offset(message_id) + 1; /* Generate a "message received" log entry. We do this by building up a dynamic @@ -4349,9 +4348,9 @@ if(!smtp_reply) #endif { log_write(0, LOG_MAIN | - (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) | - (LOGGING(received_sender) ? LOG_SENDER : 0), - "%Y", g); + (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) | + (LOGGING(received_sender) ? LOG_SENDER : 0), + "%Y", g); /* Log any control actions taken by an ACL or local_scan(). */ @@ -4389,9 +4388,16 @@ a queue-runner could grab it in the window. A fflush() was done earlier in the expectation that any write errors on the data file will be flushed(!) out thereby. Nevertheless, it is theoretically -possible for fclose() to fail - but what to do? What has happened to the lock -if this happens? We can at least log it; if it is observed on some platform -then we can think about properly declaring the message not-received. */ +possible for fclose() to fail - and this has been seen on obscure filesystems +(probably one that delayed the actual media write as long as possible) +but what to do? What has happened to the lock if this happens? +It's a mes because we already logged the acceptance. +We can at least log the issue, try to remove spoolfiles and respond with +a temp-reject. We do not want to close before logging acceptance because +we want to hold the lock until we know that logging worked. +Could we make this less likely by doing an fdatasync() just after the fflush()? +That seems like a good thing on data-security grounds, but how much will it hit +performance? */ goto TIDYUP; @@ -4404,8 +4410,27 @@ process_info[process_info_len] = 0; /* Remove message id */ if (spool_data_file && cutthrough_done == NOT_TRIED) { if (fclose(spool_data_file)) /* Frees the lock */ - log_write(0, LOG_MAIN|LOG_PANIC, - "spoolfile error on close: %s", strerror(errno)); + { + log_msg = string_sprintf("spoolfile error on close: %s", strerror(errno)); + log_write(0, LOG_MAIN|LOG_PANIC | + (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) | + (LOGGING(received_sender) ? LOG_SENDER : 0), + "%s", log_msg); + log_write(0, LOG_MAIN | + (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) | + (LOGGING(received_sender) ? LOG_SENDER : 0), + "rescind the above message-accept"); + + Uunlink(spool_name); + Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H")); + Uunlink(spool_fname(US"msglog", message_subdir, message_id, US"")); + + /* Claim a data ACL temp-reject, just to get reject logging and resposponse */ + smtp_handle_acl_fail(ACL_WHERE_DATA, rc, NULL, log_msg); + smtp_reply = US""; /* Indicate reply already sent */ + + message_id[0] = 0; /* no message accepted */ + } spool_data_file = NULL; } @@ -4434,7 +4459,7 @@ if (smtp_input) { if (fake_response != OK) smtp_respond(fake_response == DEFER ? US"450" : US"550", - 3, TRUE, fake_response_text); + 3, SR_FINAL, fake_response_text); /* An OK response is required; use "message" text if present. */ @@ -4443,7 +4468,7 @@ if (smtp_input) uschar *code = US"250"; int len = 3; smtp_message_code(&code, &len, &user_msg, NULL, TRUE); - smtp_respond(code, len, TRUE, user_msg); + smtp_respond(code, len, SR_FINAL, user_msg); } /* Default OK response */ @@ -4471,10 +4496,10 @@ if (smtp_input) else if (smtp_reply[0] != 0) if (fake_response != OK && smtp_reply[0] == '2') - smtp_respond(fake_response == DEFER ? US"450" : US"550", 3, TRUE, - fake_response_text); + smtp_respond(fake_response == DEFER ? US"450" : US"550", + 3, SR_FINAL, fake_response_text); else - smtp_printf("%.1024s\r\n", FALSE, smtp_reply); + smtp_printf("%.1024s\r\n", SP_NO_MORE, smtp_reply); switch (cutthrough_done) { diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 8cc9f74bf..c565d522d 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -764,7 +764,7 @@ for(;;) return EOD; } - smtp_printf("250 %u byte chunk received\r\n", FALSE, chunking_datasize); + smtp_printf("250 %u byte chunk received\r\n", SP_NO_MORE, chunking_datasize); chunking_state = CHUNKING_OFFERED; DEBUG(D_receive) debug_printf("chunking state %d\n", (int)chunking_state); @@ -802,7 +802,7 @@ next_cmd: case NOOP_CMD: HAD(SCH_NOOP); - smtp_printf("250 OK\r\n", FALSE); + smtp_printf("250 OK\r\n", SP_NO_MORE); goto next_cmd; case BDAT_CMD: @@ -1298,7 +1298,7 @@ smtp_closedown(uschar * message) { if (!smtp_in || smtp_batched_input) return; receive_swallow_smtp(); -smtp_printf("421 %s\r\n", FALSE, message); +smtp_printf("421 %s\r\n", SP_NO_MORE, message); for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { @@ -1307,16 +1307,16 @@ for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) case QUIT_CMD: f.smtp_in_quit = TRUE; - smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); + smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname); mac_smtp_fflush(); return; case RSET_CMD: - smtp_printf("250 Reset OK\r\n", FALSE); + smtp_printf("250 Reset OK\r\n", SP_NO_MORE); break; default: - smtp_printf("421 %s\r\n", FALSE, message); + smtp_printf("421 %s\r\n", SP_NO_MORE, message); break; } } @@ -2266,7 +2266,7 @@ if (!f.sender_host_unknown) { log_write(0, LOG_MAIN, "getsockopt() failed from %s: %s", host_and_ident(FALSE), strerror(errno)); - smtp_printf("451 SMTP service not available\r\n", FALSE); + smtp_printf("451 SMTP service not available\r\n", SP_NO_MORE); return FALSE; } } @@ -2370,7 +2370,7 @@ if (!f.sender_host_unknown) log_write(0, LOG_MAIN|LOG_REJECT, "connection from %s refused (IP options)", host_and_ident(FALSE)); - smtp_printf("554 SMTP service not available\r\n", FALSE); + smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE); return FALSE; } @@ -2425,7 +2425,7 @@ if (!f.sender_host_unknown) #ifndef DISABLE_TLS if (!tls_in.on_connect) #endif - smtp_printf("554 SMTP service not available\r\n", FALSE); + smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE); return FALSE; } @@ -2456,7 +2456,7 @@ if (!f.sender_host_unknown) log_write(L_connection_reject, LOG_MAIN|LOG_REJECT, "refused connection from %s " "(tcp wrappers)", host_and_ident(FALSE)); - smtp_printf("554 SMTP service not available\r\n", FALSE); + smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE); } else { @@ -2466,7 +2466,7 @@ if (!f.sender_host_unknown) log_write(L_connection_reject, LOG_MAIN|LOG_REJECT, "temporarily refused connection from %s " "(tcp wrappers errno=%d)", host_and_ident(FALSE), save_errno); - smtp_printf("451 Temporary local problem - please try later\r\n", FALSE); + smtp_printf("451 Temporary local problem - please try later\r\n", SP_NO_MORE); } return FALSE; } @@ -2486,7 +2486,7 @@ if (!f.sender_host_unknown) host_and_ident(FALSE), smtp_accept_count - 1, smtp_accept_max, smtp_accept_reserve, (rc == DEFER)? " (lookup deferred)" : ""); smtp_printf("421 %s: Too many concurrent SMTP connections; " - "please try again later\r\n", FALSE, smtp_active_hostname); + "please try again later\r\n", SP_NO_MORE, smtp_active_hostname); return FALSE; } reserved_host = TRUE; @@ -2507,7 +2507,7 @@ if (!f.sender_host_unknown) LOG_MAIN, "temporarily refused connection from %s: not in " "reserve list and load average = %.2f", host_and_ident(FALSE), (double)load_average/1000.0); - smtp_printf("421 %s: Too much load; please try again later\r\n", FALSE, + smtp_printf("421 %s: Too much load; please try again later\r\n", SP_NO_MORE, smtp_active_hostname); return FALSE; } @@ -2681,7 +2681,7 @@ if (!check_sync()) "synchronization error (input sent without waiting for greeting): " "rejected connection from %s input=\"%s\"", host_and_ident(TRUE), string_printing(string_copyn(smtp_inptr, n))); - smtp_printf("554 SMTP synchronization error\r\n", FALSE); + smtp_printf("554 SMTP synchronization error\r\n", SP_NO_MORE); return FALSE; } @@ -2692,7 +2692,7 @@ smtp_printf("%Y", #ifndef DISABLE_PIPE_CONNECT fl.pipe_connect_acceptable && pipeline_connect_sends(), #else - FALSE, + SP_NO_MORE, #endif ss); @@ -2751,10 +2751,10 @@ if (++synprot_error_count > smtp_max_synprot_errors) if (code > 0) { - smtp_printf("%d%c%s%s%s\r\n", FALSE, code, yield == 1 ? '-' : ' ', + smtp_printf("%d%c%s%s%s\r\n", SP_NO_MORE, code, yield == 1 ? '-' : ' ', data ? data : US"", data ? US": " : US"", errmess); if (yield == 1) - smtp_printf("%d Too many syntax or protocol errors\r\n", FALSE, code); + smtp_printf("%d Too many syntax or protocol errors\r\n", SP_NO_MORE, code); } return yield; @@ -2781,7 +2781,7 @@ Returns: nothing */ void -smtp_respond(uschar* code, int codelen, BOOL final, uschar *msg) +smtp_respond(uschar * code, int codelen, BOOL final, uschar * msg) { int esclen = 0; uschar *esc = US""; @@ -2830,7 +2830,7 @@ for (;;) } else { - smtp_printf("%.3s-%.*s%.*s\r\n", TRUE, code, esclen, esc, (int)(nl - msg), msg); + smtp_printf("%.3s-%.*s%.*s\r\n", SP_MORE, code, esclen, esc, (int)(nl - msg), msg); msg = nl + 1; Uskip_whitespace(&msg); } @@ -2936,7 +2936,7 @@ Returns: 0 in most cases */ int -smtp_handle_acl_fail(int where, int rc, uschar *user_msg, uschar *log_msg) +smtp_handle_acl_fail(int where, int rc, uschar * user_msg, uschar * log_msg) { BOOL drop = rc == FAIL_DROP; int codelen = 3; @@ -3022,7 +3022,7 @@ if (sender_verified_failed && string_sprintf(": %s", sender_verified_failed->message)); if (rc == FAIL && sender_verified_failed->user_message) - smtp_respond(smtp_code, codelen, FALSE, string_sprintf( + smtp_respond(smtp_code, codelen, SR_NOT_FINAL, string_sprintf( testflag(sender_verified_failed, af_verify_pmfail)? "Postmaster verification failed while checking <%s>\n%s\n" "Several RFCs state that you are required to have a postmaster\n" @@ -3054,7 +3054,7 @@ always a 5xx one - see comments at the start of this function. If the original rc was FAIL_DROP we drop the connection and yield 2. */ if (rc == FAIL) - smtp_respond(smtp_code, codelen, TRUE, + smtp_respond(smtp_code, codelen, SR_FINAL, user_msg ? user_msg : US"Administrative prohibition"); /* Send temporary failure response to the command. Don't give any details, @@ -3072,12 +3072,12 @@ else && sender_verified_failed && sender_verified_failed->message ) - smtp_respond(smtp_code, codelen, FALSE, sender_verified_failed->message); + smtp_respond(smtp_code, codelen, SR_NOT_FINAL, sender_verified_failed->message); - smtp_respond(smtp_code, codelen, TRUE, user_msg); + smtp_respond(smtp_code, codelen, SR_FINAL, user_msg); } else - smtp_respond(smtp_code, codelen, TRUE, + smtp_respond(smtp_code, codelen, SR_FINAL, US"Temporary local problem - please try later"); /* Log the incident to the logs that are specified by log_reject_target @@ -3194,7 +3194,7 @@ responses are all internal, they should be reasonable size. */ if (code && defaultrespond) { if (user_msg) - smtp_respond(code, 3, TRUE, user_msg); + smtp_respond(code, 3, SR_FINAL, user_msg); else { gstring * g; @@ -3203,7 +3203,7 @@ if (code && defaultrespond) va_start(ap, defaultrespond); g = string_vformat(NULL, SVFMT_EXTEND|SVFMT_REBUFFER, CS defaultrespond, ap); va_end(ap); - smtp_printf("%s %Y\r\n", FALSE, code, g); + smtp_printf("%s %Y\r\n", SP_NO_MORE, code, g); } mac_smtp_fflush(); } @@ -3360,7 +3360,7 @@ smtp_user_msg(uschar *code, uschar *user_msg) { int len = 3; smtp_message_code(&code, &len, &user_msg, NULL, TRUE); -smtp_respond(code, len, TRUE, user_msg); +smtp_respond(code, len, SR_FINAL, user_msg); } @@ -3495,7 +3495,7 @@ if (f.allow_unqualified_recipient || strcmpic(*recipient, US"postmaster") == 0) *recipient = US rewrite_address_qualify(*recipient, TRUE); return rd; } -smtp_printf("501 %s: recipient address must contain a domain\r\n", FALSE, +smtp_printf("501 %s: recipient address must contain a domain\r\n", SP_NO_MORE, smtp_cmd_data); log_write(L_smtp_syntax_error, LOG_MAIN|LOG_REJECT, "unqualified %s rejected: <%s> %s%s", @@ -3523,9 +3523,9 @@ if ( acl_smtp_quit #endif if (*user_msgp) - smtp_respond(US"221", 3, TRUE, *user_msgp); + smtp_respond(US"221", 3, SR_FINAL, *user_msgp); else - smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); + smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname); #ifdef SERVERSIDE_CLOSE_NOWAIT # ifndef DISABLE_TLS @@ -3554,7 +3554,7 @@ smtp_rset_handler(void) { HAD(SCH_RSET); incomplete_transaction_log(US"RSET"); -smtp_printf("250 Reset OK\r\n", FALSE); +smtp_printf("250 Reset OK\r\n", SP_NO_MORE); cmd_list[CL_RSET].is_mail_cmd = FALSE; if (chunking_state > CHUNKING_OFFERED) chunking_state = CHUNKING_OFFERED; @@ -3809,7 +3809,7 @@ while (done <= 0) { int rc = smtp_in_auth(au, &smtp_resp, &errmsg); - smtp_printf("%s\r\n", FALSE, smtp_resp); + smtp_printf("%s\r\n", SP_NO_MORE, smtp_resp); if (rc != OK) { uschar * logmsg = NULL; @@ -3870,7 +3870,7 @@ while (done <= 0) if (!check_helo(smtp_cmd_data)) { - smtp_printf("501 Syntactically invalid %s argument(s)\r\n", FALSE, hello); + smtp_printf("501 Syntactically invalid %s argument(s)\r\n", SP_NO_MORE, hello); log_write(0, LOG_MAIN|LOG_REJECT, "rejected %s from %s: syntactically " "invalid argument(s): %s", hello, host_and_ident(FALSE), @@ -3935,7 +3935,7 @@ while (done <= 0) { if (fl.helo_verify_required) { - smtp_printf("%d %s argument does not match calling host\r\n", FALSE, + smtp_printf("%d %s argument does not match calling host\r\n", SP_NO_MORE, tempfail? 451 : 550, hello); log_write(0, LOG_MAIN|LOG_REJECT, "%srejected \"%s %s\" from %s", tempfail? "temporarily " : "", @@ -4288,7 +4288,7 @@ while (done <= 0) done = synprot_error(L_smtp_syntax_error, resp, NULL, errmsg); else { - smtp_printf("%d %s\r\n", FALSE, resp, errmsg); + smtp_printf("%d %s\r\n", SP_NO_MORE, resp, errmsg); log_write(0, LOG_MAIN|LOG_REJECT, "rejected XCLIENT from %s: %s", host_and_ident(FALSE), errmsg); } @@ -4302,7 +4302,7 @@ while (done <= 0) We require that we do; the following HELO/EHLO handling will set sender_helo_name as normal. */ - smtp_printf("%s XCLIENT success\r\n", FALSE, smtp_code); + smtp_printf("%s XCLIENT success\r\n", SP_NO_MORE, smtp_code); } break; /* XCLIENT */ } @@ -4326,7 +4326,7 @@ while (done <= 0) if ( fl.helo_verify_required || verify_check_host(&hosts_require_helo) == OK) { - smtp_printf("503 HELO or EHLO required\r\n", FALSE); + smtp_printf("503 HELO or EHLO required\r\n", SP_NO_MORE); log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no " "HELO/EHLO given", host_and_ident(FALSE)); break; @@ -4353,7 +4353,7 @@ while (done <= 0) if (smtp_mailcmd_max > 0 && smtp_mailcmd_count > smtp_mailcmd_max) { - smtp_printf("421 too many messages in this connection\r\n", FALSE); + smtp_printf("421 too many messages in this connection\r\n", SP_NO_MORE); log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many " "messages in one connection", host_and_ident(TRUE)); break; @@ -4626,7 +4626,7 @@ while (done <= 0) if (thismessage_size_limit > 0 && message_size > thismessage_size_limit) { - smtp_printf("552 Message size exceeds maximum permitted\r\n", FALSE); + smtp_printf("552 Message size exceeds maximum permitted\r\n", SP_NO_MORE); log_write(L_size_reject, LOG_MAIN|LOG_REJECT, "rejected MAIL FROM:<%s> %s: " "message too big: size%s=%d max=%d", @@ -4651,7 +4651,7 @@ while (done <= 0) smtp_check_spool_space && message_size >= 0 ? message_size + 5000 : 0)) { - smtp_printf("452 Space shortage, please try later\r\n", FALSE); + smtp_printf("452 Space shortage, please try later\r\n", SP_NO_MORE); sender_address = NULL; break; } @@ -4673,7 +4673,7 @@ while (done <= 0) } else { - smtp_printf("501 %s: sender address must contain a domain\r\n", FALSE, + smtp_printf("501 %s: sender address must contain a domain\r\n", SP_NO_MORE, smtp_cmd_data); log_write(L_smtp_syntax_error, LOG_MAIN|LOG_REJECT, @@ -4753,7 +4753,7 @@ while (done <= 0) { if (f.smtp_in_pipelining_advertised && last_was_rej_mail) { - smtp_printf("503 sender not yet given\r\n", FALSE); + smtp_printf("503 sender not yet given\r\n", SP_NO_MORE); was_rej_mail = TRUE; } else @@ -4902,7 +4902,7 @@ while (done <= 0) if (recipients_max_reject) { rcpt_fail_count++; - smtp_printf("552 too many recipients\r\n", FALSE); + smtp_printf("552 too many recipients\r\n", SP_NO_MORE); if (!toomany) log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: message " "rejected: sender=<%s> %s", sender_address, host_and_ident(TRUE)); @@ -4910,7 +4910,7 @@ while (done <= 0) else { rcpt_defer_count++; - smtp_printf("452 too many recipients\r\n", FALSE); + smtp_printf("452 too many recipients\r\n", SP_NO_MORE); if (!toomany) log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: excess " "temporarily rejected: sender=<%s> %s", sender_address, @@ -4976,7 +4976,7 @@ while (done <= 0) if (user_msg) smtp_user_msg(US"250", user_msg); else - smtp_printf("250 Accepted\r\n", FALSE); + smtp_printf("250 Accepted\r\n", SP_NO_MORE); rcpt_fail_count++; discarded = TRUE; log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: " @@ -5063,15 +5063,15 @@ while (done <= 0) { uschar *code = US"503"; int len = Ustrlen(rcpt_smtp_response); - smtp_respond(code, 3, FALSE, US"All RCPT commands were rejected with " + smtp_respond(code, 3, SR_NOT_FINAL, US"All RCPT commands were rejected with " "this error:"); /* Responses from smtp_printf() will have \r\n on the end */ if (len > 2 && rcpt_smtp_response[len-2] == '\r') rcpt_smtp_response[len-2] = 0; - smtp_respond(code, 3, FALSE, rcpt_smtp_response); + smtp_respond(code, 3, SR_NOT_FINAL, rcpt_smtp_response); } if (f.smtp_in_pipelining_advertised && last_was_rcpt) - smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE, + smtp_printf("503 Valid RCPT command must precede %s\r\n", SP_NO_MORE, smtp_names[smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)]]); else done = synprot_error(L_smtp_protocol_error, 503, NULL, @@ -5091,7 +5091,7 @@ 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); + smtp_printf("554 Too many recipients\r\n", SP_NO_MORE); if (chunking_state > CHUNKING_OFFERED) { @@ -5132,7 +5132,7 @@ while (done <= 0) smtp_user_msg(US"354", user_msg); else smtp_printf( - "354 Enter message, ending with \".\" on a line by itself\r\n", FALSE); + "354 Enter message, ending with \".\" on a line by itself\r\n", SP_NO_MORE); } if (f.bdat_readers_wanted) @@ -5158,7 +5158,7 @@ while (done <= 0) if (!(address = parse_extract_address(smtp_cmd_data, &errmess, &start, &end, &recipient_domain, FALSE))) { - smtp_printf("501 %s\r\n", FALSE, errmess); + smtp_printf("501 %s\r\n", SP_NO_MORE, errmess); break; } @@ -5197,7 +5197,7 @@ while (done <= 0) break; } - smtp_printf("%s\r\n", FALSE, s); + smtp_printf("%s\r\n", SP_NO_MORE, s); } break; } @@ -5325,7 +5325,7 @@ while (done <= 0) if (rc == DEFER) { - smtp_printf("454 TLS currently unavailable\r\n", FALSE); + smtp_printf("454 TLS currently unavailable\r\n", SP_NO_MORE); break; } @@ -5358,15 +5358,15 @@ while (done <= 0) log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s", log_msg); if (user_msg) - smtp_respond(US"221", 3, TRUE, user_msg); + smtp_respond(US"221", 3, SR_FINAL, user_msg); else - smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); + smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname); log_close_event(US"by QUIT"); done = 2; break; default: - smtp_printf("554 Security failure\r\n", FALSE); + smtp_printf("554 Security failure\r\n", SP_NO_MORE); break; } tls_close(NULL, TLS_SHUTDOWN_NOWAIT); @@ -5394,7 +5394,7 @@ while (done <= 0) case NOOP_CMD: HAD(SCH_NOOP); - smtp_printf("250 OK\r\n", FALSE); + smtp_printf("250 OK\r\n", SP_NO_MORE); break; @@ -5405,23 +5405,23 @@ while (done <= 0) case HELP_CMD: HAD(SCH_HELP); - smtp_printf("214-Commands supported:\r\n214", TRUE); - smtp_printf(" AUTH", TRUE); + smtp_printf("214-Commands supported:\r\n214", SP_MORE); + smtp_printf(" AUTH", SP_MORE); #ifndef DISABLE_TLS if (tls_in.active.sock < 0 && verify_check_host(&tls_advertise_hosts) != FAIL) - smtp_printf(" STARTTLS", TRUE); + smtp_printf(" STARTTLS", SP_MORE); #endif - smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", TRUE); - smtp_printf(" NOOP QUIT RSET HELP", TRUE); - if (acl_smtp_etrn) smtp_printf(" ETRN", TRUE); - if (acl_smtp_expn) smtp_printf(" EXPN", TRUE); - if (acl_smtp_vrfy) smtp_printf(" VRFY", TRUE); + smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", SP_MORE); + smtp_printf(" NOOP QUIT RSET HELP", SP_MORE); + if (acl_smtp_etrn) smtp_printf(" ETRN", SP_MORE); + if (acl_smtp_expn) smtp_printf(" EXPN", SP_MORE); + if (acl_smtp_vrfy) smtp_printf(" VRFY", SP_MORE); #ifdef EXPERIMENTAL_XCLIENT if (proxy_session || verify_check_host(&hosts_xclient) != FAIL) - smtp_printf(" XCLIENT", TRUE); + smtp_printf(" XCLIENT", SP_MORE); #endif - smtp_printf("\r\n", FALSE); + smtp_printf("\r\n", SP_NO_MORE); break; @@ -5500,7 +5500,7 @@ while (done <= 0) { log_write(0, LOG_MAIN|LOG_PANIC, "failed to set up ETRN command: %s", error); - smtp_printf("458 Internal failure\r\n", FALSE); + smtp_printf("458 Internal failure\r\n", SP_NO_MORE); break; } } @@ -5531,7 +5531,7 @@ while (done <= 0) debug_printf("ETRN command is: %s\n", etrn_command); debug_printf("ETRN command execution skipped\n"); } - if (user_msg == NULL) smtp_printf("250 OK\r\n", FALSE); + if (user_msg == NULL) smtp_printf("250 OK\r\n", SP_NO_MORE); else smtp_user_msg(US"250", user_msg); break; } @@ -5542,7 +5542,7 @@ while (done <= 0) if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1)) { - smtp_printf("458 Already processing %s\r\n", FALSE, smtp_cmd_data); + smtp_printf("458 Already processing %s\r\n", SP_NO_MORE, smtp_cmd_data); break; } @@ -5607,12 +5607,12 @@ while (done <= 0) { log_write(0, LOG_MAIN|LOG_PANIC, "fork of process for ETRN failed: %s", strerror(errno)); - smtp_printf("458 Unable to fork process\r\n", FALSE); + smtp_printf("458 Unable to fork process\r\n", SP_NO_MORE); if (smtp_etrn_serialize) enq_end(etrn_serialize_key); } else if (!user_msg) - smtp_printf("250 OK\r\n", FALSE); + smtp_printf("250 OK\r\n", SP_NO_MORE); else smtp_user_msg(US"250", user_msg); @@ -5632,7 +5632,7 @@ while (done <= 0) done = synprot_error(L_smtp_syntax_error, 0, NULL, /* Just logs */ US"NUL character(s) present (shown as '?')"); smtp_printf("501 NUL characters are not allowed in SMTP commands\r\n", - FALSE); + SP_NO_MORE); break; @@ -5669,7 +5669,7 @@ while (done <= 0) #ifdef SUPPORT_PROXY case PROXY_FAIL_IGNORE_CMD: - smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", FALSE); + smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", SP_NO_MORE); break; #endif diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index efa6004a3..a17597e8b 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -3000,7 +3000,7 @@ exim_gnutls_state_st * state = NULL; if (tls_in.active.sock >= 0) { tls_error(US"STARTTLS received after TLS started", US "", NULL, errstr); - smtp_printf("554 Already in TLS\r\n", FALSE); + smtp_printf("554 Already in TLS\r\n", SP_NO_MORE); return FAIL; } @@ -3079,7 +3079,7 @@ mode, the fflush() happens when smtp_getc() is called. */ if (!state->tlsp->on_connect) { - smtp_printf("220 TLS go ahead\r\n", FALSE); + smtp_printf("220 TLS go ahead\r\n", SP_NO_MORE); fflush(smtp_out); } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index b02605eae..ef11de593 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -3504,7 +3504,7 @@ static uschar peerdn[256]; if (tls_in.active.sock >= 0) { tls_error(US"STARTTLS received after TLS started", NULL, US"", errstr); - smtp_printf("554 Already in TLS\r\n", FALSE); + smtp_printf("554 Already in TLS\r\n", SP_NO_MORE); return FAIL; } @@ -3624,7 +3624,7 @@ mode, the fflush() happens when smtp_getc() is called. */ SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx)); if (!tls_in.on_connect) { - smtp_printf("220 TLS go ahead\r\n", FALSE); + smtp_printf("220 TLS go ahead\r\n", SP_NO_MORE); fflush(smtp_out); } commit 44e35f5f592b4fb993a6a23ad9e0446af8a6d527 Author: Jeremy Harris Date: Sun Nov 5 21:29:53 2023 +0000 DANE: handle servefail for TLSA during Rverify. Bug 3030 diff --git a/src/src/verify.c b/src/src/verify.c index d8ebf5925..6361aa434 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -677,7 +677,7 @@ coding means skipping this whole loop and doing the append separately. */ sx->conn_args.interface = interface; sx->helo_data = tf->helo_data; sx->conn_args.tblock = addr->transport; - sx->conn_args.sock = -1; + sx->cctx.sock = sx->conn_args.sock = -1; sx->verify = TRUE; tls_retry_connection: @@ -1152,7 +1152,7 @@ no_conn: /* Ensure no cutthrough on multiple verifies that were incompatible */ if (options & vopt_callout_recipsender) cancel_cutthrough_connection(TRUE, US"not usable for cutthrough"); - if (sx->send_quit) + if (sx->send_quit && sx->cctx.sock >= 0) if (smtp_write_command(sx, SCMD_FLUSH, "QUIT\r\n") != -1) /* Wait a short time for response, and discard it */ smtp_read_response(sx, sx->buffer, sizeof(sx->buffer), '2', 1); commit 37b849dca4dfd855212a763662825e967a4d77b1 Author: Jeremy Harris Date: Tue Nov 7 15:02:18 2023 +0000 OpenSSL: fix non-DANE build diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index ef11de593..851ac77c5 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2605,7 +2605,7 @@ if (!(bs = OCSP_response_get1_basic(rsp))) asking for certificate-status under DANE, so this callback won't run for that combination. It still will for non-DANE. */ -#ifdef EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER +#if defined(EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER) && defined(SUPPORT_DANE) X509 * signer; if ( tls_out.dane_verified commit eb09d0da1fb995ad88f9a1c2998766c3e530be68 Author: Jeremy Harris Date: Tue Nov 7 19:38:22 2023 +0000 Fix use of empty log_reject_target. Bug 3039 Broken-by: 4243a209fd94 diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index c565d522d..e19c86ff8 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2051,16 +2051,19 @@ else DEBUG(D_receive) static void log_connect_tls_drop(const uschar * what, const uschar * log_msg) { -gstring * g = s_tlslog(NULL); -uschar * tls = string_from_gstring(g); - -log_write(L_connection_reject, - log_reject_target, "%s%s%s dropped by %s%s%s", - LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"", - host_and_ident(TRUE), - tls ? tls : US"", - what, - log_msg ? US": " : US"", log_msg); +if (log_reject_target) + { + gstring * g = s_tlslog(NULL); + uschar * tls = string_from_gstring(g); + + log_write(L_connection_reject, + log_reject_target, "%s%s%s dropped by %s%s%s", + LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"", + host_and_ident(TRUE), + tls ? tls : US"", + what, + log_msg ? US": " : US"", log_msg); + } } @@ -3085,7 +3088,7 @@ else the connection is not forcibly to be dropped, return 0. Otherwise, log why it is closing if required and return 2. */ -if (log_reject_target != 0) +if (log_reject_target) { #ifndef DISABLE_TLS gstring * g = s_tlslog(NULL); commit caf57fe7eb5018b8df196e6d9f99586232798eb3 Author: Jeremy Harris Date: Wed Nov 8 14:22:37 2023 +0000 typoes diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 851ac77c5..237303ba9 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -77,9 +77,9 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_OPENSSL_KEYLOG # define EXIM_HAVE_OPENSSL_CIPHER_GET_ID # define EXIM_HAVE_SESSION_TICKET -# define EXIM_HAVE_OPESSL_TRACE -# define EXIM_HAVE_OPESSL_GET0_SERIAL -# define EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS +# define EXIM_HAVE_OPENSSL_TRACE +# define EXIM_HAVE_OPENSSL_GET0_SERIAL +# define EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_CERTS # define EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN # ifndef DISABLE_OCSP # define EXIM_HAVE_OCSP @@ -1756,7 +1756,7 @@ level. */ DEBUG(D_tls) { SSL_CTX_set_info_callback(ctx, info_callback); -#if defined(EXIM_HAVE_OPESSL_TRACE) && !defined(OPENSSL_NO_SSL_TRACE) +#if defined(EXIM_HAVE_OPENSSL_TRACE) && !defined(OPENSSL_NO_SSL_TRACE) /* this needs a debug build of OpenSSL */ SSL_CTX_set_msg_callback(ctx, SSL_trace); #endif @@ -2442,7 +2442,7 @@ tls_in.ocsp = OCSP_NOT_RESP; if (!olist) return SSL_TLSEXT_ERR_NOACK; -#ifdef EXIM_HAVE_OPESSL_GET0_SERIAL +#ifdef EXIM_HAVE_OPENSSL_GET0_SERIAL { const X509 * cert_sent = SSL_get_certificate(s); const ASN1_INTEGER * cert_serial = X509_get0_serialNumber(cert_sent); @@ -2646,7 +2646,7 @@ if (!(bs = OCSP_response_get1_basic(rsp))) debug_printf("certs contained in basicresp:\n"); x509_stack_dump_cert_s_names( -#ifdef EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS +#ifdef EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_CERTS OCSP_resp_get0_certs(bs) #else bs->certs commit 4f780c09d2ab95bd9562ebe307a01043933adcd9 Author: Jeremy Harris Date: Fri Nov 10 14:37:23 2023 +0000 fix doubled logging of message_id diff --git a/src/src/receive.c b/src/src/receive.c index 8190c5941..041898a6b 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -3380,8 +3380,8 @@ if (extract_recip && (bad_addresses || recipients_count == 0)) } } - log_write(0, LOG_MAIN|LOG_PANIC, "%s %s found in headers", - message_id, bad_addresses ? "bad addresses" : "no recipients"); + log_write(0, LOG_MAIN|LOG_PANIC, "%s found in headers", + bad_addresses ? "bad addresses" : "no recipients"); fseek(spool_data_file, (long int)spool_data_start_offset(message_id), SEEK_SET); commit 5d5ad9fb16a2511ff2e0e7d4528d399f06f608da Author: Jeremy Harris Date: Mon Nov 13 18:12:31 2023 +0000 TLS: fix resumption for TLS-on-connect diff --git a/src/src/macros.h b/src/src/macros.h index 969393561..e2c1d0f94 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1103,14 +1103,22 @@ should not be one active. */ #define RESUME_USED BIT(4) #define RESUME_DECODE_STRING \ - US"not requested or offered : 0x02 :client requested, no server ticket" \ - ": 0x04 : 0x05 : 0x06 :client offered session, no server action" \ - ": 0x08 :no client request: 0x0A :client requested new ticket, server provided" \ - ": 0x0C :client offered session, not used: 0x0E :client offered session, server only provided new ticket" \ - ": 0x10 :session resumed unasked: 0x12 :session resumed unasked" \ - ": 0x14 : 0x15 : 0x16 :session resumed" \ - ": 0x18 :session resumed unasked: 0x1A :session resumed unasked" \ - ": 0x1C :session resumed: 0x1E :session resumed, also new ticket" + US"not requested or offered" \ + ": 0x02 :client requested, no server ticket" \ + ": 0x04 : 0x05 " \ + ": 0x06 :client offered session, no server action" \ + ": 0x08 :no client request" \ + ": 0x0A :client requested new ticket, server provided" \ + ": 0x0C :client offered session, not used" \ + ": 0x0E :client offered session, server only provided new ticket" \ + ": 0x10 :session resumed unasked" \ + ": 0x12 :session resumed unasked" \ + ": 0x14 : 0x15" \ + ": 0x16 :session resumed" \ + ": 0x18 :session resumed unasked" \ + ": 0x1A :session resumed unasked" \ + ": 0x1C :session resumed" \ + ": 0x1E :session resumed, also new ticket" /* Flags for string_vformat */ #define SVFMT_EXTEND BIT(0) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index a17597e8b..56ea93935 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2851,7 +2851,7 @@ static int tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when, unsigned incoming, const gnutls_datum_t * msg) { -DEBUG(D_tls) debug_printf("newticket cb\n"); +DEBUG(D_tls) debug_printf("newticket cb (on server)\n"); tls_in.resumption |= RESUME_CLIENT_REQUESTED; return 0; } @@ -2888,9 +2888,12 @@ tls_server_resume_posthandshake(exim_gnutls_state_st * state) { if (gnutls_session_resumption_requested(state->session)) { - /* This tells us the client sent a full ticket. We use a + /* This tells us the client sent a full (?) ticket. We use a callback on session-ticket request, elsewhere, to tell - if a client asked for a ticket. */ + if a client asked for a ticket. + XXX As of GnuTLS 3.0.1 it seems to be returning true even for + a pure ticket-req (a zero-length Session Ticket extension + in the Client Hello, for 1.2) which mucks up our logic. */ tls_in.resumption |= RESUME_CLIENT_SUGGESTED; DEBUG(D_tls) debug_printf("client requested resumption\n"); @@ -3319,7 +3322,8 @@ tls_retrieve_session(tls_support * tlsp, gnutls_session_t session, tlsp->resumption = RESUME_SUPPORTED; if (!conn_args->have_lbserver) - { DEBUG(D_tls) debug_printf("resumption not supported on continued-connection\n"); } + { DEBUG(D_tls) debug_printf( + "resumption not supported: no LB detection done (continued-conn?)\n"); } else if (verify_check_given_host(CUSS &ob->tls_resumption_hosts, conn_args->host) == OK) { dbdata_tls_session * dt; @@ -3347,6 +3351,7 @@ else if (verify_check_given_host(CUSS &ob->tls_resumption_hosts, conn_args->host dbfn_close(dbm_file); } } +else DEBUG(D_tls) debug_printf("no resumption for this host\n"); } @@ -3374,7 +3379,7 @@ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_SESSION_TICKET) int dlen = sizeof(dbdata_tls_session) + tkt.size; dbdata_tls_session * dt = store_get(dlen, GET_TAINTED); - DEBUG(D_tls) debug_printf("session data size %u\n", (unsigned)tkt.size); + DEBUG(D_tls) debug_printf(" session data size %u\n", (unsigned)tkt.size); memcpy(dt->session, tkt.data, tkt.size); gnutls_free(tkt.data); @@ -3385,11 +3390,15 @@ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_SESSION_TICKET) dbfn_close(dbm_file); DEBUG(D_tls) - debug_printf("wrote session db (len %u)\n", (unsigned)dlen); + debug_printf(" wrote session db (len %u)\n", (unsigned)dlen); } } - else DEBUG(D_tls) - debug_printf("extract session data: %s\n", US gnutls_strerror(rc)); + else + { DEBUG(D_tls) + debug_printf(" extract session data: %s\n", US gnutls_strerror(rc)); + } + else DEBUG(D_tls) + debug_printf(" host not resmable; not saving ticket\n"); } } @@ -3406,7 +3415,7 @@ tls_client_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when, exim_gnutls_state_st * state = gnutls_session_get_ptr(sess); tls_support * tlsp = state->tlsp; -DEBUG(D_tls) debug_printf("newticket cb\n"); +DEBUG(D_tls) debug_printf("newticket cb (on client)\n"); if (!tlsp->ticket_received) tls_save_session(tlsp, sess, state->host); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index af2e1f2dd..8c00a1ef2 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -203,9 +203,6 @@ smtp_transport_options_block smtp_transport_option_defaults = { .tls_tempfail_tryclear = TRUE, .tls_try_verify_hosts = US"*", .tls_verify_cert_hostnames = US"*", -# ifndef DISABLE_TLS_RESUME - .host_name_extract = US"${if and {{match{$host}{.outlook.com\\$}} {match{$item}{\\N^250-([\\w.]+)\\s\\N}}} {$1}}", -# endif #endif #ifdef SUPPORT_I18N .utf8_downconvert = US"-1", @@ -352,7 +349,7 @@ Returns: nothing void smtp_transport_init(transport_instance *tblock) { -smtp_transport_options_block *ob = SOB tblock->options_block; +smtp_transport_options_block * ob = SOB tblock->options_block; int old_pool = store_pool; /* Retry_use_local_part defaults FALSE if unset */ @@ -769,7 +766,7 @@ return TRUE; resumption when such servers do not share a session-cache */ static void -ehlo_response_lbserver(smtp_context * sx, smtp_transport_options_block * ob) +ehlo_response_lbserver(smtp_context * sx, const uschar * name_extract) { #if !defined(DISABLE_TLS) && !defined(DISABLE_TLS_RESUME) const uschar * s; @@ -778,7 +775,7 @@ uschar * save_item = iterate_item; if (sx->conn_args.have_lbserver) return; iterate_item = sx->buffer; -s = expand_cstring(ob->host_name_extract); +s = expand_cstring(name_extract); iterate_item = save_item; sx->conn_args.host_lbserver = s && !*s ? NULL : s; sx->conn_args.have_lbserver = TRUE; @@ -1067,6 +1064,8 @@ sx->pending_EHLO = FALSE; if (pending_BANNER) { + const uschar * s; + DEBUG(D_transport) debug_printf("%s expect banner\n", __FUNCTION__); (*countp)--; if (!smtp_reap_banner(sx)) @@ -1076,7 +1075,10 @@ if (pending_BANNER) goto fail; } /*XXX EXPERIMENTAL_ESMTP_LIMITS ? */ - ehlo_response_lbserver(sx, sx->conn_args.ob); + + s = ((smtp_transport_options_block *)sx->conn_args.ob)->host_name_extract; + if (!s) s = HNE_DEFAULT; + ehlo_response_lbserver(sx, s); } if (pending_EHLO) @@ -2474,10 +2476,20 @@ goto SEND_QUIT; #ifndef DISABLE_TLS if (sx->smtps) { + const uschar * s; + smtp_peer_options |= OPTION_TLS; suppress_tls = FALSE; ob->tls_tempfail_tryclear = FALSE; smtp_command = US"SSL-on-connect"; + + /* Having no EHLO response yet, cannot peek there for a servername to detect + an LB. Call this anyway, so that a dummy host_name_extract option value can + force resumption attempts. */ + + if (!(s = ob->host_name_extract)) s = US"never-LB"; + ehlo_response_lbserver(sx, s); + goto TLS_NEGOTIATE; } #endif @@ -2565,6 +2577,8 @@ goto SEND_QUIT; if (!sx->early_pipe_active) #endif { + const uschar * s; + sx->peer_offered = ehlo_response(sx->buffer, OPTION_TLS /* others checked later */ #ifndef DISABLE_PIPE_CONNECT @@ -2600,7 +2614,8 @@ goto SEND_QUIT; } } #endif - ehlo_response_lbserver(sx, ob); + if (!(s = ob->host_name_extract)) s = HNE_DEFAULT; + ehlo_response_lbserver(sx, s); } /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */ diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index cb1d72625..0d15b9626 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -109,6 +109,7 @@ typedef struct { uschar *tls_privatekey; uschar *tls_require_ciphers; # ifndef DISABLE_TLS_RESUME +# define HNE_DEFAULT US"${if and {{match{$host}{.outlook.com\\$}} {match{$item}{\\N^250-([\\w.]+)\\s\\N}}} {$1}}" uschar *host_name_extract; uschar *tls_resumption_hosts; # endif commit fba5586e6d47f55e024e97681c166e857c4f3d1c Author: Jeremy Harris Date: Tue Nov 14 14:08:36 2023 +0000 constification diff --git a/src/src/deliver.c b/src/src/deliver.c index fa624f9de..9d459167e 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -6388,7 +6388,7 @@ Returns: When the global variable mua_wrapper is FALSE: */ int -deliver_message(uschar * id, BOOL forced, BOOL give_up) +deliver_message(const uschar * id, BOOL forced, BOOL give_up) { int i, rc; int final_yield = DELIVER_ATTEMPTED_NORMAL; diff --git a/src/src/exim.c b/src/src/exim.c index 118fe5c7c..3cc2fa2fb 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1537,7 +1537,7 @@ Returns: DOES NOT RETURN */ static void -exim_usage(uschar *progname) +exim_usage(const uschar * progname) { /* Handle specific program invocation variants */ @@ -1744,9 +1744,9 @@ Returns: EXIT_SUCCESS if terminated successfully */ int -main(int argc, char **cargv) +main(int argc, char ** cargv) { -uschar **argv = USS cargv; +const uschar ** argv = CUSS cargv; int arg_receive_timeout = -1; int arg_smtp_receive_timeout = -1; int arg_error_handling = error_handling; @@ -1795,18 +1795,18 @@ BOOL verify_address_mode = FALSE; BOOL verify_as_sender = FALSE; BOOL rcpt_verify_quota = FALSE; BOOL version_printed = FALSE; -uschar *alias_arg = NULL; -uschar *called_as = US""; -uschar *cmdline_syslog_name = NULL; -uschar *start_queue_run_id = NULL; -uschar *stop_queue_run_id = NULL; -uschar *expansion_test_message = NULL; +const uschar *alias_arg = NULL; +const uschar *called_as = US""; +const uschar *cmdline_syslog_name = NULL; +const uschar *start_queue_run_id = NULL; +const uschar *stop_queue_run_id = NULL; +const uschar *expansion_test_message = NULL; const uschar *ftest_domain = NULL; const uschar *ftest_localpart = NULL; const uschar *ftest_prefix = NULL; const uschar *ftest_suffix = NULL; uschar *log_oneline = NULL; -uschar *malware_test_file = NULL; +const uschar *malware_test_file = NULL; uschar *real_sender_address; uschar *originator_home = US"/"; size_t sz; @@ -2152,8 +2152,8 @@ on the second character (the one after '-'), to save some effort. */ for (i = 1; i < argc; i++) { BOOL badarg = FALSE; - uschar * arg = argv[i]; - uschar * argrest; + const uschar * arg = argv[i]; + const uschar * argrest; uschar switchchar; /* An argument not starting with '-' is the start of a recipients list; @@ -2347,7 +2347,7 @@ on the second character (the one after '-'), to save some effort. */ case 'I': if (Ustrlen(argrest) >= 1 && *argrest == ':') { - uschar *p = argrest+1; + const uschar * p = argrest+1; info_flag = CMDINFO_HELP; if (Ustrlen(p)) if (strcmpic(p, CUS"sieve") == 0) @@ -2674,9 +2674,9 @@ on the second character (the one after '-'), to save some effort. */ #else { int ptr = 0; - macro_item *m; + macro_item * m; uschar name[24]; - uschar *s = argrest; + const uschar * s = argrest; opt_D_used = TRUE; while (isspace(*s)) s++; @@ -2833,7 +2833,7 @@ on the second character (the one after '-'), to save some effort. */ *(sender_address = store_get(1, GET_UNTAINTED)) = '\0'; /* Ensure writeable memory */ else { - uschar * temp = argrest + Ustrlen(argrest) - 1; + const uschar * temp = argrest + Ustrlen(argrest) - 1; while (temp >= argrest && isspace(*temp)) temp--; if (temp >= argrest && *temp == '.') f_end_dot = TRUE; allow_domain_literals = TRUE; @@ -3272,7 +3272,7 @@ on the second character (the one after '-'), to save some effort. */ /* -oB: Set a connection message max value for remote deliveries */ case 'B': { - uschar * p = argrest; + const uschar * p = argrest; if (!*p) if (i+1 < argc && isdigit((argv[i+1][0]))) p = argv[++i]; @@ -4432,7 +4432,7 @@ if (bi_option) if (bi_command && *bi_command) { int i = 0; - uschar *argv[3]; + const uschar * argv[3]; argv[i++] = bi_command; /* nonexpanded option so assume untainted */ if (alias_arg) argv[i++] = alias_arg; argv[i++] = NULL; @@ -4761,7 +4761,7 @@ if (rcpt_verify_quota) exim_fail("exim: missing recipient for quota check\n"); else { - verify_quota(argv[recipients_arg]); + verify_quota(US argv[recipients_arg]); /*XXX we lose track of const here */ exim_exit(EXIT_SUCCESS); } @@ -5768,7 +5768,7 @@ for (BOOL more = TRUE; more; ) { int rcount = 0; int count = argc - recipients_arg; - uschar **list = argv + recipients_arg; + const uschar ** list = argv + recipients_arg; /* These options cannot be changed dynamically for non-SMTP messages */ diff --git a/src/src/filtertest.c b/src/src/filtertest.c index 2426f7feb..2af5f87c2 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -164,7 +164,7 @@ Returns: TRUE if no errors */ BOOL -filter_runtest(int fd, uschar *filename, BOOL is_system, BOOL dot_ended) +filter_runtest(int fd, const uschar * filename, BOOL is_system, BOOL dot_ended) { int rc, filter_type; BOOL yield; diff --git a/src/src/functions.h b/src/src/functions.h index 39119ca09..ba4fd215c 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -218,7 +218,7 @@ extern void delete_pid_file(void); extern void deliver_local(address_item *, BOOL); extern address_item *deliver_make_addr(uschar *, BOOL); extern void delivery_log(int, address_item *, int, uschar *); -extern int deliver_message(uschar *, BOOL, BOOL); +extern int deliver_message(const uschar *, BOOL, BOOL); extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2); extern void deliver_set_expansions(address_item *); extern int deliver_split_address(address_item *); @@ -284,7 +284,7 @@ extern BOOL fd_ready(int, time_t); extern int filter_interpret(const uschar *, int, address_item **, uschar **); extern BOOL filter_personal(string_item *, BOOL); -extern BOOL filter_runtest(int, uschar *, BOOL, BOOL); +extern BOOL filter_runtest(int, const uschar *, BOOL, BOOL); extern BOOL filter_system_interpret(address_item **, uschar **); extern uschar * fn_hdrs_added(void); @@ -345,7 +345,7 @@ extern uschar *macros_expand(int, int *, BOOL *); extern void mainlog_close(void); #ifdef WITH_CONTENT_SCAN extern int malware(const uschar *, BOOL, int); -extern int malware_in_file(uschar *); +extern int malware_in_file(const uschar *); extern void malware_init(void); extern gstring * malware_show_supported(gstring *); #endif @@ -408,15 +408,15 @@ extern BOOL proxy_protocol_host(void); extern void proxy_protocol_setup(void); #endif -extern BOOL queue_action(uschar *, int, uschar **, int, int); +extern BOOL queue_action(const uschar *, int, const uschar **, int, int); extern void queue_check_only(void); extern unsigned queue_count(void); extern unsigned queue_count_cached(void); -extern void queue_list(int, uschar **, int); +extern void queue_list(int, const uschar **, int); #ifndef DISABLE_QUEUE_RAMP extern void queue_notify_daemon(const uschar * hostname); #endif -extern void queue_run(qrunner *, uschar *, uschar *, BOOL); +extern void queue_run(qrunner *, const uschar *, const uschar *, BOOL); extern int random_number(int); extern const uschar *rc_to_string(int); @@ -430,7 +430,7 @@ extern void readconf_driver_init(uschar *, driver_instance **, extern uschar *readconf_find_option(void *); extern void readconf_main(BOOL); extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *); -extern BOOL readconf_print(const uschar *, uschar *, BOOL); +extern BOOL readconf_print(const uschar *, const uschar *, BOOL); extern uschar *readconf_printtime(int); extern const uschar *readconf_readname(uschar *, int, const uschar *); extern int readconf_readtime(const uschar *, int, BOOL); @@ -503,7 +503,7 @@ extern int sieve_interpret(const uschar *, int, const uschar *, const uschar *, const uschar *, const uschar *, address_item **, uschar **); extern void sigalrm_handler(int); -extern void single_queue_run(qrunner *, uschar *, uschar *); +extern void single_queue_run(qrunner *, const uschar *, const uschar *); extern int smtp_boundsock(smtp_connect_args *); extern void smtp_closedown(uschar *); extern void smtp_command_timeout_exit(void) NORETURN; @@ -544,12 +544,12 @@ extern int spam(const uschar **); extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **); #endif extern void spool_clear_header_globals(void); -extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *); -extern int spool_open_datafile(uschar *); +extern BOOL spool_move_message(const uschar *, const uschar *, const uschar *, const uschar *); +extern int spool_open_datafile(const uschar *); extern int spool_open_temp(uschar *); extern int spool_read_header(uschar *, BOOL, BOOL); extern uschar *spool_sender_from_msgid(const uschar *); -extern int spool_write_header(uschar *, int, uschar **); +extern int spool_write_header(const uschar *, int, uschar **); extern int stdin_getc(unsigned); extern int stdin_feof(void); extern int stdin_ferror(void); @@ -1144,7 +1144,7 @@ return string_sprintf("%s/%s/%s/%s", # endif static inline uschar * -spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir) +spool_q_sname(const uschar * purpose, const uschar * q, const uschar * subdir) { return string_sprintf("%s%s%s%s%s", q, *q ? "/" : "", @@ -1153,7 +1153,7 @@ return string_sprintf("%s%s%s%s%s", } static inline uschar * -spool_sname(const uschar * purpose, uschar * subdir) +spool_sname(const uschar * purpose, const uschar * subdir) { return spool_q_sname(purpose, queue_name, subdir); } diff --git a/src/src/globals.c b/src/src/globals.c index e94bef75c..46ca72f20 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -726,7 +726,7 @@ gid_t config_gid = CONFIGURE_GROUP; #else gid_t config_gid = 0; #endif -uschar *config_main_filelist = US CONFIGURE_FILE +const uschar * config_main_filelist = US CONFIGURE_FILE "\0<-----------Space to patch configure_filename->"; uschar *config_main_filename = NULL; uschar *config_main_directory = NULL; @@ -939,8 +939,8 @@ uschar *fake_response_text = US"Your message has been rejected but is " int filter_n[FILTER_VARIABLE_COUNT]; int filter_sn[FILTER_VARIABLE_COUNT]; int filter_test = FTEST_NONE; -uschar *filter_test_sfile = NULL; -uschar *filter_test_ufile = NULL; +const uschar * filter_test_sfile = NULL; +const uschar * filter_test_ufile = NULL; uschar *filter_thisaddress = NULL; int finduser_retries = 0; uid_t fixed_never_users[] = { FIXED_NEVER_USERS }; @@ -1185,7 +1185,7 @@ uschar *message_size_limit = US"50M"; int message_utf8_downconvert = 0; /* -1 ifneeded; 0 never; 1 always */ #endif uschar message_subdir[2] = { 0, 0 }; -uschar *message_reference = NULL; +const uschar *message_reference= NULL; /* MIME ACL expandables */ #ifdef WITH_CONTENT_SCAN @@ -1219,7 +1219,7 @@ uschar *originator_login = NULL; uschar *originator_name = NULL; uid_t originator_uid; uschar *override_local_interfaces = NULL; -uschar *override_pid_file_path = NULL; +const uschar *override_pid_file_path = NULL; BOOL panic_coredump = FALSE; pcre2_general_context * pcre_gen_ctx = NULL; @@ -1229,7 +1229,7 @@ pcre2_general_context * pcre_mlc_ctx = NULL; pcre2_compile_context * pcre_mlc_cmp_ctx = NULL; uschar *percent_hack_domains = NULL; -uschar *pid_file_path = US PID_FILE_PATH +const uschar *pid_file_path = US PID_FILE_PATH "\0<--------------Space to patch pid_file_path->"; #ifndef DISABLE_PIPE_CONNECT uschar *pipe_connect_advertise_hosts = US"*"; @@ -1485,7 +1485,7 @@ uschar *sending_ip_address = NULL; int sending_port = -1; SIGNAL_BOOL sigalrm_seen = FALSE; const uschar *sigalarm_setter = NULL; -uschar **sighup_argv = NULL; +const uschar **sighup_argv = NULL; int slow_lookup_log = 0; /* millisecs, zero disables */ int smtp_accept_count = 0; int smtp_accept_max = 20; @@ -1572,7 +1572,7 @@ int string_datestamp_type = -1; const uschar *submission_domain = NULL; const uschar *submission_name = NULL; int syslog_facility = LOG_MAIL; -uschar *syslog_processname = US"exim"; +const uschar *syslog_processname= US"exim"; uschar *system_filter = NULL; uschar *system_filter_directory_transport = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 6ec4e619d..9ec44487f 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -438,7 +438,7 @@ extern FILE *config_file; /* Configuration file */ extern const uschar *config_filename; /* Configuration file name */ extern gid_t config_gid; /* Additional group owner */ extern int config_lineno; /* Line number */ -extern uschar *config_main_filelist; /* List of possible config files */ +extern const uschar *config_main_filelist; /* List of possible config files */ extern uschar *config_main_filename; /* File name actually used */ extern uschar *config_main_directory; /* Directory where the main config file was found */ extern uid_t config_uid; /* Additional owner */ @@ -625,8 +625,8 @@ extern uschar *fake_response_text; /* User defined message for the above. De extern int filter_n[FILTER_VARIABLE_COUNT]; /* filter variables */ extern int filter_sn[FILTER_VARIABLE_COUNT]; /* variables set by system filter */ extern int filter_test; /* Filter test type */ -extern uschar *filter_test_sfile; /* System filter test file */ -extern uschar *filter_test_ufile; /* User filter test file */ +extern const uschar *filter_test_sfile;/* System filter test file */ +extern const uschar *filter_test_ufile;/* User filter test file */ extern uschar *filter_thisaddress; /* For address looping */ extern int finduser_retries; /* Retry count for getpwnam() */ extern uid_t fixed_never_users[]; /* Can't be overridden */ @@ -755,7 +755,7 @@ extern int message_utf8_downconvert; /* convert from utf8 */ const extern pcre2_code *regex_UTF8; /* For recognizing SMTPUTF8 settings */ #endif extern uschar message_subdir[]; /* Subdirectory for messages */ -extern uschar *message_reference; /* Reference for error messages */ +extern const uschar *message_reference;/* Reference for error messages */ /* MIME ACL expandables */ #ifdef WITH_CONTENT_SCAN @@ -798,7 +798,7 @@ extern uschar *originator_login; /* Login of same */ extern uschar *originator_name; /* Full name of same */ extern uid_t originator_uid; /* Uid of ditto */ extern uschar *override_local_interfaces; /* Value of -oX argument */ -extern uschar *override_pid_file_path; /* Value of -oP argument */ +extern const uschar *override_pid_file_path; /* Value of -oP argument */ extern BOOL panic_coredump; /* SEGV rather than exit, on LOG_PANIC_DIE */ extern pcre2_general_context * pcre_gen_ctx; /* pcre memory management */ @@ -808,7 +808,7 @@ extern pcre2_general_context * pcre_mlc_ctx; extern pcre2_compile_context * pcre_mlc_cmp_ctx; extern uschar *percent_hack_domains; /* Local domains for which '% operates */ -extern uschar *pid_file_path; /* For writing daemon pids */ +extern const uschar *pid_file_path; /* For writing daemon pids */ #ifndef DISABLE_PIPE_CONNECT extern uschar *pipe_connect_advertise_hosts; /* for banner/EHLO pipelining */ #endif @@ -970,7 +970,7 @@ extern uschar *sending_ip_address; /* Address of outgoing (SMTP) interface * extern int sending_port; /* Port of outgoing interface */ extern SIGNAL_BOOL sigalrm_seen; /* Flag for sigalrm_handler */ extern const uschar *sigalarm_setter; /* For debug, set to callpoint of alarm() */ -extern uschar **sighup_argv; /* Args for re-execing after SIGHUP */ +extern const uschar **sighup_argv; /* Args for re-execing after SIGHUP */ extern int slow_lookup_log; /* Log DNS lookups taking longer than N millisecs */ extern int smtp_accept_count; /* Count of connections */ extern BOOL smtp_accept_keepalive; /* Set keepalive on incoming */ @@ -1065,7 +1065,7 @@ extern const uschar *submission_name; /* User name set from ACL */ extern BOOL syslog_duplication; /* FALSE => no duplicate logging */ extern int syslog_facility; /* As defined by Syslog.h */ extern BOOL syslog_pid; /* TRUE if PID on syslogs */ -extern uschar *syslog_processname; /* 'ident' param to openlog() */ +extern const uschar *syslog_processname; /* 'ident' param to openlog() */ extern BOOL syslog_timestamp; /* TRUE if time on syslogs */ extern uschar *system_filter; /* Name of system filter file */ diff --git a/src/src/malware.c b/src/src/malware.c index 9455d4769..760278079 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -2238,7 +2238,7 @@ Returns: Exim message processing code (OK, FAIL, DEFER, ...) where true means malware was found (condition applies) */ int -malware_in_file(uschar *eml_filename) +malware_in_file(const uschar * eml_filename) { uschar message_id_buf[64]; int ret; diff --git a/src/src/queue.c b/src/src/queue.c index fa4fc0aec..cfe87e953 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -354,7 +354,7 @@ Returns: nothing */ void -queue_run(qrunner * q, uschar * start_id, uschar * stop_id, BOOL recurse) +queue_run(qrunner * q, const uschar * start_id, const uschar * stop_id, BOOL recurse) { BOOL force_delivery = q->queue_run_force || deliver_selectstring || deliver_selectstring_sender; @@ -813,7 +813,7 @@ if (!recurse) void -single_queue_run(qrunner * q, uschar * start_id, uschar * stop_id) +single_queue_run(qrunner * q, const uschar * start_id, const uschar * stop_id) { DEBUG(D_queue_run) debug_printf("Single queue run%s%s%s%s\n", start_id ? US" starting at " : US"", @@ -919,7 +919,7 @@ Returns: nothing */ void -queue_list(int option, uschar ** list, int count) +queue_list(int option, const uschar ** list, int count) { int subcount; int now = (int)time(NULL); @@ -1093,7 +1093,7 @@ Returns: FALSE if there was any problem */ BOOL -queue_action(uschar * id, int action, uschar ** argv, int argc, +queue_action(const uschar * id, int action, const uschar ** argv, int argc, int recipients_arg) { BOOL yield = TRUE; diff --git a/src/src/readconf.c b/src/src/readconf.c index e77458d68..bbcca87f7 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -2741,7 +2741,7 @@ Returns: Boolean success */ BOOL -readconf_print(const uschar *name, uschar *type, BOOL no_labels) +readconf_print(const uschar * name, const uschar * type, BOOL no_labels) { BOOL names_only = FALSE; optionlist *ol2 = NULL; @@ -3121,8 +3121,8 @@ readconf_main(BOOL nowarn) { int sep = 0; struct stat statbuf; -uschar *s, *filename; -const uschar *list = config_main_filelist; +uschar * s, * filename; +const uschar * list = config_main_filelist; /* Loop through the possible file names */ @@ -3459,7 +3459,7 @@ leading "log_". */ if (syslog_facility_str) { int i; - uschar *s = syslog_facility_str; + uschar * s = syslog_facility_str; if ((Ustrlen(syslog_facility_str) >= 4) && (strncmpic(syslog_facility_str, US"log_", 4) == 0)) @@ -3481,10 +3481,11 @@ if (syslog_facility_str) if (*pid_file_path) { - if (!(s = expand_string(pid_file_path))) + const uschar * t = expand_cstring(pid_file_path); + if (!t) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand pid_file_path " "\"%s\": %s", pid_file_path, expand_string_message); - pid_file_path = s; + pid_file_path = t; } /* Set default value of process_log_path */ diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 737a01cdd..588effd2c 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -36,7 +36,7 @@ Side effect: message_subdir is set for the (possibly split) spool directory */ int -spool_open_datafile(uschar * id) +spool_open_datafile(const uschar * id) { struct stat statbuf; flock_t lock_data; diff --git a/src/src/spool_out.c b/src/src/spool_out.c index 9c5a683e3..f3373faed 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -152,7 +152,7 @@ Returns: the size of the header texts on success; */ int -spool_write_header(uschar * id, int where, uschar ** errmsg) +spool_write_header(const uschar * id, int where, uschar ** errmsg) { int fd, size_correction; FILE * fp; @@ -444,7 +444,7 @@ start-up time. Arguments: dir base directory name - dq destiinationqueue name + dq destination queue name subdir subdirectory name id message id suffix suffix to add to id @@ -457,8 +457,8 @@ Returns: TRUE if all went well */ static BOOL -make_link(uschar * dir, uschar * dq, uschar * subdir, uschar * id, uschar * suffix, - uschar * from, uschar * to, BOOL noentok) +make_link(const uschar * dir, const uschar * dq, const uschar * subdir, const uschar * id, + const uschar * suffix, const uschar * from, const uschar * to, BOOL noentok) { uschar * fname = spool_fname(string_sprintf("%s%s", from, dir), subdir, id, suffix); uschar * tname = spool_q_fname(string_sprintf("%s%s", to, dir), dq, subdir, id, suffix); @@ -494,8 +494,8 @@ Returns: TRUE if all went well */ static BOOL -break_link(uschar * dir, uschar * subdir, uschar * id, uschar * suffix, uschar * from, - BOOL noentok) +break_link(const uschar * dir, const uschar * subdir, const uschar * id, + const uschar * suffix, const uschar * from, BOOL noentok) { uschar * fname = spool_fname(string_sprintf("%s%s", from, dir), subdir, id, suffix); if (Uunlink(fname) < 0 && (!noentok || errno != ENOENT)) @@ -528,7 +528,8 @@ Returns: TRUE if all is well */ BOOL -spool_move_message(uschar * id, uschar * subdir, uschar * from, uschar * to) +spool_move_message(const uschar * id, const uschar * subdir, + const uschar * from, const uschar * to) { uschar * dest_qname = queue_name_dest ? queue_name_dest : queue_name; commit b8e078953178c757578f2e104d9d2c822ae0943c Author: Jeremy Harris Date: Tue Nov 14 12:10:36 2023 +0000 Check for missing commandline arg after options taking one. Bug 3049 diff --git a/src/src/exim.c b/src/src/exim.c index 3cc2fa2fb..14c057f40 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -847,7 +847,7 @@ exit(EXIT_FAILURE); /* fail if a length is too long */ static inline void -exim_len_fail_toolong(int itemlen, int maxlen, const char *description) +exim_len_fail_toolong(int itemlen, int maxlen, const char * description) { if (itemlen <= maxlen) return; @@ -858,8 +858,10 @@ exit(EXIT_FAILURE); /* only pass through the string item back to the caller if it's short enough */ static inline const uschar * -exim_str_fail_toolong(const uschar *item, int maxlen, const char *description) +exim_str_fail_toolong(const uschar * item, int maxlen, const char * description) { +if (!item) + exim_fail("exim: bad item for: %s\n", description); exim_len_fail_toolong(Ustrlen(item), maxlen, description); return item; } @@ -884,10 +886,10 @@ log_write(0, LOG_MAIN|LOG_PANIC, struct stat buf; if (0 == (fd < 0 ? stat(name, &buf) : fstat(fd, &buf))) -{ + { if (buf.st_uid == owner && buf.st_gid == group) return 0; log_write(0, LOG_MAIN|LOG_PANIC, "Wrong ownership on %s", name); -} + } else log_write(0, LOG_MAIN|LOG_PANIC, "Stat failed on %s: %s", name, strerror(errno)); #endif @@ -896,6 +898,18 @@ return -1; } +/* Bump the index for argv, checking for overflow, +and return the argument. */ + +static const uschar * +next_argv(const uschar ** argv, int * pi, int argc, const uschar * where) +{ +int i = *pi; +if (++i >= argc) exim_fail("exim: bad item for: %s\n", where); +return argv[*pi = i]; +} + + /************************************************* * Extract port from host address * *************************************************/ @@ -3151,7 +3165,8 @@ on the second character (the one after '-'), to save some effort. */ { msg_action = MSG_SETQUEUE; queue_name_dest = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_DRIVERNAME_MAX, "-MG"), + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_DRIVERNAME_MAX, "-MG"), GET_TAINTED); } else if (Ustrcmp(argrest, "mad") == 0) msg_action = MSG_MARK_ALL_DELIVERED; @@ -3363,36 +3378,36 @@ on the second character (the one after '-'), to save some effort. */ if (Ustrcmp(argrest, "a") == 0) sender_host_address = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_IPADDR_MAX, "-oMa"), - GET_TAINTED); + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_IPADDR_MAX, "-oMa"), GET_TAINTED); /* -oMaa: Set authenticator name */ else if (Ustrcmp(argrest, "aa") == 0) sender_host_authenticated = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_DRIVERNAME_MAX, "-oMaa"), - GET_TAINTED); + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_DRIVERNAME_MAX, "-oMaa"), GET_TAINTED); /* -oMas: setting authenticated sender */ else if (Ustrcmp(argrest, "as") == 0) authenticated_sender = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMas"), - GET_TAINTED); + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_EMAILADDR_MAX, "-oMas"), GET_TAINTED); /* -oMai: setting authenticated id */ else if (Ustrcmp(argrest, "ai") == 0) authenticated_id = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMai"), - GET_TAINTED); + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_EMAILADDR_MAX, "-oMai"), GET_TAINTED); /* -oMi: Set incoming interface address */ else if (Ustrcmp(argrest, "i") == 0) interface_address = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_IPADDR_MAX, "-oMi"), - GET_TAINTED); + exim_str_fail_toolong(next_argv(argv, &i, argc, arg), + EXIM_IPADDR_MAX, "-oMi"), GET_TAINTED); /* -oMm: Message reference */ @@ -3402,7 +3417,7 @@ on the second character (the one after '-'), to save some effort. */ exim_fail("-oMm must be a valid message ID\n"); if (!f.trusted_config) exim_fail("-oMm must be called by a trusted user/config\n"); - message_reference = argv[++i]; + message_reference = next_argv(argv, &i, argc, arg); } /* -oMr: Received protocol */ @@ -3412,26 +3427,32 @@ on the second character (the one after '-'), to save some effort. */ if (received_protocol) exim_fail("received_protocol is set already\n"); else - received_protocol = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_DRIVERNAME_MAX, "-oMr"), - GET_TAINTED); + if (++i >= argc) badarg = TRUE; + else + received_protocol = string_copy_taint( + exim_str_fail_toolong(argv[i], EXIM_DRIVERNAME_MAX, "-oMr"), + GET_TAINTED); /* -oMs: Set sender host name */ else if (Ustrcmp(argrest, "s") == 0) - sender_host_name = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_HOSTNAME_MAX, "-oMs"), - GET_TAINTED); + if (++i >= argc) badarg = TRUE; + else + sender_host_name = string_copy_taint( + exim_str_fail_toolong(argv[i], EXIM_HOSTNAME_MAX, "-oMs"), + GET_TAINTED); /* -oMt: Set sender ident */ else if (Ustrcmp(argrest, "t") == 0) - { - sender_ident_set = TRUE; - sender_ident = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_IDENTUSER_MAX, "-oMt"), - GET_TAINTED); - } + if (++i >= argc) badarg = TRUE; + else + { + sender_ident_set = TRUE; + sender_ident = string_copy_taint( + exim_str_fail_toolong(argv[i], EXIM_IDENTUSER_MAX, "-oMt"), + GET_TAINTED); + } /* Else a bad argument */ @@ -3459,7 +3480,9 @@ on the second character (the one after '-'), to save some effort. */ exim_fail("exim: only uid=%d or uid=%d can use -oP and -oPX " "(uid=%d euid=%d | %d)\n", root_uid, exim_uid, getuid(), geteuid(), real_uid); - if (!*argrest) override_pid_file_path = argv[++i]; + if (!*argrest) + if (++i < argc) override_pid_file_path = argv[i]; + else badarg = TRUE; else if (Ustrcmp(argrest, "X") == 0) delete_pid_file(); else badarg = TRUE; break; @@ -3487,10 +3510,9 @@ on the second character (the one after '-'), to save some effort. */ /* Limits: Is there a real limit we want here? 1024 is very arbitrary. */ case 'X': - if (*argrest) badarg = TRUE; + if (*argrest || ++i >= argc) badarg = TRUE; else override_local_interfaces = string_copy_taint( - exim_str_fail_toolong(argv[++i], 1024, "-oX"), - GET_TAINTED); + exim_str_fail_toolong(argv[i], 1024, "-oX"), GET_TAINTED); break; /* -oY: Override creation of daemon notifier socket */ @@ -3528,7 +3550,7 @@ on the second character (the one after '-'), to save some effort. */ which sets the host protocol and host name */ if (!*argrest) - if (i+1 < argc) argrest = argv[++i]; else { badarg = TRUE; break; } + argrest = next_argv(argv, &i, argc, arg); if (*argrest) { @@ -3614,8 +3636,14 @@ on the second character (the one after '-'), to save some effort. */ else { - int intvl = readconf_readtime(*argrest ? argrest : argv[++i], 0, FALSE); - if (intvl <= 0) + int intvl; + const uschar * s; + + if (*argrest) s = argrest; + else if (++i < argc) { badarg = TRUE; break; } + else s = argv[i]; + + if ((intvl = readconf_readtime(s, 0, FALSE)) <= 0) exim_fail("exim: bad time value %s: abandoned\n", argv[i]); for (qrunner * qq = qrunners; qq; qq = qq->next) @@ -3706,8 +3734,8 @@ on the second character (the one after '-'), to save some effort. */ tested. Otherwise variability of clock ticks etc. cause problems. */ case 'T': - if (f.running_in_test_harness && Ustrcmp(argrest, "qt") == 0) - fudged_queue_times = string_copy_taint(argv[++i], GET_TAINTED); + if (f.running_in_test_harness && Ustrcmp(argrest, "qt") == 0 && ++i < argc) + fudged_queue_times = string_copy_taint(argv[i], GET_TAINTED); else badarg = TRUE; break; commit fa1c8faf169384bebaa8d172f491574c45ae2aa4 Author: Jeremy Harris Date: Wed Nov 15 02:14:02 2023 +0000 constification diff --git a/src/exim_monitor/em_globals.c b/src/exim_monitor/em_globals.c index cf9b1075e..3822746ba 100644 --- a/src/exim_monitor/em_globals.c +++ b/src/exim_monitor/em_globals.c @@ -204,7 +204,7 @@ recipient_item *recipients_list = NULL; int recipients_list_max = 0; BOOL running_in_test_harness=FALSE; -uschar *sender_address = NULL; +const uschar *sender_address = NULL; uschar *sender_fullhost = NULL; uschar *sender_helo_name = NULL; uschar *sender_host_address = NULL; diff --git a/src/exim_monitor/em_hdr.h b/src/exim_monitor/em_hdr.h index 61f390d2c..feffa6bfc 100644 --- a/src/exim_monitor/em_hdr.h +++ b/src/exim_monitor/em_hdr.h @@ -309,7 +309,7 @@ extern uschar *copystring(uschar *); extern void create_dialog(uschar *, uschar *); extern void create_stripchart(Widget, uschar *); extern void debug(char *, ...); -extern dest_item *find_dest(queue_item *, uschar *, int, BOOL); +extern dest_item *find_dest(queue_item *, const uschar *, int, BOOL); extern queue_item *find_queue(uschar *, int, int); extern void init(int, uschar **); extern void menu_create(Widget, XEvent *, String *, Cardinal *); diff --git a/src/exim_monitor/em_queue.c b/src/exim_monitor/em_queue.c index 4c3d3fd18..c7c61a652 100644 --- a/src/exim_monitor/em_queue.c +++ b/src/exim_monitor/em_queue.c @@ -66,18 +66,16 @@ address is lowercased to start with, unless it begins with "*", which it does for error messages. */ dest_item * -find_dest(queue_item *q, uschar *name, int action, BOOL caseless) +find_dest(queue_item * q, const uschar * name, int action, BOOL caseless) { -dest_item *dd; -dest_item **d = &(q->destinations); +dest_item * dd; +dest_item ** d = &q->destinations; -while (*d != NULL) +while (*d) { if ((caseless? strcmpic(name,(*d)->address) : Ustrcmp(name,(*d)->address)) == 0) { - dest_item *ddd; - if (action != dest_remove) return *d; dd = *d; *d = dd->next; @@ -85,14 +83,12 @@ while (*d != NULL) /* Unset any parent pointers that were to this address */ - for (ddd = q->destinations; ddd != NULL; ddd = ddd->next) - { + for (dest_item * ddd = q->destinations; ddd; ddd = ddd->next) if (ddd->parent == dd) ddd->parent = NULL; - } return NULL; } - d = &((*d)->next); + d = &(*d)->next; } if (action != dest_add) return NULL; @@ -207,8 +203,9 @@ if it's there. */ else { q->update_time = q->input_time = received_time.tv_sec; - if ((p = strstric(sender_address+1, qualify_domain, FALSE)) != NULL && - *(--p) == '@') *p = 0; + /* deconst ok; strstric is actually safe */ + if ((p = strstric(US sender_address+1, qualify_domain, FALSE)) != NULL && + *--p == '@') *p = 0; } /* If we didn't read the whole header successfully, generate an error @@ -279,10 +276,11 @@ been delivered, and removing visible names. */ if (recipients_list) for (i = 0; i < recipients_count; i++) { - uschar * r = recipients_list[i].address; + const uschar * r = recipients_list[i].address; if (tree_search(tree_nonrecipients, r) == NULL) { - if ((p = strstric(r+1, qualify_domain, FALSE)) != NULL && + /* deconst ok; strstric is actually safe */ + if ((p = strstric(US r+1, qualify_domain, FALSE)) != NULL && *(--p) == '@') *p = 0; (void)find_dest(q, r, dest_add, FALSE); } @@ -663,13 +661,14 @@ if (recipients_list) for (i = 0; i < recipients_count; i++) { uschar * pp; - uschar * r = recipients_list[i].address; + const uschar * r = recipients_list[i].address; tree_node * node; if (!(node = tree_search(tree_nonrecipients, r))) node = tree_search(tree_nonrecipients, string_copylc(r)); - if ((pp = strstric(r+1, qualify_domain, FALSE)) && *(--pp) == '@') + /* deconst ok; strstric is actually safe */ + if ((pp = strstric(US r+1, qualify_domain, FALSE)) && *(--pp) == '@') *pp = 0; if (!node) (void)find_dest(p, r, dest_add, FALSE); diff --git a/src/src/acl.c b/src/src/acl.c index cdf60bbb8..9223fcec8 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1711,10 +1711,10 @@ BOOL no_details = FALSE; BOOL success_on_redirect = FALSE; BOOL quota = FALSE; int quota_pos_cache = QUOTA_POS_DEFAULT, quota_neg_cache = QUOTA_NEG_DEFAULT; -address_item *sender_vaddr = NULL; -uschar *verify_sender_address = NULL; -uschar *pm_mailfrom = NULL; -uschar *se_mailfrom = NULL; +address_item * sender_vaddr = NULL; +const uschar * verify_sender_address = NULL; +uschar * pm_mailfrom = NULL; +uschar * se_mailfrom = NULL; /* Some of the verify items have slash-separated options; some do not. Diagnose an error if options are given for items that don't expect them. @@ -4713,8 +4713,8 @@ Returns: OK access is granted by an ACCEPT verb int acl_where = ACL_WHERE_UNKNOWN; int -acl_check(int where, uschar *recipient, uschar *s, uschar **user_msgptr, - uschar **log_msgptr) +acl_check(int where, const uschar * recipient, uschar * s, + uschar ** user_msgptr, uschar ** log_msgptr) { int rc; address_item adb; diff --git a/src/src/deliver.c b/src/src/deliver.c index 9d459167e..e96733f73 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -27,7 +27,7 @@ typedef struct pardata { int transport_count; /* returned transport count value */ BOOL done; /* no more data needed */ uschar *msg; /* error message */ - uschar *return_path; /* return_path for these addresses */ + const uschar *return_path; /* return_path for these addresses */ } pardata; /* Values for the process_recipients variable */ @@ -77,7 +77,7 @@ static pardata *parlist = NULL; static struct pollfd *parpoll; static int return_count; static uschar *frozen_info = US""; -static uschar *used_return_path = NULL; +static const uschar * used_return_path = NULL; @@ -144,7 +144,7 @@ Returns: a pointer to an initialized address_item */ address_item * -deliver_make_addr(uschar *address, BOOL copy) +deliver_make_addr(const uschar * address, BOOL copy) { address_item * addr = store_get(sizeof(address_item), GET_UNTAINTED); *addr = address_defaults; @@ -575,7 +575,7 @@ Returns: TRUE or FALSE */ static BOOL -same_strings(uschar *one, uschar *two) +same_strings(const uschar * one, const uschar * two) { if (one == two) return TRUE; /* Includes the case where both NULL */ if (!one || !two) return FALSE; @@ -898,7 +898,7 @@ void msg_event_raise(const uschar * event, const address_item * addr) { const uschar * save_domain = deliver_domain; -uschar * save_local = deliver_localpart; +const uschar * save_local = deliver_localpart; const uschar * save_host = deliver_host; const uschar * save_address = deliver_host_address; const int save_port = deliver_host_port; @@ -950,13 +950,13 @@ router_name = transport_name = NULL; * Generate local part for logging * *************************************************/ -static uschar * -string_get_lpart_sub(const address_item * addr, uschar * s) +static const uschar * +string_get_lpart_sub(const address_item * addr, const uschar * s) { #ifdef SUPPORT_I18N if (testflag(addr, af_utf8_downcvt)) { - uschar * t = string_localpart_utf8_to_alabel(s, NULL); + const uschar * t = string_localpart_utf8_to_alabel(s, NULL); return t ? t : s; /* t is NULL on a failed conversion */ } #endif @@ -975,7 +975,7 @@ Returns: the new value of the buffer pointer static gstring * string_get_localpart(address_item * addr, gstring * yield) { -uschar * s; +const uschar * s; if (testflag(addr, af_include_affixes) && (s = addr->prefix)) yield = string_cat(yield, string_get_lpart_sub(addr, s)); @@ -5086,7 +5086,7 @@ Returns: OK int deliver_split_address(address_item * addr) { -uschar * address = addr->address; +const uschar * address = addr->address; uschar * domain; uschar * t; int len; @@ -5103,7 +5103,7 @@ where they are locally interpreted. [The new draft "821" is more explicit on this, Jan 1999.] We know the syntax is valid, so this can be done by simply removing quoting backslashes and any unquoted doublequotes. */ -t = addr->cc_local_part = store_get(len+1, address); +addr->cc_local_part = t = store_get(len+1, address); while(len-- > 0) { int c = *address++; @@ -5115,7 +5115,7 @@ while(len-- > 0) } else *t++ = c; } -*t = 0; +*t = '\0'; /* We do the percent hack only for those domains that are listed in percent_hack_domains. A loop is required, to copy with multiple %-hacks. */ @@ -5123,8 +5123,8 @@ percent_hack_domains. A loop is required, to copy with multiple %-hacks. */ if (percent_hack_domains) { int rc; - uschar *new_address = NULL; - uschar *local_part = addr->cc_local_part; + uschar * new_address = NULL; + const uschar * local_part = addr->cc_local_part; deliver_domain = addr->domain; /* set $domain */ @@ -5261,12 +5261,12 @@ Returns: TRUE if the address is not hidden */ static BOOL -print_address_information(address_item *addr, FILE *f, uschar *si, uschar *sc, - uschar *se) +print_address_information(address_item * addr, FILE * f, uschar * si, + uschar * sc, uschar * se) { BOOL yield = TRUE; -uschar *printed = US""; -address_item *ancestor = addr; +const uschar * printed = US""; +address_item * ancestor = addr; while (ancestor->parent) ancestor = ancestor->parent; fprintf(f, "%s", CS si); @@ -5281,8 +5281,8 @@ else if (!testflag(addr, af_pfr) || !addr->parent) else { - uschar *s = addr->address; - uschar *ss; + const uschar * s = addr->address; + const uschar * ss; if (addr->address[0] == '>') { ss = US"mail"; s++; } else if (addr->address[0] == '|') ss = US"pipe"; @@ -5296,7 +5296,7 @@ fprintf(f, "%s", CS string_printing(printed)); if (ancestor != addr) { - uschar *original = ancestor->onetime_parent; + const uschar * original = ancestor->onetime_parent; if (!original) original= ancestor->address; if (strcmpic(original, printed) != 0) fprintf(f, "%s(%sgenerated from %s)", sc, @@ -6973,7 +6973,7 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (!p->transport) { - address_item *badp = p; + address_item * badp = p; p = p->next; if (!addr_last) addr_new = p; else addr_last->next = p; badp->local_part = badp->address; /* Needed for log line */ @@ -7114,9 +7114,10 @@ if (process_recipients != RECIP_IGNORE) #ifndef DISABLE_EVENT if (process_recipients != RECIP_ACCEPT && event_action) { - uschar * save_local = deliver_localpart; + const uschar * save_local = deliver_localpart; const uschar * save_domain = deliver_domain; - uschar * addr = new->address, * errmsg = NULL; + const uschar * addr = new->address; + uschar * errmsg = NULL; int start, end, dom; if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) @@ -8365,7 +8366,7 @@ else if (addr_defer != (address_item *)(+1)) for (i = 0; i < recipients_count; i++) { - uschar *r = recipients_list[i].address; + const uschar * r = recipients_list[i].address; if (Ustrcmp(otaddr->onetime_parent, r) == 0) t = i; if (Ustrcmp(otaddr->address, r) == 0) break; } @@ -8393,7 +8394,7 @@ else if (addr_defer != (address_item *)(+1)) if (sender_address[0]) { - uschar * s = addr->prop.errors_address; + const uschar * s = addr->prop.errors_address; if (!s) s = sender_address; if (Ustrstr(recipients, s) == NULL) recipients = string_sprintf("%s%s%s", recipients, diff --git a/src/src/exim.c b/src/src/exim.c index 14c057f40..4473373b3 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1379,17 +1379,15 @@ Argument: the local part Returns: the local part, quoted if necessary */ -uschar * -local_part_quote(uschar *lpart) +const uschar * +local_part_quote(const uschar * lpart) { BOOL needs_quote = FALSE; gstring * g; -for (uschar * t = lpart; !needs_quote && *t != 0; t++) - { +for (const uschar * t = lpart; !needs_quote && *t; t++) needs_quote = !isalnum(*t) && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL && (*t != '.' || t == lpart || t[1] == 0); - } if (!needs_quote) return lpart; @@ -1397,8 +1395,8 @@ g = string_catn(NULL, US"\"", 1); for (;;) { - uschar *nq = US Ustrpbrk(lpart, "\\\""); - if (nq == NULL) + uschar * nq = US Ustrpbrk(lpart, "\\\""); + if (!nq) { g = string_cat(g, lpart); break; @@ -1809,20 +1807,20 @@ BOOL verify_address_mode = FALSE; BOOL verify_as_sender = FALSE; BOOL rcpt_verify_quota = FALSE; BOOL version_printed = FALSE; -const uschar *alias_arg = NULL; -const uschar *called_as = US""; -const uschar *cmdline_syslog_name = NULL; -const uschar *start_queue_run_id = NULL; -const uschar *stop_queue_run_id = NULL; -const uschar *expansion_test_message = NULL; -const uschar *ftest_domain = NULL; -const uschar *ftest_localpart = NULL; -const uschar *ftest_prefix = NULL; -const uschar *ftest_suffix = NULL; -uschar *log_oneline = NULL; -const uschar *malware_test_file = NULL; -uschar *real_sender_address; -uschar *originator_home = US"/"; +const uschar * alias_arg = NULL; +const uschar * called_as = US""; +const uschar * cmdline_syslog_name = NULL; +const uschar * start_queue_run_id = NULL; +const uschar * stop_queue_run_id = NULL; +const uschar * expansion_test_message = NULL; +const uschar * ftest_domain = NULL; +const uschar * ftest_localpart = NULL; +const uschar * ftest_prefix = NULL; +const uschar * ftest_suffix = NULL; +uschar * log_oneline = NULL; +const uschar * malware_test_file = NULL; +const uschar * real_sender_address; +uschar * originator_home = US"/"; size_t sz; struct passwd *pw; @@ -2844,7 +2842,11 @@ on the second character (the one after '-'), to save some effort. */ if (i+1 < argc) argrest = argv[++i]; else { badarg = TRUE; break; } (void) exim_str_fail_toolong(argrest, EXIM_DISPLAYMAIL_MAX, "-f"); if (!*argrest) - *(sender_address = store_get(1, GET_UNTAINTED)) = '\0'; /* Ensure writeable memory */ + { + uschar * s = store_get(1, GET_UNTAINTED); /* Ensure writeable memory */ + *s = '\0'; + sender_address = s; + } else { const uschar * temp = argrest + Ustrlen(argrest) - 1; diff --git a/src/src/expand.c b/src/src/expand.c index 40cc8d73a..9a88d38ca 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1804,20 +1804,19 @@ return g; /* A recipients list is available only during system message filtering, during ACL processing after DATA, and while expanding pipe commands generated from a system filter, but not elsewhere. Note that this does -not check for comman in the elements, and uses comma-space as seperator - +not check for commas in the elements, and uses comma-space as seperator - so cannot be used as an exim list as-is. */ static uschar * fn_recipients(void) { -uschar * s; gstring * g = NULL; if (!f.enable_dollar_recipients) return NULL; for (int i = 0; i < recipients_count; i++) { - s = recipients_list[i].address; + const uschar * s = recipients_list[i].address; g = string_append2_listele_n(g, US", ", s, Ustrlen(s)); } gstring_release_unused(g); diff --git a/src/src/functions.h b/src/src/functions.h index ba4fd215c..74cd15424 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -100,7 +100,7 @@ extern int tlsa_lookup(const host_item *, dns_answer *, BOOL); /* Everything else... */ extern acl_block *acl_read(uschar *(*)(void), uschar **); -extern int acl_check(int, uschar *, uschar *, uschar **, uschar **); +extern int acl_check(int, const uschar *, uschar *, uschar **, uschar **); extern uschar *acl_current_verb(void); extern int acl_eval(int, uschar *, uschar **, uschar **); extern uschar *acl_standalone_setvar(const uschar *); @@ -216,7 +216,7 @@ extern void decode_bits(unsigned int *, size_t, int *, const uschar *, bit_table *, int, uschar *, int); extern void delete_pid_file(void); extern void deliver_local(address_item *, BOOL); -extern address_item *deliver_make_addr(uschar *, BOOL); +extern address_item *deliver_make_addr(const uschar *, BOOL); extern void delivery_log(int, address_item *, int, uschar *); extern int deliver_message(const uschar *, BOOL, BOOL); extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2); @@ -335,7 +335,7 @@ extern int ip_streamsocket(const uschar *, uschar **, int, host_item *); extern int ipv6_nmtoa(int *, uschar *); -extern uschar *local_part_quote(uschar *); +extern const uschar *local_part_quote(const uschar *); extern int log_open_as_exim(const uschar * const); extern void log_close_all(void); @@ -375,11 +375,11 @@ extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *); extern int mime_regex(const uschar **, BOOL); extern void mime_set_anomaly(int); #endif -extern uschar *moan_check_errorcopy(uschar *); +extern uschar *moan_check_errorcopy(const uschar *); extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *, BOOL, uschar *); extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3); -extern BOOL moan_send_message(uschar *, int, error_block *eblock, +extern BOOL moan_send_message(const uschar *, int, error_block *eblock, header_line *, FILE *, uschar *); extern void moan_tell_someone(uschar *, address_item *, const uschar *, const char *, ...) PRINTF_FUNCTION(4,5); @@ -440,7 +440,7 @@ extern void readconf_save_config(const uschar *); extern void read_message_body(BOOL); extern void receive_bomb_out(uschar *, uschar *) NORETURN; extern BOOL receive_check_fs(int); -extern BOOL receive_check_set_sender(uschar *); +extern BOOL receive_check_set_sender(const uschar *); extern BOOL receive_msg(BOOL); extern int_eximarith_t receive_statvfs(BOOL, int *); extern void receive_swallow_smtp(void); @@ -636,7 +636,7 @@ extern BOOL transport_pass_socket(const uschar *, const uschar *, const uscha , unsigned, unsigned, unsigned #endif ); -extern uschar *transport_rcpt_address(address_item *, BOOL); +extern const uschar *transport_rcpt_address(address_item *, BOOL); extern BOOL transport_set_up_command(const uschar ***, const uschar *, unsigned, int, address_item *, const uschar *, uschar **); extern void transport_update_waiting(host_item *, uschar *); @@ -644,7 +644,7 @@ extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL); extern void transport_write_reset(int); extern BOOL transport_write_string(int, const char *, ...); extern BOOL transport_headers_send(transport_ctx *, - BOOL (*)(transport_ctx *, uschar *, int)); + BOOL (*)(transport_ctx *, const uschar *, int)); extern gstring * transport_show_supported(gstring *); extern BOOL transport_write_message(transport_ctx *, int); extern void tree_add_duplicate(const uschar *, address_item *); @@ -679,7 +679,7 @@ extern int verify_check_notblind(BOOL); extern int verify_check_given_host(const uschar **, const host_item *); extern int verify_check_this_host(const uschar **, unsigned int *, const uschar*, const uschar *, const uschar **); -extern address_item *verify_checked_sender(uschar *); +extern address_item *verify_checked_sender(const uschar *); extern void verify_get_ident(int); extern void verify_quota(uschar *); extern int verify_quota_call(const uschar *, int, int, uschar **); @@ -687,7 +687,7 @@ extern BOOL verify_sender(int *, uschar **); extern BOOL verify_sender_preliminary(int *, uschar **); extern void version_init(void); -extern BOOL write_chunk(transport_ctx *, uschar *, int); +extern BOOL write_chunk(transport_ctx *, const uschar *, int); extern ssize_t write_to_fd_buf(int, const uschar *, size_t); extern uschar *wrap_header(const uschar *, unsigned, unsigned, const uschar *, unsigned); diff --git a/src/src/globals.c b/src/src/globals.c index 46ca72f20..bb5bd6b1a 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -610,8 +610,8 @@ address_item address_defaults = { } }; -uschar *address_file = NULL; -uschar *address_pipe = NULL; +const uschar *address_file = NULL; +const uschar *address_pipe = NULL; tree_node *addresslist_anchor = NULL; int addresslist_count = 0; gid_t *admin_groups = NULL; @@ -683,7 +683,7 @@ int body_linecount = 0; int body_zerocount = 0; uschar *bounce_message_file = NULL; uschar *bounce_message_text = NULL; -uschar *bounce_recipient = NULL; +const uschar *bounce_recipient = NULL; int bounce_return_linesize_limit = 998; int bounce_return_size_limit = 100*1024; uschar *bounce_sender_authentication = NULL; @@ -842,14 +842,14 @@ const uschar *deliver_host_address = NULL; int deliver_host_port = 0; uschar *deliver_in_buffer = NULL; ino_t deliver_inode = 0; -uschar *deliver_localpart = NULL; +const uschar *deliver_localpart= NULL; uschar *deliver_localpart_data = NULL; -uschar *deliver_localpart_orig = NULL; -uschar *deliver_localpart_parent = NULL; -uschar *deliver_localpart_prefix = NULL; -uschar *deliver_localpart_prefix_v = NULL; -uschar *deliver_localpart_suffix = NULL; -uschar *deliver_localpart_suffix_v = NULL; +const uschar *deliver_localpart_orig = NULL; +const uschar *deliver_localpart_parent = NULL; +const uschar *deliver_localpart_prefix = NULL; +const uschar *deliver_localpart_prefix_v = NULL; +const uschar *deliver_localpart_suffix = NULL; +const uschar *deliver_localpart_suffix_v = NULL; uschar *deliver_out_buffer = NULL; int deliver_queue_load_max = -1; address_item *deliver_recipients = NULL; @@ -1276,8 +1276,8 @@ tree_node *ratelimiters_cmd = NULL; tree_node *ratelimiters_conn = NULL; tree_node *ratelimiters_mail = NULL; uschar *raw_active_hostname = NULL; -uschar *raw_sender = NULL; -uschar **raw_recipients = NULL; +const uschar *raw_sender = NULL; +const uschar **raw_recipients = NULL; int raw_recipients_count = 0; int rcpt_count = 0; @@ -1289,7 +1289,7 @@ int receive_linecount = 0; int receive_messagecount = 0; int receive_timeout = 0; int received_count = 0; -uschar *received_for = NULL; +const uschar *received_for = NULL; /* This is the default text for Received headers generated by Exim. The date will be automatically added on the end. */ @@ -1348,7 +1348,7 @@ int retry_data_expire = 7*24*60*60; int retry_interval_max = 24*60*60; int retry_maximum_timeout = 0; /* set from retry config */ retry_config *retries = NULL; -uschar *return_path = NULL; +const uschar *return_path = NULL; int rewrite_existflags = 0; uschar *rfc1413_hosts = US"@[]"; int rfc1413_query_timeout = 0; @@ -1456,10 +1456,10 @@ int runrc = 0; uschar *search_error_message = NULL; uschar *self_hostname = NULL; -uschar *sender_address = NULL; +const uschar *sender_address = NULL; unsigned int sender_address_cache[(MAX_NAMED_LIST * 2)/32]; uschar *sender_address_data = NULL; -uschar *sender_address_unrewritten = NULL; +const uschar *sender_address_unrewritten = NULL; uschar *sender_data = NULL; unsigned int sender_domain_cache[(MAX_NAMED_LIST * 2)/32]; uschar *sender_fullhost = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 9ec44487f..dff3762a8 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -350,8 +350,8 @@ extern uschar *acl_wherecodes[]; /* Response codes for ACL fails */ extern uschar *acl_wherenames[]; /* Names for messages */ extern address_item *addr_duplicate; /* Duplicate address list */ extern address_item address_defaults; /* Default data for address item */ -extern uschar *address_file; /* Name of file when delivering to one */ -extern uschar *address_pipe; /* Pipe command when delivering to one */ +extern const uschar *address_file; /* Name of file when delivering to one */ +extern const uschar *address_pipe; /* Pipe command when delivering to one */ extern tree_node *addresslist_anchor; /* Tree of defined address lists */ extern int addresslist_count; /* Number defined */ extern gid_t *admin_groups; /* List of admin groups */ @@ -400,7 +400,7 @@ extern int bsmtp_transaction_linecount; /* Start of last transaction */ extern int body_8bitmime; /* sender declared BODY= ; 7=7BIT, 8=8BITMIME */ extern uschar *bounce_message_file; /* Template file */ extern uschar *bounce_message_text; /* One-liner */ -extern uschar *bounce_recipient; /* When writing an errmsg */ +extern const uschar *bounce_recipient; /* When writing an errmsg */ extern BOOL bounce_return_body; /* Include body in returned message */ extern int bounce_return_linesize_limit; /* Max line length in return */ extern BOOL bounce_return_message; /* Include message in bounce */ @@ -517,14 +517,14 @@ extern const uschar *deliver_host_address; /* Address for remote delivery filter extern int deliver_host_port; /* Address for remote delivery filter */ extern uschar *deliver_in_buffer; /* Buffer for copying file */ extern ino_t deliver_inode; /* Inode for appendfile */ -extern uschar *deliver_localpart; /* The local part for delivery */ +extern const uschar *deliver_localpart;/* The local part for delivery */ extern uschar *deliver_localpart_data; /* From local part lookup (de-tainted) */ -extern uschar *deliver_localpart_orig; /* The original local part for delivery */ -extern uschar *deliver_localpart_parent; /* The parent local part for delivery */ -extern uschar *deliver_localpart_prefix; /* The stripped prefix, if any */ -extern uschar *deliver_localpart_prefix_v; /* The stripped-prefix variable portion, if any */ -extern uschar *deliver_localpart_suffix; /* The stripped suffix, if any */ -extern uschar *deliver_localpart_suffix_v; /* The stripped-suffix variable portion, if any */ +extern const uschar *deliver_localpart_orig; /* The original local part for delivery */ +extern const uschar *deliver_localpart_parent; /* The parent local part for delivery */ +extern const uschar *deliver_localpart_prefix; /* The stripped prefix, if any */ +extern const uschar *deliver_localpart_prefix_v; /* The stripped-prefix variable portion, if any */ +extern const uschar *deliver_localpart_suffix; /* The stripped suffix, if any */ +extern const uschar *deliver_localpart_suffix_v; /* The stripped-suffix variable portion, if any */ extern uschar *deliver_out_buffer; /* Buffer for copying file */ extern int deliver_queue_load_max; /* Different value for queue running */ extern address_item *deliver_recipients; /* Current set of addresses */ @@ -872,8 +872,8 @@ extern tree_node *ratelimiters_cmd; /* Results of command ratelimit checks */ extern tree_node *ratelimiters_conn; /* Results of connection ratelimit checks */ extern tree_node *ratelimiters_mail; /* Results of per-mail ratelimit checks */ extern uschar *raw_active_hostname; /* Pre-expansion */ -extern uschar *raw_sender; /* Before rewriting */ -extern uschar **raw_recipients; /* Before rewriting */ +extern const uschar *raw_sender; /* Before rewriting */ +extern const uschar **raw_recipients; /* Before rewriting */ extern int raw_recipients_count; extern const uschar * rc_names[]; /* Mostly for debug output */ extern int rcpt_count; /* Count of RCPT commands in a message */ @@ -885,7 +885,7 @@ extern int receive_linecount; /* Mainly for BSMTP errors */ extern int receive_messagecount; /* Mainly for BSMTP errors */ extern int receive_timeout; /* For non-SMTP acceptance */ extern int received_count; /* Count of Received: headers */ -extern uschar *received_for; /* For "for" field */ +extern const uschar *received_for; /* For "for" field */ extern uschar *received_header_text; /* Definition of Received: header */ extern int received_headers_max; /* Max count of Received: headers */ extern struct timeval received_time; /* Time the message started to be received */ @@ -926,7 +926,7 @@ extern retry_config *retries; /* Chain of retry config information */ extern int retry_data_expire; /* When to expire retry data */ extern int retry_interval_max; /* Absolute maximum */ extern int retry_maximum_timeout; /* The maximum timeout */ -extern uschar *return_path; /* Return path for a message */ +extern const uschar *return_path; /* Return path for a message */ extern BOOL return_path_remove; /* Remove return-path headers */ extern int rewrite_existflags; /* Indicate which headers have rewrites */ extern uschar *rfc1413_hosts; /* RFC hosts */ @@ -947,7 +947,7 @@ extern uschar *search_error_message; /* Details of lookup problem */ extern uschar *self_hostname; /* Self host after routing->directors */ extern unsigned int sender_address_cache[(MAX_NAMED_LIST * 2)/32]; /* Cache bits for sender */ extern uschar *sender_address_data; /* address_data from sender verify */ -extern uschar *sender_address_unrewritten; /* Set if rewritten by verify */ +extern const uschar *sender_address_unrewritten; /* Set if rewritten by verify */ extern uschar *sender_data; /* lookup result for senders */ extern unsigned int sender_domain_cache[(MAX_NAMED_LIST * 2)/32]; /* Cache bits for sender domain */ extern uschar *sender_fullhost; /* Sender host name + address */ diff --git a/src/src/local_scan.h b/src/src/local_scan.h index 153b4cb3c..ed9f26d62 100644 --- a/src/src/local_scan.h +++ b/src/src/local_scan.h @@ -153,9 +153,9 @@ field is always NULL except for one_time aliases that had errors_to on the routers that generated them. */ typedef struct recipient_item { - uschar *address; /* the recipient address */ + const uschar *address; /* the recipient address */ int pno; /* parent number for "one_time" alias, or -1 */ - uschar *errors_to; /* the errors_to address or NULL */ + const uschar *errors_to; /* the errors_to address or NULL */ uschar *orcpt; /* DSN orcpt */ int dsn_flags; /* DSN flags */ #ifdef EXPERIMENTAL_BRIGHTMAIL @@ -181,7 +181,7 @@ extern uschar *message_id; /* Internal id of message being handled * extern uschar *received_protocol; /* Name of incoming protocol */ extern int recipients_count; /* Number of recipients */ extern recipient_item *recipients_list;/* List of recipient addresses */ -extern unsigned char *sender_address; /* Sender address */ +extern const unsigned char *sender_address; /* Sender address */ extern uschar *sender_host_address; /* IP address of sender, as chars */ extern uschar *sender_host_authenticated; /* Name of authentication mechanism */ extern uschar *sender_host_name; /* Host name from lookup */ @@ -207,8 +207,8 @@ extern int lss_match_domain(uschar *, uschar *); extern int lss_match_local_part(uschar *, uschar *, BOOL); extern int lss_match_address(uschar *, uschar *, BOOL); extern int lss_match_host(uschar *, uschar *, uschar *); -extern void receive_add_recipient(uschar *, int); -extern BOOL receive_remove_recipient(uschar *); +extern void receive_add_recipient(const uschar *, int); +extern BOOL receive_remove_recipient(const uschar *); extern uschar *rfc2047_decode(uschar *, BOOL, const uschar *, int, int *, uschar **); extern int smtp_fflush(void); diff --git a/src/src/log.c b/src/src/log.c index af6e8b01b..f85823520 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -1032,11 +1032,10 @@ if ( flags & LOG_RECIPIENTS && g->ptr < LOG_BUFFER_SIZE - 6 && raw_recipients_count > 0) { - int i; g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " for", NULL); - for (i = 0; i < raw_recipients_count; i++) + for (int i = 0; i < raw_recipients_count; i++) { - uschar * s = raw_recipients[i]; + const uschar * s = raw_recipients[i]; if (LOG_BUFFER_SIZE - g->ptr < Ustrlen(s) + 3) break; g = string_fmt_append_f(g, SVFMT_TAINT_NOCHK, " %s", s); } diff --git a/src/src/moan.c b/src/src/moan.c index 25595816c..c2e38d4f7 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -158,8 +158,8 @@ Returns: TRUE if message successfully sent */ BOOL -moan_send_message(uschar *recipient, int ident, error_block *eblock, - header_line *headers, FILE *message_file, uschar *firstline) +moan_send_message(const uschar * recipient, int ident, error_block * eblock, + header_line * headers, FILE * message_file, uschar * firstline) { int written = 0; int fd; @@ -631,7 +631,7 @@ if (addr) fprintf(f, "\nThe following address(es) have yet to be delivered:\n"); for (; addr; addr = addr->next) { - uschar * parent = addr->parent ? addr->parent->address : NULL; + const uschar * parent = addr->parent ? addr->parent->address : NULL; fprintf(f, " %s", addr->address); if (parent) fprintf(f, " <%s>", parent); if (addr->basic_errno > 0) fprintf(f, ": %s", strerror(addr->basic_errno)); @@ -734,22 +734,23 @@ Returns: additional recipient list or NULL */ uschar * -moan_check_errorcopy(uschar *recipient) +moan_check_errorcopy(const uschar * recipient) { -uschar *item, *localpart, *domain; -const uschar *listptr = errors_copy; +uschar * item; +const uschar * localpart, * domain; +const uschar * listptr = errors_copy; uschar *yield = NULL; int sep = 0; int llen; -if (errors_copy == NULL) return NULL; +if (!errors_copy) return NULL; /* Set up pointer to the local part and domain, and compute the length of the local part. */ localpart = recipient; domain = Ustrrchr(recipient, '@'); -if (domain == NULL) return NULL; /* should not occur, but avoid crash */ +if (!domain) return NULL; /* should not occur, but avoid crash */ llen = domain++ - recipient; /* Scan through the configured items */ diff --git a/src/src/queue.c b/src/src/queue.c index cfe87e953..deedcde6f 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -585,7 +585,7 @@ for (int i = queue_run_in_order ? -1 : 0; else if ( deliver_selectstring_sender && !(f.deliver_selectstring_sender_regex ? regex_match(selectstring_regex_sender, sender_address, -1, NULL) - : (strstric(sender_address, deliver_selectstring_sender, FALSE) + : (strstric_c(sender_address, deliver_selectstring_sender, FALSE) != NULL) ) ) { @@ -601,10 +601,10 @@ for (int i = queue_run_in_order ? -1 : 0; int i; for (i = 0; i < recipients_count; i++) { - uschar *address = recipients_list[i].address; + const uschar * address = recipients_list[i].address; if ( (f.deliver_selectstring_regex ? regex_match(selectstring_regex, address, -1, NULL) - : (strstric(address, deliver_selectstring, FALSE) != NULL) + : (strstric_c(address, deliver_selectstring, FALSE) != NULL) ) && tree_search(tree_nonrecipients, address) == NULL ) @@ -1369,9 +1369,10 @@ switch(action) tree_search(tree_nonrecipients, recipients_list[i].address); if (!delivered) { - uschar * save_local = deliver_localpart; + const uschar * save_local = deliver_localpart; const uschar * save_domain = deliver_domain; - uschar * addr = recipients_list[i].address, * errmsg = NULL; + const uschar * addr = recipients_list[i].address; + uschar * errmsg = NULL; int start, end, dom; if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) diff --git a/src/src/rda.c b/src/src/rda.c index 9c2aa5022..7d329c580 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -466,7 +466,7 @@ Returns: FALSE if data missing */ static BOOL -rda_read_string(int fd, uschar **sp) +rda_read_string(int fd, uschar ** sp) { int len; @@ -866,9 +866,9 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || for (;;) { int i, reply_options; - address_item *addr; - uschar *recipient; - uschar *expandn[EXPAND_MAXN + 2]; + address_item * addr; + uschar * recipient, * s; + uschar * expandn[EXPAND_MAXN + 2]; /* First string is the address; NULL => end of addresses */ @@ -885,10 +885,11 @@ if (yield == FF_DELIVERED || yield == FF_NOTDELIVERED || if ( read(fd, &addr->mode, sizeof(addr->mode)) != sizeof(addr->mode) || read(fd, &addr->flags, sizeof(addr->flags)) != sizeof(addr->flags) - || !rda_read_string(fd, &addr->prop.errors_address) + || !rda_read_string(fd, &s) || read(fd, &i, sizeof(i)) != sizeof(i) ) goto DISASTER; + addr->prop.errors_address = s; addr->prop.ignore_error = (i != 0); /* Next comes a possible setting for $thisaddress and any numerical diff --git a/src/src/receive.c b/src/src/receive.c index 041898a6b..a459061ef 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -137,9 +137,9 @@ Returns: TRUE for a trusted caller */ BOOL -receive_check_set_sender(uschar *newsender) +receive_check_set_sender(const uschar * newsender) { -uschar *qnewsender; +const uschar * qnewsender; if (f.trusted_caller) return TRUE; if (!newsender || !untrusted_set_sender) return FALSE; qnewsender = Ustrchr(newsender, '@') @@ -514,7 +514,7 @@ Returns: nothing */ void -receive_add_recipient(uschar * recipient, int pno) +receive_add_recipient(const uschar * recipient, int pno) { if (recipients_count >= recipients_list_max) { @@ -591,7 +591,7 @@ Returns: TRUE if it did remove something; FALSE otherwise */ BOOL -receive_remove_recipient(uschar *recipient) +receive_remove_recipient(const uschar * recipient) { DEBUG(D_receive) debug_printf("receive_remove_recipient(\"%s\") called\n", recipient); @@ -3600,7 +3600,7 @@ else /* Loop through recipients, responses must be in same order received */ for (unsigned int c = 0; recipients_count > c; c++) { - uschar * addr= recipients_list[c].address; + const uschar * addr = recipients_list[c].address; uschar * msg= US"PRDR R=<%s> %s"; uschar * code; DEBUG(D_receive) diff --git a/src/src/rewrite.c b/src/src/rewrite.c index ec5c2cffc..c0d173abf 100644 --- a/src/src/rewrite.c +++ b/src/src/rewrite.c @@ -119,9 +119,9 @@ for (rewrite_rule * rule = rewrite_rules; { int start, end, pdomain; int count = 0; - uschar *save_localpart; - const uschar *save_domain; - uschar *error, *new; + const uschar * save_localpart; + const uschar * save_domain; + uschar * error, * new; const uschar * newparsed; /* Come back here for a repeat after a successful rewrite. We do this diff --git a/src/src/route.c b/src/src/route.c index 82d51bc68..0bd87b837 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -859,12 +859,12 @@ Returns: OK if all the tests succeed */ static BOOL -check_router_conditions(router_instance *r, address_item *addr, int verify, - struct passwd **pw, uschar **perror) +check_router_conditions(router_instance * r, address_item * addr, int verify, + struct passwd ** pw, uschar ** perror) { int rc; -uschar *check_local_part; -unsigned int *localpart_cache; +uschar * check_local_part; +unsigned int * localpart_cache; /* Reset variables to hold a home directory and data from lookup of a domain or local part, and ensure search_find_defer is unset, in case there aren't any @@ -928,15 +928,12 @@ because that doesn't have the prefix or suffix stripped. A bit of massaging is required. Also, we only use the match cache for local parts that have not had a prefix or suffix stripped. */ +check_local_part = string_copy(addr->cc_local_part); if (!addr->prefix && !addr->suffix) - { localpart_cache = addr->localpart_cache; - check_local_part = addr->cc_local_part; - } else { localpart_cache = NULL; - check_local_part = string_copy(addr->cc_local_part); if (addr->prefix) check_local_part += Ustrlen(addr->prefix); if (addr->suffix) diff --git a/src/src/routers/accept.c b/src/src/routers/accept.c index 63c8c22e4..8b72bfac1 100644 --- a/src/src/routers/accept.c +++ b/src/src/routers/accept.c @@ -104,9 +104,9 @@ accept_router_options_block *ob = (accept_router_options_block *)(rblock->options_block); */ int rc; -uschar *errors_to; -uschar *remove_headers; -header_line *extra_headers; +const uschar * errors_to; +uschar * remove_headers; +header_line * extra_headers; DEBUG(D_route) debug_printf("%s router called for %s\n domain = %s\n", rblock->name, addr->address, addr->domain); diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index 6a17c2f8d..4c8e30563 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -306,9 +306,8 @@ redirect_router_options_block *ob = while (generated) { - address_item *parent; - address_item *next = generated; - uschar *errors_address = next->prop.errors_address; + address_item * next = generated, * parent; + const uschar * errors_address = next->prop.errors_address; generated = next->next; next->parent = addr; diff --git a/src/src/routers/rf_functions.h b/src/src/routers/rf_functions.h index 91ccfb132..40d4cde1c 100644 --- a/src/src/routers/rf_functions.h +++ b/src/src/routers/rf_functions.h @@ -15,7 +15,7 @@ extern void rf_add_generated(router_instance *, address_item **, extern void rf_change_domain(address_item *, const uschar *, BOOL, address_item **); extern uschar *rf_expand_data(address_item *, uschar *, int *); extern int rf_get_errors_address(address_item *, router_instance *, - int, uschar **); + int, const uschar **); extern int rf_get_munge_headers(address_item *, router_instance *, header_line **, uschar **); extern BOOL rf_get_transport(uschar *, transport_instance **, address_item *, diff --git a/src/src/routers/rf_get_errors_address.c b/src/src/routers/rf_get_errors_address.c index f70bdf25e..222d157d8 100644 --- a/src/src/routers/rf_get_errors_address.c +++ b/src/src/routers/rf_get_errors_address.c @@ -35,13 +35,13 @@ Returns: OK if no problem */ int -rf_get_errors_address(address_item *addr, router_instance *rblock, - int verify, uschar **errors_to) +rf_get_errors_address(address_item * addr, router_instance * rblock, + int verify, const uschar ** errors_to) { uschar *s; *errors_to = addr->prop.errors_address; -if (rblock->errors_to == NULL) return OK; +if (!rblock->errors_to) return OK; s = expand_string(rblock->errors_to); @@ -84,17 +84,14 @@ if (verify != v_none) else { BOOL save_address_test_mode = f.address_test_mode; - int save1 = 0; + const uschar * save_sender = sender_address; int i; const uschar ***p; const uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT]; address_item *snew = deliver_make_addr(s, FALSE); if (sender_address) - { - save1 = sender_address[0]; - sender_address[0] = 0; - } + sender_address = US""; for (i = 0, p = address_expansions; *p;) address_expansions_save[i++] = **p++; @@ -124,7 +121,7 @@ else for (i = 0, p = address_expansions; *p; ) **p++ = address_expansions_save[i++]; - if (sender_address) sender_address[0] = save1; + sender_address = save_sender; } return OK; diff --git a/src/src/spf.c b/src/src/spf.c index e72051708..2e3f861eb 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -341,7 +341,8 @@ else for (int i = 0; i < SPF_response_messages(spf_response); i++) Return: OK/FAIL */ int -spf_process(const uschar **listptr, uschar *spf_envelope_sender, int action) +spf_process(const uschar ** listptr, const uschar * spf_envelope_sender, + int action) { int sep = 0; const uschar *list = *listptr; diff --git a/src/src/spf.h b/src/src/spf.h index 76c7522bd..afee742ed 100644 --- a/src/src/spf.h +++ b/src/src/spf.h @@ -29,7 +29,7 @@ typedef struct spf_result_id { gstring * spf_lib_version_report(gstring *); BOOL spf_init(void); BOOL spf_conn_init(uschar *, uschar *); -int spf_process(const uschar **, uschar *, int); +int spf_process(const uschar **, const uschar *, int); void spf_response_debug(SPF_response_t *); #define SPF_PROCESS_NORMAL 0 diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 588effd2c..3e3b246ab 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -456,9 +456,12 @@ n = Ustrlen(big_buffer); if (n < 3 || big_buffer[0] != '<' || big_buffer[n-2] != '>') goto SPOOL_FORMAT_ERROR; -sender_address = store_get(n-2, GET_TAINTED); -Ustrncpy(sender_address, big_buffer+1, n-3); -sender_address[n-3] = 0; + { + uschar * s = store_get(n-2, GET_TAINTED); + Ustrncpy(s, big_buffer+1, n-3); + s[n-3] = '\0'; + sender_address = s; + } where = US"time"; if (Ufgets(big_buffer, big_buffer_size, fp) == NULL) goto SPOOL_READ_ERROR; diff --git a/src/src/structs.h b/src/src/structs.h index 214819482..209d657c6 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -526,7 +526,7 @@ typedef struct address_item_propagated { uschar *address_data; /* arbitrary data to keep with the address */ uschar *domain_data; /* from "domains" lookup */ uschar *localpart_data; /* from "local_parts" lookup */ - uschar *errors_address; /* where to send errors (NULL => sender) */ + const uschar *errors_address; /* where to send errors (NULL => sender) */ header_line *extra_headers; /* additional headers */ uschar *remove_headers; /* list of those to remove */ void *variables; /* router-vasriables */ @@ -561,15 +561,15 @@ typedef struct address_item { reply_item *reply; /* data for autoreply */ retry_item *retries; /* chain of retry information */ - uschar *address; /* address being delivered or routed */ + const uschar *address; /* address being delivered or routed */ uschar *unique; /* used for disambiguating */ - uschar *cc_local_part; /* caseful local part */ - uschar *lc_local_part; /* lowercased local part */ - uschar *local_part; /* points to cc or lc version */ - uschar *prefix; /* stripped prefix of local part */ - uschar *prefix_v; /* variable part of above */ - uschar *suffix; /* stripped suffix of local part */ - uschar *suffix_v; /* variable part of above */ + const uschar *cc_local_part; /* caseful local part */ + const uschar *lc_local_part; /* lowercased local part */ + const uschar *local_part; /* points to cc or lc version */ + const uschar *prefix; /* stripped prefix of local part */ + const uschar *prefix_v; /* variable part of above */ + const uschar *suffix; /* stripped suffix of local part */ + const uschar *suffix_v; /* variable part of above */ const uschar *domain; /* working domain (lower cased) */ uschar *address_retry_key; /* retry key including full address */ @@ -580,7 +580,7 @@ typedef struct address_item { uschar *message; /* error message */ uschar *user_message; /* error message that can be sent over SMTP or quoted in bounce message */ - uschar *onetime_parent; /* saved original parent for onetime */ + const uschar *onetime_parent; /* saved original parent for onetime */ uschar **pipe_expandn; /* numeric expansions for pipe from filter */ uschar *return_filename; /* name of return file */ uschar *self_hostname; /* after self=pass */ diff --git a/src/src/transport.c b/src/src/transport.c index b3b05c0a3..a0f097579 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -434,10 +434,10 @@ Returns: TRUE on success, FALSE on failure (with errno preserved) */ BOOL -write_chunk(transport_ctx * tctx, uschar *chunk, int len) +write_chunk(transport_ctx * tctx, const uschar * chunk, int len) { -uschar *start = chunk; -uschar *end = chunk + len; +const uschar * start = chunk; +const uschar * end = chunk + len; int mlen = DELIVER_OUT_BUFFER_SIZE - nl_escape_length - 2; /* The assumption is made that the check string will never stretch over move @@ -474,7 +474,7 @@ if (nl_partial_match >= 0) for possible escaping. The code for the non-NL route should be as fast as possible. */ -for (uschar * ptr = start; ptr < end; ptr++) +for (const uschar * ptr = start; ptr < end; ptr++) { int ch, len; @@ -580,7 +580,7 @@ Arguments: Returns: a string */ -uschar * +const uschar * transport_rcpt_address(address_item *addr, BOOL include_affixes) { uschar *at; @@ -704,7 +704,7 @@ Returns: TRUE on success; FALSE on failure. */ BOOL transport_headers_send(transport_ctx * tctx, - BOOL (*sendfn)(transport_ctx * tctx, uschar * s, int len)) + BOOL (*sendfn)(transport_ctx * tctx, const uschar * s, int len)) { const uschar * list; transport_instance * tblock = tctx ? tctx->tblock : NULL; @@ -2302,7 +2302,7 @@ if (flags & TSUC_EXPAND_ARGS) address_pipe_argv = store_get((address_pipe_max_args+1)*sizeof(uschar *), GET_UNTAINTED); /* +1 because addr->local_part[0] == '|' since af_force_command is set */ - s = expand_string(addr->local_part + 1); + s = expand_cstring(addr->local_part + 1); if (!s || !*s) { diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 2c7bea11d..ec41ca035 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -502,7 +502,7 @@ Returns: nothing */ static void -notify_comsat(uschar *user, off_t offset) +notify_comsat(const uschar * user, off_t offset) { struct servent *sp; host_item host; diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index b9cc32df1..64c70e719 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -292,7 +292,7 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_direct_command(const uschar *** argvptr, uschar * cmd, +set_up_direct_command(const uschar *** argvptr, const uschar * cmd, BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname, pipe_transport_options_block * ob) { @@ -414,8 +414,8 @@ Returns: TRUE if all went well; otherwise an error will be */ static BOOL -set_up_shell_command(const uschar ***argvptr, uschar *cmd, - BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname) +set_up_shell_command(const uschar *** argvptr, const uschar * cmd, + BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname) { const uschar **argv; @@ -462,10 +462,10 @@ if (expand_arguments) } g = string_cat(g, q); - argv[2] = (cmd = string_from_gstring(g)) ? expand_string(cmd) : NULL; + argv[2] = (cmd = string_from_gstring(g)) ? expand_cstring(cmd) : NULL; } else - argv[2] = expand_string(cmd); + argv[2] = expand_cstring(cmd); f.enable_dollar_recipients = FALSE; @@ -518,11 +518,12 @@ pipe_transport_options_block *ob = int timeout = ob->timeout; BOOL written_ok = FALSE; BOOL expand_arguments; -const uschar **argv; -uschar *envp[50]; -const uschar *envlist = ob->environment; -uschar *cmd, *ss; -uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; +const uschar ** argv; +uschar * envp[50]; +const uschar * envlist = ob->environment; +const uschar * cmd; +uschar * ss; +uschar * eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { .tblock = tblock, .addr = addr, diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 8c00a1ef2..c53e1000f 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -656,8 +656,7 @@ static void deferred_event_raise(address_item * addr, host_item * host, uschar * evstr) { uschar * action = addr->transport->event_action; -const uschar * save_domain; -uschar * save_local; +const uschar * save_domain, * save_local; if (!action) return; @@ -1793,7 +1792,7 @@ return FALSE; typedef struct smtp_compare_s { - uschar * current_sender_address; + const uschar * current_sender_address; struct transport_instance * tblock; } smtp_compare_t; @@ -1803,7 +1802,7 @@ sender_address, helo_data and tls_certificate if enabled. */ static uschar * -smtp_local_identity(uschar * sender, struct transport_instance * tblock) +smtp_local_identity(const uschar * sender, struct transport_instance * tblock) { address_item * addr1; uschar * if1 = US""; @@ -1811,7 +1810,7 @@ uschar * helo1 = US""; #ifndef DISABLE_TLS uschar * tlsc1 = US""; #endif -uschar * save_sender_address = sender_address; +const uschar * save_sender_address = sender_address; uschar * local_identity = NULL; smtp_transport_options_block * ob = SOB tblock->options_block; @@ -3434,7 +3433,7 @@ buffer. */ sx->pending_MAIL = TRUE; /* The block starts with MAIL */ { - uschar * s = sx->from_addr; + const uschar * s = sx->from_addr; #ifdef SUPPORT_I18N uschar * errstr = NULL; @@ -3505,7 +3504,7 @@ for (addr = sx->first_addr, address_count = 0, pipe_limit = 100; { int cmds_sent; BOOL no_flush; - uschar * rcpt_addr; + const uschar * rcpt_addr; #ifdef EXPERIMENTAL_ESMTP_LIMITS if ( sx->single_rcpt_domain /* restriction on domains */ diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 0d15b9626..1f888ee0b 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -140,7 +140,7 @@ typedef struct { /* smtp connect context */ typedef struct { - uschar * from_addr; + const uschar * from_addr; address_item * addrlist; smtp_connect_args conn_args; diff --git a/src/src/verify.c b/src/src/verify.c index 6361aa434..bc3666285 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -105,8 +105,8 @@ Return: TRUE if result found */ static BOOL -cached_callout_lookup(address_item * addr, uschar * address_key, - uschar * from_address, int * opt_ptr, uschar ** pm_ptr, +cached_callout_lookup(address_item * addr, const uschar * address_key, + const uschar * from_address, int * opt_ptr, uschar ** pm_ptr, int * yield, uschar ** failure_ptr, dbdata_callout_cache * new_domain_record, int * old_domain_res) { @@ -278,10 +278,10 @@ return FALSE; */ static void cache_callout_write(dbdata_callout_cache * dom_rec, const uschar * domain, - int done, dbdata_callout_cache_address * addr_rec, uschar * address_key) + int done, dbdata_callout_cache_address * addr_rec, const uschar * address_key) { open_db dbblock; -open_db *dbm_file = NULL; +open_db * dbm_file = NULL; /* If we get here with done == TRUE, a successful callout happened, and yield will be set OK or FAIL according to the response to the RCPT command. @@ -502,11 +502,11 @@ do_callout(address_item *addr, host_item *host_list, transport_feedback *tf, int yield = OK; int old_domain_cache_result = ccache_accept; BOOL done = FALSE; -uschar *address_key; -uschar *from_address; -uschar *random_local_part = NULL; -const uschar *save_deliver_domain = deliver_domain; -uschar **failure_ptr = options & vopt_is_recipient +const uschar * address_key; +const uschar * from_address; +uschar * random_local_part = NULL; +const uschar * save_deliver_domain = deliver_domain; +uschar ** failure_ptr = options & vopt_is_recipient ? &recipient_verify_failure : &sender_verify_failure; dbdata_callout_cache new_domain_record; dbdata_callout_cache_address new_address_record; @@ -771,7 +771,7 @@ tls_retry_connection: if (random_local_part) { - uschar * main_address = addr->address; + const uschar * main_address = addr->address; const uschar * rcpt_domain = addr->domain; #ifdef SUPPORT_I18N @@ -942,7 +942,7 @@ tls_retry_connection: if (done) { - uschar * main_address = addr->address; + const uschar * main_address = addr->address; /*XXX oops, affixes */ addr->address = string_sprintf("postmaster@%.1000s", addr->domain); @@ -1286,7 +1286,7 @@ return FALSE; static BOOL -_cutthrough_puts(uschar * cp, int n) +_cutthrough_puts(const uschar * cp, int n) { while(n--) { @@ -1301,7 +1301,7 @@ return TRUE; /* Buffered output of counted data block. Return boolean success */ static BOOL -cutthrough_puts(uschar * cp, int n) +cutthrough_puts(const uschar * cp, int n) { if (cutthrough.cctx.sock < 0) return TRUE; if (_cutthrough_puts(cp, n)) return TRUE; @@ -1407,9 +1407,9 @@ return cutthrough_response(&cutthrough.cctx, '3', NULL, CUTTHROUGH_DATA_TIMEOUT) /* tctx arg only to match write_chunk() */ static BOOL -cutthrough_write_chunk(transport_ctx * tctx, uschar * s, int len) +cutthrough_write_chunk(transport_ctx * tctx, const uschar * s, int len) { -uschar * s2; +const uschar * s2; while(s && (s2 = Ustrchr(s, '\n'))) { if(!cutthrough_puts(s, s2-s) || !cutthrough_put_nl()) @@ -1697,16 +1697,16 @@ int yield = OK; int verify_type = expn ? v_expn : f.address_test_mode ? v_none : options & vopt_is_recipient ? v_recipient : v_sender; -address_item *addr_list; -address_item *addr_new = NULL; -address_item *addr_remote = NULL; -address_item *addr_local = NULL; -address_item *addr_succeed = NULL; -uschar **failure_ptr = options & vopt_is_recipient +address_item * addr_list; +address_item * addr_new = NULL; +address_item * addr_remote = NULL; +address_item * addr_local = NULL; +address_item * addr_succeed = NULL; +uschar ** failure_ptr = options & vopt_is_recipient ? &recipient_verify_failure : &sender_verify_failure; -uschar *ko_prefix, *cr; -uschar *address = vaddr->address; -uschar *save_sender; +uschar * ko_prefix, * cr; +const uschar * address = vaddr->address; +const uschar * save_sender; uschar null_sender[] = { 0 }; /* Ensure writeable memory */ /* Clear, just in case */ @@ -1751,9 +1751,8 @@ may have been set by domains and local part tests during an ACL. */ if (global_rewrite_rules) { - uschar *old = address; - /* deconst ok as address was not const */ - address = US rewrite_address(address, options & vopt_is_recipient, FALSE, + const uschar * old = address; + address = rewrite_address(address, options & vopt_is_recipient, FALSE, global_rewrite_rules, rewrite_existflags); if (address != old) { @@ -1919,8 +1918,8 @@ while (addr_new) if (tf.hosts && (!host_list || tf.hosts_override)) { uschar *s; - const uschar *save_deliver_domain = deliver_domain; - uschar *save_deliver_localpart = deliver_localpart; + const uschar * save_deliver_domain = deliver_domain; + const uschar * save_deliver_localpart = deliver_localpart; host_list = NULL; /* Ignore the router's hosts */ @@ -2455,11 +2454,11 @@ verify_check_notblind(BOOL case_sensitive) for (int i = 0; i < recipients_count; i++) { BOOL found = FALSE; - uschar *address = recipients_list[i].address; + const uschar * address = recipients_list[i].address; for (header_line * h = header_list; !found && h; h = h->next) { - uschar *colon, *s; + uschar * colon, * s; if (h->type != htype_to && h->type != htype_cc) continue; @@ -2533,7 +2532,7 @@ Returns: pointer to an address item, or NULL */ address_item * -verify_checked_sender(uschar *sender) +verify_checked_sender(const uschar * sender) { for (address_item * addr = sender_verified_list; addr; addr = addr->next) if (Ustrcmp(sender, addr->address) == 0) return addr; commit 9643095d7cae6866b716d361a45c9a95f605040c Author: Andrew Aitchison Date: Thu Nov 16 17:09:57 2023 +0000 Compiler quiteneing diff --git a/src/src/globals.h b/src/src/globals.h index dff3762a8..fe4a1610a 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -323,7 +323,7 @@ extern uschar *acl_smtp_connect; /* ACL run on SMTP connection */ extern uschar *acl_smtp_data; /* ACL run after DATA received */ #ifndef DISABLE_PRDR extern uschar *acl_smtp_data_prdr; /* ACL run after DATA received if in PRDR mode*/ -const extern pcre2_code *regex_PRDR; /* For recognizing PRDR settings */ +extern const pcre2_code *regex_PRDR; /* For recognizing PRDR settings */ #endif #ifndef DISABLE_DKIM extern uschar *acl_smtp_dkim; /* ACL run for DKIM signatures / domains */ @@ -752,7 +752,7 @@ extern uschar *message_size_limit; /* As it says */ #ifdef SUPPORT_I18N extern BOOL message_smtputf8; /* Internationalized mail handling */ extern int message_utf8_downconvert; /* convert from utf8 */ -const extern pcre2_code *regex_UTF8; /* For recognizing SMTPUTF8 settings */ +extern const pcre2_code *regex_UTF8; /* For recognizing SMTPUTF8 settings */ #endif extern uschar message_subdir[]; /* Subdirectory for messages */ extern const uschar *message_reference;/* Reference for error messages */ commit 79670d3c32ccb37fe06f25d8192943b58606a32a Author: Jeremy Harris Date: Fri Nov 17 16:55:17 2023 +0000 Lookups: Fix dnsdb lookup of multi-chunk TXT. Bug 3054 Broken=by: f6b1f8e7d642 diff --git a/src/src/dns.c b/src/src/dns.c index a652dcd31..74c5a58c5 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -431,7 +431,9 @@ namelen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, dnss->aptr, if (namelen < 0) goto null_return; /* Move the pointer past the name and fill in the rest of the data structure -from the following bytes. */ +from the following bytes. We seem to be assuming here that the RR blob passed +to us by the resolver library is the same as that defined for an RR by RFC 1035 +section 3.2.1 */ TRACE trace = "R-name"; if (dnss_inc_aptr(dnsa, dnss, namelen)) goto null_return; diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index ff51dec23..8288896ca 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -387,38 +387,31 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) } /* Other kinds of record just have one piece of data each, but there may be - several of them, of course. */ + several of them, of course. TXT & SPF can have data in multiple chunks. */ if (yield->ptr) yield = string_catn(yield, outsep, 1); if (type == T_TXT || type == T_SPF) - { - if (!outsep2) /* output only the first item of data */ + for (unsigned data_offset = 0; data_offset + 1 < rr->size; ) { - uschar n = (rr->data)[0]; - /* size byte + data bytes must not excced the RRs length */ - if (n + 1 <= rr->size) - yield = string_catn(yield, US (rr->data+1), n); + uschar chunk_len = (rr->data)[data_offset]; + int remain; + + if (outsep2 && *outsep2 && data_offset != 0) + yield = string_catn(yield, outsep2, 1); + + /* Apparently there are resolvers that do not check RRs before passing + them on, and glibc fails to do so. So every application must... + Check for chunk len exceeding RR */ + + remain = rr->size - ++data_offset; + if (chunk_len > remain) + chunk_len = remain; + yield = string_catn(yield, US ((rr->data) + data_offset), chunk_len); + data_offset += chunk_len; + + if (!outsep2) break; /* output only the first chunk of the RR */ } - else - for (unsigned data_offset = 0; data_offset < rr->size; ) - { - uschar chunk_len = (rr->data)[data_offset]; - int remain = rr->size - data_offset; - - /* Apparently there are resolvers that do not check RRs before passing - them on, and glibc fails to do so. So every application must... - Check for chunk len exceeding RR */ - - if (chunk_len > remain) - chunk_len = remain; - - if (*outsep2 && data_offset != 0) - yield = string_catn(yield, outsep2, 1); - yield = string_catn(yield, US ((rr->data) + ++data_offset), --chunk_len); - data_offset += chunk_len; - } - } else if (type == T_TLSA) if (rr->size < 3) continue; commit 1d19531abc45f656eff8f3dd5ba6986d919fee11 Author: Jeremy Harris Date: Sun Nov 19 11:31:45 2023 +0000 Support old-format message_id spoolfiles for mailq / -bp. Bug 3050 Broken-by: 46a36afae41f diff --git a/src/src/queue.c b/src/src/queue.c index deedcde6f..2c3d014f5 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -961,7 +961,9 @@ each time. */ if (option == QL_MSGID_ONLY) /* Print only the message IDs from the chain */ for (; qf; qf = qf->next) - fprintf(stdout, "%.*s\n", MESSAGE_ID_LENGTH, qf->text); + fprintf(stdout, "%.*s\n", + is_old_message_id(qf->text) ? MESSAGE_ID_LENGTH_OLD : MESSAGE_ID_LENGTH, + qf->text); else for (; qf && (reset_point = store_mark()); @@ -1021,7 +1023,9 @@ else for (; } fprintf(stdout, "%s %.*s", - string_format_size(size, big_buffer), MESSAGE_ID_LENGTH, qf->text); + string_format_size(size, big_buffer), + is_old_message_id(qf->text) ? MESSAGE_ID_LENGTH_OLD : MESSAGE_ID_LENGTH, + qf->text); if (env_read && sender_address) { commit 8213f508a8c66e7ed8e00a9123f72763ff99010b Author: Jeremy Harris Date: Sat Nov 25 15:46:12 2023 +0000 DMARC: fix reporting, no-ARC-support case diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 042ebe982..f684e08ea 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -311,7 +311,7 @@ g = string_fmt_append(g, "align_dkim %d\nalign_spf %d\naction %d\n", # ifdef EXPERIMENTAL_ARC g = arc_dmarc_hist_append(g); # else -g = string_fmt_append(g, "arc %d\narc_policy $d json:[]\n", +g = string_fmt_append(g, "arc %d\narc_policy %d json:[]\n", ARES_RESULT_UNKNOWN, DMARC_ARC_POLICY_RESULT_UNUSED); # endif #endif commit 33c9e43ec040c0a29394d8e3b745180ddddc0ed8 Author: Jeremy Harris Date: Sat Nov 25 16:47:35 2023 +0000 DMARC: fix reporting, ARC-support but not in message diff --git a/src/src/arc.c b/src/src/arc.c index defe9b171..bd2fa3bae 100644 --- a/src/src/arc.c +++ b/src/src/arc.c @@ -2011,7 +2011,7 @@ if (arc_state) g = string_catn(g, US" ]\n", 3); } else - g = string_fmt_append(g, "arc %d\narc_policy $d json:[]\n", + g = string_fmt_append(g, "arc %d\narc_policy %d json:[]\n", ARES_RESULT_UNKNOWN, DMARC_ARC_POLICY_RESULT_UNUSED); return g; } commit 5d0d124a8b49b484cda869bcb0d3e5224716d276 Author: Jeremy Harris Date: Sun Nov 26 20:28:07 2023 +0000 Unbreak DISABLE_TLS_RESUME build Broken-by: 5d5ad9fb16a2 diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index c53e1000f..4cf58436d 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -761,13 +761,14 @@ return TRUE; } +#if !defined(DISABLE_TLS) && !defined(DISABLE_TLS_RESUME) + /* Grab a string differentiating server behind a loadbalancer, for TLS resumption when such servers do not share a session-cache */ static void ehlo_response_lbserver(smtp_context * sx, const uschar * name_extract) { -#if !defined(DISABLE_TLS) && !defined(DISABLE_TLS_RESUME) const uschar * s; uschar * save_item = iterate_item; @@ -778,8 +779,8 @@ s = expand_cstring(name_extract); iterate_item = save_item; sx->conn_args.host_lbserver = s && !*s ? NULL : s; sx->conn_args.have_lbserver = TRUE; -#endif } +#endif @@ -1075,9 +1076,11 @@ if (pending_BANNER) } /*XXX EXPERIMENTAL_ESMTP_LIMITS ? */ +# ifndef DISABLE_TLS_RESUME s = ((smtp_transport_options_block *)sx->conn_args.ob)->host_name_extract; if (!s) s = HNE_DEFAULT; ehlo_response_lbserver(sx, s); +# endif } if (pending_EHLO) @@ -2482,13 +2485,14 @@ goto SEND_QUIT; ob->tls_tempfail_tryclear = FALSE; smtp_command = US"SSL-on-connect"; +# ifndef DISABLE_TLS_RESUME /* Having no EHLO response yet, cannot peek there for a servername to detect an LB. Call this anyway, so that a dummy host_name_extract option value can force resumption attempts. */ if (!(s = ob->host_name_extract)) s = US"never-LB"; ehlo_response_lbserver(sx, s); - +# endif goto TLS_NEGOTIATE; } #endif @@ -2613,8 +2617,10 @@ goto SEND_QUIT; } } #endif +#ifndef DISABLE_TLS_RESUME if (!(s = ob->host_name_extract)) s = HNE_DEFAULT; ehlo_response_lbserver(sx, s); +#endif } /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */ commit 5bca25510e7313419c4ed0107ae153177bee938c Author: Jeremy Harris Date: Mon Nov 27 17:51:25 2023 +0000 Build: fix for Solaris 11 diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index 8288896ca..050baa3b7 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -445,20 +445,20 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) switch (type) { case T_MXH: - if (rr_bad_size(rr, sizeof(u_int16_t))) continue; + if (rr_bad_size(rr, sizeof(uint16_t))) continue; /* mxh ignores the priority number and includes only the hostnames */ GETSHORT(priority, p); break; case T_MX: - if (rr_bad_size(rr, sizeof(u_int16_t))) continue; + if (rr_bad_size(rr, sizeof(uint16_t))) continue; GETSHORT(priority, p); sprintf(CS s, "%d%c", priority, *outsep2); yield = string_cat(yield, s); break; case T_SRV: - if (rr_bad_size(rr, 3*sizeof(u_int16_t))) continue; + if (rr_bad_size(rr, 3*sizeof(uint16_t))) continue; GETSHORT(priority, p); GETSHORT(weight, p); GETSHORT(port, p); @@ -468,7 +468,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0))) break; case T_CSA: - if (rr_bad_size(rr, 3*sizeof(u_int16_t))) continue; + if (rr_bad_size(rr, 3*sizeof(uint16_t))) continue; /* See acl_verify_csa() for more comments about CSA. */ GETSHORT(priority, p); GETSHORT(weight, p); commit e4520c7817b76d6a5453237d94b1ed10fa6d2ef3 Author: Jeremy Harris Date: Fri Dec 1 15:44:57 2023 +0000 Avoid trying to send smtp repoonse for non-smtp input, on datafile close error Broken-by: f70940c9489d diff --git a/src/src/receive.c b/src/src/receive.c index a459061ef..c4b80c236 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -4425,8 +4425,8 @@ if (spool_data_file && cutthrough_done == NOT_TRIED) Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H")); Uunlink(spool_fname(US"msglog", message_subdir, message_id, US"")); - /* Claim a data ACL temp-reject, just to get reject logging and resposponse */ - smtp_handle_acl_fail(ACL_WHERE_DATA, rc, NULL, log_msg); + /* Claim a data ACL temp-reject, just to get reject logging and response */ + if (smtp_input) smtp_handle_acl_fail(ACL_WHERE_DATA, rc, NULL, log_msg); smtp_reply = US""; /* Indicate reply already sent */ message_id[0] = 0; /* no message accepted */ commit 87229a18d1fbe959d38f82bde661b57fed11d220 Author: Jeremy Harris Date: Tue Dec 5 17:49:06 2023 +0000 Compiler quietening diff --git a/src/src/verify.c b/src/src/verify.c index bc3666285..d080ddd63 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -3005,6 +3005,8 @@ if ((semicolon = Ustrchr(ss, ';'))) endname = semicolon; opts = NULL; } +else + opts = NULL; /* If we are doing an IP address only match, then all lookups must be IP address lookups, even if there is no "net-". */ commit 2658a023286fcce529031e9f071c5579650687b8 Author: Jeremy Harris Date: Tue Dec 5 21:23:46 2023 +0000 DKIM: tighten up parsing for DKIM DNS and header records. Bug 3056 diff --git a/src/src/functions.h b/src/src/functions.h index 74cd15424..b201467b2 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -760,7 +760,7 @@ return US strncpy(CS dst, CCS src, n); /* Advance the string pointer given over any whitespace. -Return the next char as there's enought places using it to be useful. */ +Return the next char as there's enough places using it to be useful. */ #define Uskip_whitespace(sp) skip_whitespace(CUSS sp) diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index c723ae6c8..21e17c61e 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -512,10 +512,6 @@ for (uschar * p = raw_hdr; ; p++) } if (where == PDKIM_HDR_TAG) - { - if (c >= 'a' && c <= 'z') - cur_tag = string_catn(cur_tag, p, 1); - if (c == '=') { if (Ustrcmp(string_from_gstring(cur_tag), "b") == 0) @@ -526,7 +522,8 @@ for (uschar * p = raw_hdr; ; p++) where = PDKIM_HDR_VALUE; goto NEXT_CHAR; } - } + else if (!isspace(c)) + cur_tag = string_catn(cur_tag, p, 1); if (where == PDKIM_HDR_VALUE) { @@ -553,17 +550,17 @@ for (uschar * p = raw_hdr; ; p++) switch (cur_tag->s[1]) { case '\0': pdkim_decode_base64(cur_val->s, &sig->sighash); break; - case 'h': if (cur_tag->ptr == 2) - pdkim_decode_base64(cur_val->s, &sig->bodyhash); + case 'h': if (cur_tag->ptr != 2) goto bad_tag; + pdkim_decode_base64(cur_val->s, &sig->bodyhash); break; - default: break; + default: goto bad_tag; } break; case 'v': /* version */ /* We only support version 1, and that is currently the only version there is. */ sig->version = - Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1; + Ustrcmp(cur_val->s, PDKIM_SIGNATURE_VERSION) == 0 ? 1 : -1; break; case 'a': /* algorithm */ { @@ -578,6 +575,7 @@ for (uschar * p = raw_hdr; ; p++) if (Ustrcmp(elem, pdkim_hashes[i].dkim_hashname) == 0) { sig->hashtype = i; break; } } + break; case 'c': /* canonicalization */ pdkim_cstring_to_canons(cur_val->s, 0, @@ -586,15 +584,15 @@ for (uschar * p = raw_hdr; ; p++) case 'q': /* Query method (for pubkey)*/ for (int i = 0; pdkim_querymethods[i]; i++) if (Ustrcmp(cur_val->s, pdkim_querymethods[i]) == 0) - { + { sig->querymethod = i; /* we never actually use this */ break; } break; case 's': /* Selector */ - sig->selector = string_copyn(cur_val->s, cur_val->ptr); break; + sig->selector = string_copy_from_gstring(cur_val); break; case 'd': /* SDID */ - sig->domain = string_copyn(cur_val->s, cur_val->ptr); break; + sig->domain = string_copy_from_gstring(cur_val); break; case 'i': /* AUID */ sig->identity = pdkim_decode_qp(cur_val->s); break; case 't': /* Timestamp */ @@ -604,16 +602,18 @@ for (uschar * p = raw_hdr; ; p++) case 'l': /* Body length count */ sig->bodylength = strtol(CS cur_val->s, NULL, 10); break; case 'h': /* signed header fields */ - sig->headernames = string_copyn(cur_val->s, cur_val->ptr); break; + sig->headernames = string_copy_from_gstring(cur_val); break; case 'z': /* Copied headfields */ sig->copiedheaders = pdkim_decode_qp(cur_val->s); break; /*XXX draft-ietf-dcrup-dkim-crypto-05 would need 'p' tag support for rsafp signatures. But later discussion is dropping those. */ default: - DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); - break; + goto bad_tag; } } + else +bad_tag: DEBUG(D_acl) debug_printf(" Unknown tag encountered: %Y\n", cur_tag); + cur_tag = cur_val = NULL; in_b_val = FALSE; where = PDKIM_HDR_LIMBO; @@ -659,25 +659,37 @@ return sig; /* -------------------------------------------------------------------------- */ pdkim_pubkey * -pdkim_parse_pubkey_record(const uschar *raw_record) +pdkim_parse_pubkey_record(const uschar * raw_record) { -const uschar * ele; -int sep = ';'; -pdkim_pubkey * pub; +pdkim_pubkey * pub = store_get(sizeof(pdkim_pubkey), GET_TAINTED); -pub = store_get(sizeof(pdkim_pubkey), GET_TAINTED); memset(pub, 0, sizeof(pdkim_pubkey)); -while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0))) +for (const uschar * ele = raw_record, * tspec, * end, * val; *ele; ele = end) { - const uschar * val; + Uskip_whitespace(&ele); + end = US strchrnul(CS ele, ';'); + tspec = string_copyn(ele, end - ele); + if (*end) end++; /* skip the ; */ - if ((val = Ustrchr(ele, '='))) + if ((val = Ustrchr(tspec, '='))) { - int taglen = val++ - ele; + int taglen = val++ - tspec; + + DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, tspec, val); + while (taglen > 1 && isspace(tspec[taglen-1])) + taglen--; /* Ignore whitespace before = */ + while (isspace(*val)) + val++; /* Ignore whitespace after = */ + if (isspace(val[ Ustrlen(val)-1 ])) + { /* Ignore whitespace after value */ + gstring * g = string_cat(NULL, val); + while (isspace(gstring_last_char(g))) + gstring_trim(g, 1); + val = string_from_gstring(g); + } - DEBUG(D_acl) debug_printf(" %.*s=%s\n", taglen, ele, val); - switch (ele[0]) + if (taglen == 1) switch (tspec[0]) { case 'v': pub->version = val; break; case 'h': pub->hashes = val; break; @@ -689,8 +701,11 @@ while ((ele = string_nextinlist(&raw_record, &sep, NULL, 0))) case 't': if (Ustrchr(val, 'y')) pub->testing = 1; if (Ustrchr(val, 's')) pub->no_subdomaining = 1; break; - default: DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); break; + default: goto bad_tag; } + else +bad_tag: + DEBUG(D_acl) debug_printf(" Unknown tag encountered\n"); } } commit 5930166b443390a522f210c2e60ec447a7dbd080 Author: Jeremy Harris Date: Wed Dec 6 12:25:14 2023 +0000 Supply strchrnul() for platforms apparently missing it Broken-by: 2658a023286f diff --git a/src/OS/os.h-FreeBSD b/src/OS/os.h-FreeBSD index 6756d42f6..11f8b1ae7 100644 --- a/src/OS/os.h-FreeBSD +++ b/src/OS/os.h-FreeBSD @@ -78,5 +78,7 @@ extern ssize_t os_sendfile(int, int, off_t *, size_t); /*******************/ #define EXIM_HAVE_KEVENT +#define EXIM_HAVE_STRCHRNUL + /* End */ diff --git a/src/OS/os.h-Linux b/src/OS/os.h-Linux index 25a12862b..cebda3367 100644 --- a/src/OS/os.h-Linux +++ b/src/OS/os.h-Linux @@ -102,4 +102,6 @@ then change the 0 to 1 in the next block. */ # define NS_MAXMSG 65535 #endif +#define EXIM_HAVE_STRCHRNUL + /* End */ diff --git a/src/src/os.c b/src/src/os.c index 5c52c6d4d..5e5899eeb 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -893,6 +893,21 @@ return buffer ? buffer : realloc(b, strlen(b) + 1); #endif /* ----------------------------------------------------------------------- */ +/*********************************************************** +* strchrnul() * +***********************************************************/ + +#if !defined(EXIM_HAVE_STRCHRNUL) +char * +strchrnul(const char * s, int c) +{ +while (*s != c && *s) s++ +return CS s; +} +#endif + + +/* ----------------------------------------------------------------------- */ commit b0e63c7efdc2133c61545b051042d3617ecd2bbd Author: Jeremy Harris Date: Wed Dec 6 19:54:40 2023 +0000 Logging: ensure that an error for a mistyped IPv6 address in a search list is available for logging. Bug 3057 diff --git a/src/src/match.c b/src/src/match.c index df440108e..8b1a3bef6 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -886,14 +886,19 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error); goto OK_RETURN; - case ERROR: /* host name lookup failed - this can only */ - if (ignore_unknown) /* be for an incoming host (not outgoing) */ + /* The ERROR return occurs when checking hosts, when either a forward + or reverse lookup has failed. It can also occur in a match_ip list if a + non-IP address item is encountered. The error string gives details of + which it was. */ + + case ERROR: + if (ignore_unknown) { HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n", error); } else - { + { HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot, include_unknown? "yes":"no", error); (void)fclose(f); diff --git a/src/src/string.c b/src/src/string.c index dfe0f2451..3bf2f1df7 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -57,6 +57,7 @@ union { /* we do not need this, but inet_pton() needs a place for storage */ we return failure, as we do if the mask isn't a pure numerical value, or if it is negative. The actual length is checked later, once we know the address family. */ + if (slash = Ustrchr(ip_addr, '/')) { uschar * rest; @@ -74,10 +75,11 @@ if (slash = Ustrchr(ip_addr, '/')) return 0; } - *maskptr = slash - ip_addr; /* offset of the slash */ + *maskptr = slash - ip_addr; /* offset of the slash */ endp = slash; } -else if (maskptr) *maskptr = 0; /* no slash found */ +else if (maskptr) + *maskptr = 0; /* no slash found */ /* The interface-ID suffix (%) is optional (for IPv6). If it exists, we check it syntactically. Later, if we know the address @@ -160,7 +162,7 @@ switch (af) int string_is_ip_address(const uschar * ip_addr, int * maskptr) { -return string_is_ip_addressX(ip_addr, maskptr, 0); +return string_is_ip_addressX(ip_addr, maskptr, NULL); } #endif /* COMPILE_UTILITY */ diff --git a/src/src/verify.c b/src/src/verify.c index d080ddd63..194e9a76a 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -2971,7 +2971,7 @@ if (*ss == '@') a (possibly masked) comparison with the current IP address. */ if (string_is_ip_address(ss, &maskoffset) != 0) - return (host_is_in_net(cb->host_address, ss, maskoffset)? OK : FAIL); + return host_is_in_net(cb->host_address, ss, maskoffset) ? OK : FAIL; /* The pattern is not an IP address. A common error that people make is to omit one component of an IPv4 address, either by accident, or believing that, for @@ -2982,13 +2982,25 @@ ancient specification.) To aid in debugging these cases, we give a specific error if the pattern contains only digits and dots or contains a slash preceded only by digits and dots (a slash at the start indicates a file name and of course slashes may be present in lookups, but not preceded only by digits and -dots). */ +dots). Then the equivalent for IPv6 (roughly). */ -for (t = ss; isdigit(*t) || *t == '.'; ) t++; -if (!*t || (*t == '/' && t != ss)) +if (Ustrchr(ss, ':')) { - *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss); - return ERROR; + for (t = ss; isxdigit(*t) || *t == ':' || *t == '.'; ) t++; + if (!*t || (*t == '/' || *t == '%') && t != ss) + { + *error = string_sprintf("malformed IPv6 address or address mask: %.*s", (int)(t - ss), ss); + return ERROR; + } + } +else + { + for (t = ss; isdigit(*t) || *t == '.'; ) t++; + if (!*t || (*t == '/' && t != ss)) + { + *error = string_sprintf("malformed IPv4 address or address mask: %.*s", (int)(t - ss), ss); + return ERROR; + } } /* See if there is a semicolon in the pattern, separating a searchtype commit b037dd69615b2ce9e084932e8a61477afc67345e Author: Jeremy Harris Date: Wed Dec 6 22:08:08 2023 +0000 typo Broken-by: 5930166b4433 diff --git a/src/src/os.c b/src/src/os.c index 5e5899eeb..c6d1e06c2 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -901,7 +901,7 @@ return buffer ? buffer : realloc(b, strlen(b) + 1); char * strchrnul(const char * s, int c) { -while (*s != c && *s) s++ +while (*s != c && *s) s++; return CS s; } #endif commit ce336ea1afd8d5f6b79d36fc7ec4313f3d80146b Author: Jeremy Harris Date: Thu Dec 7 19:59:35 2023 +0000 Handle expansion fails in router "set" options. Bug 3058 diff --git a/src/src/route.c b/src/src/route.c index 0bd87b837..3401f15b4 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -1492,7 +1492,11 @@ for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); ) { addr->message = string_sprintf("expansion of \"%s\" failed " "in %s router: %s", ele, r->name, expand_string_message); - return DEFER; + /* Caller will replace that for logging, if a DB lookup, to avoid exposing + passwords */ + DEBUG(D_route) debug_printf("%s\n", addr->message); + if (!f.search_find_defer) + return f.search_find_defer ? DEFER : FAIL; } if (!(node = tree_search(*root, name))) @@ -1546,8 +1550,8 @@ route_address(address_item *addr, address_item **paddr_local, { int yield = OK; BOOL unseen; -router_instance *r, *nextr; -const uschar *old_domain = addr->domain; +router_instance * r, * nextr; +const uschar * old_domain = addr->domain; HDEBUG(D_route) { @@ -1561,8 +1565,8 @@ instead of at the first router. */ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) { - uschar *error; - struct passwd *pw = NULL; + uschar * error; + struct passwd * pw = NULL; struct passwd pwcopy; BOOL loop_detected = FALSE; BOOL more; @@ -1736,11 +1740,11 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) router traversal. On the addr string they are held as a variable tree, so as to maintain the post-expansion taints separate. */ - switch (set_router_vars(addr, r)) + switch (rc = set_router_vars(addr, r)) { case OK: break; case PASS: continue; /* with next router */ - default: goto ROUTE_EXIT; + default: yield = rc; goto ROUTE_EXIT; } /* Finally, expand the address_data field in the router. Forced failure