Use compressed form of ipv6 in $sender_host_address under -bh. Bug 3027
[exim.git] / src / src / environment.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /*
6  * Copyright (c) The Exim Maintainers 2022 - 2023
7  * Copyright (c) Heiko Schlittermann 2016
8  * hs@schlittermann.de
9  * See the file NOTICE for conditions of use and distribution.
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "exim.h"
14
15 extern char **environ;
16
17 /* The cleanup_environment() function is used during the startup phase
18 of the Exim process, right after reading the configurations main
19 part, before any expansions take place. It retains the environment
20 variables we trust (via the keep_environment option) and allows to
21 set additional variables (via add_environment).
22
23 Returns:    TRUE if successful
24             FALSE otherwise
25 */
26
27 BOOL
28 cleanup_environment()
29 {
30 if (!keep_environment || !*keep_environment)
31   {
32   /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55
33   Try to clear the environment.
34   a) environ = NULL crashes on OS X.
35   b) *environ = NULL doesn't work on FreeBSD 7.0.
36   c) environ = emptyenv doesn't work on Haiku OS
37   d) environ = calloc() should work everywhere */
38
39   if (environ) *environ = NULL;
40
41   }
42 else if (Ustrcmp(keep_environment, "*") != 0)
43   {
44   rmark reset_point = store_mark();
45   unsigned deb = debug_selector;
46   BOOL hc = host_checking;
47   debug_selector = 0;                   /* quieten this clearout */
48   host_checking = FALSE;
49
50   if (environ) for (uschar ** p = USS environ; *p; /* see below */)
51     {
52     /* It's considered broken if we do not find the '=', according to
53     Florian Weimer. For now we ignore such strings. unsetenv() would complain,
54     getenv() would complain. */
55     uschar * eqp = Ustrchr(*p, '=');
56
57     if (eqp)
58       {
59       uschar * name = string_copyn(*p, eqp - *p);
60
61       if (match_isinlist(name, CUSS &keep_environment,
62           0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL) == OK)
63         p++;                    /* next */
64       else if (os_unsetenv(name) == 0)
65         p = USS environ;        /* RESTART from the beginning */
66       else
67         { debug_selector = deb; host_checking = hc; return FALSE; }
68       }
69     }
70   debug_selector = deb;
71   host_checking = hc;
72   store_reset(reset_point);
73   }
74 DEBUG(D_expand)
75   {
76   debug_printf("environment after trimming:\n");
77   if (environ) for (uschar ** p = USS environ; *p; p++)
78     debug_printf(" %s\n", *p);
79   }
80 if (add_environment)
81   {
82   int sep = 0;
83   const uschar * envlist = add_environment;
84   int old_pool = store_pool;
85   store_pool = POOL_PERM;               /* Need perm memory for any created env vars */
86
87   for (const uschar * p; p = string_nextinlist(&envlist, &sep, NULL, 0); )
88     {
89     DEBUG(D_expand) debug_printf("adding %s\n", p);
90     putenv(CS p);
91     }
92   store_pool = old_pool;
93   }
94 #ifndef DISABLE_TLS
95 tls_clean_env();
96 #endif
97
98 return TRUE;
99 }