826 changes: 0 additions & 826 deletions src/src/dbstuff.h

This file was deleted.

2 changes: 1 addition & 1 deletion src/src/dcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* wbreyha@gmx.net
* See the file NOTICE for conditions of use and distribution.
*
* Copyright (c) The Exim Maintainers 2015 - 2019
* Copyright (c) The Exim Maintainers 2015 - 2021
*/

/* Code for calling dccifd. Called from acl.c. */
Expand Down
90 changes: 88 additions & 2 deletions src/src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2015 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */

Expand All @@ -12,6 +13,8 @@ static uschar debug_buffer[2048];
static uschar *debug_ptr = debug_buffer;
static int debug_prefix_length = 0;

static unsigned pretrigger_writeoff;
static unsigned pretrigger_readoff;


const uschar * rc_names[] = { /* Mostly for debug output */
Expand Down Expand Up @@ -317,8 +320,41 @@ if (debug_ptr[-1] == '\n')
}
}

fprintf(debug_file, "%s", CS debug_buffer);
fflush(debug_file);
if (debug_pretrigger_buf)
{
int needed = Ustrlen(debug_buffer)+1, avail;
char c;

if (needed > debug_pretrigger_bsize)
needed = debug_pretrigger_bsize;
if ((avail = pretrigger_readoff - pretrigger_writeoff) <= 0)
avail += debug_pretrigger_bsize;

/* We have a pretrigger set up, trigger not yet hit. Copy the line(s) to the
pretrig buffer, dropping earlier lines if needed but truncating this line if
the pbuf is maxed out. In the PTB the lines are NOT nul-terminated. */

while (avail < needed)
do
{
avail++;
c = debug_pretrigger_buf[pretrigger_readoff];
if (++pretrigger_readoff >= debug_pretrigger_bsize) pretrigger_readoff = 0;
}
while (c && c != '\n' && pretrigger_readoff != pretrigger_writeoff);

needed--;
for (int i = 0; needed; i++, needed--)
{
debug_pretrigger_buf[pretrigger_writeoff] = debug_buffer[i];
if (++pretrigger_writeoff >= debug_pretrigger_bsize) pretrigger_writeoff = 0;
}
}
else
{
fprintf(debug_file, "%s", CS debug_buffer);
fflush(debug_file);
}
debug_ptr = debug_buffer;
debug_prefix_length = 0;
}
Expand Down Expand Up @@ -409,4 +445,54 @@ else
}


/**************************************************************/
/* Pretrigger handling for debug. The debug_printf implementation
diverts output to a circular buffer if the buffer is set up.
The routines here set up the buffer, and unload it to file (and release it).
What ends up in the buffer is subject to the usual debug_selector. */

void
debug_pretrigger_setup(const uschar * size_string)
{
long size = Ustrtol(size_string, NULL, 0);
if (size > 0)
{
unsigned bufsize = MIN(size, 16384);

dtrigger_selector |= BIT(DTi_pretrigger);
if (debug_pretrigger_buf) store_free(debug_pretrigger_buf);
debug_pretrigger_buf = store_malloc((size_t)(debug_pretrigger_bsize = bufsize));
pretrigger_readoff = pretrigger_writeoff = 0;
}
}

void
debug_trigger_fire(void)
{
int nbytes;

if (!debug_pretrigger_buf) return;

if (debug_file && (nbytes = pretrigger_writeoff - pretrigger_readoff) != 0)
if (nbytes > 0)
fwrite(debug_pretrigger_buf + pretrigger_readoff, 1, nbytes, debug_file);
else
{
fwrite(debug_pretrigger_buf + pretrigger_readoff, 1,
debug_pretrigger_bsize - pretrigger_readoff, debug_file);
fwrite(debug_pretrigger_buf, 1, pretrigger_writeoff, debug_file);
}

debug_pretrigger_discard();
}

void
debug_pretrigger_discard(void)
{
if (debug_pretrigger_buf) store_free(debug_pretrigger_buf);
debug_pretrigger_buf = NULL;
dtrigger_selector = 0;
}


/* End of debug.c */
220 changes: 104 additions & 116 deletions src/src/deliver.c

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/src/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2010 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2009 */
/* Copyright (c) The Exim Maintainers 2010 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */

#include "exim.h"
Expand Down Expand Up @@ -44,8 +44,8 @@ uschar c = 1;
struct stat statbuf;
uschar * path;

if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name))
{ p = US"create"; path = US name; errno = EACCES; goto bad; }
if (is_tainted(name))
{ p = US"create"; path = US name; errno = ERRNO_TAINT; goto bad; }

if (parent)
{
Expand Down
4 changes: 2 additions & 2 deletions src/src/dkim.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge, 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* Code for DKIM support. Other DKIM relevant code is in
Expand Down Expand Up @@ -50,7 +50,7 @@ dkim_exim_query_dns_txt(const uschar * name)
dns_answer * dnsa = store_get_dns_answer();
dns_scan dnss;
rmark reset_point = store_mark();
gstring * g = string_get_tainted(256, TRUE);
gstring * g = string_get_tainted(256, GET_TAINTED);

lookup_dnssec_authenticated = NULL;
if (dns_lookup(dnsa, name, T_TXT, NULL) != DNS_SUCCEED)
Expand Down
3 changes: 2 additions & 1 deletion src/src/dkim_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */

Expand Down Expand Up @@ -169,7 +170,7 @@ if (!(dkim_signature = dkim_exim_sign(deliver_datafile, SPOOL_DATA_START_OFFSET,
#ifdef EXPERIMENTAL_ARC
if (dkim->arc_signspec) /* Prepend ARC headers */
{
uschar * e;
uschar * e = NULL;
if (!(dkim_signature = arc_sign(dkim->arc_signspec, dkim_signature, &e)))
{
*err = e;
Expand Down
18 changes: 8 additions & 10 deletions src/src/dmarc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/
/* DMARC support.
Copyright (c) The Exim Maintainers 2019 - 2022
Copyright (c) Todd Lyons <tlyons@exim.org> 2012 - 2014
Copyright (c) The Exim Maintainers 2019
License: GPL */

/* Portions Copyright (c) 2012, 2013, The Trusted Domain Project;
Expand Down Expand Up @@ -53,14 +53,12 @@ static dmarc_exim_p dmarc_policy_description[] = {
};


void
dmarc_version_report(FILE *f)
gstring *
dmarc_version_report(gstring * g)
{
const char *implementation, *version;

fprintf(f, "Library version: dmarc: Compile: %d.%d.%d.%d\n",
(OPENDMARC_LIB_VERSION & 0xff000000) >> 24, (OPENDMARC_LIB_VERSION & 0x00ff0000) >> 16,
(OPENDMARC_LIB_VERSION & 0x0000ff00) >> 8, OPENDMARC_LIB_VERSION & 0x000000ff);
return string_fmt_append(g, "Library version: dmarc: Compile: %d.%d.%d.%d\n",
(OPENDMARC_LIB_VERSION & 0xff000000) >> 24, (OPENDMARC_LIB_VERSION & 0x00ff0000) >> 16,
(OPENDMARC_LIB_VERSION & 0x0000ff00) >> 8, OPENDMARC_LIB_VERSION & 0x000000ff);
}


Expand Down Expand Up @@ -233,7 +231,7 @@ if (rc == DNS_SUCCEED)
if (rr->type == T_TXT && rr->size > 3)
{
store_free_dns_answer(dnsa);
return string_copyn_taint(US rr->data, rr->size, TRUE);
return string_copyn_taint(US rr->data, rr->size, GET_TAINTED);
}
store_free_dns_answer(dnsa);
return NULL;
Expand Down Expand Up @@ -532,7 +530,7 @@ if (!dmarc_abort && !sender_host_authenticated)
/* Can't use exim's string manipulation functions so allocate memory
for libopendmarc using its max hostname length definition. */

dmarc_domain = store_get(DMARC_MAXHOSTNAMELEN, TRUE);
dmarc_domain = store_get(DMARC_MAXHOSTNAMELEN, GET_TAINTED);
libdm_status = opendmarc_policy_fetch_utilized_domain(dmarc_pctx,
dmarc_domain, DMARC_MAXHOSTNAMELEN-1);
store_release_above(dmarc_domain + Ustrlen(dmarc_domain)+1);
Expand Down
3 changes: 2 additions & 1 deletion src/src/dmarc.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*************************************************/

/* Experimental DMARC support.
Copyright (c) The Exim Maintainers 2021 - 2022
Copyright (c) Todd Lyons <tlyons@exim.org> 2012 - 2014
License: GPL */

Expand All @@ -17,7 +18,7 @@
# endif /* SUPPORT_SPF */

/* prototypes */
void dmarc_version_report(FILE *);
gstring * dmarc_version_report(gstring *);
int dmarc_init();
int dmarc_store_data(header_line *);
int dmarc_process();
Expand Down
21 changes: 9 additions & 12 deletions src/src/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions for interfacing with the DNS. */
Expand Down Expand Up @@ -258,7 +258,7 @@ else
{
int v6[4];

g = string_get_tainted(32, is_tainted(string));
g = string_get_tainted(32, string);
(void)host_aton(string, v6);

/* The original specification for IPv6 reverse lookup was to invert each
Expand Down Expand Up @@ -637,7 +637,7 @@ if ((previous = tree_search(tree_dns_fails, node_name)))
e = previous->data.ptr;
else
{
e = store_get_perm(DNS_FAILNODE_SIZE, is_tainted(name));
e = store_get_perm(DNS_FAILNODE_SIZE, name);
new = (void *)(e+1);
dns_fail_tag(new->name, name, type);
new->data.ptr = e;
Expand Down Expand Up @@ -850,11 +850,8 @@ more.) */

if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
{
int ovector[3*(EXPAND_MAXN+1)];

dns_pattern_init();
if (pcre_exec(regex_check_dns_names, NULL, CCS name, Ustrlen(name),
0, PCRE_EOPT, ovector, nelem(ovector)) < 0)
if (!regex_match(regex_check_dns_names, name, -1, NULL))
{
DEBUG(D_dns)
debug_printf("DNS name syntax check failed: %s (%s)\n", name,
Expand Down Expand Up @@ -1068,7 +1065,7 @@ for (int i = 0; i <= dns_cname_loops; i++)
return DNS_FAIL;

/* DNS data comes from the outside, hence tainted */
data = store_get(256, TRUE);
data = store_get(256, GET_TAINTED);
if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
return DNS_FAIL;
Expand Down Expand Up @@ -1151,7 +1148,7 @@ switch (type)
case T_CSA:
{
uschar *srvname, *namesuff, *tld;
int priority, weight, port;
int priority, dummy_weight, port;
int limit, rc, i;
BOOL ipv6;
dns_record *rr;
Expand Down Expand Up @@ -1240,7 +1237,7 @@ switch (type)

/* Extract the numerical SRV fields (p is incremented) */
GETSHORT(priority, p);
GETSHORT(weight, p);
GETSHORT(dummy_weight, p);
GETSHORT(port, p);

/* Check the CSA version number */
Expand Down Expand Up @@ -1296,7 +1293,7 @@ if (rr->type == T_A)
if (p + 4 <= dnsa_lim)
{
/* the IP is not regarded as tainted */
yield = store_get(sizeof(dns_address) + 20, FALSE);
yield = store_get(sizeof(dns_address) + 20, GET_UNTAINTED);
(void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
yield->next = NULL;
}
Expand All @@ -1310,7 +1307,7 @@ else
{
struct in6_addr in6;
for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
yield = store_get(sizeof(dns_address) + 50, FALSE);
yield = store_get(sizeof(dns_address) + 50, GET_UNTAINTED);
inet_ntop(AF_INET6, &in6, CS yield->address, 50);
yield->next = NULL;
}
Expand Down
8 changes: 4 additions & 4 deletions src/src/dnsbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions concerned with dnsbls */
Expand Down Expand Up @@ -115,9 +115,9 @@ else

else
{ /* Set up a tree entry to cache the lookup */
t = store_get(sizeof(tree_node) + qlen + 1 + 1, is_tainted(query));
t = store_get(sizeof(tree_node) + qlen + 1 + 1, query);
Ustrcpy(t->name, query);
t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block), FALSE);
t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block), GET_UNTAINTED);
(void)tree_insertnode(&dnsbl_cache, t);
}

Expand Down Expand Up @@ -365,7 +365,7 @@ if (cb->rc == DNS_SUCCEED)
int len = (rr->data)[0];
if (len > 511) len = 127;
store_pool = POOL_PERM;
cb->text = string_copyn_taint(CUS (rr->data+1), len, TRUE);
cb->text = string_copyn_taint(CUS (rr->data+1), len, GET_TAINTED);
store_pool = old_pool;
break;
}
Expand Down
10 changes: 5 additions & 5 deletions src/src/drtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */


Expand Down Expand Up @@ -518,7 +518,7 @@ static struct lookupmodulestr *lookupmodules = NULL;
static void
addlookupmodule(void *dl, struct lookup_module_info *info)
{
struct lookupmodulestr *p = store_get(sizeof(struct lookupmodulestr), FALSE);
struct lookupmodulestr *p = store_get(sizeof(struct lookupmodulestr), GET_UNTAINTED);

p->dl = dl;
p->info = info;
Expand Down Expand Up @@ -728,15 +728,15 @@ if (!(dd = exim_opendir(LOOKUP_MODULE_DIR)))
}
else
{
const pcre *regex_islookupmod = regex_must_compile(
const pcre2_code *regex_islookupmod = regex_must_compile(
US"\\." DYNLIB_FN_EXT "$", FALSE, TRUE);

DEBUG(D_lookup) debug_printf("Loading lookup modules from %s\n", LOOKUP_MODULE_DIR);
while ((ent = readdir(dd)))
{
char *name = ent->d_name;
char * name = ent->d_name;
int len = (int)strlen(name);
if (pcre_exec(regex_islookupmod, NULL, name, len, 0, PCRE_EOPT, NULL, 0) >= 0)
if (regex_match(regex_islookupmod, US name, len, NUL))
{
int pathnamelen = len + (int)strlen(LOOKUP_MODULE_DIR) + 2;
void *dl;
Expand Down
1 change: 1 addition & 0 deletions src/src/dummies.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2009 */
/* Copyright (c) The Exim Maintainers 2021 */
/* See the file NOTICE for conditions of use and distribution. */

/* This file is not part of the main Exim code. There are little bits of test
Expand Down
1 change: 1 addition & 0 deletions src/src/enq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2015 */
/* Copyright (c) The Exim Maintainers 2021 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions concerned with serialization. */
Expand Down
138 changes: 71 additions & 67 deletions src/src/exigrep.src
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use Getopt::Long qw(:config no_ignore_case);
use File::Basename;

# Copyright (c) 2007-2017 University of Cambridge.
# Copyright (c) The Exim Maintainers 2020
# Copyright (c) The Exim Maintainers 2020 - 2021
# See the file NOTICE for conditions of use and distribution.

# Except when they appear in comments, the following placeholders in this
Expand Down Expand Up @@ -45,20 +45,21 @@ use POSIX qw(mktime);
# the number of seconds since the epoch. It handles optional timezone
# information.

sub seconds {
my($year,$month,$day,$hour,$min,$sec,$tzs,$tzh,$tzm) =
$_[0] =~ /^(\d{4})-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)(?:.\d+)?(?>\s([+-])(\d\d)(\d\d))?/o;
sub seconds
{
my($year,$month,$day,$hour,$min,$sec,$tzs,$tzh,$tzm) =
$_[0] =~ /^(\d{4})-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)(?:.\d+)?(?>\s([+-])(\d\d)(\d\d))?/o;

my $seconds = mktime $sec, $min, $hour, $day, $month - 1, $year - 1900;
my $seconds = mktime $sec, $min, $hour, $day, $month - 1, $year - 1900;

if (defined $tzs)
{
$seconds -= $tzh * 3600 + $tzm * 60 if $tzs eq "+";
$seconds += $tzh * 3600 + $tzm * 60 if $tzs eq "-";
}
if (defined $tzs)
{
$seconds -= $tzh * 3600 + $tzm * 60 if $tzs eq "+";
$seconds += $tzh * 3600 + $tzm * 60 if $tzs eq "-";
}

return $seconds;
}
return $seconds;
}


# This subroutine processes a single line (in $_) from a log file. Program
Expand All @@ -78,77 +79,78 @@ my $literal = 0;
my $related_re='';
my @Mids = ();

sub do_line {
sub do_line
{

# Convert syslog lines to mainlog format, as in eximstats.
# Convert syslog lines to mainlog format, as in eximstats.

if (!/^\d{4}-/o) { $_ =~ s/^.*? exim\b.*?: //o; }
if (!/^\d{4}-/o) { $_ =~ s/^.*? exim\b.*?: //o; }

return unless
my($date,$id) = /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d(?:\.\d+)? (?:[+-]\d{4} )?)(?:\[\d+\] )?(\w{6}\-\w{6}\-\w{2})?/o;
return unless
my($date,$id) = /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d(?:\.\d+)? (?:[+-]\d{4} )?)(?:\[\d+\] )?(\w{6}\-\w{6}\-\w{2})?/o;

# Handle the case when the log line belongs to a specific message. We save
# lines for specific messages until the message is complete. Then either print
# or discard.
# Handle the case when the log line belongs to a specific message. We save
# lines for specific messages until the message is complete. Then either print
# or discard.

if (defined $id)
{
$saved{$id} = '' unless defined($saved{$id});
if (defined $id)
{
$saved{$id} = '' unless defined($saved{$id});

# Save up the data for this message in case it becomes interesting later.
# Save up the data for this message in case it becomes interesting later.

$saved{$id} .= $_;
$saved{$id} .= $_;

# Are we interested in this id ? Short circuit if we already were interested.
# Are we interested in this id ? Short circuit if we already were interested.

if ($invert)
{
$id_list{$id} = 1 if (!defined($id_list{$id}));
$id_list{$id} = 0 if (($insensitive && /$pattern/io) || /$pattern/o);
}
else
{
if (defined $id_list{$id} ||
($insensitive && /$pattern/io) || /$pattern/o)
if ($invert)
{
$id_list{$id} = 1;
get_related_ids($id) if $related;
$id_list{$id} = 1 if (!defined($id_list{$id}));
$id_list{$id} = 0 if (($insensitive && /$pattern/io) || /$pattern/o);
}
elsif ($related && $related_re)
else
{
grep_for_related($_, $id);
if (defined $id_list{$id} ||
($insensitive && /$pattern/io) || /$pattern/o)
{
$id_list{$id} = 1;
get_related_ids($id) if $related;
}
elsif ($related && $related_re)
{
grep_for_related($_, $id);
}
}
}

# See if this is a completion for some message. If it is interesting,
# print it, but in any event, throw away what was saved.
# See if this is a completion for some message. If it is interesting,
# print it, but in any event, throw away what was saved.

if (index($_, 'Completed') != -1 ||
index($_, 'SMTP data timeout') != -1 ||
(index($_, 'rejected') != -1 &&
/^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d(?:\.\d+)? (?:[+-]\d{4} )?)(?:\[\d+\] )?\w{6}\-\w{6}\-\w{2} rejected/o))
{
if ($queue_time != -1 &&
$saved{$id} =~ /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d ([+-]\d{4} )?)/o)
if (index($_, 'Completed') != -1 ||
index($_, 'SMTP data timeout') != -1 ||
(index($_, 'rejected') != -1 &&
/^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d(?:\.\d+)? (?:[+-]\d{4} )?)(?:\[\d+\] )?\w{6}\-\w{6}\-\w{2} rejected/o))
{
my $old_sec = &seconds($1);
my $sec = &seconds($date);
$id_list{$id} = 0 if $id_list{$id} && $sec - $old_sec <= $queue_time;
if ($queue_time != -1 &&
$saved{$id} =~ /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d ([+-]\d{4} )?)/o)
{
my $old_sec = &seconds($1);
my $sec = &seconds($date);
$id_list{$id} = 0 if $id_list{$id} && $sec - $old_sec <= $queue_time;
}

print "$saved{$id}\n" if ($id_list{$id});
delete $id_list{$id};
delete $saved{$id};
}

print "$saved{$id}\n" if ($id_list{$id});
delete $id_list{$id};
delete $saved{$id};
}
}

# Handle the case where the log line does not belong to a specific message.
# Print it if it is interesting.
# Handle the case where the log line does not belong to a specific message.
# Print it if it is interesting.

elsif ( ($invert && (($insensitive && !/$pattern/io) || !/$pattern/o)) ||
(!$invert && (($insensitive && /$pattern/io) || /$pattern/o)) )
{ print "$_\n"; }
}
elsif ( ($invert && (($insensitive && !/$pattern/io) || !/$pattern/o)) ||
(!$invert && (($insensitive && /$pattern/io) || /$pattern/o)) )
{ print "$_\n"; }
}

# Rotated log files are frequently compressed and there are a variety of
# formats it could be compressed with. Rather than use just one that is
Expand Down Expand Up @@ -200,17 +202,19 @@ sub detect_compressor_capable
return $cmdline;
}

sub grep_for_related {
sub grep_for_related
{
my ($line,$id) = @_;
$id_list{$id} = 1 if $line =~ m/$related_re/;
}
}

sub get_related_ids {
sub get_related_ids
{
my ($id) = @_;
push @Mids, $id unless grep /\b$id\b/, @Mids;
my $re = join '|', @Mids;
$related_re = qr/$re/;
}
}

# The main program. Extract the pattern and make sure any relevant characters
# are quoted if the -l flag is given. The -t flag gives a time-on-queue value
Expand Down
599 changes: 381 additions & 218 deletions src/src/exim.c

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/src/exim.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2021 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */

Expand Down Expand Up @@ -522,19 +523,21 @@ extern int ferror(FILE *);

/* The header from the PCRE regex package */

#include <pcre.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>

/* Exim includes are in several files. Note that local_scan.h #includes
config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
*/

#include "local_scan.h"
#include "macros.h"
#include "dbstuff.h"
#include "hintsdb.h"
#include "hintsdb_structs.h"
#include "structs.h"
#include "blob.h"
#include "globals.h"
#include "hash.h"
#include "globals.h"
#include "functions.h"
#include "dbfunctions.h"
#include "osfunctions.h"
Expand All @@ -545,9 +548,6 @@ config.h, mytypes.h, and store.h, so we don't need to mention them explicitly.
#ifdef SUPPORT_SPF
# include "spf.h"
#endif
#ifdef EXPERIMENTAL_SRS_ALT
# include "srs.h"
#endif
#ifndef DISABLE_DKIM
# include "dkim.h"
#endif
Expand Down
66 changes: 22 additions & 44 deletions src/src/exim_dbmbuild.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */


Expand Down Expand Up @@ -31,7 +31,7 @@ characters. */

#include "exim.h"

uschar * spool_directory = NULL; /* dummy for dbstuff.h */
uschar * spool_directory = NULL; /* dummy for hintsdb.h */

/******************************************************************************/
/* dummies needed by Solaris build */
Expand All @@ -42,7 +42,7 @@ uschar *
readconf_printtime(int t)
{ return NULL; }
void *
store_get_3(int size, BOOL tainted, const char *filename, int linenumber)
store_get_3(int size, const void * proto_mem, const char *filename, int linenumber)
{ return NULL; }
void **
store_reset_3(void **ptr, const char *filename, int linenumber)
Expand Down Expand Up @@ -106,26 +106,6 @@ return sys_errlist[n];
#endif /* STRERROR_FROM_ERRLIST */


/* For Berkeley DB >= 2, we can define a function to be called in case of DB
errors. This should help with debugging strange DB problems, e.g. getting "File
exists" when you try to open a db file. The API changed at release 4.3. */

#if defined(USE_DB) && defined(DB_VERSION_STRING)
void
# if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
dbfn_bdb_error_callback(const DB_ENV *dbenv, const char *pfx, const char *msg)
{
dbenv = dbenv;
# else
dbfn_bdb_error_callback(const char *pfx, char *msg)
{
# endif
pfx = pfx;
printf("Berkeley DB error: %s\n", msg);
}
#endif



/*************************************************
* Interpret escape sequence *
Expand Down Expand Up @@ -266,9 +246,7 @@ else
/* It is apparently necessary to open with O_RDWR for this to work
with gdbm-1.7.3, though no reading is actually going to be done. */

EXIM_DBOPEN(temp_dbmname, dirname, O_RDWR|O_CREAT|O_EXCL, 0644, &d);

if (d == NULL)
if (!(d = exim_dbopen(temp_dbmname, dirname, O_RDWR|O_CREAT|O_EXCL, 0644)))
{
printf("exim_dbmbuild: unable to create %s: %s\n", temp_dbmname,
strerror(errno));
Expand Down Expand Up @@ -347,11 +325,11 @@ while (Ufgets(line, max_insize, f) != NULL)

if (started)
{
EXIM_DATUM_INIT(content);
EXIM_DATUM_DATA(content) = CS buffer;
EXIM_DATUM_SIZE(content) = bptr - buffer + add_zero;
exim_datum_init(&content);
exim_datum_data_set(&content, buffer);
exim_datum_size_set(&content, bptr - buffer + add_zero);

switch(rc = EXIM_DBPUTB(d, key, content))
switch(rc = exim_dbputb(d, &key, &content))
{
case EXIM_DBPUTB_OK:
count++;
Expand All @@ -361,7 +339,7 @@ while (Ufgets(line, max_insize, f) != NULL)
if (warn) fprintf(stderr, "** Duplicate key \"%s\"\n", keybuffer);
dupcount++;
if(duperr) yield = 1;
if (lastdup) EXIM_DBPUT(d, key, content);
if (lastdup) exim_dbput(d, &key, &content);
break;

default:
Expand All @@ -374,8 +352,8 @@ while (Ufgets(line, max_insize, f) != NULL)
bptr = buffer;
}

EXIM_DATUM_INIT(key);
EXIM_DATUM_DATA(key) = CS keybuffer;
exim_datum_init(&key);
exim_datum_data_set(&key, keybuffer);

/* Deal with quoted keys. Escape sequences always make one character
out of several, so we can re-build in place. */
Expand All @@ -392,16 +370,16 @@ while (Ufgets(line, max_insize, f) != NULL)
s++;
}
if (*s != 0) s++; /* Past terminating " */
EXIM_DATUM_SIZE(key) = t - keystart + add_zero;
exim_datum_size_set(&key, t - keystart + add_zero);
}
else
{
keystart = s;
while (*s != 0 && *s != ':' && !isspace(*s)) s++;
EXIM_DATUM_SIZE(key) = s - keystart + add_zero;
exim_datum_size_set(&key, s - keystart + add_zero);
}

if (EXIM_DATUM_SIZE(key) > 256)
if (exim_datum_size_get(&key) > 256)
{
printf("Keys longer than 255 characters cannot be handled\n");
started = 0;
Expand All @@ -410,10 +388,10 @@ while (Ufgets(line, max_insize, f) != NULL)
}

if (lowercase)
for (i = 0; i < EXIM_DATUM_SIZE(key) - add_zero; i++)
for (i = 0; i < exim_datum_size_get(&key) - add_zero; i++)
keybuffer[i] = tolower(keystart[i]);
else
for (i = 0; i < EXIM_DATUM_SIZE(key) - add_zero; i++)
for (i = 0; i < exim_datum_size_get(&key) - add_zero; i++)
keybuffer[i] = keystart[i];

keybuffer[i] = 0;
Expand All @@ -437,11 +415,11 @@ while (Ufgets(line, max_insize, f) != NULL)
if (started)
{
int rc;
EXIM_DATUM_INIT(content);
EXIM_DATUM_DATA(content) = CS buffer;
EXIM_DATUM_SIZE(content) = bptr - buffer + add_zero;
exim_datum_init(&content);
exim_datum_data_set(&content, buffer);
exim_datum_size_set(&content, bptr - buffer + add_zero);

switch(rc = EXIM_DBPUTB(d, key, content))
switch(rc = exim_dbputb(d, &key, &content))
{
case EXIM_DBPUTB_OK:
count++;
Expand All @@ -451,7 +429,7 @@ if (started)
if (warn) fprintf(stderr, "** Duplicate key \"%s\"\n", keybuffer);
dupcount++;
if (duperr) yield = 1;
if (lastdup) EXIM_DBPUT(d, key, content);
if (lastdup) exim_dbput(d, &key, &content);
break;

default:
Expand All @@ -466,7 +444,7 @@ if (started)

TIDYUP:

EXIM_DBCLOSE(d);
exim_dbclose(d);
(void)fclose(f);

/* If successful, output the number of entries and rename the temporary
Expand Down
196 changes: 106 additions & 90 deletions src/src/exim_dbutil.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/src/exim_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Default is -fcntl -lockfile.
Argument: the name of the lock file
Copyright (c) The Exim Maintainers 2016
Copyright (c) The Exim Maintainers 2016 - 2021
*/

#include "os.h"
Expand Down
11 changes: 8 additions & 3 deletions src/src/exiqgrep.src
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# Utility for searching and displaying queue information.
# Written by Matt Hubbard 15 August 2002
#
# Copyright (c) The Exim Maintainers 2021 - 2022

# Except when they appear in comments, the following placeholders in this
# source are replaced when it is turned into a runnable script:
Expand Down Expand Up @@ -53,12 +55,14 @@ if ($ARGV[0] eq '--version') {
exit 0;
}

getopts('hf:r:y:o:s:C:zxlibRcaG:',\%opt);
if ($ARGV[0]) { &help; exit;}
if ($opt{h}) { &help; exit;}
if (!getopts('hf:r:y:o:s:C:zxlibRcaG:E:',\%opt)) { &help; exit; }
if ($opt{h}) { &help; exit; }
if ($ARGV[0] || !($opt{f} || $opt{r} || $opt{s} || $opt{y} || $opt{o} || $opt{z} || $opt{x} || $opt{c}))
{ &help; exit(1); }
if ($opt{a}) { $eargs = '-bp'; }
if ($opt{C} && -e $opt{C} && -f $opt{C} && -R $opt{C}) { $eargs .= ' -C '.$opt{C}; }
if ($opt{G}) { $eargs .= ' -qG'.$opt{G}; }
if ($opt{E}) { $exim = $opt{E}; }

# Read message queue output into hash
&collect();
Expand All @@ -75,6 +79,7 @@ Exim message queue display utility.

-h This help message.
-C Specify which exim.conf to use.
-E Specify exim binary to use.

Selection criteria:
-f <regexp> Match sender address sender (field is "< >" wrapped)
Expand Down
2,889 changes: 1,508 additions & 1,381 deletions src/src/expand.c

Large diffs are not rendered by default.

324 changes: 169 additions & 155 deletions src/src/filter.c

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions src/src/filtertest.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2021 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2009 */
/* See the file NOTICE for conditions of use and distribution. */

Expand Down Expand Up @@ -45,11 +46,11 @@ body_len = 0;
body_linecount = 0;
header_size = message_size;

if (!dot_ended && !feof(stdin))
if (!dot_ended && !stdin_feof())
{
if (!f.dot_ends)
{
while ((ch = getc(stdin)) != EOF)
while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF)
{
if (ch == 0) body_zerocount++;
if (ch == '\n') body_linecount++;
Expand All @@ -62,7 +63,7 @@ if (!dot_ended && !feof(stdin))
else
{
int ch_state = 1;
while ((ch = getc(stdin)) != EOF)
while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF)
{
if (ch == 0) body_zerocount++;
switch (ch_state)
Expand Down Expand Up @@ -99,6 +100,7 @@ if (!dot_ended && !feof(stdin))
}
if (s == message_body_end || s[-1] != '\n') body_linecount++;
}
debug_printf("%s %d\n", __FUNCTION__, __LINE__);

message_body[body_len] = 0;
message_body_size = message_size - header_size;
Expand All @@ -112,7 +114,7 @@ if (body_len >= message_body_visible)
int above = message_body_visible - below;
if (above > 0)
{
uschar *temp = store_get(below, TRUE);
uschar * temp = store_get(below, GET_UNTAINTED);
memcpy(temp, message_body_end, below);
memmove(message_body_end, s+1, above);
memcpy(message_body_end + above, temp, below);
Expand Down Expand Up @@ -178,7 +180,7 @@ if (fstat(fd, &statbuf) != 0)
return FALSE;
}

filebuf = store_get(statbuf.st_size + 1, is_tainted(filename));
filebuf = store_get(statbuf.st_size + 1, filename);
rc = read(fd, filebuf, statbuf.st_size);
(void)close(fd);

Expand Down Expand Up @@ -250,7 +252,7 @@ if (filter_type == FILTER_FORWARD)
/* For a filter, set up the message_body variables and the message size if this
is the first time this function has been called. */

if (message_body == NULL) read_message_body(dot_ended);
if (!message_body) read_message_body(dot_ended);

/* Now pass the filter file to the function that interprets it. Because
filter_test is not FILTER_NONE, the interpreter will output comments about what
Expand All @@ -269,10 +271,9 @@ if (is_system)
}
else
{
yield = (filter_type == FILTER_SIEVE)?
sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error)
:
filter_interpret(filebuf, RDO_REWRITE, &generated, &error);
yield = filter_type == FILTER_SIEVE
? sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error)
: filter_interpret(filebuf, RDO_REWRITE, &generated, &error);
}

return yield != FF_ERROR;
Expand Down
246 changes: 145 additions & 101 deletions src/src/functions.h

Large diffs are not rendered by default.

113 changes: 49 additions & 64 deletions src/src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* All the global variables are defined together in this one module, so
Expand Down Expand Up @@ -98,10 +98,6 @@ int sqlite_lock_timeout = 5;
BOOL move_frozen_messages = FALSE;
#endif

#ifdef ALLOW_INSECURE_TAINTED_DATA
BOOL allow_insecure_tainted_data = FALSE;
#endif

/* These variables are outside the #ifdef because it keeps the code less
cluttered in several places (e.g. during logging) if we can always refer to
them. Also, the tls_ variables are now always visible. Note that these are
Expand All @@ -118,15 +114,15 @@ tls_support tls_out = {

uschar *dsn_envid = NULL;
int dsn_ret = 0;
const pcre *regex_DSN = NULL;
const pcre2_code *regex_DSN = NULL;
uschar *dsn_advertise_hosts = NULL;

#ifndef DISABLE_TLS
BOOL gnutls_compat_mode = FALSE;
BOOL gnutls_allow_auto_pkcs11 = FALSE;
uschar *hosts_require_alpn = NULL;
uschar *openssl_options = NULL;
const pcre *regex_STARTTLS = NULL;
const pcre2_code *regex_STARTTLS = NULL;
uschar *tls_advertise_hosts = US"*";
uschar *tls_alpn = US"smtp:esmtp";
uschar *tls_certificate = NULL;
Expand Down Expand Up @@ -159,28 +155,30 @@ uschar *tls_advertise_hosts = NULL;
/* Per Recipient Data Response variables */
BOOL prdr_enable = FALSE;
BOOL prdr_requested = FALSE;
const pcre *regex_PRDR = NULL;
const pcre2_code *regex_PRDR = NULL;
#endif

#ifdef SUPPORT_I18N
const pcre *regex_UTF8 = NULL;
const pcre2_code *regex_UTF8 = NULL;
#endif

/* Input-reading functions for messages, so we can use special ones for
incoming TCP/IP. The defaults use stdin. We never need these for any
stand-alone tests. */

#if !defined(STAND_ALONE) && !defined(MACRO_PREDEF)
int (*lwr_receive_getc)(unsigned) = stdin_getc;
int (*lwr_receive_getc)(unsigned) = stdin_getc;
uschar * (*lwr_receive_getbuf)(unsigned *) = NULL;
int (*lwr_receive_ungetc)(int) = stdin_ungetc;
int (*receive_getc)(unsigned) = stdin_getc;
uschar * (*receive_getbuf)(unsigned *) = NULL;
void (*receive_get_cache)(unsigned) = NULL;
int (*receive_ungetc)(int) = stdin_ungetc;
int (*receive_feof)(void) = stdin_feof;
int (*receive_ferror)(void) = stdin_ferror;
BOOL (*receive_smtp_buffered)(void) = NULL; /* Only used for SMTP */
int (*lwr_receive_ungetc)(int) = stdin_ungetc;
BOOL (*lwr_receive_hasc)(void) = stdin_hasc;

int (*receive_getc)(unsigned) = stdin_getc;
uschar * (*receive_getbuf)(unsigned *) = NULL;
void (*receive_get_cache)(unsigned) = NULL;
BOOL (*receive_hasc)(void) = stdin_hasc;
int (*receive_ungetc)(int) = stdin_ungetc;
int (*receive_feof)(void) = stdin_feof;
int (*receive_ferror)(void) = stdin_ferror;
#endif


Expand Down Expand Up @@ -417,10 +415,6 @@ BOOL spf_result_guessed = FALSE;
#endif
BOOL split_spool_directory = FALSE;
BOOL spool_wireformat = FALSE;
#ifdef EXPERIMENTAL_SRS_ALT
BOOL srs_usehash = TRUE;
BOOL srs_usetimestamp = TRUE;
#endif
BOOL strict_acl_vars = FALSE;
BOOL strip_excess_angle_brackets = FALSE;
BOOL strip_trailing_dot = FALSE;
Expand Down Expand Up @@ -606,9 +600,6 @@ address_item address_defaults = {
.extra_headers = NULL,
.remove_headers = NULL,
.variables = NULL,
#ifdef EXPERIMENTAL_SRS_ALT
.srs_sender = NULL,
#endif
.ignore_error = FALSE,
#ifdef SUPPORT_I18N
.utf8_msg = FALSE,
Expand Down Expand Up @@ -658,7 +649,8 @@ auth_instance auth_defaults = {

uschar *auth_defer_msg = US"reason not recorded";
uschar *auth_defer_user_msg = US"";
uschar *auth_vars[AUTH_VARS];
const uschar *auth_vars[AUTH_VARS];
uschar *authenticator_name = NULL;
int auto_thaw = 0;
#ifdef WITH_CONTENT_SCAN
int av_failed = FALSE; /* boolean but accessed as vtype_int*/
Expand Down Expand Up @@ -711,15 +703,18 @@ uschar *chunking_advertise_hosts = US"*";
unsigned chunking_datasize = 0;
unsigned chunking_data_left = 0;
chunking_state_t chunking_state= CHUNKING_NOT_OFFERED;
const pcre *regex_CHUNKING = NULL;
const pcre2_code *regex_CHUNKING = NULL;

#ifdef EXPERIMENTAL_ESMTP_LIMITS
const pcre *regex_LIMITS = NULL;
const pcre2_code *regex_LIMITS = NULL;
#endif

uschar *client_authenticator = NULL;
uschar *client_authenticated_id = NULL;
uschar *client_authenticated_sender = NULL;
#ifndef DISABLE_CLIENT_CMD_LOG
gstring *client_cmd_log = NULL;
#endif
int clmacro_count = 0;
uschar *clmacros[MAX_CLMACROS];
FILE *config_file = NULL;
Expand Down Expand Up @@ -819,9 +814,12 @@ bit_table debug_options[] = { /* must be in alphabetical order and use
BIT_TABLE(D, uid),
BIT_TABLE(D, verify),
};
int debug_options_count = nelem(debug_options);
int debug_options_count = nelem(debug_options);
uschar debuglog_name[LOG_NAME_SIZE] = {0};
unsigned debug_pretrigger_bsize = 0;
uschar * debug_pretrigger_buf = NULL;
unsigned int debug_selector = 0;

unsigned int debug_selector = 0;
int delay_warning[DELAY_WARNING_SIZE] = { DELAY_WARNING_SIZE, 1, 24*60*60 };
uschar *delay_warning_condition=
US"${if or {"
Expand Down Expand Up @@ -901,7 +899,10 @@ uschar *dnslist_text = NULL;
uschar *dnslist_value = NULL;
tree_node *domainlist_anchor = NULL;
int domainlist_count = 0;
const uschar *driver_srcfile = NULL;
int driver_srcline = 0;
uschar *dsn_from = US DEFAULT_DSN_FROM;
unsigned int dtrigger_selector = 0;

int errno_quota = ERRNO_QUOTA;
uschar *errors_copy = NULL;
Expand All @@ -924,7 +925,7 @@ int expand_level = 0; /* Nesting depth, indent for debug */
int expand_forbid = 0;
int expand_nlength[EXPAND_MAXN+1];
int expand_nmax = -1;
uschar *expand_nstring[EXPAND_MAXN+1];
const uschar *expand_nstring[EXPAND_MAXN+1];
uschar *expand_string_message;
uschar *extra_local_interfaces = NULL;

Expand Down Expand Up @@ -953,7 +954,7 @@ volatile sig_atomic_t had_command_timeout = 0;
volatile sig_atomic_t had_command_sigterm = 0;
volatile sig_atomic_t had_data_timeout = 0;
volatile sig_atomic_t had_data_sigint = 0;
uschar *headers_charset = US HEADERS_CHARSET;
const uschar *headers_charset = US HEADERS_CHARSET;
int header_insert_maxlen = 64 * 1024;
header_line *header_last = NULL;
header_line *header_list = NULL;
Expand Down Expand Up @@ -1057,9 +1058,6 @@ int log_default[] = { /* for initializing log_selector */
Li_size_reject,
Li_skip_delivery,
Li_smtp_confirmation,
#ifdef ALLOW_INSECURE_TAINTED_DATA
Li_tainted,
#endif
Li_tls_certificate_verified,
Li_tls_cipher,
-1
Expand Down Expand Up @@ -1129,9 +1127,6 @@ bit_table log_options[] = { /* must be in alphabetical order,
BIT_TABLE(L, smtp_protocol_error),
BIT_TABLE(L, smtp_syntax_error),
BIT_TABLE(L, subject),
#ifdef ALLOW_INSECURE_TAINTED_DATA
BIT_TABLE(L, tainted),
#endif
BIT_TABLE(L, tls_certificate_verified),
BIT_TABLE(L, tls_cipher),
BIT_TABLE(L, tls_peerdn),
Expand Down Expand Up @@ -1167,7 +1162,6 @@ uschar *message_headers = NULL;
uschar *message_id;
uschar *message_id_domain = NULL;
uschar *message_id_text = NULL;
struct timeval message_id_tv = { 0, 0 };
uschar message_id_option[MESSAGE_ID_LENGTH + 3];
uschar *message_id_external;
int message_linecount = 0;
Expand Down Expand Up @@ -1213,6 +1207,10 @@ uid_t originator_uid;
uschar *override_local_interfaces = NULL;
uschar *override_pid_file_path = NULL;

pcre2_general_context * pcre_gen_ctx = NULL;
pcre2_compile_context * pcre_cmp_ctx = NULL;
pcre2_match_context * pcre_mtc_ctx = NULL;

uschar *percent_hack_domains = NULL;
uschar *pid_file_path = US PID_FILE_PATH
"\0<--------------Space to patch pid_file_path->";
Expand Down Expand Up @@ -1306,20 +1304,20 @@ int recipients_count = 0;
recipient_item *recipients_list = NULL;
int recipients_list_max = 0;
int recipients_max = 50000;
const pcre *regex_AUTH = NULL;
const pcre *regex_check_dns_names = NULL;
const pcre *regex_From = NULL;
const pcre *regex_IGNOREQUOTA = NULL;
const pcre *regex_PIPELINING = NULL;
const pcre *regex_SIZE = NULL;
const pcre2_code *regex_AUTH = NULL;
const pcre2_code *regex_check_dns_names = NULL;
const pcre2_code *regex_From = NULL;
const pcre2_code *regex_IGNOREQUOTA = NULL;
const pcre2_code *regex_PIPELINING = NULL;
const pcre2_code *regex_SIZE = NULL;
#ifndef DISABLE_PIPE_CONNECT
const pcre *regex_EARLY_PIPE = NULL;
const pcre2_code *regex_EARLY_PIPE = NULL;
#endif
const pcre *regex_ismsgid = NULL;
const pcre *regex_smtp_code = NULL;
uschar *regex_vars[REGEX_VARS];
const pcre2_code *regex_ismsgid = NULL;
const pcre2_code *regex_smtp_code = NULL;
const uschar *regex_vars[REGEX_VARS];
#ifdef WHITELIST_D_MACROS
const pcre *regex_whitelisted_macro = NULL;
const pcre2_code *regex_whitelisted_macro = NULL;
#endif
#ifdef WITH_CONTENT_SCAN
uschar *regex_match_string = NULL;
Expand Down Expand Up @@ -1546,19 +1544,6 @@ uschar *spf_smtp_comment_template
FILE *spool_data_file = NULL;
uschar *spool_directory = US SPOOL_DIRECTORY
"\0<--------------Space to patch spool_directory->";
#ifdef EXPERIMENTAL_SRS_ALT
uschar *srs_config = NULL;
uschar *srs_db_address = NULL;
uschar *srs_db_key = NULL;
int srs_hashlength = 6;
int srs_hashmin = -1;
int srs_maxage = 31;
uschar *srs_orig_recipient = NULL;
uschar *srs_orig_sender = NULL;
uschar *srs_recipient = NULL;
uschar *srs_secrets = NULL;
uschar *srs_status = NULL;
#endif
#ifdef SUPPORT_SRS
uschar *srs_recipient = NULL;
#endif
Expand Down Expand Up @@ -1654,7 +1639,7 @@ uschar *uucp_from_sender = US"$1";
uschar *verify_mode = NULL;
uschar *version_copyright =
US"Copyright (c) University of Cambridge, 1995 - 2018\n"
"(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2020";
"(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2022";
uschar *version_date = US"?";
uschar *version_cnumber = US"????";
uschar *version_string = US"?";
Expand Down
85 changes: 43 additions & 42 deletions src/src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* Almost all the global variables are defined together in this one header, so
Expand Down Expand Up @@ -77,10 +77,6 @@ extern int sqlite_lock_timeout; /* Internal lock waiting timeout */
extern BOOL move_frozen_messages; /* Get them out of the normal directory */
#endif

#ifdef ALLOW_INSECURE_TAINTED_DATA
extern BOOL allow_insecure_tainted_data;
#endif

/* These variables are outside the #ifdef because it keeps the code less
cluttered in several places (e.g. during logging) if we can always refer to
them. Also, the tls_ variables are now always visible. */
Expand Down Expand Up @@ -112,6 +108,9 @@ typedef struct {
OCSP_VFIED /* verified */
} ocsp; /* Stapled OCSP status */
#ifndef DISABLE_TLS_RESUME
hctx resume_hctx; /* session lookup key accumulation */
const uschar * resume_index; /* session lookup key */

unsigned resumption; /* Session resumption */
BOOL host_resumable:1;
BOOL ticket_received:1;
Expand All @@ -127,7 +126,7 @@ extern BOOL gnutls_compat_mode; /* Less security, more compatibility */
extern BOOL gnutls_allow_auto_pkcs11; /* Let GnuTLS autoload PKCS11 modules */
extern uschar *hosts_require_alpn; /* Mandatory ALPN successful nogitiation */
extern uschar *openssl_options; /* OpenSSL compatibility options */
extern const pcre *regex_STARTTLS; /* For recognizing STARTTLS settings */
extern const pcre2_code *regex_STARTTLS; /* For recognizing STARTTLS settings */
extern uschar *tls_alpn; /* ALPN names acceptable */
extern uschar *tls_certificate; /* Certificate file */
extern uschar *tls_crl; /* CRL File */
Expand All @@ -153,22 +152,24 @@ extern uschar *tls_advertise_hosts; /* host for which TLS is advertised */

extern uschar *dsn_envid; /* DSN envid string */
extern int dsn_ret; /* DSN ret type*/
extern const pcre *regex_DSN; /* For recognizing DSN settings */
extern const pcre2_code *regex_DSN; /* For recognizing DSN settings */
extern uschar *dsn_advertise_hosts; /* host for which TLS is advertised */

/* Input-reading functions for messages, so we can use special ones for
incoming TCP/IP. */

extern int (*lwr_receive_getc)(unsigned);
extern uschar * (*lwr_receive_getbuf)(unsigned *);
extern BOOL (*lwr_receive_hasc)(void);
extern int (*lwr_receive_ungetc)(int);

extern int (*receive_getc)(unsigned);
extern uschar * (*receive_getbuf)(unsigned *);
extern BOOL (*receive_hasc)(void);
extern void (*receive_get_cache)(unsigned);
extern int (*receive_ungetc)(int);
extern int (*receive_feof)(void);
extern int (*receive_ferror)(void);
extern BOOL (*receive_smtp_buffered)(void);


/* For clearing, saving, restoring address expansion variables. We have to have
Expand Down Expand Up @@ -272,7 +273,7 @@ extern struct global_flags {
BOOL sender_set_untrusted :1; /* Sender set by untrusted caller */
BOOL smtp_authenticated :1; /* Sending client has authenticated */
#ifndef DISABLE_PIPE_CONNECT
BOOL smtp_in_early_pipe_advertised :1; /* server advertised PIPE_CONNECT */
BOOL smtp_in_early_pipe_advertised :1; /* server advertised PIPECONNECT */
BOOL smtp_in_early_pipe_no_auth :1; /* too many authenticator names */
BOOL smtp_in_early_pipe_used :1; /* client did send early data */
#endif
Expand Down Expand Up @@ -320,7 +321,7 @@ extern uschar *acl_smtp_connect; /* ACL run on SMTP connection */
extern uschar *acl_smtp_data; /* ACL run after DATA received */
#ifndef DISABLE_PRDR
extern uschar *acl_smtp_data_prdr; /* ACL run after DATA received if in PRDR mode*/
const extern pcre *regex_PRDR; /* For recognizing PRDR settings */
const extern pcre2_code *regex_PRDR; /* For recognizing PRDR settings */
#endif
#ifndef DISABLE_DKIM
extern uschar *acl_smtp_dkim; /* ACL run for DKIM signatures / domains */
Expand Down Expand Up @@ -366,13 +367,14 @@ extern uschar *authenticated_fail_id; /* ID that failed authentication */
extern uschar *authenticated_id; /* ID that was authenticated */
extern uschar *authenticated_sender; /* From AUTH on MAIL */
extern BOOL authentication_failed; /* TRUE if AUTH was tried and failed */
extern uschar *authenticator_name; /* for debug and error messages */
extern uschar *auth_advertise_hosts; /* Only advertise to these */
extern auth_info auths_available[]; /* Vector of available auth mechanisms */
extern auth_instance *auths; /* Chain of instantiated auths */
extern auth_instance auth_defaults; /* Default values */
extern uschar *auth_defer_msg; /* Error message for log */
extern uschar *auth_defer_user_msg; /* Error message for user */
extern uschar *auth_vars[]; /* $authn variables */
extern const uschar *auth_vars[]; /* $authn variables */
extern int auto_thaw; /* Auto-thaw interval */
#ifdef WITH_CONTENT_SCAN
extern int av_failed; /* TRUE if the AV process failed */
Expand Down Expand Up @@ -422,6 +424,9 @@ extern chunking_state_t chunking_state;
extern uschar *client_authenticator; /* Authenticator name used for smtp delivery */
extern uschar *client_authenticated_id; /* "login" name used for SMTP AUTH */
extern uschar *client_authenticated_sender; /* AUTH option to SMTP MAIL FROM (not yet used) */
#ifndef DISABLE_CLIENT_CMD_LOG
extern gstring *client_cmd_log; /* debug log of client cmds & responses */
#endif
extern int clmacro_count; /* Number of command line macros */
extern uschar *clmacros[]; /* Copy of them, for re-exec */
extern BOOL commandline_checks_require_admin; /* belt and braces for insecure setups */
Expand Down Expand Up @@ -485,7 +490,11 @@ extern FILE *debug_file; /* Where to write debugging info */
extern int debug_notall[]; /* Debug options excluded from +all */
extern bit_table debug_options[]; /* Table of debug options */
extern int debug_options_count; /* Size of table */
extern unsigned debug_pretrigger_bsize;
extern uschar *debug_pretrigger_buf; /* circular buffer for precapture */
extern BOOL debug_store; /* Do extra checks on store_reset */
extern uschar debuglog_name[LOG_NAME_SIZE]; /* ACL-init debug */

extern int delay_warning[]; /* Times between warnings */
extern uschar *delay_warning_condition; /* Condition string for warnings */
extern BOOL delivery_date_remove; /* Remove delivery-date headers */
Expand Down Expand Up @@ -573,6 +582,10 @@ extern int domainlist_count; /* Number defined */

/* This option is now a no-opt, retained for compatibility */
extern BOOL drop_cr; /* For broken local MUAs */
extern const uschar *driver_srcfile; /* For debug & errors */
extern int driver_srcline; /* For debug & errors */

extern unsigned int dtrigger_selector; /* when to start debug */

extern uschar *dsn_from; /* From: string for DSNs */

Expand Down Expand Up @@ -600,7 +613,7 @@ extern int expand_level; /* Nesting depth; indent for debug */
extern int expand_forbid; /* RDO flags for forbidding things */
extern int expand_nlength[]; /* Lengths of numbered strings */
extern int expand_nmax; /* Max numerical value */
extern uschar *expand_nstring[]; /* Numbered strings */
extern const uschar *expand_nstring[]; /* Numbered strings */
extern BOOL extract_addresses_remove_arguments; /* Controls -t behaviour */
extern uschar *extra_local_interfaces; /* Local, non-listen interfaces */

Expand Down Expand Up @@ -724,15 +737,14 @@ extern uschar message_id_option[]; /* -E<message-id> for use as option */
extern uschar *message_id_external; /* External form of following */
extern uschar *message_id_domain; /* Expanded to form domain-part of message_id */
extern uschar *message_id_text; /* Expanded to form message_id */
extern struct timeval message_id_tv; /* Time used to create last message_id */
extern int message_linecount; /* As it says */
extern BOOL message_logs; /* TRUE to write message logs */
extern int message_size; /* Size of message */
extern uschar *message_size_limit; /* As it says */
#ifdef SUPPORT_I18N
extern BOOL message_smtputf8; /* Internationalized mail handling */
extern int message_utf8_downconvert; /* convert from utf8 */
const extern pcre *regex_UTF8; /* For recognizing SMTPUTF8 settings */
const extern pcre2_code *regex_UTF8; /* For recognizing SMTPUTF8 settings */
#endif
extern uschar message_subdir[]; /* Subdirectory for messages */
extern uschar *message_reference; /* Reference for error messages */
Expand Down Expand Up @@ -780,6 +792,10 @@ 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 pcre2_general_context * pcre_gen_ctx; /* pcre memory management */
extern pcre2_compile_context * pcre_cmp_ctx;
extern pcre2_match_context * pcre_mtc_ctx;

extern uschar *percent_hack_domains; /* Local domains for which '% operates */
extern uschar *pid_file_path; /* For writing daemon pids */
#ifndef DISABLE_PIPE_CONNECT
Expand Down Expand Up @@ -866,24 +882,24 @@ extern uschar *recipient_verify_failure; /* What went wrong */
extern int recipients_list_max; /* Maximum number fitting in list */
extern int recipients_max; /* Max permitted */
extern BOOL recipients_max_reject; /* If TRUE, reject whole message */
extern const pcre *regex_AUTH; /* For recognizing AUTH settings */
extern const pcre *regex_check_dns_names; /* For DNS name checking */
extern const pcre *regex_From; /* For recognizing "From_" lines */
extern const pcre *regex_CHUNKING; /* For recognizing CHUNKING (RFC 3030) */
extern const pcre *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
extern const pcre2_code *regex_AUTH; /* For recognizing AUTH settings */
extern const pcre2_code *regex_check_dns_names; /* For DNS name checking */
extern const pcre2_code *regex_From; /* For recognizing "From_" lines */
extern const pcre2_code *regex_CHUNKING; /* For recognizing CHUNKING (RFC 3030) */
extern const pcre2_code *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
#ifdef EXPERIMENTAL_ESMTP_LIMITS
extern const pcre *regex_LIMITS; /* For recognizing LIMITS */
extern const pcre2_code *regex_LIMITS; /* For recognizing LIMITS */
#endif
extern const pcre *regex_PIPELINING; /* For recognizing PIPELINING */
extern const pcre *regex_SIZE; /* For recognizing SIZE settings */
extern const pcre2_code *regex_PIPELINING; /* For recognizing PIPELINING */
extern const pcre2_code *regex_SIZE; /* For recognizing SIZE settings */
#ifndef DISABLE_PIPE_CONNECT
extern const pcre *regex_EARLY_PIPE; /* For recognizing PIPE_CONNCT */
extern const pcre2_code *regex_EARLY_PIPE; /* For recognizing PIPE_CONNCT */
#endif
extern const pcre *regex_ismsgid; /* Compiled r.e. for message it */
extern const pcre *regex_smtp_code; /* For recognizing SMTP codes */
extern uschar *regex_vars[]; /* $regexN variables */
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 pcre *regex_whitelisted_macro; /* For -D macro values */
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) */
Expand Down Expand Up @@ -1020,21 +1036,6 @@ extern BOOL split_spool_directory; /* TRUE to use multiple subdirs */
extern FILE *spool_data_file; /* handle for -D file */
extern uschar *spool_directory; /* Name of spool directory */
extern BOOL spool_wireformat; /* can write wireformat -D files */
#ifdef EXPERIMENTAL_SRS_ALT
extern uschar *srs_config; /* SRS config secret:max age:hash length:use timestamp:use hash */
extern uschar *srs_db_address; /* SRS db address */
extern uschar *srs_db_key; /* SRS db key */
extern int srs_hashlength; /* SRS hash length */
extern int srs_hashmin; /* SRS minimum hash length */
extern int srs_maxage; /* SRS max age */
extern uschar *srs_orig_sender; /* SRS original sender */
extern uschar *srs_orig_recipient; /* SRS original recipient */
extern uschar *srs_recipient; /* SRS recipient */
extern uschar *srs_secrets; /* SRS secrets list */
extern uschar *srs_status; /* SRS staus */
extern BOOL srs_usehash; /* SRS use hash flag */
extern BOOL srs_usetimestamp; /* SRS use timestamp flag */
#endif
#ifdef SUPPORT_SRS
extern uschar *srs_recipient; /* SRS recipient */
#endif
Expand Down
83 changes: 67 additions & 16 deletions src/src/hash.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Exim - an Internet mail transport agent
*
* Copyright (C) 2010 - 2018 Exim maintainers
* Copyright (c) The Exim Maintainers 2010 - 2022
* Copyright (c) University of Cambridge 1995 - 2009
*
* Hash interface functions
Expand Down Expand Up @@ -29,17 +29,19 @@ sha1;

/******************************************************************************/
#ifdef SHA_OPENSSL
# define HAVE_PARTIAL_SHA

BOOL
exim_sha_init(hctx * h, hashmethod m)
{
# if OPENSSL_VERSION_NUMBER < 0x30000000L
switch (h->method = m)
{
case HASH_SHA1: h->hashlen = 20; SHA1_Init (&h->u.sha1); break;
case HASH_SHA2_256: h->hashlen = 32; SHA256_Init(&h->u.sha2_256); break;
case HASH_SHA2_384: h->hashlen = 48; SHA384_Init(&h->u.sha2_512); break;
case HASH_SHA2_512: h->hashlen = 64; SHA512_Init(&h->u.sha2_512); break;
#ifdef EXIM_HAVE_SHA3
# ifdef EXIM_HAVE_SHA3
case HASH_SHA3_224: h->hashlen = 28;
EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_224());
break;
Expand All @@ -52,59 +54,100 @@ switch (h->method = m)
case HASH_SHA3_512: h->hashlen = 64;
EVP_DigestInit(h->u.mctx = EVP_MD_CTX_new(), EVP_sha3_512());
break;
#endif
# endif
default: h->hashlen = 0; return FALSE;
}
return TRUE;

# else
EVP_MD * md;

h->hashlen = 0;
if (!(h->u.mctx = EVP_MD_CTX_new())) return FALSE;
switch (h->method = m)
{
case HASH_SHA1: h->hashlen = 20; md = EVP_MD_fetch(NULL, "SHA1", NULL); break;
case HASH_SHA2_256: h->hashlen = 32; md = EVP_MD_fetch(NULL, "SHA2-256", NULL); break;
case HASH_SHA2_384: h->hashlen = 48; md = EVP_MD_fetch(NULL, "SHA2-384", NULL); break;
case HASH_SHA2_512: h->hashlen = 64; md = EVP_MD_fetch(NULL, "SHA2-512", NULL); break;
case HASH_SHA3_224: h->hashlen = 28; md = EVP_MD_fetch(NULL, "SHA3-224", NULL); break;
case HASH_SHA3_256: h->hashlen = 32; md = EVP_MD_fetch(NULL, "SHA3-256", NULL); break;
case HASH_SHA3_384: h->hashlen = 48; md = EVP_MD_fetch(NULL, "SHA3-384", NULL); break;
case HASH_SHA3_512: h->hashlen = 64; md = EVP_MD_fetch(NULL, "SHA3-512", NULL); break;
default: return FALSE;
}
if (md && EVP_DigestInit_ex(h->u.mctx, md, NULL))
return TRUE;

h->hashlen = 0;
return FALSE;
# endif
}


void
exim_sha_update(hctx * h, const uschar * data, int len)
{
# if OPENSSL_VERSION_NUMBER < 0x30000000L
switch (h->method)
{
case HASH_SHA1: SHA1_Update (&h->u.sha1, data, len); break;
case HASH_SHA2_256: SHA256_Update(&h->u.sha2_256, data, len); break;
case HASH_SHA2_384: SHA384_Update(&h->u.sha2_512, data, len); break;
case HASH_SHA2_512: SHA512_Update(&h->u.sha2_512, data, len); break;
#ifdef EXIM_HAVE_SHA3
# ifdef EXIM_HAVE_SHA3
case HASH_SHA3_224:
case HASH_SHA3_256:
case HASH_SHA3_384:
case HASH_SHA3_512: EVP_DigestUpdate(h->u.mctx, data, len); break;
#endif
# endif
/* should be blocked by init not handling these, but be explicit to
guard against accidents later (and hush up clang -Wswitch) */
default: assert(0);
}

# else

EVP_DigestUpdate(h->u.mctx, data, len);
# endif
}


void
exim_sha_finish(hctx * h, blob * b)
{
/* Hashing is sufficient to purify any tainted input */
b->data = store_get(b->len = h->hashlen, FALSE);
b->data = store_get(b->len = h->hashlen, GET_UNTAINTED);

# if OPENSSL_VERSION_NUMBER < 0x30000000L
switch (h->method)
{
case HASH_SHA1: SHA1_Final (b->data, &h->u.sha1); break;
case HASH_SHA2_256: SHA256_Final(b->data, &h->u.sha2_256); break;
case HASH_SHA2_384: SHA384_Final(b->data, &h->u.sha2_512); break;
case HASH_SHA2_512: SHA512_Final(b->data, &h->u.sha2_512); break;
#ifdef EXIM_HAVE_SHA3
# ifdef EXIM_HAVE_SHA3
case HASH_SHA3_224:
case HASH_SHA3_256:
case HASH_SHA3_384:
case HASH_SHA3_512: EVP_DigestFinal(h->u.mctx, b->data, NULL); break;
#endif
# endif
default: assert(0);
}

# else

EVP_DigestFinal_ex(h->u.mctx, b->data, NULL);
EVP_MD_free((EVP_MD *) EVP_MD_CTX_get0_md(h->u.mctx));
EVP_MD_CTX_free(h->u.mctx);

# endif
}



#elif defined(SHA_GNUTLS)
# define HAVE_PARTIAL_SHA
/******************************************************************************/

BOOL
Expand Down Expand Up @@ -138,13 +181,14 @@ gnutls_hash(h->sha, data, len);
void
exim_sha_finish(hctx * h, blob * b)
{
b->data = store_get(b->len = h->hashlen, FALSE);
b->data = store_get(b->len = h->hashlen, GET_UNTAINTED);
gnutls_hash_output(h->sha, b->data);
}



#elif defined(SHA_GCRYPT)
# define HAVE_PARTIAL_SHA
/******************************************************************************/

BOOL
Expand Down Expand Up @@ -175,14 +219,15 @@ gcry_md_write(h->sha, data, len);
void
exim_sha_finish(hctx * h, blob * b)
{
b->data = store_get(b->len = h->hashlen, FALSE);
b->data = store_get(b->len = h->hashlen, GET_UNTAINTED);
memcpy(b->data, gcry_md_read(h->sha, 0), h->hashlen);
}




#elif defined(SHA_POLARSSL)
# define HAVE_PARTIAL_SHA
/******************************************************************************/

BOOL
Expand Down Expand Up @@ -213,7 +258,7 @@ switch (h->method)
void
exim_sha_finish(hctx * h, blob * b)
{
b->data = store_get(b->len = h->hashlen, FALSE);
b->data = store_get(b->len = h->hashlen, GET_INTAINTED);
switch (h->method)
{
case HASH_SHA1: sha1_finish(h->u.sha1, b->data); break;
Expand Down Expand Up @@ -391,9 +436,7 @@ if (length > 55)
memset(work, 0, 56);
}
else
{
memset(work+length+1, 0, 55-length);
}

/* The final 8 bytes of the final chunk are a 64-bit representation of the
length of the input string *bits*, before padding, high order word first, and
Expand Down Expand Up @@ -451,7 +494,7 @@ native_sha1_mid(&h->sha1, US data); /* implicit size always 64 */
void
exim_sha_finish(hctx * h, blob * b)
{
b->data = store_get(b->len = h->hashlen, FALSE);
b->data = store_get(b->len = h->hashlen, GET_UNTAINTED);

native_sha1_end(&h->sha1, NULL, 0, b->data);
}
Expand Down Expand Up @@ -515,6 +558,14 @@ memcpy(digest, b.data, 20);



#ifdef HAVE_PARTIAL_SHA
# undef HAVE_PARTIAL_SHA
void
exim_sha_update_string(hctx * h, const uschar * s)
{
if (s) exim_sha_update(h, s, Ustrlen(s));
}
#endif



Expand All @@ -524,7 +575,7 @@ memcpy(digest, b.data, 20);
**************************************************
*************************************************/

# ifdef STAND_ALONE
#ifdef STAND_ALONE

/* Test values. The first 128 may contain binary zeros and have increasing
length. */
Expand Down Expand Up @@ -839,6 +890,6 @@ printf("Computed: %s\n", s);
if (strcmp(s, atest) != 0) printf("*** No match ***\n");

}
# endif /*STAND_ALONE*/
#endif /*STAND_ALONE*/

/* End of File */
4 changes: 2 additions & 2 deletions src/src/hash.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/*
* Exim - an Internet mail transport agent
*
* Copyright (C) 1995 - 2018 Exim maintainers
* Copyright (c) The Exim Maintainers 1995 - 2022
*
* Hash interface functions
*/
Expand Down Expand Up @@ -77,6 +76,7 @@ typedef struct {

extern BOOL exim_sha_init(hctx *, hashmethod);
extern void exim_sha_update(hctx *, const uschar *a, int);
extern void exim_sha_update_string(hctx *, const uschar *a);
extern void exim_sha_finish(hctx *, blob *);

#endif
Expand Down
22 changes: 10 additions & 12 deletions src/src/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2016 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */


Expand Down Expand Up @@ -102,7 +102,7 @@ gstring gs;

if (!header_last) return NULL;

gs.s = buf = store_get(HEADER_ADD_BUFFER_SIZE, FALSE);
gs.s = buf = store_get(HEADER_ADD_BUFFER_SIZE, GET_UNTAINTED);
gs.size = HEADER_ADD_BUFFER_SIZE;
gs.ptr = 0;

Expand Down Expand Up @@ -182,7 +182,7 @@ for (p = q = gs.s; *p; p = q)
if (*(++q) != ' ' && *q != '\t') break;
}

new = store_get(sizeof(header_line), FALSE);
new = store_get(sizeof(header_line), GET_UNTAINTED);
new->text = string_copyn(p, q - p);
new->slen = q - p;
new->type = type;
Expand Down Expand Up @@ -371,7 +371,7 @@ static BOOL
one_pattern_match(uschar *name, int slen, BOOL has_addresses, uschar *pattern)
{
BOOL yield = FALSE;
const pcre *re = NULL;
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. */
Expand Down Expand Up @@ -419,10 +419,9 @@ for (header_line * h = header_list; !yield && h; h = h->next)

/* Otherwise, test for the pattern; a non-regex must be an exact match */

yield = !re
? (strcmpic(next, pattern) == 0)
: (pcre_exec(re, NULL, CS next, Ustrlen(next), 0, PCRE_EOPT, NULL, 0)
>= 0);
yield = re
? regex_match(re, next, -1, NULL)
: (strcmpic(next, pattern) == 0);
}
}

Expand All @@ -431,10 +430,9 @@ for (header_line * h = header_list; !yield && h; h = h->next)

else
{
yield = (re == NULL)?
(strstric(h->text, pattern, FALSE) != NULL)
:
(pcre_exec(re, NULL, CS h->text, h->slen, 0, PCRE_EOPT, NULL, 0) >= 0);
yield = re
? regex_match(re, h->text, h->slen, NULL)
: (strstric(h->text, pattern, FALSE) != NULL);
}
}

Expand Down
810 changes: 810 additions & 0 deletions src/src/hintsdb.h

Large diffs are not rendered by default.

189 changes: 189 additions & 0 deletions src/src/hintsdb_structs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */

/* 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
maintenance utilities as well as the main Exim binary. */

#ifndef HINTSDB_STRUCTS_H
#define HINTSDB_STRUCTS_H


/* Structure for carrying around an open DBM file, and an open locking file
that relates to it. */

typedef struct {
void * dbptr;
int lockfd;
} open_db;


/* Structures for records stored in exim database dbm files. They all
start with the same fields, described in the generic type. */


typedef struct {
time_t time_stamp; /* Timestamp of writing */
} dbdata_generic;


/* This structure keeps track of retry information for a host or a local
address. */

typedef struct {
time_t time_stamp;
/*************/
time_t first_failed; /* Time of first failure */
time_t last_try; /* Time of last try */
time_t next_try; /* Time of next try */
BOOL expired; /* Retry time has expired */
int basic_errno; /* Errno of last failure */
int more_errno; /* Additional information */
uschar text[1]; /* Text message for last failure */
} dbdata_retry;

/* These structures keep track of addresses that have had callout verification
performed on them. There are two groups of records:
1. keyed by localpart@domain -
Full address was tested and record holds result
2. keyed by domain -
Domain response upto MAIL FROM:<>, postmaster, random local part;
If a record exists, the result field is either ccache_accept or ccache_reject,
or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
rejected. The other fields, however, (which are only relevant to domain
records) may also contain ccache_unknown if that particular test has not been
done.
Originally, there was only one structure, used for both types. However, it got
expanded for domain records, so it got split. To make it possible for Exim to
handle the old type of record, we retain the old definition. The different
kinds of record can be distinguished by their different lengths. */

typedef struct {
time_t time_stamp;
/*************/
int result;
int postmaster_result; /* Postmaster is accepted */
int random_result; /* Random local part was accepted */
} dbdata_callout_cache_obs;

typedef struct {
time_t time_stamp; /* Timestamp of last address check */
/*************/
int result; /* accept or reject */
} dbdata_callout_cache_address;

/* For this new layout, we put the additional fields (the timestamps)
last so that if somebody reverts to an older Exim, the new records will
still make sense because they match the old layout. */

typedef struct {
time_t time_stamp; /* Time stamp of last connection */
/*************/
int result; /* Domain reject or accept */
int postmaster_result; /* Postmaster result */
int random_result; /* Random result */
time_t postmaster_stamp; /* Timestamp of postmaster check */
time_t random_stamp; /* Timestamp of random check */
} dbdata_callout_cache;

/* This structure keeps track of messages that are waiting for a particular
host for a particular transport. */

typedef struct {
time_t time_stamp;
/*************/
int count; /* Count of message ids */
int sequence; /* Sequence for continued records */
uschar text[1]; /* One long character string */
} dbdata_wait;


/* The contents of the "misc" database are a mixture of different kinds of
record, as defined below. The keys used for a specific type all start with a
given string such as "etrn-" or "host-serialize-". */


/* This structure records a connection to a particular host, for the
purpose of serializing access to certain hosts. For possible future extension,
a field is defined for holding the count of connections, but it is not
at present in use. The same structure is used for recording a running ETRN
process. */

typedef struct {
time_t time_stamp;
/*************/
int count; /* Reserved for possible connection count */
} dbdata_serialize;


/* This structure records the information required for the ratelimit
ACL condition. */

typedef struct {
time_t time_stamp;
/*************/
int time_usec; /* Fractional part of time, from gettimeofday() */
double rate; /* Smoothed sending rate at that time */
} dbdata_ratelimit;

/* Same as above, plus a Bloom filter for uniquifying events. */

typedef struct {
dbdata_ratelimit dbd;
time_t bloom_epoch; /* When the Bloom filter was last reset */
unsigned bloom_size; /* Number of bytes in the Bloom filter */
uschar bloom[40]; /* Bloom filter which may be larger than this */
} dbdata_ratelimit_unique;


/* For "seen" ACL condition */
typedef struct {
time_t time_stamp;
} dbdata_seen;

#ifndef DISABLE_PIPE_CONNECT
/* This structure records the EHLO responses, cleartext and crypted,
for an IP, as bitmasks (cf. OPTION_TLS). For LIMITS, also values
advertised for MAILMAX, RCPTMAX and RCPTDOMAINMAX; zero meaning no
value advertised. */

typedef struct {
unsigned short cleartext_features;
unsigned short crypted_features;
unsigned short cleartext_auths;
unsigned short crypted_auths;

# ifdef EXPERIMENTAL_ESMTP_LIMITS
unsigned int limit_mail;
unsigned int limit_rcpt;
unsigned int limit_rcptdom;
# endif
} ehlo_resp_precis;

typedef struct {
time_t time_stamp;
/*************/
ehlo_resp_precis data;
} dbdata_ehlo_resp;
#endif

typedef struct {
time_t time_stamp;
/*************/
uschar verify_override:1;
uschar ocsp:3;
uschar session[1];
} dbdata_tls_session;


#endif /* whole file */
/* End of hintsdb_structs.h */
52 changes: 27 additions & 25 deletions src/src/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
Expand Down Expand Up @@ -197,9 +197,9 @@ if ((ipa = string_is_ip_address(lname, NULL)) != 0)
|| ipa == 6 && af == AF_INET6)
{
int x[4];
yield = store_get(sizeof(struct hostent), FALSE);
alist = store_get(2 * sizeof(char *), FALSE);
adds = store_get(alen, FALSE);
yield = store_get(sizeof(struct hostent), GET_UNTAINTED);
alist = store_get(2 * sizeof(char *), GET_UNTAINTED);
adds = store_get(alen, GET_UNTAINTED);
yield->h_name = CS name;
yield->h_aliases = NULL;
yield->h_addrtype = af;
Expand Down Expand Up @@ -251,9 +251,9 @@ else
rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == type)
count++;

yield = store_get(sizeof(struct hostent), FALSE);
alist = store_get((count + 1) * sizeof(char *), FALSE);
adds = store_get(count *alen, FALSE);
yield = store_get(sizeof(struct hostent), GET_UNTAINTED);
alist = store_get((count + 1) * sizeof(char *), GET_UNTAINTED);
adds = store_get(count *alen, GET_UNTAINTED);

yield->h_name = CS name;
yield->h_aliases = NULL;
Expand Down Expand Up @@ -328,12 +328,12 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0)))
continue;
}

h = store_get(sizeof(host_item), FALSE);
h = store_get(sizeof(host_item), GET_UNTAINTED);
h->name = name;
h->address = NULL;
h->port = PORT_NONE;
h->mx = fake_mx;
h->sort_key = randomize? (-fake_mx)*1000 + random_number(1000) : 0;
h->sort_key = randomize ? (-fake_mx)*1000 + random_number(1000) : 0;
h->status = hstatus_unknown;
h->why = hwhy_unknown;
h->last_try = 0;
Expand Down Expand Up @@ -370,15 +370,18 @@ while ((name = string_nextinlist(&list, &sep, NULL, 0)))
* 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.
/* 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,
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
Expand Down Expand Up @@ -732,7 +735,6 @@ host_build_ifacelist(const uschar *list, uschar *name)
int sep = 0;
uschar *s;
ip_address_item * yield = NULL, * last = NULL, * next;
BOOL taint = is_tainted(list);

while ((s = string_nextinlist(&list, &sep, NULL, 0)))
{
Expand All @@ -751,7 +753,7 @@ while ((s = string_nextinlist(&list, &sep, NULL, 0)))
address above. The field in the ip_address_item is large enough to hold an
IPv6 address. */

next = store_get(sizeof(ip_address_item), taint);
next = store_get(sizeof(ip_address_item), list);
next->next = NULL;
Ustrcpy(next->address, s);
next->port = port;
Expand Down Expand Up @@ -915,14 +917,14 @@ if (type < 0)
struct sockaddr_in6 *sk = (struct sockaddr_in6 *)arg;
yield = US inet_ntop(family, &(sk->sin6_addr), CS addr_buffer,
sizeof(addr_buffer));
if (portptr != NULL) *portptr = ntohs(sk->sin6_port);
if (portptr) *portptr = ntohs(sk->sin6_port);
}
else
{
struct sockaddr_in *sk = (struct sockaddr_in *)arg;
yield = US inet_ntop(family, &(sk->sin_addr), CS addr_buffer,
sizeof(addr_buffer));
if (portptr != NULL) *portptr = ntohs(sk->sin_port);
if (portptr) *portptr = ntohs(sk->sin_port);
}
}
else
Expand All @@ -941,15 +943,15 @@ if (Ustrncmp(yield, "::ffff:", 7) == 0) yield += 7;
if (type < 0)
{
yield = US inet_ntoa(((struct sockaddr_in *)arg)->sin_addr);
if (portptr != NULL) *portptr = ntohs(((struct sockaddr_in *)arg)->sin_port);
if (portptr) *portptr = ntohs(((struct sockaddr_in *)arg)->sin_port);
}
else
yield = US inet_ntoa(*((struct in_addr *)arg));
#endif

/* If there is no buffer, put the string into some new store. */

if (!buffer) buffer = store_get(46, FALSE);
if (!buffer) buffer = store_get(46, GET_UNTAINTED);

/* Callers of this function with a non-NULL buffer must ensure that it is
large enough to hold an IPv6 address, namely, at least 46 bytes. That's what
Expand Down Expand Up @@ -1587,7 +1589,7 @@ Put it in permanent memory. */

for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++) count++;
store_pool = POOL_PERM;
ptr = sender_host_aliases = store_get(count * sizeof(uschar *), FALSE);
ptr = sender_host_aliases = store_get(count * sizeof(uschar *), GET_UNTAINTED);
store_pool = POOL_TAINT_PERM;

for (uschar ** aliases = USS hosts->h_aliases; *aliases; aliases++)
Expand Down Expand Up @@ -1709,15 +1711,15 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0)))
/* Get store for the list of aliases. For compatibility with
gethostbyaddr, we make an empty list if there are none. */

aptr = sender_host_aliases = store_get(count * sizeof(uschar *), FALSE);
aptr = sender_host_aliases = store_get(count * sizeof(uschar *), GET_UNTAINTED);

/* Re-scan and extract the names */

for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
rr;
rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
{
uschar * s = store_get(ssize, TRUE); /* names are tainted */
uschar * s = store_get(ssize, GET_TAINTED); /* names are tainted */

/* If an overlong response was received, the data will have been
truncated and dn_expand may fail. */
Expand Down Expand Up @@ -2119,7 +2121,7 @@ for (int i = 1; i <= times;

else
{
host_item *next = store_get(sizeof(host_item), FALSE);
host_item *next = store_get(sizeof(host_item), GET_UNTAINTED);
next->name = host->name;
#ifndef DISABLE_TLS
next->certname = host->certname;
Expand Down Expand Up @@ -2456,7 +2458,7 @@ for (; i >= 0; i--)
/* Not a duplicate */

new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
next = store_get(sizeof(host_item), FALSE);
next = store_get(sizeof(host_item), GET_UNTAINTED);

/* New address goes first: insert the new block after the first one
(so as not to disturb the original pointer) but put the new address
Expand Down Expand Up @@ -2863,7 +2865,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
/* Make a new host item and seek the correct insertion place */
{
int sort_key = precedence * 1000 + weight;
host_item *next = store_get(sizeof(host_item), FALSE);
host_item * next = store_get(sizeof(host_item), GET_UNTAINTED);
next->name = string_copy_dnsdomain(data);
next->address = NULL;
next->port = port;
Expand Down
14 changes: 4 additions & 10 deletions src/src/ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions for doing things with sockets. With the advent of IPv6 this has
Expand Down Expand Up @@ -589,9 +589,7 @@ Returns: TRUE => ready for i/o
BOOL
fd_ready(int fd, time_t timelimit)
{
fd_set select_inset;
int time_left = timelimit - time(NULL);
int rc;
int rc, time_left = timelimit - time(NULL);

if (time_left <= 0)
{
Expand All @@ -602,12 +600,8 @@ if (time_left <= 0)

do
{
struct timeval tv = { .tv_sec = time_left, .tv_usec = 0 };
FD_ZERO (&select_inset);
FD_SET (fd, &select_inset);

/*DEBUG(D_transport) debug_printf("waiting for data on fd\n");*/
rc = select(fd + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv);
rc = poll_one_fd(fd, POLLIN, time_left * 1000);

/* If some interrupt arrived, just retry. We presume this to be rare,
but it can happen (e.g. the SIGUSR1 signal sent by exiwhat causes
Expand Down Expand Up @@ -636,7 +630,7 @@ do
/* Checking the FD_ISSET is not enough, if we're interrupted, the
select_inset may still contain the 'input'. */
}
while (rc < 0 || !FD_ISSET(fd, &select_inset));
while (rc < 0);
return TRUE;
}

Expand Down
1 change: 1 addition & 0 deletions src/src/local_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 2009 */
/* Copyright (c) The Exim Maintainers 2021 */
/* See the file NOTICE for conditions of use and distribution. */


Expand Down
25 changes: 13 additions & 12 deletions src/src/local_scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2020 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* This file is the header that is the only Exim header to be included in the
Expand Down Expand Up @@ -40,8 +40,8 @@ ABI is changed in a non backward compatible way. The minor number is increased
each time a new feature is added (in a way that doesn't break backward
compatibility). */

#define LOCAL_SCAN_ABI_VERSION_MAJOR 4
#define LOCAL_SCAN_ABI_VERSION_MINOR 1
#define LOCAL_SCAN_ABI_VERSION_MAJOR 6
#define LOCAL_SCAN_ABI_VERSION_MINOR 0
#define LOCAL_SCAN_ABI_VERSION \
LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR

Expand Down Expand Up @@ -160,7 +160,7 @@ extern unsigned int debug_selector; /* Debugging bits */
extern int body_linecount; /* Line count in body */
extern int body_zerocount; /* Binary zero count in body */
extern uschar *expand_string_message; /* Error info for failing expansion */
extern uschar *headers_charset; /* Charset for RFC 2047 decoding */
extern const uschar *headers_charset; /* Charset for RFC 2047 decoding */
extern header_line *header_last; /* Final header */
extern header_line *header_list; /* First header */
extern BOOL host_checking; /* Set when checking a host */
Expand Down Expand Up @@ -198,7 +198,8 @@ extern int lss_match_address(uschar *, uschar *, BOOL);
extern int lss_match_host(uschar *, uschar *, uschar *);
extern void receive_add_recipient(uschar *, int);
extern BOOL receive_remove_recipient(uschar *);
extern uschar *rfc2047_decode(uschar *, BOOL, uschar *, int, int *, uschar **);
extern uschar *rfc2047_decode(uschar *, BOOL, const uschar *, int, int *,
uschar **);
extern int smtp_fflush(void);
extern void smtp_printf(const char *, BOOL, ...) PRINTF_FUNCTION(1,3);
extern void smtp_vprintf(const char *, BOOL, va_list);
Expand All @@ -207,12 +208,12 @@ extern void smtp_vprintf(const char *, BOOL, va_list);
string_sprintf_trc(fmt, US __FUNCTION__, __LINE__, __VA_ARGS__)
extern uschar *string_sprintf_trc(const char *, const uschar *, unsigned, ...) ALMOST_PRINTF(1,4);

#define store_get(size, tainted) \
store_get_3(size, tainted, __FUNCTION__, __LINE__)
extern void *store_get_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT;
#define store_get_perm(size, tainted) \
store_get_perm_3(size, tainted, __FUNCTION__, __LINE__)
extern void *store_get_perm_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT;
#define store_get(size, proto_mem) \
store_get_3((size), (proto_mem), __FUNCTION__, __LINE__)
extern void *store_get_3(int, const void *, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT;
#define store_get_perm(size, proto_mem) \
store_get_perm_3((size), (proto_mem), __FUNCTION__, __LINE__)
extern void *store_get_perm_3(int, const void *, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT;


#if defined(LOCAL_SCAN) || defined(DLFUNC_IMPL)
Expand All @@ -229,7 +230,7 @@ with the original name. */

extern uschar * string_copy_function(const uschar *);
extern uschar * string_copyn_function(const uschar *, int n);
extern uschar * string_copy_taint_function(const uschar *, BOOL tainted);
extern uschar * string_copy_taint_function(const uschar *, const void * proto_mem);
extern pid_t child_open_exim_function(int *, const uschar *);
extern pid_t child_open_exim2_function(int *, uschar *, uschar *, const uschar *);
extern pid_t child_open_function(uschar **, uschar **, int, int *, int *, BOOL, const uschar *);
Expand Down
317 changes: 168 additions & 149 deletions src/src/log.c

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/src/lookupapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2022 */
/* Copyright (c) University of Cambridge 1995 - 2015 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */


Expand Down Expand Up @@ -42,16 +42,19 @@ typedef struct lookup_info {
void (*tidy)(void); /* tidy function */
uschar *(*quote)( /* quoting function */
uschar *, /* string to quote */
uschar *); /* additional data from quote name */
void (*version_report)( /* diagnostic function */
FILE *); /* fh to write to */
uschar *, /* additional data from quote name */
unsigned); /* lookup type index */
gstring * (*version_report)( /* diagnostic function */
gstring *); /* string to appand to */
} lookup_info;

/* This magic number is used by the following lookup_module_info structure
for checking API compatibility. It used to be equivalent to the string"LMM3" */
#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4933
#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4935
/* Version 2 adds: version_report */
/* Version 3 change: non/cache becomes TTL in seconds */
/* Version 4 add: index on quoting function */
/* Version 5 change: version report now adds to a gstring */

typedef struct lookup_module_info {
uint magic;
Expand Down
2 changes: 2 additions & 0 deletions src/src/lookups/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Make file for building Exim's lookup modules.
# This is called from the main make file, after cd'ing
# to the lookups subdirectory.
#
# Copyright (c) The Exim Maintainers 2021

# nb: at build time, the version of this file used will have had some
# extra variable definitions and prepended to it and module build rules
Expand Down
19 changes: 10 additions & 9 deletions src/src/lookups/cdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* Exim - CDB database lookup module
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* Copyright (c) The Exim Maintainers 2020 - 2022
* Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd
* Copyright (c) The Exim Maintainers 2020
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -178,7 +178,7 @@ if (statbuf.st_size < CDB_HASH_TABLE)
}

/* Having got a file open we need the structure to put things in */
cdbp = store_get(sizeof(struct cdb_state), FALSE);
cdbp = store_get(sizeof(struct cdb_state), GET_UNTAINTED);
/* store_get() does not return if memory was not available... */
/* preload the structure.... */
cdbp->fileno = fileno;
Expand Down Expand Up @@ -213,7 +213,7 @@ DEBUG(D_lookup) debug_printf_indent("cdb mmap failed - %d\n", errno);
/* get a buffer to stash the basic offsets in - this should speed
things up a lot - especially on multiple lookups */

cdbp->cdb_offsets = store_get(CDB_HASH_TABLE, FALSE);
cdbp->cdb_offsets = store_get(CDB_HASH_TABLE, GET_UNTAINTED);

/* now fill the buffer up... */

Expand Down Expand Up @@ -343,7 +343,7 @@ if (cdbp->cdb_map != NULL)
/* ... and the returned result. Assume it is not
tainted, lacking any way of telling. */

*result = store_get(item_dat_len + 1, FALSE);
*result = store_get(item_dat_len + 1, GET_UNTAINTED);
memcpy(*result, item_ptr, item_dat_len);
(*result)[item_dat_len] = 0;
return OK;
Expand Down Expand Up @@ -387,7 +387,7 @@ for (int loop = 0; (loop < hash_offlen); ++loop)
if (item_key_len == key_len)
{ /* finally check if key matches */
rmark reset_point = store_mark();
uschar * item_key = store_get(key_len, TRUE); /* keys liable to be tainted */
uschar * item_key = store_get(key_len, GET_TAINTED); /* keys liable to be tainted */

if (cdb_bread(cdbp->fileno, item_key, key_len) == -1) return DEFER;
if (Ustrncmp(keystring, item_key, key_len) == 0)
Expand All @@ -401,7 +401,7 @@ for (int loop = 0; (loop < hash_offlen); ++loop)
/* then we build a new result string. We know we have enough
memory so disable Coverity errors about the tainted item_dat_ken */

*result = store_get(item_dat_len + 1, FALSE);
*result = store_get(item_dat_len + 1, GET_UNTAINTED);
/* coverity[tainted_data] */
if (cdb_bread(cdbp->fileno, *result, item_dat_len) == -1)
return DEFER;
Expand Down Expand Up @@ -458,12 +458,13 @@ if (cdbp->cdb_map)

#include "../version.h"

void
cdb_version_report(FILE *f)
gstring *
cdb_version_report(gstring * g)
{
#ifdef DYNLOOKUP
fprintf(f, "Library version: CDB: Exim version %s\n", EXIM_VERSION_STR);
g = string_fmt_append(g, "Library version: CDB: Exim version %s\n", EXIM_VERSION_STR);
#endif
return g;
}


Expand Down
34 changes: 18 additions & 16 deletions src/src/lookups/dbmdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

#include "../exim.h"
Expand All @@ -21,11 +21,10 @@ dbmdb_open(const uschar * filename, uschar ** errmsg)
{
uschar * dirname = string_copy(filename);
uschar * s;
EXIM_DB *yield = NULL;
EXIM_DB * yield = NULL;

if ((s = Ustrrchr(dirname, '/'))) *s = '\0';
EXIM_DBOPEN(filename, dirname, O_RDONLY, 0, &yield);
if (!yield)
if (!(yield = exim_dbopen(filename, dirname, O_RDONLY, 0)))
*errmsg = string_open_failed("%s as a %s file", filename, EXIM_DBTYPE);
return yield;
}
Expand Down Expand Up @@ -93,15 +92,17 @@ dbmdb_find(void * handle, const uschar * filename, const uschar * keystring,
EXIM_DB *d = (EXIM_DB *)handle;
EXIM_DATUM key, data;

EXIM_DATUM_INIT(key); /* Some DBM libraries require datums to */
EXIM_DATUM_INIT(data); /* be cleared before use. */
EXIM_DATUM_DATA(key) = CS keystring;
EXIM_DATUM_SIZE(key) = length + 1;
exim_datum_init(&key); /* Some DBM libraries require datums to */
exim_datum_init(&data); /* be cleared before use. */
length++;
exim_datum_data_set(&key,
memcpy(store_get(length, keystring), keystring, length)); /* key can have embedded NUL */
exim_datum_size_set(&key, length);

if (EXIM_DBGET(d, key, data))
if (exim_dbget(d, &key, &data))
{
*result = string_copyn(US EXIM_DATUM_DATA(data), EXIM_DATUM_SIZE(data));
EXIM_DATUM_FREE(data); /* Some DBM libraries need a free() call */
*result = string_copyn(exim_datum_data_get(&data), exim_datum_size_get(&data));
exim_datum_free(&data); /* Some DBM libraries need a free() call */
return OK;
}
return FAIL;
Expand Down Expand Up @@ -149,7 +150,7 @@ int buflen, bufleft, key_item_len, sep = 0;
or less than, the length of the delimited list passed in + 1. */

buflen = length + 3;
key_buffer = store_get(buflen, is_tainted(keystring));
key_buffer = store_get(buflen, keystring);

key_buffer[0] = '\0';

Expand Down Expand Up @@ -214,7 +215,7 @@ return dbmdb_find(handle, filename, key_buffer, key_item_len - 1,
void
static dbmdb_close(void *handle)
{
EXIM_DBCLOSE((EXIM_DB *)handle);
exim_dbclose((EXIM_DB *)handle);
}


Expand All @@ -227,12 +228,13 @@ EXIM_DBCLOSE((EXIM_DB *)handle);

#include "../version.h"

void
dbm_version_report(FILE *f)
gstring *
dbm_version_report(gstring * g)
{
#ifdef DYNLOOKUP
fprintf(f, "Library version: DBM: Exim version %s\n", EXIM_VERSION_STR);
g = string_fmt_append(g, "Library version: DBM: Exim version %s\n", EXIM_VERSION_STR);
#endif
return g;
}


Expand Down
9 changes: 5 additions & 4 deletions src/src/lookups/dnsdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

#include "../exim.h"
Expand Down Expand Up @@ -580,12 +580,13 @@ return rc;

#include "../version.h"

void
dnsdb_version_report(FILE *f)
gstring *
dnsdb_version_report(gstring * g)
{
#ifdef DYNLOOKUP
fprintf(f, "Library version: DNSDB: Exim version %s\n", EXIM_VERSION_STR);
g = string_fmt_append(g, "Library version: DNSDB: Exim version %s\n", EXIM_VERSION_STR);
#endif
return g;
}


Expand Down
11 changes: 6 additions & 5 deletions src/src/lookups/dsearch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2015 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* The idea for this code came from Matthew Byng-Maddick, but his original has
Expand Down Expand Up @@ -124,7 +124,7 @@ if ( Ulstat(filename, &statbuf) >= 0
{
/* Since the filename exists in the filesystem, we can return a
non-tainted result. */
*result = string_copy_taint(flags & RET_FULL ? filename : keystring, FALSE);
*result = string_copy_taint(flags & RET_FULL ? filename : keystring, GET_UNTAINTED);
return OK;
}

Expand Down Expand Up @@ -158,12 +158,13 @@ handle = handle; /* Avoid compiler warning */

#include "../version.h"

void
dsearch_version_report(FILE *f)
gstring *
dsearch_version_report(gstring * g)
{
#ifdef DYNLOOKUP
fprintf(f, "Library version: dsearch: Exim version %s\n", EXIM_VERSION_STR);
g = string_fmt_append(g, "Library version: dsearch: Exim version %s\n", EXIM_VERSION_STR);
#endif
return g;
}


Expand Down
98 changes: 40 additions & 58 deletions src/src/lookups/ibase.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */

/* The code in this module was contributed by Ard Biesheuvel. */
Expand Down Expand Up @@ -177,7 +177,7 @@ if (cn)
}
else
{
cn = store_get(sizeof(ibase_connection), FALSE);
cn = store_get(sizeof(ibase_connection), GET_UNTAINTED);
cn->server = server_copy;
cn->dbh = NULL;
cn->transh = NULL;
Expand Down Expand Up @@ -252,7 +252,7 @@ if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth))

/* Lacking any information, assume that the data is untainted */
reset_point = store_mark();
out_sqlda = store_get(XSQLDA_LENGTH(1), FALSE);
out_sqlda = store_get(XSQLDA_LENGTH(1), GET_UNTAINTED);
out_sqlda->version = SQLDA_VERSION1;
out_sqlda->sqln = 1;

Expand All @@ -272,7 +272,7 @@ if (isc_dsql_prepare
/* re-allocate the output structure if there's more than one field */
if (out_sqlda->sqln < out_sqlda->sqld)
{
XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld), FALSE);
XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld), GET_UNTAINTED);
if (isc_dsql_describe
(status, &stmth, out_sqlda->version, new_sqlda))
{
Expand All @@ -294,46 +294,46 @@ for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++)
switch (var->sqltype & ~1)
{
case SQL_VARYING:
var->sqldata = CS store_get(sizeof(char) * var->sqllen + 2, FALSE);
var->sqldata = CS store_get(sizeof(char) * var->sqllen + 2, GET_UNTAINTED);
break;
case SQL_TEXT:
var->sqldata = CS store_get(sizeof(char) * var->sqllen, FALSE);
var->sqldata = CS store_get(sizeof(char) * var->sqllen, GET_UNTAINTED);
break;
case SQL_SHORT:
var->sqldata = CS store_get(sizeof(short), FALSE);
var->sqldata = CS store_get(sizeof(short), GET_UNTAINTED);
break;
case SQL_LONG:
var->sqldata = CS store_get(sizeof(ISC_LONG), FALSE);
var->sqldata = CS store_get(sizeof(ISC_LONG), GET_UNTAINTED);
break;
#ifdef SQL_INT64
case SQL_INT64:
var->sqldata = CS store_get(sizeof(ISC_INT64), FALSE);
var->sqldata = CS store_get(sizeof(ISC_INT64), GET_UNTAINTED);
break;
#endif
case SQL_FLOAT:
var->sqldata = CS store_get(sizeof(float), FALSE);
var->sqldata = CS store_get(sizeof(float), GET_UNTAINTED);
break;
case SQL_DOUBLE:
var->sqldata = CS store_get(sizeof(double), FALSE);
var->sqldata = CS store_get(sizeof(double), GET_UNTAINTED);
break;
#ifdef SQL_TIMESTAMP
case SQL_DATE:
var->sqldata = CS store_get(sizeof(ISC_QUAD), FALSE);
var->sqldata = CS store_get(sizeof(ISC_QUAD), GET_UNTAINTED);
break;
#else
case SQL_TIMESTAMP:
var->sqldata = CS store_get(sizeof(ISC_TIMESTAMP), FALSE);
var->sqldata = CS store_get(sizeof(ISC_TIMESTAMP), GET_UNTAINTED);
break;
case SQL_TYPE_DATE:
var->sqldata = CS store_get(sizeof(ISC_DATE), FALSE);
var->sqldata = CS store_get(sizeof(ISC_DATE), GET_UNTAINTED);
break;
case SQL_TYPE_TIME:
var->sqldata = CS store_get(sizeof(ISC_TIME), FALSE);
var->sqldata = CS store_get(sizeof(ISC_TIME), GET_UNTAINTED);
break;
#endif
}
if (var->sqltype & 1)
var->sqlind = (short *) store_get(sizeof(short), FALSE);
var->sqlind = (short *) store_get(sizeof(short), GET_UNTAINTED);
}

/* finally, we're ready to execute the statement */
Expand Down Expand Up @@ -492,51 +492,32 @@ can't quote "on spec".
Arguments:
s the string to be quoted
opt additional option text or NULL if none
idx lookup type index
Returns: the processed string or NULL for a bad option
*/

static uschar *ibase_quote(uschar * s, uschar * opt)
static uschar *
ibase_quote(uschar * s, uschar * opt, unsigned idx)
{
register int c;
int count = 0;
uschar *t = s;
uschar *quoted;

if (opt != NULL)
return NULL; /* No options recognized */

while ((c = *t++) != 0)
if (Ustrchr("\n\t\r\b\'\"\\", c) != NULL)
count++;

if (count == 0)
return s;
t = quoted = store_get(Ustrlen(s) + count + 1, FALSE);

while ((c = *s++) != 0) {
if (Ustrchr("'", c) != NULL) {
*t++ = '\'';
*t++ = '\'';
/* switch(c)
{
case '\n': *t++ = 'n';
break;
case '\t': *t++ = 't';
break;
case '\r': *t++ = 'r';
break;
case '\b': *t++ = 'b';
break;
default: *t++ = c;
break;
}*/
} else
*t++ = c;
}
int c;
int count = 0;
uschar * t = s, * quoted;

if (opt)
return NULL; /* No options recognized */

while ((c = *t++))
if (c == '\'') count++;

t = quoted = store_get_quoted(Ustrlen(s) + count + 1, s, idx);

while ((c = *s++))
if (c == '\'') { *t++ = '\''; *t++ = '\''; }
else *t++ = c;

*t = 0;
return quoted;
*t = 0;
return quoted;
}


Expand All @@ -548,12 +529,13 @@ static uschar *ibase_quote(uschar * s, uschar * opt)

#include "../version.h"

void
ibase_version_report(FILE *f)
gstring *
ibase_version_report(gstring * g)
{
#ifdef DYNLOOKUP
fprintf(f, "Library version: ibase: Exim version %s\n", EXIM_VERSION_STR);
g = string_fmt_append(g, "Library version: ibase: Exim version %s\n", EXIM_VERSION_STR));
#endif
return g;
}


Expand Down
11 changes: 6 additions & 5 deletions src/src/lookups/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* Exim - an Internet mail transport agent *
*************************************************/

/* Copyright (c) Jeremy Harris 2019-2020 */
/* Copyright (c) The Exim Maintainers 2021 - 2022 */
/* Copyright (c) Jeremy Harris 2019 - 2020 */
/* See the file NOTICE for conditions of use and distribution. */

#include "../exim.h"
Expand All @@ -23,7 +24,7 @@ Assume that the file is trusted, so no tainting */
static void *
json_malloc(size_t nbytes)
{
void * p = store_get((int)nbytes, FALSE);
void * p = store_get((int)nbytes, GET_UNTAINTED);
/* debug_printf("%s %d: %p\n", __FUNCTION__, (int)nbytes, p); */
return p;
}
Expand Down Expand Up @@ -157,10 +158,10 @@ json_close(void *handle)

#include "../version.h"

void
json_version_report(FILE *f)
gstring *
json_version_report(gstring * g)
{
fprintf(f, "Library version: json: Jansonn version %s\n", JANSSON_VERSION);
return string_fmt_append(g, "Library version: json: Jansonn version %s\n", JANSSON_VERSION);
}


Expand Down
Loading