commit 9f1a75f126ae217a3a3568b106c9133b3c5c413a Merge: 57318bfd2 89318c714 Author: Jeremy Harris Date: Sun Jun 26 12:10:03 2022 +0100 Merge branch '4.next' diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index 78f5516a7..0c64d45d4 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -1,4 +1,5 @@ # This file is the basis of the main makefile for Exim and friends. The +# # makefile at the top level arranges to build the main makefile by calling # scripts/Configure-Makefile from within the build directory. This # concatenates the configuration settings from Local/Makefile and other, @@ -485,9 +486,9 @@ OBJ_LOOKUPS = lookups/lf_quote.o lookups/lf_check_file.o lookups/lf_sqlperform.o OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \ directory.o dns.o drtables.o enq.o exim.o expand.o filter.o \ filtertest.o globals.o dkim.o dkim_transport.o dnsbl.o hash.o \ - header.o host.o ip.o log.o lss.o match.o md5.o moan.o \ + header.o host.o host_address.o ip.o log.o lss.o match.o md5.o moan.o \ os.o parse.o priv.o queue.o \ - rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \ + rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o regex_cache.o \ route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \ std-crypto.o store.o string.o tls.o tod.o transport.o tree.o verify.o \ environment.o macro.o \ @@ -601,10 +602,11 @@ MONBIN = em_StripChart.o $(EXIMON_TEXTPOP) em_globals.o em_init.o \ # The complete modules list also includes some specially compiled versions of # code from the main Exim source tree. -OBJ_MONBIN = util-spool_in.o \ +OBJ_MONBIN = util-host_address.o \ + util-queue.o \ + util-spool_in.o \ util-store.o \ util-string.o \ - util-queue.o \ util-tod.o \ util-tree.o \ $(MONBIN) @@ -721,6 +723,14 @@ exim_dbmbuild.o: $(HDRS) exim_dbmbuild.c # Utilities use special versions of some modules - typically with debugging # calls cut out. +util-host_address.o: $(HDRS) host_address.c + @echo "$(CC) -DCOMPILE_UTILITY host_address.c" + $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-host_address.o host_address.c + +util-md5.o: $(HDRS) md5.c + @echo "$(CC) -DCOMPILE_UTILITY queue.c" + $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-md5.o md5.c + util-spool_in.o: $(HDRS) spool_in.c @echo "$(CC) -DCOMPILE_UTILITY spool_in.c" $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-spool_in.o spool_in.c @@ -733,10 +743,6 @@ util-string.o: $(HDRS) string.c @echo "$(CC) -DCOMPILE_UTILITY string.c" $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-string.o string.c -util-md5.o: $(HDRS) md5.c - @echo "$(CC) -DCOMPILE_UTILITY queue.c" - $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-md5.o md5.c - util-queue.o: $(HDRS) queue.c @echo "$(CC) -DCOMPILE_UTILITY queue.c" $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -DCOMPILE_UTILITY -o util-queue.o queue.c @@ -787,6 +793,7 @@ globals.o: $(HDRS) globals.c hash.o: $(HDRS) hash.c header.o: $(HDRS) header.c host.o: $(HDRS) host.c +host_address.o: $(HDRS) host_address.c ip.o: $(HDRS) ip.c log.o: $(HDRS) log.c lss.o: $(HDRS) lss.c @@ -802,6 +809,7 @@ readconf.o: $(HDRS) readconf.c receive.o: $(HDRS) receive.c retry.o: $(HDRS) retry.c rewrite.o: $(HDRS) rewrite.c +regex_cache.o: $(HDRS) regex_cache.c rfc2047.o: $(HDRS) rfc2047.c route.o: $(HDRS) route.c search.o: $(HDRS) search.c @@ -962,13 +970,13 @@ test_dbfn: config.h dbfn.c dummies.o sa-globals.o sa-os.o store.o \ rm -f dbfn.o store.o test_host: config.h child.c host.c dns.c dummies.c sa-globals.o os.o \ - store.o string.o tod.o tree.o + host_address.o store.o string.o tod.o tree.o $(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE -DTEST_HOST child.c $(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE -DTEST_HOST host.c $(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE -DTEST_HOST dns.c $(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE -DTEST_HOST dummies.c $(LNCC) -o test_host $(LFLAGS) \ - host.o child.o dns.o dummies.o sa-globals.o os.o store.o string.o \ + host.o host_address.o child.o dns.o dummies.o sa-globals.o os.o store.o string.o \ tod.o tree.o $(LIBS) $(LIBRESOLV) rm -f child.o dummies.o host.o dns.o diff --git a/src/OS/Makefile-FreeBSD b/src/OS/Makefile-FreeBSD index 02253d9c6..4793a438b 100644 --- a/src/OS/Makefile-FreeBSD +++ b/src/OS/Makefile-FreeBSD @@ -13,7 +13,7 @@ PERL_COMMAND=/usr/local/bin/perl HAVE_SA_LEN=YES # crypt() is in a separate library -LIBS=-lcrypt -lm -lutil +LIBS=-lcrypt -lm -lutil -lexecinfo # Dynamically loaded modules need to be built with -fPIC CFLAGS_DYNAMIC=-shared -rdynamic -fPIC diff --git a/src/OS/Makefile-OpenBSD b/src/OS/Makefile-OpenBSD index 697632682..7c451e2cc 100644 --- a/src/OS/Makefile-OpenBSD +++ b/src/OS/Makefile-OpenBSD @@ -23,6 +23,7 @@ EXIWHAT_EGREP_ARG='/exim( |$$)' EXIWHAT_KILL_SIGNAL=-USR1 HAVE_IPV6=YES +CFLAGS += -DNO_EXECINFO # OpenBSD ships with a too-old Berkeley DB. NDBM is the default if we don't specify one. #USE_DB=yes diff --git a/src/OS/Makefile-SunOS5 b/src/OS/Makefile-SunOS5 index 3b436f4bf..d07adcff4 100644 --- a/src/OS/Makefile-SunOS5 +++ b/src/OS/Makefile-SunOS5 @@ -20,5 +20,6 @@ X11LIB=$(X11)/lib OS_C_INCLUDES=setenv.c CFLAGS += -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__ +CFLAGS += -DNO_EXECINFO # End diff --git a/src/exim_monitor/em_main.c b/src/exim_monitor/em_main.c index 5714b999c..86caf71eb 100644 --- a/src/exim_monitor/em_main.c +++ b/src/exim_monitor/em_main.c @@ -179,70 +179,6 @@ va_end(ap); -/************************************************* -* Extract port from address string * -*************************************************/ - -/* In the spool file, a host plus port is given as an IP address followed by a -dot and a port number. This function decodes this. It is needed by the -spool-reading function, and copied here to avoid having to include the whole -host.c module. One day the interaction between exim and eximon with regard to -included code MUST be tidied up! - -Argument: - address points to the string; if there is a port, the '.' in the string - is overwritten with zero to terminate the address - -Returns: 0 if there is no port, else the port number. -*/ - -int -host_address_extract_port(uschar * address) -{ -int port = 0; -uschar *endptr; - -/* Handle the "bracketed with colon on the end" format */ - -if (*address == '[') - { - uschar *rb = address + 1; - while (*rb != 0 && *rb != ']') rb++; - if (*rb++ == 0) return 0; /* Missing ]; leave invalid address */ - if (*rb == ':') - { - port = Ustrtol(rb + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - } - else if (*rb != 0) return 0; /* Bad syntax; leave invalid address */ - memmove(address, address + 1, rb - address - 2); - rb[-2] = 0; - } - -/* Handle the "dot on the end" format */ - -else - { - int skip = -3; /* Skip 3 dots in IPv4 addresses */ - address--; - while (*(++address) != 0) - { - int ch = *address; - if (ch == ':') skip = 0; /* Skip 0 dots in IPv6 addresses */ - else if (ch == '.' && skip++ >= 0) break; - } - if (*address == 0) return 0; - port = Ustrtol(address + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - *address = 0; - } - -return port; -} - - - - /************************************************* * SIGCHLD handler * *************************************************/ diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 9cdb931f3..471b3a369 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -102,9 +102,9 @@ for f in blob.h dbfunctions.h exim.h functions.h globals.h \ acl.c buildconfig.c base64.c child.c crypt16.c daemon.c dbfn.c debug.c \ deliver.c directory.c dns.c dnsbl.c drtables.c dummies.c enq.c exim.c \ exim_dbmbuild.c exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c \ - globals.c hash.c header.c host.c ip.c log.c lss.c match.c md5.c moan.c \ + globals.c hash.c header.c host.c host_address.c ip.c log.c lss.c match.c md5.c moan.c \ parse.c perl.c priv.c queue.c rda.c readconf.c receive.c retry.c rewrite.c \ - rfc2047.c route.c search.c setenv.c environment.c \ + regex_cache.c rfc2047.c route.c search.c setenv.c environment.c \ sieve.c smtp_in.c smtp_out.c spool_in.c spool_out.c std-crypto.c store.c \ string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-cipher-stdname.c \ tls-gnu.c tls-openssl.c \ diff --git a/src/src/acl.c b/src/src/acl.c index fb78a7b5f..0078aca7d 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3125,8 +3125,9 @@ int sep = -'/'; for (; cb; cb = cb->next) { - const uschar *arg; + const uschar * arg; int control_type; + BOOL textonly = FALSE; /* The message and log_message items set up messages to be used in case of rejection. They are expanded later. */ @@ -3160,7 +3161,8 @@ for (; cb; cb = cb->next) if (!conditions[cb->type].expand_at_top) arg = cb->arg; - else if (!(arg = expand_string(cb->arg))) + + else if (!(arg = expand_string_2(cb->arg, &textonly))) { if (f.expand_string_forcedfail) continue; *log_msgptr = string_sprintf("failed to expand ACL string \"%s\": %s", @@ -3217,8 +3219,8 @@ for (; cb; cb = cb->next) switch(cb->type) { case ACLC_ADD_HEADER: - setup_header(arg); - break; + setup_header(arg); + break; /* A nested ACL that returns "discard" makes sense only for an "accept" or "discard" verb. */ @@ -3232,12 +3234,12 @@ for (; cb; cb = cb->next) verbs[verb]); return ERROR; } - break; + break; case ACLC_AUTHENTICATED: rc = sender_host_authenticated ? match_isinlist(sender_host_authenticated, &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL) : FAIL; - break; + break; #ifdef EXPERIMENTAL_BRIGHTMAIL case ACLC_BMI_OPTIN: @@ -3254,21 +3256,21 @@ for (; cb; cb = cb->next) /* The true/false parsing here should be kept in sync with that used in expand.c when dealing with ECOND_BOOL so that we don't have too many different definitions of what can be a boolean. */ - if (*arg == '-' - ? Ustrspn(arg+1, "0123456789") == Ustrlen(arg+1) /* Negative number */ - : Ustrspn(arg, "0123456789") == Ustrlen(arg)) /* Digits, or empty */ - rc = (Uatoi(arg) == 0)? FAIL : OK; - else - rc = (strcmpic(arg, US"no") == 0 || - strcmpic(arg, US"false") == 0)? FAIL : - (strcmpic(arg, US"yes") == 0 || - strcmpic(arg, US"true") == 0)? OK : DEFER; - if (rc == DEFER) - *log_msgptr = string_sprintf("invalid \"condition\" value \"%s\"", arg); - break; + if (*arg == '-' + ? Ustrspn(arg+1, "0123456789") == Ustrlen(arg+1) /* Negative number */ + : Ustrspn(arg, "0123456789") == Ustrlen(arg)) /* Digits, or empty */ + rc = (Uatoi(arg) == 0)? FAIL : OK; + else + rc = (strcmpic(arg, US"no") == 0 || + strcmpic(arg, US"false") == 0)? FAIL : + (strcmpic(arg, US"yes") == 0 || + strcmpic(arg, US"true") == 0)? OK : DEFER; + if (rc == DEFER) + *log_msgptr = string_sprintf("invalid \"condition\" value \"%s\"", arg); + break; case ACLC_CONTINUE: /* Always succeeds */ - break; + break; case ACLC_CONTROL: { @@ -3647,14 +3649,14 @@ for (; cb; cb = cb->next) while ((ss = string_nextinlist(&list, &sep, NULL, 0))) if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER) rc = FAIL; /* FAIL so that the message is passed to the next ACL */ + break; } - break; #endif #ifdef WITH_CONTENT_SCAN case ACLC_DECODE: - rc = mime_decode(&arg); - break; + rc = mime_decode(&arg); + break; #endif case ACLC_DELAY: @@ -3719,44 +3721,44 @@ for (; cb; cb = cb->next) #endif } } + break; } - break; #ifndef DISABLE_DKIM case ACLC_DKIM_SIGNER: - if (dkim_cur_signer) - rc = match_isinlist(dkim_cur_signer, + if (dkim_cur_signer) + rc = match_isinlist(dkim_cur_signer, &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); - else - rc = FAIL; - break; + else + rc = FAIL; + break; case ACLC_DKIM_STATUS: - rc = match_isinlist(dkim_verify_status, - &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); - break; + rc = match_isinlist(dkim_verify_status, + &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); + break; #endif #ifdef SUPPORT_DMARC case ACLC_DMARC_STATUS: - if (!f.dmarc_has_been_checked) - dmarc_process(); - f.dmarc_has_been_checked = TRUE; - /* used long way of dmarc_exim_expand_query() in case we need more - * view into the process in the future. */ - rc = match_isinlist(dmarc_exim_expand_query(DMARC_VERIFY_STATUS), - &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); - break; + if (!f.dmarc_has_been_checked) + dmarc_process(); + f.dmarc_has_been_checked = TRUE; + /* used long way of dmarc_exim_expand_query() in case we need more + * view into the process in the future. */ + rc = match_isinlist(dmarc_exim_expand_query(DMARC_VERIFY_STATUS), + &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); + break; #endif case ACLC_DNSLISTS: - rc = verify_check_dnsbl(where, &arg, log_msgptr); - break; + rc = verify_check_dnsbl(where, &arg, log_msgptr); + break; case ACLC_DOMAINS: - rc = match_isinlist(addr->domain, &arg, 0, &domainlist_anchor, - addr->domain_cache, MCL_DOMAIN, TRUE, CUSS &deliver_domain_data); - break; + rc = match_isinlist(addr->domain, &arg, 0, &domainlist_anchor, + addr->domain_cache, MCL_DOMAIN, TRUE, CUSS &deliver_domain_data); + break; /* The value in tls_cipher is the full cipher name, for example, TLSv1:DES-CBC3-SHA:168, whereas the values to test for are just the @@ -3765,19 +3767,20 @@ for (; cb; cb = cb->next) writing is poorly documented. */ case ACLC_ENCRYPTED: - if (tls_in.cipher == NULL) rc = FAIL; else - { - uschar *endcipher = NULL; - uschar *cipher = Ustrchr(tls_in.cipher, ':'); - if (!cipher) cipher = tls_in.cipher; else - { - endcipher = Ustrchr(++cipher, ':'); - if (endcipher) *endcipher = 0; - } - rc = match_isinlist(cipher, &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); - if (endcipher) *endcipher = ':'; - } - break; + if (!tls_in.cipher) rc = FAIL; + else + { + uschar *endcipher = NULL; + uschar *cipher = Ustrchr(tls_in.cipher, ':'); + if (!cipher) cipher = tls_in.cipher; else + { + endcipher = Ustrchr(++cipher, ':'); + if (endcipher) *endcipher = 0; + } + rc = match_isinlist(cipher, &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL); + if (endcipher) *endcipher = ':'; + } + break; /* Use verify_check_this_host() instead of verify_check_host() so that we can pass over &host_data to catch any looked up data. Once it has been @@ -3787,17 +3790,17 @@ for (; cb; cb = cb->next) message in the same SMTP connection. */ case ACLC_HOSTS: - rc = verify_check_this_host(&arg, sender_host_cache, NULL, - sender_host_address ? sender_host_address : US"", CUSS &host_data); - if (rc == DEFER) *log_msgptr = search_error_message; - if (host_data) host_data = string_copy_perm(host_data, TRUE); - break; + rc = verify_check_this_host(&arg, sender_host_cache, NULL, + sender_host_address ? sender_host_address : US"", CUSS &host_data); + if (rc == DEFER) *log_msgptr = search_error_message; + if (host_data) host_data = string_copy_perm(host_data, TRUE); + break; case ACLC_LOCAL_PARTS: - rc = match_isinlist(addr->cc_local_part, &arg, 0, - &localpartlist_anchor, addr->localpart_cache, MCL_LOCALPART, TRUE, - CUSS &deliver_localpart_data); - break; + rc = match_isinlist(addr->cc_local_part, &arg, 0, + &localpartlist_anchor, addr->localpart_cache, MCL_LOCALPART, TRUE, + CUSS &deliver_localpart_data); + break; case ACLC_LOG_REJECT_TARGET: { @@ -3818,8 +3821,8 @@ for (; cb; cb = cb->next) } } log_reject_target = logbits; + break; } - break; case ACLC_LOGWRITE: { @@ -3850,8 +3853,8 @@ for (; cb; cb = cb->next) if (logbits == 0) logbits = LOG_MAIN; log_write(0, logbits, "%s", string_printing(s)); + break; } - break; #ifdef WITH_CONTENT_SCAN case ACLC_MALWARE: /* Run the malware backend. */ @@ -3874,55 +3877,55 @@ for (; cb; cb = cb->next) return ERROR; } - rc = malware(ss, timeout); + rc = malware(ss, textonly, timeout); if (rc == DEFER && defer_ok) rc = FAIL; /* FAIL so that the message is passed to the next ACL */ + break; } - break; case ACLC_MIME_REGEX: - rc = mime_regex(&arg); - break; + rc = mime_regex(&arg, textonly); + break; #endif case ACLC_QUEUE: - if (is_tainted(arg)) - { - *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted", - arg); - return ERROR; - } - if (Ustrchr(arg, '/')) - { - *log_msgptr = string_sprintf( - "Directory separator not permitted in queue name: '%s'", arg); - return ERROR; - } - queue_name = string_copy_perm(arg, FALSE); - break; + if (is_tainted(arg)) + { + *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted", + arg); + return ERROR; + } + if (Ustrchr(arg, '/')) + { + *log_msgptr = string_sprintf( + "Directory separator not permitted in queue name: '%s'", arg); + return ERROR; + } + queue_name = string_copy_perm(arg, FALSE); + break; case ACLC_RATELIMIT: - rc = acl_ratelimit(arg, where, log_msgptr); - break; + rc = acl_ratelimit(arg, where, log_msgptr); + break; case ACLC_RECIPIENTS: - rc = match_address_list(CUS addr->address, TRUE, TRUE, &arg, NULL, -1, 0, - CUSS &recipient_data); - break; + rc = match_address_list(CUS addr->address, TRUE, TRUE, &arg, NULL, -1, 0, + CUSS &recipient_data); + break; #ifdef WITH_CONTENT_SCAN case ACLC_REGEX: - rc = regex(&arg); - break; + rc = regex(&arg, textonly); + break; #endif case ACLC_REMOVE_HEADER: - setup_remove_header(arg); - break; + setup_remove_header(arg); + break; case ACLC_SEEN: - rc = acl_seen(arg, where, log_msgptr); - break; + rc = acl_seen(arg, where, log_msgptr); + break; case ACLC_SENDER_DOMAINS: { @@ -3931,13 +3934,13 @@ for (; cb; cb = cb->next) sdomain = sdomain ? sdomain + 1 : US""; rc = match_isinlist(sdomain, &arg, 0, &domainlist_anchor, sender_domain_cache, MCL_DOMAIN, TRUE, NULL); + break; } - break; case ACLC_SENDERS: - rc = match_address_list(CUS sender_address, TRUE, TRUE, &arg, - sender_address_cache, -1, 0, CUSS &sender_data); - break; + rc = match_address_list(CUS sender_address, TRUE, TRUE, &arg, + sender_address_cache, -1, 0, CUSS &sender_data); + break; /* Connection variables must persist forever; message variables not */ @@ -3959,8 +3962,8 @@ for (; cb; cb = cb->next) #endif acl_var_create(cb->u.varname)->data.ptr = string_copy(arg); store_pool = old_pool; + break; } - break; #ifdef WITH_CONTENT_SCAN case ACLC_SPAM: @@ -3974,22 +3977,23 @@ for (; cb; cb = cb->next) while ((ss = string_nextinlist(&list, &sep, NULL, 0))) if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER) rc = FAIL; /* FAIL so that the message is passed to the next ACL */ + break; } - break; #endif #ifdef SUPPORT_SPF case ACLC_SPF: rc = spf_process(&arg, sender_address, SPF_PROCESS_NORMAL); - break; + break; + case ACLC_SPF_GUESS: rc = spf_process(&arg, sender_address, SPF_PROCESS_GUESS); - break; + break; #endif case ACLC_UDPSEND: - rc = acl_udpsend(arg, log_msgptr); - break; + rc = acl_udpsend(arg, log_msgptr); + break; /* If the verb is WARN, discard any user message from verification, because such messages are SMTP responses, not header additions. The latter come @@ -3998,16 +4002,16 @@ for (; cb; cb = cb->next) (until something changes it). */ case ACLC_VERIFY: - rc = acl_verify(where, addr, arg, user_msgptr, log_msgptr, basic_errno); - if (*user_msgptr) - acl_verify_message = *user_msgptr; - if (verb == ACL_WARN) *user_msgptr = NULL; - break; + rc = acl_verify(where, addr, arg, user_msgptr, log_msgptr, basic_errno); + if (*user_msgptr) + acl_verify_message = *user_msgptr; + if (verb == ACL_WARN) *user_msgptr = NULL; + break; default: - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "internal ACL error: unknown " - "condition %d", cb->type); - break; + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "internal ACL error: unknown " + "condition %d", cb->type); + break; } /* If a condition was negated, invert OK/FAIL. */ diff --git a/src/src/daemon.c b/src/src/daemon.c index 8e8a515e4..54725e07d 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1132,13 +1132,43 @@ exim_exit(EXIT_SUCCESS); * Listener socket for local work prompts * *************************************************/ +ssize_t +daemon_client_sockname(struct sockaddr_un * sup, uschar ** sname) +{ +#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS +sup->sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ +return offsetof(struct sockaddr_un, sun_path) + 1 + + snprintf(sup->sun_path+1, sizeof(sup->sun_path)-1, "exim_%d", getpid()); +#else +*sname = string_sprintf("%s/p_%d", spool_directory, getpid()); +return offsetof(struct sockaddr_un, sun_path) + + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", sname); +#endif +} + +ssize_t +daemon_notifier_sockname(struct sockaddr_un * sup) +{ +#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS +sup->sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ +return offsetof(struct sockaddr_un, sun_path) + 1 + + snprintf(sup->sun_path+1, sizeof(sup->sun_path)-1, "%s", + expand_string(notifier_socket)); +#else +return offsetof(struct sockaddr_un, sun_path) + + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", + expand_string(notifier_socket)); +#endif +} + + static void daemon_notifier_socket(void) { int fd; const uschar * where; struct sockaddr_un sa_un = {.sun_family = AF_UNIX}; -int len; +ssize_t len; if (!notifier_socket || !*notifier_socket) { @@ -1163,20 +1193,15 @@ if ((fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) (void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); #endif +len = daemon_notifier_sockname(&sa_un); + #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS -sa_un.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ -len = offsetof(struct sockaddr_un, sun_path) + 1 - + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", - expand_string(notifier_socket)); DEBUG(D_any) debug_printf(" @%s\n", sa_un.sun_path+1); #else /* filesystem-visible and persistent; will neeed removal */ -len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", - expand_string(notifier_socket)); DEBUG(D_any) debug_printf(" %s\n", sa_un.sun_path); #endif -if (bind(fd, (const struct sockaddr *)&sa_un, len) < 0) +if (bind(fd, (const struct sockaddr *)&sa_un, (socklen_t)len) < 0) { where = US"bind"; goto bad; } #ifdef SO_PASSCRED /* Linux */ @@ -1205,7 +1230,11 @@ bad: static uschar queuerun_msgid[MESSAGE_ID_LENGTH+1]; -/* Return TRUE if a sigalrm should be emulated */ +/* The notifier socket has something to read. Pull the message from it, decode +and do the action. + +Return TRUE if a sigalrm should be emulated */ + static BOOL daemon_notification(void) { @@ -1255,7 +1284,6 @@ for (struct cmsghdr * cp = CMSG_FIRSTHDR(&msg); { DEBUG(D_queue_run) debug_printf("%s: sender creds pid %d uid %d gid %d\n", __FUNCTION__, (int)cr->pid, (int)cr->uid, (int)cr->gid); - return FALSE; } # elif defined(LOCAL_CREDS) /* BSD-ish */ struct sockcred * cr = (struct sockcred *) CMSG_DATA(cp); @@ -1263,7 +1291,6 @@ for (struct cmsghdr * cp = CMSG_FIRSTHDR(&msg); { DEBUG(D_queue_run) debug_printf("%s: sender creds pid ??? uid %d gid %d\n", __FUNCTION__, (int)cr->sc_uid, (int)cr->sc_gid); - return FALSE; } # endif break; @@ -1294,15 +1321,18 @@ switch (buf[0]) (const struct sockaddr *)&sa_un, msg.msg_namelen) < 0) log_write(0, LOG_MAIN|LOG_PANIC, "%s: sendto: %s\n", __FUNCTION__, strerror(errno)); - return FALSE; + break; } + + case NOTIFY_REGEX: + regex_at_daemon(buf); + break; } return FALSE; } - /************************************************* * Exim Daemon Mainline * *************************************************/ diff --git a/src/src/deliver.c b/src/src/deliver.c index 8a9a174e3..725d0c872 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -7203,7 +7203,7 @@ local and remote LMTP deliveries. */ if (!regex_IGNOREQUOTA) regex_IGNOREQUOTA = - regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE); + regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", MCS_NOFLAGS, TRUE); /* Handle local deliveries */ diff --git a/src/src/dns.c b/src/src/dns.c index 7d7ee0c04..4071c5822 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -1324,7 +1324,7 @@ dns_pattern_init(void) { if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names) regex_check_dns_names = - regex_must_compile(check_dns_names_pattern, FALSE, TRUE); + regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE); } /* vi: aw ai sw=2 diff --git a/src/src/drtables.c b/src/src/drtables.c index 513ef6c4a..b2f2a4b33 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -728,8 +728,8 @@ if (!(dd = exim_opendir(LOOKUP_MODULE_DIR))) } else { - const pcre2_code *regex_islookupmod = regex_must_compile( - US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE); + const pcre2_code * regex_islookupmod = regex_must_compile( + US"\\." DYNLIB_FN_EXT "$", MCS_NOFLAGS, TRUE); DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR); while ((ent = readdir(dd))) diff --git a/src/src/exim.c b/src/src/exim.c index fd01d1355..dec8de4b4 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -17,6 +17,13 @@ Also a few functions that don't naturally fit elsewhere. */ # include #endif +#ifndef _TIME_H +# include +#endif +#ifndef NO_EXECINFO +# include +#endif + #ifdef USE_GNUTLS # include # if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP) @@ -24,10 +31,6 @@ Also a few functions that don't naturally fit elsewhere. */ # endif #endif -#ifndef _TIME_H -# include -#endif - extern void init_lookup_list(void); @@ -56,78 +59,40 @@ if (block) store_free(block); } +static void * +function_store_get(PCRE2_SIZE size, void * tag) +{ +return store_get((int)size, GET_UNTAINTED); /* loses track of taint */ +} - -/************************************************* -* Enums for cmdline interface * -*************************************************/ - -enum commandline_info { CMDINFO_NONE=0, - CMDINFO_HELP, CMDINFO_SIEVE, CMDINFO_DSCP }; +static void +function_store_nullfree(void * block, void * tag) +{ +} /************************************************* -* Compile regular expression and panic on fail * +* Enums for cmdline interface * *************************************************/ -/* This function is called when failure to compile a regular expression leads -to a panic exit. In other cases, pcre_compile() is called directly. In many -cases where this function is used, the results of the compilation are to be -placed in long-lived store, so we temporarily reset the store management -functions that PCRE uses if the use_malloc flag is set. - -Argument: - pattern the pattern to compile - caseless TRUE if caseless matching is required - use_malloc TRUE if compile into malloc store - -Returns: pointer to the compiled pattern -*/ - -const pcre2_code * -regex_must_compile(const uschar * pattern, BOOL caseless, BOOL use_malloc) -{ -size_t offset; -int options = caseless ? PCRE_COPT|PCRE2_CASELESS : PCRE_COPT; -const pcre2_code * yield; -int err; -pcre2_general_context * gctx; -pcre2_compile_context * cctx; - -if (use_malloc) - { - gctx = pcre2_general_context_create(function_store_malloc, function_store_free, NULL); - cctx = pcre2_compile_context_create(gctx); - } -else - cctx = pcre_cmp_ctx; +enum commandline_info { CMDINFO_NONE=0, + CMDINFO_HELP, CMDINFO_SIEVE, CMDINFO_DSCP }; -if (!(yield = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, - &err, &offset, cctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "regular expression error: " - "%s at offset %ld while compiling %s", errbuf, (long)offset, pattern); - } -if (use_malloc) - { - pcre2_compile_context_free(cctx); - pcre2_general_context_free(gctx); - } -return yield; -} static void pcre_init(void) { -pcre_gen_ctx = pcre2_general_context_create(function_store_malloc, function_store_free, NULL); -pcre_cmp_ctx = pcre2_compile_context_create(pcre_gen_ctx); -pcre_mtc_ctx = pcre2_match_context_create(pcre_gen_ctx); +pcre_mlc_ctx = pcre2_general_context_create(function_store_malloc, function_store_free, NULL); +pcre_gen_ctx = pcre2_general_context_create(function_store_get, function_store_nullfree, NULL); + +pcre_mlc_cmp_ctx = pcre2_compile_context_create(pcre_mlc_ctx); +pcre_gen_cmp_ctx = pcre2_compile_context_create(pcre_gen_ctx); + +pcre_gen_mtc_ctx = pcre2_match_context_create(pcre_gen_ctx); } @@ -157,7 +122,7 @@ regex_match_and_setup(const pcre2_code * re, const uschar * subject, int options { pcre2_match_data * md = pcre2_match_data_create_from_pattern(re, pcre_gen_ctx); int res = pcre2_match(re, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0, - PCRE_EOPT | options, md, pcre_mtc_ctx); + PCRE_EOPT | options, md, pcre_gen_mtc_ctx); BOOL yield; if ((yield = (res >= 0))) @@ -179,7 +144,7 @@ else if (res != PCRE2_ERROR_NOMATCH) DEBUG(D_any) pcre2_get_error_message(res, errbuf, sizeof(errbuf)); debug_printf_indent("pcre2: %s\n", errbuf); } -pcre2_match_data_free(md); +/* pcre2_match_data_free(md); gen ctx needs no free */ return yield; } @@ -201,13 +166,18 @@ regex_match(const pcre2_code * re, const uschar * subject, int slen, uschar ** r pcre2_match_data * md = pcre2_match_data_create(1, pcre_gen_ctx); int rc = pcre2_match(re, (PCRE2_SPTR)subject, slen >= 0 ? slen : PCRE2_ZERO_TERMINATED, - 0, PCRE_EOPT, md, pcre_mtc_ctx); + 0, PCRE_EOPT, md, pcre_gen_mtc_ctx); PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); -if (rc < 0) - return FALSE; -if (rptr) - *rptr = string_copyn(subject + ovec[0], ovec[1] - ovec[0]); -return TRUE; +BOOL ret = FALSE; + +if (rc >= 0) + { + if (rptr) + *rptr = string_copyn(subject + ovec[0], ovec[1] - ovec[0]); + ret = TRUE; + } +/* pcre2_match_data_free(md); gen ctx needs no free */ +return ret; } @@ -261,6 +231,31 @@ exit(1); * Handler for SIGSEGV * ***********************************************/ +#define STACKDUMP_MAX 24 +static void +stackdump(void) +{ +#ifndef NO_EXECINFO +void * buf[STACKDUMP_MAX]; +char ** ss; +int nptrs = backtrace(buf, STACKDUMP_MAX); + +log_write(0, LOG_MAIN|LOG_PANIC, "backtrace\n"); +log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); +if ((ss = backtrace_symbols(buf, nptrs))) + { + for (int i = 0; i < nptrs; i++) + log_write(0, LOG_MAIN|LOG_PANIC, "\t%s\n", ss[i]); + free(ss); + } +else + log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s\n", strerror(errno)); +log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); +#endif +} +#undef STACKDUMP_MAX + + static void #ifdef SA_SIGINFO segv_handler(int sig, siginfo_t * info, void * uctx) @@ -281,6 +276,7 @@ else log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)"); if (process_info_len > 0) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info); +stackdump(); signal(SIGSEGV, SIG_DFL); kill(getpid(), sig); } @@ -291,6 +287,7 @@ segv_handler(int sig) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)"); if (process_info_len > 0) log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info); +stackdump(); signal(SIGSEGV, SIG_DFL); kill(getpid(), sig); } @@ -1983,7 +1980,7 @@ this here, because the -M options check their arguments for syntactic validity using mac_ismsgid, which uses this. */ regex_ismsgid = - regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", FALSE, TRUE); + regex_must_compile(US"^(?:[^\\W_]{6}-){2}[^\\W_]{2}$", MCS_NOFLAGS, TRUE); /* Precompile the regular expression that is used for matching an SMTP error code, possibly extended, at the start of an error message. Note that the @@ -1991,14 +1988,14 @@ terminating whitespace character is included. */ regex_smtp_code = regex_must_compile(US"^\\d\\d\\d\\s(?:\\d\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\s)?", - FALSE, TRUE); + MCS_NOFLAGS, TRUE); #ifdef WHITELIST_D_MACROS /* Precompile the regular expression used to filter the content of macros given to -D for permissibility. */ regex_whitelisted_macro = - regex_must_compile(US"^[A-Za-z0-9_/.-]*$", FALSE, TRUE); + regex_must_compile(US"^[A-Za-z0-9_/.-]*$", MCS_NOFLAGS, TRUE); #endif for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; @@ -2216,7 +2213,7 @@ on the second character (the one after '-'), to save some effort. */ -bdf: Ditto, but in the foreground. */ case 'd': - f.daemon_listen = TRUE; + f.daemon_listen = f.daemon_scion = TRUE; if (*argrest == 'f') f.background_daemon = FALSE; else if (*argrest) badarg = TRUE; break; @@ -2476,7 +2473,7 @@ on the second character (the one after '-'), to save some effort. */ case 'w': f.inetd_wait_mode = TRUE; f.background_daemon = FALSE; - f.daemon_listen = TRUE; + f.daemon_listen = f.daemon_scion = TRUE; if (*argrest) if ((inetd_wait_timeout = readconf_readtime(argrest, 0, FALSE)) <= 0) exim_fail("exim: bad time value %s: abandoned\n", argv[i]); @@ -5003,7 +5000,7 @@ for (i = 0;;) if (gecos_pattern && gecos_name) { const pcre2_code *re; - re = regex_must_compile(gecos_pattern, FALSE, TRUE); /* Use malloc */ + re = regex_must_compile(gecos_pattern, MCS_NOFLAGS, TRUE); /* Use malloc */ if (regex_match_and_setup(re, name, 0, -1)) { @@ -5399,7 +5396,10 @@ if (host_checking) memset(sender_host_cache, 0, sizeof(sender_host_cache)); if (verify_check_host(&hosts_connection_nolog) == OK) + { BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection); + BIT_CLEAR(log_selector, log_selector_size, Li_smtp_no_mail); + } log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info()); /* NOTE: We do *not* call smtp_log_no_mail() if smtp_start_session() fails, @@ -5588,7 +5588,10 @@ if (smtp_input) smtp_out = stdout; memset(sender_host_cache, 0, sizeof(sender_host_cache)); if (verify_check_host(&hosts_connection_nolog) == OK) + { BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection); + BIT_CLEAR(log_selector, log_selector_size, Li_smtp_no_mail); + } log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info()); if (!smtp_start_session()) { diff --git a/src/src/expand.c b/src/src/expand.c index 36c9f423b..ffbdc14e5 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -12,9 +12,15 @@ #include "exim.h" +typedef unsigned esi_flags; +#define ESI_NOFLAGS 0 +#define ESI_BRACE_ENDS BIT(0) /* expansion should stop at } */ +#define ESI_HONOR_DOLLAR BIT(1) /* $ is meaningfull */ +#define ESI_SKIPPING BIT(2) /* value will not be needed */ + /* Recursively called function */ -static uschar *expand_string_internal(const uschar *, BOOL, const uschar **, BOOL, BOOL, BOOL *); +static uschar *expand_string_internal(const uschar *, esi_flags, const uschar **, BOOL *, BOOL *); static int_eximarith_t expanded_string_integer(const uschar *, BOOL); #ifdef STAND_ALONE @@ -686,6 +692,7 @@ static var_entry var_table[] = { { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, { "recipients", vtype_string_func, (void *) &fn_recipients }, { "recipients_count", vtype_int, &recipients_count }, + { "regex_cachesize", vtype_int, ®ex_cachesize },/* undocumented; devel observability */ #ifdef WITH_CONTENT_SCAN { "regex_match_string", vtype_stringptr, ®ex_match_string }, #endif @@ -1748,9 +1755,7 @@ uschar buf[16]; int fd; ssize_t len; const uschar * where; -#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS uschar * sname; -#endif if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { @@ -1758,17 +1763,9 @@ if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) return NULL; } -#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS -sa_un.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ -len = offsetof(struct sockaddr_un, sun_path) + 1 - + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "exim_%d", getpid()); -#else -sname = string_sprintf("%s/p_%d", spool_directory, getpid()); -len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", sname); -#endif +len = daemon_client_sockname(&sa_un, &sname); -if (bind(fd, (const struct sockaddr *)&sa_un, len) < 0) +if (bind(fd, (const struct sockaddr *)&sa_un, (socklen_t)len) < 0) { where = US"bind"; goto bad; } #ifdef notdef @@ -1777,17 +1774,7 @@ debug_printf("local addr '%s%s'\n", sa_un.sun_path + (*sa_un.sun_path ? 0 : 1)); #endif -#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS -sa_un.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ -len = offsetof(struct sockaddr_un, sun_path) + 1 - + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", - expand_string(notifier_socket)); -#else -len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", - expand_string(notifier_socket)); -#endif - +len = daemon_notifier_sockname(&sa_un); if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0) { where = US"connect"; goto bad2; } @@ -2114,27 +2101,33 @@ Arguments: n maximum number of substrings m minimum required sptr points to current string pointer - skipping the skipping flag + flags + skipping the skipping flag check_end if TRUE, check for final '}' name name of item, for error message resetok if not NULL, pointer to flag - write FALSE if unsafe to reset - the store. + the store + textonly_p if not NULL, pointer to bitmask of which subs were text-only + (did not change when expended) -Returns: 0 OK; string pointer updated +Returns: -1 OK; string pointer updated, but in "skipping" mode + 0 OK; string pointer updated 1 curly bracketing error (too few arguments) 2 too many arguments (only if check_end is set); message set 3 other error (expansion failure) */ static int -read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping, - BOOL check_end, uschar *name, BOOL *resetok) +read_subs(uschar ** sub, int n, int m, const uschar ** sptr, esi_flags flags, + BOOL check_end, uschar * name, BOOL * resetok, unsigned * textonly_p) { -const uschar *s = *sptr; +const uschar * s = *sptr; +unsigned textonly_l = 0; Uskip_whitespace(&s); for (int i = 0; i < n; i++) { + BOOL textonly; if (*s != '{') { if (i < m) @@ -2146,11 +2139,14 @@ for (int i = 0; i < n; i++) sub[i] = NULL; break; } - if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, resetok))) + if (!(sub[i] = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags & ESI_SKIPPING, &s, resetok, + textonly_p ? &textonly : NULL))) return 3; if (*s++ != '}') return 1; + if (textonly_p && textonly) textonly_l |= BIT(i); Uskip_whitespace(&s); - } + } /*{*/ if (check_end && *s++ != '}') { if (s[-1] == '{') @@ -2163,8 +2159,9 @@ if (check_end && *s++ != '}') return 1; } +if (textonly_p) *textonly_p = textonly_l; *sptr = s; -return 0; +return flags & ESI_SKIPPING ? -1 : 0; } @@ -2523,11 +2520,11 @@ Returns: a pointer to the first character after the condition, or */ static const uschar * -eval_condition(const uschar *s, BOOL *resetok, BOOL *yield) +eval_condition(const uschar * s, BOOL * resetok, BOOL * yield) { BOOL testfor = TRUE; BOOL tempcond, combined_cond; -BOOL *subcondptr; +BOOL * subcondptr; BOOL sub2_honour_dollar = TRUE; BOOL is_forany, is_json, is_jsons; int rc, cond_type; @@ -2535,7 +2532,8 @@ int_eximarith_t num[2]; struct stat statbuf; uschar * opname; uschar name[256]; -const uschar *sub[10]; +const uschar * sub[10]; +unsigned sub_textonly = 0; for (;;) if (Uskip_whitespace(&s) == '!') { testfor = !testfor; s++; } else break; @@ -2629,8 +2627,14 @@ switch(cond_type = identify_operator(&s, &opname)) if (Uskip_whitespace(&s) != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ - sub[0] = expand_string_internal(s+1, TRUE, &s, yield == NULL, TRUE, resetok); - if (!sub[0]) return NULL; + { + BOOL textonly; + sub[0] = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | (yield ? ESI_NOFLAGS : ESI_SKIPPING), + &s, resetok, &textonly); + if (!sub[0]) return NULL; + if (textonly) sub_textonly |= BIT(0); + } /* {-for-text-editors */ if (*s++ != '}') goto COND_FAILED_CURLY_END; @@ -2727,8 +2731,8 @@ switch(cond_type = identify_operator(&s, &opname)) Uskip_whitespace(&s); if (*s++ != '{') goto COND_FAILED_CURLY_START; /*}*/ - switch(read_subs(sub, nelem(sub), 1, - &s, yield == NULL, TRUE, name, resetok)) + switch(read_subs(sub, nelem(sub), 1, &s, + yield ? ESI_NOFLAGS : ESI_SKIPPING, TRUE, name, resetok, NULL)) { case 1: expand_string_message = US"too few arguments or bracketing " "error for acl"; @@ -2779,8 +2783,8 @@ switch(cond_type = identify_operator(&s, &opname)) uschar *sub[4]; Uskip_whitespace(&s); if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ - switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, name, - resetok)) + switch(read_subs(sub, nelem(sub), 2, &s, + yield ? ESI_NOFLAGS : ESI_SKIPPING, TRUE, name, resetok, NULL)) { case 1: expand_string_message = US"too few arguments or bracketing " "error for saslauthd"; @@ -2848,12 +2852,16 @@ switch(cond_type = identify_operator(&s, &opname)) for (int i = 0; i < 2; i++) { + BOOL textonly; /* Sometimes, we don't expand substrings; too many insecure configurations created using match_address{}{} and friends, where the second param includes information from untrustworthy sources. */ - BOOL honour_dollar = TRUE; - if ((i > 0) && !sub2_honour_dollar) - honour_dollar = FALSE; + /*XXX is this moot given taint-tracking? */ + + esi_flags flags = ESI_BRACE_ENDS; + + if (!(i > 0 && !sub2_honour_dollar)) flags |= ESI_HONOR_DOLLAR; + if (!yield) flags |= ESI_SKIPPING; if (Uskip_whitespace(&s) != '{') { @@ -2862,9 +2870,9 @@ switch(cond_type = identify_operator(&s, &opname)) "after \"%s\"", opname); return NULL; } - if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL, - honour_dollar, resetok))) + if (!(sub[i] = expand_string_internal(s+1, flags, &s, resetok, &textonly))) return NULL; + if (textonly) sub_textonly |= BIT(i); DEBUG(D_expand) if (i == 1 && !sub2_honour_dollar && Ustrchr(sub[1], '$')) debug_printf_indent("WARNING: the second arg is NOT expanded," " for security reasons\n"); @@ -2944,19 +2952,11 @@ switch(cond_type = identify_operator(&s, &opname)) case ECOND_MATCH: /* Regular expression match */ { - const pcre2_code * re; - PCRE2_SIZE offset; - int err; - - if (!(re = pcre2_compile((PCRE2_SPTR)sub[1], PCRE2_ZERO_TERMINATED, - PCRE_COPT, &err, &offset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - expand_string_message = string_sprintf("regular expression error in " - "\"%s\": %s at offset %ld", sub[1], errbuf, (long)offset); + const pcre2_code * re = regex_compile(sub[1], + sub_textonly & BIT(1) ? MCS_CACHEABLE : MCS_NOFLAGS, + &expand_string_message, pcre_gen_cmp_ctx); + if (!re) return NULL; - } tempcond = regex_match_and_setup(re, sub[0], 0, -1); break; @@ -3274,7 +3274,9 @@ switch(cond_type = identify_operator(&s, &opname)) Uskip_whitespace(&s); if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ - if (!(sub[0] = expand_string_internal(s, TRUE, &s, yield == NULL, TRUE, resetok))) + if (!(sub[0] = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | (yield ? ESI_NOFLAGS : ESI_SKIPPING), + &s, resetok, NULL))) return NULL; /* {-for-text-editors */ if (*s++ != '}') goto COND_FAILED_CURLY_END; @@ -3362,7 +3364,8 @@ switch(cond_type = identify_operator(&s, &opname)) if (Uskip_whitespace(&s) != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */ ourname = cond_type == ECOND_BOOL_LAX ? US"bool_lax" : US"bool"; - switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, ourname, resetok)) + switch(read_subs(sub_arg, 1, 1, &s, + yield ? ESI_NOFLAGS : ESI_SKIPPING, FALSE, ourname, resetok, NULL)) { case 1: expand_string_message = string_sprintf( "too few arguments or bracketing error for %s", @@ -3430,7 +3433,8 @@ switch(cond_type = identify_operator(&s, &opname)) uschar cksum[4]; BOOL boolvalue = FALSE; - switch(read_subs(sub, 2, 2, CUSS &s, yield == NULL, FALSE, name, resetok)) + switch(read_subs(sub, 2, 2, CUSS &s, + yield ? ESI_NOFLAGS : ESI_SKIPPING, FALSE, name, resetok, NULL)) { case 1: expand_string_message = US"too few arguments or bracketing " "error for inbound_srs"; @@ -3441,10 +3445,10 @@ switch(cond_type = identify_operator(&s, &opname)) /* Match the given local_part against the SRS-encoded pattern */ re = regex_must_compile(US"^(?i)SRS0=([^=]+)=([A-Z2-7]+)=([^=]*)=(.*)$", - TRUE, FALSE); + MCS_CASELESS | MCS_CACHEABLE, FALSE); md = pcre2_match_data_create(4+1, pcre_gen_ctx); if (pcre2_match(re, sub[0], PCRE2_ZERO_TERMINATED, 0, PCRE_EOPT, - md, pcre_mtc_ctx) < 0) + md, pcre_gen_mtc_ctx) < 0) { DEBUG(D_expand) debug_printf("no match for SRS'd local-part pattern\n"); goto srs_result; @@ -3521,6 +3525,7 @@ switch(cond_type = identify_operator(&s, &opname)) boolvalue = TRUE; srs_result: + /* pcre2_match_data_free(md); gen ctx needs no free */ if (yield) *yield = (boolvalue == testfor); return s; } @@ -3628,7 +3633,8 @@ expanded, to check their syntax, but "skipping" is set when the result is not needed - this avoids unnecessary nested lookups. Arguments: - skipping TRUE if we were skipping when this item was reached + flags + skipping TRUE if we were skipping when this item was reached yes TRUE if the first string is to be used, else use the second save_lookup a value to put back into lookup_value before the 2nd expansion sptr points to the input string pointer @@ -3644,7 +3650,7 @@ Returns: 0 OK; lookup_value has been reset to save_lookup */ static int -process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, const uschar **sptr, +process_yesno(esi_flags flags, BOOL yes, uschar *save_lookup, const uschar **sptr, gstring ** yieldptr, uschar *type, BOOL *resetok) { int rc = 0; @@ -3652,6 +3658,8 @@ const uschar *s = *sptr; /* Local value */ uschar *sub1, *sub2; const uschar * errwhere; +flags &= ESI_SKIPPING; /* Ignore all buf the skipping flag */ + /* If there are no following strings, we substitute the contents of $value for lookups and for extractions in the success case. For the ${if item, the string "true" is substituted. In the fail case, nothing is substituted for all three @@ -3661,12 +3669,12 @@ if (skip_whitespace(&s) == '}') { if (type[0] == 'i') { - if (yes && !skipping) + if (yes && !(flags & ESI_SKIPPING)) *yieldptr = string_catn(*yieldptr, US"true", 4); } else { - if (yes && lookup_value && !skipping) + if (yes && lookup_value && !(flags & ESI_SKIPPING)) *yieldptr = string_cat(*yieldptr, lookup_value); lookup_value = save_lookup; } @@ -3678,7 +3686,7 @@ if (skip_whitespace(&s) == '}') if (*s++ != '{') { - errwhere = US"'yes' part did not start with '{'"; + errwhere = US"'yes' part did not start with '{'"; /*}}*/ goto FAILED_CURLY; } @@ -3686,9 +3694,12 @@ if (*s++ != '{') want this string. Set skipping in the call in the fail case (this will always be the case if we were already skipping). */ -sub1 = expand_string_internal(s, TRUE, &s, !yes, TRUE, resetok); +sub1 = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | (yes ? ESI_NOFLAGS : ESI_SKIPPING), + &s, resetok, NULL); if (sub1 == NULL && (yes || !f.expand_string_forcedfail)) goto FAILED; f.expand_string_forcedfail = FALSE; + /*{{*/ if (*s++ != '}') { errwhere = US"'yes' part did not end with '}'"; @@ -3713,14 +3724,16 @@ time, forced failures are noticed only if we want the second string. We must set skipping in the nested call if we don't want this string, or if we were already skipping. */ -if (skip_whitespace(&s) == '{') +if (skip_whitespace(&s) == '{') /*}*/ { - sub2 = expand_string_internal(s+1, TRUE, &s, yes || skipping, TRUE, resetok); - if (sub2 == NULL && (!yes || !f.expand_string_forcedfail)) goto FAILED; - f.expand_string_forcedfail = FALSE; + esi_flags s_flags = ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags; + if (yes) s_flags |= ESI_SKIPPING; + sub2 = expand_string_internal(s+1, s_flags, &s, resetok, NULL); + if (!sub2 && (!yes || !f.expand_string_forcedfail)) goto FAILED; + f.expand_string_forcedfail = FALSE; /*{*/ if (*s++ != '}') { - errwhere = US"'no' part did not start with '{'"; + errwhere = US"'no' part did not start with '{'"; /*}*/ goto FAILED_CURLY; } @@ -3729,7 +3742,7 @@ if (skip_whitespace(&s) == '{') if (!yes) *yieldptr = string_cat(*yieldptr, sub2); } - + /*{{*/ /* If there is no second string, but the word "fail" is present when the use of the second string is wanted, set a flag indicating it was a forced failure rather than a syntactic error. Swallow the terminating } in case this is nested @@ -3742,9 +3755,9 @@ else if (*s != '}') s = US read_name(name, sizeof(name), s, US"_"); if (Ustrcmp(name, "fail") == 0) { - if (!yes && !skipping) + if (!yes && !(flags & ESI_SKIPPING)) { - Uskip_whitespace(&s); + Uskip_whitespace(&s); /*{{*/ if (*s++ != '}') { errwhere = US"did not close with '}' after forcedfail"; @@ -3766,7 +3779,7 @@ else if (*s != '}') /* All we have to do now is to check on the final closing brace. */ -skip_whitespace(&s); +skip_whitespace(&s); /*{{*/ if (*s++ != '}') { errwhere = US"did not close with '}'"; @@ -4445,15 +4458,17 @@ string expansion becoming too powerful. Arguments: string the string to be expanded - ket_ends true if expansion is to stop at } + flags + brace_ends expansion is to stop at } + honour_dollar TRUE if $ is to be expanded, + FALSE if it's just another character + skipping TRUE for recursive calls when the value isn't actually going + to be used (to allow for optimisation) left if not NULL, a pointer to the first character after the - expansion is placed here (typically used with ket_ends) - skipping TRUE for recursive calls when the value isn't actually going - to be used (to allow for optimisation) - honour_dollar TRUE if $ is to be expanded, - FALSE if it's just another character + expansion is placed here (typically used with brace_ends) resetok_p if not NULL, pointer to flag - write FALSE if unsafe to reset the store. + textonly_p if not NULL, pointer to flag - write bool for only-met-text Returns: NULL if expansion fails: expand_string_forcedfail is set TRUE if failure was forced @@ -4462,8 +4477,8 @@ Returns: NULL if expansion fails: */ static uschar * -expand_string_internal(const uschar *string, BOOL ket_ends, const uschar **left, - BOOL skipping, BOOL honour_dollar, BOOL *resetok_p) +expand_string_internal(const uschar * string, esi_flags flags, const uschar ** left, + BOOL *resetok_p, BOOL * textonly_p) { rmark reset_point = store_mark(); gstring * yield = string_get(Ustrlen(string) + 64); @@ -4471,7 +4486,7 @@ int item_type; const uschar * s = string; const uschar * save_expand_nstring[EXPAND_MAXN+1]; int save_expand_nlength[EXPAND_MAXN+1]; -BOOL resetok = TRUE, first = TRUE; +BOOL resetok = TRUE, first = TRUE, textonly = TRUE; expand_level++; f.expand_string_forcedfail = FALSE; @@ -4494,11 +4509,11 @@ while (*s) DEBUG(D_noutf8) debug_printf_indent("%c%s: %s\n", first ? '/' : '|', - skipping ? "---scanning" : "considering", s); + flags & ESI_SKIPPING ? "---scanning" : "considering", s); else debug_printf_indent("%s%s: %s\n", first ? UTF8_DOWN_RIGHT : UTF8_VERT_RIGHT, - skipping + flags & ESI_SKIPPING ? UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ "scanning" : "considering", s); @@ -4524,7 +4539,7 @@ while (*s) for (s = t; *s ; s++) if (*s == '\\' && s[1] == 'N') break; DEBUG(D_expand) - debug_expansion_interim(US"protected", t, (int)(s - t), skipping); + debug_expansion_interim(US"protected", t, (int)(s - t), !!(flags & ESI_SKIPPING)); yield = string_catn(yield, t, s - t); if (*s) s += 2; } @@ -4547,20 +4562,21 @@ while (*s) /* Anything other than $ is just copied verbatim, unless we are looking for a terminating } character. */ - if (ket_ends && *s == '}') break; + if (flags & ESI_BRACE_ENDS && *s == '}') break; - if (*s != '$' || !honour_dollar) + if (*s != '$' || !(flags & ESI_HONOR_DOLLAR)) { int i = 1; /*{*/ for (const uschar * t = s+1; *t && *t != '$' && *t != '}' && *t != '\\'; t++) i++; - DEBUG(D_expand) debug_expansion_interim(US"text", s, i, skipping); + DEBUG(D_expand) debug_expansion_interim(US"text", s, i, !!(flags & ESI_SKIPPING)); yield = string_catn(yield, s, i); s += i; continue; } + textonly = FALSE; /* No { after the $ - must be a plain name or a number for string match variable. There has to be a fudge for variables that are the @@ -4622,7 +4638,7 @@ while (*s) /* Variable */ - else if (!(value = find_variable(name, FALSE, skipping, &newsize))) + else if (!(value = find_variable(name, FALSE, !!(flags & ESI_SKIPPING), &newsize))) { expand_string_message = string_sprintf("unknown variable name \"%s\"", name); @@ -4722,14 +4738,13 @@ while (*s) uschar * user_msg; int rc; - switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, name, - &resetok)) + switch(read_subs(sub, nelem(sub), 1, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - if (skipping) continue; resetok = FALSE; switch(rc = eval_acl(sub, nelem(sub), &user_msg)) @@ -4758,13 +4773,13 @@ while (*s) { uschar * sub_arg[1]; - switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name, - &resetok)) + switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, flags, TRUE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } + /*XXX no skipping-optimisation? */ yield = string_append(yield, 3, US"Authentication-Results: ", sub_arg[0], US"; none"); @@ -4802,14 +4817,14 @@ while (*s) uschar * save_lookup_value = lookup_value; Uskip_whitespace(&s); - if (!(next_s = eval_condition(s, &resetok, skipping ? NULL : &cond))) + if (!(next_s = eval_condition(s, &resetok, flags & ESI_SKIPPING ? NULL : &cond))) goto EXPAND_FAILED; /* message already set */ DEBUG(D_expand) { - debug_expansion_interim(US"condition", s, (int)(next_s - s), skipping); + debug_expansion_interim(US"condition", s, (int)(next_s - s), !!(flags & ESI_SKIPPING)); debug_expansion_interim(US"result", - cond ? US"true" : US"false", cond ? 4 : 5, skipping); + cond ? US"true" : US"false", cond ? 4 : 5, !!(flags & ESI_SKIPPING)); } s = next_s; @@ -4818,12 +4833,12 @@ while (*s) function that is also used by ${lookup} and ${extract} and ${run}. */ switch(process_yesno( - skipping, /* were previously skipping */ - cond, /* success/failure indicator */ - lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"if", /* condition type */ + flags, /* were previously skipping */ + cond, /* success/failure indicator */ + lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"if", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ @@ -4845,13 +4860,13 @@ while (*s) uschar *sub_arg[3]; uschar *encoded; - switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name, - &resetok)) + switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, flags, TRUE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } + /*XXX no skipping-optimisation? */ if (!sub_arg[1]) /* One argument */ { @@ -4867,7 +4882,7 @@ while (*s) goto EXPAND_FAILED; } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; if (!(encoded = imap_utf7_encode(sub_arg[0], headers_charset, sub_arg[1][0], sub_arg[2], &expand_string_message))) @@ -4906,7 +4921,8 @@ while (*s) if (Uskip_whitespace(&s) == '{') /*}*/ { - key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + key = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!key) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -4976,7 +4992,8 @@ while (*s) expand_string_message = US"missing '{' for lookup file-or-query arg"; goto EXPAND_FAILED_CURLY; /*}}*/ } - if (!(filename = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))) + if (!(filename = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL))) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') @@ -5007,7 +5024,7 @@ while (*s) since new variables will have been set. Note that at the end of this "lookup" section, the old numeric variables are restored. */ - if (skipping) + if (flags & ESI_SKIPPING) lookup_value = NULL; else { @@ -5033,12 +5050,12 @@ while (*s) function that is also used by ${if} and ${extract}. */ switch(process_yesno( - skipping, /* were previously skipping */ - lookup_value != NULL, /* success/failure indicator */ - save_lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"lookup", /* condition type */ + flags, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"lookup", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ @@ -5051,7 +5068,7 @@ while (*s) restore_expand_strings(save_expand_nmax, save_expand_nstring, save_expand_nlength); - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -5079,18 +5096,15 @@ while (*s) goto EXPAND_FAILED; } - switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, skipping, TRUE, - name, &resetok)) + switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, flags, TRUE, + name, &resetok, NULL)) { + case -1: continue; /* If skipping, we don't actually do anything */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /* If skipping, we don't actually do anything */ - - if (skipping) continue; - /* Start the interpreter if necessary */ if (!opt_perl_started) @@ -5150,16 +5164,14 @@ while (*s) { uschar * sub_arg[3], * p, * domain; - switch(read_subs(sub_arg, 3, 2, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub_arg, 3, 2, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* If skipping, we don't actually do anything */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /* If skipping, we don't actually do anything */ - if (skipping) continue; - /* sub_arg[0] is the address */ if ( !(domain = Ustrrchr(sub_arg[0],'@')) || domain == sub_arg[0] || Ustrlen(domain) == 1) @@ -5208,30 +5220,21 @@ while (*s) gstring * g; const pcre2_code * re; - /* TF: Ugliness: We want to expand parameter 1 first, then set - up expansion variables that are used in the expansion of - parameter 2. So we clone the string for the first - expansion, where we only expand parameter 1. - - PH: Actually, that isn't necessary. The read_subs() function is - designed to work this way for the ${if and ${lookup expansions. I've - tidied the code. - */ /*}}*/ - /* Reset expansion variables */ prvscheck_result = NULL; prvscheck_address = NULL; prvscheck_keynum = NULL; - switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok)) + switch(read_subs(sub_arg, 1, 1, &s, flags, FALSE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - re = regex_must_compile(US"^prvs\\=([0-9])([0-9]{3})([A-F0-9]{6})\\=(.+)\\@(.+)$", - TRUE,FALSE); + re = regex_must_compile( + US"^prvs\\=([0-9])([0-9]{3})([A-F0-9]{6})\\=(.+)\\@(.+)$", + MCS_CASELESS | MCS_CACHEABLE, FALSE); if (regex_match_and_setup(re,sub_arg[0],0,-1)) { @@ -5241,11 +5244,14 @@ while (*s) uschar * hash = string_copyn(expand_nstring[3],expand_nlength[3]); uschar * domain = string_copyn(expand_nstring[5],expand_nlength[5]); - DEBUG(D_expand) debug_printf_indent("prvscheck localpart: %s\n", local_part); - DEBUG(D_expand) debug_printf_indent("prvscheck key number: %s\n", key_num); - DEBUG(D_expand) debug_printf_indent("prvscheck daystamp: %s\n", daystamp); - DEBUG(D_expand) debug_printf_indent("prvscheck hash: %s\n", hash); - DEBUG(D_expand) debug_printf_indent("prvscheck domain: %s\n", domain); + DEBUG(D_expand) + { + debug_printf_indent("prvscheck localpart: %s\n", local_part); + debug_printf_indent("prvscheck key number: %s\n", key_num); + debug_printf_indent("prvscheck daystamp: %s\n", daystamp); + debug_printf_indent("prvscheck hash: %s\n", hash); + debug_printf_indent("prvscheck domain: %s\n", domain); + } /* Set up expansion variables */ g = string_cat (NULL, local_part); @@ -5255,7 +5261,7 @@ while (*s) prvscheck_keynum = string_copy(key_num); /* Now expand the second argument */ - switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok)) + switch(read_subs(sub_arg, 1, 1, &s, flags, FALSE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -5266,7 +5272,6 @@ while (*s) p = prvs_hmac_sha1(prvscheck_address, sub_arg[0], prvscheck_keynum, daystamp); - if (!p) { expand_string_message = US"hmac-sha1 conversion failed"; @@ -5309,7 +5314,7 @@ while (*s) /* Now expand the final argument. We leave this till now so that it can include $prvscheck_result. */ - switch(read_subs(sub_arg, 1, 0, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub_arg, 1, 0, &s, flags, TRUE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -5330,14 +5335,14 @@ while (*s) We need to make sure all subs are expanded first, so as to skip over the entire item. */ - switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub_arg, 2, 1, &s, flags, TRUE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -5354,7 +5359,7 @@ while (*s) goto EXPAND_FAILED; } - switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub_arg, 2, 1, &s, flags, TRUE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: @@ -5363,7 +5368,7 @@ while (*s) /* If skipping, we don't actually do anything */ - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; /* Open the file and read it */ @@ -5395,7 +5400,7 @@ while (*s) /* Read up to 4 arguments, but don't do the end of item check afterwards, because there may be a string for expansion on failure. */ - switch(read_subs(sub_arg, 4, 2, &s, skipping, FALSE, name, &resetok)) + switch(read_subs(sub_arg, 4, 2, &s, flags, FALSE, name, &resetok, NULL)) { case 1: goto EXPAND_FAILED_CURLY; case 2: /* Won't occur: no end check */ @@ -5405,7 +5410,7 @@ while (*s) /* If skipping, we don't actually do anything. Otherwise, arrange to connect to either an IP or a Unix socket. */ - if (!skipping) + if (!(flags & ESI_SKIPPING)) { int stype = search_findtype(US"readsock", 8); gstring * g = NULL; @@ -5483,7 +5488,8 @@ while (*s) if (*s == '{') /*}*/ { - if (!expand_string_internal(s+1, TRUE, &s, TRUE, TRUE, &resetok)) + if (!expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &s, &resetok, NULL)) goto EXPAND_FAILED; /*{*/ if (*s++ != '}') { /*{*/ @@ -5499,7 +5505,7 @@ while (*s) expand_string_message = US"missing '}' closing readsocket"; goto EXPAND_FAILED_CURLY; } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; /* Come here on failure to create socket, connect socket, write to the @@ -5509,7 +5515,8 @@ while (*s) SOCK_FAIL: if (*s != '{') goto EXPAND_FAILED; /*}*/ DEBUG(D_any) debug_printf("%s\n", expand_string_message); - if (!(arg = expand_string_internal(s+1, TRUE, &s, FALSE, TRUE, &resetok))) + if (!(arg = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR, &s, &resetok, NULL))) goto EXPAND_FAILED; yield = string_cat(yield, arg); /*{*/ if (*s++ != '}') @@ -5560,14 +5567,15 @@ while (*s) s++; if (late_expand) /* this is the default case */ - { + { /*{*/ int n = Ustrcspn(s, "}"); - arg = skipping ? NULL : string_copyn(s, n); + arg = flags & ESI_SKIPPING ? NULL : string_copyn(s, n); s += n; } else { - if (!(arg = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok))) + if (!(arg = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL))) goto EXPAND_FAILED; Uskip_whitespace(&s); } @@ -5578,7 +5586,7 @@ while (*s) goto EXPAND_FAILED_CURLY; } - if (skipping) /* Just pretend it worked when we're skipping */ + if (flags & ESI_SKIPPING) /* Just pretend it worked when we're skipping */ { runrc = 0; lookup_value = NULL; @@ -5652,19 +5660,19 @@ while (*s) /* Process the yes/no strings; $value may be useful in both cases */ switch(process_yesno( - skipping, /* were previously skipping */ - runrc == 0, /* success/failure indicator */ - lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"run", /* condition type */ + flags, /* were previously skipping */ + runrc == 0, /* success/failure indicator */ + lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"run", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */ } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -5676,8 +5684,9 @@ while (*s) int o2m; uschar * sub[3]; - switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub, 3, 3, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; @@ -5696,7 +5705,6 @@ while (*s) } } - if (skipping) continue; break; } @@ -5717,9 +5725,10 @@ while (*s) Ensure that sub[2] is set in the ${length } case. */ sub[2] = NULL; - switch(read_subs(sub, (item_type == EITEM_LENGTH)? 2:3, 2, &s, skipping, - TRUE, name, &resetok)) + switch(read_subs(sub, item_type == EITEM_LENGTH ? 2:3, 2, &s, flags, + TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; @@ -5760,7 +5769,6 @@ while (*s) if (!ret) goto EXPAND_FAILED; yield = string_catn(yield, ret, len); - if (skipping) continue; break; } @@ -5793,15 +5801,14 @@ while (*s) uschar innerkey[MAX_HASHBLOCKLEN]; uschar outerkey[MAX_HASHBLOCKLEN]; - switch (read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok)) + switch (read_subs(sub, 3, 3, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - if (skipping) continue; - if (Ustrcmp(sub[0], "md5") == 0) { type = HMAC_MD5; @@ -5881,32 +5888,29 @@ while (*s) { const pcre2_code * re; int moffset, moffsetextra, slen; - PCRE2_SIZE roffset; pcre2_match_data * md; - int err, emptyopt; + int emptyopt; uschar * subject, * sub[3]; int save_expand_nmax = save_expand_strings(save_expand_nstring, save_expand_nlength); + unsigned sub_textonly = 0; - switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub, 3, 3, &s, flags, TRUE, name, &resetok, &sub_textonly)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /*XXX no handling of skipping? */ /* Compile the regular expression */ - if (!(re = pcre2_compile((PCRE2_SPTR)sub[1], PCRE2_ZERO_TERMINATED, - PCRE_COPT, &err, &roffset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - expand_string_message = string_sprintf("regular expression error in " - "\"%s\": %s at offset %ld", sub[1], errbuf, (long)roffset); + re = regex_compile(sub[1], + sub_textonly & BIT(1) ? MCS_CACHEABLE : MCS_NOFLAGS, + &expand_string_message, pcre_gen_cmp_ctx); + if (!re) goto EXPAND_FAILED; - } + md = pcre2_match_data_create(EXPAND_MAXN + 1, pcre_gen_ctx); /* Now run a loop to do the substitutions as often as necessary. It ends @@ -5922,7 +5926,7 @@ while (*s) { PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); int n = pcre2_match(re, (PCRE2_SPTR)subject, slen, moffset + moffsetextra, - PCRE_EOPT | emptyopt, md, pcre_mtc_ctx); + PCRE_EOPT | emptyopt, md, pcre_gen_mtc_ctx); uschar * insert; /* No match - if we previously set PCRE_NOTEMPTY after a null match, this @@ -5984,9 +5988,9 @@ while (*s) /* All done - restore numerical variables. */ + /* pcre2_match_data_free(md); gen ctx needs no free */ restore_expand_strings(save_expand_nmax, save_expand_nstring, save_expand_nlength); - if (skipping) continue; break; } @@ -6021,11 +6025,12 @@ while (*s) available (eg. $item) hence cannot decide on numeric vs. keyed. Read a maximum of 5 arguments (including the yes/no) */ - if (skipping) + if (flags & ESI_SKIPPING) { for (int j = 5; j > 0 && *s == '{'; j--) /*'}'*/ { - if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok)) + if (!expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL)) goto EXPAND_FAILED; /*'{'*/ if (*s++ != '}') { @@ -6052,7 +6057,8 @@ while (*s) { if (Uskip_whitespace(&s) == '{') /*'}'*/ { - if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))) + if (!(sub[i] = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL))) goto EXPAND_FAILED; /*'{'*/ if (*s++ != '}') { @@ -6111,7 +6117,7 @@ while (*s) /* Extract either the numbered or the keyed substring into $value. If skipping, just pretend the extraction failed. */ - if (skipping) + if (flags & ESI_SKIPPING) lookup_value = NULL; else switch (fmt) { @@ -6205,12 +6211,12 @@ while (*s) be yes/no strings, as for lookup or if. */ switch(process_yesno( - skipping, /* were previously skipping */ - lookup_value != NULL, /* success/failure indicator */ - save_lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"extract", /* condition type */ + flags, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"extract", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ @@ -6222,7 +6228,7 @@ while (*s) restore_expand_strings(save_expand_nmax, save_expand_nstring, save_expand_nlength); - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -6246,7 +6252,8 @@ while (*s) goto EXPAND_FAILED_CURLY; } - sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + sub[i] = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!sub[i]) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6271,7 +6278,7 @@ while (*s) while (len > 0 && isspace(p[len-1])) len--; p[len] = 0; - if (!*p && !skipping) + if (!*p && !(flags & ESI_SKIPPING)) { expand_string_message = US"first argument of \"listextract\" must " "not be empty"; @@ -6297,18 +6304,18 @@ while (*s) /* Extract the numbered element into $value. If skipping, just pretend the extraction failed. */ - lookup_value = skipping ? NULL : expand_getlistele(field_number, sub[1]); + lookup_value = flags & ESI_SKIPPING ? NULL : expand_getlistele(field_number, sub[1]); /* If no string follows, $value gets substituted; otherwise there can be yes/no strings, as for lookup or if. */ switch(process_yesno( - skipping, /* were previously skipping */ - lookup_value != NULL, /* success/failure indicator */ - save_lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"listextract", /* condition type */ + flags, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"listextract", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ @@ -6320,15 +6327,16 @@ while (*s) restore_expand_strings(save_expand_nmax, save_expand_nstring, save_expand_nlength); - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } case EITEM_LISTQUOTE: { uschar * sub[2]; - switch(read_subs(sub, 2, 2, &s, skipping, TRUE, name, &resetok)) + switch(read_subs(sub, 2, 2, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; @@ -6339,7 +6347,6 @@ while (*s) yield = string_catn(yield, sub[1], 1); } else yield = string_catn(yield, US" ", 1); - if (skipping) continue; break; } @@ -6356,7 +6363,8 @@ while (*s) expand_string_message = US"missing '{' for field arg of certextract"; goto EXPAND_FAILED_CURLY; /*}*/ } - sub[0] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + sub[0] = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!sub[0]) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6388,7 +6396,8 @@ while (*s) "be a certificate variable"; goto EXPAND_FAILED; } - sub[1] = expand_string_internal(s+1, TRUE, &s, skipping, FALSE, &resetok); + sub[1] = expand_string_internal(s+1, + ESI_BRACE_ENDS | flags & ESI_SKIPPING, &s, &resetok, NULL); if (!sub[1]) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6396,7 +6405,7 @@ while (*s) goto EXPAND_FAILED_CURLY; } - if (skipping) + if (flags & ESI_SKIPPING) lookup_value = NULL; else { @@ -6404,12 +6413,12 @@ while (*s) if (*expand_string_message) goto EXPAND_FAILED; } switch(process_yesno( - skipping, /* were previously skipping */ - lookup_value != NULL, /* success/failure indicator */ - save_lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"certextract", /* condition type */ + flags, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"certextract", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ @@ -6418,7 +6427,7 @@ while (*s) restore_expand_strings(save_expand_nmax, save_expand_nstring, save_expand_nlength); - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } #endif /*DISABLE_TLS*/ @@ -6443,7 +6452,8 @@ while (*s) goto EXPAND_FAILED_CURLY; /*}*/ } - if (!(list = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok))) + if (!(list = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL))) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6461,7 +6471,8 @@ while (*s) expand_string_message = US"missing '{' for second arg of reduce"; goto EXPAND_FAILED_CURLY; /*}*/ } - t = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok); + t = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!t) goto EXPAND_FAILED; lookup_value = t; /*{{*/ if (*s++ != '}') @@ -6488,7 +6499,8 @@ while (*s) the normal internal expansion function. */ if (item_type != EITEM_FILTER) - temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok); + temp = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &s, &resetok, NULL); else if ((temp = eval_condition(expr, &resetok, NULL))) s = temp; @@ -6519,7 +6531,7 @@ while (*s) /* If we are skipping, we can now just move on to the next item. When processing for real, we perform the iteration. */ - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0))) { *outsep = (uschar)sep; /* Separator as a string */ @@ -6550,7 +6562,8 @@ while (*s) else { - uschar * t = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok); + uschar * t = expand_string_internal(expr, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, NULL, &resetok, NULL); temp = t; if (!temp) { @@ -6622,7 +6635,7 @@ while (*s) /* Restore preserved $item */ iterate_item = save_iterate_item; - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -6641,7 +6654,8 @@ while (*s) goto EXPAND_FAILED_CURLY; /*}*/ } - srclist = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok); + srclist = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!srclist) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6656,7 +6670,8 @@ while (*s) goto EXPAND_FAILED_CURLY; /*}*/ } - cmp = expand_string_internal(s, TRUE, &s, skipping, FALSE, &resetok); + cmp = expand_string_internal(s, + ESI_BRACE_ENDS | flags & ESI_SKIPPING, &s, &resetok, NULL); if (!cmp) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6691,7 +6706,8 @@ while (*s) } xtract = s; - if (!(tmp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok))) + if (!(tmp = expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &s, &resetok, NULL))) goto EXPAND_FAILED; xtract = string_copyn(xtract, s - xtract); /*{{*/ @@ -6707,7 +6723,7 @@ while (*s) goto EXPAND_FAILED; } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; while ((srcitem = string_nextinlist(&srclist, &sep, NULL, 0))) { @@ -6718,8 +6734,8 @@ while (*s) /* extract field for comparisons */ iterate_item = srcitem; - if ( !(srcfield = expand_string_internal(xtract, FALSE, NULL, FALSE, - TRUE, &resetok)) + if ( !(srcfield = expand_string_internal(xtract, + ESI_HONOR_DOLLAR, NULL, &resetok, NULL)) || !*srcfield) { expand_string_message = string_sprintf( @@ -6824,18 +6840,15 @@ while (*s) goto EXPAND_FAILED; } - switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping, - TRUE, name, &resetok)) + switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, flags, + TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /* If skipping, we don't actually do anything */ - - if (skipping) continue; - /* Look up the dynamically loaded object handle in the tree. If it isn't found, dlopen() the file and put the handle in the tree for next time. */ @@ -6901,7 +6914,8 @@ while (*s) if (Uskip_whitespace(&s) != '{') /*}*/ goto EXPAND_FAILED; - key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + key = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!key) goto EXPAND_FAILED; /*{{*/ if (*s++ != '}') { @@ -6912,18 +6926,18 @@ while (*s) lookup_value = US getenv(CS key); switch(process_yesno( - skipping, /* were previously skipping */ - lookup_value != NULL, /* success/failure indicator */ - save_lookup_value, /* value to reset for string2 */ - &s, /* input pointer */ - &yield, /* output pointer */ - US"env", /* condition type */ + flags, /* were previously skipping */ + lookup_value != NULL, /* success/failure indicator */ + save_lookup_value, /* value to reset for string2 */ + &s, /* input pointer */ + &yield, /* output pointer */ + US"env", /* condition type */ &resetok)) { case 1: goto EXPAND_FAILED; /* when all is well, the */ case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */ } - if (skipping) continue; + if (flags & ESI_SKIPPING) continue; break; } @@ -6936,13 +6950,13 @@ while (*s) gstring * g = NULL; BOOL quoted = FALSE; - switch (read_subs(sub, 3, 3, CUSS &s, skipping, TRUE, name, &resetok)) + switch (read_subs(sub, 3, 3, CUSS &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* skipping */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - if (skipping) continue; if (sub[1] && *(sub[1])) { @@ -7024,7 +7038,7 @@ while (*s) DEBUG(D_expand) if (yield && (start > 0 || *s)) /* only if not the sole expansion of the line */ debug_expansion_interim(US"item-res", - yield->s + start, yield->ptr - start, skipping); + yield->s + start, yield->ptr - start, !!(flags & ESI_SKIPPING)); continue; NOT_ITEM: ; @@ -7070,8 +7084,8 @@ NOT_ITEM: ; if (s[1] == '$') { const uschar * s1 = s; - sub = expand_string_internal(s+2, TRUE, &s1, skipping, - FALSE, &resetok); + sub = expand_string_internal(s+2, + ESI_BRACE_ENDS | flags & ESI_SKIPPING, &s1, &resetok, NULL); if (!sub) goto EXPAND_FAILED; /*{*/ if (*s1 != '}') { /*{*/ @@ -7089,7 +7103,8 @@ NOT_ITEM: ; /*FALLTHROUGH*/ #endif default: - sub = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok); + sub = expand_string_internal(s+1, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL); if (!sub) goto EXPAND_FAILED; s++; break; @@ -7101,7 +7116,7 @@ NOT_ITEM: ; for the existence of $sender_host_address before trying to mask it. For other operations, doing them may not fail, but it is a waste of time. */ - if (skipping && c >= 0) continue; + if (flags & ESI_SKIPPING && c >= 0) continue; /* Otherwise, switch on the operator type. After handling go back to the main loop top. */ @@ -7186,7 +7201,8 @@ NOT_ITEM: ; case EOP_EXPAND: { - uschar *expanded = expand_string_internal(sub, FALSE, NULL, skipping, TRUE, &resetok); + uschar *expanded = expand_string_internal(sub, + ESI_HONOR_DOLLAR | flags & ESI_SKIPPING, NULL, &resetok, NULL); if (!expanded) { expand_string_message = @@ -8177,7 +8193,7 @@ NOT_ITEM: ; debug_printf_indent("|-----op-res: %.*s\n", i, s); if (tainted) { - debug_printf_indent("%s \\__", skipping ? "| " : " "); + debug_printf_indent("%s \\__", flags & ESI_SKIPPING ? "| " : " "); debug_print_taint(yield->s); } } @@ -8189,7 +8205,7 @@ NOT_ITEM: ; if (tainted) { debug_printf_indent("%s", - skipping + flags & ESI_SKIPPING ? UTF8_VERT " " : " " UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ); debug_print_taint(yield->s); } @@ -8223,7 +8239,7 @@ NOT_ITEM: ; reset_point = store_mark(); g = store_get(sizeof(gstring), GET_UNTAINTED); /* alloc _before_ calling find_variable() */ } - if (!(value = find_variable(name, FALSE, skipping, &newsize))) + if (!(value = find_variable(name, FALSE, !!(flags & ESI_SKIPPING), &newsize))) { expand_string_message = string_sprintf("unknown variable in \"${%s}\"", name); @@ -8251,11 +8267,11 @@ NOT_ITEM: ; goto EXPAND_FAILED; } -/* If we hit the end of the string when ket_ends is set, there is a missing +/* If we hit the end of the string when brace_ends is set, there is a missing terminating brace. */ -if (ket_ends && !*s) - { +if (flags & ESI_BRACE_ENDS && !*s) + { /*{{*/ expand_string_message = malformed_header ? US"missing } at end of string - could be header name not terminated by colon" : US"missing } at end of string"; @@ -8285,13 +8301,13 @@ DEBUG(D_expand) { debug_printf_indent("|--expanding: %.*s\n", (int)(s - string), string); debug_printf_indent("%sresult: %s\n", - skipping ? "|-----" : "\\_____", yield->s); + flags & ESI_SKIPPING ? "|-----" : "\\_____", yield->s); if (tainted) { - debug_printf_indent("%s \\__", skipping ? "| " : " "); + debug_printf_indent("%s \\__", flags & ESI_SKIPPING ? "| " : " "); debug_print_taint(yield->s); } - if (skipping) + if (flags & ESI_SKIPPING) debug_printf_indent("\\___skipping: result is not used\n"); } else @@ -8301,20 +8317,21 @@ DEBUG(D_expand) (int)(s - string), string); debug_printf_indent("%s" UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ "result: %s\n", - skipping ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT, + flags & ESI_SKIPPING ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT, yield->s); if (tainted) { debug_printf_indent("%s", - skipping + flags & ESI_SKIPPING ? UTF8_VERT " " : " " UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ); debug_print_taint(yield->s); } - if (skipping) + if (flags & ESI_SKIPPING) debug_printf_indent(UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ "skipping: result is not used\n"); } } +if (textonly_p) *textonly_p = textonly; expand_level--; return yield->s; @@ -8363,16 +8380,20 @@ return NULL; } + /* This is the external function call. Do a quick check for any expansion metacharacters, and if there are none, just return the input string. -Argument: the string to be expanded +Arguments + the string to be expanded + optional pointer for return boolean indicating no-dynamic-expansions + Returns: the expanded string, or NULL if expansion failed; if failure was due to a lookup deferring, search_find_defer will be TRUE */ const uschar * -expand_cstring(const uschar * string) +expand_string_2(const uschar * string, BOOL * textonly_p) { if (Ustrpbrk(string, "$\\") != NULL) { @@ -8382,19 +8403,22 @@ if (Ustrpbrk(string, "$\\") != NULL) f.search_find_defer = FALSE; malformed_header = FALSE; store_pool = POOL_MAIN; - s = expand_string_internal(string, FALSE, NULL, FALSE, TRUE, NULL); + s = expand_string_internal(string, ESI_HONOR_DOLLAR, NULL, NULL, textonly_p); store_pool = old_pool; return s; } +if (textonly_p) *textonly_p = TRUE; return string; } +const uschar * +expand_cstring(const uschar * string) +{ return expand_string_2(string, NULL); } uschar * expand_string(uschar * string) -{ -return US expand_cstring(CUS string); -} +{ return US expand_string_2(CUS string, NULL); } + diff --git a/src/src/filter.c b/src/src/filter.c index ad017e567..cc4af230e 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -1424,213 +1424,203 @@ Returns: TRUE if the condition is met */ static BOOL -test_condition(condition_block *c, BOOL toplevel) +test_condition(condition_block * c, BOOL toplevel) { -BOOL yield = FALSE; -const uschar *exp[2], * p, * pp; +BOOL yield = FALSE, textonly_re; +const uschar * exp[2], * p, * pp; int val[2]; -int i; -if (c == NULL) return TRUE; /* does this ever occur? */ +if (!c) return TRUE; /* does this ever occur? */ switch (c->type) { case cond_and: - yield = test_condition(c->left.c, FALSE) && - *error_pointer == NULL && - test_condition(c->right.c, FALSE); - break; + yield = test_condition(c->left.c, FALSE) && + *error_pointer == NULL && + test_condition(c->right.c, FALSE); + break; case cond_or: - yield = test_condition(c->left.c, FALSE) || - (*error_pointer == NULL && - test_condition(c->right.c, FALSE)); - break; + yield = test_condition(c->left.c, FALSE) || + (*error_pointer == NULL && + test_condition(c->right.c, FALSE)); + break; - /* The personal test is meaningless in a system filter. The tests are now in - a separate function (so Sieve can use them). However, an Exim filter does not - scan Cc: (hence the FALSE argument). */ + /* The personal test is meaningless in a system filter. The tests are now in + a separate function (so Sieve can use them). However, an Exim filter does not + scan Cc: (hence the FALSE argument). */ case cond_personal: - yield = f.system_filtering? FALSE : filter_personal(c->left.a, FALSE); - break; + yield = f.system_filtering? FALSE : filter_personal(c->left.a, FALSE); + break; case cond_delivered: - yield = filter_delivered; - break; + yield = filter_delivered; + break; - /* Only TRUE if a message is actually being processed; FALSE for address - testing and verification. */ + /* Only TRUE if a message is actually being processed; FALSE for address + testing and verification. */ case cond_errormsg: - yield = message_id[0] != 0 && - (sender_address == NULL || sender_address[0] == 0); - break; + yield = message_id[0] != 0 && + (sender_address == NULL || sender_address[0] == 0); + break; - /* Only FALSE if a message is actually being processed; TRUE for address - and filter testing and verification. */ + /* Only FALSE if a message is actually being processed; TRUE for address + and filter testing and verification. */ case cond_firsttime: - yield = filter_test != FTEST_NONE || message_id[0] == 0 || f.deliver_firsttime; - break; + yield = filter_test != FTEST_NONE || message_id[0] == 0 || f.deliver_firsttime; + break; - /* Only TRUE if a message is actually being processed; FALSE for address - testing and verification. */ + /* Only TRUE if a message is actually being processed; FALSE for address + testing and verification. */ case cond_manualthaw: - yield = message_id[0] != 0 && f.deliver_manual_thaw; - break; + yield = message_id[0] != 0 && f.deliver_manual_thaw; + break; - /* The foranyaddress condition loops through a list of addresses */ + /* The foranyaddress condition loops through a list of addresses */ case cond_foranyaddress: - p = c->left.u; - if (!(pp = expand_cstring(p))) - { - *error_pointer = string_sprintf("failed to expand \"%s\" in " - "filter file: %s", p, expand_string_message); - return FALSE; - } + p = c->left.u; + if (!(pp = expand_cstring(p))) + { + *error_pointer = string_sprintf("failed to expand \"%s\" in " + "filter file: %s", p, expand_string_message); + return FALSE; + } - yield = FALSE; - f.parse_allow_group = TRUE; /* Allow group syntax */ + yield = FALSE; + f.parse_allow_group = TRUE; /* Allow group syntax */ - while (*pp) - { - uschar *error; - int start, end, domain; - uschar * s; + while (*pp) + { + uschar *error; + int start, end, domain; + uschar * s; - p = parse_find_address_end(pp, FALSE); - s = string_copyn(pp, p - pp); + p = parse_find_address_end(pp, FALSE); + s = string_copyn(pp, p - pp); - filter_thisaddress = - parse_extract_address(s, &error, &start, &end, &domain, FALSE); + filter_thisaddress = + parse_extract_address(s, &error, &start, &end, &domain, FALSE); - if (filter_thisaddress) - { - if ((filter_test != FTEST_NONE && debug_selector != 0) || - (debug_selector & D_filter) != 0) - { - indent(); - debug_printf_indent("Extracted address %s\n", filter_thisaddress); - } - yield = test_condition(c->right.c, FALSE); - } + if (filter_thisaddress) + { + if ((filter_test != FTEST_NONE && debug_selector != 0) || + (debug_selector & D_filter) != 0) + { + indent(); + debug_printf_indent("Extracted address %s\n", filter_thisaddress); + } + yield = test_condition(c->right.c, FALSE); + } - if (yield) break; - if (!*p) break; - pp = p + 1; - } + if (yield) break; + if (!*p) break; + pp = p + 1; + } - f.parse_allow_group = FALSE; /* Reset group syntax flags */ - f.parse_found_group = FALSE; - break; + f.parse_allow_group = FALSE; /* Reset group syntax flags */ + f.parse_found_group = FALSE; + break; - /* All other conditions have left and right values that need expanding; - on error, it doesn't matter what value is returned. */ + /* All other conditions have left and right values that need expanding; + on error, it doesn't matter what value is returned. */ - default: - p = c->left.u; - for (i = 0; i < 2; i++) - { - if (!(exp[i] = expand_cstring(p))) + default: + p = c->left.u; + for (int i = 0; i < 2; i++) { - *error_pointer = string_sprintf("failed to expand \"%s\" in " - "filter file: %s", p, expand_string_message); - return FALSE; + if (!(exp[i] = expand_string_2(p, &textonly_re))) + { + *error_pointer = string_sprintf("failed to expand \"%s\" in " + "filter file: %s", p, expand_string_message); + return FALSE; + } + p = c->right.u; } - p = c->right.u; - } - /* Inner switch for the different cases */ - - switch(c->type) - { - case cond_is: - yield = strcmpic(exp[0], exp[1]) == 0; - break; + /* Inner switch for the different cases */ - case cond_IS: - yield = Ustrcmp(exp[0], exp[1]) == 0; - break; - - case cond_contains: - yield = strstric_c(exp[0], exp[1], FALSE) != NULL; - break; + switch(c->type) + { + case cond_is: + yield = strcmpic(exp[0], exp[1]) == 0; + break; - case cond_CONTAINS: - yield = Ustrstr(exp[0], exp[1]) != NULL; - break; + case cond_IS: + yield = Ustrcmp(exp[0], exp[1]) == 0; + break; - case cond_begins: - yield = strncmpic(exp[0], exp[1], Ustrlen(exp[1])) == 0; - break; + case cond_contains: + yield = strstric_c(exp[0], exp[1], FALSE) != NULL; + break; - case cond_BEGINS: - yield = Ustrncmp(exp[0], exp[1], Ustrlen(exp[1])) == 0; - break; + case cond_CONTAINS: + yield = Ustrstr(exp[0], exp[1]) != NULL; + break; - case cond_ends: - case cond_ENDS: - { - int len = Ustrlen(exp[1]); - const uschar *s = exp[0] + Ustrlen(exp[0]) - len; - yield = s < exp[0] - ? FALSE - : (c->type == cond_ends ? strcmpic(s, exp[1]) : Ustrcmp(s, exp[1])) == 0; - } - break; + case cond_begins: + yield = strncmpic(exp[0], exp[1], Ustrlen(exp[1])) == 0; + break; - case cond_matches: - case cond_MATCHES: - { - const pcre2_code *re; - int err; - PCRE2_SIZE offset; + case cond_BEGINS: + yield = Ustrncmp(exp[0], exp[1], Ustrlen(exp[1])) == 0; + break; - if ((filter_test != FTEST_NONE && debug_selector != 0) || - (debug_selector & D_filter) != 0) + case cond_ends: + case cond_ENDS: { - debug_printf_indent("Match expanded arguments:\n"); - debug_printf_indent(" Subject = %s\n", exp[0]); - debug_printf_indent(" Pattern = %s\n", exp[1]); + int len = Ustrlen(exp[1]); + const uschar *s = exp[0] + Ustrlen(exp[0]) - len; + yield = s < exp[0] + ? FALSE + : (c->type == cond_ends ? strcmpic(s, exp[1]) : Ustrcmp(s, exp[1])) == 0; + break; } - if (!(re = pcre2_compile((PCRE2_SPTR)exp[1], PCRE2_ZERO_TERMINATED, - PCRE_COPT | (c->type == cond_matches ? PCRE2_CASELESS : 0), - &err, &offset, pcre_cmp_ctx))) + case cond_matches: + case cond_MATCHES: { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - *error_pointer = string_sprintf("error while compiling " - "regular expression \"%s\": %s at offset %ld", - exp[1], errbuf, (long)offset); - return FALSE; - } + const pcre2_code * re; + mcs_flags flags = textonly_re ? MCS_CACHEABLE : MCS_NOFLAGS; - yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1); - break; - } + if ((filter_test != FTEST_NONE && debug_selector != 0) || + (debug_selector & D_filter) != 0) + { + debug_printf_indent("Match expanded arguments:\n"); + debug_printf_indent(" Subject = %s\n", exp[0]); + debug_printf_indent(" Pattern = %s\n", exp[1]); + } - /* For above and below, convert the strings to numbers */ + if (c->type == cond_matches) flags |= MCS_CASELESS; + if (!(re = regex_compile(exp[1], flags, error_pointer, pcre_gen_cmp_ctx))) + return FALSE; - case cond_above: - case cond_below: - for (i = 0; i < 2; i++) - { - val[i] = get_number(exp[i], &yield); - if (!yield) - { - *error_pointer = string_sprintf("malformed numerical string \"%s\"", - exp[i]); - return FALSE; - } + yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1); + break; + } + + /* For above and below, convert the strings to numbers */ + + case cond_above: + case cond_below: + for (int i = 0; i < 2; i++) + { + val[i] = get_number(exp[i], &yield); + if (!yield) + { + *error_pointer = string_sprintf("malformed numerical string \"%s\"", + exp[i]); + return FALSE; + } + } + yield = c->type == cond_above ? (val[0] > val[1]) : (val[0] < val[1]); + break; } - yield = (c->type == cond_above)? (val[0] > val[1]) : (val[0] < val[1]); break; - } - break; } if ((filter_test != FTEST_NONE && debug_selector != 0) || @@ -2356,7 +2346,7 @@ while (commands) commands = commands->next; } -return filter_delivered? FF_DELIVERED : FF_NOTDELIVERED; +return filter_delivered ? FF_DELIVERED : FF_NOTDELIVERED; } diff --git a/src/src/functions.h b/src/src/functions.h index 224666cb1..4caae346d 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -182,6 +182,10 @@ extern BOOL cutthrough_predata(void); extern void release_cutthrough_connection(const uschar *); extern void daemon_go(void); +#ifndef COMPILE_UTILITY +extern ssize_t daemon_client_sockname(struct sockaddr_un *, uschar **); +extern ssize_t daemon_notifier_sockname(struct sockaddr_un *); +#endif #ifdef EXPERIMENTAL_DCC extern int dcc_process(uschar **); @@ -260,6 +264,7 @@ extern int exp_bool(address_item *addr, extern BOOL expand_check_condition(uschar *, uschar *, uschar *); extern uschar *expand_file_big_buffer(const uschar *); extern uschar *expand_string(uschar *); /* public, cannot make const */ +extern const uschar *expand_string_2(const uschar *, BOOL *); extern const uschar *expand_cstring(const uschar *); /* ... so use this one */ extern uschar *expand_getkeyed(const uschar *, const uschar *); @@ -332,7 +337,7 @@ extern BOOL macro_read_assignment(uschar *); extern uschar *macros_expand(int, int *, BOOL *); extern void mainlog_close(void); #ifdef WITH_CONTENT_SCAN -extern int malware(const uschar *, int); +extern int malware(const uschar *, BOOL, int); extern int malware_in_file(uschar *); extern void malware_init(void); extern gstring * malware_show_supported(gstring *); @@ -345,7 +350,7 @@ extern int match_check_list(const uschar **, int, tree_node **, unsigned int const uschar *, const uschar **); extern int match_isinlist(const uschar *, const uschar **, int, tree_node **, unsigned int *, int, BOOL, const uschar **); -extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL, +extern int match_check_string(const uschar *, const uschar *, int, mcs_flags, const uschar **); extern void message_start(void); @@ -360,7 +365,7 @@ extern int mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *, uschar **, uschar **); extern int mime_decode(const uschar **); extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *); -extern int mime_regex(const uschar **); +extern int mime_regex(const uschar **, BOOL); extern void mime_set_anomaly(int); #endif extern uschar *moan_check_errorcopy(uschar *); @@ -433,11 +438,14 @@ extern BOOL receive_msg(BOOL); extern int_eximarith_t receive_statvfs(BOOL, int *); extern void receive_swallow_smtp(void); #ifdef WITH_CONTENT_SCAN -extern int regex(const uschar **); +extern int regex(const uschar **, BOOL); #endif +extern void regex_at_daemon(const uschar *); extern BOOL regex_match(const pcre2_code *, const uschar *, int, uschar **); extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, int); -extern const pcre2_code *regex_must_compile(const uschar *, BOOL, BOOL); +extern const pcre2_code *regex_compile(const uschar *, mcs_flags, uschar **, + pcre2_compile_context *); +extern const pcre2_code *regex_must_compile(const uschar *, mcs_flags, BOOL); extern void retry_add_item(address_item *, uschar *, int); extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL, uschar **, uschar **); @@ -1221,6 +1229,7 @@ pid_t pid; DEBUG(D_any) debug_printf("%s forking for %s\n", process_purpose, purpose); if ((pid = fork()) == 0) { + f.daemon_listen = FALSE; process_purpose = purpose; DEBUG(D_any) debug_printf("postfork: %s\n", purpose); } diff --git a/src/src/globals.c b/src/src/globals.c index ff246feb4..c95d24b47 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -234,6 +234,7 @@ struct global_flags f = .continue_more = FALSE, .daemon_listen = FALSE, + .daemon_scion = FALSE, .debug_daemon = FALSE, .deliver_firsttime = FALSE, .deliver_force = FALSE, @@ -391,7 +392,7 @@ BOOL proxy_session = FALSE; #endif #ifndef DISABLE_QUEUE_RAMP -BOOL queue_fast_ramp = FALSE; +BOOL queue_fast_ramp = TRUE; #endif BOOL queue_list_requires_admin = TRUE; BOOL queue_only = FALSE; @@ -1207,9 +1208,12 @@ uid_t originator_uid; uschar *override_local_interfaces = NULL; uschar *override_pid_file_path = NULL; +BOOL panic_coredump = FALSE; pcre2_general_context * pcre_gen_ctx = NULL; -pcre2_compile_context * pcre_cmp_ctx = NULL; -pcre2_match_context * pcre_mtc_ctx = NULL; +pcre2_compile_context * pcre_gen_cmp_ctx = NULL; +pcre2_match_context * pcre_gen_mtc_ctx = NULL; +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 @@ -1313,6 +1317,7 @@ const pcre2_code *regex_SIZE = NULL; #ifndef DISABLE_PIPE_CONNECT const pcre2_code *regex_EARLY_PIPE = NULL; #endif +int regex_cachesize = 0; const pcre2_code *regex_ismsgid = NULL; const pcre2_code *regex_smtp_code = NULL; const uschar *regex_vars[REGEX_VARS]; @@ -1323,7 +1328,7 @@ const pcre2_code *regex_whitelisted_macro = NULL; uschar *regex_match_string = NULL; #endif int remote_delivery_count = 0; -int remote_max_parallel = 2; +int remote_max_parallel = 4; uschar *remote_sort_domains = NULL; int retry_data_expire = 7*24*60*60; int retry_interval_max = 24*60*60; diff --git a/src/src/globals.h b/src/src/globals.h index fe099e402..c9ef5e484 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -199,6 +199,7 @@ extern struct global_flags { BOOL continue_more :1; /* Flag more addresses waiting */ BOOL daemon_listen :1; /* True if listening required */ + BOOL daemon_scion :1; /* Ancestor proc is daemon, and not re-exec'd */ BOOL debug_daemon :1; /* Debug the daemon process only */ BOOL deliver_firsttime :1; /* True for first delivery attempt */ BOOL deliver_force :1; /* TRUE if delivery was forced */ @@ -792,9 +793,12 @@ 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 BOOL panic_coredump; /* SEGV rather than exit, on LOG_PANIC_DIE */ extern pcre2_general_context * pcre_gen_ctx; /* pcre memory management */ -extern pcre2_compile_context * pcre_cmp_ctx; -extern pcre2_match_context * pcre_mtc_ctx; +extern pcre2_compile_context * pcre_gen_cmp_ctx; +extern pcre2_match_context * pcre_gen_mtc_ctx; +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 */ @@ -895,6 +899,7 @@ extern const pcre2_code *regex_SIZE; /* For recognizing SIZE settings */ #ifndef DISABLE_PIPE_CONNECT extern const pcre2_code *regex_EARLY_PIPE; /* For recognizing PIPE_CONNCT */ #endif +extern int regex_cachesize; /* number of entries */ extern const pcre2_code *regex_ismsgid; /* Compiled r.e. for message ID */ extern const pcre2_code *regex_smtp_code; /* For recognizing SMTP codes */ extern const uschar *regex_vars[]; /* $regexN variables */ diff --git a/src/src/header.c b/src/src/header.c index 898d8d5c4..7ef59ff53 100644 --- a/src/src/header.c +++ b/src/src/header.c @@ -368,7 +368,7 @@ Returns: cond if the header exists and contains one of the strings; /* First we have a local subroutine to handle a single pattern */ static BOOL -one_pattern_match(uschar *name, int slen, BOOL has_addresses, uschar *pattern) +one_pattern_match(uschar * name, int slen, BOOL has_addresses, uschar * pattern) { BOOL yield = FALSE; const pcre2_code *re = NULL; @@ -376,7 +376,7 @@ const pcre2_code *re = NULL; /* If the pattern is a regex, compile it. Bomb out if compiling fails; these patterns are all constructed internally and should be valid. */ -if (*pattern == '^') re = regex_must_compile(pattern, TRUE, FALSE); +if (*pattern == '^') re = regex_must_compile(pattern, MCS_CASELESS, FALSE); /* Scan for the required header(s) and scan each one */ @@ -443,7 +443,7 @@ return yield; /* The externally visible interface */ BOOL -header_match(uschar *name, BOOL has_addresses, BOOL cond, string_item *strings, +header_match(uschar * name, BOOL has_addresses, BOOL cond, string_item * strings, int count, ...) { va_list ap; diff --git a/src/src/host.c b/src/src/host.c index e43b507e5..fed9f4b5f 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -363,80 +363,6 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0))) } - - - -/************************************************* -* Extract port from address string * -*************************************************/ - -/* In the -oMa and -oMi options, a host plus port is given as an IP address -followed by a dot and a port number. This function decodes this. - -An alternative format for the -oMa and -oMi options is [ip address]:port which -is what Exim uses for output, because it seems to becoming commonly used, -whereas the dot form confuses some programs/people. So we recognize that form -too. - -The spool file used to use the first form, but this breaks with a v4mapped ipv6 -hybrid, because the parsing here is not clever. So for spool we now use the -second form. - -Argument: - address points to the string; if there is a port, the '.' in the string - is overwritten with zero to terminate the address; if the string - is in the [xxx]:ppp format, the address is shifted left and the - brackets are removed - -Returns: 0 if there is no port, else the port number. If there's a syntax - error, leave the incoming address alone, and return 0. -*/ - -int -host_address_extract_port(uschar *address) -{ -int port = 0; -uschar *endptr; - -/* Handle the "bracketed with colon on the end" format */ - -if (*address == '[') - { - uschar *rb = address + 1; - while (*rb != 0 && *rb != ']') rb++; - if (*rb++ == 0) return 0; /* Missing ]; leave invalid address */ - if (*rb == ':') - { - port = Ustrtol(rb + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - } - else if (*rb != 0) return 0; /* Bad syntax; leave invalid address */ - memmove(address, address + 1, rb - address - 2); - rb[-2] = 0; - } - -/* Handle the "dot on the end" format */ - -else - { - int skip = -3; /* Skip 3 dots in IPv4 addresses */ - address--; - while (*(++address) != 0) - { - int ch = *address; - if (ch == ':') skip = 0; /* Skip 0 dots in IPv6 addresses */ - else if (ch == '.' && skip++ >= 0) break; - } - if (*address == 0) return 0; - port = Ustrtol(address + 1, &endptr, 10); - if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ - *address = 0; - } - -return port; -} - - /************************************************* * Get port from a host item's name * *************************************************/ diff --git a/src/src/host_address.c b/src/src/host_address.c new file mode 100644 index 000000000..9e6f958be --- /dev/null +++ b/src/src/host_address.c @@ -0,0 +1,80 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* See the file NOTICE for conditions of use and distribution. */ + +#include "exim.h" + +/************************************************* +* Extract port from address string * +*************************************************/ + +/* In the spool file, and in the -oMa and -oMi options, a host plus port is +given as an IP address followed by a dot and a port number. This function +decodes this. + +An alternative format for the -oMa and -oMi options is [ip address]:port which +is what Exim 4 uses for output, because it seems to becoming commonly used, +whereas the dot form confuses some programs/people. So we recognize that form +too. + +Argument: + address points to the string; if there is a port, the '.' in the string + is overwritten with zero to terminate the address; if the string + is in the [xxx]:ppp format, the address is shifted left and the + brackets are removed + +Returns: 0 if there is no port, else the port number. If there's a syntax + error, leave the incoming address alone, and return 0. +*/ + +int +host_address_extract_port(uschar * address) +{ +int port = 0; +uschar *endptr; + +/* Handle the "bracketed with colon on the end" format */ + +if (*address == '[') + { + uschar *rb = address + 1; + while (*rb != 0 && *rb != ']') rb++; + if (*rb++ == 0) return 0; /* Missing ]; leave invalid address */ + if (*rb == ':') + { + port = Ustrtol(rb + 1, &endptr, 10); + if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ + } + else if (*rb != 0) return 0; /* Bad syntax; leave invalid address */ + memmove(address, address + 1, rb - address - 2); + rb[-2] = 0; + } + +/* Handle the "dot on the end" format */ + +else + { + int skip = -3; /* Skip 3 dots in IPv4 addresses */ + address--; + while (*(++address) != 0) + { + int ch = *address; + if (ch == ':') skip = 0; /* Skip 0 dots in IPv6 addresses */ + else if (ch == '.' && skip++ >= 0) break; + } + if (*address == 0) return 0; + port = Ustrtol(address + 1, &endptr, 10); + if (*endptr != 0) return 0; /* Invalid port; leave invalid address */ + *address = 0; + } + +return port; +} + +/* vi: aw ai sw=2 +*/ +/* End of host.c */ diff --git a/src/src/log.c b/src/src/log.c index 8ca973f2d..a46d523db 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -1278,7 +1278,10 @@ if (flags & LOG_PANIC) /* Give up if the DIE flag is set */ if ((flags & LOG_PANIC_DIE) != LOG_PANIC) - die(NULL, US"Unexpected failure, please try later"); + if (panic_coredump) + kill(getpid(), SIGSEGV); /* deliberate trap */ + else + die(NULL, US"Unexpected failure, please try later"); } } diff --git a/src/src/macros.h b/src/src/macros.h index fa89de12d..adbe6a267 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1111,7 +1111,17 @@ should not be one active. */ #define NOTIFIER_SOCKET_NAME "exim_daemon_notify" -#define NOTIFY_MSG_QRUN 1 /* Notify message types */ +/* Notify message types */ +#define NOTIFY_MSG_QRUN 1 #define NOTIFY_QUEUE_SIZE_REQ 2 +#define NOTIFY_REGEX 3 + +/* Flags for match_check_string() */ +typedef unsigned mcs_flags; +#define MCS_NOFLAGS 0 +#define MCS_PARTIAL BIT(0) /* permit partial- search types */ +#define MCS_CASELESS BIT(1) /* caseless matching where possible */ +#define MCS_AT_SPECIAL BIT(2) /* recognize @, @[], etc. */ +#define MCS_CACHEABLE BIT(3) /* no dynamic expansions used for pattern */ /* End of macros.h */ diff --git a/src/src/malware.c b/src/src/malware.c index 4719a5d61..8b5ec27c4 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -299,39 +299,29 @@ return sock; } static const pcre2_code * -m_pcre_compile(const uschar * re, uschar ** errstr) +m_pcre_compile(const uschar * re, BOOL cacheable, uschar ** errstr) { -int err; -PCRE2_SIZE roffset; -const pcre2_code * cre; - -if (!(cre = pcre2_compile((PCRE2_SPTR)re, PCRE2_ZERO_TERMINATED, - PCRE_COPT, &err, &roffset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - *errstr= string_sprintf("regular expression error in '%s': %s at offset %ld", - re, errbuf, (long)roffset); - } -return cre; +return regex_compile(re, cacheable ? MCS_CACHEABLE : MCS_NOFLAGS, errstr, + pcre_gen_cmp_ctx); } uschar * m_pcre_exec(const pcre2_code * cre, uschar * text) { pcre2_match_data * md = pcre2_match_data_create(2, pcre_gen_ctx); -int i = pcre2_match(cre, text, PCRE2_ZERO_TERMINATED, 0, 0, md, pcre_mtc_ctx); +int i = pcre2_match(cre, text, PCRE2_ZERO_TERMINATED, 0, 0, md, pcre_gen_mtc_ctx); PCRE2_UCHAR * substr = NULL; PCRE2_SIZE slen; if (i >= 2) /* Got it */ - pcre2_substring_get_bynumber(md, 1, &substr, &slen); + pcre2_substring_get_bynumber(md, 1, &substr, &slen); /* uses same ctx as md */ +/* pcre2_match_data_free(md); gen ctx needs no free */ return US substr; } static const pcre2_code * m_pcre_nextinlist(const uschar ** list, int * sep, - char * listerr, uschar ** errstr) + BOOL cacheable, char * listerr, uschar ** errstr) { const uschar * list_ele; const pcre2_code * cre = NULL; @@ -342,7 +332,7 @@ else { DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "RE: ", string_printing(list_ele)); - cre = m_pcre_compile(CUS list_ele, errstr); + cre = m_pcre_compile(CUS list_ele, cacheable, errstr); } return cre; } @@ -568,6 +558,7 @@ is via malware(), or there's malware_in_file() used for testing/debugging. Arguments: malware_re match condition for "malware=" + cacheable the RE did not use any dynamic elements during expansion scan_filename the file holding the email to be scanned, if we're faking this up for the -bmalware test, else NULL timeout if nonzero, non-default timeoutl @@ -576,11 +567,12 @@ Returns: Exim message processing code (OK, FAIL, DEFER, ...) where true means malware was found (condition applies) */ static int -malware_internal(const uschar * malware_re, const uschar * scan_filename, - int timeout) +malware_internal(const uschar * malware_re, BOOL cacheable, + const uschar * scan_filename, int timeout) { int sep = 0; const uschar *av_scanner_work = av_scanner; +BOOL av_scanner_textonly; uschar *scanner_name; unsigned long mbox_size; FILE *mbox_file; @@ -607,30 +599,30 @@ the name), so we can close it right away. Get the directory too. */ eml_dir = string_copyn(eml_filename, Ustrrchr(eml_filename, '/') - eml_filename); /* parse 1st option */ -if (strcmpic(malware_re, US"false") == 0 || Ustrcmp(malware_re,"0") == 0) +if (strcmpic(malware_re, US"false") == 0 || Ustrcmp(malware_re, "0") == 0) return FAIL; /* explicitly no matching */ /* special cases (match anything except empty) */ -if ( strcmpic(malware_re,US"true") == 0 - || Ustrcmp(malware_re,"*") == 0 - || Ustrcmp(malware_re,"1") == 0 +if ( strcmpic(malware_re, US"true") == 0 + || Ustrcmp(malware_re, "*") == 0 + || Ustrcmp(malware_re, "1") == 0 ) { if ( !malware_default_re - && !(malware_default_re = m_pcre_compile(malware_regex_default, &errstr))) + && !(malware_default_re = m_pcre_compile(malware_regex_default, FALSE, &errstr))) return malware_panic_defer(errstr); malware_re = malware_regex_default; re = malware_default_re; } /* compile the regex, see if it works */ -else if (!(re = m_pcre_compile(malware_re, &errstr))) +else if (!(re = m_pcre_compile(malware_re, cacheable, &errstr))) return malware_panic_defer(errstr); /* if av_scanner starts with a dollar, expand it first */ if (*av_scanner == '$') { - if (!(av_scanner_work = expand_string(av_scanner))) + if (!(av_scanner_work = expand_string_2(av_scanner, &av_scanner_textonly))) return malware_panic_defer( string_sprintf("av_scanner starts with $, but expansion failed: %s", expand_string_message)); @@ -641,6 +633,8 @@ if (*av_scanner == '$') malware_name = NULL; malware_ok = FALSE; } +else + av_scanner_textonly = TRUE; /* Do not scan twice (unless av_scanner is dynamic). */ if (!malware_ok) @@ -745,13 +739,11 @@ if (!malware_ok) case M_FPROT6D: /* "f-prot6d" scanner type ----------------------------------- */ { int bread; - uschar * e; - uschar * linebuffer; - uschar * scanrequest; + uschar * e, * linebuffer, * scanrequest; uschar av_buffer[1024]; - if ((!fprot6d_re_virus && !(fprot6d_re_virus = m_pcre_compile(fprot6d_re_virus_str, &errstr))) - || (!fprot6d_re_error && !(fprot6d_re_error = m_pcre_compile(fprot6d_re_error_str, &errstr)))) + if ((!fprot6d_re_virus && !(fprot6d_re_virus = m_pcre_compile(fprot6d_re_virus_str, FALSE, &errstr))) + || (!fprot6d_re_error && !(fprot6d_re_error = m_pcre_compile(fprot6d_re_error_str, FALSE, &errstr)))) return malware_panic_defer(errstr); scanrequest = string_sprintf("SCAN FILE %s\n", eml_filename); @@ -921,7 +913,7 @@ badseek: err = errno; /* set up match regex */ if (!drweb_re) - drweb_re = m_pcre_compile(drweb_re_str, &errstr); + drweb_re = m_pcre_compile(drweb_re_str, FALSE, &errstr); /* read and concatenate virus names into one string */ for (int i = 0; i < drweb_vnum; i++) @@ -945,7 +937,7 @@ badseek: err = errno; /* try matcher on the line, grab substring */ result = pcre2_match(drweb_re, (PCRE2_SPTR)tmpbuf, PCRE2_ZERO_TERMINATED, - 0, 0, md, pcre_mtc_ctx); + 0, 0, md, pcre_gen_mtc_ctx); if (result >= 2) { PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); @@ -959,6 +951,7 @@ badseek: err = errno; g = string_catn(g, US ovec[2], ovec[3] - ovec[2]); } } + /* pcre2_match_data_free(md); gen ctx needs no free */ } malware_name = string_from_gstring(g); } @@ -1099,7 +1092,7 @@ badseek: err = errno; /* set up match */ /* todo also SUSPICION\t */ if (!fsec_re) - fsec_re = m_pcre_compile(fsec_re_str, &errstr); + fsec_re = m_pcre_compile(fsec_re_str, FALSE, &errstr); /* read report, linewise. Apply a timeout as the Fsecure daemon sometimes wants an answer to "PING" but they won't tell us what */ @@ -1223,12 +1216,12 @@ badseek: err = errno; /* set up match regex, depends on retcode */ if (kav_rc == 3) { - if (!kav_re_sus) kav_re_sus = m_pcre_compile(kav_re_sus_str, &errstr); + if (!kav_re_sus) kav_re_sus = m_pcre_compile(kav_re_sus_str, FALSE, &errstr); kav_re = kav_re_sus; } else { - if (!kav_re_inf) kav_re_inf = m_pcre_compile(kav_re_inf_str, &errstr); + if (!kav_re_inf) kav_re_inf = m_pcre_compile(kav_re_inf_str, FALSE, &errstr); kav_re = kav_re_inf; } @@ -1277,13 +1270,13 @@ badseek: err = errno; return m_panic_defer(scanent, NULL, errstr); /* find scanner output trigger */ - cmdline_trigger_re = m_pcre_nextinlist(&av_scanner_work, &sep, + cmdline_trigger_re = m_pcre_nextinlist(&av_scanner_work, &sep, av_scanner_textonly, "missing trigger specification", &errstr); if (!cmdline_trigger_re) return m_panic_defer(scanent, NULL, errstr); /* find scanner name regex */ - cmdline_regex_re = m_pcre_nextinlist(&av_scanner_work, &sep, + cmdline_regex_re = m_pcre_nextinlist(&av_scanner_work, &sep, av_scanner_textonly, "missing virus name regex specification", &errstr); if (!cmdline_regex_re) return m_panic_defer(scanent, NULL, errstr); @@ -1906,13 +1899,13 @@ badseek: err = errno; string_printing(sockline_scanner)); /* find scanner output trigger */ - sockline_trig_re = m_pcre_nextinlist(&av_scanner_work, &sep, + sockline_trig_re = m_pcre_nextinlist(&av_scanner_work, &sep, av_scanner_textonly, "missing trigger specification", &errstr); if (!sockline_trig_re) return m_panic_defer_3(scanent, NULL, errstr, malware_daemon_ctx.sock); /* find virus name regex */ - sockline_name_re = m_pcre_nextinlist(&av_scanner_work, &sep, + sockline_name_re = m_pcre_nextinlist(&av_scanner_work, &sep, av_scanner_textonly, "missing virus name regex specification", &errstr); if (!sockline_name_re) return m_panic_defer_3(scanent, NULL, errstr, malware_daemon_ctx.sock); @@ -2043,11 +2036,11 @@ badseek: err = errno; */ if ( ( !ava_re_clean - && !(ava_re_clean = m_pcre_compile(ava_re_clean_str, &errstr))) + && !(ava_re_clean = m_pcre_compile(ava_re_clean_str, FALSE, &errstr))) || ( !ava_re_virus - && !(ava_re_virus = m_pcre_compile(ava_re_virus_str, &errstr))) + && !(ava_re_virus = m_pcre_compile(ava_re_virus_str, FALSE, &errstr))) || ( !ava_re_error - && !(ava_re_error = m_pcre_compile(ava_re_error_str, &errstr))) + && !(ava_re_error = m_pcre_compile(ava_re_error_str, FALSE, &errstr))) ) return malware_panic_defer(errstr); @@ -2209,15 +2202,16 @@ filename; it's a wrapper around the malware_file function. Arguments: malware_re match condition for "malware=" + cacheable the RE did not use any dynamic elements during expansion timeout if nonzero, timeout in seconds Returns: Exim message processing code (OK, FAIL, DEFER, ...) where true means malware was found (condition applies) */ int -malware(const uschar * malware_re, int timeout) +malware(const uschar * malware_re, BOOL cacheable, int timeout) { -int ret = malware_internal(malware_re, NULL, timeout); +int ret = malware_internal(malware_re, cacheable, NULL, timeout); if (ret == DEFER) av_failed = TRUE; return ret; @@ -2257,7 +2251,7 @@ recipients_list = NULL; receive_add_recipient(US"malware-victim@example.net", -1); f.enable_dollar_recipients = TRUE; -ret = malware_internal(US"*", eml_filename, 0); +ret = malware_internal(US"*", TRUE, eml_filename, 0); Ustrncpy(spooled_message_id, message_id, sizeof(spooled_message_id)); spool_mbox_ok = 1; @@ -2278,35 +2272,35 @@ void malware_init(void) { if (!malware_default_re) - malware_default_re = regex_must_compile(malware_regex_default, FALSE, TRUE); + malware_default_re = regex_must_compile(malware_regex_default, MCS_NOFLAGS, TRUE); #ifndef DISABLE_MAL_DRWEB if (!drweb_re) - drweb_re = regex_must_compile(drweb_re_str, FALSE, TRUE); + drweb_re = regex_must_compile(drweb_re_str, MCS_NOFLAGS, TRUE); #endif #ifndef DISABLE_MAL_FSECURE if (!fsec_re) - fsec_re = regex_must_compile(fsec_re_str, FALSE, TRUE); + fsec_re = regex_must_compile(fsec_re_str, MCS_NOFLAGS, TRUE); #endif #ifndef DISABLE_MAL_KAV if (!kav_re_sus) - kav_re_sus = regex_must_compile(kav_re_sus_str, FALSE, TRUE); + kav_re_sus = regex_must_compile(kav_re_sus_str, MCS_NOFLAGS, TRUE); if (!kav_re_inf) - kav_re_inf = regex_must_compile(kav_re_inf_str, FALSE, TRUE); + kav_re_inf = regex_must_compile(kav_re_inf_str, MCS_NOFLAGS, TRUE); #endif #ifndef DISABLE_MAL_AVAST if (!ava_re_clean) - ava_re_clean = regex_must_compile(ava_re_clean_str, FALSE, TRUE); + ava_re_clean = regex_must_compile(ava_re_clean_str, MCS_NOFLAGS, TRUE); if (!ava_re_virus) - ava_re_virus = regex_must_compile(ava_re_virus_str, FALSE, TRUE); + ava_re_virus = regex_must_compile(ava_re_virus_str, MCS_NOFLAGS, TRUE); if (!ava_re_error) - ava_re_error = regex_must_compile(ava_re_error_str, FALSE, TRUE); + ava_re_error = regex_must_compile(ava_re_error_str, MCS_NOFLAGS, TRUE); #endif #ifndef DISABLE_MAL_FFROT6D if (!fprot6d_re_error) - fprot6d_re_error = regex_must_compile(fprot6d_re_error_str, FALSE, TRUE); + fprot6d_re_error = regex_must_compile(fprot6d_re_error_str, MCS_NOFLAGS, TRUE); if (!fprot6d_re_virus) - fprot6d_re_virus = regex_must_compile(fprot6d_re_virus_str, FALSE, TRUE); + fprot6d_re_virus = regex_must_compile(fprot6d_re_virus_str, MCS_NOFLAGS, TRUE); #endif } diff --git a/src/src/match.c b/src/src/match.c index 2e4bff078..b4a0352ee 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -19,9 +19,7 @@ typedef struct check_string_block { const uschar *origsubject; /* caseful; keep these two first, in */ const uschar *subject; /* step with the block below */ int expand_setup; - BOOL use_partial; - BOOL caseless; - BOOL at_is_special; + mcs_flags flags; /* MCS_* defs in macros.h */ } check_string_block; @@ -32,7 +30,7 @@ typedef struct check_address_block { const uschar *origaddress; /* caseful; keep these two first, in */ uschar *address; /* step with the block above */ int expand_setup; - BOOL caseless; + mcs_flags flags; /* MCS_CASELESS, MCS_TEXTONLY_RE */ } check_address_block; @@ -93,9 +91,10 @@ Returns: OK if matched */ static int -check_string(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error) +check_string(void * arg, const uschar * pattern, const uschar ** valueptr, + uschar ** error) { -const check_string_block *cb = arg; +const check_string_block * cb = arg; int search_type, partial, affixlen, starflags; int expand_setup = cb->expand_setup; const uschar * affix, * opts; @@ -128,7 +127,8 @@ required. */ if (pattern[0] == '^') { - const pcre2_code * re = regex_must_compile(pattern, cb->caseless, FALSE); + const pcre2_code * re = regex_must_compile(pattern, + cb->flags & (MCS_CACHEABLE | MCS_CASELESS), FALSE); if (expand_setup < 0 ? !regex_match(re, s, -1, NULL) : !regex_match_and_setup(re, s, 0, expand_setup) @@ -147,7 +147,7 @@ if (pattern[0] == '*') patlen = Ustrlen(++pattern); if (patlen > slen) return FAIL; - if (cb->caseless + if (cb->flags & MCS_CASELESS ? strncmpic(s + slen - patlen, pattern, patlen) != 0 : Ustrncmp(s + slen - patlen, pattern, patlen) != 0) return FAIL; @@ -166,7 +166,7 @@ the primary host name - implement this by changing the pattern. For the other cases we have to do some more work. If we don't recognize a special pattern, just fall through - the match will fail. */ -if (cb->at_is_special && pattern[0] == '@') +if (cb->flags & MCS_AT_SPECIAL && pattern[0] == '@') { if (pattern[1] == 0) { @@ -260,10 +260,10 @@ NOT_AT_SPECIAL: if ((semicolon = Ustrchr(pattern, ';')) == NULL) { - if (cb->caseless ? strcmpic(s, pattern) != 0 : Ustrcmp(s, pattern) != 0) + if (cb->flags & MCS_CASELESS ? strcmpic(s, pattern) != 0 : Ustrcmp(s, pattern) != 0) return FAIL; - if (expand_setup >= 0) expand_nmax = expand_setup; /* Original code! $0 gets the matched subject */ - if (valueptr) *valueptr = pattern; /* "value" gets the pattern */ + if (expand_setup >= 0) expand_nmax = expand_setup; /* $0 gets the matched subject */ + if (valueptr) *valueptr = pattern; /* "value" gets the pattern */ return OK; } @@ -280,7 +280,7 @@ if (search_type < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", /* Partial matching is not appropriate for certain lookups (e.g. when looking up user@domain for sender rejection). There's a flag to disable it. */ -if (!cb->use_partial) partial = -1; +if (!(cb->flags & MCS_PARTIAL)) partial = -1; /* Set the parameters for the three different kinds of lookup. */ @@ -316,9 +316,10 @@ Arguments: s the subject string to be checked pattern the pattern to check it against expand_setup expansion setup option (see check_string()) - use_partial if FALSE, override any partial- search types - caseless TRUE for caseless matching where possible - at_is_special TRUE to recognize @, @[], etc. + flags + use_partial if FALSE, override any partial- search types + caseless TRUE for caseless matching where possible + at_is_special TRUE to recognize @, @[], etc. valueptr if not NULL, and a file lookup was done, return the result here instead of discarding it; else set it to point to NULL @@ -328,16 +329,14 @@ Returns: OK if matched */ int -match_check_string(const uschar *s, const uschar *pattern, int expand_setup, - BOOL use_partial, BOOL caseless, BOOL at_is_special, const uschar **valueptr) +match_check_string(const uschar * s, const uschar * pattern, int expand_setup, + mcs_flags flags, const uschar ** valueptr) { check_string_block cb; cb.origsubject = s; -cb.subject = caseless ? string_copylc(s) : string_copy(s); +cb.subject = flags & MCS_CASELESS ? string_copylc(s) : string_copy(s); cb.expand_setup = expand_setup; -cb.use_partial = use_partial; -cb.caseless = caseless; -cb.at_is_special = at_is_special; +cb.flags = flags; return check_string(&cb, pattern, valueptr, NULL); } @@ -364,14 +363,9 @@ switch(type) { case MCL_STRING: case MCL_DOMAIN: - case MCL_LOCALPART: - return ((check_string_block *)arg)->subject; - - case MCL_HOST: - return ((check_host_block *)arg)->host_address; - - case MCL_ADDRESS: - return ((check_address_block *)arg)->address; + case MCL_LOCALPART: return ((check_string_block *)arg)->subject; + case MCL_HOST: return ((check_host_block *)arg)->host_address; + case MCL_ADDRESS: return ((check_address_block *)arg)->address; } return US""; /* In practice, should never happen */ } @@ -438,6 +432,7 @@ BOOL include_unknown = FALSE, ignore_unknown = FALSE, const uschar *list; uschar *sss; uschar *ot = NULL; +BOOL textonly_re; /* Save time by not scanning for the option name when we don't need it. */ @@ -465,6 +460,7 @@ if (type >= MCL_NOEXPAND) { list = *listptr; type -= MCL_NOEXPAND; /* Remove the "no expand" flag */ + textonly_re = TRUE; } else { @@ -475,11 +471,11 @@ else { check_string_block *cb = (check_string_block *)arg; deliver_domain = string_copy(cb->subject); - list = expand_cstring(*listptr); + list = expand_string_2(*listptr, &textonly_re); deliver_domain = NULL; } else - list = expand_cstring(*listptr); + list = expand_string_2(*listptr, &textonly_re); if (!list) { @@ -495,6 +491,15 @@ else } } +if (textonly_re) switch (type) + { + case MCL_STRING: + case MCL_DOMAIN: + case MCL_LOCALPART: ((check_string_block *)arg)->flags |= MCS_CACHEABLE; break; + case MCL_HOST: ((check_host_block *)arg)->flags |= MCS_CACHEABLE; break; + case MCL_ADDRESS: ((check_address_block *)arg)->flags |= MCS_CACHEABLE; break; + } + /* For an unnamed list, use the expanded version in comments */ #define LIST_LIMIT_PR 2048 @@ -530,7 +535,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) if (at) Ustrncpy(cb->address, cb->origaddress, at - cb->origaddress); - cb->caseless = FALSE; + cb->flags &= ~MCS_CASELESS; continue; } } @@ -543,7 +548,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) { check_string_block *cb = (check_string_block *)arg; Ustrcpy(US cb->subject, cb->origsubject); - cb->caseless = FALSE; + cb->flags &= ~MCS_CASELESS; continue; } } @@ -958,15 +963,13 @@ unsigned int *local_cache_bits = cache_bits; check_string_block cb; cb.origsubject = s; cb.subject = caseless ? string_copylc(s) : string_copy(s); -cb.at_is_special = FALSE; +cb.flags = caseless ? MCS_PARTIAL+MCS_CASELESS : MCS_PARTIAL; switch (type & ~MCL_NOEXPAND) { - case MCL_DOMAIN: cb.at_is_special = TRUE; /*FALLTHROUGH*/ + case MCL_DOMAIN: cb.flags |= MCS_AT_SPECIAL; /*FALLTHROUGH*/ case MCL_LOCALPART: cb.expand_setup = 0; break; default: cb.expand_setup = sep > UCHAR_MAX ? 0 : -1; break; } -cb.use_partial = TRUE; -cb.caseless = caseless; if (valueptr) *valueptr = NULL; return match_check_list(listptr, sep, anchorptr, &local_cache_bits, check_string, &cb, type, s, valueptr); @@ -1003,7 +1006,8 @@ Returns: OK for a match */ static int -check_address(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error) +check_address(void * arg, const uschar * pattern, const uschar ** valueptr, + uschar ** error) { check_address_block * cb = (check_address_block *)arg; check_string_block csb; @@ -1026,7 +1030,7 @@ sdomain = Ustrrchr(subject, '@'); /* The only case where a subject may not have a domain is if the subject is empty. Otherwise, a subject with no domain is a serious configuration error. */ -if (sdomain == NULL && *subject != 0) +if (!sdomain && *subject) { log_write(0, LOG_MAIN|LOG_PANIC, "no @ found in the subject of an " "address list match: subject=\"%s\" pattern=\"%s\"", subject, pattern); @@ -1037,14 +1041,14 @@ if (sdomain == NULL && *subject != 0) This may be the empty address. */ if (*pattern == '^') - return match_check_string(subject, pattern, cb->expand_setup, TRUE, - cb->caseless, FALSE, NULL); + return match_check_string(subject, pattern, cb->expand_setup, + cb->flags | MCS_PARTIAL, NULL); /* Handle a pattern that is just a lookup. Skip over possible lookup names (letters, digits, hyphens). Skip over a possible * or *@ at the end. Then we must have a semicolon for it to be a lookup. */ -for (s = pattern; isalnum(*s) || *s == '-'; s++); +for (s = pattern; isalnum(*s) || *s == '-'; s++) ; if (*s == '*') s++; if (*s == '@') s++; @@ -1057,8 +1061,7 @@ if (*s == ';') if (Ustrncmp(pattern, "partial-", 8) == 0) log_write(0, LOG_MAIN|LOG_PANIC, "partial matching is not applicable to " "whole-address lookups: ignored \"partial-\" in \"%s\"", pattern); - return match_check_string(subject, pattern, -1, FALSE, cb->caseless, FALSE, - valueptr); + return match_check_string(subject, pattern, -1, cb->flags, valueptr); } /* For the remaining cases, an empty subject matches only an empty pattern, @@ -1085,19 +1088,20 @@ if (pattern[0] == '@' && pattern[1] == '@') { int sep = 0; - if ((rc = match_check_string(key, pattern + 2, -1, TRUE, FALSE, FALSE, - CUSS &list)) != OK) return rc; + if ((rc = match_check_string(key, pattern + 2, -1, MCS_PARTIAL, CUSS &list)) + != OK) + return rc; /* Check for chaining from the last item; set up the next key if one is found. */ ss = Ustrrchr(list, ':'); - if (ss == NULL) ss = list; else ss++; - while (isspace(*ss)) ss++; + if (!ss) ss = list; else ss++; + Uskip_whitespace(&ss); if (*ss == '>') { *ss++ = 0; - while (isspace(*ss)) ss++; + Uskip_whitespace(&ss); key = string_copy(ss); } else key = NULL; @@ -1117,8 +1121,7 @@ if (pattern[0] == '@' && pattern[1] == '@') else local_yield = OK; *sdomain = 0; - rc = match_check_string(subject, ss, -1, TRUE, cb->caseless, FALSE, - valueptr); + rc = match_check_string(subject, ss, -1, cb->flags + MCS_PARTIAL, valueptr); *sdomain = '@'; switch(rc) @@ -1148,8 +1151,7 @@ if (pattern[0] == '@' && pattern[1] == '@') /* We get here if the pattern is not a lookup or a regular expression. If it contains an @ there is both a local part and a domain. */ -pdomain = Ustrrchr(pattern, '@'); -if (pdomain != NULL) +if ((pdomain = Ustrrchr(pattern, '@'))) { int pllen, sllen; @@ -1177,7 +1179,7 @@ if (pdomain != NULL) { int cllen = pllen - 1; if (sllen < cllen) return FAIL; - if (cb->caseless + if (cb->flags & MCS_CASELESS ? strncmpic(subject+sllen-cllen, pattern + 1, cllen) != 0 : Ustrncmp(subject+sllen-cllen, pattern + 1, cllen) != 0) return FAIL; @@ -1192,7 +1194,7 @@ if (pdomain != NULL) else { if (sllen != pllen) return FAIL; - if (cb->caseless + if (cb->flags & MCS_CASELESS ? strncmpic(subject, pattern, sllen) != 0 : Ustrncmp(subject, pattern, sllen) != 0) return FAIL; } @@ -1205,18 +1207,17 @@ original code read as follows: return match_check_string(sdomain + 1, pdomain ? pdomain + 1 : pattern, - cb->expand_setup + expand_inc, TRUE, cb->caseless, TRUE, NULL); + cb->expand_setup + expand_inc, cb->flags, NULL); This supported only literal domains and *.x.y patterns. In order to allow for -named domain lists (so that you can right, for example, "senders=+xxxx"), it +named domain lists (so that you can write, for example, "senders=+xxxx"), it was changed to use the list scanning function. */ csb.origsubject = sdomain + 1; -csb.subject = cb->caseless ? string_copylc(sdomain+1) : string_copy(sdomain+1); +csb.subject = cb->flags & MCS_CASELESS + ? string_copylc(sdomain+1) : string_copy(sdomain+1); csb.expand_setup = cb->expand_setup + expand_inc; -csb.use_partial = TRUE; -csb.caseless = cb->caseless; -csb.at_is_special = TRUE; +csb.flags = MCS_PARTIAL | MCS_AT_SPECIAL | cb->flags & MCS_CASELESS; listptr = pdomain ? pdomain + 1 : pattern; if (valueptr) *valueptr = NULL; @@ -1321,10 +1322,10 @@ if (expand_setup == 0) ab.origaddress = address; /* ab.address is above */ ab.expand_setup = expand_setup; -ab.caseless = caseless; +ab.flags = caseless ? MCS_CASELESS : 0; return match_check_list(listptr, sep, &addresslist_anchor, &local_cache_bits, - check_address, &ab, MCL_ADDRESS + (expand? 0:MCL_NOEXPAND), address, + check_address, &ab, MCL_ADDRESS + (expand ? 0 : MCL_NOEXPAND), address, valueptr); } diff --git a/src/src/queue.c b/src/src/queue.c index 4bdd6fb14..6e47d2c8a 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -423,11 +423,11 @@ if (!recurse) /* If deliver_selectstring is a regex, compile it. */ if (deliver_selectstring && f.deliver_selectstring_regex) - selectstring_regex = regex_must_compile(deliver_selectstring, TRUE, FALSE); + selectstring_regex = regex_must_compile(deliver_selectstring, MCS_CASELESS, FALSE); if (deliver_selectstring_sender && f.deliver_selectstring_sender_regex) selectstring_regex_sender = - regex_must_compile(deliver_selectstring_sender, TRUE, FALSE); + regex_must_compile(deliver_selectstring_sender, MCS_CASELESS, FALSE); /* If the spool is split into subdirectories, we want to process it one directory at a time, so as to spread out the directory scanning and the @@ -1562,19 +1562,9 @@ memcpy(buf+1, msgid, MESSAGE_ID_LENGTH+1); if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) >= 0) { struct sockaddr_un sa_un = {.sun_family = AF_UNIX}; + ssize_t len = daemon_notifier_sockname(&sa_un); -#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS - int len = offsetof(struct sockaddr_un, sun_path) + 1 - + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", - expand_string(notifier_socket)); - sa_un.sun_path[0] = 0; -#else - int len = offsetof(struct sockaddr_un, sun_path) - + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", - expand_string(notifier_socket)); -#endif - - if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa_un, len) < 0) + if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa_un, (socklen_t)len) < 0) DEBUG(D_queue_run) debug_printf("%s: sendto %s\n", __FUNCTION__, strerror(errno)); close(fd); diff --git a/src/src/readconf.c b/src/src/readconf.c index 06bc50fd8..5068dc60e 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -243,6 +243,7 @@ static optionlist optionlist_config[] = { #ifdef LOOKUP_ORACLE { "oracle_servers", opt_stringptr, {&oracle_servers} }, #endif + { "panic_coredump", opt_bool, {&panic_coredump} }, { "percent_hack_domains", opt_stringptr, {&percent_hack_domains} }, #ifdef EXIM_PERL { "perl_at_start", opt_bool, {&opt_perl_at_start} }, @@ -2667,8 +2668,8 @@ switch(ol->type & opt_mask) break; case opt_bit: - printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))? - "" : "no_", name); + printf("%s%s\n", (*((int *)value)) & (1 << ((ol->type >> 16) & 31)) + ? "" : "no_", name); break; case opt_expand_bool: @@ -2693,7 +2694,7 @@ switch(ol->type & opt_mask) case opt_bool: case opt_bool_verify: case opt_bool_set: - printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name); + printf("%s%s\n", *((BOOL *)value) ? "" : "no_", name); break; case opt_func: @@ -3497,7 +3498,7 @@ if (!process_log_path || !*process_log_path) /* Compile the regex for matching a UUCP-style "From_" line in an incoming message. */ -regex_From = regex_must_compile(uucp_from_pattern, FALSE, TRUE); +regex_From = regex_must_compile(uucp_from_pattern, MCS_NOFLAGS, TRUE); /* Unpick the SMTP rate limiting options, if set */ diff --git a/src/src/regex.c b/src/src/regex.c index 5c0f7c4e0..5de1c1704 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -18,9 +18,9 @@ /* Structure to hold a list of Regular expressions */ typedef struct pcre_list { - pcre2_code *re; - uschar *pcre_text; - struct pcre_list *next; + const pcre2_code * re; + uschar * pcre_text; + struct pcre_list * next; } pcre_list; uschar regex_match_string_buffer[1024]; @@ -28,31 +28,27 @@ uschar regex_match_string_buffer[1024]; extern FILE *mime_stream; extern uschar *mime_current_boundary; + static pcre_list * -compile(const uschar * list) +compile(const uschar * list, BOOL cacheable) { int sep = 0; -uschar *regex_string; -pcre_list *re_list_head = NULL; -pcre_list *ri; +uschar * regex_string; +pcre_list * re_list_head = NULL; +pcre_list * ri; /* precompile our regexes */ while ((regex_string = string_nextinlist(&list, &sep, NULL, 0))) if (strcmpic(regex_string, US"false") != 0 && Ustrcmp(regex_string, "0") != 0) { - pcre2_code * re; - int err; - PCRE2_SIZE pcre_erroffset; - /* compile our regular expression */ - if (!(re = pcre2_compile( (PCRE2_SPTR) regex_string, PCRE2_ZERO_TERMINATED, - 0, &err, &pcre_erroffset, pcre_cmp_ctx))) + uschar * errstr; + const pcre2_code * re = regex_compile(regex_string, + cacheable ? MCS_CACHEABLE : MCS_NOFLAGS, &errstr, pcre_gen_cmp_ctx); + + if (!re) { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - log_write(0, LOG_MAIN, - "regex acl condition warning - error in regex '%s': %s at offset %ld, skipped.", - regex_string, errbuf, (long)pcre_erroffset); + log_write(0, LOG_MAIN, "regex acl condition warning - %s, skipped", errstr); continue; } @@ -75,7 +71,7 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next) int n; /* try matcher on the line */ - if ((n = pcre2_match(ri->re, (PCRE2_SPTR)linebuffer, len, 0, 0, md, pcre_mtc_ctx)) > 0) + if ((n = pcre2_match(ri->re, (PCRE2_SPTR)linebuffer, len, 0, 0, md, pcre_gen_mtc_ctx)) > 0) { Ustrncpy(regex_match_string_buffer, ri->pcre_text, sizeof(regex_match_string_buffer)-1); @@ -85,19 +81,21 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next) { PCRE2_UCHAR * cstr; PCRE2_SIZE cslen; - pcre2_substring_get_bynumber(md, nn, &cstr, &cslen); + pcre2_substring_get_bynumber(md, nn, &cstr, &cslen); /* uses same ctx as md */ regex_vars[nn-1] = CUS cstr; } return OK; } } -pcre2_match_data_free(md); +/* pcre2_match_data_free(md); gen ctx needs no free */ return FAIL; } + + int -regex(const uschar **listptr) +regex(const uschar **listptr, BOOL cacheable) { unsigned long mbox_size; FILE *mbox_file; @@ -130,7 +128,7 @@ else } /* precompile our regexes */ -if (!(re_list_head = compile(*listptr))) +if (!(re_list_head = compile(*listptr, cacheable))) return FAIL; /* no regexes -> nothing to do */ /* match each line against all regexes */ @@ -167,7 +165,7 @@ return ret; int -mime_regex(const uschar **listptr) +mime_regex(const uschar **listptr, BOOL cacheable) { pcre_list *re_list_head = NULL; FILE *f; @@ -179,7 +177,7 @@ int ret; regex_match_string = NULL; /* precompile our regexes */ -if (!(re_list_head = compile(*listptr))) +if (!(re_list_head = compile(*listptr, cacheable))) return FAIL; /* no regexes -> nothing to do */ /* check if the file is already decoded */ diff --git a/src/src/regex_cache.c b/src/src/regex_cache.c new file mode 100644 index 000000000..63cddce1d --- /dev/null +++ b/src/src/regex_cache.c @@ -0,0 +1,252 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* + * Copyright (c) The Exim Maintainers 2022 + * License: GPL + */ + +/* Caching layers for compiled REs. There is a local layer in the process, +implemented as a tree for inserts and lookup. This cache is inherited from +the daemon, for the process tree deriving from there - but not by re-exec'd +proceses or commandline submission processes. + +If the process has to compile, and is not the daemon or a re-exec'd exim, +it notifies the use of the RE to the daemon via a unix-domain socket. +This is a fire-and-forget send with no response, hence cheap from the point-of +view of the sender. I have not measured the overall comms costs. The +daemon also compiles the RE, and caches the result. + +A second layer would be possible by asking the daemon via the notifier socket +(for a result from its cache, or a compile if it must). The comms overhead +is significant, not only for the channel but also for de/serialisation of +the compiled object. This makes it untenable for the primary use-case, the +transport process which has been re-exec'd to gain privs - and therefore does not +have the daemon-maintained cache. Using shared-memory might reduce that cost +(the attach time for the memory segment will matter); the implimentation +would require suitable R/W locks. +*/ + +#include "exim.h" + +typedef struct re_req { + uschar notifier_reqtype; + BOOL caseless; + uschar re[1]; /* extensible */ +} re_req; + +static tree_node * regex_cache = NULL; +static tree_node * regex_caseless_cache = NULL; + +#define REGEX_CACHESIZE_LIMIT 1000 + +/******************************************************************************/ + +static void +regex_to_daemon(const uschar * key, BOOL caseless) +{ +int klen = Ustrlen(key) + 1; +int rlen = sizeof(re_req) + klen; +re_req * req; +int fd, old_pool = store_pool; + +DEBUG(D_expand|D_lists) + debug_printf_indent("sending RE '%s' to daemon\n", key); + +store_pool = POOL_MAIN; + req = store_get(rlen, key); /* maybe need a size limit */ +store_pool = old_pool;; +req->notifier_reqtype = NOTIFY_REGEX; +req->caseless = caseless; +memcpy(req->re, key, klen); + +if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) >= 0) + { + struct sockaddr_un sa_un = {.sun_family = AF_UNIX}; + ssize_t len = daemon_notifier_sockname(&sa_un); + + if (sendto(fd, req, rlen, 0, (struct sockaddr *)&sa_un, (socklen_t)len) < 0) + DEBUG(D_queue_run) + debug_printf("%s: sendto %s\n", __FUNCTION__, strerror(errno)); + close(fd); + } +else DEBUG(D_queue_run) debug_printf(" socket: %s\n", strerror(errno)); +} + + +static const pcre2_code * +regex_from_cache(const uschar * key, BOOL caseless) +{ +tree_node * node = + tree_search(caseless ? regex_caseless_cache : regex_cache, key); +DEBUG(D_expand|D_lists) + debug_printf_indent("compiled %sRE '%s' %sfound in local cache\n", + caseless ? "caseless " : "", key, node ? "" : "not "); + +return node ? node->data.ptr : NULL; +} + + +static void +regex_to_cache(const uschar * key, BOOL caseless, const pcre2_code * cre) +{ +PCRE2_SIZE srelen; +uschar * sre; +tree_node * node; + +node = store_get(sizeof(tree_node) + Ustrlen(key) + 1, key); /* we are called with STORE_PERM */ +Ustrcpy(node->name, key); +node->data.ptr = (void *)cre; + +if (!tree_insertnode(caseless ? ®ex_caseless_cache : ®ex_cache, node)) + { DEBUG(D_expand|D_lists) debug_printf_indent("duplicate key!\n"); } +else DEBUG(D_expand|D_lists) + debug_printf_indent("compiled RE '%s' saved in local cache\n", key); + +/* Additionally, if not re-execed and not the daemon, tell the daemon of the RE +so it can add to the cache */ + +if (f.daemon_scion && !f.daemon_listen) + regex_to_daemon(key, caseless); + +return; +} + +/******************************************************************************/ + +/************************************************* +* Compile regular expression and panic on fail * +*************************************************/ + +/* This function is called when failure to compile a regular expression leads +to a panic exit. In other cases, pcre_compile() is called directly. In many +cases where this function is used, the results of the compilation are to be +placed in long-lived store, so we temporarily reset the store management +functions that PCRE uses if the use_malloc flag is set. + +Argument: + pattern the pattern to compile + flags + caseless caseless matching is required + cacheable use (writeback) cache + use_malloc TRUE if compile into malloc store + +Returns: pointer to the compiled pattern +*/ + +const pcre2_code * +regex_must_compile(const uschar * pattern, mcs_flags flags, BOOL use_malloc) +{ +BOOL caseless = !!(flags & MCS_CASELESS); +size_t offset; +const pcre2_code * yield; +int old_pool = store_pool, err; + +/* Optionall, check the cache and return if found */ + +if ( flags & MCS_CACHEABLE + && (yield = regex_from_cache(pattern, caseless))) + return yield; + +store_pool = POOL_PERM; + +if (!(yield = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, + caseless ? PCRE_COPT|PCRE2_CASELESS : PCRE_COPT, + &err, &offset, use_malloc ? pcre_mlc_cmp_ctx : pcre_gen_cmp_ctx))) + { + uschar errbuf[128]; + pcre2_get_error_message(err, errbuf, sizeof(errbuf)); + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "regular expression error: " + "%s at offset %ld while compiling %s", errbuf, (long)offset, pattern); + } + +if (use_malloc) + { + /*pcre2_general_context_free(gctx);*/ + } + +if (flags & MCS_CACHEABLE) + regex_to_cache(pattern, caseless, yield); + +store_pool = old_pool; +return yield; +} + + + + +/* Wrapper for pcre2_compile() and error-message handling. + +Arguments: pattern regex to compile + flags + caseless flag for match variant + cacheable use (writeback) cache + errstr on error, filled in with error message + cctx compile-context for pcre2 + +Return: NULL on error, with errstr set. Otherwise, the compiled RE object +*/ + +const pcre2_code * +regex_compile(const uschar * pattern, mcs_flags flags, uschar ** errstr, + pcre2_compile_context * cctx) +{ +const uschar * key = pattern; +BOOL caseless = !!(flags & MCS_CASELESS); +int err; +PCRE2_SIZE offset; +const pcre2_code * yield; +int old_pool = store_pool; + +/* Optionally, check the cache and return if found */ + +if ( flags & MCS_CACHEABLE + && (yield = regex_from_cache(key, caseless))) + return yield; + +DEBUG(D_expand|D_lists) debug_printf_indent("compiling %sRE '%s'\n", + caseless ? "caseless " : "", pattern); + +store_pool = POOL_PERM; +if (!(yield = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, + caseless ? PCRE_COPT|PCRE2_CASELESS : PCRE_COPT, + &err, &offset, cctx))) + { + uschar errbuf[128]; + pcre2_get_error_message(err, errbuf, sizeof(errbuf)); + store_pool = old_pool; + *errstr = string_sprintf("regular expression error in " + "\"%s\": %s at offset %ld", pattern, errbuf, (long)offset); + } +else if (flags & MCS_CACHEABLE) + regex_to_cache(key, caseless, yield); +store_pool = old_pool; + +return yield; +} + + + +/* Handle a regex notify arriving at the daemon. We get sent the original RE; +compile it (again) and write to the cache. Later forked procs will be able to +read from the cache, unless they re-execed. Therefore, those latter never bother +sending us a notification. */ + +void +regex_at_daemon(const uschar * reqbuf) +{ +const re_req * req = (const re_req *)reqbuf; +uschar * errstr; +const pcre2_code * cre; + +if (regex_cachesize >= REGEX_CACHESIZE_LIMIT) + errstr = US"regex cache size limit reached"; +else if ((cre = regex_compile(req->re, + req->caseless ? MCS_CASELESS | MCS_CACHEABLE : MCS_CACHEABLE, + &errstr, pcre_gen_cmp_ctx))) + regex_cachesize++; + +DEBUG(D_any) if (!cre) debug_printf("%s\n", errstr); +return; +} diff --git a/src/src/rewrite.c b/src/src/rewrite.c index 005dc51fe..bfd78b5f1 100644 --- a/src/src/rewrite.c +++ b/src/src/rewrite.c @@ -136,7 +136,8 @@ for (rewrite_rule * rule = rewrite_rules; if (flag & rewrite_smtp) { - uschar *key = expand_string(rule->key); + BOOL textonly_re; + const uschar * key = expand_string_2(rule->key, &textonly_re); if (!key) { if (!f.expand_string_forcedfail) @@ -144,7 +145,8 @@ for (rewrite_rule * rule = rewrite_rules; "checking for SMTP rewriting: %s", rule->key, expand_string_message); continue; } - if (match_check_string(subject, key, 0, TRUE, FALSE, FALSE, NULL) != OK) + if (match_check_string(subject, key, 0, + textonly_re ? MCS_CACHEABLE | MCS_PARTIAL : MCS_PARTIAL, NULL) != OK) continue; new = expand_string(rule->replacement); } diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index 94cde4e04..8b67f3116 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -84,10 +84,10 @@ iplookup_router_options_block iplookup_router_option_defaults = { consistency checks to be done, or anything else that needs to be set up. */ void -iplookup_router_init(router_instance *rblock) +iplookup_router_init(router_instance * rblock) { -iplookup_router_options_block *ob = - (iplookup_router_options_block *)(rblock->options_block); +iplookup_router_options_block * ob = + (iplookup_router_options_block *) rblock->options_block; /* A port and a host list must be given */ @@ -95,13 +95,13 @@ if (ob->port < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n " "a port must be specified", rblock->name); -if (ob->hosts == NULL) +if (!ob->hosts) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n " "a host list must be specified", rblock->name); /* Translate protocol name into value */ -if (ob->protocol_name != NULL) +if (ob->protocol_name) { if (Ustrcmp(ob->protocol_name, "udp") == 0) ob->protocol = ip_udp; else if (Ustrcmp(ob->protocol_name, "tcp") == 0) ob->protocol = ip_tcp; @@ -111,9 +111,9 @@ if (ob->protocol_name != NULL) /* If a response pattern is given, compile it now to get the error early. */ -if (ob->response_pattern != NULL) +if (ob->response_pattern) ob->re_response_pattern = - regex_must_compile(ob->response_pattern, FALSE, TRUE); + regex_must_compile(ob->response_pattern, MCS_NOFLAGS, TRUE); } diff --git a/src/src/structs.h b/src/src/structs.h index b38aa6a9d..06cd06084 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -895,7 +895,7 @@ typedef struct check_host_block { const uschar *host_name; const uschar *host_address; const uschar *host_ipv4; - BOOL negative; + mcs_flags flags; } check_host_block; /* Structure for remembering lookup data when caching the result of diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 93281efda..7e29dd3bc 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -681,7 +681,7 @@ for (struct dirent *ent; ent = readdir(dir); ) { pcre2_match_data * md = pcre2_match_data_create(2, pcre_gen_ctx); int rc = pcre2_match(re, (PCRE2_SPTR)name, PCRE2_ZERO_TERMINATED, - 0, 0, md, pcre_mtc_ctx); + 0, 0, md, pcre_gen_mtc_ctx); PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); if ( rc >= 0 && (rc = pcre2_get_ovector_count(md)) >= 2) @@ -694,9 +694,11 @@ for (struct dirent *ent; ent = readdir(dir); ) DEBUG(D_transport) debug_printf("check_dir_size: size from %s is " OFF_T_FMT "\n", name, size); + /* pcre2_match_data_free(md); gen ctx needs no free */ continue; } } + /* pcre2_match_data_free(md); gen ctx needs no free */ DEBUG(D_transport) debug_printf("check_dir_size: regex did not match %s\n", name); } @@ -2211,23 +2213,14 @@ else if (ob->quota_value > 0 || THRESHOLD_CHECK || ob->maildir_use_size_file) { - PCRE2_SIZE offset; - int err; - /* Compile the regex if there is one. */ if (ob->quota_size_regex) { - if (!(re = pcre2_compile((PCRE2_SPTR)ob->quota_size_regex, - PCRE2_ZERO_TERMINATED, PCRE_COPT, &err, &offset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - addr->message = string_sprintf("appendfile: regular expression " - "error: %s at offset %ld while compiling %s", errbuf, (long)offset, - ob->quota_size_regex); + if (!(re = regex_compile(ob->quota_size_regex, + MCS_NOFLAGS, &addr->message, pcre_gen_cmp_ctx))) return FALSE; - } + DEBUG(D_transport) debug_printf("using regex for file sizes: %s\n", ob->quota_size_regex); } @@ -2300,23 +2293,14 @@ else if (ob->maildir_use_size_file) { const pcre2_code * dir_regex = NULL; - PCRE2_SIZE offset; - int err; if (ob->maildir_dir_regex) { int check_path_len = Ustrlen(check_path); - if (!(dir_regex = pcre2_compile((PCRE2_SPTR)ob->maildir_dir_regex, - PCRE2_ZERO_TERMINATED, PCRE_COPT, &err, &offset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - addr->message = string_sprintf("appendfile: regular expression " - "error: %s at offset %ld while compiling %s", errbuf, (long)offset, - ob->maildir_dir_regex); + if (!(dir_regex = regex_compile(ob->maildir_dir_regex, + MCS_NOFLAGS, &addr->message, pcre_gen_cmp_ctx))) return FALSE; - } DEBUG(D_transport) debug_printf("using regex for maildir directory selection: %s\n", diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 7f529b7ca..6eee04d03 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -275,7 +275,7 @@ struct list for (struct list * l = list; l < list + nelem(list); l++) if (!*l->re) - *l->re = regex_must_compile(l->string, FALSE, TRUE); + *l->re = regex_must_compile(l->string, MCS_NOFLAGS, TRUE); } @@ -1000,7 +1000,7 @@ uschar authnum; unsigned short authbits = 0; if (!sx->esmtp) return 0; -if (!regex_AUTH) regex_AUTH = regex_must_compile(AUTHS_REGEX, FALSE, TRUE); +if (!regex_AUTH) regex_AUTH = regex_must_compile(AUTHS_REGEX, MCS_NOFLAGS, TRUE); if (!regex_match_and_setup(regex_AUTH, sx->buffer, 0, -1)) return 0; expand_nmax = -1; /* reset */ names = string_copyn(expand_nstring[1], expand_nlength[1]); @@ -1563,7 +1563,7 @@ f.smtp_authenticated = FALSE; client_authenticator = client_authenticated_id = client_authenticated_sender = NULL; if (!regex_AUTH) - regex_AUTH = regex_must_compile(AUTHS_REGEX, FALSE, TRUE); + regex_AUTH = regex_must_compile(AUTHS_REGEX, MCS_NOFLAGS, TRUE); /* Is the server offering AUTH? */ @@ -1849,57 +1849,57 @@ pcre2_match_data * md = pcre2_match_data_create(1, pcre_gen_ctx); #ifndef DISABLE_TLS if ( checks & OPTION_TLS && pcre2_match(regex_STARTTLS, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) #endif checks &= ~OPTION_TLS; if ( checks & OPTION_IGNQ && pcre2_match(regex_IGNOREQUOTA, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) checks &= ~OPTION_IGNQ; if ( checks & OPTION_CHUNKING && pcre2_match(regex_CHUNKING, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) checks &= ~OPTION_CHUNKING; #ifndef DISABLE_PRDR if ( checks & OPTION_PRDR && pcre2_match(regex_PRDR, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) #endif checks &= ~OPTION_PRDR; #ifdef SUPPORT_I18N if ( checks & OPTION_UTF8 && pcre2_match(regex_UTF8, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) #endif checks &= ~OPTION_UTF8; if ( checks & OPTION_DSN && pcre2_match(regex_DSN, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) checks &= ~OPTION_DSN; if ( checks & OPTION_PIPE && pcre2_match(regex_PIPELINING, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) checks &= ~OPTION_PIPE; if ( checks & OPTION_SIZE && pcre2_match(regex_SIZE, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) checks &= ~OPTION_SIZE; #ifndef DISABLE_PIPE_CONNECT if ( checks & OPTION_EARLY_PIPE && pcre2_match(regex_EARLY_PIPE, - (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_mtc_ctx) < 0) + (PCRE2_SPTR)buf, bsize, 0, PCRE_EOPT, md, pcre_gen_mtc_ctx) < 0) #endif checks &= ~OPTION_EARLY_PIPE; -pcre2_match_data_free(md); +/* pcre2_match_data_free(md); gen ctx needs no free */ /* debug_printf("%s: found 0x%04x\n", __FUNCTION__, checks); */ return checks; } diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c index a83fc6f09..205ee41cb 100644 --- a/src/src/transports/tf_maildir.c +++ b/src/src/transports/tf_maildir.c @@ -142,22 +142,13 @@ a subfolder, and should ensure that a maildirfolder file exists. */ if (maildirfolder_create_regex) { - int err; - PCRE2_SIZE offset; const pcre2_code * re; DEBUG(D_transport) debug_printf("checking for maildirfolder requirement\n"); - if (!(re = pcre2_compile((PCRE2_SPTR)maildirfolder_create_regex, - PCRE2_ZERO_TERMINATED, PCRE_COPT, &err, &offset, pcre_cmp_ctx))) - { - uschar errbuf[128]; - pcre2_get_error_message(err, errbuf, sizeof(errbuf)); - addr->message = string_sprintf("appendfile: regular expression " - "error: %s at offset %ld while compiling %s", errbuf, (long)offset, - maildirfolder_create_regex); + if (!(re = regex_compile(maildirfolder_create_regex, + MCS_NOFLAGS, &addr->message, pcre_gen_cmp_ctx))) return FALSE; - } if (regex_match(re, path, -1, NULL)) { diff --git a/src/src/verify.c b/src/src/verify.c index b4c2b9a8f..afc18d553 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -3074,7 +3074,7 @@ digits, full stops, and hyphens (the constituents of domain names). Allow underscores, as they are all too commonly found. Sigh. Also, if allow_utf8_domains is set, allow top-bit characters. */ -for (t = ss; *t != 0; t++) +for (t = ss; *t; t++) if (!isalnum(*t) && *t != '.' && *t != '-' && *t != '_' && (!allow_utf8_domains || *t < 128)) break; @@ -3082,7 +3082,7 @@ for (t = ss; *t != 0; t++) its IP address and match against that. Note that a multi-homed host will add items to the chain. */ -if (*t == 0) +if (!*t) { int rc; host_item h; @@ -3113,8 +3113,8 @@ outgoing hosts, the name is always given explicitly. If it is NULL, it means we must use sender_host_name and its aliases, looking them up if necessary. */ if (cb->host_name) /* Explicit host name given */ - return match_check_string(cb->host_name, ss, -1, TRUE, TRUE, TRUE, - valueptr); + return match_check_string(cb->host_name, ss, -1, + MCS_PARTIAL | MCS_CASELESS | MCS_AT_SPECIAL | cb->flags, valueptr); /* Host name not given; in principle we need the sender host name and its aliases. However, for query-style lookups, we do not need the name if the @@ -3143,7 +3143,9 @@ if ((semicolon = Ustrchr(ss, ';'))) if (isquery) { - switch(match_check_string(US"", ss, -1, TRUE, TRUE, TRUE, valueptr)) + switch(match_check_string(US"", ss, -1, + MCS_PARTIAL| MCS_CASELESS| MCS_AT_SPECIAL | (cb->flags & MCS_CACHEABLE), + valueptr)) { case OK: return OK; case DEFER: return DEFER; @@ -3169,7 +3171,9 @@ if (!sender_host_name) /* Match on the sender host name, using the general matching function */ -switch(match_check_string(sender_host_name, ss, -1, TRUE, TRUE, TRUE, valueptr)) +switch(match_check_string(sender_host_name, ss, -1, + MCS_PARTIAL| MCS_CASELESS| MCS_AT_SPECIAL | (cb->flags & MCS_CACHEABLE), + valueptr)) { case OK: return OK; case DEFER: return DEFER; @@ -3179,7 +3183,9 @@ switch(match_check_string(sender_host_name, ss, -1, TRUE, TRUE, TRUE, valueptr)) aliases = sender_host_aliases; while (*aliases) - switch(match_check_string(*aliases++, ss, -1, TRUE, TRUE, TRUE, valueptr)) + switch(match_check_string(*aliases++, ss, -1, + MCS_PARTIAL| MCS_CASELESS| MCS_AT_SPECIAL | (cb->flags & MCS_CACHEABLE), + valueptr)) { case OK: return OK; case DEFER: return DEFER; @@ -3255,8 +3261,8 @@ rc = match_check_list( check_host, /* function for testing */ &cb, /* argument for function */ MCL_HOST, /* type of check */ - (host_address == sender_host_address)? - US"host" : host_address, /* text for debugging */ + host_address == sender_host_address + ? US"host" : host_address, /* text for debugging */ valueptr); /* where to pass back data */ deliver_host_address = save_host_address; return rc; commit d05685413efd3262b4a5622717f90bba351f1074 Author: Jeremy Harris Date: Sun Jun 26 12:29:05 2022 +0100 typo diff --git a/src/src/drtables.c b/src/src/drtables.c index b2f2a4b33..30eb855e3 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -736,7 +736,7 @@ else { char * name = ent->d_name; int len = (int)strlen(name); - if (regex_match(regex_islookupmod, US name, len, NUL)) + if (regex_match(regex_islookupmod, US name, len, NULL)) { int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2; void *dl; commit c6887a05b9c56d373086e9a79e20c26bebd300b2 Author: Jeremy Harris Date: Sun Jun 26 15:27:32 2022 +0100 Variable setting in -be diff --git a/src/src/acl.c b/src/src/acl.c index 0078aca7d..3af3a4eee 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -734,6 +734,78 @@ return -1; } +static BOOL +acl_varname_to_cond(const uschar ** sp, acl_condition_block * cond, uschar ** error) +{ +const uschar * s = *sp, * endptr; + +#ifndef DISABLE_DKIM +if ( Ustrncmp(s, "dkim_verify_status", 18) == 0 + || Ustrncmp(s, "dkim_verify_reason", 18) == 0) + { + endptr = s+18; + if (isalnum(*endptr)) + { + *error = string_sprintf("invalid variable name after \"set\" in ACL " + "modifier \"set %s\" " + "(only \"dkim_verify_status\" or \"dkim_verify_reason\" permitted)", + s); + return FALSE; + } + cond->u.varname = string_copyn(s, 18); + } +else +#endif + { + if (Ustrncmp(s, "acl_c", 5) != 0 && Ustrncmp(s, "acl_m", 5) != 0) + { + *error = string_sprintf("invalid variable name after \"set\" in ACL " + "modifier \"set %s\" (must start \"acl_c\" or \"acl_m\")", s); + return FALSE; + } + + endptr = s + 5; + if (!isdigit(*endptr) && *endptr != '_') + { + *error = string_sprintf("invalid variable name after \"set\" in ACL " + "modifier \"set %s\" (digit or underscore must follow acl_c or acl_m)", + s); + return FALSE; + } + + for ( ; *endptr && *endptr != '=' && !isspace(*endptr); endptr++) + if (!isalnum(*endptr) && *endptr != '_') + { + *error = string_sprintf("invalid character \"%c\" in variable name " + "in ACL modifier \"set %s\"", *endptr, s); + return FALSE; + } + + cond->u.varname = string_copyn(s + 4, endptr - s - 4); + } +s = endptr; +Uskip_whitespace(&s); +*sp = s; +return TRUE; +} + + +static BOOL +acl_data_to_cond(const uschar * s, acl_condition_block * cond, + const uschar * name, uschar ** error) +{ +if (*s++ != '=') + { + *error = string_sprintf("\"=\" missing after ACL \"%s\" %s", name, + conditions[cond->type].is_modifier ? US"modifier" : US"condition"); + return FALSE;; + } +Uskip_whitespace(&s); +cond->arg = string_copy(s); +return TRUE; +} + + /************************************************* * Read and parse one ACL * *************************************************/ @@ -760,7 +832,7 @@ acl_block **lastp = &yield; acl_block *this = NULL; acl_condition_block *cond; acl_condition_block **condp = NULL; -uschar * s; +const uschar * s; *error = NULL; @@ -768,7 +840,7 @@ while ((s = (*func)())) { int v, c; BOOL negated = FALSE; - uschar *saveline = s; + const uschar * saveline = s; uschar name[EXIM_DRIVERNAME_MAX]; /* Conditions (but not verbs) are allowed to be negated by an initial @@ -808,16 +880,15 @@ while ((s = (*func)())) *error = string_sprintf("malformed ACL line \"%s\"", saveline); return NULL; } - this = store_get(sizeof(acl_block), GET_UNTAINTED); - *lastp = this; - lastp = &(this->next); + *lastp = this = store_get(sizeof(acl_block), GET_UNTAINTED); + lastp = &this->next; this->next = NULL; this->condition = NULL; this->verb = v; this->srcline = config_lineno; /* for debug output */ this->srcfile = config_filename; /**/ - condp = &(this->condition); - if (*s == 0) continue; /* No condition on this line */ + condp = &this->condition; + if (!*s) continue; /* No condition on this line */ if (*s == '!') { negated = TRUE; @@ -861,7 +932,7 @@ while ((s = (*func)())) cond->u.negated = negated; *condp = cond; - condp = &(cond->next); + condp = &cond->next; /* The "set" modifier is different in that its argument is "name=value" rather than just a value, and we can check the validity of the name, which @@ -874,75 +945,13 @@ while ((s = (*func)())) compatibility. */ if (c == ACLC_SET) -#ifndef DISABLE_DKIM - if ( Ustrncmp(s, "dkim_verify_status", 18) == 0 - || Ustrncmp(s, "dkim_verify_reason", 18) == 0) - { - uschar * endptr = s+18; - - if (isalnum(*endptr)) - { - *error = string_sprintf("invalid variable name after \"set\" in ACL " - "modifier \"set %s\" " - "(only \"dkim_verify_status\" or \"dkim_verify_reason\" permitted)", - s); - return NULL; - } - cond->u.varname = string_copyn(s, 18); - s = endptr; - Uskip_whitespace(&s); - } - else -#endif - { - uschar *endptr; - - if (Ustrncmp(s, "acl_c", 5) != 0 && Ustrncmp(s, "acl_m", 5) != 0) - { - *error = string_sprintf("invalid variable name after \"set\" in ACL " - "modifier \"set %s\" (must start \"acl_c\" or \"acl_m\")", s); - return NULL; - } - - endptr = s + 5; - if (!isdigit(*endptr) && *endptr != '_') - { - *error = string_sprintf("invalid variable name after \"set\" in ACL " - "modifier \"set %s\" (digit or underscore must follow acl_c or acl_m)", - s); - return NULL; - } - - while (*endptr && *endptr != '=' && !isspace(*endptr)) - { - if (!isalnum(*endptr) && *endptr != '_') - { - *error = string_sprintf("invalid character \"%c\" in variable name " - "in ACL modifier \"set %s\"", *endptr, s); - return NULL; - } - endptr++; - } - - cond->u.varname = string_copyn(s + 4, endptr - s - 4); - s = endptr; - Uskip_whitespace(&s); - } + if (!acl_varname_to_cond(&s, cond, error)) return NULL; /* For "set", we are now positioned for the data. For the others, only "endpass" has no data */ if (c != ACLC_ENDPASS) - { - if (*s++ != '=') - { - *error = string_sprintf("\"=\" missing after ACL \"%s\" %s", name, - conditions[c].is_modifier ? US"modifier" : US"condition"); - return NULL; - } - Uskip_whitespace(&s); - cond->arg = string_copy(s); - } + if (!acl_data_to_cond(s, cond, name, error)) return NULL; } return yield; @@ -4894,6 +4903,29 @@ if (is_tainted(value)) fprintf(f, "acl%c %s %d\n%s\n", name[0], name+1, Ustrlen(value), value); } + + + +uschar * +acl_standalone_setvar(const uschar * s) +{ +acl_condition_block * cond = store_get(sizeof(acl_condition_block), GET_UNTAINTED); +uschar * errstr = NULL, * log_msg = NULL; +BOOL endpass_seen; +int e; + +cond->next = NULL; +cond->type = ACLC_SET; +if (!acl_varname_to_cond(&s, cond, &errstr)) return errstr; +if (!acl_data_to_cond(s, cond, US"'-be'", &errstr)) return errstr; + +if (acl_check_condition(ACL_WARN, cond, ACL_WHERE_UNKNOWN, + NULL, 0, &endpass_seen, &errstr, &log_msg, &e) != OK) + return string_sprintf("oops: %s", errstr); +return string_sprintf("variable %s set", cond->u.varname); +} + + #endif /* !MACRO_PREDEF */ /* vi: aw ai sw=2 */ diff --git a/src/src/exim.c b/src/src/exim.c index dec8de4b4..23e206d2a 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1670,6 +1670,8 @@ if (isupper(big_buffer[0])) if (macro_read_assignment(big_buffer)) printf("Defined macro '%s'\n", mlast->name); } +else if (Ustrncmp(big_buffer, "set ", 4) == 0) + printf("%s\n", acl_standalone_setvar(big_buffer+4)); else if ((s = expand_string(big_buffer))) printf("%s\n", CS s); else printf("Failed: %s\n", expand_string_message); diff --git a/src/src/functions.h b/src/src/functions.h index 4caae346d..e71823410 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -100,6 +100,7 @@ extern acl_block *acl_read(uschar *(*)(void), uschar **); extern int acl_check(int, 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 *); extern tree_node *acl_var_create(uschar *); extern void acl_var_write(uschar *, uschar *, void *); @@ -425,7 +426,7 @@ 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 uschar *readconf_printtime(int); -extern uschar *readconf_readname(uschar *, int, uschar *); +extern const uschar *readconf_readname(uschar *, int, const uschar *); extern int readconf_readtime(const uschar *, int, BOOL); extern void readconf_rest(void); extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *); diff --git a/src/src/readconf.c b/src/src/readconf.c index 5068dc60e..83ee51b65 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1172,8 +1172,8 @@ Arguments: Returns: new input pointer */ -uschar * -readconf_readname(uschar *name, int len, uschar *s) +const uschar * +readconf_readname(uschar * name, int len, const uschar * s) { int p = 0; BOOL broken = FALSE; @@ -1632,7 +1632,7 @@ rmark reset_point; int intbase = 0; uschar *inttype = US""; uschar *sptr; -uschar *s = buffer; +const uschar * s = buffer; uschar **str_target; uschar name[EXIM_DRIVERNAME_MAX]; uschar name2[EXIM_DRIVERNAME_MAX]; @@ -1752,337 +1752,337 @@ switch (type) case opt_gidlist: case opt_rewrite: - reset_point = store_mark(); - sptr = read_string(s, name); + reset_point = store_mark(); + sptr = read_string(s, name); - /* Having read a string, we now have several different ways of using it, - depending on the data type, so do another switch. If keeping the actual - string is not required (because it is interpreted), freesptr is set TRUE, - and at the end we reset the pool. */ + /* Having read a string, we now have several different ways of using it, + depending on the data type, so do another switch. If keeping the actual + string is not required (because it is interpreted), freesptr is set TRUE, + and at the end we reset the pool. */ - switch (type) - { - /* If this was a string, set the variable to point to the new string, - and set the flag so its store isn't reclaimed. If it was a list of rewrite - rules, we still keep the string (for printing), and parse the rules into a - control block and flags word. */ - - case opt_stringptr: - str_target = data_block ? USS (US data_block + ol->v.offset) - : USS ol->v.value; - if (ol->type & opt_rep_con) - { - uschar * saved_condition; - /* We already have a condition, we're conducting a crude hack to let - multiple condition rules be chained together, despite storing them in - text form. */ - *str_target = string_copy_perm( (saved_condition = *str_target) - ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}", - saved_condition, sptr) - : sptr, - FALSE); - /* TODO(pdp): there is a memory leak here and just below - when we set 3 or more conditions; I still don't - understand the store mechanism enough to know - what's the safe way to free content from an earlier store. - AFAICT, stores stack, so freeing an early stored item also stores - all data alloc'd after it. If we knew conditions were adjacent, - we could survive that, but we don't. So I *think* we need to take - another bit from opt_type to indicate "malloced"; this seems like - quite a hack, especially for this one case. It also means that - we can't ever reclaim the store from the *first* condition. - - Because we only do this once, near process start-up, I'm prepared to - let this slide for the time being, even though it rankles. */ - } - else if (ol->type & opt_rep_str) + switch (type) { - uschar sep_o = - Ustrncmp(name, "headers_add", 11) == 0 ? '\n' - : Ustrncmp(name, "set", 3) == 0 ? ';' - : ':'; - int sep_i = -(int)sep_o; - const uschar * list = sptr; - uschar * s; - gstring * list_o = NULL; - - if (*str_target) - { - list_o = string_get(Ustrlen(*str_target) + Ustrlen(sptr)); - list_o = string_cat(list_o, *str_target); - } - - while ((s = string_nextinlist(&list, &sep_i, NULL, 0))) - list_o = string_append_listele(list_o, sep_o, s); + /* If this was a string, set the variable to point to the new string, + and set the flag so its store isn't reclaimed. If it was a list of rewrite + rules, we still keep the string (for printing), and parse the rules into a + control block and flags word. */ + + case opt_stringptr: + str_target = data_block ? USS (US data_block + ol->v.offset) + : USS ol->v.value; + if (ol->type & opt_rep_con) + { + uschar * saved_condition; + /* We already have a condition, we're conducting a crude hack to let + multiple condition rules be chained together, despite storing them in + text form. */ + *str_target = string_copy_perm( (saved_condition = *str_target) + ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}", + saved_condition, sptr) + : sptr, + FALSE); + /* TODO(pdp): there is a memory leak here and just below + when we set 3 or more conditions; I still don't + understand the store mechanism enough to know + what's the safe way to free content from an earlier store. + AFAICT, stores stack, so freeing an early stored item also stores + all data alloc'd after it. If we knew conditions were adjacent, + we could survive that, but we don't. So I *think* we need to take + another bit from opt_type to indicate "malloced"; this seems like + quite a hack, especially for this one case. It also means that + we can't ever reclaim the store from the *first* condition. + + Because we only do this once, near process start-up, I'm prepared to + let this slide for the time being, even though it rankles. */ + } + else if (ol->type & opt_rep_str) + { + uschar sep_o = + Ustrncmp(name, "headers_add", 11) == 0 ? '\n' + : Ustrncmp(name, "set", 3) == 0 ? ';' + : ':'; + int sep_i = -(int)sep_o; + const uschar * list = sptr; + uschar * s; + gstring * list_o = NULL; + + if (*str_target) + { + list_o = string_get(Ustrlen(*str_target) + Ustrlen(sptr)); + list_o = string_cat(list_o, *str_target); + } - if (list_o) - *str_target = string_copy_perm(string_from_gstring(list_o), FALSE); - } - else - { - *str_target = sptr; - freesptr = FALSE; - } - break; + while ((s = string_nextinlist(&list, &sep_i, NULL, 0))) + list_o = string_append_listele(list_o, sep_o, s); - case opt_rewrite: - if (data_block) - *USS (US data_block + ol->v.offset) = sptr; - else - *USS ol->v.value = sptr; - freesptr = FALSE; - if (type == opt_rewrite) - { - int sep = 0; - int *flagptr; - uschar *p = sptr; - rewrite_rule **chain; - optionlist *ol3; - - sprintf(CS name2, "*%.50s_rules", name); - ol2 = find_option(name2, oltop, last); - sprintf(CS name2, "*%.50s_flags", name); - ol3 = find_option(name2, oltop, last); - - if (!ol2 || !ol3) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "rewrite rules not available for driver"); + if (list_o) + *str_target = string_copy_perm(string_from_gstring(list_o), FALSE); + } + else + { + *str_target = sptr; + freesptr = FALSE; + } + break; - if (data_block) - { - chain = (rewrite_rule **)(US data_block + ol2->v.offset); - flagptr = (int *)(US data_block + ol3->v.offset); - } - else - { - chain = (rewrite_rule **)ol2->v.value; - flagptr = (int *)ol3->v.value; - } + case opt_rewrite: + if (data_block) + *USS (US data_block + ol->v.offset) = sptr; + else + *USS ol->v.value = sptr; + freesptr = FALSE; + if (type == opt_rewrite) + { + int sep = 0; + int *flagptr; + uschar *p = sptr; + rewrite_rule **chain; + optionlist *ol3; + + sprintf(CS name2, "*%.50s_rules", name); + ol2 = find_option(name2, oltop, last); + sprintf(CS name2, "*%.50s_flags", name); + ol3 = find_option(name2, oltop, last); + + if (!ol2 || !ol3) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "rewrite rules not available for driver"); + + if (data_block) + { + chain = (rewrite_rule **)(US data_block + ol2->v.offset); + flagptr = (int *)(US data_block + ol3->v.offset); + } + else + { + chain = (rewrite_rule **)ol2->v.value; + flagptr = (int *)ol3->v.value; + } - /* This will trap if sptr is tainted. Not sure if that can happen */ - while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE))) - { - rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE); - *chain = next; - chain = &(next->next); - } + /* This will trap if sptr is tainted. Not sure if that can happen */ + while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE))) + { + rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE); + *chain = next; + chain = &(next->next); + } - if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a " - "non-header rewrite - not allowed at transport time -"); - } - break; + if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a " + "non-header rewrite - not allowed at transport time -"); + } + break; - /* If it was an expanded uid, see if there is any expansion to be - done by checking for the presence of a $ character. If there is, save it - in the corresponding *expand_user option field. Otherwise, fall through - to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds - of data. */ + /* If it was an expanded uid, see if there is any expansion to be + done by checking for the presence of a $ character. If there is, save it + in the corresponding *expand_user option field. Otherwise, fall through + to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds + of data. */ - case opt_expand_uid: - sprintf(CS name2, "*expand_%.50s", name); - if ((ol2 = find_option(name2, oltop, last))) - { - uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL; + case opt_expand_uid: + sprintf(CS name2, "*expand_%.50s", name); + if ((ol2 = find_option(name2, oltop, last))) + { + uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL; - if (data_block) - *(USS(US data_block + ol2->v.offset)) = ss; - else - *(USS ol2->v.value) = ss; + if (data_block) + *(USS(US data_block + ol2->v.offset)) = ss; + else + *(USS ol2->v.value) = ss; - if (ss) - { - *(get_set_flag(name, oltop, last, data_block)) = FALSE; - freesptr = FALSE; - break; - } - } + if (ss) + { + *(get_set_flag(name, oltop, last, data_block)) = FALSE; + freesptr = FALSE; + break; + } + } - /* Look up a fixed uid, and also make use of the corresponding gid - if a passwd entry is returned and the gid has not been set. */ + /* Look up a fixed uid, and also make use of the corresponding gid + if a passwd entry is returned and the gid has not been set. */ - case opt_uid: - if (!route_finduser(sptr, &pw, &uid)) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr); - if (data_block) - *(uid_t *)(US data_block + ol->v.offset) = uid; - else - *(uid_t *)ol->v.value = uid; + case opt_uid: + if (!route_finduser(sptr, &pw, &uid)) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr); + if (data_block) + *(uid_t *)(US data_block + ol->v.offset) = uid; + else + *(uid_t *)ol->v.value = uid; - /* Set the flag indicating a fixed value is set */ + /* Set the flag indicating a fixed value is set */ - *(get_set_flag(name, oltop, last, data_block)) = TRUE; + *(get_set_flag(name, oltop, last, data_block)) = TRUE; - /* Handle matching gid if we have a passwd entry: done by finding the - same name with terminating "user" changed to "group"; if not found, - ignore. Also ignore if the value is already set. */ + /* Handle matching gid if we have a passwd entry: done by finding the + same name with terminating "user" changed to "group"; if not found, + ignore. Also ignore if the value is already set. */ - if (pw == NULL) break; - Ustrcpy(name+Ustrlen(name)-4, US"group"); - ol2 = find_option(name, oltop, last); - if (ol2 && ((ol2->type & opt_mask) == opt_gid || - (ol2->type & opt_mask) == opt_expand_gid)) - { - BOOL *set_flag = get_set_flag(name, oltop, last, data_block); - if (!*set_flag) - { - if (data_block) - *((gid_t *)(US data_block + ol2->v.offset)) = pw->pw_gid; - else - *((gid_t *)ol2->v.value) = pw->pw_gid; - *set_flag = TRUE; - } - } - break; + if (pw == NULL) break; + Ustrcpy(name+Ustrlen(name)-4, US"group"); + ol2 = find_option(name, oltop, last); + if (ol2 && ((ol2->type & opt_mask) == opt_gid || + (ol2->type & opt_mask) == opt_expand_gid)) + { + BOOL *set_flag = get_set_flag(name, oltop, last, data_block); + if (!*set_flag) + { + if (data_block) + *((gid_t *)(US data_block + ol2->v.offset)) = pw->pw_gid; + else + *((gid_t *)ol2->v.value) = pw->pw_gid; + *set_flag = TRUE; + } + } + break; - /* If it was an expanded gid, see if there is any expansion to be - done by checking for the presence of a $ character. If there is, save it - in the corresponding *expand_user option field. Otherwise, fall through - to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds - of data. */ + /* If it was an expanded gid, see if there is any expansion to be + done by checking for the presence of a $ character. If there is, save it + in the corresponding *expand_user option field. Otherwise, fall through + to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds + of data. */ - case opt_expand_gid: - sprintf(CS name2, "*expand_%.50s", name); - if ((ol2 = find_option(name2, oltop, last))) - { - uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL; + case opt_expand_gid: + sprintf(CS name2, "*expand_%.50s", name); + if ((ol2 = find_option(name2, oltop, last))) + { + uschar *ss = (Ustrchr(sptr, '$') != NULL) ? sptr : NULL; - if (data_block) - *(USS(US data_block + ol2->v.offset)) = ss; - else - *(USS ol2->v.value) = ss; + if (data_block) + *(USS(US data_block + ol2->v.offset)) = ss; + else + *(USS ol2->v.value) = ss; - if (ss) - { - *(get_set_flag(name, oltop, last, data_block)) = FALSE; - freesptr = FALSE; - break; - } - } + if (ss) + { + *(get_set_flag(name, oltop, last, data_block)) = FALSE; + freesptr = FALSE; + break; + } + } - /* Handle freestanding gid */ + /* Handle freestanding gid */ - case opt_gid: - if (!route_findgroup(sptr, &gid)) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr); - if (data_block) - *((gid_t *)(US data_block + ol->v.offset)) = gid; - else - *((gid_t *)ol->v.value) = gid; - *(get_set_flag(name, oltop, last, data_block)) = TRUE; - break; + case opt_gid: + if (!route_findgroup(sptr, &gid)) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr); + if (data_block) + *((gid_t *)(US data_block + ol->v.offset)) = gid; + else + *((gid_t *)ol->v.value) = gid; + *(get_set_flag(name, oltop, last, data_block)) = TRUE; + break; - /* If it was a uid list, look up each individual entry, and build - a vector of uids, with a count in the first element. Put the vector - in malloc store so we can free the string. (We are reading into - permanent store already.) */ + /* If it was a uid list, look up each individual entry, and build + a vector of uids, with a count in the first element. Put the vector + in malloc store so we can free the string. (We are reading into + permanent store already.) */ - case opt_uidlist: - { - int count = 1; - uid_t *list; - int ptr = 0; - const uschar *p; - const uschar *op = expand_string (sptr); - - if (op == NULL) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s", - name, expand_string_message); - - p = op; - if (*p != 0) count++; - while (*p != 0) if (*p++ == ':' && *p != 0) count++; - list = store_malloc(count*sizeof(uid_t)); - list[ptr++] = (uid_t)(count - 1); - - if (data_block) - *((uid_t **)(US data_block + ol->v.offset)) = list; - else - *((uid_t **)ol->v.value) = list; + case opt_uidlist: + { + int count = 1; + uid_t *list; + int ptr = 0; + const uschar *p; + const uschar *op = expand_string (sptr); + + if (op == NULL) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s", + name, expand_string_message); + + p = op; + if (*p != 0) count++; + while (*p != 0) if (*p++ == ':' && *p != 0) count++; + list = store_malloc(count*sizeof(uid_t)); + list[ptr++] = (uid_t)(count - 1); + + if (data_block) + *((uid_t **)(US data_block + ol->v.offset)) = list; + else + *((uid_t **)ol->v.value) = list; - p = op; - while (count-- > 1) - { - int sep = 0; - /* If p is tainted we trap. Not sure that can happen */ - (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE); - if (!route_finduser(big_buffer, NULL, &uid)) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", - big_buffer); - list[ptr++] = uid; - } - } - break; + p = op; + while (count-- > 1) + { + int sep = 0; + /* If p is tainted we trap. Not sure that can happen */ + (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE); + if (!route_finduser(big_buffer, NULL, &uid)) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", + big_buffer); + list[ptr++] = uid; + } + break; + } - /* If it was a gid list, look up each individual entry, and build - a vector of gids, with a count in the first element. Put the vector - in malloc store so we can free the string. (We are reading into permanent - store already.) */ + /* If it was a gid list, look up each individual entry, and build + a vector of gids, with a count in the first element. Put the vector + in malloc store so we can free the string. (We are reading into permanent + store already.) */ - case opt_gidlist: - { - int count = 1; - gid_t *list; - int ptr = 0; - const uschar *p; - const uschar *op = expand_string (sptr); - - if (!op) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s", - name, expand_string_message); - - p = op; - if (*p != 0) count++; - while (*p != 0) if (*p++ == ':' && *p != 0) count++; - list = store_malloc(count*sizeof(gid_t)); - list[ptr++] = (gid_t)(count - 1); - - if (data_block) - *((gid_t **)(US data_block + ol->v.offset)) = list; - else - *((gid_t **)ol->v.value) = list; + case opt_gidlist: + { + int count = 1; + gid_t *list; + int ptr = 0; + const uschar *p; + const uschar *op = expand_string (sptr); + + if (!op) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s", + name, expand_string_message); + + p = op; + if (*p != 0) count++; + while (*p != 0) if (*p++ == ':' && *p != 0) count++; + list = store_malloc(count*sizeof(gid_t)); + list[ptr++] = (gid_t)(count - 1); + + if (data_block) + *((gid_t **)(US data_block + ol->v.offset)) = list; + else + *((gid_t **)ol->v.value) = list; - p = op; - while (count-- > 1) - { - int sep = 0; - /* If p is tainted we trap. Not sure that can happen */ - (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE); - if (!route_findgroup(big_buffer, &gid)) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", - big_buffer); - list[ptr++] = gid; - } + p = op; + while (count-- > 1) + { + int sep = 0; + /* If p is tainted we trap. Not sure that can happen */ + (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE); + if (!route_findgroup(big_buffer, &gid)) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", + big_buffer); + list[ptr++] = gid; + } + break; + } } - break; - } - /* Release store if the value of the string doesn't need to be kept. */ + /* Release store if the value of the string doesn't need to be kept. */ - if (freesptr) reset_point = store_reset(reset_point); - break; + if (freesptr) reset_point = store_reset(reset_point); + break; /* Expanded boolean: if no characters follow, or if there are no dollar characters, this is a fixed-valued boolean, and we fall through. Otherwise, save the string for later expansion in the alternate place. */ case opt_expand_bool: - if (*s && Ustrchr(s, '$') != 0) - { - sprintf(CS name2, "*expand_%.50s", name); - if ((ol2 = find_option(name2, oltop, last))) + if (*s && Ustrchr(s, '$') != 0) { - reset_point = store_mark(); - sptr = read_string(s, name); - if (data_block) - *(USS(US data_block + ol2->v.offset)) = sptr; - else - *(USS ol2->v.value) = sptr; - freesptr = FALSE; - break; + sprintf(CS name2, "*expand_%.50s", name); + if ((ol2 = find_option(name2, oltop, last))) + { + reset_point = store_mark(); + sptr = read_string(s, name); + if (data_block) + *(USS(US data_block + ol2->v.offset)) = sptr; + else + *(USS ol2->v.value) = sptr; + freesptr = FALSE; + break; + } } - } - /* Fall through */ + /* Fall through */ /* Boolean: if no characters follow, the value is boolvalue. Otherwise look for yes/not/true/false. Some booleans are stored in a single bit in @@ -2095,121 +2095,121 @@ switch (type) case opt_bit: case opt_bool_verify: case opt_bool_set: - if (*s != 0) - { - s = readconf_readname(name2, EXIM_DRIVERNAME_MAX, s); - if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0) - boolvalue = TRUE; - else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0) - boolvalue = FALSE; - else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "\"%s\" is not a valid value for the \"%s\" option", name2, name); - if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2), - US"for boolean option ", name); - } + if (*s) + { + s = readconf_readname(name2, EXIM_DRIVERNAME_MAX, s); + if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0) + boolvalue = TRUE; + else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0) + boolvalue = FALSE; + else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "\"%s\" is not a valid value for the \"%s\" option", name2, name); + if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2), + US"for boolean option ", name); + } - /* Handle single-bit type. */ + /* Handle single-bit type. */ - if (type == opt_bit) - { - int bit = 1 << ((ol->type >> 16) & 31); - int * ptr = data_block - ? (int *)(US data_block + ol->v.offset) - : (int *)ol->v.value; - if (boolvalue) *ptr |= bit; else *ptr &= ~bit; - break; - } + if (type == opt_bit) + { + int bit = 1 << ((ol->type >> 16) & 31); + int * ptr = data_block + ? (int *)(US data_block + ol->v.offset) + : (int *)ol->v.value; + if (boolvalue) *ptr |= bit; else *ptr &= ~bit; + break; + } - /* Handle full BOOL types */ + /* Handle full BOOL types */ - if (data_block) - *((BOOL *)(US data_block + ol->v.offset)) = boolvalue; - else - *((BOOL *)ol->v.value) = boolvalue; + if (data_block) + *((BOOL *)(US data_block + ol->v.offset)) = boolvalue; + else + *((BOOL *)ol->v.value) = boolvalue; - /* Verify fudge */ + /* Verify fudge */ - if (type == opt_bool_verify) - { - sprintf(CS name2, "%.50s_recipient", name + offset); - if ((ol2 = find_option(name2, oltop, last))) - if (data_block) - *((BOOL *)(US data_block + ol2->v.offset)) = boolvalue; - else - *((BOOL *)ol2->v.value) = boolvalue; - } + if (type == opt_bool_verify) + { + sprintf(CS name2, "%.50s_recipient", name + offset); + if ((ol2 = find_option(name2, oltop, last))) + if (data_block) + *((BOOL *)(US data_block + ol2->v.offset)) = boolvalue; + else + *((BOOL *)ol2->v.value) = boolvalue; + } - /* Note that opt_bool_set type is set, if there is somewhere to do so */ + /* Note that opt_bool_set type is set, if there is somewhere to do so */ - else if (type == opt_bool_set) - { - sprintf(CS name2, "*set_%.50s", name + offset); - if ((ol2 = find_option(name2, oltop, last))) - if (data_block) - *((BOOL *)(US data_block + ol2->v.offset)) = TRUE; - else - *((BOOL *)ol2->v.value) = TRUE; - } - break; + else if (type == opt_bool_set) + { + sprintf(CS name2, "*set_%.50s", name + offset); + if ((ol2 = find_option(name2, oltop, last))) + if (data_block) + *((BOOL *)(US data_block + ol2->v.offset)) = TRUE; + else + *((BOOL *)ol2->v.value) = TRUE; + } + break; /* Octal integer */ case opt_octint: - intbase = 8; - inttype = US"octal "; + intbase = 8; + inttype = US"octal "; /* Integer: a simple(ish) case; allow octal and hex formats, and suffixes K, M, G, and T. The different types affect output, not input. */ case opt_mkint: case opt_int: - { - uschar *endptr; - long int lvalue; + { + uschar *endptr; + long int lvalue; - errno = 0; - lvalue = strtol(CS s, CSS &endptr, intbase); + errno = 0; + lvalue = strtol(CS s, CSS &endptr, intbase); - if (endptr == s) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s", - inttype, name); - - if (errno != ERANGE && *endptr) - { - uschar * mp = US"TtGgMmKk\0"; /* YyZzEePpTtGgMmKk */ + if (endptr == s) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s", + inttype, name); - if ((mp = Ustrchr(mp, *endptr))) + if (errno != ERANGE && *endptr) { - endptr++; - do + uschar * mp = US"TtGgMmKk\0"; /* YyZzEePpTtGgMmKk */ + + if ((mp = Ustrchr(mp, *endptr))) { - if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) + endptr++; + do { - errno = ERANGE; - break; + if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) + { + errno = ERANGE; + break; + } + lvalue *= 1024; } - lvalue *= 1024; + while (*(mp += 2)); } - while (*(mp += 2)); } - } - if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "absolute value of integer \"%s\" is too large (overflow)", s); + if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "absolute value of integer \"%s\" is too large (overflow)", s); - while (isspace(*endptr)) endptr++; - if (*endptr) - extra_chars_error(endptr, inttype, US"integer value for ", name); + while (isspace(*endptr)) endptr++; + if (*endptr) + extra_chars_error(endptr, inttype, US"integer value for ", name); - value = (int)lvalue; - } + value = (int)lvalue; + } - if (data_block) - *(int *)(US data_block + ol->v.offset) = value; - else - *(int *)ol->v.value = value; - break; + if (data_block) + *(int *)(US data_block + ol->v.offset) = value; + else + *(int *)ol->v.value = value; + break; /* Integer held in K: again, allow formats and suffixes as above. */ @@ -2261,56 +2261,56 @@ switch (type) /* Fixed-point number: held to 3 decimal places. */ case opt_fixed: - if (sscanf(CS s, "%d%n", &value, &count) != 1) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "fixed-point number expected for %s", name); + if (sscanf(CS s, "%d%n", &value, &count) != 1) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "fixed-point number expected for %s", name); - if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "integer \"%s\" is too large (overflow)", s); + if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "integer \"%s\" is too large (overflow)", s); - value *= 1000; + value *= 1000; - if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "integer \"%s\" is too large (overflow)", s); + if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, + "integer \"%s\" is too large (overflow)", s); - /* We get a coverity error here for using count, as it derived - from the tainted buffer pointed to by s, as parsed by sscanf(). - By the definition of sscanf we must be accessing between start - and end of s (assuming it is nul-terminated...) so ignore the error. */ - /* coverity[tainted_data] */ - if (s[count] == '.') - { - int d = 100; - while (isdigit(s[++count])) + /* We get a coverity error here for using count, as it derived + from the tainted buffer pointed to by s, as parsed by sscanf(). + By the definition of sscanf we must be accessing between start + and end of s (assuming it is nul-terminated...) so ignore the error. */ + /* coverity[tainted_data] */ + if (s[count] == '.') { - value += (s[count] - '0') * d; - d /= 10; + int d = 100; + while (isdigit(s[++count])) + { + value += (s[count] - '0') * d; + d /= 10; + } } - } - while (isspace(s[count])) count++; + while (isspace(s[count])) count++; - if (s[count] != 0) - extra_chars_error(s+count, US"fixed-point value for ", name, US""); + if (s[count] != 0) + extra_chars_error(s+count, US"fixed-point value for ", name, US""); - if (data_block) - *((int *)(US data_block + ol->v.offset)) = value; - else - *((int *)ol->v.value) = value; - break; + if (data_block) + *((int *)(US data_block + ol->v.offset)) = value; + else + *((int *)ol->v.value) = value; + break; /* There's a special routine to read time values. */ case opt_time: - value = readconf_readtime(s, 0, FALSE); - if (value < 0) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s", - name); - if (data_block) - *((int *)(US data_block + ol->v.offset)) = value; - else - *((int *)ol->v.value) = value; - break; + value = readconf_readtime(s, 0, FALSE); + if (value < 0) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s", + name); + if (data_block) + *((int *)(US data_block + ol->v.offset)) = value; + else + *((int *)ol->v.value) = value; + break; /* A time list is a list of colon-separated times, with the first element holding the size of the list and the second the number of @@ -3714,14 +3714,14 @@ readconf_driver_init( optionlist *driver_optionlist, int driver_optionlist_count) { -driver_instance **p = anchor; -driver_instance *d = NULL; -uschar *buffer; +driver_instance ** p = anchor; +driver_instance * d = NULL; +uschar * buffer; while ((buffer = get_config_line())) { uschar name[EXIM_DRIVERNAME_MAX]; - uschar *s; + const uschar * s; /* Read the first name on the line and test for the start of a new driver. A macro definition indicates the end of the previous driver. If this isn't the @@ -4241,8 +4241,6 @@ Returns: nothing static void readconf_acl(void) { -uschar *p; - /* Read each ACL and add it into the tree. Macro (re)definitions are allowed between ACLs. */ @@ -4251,10 +4249,10 @@ acl_line = get_config_line(); while(acl_line) { uschar name[EXIM_DRIVERNAME_MAX]; - tree_node *node; - uschar *error; + tree_node * node; + uschar * error; + const uschar * p = readconf_readname(name, sizeof(name), acl_line); - p = readconf_readname(name, sizeof(name), acl_line); if (isupper(*name) && *p == '=') { if (!macro_read_assignment(acl_line)) exim_exit(EXIT_FAILURE); commit 5c0ee71aefd482e1bfa8720b62e46bfce280a6a3 Author: Jeremy Harris Date: Wed Jun 29 14:14:44 2022 +0100 Build: fix commentary describing configuration directives diff --git a/src/src/EDITME b/src/src/EDITME index 53022e593..3c33dc5f3 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -473,11 +473,11 @@ PCRE2_CONFIG=yes #------------------------------------------------------------------------------ -# Comment out the following line to remove DANE support -# Note: Enabling this unconditionally overrides DISABLE_DNSSEC -# forces you to have SUPPORT_TLS enabled (the default). For DANE under -# GnuTLS we need an additional library. See TLS_LIBS or USE_GNUTLS_PC -# below. +# Comment out the following line to remove DANE support. +# Note: DANE support requires DNSSEC support (the default) and +# SUPPORT_TLS (the default). For DANE under GnuTLS we need an additional +# library. See TLS_LIBS or USE_GNUTLS_PC below. + SUPPORT_DANE=yes #------------------------------------------------------------------------------ @@ -568,7 +568,7 @@ DISABLE_MAL_MKS=yes # By default, Exim has support for checking the AD bit in a DNS response, to # determine if DNSSEC validation was successful. If your system libraries # do not support that bit, then set DISABLE_DNSSEC to "yes" -# Note: Enabling SUPPORT_DANE unconditionally overrides this setting. +# Note: DNSSEC is required for DANE support. # DISABLE_DNSSEC=yes commit 6d05006594ffacbfde1c8c4e759332873a702087 Author: Jeremy Harris Date: Sun Jul 3 12:42:31 2022 +0100 OpenSSL: add IP & DN to OCSP fail log line diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 2b8a4e61c..4c61fc0e6 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2405,7 +2405,7 @@ BIO_puts(bp, "\n"); } static int -tls_client_stapling_cb(SSL *s, void *arg) +tls_client_stapling_cb(SSL * ssl, void * arg) { exim_openssl_state_st * cbinfo = arg; const unsigned char * p; @@ -2415,10 +2415,10 @@ OCSP_BASICRESP * bs; int i; DEBUG(D_tls) debug_printf("Received TLS status callback (OCSP stapling):\n"); -len = SSL_get_tlsext_status_ocsp_resp(s, &p); +len = SSL_get_tlsext_status_ocsp_resp(ssl, &p); if(!p) { /* Expect this when we requested ocsp but got none */ - if (SSL_session_reused(s) && tls_out.ocsp == OCSP_VFIED) + if (SSL_session_reused(ssl) && tls_out.ocsp == OCSP_VFIED) { DEBUG(D_tls) debug_printf(" null, but resumed; ocsp vfy stored with session is good\n"); return 1; @@ -2476,9 +2476,19 @@ if (!(bs = OCSP_response_get1_basic(rsp))) if (ERR_peek_error()) { tls_out.ocsp = OCSP_FAILED; - if (LOGGING(tls_cipher)) log_write(0, LOG_MAIN, - "Received TLS cert status response, itself unverifiable: %s", - ERR_reason_error_string(ERR_peek_error())); + if (LOGGING(tls_cipher)) + { + const uschar * errstr = CUS ERR_reason_error_string(ERR_peek_error()); + static uschar peerdn[256]; + X509_NAME_oneline(X509_get_subject_name(SSL_get_peer_certificate(ssl)), + CS peerdn, sizeof(peerdn)); + log_write(0, LOG_MAIN, + "[%s] %s Received TLS cert (DN: '%.*s') status response, " + "itself unverifiable: %s", + sender_host_address, sender_host_name, + (int)sizeof(peerdn), peerdn, + errstr); + } DEBUG(D_tls) { BIO_printf(bp, "OCSP response verify failure\n"); commit e7ec503729970a03d4509921342bc81313976126 Author: Jeremy Harris Date: Tue Jul 12 22:14:04 2022 +0100 Fix exit on attempt to rewrite a malformed address. Bug 2903 diff --git a/src/src/rewrite.c b/src/src/rewrite.c index bfd78b5f1..90614e626 100644 --- a/src/src/rewrite.c +++ b/src/src/rewrite.c @@ -497,15 +497,14 @@ while (*s) if (!recipient) { - /* Handle unparesable addresses in the header. Slightly ugly because a + /* Log unparesable addresses in the header. Slightly ugly because a null output from the extract can also result from a header without an - address, "To: undisclosed recpients:;" being the classic case. */ + address, "To: undisclosed recpients:;" being the classic case. Ignore + this one and carry on. */ if ((rewrite_rules || routed_old) && Ustrcmp(errmess, "empty address") != 0) - { log_write(0, LOG_MAIN, "rewrite: %s", errmess); - exim_exit(EXIT_FAILURE); - } + loop_reset_point = store_reset(loop_reset_point); continue; } commit 7a97480c2bb86d9385597680ec2d4461e1656193 Author: Jeremy Harris Date: Tue Jul 19 23:37:27 2022 +0100 Event for auth fail diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index edb0adfaf..4a5c44714 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3765,7 +3765,7 @@ smtp_respond(code, len, TRUE, user_msg); static int -smtp_in_auth(auth_instance *au, uschar ** s, uschar ** ss) +smtp_in_auth(auth_instance *au, uschar ** smtp_resp, uschar ** errmsg) { const uschar *set_id = NULL; int rc; @@ -3829,7 +3829,7 @@ switch(rc) received_protocol = (sender_host_address ? protocols : protocols_local) [pextend + pauthed + (tls_in.active.sock >= 0 ? pcrpted:0)]; - *s = *ss = US"235 Authentication succeeded"; + *smtp_resp = *errmsg = US"235 Authentication succeeded"; authenticated_by = au; break; } @@ -3842,34 +3842,34 @@ switch(rc) case DEFER: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = string_sprintf("435 Unable to authenticate at present%s", + *smtp_resp = string_sprintf("435 Unable to authenticate at present%s", auth_defer_user_msg); - *ss = string_sprintf("435 Unable to authenticate at present%s: %s", + *errmsg = string_sprintf("435 Unable to authenticate at present%s: %s", set_id, auth_defer_msg); break; case BAD64: - *s = *ss = US"501 Invalid base64 data"; + *smtp_resp = *errmsg = US"501 Invalid base64 data"; break; case CANCELLED: - *s = *ss = US"501 Authentication cancelled"; + *smtp_resp = *errmsg = US"501 Authentication cancelled"; break; case UNEXPECTED: - *s = *ss = US"553 Initial data not expected"; + *smtp_resp = *errmsg = US"553 Initial data not expected"; break; case FAIL: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"535 Incorrect authentication data"; - *ss = string_sprintf("535 Incorrect authentication data%s", set_id); + *smtp_resp = US"535 Incorrect authentication data"; + *errmsg = string_sprintf("535 Incorrect authentication data%s", set_id); break; default: if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"435 Internal error"; - *ss = string_sprintf("435 Internal error%s: return %d from authentication " + *smtp_resp = US"435 Internal error"; + *errmsg = string_sprintf("435 Internal error%s: return %d from authentication " "check", set_id, rc); break; } @@ -4098,7 +4098,13 @@ while (done <= 0) if (smtp_in_auth(au, &s, &ss) == OK) { DEBUG(D_auth) debug_printf("tls auth succeeded\n"); } else - { DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); } + { + uschar * save_name = sender_host_authenticated; + DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); + sender_host_authenticated = au->name; + (void) event_raise(event_action, US"auth:fail", s, NULL); + sender_host_authenticated = save_name; + } } break; } @@ -4188,6 +4194,8 @@ while (done <= 0) { auth_instance * au; + uschar * smtp_resp, * errmsg; + for (au = auths; au; au = au->next) if (strcmpic(s, au->public_name) == 0 && au->server && (au->advertised || f.allow_auth_unadvertised)) @@ -4195,12 +4203,19 @@ while (done <= 0) if (au) { - c = smtp_in_auth(au, &s, &ss); + int rc = smtp_in_auth(au, &smtp_resp, &errmsg); + + smtp_printf("%s\r\n", FALSE, smtp_resp); + if (rc != OK) + { + uschar * save_name = sender_host_authenticated; - smtp_printf("%s\r\n", FALSE, s); - if (c != OK) log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s", - au->name, host_and_ident(FALSE), ss); + au->name, host_and_ident(FALSE), errmsg); + sender_host_authenticated = au->name; + (void) event_raise(event_action, US"auth:fail", smtp_resp, NULL); + sender_host_authenticated = save_name; + } } else done = synprot_error(L_smtp_protocol_error, 504, NULL, @@ -4389,7 +4404,7 @@ while (done <= 0) else { - char *ss; + char * ss; int codelen = 4; smtp_message_code(&smtp_code, &codelen, &user_msg, NULL, TRUE); s = string_sprintf("%.*s%s", codelen, smtp_code, user_msg); commit 9b3a1518f52a1de4469c85af8dde74489b974a66 Author: Jeremy Harris Date: Thu Jul 21 16:41:25 2022 +0100 Event for auth fail: client side diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 4a5c44714..11e7436b9 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -4099,11 +4099,16 @@ while (done <= 0) { DEBUG(D_auth) debug_printf("tls auth succeeded\n"); } else { - uschar * save_name = sender_host_authenticated; DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); - sender_host_authenticated = au->name; - (void) event_raise(event_action, US"auth:fail", s, NULL); - sender_host_authenticated = save_name; +#ifndef DISABLE_EVENT + { + uschar * save_name = sender_host_authenticated, * logmsg; + sender_host_authenticated = au->name; + if ((logmsg = event_raise(event_action, US"auth:fail", s, NULL))) + log_write(0, LOG_MAIN, "%s", logmsg); + sender_host_authenticated = save_name; + } +#endif } } break; @@ -4208,13 +4213,19 @@ while (done <= 0) smtp_printf("%s\r\n", FALSE, smtp_resp); if (rc != OK) { - uschar * save_name = sender_host_authenticated; - - log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s", - au->name, host_and_ident(FALSE), errmsg); - sender_host_authenticated = au->name; - (void) event_raise(event_action, US"auth:fail", smtp_resp, NULL); - sender_host_authenticated = save_name; + uschar * logmsg = NULL; +#ifndef DISABLE_EVENT + {uschar * save_name = sender_host_authenticated; + sender_host_authenticated = au->name; + logmsg = event_raise(event_action, US"auth:fail", smtp_resp, NULL); + sender_host_authenticated = save_name; + } +#endif + if (logmsg) + log_write(0, LOG_MAIN|LOG_REJECT, "%s", logmsg); + else + log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s", + au->name, host_and_ident(FALSE), errmsg); } } else diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 6eee04d03..d7f251b0b 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1476,7 +1476,7 @@ rc = (au->info->clientcode)(au, sx, ob->command_timeout, sx->buffer, sizeof(sx->buffer)); sx->outblock.authenticating = FALSE; driver_srcfile = authenticator_name = NULL; driver_srcline = 0; -DEBUG(D_transport) debug_printf("%s authenticator yielded %d\n", au->name, rc); +DEBUG(D_transport) debug_printf("%s authenticator yielded %s\n", au->name, rc_names[rc]); /* A temporary authentication failure must hold up delivery to this host. After a permanent authentication failure, we carry on @@ -1500,10 +1500,25 @@ switch(rc) /* Failure after reading a response */ case FAIL: + { + uschar * logmsg = NULL; + if (errno != 0 || sx->buffer[0] != '5') return FAIL; - log_write(0, LOG_MAIN, "%s authenticator failed H=%s [%s] %s", - au->name, host->name, host->address, sx->buffer); +#ifndef DISABLE_EVENT + { + uschar * save_name = sender_host_authenticated; + sender_host_authenticated = au->name; + if ((logmsg = event_raise(sx->conn_args.tblock->event_action, US"auth:fail", + sx->buffer, NULL))) + log_write(0, LOG_MAIN, "%s", logmsg); + sender_host_authenticated = save_name; + } +#endif + if (!logmsg) + log_write(0, LOG_MAIN, "%s authenticator failed H=%s [%s] %s", + au->name, host->name, host->address, sx->buffer); break; + } /* Failure by some other means. In effect, the authenticator decided it wasn't prepared to handle this case. Typically this commit 93c722ce0549360af68269f088f4e59ed8fc130e Author: Jeremy Harris Date: Sun Aug 7 17:00:27 2022 +0100 SPF: fix memory accounting for error case diff --git a/src/src/spf.c b/src/src/spf.c index db6eea3a8..a8c0f75c4 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -204,7 +204,7 @@ spf_nxdomain = SPF_dns_rr_new_init(spf_dns_server, "", ns_t_any, 24 * 60 * 60, HOST_NOT_FOUND); if (!spf_nxdomain) { - free(spf_dns_server); + store_free(spf_dns_server); return NULL; } commit ef57b25bfa7623c3f8a8e65f927165c4ddc7c43b Author: Jeremy Harris Date: Mon Aug 8 19:46:03 2022 +0100 Symlink following for TLS creds files diff --git a/src/src/tls.c b/src/src/tls.c index 3ed37bbb0..76e72b5f5 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -143,15 +143,29 @@ static BOOL tls_set_one_watch(const uschar * filename) # ifdef EXIM_HAVE_INOTIFY { +uschar buf[PATH_MAX]; +ssize_t len; uschar * s; if (Ustrcmp(filename, "system,cache") == 0) return TRUE; - if (!(s = Ustrrchr(filename, '/'))) return FALSE; + +for (unsigned loop = 20; + (len = readlink(CCS filename, CS buf, sizeof(buf))) >= 0; ) + { /* a symlink */ + if (--loop == 0) { errno = ELOOP; return FALSE; } + filename = buf[0] == '/' + ? string_copyn(buf, (unsigned)len) /* mem released by tls_set_watch */ + : string_sprintf("%.*s/%.*s", (int)(s - filename), (int)len); + s = Ustrrchr(filename, '/'); + } +if (errno != EINVAL) + return FALSE; /* other error */ + +/* not a symlink */ s = string_copyn(filename, s - filename); /* mem released by tls_set_watch */ -DEBUG(D_tls) debug_printf("watch dir '%s'\n", s); -/*XXX unclear what effect symlinked files will have for inotify */ +DEBUG(D_tls) debug_printf("watch dir '%s'\n", s); if (inotify_add_watch(tls_watch_fd, CCS s, IN_ONESHOT | IN_CLOSE_WRITE | IN_DELETE | IN_DELETE_SELF commit b855ee2fb3776667c8b08aa6b80453d60e4fb509 Author: Jeremy Harris Date: Tue Aug 9 10:57:56 2022 +0100 Filter rDNS returns for bad chars diff --git a/src/src/globals.c b/src/src/globals.c index c95d24b47..574ee60a4 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1016,6 +1016,10 @@ uschar *keep_environment = NULL; int keep_malformed = 4*24*60*60; /* 4 days */ uschar *eldap_dn = NULL; +const uschar *letter_digit_hyphen_dot = + US"abcdefghijklmnopqrstuvwxyz" + ".-0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #ifdef EXPERIMENTAL_ESMTP_LIMITS uschar *limits_advertise_hosts = US"*"; #endif diff --git a/src/src/globals.h b/src/src/globals.h index c9ef5e484..3f3c798b7 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -680,6 +680,7 @@ extern uschar *keep_environment; /* Whitelist for environment variables */ extern int keep_malformed; /* Time to keep malformed messages */ extern uschar *eldap_dn; /* Where LDAP DNs are left */ +extern const uschar *letter_digit_hyphen_dot; /* Legitimate DNS host name chars */ #ifdef EXPERIMENTAL_ESMTP_LIMITS extern uschar *limits_advertise_hosts; /* for banner/EHLO pipelining */ #endif diff --git a/src/src/host.c b/src/src/host.c index fed9f4b5f..b6c2ea082 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -84,13 +84,13 @@ random_number(int limit) if (limit < 1) return 0; if (random_seed == 0) - { - if (f.running_in_test_harness) random_seed = 42; else + if (f.running_in_test_harness) + random_seed = 42; + else { int p = (int)getpid(); random_seed = (int)time(NULL) ^ ((p << 16) | p); } - } random_seed = 1103515245 * random_seed + 12345; return (unsigned int)(random_seed >> 16) % limit; } @@ -1646,6 +1646,7 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR) { uschar * s = store_get(ssize, GET_TAINTED); /* names are tainted */ + unsigned slen; /* If an overlong response was received, the data will have been truncated and dn_expand may fail. */ @@ -1658,13 +1659,19 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) break; } - store_release_above(s + Ustrlen(s) + 1); - if (!s[0]) + store_release_above(s + (slen = Ustrlen(s)) + 1); + if (!*s) { HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " "empty name: treated as non-existent host name\n"); continue; } + if (Ustrspn(s, letter_digit_hyphen_dot) != slen) + { + HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " + "illegal name (bad char): treated as non-existent host name\n"); + continue; + } if (!sender_host_name) sender_host_name = s; else *aptr++ = s; while (*s) { *s = tolower(*s); s++; } commit 766af058762b2c4e21b69f335adf77265fe9509a Author: Jeremy Harris Date: Sat Aug 13 20:58:29 2022 +0100 Dump stack for "bad memory reference". Bug 2904 diff --git a/src/src/exim.c b/src/src/exim.c index 23e206d2a..ea4286af3 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -232,7 +232,7 @@ exit(1); ***********************************************/ #define STACKDUMP_MAX 24 -static void +void stackdump(void) { #ifndef NO_EXECINFO diff --git a/src/src/functions.h b/src/src/functions.h index e71823410..92a4831e3 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -547,6 +547,7 @@ extern int stdin_ferror(void); extern BOOL stdin_hasc(void); extern int stdin_ungetc(int); +extern void stackdump(void); extern void store_exit(void); extern void store_init(void); extern void store_writeprotect(int); diff --git a/src/src/store.c b/src/src/store.c index c98fcbf21..d99d2ab69 100644 --- a/src/src/store.c +++ b/src/src/store.c @@ -274,6 +274,9 @@ for (pp = paired_pools; pp < paired_pools + N_PAIRED_POOLS; pp++) for (b = pp->chainbase; b; b = b->next) if (is_pointer_in_block(b, p)) return pp; +#ifndef COMPILE_UTILITY +stackdump(); +#endif log_write(0, LOG_MAIN|LOG_PANIC_DIE, "bad memory reference; pool not found, at %s %d", func, linenumber); return NULL; commit fd9f0b7354ffc2986f0b2e7b074117feb29b5102 Author: Jeremy Harris Date: Sat Aug 13 20:19:16 2022 +0100 Partial workaround for TCP Fast Open issue. Bug 2907 diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 7b7bdf752..7f364d942 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -372,7 +372,7 @@ if (!save_errno) # ifdef TCP_FASTOPEN_CONNECT else { /* expecting client data */ - debug_printf(" set up lazy-connect\n"); + DEBUG(D_transport|D_acl|D_v) debug_printf(" set up lazy-connect\n"); setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, US &on, sizeof(on)); /* fastopen_blob = NULL; lazy TFO, triggered by data write */ } diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index d7f251b0b..bbff1cad8 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -5312,6 +5312,17 @@ retry_non_continued: uschar *retry_message_key = NULL; uschar *serialize_key = NULL; + /* Deal slightly better with a possible Linux kernel bug that results + in intermittent TFO-conn fails deep into the TCP flow. Bug 2907 tracks. + Hack: Clear TFO option for any further hosts on this tpt run. */ + + if (total_hosts_tried > 0) + { + DEBUG(D_transport|D_acl|D_v) + debug_printf("Clearing TFO as not first host for message\n"); + ob->hosts_try_fastopen = US""; + } + /* Default next host is next host. :-) But this can vary if the hosts_max_try limit is hit (see below). It may also be reset if a host address is looked up here (in case the host was multihomed). */ commit a1ec98dd963767551514cae86c7af56c6aa3f36e Author: Ulrich Landgraf Date: Mon Aug 15 16:50:36 2022 +0100 Fix symlink-following. Bug 2909 Broken-by: ef57b25bfa diff --git a/src/src/tls.c b/src/src/tls.c index 76e72b5f5..32b29ee3e 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -156,7 +156,7 @@ for (unsigned loop = 20; if (--loop == 0) { errno = ELOOP; return FALSE; } filename = buf[0] == '/' ? string_copyn(buf, (unsigned)len) /* mem released by tls_set_watch */ - : string_sprintf("%.*s/%.*s", (int)(s - filename), (int)len); + : string_sprintf("%.*s/%.*s", (int)(s - filename), filename, (int)len, buf); s = Ustrrchr(filename, '/'); } if (errno != EINVAL) commit 9b5fdee115fdd09588bd03f3ebdc85cfe7357fc5 Author: Jeremy Harris Date: Mon Aug 15 18:42:28 2022 +0100 OpenSSL: strip spaces & newlines from cert signature expansion diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c index 168e35b7f..ac353b25f 100644 --- a/src/src/tlscert-openssl.c +++ b/src/src/tlscert-openssl.c @@ -261,11 +261,19 @@ if (X509_print_ex(bp, (X509 *)cert, 0, X509_FLAG_NO_AUX) == 1) { long len = BIO_get_mem_data(bp, &cp); + gstring * g = NULL; /* Strip leading "Signature Algorithm" line */ while (*cp && *cp != '\n') { cp++; len--; } + if (*cp) { cp++; len--; } - cp = string_copyn(cp+1, len-1); + /* Strip possible leading " Signature Value:\n" (seen with OpenSSL 3.0.5) */ + if (Ustrncmp(cp, " Signature Value:\n", 21) == 0) { cp += 21; len -= 21; } + + /* Copy only hexchars and colon (different OpenSSL versions do different spacing) */ + for ( ; len-- && *cp; cp++) + if (Ustrchr("0123456789abcdef:", *cp)) g = string_catn(g, cp, 1); + cp = string_from_gstring(g); } BIO_free(bp); return cp; commit 4e3a01c2607937d5fbc477b6e14495adc2281941 Author: Jeremy Harris Date: Thu Aug 18 20:47:01 2022 +0100 GSASL: use tls-exporter for SCRAM*PLUS methods under TLSv1.3 diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c index bae5f081b..e49e83b81 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl_exim.c @@ -39,22 +39,34 @@ static void dummy(int x) { dummy2(x-1); } #include "gsasl_exim.h" -#if GSASL_VERSION_MINOR >= 10 -# define EXIM_GSASL_HAVE_SCRAM_SHA_256 -# define EXIM_GSASL_SCRAM_S_KEY +#if GSASL_VERSION_MAJOR == 2 -#elif GSASL_VERSION_MINOR == 9 # define EXIM_GSASL_HAVE_SCRAM_SHA_256 +# define EXIM_GSASL_SCRAM_S_KEY +# if GSASL_VERSION_MINOR >= 1 +# define EXIM_GSASL_HAVE_EXPORTER +# elif GSASL_VERSION_PATCH >= 1 +# define EXIM_GSASL_HAVE_EXPORTER +# endif -# if GSASL_VERSION_PATCH >= 1 +#elif GSASL_VERSION_MAJOR == 1 +# if GSASL_VERSION_MINOR >= 10 +# define EXIM_GSASL_HAVE_SCRAM_SHA_256 # define EXIM_GSASL_SCRAM_S_KEY -# endif -# if GSASL_VERSION_PATCH < 2 + +# elif GSASL_VERSION_MINOR == 9 +# define EXIM_GSASL_HAVE_SCRAM_SHA_256 + +# if GSASL_VERSION_PATCH >= 1 +# define EXIM_GSASL_SCRAM_S_KEY +# endif +# if GSASL_VERSION_PATCH < 2 +# define CHANNELBIND_HACK +# endif + +# else # define CHANNELBIND_HACK # endif - -#else -# define CHANNELBIND_HACK #endif /* Convenience for testing strings */ @@ -258,7 +270,7 @@ if (!cb_state) if (prop == GSASL_CB_TLS_UNIQUE) { uschar * s; - if ((s = gsasl_callback_hook_get(ctx))) + if ((s = gsasl_callback_hook_get(ctx))) /* Gross hack for early lib vers */ { HDEBUG(D_auth) debug_printf("GSASL_CB_TLS_UNIQUE from ctx hook\n"); gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CS s); @@ -332,6 +344,9 @@ switch (prop) #ifdef EXIM_GSASL_SCRAM_S_KEY case GSASL_SCRAM_STOREDKEY: return US"SCRAM_STOREDKEY"; case GSASL_SCRAM_SERVERKEY: return US"SCRAM_SERVERKEY"; +#endif +#ifdef EXIM_GSASL_HAVE_EXPORTER /* v. 2.1.0 */ + case GSASL_CB_TLS_EXPORTER: return US"CB_TLS_EXPORTER"; #endif case GSASL_CB_TLS_UNIQUE: return US"CB_TLS_UNIQUE"; case GSASL_SAML20_IDP_IDENTIFIER: return US"SAML20_IDP_IDENTIFIER"; @@ -351,6 +366,14 @@ switch (prop) return CUS string_sprintf("(unknown prop: %d)", (int)prop); } +static void +preload_prop(Gsasl_session * sctx, Gsasl_property propcode, const uschar * val) +{ +DEBUG(D_auth) debug_printf("preloading prop %s val %s\n", + gsasl_prop_code_to_name(propcode), val); +gsasl_property_set(sctx, propcode, CCS val); +} + /************************************************* * Server entry point * *************************************************/ @@ -358,12 +381,12 @@ return CUS string_sprintf("(unknown prop: %d)", (int)prop); /* For interface, see auths/README */ int -auth_gsasl_server(auth_instance *ablock, uschar *initial_data) +auth_gsasl_server(auth_instance * ablock, uschar * initial_data) { -char *tmps; -char *to_send, *received; -Gsasl_session *sctx = NULL; -auth_gsasl_options_block *ob = +uschar * tmps; +char * to_send, * received; +Gsasl_session * sctx = NULL; +auth_gsasl_options_block * ob = (auth_gsasl_options_block *)(ablock->options_block); struct callback_exim_state cb_state; int rc, auth_result, exim_error, exim_error_override; @@ -406,18 +429,18 @@ cb_state.ablock = ablock; cb_state.currently = CURRENTLY_SERVER; gsasl_session_hook_set(sctx, &cb_state); -tmps = CS expand_string(ob->server_service); -gsasl_property_set(sctx, GSASL_SERVICE, tmps); -tmps = CS expand_string(ob->server_hostname); -gsasl_property_set(sctx, GSASL_HOSTNAME, tmps); +tmps = expand_string(ob->server_service); +preload_prop(sctx, GSASL_SERVICE, tmps); +tmps = expand_string(ob->server_hostname); +preload_prop(sctx, GSASL_HOSTNAME, tmps); if (ob->server_realm) { - tmps = CS expand_string(ob->server_realm); + tmps = expand_string(ob->server_realm); if (tmps && *tmps) - gsasl_property_set(sctx, GSASL_REALM, tmps); + preload_prop(sctx, GSASL_REALM, tmps); } /* We don't support protection layers. */ -gsasl_property_set(sctx, GSASL_QOPS, "qop-auth"); +preload_prop(sctx, GSASL_QOPS, US "qop-auth"); #ifndef DISABLE_TLS if (tls_in.channelbinding) @@ -451,7 +474,12 @@ if (tls_in.channelbinding) HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n", ablock->name); # ifndef CHANNELBIND_HACK - gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CCS tls_in.channelbinding); + preload_prop(sctx, +# ifdef EXIM_GSASL_HAVE_EXPORTER + tls_in.channelbind_exporter ? GSASL_CB_TLS_EXPORTER : +# endif + GSASL_CB_TLS_UNIQUE, + tls_in.channelbinding); # endif } else @@ -811,13 +839,13 @@ return TRUE; int auth_gsasl_client( - auth_instance *ablock, /* authenticator block */ + auth_instance * ablock, /* authenticator block */ void * sx, /* connection */ int timeout, /* command timeout */ - uschar *buffer, /* buffer for reading response */ + uschar * buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ { -auth_gsasl_options_block *ob = +auth_gsasl_options_block * ob = (auth_gsasl_options_block *)(ablock->options_block); Gsasl_session * sctx = NULL; struct callback_exim_state cb_state; @@ -883,7 +911,12 @@ if (tls_out.channelbinding) HDEBUG(D_auth) debug_printf("Auth %s: Enabling channel-binding\n", ablock->name); # ifndef CHANNELBIND_HACK - gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CCS tls_out.channelbinding); + preload_prop(sctx, +# ifdef EXIM_GSASL_HAVE_EXPORTER + tls_out.channelbind_exporter ? GSASL_CB_TLS_EXPORTER : +# endif + GSASL_CB_TLS_UNIQUE, + tls_out.channelbinding); # endif } else @@ -968,9 +1001,18 @@ HDEBUG(D_auth) debug_printf("GNU SASL callback %s for %s/%s as client\n", gsasl_prop_code_to_name(prop), ablock->name, ablock->public_name); switch (prop) { - case GSASL_CB_TLS_UNIQUE: /*XXX should never get called for this */ - HDEBUG(D_auth) - debug_printf(" filling in\n"); +#ifdef EXIM_GSASL_HAVE_EXPORTER + case GSASL_CB_TLS_EXPORTER: /* Should never get called for this, as pre-set */ + if (!tls_out.channelbind_exporter) break; + HDEBUG(D_auth) debug_printf(" filling in\n"); + gsasl_property_set(sctx, GSASL_CB_TLS_EXPORTER, CCS tls_out.channelbinding); + return GSASL_OK; +#endif + case GSASL_CB_TLS_UNIQUE: /* Should never get called for this, as pre-set */ +#ifdef EXIM_GSASL_HAVE_EXPORTER + if (tls_out.channelbind_exporter) break; +#endif + HDEBUG(D_auth) debug_printf(" filling in\n"); gsasl_property_set(sctx, GSASL_CB_TLS_UNIQUE, CCS tls_out.channelbinding); return GSASL_OK; case GSASL_SCRAM_SALTED_PASSWORD: diff --git a/src/src/globals.h b/src/src/globals.h index 3f3c798b7..c40ae4beb 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -117,6 +117,7 @@ typedef struct { #endif BOOL verify_override:1; /* certificate_verified only due to tls_try_verify_hosts */ BOOL ext_master_secret:1; /* extended-master-secret was used */ + BOOL channelbind_exporter:1; /* channelbinding is EXPORTER not UNIQUE */ } tls_support; extern tls_support tls_in; extern tls_support tls_out; diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index fcb8f7ac4..7a6db94e1 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -121,6 +121,10 @@ require current GnuTLS, then we'll drop support for the ancient libraries). # endif #endif +#if GNUTLS_VERSION_NUMBER >= 0x030702 +# define HAVE_GNUTLS_EXPORTER +#endif + #ifndef DISABLE_OCSP # include #endif @@ -646,14 +650,20 @@ tlsp->channelbinding = NULL; #ifdef HAVE_GNUTLS_SESSION_CHANNEL_BINDING { gnutls_datum_t channel = {.data = NULL, .size = 0}; - uschar * buf; int rc; -# ifdef HAVE_GNUTLS_PRF_RFC5705 +# ifdef HAVE_GNUTLS_EXPORTER + if (gnutls_protocol_get_version(state->session) >= GNUTLS_TLS1_3) + { + rc = gnutls_session_channel_binding(state->session, GNUTLS_CB_TLS_EXPORTER, &channel); + tlsp->channelbind_exporter = TRUE; + } + else +# elif defined(HAVE_GNUTLS_PRF_RFC5705) /* Older libraries may not have GNUTLS_TLS1_3 defined! */ if (gnutls_protocol_get_version(state->session) > GNUTLS_TLS1_2) { - buf = store_get(32, state->host ? GET_TAINTED : GET_UNTAINTED); + uschar * buf = store_get(32, state->host ? GET_TAINTED : GET_UNTAINTED); rc = gnutls_prf_rfc5705(state->session, (size_t)24, "EXPORTER-Channel-Binding", (size_t)0, "", 32, CS buf); @@ -670,11 +680,11 @@ tlsp->channelbinding = NULL; { int old_pool = store_pool; /* Declare the taintedness of the binding info. On server, untainted; on - client, tainted - being the Finish msg from the server. */ + client, tainted if we used the Finish msg from the server. */ store_pool = POOL_PERM; tlsp->channelbinding = b64encode_taint(CUS channel.data, (int)channel.size, - state->host ? GET_TAINTED : GET_UNTAINTED); + !tlsp->channelbind_exporter && state->host ? GET_TAINTED : GET_UNTAINTED); store_pool = old_pool; DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage\n"); } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 4c61fc0e6..22750d273 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -94,6 +94,10 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_OPENSSL_CIPHER_GET_ID #endif +#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x030000000L) +# define EXIM_HAVE_EXPORT_CHNL_BNGNG +#endif + #if !defined(LIBRESSL_VERSION_NUMBER) \ || LIBRESSL_VERSION_NUMBER >= 0x20010000L # if !defined(OPENSSL_NO_ECDH) @@ -111,11 +115,16 @@ change this guard and punt the issue for a while longer. */ # define OPENSSL_HAVE_KEYLOG_CB # define OPENSSL_HAVE_NUM_TICKETS # define EXIM_HAVE_OPENSSL_CIPHER_STD_NAME +# define EXIM_HAVE_EXP_CHNL_BNGNG # else # define OPENSSL_BAD_SRVR_OURCERT # endif #endif +#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x010002000L) +# define EXIM_HAVE_EXPORT_CHNL_BNGNG +#endif + #if !defined(EXIM_HAVE_OPENSSL_TLSEXT) && !defined(DISABLE_OCSP) # warning "OpenSSL library version too old; define DISABLE_OCSP in Makefile" # define DISABLE_OCSP @@ -3170,6 +3179,52 @@ tls_dump_keylog(SSL * ssl) } +/* Channel-binding info for authenticators +See description in https://paquier.xyz/postgresql-2/channel-binding-openssl/ +for pre-TLS1.3 +*/ + +static void +tls_get_channel_binding(SSL * ssl, tls_support * tlsp, const void * taintval) +{ +uschar c, * s; +size_t len; + +#ifdef EXIM_HAVE_EXPORT_CHNL_BNGNG +if (SSL_version(ssl) >= TLS1_3_VERSION) + { + /* It's not documented by OpenSSL how big the output buffer must be. + The OpenSSL testcases use 80 bytes but don't say why. The GnuTLS impl only + serves out 32B. RFC 9266 says it is 32B. + Interop fails unless we use the same each end. */ + len = 32; + + tlsp->channelbind_exporter = TRUE; + taintval = GET_UNTAINTED; + if (SSL_export_keying_material(ssl, + s = store_get((int)len, taintval), len, + "EXPORTER-Channel-Binding", (size_t) 24, + NULL, 0, 0) != 1) + len = 0; + } +else +#endif + { + len = SSL_get_peer_finished(ssl, &c, 0); + len = SSL_get_peer_finished(ssl, s = store_get((int)len, taintval), len); + } + +if (len > 0) + { + int old_pool = store_pool; + store_pool = POOL_PERM; + tlsp->channelbinding = b64encode_taint(CUS s, (int)len, taintval); + store_pool = old_pool; + DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage %p %p\n", tlsp->channelbinding, tlsp); + } +} + + /************************************************* * Start a TLS session in a server * *************************************************/ @@ -3446,6 +3501,7 @@ else DEBUG(D_tls) adjust the input functions to read via TLS, and initialize things. */ #ifdef SSL_get_extms_support +/*XXX what does this return for tls1.3 ? */ tls_in.ext_master_secret = SSL_get_extms_support(ssl) == 1; #endif peer_cert(ssl, &tls_in, peerdn, sizeof(peerdn)); @@ -3478,19 +3534,7 @@ DEBUG(D_tls) tls_in.ourcert = crt ? X509_dup(crt) : NULL; } -/* Channel-binding info for authenticators -See description in https://paquier.xyz/postgresql-2/channel-binding-openssl/ */ - { - uschar c, * s; - size_t len = SSL_get_peer_finished(ssl, &c, 0); - int old_pool = store_pool; - - SSL_get_peer_finished(ssl, s = store_get((int)len, GET_UNTAINTED), len); - store_pool = POOL_PERM; - tls_in.channelbinding = b64encode_taint(CUS s, (int)len, GET_UNTAINTED); - store_pool = old_pool; - DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage %p\n", tls_in.channelbinding); - } +tls_get_channel_binding(ssl, &tls_in, GET_UNTAINTED); /* Only used by the server-side tls (tls_in), including tls_getc. Client-side (tls_out) reads (seem to?) go via @@ -4168,18 +4212,7 @@ tlsp->cipher_stdname = cipher_stdname_ssl(exim_client_ctx->ssl); } /*XXX will this work with continued-TLS? */ -/* Channel-binding info for authenticators */ - { - uschar c, * s; - size_t len = SSL_get_finished(exim_client_ctx->ssl, &c, 0); - int old_pool = store_pool; - - SSL_get_finished(exim_client_ctx->ssl, s = store_get((int)len, GET_TAINTED), len); - store_pool = POOL_PERM; - tlsp->channelbinding = b64encode_taint(CUS s, (int)len, GET_TAINTED); - store_pool = old_pool; - DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage %p %p\n", tlsp->channelbinding, tlsp); - } +tls_get_channel_binding(exim_client_ctx->ssl, tlsp, GET_TAINTED); tlsp->active.sock = cctx->sock; tlsp->active.tls_ctx = exim_client_ctx; diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index bbff1cad8..0fca4584d 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -4695,7 +4695,10 @@ if (sx->completed_addr && sx->ok && sx->send_quit) open, we must shut down TLS. Not all MTAs allow for the continuation of the SMTP session when TLS is shut down. We test for this by sending a new EHLO. If we don't get a good response, we don't attempt to pass - the socket on. */ + the socket on. + NB: TLS close is *required* per RFC 9266 when tls-exporter info has + been used, which we do under TLSv1.3 for the gsasl SCRAM*PLUS methods. + But we were always doing it anyway. */ tls_close(sx->cctx.tls_ctx, sx->send_tlsclose ? TLS_SHUTDOWN_WAIT : TLS_SHUTDOWN_WONLY); commit ba47f2909371787b76d213ea012c6b950f9f8080 Author: Jeremy Harris Date: Thu Aug 18 21:20:15 2022 +0100 OpenSSL: unbreak build with older library version Broken-by: 4e3a01c260 diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 22750d273..c46bc75a5 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -3191,7 +3191,7 @@ uschar c, * s; size_t len; #ifdef EXIM_HAVE_EXPORT_CHNL_BNGNG -if (SSL_version(ssl) >= TLS1_3_VERSION) +if (SSL_version(ssl) > TLS1_2_VERSION) { /* It's not documented by OpenSSL how big the output buffer must be. The OpenSSL testcases use 80 bytes but don't say why. The GnuTLS impl only commit 9641b6648d2d2d87e14856f9c3383deb86772757 Author: Jeremy Harris Date: Sat Aug 20 16:43:03 2022 +0100 OpenSSL: fix reload of changed OCSP proof diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index c46bc75a5..c63e56c0e 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1477,12 +1477,12 @@ return; static void -ocsp_free_response_list(exim_openssl_state_st * cbinfo) +ocsp_free_response_list(exim_openssl_state_st * state) { -for (ocsp_resplist * olist = cbinfo->u_ocsp.server.olist; olist; +for (ocsp_resplist * olist = state->u_ocsp.server.olist; olist; olist = olist->next) OCSP_RESPONSE_free(olist->resp); -cbinfo->u_ocsp.server.olist = NULL; +state->u_ocsp.server.olist = NULL; } #endif /*!DISABLE_OCSP*/ @@ -1574,6 +1574,11 @@ else if (olist && !*olist) olist = NULL; + /* If doing a re-expand after SNI, avoid reloading the OCSP + responses when the list of filenames has not changed. + The creds-invali on content change wipes file_expanded, so that + always reloads here. */ + if ( state->u_ocsp.server.file_expanded && olist && (Ustrcmp(olist, state->u_ocsp.server.file_expanded) == 0)) { @@ -1918,6 +1923,7 @@ tls_server_creds_invalidate(void) { SSL_CTX_free(state_server.lib_state.lib_ctx); state_server.lib_state = null_tls_preload; +state_server.u_ocsp.server.file_expanded = NULL; } @@ -2763,7 +2769,7 @@ if (state->lib_state.conn_certs) else { #ifndef DISABLE_OCSP - if (!host) + if (!host) /* server */ { state->u_ocsp.server.file = ocsp_file; state->u_ocsp.server.file_expanded = NULL; diff --git a/src/src/tls.c b/src/src/tls.c index 32b29ee3e..d7cefce67 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -361,6 +361,8 @@ tls_watch_invalidate(); #endif tls_server_creds_invalidate(); + +/* _expire is for a time-limited selfsign server cert */ tls_creds_expire = (lifetime = tls_server_creds_init()) ? time(NULL) + lifetime : 0; commit 1072af868662ea8fec30454c2d62afdee24f2c8e Author: Jeremy Harris Date: Tue Aug 23 18:34:29 2022 +0100 OpenSSL: fix non-OCSP build Broken-by: 9641b6648d diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index c63e56c0e..043755c84 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1923,7 +1923,9 @@ tls_server_creds_invalidate(void) { SSL_CTX_free(state_server.lib_state.lib_ctx); state_server.lib_state = null_tls_preload; +#ifndef DISABLE_OCSP state_server.u_ocsp.server.file_expanded = NULL; +#endif } commit 4e9ed49f8f12eb331b29bd5b6dc3693c520fddc2 Author: Jeremy Harris Date: Wed Aug 31 15:37:40 2022 +0100 Fix $regex use-after-free. Bug 2915 diff --git a/src/src/exim.c b/src/src/exim.c index ea4286af3..b9328f017 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2000,8 +2000,6 @@ regex_whitelisted_macro = regex_must_compile(US"^[A-Za-z0-9_/.-]*$", MCS_NOFLAGS, TRUE); #endif -for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; - /* If the program is called as "mailq" treat it as equivalent to "exim -bp"; this seems to be a generally accepted convention, since one finds symbolic links called "mailq" in standard OS configurations. */ @@ -6089,7 +6087,7 @@ MORELOOP: deliver_localpart_data = deliver_domain_data = recipient_data = sender_data = NULL; acl_var_m = NULL; - for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; + regex_vars_clear(); store_reset(reset_point); } diff --git a/src/src/expand.c b/src/src/expand.c index ffbdc14e5..89de56255 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1860,7 +1860,7 @@ else if (Ustrncmp(name, "r_", 2) == 0) return node ? node->data.ptr : strict_acl_vars ? NULL : US""; } -/* Handle $auth variables. */ +/* Handle $auth, $regex variables. */ if (Ustrncmp(name, "auth", 4) == 0) { diff --git a/src/src/functions.h b/src/src/functions.h index 92a4831e3..345d7bce6 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -447,6 +447,7 @@ extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, in extern const pcre2_code *regex_compile(const uschar *, mcs_flags, uschar **, pcre2_compile_context *); extern const pcre2_code *regex_must_compile(const uschar *, mcs_flags, BOOL); +extern void regex_vars_clear(void); extern void retry_add_item(address_item *, uschar *, int); extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL, uschar **, uschar **); diff --git a/src/src/globals.c b/src/src/globals.c index 574ee60a4..cafb15992 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1324,7 +1324,7 @@ const pcre2_code *regex_EARLY_PIPE = NULL; int regex_cachesize = 0; const pcre2_code *regex_ismsgid = NULL; const pcre2_code *regex_smtp_code = NULL; -const uschar *regex_vars[REGEX_VARS]; +const uschar *regex_vars[REGEX_VARS] = { 0 };; #ifdef WHITELIST_D_MACROS const pcre2_code *regex_whitelisted_macro = NULL; #endif diff --git a/src/src/regex.c b/src/src/regex.c index 5de1c1704..25496f950 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -93,19 +93,27 @@ return FAIL; } +/* reset expansion variables */ +void +regex_vars_clear(void) +{ +regex_match_string = NULL; +for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; +} + + int -regex(const uschar **listptr, BOOL cacheable) +regex(const uschar ** listptr, BOOL cacheable) { unsigned long mbox_size; -FILE *mbox_file; -pcre_list *re_list_head; -uschar *linebuffer; +FILE * mbox_file; +pcre_list * re_list_head; +uschar * linebuffer; long f_pos = 0; int ret = FAIL; -/* reset expansion variable */ -regex_match_string = NULL; +regex_vars_clear(); if (!mime_stream) /* We are in the DATA ACL */ { @@ -167,14 +175,13 @@ return ret; int mime_regex(const uschar **listptr, BOOL cacheable) { -pcre_list *re_list_head = NULL; -FILE *f; -uschar *mime_subject = NULL; +pcre_list * re_list_head = NULL; +FILE * f; +uschar * mime_subject = NULL; int mime_subject_len = 0; int ret; -/* reset expansion variable */ -regex_match_string = NULL; +regex_vars_clear(); /* precompile our regexes */ if (!(re_list_head = compile(*listptr, cacheable))) diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 11e7436b9..a15280bdc 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2157,8 +2157,10 @@ prdr_requested = FALSE; #ifdef SUPPORT_I18N message_smtputf8 = FALSE; #endif +regex_vars_clear(); body_linecount = body_zerocount = 0; +lookup_value = NULL; /* Can be set by ACL */ sender_rate = sender_rate_limit = sender_rate_period = NULL; ratelimiters_mail = NULL; /* Updated by ratelimit ACL condition */ /* Note that ratelimiters_conn persists across resets. */ commit d8ecc7bf97934a1e2244788c610c958cacd740bd Author: Jeremy Harris Date: Wed Aug 31 17:03:37 2022 +0100 Fix non-WITH_CONTENT_SCAN build. Broken-by: 4e9ed49f8f diff --git a/src/src/exim.c b/src/src/exim.c index b9328f017..82e833067 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1678,6 +1678,17 @@ else } +/* reset regex expansion variables */ +void +regex_vars_clear(void) +{ +regex_match_string = NULL; +for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; +} + + + + /************************************************* * Entry point and high-level code * diff --git a/src/src/regex.c b/src/src/regex.c index 25496f950..3088f0066 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -93,16 +93,6 @@ return FAIL; } -/* reset expansion variables */ -void -regex_vars_clear(void) -{ -regex_match_string = NULL; -for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; -} - - - int regex(const uschar ** listptr, BOOL cacheable) { commit 158dff9936e36a2d31d037d3988b9353458d6471 Author: Jeremy Harris Date: Wed Aug 31 17:17:59 2022 +0100 Fix non-WITH_CONTENT_SCAN build (2) Broken-by: d8ecc7bf97 diff --git a/src/src/exim.c b/src/src/exim.c index 82e833067..f2a787e8a 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1678,17 +1678,6 @@ else } -/* reset regex expansion variables */ -void -regex_vars_clear(void) -{ -regex_match_string = NULL; -for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; -} - - - - /************************************************* * Entry point and high-level code * @@ -6092,13 +6081,13 @@ MORELOOP: dnslist_domain = dnslist_matched = NULL; #ifdef WITH_CONTENT_SCAN malware_name = NULL; + regex_vars_clear(); #endif callout_address = NULL; sending_ip_address = NULL; deliver_localpart_data = deliver_domain_data = recipient_data = sender_data = NULL; acl_var_m = NULL; - regex_vars_clear(); store_reset(reset_point); } diff --git a/src/src/functions.h b/src/src/functions.h index 345d7bce6..d5164547a 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -440,6 +440,7 @@ extern int_eximarith_t receive_statvfs(BOOL, int *); extern void receive_swallow_smtp(void); #ifdef WITH_CONTENT_SCAN extern int regex(const uschar **, BOOL); +extern void regex_vars_clear(void); #endif extern void regex_at_daemon(const uschar *); extern BOOL regex_match(const pcre2_code *, const uschar *, int, uschar **); @@ -447,7 +448,6 @@ extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, in extern const pcre2_code *regex_compile(const uschar *, mcs_flags, uschar **, pcre2_compile_context *); extern const pcre2_code *regex_must_compile(const uschar *, mcs_flags, BOOL); -extern void regex_vars_clear(void); extern void retry_add_item(address_item *, uschar *, int); extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL, uschar **, uschar **); diff --git a/src/src/globals.h b/src/src/globals.h index c40ae4beb..ae74147d4 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -904,12 +904,12 @@ extern const pcre2_code *regex_EARLY_PIPE; /* For recognizing PIPE_CONNCT */ extern int regex_cachesize; /* number of entries */ extern const pcre2_code *regex_ismsgid; /* Compiled r.e. for message ID */ extern const pcre2_code *regex_smtp_code; /* For recognizing SMTP codes */ -extern const uschar *regex_vars[]; /* $regexN variables */ #ifdef WHITELIST_D_MACROS extern const pcre2_code *regex_whitelisted_macro; /* For -D macro values */ #endif #ifdef WITH_CONTENT_SCAN extern uschar *regex_match_string; /* regex that matched a line (regex ACL condition) */ +extern const uschar *regex_vars[]; #endif extern int remote_delivery_count; /* Number of remote addresses */ extern int remote_max_parallel; /* Maximum parallel delivery */ diff --git a/src/src/regex.c b/src/src/regex.c index 3088f0066..25496f950 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -93,6 +93,16 @@ return FAIL; } +/* reset expansion variables */ +void +regex_vars_clear(void) +{ +regex_match_string = NULL; +for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; +} + + + int regex(const uschar ** listptr, BOOL cacheable) { diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index a15280bdc..28e529bae 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2157,7 +2157,9 @@ prdr_requested = FALSE; #ifdef SUPPORT_I18N message_smtputf8 = FALSE; #endif +#ifdef WITH_CONTENT_SCAN regex_vars_clear(); +#endif body_linecount = body_zerocount = 0; lookup_value = NULL; /* Can be set by ACL */ commit 32da6327e434e986a18b75a84f2d8c687ba14619 Author: Jeremy Harris Date: Thu Sep 1 15:54:35 2022 +0100 Fix non-WITH_CONTENT_SCAN build (3) Broken-by: d8ecc7bf97 diff --git a/src/src/expand.c b/src/src/expand.c index 89de56255..831ca2b75 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1869,6 +1869,7 @@ if (Ustrncmp(name, "auth", 4) == 0) if (!*endptr && n != 0 && n <= AUTH_VARS) return auth_vars[n-1] ? auth_vars[n-1] : US""; } +#ifdef WITH_CONTENT_SCAN else if (Ustrncmp(name, "regex", 5) == 0) { uschar *endptr; @@ -1876,6 +1877,7 @@ else if (Ustrncmp(name, "regex", 5) == 0) if (!*endptr && n != 0 && n <= REGEX_VARS) return regex_vars[n-1] ? regex_vars[n-1] : US""; } +#endif /* For all other variables, search the table */ @@ -8715,9 +8717,11 @@ assert_variable_notin() treats as const, so deconst is safe. */ for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i]) assert_variable_notin(US"auth", US auth_vars[i], &e); +#ifdef WITH_CONTENT_SCAN /* check regex variables. assert_variable_notin() treats as const. */ for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i]) assert_variable_notin(US"regex", US regex_vars[i], &e); +#endif /* check known-name variables */ for (var_entry * v = var_table; v < var_table + var_table_size; v++) commit 04644f4ca7c85d5e4dff1bd9e48b3429130e4fdd Author: Jeremy Harris Date: Fri Sep 2 11:15:33 2022 +0100 EXPERIMENTAL_DCC: make build without WITH_CONTENT_SCAN fail rather than auto-include the support diff --git a/src/src/EDITME b/src/src/EDITME index 3c33dc5f3..80bd07817 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -596,7 +596,7 @@ DISABLE_MAL_MKS=yes # Uncomment the following line to add support for talking to dccifd. This # defaults the socket path to /usr/local/dcc/var/dccifd. -# Doing so will also explicitly turn on the WITH_CONTENT_SCAN option. +# This support also requires WITH_CONTENT_SCAN enabled. # EXPERIMENTAL_DCC=yes diff --git a/src/src/acl.c b/src/src/acl.c index 3af3a4eee..1e7d28a90 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3125,12 +3125,9 @@ acl_check_condition(int verb, acl_condition_block *cb, int where, address_item *addr, int level, BOOL *epp, uschar **user_msgptr, uschar **log_msgptr, int *basic_errno) { -uschar *user_message = NULL; -uschar *log_message = NULL; +uschar * user_message = NULL; +uschar * log_message = NULL; int rc = OK; -#ifdef WITH_CONTENT_SCAN -int sep = -'/'; -#endif for (; cb; cb = cb->next) { @@ -3646,12 +3643,13 @@ for (; cb; cb = cb->next) break; } - #ifdef EXPERIMENTAL_DCC +#ifdef EXPERIMENTAL_DCC case ACLC_DCC: { /* Separate the regular expression and any optional parameters. */ const uschar * list = arg; - uschar *ss = string_nextinlist(&list, &sep, NULL, 0); + int sep = -'/'; + uschar * ss = string_nextinlist(&list, &sep, NULL, 0); /* Run the dcc backend. */ rc = dcc_process(&ss); /* Modify return code based upon the existence of options. */ @@ -3660,13 +3658,13 @@ for (; cb; cb = cb->next) rc = FAIL; /* FAIL so that the message is passed to the next ACL */ break; } - #endif +#endif - #ifdef WITH_CONTENT_SCAN +#ifdef WITH_CONTENT_SCAN case ACLC_DECODE: rc = mime_decode(&arg); break; - #endif +#endif case ACLC_DELAY: { @@ -3813,11 +3811,10 @@ for (; cb; cb = cb->next) case ACLC_LOG_REJECT_TARGET: { - int logbits = 0; - int sep = 0; - const uschar *s = arg; - uschar * ss; - while ((ss = string_nextinlist(&s, &sep, NULL, 0))) + int logbits = 0, sep = 0; + const uschar * s = arg; + + for (uschar * ss; ss = string_nextinlist(&s, &sep, NULL, 0); ) { if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN; else if (Ustrcmp(ss, "panic") == 0) logbits |= LOG_PANIC; @@ -3865,17 +3862,16 @@ for (; cb; cb = cb->next) break; } - #ifdef WITH_CONTENT_SCAN +#ifdef WITH_CONTENT_SCAN case ACLC_MALWARE: /* Run the malware backend. */ { /* Separate the regular expression and any optional parameters. */ const uschar * list = arg; - uschar * ss = string_nextinlist(&list, &sep, NULL, 0); - uschar * opt; BOOL defer_ok = FALSE; - int timeout = 0; + int timeout = 0, sep = -'/'; + uschar * ss = string_nextinlist(&list, &sep, NULL, 0); - while ((opt = string_nextinlist(&list, &sep, NULL, 0))) + for (uschar * opt; opt = string_nextinlist(&list, &sep, NULL, 0); ) if (strcmpic(opt, US"defer_ok") == 0) defer_ok = TRUE; else if ( strncmpic(opt, US"tmo=", 4) == 0 @@ -3895,7 +3891,7 @@ for (; cb; cb = cb->next) case ACLC_MIME_REGEX: rc = mime_regex(&arg, textonly); break; - #endif +#endif case ACLC_QUEUE: if (is_tainted(arg)) @@ -3979,7 +3975,8 @@ for (; cb; cb = cb->next) { /* Separate the regular expression and any optional parameters. */ const uschar * list = arg; - uschar *ss = string_nextinlist(&list, &sep, NULL, 0); + int sep = -'/'; + uschar * ss = string_nextinlist(&list, &sep, NULL, 0); rc = spam(CUSS &ss); /* Modify return code based upon the existence of options. */ diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c index f9a8febdf..bbbaefe9c 100644 --- a/src/src/buildconfig.c +++ b/src/src/buildconfig.c @@ -740,19 +740,6 @@ else if (isgroup) continue; } - /* WITH_CONTENT_SCAN is another special case: it must be set if it or - EXPERIMENTAL_DCC is set. */ - - if (strcmp(name, "WITH_CONTENT_SCAN") == 0) - { - char *wcs = getenv("WITH_CONTENT_SCAN"); - char *dcc = getenv("EXPERIMENTAL_DCC"); - fprintf(new, wcs || dcc - ? "#define WITH_CONTENT_SCAN yes\n" - : "/* WITH_CONTENT_SCAN not set */\n"); - continue; - } - /* DISABLE_DKIM is special; must be forced if DISABLE_TLS */ if (strcmp(name, "DISABLE_DKIM") == 0) { diff --git a/src/src/dcc.c b/src/src/dcc.c index a9124a013..56dd6d570 100644 --- a/src/src/dcc.c +++ b/src/src/dcc.c @@ -7,13 +7,17 @@ * wbreyha@gmx.net * See the file NOTICE for conditions of use and distribution. * - * Copyright (c) The Exim Maintainers 2015 - 2021 + * Copyright (c) The Exim Maintainers 2015 - 2022 */ /* Code for calling dccifd. Called from acl.c. */ #include "exim.h" #ifdef EXPERIMENTAL_DCC +#ifndef WITH_CONTENT_SCAN +# error EXPERIMENTAL_DCC requires WITH_CONTENT_SCAN +#endif + #include "dcc.h" #include "unistd.h" commit a3d3e7ef81a649d2bbd6599fc561cf22c6875e70 Author: Jeremy Harris Date: Thu Sep 22 15:09:07 2022 +0100 Fix ${filter } for conditions modifying $value diff --git a/src/src/expand.c b/src/src/expand.c index 831ca2b75..ff0b4d600 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -6544,6 +6544,9 @@ while (*s) if (item_type == EITEM_FILTER) { BOOL condresult; + /* the condition could modify $value, as a side-effect */ + uschar * save_value = lookup_value; + if (!eval_condition(expr, &resetok, &condresult)) { iterate_item = save_iterate_item; @@ -6552,6 +6555,7 @@ while (*s) expand_string_message, name); goto EXPAND_FAILED; } + lookup_value = save_value; DEBUG(D_expand) debug_printf_indent("%s: condition is %s\n", name, condresult? "true":"false"); if (condresult) @@ -6560,14 +6564,12 @@ while (*s) continue; /* FALSE => skip this item */ } - /* EITEM_MAP and EITEM_REDUCE */ - - else + else /* EITEM_MAP and EITEM_REDUCE */ { + /* the expansion could modify $value, as a side-effect */ uschar * t = expand_string_internal(expr, ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, NULL, &resetok, NULL); - temp = t; - if (!temp) + if (!(temp = t)) { iterate_item = save_iterate_item; expand_string_message = string_sprintf("%s inside \"%s\" item", commit ece23f05d6a430a461a75639197271c23f6858ec Author: Jasen Betts Date: Fri Sep 30 13:49:41 2022 +0100 GnuTLS: fix for clients offering no TLS extensions diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 7a6db94e1..1fc7828cf 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1142,8 +1142,9 @@ tls_server_clienthello_cb(gnutls_session_t session, unsigned int htype, unsigned when, unsigned int incoming, const gnutls_datum_t * msg) { /* Call fn for each extension seen. 3.6.3 onwards */ -return gnutls_ext_raw_parse(NULL, tls_server_clienthello_ext, msg, +int rc = gnutls_ext_raw_parse(NULL, tls_server_clienthello_ext, msg, GNUTLS_EXT_RAW_FLAG_TLS_CLIENT_HELLO); +return rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE ? 0 : rc; } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 043755c84..0129fb93e 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -951,36 +951,35 @@ Returns: nothing */ static void -info_callback(SSL *s, int where, int ret) +info_callback(SSL * s, int where, int ret) { DEBUG(D_tls) { - const uschar * str; - - if (where & SSL_ST_CONNECT) - str = US"SSL_connect"; - else if (where & SSL_ST_ACCEPT) - str = US"SSL_accept"; - else - str = US"SSL info (undefined)"; + gstring * g = NULL; + + if (where & SSL_ST_CONNECT) g = string_append_listele(g, ',', US"SSL_connect"); + if (where & SSL_ST_ACCEPT) g = string_append_listele(g, ',', US"SSL_accept"); + if (where & SSL_CB_LOOP) g = string_append_listele(g, ',', US"state_chg"); + if (where & SSL_CB_EXIT) g = string_append_listele(g, ',', US"hshake_exit"); + if (where & SSL_CB_READ) g = string_append_listele(g, ',', US"read"); + if (where & SSL_CB_WRITE) g = string_append_listele(g, ',', US"write"); + if (where & SSL_CB_ALERT) g = string_append_listele(g, ',', US"alert"); + if (where & SSL_CB_HANDSHAKE_START) g = string_append_listele(g, ',', US"hshake_start"); + if (where & SSL_CB_HANDSHAKE_DONE) g = string_append_listele(g, ',', US"hshake_done"); if (where & SSL_CB_LOOP) - debug_printf("%s: %s\n", str, SSL_state_string_long(s)); + debug_printf("SSL %s: %s\n", g->s, SSL_state_string_long(s)); else if (where & SSL_CB_ALERT) - debug_printf("SSL3 alert %s:%s:%s\n", - str = where & SSL_CB_READ ? US"read" : US"write", + debug_printf("SSL %s %s:%s\n", g->s, SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); else if (where & SSL_CB_EXIT) { - if (ret == 0) - debug_printf("%s: failed in %s\n", str, SSL_state_string_long(s)); - else if (ret < 0) - debug_printf("%s: error in %s\n", str, SSL_state_string_long(s)); + if (ret <= 0) + debug_printf("SSL %s: %s in %s\n", g->s, + ret == 0 ? "failed" : "error", SSL_state_string_long(s)); } - else if (where & SSL_CB_HANDSHAKE_START) - debug_printf("%s: hshake start: %s\n", str, SSL_state_string_long(s)); - else if (where & SSL_CB_HANDSHAKE_DONE) - debug_printf("%s: hshake done: %s\n", str, SSL_state_string_long(s)); + else if (where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)) + debug_printf("SSL %s: %s\n", g->s, SSL_state_string_long(s)); } } commit 96751ae76e6c6db435f5a4f141511d6f973b6583 Author: Jeremy Harris Date: Tue Oct 4 13:20:29 2022 +0100 OpenSSL: fix configuration of older TLS protocol versions diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 0129fb93e..9ddb16fc4 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2210,7 +2210,9 @@ already exists. Might even need this selfsame callback, for reneg? */ SSL_CTX * ctx = state_server.lib_state.lib_ctx; SSL_CTX_set_info_callback(server_sni, SSL_CTX_get_info_callback(ctx)); SSL_CTX_set_mode(server_sni, SSL_CTX_get_mode(ctx)); + SSL_CTX_set_min_proto_version(server_sni, SSL3_VERSION); SSL_CTX_set_options(server_sni, SSL_CTX_get_options(ctx)); + SSL_CTX_clear_options(server_sni, ~SSL_CTX_get_options(ctx)); SSL_CTX_set_timeout(server_sni, SSL_CTX_get_timeout(ctx)); SSL_CTX_set_tlsext_servername_callback(server_sni, tls_servername_cb); SSL_CTX_set_tlsext_servername_arg(server_sni, state); @@ -2726,10 +2728,15 @@ if (init_options) } #endif - DEBUG(D_tls) debug_printf("setting SSL CTX options: %#lx\n", init_options); - if (!(SSL_CTX_set_options(ctx, init_options))) - return tls_error(string_sprintf( + SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); + DEBUG(D_tls) debug_printf("setting SSL CTX options: %016lx\n", init_options); + SSL_CTX_set_options(ctx, init_options); + { + ulong readback = SSL_CTX_clear_options(ctx, ~init_options); + if (readback != init_options) + return tls_error(string_sprintf( "SSL_CTX_set_option(%#lx)", init_options), host, NULL, errstr); + } } else DEBUG(D_tls) debug_printf("no SSL CTX options to set\n"); commit 27e646d341ea843245b8305166686c2fd888bf0e Author: Jeremy Harris Date: Tue Oct 4 19:11:03 2022 +0100 Fix build with older OpenSSL. Broken-by: 96751ae76e diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 9ddb16fc4..b46c0c7fd 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -48,6 +48,7 @@ functions from the OpenSSL library. */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L # define EXIM_HAVE_OCSP_RESP_COUNT # define OPENSSL_AUTO_SHA256 +# define OPENSSL_MIN_PROTO_VERSION #else # define EXIM_HAVE_EPHEM_RSA_KEX # define EXIM_HAVE_RAND_PSEUDO @@ -2210,7 +2211,9 @@ already exists. Might even need this selfsame callback, for reneg? */ SSL_CTX * ctx = state_server.lib_state.lib_ctx; SSL_CTX_set_info_callback(server_sni, SSL_CTX_get_info_callback(ctx)); SSL_CTX_set_mode(server_sni, SSL_CTX_get_mode(ctx)); +#ifdef OPENSSL_MIN_PROTO_VERSION SSL_CTX_set_min_proto_version(server_sni, SSL3_VERSION); +#endif SSL_CTX_set_options(server_sni, SSL_CTX_get_options(ctx)); SSL_CTX_clear_options(server_sni, ~SSL_CTX_get_options(ctx)); SSL_CTX_set_timeout(server_sni, SSL_CTX_get_timeout(ctx)); @@ -2728,7 +2731,9 @@ if (init_options) } #endif +#ifdef OPENSSL_MIN_PROTO_VERSION SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); +#endif DEBUG(D_tls) debug_printf("setting SSL CTX options: %016lx\n", init_options); SSL_CTX_set_options(ctx, init_options); { commit 635e657ce2c75c781d40469bbdd28645e64d89b0 Author: Jeremy Harris Date: Tue Oct 4 19:12:13 2022 +0100 Quieten clang build diff --git a/src/src/mytypes.h b/src/src/mytypes.h index 49fed0a9d..141d2c613 100644 --- a/src/src/mytypes.h +++ b/src/src/mytypes.h @@ -42,8 +42,12 @@ so we have to give up on all of the available parameter checking. */ # define FUNC_MAYBE_UNUSED __attribute__((__unused__)) # define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) # define ALLOC __attribute__((malloc)) -# define ALLOC_SIZE(A) __attribute__((alloc_size(A))) # define NORETURN __attribute__((noreturn)) +# ifndef __clang__ +# define ALLOC_SIZE(A) __attribute__((alloc_size(A))) +# else +# define ALLOC_SIZE(A) /**/ +# endif #else # define ARG_UNUSED /**/ # define FUNC_MAYBE_UNUSED /**/ commit 699f306744e5f0e1ad860a460454efe85fe63c74 Author: Jeremy Harris Date: Tue Oct 4 21:30:55 2022 +0100 Unbreak FreeBSD build Broken-by: 96751ae76e diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index b46c0c7fd..68ad6f15b 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2737,7 +2737,7 @@ if (init_options) DEBUG(D_tls) debug_printf("setting SSL CTX options: %016lx\n", init_options); SSL_CTX_set_options(ctx, init_options); { - ulong readback = SSL_CTX_clear_options(ctx, ~init_options); + uint64_t readback = SSL_CTX_clear_options(ctx, ~init_options); if (readback != init_options) return tls_error(string_sprintf( "SSL_CTX_set_option(%#lx)", init_options), host, NULL, errstr); commit 1561c5d88b3a23a4348d8e3c1ce28554fcbcfe46 Author: Heiko Schlittermann (HS12-RIPE) Date: Sat Oct 15 19:30:58 2022 +0200 Fix: Build with libopendmarc 1.4.x (fixes 2728) diff --git a/src/src/EDITME b/src/src/EDITME index 80bd07817..28d3d538e 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -602,14 +602,17 @@ DISABLE_MAL_MKS=yes # Uncomment the following line to add DMARC checking capability, implemented # using libopendmarc libraries. You must have SPF and DKIM support enabled also. -# Library version libopendmarc-1.4.1-1.fc33.x86_64 (on Fedora 33) is known broken; -# 1.3.2-3 works. I seems that the OpenDMARC project broke their API. # SUPPORT_DMARC=yes # CFLAGS += -I/usr/local/include # LDFLAGS += -lopendmarc # Uncomment the following if you need to change the default. You can # override it at runtime (main config option dmarc_tld_file) # DMARC_TLD_FILE=/etc/exim/opendmarc.tlds +# +# Library version libopendmarc-1.4.1-1.fc33.x86_64 (on Fedora 33) is known broken; +# 1.3.2-3 works. It seems that the OpenDMARC project broke their API. +# Use this option if you need to build with an old library (1.3.x) +# DMARC_API=100300 # Uncomment the following line to add ARC (Authenticated Received Chain) # support. You must have SPF and DKIM support enabled also. diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 25ab75506..221705224 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -150,6 +150,7 @@ Do not put spaces between # and the 'define'. #define SUPPORT_CRYPTEQ #define SUPPORT_DANE #define SUPPORT_DMARC +#define DMARC_API 100400 #define DMARC_TLD_FILE "/etc/exim/opendmarc.tlds" #define SUPPORT_I18N #define SUPPORT_I18N_2008 diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 17bba9d75..ad0c26c91 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -459,7 +459,12 @@ if (!dmarc_abort && !sender_host_authenticated) vs == PDKIM_VERIFY_INVALID ? DMARC_POLICY_DKIM_OUTCOME_TMPFAIL : DMARC_POLICY_DKIM_OUTCOME_NONE; libdm_status = opendmarc_policy_store_dkim(dmarc_pctx, US sig->domain, - dkim_result, US""); +/* The opendmarc project broke its API in a way we can't detect * easily. + * The EDITME provides a DMARC_API variable */ +#if DMARC_API >= 100400 + sig->selector, +#endif + dkim_result, US""); DEBUG(D_receive) debug_printf("DMARC adding DKIM sender domain = %s\n", sig->domain); if (libdm_status != DMARC_PARSE_OKAY) commit 12fb3842f81bcbd4a4519d5728f2d7e0e3ca1445 Author: Lorenz Brun Date: Fri Oct 14 21:02:51 2022 +0200 DMARC: fix use-after-free in dmarc_dns_lookup This fixes a use-after-free in dmarc_dns_lookup where the result of dns_lookup in dnsa is freed before the required data is copied out. Fixes: 9258363 ("DNS: explicit alloc/free of workspace") diff --git a/src/src/dmarc.c b/src/src/dmarc.c index ad0c26c91..53c2752ac 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -230,8 +230,9 @@ if (rc == DNS_SUCCEED) rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_TXT && rr->size > 3) { + uschar *record = string_copyn_taint(US rr->data, rr->size, GET_TAINTED); store_free_dns_answer(dnsa); - return string_copyn_taint(US rr->data, rr->size, GET_TAINTED); + return record; } store_free_dns_answer(dnsa); return NULL; commit d5eda1c258df2996ace50a723ba8b1d78bb86be6 Author: Jeremy Harris Date: Mon Oct 31 10:18:28 2022 +0000 Release process: permit minor version numbers after 99 commit 221321d2c51b83d1feced80ecd6c2fe33ec5456c Author: Jeremy Harris Date: Thu Nov 3 20:08:25 2022 +0000 Fix daemon startup. Bug 2930 Broken-by: 7d5055276a diff --git a/src/src/daemon.c b/src/src/daemon.c index 54725e07d..8446f81cb 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1776,15 +1776,19 @@ if (f.background_daemon) daemon as the result of a SIGHUP. In this case, there is no need to do anything, because the controlling terminal has long gone. Otherwise, fork, in case current process is a process group leader (see 'man setsid' for an - explanation) before calling setsid(). */ + explanation) before calling setsid(). + All other forks want daemon_listen cleared. Rather than blow a register, jsut + restore it here. */ if (getppid() != 1) { + BOOL daemon_listen = f.daemon_listen; pid_t pid = exim_fork(US"daemon"); if (pid < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork() failed when starting daemon: %s", strerror(errno)); if (pid > 0) exit(EXIT_SUCCESS); /* in parent process, just exit */ (void)setsid(); /* release controlling terminal */ + f.daemon_listen = daemon_listen; } } @@ -2122,7 +2126,7 @@ else if (f.daemon_listen) if (*--p == '}') *p = '\0'; /* drop EOL */ while (isdigit(*--p)) ; /* char before port */ - i2->log = *p == ':' /* no list yet? */ + i2->log = *p == ':' /* no list yet? { */ ? string_sprintf("%.*s{%s,%d}", (int)(p - i2->log + 1), i2->log, p+1, ipa->port) : string_sprintf("%s,%d}", i2->log, ipa->port); commit 6b331d5834d12bdda21857cd6fffac17038ce3c7 Author: Ruben Jenster Date: Thu Nov 3 21:38:15 2022 +0000 Fix $reccipients after ${run...}. Bug 2929 Broken-by: cfe6acff2d diff --git a/src/src/transport.c b/src/src/transport.c index cce1c46ae..7477882cb 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -2344,9 +2344,10 @@ if (expand_arguments) else { const uschar *expanded_arg; + BOOL enable_dollar_recipients_g = f.enable_dollar_recipients; f.enable_dollar_recipients = allow_dollar_recipients; expanded_arg = expand_cstring(argv[i]); - f.enable_dollar_recipients = FALSE; + f.enable_dollar_recipients = enable_dollar_recipients_g; if (!expanded_arg) { commit 20edc59755798df57b094d1f5ccf24726acbe319 Author: Mehmet Suslu Date: Tue Mar 1 10:33:23 2022 +0300 typo: error message referenced wrong option Fix typo, -oMas -> -oMai (cherry picked from commit 330ab60ef29c01fb472b6ce14e935ccb93e905ac) diff --git a/src/src/exim.c b/src/src/exim.c index f2a787e8a..b3fd9eff0 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -3329,7 +3329,7 @@ on the second character (the one after '-'), to save some effort. */ else if (Ustrcmp(argrest, "ai") == 0) authenticated_id = string_copy_taint( - exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMas"), + exim_str_fail_toolong(argv[++i], EXIM_EMAILADDR_MAX, "-oMai"), GET_TAINTED); /* -oMi: Set incoming interface address */ commit 36d65c9fc4bd2f0f260439fa624b667e29e5a280 Author: Tim Gates Date: Thu Dec 17 21:07:18 2020 +1100 typo: code comment signture -> signature There is a small typo in src/src/globals.h. Should read `signature` rather than `signture`. diff --git a/src/src/globals.h b/src/src/globals.h index ae74147d4..1be96daec 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -545,7 +545,7 @@ extern uschar *dkim_signing_selector; /* Expansion variable, selector used for extern uschar *dkim_verify_hashes; /* Preference order for signatures */ extern uschar *dkim_verify_keytypes; /* Preference order for signatures */ extern uschar *dkim_verify_min_keysizes; /* list of minimum key sizes, keyed by algo */ -extern BOOL dkim_verify_minimal; /* Shortcircuit signture verification */ +extern BOOL dkim_verify_minimal; /* Shortcircuit signature verification */ extern uschar *dkim_verify_overall; /* First successful domain verified, or null */ extern uschar *dkim_verify_signers; /* Colon-separated list of domains for each of which we call the DKIM ACL */ extern uschar *dkim_verify_status; /* result for this signature */ commit e63825824cc406c160ccbf2b154c5d81b168604a Author: Jeremy Harris Date: Fri Nov 11 00:05:59 2022 +0000 Fix regext substring capture variables for null matches. Bug 2933 broken-by: 59d66fdc13f0 diff --git a/src/src/exim.c b/src/src/exim.c index b3fd9eff0..47a685aa7 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -134,6 +134,8 @@ if ((yield = (res >= 0))) PCRE2_SIZE len; pcre2_substring_get_bynumber(md, matchnum, (PCRE2_UCHAR **)&expand_nstring[expand_nmax], &len); + if (!expand_nstring[expand_nmax]) + { expand_nstring[expand_nmax] = US""; len = 0; } expand_nlength[expand_nmax++] = (int)len; } expand_nmax--; diff --git a/src/src/malware.c b/src/src/malware.c index 8b5ec27c4..423a5b692 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -314,7 +314,10 @@ PCRE2_UCHAR * substr = NULL; PCRE2_SIZE slen; if (i >= 2) /* Got it */ + { pcre2_substring_get_bynumber(md, 1, &substr, &slen); /* uses same ctx as md */ + if (!substr) substr = US""; + } /* pcre2_match_data_free(md); gen ctx needs no free */ return US substr; } diff --git a/src/src/regex.c b/src/src/regex.c index 25496f950..b401ba0d7 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -82,7 +82,7 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next) PCRE2_UCHAR * cstr; PCRE2_SIZE cslen; pcre2_substring_get_bynumber(md, nn, &cstr, &cslen); /* uses same ctx as md */ - regex_vars[nn-1] = CUS cstr; + regex_vars[nn-1] = cstr ? CUS cstr : CUS""; } return OK; commit 7ad1a2b2cc57b5f4bcb59186a9a8abcbed9f4f76 Author: Jeremy Harris Date: Fri Nov 11 18:22:00 2022 +0000 Fix regex substring capture variables for null matches (again). Bug 2933 Broken-by: 59d66fdc13f0 diff --git a/src/src/exim.c b/src/src/exim.c index 47a685aa7..16c0184e0 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -127,16 +127,15 @@ BOOL yield; if ((yield = (res >= 0))) { + PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); res = pcre2_get_ovector_count(md); expand_nmax = setup < 0 ? 0 : setup + 1; for (int matchnum = setup < 0 ? 0 : 1; matchnum < res; matchnum++) { - PCRE2_SIZE len; - pcre2_substring_get_bynumber(md, matchnum, - (PCRE2_UCHAR **)&expand_nstring[expand_nmax], &len); - if (!expand_nstring[expand_nmax]) - { expand_nstring[expand_nmax] = US""; len = 0; } - expand_nlength[expand_nmax++] = (int)len; + int off = matchnum * 2; + int len = ovec[off + 1] - ovec[off]; + expand_nstring[expand_nmax] = string_copyn(subject + ovec[off], len); + expand_nlength[expand_nmax++] = len; } expand_nmax--; } diff --git a/src/src/malware.c b/src/src/malware.c index 423a5b692..01dd455ba 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -310,16 +310,16 @@ m_pcre_exec(const pcre2_code * cre, uschar * text) { pcre2_match_data * md = pcre2_match_data_create(2, pcre_gen_ctx); int i = pcre2_match(cre, text, PCRE2_ZERO_TERMINATED, 0, 0, md, pcre_gen_mtc_ctx); -PCRE2_UCHAR * substr = NULL; -PCRE2_SIZE slen; +uschar * substr = NULL; if (i >= 2) /* Got it */ { - pcre2_substring_get_bynumber(md, 1, &substr, &slen); /* uses same ctx as md */ - if (!substr) substr = US""; + PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); + int len = ovec[3] - ovec[2]; + substr = string_copyn(text + ovec[2], len); } /* pcre2_match_data_free(md); gen ctx needs no free */ -return US substr; +return substr; } static const pcre2_code * diff --git a/src/src/regex.c b/src/src/regex.c index b401ba0d7..210620f26 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -79,10 +79,10 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next) for (int nn = 1; nn < n; nn++) { - PCRE2_UCHAR * cstr; - PCRE2_SIZE cslen; - pcre2_substring_get_bynumber(md, nn, &cstr, &cslen); /* uses same ctx as md */ - regex_vars[nn-1] = cstr ? CUS cstr : CUS""; + PCRE2_SIZE * ovec = pcre2_get_ovector_pointer(md); + int off = nn * 2; + int len = ovec[off + 1] - ovec[off]; + regex_vars[nn-1] = string_copyn(linebuffer + ovec[off], len); } return OK; commit 9ba47886c71d40edc99b026a99edee269d9c9c6f Author: Jeremy Harris Date: Sat Nov 12 12:38:22 2022 +0000 Fix regex substring capture - commentary. Bug 2933 Broken-by (corrected): 22ed7a5295f1 diff --git a/src/src/exim.c b/src/src/exim.c index 16c0184e0..625494ce4 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -104,7 +104,9 @@ pcre_gen_mtc_ctx = pcre2_match_context_create(pcre_gen_ctx); /* This function runs a regular expression match, and sets up the pointers to the matched substrings. The matched strings are copied so the lifetime of -the subject is not a problem. +the subject is not a problem. Matched strings will have the same taint status +as the subject string (this is not a de-taint method, and must not be made so +given the support for wildcards in REs). Arguments: re the compiled expression @@ -132,6 +134,11 @@ if ((yield = (res >= 0))) expand_nmax = setup < 0 ? 0 : setup + 1; for (int matchnum = setup < 0 ? 0 : 1; matchnum < res; matchnum++) { + /* Although PCRE2 has a pcre2_substring_get_bynumber() conveneience, it + seems to return a bad pointer when a capture group had no data, eg. (.*) + matching zero letters. So use the underlying ovec and hope (!) that the + offsets are sane (including that case). Should we go further and range- + check each one vs. the subject string length? */ int off = matchnum * 2; int len = ovec[off + 1] - ovec[off]; expand_nstring[expand_nmax] = string_copyn(subject + ovec[off], len); commit dae16fc62c042f1c300db82ec1fc0d95cb8d66d3 Author: Jeremy Harris Date: Sat Nov 12 20:17:55 2022 +0000 tidy segv stacktrace logging diff --git a/src/src/exim.c b/src/src/exim.c index 625494ce4..3cd1d5f6d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -248,17 +248,17 @@ void * buf[STACKDUMP_MAX]; char ** ss; int nptrs = backtrace(buf, STACKDUMP_MAX); -log_write(0, LOG_MAIN|LOG_PANIC, "backtrace\n"); -log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); +log_write(0, LOG_MAIN|LOG_PANIC, "backtrace"); +log_write(0, LOG_MAIN|LOG_PANIC, "---"); if ((ss = backtrace_symbols(buf, nptrs))) { for (int i = 0; i < nptrs; i++) - log_write(0, LOG_MAIN|LOG_PANIC, "\t%s\n", ss[i]); + log_write(0, LOG_MAIN|LOG_PANIC, "\t%s", ss[i]); free(ss); } else - log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s\n", strerror(errno)); -log_write(0, LOG_MAIN|LOG_PANIC, "---\n"); + log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s", strerror(errno)); +log_write(0, LOG_MAIN|LOG_PANIC, "---"); #endif } #undef STACKDUMP_MAX commit 7f65a63b60c6ea86db683ac00e221939f3bb1d47 Author: Jeremy Harris Date: Tue Oct 25 21:26:30 2022 +0100 OpenSSL: when preloading creds do the server certs before the OCSP proofs so that the latter can ve verified before loading diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 68ad6f15b..fdf0d92b2 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -445,6 +445,8 @@ setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host, /* Callbacks */ #ifndef DISABLE_OCSP static int tls_server_stapling_cb(SSL *s, void *arg); +static void x509_stack_dump_cert_s_names(const STACK_OF(X509) * sk); +static void x509_store_dump_cert_s_names(X509_STORE * store); #endif @@ -1311,7 +1313,6 @@ OCSP_BASICRESP * basic_response; OCSP_SINGLERESP * single_response; ASN1_GENERALIZEDTIME * rev, * thisupd, * nextupd; STACK_OF(X509) * sk; -unsigned long verify_flags; int status, reason, i; DEBUG(D_tls) @@ -1376,20 +1377,20 @@ if (!(basic_response = OCSP_response_get1_basic(resp))) goto bad; } -sk = state->verify_stack; -verify_flags = OCSP_NOVERIFY; /* check sigs, but not purpose */ +sk = state->verify_stack; /* set by setup_certs() / chain_from_pem_file() */ /* May need to expose ability to adjust those flags? OCSP_NOSIGS OCSP_NOVERIFY OCSP_NOCHAIN OCSP_NOCHECKS OCSP_NOEXPLICIT OCSP_TRUSTOTHER OCSP_NOINTERN */ -/* This does a full verify on the OCSP proof before we load it for serving -up; possibly overkill - just date-checks might be nice enough. +/* This does a partial verify (only the signer link, not the whole chain-to-CA) +on the OCSP proof before we load it for serving up; possibly overkill - +just date-checks might be nice enough. OCSP_basic_verify takes a "store" arg, but does not -use it for the chain verification, which is all we do -when OCSP_NOVERIFY is set. The content from the wire -"basic_response" and a cert-stack "sk" are all that is used. +use it for the chain verification, when OCSP_NOVERIFY is set. +The content from the wire "basic_response" and a cert-stack "sk" are all +that is used. We have a stack, loaded in setup_certs() if tls_verify_certificates was a file (not a directory, or "system"). It is unfortunate we @@ -1406,7 +1407,7 @@ But what with? We also use OCSP_basic_verify in the client stapling callback. And there we NEED it; we must verify that status... unless the library does it for us anyway? */ -if ((i = OCSP_basic_verify(basic_response, sk, NULL, verify_flags)) < 0) +if ((i = OCSP_basic_verify(basic_response, sk, NULL, OCSP_NOVERIFY)) < 0) { DEBUG(D_tls) { @@ -1751,53 +1752,10 @@ else DEBUG(D_tls) debug_printf("TLS: not preloading ECDH curve for server\n"); #if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT) -/* If we can, preload the server-side cert, key and ocsp */ - -if ( opt_set_and_noexpand(tls_certificate) -# ifndef DISABLE_OCSP - && opt_unset_or_noexpand(tls_ocsp_file) -#endif - && opt_unset_or_noexpand(tls_privatekey)) - { - /* Set watches on the filenames. The implementation does de-duplication - so we can just blindly do them all. */ - - if ( tls_set_watch(tls_certificate, TRUE) -# ifndef DISABLE_OCSP - && tls_set_watch(tls_ocsp_file, TRUE) -#endif - && tls_set_watch(tls_privatekey, TRUE)) - { - state_server.certificate = tls_certificate; - state_server.privatekey = tls_privatekey; -#ifndef DISABLE_OCSP - state_server.u_ocsp.server.file = tls_ocsp_file; -#endif - - DEBUG(D_tls) debug_printf("TLS: preloading server certs\n"); - if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK) - state_server.lib_state.conn_certs = TRUE; - } - } -else if ( !tls_certificate && !tls_privatekey -# ifndef DISABLE_OCSP - && !tls_ocsp_file -#endif - ) - { /* Generate & preload a selfsigned cert. No files to watch. */ - if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK) - { - state_server.lib_state.conn_certs = TRUE; - lifetime = f.running_in_test_harness ? 2 : 60 * 60; /* 1 hour */ - } - } -else - DEBUG(D_tls) debug_printf("TLS: not preloading server certs\n"); - - /* If we can, preload the Authorities for checking client certs against. Actual choice to do verify is made (tls_{,try_}verify_hosts) -at TLS conn startup */ +at TLS conn startup. +Do this before the server ocsp so that its info can verify the ocsp. */ if ( opt_set_and_noexpand(tls_verify_certificates) && opt_unset_or_noexpand(tls_crl)) @@ -1813,10 +1771,55 @@ if ( opt_set_and_noexpand(tls_verify_certificates) if (setup_certs(ctx, tls_verify_certificates, tls_crl, NULL, &dummy_errstr) == OK) state_server.lib_state.cabundle = TRUE; - } + + /* If we can, preload the server-side cert, key and ocsp */ + + if ( opt_set_and_noexpand(tls_certificate) +# ifndef DISABLE_OCSP + && opt_unset_or_noexpand(tls_ocsp_file) +# endif + && opt_unset_or_noexpand(tls_privatekey)) + { + /* Set watches on the filenames. The implementation does de-duplication + so we can just blindly do them all. */ + + if ( tls_set_watch(tls_certificate, TRUE) +# ifndef DISABLE_OCSP + && tls_set_watch(tls_ocsp_file, TRUE) +# endif + && tls_set_watch(tls_privatekey, TRUE)) + { + state_server.certificate = tls_certificate; + state_server.privatekey = tls_privatekey; +#ifndef DISABLE_OCSP + state_server.u_ocsp.server.file = tls_ocsp_file; +# endif + + DEBUG(D_tls) debug_printf("TLS: preloading server certs\n"); + if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK) + state_server.lib_state.conn_certs = TRUE; + } + } + else if ( !tls_certificate && !tls_privatekey +# ifndef DISABLE_OCSP + && !tls_ocsp_file +# endif + ) + { /* Generate & preload a selfsigned cert. No files to watch. */ + if (tls_expand_session_files(ctx, &state_server, &dummy_errstr) == OK) + { + state_server.lib_state.conn_certs = TRUE; + lifetime = f.running_in_test_harness ? 2 : 60 * 60; /* 1 hour */ + } + } + else + DEBUG(D_tls) debug_printf("TLS: not preloading server certs\n"); + } } else DEBUG(D_tls) debug_printf("TLS: not preloading CA bundle for server\n"); + + #endif /* EXIM_HAVE_INOTIFY */ commit 62b97c2ecf148ee86053d82e5509e4c3a5a20054 Author: Jeremy Harris Date: Sat Oct 29 22:33:43 2022 +0100 OpenSSL: fix double-expansion of tls_verify_certificates diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index fdf0d92b2..2e09882d2 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -439,7 +439,7 @@ exim_openssl_state_st *client_static_state = NULL; /*XXX should not use static; exim_openssl_state_st state_server = {.is_server = TRUE}; static int -setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host, +setup_certs(SSL_CTX * sctx, uschar ** certs, uschar * crl, host_item * host, uschar ** errstr ); /* Callbacks */ @@ -1766,10 +1766,10 @@ if ( opt_set_and_noexpand(tls_verify_certificates) && tls_set_watch(tls_verify_certificates, FALSE) && tls_set_watch(tls_crl, FALSE)) { + uschar * v_certs = tls_verify_certificates; DEBUG(D_tls) debug_printf("TLS: preloading CA bundle for server\n"); - if (setup_certs(ctx, tls_verify_certificates, tls_crl, NULL, &dummy_errstr) - == OK) + if (setup_certs(ctx, &v_certs, tls_crl, NULL, &dummy_errstr) == OK) state_server.lib_state.cabundle = TRUE; /* If we can, preload the server-side cert, key and ocsp */ @@ -1901,10 +1901,11 @@ if ( opt_set_and_noexpand(ob->tls_verify_certificates) && tls_set_watch(ob->tls_crl, FALSE) ) { + uschar * v_certs = ob->tls_verify_certificates; DEBUG(D_tls) debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name); - if (setup_certs(ctx, ob->tls_verify_certificates, + if (setup_certs(ctx, &v_certs, ob->tls_crl, dummy_host, &dummy_errstr) == OK) ob->tls_preload.cabundle = TRUE; } @@ -2242,14 +2243,12 @@ if (state->u_ocsp.server.file) #endif { - uschar * expcerts; - if ( !expand_check(tls_verify_certificates, US"tls_verify_certificates", - &expcerts, &dummy_errstr) - || (rc = setup_certs(server_sni, expcerts, tls_crl, NULL, + uschar * v_certs = tls_verify_certificates; + if ((rc = setup_certs(server_sni, &v_certs, tls_crl, NULL, &dummy_errstr)) != OK) goto bad; - if (expcerts && *expcerts) + if (v_certs && *v_certs) setup_cert_verify(server_sni, FALSE, verify_callback_server); } @@ -3021,7 +3020,7 @@ repeated after a Server Name Indication. Arguments: sctx SSL_CTX* to initialise - certs certs file, expanded + certs certs file, returned expanded crl CRL file or NULL host NULL in a server; the remote host in a client errstr error string pointer @@ -3030,15 +3029,16 @@ Returns: OK/DEFER/FAIL */ static int -setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host, +setup_certs(SSL_CTX * sctx, uschar ** certsp, uschar * crl, host_item * host, uschar ** errstr) { -uschar *expcerts, *expcrl; +uschar * expcerts, * expcrl; -if (!expand_check(certs, US"tls_verify_certificates", &expcerts, errstr)) +if (!expand_check(*certsp, US"tls_verify_certificates", &expcerts, errstr)) return DEFER; DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts); +*certsp = expcerts; if (expcerts && *expcerts) { /* Tell the library to use its compiled-in location for the system default @@ -3334,20 +3334,20 @@ else goto skip_certs; { - uschar * expcerts; - if (!expand_check(tls_verify_certificates, US"tls_verify_certificates", - &expcerts, errstr)) - return DEFER; - DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts); + uschar * v_certs = tls_verify_certificates; if (state_server.lib_state.cabundle) - { DEBUG(D_tls) debug_printf("TLS: CA bundle for server was preloaded\n"); } + { + DEBUG(D_tls) debug_printf("TLS: CA bundle for server was preloaded\n"); + setup_cert_verify(ctx, server_verify_optional, verify_callback_server); + } else - if ((rc = setup_certs(ctx, expcerts, tls_crl, NULL, errstr)) != OK) + { + if ((rc = setup_certs(ctx, &v_certs, tls_crl, NULL, errstr)) != OK) return rc; - - if (expcerts && *expcerts) - setup_cert_verify(ctx, server_verify_optional, verify_callback_server); + if (v_certs && *v_certs) + setup_cert_verify(ctx, server_verify_optional, verify_callback_server); + } } skip_certs: ; @@ -3610,20 +3610,20 @@ else return OK; { - uschar * expcerts; - if (!expand_check(ob->tls_verify_certificates, US"tls_verify_certificates", - &expcerts, errstr)) - return DEFER; - DEBUG(D_tls) debug_printf("tls_verify_certificates: %s\n", expcerts); + uschar * v_certs = ob->tls_verify_certificates; if (state->lib_state.cabundle) - { DEBUG(D_tls) debug_printf("TLS: CA bundle was preloaded\n"); } + { + DEBUG(D_tls) debug_printf("TLS: CA bundle for tpt was preloaded\n"); + setup_cert_verify(ctx, client_verify_optional, verify_callback_client); + } else - if ((rc = setup_certs(ctx, expcerts, ob->tls_crl, host, errstr)) != OK) + { + if ((rc = setup_certs(ctx, &v_certs, ob->tls_crl, host, errstr)) != OK) return rc; - - if (expcerts && *expcerts) - setup_cert_verify(ctx, client_verify_optional, verify_callback_client); + if (v_certs && *v_certs) + setup_cert_verify(ctx, client_verify_optional, verify_callback_client); + } } if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK) commit 415c5379af11bf8777af1a082a336ad7c5369525 Author: Jeremy Harris Date: Tue Nov 22 22:32:59 2022 +0000 OpenSSL: OCSP under DANE diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 2e09882d2..3873bbba3 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -97,6 +97,7 @@ change this guard and punt the issue for a while longer. */ #if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x030000000L) # define EXIM_HAVE_EXPORT_CHNL_BNGNG +# define EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS #endif #if !defined(LIBRESSL_VERSION_NUMBER) \ @@ -117,6 +118,7 @@ change this guard and punt the issue for a while longer. */ # define OPENSSL_HAVE_NUM_TICKETS # define EXIM_HAVE_OPENSSL_CIPHER_STD_NAME # define EXIM_HAVE_EXP_CHNL_BNGNG +# define EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER # else # define OPENSSL_BAD_SRVR_OURCERT # endif @@ -408,15 +410,16 @@ typedef struct exim_openssl_state { uschar * privatekey; BOOL is_server; #ifndef DISABLE_OCSP - STACK_OF(X509) *verify_stack; /* chain for verifying the proof */ union { struct { uschar *file; const uschar *file_expanded; ocsp_resplist *olist; + STACK_OF(X509) *verify_stack; /* chain for verifying the proof */ } server; struct { X509_STORE *verify_store; /* non-null if status requested */ + uschar *verify_errstr; /* only if _required */ BOOL verify_required; } client; } u_ocsp; @@ -440,7 +443,7 @@ exim_openssl_state_st state_server = {.is_server = TRUE}; static int setup_certs(SSL_CTX * sctx, uschar ** certs, uschar * crl, host_item * host, - uschar ** errstr ); + uschar ** errstr); /* Callbacks */ #ifndef DISABLE_OCSP @@ -1119,18 +1122,6 @@ if (preverify_ok == 0) else if (depth != 0) { DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d SN=%s\n", depth, dn); -#ifndef DISABLE_OCSP - if (tlsp == &tls_out && client_static_state->u_ocsp.client.verify_store) - { /* client, wanting stapling */ - /* Add the server cert's signing chain as the one - for the verification of the OCSP stapled information. */ - - if (!X509_STORE_add_cert(client_static_state->u_ocsp.client.verify_store, - cert)) - ERR_clear_error(); - sk_X509_push(client_static_state->verify_stack, cert); - } -#endif #ifndef DISABLE_EVENT if (verify_event(tlsp, cert, depth, dn, calledp, optionalp, US"SSL")) return 0; /* reject, with peercert set */ @@ -1258,21 +1249,7 @@ DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s depth %d %s\n", #endif if (preverify_ok == 1) - { tls_out.dane_verified = TRUE; -#ifndef DISABLE_OCSP - if (client_static_state->u_ocsp.client.verify_store) - { /* client, wanting stapling */ - /* Add the server cert's signing chain as the one - for the verification of the OCSP stapled information. */ - - if (!X509_STORE_add_cert(client_static_state->u_ocsp.client.verify_store, - cert)) - ERR_clear_error(); - sk_X509_push(client_static_state->verify_stack, cert); - } -#endif - } else { int err = X509_STORE_CTX_get_error(x509ctx); @@ -1288,6 +1265,14 @@ return preverify_ok; #ifndef DISABLE_OCSP +static void +time_print(BIO * bp, const char * str, ASN1_GENERALIZEDTIME * time) +{ +BIO_printf(bp, "\t%s: ", str); +ASN1_GENERALIZEDTIME_print(bp, time); +BIO_puts(bp, "\n"); +} + /************************************************* * Load OCSP information into state * *************************************************/ @@ -1377,7 +1362,7 @@ if (!(basic_response = OCSP_response_get1_basic(resp))) goto bad; } -sk = state->verify_stack; /* set by setup_certs() / chain_from_pem_file() */ +sk = state->u_ocsp.server.verify_stack; /* set by setup_certs() / chain_from_pem_file() */ /* May need to expose ability to adjust those flags? OCSP_NOSIGS OCSP_NOVERIFY OCSP_NOCHAIN OCSP_NOCHECKS OCSP_NOEXPLICIT @@ -1398,11 +1383,13 @@ cannot used the connection context store, as that would neatly handle the "system" case too, but there seems to be no library function for getting a stack from a store. [ In OpenSSL 1.1 - ? X509_STORE_CTX_get0_chain(ctx) ? ] +[ 3.0.0 - sk = X509_STORE_get1_all_certs(store) ] We do not free the stack since it could be needed a second time for SNI handling. Separately we might try to replace using OCSP_basic_verify() - which seems to not be a public interface into the OpenSSL library (there's no manual entry) - +(in 3.0.0 + is is public) But what with? We also use OCSP_basic_verify in the client stapling callback. And there we NEED it; we must verify that status... unless the library does it for us anyway? */ @@ -1412,7 +1399,7 @@ if ((i = OCSP_basic_verify(basic_response, sk, NULL, OCSP_NOVERIFY)) < 0) DEBUG(D_tls) { ERR_error_string_n(ERR_get_error(), ssl_errstring, sizeof(ssl_errstring)); - debug_printf("OCSP response verify failure: %s\n", US ssl_errstring); + debug_printf("OCSP response has bad signature: %s\n", US ssl_errstring); } goto bad; } @@ -1446,7 +1433,16 @@ if (status != V_OCSP_CERTSTATUS_GOOD) if (!OCSP_check_validity(thisupd, nextupd, EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE)) { - DEBUG(D_tls) debug_printf("OCSP status invalid times.\n"); + DEBUG(D_tls) + { + BIO * bp = BIO_new(BIO_s_mem()); + uschar * s = NULL; + int len; + time_print(bp, "This OCSP Update", thisupd); + if (nextupd) time_print(bp, "Next OCSP Update", nextupd); + if ((len = (int) BIO_get_mem_data(bp, CSS &s)) > 0) debug_printf("%.*s", len, s); + debug_printf("OCSP status invalid times.\n"); + } goto bad; } @@ -1921,7 +1917,7 @@ else #if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT) /* Invalidate the creds cached, by dropping the current ones. Call when we notice one of the source files has changed. */ - + static void tls_server_creds_invalidate(void) { @@ -1955,28 +1951,61 @@ tls_client_creds_invalidate(transport_instance * t) /* Extreme debug + * */ #ifndef DISABLE_OCSP -void -x509_store_dump_cert_s_names(X509_STORE * store) +static void +debug_print_sn(const X509 * cert) { -STACK_OF(X509_OBJECT) * roots= store->objs; +X509_NAME * sn = X509_get_subject_name(cert); static uschar name[256]; +if (X509_NAME_oneline(sn, CS name, sizeof(name))) + { + name[sizeof(name)-1] = '\0'; + debug_printf(" %s\n", name); + } +} -for (int i= 0; i < sk_X509_OBJECT_num(roots); i++) +static void +x509_stack_dump_cert_s_names(const STACK_OF(X509) * sk) +{ +if (!sk) + debug_printf(" (null)\n"); +else { - X509_OBJECT * tmp_obj= sk_X509_OBJECT_value(roots, i); - if(tmp_obj->type == X509_LU_X509) + int idx = sk_X509_num(sk); + if (!idx) + debug_printf(" (empty)\n"); + else + while (--idx >= 0) debug_print_sn(sk_X509_value(sk, idx)); + } +} + +static void +x509_store_dump_cert_s_names(X509_STORE * store) +{ +# ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS +STACK_OF(X509) * sk = X509_STORE_get1_all_certs(store); +x509_stack_dump_cert_s_names(sk); +sk_X509_pop_free(sk, X509_free); + +# else +if (!store) + debug_printf(" (no store)\n"); +else + { + STACK_OF(X509_OBJECT) * objs = X509_STORE_get0_objects(store); + if (!objs) + debug_printf(" (null objectlist)\n"); + else for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) { - X509_NAME * sn = X509_get_subject_name(tmp_obj->data.x509); - if (X509_NAME_oneline(sn, CS name, sizeof(name))) - { - name[sizeof(name)-1] = '\0'; - debug_printf(" %s\n", name); - } + X509 * cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); + if (cert) debug_print_sn(cert); } } +# endif } -#endif +#endif /*!DISABLE_OCSP*/ +/* */ @@ -2420,11 +2449,21 @@ return SSL_TLSEXT_ERR_OK; static void -time_print(BIO * bp, const char * str, ASN1_GENERALIZEDTIME * time) +add_chain_to_store(X509_STORE * store, STACK_OF(X509) * sk, + const char * debug_text) { -BIO_printf(bp, "\t%s: ", str); -ASN1_GENERALIZEDTIME_print(bp, time); -BIO_puts(bp, "\n"); +int idx; + +DEBUG(D_tls) + { + debug_printf("chain for %s:\n", debug_text); + x509_stack_dump_cert_s_names(sk); + } +if (sk) + if ((idx = sk_X509_num(sk)) > 0) + while (--idx >= 0) + X509_STORE_add_cert(store, sk_X509_value(sk, idx)); + } static int @@ -2440,18 +2479,24 @@ int i; DEBUG(D_tls) debug_printf("Received TLS status callback (OCSP stapling):\n"); len = SSL_get_tlsext_status_ocsp_resp(ssl, &p); if(!p) - { /* Expect this when we requested ocsp but got none */ + { /* Expect this when we requested ocsp but got none */ if (SSL_session_reused(ssl) && tls_out.ocsp == OCSP_VFIED) { DEBUG(D_tls) debug_printf(" null, but resumed; ocsp vfy stored with session is good\n"); return 1; } + if (cbinfo->u_ocsp.client.verify_required && LOGGING(tls_cipher)) log_write(0, LOG_MAIN, "Required TLS certificate status not received"); else DEBUG(D_tls) debug_printf(" null\n"); - return cbinfo->u_ocsp.client.verify_required ? 0 : 1; - } + + if (!cbinfo->u_ocsp.client.verify_required) + return 1; + cbinfo->u_ocsp.client.verify_errstr = + US"(SSL_connect) Required TLS certificate status not received"; + return 0; + } if (!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len))) { @@ -2483,39 +2528,140 @@ if (!(bs = OCSP_response_get1_basic(rsp))) */ { BIO * bp = NULL; + X509_STORE * verify_store = NULL; + BOOL have_verified_OCSP_signer = FALSE; #ifndef EXIM_HAVE_OCSP_RESP_COUNT STACK_OF(OCSP_SINGLERESP) * sresp = bs->tbsResponseData->responses; #endif DEBUG(D_tls) bp = BIO_new(BIO_s_mem()); - /*OCSP_RESPONSE_print(bp, rsp, 0); extreme debug: stapling content */ + /* Use the CA & chain that verified the server cert to verify the stapled info */ + + { + /* If this routine is not available, we've avoided [in tls_client_start()] + 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 + X509 * signer; + + if ( tls_out.dane_verified + && (have_verified_OCSP_signer = + OCSP_resp_get0_signer(bs, &signer, SSL_get0_verified_chain(ssl)) == 1)) + { + DEBUG(D_tls) + debug_printf("signer for OCSP basicres is in the verified chain;" + " shortcut its verification\n"); + } + else +#endif + { + STACK_OF(X509) * verified_chain; + + verify_store = X509_STORE_new(); + + SSL_get0_chain_certs(ssl, &verified_chain); + add_chain_to_store(verify_store, verified_chain, + "'current cert' per SSL_get0_chain_certs()"); + + verified_chain = SSL_get0_verified_chain(ssl); + add_chain_to_store(verify_store, verified_chain, + "SSL_get0_verified_chain()"); + } + } + + DEBUG(D_tls) + { + debug_printf("Untrusted intermediate cert stack (from SSL_get_peer_cert_chain()):\n"); + x509_stack_dump_cert_s_names(SSL_get_peer_cert_chain(ssl)); + + debug_printf("will use this CA store for verifying basicresp:\n"); + x509_store_dump_cert_s_names(verify_store); + + /* OCSP_RESPONSE_print(bp, rsp, 0); extreme debug: stapling content */ + + debug_printf("certs contained in basicresp:\n"); + x509_stack_dump_cert_s_names((STACK_OF(X509 *))OCSP_resp_get0_certs(bs)); + +#ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS /* else, could bodge via X509_STORE_get0_objects() + - but is OCSP_resp_get0_signer) avail? from 1.1.1 */ + { + X509 * signer; + if (OCSP_resp_get0_signer(bs, &signer, X509_STORE_get1_all_certs(verify_store)) == 1) + { + debug_printf("found signer for basicres:\n"); + debug_print_sn(signer); + } + else + { + debug_printf("failed to find signer for basicres:\n"); + ERR_print_errors(bp); + } + } +#endif + + } + + ERR_clear_error(); + + /* Under DANE the trust-anchor (at least in TA mode) is indicated by the TLSA + record in DNS, and probably is not the root of the chain of certificates. So + accept a partial chain for that case (and hope that anchor is visible for + verifying the OCSP stapling). + XXX for EE mode it won't even be that. Does that make OCSP useless for EE? - /* Use the chain that verified the server cert to verify the stapled info */ - /* DEBUG(D_tls) x509_store_dump_cert_s_names(cbinfo->u_ocsp.client.verify_store); */ + Worse, for LetsEncrypt-mode (ocsp signer is leaf-signer) under DANE, the + data used within OpenSSL for the signer has nil pointers for signing + algorithms - and a crash results. Avoid this by shortcutting verification, + having determined that the OCSP signer is in the (DANE-)validated set. + */ + +#ifndef OCSP_PARTIAL_CHAIN /* defined for 3.0.0 onwards */ +# define OCSP_PARTIAL_CHAIN 0 +#endif - if ((i = OCSP_basic_verify(bs, cbinfo->verify_stack, - cbinfo->u_ocsp.client.verify_store, OCSP_NOEXPLICIT)) <= 0) + if ((i = OCSP_basic_verify(bs, SSL_get_peer_cert_chain(ssl), + verify_store, + tls_out.dane_verified + ? have_verified_OCSP_signer + ? OCSP_NOVERIFY | OCSP_NOEXPLICIT + : OCSP_PARTIAL_CHAIN | OCSP_NOEXPLICIT + : OCSP_NOEXPLICIT)) <= 0) + { + DEBUG(D_tls) debug_printf("OCSP_basic_verify() fail: returned %d\n", i); if (ERR_peek_error()) { tls_out.ocsp = OCSP_FAILED; if (LOGGING(tls_cipher)) { - const uschar * errstr = CUS ERR_reason_error_string(ERR_peek_error()); static uschar peerdn[256]; + const uschar * errstr;; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + ERR_peek_error_all(NULL, NULL, NULL, CCSS &errstr, NULL); + if (!errstr) +#endif + errstr = CUS ERR_reason_error_string(ERR_peek_error()); + X509_NAME_oneline(X509_get_subject_name(SSL_get_peer_certificate(ssl)), CS peerdn, sizeof(peerdn)); log_write(0, LOG_MAIN, "[%s] %s Received TLS cert (DN: '%.*s') status response, " "itself unverifiable: %s", - sender_host_address, sender_host_name, - (int)sizeof(peerdn), peerdn, - errstr); + deliver_host_address, deliver_host, + (int)sizeof(peerdn), peerdn, errstr); } DEBUG(D_tls) { BIO_printf(bp, "OCSP response verify failure\n"); ERR_print_errors(bp); + { + uschar * s = NULL; + int len = (int) BIO_get_mem_data(bp, CSS &s); + if (len > 0) debug_printf("%.*s", len, s); + BIO_reset(bp); + } OCSP_RESPONSE_print(bp, rsp, 0); } goto failed; @@ -2523,6 +2669,7 @@ if (!(bs = OCSP_response_get1_basic(rsp))) else DEBUG(D_tls) debug_printf("no explicit trust for OCSP signing" " in the root CA certificate; ignoring\n"); + } DEBUG(D_tls) debug_printf("OCSP response well-formed and signed OK\n"); @@ -2565,6 +2712,8 @@ if (!(bs = OCSP_response_get1_basic(rsp))) { tls_out.ocsp = OCSP_FAILED; DEBUG(D_tls) ERR_print_errors(bp); + cbinfo->u_ocsp.client.verify_errstr = + US"(SSL_connect) Server certificate status is out-of-date"; log_write(0, LOG_MAIN, "OCSP dates invalid"); goto failed; } @@ -2576,12 +2725,16 @@ if (!(bs = OCSP_response_get1_basic(rsp))) case V_OCSP_CERTSTATUS_GOOD: continue; /* the idx loop */ case V_OCSP_CERTSTATUS_REVOKED: + cbinfo->u_ocsp.client.verify_errstr = + US"(SSL_connect) Server certificate revoked"; log_write(0, LOG_MAIN, "Server certificate revoked%s%s", reason != -1 ? "; reason: " : "", reason != -1 ? OCSP_crl_reason_str(reason) : ""); DEBUG(D_tls) time_print(bp, "Revocation Time", rev); break; default: + cbinfo->u_ocsp.client.verify_errstr = + US"(SSL_connect) Server certificate has unknown status"; log_write(0, LOG_MAIN, "Server certificate status unknown, in OCSP stapling"); break; @@ -2635,8 +2788,7 @@ tls_init(host_item * host, smtp_transport_options_block * ob, uschar *ocsp_file, #endif address_item *addr, exim_openssl_state_st ** caller_state, - tls_support * tlsp, - uschar ** errstr) + tls_support * tlsp, uschar ** errstr) { SSL_CTX * ctx; exim_openssl_state_st * state; @@ -2798,7 +2950,7 @@ else #ifdef EXIM_HAVE_OPENSSL_TLSEXT # ifndef DISABLE_OCSP - if (!(state->verify_stack = sk_X509_new_null())) + if (!host && !(state->u_ocsp.server.verify_stack = sk_X509_new_null())) { DEBUG(D_tls) debug_printf("failed to create stack for stapling verify\n"); return FAIL; @@ -2847,11 +2999,12 @@ else /* client */ DEBUG(D_tls) debug_printf("failed to create store for stapling verify\n"); return FAIL; } + SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb); SSL_CTX_set_tlsext_status_arg(ctx, state); } # endif -#endif +#endif /*EXIM_HAVE_OPENSSL_TLSEXT*/ state->verify_cert_hostnames = NULL; @@ -2990,7 +3143,7 @@ if (tlsp->peercert) *************************************************/ #ifndef DISABLE_OCSP -/* Load certs from file, return TRUE on success */ +/* In the server, load certs from file, return TRUE on success */ static BOOL chain_from_pem_file(const uschar * file, STACK_OF(X509) ** vp) @@ -3020,7 +3173,7 @@ repeated after a Server Name Indication. Arguments: sctx SSL_CTX* to initialise - certs certs file, returned expanded + certsp certs file, returned expanded crl CRL file or NULL host NULL in a server; the remote host in a client errstr error string pointer @@ -3066,19 +3219,20 @@ if (expcerts && *expcerts) { STACK_OF(X509) * verify_stack = #ifndef DISABLE_OCSP - !host ? state_server.verify_stack : + !host ? state_server.u_ocsp.server.verify_stack : #endif NULL; STACK_OF(X509) ** vp = &verify_stack; file = expcerts; dir = NULL; #ifndef DISABLE_OCSP - /* In the server if we will be offering an OCSP proof, load chain from + /* In the server if we will be offering an OCSP proof; load chain from file for verifying the OCSP proof at load time. */ /*XXX Glitch! The file here is tls_verify_certs: the chain for verifying the client cert. This is inconsistent with the need to verify the OCSP proof of the server cert. */ +/* *debug_printf("file for checking server ocsp stapling is: %s\n", file); */ if ( !host && statbuf.st_size > 0 && state_server.u_ocsp.server.file @@ -3304,7 +3458,7 @@ TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 if (state_server.lib_state.pri_string) { DEBUG(D_tls) debug_printf("TLS: cipher list was preloaded\n"); } -else +else { if (!expand_check(tls_require_ciphers, US"tls_require_ciphers", &expciphers, errstr)) return FAIL; @@ -3707,7 +3861,6 @@ tls_retrieve_session(tls_support * tlsp, SSL * ssl) { if (tlsp->host_resumable) { - const uschar * key = tlsp->resume_index; dbdata_tls_session * dt; int len; open_db dbblock, * dbm_file; @@ -3956,7 +4109,6 @@ tlsp->tlsa_usage = 0; #ifndef DISABLE_OCSP { # ifdef SUPPORT_DANE - /*XXX this should be moved to caller, to be common across gnutls/openssl */ if ( conn_args->dane && ob->hosts_request_ocsp[0] == '*' && ob->hosts_request_ocsp[1] == '\0' @@ -3979,6 +4131,15 @@ tlsp->tlsa_usage = 0; # endif request_ocsp = verify_check_given_host(CUSS &ob->hosts_request_ocsp, host) == OK; + +# if defined(SUPPORT_DANE) && !defined(EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER) + if (conn_args->dane && (require_ocsp || request_ocsp)) + { + DEBUG(D_tls) debug_printf("OpenSSL version to early to combine OCSP" + " and DANE; disabling OCSP\n"); + require_ocsp = request_ocsp = FALSE; + } +# endif } #endif @@ -4050,6 +4211,7 @@ if (conn_args->dane) tls_error(US"context init", host, NULL, errstr); return FALSE; } + DEBUG(D_tls) debug_printf("since dane-mode conn, not loading the usual CA bundle\n"); } else @@ -4186,7 +4348,12 @@ if (conn_args->dane) if (rc <= 0) { - tls_error(US"SSL_connect", host, sigalrm_seen ? US"timed out" : NULL, errstr); +#ifndef DISABLE_OCSP + if (client_static_state->u_ocsp.client.verify_errstr) + { if (errstr) *errstr = client_static_state->u_ocsp.client.verify_errstr; } + else +#endif + tls_error(US"SSL_connect", host, sigalrm_seen ? US"timed out" : NULL, errstr); return FALSE; } @@ -4373,7 +4540,6 @@ tls_get_cache(unsigned lim) { #ifndef DISABLE_DKIM int n = ssl_xfer_buffer_hwm - ssl_xfer_buffer_lwm; -debug_printf("tls_get_cache\n"); if (n > lim) n = lim; if (n > 0) @@ -4633,8 +4799,8 @@ if (do_shutdown > TLS_NO_SHUTDOWN) if (!o_ctx) /* server side */ { #ifndef DISABLE_OCSP - sk_X509_pop_free(state_server.verify_stack, X509_free); - state_server.verify_stack = NULL; + sk_X509_pop_free(state_server.u_ocsp.server.verify_stack, X509_free); + state_server.u_ocsp.server.verify_stack = NULL; #endif receive_getc = smtp_getc; commit 6bf0021993572586f031ac7d973ca33358c2dac8 Author: Jeremy Harris Date: Fri Nov 25 12:33:28 2022 +0000 OpenSSL: fix build on older library version diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 3873bbba3..e673cb9f9 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -47,6 +47,7 @@ functions from the OpenSSL library. */ #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L # define EXIM_HAVE_OCSP_RESP_COUNT +# define EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN # define OPENSSL_AUTO_SHA256 # define OPENSSL_MIN_PROTO_VERSION #else @@ -78,6 +79,7 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_SESSION_TICKET # define EXIM_HAVE_OPESSL_TRACE # define EXIM_HAVE_OPESSL_GET0_SERIAL +# define EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS # ifndef DISABLE_OCSP # define EXIM_HAVE_OCSP # endif @@ -1956,7 +1958,7 @@ tls_client_creds_invalidate(transport_instance * t) static void debug_print_sn(const X509 * cert) { -X509_NAME * sn = X509_get_subject_name(cert); +X509_NAME * sn = X509_get_subject_name((X509 *)cert); static uschar name[256]; if (X509_NAME_oneline(sn, CS name, sizeof(name))) { @@ -1984,23 +1986,13 @@ static void x509_store_dump_cert_s_names(X509_STORE * store) { # ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS -STACK_OF(X509) * sk = X509_STORE_get1_all_certs(store); -x509_stack_dump_cert_s_names(sk); -sk_X509_pop_free(sk, X509_free); - -# else if (!store) debug_printf(" (no store)\n"); else { - STACK_OF(X509_OBJECT) * objs = X509_STORE_get0_objects(store); - if (!objs) - debug_printf(" (null objectlist)\n"); - else for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) - { - X509 * cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); - if (cert) debug_print_sn(cert); - } + STACK_OF(X509) * sk = X509_STORE_get1_all_certs(store); + x509_stack_dump_cert_s_names(sk); + sk_X509_pop_free(sk, X509_free); } # endif } @@ -2564,10 +2556,11 @@ if (!(bs = OCSP_response_get1_basic(rsp))) SSL_get0_chain_certs(ssl, &verified_chain); add_chain_to_store(verify_store, verified_chain, "'current cert' per SSL_get0_chain_certs()"); - +#ifdef EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN verified_chain = SSL_get0_verified_chain(ssl); add_chain_to_store(verify_store, verified_chain, "SSL_get0_verified_chain()"); +#endif } } @@ -2582,10 +2575,16 @@ if (!(bs = OCSP_response_get1_basic(rsp))) /* OCSP_RESPONSE_print(bp, rsp, 0); extreme debug: stapling content */ debug_printf("certs contained in basicresp:\n"); - x509_stack_dump_cert_s_names((STACK_OF(X509 *))OCSP_resp_get0_certs(bs)); + x509_stack_dump_cert_s_names( +#ifdef EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS + OCSP_resp_get0_certs(bs) +#else + bs->certs +#endif + ); -#ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS /* else, could bodge via X509_STORE_get0_objects() - - but is OCSP_resp_get0_signer) avail? from 1.1.1 */ +#ifdef EXIM_HAVE_OPENSSL_X509_STORE_GET1_ALL_CERTS +/* could do via X509_STORE_get0_objects(); not worth it just for debug info */ { X509 * signer; if (OCSP_resp_get0_signer(bs, &signer, X509_STORE_get1_all_certs(verify_store)) == 1) @@ -2623,11 +2622,14 @@ if (!(bs = OCSP_response_get1_basic(rsp))) if ((i = OCSP_basic_verify(bs, SSL_get_peer_cert_chain(ssl), verify_store, +#ifdef SUPPORT_DANE tls_out.dane_verified ? have_verified_OCSP_signer ? OCSP_NOVERIFY | OCSP_NOEXPLICIT : OCSP_PARTIAL_CHAIN | OCSP_NOEXPLICIT - : OCSP_NOEXPLICIT)) <= 0) + : +#endif + OCSP_NOEXPLICIT)) <= 0) { DEBUG(D_tls) debug_printf("OCSP_basic_verify() fail: returned %d\n", i); if (ERR_peek_error()) commit 02a33248dc5981a63931530a57c76ff27464bde5 Author: Jeremy Harris Date: Sun Nov 27 11:29:40 2022 +0000 Fix LibreSSL build diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index e673cb9f9..8ed413e91 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -47,7 +47,6 @@ functions from the OpenSSL library. */ #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L # define EXIM_HAVE_OCSP_RESP_COUNT -# define EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN # define OPENSSL_AUTO_SHA256 # define OPENSSL_MIN_PROTO_VERSION #else @@ -80,6 +79,7 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_OPESSL_TRACE # define EXIM_HAVE_OPESSL_GET0_SERIAL # define EXIM_HAVE_OPESSL_OCSP_RESP_GET0_CERTS +# define EXIM_HAVE_SSL_GET0_VERIFIED_CHAIN # ifndef DISABLE_OCSP # define EXIM_HAVE_OCSP # endif @@ -2232,7 +2232,7 @@ if (lib_ctx_new(&server_sni, NULL, &dummy_errstr) != OK) /* Not sure how many of these are actually needed, since SSL object already exists. Might even need this selfsame callback, for reneg? */ - { + { SSL_CTX * ctx = state_server.lib_state.lib_ctx; SSL_CTX_set_info_callback(server_sni, SSL_CTX_get_info_callback(ctx)); SSL_CTX_set_mode(server_sni, SSL_CTX_get_mode(ctx)); @@ -2244,7 +2244,7 @@ already exists. Might even need this selfsame callback, for reneg? */ SSL_CTX_set_timeout(server_sni, SSL_CTX_get_timeout(ctx)); SSL_CTX_set_tlsext_servername_callback(server_sni, tls_servername_cb); SSL_CTX_set_tlsext_servername_arg(server_sni, state); - } + } if ( !init_dh(server_sni, state->dhparam, &dummy_errstr) || !init_ecdh(server_sni, &dummy_errstr) commit a85c067ba6c6940512cf57ec213277a370d87e70 Author: Jeremy Harris Date: Sun Nov 27 14:38:37 2022 +0000 SPDX: license tags (mostly by guesswork) diff --git a/src/exim_monitor/em_StripChart.c b/src/exim_monitor/em_StripChart.c index 3b94c2231..3eb98e4fb 100644 --- a/src/exim_monitor/em_StripChart.c +++ b/src/exim_monitor/em_StripChart.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /*********************************************************** Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. diff --git a/src/exim_monitor/em_TextPop.c b/src/exim_monitor/em_TextPop.c index ff5d1a8f7..0e87cb580 100644 --- a/src/exim_monitor/em_TextPop.c +++ b/src/exim_monitor/em_TextPop.c @@ -2,6 +2,7 @@ Copyright (c) The Exim Maintainers 2022 Copyright 1989 by the Massachusetts Institute of Technology, Cambridge, Massachusetts. +SPDX-License-Identifier: GPL-2.0-only All Rights Reserved diff --git a/src/exim_monitor/em_globals.c b/src/exim_monitor/em_globals.c index 3d452c6ec..2943065b4 100644 --- a/src/exim_monitor/em_globals.c +++ b/src/exim_monitor/em_globals.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_hdr.h b/src/exim_monitor/em_hdr.h index ab37806b7..76970c997 100644 --- a/src/exim_monitor/em_hdr.h +++ b/src/exim_monitor/em_hdr.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This is the general header file for all the modules that comprise diff --git a/src/exim_monitor/em_init.c b/src/exim_monitor/em_init.c index e0bc3b066..e1f53fbba 100644 --- a/src/exim_monitor/em_init.c +++ b/src/exim_monitor/em_init.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module contains code to initialize things from the environment and the arguments. */ diff --git a/src/exim_monitor/em_log.c b/src/exim_monitor/em_log.c index 8d85c13f1..d625056c5 100644 --- a/src/exim_monitor/em_log.c +++ b/src/exim_monitor/em_log.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainters 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module contains code for scanning the main log, extracting information from it, and displaying a "tail". */ diff --git a/src/exim_monitor/em_main.c b/src/exim_monitor/em_main.c index 86caf71eb..919cde632 100644 --- a/src/exim_monitor/em_main.c +++ b/src/exim_monitor/em_main.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_menu.c b/src/exim_monitor/em_menu.c index 881f3748c..afcd31540 100644 --- a/src/exim_monitor/em_menu.c +++ b/src/exim_monitor/em_menu.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_queue.c b/src/exim_monitor/em_queue.c index 9badd2451..d9cfad38a 100644 --- a/src/exim_monitor/em_queue.c +++ b/src/exim_monitor/em_queue.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_strip.c b/src/exim_monitor/em_strip.c index 03864d290..cfafe9257 100644 --- a/src/exim_monitor/em_strip.c +++ b/src/exim_monitor/em_strip.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_text.c b/src/exim_monitor/em_text.c index 3a3682959..1077353e0 100644 --- a/src/exim_monitor/em_text.c +++ b/src/exim_monitor/em_text.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_version.c b/src/exim_monitor/em_version.c index b627a6e2b..c5d4d62d8 100644 --- a/src/exim_monitor/em_version.c +++ b/src/exim_monitor/em_version.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #define EM_VERSION_C diff --git a/src/exim_monitor/em_xs.c b/src/exim_monitor/em_xs.c index ee91f7c15..dd19c7f43 100644 --- a/src/exim_monitor/em_xs.c +++ b/src/exim_monitor/em_xs.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge, 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file contains a number of subroutines that are in effect just alternative packaging for calls to various X functions that diff --git a/src/scripts/Configure-config.h b/src/scripts/Configure-config.h index 75d366fca..c750f64f1 100755 --- a/src/scripts/Configure-config.h +++ b/src/scripts/Configure-config.h @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0-only # Build the config.h file, using the buildconfig program, first ensuring that # it exists. diff --git a/src/scripts/Configure-os.c b/src/scripts/Configure-os.c index f00a5627a..ab40ad183 100755 --- a/src/scripts/Configure-os.c +++ b/src/scripts/Configure-os.c @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0-only # Shell script to build os.c. There doesn't have to be an OS-specific os.c # file, but if there is, it gets copied at the start of os.c. The basic src diff --git a/src/scripts/Configure-os.h b/src/scripts/Configure-os.h index ae1ecf943..f95a61a5d 100755 --- a/src/scripts/Configure-os.h +++ b/src/scripts/Configure-os.h @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0-only # Shell script to create a link to the appropriate OS-specific header file. diff --git a/src/src/acl.c b/src/src/acl.c index 1e7d28a90..92af9991f 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Code for handling Access Control Lists (ACLs) */ diff --git a/src/src/arc.c b/src/src/arc.c index 86688f6e3..e3a2b3dad 100644 --- a/src/src/arc.c +++ b/src/src/arc.c @@ -5,6 +5,7 @@ Copyright (c) Jeremy Harris 2018 - 2020 Copyright (c) The Exim Maintainers 2021 - 2022 License: GPL + SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/auths/auth-spa.c b/src/src/auths/auth-spa.c index 8d886b6b6..32276c3f3 100644 --- a/src/src/auths/auth-spa.c +++ b/src/src/auths/auth-spa.c @@ -10,6 +10,7 @@ * Samba project (by Andrew Tridgell, Jeremy Allison, and others). * * Copyright (c) The Exim Maintainers 2021 + * SPDX-License-Identifier: GPL-2.0-only * Tom Kistner provided additional code, adding spa_build_auth_challenge() to * support server authentication mode. diff --git a/src/src/auths/auth-spa.h b/src/src/auths/auth-spa.h index cfe1b086d..df250d7a6 100644 --- a/src/src/auths/auth-spa.h +++ b/src/src/auths/auth-spa.h @@ -9,6 +9,7 @@ * All the code used here was torn by Marc Prud'hommeaux out of the * Samba project (by Andrew Tridgell, Jeremy Allison, and others). */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* December 2004: The spa_base64_to_bits() function has no length checking in it. I have added a check. PH */ diff --git a/src/src/auths/call_pam.c b/src/src/auths/call_pam.c index 80f80f1a8..483b083be 100644 --- a/src/src/auths/call_pam.c +++ b/src/src/auths/call_pam.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/auths/call_pwcheck.c b/src/src/auths/call_pwcheck.c index 0adde4471..436b1a8de 100644 --- a/src/src/auths/call_pwcheck.c +++ b/src/src/auths/call_pwcheck.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module contains interface functions to the two Cyrus authentication daemons. The original one was "pwcheck", which gives its name to the source diff --git a/src/src/auths/call_radius.c b/src/src/auths/call_radius.c index e7f9f521d..f4d7a9569 100644 --- a/src/src/auths/call_radius.c +++ b/src/src/auths/call_radius.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file was originally supplied by Ian Kirk. The libradius support came from Alex Kiernan. */ diff --git a/src/src/auths/check_serv_cond.c b/src/src/auths/check_serv_cond.c index 457a7150c..033d2026b 100644 --- a/src/src/auths/check_serv_cond.c +++ b/src/src/auths/check_serv_cond.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c index 2c0616ca2..60128b83e 100644 --- a/src/src/auths/cram_md5.c +++ b/src/src/auths/cram_md5.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The stand-alone version just tests the algorithm. We have to drag diff --git a/src/src/auths/cram_md5.h b/src/src/auths/cram_md5.h index 95644db68..25470a61b 100644 --- a/src/src/auths/cram_md5.h +++ b/src/src/auths/cram_md5.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index c8e2da5de..4fe257ba7 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This code was originally contributed by Matthew Byng-Maddick */ diff --git a/src/src/auths/cyrus_sasl.h b/src/src/auths/cyrus_sasl.h index 6cf883454..144ac5c80 100644 --- a/src/src/auths/cyrus_sasl.h +++ b/src/src/auths/cyrus_sasl.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) A L Digital Ltd 2004 */ diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index 5d7713389..ed56ab8cd 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -1,6 +1,7 @@ /* * Copyright (c) The Exim Maintainers 2006 - 2022 * Copyright (c) 2004 Andrey Panin + * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published diff --git a/src/src/auths/dovecot.h b/src/src/auths/dovecot.h index bfe1f0775..b5eaf4f16 100644 --- a/src/src/auths/dovecot.h +++ b/src/src/auths/dovecot.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainters 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/auths/external.c b/src/src/auths/external.c index 7e7fca841..736c33982 100644 --- a/src/src/auths/external.c +++ b/src/src/auths/external.c @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 2019-2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file provides an Exim authenticator driver for a server to verify a client SSL certificate, using the EXTERNAL diff --git a/src/src/auths/external.h b/src/src/auths/external.h index 7d43650bb..9abb46a6b 100644 --- a/src/src/auths/external.h +++ b/src/src/auths/external.h @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 2019 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index e0d79db3c..0c85d2651 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/auths/get_no64_data.c b/src/src/auths/get_no64_data.c index a019756e5..76f421473 100644 --- a/src/src/auths/get_no64_data.c +++ b/src/src/auths/get_no64_data.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c index e49e83b81..aac9c84e6 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl_exim.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/gsasl_exim.h b/src/src/auths/gsasl_exim.h index 19c903611..691d7d706 100644 --- a/src/src/auths/gsasl_exim.h +++ b/src/src/auths/gsasl_exim.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) Twitter Inc 2012 */ diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c index 381763299..12267e3fc 100644 --- a/src/src/auths/heimdal_gssapi.c +++ b/src/src/auths/heimdal_gssapi.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/heimdal_gssapi.h b/src/src/auths/heimdal_gssapi.h index 49775aff9..031b580ef 100644 --- a/src/src/auths/heimdal_gssapi.h +++ b/src/src/auths/heimdal_gssapi.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c index 58d178359..61be5867e 100644 --- a/src/src/auths/plaintext.c +++ b/src/src/auths/plaintext.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "plaintext.h" diff --git a/src/src/auths/plaintext.h b/src/src/auths/plaintext.h index 4c6d01136..49862ff9b 100644 --- a/src/src/auths/plaintext.h +++ b/src/src/auths/plaintext.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/auths/pwcheck.c b/src/src/auths/pwcheck.c index 7dd529fbc..aff5ed39c 100644 --- a/src/src/auths/pwcheck.c +++ b/src/src/auths/pwcheck.c @@ -4,6 +4,7 @@ * $Id: checkpw.c,v 1.49 2002/03/07 19:14:04 ken3 Exp $ */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. * diff --git a/src/src/auths/pwcheck.h b/src/src/auths/pwcheck.h index 1287ea253..4247b4e8b 100644 --- a/src/src/auths/pwcheck.h +++ b/src/src/auths/pwcheck.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file provides support for authentication via the Cyrus SASL pwcheck daemon (whence its name) and the newer saslauthd daemon. */ diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c index ff90d33a3..c5e6d83d5 100644 --- a/src/src/auths/spa.c +++ b/src/src/auths/spa.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file, which provides support for Microsoft's Secure Password Authentication, was contributed by Marc Prud'hommeaux. Tom Kistner added SPA diff --git a/src/src/auths/spa.h b/src/src/auths/spa.h index ca93469a3..4321971d9 100644 --- a/src/src/auths/spa.h +++ b/src/src/auths/spa.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file, which provides support for Microsoft's Secure Password Authentication, was contributed by Marc Prud'hommeaux. */ diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c index 325e7b4c7..d3ca8f796 100644 --- a/src/src/auths/tls.c +++ b/src/src/auths/tls.c @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file provides an Exim authenticator driver for a server to verify a client SSL certificate diff --git a/src/src/auths/tls.h b/src/src/auths/tls.h index 7aa95b6c7..24e116464 100644 --- a/src/src/auths/tls.h +++ b/src/src/auths/tls.h @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/auths/xtextdecode.c b/src/src/auths/xtextdecode.c index 746dfbdb4..39c1f2b60 100644 --- a/src/src/auths/xtextdecode.c +++ b/src/src/auths/xtextdecode.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/auths/xtextencode.c b/src/src/auths/xtextencode.c index fc571c799..89f12f1f1 100644 --- a/src/src/auths/xtextencode.c +++ b/src/src/auths/xtextencode.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/base64.c b/src/src/base64.c index fa06a7a34..14e8cfffe 100644 --- a/src/src/base64.c +++ b/src/src/base64.c @@ -4,6 +4,7 @@ /* Copyright (c) Tom Kistner 2004, 2015 */ /* License: GPL */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ diff --git a/src/src/blob.h b/src/src/blob.h index a3f1e24d4..95a987f0a 100644 --- a/src/src/blob.h +++ b/src/src/blob.h @@ -2,6 +2,7 @@ * Blob - a general pointer/size item for a memory chunk * * Copyright (C) 2016 Exim maintainers + * SPDX-License-Identifier: GPL-2.0-only */ #ifndef BLOB_H /* entire file */ diff --git a/src/src/bmi_spam.c b/src/src/bmi_spam.c index af4bc4640..140bec48f 100644 --- a/src/src/bmi_spam.c +++ b/src/src/bmi_spam.c @@ -6,6 +6,7 @@ Copyright (c) Tom Kistner 2004 License: GPL */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" #ifdef EXPERIMENTAL_BRIGHTMAIL diff --git a/src/src/bmi_spam.h b/src/src/bmi_spam.h index a9af7784e..a9833b200 100644 --- a/src/src/bmi_spam.h +++ b/src/src/bmi_spam.h @@ -5,6 +5,7 @@ /* Code for calling Brightmail AntiSpam. Copyright (c) Tom Kistner 2004 License: GPL */ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifdef EXPERIMENTAL_BRIGHTMAIL diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c index bbbaefe9c..710b53550 100644 --- a/src/src/buildconfig.c +++ b/src/src/buildconfig.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /************************************************* diff --git a/src/src/child.c b/src/src/child.c index 1f38b585c..b94e814a1 100644 --- a/src/src/child.c +++ b/src/src/child.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/crypt16.c b/src/src/crypt16.c index 56353c326..659bf88bd 100644 --- a/src/src/crypt16.c +++ b/src/src/crypt16.c @@ -2,6 +2,7 @@ * Copyright (c) 2000-2002 * Chris Adams * written for HiWAAY Internet Services + * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/src/daemon.c b/src/src/daemon.c index 8446f81cb..0afc7ca86 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with running Exim as a daemon */ diff --git a/src/src/dane.c b/src/src/dane.c index 5ba61961a..f2ad22481 100644 --- a/src/src/dane.c +++ b/src/src/dane.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012, 2014 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module provides DANE (RFC6659) support for Exim. See also the draft RFC for DANE-over-SMTP, "SMTP security via opportunistic DANE TLS" diff --git a/src/src/dbfn.c b/src/src/dbfn.c index ea94b7ff0..f932520f9 100644 --- a/src/src/dbfn.c +++ b/src/src/dbfn.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/dbfunctions.h b/src/src/dbfunctions.h index 07d4a6233..93e1d3405 100644 --- a/src/src/dbfunctions.h +++ b/src/src/dbfunctions.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef DBFUNCTIONS_H #define DBFUNCTIONS_H diff --git a/src/src/dcc.c b/src/src/dcc.c index 56dd6d570..d8e22b30c 100644 --- a/src/src/dcc.c +++ b/src/src/dcc.c @@ -8,6 +8,7 @@ * See the file NOTICE for conditions of use and distribution. * * Copyright (c) The Exim Maintainers 2015 - 2022 + * SPDX-License-Identifier: GPL-2.0-only */ /* Code for calling dccifd. Called from acl.c. */ diff --git a/src/src/debug.c b/src/src/debug.c index 26d09ea2f..38e8f8001 100644 --- a/src/src/debug.c +++ b/src/src/debug.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2015 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/deliver.c b/src/src/deliver.c index 725d0c872..719fa9d93 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The main code for delivering a message. */ diff --git a/src/src/directory.c b/src/src/directory.c index 189020855..c3b341bbb 100644 --- a/src/src/directory.c +++ b/src/src/directory.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2010 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/dkim.c b/src/src/dkim.c index bb916d2eb..9b6e14a3f 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge, 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Code for DKIM support. Other DKIM relevant code is in receive.c, transport.c and transports/smtp.c */ diff --git a/src/src/dkim.h b/src/src/dkim.h index 7b94f22ef..61d83a9df 100644 --- a/src/src/dkim.h +++ b/src/src/dkim.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge, 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ void dkim_exim_init(void); gstring * dkim_exim_sign(int, off_t, uschar *, struct ob_dkim *, const uschar **); diff --git a/src/src/dkim_transport.c b/src/src/dkim_transport.c index cfd4b9085..142f4552a 100644 --- a/src/src/dkim_transport.c +++ b/src/src/dkim_transport.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Transport shim for dkim signing */ diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 53c2752ac..c0313bf5c 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -5,6 +5,7 @@ Copyright (c) The Exim Maintainers 2019 - 2022 Copyright (c) Todd Lyons 2012 - 2014 License: GPL */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; All rights reserved, licensed for use per LICENSE.opendmarc. */ diff --git a/src/src/dmarc.h b/src/src/dmarc.h index 899cd7e13..f71f1fd5a 100644 --- a/src/src/dmarc.h +++ b/src/src/dmarc.h @@ -6,6 +6,7 @@ Copyright (c) The Exim Maintainers 2021 - 2022 Copyright (c) Todd Lyons 2012 - 2014 License: GPL */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; All rights reserved, licensed for use per LICENSE.opendmarc. */ diff --git a/src/src/dns.c b/src/src/dns.c index 4071c5822..8106fb688 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for interfacing with the DNS. */ diff --git a/src/src/dnsbl.c b/src/src/dnsbl.c index db839af04..af80f6be1 100644 --- a/src/src/dnsbl.c +++ b/src/src/dnsbl.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with dnsbls */ diff --git a/src/src/drtables.c b/src/src/drtables.c index 30eb855e3..a6cbede89 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/dummies.c b/src/src/dummies.c index 38b514b6c..a72767ccd 100644 --- a/src/src/dummies.c +++ b/src/src/dummies.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file is not part of the main Exim code. There are little bits of test code for some of Exim's modules, and when they are used, the module they are diff --git a/src/src/enq.c b/src/src/enq.c index f7f8c9c16..054aeaed8 100644 --- a/src/src/enq.c +++ b/src/src/enq.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with serialization. */ diff --git a/src/src/environment.c b/src/src/environment.c index 9cb90c86f..06f804e69 100644 --- a/src/src/environment.c +++ b/src/src/environment.c @@ -5,6 +5,7 @@ /* Copyright (c) Heiko Schlittermann 2016 * hs@schlittermann.de * See the file NOTICE for conditions of use and distribution. + * SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/exim.c b/src/src/exim.c index 3cd1d5f6d..62413e367 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The main function: entry point, initialization, and high-level control. diff --git a/src/src/exim.h b/src/src/exim.h index 61642b5e7..24fedcced 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Source files for exim all #include this header, which drags in everything diff --git a/src/src/exim_dbmbuild.c b/src/src/exim_dbmbuild.c index 5c046347b..bb04adc02 100644 --- a/src/src/exim_dbmbuild.c +++ b/src/src/exim_dbmbuild.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* A small freestanding program to build dbm databases from serial input. For diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c index 3824309b5..669f7098d 100644 --- a/src/src/exim_dbutil.c +++ b/src/src/exim_dbutil.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This single source file is used to compile three utility programs for diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c index 427d22c1e..1a54a92ad 100644 --- a/src/src/exim_lock.c +++ b/src/src/exim_lock.c @@ -11,6 +11,7 @@ Default is -fcntl -lockfile. Argument: the name of the lock file Copyright (c) The Exim Maintainers 2016 - 2021 +SPDX-License-Identifier: GPL-2.0-only */ #include "os.h" diff --git a/src/src/expand.c b/src/src/expand.c index ff0b4d600..050f01297 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for handling string expansion. */ diff --git a/src/src/filter.c b/src/src/filter.c index cc4af230e..82a9122c6 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Code for mail filtering functions. */ diff --git a/src/src/filtertest.c b/src/src/filtertest.c index 87ebfb14f..8bab65e78 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Code for the filter test function. */ diff --git a/src/src/functions.h b/src/src/functions.h index d5164547a..be1fae00d 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Prototypes for functions that appear in various modules. Gathered together diff --git a/src/src/globals.c b/src/src/globals.c index cafb15992..429952edc 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* All the global variables are defined together in this one module, so that they are easy to find. */ diff --git a/src/src/globals.h b/src/src/globals.h index 1be96daec..48d93a1c3 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Almost all the global variables are defined together in this one header, so that they are easy to find. However, those that are visible during the diff --git a/src/src/hash.c b/src/src/hash.c index 51bcd4604..2b71463f1 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -3,6 +3,7 @@ * * Copyright (c) The Exim Maintainers 2010 - 2022 * Copyright (c) University of Cambridge 1995 - 2009 + * SPDX-License-Identifier: GPL-2.0-only * * Hash interface functions */ diff --git a/src/src/hash.h b/src/src/hash.h index 588325baf..c94e53129 100644 --- a/src/src/hash.h +++ b/src/src/hash.h @@ -1,6 +1,7 @@ /* * Exim - an Internet mail transport agent * Copyright (c) The Exim Maintainers 1995 - 2022 + * SPDX-License-Identifier: GPL-2.0-only * * Hash interface functions */ diff --git a/src/src/header.c b/src/src/header.c index 7ef59ff53..2a8fbfe64 100644 --- a/src/src/header.c +++ b/src/src/header.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/hintsdb.h b/src/src/hintsdb.h index b8e6744d6..e79e6bd49 100644 --- a/src/src/hintsdb.h +++ b/src/src/hintsdb.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This header file contains macro definitions so that a variety of DBM libraries can be used by Exim. Nigel Metheringham provided the original set for diff --git a/src/src/hintsdb_structs.h b/src/src/hintsdb_structs.h index e0670a10e..27cd9edf9 100644 --- a/src/src/hintsdb_structs.h +++ b/src/src/hintsdb_structs.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This header file contains the definitions of the structures used in the various hints databases are also kept in this file, which is used by the diff --git a/src/src/host.c b/src/src/host.c index b6c2ea082..874e19a08 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or directly via the DNS. When IPv6 is supported, getipnodebyname() and diff --git a/src/src/host_address.c b/src/src/host_address.c index 9e6f958be..28a8a685f 100644 --- a/src/src/host_address.c +++ b/src/src/host_address.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/imap_utf7.c b/src/src/imap_utf7.c index aac0fef6a..75ecb1a4b 100644 --- a/src/src/imap_utf7.c +++ b/src/src/imap_utf7.c @@ -1,5 +1,6 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/ip.c b/src/src/ip.c index aa42343fb..2ac2b267d 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for doing things with sockets. With the advent of IPv6 this has got messier, so that it's worth pulling out the code into separate functions diff --git a/src/src/local_scan.c b/src/src/local_scan.c index 7a3bae7e3..85ecba8cb 100644 --- a/src/src/local_scan.c +++ b/src/src/local_scan.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /****************************************************************************** diff --git a/src/src/local_scan.h b/src/src/local_scan.h index c609a27e3..2eabc5929 100644 --- a/src/src/local_scan.h +++ b/src/src/local_scan.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file is the header that is the only Exim header to be included in the source for the local_scan.c() function. It contains definitions that are made diff --git a/src/src/log.c b/src/src/log.c index a46d523db..f1d435ce4 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for writing log files. The code for maintaining datestamped log files was originally contributed by Tony Sheen. */ diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h index 41cc239ce..cec8f976b 100644 --- a/src/src/lookupapi.h +++ b/src/src/lookupapi.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The "type" field in each item is a set of bit flags: diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c index 966078f1a..696e52019 100644 --- a/src/src/lookups/cdb.c +++ b/src/src/lookups/cdb.c @@ -8,6 +8,7 @@ * * Copyright (c) The Exim Maintainers 2020 - 2022 * Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd + * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c index 32514afcc..c99e948b5 100644 --- a/src/src/lookups/dbmdb.c +++ b/src/src/lookups/dbmdb.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index 355be1b5d..4f43cf674 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c index a7691024a..6cae0dafb 100644 --- a/src/src/lookups/dsearch.c +++ b/src/src/lookups/dsearch.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The idea for this code came from Matthew Byng-Maddick, but his original has been heavily reworked a lot for Exim 4 (and it now uses stat() (more precisely: diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c index c4fff71bd..d42e490c4 100644 --- a/src/src/lookups/ibase.c +++ b/src/src/lookups/ibase.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* The code in this module was contributed by Ard Biesheuvel. */ diff --git a/src/src/lookups/json.c b/src/src/lookups/json.c index c9abf8c4c..b1e5fb742 100644 --- a/src/src/lookups/json.c +++ b/src/src/lookups/json.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2019 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index 9751fa3b3..17c431e5c 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Many thanks to Stuart Lynne for contributing the original code for this driver. Further contributions from Michael Haardt, Brian Candler, Barry diff --git a/src/src/lookups/ldap.h b/src/src/lookups/ldap.h index ddfda8597..30228aebe 100644 --- a/src/src/lookups/ldap.h +++ b/src/src/lookups/ldap.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for eldapauth_find */ diff --git a/src/src/lookups/lf_check_file.c b/src/src/lookups/lf_check_file.c index 7f0f12806..1649f9f83 100644 --- a/src/src/lookups/lf_check_file.c +++ b/src/src/lookups/lf_check_file.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h index fd9eb303a..b83b9652a 100644 --- a/src/src/lookups/lf_functions.h +++ b/src/src/lookups/lf_functions.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for the functions that are shared by the lookups */ diff --git a/src/src/lookups/lf_quote.c b/src/src/lookups/lf_quote.c index 6f4143d9f..816fe01e2 100644 --- a/src/src/lookups/lf_quote.c +++ b/src/src/lookups/lf_quote.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c index ce6f1635a..cf4b9cd0b 100644 --- a/src/src/lookups/lf_sqlperform.c +++ b/src/src/lookups/lf_sqlperform.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/lmdb.c b/src/src/lookups/lmdb.c index a32c7f7fb..ccfdbe453 100644 --- a/src/src/lookups/lmdb.c +++ b/src/src/lookups/lmdb.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 2016 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c index dcfdec91e..da73ae8bf 100644 --- a/src/src/lookups/lsearch.c +++ b/src/src/lookups/lsearch.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c index 78b8c2b19..a8dae4ade 100644 --- a/src/src/lookups/mysql.c +++ b/src/src/lookups/mysql.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Thanks to Paul Kelly for contributing the original code for these functions. */ diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c index 0024f44cf..e7c124757 100644 --- a/src/src/lookups/nis.c +++ b/src/src/lookups/nis.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c index d9f3f7d83..78c79563f 100644 --- a/src/src/lookups/nisplus.c +++ b/src/src/lookups/nisplus.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c index d32b5e44d..3f3868fe9 100644 --- a/src/src/lookups/oracle.c +++ b/src/src/lookups/oracle.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Interface to an Oracle database. This code was originally supplied by Paul Kelly, but I have hacked it around for various reasons, and tried to add diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c index eaf78b210..7df1a5aaf 100644 --- a/src/src/lookups/passwd.c +++ b/src/src/lookups/passwd.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c index 4bb693ad1..4fcd0e3ed 100644 --- a/src/src/lookups/pgsql.c +++ b/src/src/lookups/pgsql.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Thanks to Petr Cech for contributing the original code for these functions. Thanks to Joachim Wieland for the initial patch for the Unix domain diff --git a/src/src/lookups/readsock.c b/src/src/lookups/readsock.c index 22179c91c..7c7b9cfa8 100644 --- a/src/src/lookups/readsock.c +++ b/src/src/lookups/readsock.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c index 9c8559c1e..c7fcb66f0 100644 --- a/src/src/lookups/redis.c +++ b/src/src/lookups/redis.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/lookups/spf.c b/src/src/lookups/spf.c index 78d954c8c..a1052d7fc 100644 --- a/src/src/lookups/spf.c +++ b/src/src/lookups/spf.c @@ -7,6 +7,7 @@ Copyright (c) The Exim Maintainers 2020 - 2022 Copyright (c) 2005 Chris Webb, Arachsys Internet Services Ltd +SPDX-License-Identifier: GPL-2.0-or-later This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c index 9080ae702..b9a735e18 100644 --- a/src/src/lookups/sqlite.c +++ b/src/src/lookups/sqlite.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c index 48241615f..f94150b68 100644 --- a/src/src/lookups/testdb.c +++ b/src/src/lookups/testdb.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c index 990703fd0..cd236787e 100644 --- a/src/src/lookups/whoson.c +++ b/src/src/lookups/whoson.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This code originally came from Robert Wal. */ diff --git a/src/src/lss.c b/src/src/lss.c index 167522d2f..0d20c07b6 100644 --- a/src/src/lss.c +++ b/src/src/lss.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Support functions for calling from local_scan(). These are mostly just wrappers for various internal functions. */ diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index a0c659c9f..fe814500d 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) Jeremy Harris 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Create a static data structure with the predefined macros, to be included in the main Exim build */ diff --git a/src/src/macro_predef.h b/src/src/macro_predef.h index 59b1bbe3b..d3bc5c074 100644 --- a/src/src/macro_predef.h +++ b/src/src/macro_predef.h @@ -5,6 +5,7 @@ /* Copyright (c) Jeremy Harris 2017 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Global functions */ diff --git a/src/src/macros.h b/src/src/macros.h index adbe6a267..db1c34b65 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* These two macros make it possible to obtain the result of macro-expanding diff --git a/src/src/malware.c b/src/src/malware.c index 01dd455ba..96514e276 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -6,6 +6,7 @@ * Copyright (c) The Exim Maintainers 2015 - 2022 * Copyright (c) Tom Kistner 2003 - 2015 * License: GPL + * SPDX-License-Identifier: GPL-2.0-only */ /* Code for calling virus (malware) scanners. Called from acl.c. */ diff --git a/src/src/match.c b/src/src/match.c index b4a0352ee..a877aef3b 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for matching strings */ diff --git a/src/src/md5.c b/src/src/md5.c index fdb144e67..e6df32c7a 100644 --- a/src/src/md5.c +++ b/src/src/md5.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef STAND_ALONE #include "exim.h" diff --git a/src/src/mime.c b/src/src/mime.c index c1921992e..bebe9bf44 100644 --- a/src/src/mime.c +++ b/src/src/mime.c @@ -6,6 +6,7 @@ * Copyright (c) The Exim Maintainers 2015 - 2022 * Copyright (c) Tom Kistner 2004 - 2015 * License: GPL + * SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/mime.h b/src/src/mime.h index 5fd4392d5..48bbd81de 100644 --- a/src/src/mime.h +++ b/src/src/mime.h @@ -5,6 +5,7 @@ /* Copyright (c) Tom Kistner 2004, 2015 * License: GPL * Copyright (c) The Exim Maintainers 2016 + * SPDX-License-Identifier: GPL-2.0-only */ #ifdef WITH_CONTENT_SCAN diff --git a/src/src/moan.c b/src/src/moan.c index 4f2550d82..387359458 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for sending messages to sender or to mailmaster. */ diff --git a/src/src/mytypes.h b/src/src/mytypes.h index 141d2c613..06426af7a 100644 --- a/src/src/mytypes.h +++ b/src/src/mytypes.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This header file contains type definitions and macros that I use as diff --git a/src/src/os.c b/src/src/os.c index ac5f61b65..4edb2ca98 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifdef STAND_ALONE # include diff --git a/src/src/osfunctions.h b/src/src/osfunctions.h index 547cf1379..454e9f77f 100644 --- a/src/src/osfunctions.h +++ b/src/src/osfunctions.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Prototypes for os-specific functions. For utilities, we don't need the one that uses a type that isn't defined for them. */ diff --git a/src/src/parse.c b/src/src/parse.c index bdba3ecd0..93b12bc77 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for parsing addresses */ diff --git a/src/src/pdkim/crypt_ver.h b/src/src/pdkim/crypt_ver.h index a6d7e36af..367527e39 100644 --- a/src/src/pdkim/crypt_ver.h +++ b/src/src/pdkim/crypt_ver.h @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Signing and hashing routine selection for PDKIM */ diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index e47bfc505..eb26b3864 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -4,6 +4,7 @@ * Copyright (c) The Exim Maintainers 2021 - 2022 * Copyright (C) 2009 - 2016 Tom Kistner * Copyright (C) 2016 - 2020 Jeremy Harris + * SPDX-License-Identifier: GPL-2.0-or-later * * http://duncanthrax.net/pdkim/ * diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h index f6ff78251..f918938e8 100644 --- a/src/src/pdkim/pdkim.h +++ b/src/src/pdkim/pdkim.h @@ -3,6 +3,7 @@ * * Copyright (C) 2009 - 2012 Tom Kistner * Copyright (c) 2016 - 2020 Jeremy Harris + * SPDX-License-Identifier: GPL-2.0-or-later * * http://duncanthrax.net/pdkim/ * diff --git a/src/src/pdkim/pdkim_hash.h b/src/src/pdkim/pdkim_hash.h index 8f9a12628..e470299a4 100644 --- a/src/src/pdkim/pdkim_hash.h +++ b/src/src/pdkim/pdkim_hash.h @@ -2,6 +2,7 @@ * PDKIM - a RFC4871 (DKIM) implementation * * Copyright (C) 1995 - 2018 Exim maintainers + * SPDX-License-Identifier: GPL-2.0-only * * Hash interface functions */ diff --git a/src/src/pdkim/signing.c b/src/src/pdkim/signing.c index d78f31acf..8876f617c 100644 --- a/src/src/pdkim/signing.c +++ b/src/src/pdkim/signing.c @@ -1,6 +1,7 @@ /* * PDKIM - a RFC4871 (DKIM) implementation * Copyright (c) The Exim Maintainers 1995 - 2022 + * SPDX-License-Identifier: GPL-2.0-only * * signing/verification interface */ diff --git a/src/src/pdkim/signing.h b/src/src/pdkim/signing.h index ed6f397ce..880342b6f 100644 --- a/src/src/pdkim/signing.h +++ b/src/src/pdkim/signing.h @@ -2,6 +2,7 @@ * PDKIM - a RFC4871 (DKIM) implementation * * Copyright (C) 1995 - 2020 Exim maintainers + * SPDX-License-Identifier: GPL-2.0-only * * RSA signing/verification interface */ diff --git a/src/src/perl.c b/src/src/perl.c index f07ee2e27..b5c3f882e 100644 --- a/src/src/perl.c +++ b/src/src/perl.c @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 1999 - 2022 */ /* Copyright (c) 1998 Malcolm Beattie */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Modified by PH to get rid of the "na" usage, March 1999. Modified further by PH for general tidying for Exim 4. diff --git a/src/src/priv.c b/src/src/priv.c index 94d425401..c818b5b78 100644 --- a/src/src/priv.c +++ b/src/src/priv.c @@ -1,3 +1,6 @@ +/* Copyright (c) The Exim Maintainers 2022 * +/* SPDX-License-Identifier: GPL-2.0-only */ + #include "exim.h" #include #include diff --git a/src/src/queue.c b/src/src/queue.c index 6e47d2c8a..fd84d303f 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions that operate on the input queue. */ diff --git a/src/src/rda.c b/src/src/rda.c index b635ebfde..1bc322e34 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module contains code for extracting addresses from a forwarding list (from an alias or forward file) or by running the filter interpreter. It may do diff --git a/src/src/readconf.c b/src/src/readconf.c index 83ee51b65..b0d688772 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for reading the configuration file, and for displaying overall configuration values. Thanks to Brian Candler for the original diff --git a/src/src/receive.c b/src/src/receive.c index 0a27c7950..d9d0757ef 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Code for receiving a message and setting up spool files. */ diff --git a/src/src/regex.c b/src/src/regex.c index 210620f26..eefba8ecf 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -6,6 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Tom Kistner 2003-2015 * License: GPL + * SPDX-License-Identifier: GPL-2.0-only */ /* Code for matching regular expressions against headers and body. diff --git a/src/src/regex_cache.c b/src/src/regex_cache.c index 63cddce1d..e4771aab9 100644 --- a/src/src/regex_cache.c +++ b/src/src/regex_cache.c @@ -5,6 +5,7 @@ /* * Copyright (c) The Exim Maintainers 2022 * License: GPL + * SPDX-License-Identifier: GPL-2.0-only */ /* Caching layers for compiled REs. There is a local layer in the process, diff --git a/src/src/retry.c b/src/src/retry.c index 033afb4bf..e1490266c 100644 --- a/src/src/retry.c +++ b/src/src/retry.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with retrying unsuccessful deliveries. */ diff --git a/src/src/rewrite.c b/src/src/rewrite.c index 90614e626..040525ec5 100644 --- a/src/src/rewrite.c +++ b/src/src/rewrite.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with rewriting headers */ diff --git a/src/src/rfc2047.c b/src/src/rfc2047.c index 1ed1dd809..af8993695 100644 --- a/src/src/rfc2047.c +++ b/src/src/rfc2047.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file contains a function for decoding message header lines that may contain encoded "words" according to the rules described in diff --git a/src/src/route.c b/src/src/route.c index fa69b8b74..7e6e4eb69 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with routing, and the list of generic router options. */ diff --git a/src/src/routers/accept.c b/src/src/routers/accept.c index 110a1efe4..ab02716eb 100644 --- a/src/src/routers/accept.c +++ b/src/src/routers/accept.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/accept.h b/src/src/routers/accept.h index 43494fbc4..e025179ee 100644 --- a/src/src/routers/accept.h +++ b/src/src/routers/accept.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options (there aren't any). */ diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index a845b4e52..0b1abeb8e 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/dnslookup.h b/src/src/routers/dnslookup.h index b7e091587..0272db300 100644 --- a/src/src/routers/dnslookup.h +++ b/src/src/routers/dnslookup.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/routers/ipliteral.c b/src/src/routers/ipliteral.c index 3d68642a2..cfbf276ff 100644 --- a/src/src/routers/ipliteral.c +++ b/src/src/routers/ipliteral.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/ipliteral.h b/src/src/routers/ipliteral.h index 1ddb38b10..f7e99b9c2 100644 --- a/src/src/routers/ipliteral.h +++ b/src/src/routers/ipliteral.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. Some compilers do not like empty diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index 8b67f3116..970ec7704 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/iplookup.h b/src/src/routers/iplookup.h index dbcb03c9e..3b7295574 100644 --- a/src/src/routers/iplookup.h +++ b/src/src/routers/iplookup.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c index 974ad0cf4..6a500d09a 100644 --- a/src/src/routers/manualroute.c +++ b/src/src/routers/manualroute.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/manualroute.h b/src/src/routers/manualroute.h index 9c20b6fa0..e27d90953 100644 --- a/src/src/routers/manualroute.h +++ b/src/src/routers/manualroute.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for the manualroute router */ diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c index 55f03a477..51b7b7551 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/queryprogram.h b/src/src/routers/queryprogram.h index 93046bd0f..148846fae 100644 --- a/src/src/routers/queryprogram.h +++ b/src/src/routers/queryprogram.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index 31c07f518..6126555fe 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/redirect.h b/src/src/routers/redirect.h index 4c0399a36..76d02f261 100644 --- a/src/src/routers/redirect.h +++ b/src/src/routers/redirect.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for the redirect router */ diff --git a/src/src/routers/rf_change_domain.c b/src/src/routers/rf_change_domain.c index d7c9c1cb8..4f8d47299 100644 --- a/src/src/routers/rf_change_domain.c +++ b/src/src/routers/rf_change_domain.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/rf_expand_data.c b/src/src/routers/rf_expand_data.c index 6a8ad1779..5fbf0ac78 100644 --- a/src/src/routers/rf_expand_data.c +++ b/src/src/routers/rf_expand_data.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/rf_functions.h b/src/src/routers/rf_functions.h index f310d5a42..d8fca68c5 100644 --- a/src/src/routers/rf_functions.h +++ b/src/src/routers/rf_functions.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for the functions that are shared by the routers */ diff --git a/src/src/routers/rf_get_errors_address.c b/src/src/routers/rf_get_errors_address.c index b9cf78124..1189fd9e0 100644 --- a/src/src/routers/rf_get_errors_address.c +++ b/src/src/routers/rf_get_errors_address.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c index d304d1145..be86a4e0e 100644 --- a/src/src/routers/rf_get_munge_headers.c +++ b/src/src/routers/rf_get_munge_headers.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_transport.c b/src/src/routers/rf_get_transport.c index 2f639e037..0c1fa8173 100644 --- a/src/src/routers/rf_get_transport.c +++ b/src/src/routers/rf_get_transport.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_ugid.c b/src/src/routers/rf_get_ugid.c index 1735e5919..15144beb1 100644 --- a/src/src/routers/rf_get_ugid.c +++ b/src/src/routers/rf_get_ugid.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index 79a779927..affd70b6e 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/rf_queue_add.c b/src/src/routers/rf_queue_add.c index 0693c8c6e..49dd83117 100644 --- a/src/src/routers/rf_queue_add.c +++ b/src/src/routers/rf_queue_add.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_self_action.c b/src/src/routers/rf_self_action.c index 9a4dc3cc7..7cc592039 100644 --- a/src/src/routers/rf_self_action.c +++ b/src/src/routers/rf_self_action.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/routers/rf_set_ugid.c b/src/src/routers/rf_set_ugid.c index e1346b4be..65f5200a2 100644 --- a/src/src/routers/rf_set_ugid.c +++ b/src/src/routers/rf_set_ugid.c @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/search.c b/src/src/search.c index eec543776..32099ab9e 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* A set of functions to search databases in various formats. An open database is represented by a void * value which is returned from a lookup- diff --git a/src/src/setenv.c b/src/src/setenv.c index 90e679304..877fe388f 100644 --- a/src/src/setenv.c +++ b/src/src/setenv.c @@ -6,6 +6,7 @@ * Copyright (c) Jeremy Harris 2015 - 2016 * Copyright (c) The Exim Maintainers 2016 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module provides (un)setenv routines for those environments lacking them in libraries. It is #include'd by OS/os.c-foo files. */ diff --git a/src/src/sha_ver.h b/src/src/sha_ver.h index bc2b2f89e..8385c1377 100644 --- a/src/src/sha_ver.h +++ b/src/src/sha_ver.h @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* SHA routine selection */ diff --git a/src/src/sieve.c b/src/src/sieve.c index af3bc9d9a..033a9734a 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -6,6 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Michael Haardt 2003 - 2015 * See the file NOTICE for conditions of use and distribution. + * SPDX-License-Identifier: GPL-2.0-only */ /* This code was contributed by Michael Haardt. */ diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 28e529bae..3c6339c82 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for handling an incoming SMTP call. */ diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 7f364d942..db39dcab5 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* A number of functions for driving outgoing SMTP calls. */ diff --git a/src/src/spam.c b/src/src/spam.c index a68b9bf60..f6575c293 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -6,6 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Tom Kistner 2003 - 2015 * License: GPL + * SPDX-License-Identifier: GPL-2.0-only */ /* Code for calling spamassassin's spamd. Called from acl.c. */ diff --git a/src/src/spam.h b/src/src/spam.h index cc36ffd3f..c410198d7 100644 --- a/src/src/spam.h +++ b/src/src/spam.h @@ -5,6 +5,7 @@ /* Copyright (c) Tom Kistner 2003 - 2015 */ /* Copyright (c) The Exim Maintainers 2021 */ /* License: GPL */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* spam defines */ diff --git a/src/src/spf.c b/src/src/spf.c index a8c0f75c4..a94bc9677 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -6,6 +6,7 @@ Copyright (c) The Exim Maintainers 2015 - 2022 Copyright (c) Tom Kistner 2004 - 2014 License: GPL + SPDX-License-Identifier: GPL-2.0-only */ /* Code for calling spf checks via libspf-alt. Called from acl.c. */ diff --git a/src/src/spf.h b/src/src/spf.h index f32d06906..8fb7b04cb 100644 --- a/src/src/spf.h +++ b/src/src/spf.h @@ -6,6 +6,7 @@ Copyright (c) The Exim Maintainers 2016 - 2022 Copyright (c) Tom Kistner 2004 License: GPL + SPDX-License-Identifier: GPL-2.0-only */ #ifdef SUPPORT_SPF diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 2aa0b0b55..82d11bf65 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for reading spool files. When compiling for a utility (eximon), not all are needed, and some functionality can be cut out. */ diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index 8b2aae394..d9767ec3c 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -5,6 +5,7 @@ /* Copyright (c) Tom Kistner 2003 - 2015 * License: GPL * Copyright (c) The Exim Maintainers 2016 - 2021 + * SPDX-License-Identifier: GPL-2.0-only */ /* Code for setting up a MBOX style spool file inside a /scan/ diff --git a/src/src/spool_out.c b/src/src/spool_out.c index 510eda6c1..cb409c641 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for writing spool files, and moving them about. */ diff --git a/src/src/std-crypto.c b/src/src/std-crypto.c index 200fb7144..c1eef6c35 100644 --- a/src/src/std-crypto.c +++ b/src/src/std-crypto.c @@ -7,6 +7,8 @@ * But almost everything here is fixed published constants from RFCs, so also: * Copyright (C) The Internet Society (2003) * Copyright (C) The IETF Trust (2008) + * SPDX-License-Identifier: GPL-2.0-only + * * Most of the text in RFC referencing comments is copy/paste from RFC, * as is undoubtedly the intention. * The constants are generated from that text using util/gen_pkcs3.c invoked diff --git a/src/src/store.c b/src/src/store.c index d99d2ab69..449fb4ead 100644 --- a/src/src/store.c +++ b/src/src/store.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Exim gets and frees all its store through these functions. In the original implementation there was a lot of mallocing and freeing of small bits of store. diff --git a/src/src/store.h b/src/src/store.h index ee6d79c36..47ed963cd 100644 --- a/src/src/store.h +++ b/src/src/store.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header for Exim's memory allocation functions */ diff --git a/src/src/string.c b/src/src/string.c index a5161bb31..ff4180b2b 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Miscellaneous string-handling functions. Some are not required for utilities and tests, and are cut out by the COMPILE_UTILITY macro. */ diff --git a/src/src/structs.h b/src/src/structs.h index 06cd06084..1cb69236e 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Definitions of various structures. In addition, those that are visible for diff --git a/src/src/tls-cipher-stdname.c b/src/src/tls-cipher-stdname.c index ab973af51..fe442a050 100644 --- a/src/src/tls-cipher-stdname.c +++ b/src/src/tls-cipher-stdname.c @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 2019 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Translate an IETF TLS ciphersuite code to an IETF ciphersuite name, for use when the TLS library do not provide such names. diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 1fc7828cf..c98760202 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -6,6 +6,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) Phil Pennock 2012 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file provides TLS/SSL support for Exim using the GnuTLS library, one of the available supported implementations. This file is #included into diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 8ed413e91..052d8161d 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2019 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Portions Copyright (c) The OpenSSL Project 1999 */ diff --git a/src/src/tls.c b/src/src/tls.c index d7cefce67..9e20b5bca 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module provides TLS (aka SSL) support for Exim. The code for OpenSSL is based on a patch that was originally contributed by Steve Haslam. It was diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c index a40bb30bf..8840d5cfd 100644 --- a/src/src/tlscert-gnu.c +++ b/src/src/tlscert-gnu.c @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2014 - 2018 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This file provides TLS/SSL support for Exim using the GnuTLS library, one of the available supported implementations. This file is #included into diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c index ac353b25f..a4c3d19fa 100644 --- a/src/src/tlscert-openssl.c +++ b/src/src/tlscert-openssl.c @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) Jeremy Harris 2014 - 2019 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* This module provides TLS (aka SSL) support for Exim using the OpenSSL library. It is #included into the tls.c file when that library is used. diff --git a/src/src/tod.c b/src/src/tod.c index 1f0bcc05e..ac4ed35b9 100644 --- a/src/src/tod.c +++ b/src/src/tod.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* A function for returning the time of day in various formats */ diff --git a/src/src/transport.c b/src/src/transport.c index 7477882cb..ff2e0b1d4 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* General functions concerned with transportation, and generic options for all transports. */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 7e29dd3bc..18badde86 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/transports/appendfile.h b/src/src/transports/appendfile.h index 3fd2f467c..108114905 100644 --- a/src/src/transports/appendfile.h +++ b/src/src/transports/appendfile.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 211e32810..eff1a3792 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/transports/autoreply.h b/src/src/transports/autoreply.h index fcfd981e7..5f278a51e 100644 --- a/src/src/transports/autoreply.h +++ b/src/src/transports/autoreply.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index f751771c1..c734c3a26 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/transports/lmtp.h b/src/src/transports/lmtp.h index 93f0f89cc..71fd77f26 100644 --- a/src/src/transports/lmtp.h +++ b/src/src/transports/lmtp.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index bdbe27d57..b8103e2f6 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" diff --git a/src/src/transports/pipe.h b/src/src/transports/pipe.h index ed5c142b3..416569608 100644 --- a/src/src/transports/pipe.h +++ b/src/src/transports/pipe.h @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/transports/queuefile.c b/src/src/transports/queuefile.c index 74131cc64..3a2bae22f 100644 --- a/src/src/transports/queuefile.c +++ b/src/src/transports/queuefile.c @@ -6,6 +6,7 @@ /* Copyright (c) University of Cambridge 2016 */ /* Copyright (c) The Exim Maintainers 1995 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/src/transports/queuefile.h b/src/src/transports/queuefile.h index 0e45b51b0..22759a7f7 100644 --- a/src/src/transports/queuefile.h +++ b/src/src/transports/queuefile.h @@ -5,6 +5,7 @@ /* Copyright (c) Andrew Colin Kissa 2016 */ /* Copyright (c) University of Cambridge 2016 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Private structure for the private options. */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 0fca4584d..2d2db1b10 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "../exim.h" #include "smtp.h" diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 319e8494e..8793ece4f 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #define DELIVER_BUFFER_SIZE 4096 diff --git a/src/src/transports/smtp_socks.c b/src/src/transports/smtp_socks.c index 0e58732c6..353a69618 100644 --- a/src/src/transports/smtp_socks.c +++ b/src/src/transports/smtp_socks.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2015 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* SOCKS version 5 proxy, client-mode */ diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c index 205ee41cb..925b8fac0 100644 --- a/src/src/transports/tf_maildir.c +++ b/src/src/transports/tf_maildir.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions in support of the use of maildirsize files for handling quotas in maildir directories. Some of the rules are a bit baroque: diff --git a/src/src/transports/tf_maildir.h b/src/src/transports/tf_maildir.h index b3707b1a9..d314c3203 100644 --- a/src/src/transports/tf_maildir.h +++ b/src/src/transports/tf_maildir.h @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Header file for the functions that are used to support the use of maildirsize files for quota handling in maildir directories. */ diff --git a/src/src/tree.c b/src/src/tree.c index bb8ad44db..e340d986a 100644 --- a/src/src/tree.c +++ b/src/src/tree.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions for maintaining binary balanced trees and some associated functions as well. */ diff --git a/src/src/utf8.c b/src/src/utf8.c index bc7adb828..6604727ff 100644 --- a/src/src/utf8.c +++ b/src/src/utf8.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) Jeremy Harris 2015 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ #include "exim.h" diff --git a/src/src/verify.c b/src/src/verify.c index afc18d553..3a8914e38 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with verifying things. The original code for callout caching was contributed by Kevin Fleming (but I hacked it around a bit). */ diff --git a/src/src/version.c b/src/src/version.c index 118ebbdf2..cbaaef24b 100644 --- a/src/src/version.c +++ b/src/src/version.c @@ -5,6 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2010 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Function for setting up the version string. */ diff --git a/src/util/chunking_fixqueue_finalnewlines.pl b/src/util/chunking_fixqueue_finalnewlines.pl index 5dddfa505..b8ab17bd7 100755 --- a/src/util/chunking_fixqueue_finalnewlines.pl +++ b/src/util/chunking_fixqueue_finalnewlines.pl @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0-only use warnings; use strict; diff --git a/src/util/cramtest.pl b/src/util/cramtest.pl index 48f989a0c..a6124628b 100755 --- a/src/util/cramtest.pl +++ b/src/util/cramtest.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl +# SPDX-License-Identifier: GPL-2.0-only # This script is contributed by Vadim Vygonets to aid in debugging CRAM-MD5 # authentication. diff --git a/src/util/gen_pkcs3.c b/src/util/gen_pkcs3.c index 2fe9a6c5e..3ef3110de 100644 --- a/src/util/gen_pkcs3.c +++ b/src/util/gen_pkcs3.c @@ -2,6 +2,7 @@ * Copyright (c) The Exim Maintainers 2021 * This is distributed as part of Exim and licensed under the GPL. * See the file "NOTICE" for more details. + * SPDX-License-Identifier: GPL-2.0-only */ /* Build with: diff --git a/src/util/logargs.sh b/src/util/logargs.sh index 87369a64b..814228d10 100755 --- a/src/util/logargs.sh +++ b/src/util/logargs.sh @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0-only # This script can be interposed between a calling program and another # program, in order to log the arguments which are being used. This can diff --git a/src/util/mkcdb.pl b/src/util/mkcdb.pl index 691849dcd..e2b5931e7 100755 --- a/src/util/mkcdb.pl +++ b/src/util/mkcdb.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -wT +# SPDX-License-Identifier: GPL-2.0-only # # Create cdb file from flat alias file. DPC: 15/10/98. # Args: source (may be relative or absolute) diff --git a/src/util/ocsp_fetch.pl b/src/util/ocsp_fetch.pl index 08ca4cbe4..2afbdbdac 100755 --- a/src/util/ocsp_fetch.pl +++ b/src/util/ocsp_fetch.pl @@ -1,6 +1,8 @@ #!/usr/bin/perl # Copyright (C) 2012 Wizards Internet Ltd # License GPLv2: GNU GPL version 2 +# SPDX-License-Identifier: GPL-2.0-only + use strict; BEGIN { pop @INC if $INC[-1] eq '.' }; use Getopt::Std; diff --git a/src/util/proxy_protocol_client.pl b/src/util/proxy_protocol_client.pl index 67a171d5d..8b4311b64 100644 --- a/src/util/proxy_protocol_client.pl +++ b/src/util/proxy_protocol_client.pl @@ -3,6 +3,7 @@ # Copyright (C) 2014 Todd Lyons # License GPLv2: GNU GPL version 2 # +# SPDX-License-Identifier: GPL-2.0-only # # This script emulates a proxy which uses Proxy Protocol to communicate # to a backend server. It should be run from an IP which is configured diff --git a/src/util/ratelimit.pl b/src/util/ratelimit.pl index e212fa241..2ceeebbfa 100644 --- a/src/util/ratelimit.pl +++ b/src/util/ratelimit.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -wT +# SPDX-License-Identifier: GPL-2.0-only use strict; diff --git a/src/util/renew-opendmarc-tlds.sh b/src/util/renew-opendmarc-tlds.sh index 9967018e2..583dc0e40 100755 --- a/src/util/renew-opendmarc-tlds.sh +++ b/src/util/renew-opendmarc-tlds.sh @@ -1,4 +1,5 @@ #!/bin/sh -eu +# SPDX-License-Identifier: GPL-2.0-only # # Short version of this script: # curl -f -o /var/cache/exim/opendmarc.tlds https://publicsuffix.org/list/public_suffix_list.dat diff --git a/src/util/unknownuser.sh b/src/util/unknownuser.sh index fe04dc6b1..01e617978 100755 --- a/src/util/unknownuser.sh +++ b/src/util/unknownuser.sh @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0-only # This is a sample script for demonstrating how to handle unknown users in # a more friendly way than just returning a "user unknown" error. It can commit 1d28cc061677bd07d9bed48dd84bd5c590247043 Author: Jeremy Harris Date: Sun Nov 27 14:40:20 2022 +0000 SPDX: Mass-update to GPL-2.0-or-later This is based on the text in src/NOTICE which is taken to override text in individual files diff --git a/src/Makefile b/src/Makefile index b774b43dd..d190d9aa0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,6 +4,7 @@ # Copyright (c) The Exim Maintainers 2022 # Copyright (c) University of Cambridge, 1995 - 2018 +# SPDX-License-Identifier: GPL-2.0-or-later # See the file NOTICE for conditions of use and distribution. # IRIX make uses the shell that is in the SHELL variable, which often defaults diff --git a/src/NOTICE b/src/NOTICE index b4a5c407f..4aa562ea3 100644 --- a/src/NOTICE +++ b/src/NOTICE @@ -2,6 +2,7 @@ THE EXIM MAIL TRANSFER AGENT ---------------------------- Copyright (c) 2004 University of Cambridge +SPDX-License-Identifier: GPL-2.0-or-later This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index 0c64d45d4..4e1f61a26 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -1,5 +1,4 @@ # This file is the basis of the main makefile for Exim and friends. The -# # makefile at the top level arranges to build the main makefile by calling # scripts/Configure-Makefile from within the build directory. This # concatenates the configuration settings from Local/Makefile and other, @@ -7,6 +6,7 @@ # build directory. # # Copyright (c) The Exim Maintainers 1995 - 2022 +# SPDX-License-Identifier: GPL-2.0-or-later SHELL = $(MAKE_SHELL) SCRIPTS = ../scripts diff --git a/src/OS/Makefile-Default b/src/OS/Makefile-Default index 6e42db471..7481d3163 100644 --- a/src/OS/Makefile-Default +++ b/src/OS/Makefile-Default @@ -2,6 +2,9 @@ # The Exim mail transport agent # ################################################## +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Generic default make file containing settings that relate to the OS or # to selectable features within the OS. The configuration options for Exim # itself live in Local/Makefile, which is constructed by editing src/EDITME. diff --git a/src/OS/Makefile-FreeBSD b/src/OS/Makefile-FreeBSD index 4793a438b..f0fb8f2c9 100644 --- a/src/OS/Makefile-FreeBSD +++ b/src/OS/Makefile-FreeBSD @@ -1,5 +1,7 @@ # Exim: OS-specific make file for FreeBSD +# # Copyright (c) The Exim Maintainers 2020 +# SPDX-License-Identifier: GPL-2.0-or-later CHOWN_COMMAND=/usr/sbin/chown #STRIP_COMMAND=/usr/bin/strip diff --git a/src/OS/Makefile-GNU b/src/OS/Makefile-GNU index b49976f8c..366ce4263 100644 --- a/src/OS/Makefile-GNU +++ b/src/OS/Makefile-GNU @@ -1,5 +1,7 @@ # Exim: OS-specific make file for GNU and variants. +# # Copyright (c) The Exim Maintainers 2020 +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes diff --git a/src/OS/Makefile-OpenBSD b/src/OS/Makefile-OpenBSD index 7c451e2cc..da648df43 100644 --- a/src/OS/Makefile-OpenBSD +++ b/src/OS/Makefile-OpenBSD @@ -1,5 +1,6 @@ # Exim: OS-specific make file for OpenBSD # Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later CHOWN_COMMAND=/usr/sbin/chown CHGRP_COMMAND=/usr/sbin/chgrp diff --git a/src/OS/Makefile-SunOS5 b/src/OS/Makefile-SunOS5 index d07adcff4..e8b0d9506 100644 --- a/src/OS/Makefile-SunOS5 +++ b/src/OS/Makefile-SunOS5 @@ -1,5 +1,6 @@ # Exim: OS-specific make file for SunOS5 # Copyright (c) The Exim Maintainers 2020 +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes diff --git a/src/OS/eximon.conf-Default b/src/OS/eximon.conf-Default index 2f874ef53..d003156e6 100644 --- a/src/OS/eximon.conf-Default +++ b/src/OS/eximon.conf-Default @@ -2,6 +2,9 @@ # These can be overridden by OS-specific scripts and local installation # scripts, and also at run time by shell variables. +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # The name of the eximon binary, usually the same as the eximon script, # with .bin stuck on the end. diff --git a/src/OS/os.c-FreeBSD b/src/OS/os.c-FreeBSD index 02b78587b..d65a789c0 100644 --- a/src/OS/os.c-FreeBSD +++ b/src/OS/os.c-FreeBSD @@ -4,6 +4,7 @@ /* Copyright (c) Jeremy Harris 1995 - 2020 */ /* Copyright (c) The Exim Maintainers 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* FreeBSD-specific code. This is concatenated onto the generic diff --git a/src/OS/os.c-GNU b/src/OS/os.c-GNU index dbd014918..2b2aeed22 100644 --- a/src/OS/os.c-GNU +++ b/src/OS/os.c-GNU @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) The Exim Maintainers 2020 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* GNU-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/os.c-Linux b/src/OS/os.c-Linux index 59d81f8ad..34dd7c190 100644 --- a/src/OS/os.c-Linux +++ b/src/OS/os.c-Linux @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1997 - 2018 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Linux-specific code. This is concatenated onto the generic diff --git a/src/OS/os.c-SunOS5 b/src/OS/os.c-SunOS5 index 162486958..ec4bb8d42 100644 --- a/src/OS/os.c-SunOS5 +++ b/src/OS/os.c-SunOS5 @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 2016 */ /* Copyright (c) Jeremy Harris 2016 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Solaris-specific code. This is concatenated onto the generic diff --git a/src/OS/os.h-FreeBSD b/src/OS/os.h-FreeBSD index 06e217a44..6756d42f6 100644 --- a/src/OS/os.h-FreeBSD +++ b/src/OS/os.h-FreeBSD @@ -1,6 +1,7 @@ /* Exim: OS-specific C header file for FreeBSD */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/OS/os.h-GNU b/src/OS/os.h-GNU index 4b222600e..4fe55fa5e 100644 --- a/src/OS/os.h-GNU +++ b/src/OS/os.h-GNU @@ -1,5 +1,6 @@ /* Exim: OS-specific C header file for GNU/Hurd */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include diff --git a/src/OS/os.h-Linux b/src/OS/os.h-Linux index e6a8d288e..25a12862b 100644 --- a/src/OS/os.h-Linux +++ b/src/OS/os.h-Linux @@ -1,6 +1,7 @@ /* Exim: OS-specific C header file for Linux */ /* Copyright (c) University of Cambridge 1995 - 2020 */ /* Copyright (c) The Exim Maintainers 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/OS/os.h-OpenBSD b/src/OS/os.h-OpenBSD index c690b6e4a..19db7189a 100644 --- a/src/OS/os.h-OpenBSD +++ b/src/OS/os.h-OpenBSD @@ -1,6 +1,7 @@ /* Exim: OS-specific C header file for OpenBSD */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/OS/os.h-SunOS5 b/src/OS/os.h-SunOS5 index 71253213c..b3f55bf83 100644 --- a/src/OS/os.h-SunOS5 +++ b/src/OS/os.h-SunOS5 @@ -1,5 +1,6 @@ /* Exim: OS-specific C header file for SunOS5 aka Solaris */ /* Copyright (c) The Exim Maintainers 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define HAVE_MMAP diff --git a/src/OS/unsupported/Makefile-AIX b/src/OS/unsupported/Makefile-AIX index fc32aa286..f407cbcaf 100644 --- a/src/OS/unsupported/Makefile-AIX +++ b/src/OS/unsupported/Makefile-AIX @@ -1,6 +1,7 @@ # Exim: OS-specific make file for AIX # Written by Nick Waterman (nick@cimio.co.uk) # Modified by PH following a message from Mike Meredith +# SPDX-License-Identifier: GPL-2.0-or-later # Note that the output of uname -m is probably not what Philip expected, # so you might end up with more build-AIX-random_number directories than diff --git a/src/OS/unsupported/Makefile-BSDI b/src/OS/unsupported/Makefile-BSDI index d56aa9b57..6ea176319 100644 --- a/src/OS/unsupported/Makefile-BSDI +++ b/src/OS/unsupported/Makefile-BSDI @@ -1,5 +1,6 @@ # Exim: OS-specific make file for BSDI aka BSD/OS. Its antique link editor # cannot handle the TextPop overriding. +# SPDX-License-Identifier: GPL-2.0-or-later CFLAGS=-O CHOWN_COMMAND=/usr/sbin/chown diff --git a/src/OS/unsupported/Makefile-CYGWIN b/src/OS/unsupported/Makefile-CYGWIN index 5e608fe9e..bc4545b47 100644 --- a/src/OS/unsupported/Makefile-CYGWIN +++ b/src/OS/unsupported/Makefile-CYGWIN @@ -1,4 +1,5 @@ # OS-specific file for Cygwin. +# SPDX-License-Identifier: GPL-2.0-or-later # This file provided by Pierre A. Humblet diff --git a/src/OS/unsupported/Makefile-DGUX b/src/OS/unsupported/Makefile-DGUX index 667c63f49..1258ba4e4 100644 --- a/src/OS/unsupported/Makefile-DGUX +++ b/src/OS/unsupported/Makefile-DGUX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for DGUX +# SPDX-License-Identifier: GPL-2.0-or-later # # Written by Ken Bailey (K.Bailey@rbgkew.org.uk) Feb 1998 # on dgux R4.11MU04 generic AViiON mc88100 diff --git a/src/OS/unsupported/Makefile-Darwin b/src/OS/unsupported/Makefile-Darwin index 517bbc493..bdd9d110d 100644 --- a/src/OS/unsupported/Makefile-Darwin +++ b/src/OS/unsupported/Makefile-Darwin @@ -1,4 +1,5 @@ # Exim: OS-specific make file for Darwin (Mac OS X). +# SPDX-License-Identifier: GPL-2.0-or-later CC=cc diff --git a/src/OS/unsupported/Makefile-DragonFly b/src/OS/unsupported/Makefile-DragonFly index c49c59ffc..9d845f13f 100644 --- a/src/OS/unsupported/Makefile-DragonFly +++ b/src/OS/unsupported/Makefile-DragonFly @@ -1,4 +1,6 @@ # Exim: OS-specific make file for DragonFly +# SPDX-License-Identifier: GPL-2.0-or-later +# # There's no setting of CFLAGS here, to allow the system default # for "make" to be the default. diff --git a/src/OS/unsupported/Makefile-GNUkFreeBSD b/src/OS/unsupported/Makefile-GNUkFreeBSD index 801928143..b5ed325d1 100644 --- a/src/OS/unsupported/Makefile-GNUkFreeBSD +++ b/src/OS/unsupported/Makefile-GNUkFreeBSD @@ -1,4 +1,5 @@ # Exim: OS-specific make file for GNU and variants. +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes diff --git a/src/OS/unsupported/Makefile-GNUkNetBSD b/src/OS/unsupported/Makefile-GNUkNetBSD index 801928143..b5ed325d1 100644 --- a/src/OS/unsupported/Makefile-GNUkNetBSD +++ b/src/OS/unsupported/Makefile-GNUkNetBSD @@ -1,4 +1,5 @@ # Exim: OS-specific make file for GNU and variants. +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes diff --git a/src/OS/unsupported/Makefile-HI-OSF b/src/OS/unsupported/Makefile-HI-OSF index da3d487a4..66aac36b9 100644 --- a/src/OS/unsupported/Makefile-HI-OSF +++ b/src/OS/unsupported/Makefile-HI-OSF @@ -1,4 +1,5 @@ # Exim: OS-specific make file for HI-OSF/1-MJ and HI-UX/MPP +# SPDX-License-Identifier: GPL-2.0-or-later CC=cc CFLAGS=-O diff --git a/src/OS/unsupported/Makefile-HI-UX b/src/OS/unsupported/Makefile-HI-UX index 870ee8460..c1f4fe51a 100644 --- a/src/OS/unsupported/Makefile-HI-UX +++ b/src/OS/unsupported/Makefile-HI-UX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for HI-UX +# SPDX-License-Identifier: GPL-2.0-or-later CC=cc -Aa -D_HIUX_SOURCE HAVE_SETRESUID=YES diff --git a/src/OS/unsupported/Makefile-HP-UX b/src/OS/unsupported/Makefile-HP-UX index ea35144bb..7e6cd9dba 100644 --- a/src/OS/unsupported/Makefile-HP-UX +++ b/src/OS/unsupported/Makefile-HP-UX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for HP-UX later than 9 +# SPDX-License-Identifier: GPL-2.0-or-later # HP ANSI C compiler #CC=cc diff --git a/src/OS/unsupported/Makefile-HP-UX-9 b/src/OS/unsupported/Makefile-HP-UX-9 index 153000944..ad28d4fdb 100644 --- a/src/OS/unsupported/Makefile-HP-UX-9 +++ b/src/OS/unsupported/Makefile-HP-UX-9 @@ -1,4 +1,5 @@ # Exim: OS-specific make file for HP-UX 9 +# SPDX-License-Identifier: GPL-2.0-or-later CFLAGS=-O BASENAME_COMMAND=/bin/basename diff --git a/src/OS/unsupported/Makefile-IRIX b/src/OS/unsupported/Makefile-IRIX index 7b9578339..a9925956b 100644 --- a/src/OS/unsupported/Makefile-IRIX +++ b/src/OS/unsupported/Makefile-IRIX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for IRIX +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes BASENAME_COMMAND=/sbin/basename diff --git a/src/OS/unsupported/Makefile-IRIX6 b/src/OS/unsupported/Makefile-IRIX6 index be0113846..6140649d1 100644 --- a/src/OS/unsupported/Makefile-IRIX6 +++ b/src/OS/unsupported/Makefile-IRIX6 @@ -1,4 +1,5 @@ # Exim: OS-specific make file for IRIX6 on 64-bit systems +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes HOSTNAME_COMMAND=/usr/bsd/hostname diff --git a/src/OS/unsupported/Makefile-IRIX632 b/src/OS/unsupported/Makefile-IRIX632 index b567fc64e..2b19463ff 100644 --- a/src/OS/unsupported/Makefile-IRIX632 +++ b/src/OS/unsupported/Makefile-IRIX632 @@ -1,4 +1,6 @@ # Exim: OS-specific make file for IRIX 6 on 32-bit systems. +# SPDX-License-Identifier: GPL-2.0-or-later + # There seems to be some variation. The commented settings show # some alternatives. diff --git a/src/OS/unsupported/Makefile-IRIX65 b/src/OS/unsupported/Makefile-IRIX65 index 50e77450a..4ad77a66f 100644 --- a/src/OS/unsupported/Makefile-IRIX65 +++ b/src/OS/unsupported/Makefile-IRIX65 @@ -1,4 +1,5 @@ # Exim: OS-specific make file for IRIX 6.5 +# SPDX-License-Identifier: GPL-2.0-or-later HAVE_ICONV=yes HOSTNAME_COMMAND=/usr/bsd/hostname diff --git a/src/OS/unsupported/Makefile-NetBSD b/src/OS/unsupported/Makefile-NetBSD index 35d03a24a..6792da216 100644 --- a/src/OS/unsupported/Makefile-NetBSD +++ b/src/OS/unsupported/Makefile-NetBSD @@ -1,4 +1,5 @@ # Exim: OS-specific make file for NetBSD (ELF object format) +# SPDX-License-Identifier: GPL-2.0-or-later CHOWN_COMMAND=/usr/sbin/chown CHMOD_COMMAND=/bin/chmod diff --git a/src/OS/unsupported/Makefile-NetBSD-a.out b/src/OS/unsupported/Makefile-NetBSD-a.out index e210efdda..5bee773ae 100644 --- a/src/OS/unsupported/Makefile-NetBSD-a.out +++ b/src/OS/unsupported/Makefile-NetBSD-a.out @@ -1,4 +1,5 @@ # Exim: OS-specific make file for NetBSD (a.out/COFF object format) +# SPDX-License-Identifier: GPL-2.0-or-later CHOWN_COMMAND=/usr/sbin/chown CHMOD_COMMAND=/bin/chmod diff --git a/src/OS/unsupported/Makefile-OSF1 b/src/OS/unsupported/Makefile-OSF1 index 811ca07a9..73814cec6 100644 --- a/src/OS/unsupported/Makefile-OSF1 +++ b/src/OS/unsupported/Makefile-OSF1 @@ -1,4 +1,5 @@ # Exim: OS-specific make file for OSF1 +# SPDX-License-Identifier: GPL-2.0-or-later CFLAGS=-O LIBS=-liconv -lm diff --git a/src/OS/unsupported/Makefile-OpenUNIX b/src/OS/unsupported/Makefile-OpenUNIX index e4d726158..dbab2b557 100644 --- a/src/OS/unsupported/Makefile-OpenUNIX +++ b/src/OS/unsupported/Makefile-OpenUNIX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for OpenUNIX +# SPDX-License-Identifier: GPL-2.0-or-later CC=/usr/bin/cc CFLAGS=-O -I/usr/local/include diff --git a/src/OS/unsupported/Makefile-QNX b/src/OS/unsupported/Makefile-QNX index 3cf81c41b..7d957b27c 100644 --- a/src/OS/unsupported/Makefile-QNX +++ b/src/OS/unsupported/Makefile-QNX @@ -1,4 +1,5 @@ # Exim: OS-specific makefile for QNX +# SPDX-License-Identifier: GPL-2.0-or-later BASENAME_COMMAND=/bin/basename MAKE_SHELL=/usr/bin/bash diff --git a/src/OS/unsupported/Makefile-SCO b/src/OS/unsupported/Makefile-SCO index baa61d80b..c936ec536 100644 --- a/src/OS/unsupported/Makefile-SCO +++ b/src/OS/unsupported/Makefile-SCO @@ -1,4 +1,5 @@ # Exim: OS-specific make file for SCO +# SPDX-License-Identifier: GPL-2.0-or-later # It was reported that some versions of gcc (e.g. 2.8.1) require this to be # CFLAGS=-melf diff --git a/src/OS/unsupported/Makefile-SCO_SV b/src/OS/unsupported/Makefile-SCO_SV index 249b81a0f..9baf1c470 100644 --- a/src/OS/unsupported/Makefile-SCO_SV +++ b/src/OS/unsupported/Makefile-SCO_SV @@ -1,6 +1,7 @@ # Exim: OS-specific make file for SCO_SV release 5 (tested on 5.0.5 & 5.0.5) # (see the UNIX_SV files for SCO 4.2) # Supplied by: Tony Earnshaw +# SPDX-License-Identifier: GPL-2.0-or-later # Note that 'gcc -melf -m486' applies to gcc 2.7.2 and higher; # 2.7.1 and SCO's SDK need '-belf'. diff --git a/src/OS/unsupported/Makefile-SunOS4 b/src/OS/unsupported/Makefile-SunOS4 index c876998e5..0dec44b65 100644 --- a/src/OS/unsupported/Makefile-SunOS4 +++ b/src/OS/unsupported/Makefile-SunOS4 @@ -1,4 +1,5 @@ # Exim: OS-specific make file for SunOS4 +# SPDX-License-Identifier: GPL-2.0-or-later CFLAGS=-O diff --git a/src/OS/unsupported/Makefile-SunOS5-hal b/src/OS/unsupported/Makefile-SunOS5-hal index 05ea893af..05759f369 100644 --- a/src/OS/unsupported/Makefile-SunOS5-hal +++ b/src/OS/unsupported/Makefile-SunOS5-hal @@ -1,4 +1,5 @@ # Exim: OS-specific make file for SunOS5 on a HAL +# SPDX-License-Identifier: GPL-2.0-or-later # Note: The HAL runs a standard SunOS5 except that it has a 64 bit C # compiler called hcc. To make things work pass the -KV7 flag to force diff --git a/src/OS/unsupported/Makefile-ULTRIX b/src/OS/unsupported/Makefile-ULTRIX index 9e912b3cb..00a95b950 100644 --- a/src/OS/unsupported/Makefile-ULTRIX +++ b/src/OS/unsupported/Makefile-ULTRIX @@ -1,4 +1,5 @@ # Exim: OS-specific make file for Ultrix +# SPDX-License-Identifier: GPL-2.0-or-later MAKE_SHELL=/usr/bin/sh5 diff --git a/src/OS/unsupported/Makefile-UNIX_SV b/src/OS/unsupported/Makefile-UNIX_SV index bfcfae1c0..5ea8567a5 100644 --- a/src/OS/unsupported/Makefile-UNIX_SV +++ b/src/OS/unsupported/Makefile-UNIX_SV @@ -1,4 +1,5 @@ # Exim: OS-specific make file for SCO SVR4.2MP (and maybe Unixware) +# SPDX-License-Identifier: GPL-2.0-or-later # # *** Note that for SCO 5 the configuration file is called SCO_SV, # *** and that Unixware7 has its own configuration. This is an old diff --git a/src/OS/unsupported/Makefile-USG b/src/OS/unsupported/Makefile-USG index 753a2d7e8..69a31bc15 100644 --- a/src/OS/unsupported/Makefile-USG +++ b/src/OS/unsupported/Makefile-USG @@ -1,4 +1,5 @@ # Exim: OS-specific make file for Unixware 2.x +# SPDX-License-Identifier: GPL-2.0-or-later # # Note that Unixware does not include db/dbm/ndbm with their standard compiler # (it is available with /usr/ucb/cc, but that has bugs of its own). You diff --git a/src/OS/unsupported/Makefile-Unixware7 b/src/OS/unsupported/Makefile-Unixware7 index 88a883801..0dc1afb1a 100644 --- a/src/OS/unsupported/Makefile-Unixware7 +++ b/src/OS/unsupported/Makefile-Unixware7 @@ -1,5 +1,6 @@ # Exim: OS-specific make file for Unixware7 # Based on information from James FitzGibbon +# SPDX-License-Identifier: GPL-2.0-or-later # If you want to use libbind, you need to # add -I/usr/local/bind/include to CFLAGS diff --git a/src/OS/unsupported/Makefile-mips b/src/OS/unsupported/Makefile-mips index ff3313937..d48adb411 100644 --- a/src/OS/unsupported/Makefile-mips +++ b/src/OS/unsupported/Makefile-mips @@ -1,4 +1,5 @@ # Exim: OS-specific make file for RiscOS4bsd +# SPDX-License-Identifier: GPL-2.0-or-later HOSTNAME_COMMAND=/usr/ucb/hostname EXIT_FAILURE=1 diff --git a/src/OS/unsupported/os.c-BSDI b/src/OS/unsupported/os.c-BSDI index 03a7a1cef..42160046b 100644 --- a/src/OS/unsupported/os.c-BSDI +++ b/src/OS/unsupported/os.c-BSDI @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) 2016 Heiko Schlittermann */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* BSDI-specific code. This is concatenated onto the generic diff --git a/src/OS/unsupported/os.c-HI-OSF b/src/OS/unsupported/os.c-HI-OSF index 5e3d336f2..56db57fd5 100644 --- a/src/OS/unsupported/os.c-HI-OSF +++ b/src/OS/unsupported/os.c-HI-OSF @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* HI-OSF-specific code. This is concatenated onto the generic diff --git a/src/OS/unsupported/os.c-HP-UX b/src/OS/unsupported/os.c-HP-UX index fdd8708a2..1178b782f 100644 --- a/src/OS/unsupported/os.c-HP-UX +++ b/src/OS/unsupported/os.c-HP-UX @@ -4,6 +4,7 @@ /* Copyright (c) University of Cambridge 2016 */ /* Copyright (c) Jeremy Harris 2016 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* HP-UX-specific code. This is concatenated onto the generic diff --git a/src/OS/unsupported/os.c-IRIX b/src/OS/unsupported/os.c-IRIX index 19172389b..1019901dc 100644 --- a/src/OS/unsupported/os.c-IRIX +++ b/src/OS/unsupported/os.c-IRIX @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Irix-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/unsupported/os.c-IRIX6 b/src/OS/unsupported/os.c-IRIX6 index 19172389b..1019901dc 100644 --- a/src/OS/unsupported/os.c-IRIX6 +++ b/src/OS/unsupported/os.c-IRIX6 @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Irix-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/unsupported/os.c-IRIX632 b/src/OS/unsupported/os.c-IRIX632 index 19172389b..1019901dc 100644 --- a/src/OS/unsupported/os.c-IRIX632 +++ b/src/OS/unsupported/os.c-IRIX632 @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Irix-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/unsupported/os.c-IRIX65 b/src/OS/unsupported/os.c-IRIX65 index 19172389b..1019901dc 100644 --- a/src/OS/unsupported/os.c-IRIX65 +++ b/src/OS/unsupported/os.c-IRIX65 @@ -4,6 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* Irix-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/unsupported/os.c-OSF1 b/src/OS/unsupported/os.c-OSF1 index ad91b63d1..4dc700f79 100644 --- a/src/OS/unsupported/os.c-OSF1 +++ b/src/OS/unsupported/os.c-OSF1 @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 2001 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* See the file NOTICE for conditions of use and distribution. */ /* OSF1-specific code. This is concatenated onto the generic src/os.c file. diff --git a/src/OS/unsupported/os.c-cygwin b/src/OS/unsupported/os.c-cygwin index 5ca05a8db..56085b857 100644 --- a/src/OS/unsupported/os.c-cygwin +++ b/src/OS/unsupported/os.c-cygwin @@ -1,6 +1,7 @@ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Cygwin-specific code. December 2002. Updated Jan 2015. This is prefixed to the src/os.c file. diff --git a/src/OS/unsupported/os.h-AIX b/src/OS/unsupported/os.h-AIX index 5cd4501a4..d70b907f5 100644 --- a/src/OS/unsupported/os.h-AIX +++ b/src/OS/unsupported/os.h-AIX @@ -1,4 +1,6 @@ /* Exim: OS-specific C header file for AIX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + /* Written by Nick Waterman */ /* Modified by Philip Hazel with data from Niels Provos diff --git a/src/OS/unsupported/os.h-BSDI b/src/OS/unsupported/os.h-BSDI index a1705ec95..0a5dd93e6 100644 --- a/src/OS/unsupported/os.h-BSDI +++ b/src/OS/unsupported/os.h-BSDI @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for BSDI */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_BSD_GETLOADAVG #define HAVE_SETCLASSRESOURCES diff --git a/src/OS/unsupported/os.h-DGUX b/src/OS/unsupported/os.h-DGUX index 9040f0e72..a4918b649 100644 --- a/src/OS/unsupported/os.h-DGUX +++ b/src/OS/unsupported/os.h-DGUX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for DGUX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Written by Ken Bailey (K.Bailey@rbgkew.org.uk) Feb 1998 */ /* on dgux R4.11MU04 generic AViiON mc88100 */ diff --git a/src/OS/unsupported/os.h-Darwin b/src/OS/unsupported/os.h-Darwin index a85e92f05..8cec8a90f 100644 --- a/src/OS/unsupported/os.h-Darwin +++ b/src/OS/unsupported/os.h-Darwin @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for Darwin (Mac OS X) */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* #define CRYPT_H */ /* Apparently this isn't needed */ diff --git a/src/OS/unsupported/os.h-DragonFly b/src/OS/unsupported/os.h-DragonFly index 4c2f1d508..122957f8d 100644 --- a/src/OS/unsupported/os.h-DragonFly +++ b/src/OS/unsupported/os.h-DragonFly @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for DragonFly */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_BSD_GETLOADAVG #define HAVE_MMAP diff --git a/src/OS/unsupported/os.h-GNUkFreeBSD b/src/OS/unsupported/os.h-GNUkFreeBSD index ab3503131..9326951c2 100644 --- a/src/OS/unsupported/os.h-GNUkFreeBSD +++ b/src/OS/unsupported/os.h-GNUkFreeBSD @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for GNU/kFreeBSD */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define GLIBC_IP_OPTIONS diff --git a/src/OS/unsupported/os.h-GNUkNetBSD b/src/OS/unsupported/os.h-GNUkNetBSD index bc3bc259d..f255b383d 100644 --- a/src/OS/unsupported/os.h-GNUkNetBSD +++ b/src/OS/unsupported/os.h-GNUkNetBSD @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for GNU/kNetBSD */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define GLIBC_IP_OPTIONS diff --git a/src/OS/unsupported/os.h-HI-OSF b/src/OS/unsupported/os.h-HI-OSF index 0f50fb660..9dc59cbcd 100644 --- a/src/OS/unsupported/os.h-HI-OSF +++ b/src/OS/unsupported/os.h-HI-OSF @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for HI-OSF/1-MJ and HI-UX/MPP */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_SYS_MOUNT_H diff --git a/src/OS/unsupported/os.h-HI-UX b/src/OS/unsupported/os.h-HI-UX index f3df9638c..8a83ce0b0 100644 --- a/src/OS/unsupported/os.h-HI-UX +++ b/src/OS/unsupported/os.h-HI-UX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for HI-UX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define LOAD_AVG_NEEDS_ROOT #define HAVE_DEV_KMEM diff --git a/src/OS/unsupported/os.h-HP-UX b/src/OS/unsupported/os.h-HP-UX index 4998734f6..e74c254f6 100644 --- a/src/OS/unsupported/os.h-HP-UX +++ b/src/OS/unsupported/os.h-HP-UX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for HP-UX versions greater than 9 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define EXIM_SOCKLEN_T size_t diff --git a/src/OS/unsupported/os.h-HP-UX-9 b/src/OS/unsupported/os.h-HP-UX-9 index 5a260d607..cb967a001 100644 --- a/src/OS/unsupported/os.h-HP-UX-9 +++ b/src/OS/unsupported/os.h-HP-UX-9 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for HP-UX version 9 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define LOAD_AVG_NEEDS_ROOT #define HAVE_DEV_KMEM diff --git a/src/OS/unsupported/os.h-IRIX b/src/OS/unsupported/os.h-IRIX index 1d4bf46ba..ceff6ea05 100644 --- a/src/OS/unsupported/os.h-IRIX +++ b/src/OS/unsupported/os.h-IRIX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for IRIX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define DN_EXPAND_ARG4_TYPE u_char * diff --git a/src/OS/unsupported/os.h-IRIX6 b/src/OS/unsupported/os.h-IRIX6 index bf3076713..59bf6c46e 100644 --- a/src/OS/unsupported/os.h-IRIX6 +++ b/src/OS/unsupported/os.h-IRIX6 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for IRIX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define LOAD_AVG_NEEDS_ROOT diff --git a/src/OS/unsupported/os.h-IRIX632 b/src/OS/unsupported/os.h-IRIX632 index 90f1c582c..8c171147b 100644 --- a/src/OS/unsupported/os.h-IRIX632 +++ b/src/OS/unsupported/os.h-IRIX632 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for IRIX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define DN_EXPAND_ARG4_TYPE u_char * diff --git a/src/OS/unsupported/os.h-IRIX65 b/src/OS/unsupported/os.h-IRIX65 index 4b248fe36..381acbd57 100644 --- a/src/OS/unsupported/os.h-IRIX65 +++ b/src/OS/unsupported/os.h-IRIX65 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for IRIX 6.5 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define CRYPT_H #define LOAD_AVG_NEEDS_ROOT diff --git a/src/OS/unsupported/os.h-NetBSD b/src/OS/unsupported/os.h-NetBSD index 0b9fc03f0..a8e32107a 100644 --- a/src/OS/unsupported/os.h-NetBSD +++ b/src/OS/unsupported/os.h-NetBSD @@ -1,5 +1,6 @@ /* Exim: OS-specific C header file for NetBSD */ /* Copyright (c) The Exim Maintainers 2021 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_BSD_GETLOADAVG #define HAVE_GETIFADDRS diff --git a/src/OS/unsupported/os.h-NetBSD-a.out b/src/OS/unsupported/os.h-NetBSD-a.out index 29a8feeff..59eb79241 100644 --- a/src/OS/unsupported/os.h-NetBSD-a.out +++ b/src/OS/unsupported/os.h-NetBSD-a.out @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for NetBSD (a.out binary format) */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../OS/os.h-NetBSD" /* Same as for ELF format */ diff --git a/src/OS/unsupported/os.h-OSF1 b/src/OS/unsupported/os.h-OSF1 index 6b5fa4973..4c985e8f2 100644 --- a/src/OS/unsupported/os.h-OSF1 +++ b/src/OS/unsupported/os.h-OSF1 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for OSF1 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_SYS_MOUNT_H #define HAVE_GETIPNODEBYNAME 1 diff --git a/src/OS/unsupported/os.h-OpenUNIX b/src/OS/unsupported/os.h-OpenUNIX index 67d1063b0..e8fae863a 100644 --- a/src/OS/unsupported/os.h-OpenUNIX +++ b/src/OS/unsupported/os.h-OpenUNIX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for OpenUNIX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define NO_SYSEXITS diff --git a/src/OS/unsupported/os.h-QNX b/src/OS/unsupported/os.h-QNX index 798f799ed..e5b04826c 100644 --- a/src/OS/unsupported/os.h-QNX +++ b/src/OS/unsupported/os.h-QNX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for QNX */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Modified for QNX 6.2.0 with diffs from Samuli Tuomola. */ #include diff --git a/src/OS/unsupported/os.h-SCO b/src/OS/unsupported/os.h-SCO index e5e915ed0..99585ae46 100644 --- a/src/OS/unsupported/os.h-SCO +++ b/src/OS/unsupported/os.h-SCO @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for SCO */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define DN_EXPAND_ARG4_TYPE u_char * diff --git a/src/OS/unsupported/os.h-SCO_SV b/src/OS/unsupported/os.h-SCO_SV index 0ca29f74a..724753e29 100644 --- a/src/OS/unsupported/os.h-SCO_SV +++ b/src/OS/unsupported/os.h-SCO_SV @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for SCO_SV */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define LOAD_AVG_NEEDS_ROOT #define HAVE_DEV_KMEM diff --git a/src/OS/unsupported/os.h-SunOS4 b/src/OS/unsupported/os.h-SunOS4 index 65556204c..d12acc05c 100644 --- a/src/OS/unsupported/os.h-SunOS4 +++ b/src/OS/unsupported/os.h-SunOS4 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for SunOS4 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define LOAD_AVG_NEEDS_ROOT #define HAVE_DEV_KMEM diff --git a/src/OS/unsupported/os.h-SunOS5-hal b/src/OS/unsupported/os.h-SunOS5-hal index cd9e877a9..1a1e43f95 100644 --- a/src/OS/unsupported/os.h-SunOS5-hal +++ b/src/OS/unsupported/os.h-SunOS5-hal @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for SunOS5 on HAL */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define HAVE_MMAP diff --git a/src/OS/unsupported/os.h-ULTRIX b/src/OS/unsupported/os.h-ULTRIX index 08db5aec8..83b0fc4aa 100644 --- a/src/OS/unsupported/os.h-ULTRIX +++ b/src/OS/unsupported/os.h-ULTRIX @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for Ultrix */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Well, it *does* have statfs(), but its structure is called something different, all the members have different names, and the function returns diff --git a/src/OS/unsupported/os.h-UNIX_SV b/src/OS/unsupported/os.h-UNIX_SV index 4943a07de..275475322 100644 --- a/src/OS/unsupported/os.h-UNIX_SV +++ b/src/OS/unsupported/os.h-UNIX_SV @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for SCO SVR4.2 (and maybe Unixware) */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /** *** Note that for SCO 5 the configuration file is called SCO_SV, diff --git a/src/OS/unsupported/os.h-USG b/src/OS/unsupported/os.h-USG index e76922067..597c52f9d 100644 --- a/src/OS/unsupported/os.h-USG +++ b/src/OS/unsupported/os.h-USG @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for Unixware 2.x */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define NO_SYSEXITS diff --git a/src/OS/unsupported/os.h-Unixware7 b/src/OS/unsupported/os.h-Unixware7 index 4d3ed42f2..e8f8c3210 100644 --- a/src/OS/unsupported/os.h-Unixware7 +++ b/src/OS/unsupported/os.h-Unixware7 @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for Unixware 7 */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define NO_SYSEXITS diff --git a/src/OS/unsupported/os.h-cygwin b/src/OS/unsupported/os.h-cygwin index 6ef59e0cc..7f81c074f 100644 --- a/src/OS/unsupported/os.h-cygwin +++ b/src/OS/unsupported/os.h-cygwin @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for Cygwin */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This code was supplied by Pierre A. Humblet December 2002. Updated Jan 2015. */ diff --git a/src/OS/unsupported/os.h-mips b/src/OS/unsupported/os.h-mips index 325e3a134..39e0019cb 100644 --- a/src/OS/unsupported/os.h-mips +++ b/src/OS/unsupported/os.h-mips @@ -1,4 +1,5 @@ /* Exim: OS-specific C header file for RiscOS4bsd */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define LOAD_AVG_NEEDS_ROOT #define HAVE_DEV_KMEM diff --git a/src/README b/src/README index d9379f7f8..e335cc22e 100644 --- a/src/README +++ b/src/README @@ -2,6 +2,7 @@ THE EXIM MAIL TRANSFER AGENT VERSION 4 -------------------------------------- Copyright (c) 1995 - 2018 University of Cambridge. +SPDX-License-Identifier: GPL-2.0-or-later See the file NOTICE for conditions of use and distribution. There is a book about Exim by Philip Hazel called "The Exim SMTP Mail Server", diff --git a/src/exim_monitor/EDITME b/src/exim_monitor/EDITME index a70b7cb61..1b6320c8f 100644 --- a/src/exim_monitor/EDITME +++ b/src/exim_monitor/EDITME @@ -2,6 +2,9 @@ # The Exim Monitor # ################################################## +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # This is the template for the Exim monitor's main build-time configuration # file. It contains settings that are independent of any operating system. It # should be edited and then saved to a file called Local/eximon.conf before diff --git a/src/exim_monitor/em_StripChart.c b/src/exim_monitor/em_StripChart.c index 3eb98e4fb..a974790d3 100644 --- a/src/exim_monitor/em_StripChart.c +++ b/src/exim_monitor/em_StripChart.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /*********************************************************** Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. diff --git a/src/exim_monitor/em_TextPop.c b/src/exim_monitor/em_TextPop.c index 0e87cb580..0360f852b 100644 --- a/src/exim_monitor/em_TextPop.c +++ b/src/exim_monitor/em_TextPop.c @@ -2,7 +2,7 @@ Copyright (c) The Exim Maintainers 2022 Copyright 1989 by the Massachusetts Institute of Technology, Cambridge, Massachusetts. -SPDX-License-Identifier: GPL-2.0-only +SPDX-License-Identifier: GPL-2.0-or-later All Rights Reserved diff --git a/src/exim_monitor/em_globals.c b/src/exim_monitor/em_globals.c index 2943065b4..cf9b1075e 100644 --- a/src/exim_monitor/em_globals.c +++ b/src/exim_monitor/em_globals.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_hdr.h b/src/exim_monitor/em_hdr.h index 76970c997..61f390d2c 100644 --- a/src/exim_monitor/em_hdr.h +++ b/src/exim_monitor/em_hdr.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This is the general header file for all the modules that comprise diff --git a/src/exim_monitor/em_init.c b/src/exim_monitor/em_init.c index e1f53fbba..b9289715d 100644 --- a/src/exim_monitor/em_init.c +++ b/src/exim_monitor/em_init.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module contains code to initialize things from the environment and the arguments. */ diff --git a/src/exim_monitor/em_log.c b/src/exim_monitor/em_log.c index d625056c5..55925d786 100644 --- a/src/exim_monitor/em_log.c +++ b/src/exim_monitor/em_log.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainters 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module contains code for scanning the main log, extracting information from it, and displaying a "tail". */ diff --git a/src/exim_monitor/em_main.c b/src/exim_monitor/em_main.c index 919cde632..50b8cd8bd 100644 --- a/src/exim_monitor/em_main.c +++ b/src/exim_monitor/em_main.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_menu.c b/src/exim_monitor/em_menu.c index afcd31540..e4db84915 100644 --- a/src/exim_monitor/em_menu.c +++ b/src/exim_monitor/em_menu.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_queue.c b/src/exim_monitor/em_queue.c index d9cfad38a..5eb44648a 100644 --- a/src/exim_monitor/em_queue.c +++ b/src/exim_monitor/em_queue.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_strip.c b/src/exim_monitor/em_strip.c index cfafe9257..21e5739db 100644 --- a/src/exim_monitor/em_strip.c +++ b/src/exim_monitor/em_strip.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_text.c b/src/exim_monitor/em_text.c index 1077353e0..4d03570fd 100644 --- a/src/exim_monitor/em_text.c +++ b/src/exim_monitor/em_text.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "em_hdr.h" diff --git a/src/exim_monitor/em_version.c b/src/exim_monitor/em_version.c index c5d4d62d8..4c562925c 100644 --- a/src/exim_monitor/em_version.c +++ b/src/exim_monitor/em_version.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define EM_VERSION_C diff --git a/src/exim_monitor/em_xs.c b/src/exim_monitor/em_xs.c index dd19c7f43..ac36b8f58 100644 --- a/src/exim_monitor/em_xs.c +++ b/src/exim_monitor/em_xs.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge, 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file contains a number of subroutines that are in effect just alternative packaging for calls to various X functions that diff --git a/src/scripts/Configure b/src/scripts/Configure index 6c340ee25..4c68b5940 100755 --- a/src/scripts/Configure +++ b/src/scripts/Configure @@ -2,6 +2,9 @@ # A script to be called to run all the other configuring scripts manually. +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + scripts/Configure-Makefile scripts/Configure-os.h scripts/Configure-os.c diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile index ed77b6a8f..dc5015f6f 100755 --- a/src/scripts/Configure-Makefile +++ b/src/scripts/Configure-Makefile @@ -1,13 +1,15 @@ #! /bin/sh -LC_ALL=C -export LC_ALL - # Shell script to build Makefile in a build directory. It must be called # from inside the directory. It does its own checking of when to rebuild; it # just got too horrendous to get it right in "make", because of the optionally # existing configuration files. # # Copyright (c) The Exim Maintainers 1995 - 2021 +# SPDX-License-Identifier: GPL-2.0-or-later + + +LC_ALL=C +export LC_ALL # First off, get the OS type, and check that there is a make file for it. diff --git a/src/scripts/Configure-config.h b/src/scripts/Configure-config.h index c750f64f1..6744755f7 100755 --- a/src/scripts/Configure-config.h +++ b/src/scripts/Configure-config.h @@ -1,5 +1,6 @@ #! /bin/sh -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # Build the config.h file, using the buildconfig program, first ensuring that # it exists. diff --git a/src/scripts/Configure-eximon b/src/scripts/Configure-eximon index 0aca3b338..00076154d 100755 --- a/src/scripts/Configure-eximon +++ b/src/scripts/Configure-eximon @@ -1,5 +1,8 @@ #! /bin/sh +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Shell script to build the configurable part of the Exim monitor's start-up # script. This is built from various configuration files. The final part is # added in the Makefile, using various macros that are available at that stage. diff --git a/src/scripts/Configure-os.c b/src/scripts/Configure-os.c index ab40ad183..7e9f14421 100755 --- a/src/scripts/Configure-os.c +++ b/src/scripts/Configure-os.c @@ -1,5 +1,7 @@ #! /bin/sh -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Shell script to build os.c. There doesn't have to be an OS-specific os.c # file, but if there is, it gets copied at the start of os.c. The basic src diff --git a/src/scripts/Configure-os.h b/src/scripts/Configure-os.h index f95a61a5d..dca0b9a3f 100755 --- a/src/scripts/Configure-os.h +++ b/src/scripts/Configure-os.h @@ -1,5 +1,7 @@ #! /bin/sh -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Shell script to create a link to the appropriate OS-specific header file. diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index 471b3a369..6e0b65f5d 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -4,6 +4,7 @@ # specific build directory. It should be run from within that directory. # # Copyright (c) The Exim Maintainers 1995 - 2022 +# SPDX-License-Identifier: GPL-2.0-or-later test ! -d ../src && \ echo "*** $0 should be run in a system-specific subdirectory." && \ diff --git a/src/scripts/arch-type b/src/scripts/arch-type index f5fe8ebd3..0218c0233 100755 --- a/src/scripts/arch-type +++ b/src/scripts/arch-type @@ -1,7 +1,9 @@ #! /bin/sh - # Shell script to determine the architecture type. +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # If EXIM_ARCHTYPE is set, use it. This allows a manual override. case "$EXIM_ARCHTYPE" in ?*) arch="$EXIM_ARCHTYPE";; esac diff --git a/src/scripts/exim_install b/src/scripts/exim_install index 1e8805024..827841ffc 100755 --- a/src/scripts/exim_install +++ b/src/scripts/exim_install @@ -1,5 +1,8 @@ #! /bin/sh +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Script to install Exim binaries in BIN_DIRECTORY, which is defined in # the local Makefile. It expects to be run in a build directory. It needs # to be run as root in order to make exim setuid to root. If exim runs setuid diff --git a/src/scripts/lookups-Makefile b/src/scripts/lookups-Makefile index ed8b0cb5c..8dcac585b 100755 --- a/src/scripts/lookups-Makefile +++ b/src/scripts/lookups-Makefile @@ -1,6 +1,7 @@ #! /bin/sh # Copyright (c) The Exim Maintainers 1995 - 2021 +# SPDX-License-Identifier: GPL-2.0-or-later # We turn the configure-built build-$foo/lookups/Makefile.predynamic into Makefile diff --git a/src/scripts/newer b/src/scripts/newer index 24c09e8f0..3bd65fb41 100755 --- a/src/scripts/newer +++ b/src/scripts/newer @@ -5,6 +5,9 @@ # if the second does not exist, the answer is "yes"; # otherwise their ages are compared using "find". +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + if [ $# -ne 2 ]; then echo "*** Two file names needed for 'newer' ***" exit 2; diff --git a/src/scripts/os-type b/src/scripts/os-type index a188c4a56..1fcd37bc3 100755 --- a/src/scripts/os-type +++ b/src/scripts/os-type @@ -1,5 +1,8 @@ #! /bin/sh +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later + # Shell script to determine the operating system type. Some of the heuristics # herein have accumulated over the years and may not strictly be needed now, # but they are left in under the principle of "If it ain't broke, don't fix diff --git a/src/scripts/reversion b/src/scripts/reversion index b932224f5..6fd0782a4 100755 --- a/src/scripts/reversion +++ b/src/scripts/reversion @@ -1,5 +1,6 @@ #!/bin/sh # Copyright (c) The Exim Maintainers 1995 - 2021 +# SPDX-License-Identifier: GPL-2.0-or-later set -e LC_ALL=C diff --git a/src/scripts/source_checks b/src/scripts/source_checks index 918a6f8eb..8620b27f5 100644 --- a/src/scripts/source_checks +++ b/src/scripts/source_checks @@ -1,4 +1,6 @@ #!/bin/sh +# Copyright (c) The Exim Maintainters 2022 +# SPDX-License-Identifier: GPL-2.0-or-later cd src; diff --git a/src/src/EDITME b/src/src/EDITME index 28d3d538e..625df18f5 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -1,6 +1,8 @@ ################################################## # The Exim mail transport agent # ################################################## +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # This is the template for Exim's main build-time configuration file. It # contains settings that are independent of any operating system. These are diff --git a/src/src/acl.c b/src/src/acl.c index 92af9991f..143890668 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for handling Access Control Lists (ACLs) */ diff --git a/src/src/arc.c b/src/src/arc.c index e3a2b3dad..30a66320e 100644 --- a/src/src/arc.c +++ b/src/src/arc.c @@ -5,7 +5,7 @@ Copyright (c) Jeremy Harris 2018 - 2020 Copyright (c) The Exim Maintainers 2021 - 2022 License: GPL - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/auths/auth-spa.c b/src/src/auths/auth-spa.c index 32276c3f3..bcf88c84d 100644 --- a/src/src/auths/auth-spa.c +++ b/src/src/auths/auth-spa.c @@ -10,7 +10,7 @@ * Samba project (by Andrew Tridgell, Jeremy Allison, and others). * * Copyright (c) The Exim Maintainers 2021 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * Tom Kistner provided additional code, adding spa_build_auth_challenge() to * support server authentication mode. diff --git a/src/src/auths/auth-spa.h b/src/src/auths/auth-spa.h index df250d7a6..db93891ab 100644 --- a/src/src/auths/auth-spa.h +++ b/src/src/auths/auth-spa.h @@ -9,7 +9,7 @@ * All the code used here was torn by Marc Prud'hommeaux out of the * Samba project (by Andrew Tridgell, Jeremy Allison, and others). */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* December 2004: The spa_base64_to_bits() function has no length checking in it. I have added a check. PH */ diff --git a/src/src/auths/call_pam.c b/src/src/auths/call_pam.c index 483b083be..3ff15711d 100644 --- a/src/src/auths/call_pam.c +++ b/src/src/auths/call_pam.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/auths/call_pwcheck.c b/src/src/auths/call_pwcheck.c index 436b1a8de..88f708f62 100644 --- a/src/src/auths/call_pwcheck.c +++ b/src/src/auths/call_pwcheck.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module contains interface functions to the two Cyrus authentication daemons. The original one was "pwcheck", which gives its name to the source diff --git a/src/src/auths/call_radius.c b/src/src/auths/call_radius.c index f4d7a9569..65882c108 100644 --- a/src/src/auths/call_radius.c +++ b/src/src/auths/call_radius.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file was originally supplied by Ian Kirk. The libradius support came from Alex Kiernan. */ diff --git a/src/src/auths/check_serv_cond.c b/src/src/auths/check_serv_cond.c index 033d2026b..5201d2177 100644 --- a/src/src/auths/check_serv_cond.c +++ b/src/src/auths/check_serv_cond.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c index 60128b83e..280b5293a 100644 --- a/src/src/auths/cram_md5.c +++ b/src/src/auths/cram_md5.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The stand-alone version just tests the algorithm. We have to drag diff --git a/src/src/auths/cram_md5.h b/src/src/auths/cram_md5.h index 25470a61b..984bc14c7 100644 --- a/src/src/auths/cram_md5.h +++ b/src/src/auths/cram_md5.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index 4fe257ba7..b5d2d1d3b 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This code was originally contributed by Matthew Byng-Maddick */ diff --git a/src/src/auths/cyrus_sasl.h b/src/src/auths/cyrus_sasl.h index 144ac5c80..05071b6e5 100644 --- a/src/src/auths/cyrus_sasl.h +++ b/src/src/auths/cyrus_sasl.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) A L Digital Ltd 2004 */ diff --git a/src/src/auths/dovecot.h b/src/src/auths/dovecot.h index b5eaf4f16..74c451930 100644 --- a/src/src/auths/dovecot.h +++ b/src/src/auths/dovecot.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainters 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/auths/external.c b/src/src/auths/external.c index 736c33982..078aad0fa 100644 --- a/src/src/auths/external.c +++ b/src/src/auths/external.c @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 2019-2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file provides an Exim authenticator driver for a server to verify a client SSL certificate, using the EXTERNAL diff --git a/src/src/auths/external.h b/src/src/auths/external.h index 9abb46a6b..0a9b0b50e 100644 --- a/src/src/auths/external.h +++ b/src/src/auths/external.h @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 2019 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/auths/get_data.c b/src/src/auths/get_data.c index 0c85d2651..caf4cfdb8 100644 --- a/src/src/auths/get_data.c +++ b/src/src/auths/get_data.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/auths/get_no64_data.c b/src/src/auths/get_no64_data.c index 76f421473..e2cadfbc6 100644 --- a/src/src/auths/get_no64_data.c +++ b/src/src/auths/get_no64_data.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c index aac9c84e6..2c39d0f21 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl_exim.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/gsasl_exim.h b/src/src/auths/gsasl_exim.h index 691d7d706..a56535710 100644 --- a/src/src/auths/gsasl_exim.h +++ b/src/src/auths/gsasl_exim.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) Twitter Inc 2012 */ diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c index 12267e3fc..1336d0fab 100644 --- a/src/src/auths/heimdal_gssapi.c +++ b/src/src/auths/heimdal_gssapi.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/heimdal_gssapi.h b/src/src/auths/heimdal_gssapi.h index 031b580ef..6c9b24298 100644 --- a/src/src/auths/heimdal_gssapi.h +++ b/src/src/auths/heimdal_gssapi.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) Twitter Inc 2012 Author: Phil Pennock */ diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c index 61be5867e..6692a676e 100644 --- a/src/src/auths/plaintext.c +++ b/src/src/auths/plaintext.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "plaintext.h" diff --git a/src/src/auths/plaintext.h b/src/src/auths/plaintext.h index 49862ff9b..fdf0feb93 100644 --- a/src/src/auths/plaintext.h +++ b/src/src/auths/plaintext.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/auths/pwcheck.c b/src/src/auths/pwcheck.c index aff5ed39c..bf305832f 100644 --- a/src/src/auths/pwcheck.c +++ b/src/src/auths/pwcheck.c @@ -4,7 +4,7 @@ * $Id: checkpw.c,v 1.49 2002/03/07 19:14:04 ken3 Exp $ */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. * diff --git a/src/src/auths/pwcheck.h b/src/src/auths/pwcheck.h index 4247b4e8b..4c1d71d92 100644 --- a/src/src/auths/pwcheck.h +++ b/src/src/auths/pwcheck.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file provides support for authentication via the Cyrus SASL pwcheck daemon (whence its name) and the newer saslauthd daemon. */ diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c index c5e6d83d5..222ccea86 100644 --- a/src/src/auths/spa.c +++ b/src/src/auths/spa.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file, which provides support for Microsoft's Secure Password Authentication, was contributed by Marc Prud'hommeaux. Tom Kistner added SPA diff --git a/src/src/auths/spa.h b/src/src/auths/spa.h index 4321971d9..625a252d6 100644 --- a/src/src/auths/spa.h +++ b/src/src/auths/spa.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file, which provides support for Microsoft's Secure Password Authentication, was contributed by Marc Prud'hommeaux. */ diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c index d3ca8f796..72ad56c4e 100644 --- a/src/src/auths/tls.c +++ b/src/src/auths/tls.c @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file provides an Exim authenticator driver for a server to verify a client SSL certificate diff --git a/src/src/auths/tls.h b/src/src/auths/tls.h index 24e116464..472a3e260 100644 --- a/src/src/auths/tls.h +++ b/src/src/auths/tls.h @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/auths/xtextdecode.c b/src/src/auths/xtextdecode.c index 39c1f2b60..b6a927194 100644 --- a/src/src/auths/xtextdecode.c +++ b/src/src/auths/xtextdecode.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/auths/xtextencode.c b/src/src/auths/xtextencode.c index 89f12f1f1..c08288831 100644 --- a/src/src/auths/xtextencode.c +++ b/src/src/auths/xtextencode.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/base64.c b/src/src/base64.c index 14e8cfffe..e9ac41a55 100644 --- a/src/src/base64.c +++ b/src/src/base64.c @@ -4,7 +4,7 @@ /* Copyright (c) Tom Kistner 2004, 2015 */ /* License: GPL */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ diff --git a/src/src/blob.h b/src/src/blob.h index 95a987f0a..72b7fe564 100644 --- a/src/src/blob.h +++ b/src/src/blob.h @@ -2,7 +2,7 @@ * Blob - a general pointer/size item for a memory chunk * * Copyright (C) 2016 Exim maintainers - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef BLOB_H /* entire file */ diff --git a/src/src/bmi_spam.c b/src/src/bmi_spam.c index 140bec48f..03e8defa6 100644 --- a/src/src/bmi_spam.c +++ b/src/src/bmi_spam.c @@ -6,7 +6,7 @@ Copyright (c) Tom Kistner 2004 License: GPL */ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" #ifdef EXPERIMENTAL_BRIGHTMAIL diff --git a/src/src/bmi_spam.h b/src/src/bmi_spam.h index a9833b200..bb1c859a9 100644 --- a/src/src/bmi_spam.h +++ b/src/src/bmi_spam.h @@ -5,7 +5,7 @@ /* Code for calling Brightmail AntiSpam. Copyright (c) Tom Kistner 2004 License: GPL */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef EXPERIMENTAL_BRIGHTMAIL diff --git a/src/src/buildconfig.c b/src/src/buildconfig.c index 710b53550..8f37e508a 100644 --- a/src/src/buildconfig.c +++ b/src/src/buildconfig.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /************************************************* diff --git a/src/src/child.c b/src/src/child.c index b94e814a1..359b791e8 100644 --- a/src/src/child.c +++ b/src/src/child.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/daemon.c b/src/src/daemon.c index 0afc7ca86..be008c3d4 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with running Exim as a daemon */ diff --git a/src/src/dane.c b/src/src/dane.c index f2ad22481..a12e16238 100644 --- a/src/src/dane.c +++ b/src/src/dane.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2012, 2014 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module provides DANE (RFC6659) support for Exim. See also the draft RFC for DANE-over-SMTP, "SMTP security via opportunistic DANE TLS" diff --git a/src/src/dbfn.c b/src/src/dbfn.c index f932520f9..3c51162a4 100644 --- a/src/src/dbfn.c +++ b/src/src/dbfn.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/dbfunctions.h b/src/src/dbfunctions.h index 93e1d3405..1f0dec1f7 100644 --- a/src/src/dbfunctions.h +++ b/src/src/dbfunctions.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef DBFUNCTIONS_H #define DBFUNCTIONS_H diff --git a/src/src/dcc.c b/src/src/dcc.c index d8e22b30c..8986dedde 100644 --- a/src/src/dcc.c +++ b/src/src/dcc.c @@ -8,7 +8,7 @@ * See the file NOTICE for conditions of use and distribution. * * Copyright (c) The Exim Maintainers 2015 - 2022 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling dccifd. Called from acl.c. */ diff --git a/src/src/debug.c b/src/src/debug.c index 38e8f8001..44ad763e1 100644 --- a/src/src/debug.c +++ b/src/src/debug.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2015 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/deliver.c b/src/src/deliver.c index 719fa9d93..c4fce4602 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The main code for delivering a message. */ diff --git a/src/src/directory.c b/src/src/directory.c index c3b341bbb..94303db0b 100644 --- a/src/src/directory.c +++ b/src/src/directory.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2010 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/dkim.c b/src/src/dkim.c index 9b6e14a3f..0a8ab6fb3 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge, 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for DKIM support. Other DKIM relevant code is in receive.c, transport.c and transports/smtp.c */ diff --git a/src/src/dkim.h b/src/src/dkim.h index 61d83a9df..915c6c739 100644 --- a/src/src/dkim.h +++ b/src/src/dkim.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge, 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ void dkim_exim_init(void); gstring * dkim_exim_sign(int, off_t, uschar *, struct ob_dkim *, const uschar **); diff --git a/src/src/dkim_transport.c b/src/src/dkim_transport.c index 142f4552a..c127d5b73 100644 --- a/src/src/dkim_transport.c +++ b/src/src/dkim_transport.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Transport shim for dkim signing */ diff --git a/src/src/dmarc.c b/src/src/dmarc.c index c0313bf5c..118720750 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -5,7 +5,7 @@ Copyright (c) The Exim Maintainers 2019 - 2022 Copyright (c) Todd Lyons 2012 - 2014 License: GPL */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; All rights reserved, licensed for use per LICENSE.opendmarc. */ diff --git a/src/src/dmarc.h b/src/src/dmarc.h index f71f1fd5a..86d3b1e1c 100644 --- a/src/src/dmarc.h +++ b/src/src/dmarc.h @@ -6,7 +6,7 @@ Copyright (c) The Exim Maintainers 2021 - 2022 Copyright (c) Todd Lyons 2012 - 2014 License: GPL */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; All rights reserved, licensed for use per LICENSE.opendmarc. */ diff --git a/src/src/dns.c b/src/src/dns.c index 8106fb688..4e01d8661 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for interfacing with the DNS. */ diff --git a/src/src/dnsbl.c b/src/src/dnsbl.c index af80f6be1..1172d6183 100644 --- a/src/src/dnsbl.c +++ b/src/src/dnsbl.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with dnsbls */ diff --git a/src/src/drtables.c b/src/src/drtables.c index a6cbede89..cf7c4e0b1 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/dummies.c b/src/src/dummies.c index a72767ccd..df8ef6d5b 100644 --- a/src/src/dummies.c +++ b/src/src/dummies.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file is not part of the main Exim code. There are little bits of test code for some of Exim's modules, and when they are used, the module they are diff --git a/src/src/enq.c b/src/src/enq.c index 054aeaed8..43f53a585 100644 --- a/src/src/enq.c +++ b/src/src/enq.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with serialization. */ diff --git a/src/src/environment.c b/src/src/environment.c index 06f804e69..68adf3c0c 100644 --- a/src/src/environment.c +++ b/src/src/environment.c @@ -5,7 +5,7 @@ /* Copyright (c) Heiko Schlittermann 2016 * hs@schlittermann.de * See the file NOTICE for conditions of use and distribution. - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/exim.c b/src/src/exim.c index 62413e367..35f4ae4f7 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The main function: entry point, initialization, and high-level control. diff --git a/src/src/exim.h b/src/src/exim.h index 24fedcced..ccf14f0fd 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Source files for exim all #include this header, which drags in everything diff --git a/src/src/exim_dbmbuild.c b/src/src/exim_dbmbuild.c index bb04adc02..0ea71795f 100644 --- a/src/src/exim_dbmbuild.c +++ b/src/src/exim_dbmbuild.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* A small freestanding program to build dbm databases from serial input. For diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c index 669f7098d..f16570d86 100644 --- a/src/src/exim_dbutil.c +++ b/src/src/exim_dbutil.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This single source file is used to compile three utility programs for diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c index 1a54a92ad..363c1bc71 100644 --- a/src/src/exim_lock.c +++ b/src/src/exim_lock.c @@ -11,7 +11,7 @@ Default is -fcntl -lockfile. Argument: the name of the lock file Copyright (c) The Exim Maintainers 2016 - 2021 -SPDX-License-Identifier: GPL-2.0-only +SPDX-License-Identifier: GPL-2.0-or-later */ #include "os.h" diff --git a/src/src/expand.c b/src/src/expand.c index 050f01297..657cf3cb9 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for handling string expansion. */ diff --git a/src/src/filter.c b/src/src/filter.c index 82a9122c6..530d772b3 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for mail filtering functions. */ diff --git a/src/src/filtertest.c b/src/src/filtertest.c index 8bab65e78..2426f7feb 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for the filter test function. */ diff --git a/src/src/functions.h b/src/src/functions.h index be1fae00d..a2c8976e8 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Prototypes for functions that appear in various modules. Gathered together diff --git a/src/src/globals.c b/src/src/globals.c index 429952edc..e5b72592f 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* All the global variables are defined together in this one module, so that they are easy to find. */ diff --git a/src/src/globals.h b/src/src/globals.h index 48d93a1c3..5aae73fba 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Almost all the global variables are defined together in this one header, so that they are easy to find. However, those that are visible during the diff --git a/src/src/hash.c b/src/src/hash.c index 2b71463f1..10af1b43d 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -3,7 +3,7 @@ * * Copyright (c) The Exim Maintainers 2010 - 2022 * Copyright (c) University of Cambridge 1995 - 2009 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * Hash interface functions */ diff --git a/src/src/hash.h b/src/src/hash.h index c94e53129..788c9f0ad 100644 --- a/src/src/hash.h +++ b/src/src/hash.h @@ -1,7 +1,7 @@ /* * Exim - an Internet mail transport agent * Copyright (c) The Exim Maintainers 1995 - 2022 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * Hash interface functions */ diff --git a/src/src/header.c b/src/src/header.c index 2a8fbfe64..a4dd6e72e 100644 --- a/src/src/header.c +++ b/src/src/header.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/hintsdb.h b/src/src/hintsdb.h index e79e6bd49..2d7199eda 100644 --- a/src/src/hintsdb.h +++ b/src/src/hintsdb.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This header file contains macro definitions so that a variety of DBM libraries can be used by Exim. Nigel Metheringham provided the original set for diff --git a/src/src/hintsdb_structs.h b/src/src/hintsdb_structs.h index 27cd9edf9..0e5853b2b 100644 --- a/src/src/hintsdb_structs.h +++ b/src/src/hintsdb_structs.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This header file contains the definitions of the structures used in the various hints databases are also kept in this file, which is used by the diff --git a/src/src/host.c b/src/src/host.c index 874e19a08..ecdc6d681 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or directly via the DNS. When IPv6 is supported, getipnodebyname() and diff --git a/src/src/host_address.c b/src/src/host_address.c index 28a8a685f..4c13f0bb7 100644 --- a/src/src/host_address.c +++ b/src/src/host_address.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/imap_utf7.c b/src/src/imap_utf7.c index 75ecb1a4b..1c09db621 100644 --- a/src/src/imap_utf7.c +++ b/src/src/imap_utf7.c @@ -1,6 +1,6 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/ip.c b/src/src/ip.c index 2ac2b267d..b50130be3 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for doing things with sockets. With the advent of IPv6 this has got messier, so that it's worth pulling out the code into separate functions diff --git a/src/src/local_scan.c b/src/src/local_scan.c index 85ecba8cb..da44cb7e6 100644 --- a/src/src/local_scan.c +++ b/src/src/local_scan.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /****************************************************************************** diff --git a/src/src/local_scan.h b/src/src/local_scan.h index 2eabc5929..69b3c6cdb 100644 --- a/src/src/local_scan.h +++ b/src/src/local_scan.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file is the header that is the only Exim header to be included in the source for the local_scan.c() function. It contains definitions that are made diff --git a/src/src/log.c b/src/src/log.c index f1d435ce4..6c483216a 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for writing log files. The code for maintaining datestamped log files was originally contributed by Tony Sheen. */ diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h index cec8f976b..62c8c0524 100644 --- a/src/src/lookupapi.h +++ b/src/src/lookupapi.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The "type" field in each item is a set of bit flags: diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c index c99e948b5..aa930e654 100644 --- a/src/src/lookups/dbmdb.c +++ b/src/src/lookups/dbmdb.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index 4f43cf674..5482cd9d1 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c index 6cae0dafb..74439bfc8 100644 --- a/src/src/lookups/dsearch.c +++ b/src/src/lookups/dsearch.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The idea for this code came from Matthew Byng-Maddick, but his original has been heavily reworked a lot for Exim 4 (and it now uses stat() (more precisely: diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c index d42e490c4..7e4973e01 100644 --- a/src/src/lookups/ibase.c +++ b/src/src/lookups/ibase.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* The code in this module was contributed by Ard Biesheuvel. */ diff --git a/src/src/lookups/json.c b/src/src/lookups/json.c index b1e5fb742..43575cacf 100644 --- a/src/src/lookups/json.c +++ b/src/src/lookups/json.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2019 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index 17c431e5c..feeea0e41 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Many thanks to Stuart Lynne for contributing the original code for this driver. Further contributions from Michael Haardt, Brian Candler, Barry diff --git a/src/src/lookups/ldap.h b/src/src/lookups/ldap.h index 30228aebe..2ce62fc05 100644 --- a/src/src/lookups/ldap.h +++ b/src/src/lookups/ldap.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for eldapauth_find */ diff --git a/src/src/lookups/lf_check_file.c b/src/src/lookups/lf_check_file.c index 1649f9f83..5c74816ef 100644 --- a/src/src/lookups/lf_check_file.c +++ b/src/src/lookups/lf_check_file.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h index b83b9652a..b7acbb5a9 100644 --- a/src/src/lookups/lf_functions.h +++ b/src/src/lookups/lf_functions.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for the functions that are shared by the lookups */ diff --git a/src/src/lookups/lf_quote.c b/src/src/lookups/lf_quote.c index 816fe01e2..72e37bfb4 100644 --- a/src/src/lookups/lf_quote.c +++ b/src/src/lookups/lf_quote.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c index cf4b9cd0b..ecb0a3221 100644 --- a/src/src/lookups/lf_sqlperform.c +++ b/src/src/lookups/lf_sqlperform.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/lmdb.c b/src/src/lookups/lmdb.c index ccfdbe453..3a3eebcba 100644 --- a/src/src/lookups/lmdb.c +++ b/src/src/lookups/lmdb.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 2016 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c index da73ae8bf..f668f60f2 100644 --- a/src/src/lookups/lsearch.c +++ b/src/src/lookups/lsearch.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c index a8dae4ade..7e0343233 100644 --- a/src/src/lookups/mysql.c +++ b/src/src/lookups/mysql.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Thanks to Paul Kelly for contributing the original code for these functions. */ diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c index e7c124757..6a08ebc37 100644 --- a/src/src/lookups/nis.c +++ b/src/src/lookups/nis.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c index 78c79563f..3f89c7f81 100644 --- a/src/src/lookups/nisplus.c +++ b/src/src/lookups/nisplus.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c index 3f3868fe9..d0604c245 100644 --- a/src/src/lookups/oracle.c +++ b/src/src/lookups/oracle.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Interface to an Oracle database. This code was originally supplied by Paul Kelly, but I have hacked it around for various reasons, and tried to add diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c index 7df1a5aaf..f185a9091 100644 --- a/src/src/lookups/passwd.c +++ b/src/src/lookups/passwd.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c index 4fcd0e3ed..1583378d5 100644 --- a/src/src/lookups/pgsql.c +++ b/src/src/lookups/pgsql.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Thanks to Petr Cech for contributing the original code for these functions. Thanks to Joachim Wieland for the initial patch for the Unix domain diff --git a/src/src/lookups/readsock.c b/src/src/lookups/readsock.c index 7c7b9cfa8..b1ea42c7f 100644 --- a/src/src/lookups/readsock.c +++ b/src/src/lookups/readsock.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c index c7fcb66f0..7b680f086 100644 --- a/src/src/lookups/redis.c +++ b/src/src/lookups/redis.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c index b9a735e18..6c7af4225 100644 --- a/src/src/lookups/sqlite.c +++ b/src/src/lookups/sqlite.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c index f94150b68..8de7090b7 100644 --- a/src/src/lookups/testdb.c +++ b/src/src/lookups/testdb.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "lf_functions.h" diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c index cd236787e..cd6c7e85c 100644 --- a/src/src/lookups/whoson.c +++ b/src/src/lookups/whoson.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This code originally came from Robert Wal. */ diff --git a/src/src/lss.c b/src/src/lss.c index 0d20c07b6..e6ec1d6d1 100644 --- a/src/src/lss.c +++ b/src/src/lss.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Support functions for calling from local_scan(). These are mostly just wrappers for various internal functions. */ diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index fe814500d..618c914dc 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) Jeremy Harris 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Create a static data structure with the predefined macros, to be included in the main Exim build */ diff --git a/src/src/macro_predef.h b/src/src/macro_predef.h index d3bc5c074..8b7b375c6 100644 --- a/src/src/macro_predef.h +++ b/src/src/macro_predef.h @@ -5,7 +5,7 @@ /* Copyright (c) Jeremy Harris 2017 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Global functions */ diff --git a/src/src/macros.h b/src/src/macros.h index db1c34b65..243c1e5a0 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* These two macros make it possible to obtain the result of macro-expanding diff --git a/src/src/malware.c b/src/src/malware.c index 96514e276..f36c46b0f 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -6,7 +6,7 @@ * Copyright (c) The Exim Maintainers 2015 - 2022 * Copyright (c) Tom Kistner 2003 - 2015 * License: GPL - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling virus (malware) scanners. Called from acl.c. */ diff --git a/src/src/match.c b/src/src/match.c index a877aef3b..15209f84a 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for matching strings */ diff --git a/src/src/md5.c b/src/src/md5.c index e6df32c7a..1d54ab4f1 100644 --- a/src/src/md5.c +++ b/src/src/md5.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef STAND_ALONE #include "exim.h" diff --git a/src/src/mime.c b/src/src/mime.c index bebe9bf44..7c3a33d62 100644 --- a/src/src/mime.c +++ b/src/src/mime.c @@ -6,7 +6,7 @@ * Copyright (c) The Exim Maintainers 2015 - 2022 * Copyright (c) Tom Kistner 2004 - 2015 * License: GPL - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/mime.h b/src/src/mime.h index 48bbd81de..d436bcacb 100644 --- a/src/src/mime.h +++ b/src/src/mime.h @@ -5,7 +5,7 @@ /* Copyright (c) Tom Kistner 2004, 2015 * License: GPL * Copyright (c) The Exim Maintainers 2016 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef WITH_CONTENT_SCAN diff --git a/src/src/moan.c b/src/src/moan.c index 387359458..ebfd440f6 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for sending messages to sender or to mailmaster. */ diff --git a/src/src/mytypes.h b/src/src/mytypes.h index 06426af7a..954f683c8 100644 --- a/src/src/mytypes.h +++ b/src/src/mytypes.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This header file contains type definitions and macros that I use as diff --git a/src/src/os.c b/src/src/os.c index 4edb2ca98..fc29f1766 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef STAND_ALONE # include diff --git a/src/src/osfunctions.h b/src/src/osfunctions.h index 454e9f77f..f88210943 100644 --- a/src/src/osfunctions.h +++ b/src/src/osfunctions.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2016 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Prototypes for os-specific functions. For utilities, we don't need the one that uses a type that isn't defined for them. */ diff --git a/src/src/parse.c b/src/src/parse.c index 93b12bc77..53d660869 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for parsing addresses */ diff --git a/src/src/pdkim/crypt_ver.h b/src/src/pdkim/crypt_ver.h index 367527e39..56ae236c1 100644 --- a/src/src/pdkim/crypt_ver.h +++ b/src/src/pdkim/crypt_ver.h @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Signing and hashing routine selection for PDKIM */ diff --git a/src/src/pdkim/pdkim_hash.h b/src/src/pdkim/pdkim_hash.h index e470299a4..d56e3ce34 100644 --- a/src/src/pdkim/pdkim_hash.h +++ b/src/src/pdkim/pdkim_hash.h @@ -2,7 +2,7 @@ * PDKIM - a RFC4871 (DKIM) implementation * * Copyright (C) 1995 - 2018 Exim maintainers - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * Hash interface functions */ diff --git a/src/src/pdkim/signing.c b/src/src/pdkim/signing.c index 8876f617c..07737ab41 100644 --- a/src/src/pdkim/signing.c +++ b/src/src/pdkim/signing.c @@ -1,7 +1,7 @@ /* * PDKIM - a RFC4871 (DKIM) implementation * Copyright (c) The Exim Maintainers 1995 - 2022 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * signing/verification interface */ diff --git a/src/src/pdkim/signing.h b/src/src/pdkim/signing.h index 880342b6f..7760ce73f 100644 --- a/src/src/pdkim/signing.h +++ b/src/src/pdkim/signing.h @@ -2,7 +2,7 @@ * PDKIM - a RFC4871 (DKIM) implementation * * Copyright (C) 1995 - 2020 Exim maintainers - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * RSA signing/verification interface */ diff --git a/src/src/perl.c b/src/src/perl.c index b5c3f882e..2a10452d3 100644 --- a/src/src/perl.c +++ b/src/src/perl.c @@ -4,7 +4,7 @@ /* Copyright (c) The Exim Maintainers 1999 - 2022 */ /* Copyright (c) 1998 Malcolm Beattie */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Modified by PH to get rid of the "na" usage, March 1999. Modified further by PH for general tidying for Exim 4. diff --git a/src/src/priv.c b/src/src/priv.c index c818b5b78..3a100cd9e 100644 --- a/src/src/priv.c +++ b/src/src/priv.c @@ -1,5 +1,5 @@ /* Copyright (c) The Exim Maintainers 2022 * -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" #include diff --git a/src/src/queue.c b/src/src/queue.c index fd84d303f..f86e24b42 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions that operate on the input queue. */ diff --git a/src/src/rda.c b/src/src/rda.c index 1bc322e34..9c2aa5022 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module contains code for extracting addresses from a forwarding list (from an alias or forward file) or by running the filter interpreter. It may do diff --git a/src/src/readconf.c b/src/src/readconf.c index b0d688772..48b648bb2 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for reading the configuration file, and for displaying overall configuration values. Thanks to Brian Candler for the original diff --git a/src/src/receive.c b/src/src/receive.c index d9d0757ef..9bf834aaf 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for receiving a message and setting up spool files. */ diff --git a/src/src/regex.c b/src/src/regex.c index eefba8ecf..757243e7f 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -6,7 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Tom Kistner 2003-2015 * License: GPL - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for matching regular expressions against headers and body. diff --git a/src/src/regex_cache.c b/src/src/regex_cache.c index e4771aab9..a9b482174 100644 --- a/src/src/regex_cache.c +++ b/src/src/regex_cache.c @@ -5,7 +5,7 @@ /* * Copyright (c) The Exim Maintainers 2022 * License: GPL - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Caching layers for compiled REs. There is a local layer in the process, diff --git a/src/src/retry.c b/src/src/retry.c index e1490266c..f073af665 100644 --- a/src/src/retry.c +++ b/src/src/retry.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with retrying unsuccessful deliveries. */ diff --git a/src/src/rewrite.c b/src/src/rewrite.c index 040525ec5..c6a7b9fa5 100644 --- a/src/src/rewrite.c +++ b/src/src/rewrite.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with rewriting headers */ diff --git a/src/src/rfc2047.c b/src/src/rfc2047.c index af8993695..c40518a5d 100644 --- a/src/src/rfc2047.c +++ b/src/src/rfc2047.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file contains a function for decoding message header lines that may contain encoded "words" according to the rules described in diff --git a/src/src/route.c b/src/src/route.c index 7e6e4eb69..82d51bc68 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with routing, and the list of generic router options. */ diff --git a/src/src/routers/accept.c b/src/src/routers/accept.c index ab02716eb..63c8c22e4 100644 --- a/src/src/routers/accept.c +++ b/src/src/routers/accept.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/accept.h b/src/src/routers/accept.h index e025179ee..ca768b26e 100644 --- a/src/src/routers/accept.h +++ b/src/src/routers/accept.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options (there aren't any). */ diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index 0b1abeb8e..d27757c7e 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/dnslookup.h b/src/src/routers/dnslookup.h index 0272db300..ce1daf3c0 100644 --- a/src/src/routers/dnslookup.h +++ b/src/src/routers/dnslookup.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/routers/ipliteral.c b/src/src/routers/ipliteral.c index cfbf276ff..1297b97f2 100644 --- a/src/src/routers/ipliteral.c +++ b/src/src/routers/ipliteral.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/ipliteral.h b/src/src/routers/ipliteral.h index f7e99b9c2..7db24cfd1 100644 --- a/src/src/routers/ipliteral.h +++ b/src/src/routers/ipliteral.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. Some compilers do not like empty diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c index 970ec7704..7faaea0cd 100644 --- a/src/src/routers/iplookup.c +++ b/src/src/routers/iplookup.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/iplookup.h b/src/src/routers/iplookup.h index 3b7295574..ccce2eef5 100644 --- a/src/src/routers/iplookup.h +++ b/src/src/routers/iplookup.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c index 6a500d09a..160c866b9 100644 --- a/src/src/routers/manualroute.c +++ b/src/src/routers/manualroute.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/manualroute.h b/src/src/routers/manualroute.h index e27d90953..1201c8362 100644 --- a/src/src/routers/manualroute.h +++ b/src/src/routers/manualroute.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for the manualroute router */ diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c index 51b7b7551..51fdad229 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/queryprogram.h b/src/src/routers/queryprogram.h index 148846fae..f2cff1dab 100644 --- a/src/src/routers/queryprogram.h +++ b/src/src/routers/queryprogram.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c index 6126555fe..6a17c2f8d 100644 --- a/src/src/routers/redirect.c +++ b/src/src/routers/redirect.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/redirect.h b/src/src/routers/redirect.h index 76d02f261..8aeb892cb 100644 --- a/src/src/routers/redirect.h +++ b/src/src/routers/redirect.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for the redirect router */ diff --git a/src/src/routers/rf_change_domain.c b/src/src/routers/rf_change_domain.c index 4f8d47299..144fabbcd 100644 --- a/src/src/routers/rf_change_domain.c +++ b/src/src/routers/rf_change_domain.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/rf_expand_data.c b/src/src/routers/rf_expand_data.c index 5fbf0ac78..9892567f0 100644 --- a/src/src/routers/rf_expand_data.c +++ b/src/src/routers/rf_expand_data.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/rf_functions.h b/src/src/routers/rf_functions.h index d8fca68c5..91ccfb132 100644 --- a/src/src/routers/rf_functions.h +++ b/src/src/routers/rf_functions.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for the functions that are shared by the routers */ diff --git a/src/src/routers/rf_get_errors_address.c b/src/src/routers/rf_get_errors_address.c index 1189fd9e0..f70bdf25e 100644 --- a/src/src/routers/rf_get_errors_address.c +++ b/src/src/routers/rf_get_errors_address.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c index be86a4e0e..58b5bc7ad 100644 --- a/src/src/routers/rf_get_munge_headers.c +++ b/src/src/routers/rf_get_munge_headers.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_transport.c b/src/src/routers/rf_get_transport.c index 0c1fa8173..d54e3c296 100644 --- a/src/src/routers/rf_get_transport.c +++ b/src/src/routers/rf_get_transport.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_get_ugid.c b/src/src/routers/rf_get_ugid.c index 15144beb1..cefe527a5 100644 --- a/src/src/routers/rf_get_ugid.c +++ b/src/src/routers/rf_get_ugid.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index affd70b6e..f10ff5921 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/rf_queue_add.c b/src/src/routers/rf_queue_add.c index 49dd83117..8d94f5725 100644 --- a/src/src/routers/rf_queue_add.c +++ b/src/src/routers/rf_queue_add.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/routers/rf_self_action.c b/src/src/routers/rf_self_action.c index 7cc592039..73d07db40 100644 --- a/src/src/routers/rf_self_action.c +++ b/src/src/routers/rf_self_action.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/routers/rf_set_ugid.c b/src/src/routers/rf_set_ugid.c index 65f5200a2..ac63222b3 100644 --- a/src/src/routers/rf_set_ugid.c +++ b/src/src/routers/rf_set_ugid.c @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "rf_functions.h" diff --git a/src/src/search.c b/src/src/search.c index 32099ab9e..2b6e5d37f 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* A set of functions to search databases in various formats. An open database is represented by a void * value which is returned from a lookup- diff --git a/src/src/setenv.c b/src/src/setenv.c index 877fe388f..a5f056aee 100644 --- a/src/src/setenv.c +++ b/src/src/setenv.c @@ -6,7 +6,7 @@ * Copyright (c) Jeremy Harris 2015 - 2016 * Copyright (c) The Exim Maintainers 2016 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module provides (un)setenv routines for those environments lacking them in libraries. It is #include'd by OS/os.c-foo files. */ diff --git a/src/src/sha_ver.h b/src/src/sha_ver.h index 8385c1377..0d57db84f 100644 --- a/src/src/sha_ver.h +++ b/src/src/sha_ver.h @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SHA routine selection */ diff --git a/src/src/sieve.c b/src/src/sieve.c index 033a9734a..0b347e48d 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -6,7 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Michael Haardt 2003 - 2015 * See the file NOTICE for conditions of use and distribution. - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* This code was contributed by Michael Haardt. */ diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 3c6339c82..9b60702c1 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for handling an incoming SMTP call. */ diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index db39dcab5..e705965ba 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* A number of functions for driving outgoing SMTP calls. */ diff --git a/src/src/spam.c b/src/src/spam.c index f6575c293..401fdb269 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -6,7 +6,7 @@ * Copyright (c) The Exim Maintainers 2016 - 2022 * Copyright (c) Tom Kistner 2003 - 2015 * License: GPL - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling spamassassin's spamd. Called from acl.c. */ diff --git a/src/src/spam.h b/src/src/spam.h index c410198d7..0362e49dd 100644 --- a/src/src/spam.h +++ b/src/src/spam.h @@ -5,7 +5,7 @@ /* Copyright (c) Tom Kistner 2003 - 2015 */ /* Copyright (c) The Exim Maintainers 2021 */ /* License: GPL */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* spam defines */ diff --git a/src/src/spf.c b/src/src/spf.c index a94bc9677..6f0917a9c 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -6,7 +6,7 @@ Copyright (c) The Exim Maintainers 2015 - 2022 Copyright (c) Tom Kistner 2004 - 2014 License: GPL - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling spf checks via libspf-alt. Called from acl.c. */ diff --git a/src/src/spf.h b/src/src/spf.h index 8fb7b04cb..76c7522bd 100644 --- a/src/src/spf.h +++ b/src/src/spf.h @@ -6,7 +6,7 @@ Copyright (c) The Exim Maintainers 2016 - 2022 Copyright (c) Tom Kistner 2004 License: GPL - SPDX-License-Identifier: GPL-2.0-only + SPDX-License-Identifier: GPL-2.0-or-later */ #ifdef SUPPORT_SPF diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 82d11bf65..6d6651f57 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for reading spool files. When compiling for a utility (eximon), not all are needed, and some functionality can be cut out. */ diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index d9767ec3c..7ea565a58 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -5,7 +5,7 @@ /* Copyright (c) Tom Kistner 2003 - 2015 * License: GPL * Copyright (c) The Exim Maintainers 2016 - 2021 - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for setting up a MBOX style spool file inside a /scan/ diff --git a/src/src/spool_out.c b/src/src/spool_out.c index cb409c641..9c5e8eb33 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for writing spool files, and moving them about. */ diff --git a/src/src/std-crypto.c b/src/src/std-crypto.c index c1eef6c35..29efa6997 100644 --- a/src/src/std-crypto.c +++ b/src/src/std-crypto.c @@ -7,7 +7,7 @@ * But almost everything here is fixed published constants from RFCs, so also: * Copyright (C) The Internet Society (2003) * Copyright (C) The IETF Trust (2008) - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later * * Most of the text in RFC referencing comments is copy/paste from RFC, * as is undoubtedly the intention. diff --git a/src/src/store.c b/src/src/store.c index 449fb4ead..9e4536eae 100644 --- a/src/src/store.c +++ b/src/src/store.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim maintainers 2019 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Exim gets and frees all its store through these functions. In the original implementation there was a lot of mallocing and freeing of small bits of store. diff --git a/src/src/store.h b/src/src/store.h index 47ed963cd..834457aaa 100644 --- a/src/src/store.h +++ b/src/src/store.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header for Exim's memory allocation functions */ diff --git a/src/src/string.c b/src/src/string.c index ff4180b2b..2cb419517 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Miscellaneous string-handling functions. Some are not required for utilities and tests, and are cut out by the COMPILE_UTILITY macro. */ diff --git a/src/src/structs.h b/src/src/structs.h index 1cb69236e..e1d93a943 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Definitions of various structures. In addition, those that are visible for diff --git a/src/src/tls-cipher-stdname.c b/src/src/tls-cipher-stdname.c index fe442a050..ef3de99cb 100644 --- a/src/src/tls-cipher-stdname.c +++ b/src/src/tls-cipher-stdname.c @@ -4,7 +4,7 @@ /* Copyright (c) Jeremy Harris 2019 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Translate an IETF TLS ciphersuite code to an IETF ciphersuite name, for use when the TLS library do not provide such names. diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index c98760202..703a0a4ca 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -6,7 +6,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) Phil Pennock 2012 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file provides TLS/SSL support for Exim using the GnuTLS library, one of the available supported implementations. This file is #included into diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 052d8161d..2b3f02712 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2019 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Portions Copyright (c) The OpenSSL Project 1999 */ diff --git a/src/src/tls.c b/src/src/tls.c index 9e20b5bca..4a23aaae9 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module provides TLS (aka SSL) support for Exim. The code for OpenSSL is based on a patch that was originally contributed by Steve Haslam. It was diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c index 8840d5cfd..a3f6d4434 100644 --- a/src/src/tlscert-gnu.c +++ b/src/src/tlscert-gnu.c @@ -4,7 +4,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2014 - 2018 */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file provides TLS/SSL support for Exim using the GnuTLS library, one of the available supported implementations. This file is #included into diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c index a4c3d19fa..32177ea81 100644 --- a/src/src/tlscert-openssl.c +++ b/src/src/tlscert-openssl.c @@ -4,7 +4,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) Jeremy Harris 2014 - 2019 */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This module provides TLS (aka SSL) support for Exim using the OpenSSL library. It is #included into the tls.c file when that library is used. diff --git a/src/src/tod.c b/src/src/tod.c index ac4ed35b9..364703d53 100644 --- a/src/src/tod.c +++ b/src/src/tod.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* A function for returning the time of day in various formats */ diff --git a/src/src/transport.c b/src/src/transport.c index ff2e0b1d4..d04ea516a 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* General functions concerned with transportation, and generic options for all transports. */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 18badde86..c39c07c9f 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2020 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/transports/appendfile.h b/src/src/transports/appendfile.h index 108114905..c3b7c59c4 100644 --- a/src/src/transports/appendfile.h +++ b/src/src/transports/appendfile.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index eff1a3792..fa884cec4 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/transports/autoreply.h b/src/src/transports/autoreply.h index 5f278a51e..83061719c 100644 --- a/src/src/transports/autoreply.h +++ b/src/src/transports/autoreply.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index c734c3a26..e04c991ab 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/transports/lmtp.h b/src/src/transports/lmtp.h index 71fd77f26..fe51b18cc 100644 --- a/src/src/transports/lmtp.h +++ b/src/src/transports/lmtp.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index b8103e2f6..c3547eefe 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" diff --git a/src/src/transports/pipe.h b/src/src/transports/pipe.h index 416569608..be5ec3424 100644 --- a/src/src/transports/pipe.h +++ b/src/src/transports/pipe.h @@ -4,7 +4,7 @@ /* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/transports/queuefile.c b/src/src/transports/queuefile.c index 3a2bae22f..b6511133c 100644 --- a/src/src/transports/queuefile.c +++ b/src/src/transports/queuefile.c @@ -6,7 +6,7 @@ /* Copyright (c) University of Cambridge 2016 */ /* Copyright (c) The Exim Maintainers 1995 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/src/src/transports/queuefile.h b/src/src/transports/queuefile.h index 22759a7f7..f5362515b 100644 --- a/src/src/transports/queuefile.h +++ b/src/src/transports/queuefile.h @@ -5,7 +5,7 @@ /* Copyright (c) Andrew Colin Kissa 2016 */ /* Copyright (c) University of Cambridge 2016 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Private structure for the private options. */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 2d2db1b10..1183fa478 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "../exim.h" #include "smtp.h" diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 8793ece4f..cb1d72625 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #define DELIVER_BUFFER_SIZE 4096 diff --git a/src/src/transports/smtp_socks.c b/src/src/transports/smtp_socks.c index 353a69618..22ee74bd8 100644 --- a/src/src/transports/smtp_socks.c +++ b/src/src/transports/smtp_socks.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) Jeremy Harris 2015 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SOCKS version 5 proxy, client-mode */ diff --git a/src/src/transports/tf_maildir.c b/src/src/transports/tf_maildir.c index 925b8fac0..df932b13e 100644 --- a/src/src/transports/tf_maildir.c +++ b/src/src/transports/tf_maildir.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions in support of the use of maildirsize files for handling quotas in maildir directories. Some of the rules are a bit baroque: diff --git a/src/src/transports/tf_maildir.h b/src/src/transports/tf_maildir.h index d314c3203..9f2f0e3f8 100644 --- a/src/src/transports/tf_maildir.h +++ b/src/src/transports/tf_maildir.h @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2021 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Header file for the functions that are used to support the use of maildirsize files for quota handling in maildir directories. */ diff --git a/src/src/tree.c b/src/src/tree.c index e340d986a..13fc28cc2 100644 --- a/src/src/tree.c +++ b/src/src/tree.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2021 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2015 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for maintaining binary balanced trees and some associated functions as well. */ diff --git a/src/src/utf8.c b/src/src/utf8.c index 6604727ff..c05853838 100644 --- a/src/src/utf8.c +++ b/src/src/utf8.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2022 */ /* Copyright (c) Jeremy Harris 2015 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/verify.c b/src/src/verify.c index 3a8914e38..0ca096130 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -5,7 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions concerned with verifying things. The original code for callout caching was contributed by Kevin Fleming (but I hacked it around a bit). */ diff --git a/src/src/version.c b/src/src/version.c index cbaaef24b..2637ee94a 100644 --- a/src/src/version.c +++ b/src/src/version.c @@ -5,7 +5,7 @@ /* Copyright (c) University of Cambridge 1995 - 2009 */ /* Copyright (c) The Exim Maintainers 2010 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Function for setting up the version string. */ diff --git a/src/util/chunking_fixqueue_finalnewlines.pl b/src/util/chunking_fixqueue_finalnewlines.pl index b8ab17bd7..832b6a71f 100755 --- a/src/util/chunking_fixqueue_finalnewlines.pl +++ b/src/util/chunking_fixqueue_finalnewlines.pl @@ -1,5 +1,6 @@ #!/usr/bin/env perl -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later use warnings; use strict; diff --git a/src/util/cramtest.pl b/src/util/cramtest.pl index a6124628b..9fc797ba2 100755 --- a/src/util/cramtest.pl +++ b/src/util/cramtest.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # This script is contributed by Vadim Vygonets to aid in debugging CRAM-MD5 # authentication. diff --git a/src/util/gen_pkcs3.c b/src/util/gen_pkcs3.c index 3ef3110de..c5a4453cb 100644 --- a/src/util/gen_pkcs3.c +++ b/src/util/gen_pkcs3.c @@ -2,7 +2,7 @@ * Copyright (c) The Exim Maintainers 2021 * This is distributed as part of Exim and licensed under the GPL. * See the file "NOTICE" for more details. - * SPDX-License-Identifier: GPL-2.0-only + * SPDX-License-Identifier: GPL-2.0-or-later */ /* Build with: diff --git a/src/util/logargs.sh b/src/util/logargs.sh index 814228d10..782ff8566 100755 --- a/src/util/logargs.sh +++ b/src/util/logargs.sh @@ -1,5 +1,6 @@ #! /bin/sh -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # This script can be interposed between a calling program and another # program, in order to log the arguments which are being used. This can diff --git a/src/util/mkcdb.pl b/src/util/mkcdb.pl index e2b5931e7..3a438182c 100755 --- a/src/util/mkcdb.pl +++ b/src/util/mkcdb.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl -wT -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # # Create cdb file from flat alias file. DPC: 15/10/98. # Args: source (may be relative or absolute) diff --git a/src/util/ocsp_fetch.pl b/src/util/ocsp_fetch.pl index 2afbdbdac..9255311a4 100755 --- a/src/util/ocsp_fetch.pl +++ b/src/util/ocsp_fetch.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # Copyright (C) 2012 Wizards Internet Ltd # License GPLv2: GNU GPL version 2 -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: GPL-2.0-or-later use strict; BEGIN { pop @INC if $INC[-1] eq '.' }; diff --git a/src/util/proxy_protocol_client.pl b/src/util/proxy_protocol_client.pl index 8b4311b64..8253fc4ac 100644 --- a/src/util/proxy_protocol_client.pl +++ b/src/util/proxy_protocol_client.pl @@ -3,7 +3,7 @@ # Copyright (C) 2014 Todd Lyons # License GPLv2: GNU GPL version 2 # -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: GPL-2.0-or-later # # This script emulates a proxy which uses Proxy Protocol to communicate # to a backend server. It should be run from an IP which is configured diff --git a/src/util/ratelimit.pl b/src/util/ratelimit.pl index 2ceeebbfa..ce54fe6c3 100644 --- a/src/util/ratelimit.pl +++ b/src/util/ratelimit.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl -wT -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later use strict; diff --git a/src/util/renew-opendmarc-tlds.sh b/src/util/renew-opendmarc-tlds.sh index 583dc0e40..d626aac37 100755 --- a/src/util/renew-opendmarc-tlds.sh +++ b/src/util/renew-opendmarc-tlds.sh @@ -1,5 +1,6 @@ #!/bin/sh -eu -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # # Short version of this script: # curl -f -o /var/cache/exim/opendmarc.tlds https://publicsuffix.org/list/public_suffix_list.dat diff --git a/src/util/unknownuser.sh b/src/util/unknownuser.sh index 01e617978..a57a84bba 100755 --- a/src/util/unknownuser.sh +++ b/src/util/unknownuser.sh @@ -1,5 +1,6 @@ #! /bin/sh -# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) The Exim Maintainers 2022 +# SPDX-License-Identifier: GPL-2.0-or-later # This is a sample script for demonstrating how to handle unknown users in # a more friendly way than just returning a "user unknown" error. It can commit f5730918ef684baafbd9e606a1d4eb06914563cc Author: Jeremy Harris Date: Mon Aug 15 20:41:56 2022 +0100 tidying diff --git a/src/src/lookups/lf_check_file.c b/src/src/lookups/lf_check_file.c index 5c74816ef..c4c05e44d 100644 --- a/src/src/lookups/lf_check_file.c +++ b/src/src/lookups/lf_check_file.c @@ -45,8 +45,7 @@ lf_check_file(int fd, const uschar * filename, int s_type, int modemask, { struct stat statbuf; -if ((fd >= 0 && fstat(fd, &statbuf) != 0) || - (fd < 0 && Ustat(filename, &statbuf) != 0)) +if ((fd < 0 ? Ustat(filename, &statbuf) : fstat(fd, &statbuf)) != 0) { int save_errno = errno; *errmsg = string_sprintf("%s: stat failed", filename); @@ -80,7 +79,7 @@ if ((statbuf.st_mode & modemask) != 0) return +1; } -if (owners != NULL) +if (owners) { BOOL uid_ok = FALSE; for (int i = 1; i <= (int)owners[0]; i++) @@ -94,7 +93,7 @@ if (owners != NULL) } } -if (owngroups != NULL) +if (owngroups) { BOOL gid_ok = FALSE; for (int i = 1; i <= (int)owngroups[0]; i++) diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 703a0a4ca..69387a3a7 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2743,25 +2743,25 @@ exim_gnutls_state_st * state = gnutls_session_get_ptr(session); if ((cert_list = gnutls_certificate_get_peers(session, &cert_list_size))) while (cert_list_size--) - { - if ((rc = import_cert(&cert_list[cert_list_size], &crt)) != GNUTLS_E_SUCCESS) { - DEBUG(D_tls) debug_printf("TLS: peer cert problem: depth %d: %s\n", - cert_list_size, gnutls_strerror(rc)); - break; - } + if ((rc = import_cert(&cert_list[cert_list_size], &crt)) != GNUTLS_E_SUCCESS) + { + DEBUG(D_tls) debug_printf("TLS: peer cert problem: depth %d: %s\n", + cert_list_size, gnutls_strerror(rc)); + break; + } - state->tlsp->peercert = crt; - if ((yield = event_raise(state->event_action, - US"tls:cert", string_sprintf("%d", cert_list_size), &errno))) - { - log_write(0, LOG_MAIN, - "SSL verify denied by event-action: depth=%d: %s", - cert_list_size, yield); - return 1; /* reject */ + state->tlsp->peercert = crt; + if ((yield = event_raise(state->event_action, + US"tls:cert", string_sprintf("%d", cert_list_size), &errno))) + { + log_write(0, LOG_MAIN, + "SSL verify denied by event-action: depth=%d: %s", + cert_list_size, yield); + return 1; /* reject */ + } + state->tlsp->peercert = NULL; } - state->tlsp->peercert = NULL; - } return 0; } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 2b3f02712..eabe34f31 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2530,6 +2530,8 @@ if (!(bs = OCSP_response_get1_basic(rsp))) DEBUG(D_tls) bp = BIO_new(BIO_s_mem()); /* Use the CA & chain that verified the server cert to verify the stapled info */ + /*XXX could we do an event here, for observability of ocsp? What reasonable data could we give access to? */ + /* Dates would be a start. Do we need another opaque variable type, as for certs, plus an extract expansion? */ { /* If this routine is not available, we've avoided [in tls_client_start()] diff --git a/src/src/verify.c b/src/src/verify.c index 0ca096130..125df8d91 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1056,6 +1056,8 @@ no_conn: HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n"); } #ifndef DISABLE_DKIM + /* DKIM signing needs to add a header after seeing the whole body, so we cannot just copy + body bytes to the outbound as they are received, which is the intent of cutthrough. */ if (ob->dkim.dkim_domain) { cutthrough.delivery= FALSE; commit 340e5f5781abb5388c41fa326d6e1cabf7ba96ff Author: Jeremy Harris Date: Tue Nov 29 15:02:01 2022 +0000 Tweak debug output diff --git a/src/src/retry.c b/src/src/retry.c index f073af665..a34bf80ca 100644 --- a/src/src/retry.c +++ b/src/src/retry.c @@ -135,7 +135,7 @@ dbdata_retry * host_retry_record, * message_retry_record; *retry_host_key = *retry_message_key = NULL; -DEBUG(D_transport|D_retry) debug_printf("checking status of %s\n", host->name); +DEBUG(D_transport|D_retry) debug_printf("checking retry status of %s\n", host->name); /* Do nothing if status already set; otherwise initialize status as usable. */ commit fc37f2acaaa440c5265dc01fd693d8f5406f5cf9 Author: Jeremy Harris Date: Tue Nov 29 15:55:05 2022 +0000 Add predefined macros for expansions diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index 4e1f61a26..a290b90b0 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -111,8 +111,8 @@ MACRO_HSRC = macro_predef.h os.h globals.h config.h macros.h \ routers/redirect.h OBJ_MACRO = macro_predef.o \ - macro-globals.o macro-readconf.o macro-route.o macro-transport.o macro-drtables.o \ - macro-acl.o macro-tls.o \ + macro-globals.o macro-readconf.o macro-expand.o macro-route.o \ + macro-transport.o macro-drtables.o macro-acl.o macro-tls.o \ macro-appendfile.o macro-autoreply.o macro-lmtp.o macro-pipe.o macro-queuefile.o \ macro-smtp.o macro-accept.o macro-dnslookup.o macro-ipliteral.o macro-iplookup.o \ macro-manualroute.o macro-queryprogram.o macro-redirect.o \ @@ -131,6 +131,9 @@ macro-globals.o : globals.c macro-readconf.o : readconf.c @echo "$(CC) -DMACRO_PREDEF readconf.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ readconf.c +macro-expand.o : expand.c + @echo "$(CC) -DMACRO_PREDEF expand.c" + $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ expand.c macro-route.o : route.c @echo "$(CC) -DMACRO_PREDEF route.c" $(FE)$(CC) -c $(CFLAGS) -DMACRO_PREDEF $(INCLUDE) -o $@ route.c diff --git a/src/src/expand.c b/src/src/expand.c index 657cf3cb9..6def3c102 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -13,6 +13,10 @@ #include "exim.h" +#ifdef MACRO_PREDEF +# include "macro_predef.h" +#endif + typedef unsigned esi_flags; #define ESI_NOFLAGS 0 #define ESI_BRACE_ENDS BIT(0) /* expansion should stop at } */ @@ -831,6 +835,76 @@ static var_entry var_table[] = { }; static int var_table_size = nelem(var_table); + +#ifdef MACRO_PREDEF + +/* dummies */ +uschar * fn_arc_domains(void) {return NULL;} +uschar * fn_hdrs_added(void) {return NULL;} +uschar * fn_queue_size(void) {return NULL;} +uschar * fn_recipients(void) {return NULL;} +uschar * sender_helo_verified_boolstr(void) {return NULL;} +uschar * smtp_cmd_hist(void) {return NULL;} + + + +static void +expansion_items(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(item_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_ITEM_%T", item_table[i]); + builtin_macro_create(buf); + } +} +static void +expansion_operators(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(op_table_underscore); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_underscore[i]); + builtin_macro_create(buf); + } +for (int i = 0; i < nelem(op_table_main); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_main[i]); + builtin_macro_create(buf); + } +} +static void +expansion_conditions(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(cond_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_COND_%T", cond_table[i]); + builtin_macro_create(buf); + } +} +static void +expansion_variables(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(var_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_VAR_%T", var_table[i].name); + builtin_macro_create(buf); + } +} + +void +expansions(void) +{ +expansion_items(); +expansion_operators(); +expansion_conditions(); +expansion_variables(); +} + +#else /*!MACRO_PREDEF*/ + static uschar var_buffer[256]; static BOOL malformed_header; @@ -8861,8 +8935,9 @@ search_tidyup(); return 0; } -#endif +#endif /*STAND_ALONE*/ +#endif /*!MACRO_PREDEF*/ /* vi: aw ai sw=2 */ /* End of expand.c */ diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index 618c914dc..0053cb245 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -338,6 +338,7 @@ printf("#include \"exim.h\"\n"); features(); exp_features(); options(); +expansions(); params(); printf("macro_item * macros = &p%d;\n", mp_index-1); diff --git a/src/src/macro_predef.h b/src/src/macro_predef.h index 8b7b375c6..94f68dfa3 100644 --- a/src/src/macro_predef.h +++ b/src/src/macro_predef.h @@ -22,6 +22,7 @@ extern void options_routers(void); extern void options_transports(void); extern void options_auths(void); extern void options_logging(void); +extern void expansions(void); extern void params_dkim(void); #ifndef DISABLE_TLS extern void options_tls(void); commit 2484a8253df7795a45fb5b4aff6df0bf0e4d56e5 Author: Jeremy Harris Date: Tue Nov 29 14:34:25 2022 +0000 Add variable $sender_helo_verified diff --git a/src/src/acl.c b/src/src/acl.c index 143890668..8e1d92457 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1643,6 +1643,30 @@ return period; +static BOOL +sender_helo_verified_internal(void) +{ +/* We can test the result of optional HELO verification that might have +occurred earlier. If not, we can attempt the verification now. */ + +if (!f.helo_verified && !f.helo_verify_failed) smtp_verify_helo(); +return f.helo_verified; +} + +static int +sender_helo_verified_cond(void) +{ +return sender_helo_verified_internal() ? OK : FAIL; +} + +uschar * +sender_helo_verified_boolstr(void) +{ +return sender_helo_verified_internal() ? US"yes" : US"no"; +} + + + /* This function implements the "verify" condition. It is called when encountered in any ACL, because some tests are almost always permitted. Some just don't make sense, and always fail (for example, an attempt to test a host @@ -1739,11 +1763,7 @@ switch(vp->value) return FAIL; case VERIFY_HELO: - /* We can test the result of optional HELO verification that might have - occurred earlier. If not, we can attempt the verification now. */ - - if (!f.helo_verified && !f.helo_verify_failed) smtp_verify_helo(); - return f.helo_verified ? OK : FAIL; + return sender_helo_verified_cond(); case VERIFY_CSA: /* Do Client SMTP Authorization checks in a separate function, and turn the diff --git a/src/src/expand.c b/src/src/expand.c index 6def3c102..57ad76f77 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -715,6 +715,7 @@ static var_entry var_table[] = { { "sender_fullhost", vtype_stringptr, &sender_fullhost }, { "sender_helo_dnssec", vtype_bool, &sender_helo_dnssec }, { "sender_helo_name", vtype_stringptr, &sender_helo_name }, + { "sender_helo_verified",vtype_string_func, (void *) &sender_helo_verified_boolstr }, { "sender_host_address", vtype_stringptr, &sender_host_address }, { "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated }, { "sender_host_dnssec", vtype_bool, &sender_host_dnssec }, diff --git a/src/src/functions.h b/src/src/functions.h index a2c8976e8..3ca346c04 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -489,6 +489,7 @@ extern int search_findtype_partial(const uschar *, int *, const uschar **, i int *, const uschar **); extern void *search_open(const uschar *, int, int, uid_t *, gid_t *); extern void search_tidyup(void); +extern uschar *sender_helo_verified_boolstr(void); extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2); extern void sha1_end(hctx *, const uschar *, int, uschar *); extern void sha1_mid(hctx *, const uschar *); commit e8297f953ed9c8e42f1b406b5ecad4ccdd9d95d3 Author: Jeremy Harris Date: Sat Dec 3 15:16:48 2022 +0000 tidying diff --git a/src/src/log.c b/src/src/log.c index 6c483216a..a01e9c59f 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -1544,6 +1544,7 @@ else DEBUG(D_deliver) void debug_logging_stop(BOOL kill) { +debug_printf("debug terminated by %s\n", kill ? "kill" : "stop"); debug_pretrigger_discard(); if (!debug_file || !debuglog_name[0]) return; diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index eabe34f31..db77a1274 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -3999,7 +3999,7 @@ if (tlsp->host_resumable) tls_error(US"set ex_data", host, NULL, errstr); return FALSE; } - debug_printf("tls_exdata_idx %d cbinfo %p\n", tls_exdata_idx, client_static_state); + /* debug_printf("tls_exdata_idx %d cbinfo %p\n", tls_exdata_idx, client_static_state); */ } tlsp->resumption = RESUME_SUPPORTED; diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 1183fa478..ed5f83b3e 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -990,7 +990,7 @@ return FALSE; /* Return an auths bitmap for the set of AUTH methods offered by the server -which match our authenticators. */ +which match our client-side authenticators. */ static unsigned short study_ehlo_auths(smtp_context * sx) @@ -1016,7 +1016,7 @@ for (au = auths, authnum = 0; au; au = au->next, authnum++) if (au->client) } DEBUG(D_transport) - debug_printf("server offers %s AUTH, methods '%s', bitmap 0x%04x\n", + debug_printf("server offers %s AUTH, methods '%s', usable-bitmap 0x%04x\n", tls_out.active.sock >= 0 ? "crypted" : "plaintext", names, authbits); if (tls_out.active.sock >= 0) commit 0da41dc541d0f2536f9d2afc7188e9dfb97b0c09 Author: Jeremy Harris Date: Sat Dec 3 17:50:17 2022 +0000 compiler quietening diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index feeea0e41..ba77c98c2 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -1470,27 +1470,20 @@ t = quoted = store_get_quoted(len + count + 1, s, idx); /* Handle plain quote_ldap */ if (!dn) - { - while ((c = *s++)) - { + for (; c = *s++; *t++ = c) if (!isalnum(c)) { if (Ustrchr(LDAP_QUOTE, c) != NULL) { sprintf(CS t, "%%5C%02X", c); /* e.g. * => %5C2A */ t += 5; - continue; } - if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ + else if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ { sprintf(CS t, "%%%02X", c); t += 3; - continue; } } - *t++ = c; /* unquoted character */ - } - } /* Handle quote_ldap_dn */ @@ -1520,8 +1513,8 @@ else { if (Ustrchr(LDAP_DN_QUOTE, c) != NULL) { - Ustrncpy(t, US"%5C", 3); /* insert \ where needed */ - t += 3; /* fall through to check URL */ + Ustrcpy(t, US"%5C"); /* insert \ where needed */ + t += 3; /* fall through to check URL */ } if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ { @@ -1535,9 +1528,9 @@ else /* Handle the trailing spaces */ - while (*ss++ != 0) + while (*ss++) { - Ustrncpy(t, US"%5C%20", 6); + Ustrcpy(t, US"%5C%20"); t += 6; } } commit 44b6e099b76f403a55e77650821f8a69e9d2682e Author: Jeremy Harris Date: Sat Dec 3 23:13:53 2022 +0000 Fix ${run } arg parsing Broken-by: cfe6acff2ddc diff --git a/src/src/expand.c b/src/src/expand.c index 57ad76f77..7bb2e4274 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -5614,7 +5614,7 @@ while (*s) const uschar * arg, ** argv; BOOL late_expand = TRUE; - if ((expand_forbid & RDO_RUN) != 0) + if (expand_forbid & RDO_RUN) { expand_string_message = US"running a command is not permitted"; goto EXPAND_FAILED; @@ -5645,13 +5645,20 @@ while (*s) s++; if (late_expand) /* this is the default case */ - { /*{*/ - int n = Ustrcspn(s, "}"); + { + int n; + const uschar * t; + /* Locate the end of the args */ + (void) expand_string_internal(s, + ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | ESI_SKIPPING, &t, NULL, NULL); + n = t - s; arg = flags & ESI_SKIPPING ? NULL : string_copyn(s, n); s += n; } else { + DEBUG(D_expand) + debug_printf_indent("args string for ${run} expand before split\n"); if (!(arg = expand_string_internal(s, ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, &s, &resetok, NULL))) goto EXPAND_FAILED; diff --git a/src/src/transport.c b/src/src/transport.c index d04ea516a..d6cedf911 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -2190,6 +2190,8 @@ if (expand_arguments) for (int i = 0; argv[i]; i++) { + DEBUG(D_expand) debug_printf_indent("arg %d\n", i); + /* Handle special fudge for passing an address list */ if (addr && @@ -2364,7 +2366,7 @@ if (expand_arguments) return FALSE; } - if ( f.running_in_test_harness && is_tainted(expanded_arg) + if ( f.running_in_test_harness && is_tainted(expanded_arg) && Ustrcmp(etext, "queryprogram router") == 0) { /* hack, would be good to not need it */ DEBUG(D_transport) commit 4243a209fd9499f30bebd58ceaa2d0d9845407ae Author: Jeremy Harris Date: Sat Dec 10 10:47:05 2022 +0000 Move connect ACL before TLS-on-connect diff --git a/src/src/EDITME b/src/src/EDITME index 625df18f5..4fcaeda5b 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -401,7 +401,7 @@ TRANSPORT_SMTP=yes # For Redis you need to have hiredis installed on your system # (https://github.com/redis/hiredis). # Depending on where it is installed you may have to edit the CFLAGS -# (often += -I/usr/local/include) and LDFLAGS (-lhiredis) lines. +# (often += -I/usr/local/include) and LOOKUP_LIBS (-lhiredis) lines. # If your system has pkg-config then the _INCLUDE/_LIBS setting can be # handled for you automatically by also defining the _PC variable to reference diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 9b60702c1..b161f362d 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2505,6 +2505,22 @@ else DEBUG(D_receive) #endif +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); +} + + /************************************************* * Start an SMTP session * *************************************************/ @@ -2857,7 +2873,10 @@ if (!f.sender_host_unknown) { log_write(L_connection_reject, LOG_MAIN|LOG_REJECT, "refused connection " "from %s (host_reject_connection)", host_and_ident(FALSE)); - smtp_printf("554 SMTP service not available\r\n", FALSE); +#ifndef DISABLE_TLS + if (!tls_in.on_connect) +#endif + smtp_printf("554 SMTP service not available\r\n", FALSE); return FALSE; } @@ -2983,18 +3002,6 @@ if (check_proxy_protocol_host()) setup_proxy_protocol_host(); #endif -/* Start up TLS if tls_on_connect is set. This is for supporting the legacy -smtps port for use with older style SSL MTAs. */ - -#ifndef DISABLE_TLS -if (tls_in.on_connect) - { - if (tls_server_start(&user_msg) != OK) - return smtp_log_tls_fail(user_msg); - cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE; - } -#endif - /* Run the connect ACL if it exists */ user_msg = NULL; @@ -3004,11 +3011,28 @@ if (acl_smtp_connect) if ((rc = acl_check(ACL_WHERE_CONNECT, NULL, acl_smtp_connect, &user_msg, &log_msg)) != OK) { - (void) smtp_handle_acl_fail(ACL_WHERE_CONNECT, rc, user_msg, log_msg); +#ifndef DISABLE_TLS + if (tls_in.on_connect) + log_connect_tls_drop(US"'connect' ACL", log_msg); + else +#endif + (void) smtp_handle_acl_fail(ACL_WHERE_CONNECT, rc, user_msg, log_msg); return FALSE; } } +/* Start up TLS if tls_on_connect is set. This is for supporting the legacy +smtps port for use with older style SSL MTAs. */ + +#ifndef DISABLE_TLS +if (tls_in.on_connect) + { + if (tls_server_start(&user_msg) != OK) + return smtp_log_tls_fail(user_msg); + cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE; + } +#endif + /* Output the initial message for a two-way SMTP connection. It may contain newlines, which then cause a multi-line response to be given. */ commit 4f7a93c27e3d43b44c42d3fc503f03b9b42ca622 Author: Jeremy Harris Date: Sat Dec 10 16:19:16 2022 +0000 Allow a forced-fail for banner expansion to close connection without panic-log diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index b161f362d..6c043d434 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3040,13 +3040,7 @@ code = US"220"; /* Default status code */ esc = US""; /* Default extended status code */ esclen = 0; /* Length of esc */ -if (!user_msg) - { - if (!(s = expand_string(smtp_banner))) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Expansion of \"%s\" (smtp_banner) " - "failed: %s", smtp_banner, expand_string_message); - } -else +if (user_msg) { int codelen = 3; s = user_msg; @@ -3057,6 +3051,17 @@ else esclen = codelen - 4; } } +else if (!(s = expand_string(smtp_banner))) + { + log_write(0, f.expand_string_forcedfail ? LOG_MAIN : LOG_MAIN|LOG_PANIC_DIE, + "Expansion of \"%s\" (smtp_banner) failed: %s", + smtp_banner, expand_string_message); + /* for force-fail */ +#ifndef DISABLE_TLS + if (tls_in.on_connect) tls_close(NULL, TLS_SHUTDOWN_WAIT); +#endif + return FALSE; + } /* Remove any terminating newlines; might as well remove trailing space too */ commit 520ef00f56cea3d35688bf4e13599a6e37ba275f Author: Jeremy Harris Date: Sun Dec 11 15:14:54 2022 +0000 TLS: Fix handling for server cert/key file SNI re-expansion forced-fail diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 69387a3a7..f8cc34406 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -398,7 +398,8 @@ tls_error_gnu(exim_gnutls_state_st * state, const uschar *prefix, int err, { return tls_error(prefix, state && err == GNUTLS_E_FATAL_ALERT_RECEIVED - ? US gnutls_alert_get_name(gnutls_alert_get(state->session)) + ? string_sprintf("rxd alert: %s", + US gnutls_alert_get_name(gnutls_alert_get(state->session))) : US gnutls_strerror(err), state ? state->host : NULL, errstr); @@ -1293,7 +1294,7 @@ while (cfile = string_nextinlist(&clist, &csep, NULL, 0)) if (!(kfile = string_nextinlist(&klist, &ksep, NULL, 0))) return tls_error(US"cert/key setup: out of keys", NULL, NULL, errstr); - else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) > 0) + else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) != OK) return rc; else { @@ -1810,8 +1811,13 @@ D-H generation. */ if (!state->lib_state.conn_certs) { - if (!Expand_check_tlsvar(tls_certificate, errstr)) + if ( !Expand_check_tlsvar(tls_certificate, errstr) + || f.expand_string_forcedfail) + { + if (f.expand_string_forcedfail) + *errstr = US"expansion of tls_certificate failed"; return DEFER; + } /* certificate is mandatory in server, optional in client */ @@ -1823,8 +1829,14 @@ if (!state->lib_state.conn_certs) else DEBUG(D_tls) debug_printf("TLS: no client certificate specified; okay\n"); - if (state->tls_privatekey && !Expand_check_tlsvar(tls_privatekey, errstr)) + if ( state->tls_privatekey && !Expand_check_tlsvar(tls_privatekey, errstr) + || f.expand_string_forcedfail + ) + { + if (f.expand_string_forcedfail) + *errstr = US"expansion of tls_privatekey failed"; return DEFER; + } /* tls_privatekey is optional, defaulting to same file as certificate */ @@ -1866,7 +1878,11 @@ if (!state->lib_state.conn_certs) tls_ocsp_file, #endif errstr) - ) ) return rc; + ) ) + { + DEBUG(D_tls) debug_printf("load-cert: '%s'\n", *errstr); + return rc; + } } } else @@ -2710,11 +2726,12 @@ if ((rc = tls_expand_session_files(state, &dummy_errstr)) != OK) { /* If the setup of certs/etc failed before handshake, TLS would not have been offered. The best we can do now is abort. */ - return GNUTLS_E_APPLICATION_ERROR_MIN; + DEBUG(D_tls) debug_printf("expansion for SNI-dependent session files failed\n"); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } rc = tls_set_remaining_x509(state, &dummy_errstr); -if (rc != OK) return GNUTLS_E_APPLICATION_ERROR_MIN; +if (rc != OK) return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; return 0; } diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index db77a1274..3b060cc9c 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1553,8 +1553,13 @@ else ) ) reexpand_tls_files_for_sni = TRUE; - if (!expand_check(state->certificate, US"tls_certificate", &expanded, errstr)) + if ( !expand_check(state->certificate, US"tls_certificate", &expanded, errstr) + || f.expand_string_forcedfail) + { + if (f.expand_string_forcedfail) + *errstr = US"expansion of tls_certificate failed"; return DEFER; + } if (expanded) if (state->is_server) @@ -1622,9 +1627,14 @@ else if ((err = tls_add_certfile(sctx, state, expanded, errstr))) return err; - if ( state->privatekey - && !expand_check(state->privatekey, US"tls_privatekey", &expanded, errstr)) + if ( state->privatekey + && !expand_check(state->privatekey, US"tls_privatekey", &expanded, errstr) + || f.expand_string_forcedfail) + { + if (f.expand_string_forcedfail) + *errstr = US"expansion of tls_privatekey failed"; return DEFER; + } /* If expansion was forced to fail, key_expanded will be NULL. If the result of the expansion is an empty string, ignore it also, and assume the private @@ -2201,13 +2211,13 @@ per https://www.openssl.org/docs/manmaster/man3/SSL_client_hello_cb_fn.html #ifdef EXIM_HAVE_OPENSSL_TLSEXT static int -tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg) +tls_servername_cb(SSL * s, int * ad ARG_UNUSED, void * arg) { -const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); -exim_openssl_state_st *state = (exim_openssl_state_st *) arg; +const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); +exim_openssl_state_st * state = (exim_openssl_state_st *) arg; int rc; int old_pool = store_pool; -uschar * dummy_errstr; +uschar * errstr; if (!servername) return SSL_TLSEXT_ERR_OK; @@ -2227,7 +2237,7 @@ if (!reexpand_tls_files_for_sni) not confident that memcpy wouldn't break some internal reference counting. Especially since there's a references struct member, which would be off. */ -if (lib_ctx_new(&server_sni, NULL, &dummy_errstr) != OK) +if (lib_ctx_new(&server_sni, NULL, &errstr) != OK) goto bad; /* Not sure how many of these are actually needed, since SSL object @@ -2247,8 +2257,8 @@ already exists. Might even need this selfsame callback, for reneg? */ SSL_CTX_set_tlsext_servername_arg(server_sni, state); } -if ( !init_dh(server_sni, state->dhparam, &dummy_errstr) - || !init_ecdh(server_sni, &dummy_errstr) +if ( !init_dh(server_sni, state->dhparam, &errstr) + || !init_ecdh(server_sni, &errstr) ) goto bad; @@ -2267,7 +2277,7 @@ if (state->u_ocsp.server.file) { uschar * v_certs = tls_verify_certificates; if ((rc = setup_certs(server_sni, &v_certs, tls_crl, NULL, - &dummy_errstr)) != OK) + &errstr)) != OK) goto bad; if (v_certs && *v_certs) @@ -2276,14 +2286,16 @@ if (state->u_ocsp.server.file) /* do this after setup_certs, because this can require the certs for verifying OCSP information. */ -if ((rc = tls_expand_session_files(server_sni, state, &dummy_errstr)) != OK) +if ((rc = tls_expand_session_files(server_sni, state, &errstr)) != OK) goto bad; DEBUG(D_tls) debug_printf("Switching SSL context.\n"); SSL_set_SSL_CTX(s, server_sni); return SSL_TLSEXT_ERR_OK; -bad: return SSL_TLSEXT_ERR_ALERT_FATAL; +bad: + log_write(0, LOG_MAIN|LOG_PANIC, "%s", errstr); + return SSL_TLSEXT_ERR_ALERT_FATAL; } #endif /* EXIM_HAVE_OPENSSL_TLSEXT */ commit 60b8e1d8c24d1ab487134d8b5fb1e8523f786c33 Author: Jeremy Harris Date: Sat Nov 12 20:13:32 2022 +0000 tidying diff --git a/src/src/daemon.c b/src/src/daemon.c index be008c3d4..05ef3bfdd 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1258,10 +1258,14 @@ if (sz >= sizeof(buf)) return FALSE; #ifdef notdef debug_printf("addrlen %d\n", msg.msg_namelen); #endif -DEBUG(D_queue_run) debug_printf("%s from addr '%s%.*s'\n", __FUNCTION__, - *sa_un.sun_path ? "" : "@", - (int)msg.msg_namelen - (*sa_un.sun_path ? 0 : 1), - sa_un.sun_path + (*sa_un.sun_path ? 0 : 1)); +DEBUG(D_queue_run) + if (msg.msg_namelen > 0) + debug_printf("%s from addr '%s%.*s'\n", __FUNCTION__, + *sa_un.sun_path ? "" : "@", + (int)msg.msg_namelen - (*sa_un.sun_path ? 0 : 1), + sa_un.sun_path + (*sa_un.sun_path ? 0 : 1)); + else + debug_printf("%s (from unknown addr)\n", __FUNCTION__); /* Refuse to handle the item unless the peer has good credentials */ #ifdef SCM_CREDENTIALS diff --git a/src/src/expand.c b/src/src/expand.c index 7bb2e4274..62b4a1890 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -4853,11 +4853,11 @@ while (*s) switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* If skipping, we don't actually do anything */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /*XXX no skipping-optimisation? */ yield = string_append(yield, 3, US"Authentication-Results: ", sub_arg[0], US"; none"); @@ -4944,7 +4944,6 @@ while (*s) case 2: case 3: goto EXPAND_FAILED; } - /*XXX no skipping-optimisation? */ if (!sub_arg[1]) /* One argument */ { @@ -5439,15 +5438,12 @@ while (*s) switch(read_subs(sub_arg, 2, 1, &s, flags, TRUE, name, &resetok, NULL)) { + case -1: continue; /* If skipping, we don't actually do anything */ case 1: goto EXPAND_FAILED_CURLY; case 2: case 3: goto EXPAND_FAILED; } - /* If skipping, we don't actually do anything */ - - if (flags & ESI_SKIPPING) continue; - /* Open the file and read it */ if (!(f = Ufopen(sub_arg[0], "rb"))) @@ -6327,6 +6323,7 @@ while (*s) save_expand_strings(save_expand_nstring, save_expand_nlength); /* Read the field & list arguments */ + /*XXX Could we use read_subs here (and get better efficiency for skipping)? */ for (int i = 0; i < 2; i++) { commit 419ad98ed05e32ccbf1a05549984017e8f0bd79a Author: Jeremy Harris Date: Tue Dec 13 13:38:53 2022 +0000 GnuTLS: fix cert loading Broken-by: 520ef00f56ce diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index f8cc34406..729fb5879 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -379,7 +379,7 @@ Argument: the connected host if setting up a client errstr pointer to returned error string -Returns: OK/DEFER/FAIL +Returns: DEFER/FAIL */ static int @@ -392,6 +392,7 @@ return host ? FAIL : DEFER; } +/* Returns: DEFER/FAIL */ static int tls_error_gnu(exim_gnutls_state_st * state, const uschar *prefix, int err, uschar ** errstr) @@ -1271,6 +1272,7 @@ DEBUG(D_tls) debug_printf("TLS: basic cred init, %s\n", server ? "server" : "client"); } +/* Returns OK/DEFER/FAIL */ static int creds_load_server_certs(exim_gnutls_state_st * state, const uschar * cert, const uschar * pkey, const uschar * ocsp, uschar ** errstr) @@ -1294,7 +1296,7 @@ while (cfile = string_nextinlist(&clist, &csep, NULL, 0)) if (!(kfile = string_nextinlist(&klist, &ksep, NULL, 0))) return tls_error(US"cert/key setup: out of keys", NULL, NULL, errstr); - else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) != OK) + else if ((rc = tls_add_certfile(state, NULL, cfile, kfile, errstr)) > OK) return rc; else { @@ -1372,7 +1374,7 @@ while (cfile = string_nextinlist(&clist, &csep, NULL, 0)) } #endif /* DISABLE_OCSP */ } -return 0; +return OK; } static int @@ -1382,7 +1384,7 @@ creds_load_client_certs(exim_gnutls_state_st * state, const host_item * host, int rc = tls_add_certfile(state, host, cert, pkey, errstr); if (rc > 0) return rc; DEBUG(D_tls) debug_printf("TLS: cert/key registered\n"); -return 0; +return OK; } static int commit 85f4056d71b45977bf269c7e595386647538d14b Author: Jeremy Harris Date: Tue Dec 13 15:46:01 2022 +0000 ACL: Permit the "encrypted" condition to be used in a HELO/EHLO ACL diff --git a/src/src/acl.c b/src/src/acl.c index 8e1d92457..74b59b0fe 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -223,7 +223,7 @@ static condition_def conditions[] = { }, [ACLC_ENCRYPTED] = { US"encrypted", FALSE, FALSE, ACL_BIT_NOTSMTP | ACL_BIT_NOTSMTP_START | - ACL_BIT_HELO, + ACL_BIT_CONNECT }, [ACLC_ENDPASS] = { US"endpass", TRUE, TRUE, 0 }, commit 5fd353d843a09c53c6767cbc89671a751b719555 Author: Jeremy Harris Date: Sat Dec 17 16:20:19 2022 +0000 Add template lines for alternate DBM libraries, in the teplate Makefile diff --git a/src/src/EDITME b/src/src/EDITME index 4fcaeda5b..6344561d6 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -647,6 +647,29 @@ DISABLE_MAL_MKS=yes # understand these issues, go with the defaults, which are used by many sites. +#------------------------------------------------------------------------------ +# Which DBM library to use. If you do not specify a specific here, you get +# the platform default. Uncomment the pair of lines as preferred. +# Note: when changing an installation from one DB type to another all the +# hints-DB files, in spool/db, should be removed. + +# gdbm in native mode +# USE_GDBM = yes +# DBMLIB = -lgdbm + +# gdbm in Berkeley-DB compatibility mode +# USE_NDBM = yes +# DBMLIB = -lgdbm -lgdbm_compat + +# tdb +# USE_TDB = yes +# DBMLIB = -ltdb + +# Berkeley DB +# USE_DB = yes +# DBMLIB = -ldb + + #------------------------------------------------------------------------------ # Although Exim is normally a setuid program, owned by root, it refuses to run # local deliveries as root by default. There is a runtime option called commit 1ed24e36e279c922d3366f6c3144570cc5f54d7a Author: Jeremy Harris Date: Mon Dec 19 21:09:17 2022 +0000 Fix logging of max-size log line Broken-by: d12746bc15d8 diff --git a/src/src/log.c b/src/src/log.c index a01e9c59f..d11b933f9 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -806,7 +806,7 @@ log_write(unsigned int selector, int flags, const char *format, ...) { int paniclogfd; ssize_t written_len; -gstring gs = { .size = LOG_BUFFER_SIZE-1, .ptr = 0, .s = log_buffer }; +gstring gs = { .size = LOG_BUFFER_SIZE-2, .ptr = 0, .s = log_buffer }; gstring * g; va_list ap; @@ -952,11 +952,10 @@ DEBUG(D_any|D_v) } va_end(ap); - g->size = LOG_BUFFER_SIZE; g = string_catn(g, US"\n", 1); debug_printf("%s", string_from_gstring(g)); - gs.size = LOG_BUFFER_SIZE-1; /* Having used the buffer for debug output, */ + gs.size = LOG_BUFFER_SIZE-2; /* Having used the buffer for debug output, */ gs.ptr = 0; /* reset it for the real use. */ gs.s = log_buffer; } @@ -1038,6 +1037,8 @@ if ( flags & LOG_RECIPIENTS } } +/* actual size, now we are placing the newline (and space for NUL) */ +gs.size = LOG_BUFFER_SIZE; g = string_catn(g, US"\n", 1); string_from_gstring(g); commit d439520cf2ccd61b0a2190bb331b1dded18547b8 Author: Jeremy Harris Date: Tue Dec 20 14:38:26 2022 +0000 cppcheck sliencing diff --git a/src/src/acl.c b/src/src/acl.c index 74b59b0fe..5ab674776 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -2550,6 +2550,7 @@ else switch(mode) anchor = NULL; /* silence an "unused" complaint */ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "internal ACL error: unknown ratelimit mode %d", mode); + /*NOTREACHED*/ break; } diff --git a/src/src/deliver.c b/src/src/deliver.c index c4fce4602..c5e00eaef 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -342,13 +342,7 @@ if (Ustrstr(filename, US"/../")) for (int i = 2; i > 0; i--) { int fd = Uopen(filename, -#ifdef O_CLOEXEC - O_CLOEXEC | -#endif -#ifdef O_NOFOLLOW - O_NOFOLLOW | -#endif - O_WRONLY|O_APPEND|O_CREAT, mode); + EXIM_CLOEXEC | EXIM_NOFOLLOW | O_WRONLY|O_APPEND|O_CREAT, mode); if (fd >= 0) { /* Set the close-on-exec flag and change the owner to the exim uid/gid (this @@ -4705,17 +4699,13 @@ all pipes, so I do not see a reason to use non-blocking IO here { uschar * fname = spool_fname(US"input", message_subdir, message_id, US"-D"); - if ((deliver_datafile = Uopen(fname, -#ifdef O_CLOEXEC - O_CLOEXEC | -#endif - O_RDWR | O_APPEND, 0)) < 0) + if ( (deliver_datafile = Uopen(fname, EXIM_CLOEXEC | O_RDWR | O_APPEND, 0)) + < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to reopen %s for remote " "parallel delivery: %s", fname, strerror(errno)); } - /* Set the close-on-exec flag */ -#ifndef O_CLOEXEC +#ifndef O_CLOEXEC /* Set the close-on-exec flag */ (void)fcntl(deliver_datafile, F_SETFD, fcntl(deliver_datafile, F_GETFD) | FD_CLOEXEC); #endif @@ -5749,14 +5739,8 @@ Otherwise it might be needed again. */ uschar * fname = spool_fname(US"input", message_subdir, id, US"-J"); FILE * jread; - if ( (journal_fd = Uopen(fname, O_RDWR|O_APPEND -#ifdef O_CLOEXEC - | O_CLOEXEC -#endif -#ifdef O_NOFOLLOW - | O_NOFOLLOW -#endif - , SPOOL_MODE)) >= 0 + if ( (journal_fd = Uopen(fname, + O_RDWR|O_APPEND | EXIM_CLOEXEC | EXIM_NOFOLLOW, SPOOL_MODE)) >= 0 && lseek(journal_fd, 0, SEEK_SET) == 0 && (jread = fdopen(journal_fd, "rb")) ) @@ -7154,10 +7138,7 @@ if (addr_local || addr_remote) uschar * fname = spool_fname(US"input", message_subdir, id, US"-J"); if ((journal_fd = Uopen(fname, -#ifdef O_CLOEXEC - O_CLOEXEC | -#endif - O_WRONLY|O_APPEND|O_CREAT|O_EXCL, SPOOL_MODE)) < 0) + EXIM_CLOEXEC | O_WRONLY|O_APPEND|O_CREAT|O_EXCL, SPOOL_MODE)) < 0) { log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't open journal file %s: %s", fname, strerror(errno)); diff --git a/src/src/exim.c b/src/src/exim.c index 35f4ae4f7..dc082f392 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -841,6 +841,7 @@ exim_fail(const char * fmt, ...) va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); +va_end(ap); exit(EXIT_FAILURE); } @@ -1224,13 +1225,11 @@ DEBUG(D_any) #if defined(__clang__) g = string_fmt_append(g, "Compiler: CLang [%s]\n", __clang_version__); #elif defined(__GNUC__) - g = string_fmt_append(g, "Compiler: GCC [%s]\n", # ifdef __VERSION__ - __VERSION__ + g = string_fmt_append(g, "Compiler: GCC [%s]\n", __VERSION__); # else - "? unknown version ?" + g = string_fmt_append(g, "Compiler: GCC [%s]\n", "? unknown version ?"; # endif - ); #else g = string_cat(g, US"Compiler: \n"); #endif diff --git a/src/src/hash.c b/src/src/hash.c index 10af1b43d..95860fc50 100644 --- a/src/src/hash.c +++ b/src/src/hash.c @@ -408,7 +408,7 @@ Returns: nothing */ static void -native_sha1_end(sha1 *base, const uschar *text, int length, uschar *digest) +native_sha1_end(sha1 * base, const uschar * text, int length, uschar * digest) { uschar work[64]; @@ -426,7 +426,7 @@ out to 64, process it, and then set up the final chunk as 56 bytes of padding. If it has less than 56 bytes, we pad it out to 56 bytes as the final chunk. */ -memcpy(work, text, length); +if (length) memcpy(work, text, length); work[length] = 0x80; if (length > 55) diff --git a/src/src/host.c b/src/src/host.c index ecdc6d681..8d53eb3de 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -912,7 +912,7 @@ Returns: the number of ints used */ int -host_aton(const uschar *address, int *bin) +host_aton(const uschar * address, int * bin) { int x[4]; int v4offset = 0; @@ -924,13 +924,10 @@ supported. */ if (Ustrchr(address, ':') != NULL) { - const uschar *p = address; - const uschar *component[8]; + const uschar * p = address; + const uschar * component[8]; BOOL ipv4_ends = FALSE; - int ci = 0; - int nulloffset = 0; - int v6count = 8; - int i; + int ci = 0, nulloffset = 0, v6count = 8, i; /* If the address starts with a colon, it will start with two colons. Just lose the first one, which will leave a null first component. */ @@ -942,7 +939,7 @@ if (Ustrchr(address, ':') != NULL) overlooked; to guard against that happening again, check here and crash if there are too many components. */ - while (*p != 0 && *p != '%') + while (*p && *p != '%') { int len = Ustrcspn(p, ":%"); if (len == 0) nulloffset = ci; diff --git a/src/src/macros.h b/src/src/macros.h index 243c1e5a0..a631877a1 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1125,4 +1125,15 @@ typedef unsigned mcs_flags; #define MCS_AT_SPECIAL BIT(2) /* recognize @, @[], etc. */ #define MCS_CACHEABLE BIT(3) /* no dynamic expansions used for pattern */ +/* Flags for open() */ +#ifdef O_CLOEXEC +# define EXIM_CLOEXEC O_CLOEXEC +#else +# define EXIM_CLOEXEC 0 +#endif +#ifdef O_NOFOLLOW +# define EXIM_NOFOLLOW O_NOFOLLOW +#else +# define EXIM_NOFOLLOW 0 +#endif /* End of macros.h */ diff --git a/src/src/os.c b/src/src/os.c index fc29f1766..87a336935 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -11,6 +11,8 @@ # include # include # include +#else +# define DEBUG(x) if (debug_selector & (x)) #endif #ifndef CS @@ -50,9 +52,9 @@ sigemptyset(&(act.sa_mask)); act.sa_flags = SA_RESTART; sigaction(sig, &act, NULL); -#ifdef STAND_ALONE +# ifdef STAND_ALONE printf("Used SA_RESTART\n"); -#endif +# endif /* SunOS4 and Ultrix default to non-interruptable signals, with SV_INTERRUPT for making them interruptable. This seems to be a dying fashion. */ @@ -60,9 +62,9 @@ for making them interruptable. This seems to be a dying fashion. */ #elif defined SV_INTERRUPT signal(sig, handler); -#ifdef STAND_ALONE +# ifdef STAND_ALONE printf("Used default signal()\n"); -#endif +# endif /* If neither SA_RESTART nor SV_INTERRUPT is available we don't know how to @@ -71,9 +73,9 @@ set up a restarting signal, so simply suppress the facility. */ #else signal(sig, SIG_IGN); -#ifdef STAND_ALONE +# ifdef STAND_ALONE printf("Used SIG_IGN\n"); -#endif +# endif #endif } @@ -361,9 +363,9 @@ here as there is the -hal variant, and other systems might follow this road one day. */ #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_KSTAT) -#define OS_LOAD_AVERAGE +# define OS_LOAD_AVERAGE -#include +# include int os_getloadavg(void) @@ -397,7 +399,7 @@ return avg; #if !defined(OS_LOAD_AVERAGE) && defined(HAVE_DEV_KMEM) #define OS_LOAD_AVERAGE -#include +# include static int avg_kd = -1; static long avg_offset; @@ -481,7 +483,7 @@ Returns: a chain of ip_address_items, each pointing to a textual #ifdef HAVE_GETIFADDRS -#include +# include ip_address_item * os_common_find_running_interfaces(void) @@ -630,13 +632,13 @@ what we want to know. */ if ((vs = socket(FAMILY, SOCK_DGRAM, 0)) < 0) { - #if HAVE_IPV6 +#if HAVE_IPV6 DEBUG(D_interface) debug_printf("Unable to create IPv6 socket to find interface addresses:\n " "error %d %s\nTrying for an IPv4 socket\n", errno, strerror(errno)); vs = socket(AF_INET, SOCK_DGRAM, 0); if (vs < 0) - #endif +#endif log_write(0, LOG_PANIC_DIE, "Unable to create IPv4 socket to find interface " "addresses: %d %s", errno, strerror(errno)); } @@ -816,7 +818,7 @@ programmer creates their own structs. */ #if !defined(OS_GET_DNS_RESOLVER_RES) && !defined(COMPILE_UTILITY) -#include +# include /* confirmed that res_state is typedef'd as a struct* on BSD and Linux, will find out how unportable it is on other OSes, but most resolver implementations diff --git a/src/src/retry.c b/src/src/retry.c index a34bf80ca..1897c782f 100644 --- a/src/src/retry.c +++ b/src/src/retry.c @@ -518,8 +518,8 @@ Returns: nothing */ void -retry_update(address_item **addr_defer, address_item **addr_failed, - address_item **addr_succeed) +retry_update(address_item ** addr_defer, address_item ** addr_failed, + address_item ** addr_succeed) { open_db dbblock; open_db *dbm_file = NULL; @@ -533,11 +533,10 @@ to the failed chain if they have timed out. */ for (int i = 0; i < 3; i++) { - address_item *endaddr, *addr; - address_item *last_first = NULL; - address_item **paddr = i==0 ? addr_succeed : - i==1 ? addr_failed : addr_defer; - address_item **saved_paddr = NULL; + address_item * endaddr, *addr; + address_item * last_first = NULL; + address_item ** paddr = i==0 ? addr_succeed : i==1 ? addr_failed : addr_defer; + address_item ** saved_paddr = NULL; DEBUG(D_retry) debug_printf("%s addresses:\n", i == 0 ? "Succeeded" : i == 1 ? "Failed" : "Deferred"); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 6c043d434..1cfcc0404 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2680,32 +2680,32 @@ if (!f.sender_host_unknown) #if !HAVE_IPV6 && !defined(NO_IP_OPTIONS) - #ifdef GLIBC_IP_OPTIONS - #if (!defined __GLIBC__) || (__GLIBC__ < 2) - #define OPTSTYLE 1 - #else - #define OPTSTYLE 2 - #endif - #elif defined DARWIN_IP_OPTIONS - #define OPTSTYLE 2 - #else - #define OPTSTYLE 3 - #endif +# ifdef GLIBC_IP_OPTIONS +# if (!defined __GLIBC__) || (__GLIBC__ < 2) +# define OPTSTYLE 1 +# else +# define OPTSTYLE 2 +# endif +# elif defined DARWIN_IP_OPTIONS +# define OPTSTYLE 2 +# else +# define OPTSTYLE 3 +# endif if (!host_checking && !f.sender_host_notsocket) { - #if OPTSTYLE == 1 +# if OPTSTYLE == 1 EXIM_SOCKLEN_T optlen = sizeof(struct ip_options) + MAX_IPOPTLEN; struct ip_options *ipopt = store_get(optlen, GET_UNTAINTED); - #elif OPTSTYLE == 2 +# elif OPTSTYLE == 2 struct ip_opts ipoptblock; struct ip_opts *ipopt = &ipoptblock; EXIM_SOCKLEN_T optlen = sizeof(ipoptblock); - #else +# else struct ipoption ipoptblock; struct ipoption *ipopt = &ipoptblock; EXIM_SOCKLEN_T optlen = sizeof(ipoptblock); - #endif +# endif /* Occasional genuine failures of getsockopt() have been seen - for example, "reset by peer". Therefore, just log and give up on this @@ -2735,19 +2735,19 @@ if (!f.sender_host_unknown) else if (optlen > 0) { - uschar *p = big_buffer; - uschar *pend = big_buffer + big_buffer_size; - uschar *adptr; + uschar * p = big_buffer; + uschar * pend = big_buffer + big_buffer_size; + uschar * adptr; int optcount; struct in_addr addr; - #if OPTSTYLE == 1 - uschar *optstart = US (ipopt->__data); - #elif OPTSTYLE == 2 - uschar *optstart = US (ipopt->ip_opts); - #else - uschar *optstart = US (ipopt->ipopt_list); - #endif +# if OPTSTYLE == 1 + uschar * optstart = US (ipopt->__data); +# elif OPTSTYLE == 2 + uschar * optstart = US (ipopt->ip_opts); +# else + uschar * optstart = US (ipopt->ipopt_list); +# endif DEBUG(D_receive) debug_printf("IP options exist\n"); @@ -2758,59 +2758,65 @@ if (!f.sender_host_unknown) switch (*opt) { case IPOPT_EOL: - opt = NULL; - break; + opt = NULL; + break; case IPOPT_NOP: - opt++; - break; + opt++; + break; case IPOPT_SSRR: case IPOPT_LSRR: - if (!string_format(p, pend-p, " %s [@%s", - (*opt == IPOPT_SSRR)? "SSRR" : "LSRR", - #if OPTSTYLE == 1 - inet_ntoa(*((struct in_addr *)(&(ipopt->faddr)))))) - #elif OPTSTYLE == 2 - inet_ntoa(ipopt->ip_dst))) - #else - inet_ntoa(ipopt->ipopt_dst))) - #endif - { - opt = NULL; - break; - } + if (! +# if OPTSTYLE == 1 + string_format(p, pend-p, " %s [@%s", + (*opt == IPOPT_SSRR)? "SSRR" : "LSRR", + inet_ntoa(*((struct in_addr *)(&(ipopt->faddr))))) +# elif OPTSTYLE == 2 + string_format(p, pend-p, " %s [@%s", + (*opt == IPOPT_SSRR)? "SSRR" : "LSRR", + inet_ntoa(ipopt->ip_dst)) +# else + string_format(p, pend-p, " %s [@%s", + (*opt == IPOPT_SSRR)? "SSRR" : "LSRR", + inet_ntoa(ipopt->ipopt_dst)) +# endif + ) + { + opt = NULL; + break; + } - p += Ustrlen(p); - optcount = (opt[1] - 3) / sizeof(struct in_addr); - adptr = opt + 3; - while (optcount-- > 0) - { - memcpy(&addr, adptr, sizeof(addr)); - if (!string_format(p, pend - p - 1, "%s%s", - (optcount == 0)? ":" : "@", inet_ntoa(addr))) - { - opt = NULL; - break; - } - p += Ustrlen(p); - adptr += sizeof(struct in_addr); - } - *p++ = ']'; - opt += opt[1]; - break; + p += Ustrlen(p); + optcount = (opt[1] - 3) / sizeof(struct in_addr); + adptr = opt + 3; + while (optcount-- > 0) + { + memcpy(&addr, adptr, sizeof(addr)); + if (!string_format(p, pend - p - 1, "%s%s", + (optcount == 0)? ":" : "@", inet_ntoa(addr))) + { + opt = NULL; + break; + } + p += Ustrlen(p); + adptr += sizeof(struct in_addr); + } + *p++ = ']'; + opt += opt[1]; + break; default: - { - if (pend - p < 4 + 3*opt[1]) { opt = NULL; break; } - Ustrcat(p, "[ "); - p += 2; - for (int i = 0; i < opt[1]; i++) - p += sprintf(CS p, "%2.2x ", opt[i]); - *p++ = ']'; - } - opt += opt[1]; - break; + { + if (pend - p < 4 + 3*opt[1]) { opt = NULL; break; } + Ustrcat(p, "[ "); + p += 2; + for (int i = 0; i < opt[1]; i++) + p += sprintf(CS p, "%2.2x ", opt[i]); + *p++ = ']'; + } + opt += opt[1]; + break; } *p = 0; diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 6d6651f57..e785f695b 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -64,13 +64,7 @@ for (int i = 0; i < 2; i++) * No -D file inside the spool area should be a symlink. */ if ((fd = Uopen(fname, -#ifdef O_CLOEXEC - O_CLOEXEC | -#endif -#ifdef O_NOFOLLOW - O_NOFOLLOW | -#endif - O_RDWR | O_APPEND, 0)) >= 0) + EXIM_CLOEXEC | EXIM_NOFOLLOW | O_RDWR | O_APPEND, 0)) >= 0) break; save_errno = errno; if (errno == ENOENT) diff --git a/src/src/string.c b/src/src/string.c index 2cb419517..b30673c04 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1783,7 +1783,7 @@ while (fgets(CS buffer, sizeof(buffer), stdin) != NULL) int llflag = 0; int n = 0; int count; - int countset = 0; + BOOL countset = FASE; uschar format[256]; uschar outbuf[256]; uschar *s; @@ -1825,7 +1825,7 @@ while (fgets(CS buffer, sizeof(buffer), stdin) != NULL) else if (Ustrcmp(ss, "*") == 0) { args[n++] = (void *)(&count); - countset = 1; + countset = TRUE; } else commit c7bec9723a721f566c67df0a526e4de18b723659 Author: Jeremy Harris Date: Sun Dec 18 18:44:54 2022 +0000 Rework "compiler quietening" This partially reverts commit 0da41dc541d0f2536f9d2afc7188e9dfb97b0c09. diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index ba77c98c2..b2ad3bbbc 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -1470,20 +1470,27 @@ t = quoted = store_get_quoted(len + count + 1, s, idx); /* Handle plain quote_ldap */ if (!dn) - for (; c = *s++; *t++ = c) + { + while ((c = *s++)) + { if (!isalnum(c)) { if (Ustrchr(LDAP_QUOTE, c) != NULL) { sprintf(CS t, "%%5C%02X", c); /* e.g. * => %5C2A */ t += 5; + continue; } - else if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ + if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ { sprintf(CS t, "%%%02X", c); t += 3; + continue; } } + *t++ = c; /* unquoted character */ + } + } /* Handle quote_ldap_dn */ @@ -1513,7 +1520,7 @@ else { if (Ustrchr(LDAP_DN_QUOTE, c) != NULL) { - Ustrcpy(t, US"%5C"); /* insert \ where needed */ + memcpy(t, US"%5C", 3); /* insert \ where needed */ t += 3; /* fall through to check URL */ } if (Ustrchr(URL_NONQUOTE, c) == NULL) /* e.g. ] => %5D */ @@ -1530,7 +1537,7 @@ else while (*ss++) { - Ustrcpy(t, US"%5C%20"); + memcpy(t, US"%5C%20", 6); t += 6; } } commit 0762e1a4d6de4b7b0206314302297c9dd6d7ae73 Author: Jeremy Harris Date: Fri Dec 23 18:02:25 2022 +0000 Expand max_rcpt option on smtp transport. Bug 2946 diff --git a/src/src/deliver.c b/src/src/deliver.c index c5e00eaef..ca31df587 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -4290,10 +4290,14 @@ So look out for the place it gets used. } /* Get the maximum it can handle in one envelope, with zero meaning - unlimited, which is forced for the MUA wrapper case. */ - - address_count_max = tp->max_addresses; - if (address_count_max == 0 || mua_wrapper) address_count_max = 999999; + unlimited, which is forced for the MUA wrapper case and if the + value could vary depending on the messages. + For those, we only split (below) by (tpt,dest,erraddr,hdrs) and rely on the + transport splitting further by max_rcp. So we potentially lose some + parallellism. */ + + address_count_max = mua_wrapper || Ustrchr(tp->max_addresses, '$') + ? UNLIMITED_ADDRS : expand_max_rcpt(tp->max_addresses); /************************************************************************/ diff --git a/src/src/functions.h b/src/src/functions.h index 3ca346c04..1817144ea 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1307,6 +1307,14 @@ debug_printf("cmdlog: '%s'\n", client_cmd_log ? client_cmd_log->s : US"(unset)") +static inline int +expand_max_rcpt(const uschar * str_max_rcpt) +{ +const uschar * s = expand_cstring(str_max_rcpt); +int res; +return !s || !*s || (res = Uatoi(s)) == 0 ? UNLIMITED_ADDRS : res; +} + # endif /* !COMPILE_UTILITY */ /******************************************************************************/ @@ -1314,6 +1322,6 @@ debug_printf("cmdlog: '%s'\n", client_cmd_log ? client_cmd_log->s : US"(unset)") #endif /* _FUNCTIONS_H_ */ -/* vi: aw +/* vi: aw ai sw=2 */ /* End of functions.h */ diff --git a/src/src/globals.c b/src/src/globals.c index e5b72592f..efe34902a 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1592,7 +1592,7 @@ transport_instance transport_defaults = { /* All non-mentioned elements zero/NULL/FALSE */ .batch_max = 1, .multi_domain = TRUE, - .max_addresses = 100, + .max_addresses = US"100", .connection_max_messages = 500, .uid = (uid_t)(-1), .gid = (gid_t)(-1), diff --git a/src/src/macros.h b/src/src/macros.h index a631877a1..585067fc9 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1136,4 +1136,8 @@ typedef unsigned mcs_flags; #else # define EXIM_NOFOLLOW 0 #endif + +/* A big number for (effectively) unlimited envelope addresses */ +#define UNLIMITED_ADDRS 999999 + /* End of macros.h */ diff --git a/src/src/structs.h b/src/src/structs.h index e1d93a943..eae66e88d 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -183,7 +183,7 @@ typedef struct transport_instance { uschar *expand_multi_domain; /* ) */ BOOL multi_domain; /* ) */ BOOL overrides_hosts; /* ) Used only for remote transports */ - int max_addresses; /* ) */ + uschar *max_addresses; /* ) */ int connection_max_messages;/* ) */ /**************************************/ BOOL deliver_as_creator; /* Used only by pipe at present */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index ed5f83b3e..c5951832b 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -114,7 +114,7 @@ optionlist smtp_transport_options[] = { { "interface", opt_stringptr, LOFF(interface) }, { "keepalive", opt_bool, LOFF(keepalive) }, { "lmtp_ignore_quota", opt_bool, LOFF(lmtp_ignore_quota) }, - { "max_rcpt", opt_int | opt_public, + { "max_rcpt", opt_stringptr | opt_public, OPT_OFF(transport_instance, max_addresses) }, { "message_linelength_limit", opt_int, LOFF(message_linelength_limit) }, { "multi_domain", opt_expand_bool | opt_public, @@ -2121,8 +2121,9 @@ sx->dane_required = verify_check_given_host(CUSS &ob->hosts_require_dane, sx->conn_args.host) == OK; #endif -if ((sx->max_mail = sx->conn_args.tblock->connection_max_messages) == 0) sx->max_mail = 999999; -if ((sx->max_rcpt = sx->conn_args.tblock->max_addresses) == 0) sx->max_rcpt = 999999; +if ((sx->max_mail = sx->conn_args.tblock->connection_max_messages) == 0) + sx->max_mail = UNLIMITED_ADDRS; +sx->max_rcpt = expand_max_rcpt(sx->conn_args.tblock->max_addresses); sx->igquotstr = US""; if (!sx->helo_data) sx->helo_data = ob->helo_data; @@ -2819,8 +2820,9 @@ if (tls_out.active.sock >= 0) #ifdef EXPERIMMENTAL_ESMTP_LIMITS /* As we are about to send another EHLO, forget any LIMITS received so far. */ sx->peer_limit_mail = sx->peer_limit_rcpt = sx->peer_limit_rcptdom = 0; - if ((sx->max_mail = sx->conn_args.tblock->connection_max_message) == 0) sx->max_mail = 999999; - if ((sx->max_rcpt = sx->conn_args.tblock->max_addresses) == 0) sx->max_rcpt = 999999; + if ((sx->max_mail = sx->conn_args.tblock->connection_max_message) == 0) + sx->max_mail = UNLIMITED_ADDRS; + sx->max_rcpt = expand_max_rcpt(sx->conn_args.tblock->max_addresses); sx->single_rcpt_domain = FALSE; #endif commit 2b7e98456504911562b1b5aca7fa94492bbe5204 Author: Jeremy Harris Date: Sun Dec 25 21:05:42 2022 +0000 FreeBSD: fix notifier socket use diff --git a/src/src/daemon.c b/src/src/daemon.c index 05ef3bfdd..d3fec42ee 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -45,6 +45,9 @@ static smtp_slot *smtp_slots = NULL; static BOOL write_pid = TRUE; +#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS +static uschar * notifier_socket_name; +#endif /************************************************* @@ -129,15 +132,14 @@ if (smtp_out) smtp_printf("421 %s\r\n", FALSE, smtp_msg); /************************************************* *************************************************/ -#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS static void unlink_notifier_socket(void) { -uschar * s = expand_string(notifier_socket); -DEBUG(D_any) debug_printf("unlinking notifier socket %s\n", s); -Uunlink(s); -} +#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS +DEBUG(D_any) debug_printf("unlinking notifier socket %s\n", notifier_socket_name); +Uunlink(notifier_socket_name); #endif +} static void @@ -148,9 +150,6 @@ if (daemon_notifier_fd >= 0) { (void) close(daemon_notifier_fd); daemon_notifier_fd = -1; -#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS - unlink_notifier_socket(); -#endif } for (int i = 0; i < listen_socket_count; i++) (void) close(fd_polls[i].fd); @@ -1105,9 +1104,7 @@ if (daemon_notifier_fd >= 0) { close(daemon_notifier_fd); daemon_notifier_fd = -1; -#ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS unlink_notifier_socket(); -#endif } if (f.running_in_test_harness || write_pid) @@ -1143,7 +1140,7 @@ return offsetof(struct sockaddr_un, sun_path) + 1 #else *sname = string_sprintf("%s/p_%d", spool_directory, getpid()); return offsetof(struct sockaddr_un, sun_path) - + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", sname); + + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", CS *sname); #endif } @@ -1154,11 +1151,12 @@ daemon_notifier_sockname(struct sockaddr_un * sup) sup->sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */ return offsetof(struct sockaddr_un, sun_path) + 1 + snprintf(sup->sun_path+1, sizeof(sup->sun_path)-1, "%s", - expand_string(notifier_socket)); + CS expand_string(notifier_socket)); #else +notifier_socket_name = expand_string(notifier_socket); return offsetof(struct sockaddr_un, sun_path) + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", - expand_string(notifier_socket)); + CS notifier_socket_name); #endif } @@ -1260,10 +1258,17 @@ debug_printf("addrlen %d\n", msg.msg_namelen); #endif DEBUG(D_queue_run) if (msg.msg_namelen > 0) - debug_printf("%s from addr '%s%.*s'\n", __FUNCTION__, - *sa_un.sun_path ? "" : "@", - (int)msg.msg_namelen - (*sa_un.sun_path ? 0 : 1), - sa_un.sun_path + (*sa_un.sun_path ? 0 : 1)); + { + BOOL abstract = !*sa_un.sun_path; + char * name = sa_un.sun_path + (abstract ? 1 : 0); + int namelen = (int)msg.msg_namelen - abstract ? 1 : 0; + if (*name) + debug_printf("%s from addr '%s%.*s'\n", __FUNCTION__, + abstract ? "@" : "", + namelen, name); + else + debug_printf("%s (from unknown addr)\n", __FUNCTION__); + } else debug_printf("%s (from unknown addr)\n", __FUNCTION__); @@ -2673,6 +2678,7 @@ for (;;) log_write(0, LOG_MAIN, "pid %d: SIGHUP received: re-exec daemon", getpid()); close_daemon_sockets(daemon_notifier_fd, fd_polls, listen_socket_count); + unlink_notifier_socket(); ALARM_CLR(0); signal(SIGHUP, SIG_IGN); sighup_argv[0] = exim_path; commit 1d38781da934809e6ce0b8c3718c4b3bccdfe1d2 Author: Jeremy Harris Date: Wed Dec 28 19:39:06 2022 +0000 Fix recursion on dns_again_means_nonexist. Bug 2911 diff --git a/src/src/dns.c b/src/src/dns.c index 4e01d8661..2355409ec 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -802,6 +802,7 @@ dns_basic_lookup(dns_answer * dnsa, const uschar * name, int type) int rc; #ifndef STAND_ALONE const uschar * save_domain; +static BOOL try_again_recursion = FALSE; #endif /* DNS lookup failures of any kind are cached in a tree. This is mainly so that @@ -906,11 +907,22 @@ if (dnsa->answerlen < 0) switch (h_errno) /* Cut this out for various test programs */ #ifndef STAND_ALONE + if (try_again_recursion) + { + log_write(0, LOG_MAIN|LOG_PANIC, + "dns_again_means_nonexist recursion seen for %s (assuming nonexist)", + name); + return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH); + } + + try_again_recursion = TRUE; save_domain = deliver_domain; deliver_domain = string_copy(name); /* set $domain */ rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL); deliver_domain = save_domain; + try_again_recursion = FALSE; + if (rc != OK) { DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n"); commit 6fc54bd18aa7a51e11dce5a905e754cedb526230 Author: Jeremy Harris Date: Thu Dec 29 00:50:50 2022 +0000 Debug: list searching diff --git a/src/src/match.c b/src/src/match.c index 15209f84a..91a49c0f0 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -430,9 +430,9 @@ int yield = OK; unsigned int * original_cache_bits = *cache_ptr; BOOL include_unknown = FALSE, ignore_unknown = FALSE, include_defer = FALSE, ignore_defer = FALSE; -const uschar *list; -uschar *sss; -uschar *ot = NULL; +const uschar * list; +uschar * sss; +uschar * ot = NULL; BOOL textonly_re; /* Save time by not scanning for the option name when we don't need it. */ @@ -514,6 +514,11 @@ HDEBUG(D_any) if (!ot) gstring_release_unused(g); ot = string_from_gstring(g); } +HDEBUG(D_lists) + { + debug_printf_indent("%s\n", ot); + expand_level++; + } /* Now scan the list and process each item in turn, until one of them matches, or we hit an error. */ @@ -522,6 +527,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) { uschar * ss = sss; + HDEBUG(D_lists) debug_printf_indent("list element: %s\n", ss); + /* Address lists may contain +caseful, to restore caseful matching of the local part. We have to know the layout of the control block, unfortunately. The lower cased address is in a temporary buffer, so we just copy the local @@ -605,14 +612,15 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) { if (*ss == '+' && anchorptr) { - int bits = 0; - int offset = 0; - int shift = 0; - unsigned int *use_cache_bits = original_cache_bits; - uschar *cached = US""; - namedlist_block *nb; + int bits = 0, offset = 0, shift = 0; + unsigned int * use_cache_bits = original_cache_bits; + uschar * cached = US""; + namedlist_block * nb; tree_node * t; + DEBUG(D_lists) + { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; } + if (!(t = tree_search(*anchorptr, ss+1))) { log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"", @@ -621,7 +629,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) type == MCL_ADDRESS ? " address" : type == MCL_LOCALPART ? " local part" : "", ss); - return DEFER; + goto DEFER_RETURN; } nb = t->data.ptr; @@ -645,8 +653,12 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) if (bits == 0) { - switch (match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits, - func, arg, type, name, valueptr)) + int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits, + func, arg, type, name, valueptr); + DEBUG(D_lists) + { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); } + + switch (res) { case OK: bits = 1; break; case FAIL: bits = 3; break; @@ -695,8 +707,12 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) else { - DEBUG(D_lists) debug_printf_indent("cached %s match for %s\n", - (bits & (-bits)) == bits ? "yes" : "no", ss); + DEBUG(D_lists) + { + expand_level -= 2; + debug_printf_indent("cached %s match for %s\n", + (bits & (-bits)) == bits ? "yes" : "no", ss); + } cached = US" - cached"; if (valueptr) @@ -720,7 +736,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) { HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\"%s)\n", ot, yield == OK ? "yes" : "no", sss, cached); - return yield; + goto YIELD_RETURN; } } @@ -734,7 +750,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) case OK: HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot, (yield == OK)? "yes" : "no", sss); - return yield; + goto YIELD_RETURN; case DEFER: if (!error) @@ -852,7 +868,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) Copy it to allocated memory now we know it matched. */ if (valueptr) *valueptr = string_copy(ss); - return file_yield; + yield = file_yield; + goto YIELD_RETURN; case DEFER: if (!error) @@ -864,12 +881,10 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) break; } (void)fclose(f); - if (include_defer) - { - log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error); - return OK; - } - goto DEFER_RETURN; + if (!include_defer) + goto DEFER_RETURN; + 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) */ @@ -886,10 +901,10 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) { if (LOGGING(unknown_in_list)) log_write(0, LOG_MAIN, "list matching forced to fail: %s", error); - return FAIL; + goto FAIL_RETURN; } log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error); - return OK; + goto OK_RETURN; } } } @@ -905,14 +920,33 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) /* End of list reached: if the last item was negated yield OK, else FAIL. */ HDEBUG(D_lists) - debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes"); -return yield == OK ? FAIL : OK; + HDEBUG(D_lists) + { + expand_level--; + debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes"); + } + return yield == OK ? FAIL : OK; /* Something deferred */ DEFER_RETURN: -HDEBUG(D_lists) debug_printf("%s list match deferred for %s\n", ot, sss); -return DEFER; + HDEBUG(D_lists) + { + expand_level--; + debug_printf_indent("%s list match deferred for %s\n", ot, sss); + } + return DEFER; + +FAIL_RETURN: + yield = FAIL; + goto YIELD_RETURN; + +OK_RETURN: + yield = OK; + +YIELD_RETURN: + HDEBUG(D_lists) expand_level--; + return yield; } commit caf28f95ce0a617b075cf66e24a0e4b0b8aaf18e Author: Jeremy Harris Date: Thu Dec 29 17:14:31 2022 +0000 Debug: quieten environment-cleaning diff --git a/src/src/environment.c b/src/src/environment.c index 68adf3c0c..b05b1aefd 100644 --- a/src/src/environment.c +++ b/src/src/environment.c @@ -4,6 +4,7 @@ /* Copyright (c) Heiko Schlittermann 2016 * hs@schlittermann.de + * Copyright (c) The Exim Maintainers 2022 * See the file NOTICE for conditions of use and distribution. * SPDX-License-Identifier: GPL-2.0-or-later */ @@ -25,10 +26,7 @@ Returns: TRUE if successful BOOL cleanup_environment() { -int old_pool = store_pool; -store_pool = POOL_PERM; /* Need perm memory for any created env vars */ - -if (!keep_environment || *keep_environment == '\0') +if (!keep_environment || !*keep_environment) { /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55 Try to clear the environment. @@ -43,6 +41,11 @@ if (!keep_environment || *keep_environment == '\0') else if (Ustrcmp(keep_environment, "*") != 0) { rmark reset_point = store_mark(); + unsigned deb = debug_selector; + BOOL hc = host_checking; + debug_selector = 0; /* quieten this clearout */ + host_checking = FALSE; + if (environ) for (uschar ** p = USS environ; *p; /* see below */) { /* It's considered broken if we do not find the '=', according to @@ -54,31 +57,42 @@ else if (Ustrcmp(keep_environment, "*") != 0) { uschar * name = string_copyn(*p, eqp - *p); - if (OK != match_isinlist(name, CUSS &keep_environment, - 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL)) - if (os_unsetenv(name) < 0) return FALSE; - else p = USS environ; /* RESTART from the beginning */ - else p++; + if (match_isinlist(name, CUSS &keep_environment, + 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL) == OK) + p++; /* next */ + else if (os_unsetenv(name) == 0) + p = USS environ; /* RESTART from the beginning */ + else + { debug_selector = deb; host_checking = hc; return FALSE; } } } + debug_selector = deb; + host_checking = hc; store_reset(reset_point); } +DEBUG(D_expand) + { + debug_printf("environment after trimming:\n"); + if (environ) for (uschar ** p = USS environ; *p; p++) + debug_printf(" %s\n", *p); + } if (add_environment) { - uschar * p; int sep = 0; const uschar * envlist = add_environment; + int old_pool = store_pool; + store_pool = POOL_PERM; /* Need perm memory for any created env vars */ - while ((p = string_nextinlist(&envlist, &sep, NULL, 0))) + for (const uschar * p; p = string_nextinlist(&envlist, &sep, NULL, 0); ) { DEBUG(D_expand) debug_printf("adding %s\n", p); putenv(CS p); } + store_pool = old_pool; } #ifndef DISABLE_TLS tls_clean_env(); #endif -store_pool = old_pool; return TRUE; } commit 5281dce92f37ab268bfa781e384d64dc5947203f Author: Jeremy Harris Date: Fri Dec 30 18:53:51 2022 +0000 FreeBSD: fix listener-socket backlog monitoring diff --git a/src/src/daemon.c b/src/src/daemon.c index d3fec42ee..05d94b188 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -2553,7 +2553,19 @@ for (;;) if (p->revents & POLLIN) { EXIM_SOCKLEN_T alen = sizeof(accepted); -#ifdef TCP_INFO +#if defined(__FreeBSD__) && defined(SO_LISTENQLEN) + int backlog; + socklen_t blen = sizeof(backlog); + + if ( smtp_backlog_monitor > 0 + && getsockopt(p->fd, SOL_SOCKET, SO_LISTENQLEN, &backlog, &blen) == 0) + { + DEBUG(D_interface) + debug_printf("listen fd %d queue curr %d\n", p->fd, backlog); + smtp_listen_backlog = backlog; + } + +#elif defined(TCP_INFO) && defined(EXIM_HAVE_TCPI_UNACKED) struct tcp_info ti; socklen_t tlen = sizeof(ti); @@ -2563,15 +2575,9 @@ for (;;) if ( smtp_backlog_monitor > 0 && getsockopt(p->fd, IPPROTO_TCP, TCP_INFO, &ti, &tlen) == 0) { -# ifdef EXIM_HAVE_TCPI_UNACKED DEBUG(D_interface) debug_printf("listen fd %d queue max %u curr %u\n", p->fd, ti.tcpi_sacked, ti.tcpi_unacked); smtp_listen_backlog = ti.tcpi_unacked; -# elif defined(__FreeBSD__) /* This does not work. Investigate kernel sourcecode. */ - DEBUG(D_interface) debug_printf("listen fd %d queue max %u curr %u\n", - p->fd, ti.__tcpi_sacked, ti.__tcpi_unacked); - smtp_listen_backlog = ti.__tcpi_unacked; -# endif } #endif p->revents = 0; commit 57d70161718e02927a22d6a3481803b72035ac46 Author: Jeremy Harris Date: Sat Dec 31 13:37:17 2022 +0000 Close server smtp socket explicitly on connect ACL "drop" diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 1cfcc0404..6880e3c09 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3565,6 +3565,19 @@ problem, because we get here only if some other ACL has issued "drop", and in that case, *its* custom messages will have been used above. */ smtp_notquit_exit(US"acl-drop", NULL, NULL); + +/* An overenthusiastic fail2ban/iptables implimentation has been seen to result +in the TCP conn staying open, and retrying, despite this process exiting. A +malicious client could possibly do the same, tying up server netowrking +resources. Close the socket explicitly to try to avoid that (there's a note in +the Linux socket(7) manpage, SO_LINGER para, to the effect that exim() without +close() results in the socket always lingering). */ + +(void) poll_one_fd(fileno(smtp_in), POLLIN, 200); +DEBUG(D_any) debug_printf_indent("SMTP(close)>>\n"); +(void) fclose(smtp_in); +(void) fclose(smtp_out); + return 2; } commit 313dcd5968cd8a02995322fa771f4d56b9f15e49 Author: Jeremy Harris Date: Sat Dec 31 18:32:37 2022 +0000 Testsuite: longer timing for OpenSSL resumption tests diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 3b060cc9c..ae0986aac 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -155,6 +155,7 @@ change this guard and punt the issue for a while longer. */ # endif #endif +#define TESTSUITE_TICKET_LIFE 10 /* seconds */ /************************************************* * OpenSSL option parse * *************************************************/ @@ -2044,7 +2045,7 @@ if (exim_tk.name[0]) exim_tk_old = exim_tk; } -if (f.running_in_test_harness) ssl_session_timeout = 6; +if (f.running_in_test_harness) ssl_session_timeout = TESTSUITE_TICKET_LIFE; DEBUG(D_tls) debug_printf("OpenSSL: %s STEK\n", exim_tk.name[0] ? "rotating" : "creating"); if (RAND_bytes(exim_tk.aes_key, sizeof(exim_tk.aes_key)) <= 0) return; @@ -3908,16 +3909,17 @@ if (tlsp->host_resumable) #ifdef EXIM_HAVE_SESSION_TICKET SSL_SESSION_get_ticket_lifetime_hint(ss); #else /* Use, fairly arbitrilarily, what we as server would */ - f.running_in_test_harness ? 6 : ssl_session_timeout; + f.running_in_test_harness ? TESTSUITE_TICKET_LIFE : ssl_session_timeout; #endif - if (lifetime + dt->time_stamp < time(NULL)) + time_t now = time(NULL), expires = lifetime + dt->time_stamp; + if (expires < now) { - DEBUG(D_tls) debug_printf("session expired\n"); + DEBUG(D_tls) debug_printf("session expired (by " TIME_T_FMT "s from %lus)\n", now - expires, lifetime); dbfn_delete(dbm_file, tlsp->resume_index); } else if (SSL_set_session(ssl, ss)) { - DEBUG(D_tls) debug_printf("good session\n"); + DEBUG(D_tls) debug_printf("good session (" TIME_T_FMT "s left of %lus)\n", expires - now, lifetime); tlsp->resumption |= RESUME_CLIENT_SUGGESTED; tlsp->verify_override = dt->verify_override; tlsp->ocsp = dt->ocsp; commit ca4014de81e6aa367aa0a54c49b4c3d4b137814c Author: Jeremy Harris Date: Sun Jan 1 12:18:38 2023 +0000 OpenSSL: fix tls_eccurve setting explicit curve/group. Bug 2954 diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index ae0986aac..4d0f99ea9 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -676,12 +676,12 @@ if (dh_bitsize <= tls_dh_max_bits) } else DEBUG(D_tls) - debug_printf("Diffie-Hellman initialized from %s with %d-bit prime\n", + debug_printf(" Diffie-Hellman initialized from %s with %d-bit prime\n", dhexpanded ? dhexpanded : US"default", dh_bitsize); } else DEBUG(D_tls) - debug_printf("dhparams '%s' %d bits, is > tls_dh_max_bits limit of %d\n", + debug_printf(" dhparams '%s' %d bits, is > tls_dh_max_bits limit of %d\n", dhexpanded ? dhexpanded : US"default", dh_bitsize, tls_dh_max_bits); #if OPENSSL_VERSION_NUMBER < 0x30000000L @@ -731,19 +731,27 @@ return TRUE; #else uschar * exp_curve; -int nid; -BOOL rv; +int nid, rc; # ifndef EXIM_HAVE_ECDH DEBUG(D_tls) - debug_printf("No OpenSSL API to define ECDH parameters, skipping\n"); + debug_printf(" No OpenSSL API to define ECDH parameters, skipping\n"); return TRUE; # else if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve, errstr)) return FALSE; + +/* Is the option deliberately empty? */ + if (!exp_curve || !*exp_curve) + { +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + DEBUG(D_tls) debug_printf( " ECDH OpenSSL 1.0.2+: clearing curves list\n"); + (void) SSL_CTX_set1_curves(sctx, &nid, 0); +#endif return TRUE; + } /* "auto" needs to be handled carefully. * OpenSSL < 1.0.2: we do not select anything, but fallback to prime256v1 @@ -756,23 +764,22 @@ if (Ustrcmp(exp_curve, "auto") == 0) { #if OPENSSL_VERSION_NUMBER < 0x10002000L DEBUG(D_tls) debug_printf( - "ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n"); + " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n"); exp_curve = US"prime256v1"; #else # if defined SSL_CTRL_SET_ECDH_AUTO DEBUG(D_tls) debug_printf( - "ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n"); + " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n"); SSL_CTX_set_ecdh_auto(sctx, 1); return TRUE; # else DEBUG(D_tls) debug_printf( - "ECDH OpenSSL 1.1.0+: temp key parameter settings: default selection\n"); + " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n"); return TRUE; # endif #endif } -DEBUG(D_tls) debug_printf("ECDH: curve '%s'\n", exp_curve); if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef # ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID && (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef @@ -796,23 +803,23 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef /* The "tmp" in the name here refers to setting a temporary key not to the stability of the interface. */ - if ((rv = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0)) + if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0)) tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), NULL, NULL, errstr); else - DEBUG(D_tls) debug_printf("ECDH: enabled '%s' curve\n", exp_curve); + DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve); EC_KEY_free(ecdh); } #else /* v 3.0.0 + */ -if ((rv = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0) +if ((rc = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0) tls_error(string_sprintf("Error enabling '%s' group", exp_curve), NULL, NULL, errstr); else - DEBUG(D_tls) debug_printf("ECDH: enabled '%s' group\n", exp_curve); + DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group\n", exp_curve); #endif -return !rv; +return !!rc; # endif /*EXIM_HAVE_ECDH*/ #endif /*OPENSSL_NO_ECDH*/ @@ -1746,7 +1753,7 @@ state_server.lib_state.lib_ctx = ctx; if (opt_unset_or_noexpand(tls_dhparam)) { - DEBUG(D_tls) debug_printf("TLS: preloading DH params for server\n"); + DEBUG(D_tls) debug_printf("TLS: preloading DH params '%s' for server\n", tls_dhparam); if (init_dh(ctx, tls_dhparam, &dummy_errstr)) state_server.lib_state.dh = TRUE; } @@ -1754,7 +1761,7 @@ else DEBUG(D_tls) debug_printf("TLS: not preloading DH params for server\n"); if (opt_unset_or_noexpand(tls_eccurve)) { - DEBUG(D_tls) debug_printf("TLS: preloading ECDH curve for server\n"); + DEBUG(D_tls) debug_printf("TLS: preloading ECDH curve '%s' for server\n", tls_eccurve); if (init_ecdh(ctx, &dummy_errstr)) state_server.lib_state.ecdh = TRUE; } commit 7fa5764c203f2f4a900898a79ed02d674075313f Author: Jeremy Harris Date: Mon Jan 2 15:04:14 2023 +0000 OpenSSL: Fix tls_eccurve on earlier versions than 3.0.0. Bug 2954 Broken-by: ca4014de81e6 diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 4d0f99ea9..e063d29bd 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -786,8 +786,9 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef # endif ) { - tls_error(string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve), - NULL, NULL, errstr); + uschar * s = string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve); + DEBUG(D_tls) debug_printf("TLS error '%s'\n", s); + if (errstr) *errstr = s; return FALSE; } @@ -803,7 +804,7 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef /* The "tmp" in the name here refers to setting a temporary key not to the stability of the interface. */ - if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0)) + if ((rc = SSL_CTX_set_tmp_ecdh(sctx, ecdh)) == 0) tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), NULL, NULL, errstr); else DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve); commit e1aca33756f73c22b00a98d40ce2be8ed94464b1 Author: Jeremy Harris Date: Thu Jan 5 13:03:37 2023 +0000 OpenSSL: log conns rejected for bad ALPN, with the offered value Unfortunately, no way to do this under GnuTLS diff --git a/src/src/match.c b/src/src/match.c index 91a49c0f0..07070362d 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -968,6 +968,7 @@ Arguments: s string to search for listptr ptr to ptr to colon separated list of patterns, or NULL sep a separator value for the list (see string_nextinlist()) + or zero for auto anchorptr ptr to tree for named items, or NULL if no named items cache_bits ptr to cache_bits for ditto, or NULL if not caching type MCL_DOMAIN when matching a domain list diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 729fb5879..b47fabf1d 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1119,21 +1119,28 @@ switch (tls_id) /* The format of "data" here doesn't seem to be documented, but appears to be a 2-byte field with a (redundant, given the "size" arg) total length then a sequence of one-byte size then string (not nul-term) names. The - latter is as described in OpenSSL documentation. */ + latter is as described in OpenSSL documentation. + Note that we do not get called for a match_fail, making it hard to log + a single bad ALPN being offered (the common case). */ + { + gstring * g = NULL; DEBUG(D_tls) debug_printf("Seen ALPN extension from client (s=%u):", size); for (const uschar * s = data+2; s-data < size-1; s += *s + 1) { server_seen_alpn++; + g = string_append_listele_n(g, ':', s+1, *s); DEBUG(D_tls) debug_printf(" '%.*s'", (int)*s, s+1); } DEBUG(D_tls) debug_printf("\n"); if (server_seen_alpn > 1) { + log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g)); DEBUG(D_tls) debug_printf("TLS: too many ALPNs presented in handshake\n"); return GNUTLS_E_NO_APPLICATION_PROTOCOL; } break; + } #endif } return 0; diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index e063d29bd..513ba0d3a 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2324,6 +2324,8 @@ static int tls_server_alpn_cb(SSL *ssl, const uschar ** out, uschar * outlen, const uschar * in, unsigned int inlen, void * arg) { +gstring * g = NULL; + server_seen_alpn = TRUE; DEBUG(D_tls) { @@ -2354,12 +2356,19 @@ if ( inlen > 1 /* at least one name */ } } -/* More than one name from clilent, or name did not match our list. */ +/* More than one name from client, or name did not match our list. */ /* This will be fatal to the TLS conn; would be nice to kill TCP also. Maybe as an option in future; for now leave control to the config (must-tls). */ -DEBUG(D_tls) debug_printf("TLS ALPN rejected\n"); +for (int pos = 0, siz; pos < inlen; pos += siz+1) + { + siz = in[pos]; + if (pos + 1 + siz > inlen) siz = inlen - pos - 1; + g = string_append_listele_n(g, ':', in + pos + 1, siz); + } +log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g)); +gstring_release_unused(g); return SSL_TLSEXT_ERR_ALERT_FATAL; } #endif /* EXIM_HAVE_ALPN */ commit 30520c8f87fcf660ed99a2344cae7f9787f7bc89 Author: Jeremy Harris Date: Thu Jan 5 18:39:51 2023 +0000 DANE: do not check dns_again_means_nonexist for TLSA results of TRY_AGAIN diff --git a/src/src/dns.c b/src/src/dns.c index 2355409ec..d39b4b590 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -907,21 +907,30 @@ if (dnsa->answerlen < 0) switch (h_errno) /* Cut this out for various test programs */ #ifndef STAND_ALONE - if (try_again_recursion) + /* Permitting dns_again_means nonexist for TLSA lookups breaks the + doewngrade resistance of dane, so avoid for those. */ + + if (type == T_TLSA) + rc = FAIL; + else { - log_write(0, LOG_MAIN|LOG_PANIC, - "dns_again_means_nonexist recursion seen for %s (assuming nonexist)", - name); - return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH); - } + if (try_again_recursion) + { + log_write(0, LOG_MAIN|LOG_PANIC, + "dns_again_means_nonexist recursion seen for %s" + " (assuming nonexist)", name); + return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), + DNS_NOMATCH); + } - try_again_recursion = TRUE; - save_domain = deliver_domain; - deliver_domain = string_copy(name); /* set $domain */ - rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0, - &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL); - deliver_domain = save_domain; - try_again_recursion = FALSE; + try_again_recursion = TRUE; + save_domain = deliver_domain; + deliver_domain = string_copy(name); /* set $domain */ + rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0, + &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL); + deliver_domain = save_domain; + try_again_recursion = FALSE; + } if (rc != OK) { commit 31c546c4d0c3baf1b1e0ab292b4d096cffe64c34 Author: Jeremy Harris Date: Fri Jan 6 20:50:23 2023 +0000 Debug: show received Proxy Protocol bytes diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 6880e3c09..5d8ffd3d0 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -1187,6 +1187,16 @@ errno = EOVERFLOW; return -1; } + +static void +proxy_debug(uschar * buf, unsigned start, unsigned end) +{ +debug_printf("PROXY<<"); +while (start < end) debug_printf(" %02x", buf[start++]); +debug_printf("\n"); +} + + /************************************************* * Setup host for proxy protocol * *************************************************/ @@ -1263,11 +1273,11 @@ So to safely handle v1 and v2, with client-sent-first supported correctly, we have to do a minimum of 3 read calls, not 1. Eww. */ -#define PROXY_INITIAL_READ 14 -#define PROXY_V2_HEADER_SIZE 16 -#if PROXY_INITIAL_READ > PROXY_V2_HEADER_SIZE -# error Code bug in sizes of data to read for proxy usage -#endif +# define PROXY_INITIAL_READ 14 +# define PROXY_V2_HEADER_SIZE 16 +# if PROXY_INITIAL_READ > PROXY_V2_HEADER_SIZE +# error Code bug in sizes of data to read for proxy usage +# endif int get_ok = 0; int size, ret; @@ -1287,11 +1297,11 @@ do "safe". Can't take it all because TLS-on-connect clients follow immediately with TLS handshake. */ ret = read(fd, &hdr, PROXY_INITIAL_READ); - } - while (ret == -1 && errno == EINTR && !had_command_timeout); + } while (ret == -1 && errno == EINTR && !had_command_timeout); if (ret == -1) goto proxyfail; +DEBUG(D_receive) proxy_debug(US &hdr, 0, ret); /* For v2, handle reading the length, and then the rest. */ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0)) @@ -1299,6 +1309,8 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0)) int retmore; uint8_t ver; + DEBUG(D_receive) debug_printf("v2\n"); + /* First get the length fields. */ do { @@ -1306,6 +1318,8 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0)) } while (retmore == -1 && errno == EINTR && !had_command_timeout); if (retmore == -1) goto proxyfail; + DEBUG(D_receive) proxy_debug(US &hdr, ret, ret + retmore); + ret += retmore; ver = (hdr.v2.ver_cmd & 0xf0) >> 4; @@ -1343,6 +1357,7 @@ if ((ret == PROXY_INITIAL_READ) && (memcmp(&hdr.v2, v2sig, sizeof(v2sig)) == 0)) } while (retmore == -1 && errno == EINTR && !had_command_timeout); if (retmore == -1) goto proxyfail; + DEBUG(D_receive) proxy_debug(US &hdr, ret, ret + retmore); ret += retmore; DEBUG(D_receive) debug_printf("PROXYv2: have %d/%d required octets\n", ret, size); } while (ret < size); @@ -1588,7 +1603,7 @@ bad: ALARM(0); return; } -#endif +#endif /*SUPPORT_PROXY*/ /************************************************* * Read one command line * commit 42f1855e94bd87f98bc6c74255be53ed6d805ba6 Author: Jeremy Harris Date: Sat Jan 7 00:17:08 2023 +0000 OpenSSL: tls_eccurves list support. Bug 2955 diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 513ba0d3a..96be7c4a2 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -122,6 +122,7 @@ change this guard and punt the issue for a while longer. */ # define EXIM_HAVE_OPENSSL_CIPHER_STD_NAME # define EXIM_HAVE_EXP_CHNL_BNGNG # define EXIM_HAVE_OPENSSL_OCSP_RESP_GET0_SIGNER +# define EXIM_HAVE_OPENSSL_SET1_GROUPS # else # define OPENSSL_BAD_SRVR_OURCERT # endif @@ -700,6 +701,41 @@ return TRUE; * Initialize for ECDH * *************************************************/ +/* "auto" needs to be handled carefully. +OpenSSL < 1.0.2: we do not select anything, but fallback to prime256v1 +OpenSSL < 1.1.0: we have to call SSL_CTX_set_ecdh_auto + (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO) +OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection + https://github.com/openssl/openssl/commit/fe6ef2472db933f01b59cad82aa925736935984b + +*/ + +static uschar * +init_ecdh_auto(SSL_CTX * ctx) +{ +#if OPENSSL_VERSION_NUMBER < 0x10002000L +DEBUG(D_tls) debug_printf( + " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n"); +return US"prime256v1"; + +#else +# if defined SSL_CTRL_SET_ECDH_AUTO + +DEBUG(D_tls) debug_printf( + " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n"); +SSL_CTX_set_ecdh_auto(sctx, 1); +return NULL; + +# else + +DEBUG(D_tls) debug_printf( + " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n"); +return NULL; + +# endif +#endif +} + /* Load parameters for ECDH encryption. Server only. For now, we stick to NIST P-256 because: it's simple and easy to configure; @@ -730,72 +766,76 @@ init_ecdh(SSL_CTX * sctx, uschar ** errstr) return TRUE; #else -uschar * exp_curve; -int nid, rc; - # ifndef EXIM_HAVE_ECDH DEBUG(D_tls) debug_printf(" No OpenSSL API to define ECDH parameters, skipping\n"); return TRUE; # else +uschar * exp_curve; +int ngroups, rc, sep; +const uschar * curves_list, * curve; +# ifdef EXIM_HAVE_OPENSSL_SET1_GROUPS +int nids[16]; +# else +int nids[1]; +# endif + if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve, errstr)) return FALSE; /* Is the option deliberately empty? */ if (!exp_curve || !*exp_curve) - { -#if OPENSSL_VERSION_NUMBER >= 0x10002000L - DEBUG(D_tls) debug_printf( " ECDH OpenSSL 1.0.2+: clearing curves list\n"); - (void) SSL_CTX_set1_curves(sctx, &nid, 0); -#endif return TRUE; - } -/* "auto" needs to be handled carefully. - * OpenSSL < 1.0.2: we do not select anything, but fallback to prime256v1 - * OpenSSL < 1.1.0: we have to call SSL_CTX_set_ecdh_auto - * (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO) - * OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection - * https://github.com/openssl/openssl/commit/fe6ef2472db933f01b59cad82aa925736935984b - */ -if (Ustrcmp(exp_curve, "auto") == 0) - { -#if OPENSSL_VERSION_NUMBER < 0x10002000L - DEBUG(D_tls) debug_printf( - " ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n"); - exp_curve = US"prime256v1"; -#else -# if defined SSL_CTRL_SET_ECDH_AUTO - DEBUG(D_tls) debug_printf( - " ECDH OpenSSL 1.0.2+: temp key parameter settings: autoselection\n"); - SSL_CTX_set_ecdh_auto(sctx, 1); - return TRUE; -# else - DEBUG(D_tls) debug_printf( - " ECDH OpenSSL 1.1.0+: temp key parameter settings: library default selection\n"); - return TRUE; -# endif -#endif - } +/* Limit the list to hardwired array size. Drop out if any element is "suto". */ -if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef -# ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID - && (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef -# endif - ) - { - uschar * s = string_sprintf("Unknown curve name tls_eccurve '%s'", exp_curve); - DEBUG(D_tls) debug_printf("TLS error '%s'\n", s); - if (errstr) *errstr = s; - return FALSE; - } +curves_list = exp_curve; +sep = 0; +for (ngroups = 0; + ngroups < nelem(nids) + && (curve = string_nextinlist(&curves_list, &sep, NULL, 0)); + ) + if (Ustrcmp(curve, "auto") == 0) + { + DEBUG(D_tls) if (ngroups > 0) + debug_printf(" tls_eccurve 'auto' item takes precedence\n"); + if ((exp_curve = init_ecdh_auto(sctx))) break; /* have a curve name to set */ + return TRUE; /* all done */ + } + else + ngroups++; -# if OPENSSL_VERSION_NUMBER < 0x30000000L +/* Translate to NIDs */ + +curves_list = exp_curve; +for (ngroups = 0; curve = string_nextinlist(&curves_list, &sep, NULL, 0); + ngroups++) + if ( (nids[ngroups] = OBJ_sn2nid (CCS curve)) == NID_undef +# ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID + && (nids[ngroups] = EC_curve_nist2nid(CCS curve)) == NID_undef +# endif + ) + { + uschar * s = string_sprintf("Unknown curve name in tls_eccurve '%s'", curve); + DEBUG(D_tls) debug_printf("TLS error: %s\n", s); + if (errstr) *errstr = s; + return FALSE; + } + +# ifdef EXIM_HAVE_OPENSSL_SET1_GROUPS +/* Set the groups */ + +if ((rc = SSL_CTX_set1_groups(sctx, nids, ngroups)) == 0) + tls_error(string_sprintf("Error enabling '%s' group(s)", exp_curve), NULL, NULL, errstr); +else + DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group(s)\n", exp_curve); + +# else /* Cannot handle a list; only 1 element nids array */ { EC_KEY * ecdh; - if (!(ecdh = EC_KEY_new_by_curve_name(nid))) + if (!(ecdh = EC_KEY_new_by_curve_name(nids[0]))) { tls_error(US"Unable to create ec curve", NULL, NULL, errstr); return FALSE; @@ -810,15 +850,7 @@ if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' curve\n", exp_curve); EC_KEY_free(ecdh); } - -#else /* v 3.0.0 + */ - -if ((rc = SSL_CTX_set1_groups(sctx, &nid, 1)) == 0) - tls_error(string_sprintf("Error enabling '%s' group", exp_curve), NULL, NULL, errstr); -else - DEBUG(D_tls) debug_printf(" ECDH: enabled '%s' group\n", exp_curve); - -#endif +# endif /*!EXIM_HAVE_OPENSSL_SET1_GROUPS*/ return !!rc; diff --git a/src/src/tls.c b/src/src/tls.c index 4a23aaae9..f7be5293d 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -106,7 +106,8 @@ Returns: TRUE if OK; result may still be NULL after forced failure */ static BOOL -expand_check(const uschar *s, const uschar *name, uschar **result, uschar ** errstr) +expand_check(const uschar * s, const uschar * name, + uschar ** result, uschar ** errstr) { if (!s) *result = NULL; commit fb09cfc3f2b667aa09deef8a0f9933a2e710be8f Author: Jeremy Harris Date: Sat Jan 7 16:15:46 2023 +0000 OpenSSL: fix build for pre-1.1.0 Broken-by: 42f1855e94bd diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 96be7c4a2..10b5f2aa5 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -711,7 +711,7 @@ OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection */ static uschar * -init_ecdh_auto(SSL_CTX * ctx) +init_ecdh_auto(SSL_CTX * sctx) { #if OPENSSL_VERSION_NUMBER < 0x10002000L DEBUG(D_tls) debug_printf( commit d23b36cd691de33b709eae04f6f100272a8081eb Author: Jeremy Harris Date: Sun Jan 15 22:08:48 2023 +0000 tidying diff --git a/src/src/expand.c b/src/src/expand.c index 62b4a1890..2949579c5 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -23,16 +23,18 @@ typedef unsigned esi_flags; #define ESI_HONOR_DOLLAR BIT(1) /* $ is meaningfull */ #define ESI_SKIPPING BIT(2) /* value will not be needed */ +#ifdef STAND_ALONE +# ifndef SUPPORT_CRYPTEQ +# define SUPPORT_CRYPTEQ +# endif +#else + /* Recursively called function */ static uschar *expand_string_internal(const uschar *, esi_flags, const uschar **, BOOL *, BOOL *); static int_eximarith_t expanded_string_integer(const uschar *, BOOL); -#ifdef STAND_ALONE -# ifndef SUPPORT_CRYPTEQ -# define SUPPORT_CRYPTEQ -# endif -#endif +#endif /*!STAND_ALONE*/ #ifdef LOOKUP_LDAP # include "lookups/ldap.h" @@ -835,8 +837,6 @@ static var_entry var_table[] = { { "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients } }; -static int var_table_size = nelem(var_table); - #ifdef MACRO_PREDEF /* dummies */ @@ -1278,7 +1278,7 @@ static var_entry * find_var_ent(uschar * name) { int first = 0; -int last = var_table_size; +int last = nelem(var_table); while (last > first) { @@ -8806,7 +8806,7 @@ for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i]) #endif /* check known-name variables */ -for (var_entry * v = var_table; v < var_table + var_table_size; v++) +for (var_entry * v = var_table; v < var_table + nelem(var_table); v++) if (v->type == vtype_stringptr) assert_variable_notin(US v->name, *(USS v->value), &e); diff --git a/src/src/filter.c b/src/src/filter.c index 530d772b3..d878acb8f 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -671,8 +671,8 @@ for (;;) { // if (toplevel) *saveptr = 0; // else - if (!toplevel) - *error_pointer = string_sprintf("missing \")\" at end of " + if (!toplevel) + *error_pointer = string_sprintf("missing \")\" at end of " "condition near line %d of filter file", line_number); break; } diff --git a/src/src/priv.c b/src/src/priv.c index 3a100cd9e..9305f8b45 100644 --- a/src/src/priv.c +++ b/src/src/priv.c @@ -1,4 +1,4 @@ -/* Copyright (c) The Exim Maintainers 2022 * +/* Copyright (c) The Exim Maintainers 2022 */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "exim.h" diff --git a/src/src/regex_cache.c b/src/src/regex_cache.c index a9b482174..1ca3c96d5 100644 --- a/src/src/regex_cache.c +++ b/src/src/regex_cache.c @@ -239,7 +239,7 @@ regex_at_daemon(const uschar * reqbuf) { const re_req * req = (const re_req *)reqbuf; uschar * errstr; -const pcre2_code * cre; +const pcre2_code * cre = NULL; if (regex_cachesize >= REGEX_CACHESIZE_LIMIT) errstr = US"regex cache size limit reached"; diff --git a/src/src/spool_in.c b/src/src/spool_in.c index e785f695b..1291197de 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -496,15 +496,18 @@ for (;;) if (*var == '(') /* marker for quoted value */ { uschar * s; - int idx; for (s = ++var; *s != ')'; ) s++; #ifndef COMPILE_UTILITY - if ((idx = search_findtype(var, s - var)) < 0) { - DEBUG(D_any) debug_printf("Unrecognised quoter %.*s\n", (int)(s - var), var+1); - goto SPOOL_FORMAT_ERROR; + int idx; + if ((idx = search_findtype(var, s - var)) < 0) + { + DEBUG(D_any) + debug_printf("Unrecognised quoter %.*s\n", (int)(s - var), var+1); + goto SPOOL_FORMAT_ERROR; + } + proto_mem = store_get_quoted(1, GET_TAINTED, idx); } - proto_mem = store_get_quoted(1, GET_TAINTED, idx); #endif /* COMPILE_UTILITY */ var = s + 1; } diff --git a/src/src/tls.c b/src/src/tls.c index f7be5293d..ba7c2de38 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -26,11 +26,6 @@ functions from the OpenSSL or GNU TLS libraries. */ #endif -/* Forward decl. */ -static void tls_client_resmption_key(tls_support *, smtp_connect_args *, - smtp_transport_options_block *); - - #if defined(MACRO_PREDEF) && !defined(DISABLE_TLS) # include "macro_predef.h" # ifdef USE_GNUTLS @@ -459,6 +454,10 @@ tzset(); /************************************************* * Many functions are package-specific * *************************************************/ +/* Forward decl. */ +static void tls_client_resmption_key(tls_support *, smtp_connect_args *, + smtp_transport_options_block *); + #ifdef USE_GNUTLS # include "tls-gnu.c" commit aae673d7db4b26e8c4a8cc3d59fe94de4c47ba16 Author: Jeremy Harris Date: Wed Jan 18 11:34:07 2023 +0000 Logging: Add "D=" to more connection closure log lines. Bug 2434 diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 5d8ffd3d0..04b20d27c 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -333,7 +333,7 @@ Returns: nothing */ static void -incomplete_transaction_log(uschar *what) +incomplete_transaction_log(uschar * what) { if (!sender_address /* No transaction in progress */ || !LOGGING(smtp_incomplete_transaction)) @@ -355,13 +355,21 @@ log_write(L_smtp_incomplete_transaction, LOG_MAIN|LOG_SENDER|LOG_RECIPIENTS, +static void +log_close_event(const uschar * reason) +{ +log_write(L_smtp_connection, LOG_MAIN, "%s D=%s closed %s", + smtp_get_connection_info(), string_timesince(&smtp_connection_start), reason); +} + void smtp_command_timeout_exit(void) { log_write(L_lost_incoming_connection, - LOG_MAIN, "SMTP command timeout on%s connection from %s", - tls_in.active.sock >= 0 ? " TLS" : "", host_and_ident(FALSE)); + LOG_MAIN, "SMTP command timeout on%s connection from %s D=%s", + tls_in.active.sock >= 0 ? " TLS" : "", host_and_ident(FALSE), + string_timesince(&smtp_connection_start)); if (smtp_batched_input) moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */ smtp_notquit_exit(US"command-timeout", US"421", @@ -373,7 +381,7 @@ exim_exit(EXIT_FAILURE); void smtp_command_sigterm_exit(void) { -log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info()); +log_close_event(US"after SIGTERM"); if (smtp_batched_input) moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */ smtp_notquit_exit(US"signal-exit", US"421", @@ -384,9 +392,10 @@ exim_exit(EXIT_FAILURE); void smtp_data_timeout_exit(void) { -log_write(L_lost_incoming_connection, - LOG_MAIN, "SMTP data timeout (message abandoned) on connection from %s F=<%s>", - sender_fullhost ? sender_fullhost : US"local process", sender_address); +log_write(L_lost_incoming_connection, LOG_MAIN, + "SMTP data timeout (message abandoned) on connection from %s F=<%s> D=%s", + sender_fullhost ? sender_fullhost : US"local process", sender_address, + string_timesince(&smtp_connection_start)); receive_bomb_out(US"data-timeout", US"SMTP incoming data timeout"); /* Does not return */ } @@ -394,8 +403,7 @@ receive_bomb_out(US"data-timeout", US"SMTP incoming data timeout"); void smtp_data_sigint_exit(void) { -log_write(0, LOG_MAIN, "%s closed after %s", - smtp_get_connection_info(), had_data_sigint == SIGTERM ? "SIGTERM":"SIGINT"); +log_close_event(had_data_sigint == SIGTERM ? US"SIGTERM":US"SIGINT"); receive_bomb_out(US"signal-exit", US"Service not available - SIGTERM or SIGINT received"); /* Does not return */ @@ -3572,8 +3580,7 @@ if (log_reject_target != 0) if (!drop) return 0; -log_write(L_smtp_connection, LOG_MAIN, "%s closed by DROP in ACL", - smtp_get_connection_info()); +log_close_event(US"by DROP in ACL"); /* Run the not-quit ACL, but without any custom messages. This should not be a problem, because we get here only if some other ACL has issued "drop", and @@ -3999,16 +4006,14 @@ else tls_close(NULL, TLS_SHUTDOWN_NOWAIT); # endif -log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", - smtp_get_connection_info()); +log_close_event(US"by QUIT"); #else # ifndef DISABLE_TLS tls_close(NULL, TLS_SHUTDOWN_WAIT); # endif -log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", - smtp_get_connection_info()); +log_close_event(US"by QUIT"); /* Pause, hoping client will FIN first so that they get the TIME_WAIT. The socket should become readble (though with no data) */ @@ -5763,8 +5768,7 @@ while (done <= 0) while (done <= 0) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { case EOF_CMD: - log_write(L_smtp_connection, LOG_MAIN, "%s closed by EOF", - smtp_get_connection_info()); + log_close_event(US"by EOF"); smtp_notquit_exit(US"tls-failed", NULL, NULL); done = 2; break; @@ -5786,8 +5790,7 @@ while (done <= 0) smtp_respond(US"221", 3, TRUE, user_msg); else smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); - log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", - smtp_get_connection_info()); + log_close_event(US"by QUIT"); done = 2; break;