Browse code

Move env helper functions into their own module/file

To avoid a dependency on misc.c - which is a dependency mess - in the
tls-crypt unit tests, split the env_set functionality out into it's own
file.

Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1512734870-17133-8-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16066.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2017/12/08 21:07:47
Showing 6 changed files
... ...
@@ -51,6 +51,7 @@ openvpn_SOURCES = \
51 51
 	crypto_openssl.c crypto_openssl.h \
52 52
 	crypto_mbedtls.c crypto_mbedtls.h \
53 53
 	dhcp.c dhcp.h \
54
+	env_set.c env_set.h \
54 55
 	errlevel.h \
55 56
 	error.c error.h \
56 57
 	event.c event.h \
... ...
@@ -37,6 +37,7 @@
37 37
 
38 38
 #include "argv.h"
39 39
 #include "integer.h"
40
+#include "env_set.h"
40 41
 #include "options.h"
41 42
 
42 43
 static void
43 44
new file mode 100644
... ...
@@ -0,0 +1,459 @@
0
+/*
1
+ *  OpenVPN -- An application to securely tunnel IP networks
2
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
3
+ *             session authentication and key exchange,
4
+ *             packet encryption, packet authentication, and
5
+ *             packet compression.
6
+ *
7
+ *  Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
8
+ *  Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
9
+ *  Copyright (C) 2016-2017 David Sommerseth <davids@openvpn.net>
10
+ *
11
+ *  This program is free software; you can redistribute it and/or modify
12
+ *  it under the terms of the GNU General Public License version 2
13
+ *  as published by the Free Software Foundation.
14
+ *
15
+ *  This program is distributed in the hope that it will be useful,
16
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
+ *  GNU General Public License for more details.
19
+ *
20
+ *  You should have received a copy of the GNU General Public License
21
+ *  along with this program (see the file COPYING included with this
22
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
23
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
+ */
25
+
26
+#ifdef HAVE_CONFIG_H
27
+#include "config.h"
28
+#elif defined(_MSC_VER)
29
+#include "config-msvc.h"
30
+#endif
31
+
32
+#include "syshead.h"
33
+
34
+#include "misc.h"
35
+
36
+#include "env_set.h"
37
+
38
+/*
39
+ * Set environmental variable (int or string).
40
+ *
41
+ * On Posix, we use putenv for portability,
42
+ * and put up with its painful semantics
43
+ * that require all the support code below.
44
+ */
45
+
46
+/* General-purpose environmental variable set functions */
47
+
48
+static char *
49
+construct_name_value(const char *name, const char *value, struct gc_arena *gc)
50
+{
51
+    struct buffer out;
52
+
53
+    ASSERT(name);
54
+    if (!value)
55
+    {
56
+        value = "";
57
+    }
58
+    out = alloc_buf_gc(strlen(name) + strlen(value) + 2, gc);
59
+    buf_printf(&out, "%s=%s", name, value);
60
+    return BSTR(&out);
61
+}
62
+
63
+static bool
64
+env_string_equal(const char *s1, const char *s2)
65
+{
66
+    int c1, c2;
67
+    ASSERT(s1);
68
+    ASSERT(s2);
69
+
70
+    while (true)
71
+    {
72
+        c1 = *s1++;
73
+        c2 = *s2++;
74
+        if (c1 == '=')
75
+        {
76
+            c1 = 0;
77
+        }
78
+        if (c2 == '=')
79
+        {
80
+            c2 = 0;
81
+        }
82
+        if (!c1 && !c2)
83
+        {
84
+            return true;
85
+        }
86
+        if (c1 != c2)
87
+        {
88
+            break;
89
+        }
90
+    }
91
+    return false;
92
+}
93
+
94
+static bool
95
+remove_env_item(const char *str, const bool do_free, struct env_item **list)
96
+{
97
+    struct env_item *current, *prev;
98
+
99
+    ASSERT(str);
100
+    ASSERT(list);
101
+
102
+    for (current = *list, prev = NULL; current != NULL; current = current->next)
103
+    {
104
+        if (env_string_equal(current->string, str))
105
+        {
106
+            if (prev)
107
+            {
108
+                prev->next = current->next;
109
+            }
110
+            else
111
+            {
112
+                *list = current->next;
113
+            }
114
+            if (do_free)
115
+            {
116
+                secure_memzero(current->string, strlen(current->string));
117
+                free(current->string);
118
+                free(current);
119
+            }
120
+            return true;
121
+        }
122
+        prev = current;
123
+    }
124
+    return false;
125
+}
126
+
127
+static void
128
+add_env_item(char *str, const bool do_alloc, struct env_item **list, struct gc_arena *gc)
129
+{
130
+    struct env_item *item;
131
+
132
+    ASSERT(str);
133
+    ASSERT(list);
134
+
135
+    ALLOC_OBJ_GC(item, struct env_item, gc);
136
+    item->string = do_alloc ? string_alloc(str, gc) : str;
137
+    item->next = *list;
138
+    *list = item;
139
+}
140
+
141
+/* struct env_set functions */
142
+
143
+static bool
144
+env_set_del_nolock(struct env_set *es, const char *str)
145
+{
146
+    return remove_env_item(str, es->gc == NULL, &es->list);
147
+}
148
+
149
+static void
150
+env_set_add_nolock(struct env_set *es, const char *str)
151
+{
152
+    remove_env_item(str, es->gc == NULL, &es->list);
153
+    add_env_item((char *)str, true, &es->list, es->gc);
154
+}
155
+
156
+struct env_set *
157
+env_set_create(struct gc_arena *gc)
158
+{
159
+    struct env_set *es;
160
+    ALLOC_OBJ_CLEAR_GC(es, struct env_set, gc);
161
+    es->list = NULL;
162
+    es->gc = gc;
163
+    return es;
164
+}
165
+
166
+void
167
+env_set_destroy(struct env_set *es)
168
+{
169
+    if (es && es->gc == NULL)
170
+    {
171
+        struct env_item *e = es->list;
172
+        while (e)
173
+        {
174
+            struct env_item *next = e->next;
175
+            free(e->string);
176
+            free(e);
177
+            e = next;
178
+        }
179
+        free(es);
180
+    }
181
+}
182
+
183
+bool
184
+env_set_del(struct env_set *es, const char *str)
185
+{
186
+    bool ret;
187
+    ASSERT(es);
188
+    ASSERT(str);
189
+    ret = env_set_del_nolock(es, str);
190
+    return ret;
191
+}
192
+
193
+void
194
+env_set_add(struct env_set *es, const char *str)
195
+{
196
+    ASSERT(es);
197
+    ASSERT(str);
198
+    env_set_add_nolock(es, str);
199
+}
200
+
201
+const char *
202
+env_set_get(const struct env_set *es, const char *name)
203
+{
204
+    const struct env_item *item = es->list;
205
+    while (item && !env_string_equal(item->string, name))
206
+    {
207
+        item = item->next;
208
+    }
209
+    return item ? item->string : NULL;
210
+}
211
+
212
+void
213
+env_set_print(int msglevel, const struct env_set *es)
214
+{
215
+    if (check_debug_level(msglevel))
216
+    {
217
+        const struct env_item *e;
218
+        int i;
219
+
220
+        if (es)
221
+        {
222
+            e = es->list;
223
+            i = 0;
224
+
225
+            while (e)
226
+            {
227
+                if (env_safe_to_print(e->string))
228
+                {
229
+                    msg(msglevel, "ENV [%d] '%s'", i, e->string);
230
+                }
231
+                ++i;
232
+                e = e->next;
233
+            }
234
+        }
235
+    }
236
+}
237
+
238
+void
239
+env_set_inherit(struct env_set *es, const struct env_set *src)
240
+{
241
+    const struct env_item *e;
242
+
243
+    ASSERT(es);
244
+
245
+    if (src)
246
+    {
247
+        e = src->list;
248
+        while (e)
249
+        {
250
+            env_set_add_nolock(es, e->string);
251
+            e = e->next;
252
+        }
253
+    }
254
+}
255
+
256
+
257
+/* add/modify/delete environmental strings */
258
+
259
+void
260
+setenv_counter(struct env_set *es, const char *name, counter_type value)
261
+{
262
+    char buf[64];
263
+    openvpn_snprintf(buf, sizeof(buf), counter_format, value);
264
+    setenv_str(es, name, buf);
265
+}
266
+
267
+void
268
+setenv_int(struct env_set *es, const char *name, int value)
269
+{
270
+    char buf[64];
271
+    openvpn_snprintf(buf, sizeof(buf), "%d", value);
272
+    setenv_str(es, name, buf);
273
+}
274
+
275
+void
276
+setenv_long_long(struct env_set *es, const char *name, long long value)
277
+{
278
+    char buf[64];
279
+    openvpn_snprintf(buf, sizeof(buf), "%"PRIi64, (int64_t)value);
280
+    setenv_str(es, name, buf);
281
+}
282
+
283
+void
284
+setenv_str(struct env_set *es, const char *name, const char *value)
285
+{
286
+    setenv_str_ex(es, name, value, CC_NAME, 0, 0, CC_PRINT, 0, 0);
287
+}
288
+
289
+void
290
+setenv_str_safe(struct env_set *es, const char *name, const char *value)
291
+{
292
+    uint8_t b[64];
293
+    struct buffer buf;
294
+    buf_set_write(&buf, b, sizeof(b));
295
+    if (buf_printf(&buf, "OPENVPN_%s", name))
296
+    {
297
+        setenv_str(es, BSTR(&buf), value);
298
+    }
299
+    else
300
+    {
301
+        msg(M_WARN, "setenv_str_safe: name overflow");
302
+    }
303
+}
304
+
305
+void
306
+setenv_str_incr(struct env_set *es, const char *name, const char *value)
307
+{
308
+    unsigned int counter = 1;
309
+    const size_t tmpname_len = strlen(name) + 5; /* 3 digits counter max */
310
+    char *tmpname = gc_malloc(tmpname_len, true, NULL);
311
+    strcpy(tmpname, name);
312
+    while (NULL != env_set_get(es, tmpname) && counter < 1000)
313
+    {
314
+        ASSERT(openvpn_snprintf(tmpname, tmpname_len, "%s_%u", name, counter));
315
+        counter++;
316
+    }
317
+    if (counter < 1000)
318
+    {
319
+        setenv_str(es, tmpname, value);
320
+    }
321
+    else
322
+    {
323
+        msg(D_TLS_DEBUG_MED, "Too many same-name env variables, ignoring: %s", name);
324
+    }
325
+    free(tmpname);
326
+}
327
+
328
+void
329
+setenv_del(struct env_set *es, const char *name)
330
+{
331
+    ASSERT(name);
332
+    setenv_str(es, name, NULL);
333
+}
334
+
335
+void
336
+setenv_str_ex(struct env_set *es,
337
+              const char *name,
338
+              const char *value,
339
+              const unsigned int name_include,
340
+              const unsigned int name_exclude,
341
+              const char name_replace,
342
+              const unsigned int value_include,
343
+              const unsigned int value_exclude,
344
+              const char value_replace)
345
+{
346
+    struct gc_arena gc = gc_new();
347
+    const char *name_tmp;
348
+    const char *val_tmp = NULL;
349
+
350
+    ASSERT(name && strlen(name) > 1);
351
+
352
+    name_tmp = string_mod_const(name, name_include, name_exclude, name_replace, &gc);
353
+
354
+    if (value)
355
+    {
356
+        val_tmp = string_mod_const(value, value_include, value_exclude, value_replace, &gc);
357
+    }
358
+
359
+    ASSERT(es);
360
+
361
+    if (val_tmp)
362
+    {
363
+        const char *str = construct_name_value(name_tmp, val_tmp, &gc);
364
+        env_set_add(es, str);
365
+#if DEBUG_VERBOSE_SETENV
366
+        msg(M_INFO, "SETENV_ES '%s'", str);
367
+#endif
368
+    }
369
+    else
370
+    {
371
+        env_set_del(es, name_tmp);
372
+    }
373
+
374
+    gc_free(&gc);
375
+}
376
+
377
+/*
378
+ * Setenv functions that append an integer index to the name
379
+ */
380
+static const char *
381
+setenv_format_indexed_name(const char *name, const int i, struct gc_arena *gc)
382
+{
383
+    struct buffer out = alloc_buf_gc(strlen(name) + 16, gc);
384
+    if (i >= 0)
385
+    {
386
+        buf_printf(&out, "%s_%d", name, i);
387
+    }
388
+    else
389
+    {
390
+        buf_printf(&out, "%s", name);
391
+    }
392
+    return BSTR(&out);
393
+}
394
+
395
+void
396
+setenv_int_i(struct env_set *es, const char *name, const int value, const int i)
397
+{
398
+    struct gc_arena gc = gc_new();
399
+    const char *name_str = setenv_format_indexed_name(name, i, &gc);
400
+    setenv_int(es, name_str, value);
401
+    gc_free(&gc);
402
+}
403
+
404
+void
405
+setenv_str_i(struct env_set *es, const char *name, const char *value, const int i)
406
+{
407
+    struct gc_arena gc = gc_new();
408
+    const char *name_str = setenv_format_indexed_name(name, i, &gc);
409
+    setenv_str(es, name_str, value);
410
+    gc_free(&gc);
411
+}
412
+
413
+bool
414
+env_allowed(const char *str)
415
+{
416
+    return (script_security >= SSEC_PW_ENV || !is_password_env_var(str));
417
+}
418
+
419
+/* Make arrays of strings */
420
+
421
+const char **
422
+make_env_array(const struct env_set *es,
423
+               const bool check_allowed,
424
+               struct gc_arena *gc)
425
+{
426
+    char **ret = NULL;
427
+    struct env_item *e = NULL;
428
+    int i = 0, n = 0;
429
+
430
+    /* figure length of es */
431
+    if (es)
432
+    {
433
+        for (e = es->list; e != NULL; e = e->next)
434
+        {
435
+            ++n;
436
+        }
437
+    }
438
+
439
+    /* alloc return array */
440
+    ALLOC_ARRAY_CLEAR_GC(ret, char *, n+1, gc);
441
+
442
+    /* fill return array */
443
+    if (es)
444
+    {
445
+        i = 0;
446
+        for (e = es->list; e != NULL; e = e->next)
447
+        {
448
+            if (!check_allowed || env_allowed(e->string))
449
+            {
450
+                ASSERT(i < n);
451
+                ret[i++] = e->string;
452
+            }
453
+        }
454
+    }
455
+
456
+    ret[i] = NULL;
457
+    return (const char **)ret;
458
+}
0 459
new file mode 100644
... ...
@@ -0,0 +1,121 @@
0
+/*
1
+ *  OpenVPN -- An application to securely tunnel IP networks
2
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
3
+ *             session authentication and key exchange,
4
+ *             packet encryption, packet authentication, and
5
+ *             packet compression.
6
+ *
7
+ *  Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
8
+ *
9
+ *  This program is free software; you can redistribute it and/or modify
10
+ *  it under the terms of the GNU General Public License version 2
11
+ *  as published by the Free Software Foundation.
12
+ *
13
+ *  This program is distributed in the hope that it will be useful,
14
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ *  GNU General Public License for more details.
17
+ *
18
+ *  You should have received a copy of the GNU General Public License
19
+ *  along with this program (see the file COPYING included with this
20
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
21
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
+ */
23
+
24
+#ifndef ENV_SET_H
25
+#define ENV_SET_H
26
+
27
+#include "argv.h"
28
+#include "basic.h"
29
+#include "buffer.h"
30
+#include "common.h"
31
+
32
+/*
33
+ * Handle environmental variable lists
34
+ */
35
+
36
+struct env_item {
37
+    char *string;
38
+    struct env_item *next;
39
+};
40
+
41
+struct env_set {
42
+    struct gc_arena *gc;
43
+    struct env_item *list;
44
+};
45
+
46
+/* set/delete environmental variable */
47
+void setenv_str_ex(struct env_set *es,
48
+                   const char *name,
49
+                   const char *value,
50
+                   const unsigned int name_include,
51
+                   const unsigned int name_exclude,
52
+                   const char name_replace,
53
+                   const unsigned int value_include,
54
+                   const unsigned int value_exclude,
55
+                   const char value_replace);
56
+
57
+void setenv_counter(struct env_set *es, const char *name, counter_type value);
58
+
59
+void setenv_int(struct env_set *es, const char *name, int value);
60
+
61
+void setenv_long_long(struct env_set *es, const char *name, long long value);
62
+
63
+void setenv_str(struct env_set *es, const char *name, const char *value);
64
+
65
+void setenv_str_safe(struct env_set *es, const char *name, const char *value);
66
+
67
+void setenv_del(struct env_set *es, const char *name);
68
+
69
+/**
70
+ * Store the supplied name value pair in the env_set.  If the variable with the
71
+ * supplied name  already exists, append _N to the name, starting at N=1.
72
+ */
73
+void setenv_str_incr(struct env_set *es, const char *name, const char *value);
74
+
75
+void setenv_int_i(struct env_set *es, const char *name, const int value, const int i);
76
+
77
+void setenv_str_i(struct env_set *es, const char *name, const char *value, const int i);
78
+
79
+/* struct env_set functions */
80
+
81
+struct env_set *env_set_create(struct gc_arena *gc);
82
+
83
+void env_set_destroy(struct env_set *es);
84
+
85
+bool env_set_del(struct env_set *es, const char *str);
86
+
87
+void env_set_add(struct env_set *es, const char *str);
88
+
89
+const char *env_set_get(const struct env_set *es, const char *name);
90
+
91
+void env_set_print(int msglevel, const struct env_set *es);
92
+
93
+void env_set_inherit(struct env_set *es, const struct env_set *src);
94
+
95
+/* returns true if environmental variable name starts with 'password' */
96
+static inline bool is_password_env_var(const char *str)
97
+{
98
+    return (strncmp(str, "password", 8) == 0);
99
+}
100
+
101
+/* returns true if environmental variable safe to print to log */
102
+static inline bool env_safe_to_print(const char *str)
103
+{
104
+#ifndef UNSAFE_DEBUG
105
+    if (is_password_env_var(str))
106
+    {
107
+        return false;
108
+    }
109
+#endif
110
+    return true;
111
+}
112
+
113
+/* returns true if environmental variable may be passed to an external program */
114
+bool env_allowed(const char *str);
115
+
116
+const char **make_env_array(const struct env_set *es,
117
+                            const bool check_allowed,
118
+                            struct gc_arena *gc);
119
+
120
+#endif /* ifndef ENV_SET_H */
... ...
@@ -314,382 +314,6 @@ openvpn_popen(const struct argv *a,  const struct env_set *es)
314 314
 }
315 315
 
316 316
 
317
-
318
-/*
319
- * Set environmental variable (int or string).
320
- *
321
- * On Posix, we use putenv for portability,
322
- * and put up with its painful semantics
323
- * that require all the support code below.
324
- */
325
-
326
-/* General-purpose environmental variable set functions */
327
-
328
-static char *
329
-construct_name_value(const char *name, const char *value, struct gc_arena *gc)
330
-{
331
-    struct buffer out;
332
-
333
-    ASSERT(name);
334
-    if (!value)
335
-    {
336
-        value = "";
337
-    }
338
-    out = alloc_buf_gc(strlen(name) + strlen(value) + 2, gc);
339
-    buf_printf(&out, "%s=%s", name, value);
340
-    return BSTR(&out);
341
-}
342
-
343
-static bool
344
-env_string_equal(const char *s1, const char *s2)
345
-{
346
-    int c1, c2;
347
-    ASSERT(s1);
348
-    ASSERT(s2);
349
-
350
-    while (true)
351
-    {
352
-        c1 = *s1++;
353
-        c2 = *s2++;
354
-        if (c1 == '=')
355
-        {
356
-            c1 = 0;
357
-        }
358
-        if (c2 == '=')
359
-        {
360
-            c2 = 0;
361
-        }
362
-        if (!c1 && !c2)
363
-        {
364
-            return true;
365
-        }
366
-        if (c1 != c2)
367
-        {
368
-            break;
369
-        }
370
-    }
371
-    return false;
372
-}
373
-
374
-static bool
375
-remove_env_item(const char *str, const bool do_free, struct env_item **list)
376
-{
377
-    struct env_item *current, *prev;
378
-
379
-    ASSERT(str);
380
-    ASSERT(list);
381
-
382
-    for (current = *list, prev = NULL; current != NULL; current = current->next)
383
-    {
384
-        if (env_string_equal(current->string, str))
385
-        {
386
-            if (prev)
387
-            {
388
-                prev->next = current->next;
389
-            }
390
-            else
391
-            {
392
-                *list = current->next;
393
-            }
394
-            if (do_free)
395
-            {
396
-                secure_memzero(current->string, strlen(current->string));
397
-                free(current->string);
398
-                free(current);
399
-            }
400
-            return true;
401
-        }
402
-        prev = current;
403
-    }
404
-    return false;
405
-}
406
-
407
-static void
408
-add_env_item(char *str, const bool do_alloc, struct env_item **list, struct gc_arena *gc)
409
-{
410
-    struct env_item *item;
411
-
412
-    ASSERT(str);
413
-    ASSERT(list);
414
-
415
-    ALLOC_OBJ_GC(item, struct env_item, gc);
416
-    item->string = do_alloc ? string_alloc(str, gc) : str;
417
-    item->next = *list;
418
-    *list = item;
419
-}
420
-
421
-/* struct env_set functions */
422
-
423
-static bool
424
-env_set_del_nolock(struct env_set *es, const char *str)
425
-{
426
-    return remove_env_item(str, es->gc == NULL, &es->list);
427
-}
428
-
429
-static void
430
-env_set_add_nolock(struct env_set *es, const char *str)
431
-{
432
-    remove_env_item(str, es->gc == NULL, &es->list);
433
-    add_env_item((char *)str, true, &es->list, es->gc);
434
-}
435
-
436
-struct env_set *
437
-env_set_create(struct gc_arena *gc)
438
-{
439
-    struct env_set *es;
440
-    ALLOC_OBJ_CLEAR_GC(es, struct env_set, gc);
441
-    es->list = NULL;
442
-    es->gc = gc;
443
-    return es;
444
-}
445
-
446
-void
447
-env_set_destroy(struct env_set *es)
448
-{
449
-    if (es && es->gc == NULL)
450
-    {
451
-        struct env_item *e = es->list;
452
-        while (e)
453
-        {
454
-            struct env_item *next = e->next;
455
-            free(e->string);
456
-            free(e);
457
-            e = next;
458
-        }
459
-        free(es);
460
-    }
461
-}
462
-
463
-bool
464
-env_set_del(struct env_set *es, const char *str)
465
-{
466
-    bool ret;
467
-    ASSERT(es);
468
-    ASSERT(str);
469
-    ret = env_set_del_nolock(es, str);
470
-    return ret;
471
-}
472
-
473
-void
474
-env_set_add(struct env_set *es, const char *str)
475
-{
476
-    ASSERT(es);
477
-    ASSERT(str);
478
-    env_set_add_nolock(es, str);
479
-}
480
-
481
-const char *
482
-env_set_get(const struct env_set *es, const char *name)
483
-{
484
-    const struct env_item *item = es->list;
485
-    while (item && !env_string_equal(item->string, name))
486
-    {
487
-        item = item->next;
488
-    }
489
-    return item ? item->string : NULL;
490
-}
491
-
492
-void
493
-env_set_print(int msglevel, const struct env_set *es)
494
-{
495
-    if (check_debug_level(msglevel))
496
-    {
497
-        const struct env_item *e;
498
-        int i;
499
-
500
-        if (es)
501
-        {
502
-            e = es->list;
503
-            i = 0;
504
-
505
-            while (e)
506
-            {
507
-                if (env_safe_to_print(e->string))
508
-                {
509
-                    msg(msglevel, "ENV [%d] '%s'", i, e->string);
510
-                }
511
-                ++i;
512
-                e = e->next;
513
-            }
514
-        }
515
-    }
516
-}
517
-
518
-void
519
-env_set_inherit(struct env_set *es, const struct env_set *src)
520
-{
521
-    const struct env_item *e;
522
-
523
-    ASSERT(es);
524
-
525
-    if (src)
526
-    {
527
-        e = src->list;
528
-        while (e)
529
-        {
530
-            env_set_add_nolock(es, e->string);
531
-            e = e->next;
532
-        }
533
-    }
534
-}
535
-
536
-
537
-/* add/modify/delete environmental strings */
538
-
539
-void
540
-setenv_counter(struct env_set *es, const char *name, counter_type value)
541
-{
542
-    char buf[64];
543
-    openvpn_snprintf(buf, sizeof(buf), counter_format, value);
544
-    setenv_str(es, name, buf);
545
-}
546
-
547
-void
548
-setenv_int(struct env_set *es, const char *name, int value)
549
-{
550
-    char buf[64];
551
-    openvpn_snprintf(buf, sizeof(buf), "%d", value);
552
-    setenv_str(es, name, buf);
553
-}
554
-
555
-void
556
-setenv_long_long(struct env_set *es, const char *name, long long value)
557
-{
558
-    char buf[64];
559
-    openvpn_snprintf(buf, sizeof(buf), "%"PRIi64, (int64_t)value);
560
-    setenv_str(es, name, buf);
561
-}
562
-
563
-void
564
-setenv_str(struct env_set *es, const char *name, const char *value)
565
-{
566
-    setenv_str_ex(es, name, value, CC_NAME, 0, 0, CC_PRINT, 0, 0);
567
-}
568
-
569
-void
570
-setenv_str_safe(struct env_set *es, const char *name, const char *value)
571
-{
572
-    uint8_t b[64];
573
-    struct buffer buf;
574
-    buf_set_write(&buf, b, sizeof(b));
575
-    if (buf_printf(&buf, "OPENVPN_%s", name))
576
-    {
577
-        setenv_str(es, BSTR(&buf), value);
578
-    }
579
-    else
580
-    {
581
-        msg(M_WARN, "setenv_str_safe: name overflow");
582
-    }
583
-}
584
-
585
-void
586
-setenv_str_incr(struct env_set *es, const char *name, const char *value)
587
-{
588
-    unsigned int counter = 1;
589
-    const size_t tmpname_len = strlen(name) + 5; /* 3 digits counter max */
590
-    char *tmpname = gc_malloc(tmpname_len, true, NULL);
591
-    strcpy(tmpname, name);
592
-    while (NULL != env_set_get(es, tmpname) && counter < 1000)
593
-    {
594
-        ASSERT(openvpn_snprintf(tmpname, tmpname_len, "%s_%u", name, counter));
595
-        counter++;
596
-    }
597
-    if (counter < 1000)
598
-    {
599
-        setenv_str(es, tmpname, value);
600
-    }
601
-    else
602
-    {
603
-        msg(D_TLS_DEBUG_MED, "Too many same-name env variables, ignoring: %s", name);
604
-    }
605
-    free(tmpname);
606
-}
607
-
608
-void
609
-setenv_del(struct env_set *es, const char *name)
610
-{
611
-    ASSERT(name);
612
-    setenv_str(es, name, NULL);
613
-}
614
-
615
-void
616
-setenv_str_ex(struct env_set *es,
617
-              const char *name,
618
-              const char *value,
619
-              const unsigned int name_include,
620
-              const unsigned int name_exclude,
621
-              const char name_replace,
622
-              const unsigned int value_include,
623
-              const unsigned int value_exclude,
624
-              const char value_replace)
625
-{
626
-    struct gc_arena gc = gc_new();
627
-    const char *name_tmp;
628
-    const char *val_tmp = NULL;
629
-
630
-    ASSERT(name && strlen(name) > 1);
631
-
632
-    name_tmp = string_mod_const(name, name_include, name_exclude, name_replace, &gc);
633
-
634
-    if (value)
635
-    {
636
-        val_tmp = string_mod_const(value, value_include, value_exclude, value_replace, &gc);
637
-    }
638
-
639
-    ASSERT(es);
640
-
641
-    if (val_tmp)
642
-    {
643
-        const char *str = construct_name_value(name_tmp, val_tmp, &gc);
644
-        env_set_add(es, str);
645
-#if DEBUG_VERBOSE_SETENV
646
-        msg(M_INFO, "SETENV_ES '%s'", str);
647
-#endif
648
-    }
649
-    else
650
-    {
651
-        env_set_del(es, name_tmp);
652
-    }
653
-
654
-    gc_free(&gc);
655
-}
656
-
657
-/*
658
- * Setenv functions that append an integer index to the name
659
- */
660
-static const char *
661
-setenv_format_indexed_name(const char *name, const int i, struct gc_arena *gc)
662
-{
663
-    struct buffer out = alloc_buf_gc(strlen(name) + 16, gc);
664
-    if (i >= 0)
665
-    {
666
-        buf_printf(&out, "%s_%d", name, i);
667
-    }
668
-    else
669
-    {
670
-        buf_printf(&out, "%s", name);
671
-    }
672
-    return BSTR(&out);
673
-}
674
-
675
-void
676
-setenv_int_i(struct env_set *es, const char *name, const int value, const int i)
677
-{
678
-    struct gc_arena gc = gc_new();
679
-    const char *name_str = setenv_format_indexed_name(name, i, &gc);
680
-    setenv_int(es, name_str, value);
681
-    gc_free(&gc);
682
-}
683
-
684
-void
685
-setenv_str_i(struct env_set *es, const char *name, const char *value, const int i)
686
-{
687
-    struct gc_arena gc = gc_new();
688
-    const char *name_str = setenv_format_indexed_name(name, i, &gc);
689
-    setenv_str(es, name_str, value);
690
-    gc_free(&gc);
691
-}
692
-
693 317
 /* return true if filename can be opened for read */
694 318
 bool
695 319
 test_file(const char *filename)
... ...
@@ -1288,71 +912,6 @@ safe_print(const char *str, struct gc_arena *gc)
1288 1288
     return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
1289 1289
 }
1290 1290
 
1291
-static bool
1292
-is_password_env_var(const char *str)
1293
-{
1294
-    return (strncmp(str, "password", 8) == 0);
1295
-}
1296
-
1297
-bool
1298
-env_allowed(const char *str)
1299
-{
1300
-    return (script_security >= SSEC_PW_ENV || !is_password_env_var(str));
1301
-}
1302
-
1303
-bool
1304
-env_safe_to_print(const char *str)
1305
-{
1306
-#ifndef UNSAFE_DEBUG
1307
-    if (is_password_env_var(str))
1308
-    {
1309
-        return false;
1310
-    }
1311
-#endif
1312
-    return true;
1313
-}
1314
-
1315
-/* Make arrays of strings */
1316
-
1317
-const char **
1318
-make_env_array(const struct env_set *es,
1319
-               const bool check_allowed,
1320
-               struct gc_arena *gc)
1321
-{
1322
-    char **ret = NULL;
1323
-    struct env_item *e = NULL;
1324
-    int i = 0, n = 0;
1325
-
1326
-    /* figure length of es */
1327
-    if (es)
1328
-    {
1329
-        for (e = es->list; e != NULL; e = e->next)
1330
-        {
1331
-            ++n;
1332
-        }
1333
-    }
1334
-
1335
-    /* alloc return array */
1336
-    ALLOC_ARRAY_CLEAR_GC(ret, char *, n+1, gc);
1337
-
1338
-    /* fill return array */
1339
-    if (es)
1340
-    {
1341
-        i = 0;
1342
-        for (e = es->list; e != NULL; e = e->next)
1343
-        {
1344
-            if (!check_allowed || env_allowed(e->string))
1345
-            {
1346
-                ASSERT(i < n);
1347
-                ret[i++] = e->string;
1348
-            }
1349
-        }
1350
-    }
1351
-
1352
-    ret[i] = NULL;
1353
-    return (const char **)ret;
1354
-}
1355
-
1356 1291
 const char **
1357 1292
 make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
1358 1293
 {
... ...
@@ -27,6 +27,7 @@
27 27
 #include "argv.h"
28 28
 #include "basic.h"
29 29
 #include "common.h"
30
+#include "env_set.h"
30 31
 #include "integer.h"
31 32
 #include "buffer.h"
32 33
 #include "platform.h"
... ...
@@ -37,20 +38,6 @@
37 37
 /* forward declarations */
38 38
 struct plugin_list;
39 39
 
40
-/*
41
- * Handle environmental variable lists
42
- */
43
-
44
-struct env_item {
45
-    char *string;
46
-    struct env_item *next;
47
-};
48
-
49
-struct env_set {
50
-    struct gc_arena *gc;
51
-    struct env_item *list;
52
-};
53
-
54 40
 /* system flags */
55 41
 #define S_SCRIPT (1<<0)
56 42
 #define S_FATAL  (1<<1)
... ...
@@ -83,61 +70,8 @@ void set_std_files_to_null(bool stdin_only);
83 83
 extern int inetd_socket_descriptor;
84 84
 void save_inetd_socket_descriptor(void);
85 85
 
86
-/* set/delete environmental variable */
87
-void setenv_str_ex(struct env_set *es,
88
-                   const char *name,
89
-                   const char *value,
90
-                   const unsigned int name_include,
91
-                   const unsigned int name_exclude,
92
-                   const char name_replace,
93
-                   const unsigned int value_include,
94
-                   const unsigned int value_exclude,
95
-                   const char value_replace);
96
-
97
-void setenv_counter(struct env_set *es, const char *name, counter_type value);
98
-
99
-void setenv_int(struct env_set *es, const char *name, int value);
100
-
101
-void setenv_long_long(struct env_set *es, const char *name, long long value);
102
-
103
-void setenv_str(struct env_set *es, const char *name, const char *value);
104
-
105
-void setenv_str_safe(struct env_set *es, const char *name, const char *value);
106
-
107
-void setenv_del(struct env_set *es, const char *name);
108
-
109
-/**
110
- * Store the supplied name value pair in the env_set.  If the variable with the
111
- * supplied name  already exists, append _N to the name, starting at N=1.
112
- */
113
-void setenv_str_incr(struct env_set *es, const char *name, const char *value);
114
-
115
-void setenv_int_i(struct env_set *es, const char *name, const int value, const int i);
116
-
117
-void setenv_str_i(struct env_set *es, const char *name, const char *value, const int i);
118
-
119
-/* struct env_set functions */
120
-
121
-struct env_set *env_set_create(struct gc_arena *gc);
122
-
123
-void env_set_destroy(struct env_set *es);
124
-
125
-bool env_set_del(struct env_set *es, const char *str);
126
-
127
-void env_set_add(struct env_set *es, const char *str);
128
-
129
-const char *env_set_get(const struct env_set *es, const char *name);
130
-
131
-void env_set_print(int msglevel, const struct env_set *es);
132
-
133
-void env_set_inherit(struct env_set *es, const struct env_set *src);
134
-
135 86
 /* Make arrays of strings */
136 87
 
137
-const char **make_env_array(const struct env_set *es,
138
-                            const bool check_allowed,
139
-                            struct gc_arena *gc);
140
-
141 88
 const char **make_arg_array(const char *first, const char *parms, struct gc_arena *gc);
142 89
 
143 90
 const char **make_extended_arg_array(char **p, struct gc_arena *gc);
... ...
@@ -259,11 +193,6 @@ void set_auth_token(struct user_pass *up, const char *token);
259 259
  */
260 260
 const char *safe_print(const char *str, struct gc_arena *gc);
261 261
 
262
-/* returns true if environmental variable safe to print to log */
263
-bool env_safe_to_print(const char *str);
264
-
265
-/* returns true if environmental variable may be passed to an external program */
266
-bool env_allowed(const char *str);
267 262
 
268 263
 void configure_path(void);
269 264