X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fexim.c;h=1410359bc821a71318765bbd0b72eed599a370d9;hb=3fc73bdc7aa8ac2b2b290033f602bdb947ae8049;hp=f0f373f6080ef4b66bc6a0814392cf6e66b3049d;hpb=165acdd1ea3b7399b2279f94c881f8e366efaf71;p=exim.git diff --git a/src/src/exim.c b/src/src/exim.c index f0f373f60..1410359bc 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2017 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -187,7 +187,15 @@ DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info); va_end(ap); } +/*********************************************** +* Handler for SIGTERM * +***********************************************/ +static void +term_handler(int sig) +{ + exit(1); +} /************************************************* @@ -542,9 +550,9 @@ close_unwanted(void) { if (smtp_input) { - #ifdef SUPPORT_TLS - tls_close(TRUE, FALSE); /* Shut down the TLS library */ - #endif +#ifdef SUPPORT_TLS + tls_close(NULL, TLS_NO_SHUTDOWN); /* Shut down the TLS library */ +#endif (void)close(fileno(smtp_in)); (void)close(fileno(smtp_out)); smtp_in = NULL; @@ -832,6 +840,9 @@ fprintf(f, "Support for:"); #ifdef WITH_CONTENT_SCAN fprintf(f, " Content_Scanning"); #endif +#ifdef SUPPORT_DANE + fprintf(f, " DANE"); +#endif #ifndef DISABLE_DKIM fprintf(f, " DKIM"); #endif @@ -872,12 +883,12 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_SRS fprintf(f, " Experimental_SRS"); #endif +#ifdef EXPERIMENTAL_ARC + fprintf(f, " Experimental_ARC"); +#endif #ifdef EXPERIMENTAL_BRIGHTMAIL fprintf(f, " Experimental_Brightmail"); #endif -#ifdef EXPERIMENTAL_DANE - fprintf(f, " Experimental_DANE"); -#endif #ifdef EXPERIMENTAL_DCC fprintf(f, " Experimental_DCC"); #endif @@ -887,6 +898,9 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_DSN_INFO fprintf(f, " Experimental_DSN_info"); #endif +#ifdef EXPERIMENTAL_REQUIRETLS + fprintf(f, " Experimental_REQUIRETLS"); +#endif fprintf(f, "\n"); fprintf(f, "Lookups (built-in):"); @@ -1295,32 +1309,6 @@ exit(EXIT_FAILURE); * Validate that the macros given are okay * *************************************************/ -#ifdef WHITELIST_D_MACROS -static void -wlist_check(uschar * name, uschar * val, void * ctx) -{ -uschar ** w, ** whites = ctx; -unsigned len; -int n; - -for (w = whites; *w; ++w) - if (Ustrcmp(*w, name) == 0) break; -if (*w) - { - if (!val || !*val) return; - len = Ustrlen(val); - if ((n = pcre_exec(regex_whitelisted_macro, NULL, CS val, len, - 0, PCRE_EOPT, NULL, 0)) >= 0) - return; - if (n != PCRE_ERROR_NOMATCH) - debug_printf("macros_trusted checking %s returned %d\n", name, n); - } -*whites = NULL; -return; -} -#endif - - /* Typically, Exim will drop privileges if macros are supplied. In some cases, we want to not do so. @@ -1333,7 +1321,7 @@ macros_trusted(BOOL opt_D_used) { #ifdef WHITELIST_D_MACROS macro_item *m; -uschar *whitelisted, *end, *p, **whites; +uschar *whitelisted, *end, *p, **whites, **w; int white_count, i, n; size_t len; BOOL prev_char_item, found; @@ -1396,9 +1384,32 @@ for (p = whitelisted, i = 0; (p != end) && (i < white_count); ++p) } whites[i] = NULL; -tree_walk(tree_macros, wlist_check, whites); -if (!*whites) return FALSE; - +/* The list of commandline macros should be very short. +Accept the N*M complexity. */ +for (m = macros_user; m; m = m->next) if (m->command_line) + { + found = FALSE; + for (w = whites; *w; ++w) + if (Ustrcmp(*w, m->name) == 0) + { + found = TRUE; + break; + } + if (!found) + return FALSE; + if (!m->replacement) + continue; + if ((len = m->replen) == 0) + continue; + n = pcre_exec(regex_whitelisted_macro, NULL, CS m->replacement, len, + 0, PCRE_EOPT, NULL, 0); + if (n < 0) + { + if (n != PCRE_ERROR_NOMATCH) + debug_printf("macros_trusted checking %s returned %d\n", m->name, n); + return FALSE; + } + } DEBUG(D_any) debug_printf("macros_trusted overridden to true by whitelisting\n"); return TRUE; #endif @@ -1430,10 +1441,7 @@ len = Ustrlen(big_buffer); if (isupper(big_buffer[0])) { if (macro_read_assignment(big_buffer)) - { - uschar * s = Ustrchr(big_buffer, '='); - printf("Defined macro '%.*s'\n", s - big_buffer, big_buffer); - } + printf("Defined macro '%s'\n", mlast->name); } else if ((line = expand_string(big_buffer))) printf("%s\n", CS line); @@ -1627,6 +1635,8 @@ testing harness; do a fast initial check, and then the whole thing. */ running_in_test_harness = *running_status == '<' && Ustrcmp(running_status, "<<>>") == 0; +if (running_in_test_harness) + debug_store = TRUE; /* The C standard says that the equivalent of setlocale(LC_ALL, "C") is obeyed at the start of a program; however, it seems that some environments do not @@ -1679,6 +1689,10 @@ descriptive text. */ set_process_info("initializing"); os_restarting_signal(SIGUSR1, usr1_handler); +/* If running in a dockerized environment, the TERM signal is only +delegated to the PID 1 if we request it by setting an signal handler */ +if (getpid() == 1) signal(SIGTERM, term_handler); + /* SIGHUP is used to get the daemon to reconfigure. It gets set as appropriate in the daemon code. For the rest of Exim's uses, we ignore it. */ @@ -2428,11 +2442,12 @@ for (i = 1; i < argc; i++) while (isspace(*s)) s++; } - if (macro_search(name)) - { - fprintf(stderr, "exim: duplicated -D in command line\n"); - exit(EXIT_FAILURE); - } + for (m = macros_user; m; m = m->next) + if (Ustrcmp(m->name, name) == 0) + { + fprintf(stderr, "exim: duplicated -D in command line\n"); + exit(EXIT_FAILURE); + } m = macro_create(name, s, TRUE); @@ -2441,8 +2456,8 @@ for (i = 1; i < argc; i++) fprintf(stderr, "exim: too many -D options on command line\n"); exit(EXIT_FAILURE); } - clmacros[clmacro_count++] = string_sprintf("-D%s=%s", - m->tnode.name, m->tnode.data.ptr); + clmacros[clmacro_count++] = string_sprintf("-D%s=%s", m->name, + m->replacement); } #endif break; @@ -2771,8 +2786,18 @@ for (i = 1; i < argc; i++) default: badarg = TRUE; break; } - break; + break; + } + +#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS) + /* -MS set REQUIRETLS on (new) message */ + + else if (*argrest == 'S') + { + tls_requiretls |= REQUIRETLS_MSG; + break; } +#endif /* -M[x]: various operations on the following list of message ids: -M deliver the messages, ignoring next retry times and thawing @@ -4071,16 +4096,24 @@ a debugging feature for finding out what arguments certain MUAs actually use. Don't attempt it if logging is disabled, or if listing variables or if verifying/testing addresses or expansions. */ -if (((debug_selector & D_any) != 0 || LOGGING(arguments)) - && really_exim && !list_options && !checking) +if ( (debug_selector & D_any || LOGGING(arguments)) + && really_exim && !list_options && !checking) { int i; uschar *p = big_buffer; Ustrcpy(p, "cwd= (failed)"); - Ustrncpy(p + 4, initial_cwd, big_buffer_size-5); + if (!initial_cwd) + p += 13; + else + { + Ustrncpy(p + 4, initial_cwd, big_buffer_size-5); + p += 4 + Ustrlen(initial_cwd); + /* in case p is near the end and we don't provide enough space for + * string_format to be willing to write. */ + *p = '\0'; + } - while (*p) p++; (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc); while (*p) p++; for (i = 0; i < argc; i++) @@ -4573,30 +4606,33 @@ if (test_retry_arg >= 0) if (list_options) { + BOOL fail = FALSE; set_process_info("listing variables"); - if (recipients_arg >= argc) readconf_print(US"all", NULL, flag_n); - else for (i = recipients_arg; i < argc; i++) + if (recipients_arg >= argc) + fail = !readconf_print(US"all", NULL, flag_n); + else for (i = recipients_arg; i < argc; i++) + { + if (i < argc - 1 && + (Ustrcmp(argv[i], "router") == 0 || + Ustrcmp(argv[i], "transport") == 0 || + Ustrcmp(argv[i], "authenticator") == 0 || + Ustrcmp(argv[i], "macro") == 0 || + Ustrcmp(argv[i], "environment") == 0)) { - if (i < argc - 1 && - (Ustrcmp(argv[i], "router") == 0 || - Ustrcmp(argv[i], "transport") == 0 || - Ustrcmp(argv[i], "authenticator") == 0 || - Ustrcmp(argv[i], "macro") == 0 || - Ustrcmp(argv[i], "environment") == 0)) - { - readconf_print(argv[i+1], argv[i], flag_n); - i++; - } - else readconf_print(argv[i], NULL, flag_n); + fail |= !readconf_print(argv[i+1], argv[i], flag_n); + i++; } - exim_exit(EXIT_SUCCESS, US"main"); + else + fail = !readconf_print(argv[i], NULL, flag_n); + } + exim_exit(fail ? EXIT_FAILURE : EXIT_SUCCESS, US"main"); } if (list_config) { set_process_info("listing config"); - readconf_print(US"config", NULL, flag_n); - exim_exit(EXIT_SUCCESS, US"main"); + exim_exit(readconf_print(US"config", NULL, flag_n) + ? EXIT_SUCCESS : EXIT_FAILURE, US"main"); } @@ -4990,7 +5026,7 @@ if (expansion_test) /* Only admin users may see config-file macros this way */ - if (!admin_user) tree_macros = NULL; + if (!admin_user) macros_user = macros = mlast = NULL; /* Allow $recipients for this testing */ @@ -5137,6 +5173,8 @@ if (recipients_arg >= argc && !extract_recipients && !smtp_input) { if (version_printed) { + if (Ustrchr(config_main_filelist, ':')) + printf("Configuration file search path is %s\n", config_main_filelist); printf("Configuration file is %s\n", config_main_filename); return EXIT_SUCCESS; } @@ -5210,7 +5248,7 @@ already been done (which it will have been for inetd). This caters for the case when it is forced by -oMa. However, we must flag that it isn't a socket, so that the test for IP options is skipped for -bs input. */ -if (sender_host_address != NULL && sender_fullhost == NULL) +if (sender_host_address && !sender_fullhost) { host_build_sender_fullhost(); set_process_info("handling incoming connection from %s via -oMa",