Browse code

Move file-related functions from misc.c to platform.c

To avoid having to include misc.c - which is a dependency mess - in the
tls-crypt unit tests, move file-handing related functions to platform.c
(which is where other file-related functions already reside).

Note that platform_create_temp_file() needs random. To avoid including
misc.c in other tests that use platform.c, add a mock get_random().

(Almost every test includes platform.c, because buffer.c depends on it.
That smells like it needs cleanup too, but not in this patch set.)

Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20180704175404.22371-1-steffan@karger.me>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17208.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Steffan Karger authored on 2018/07/05 02:53:56
Showing 11 changed files
... ...
@@ -807,7 +807,7 @@ init_static(void)
807 807
 #ifdef STATUS_PRINTF_TEST
808 808
     {
809 809
         struct gc_arena gc = gc_new();
810
-        const char *tmp_file = create_temp_file("/tmp", "foo", &gc);
810
+        const char *tmp_file = platform_create_temp_file("/tmp", "foo", &gc);
811 811
         struct status_output *so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE);
812 812
         status_printf(so, "%s", "foo");
813 813
         status_printf(so, "%s", "bar");
... ...
@@ -313,87 +313,6 @@ openvpn_popen(const struct argv *a,  const struct env_set *es)
313 313
     return ret;
314 314
 }
315 315
 
316
-
317
-/* return true if filename can be opened for read */
318
-bool
319
-test_file(const char *filename)
320
-{
321
-    bool ret = false;
322
-    if (filename)
323
-    {
324
-        FILE *fp = platform_fopen(filename, "r");
325
-        if (fp)
326
-        {
327
-            fclose(fp);
328
-            ret = true;
329
-        }
330
-        else
331
-        {
332
-            if (openvpn_errno() == EACCES)
333
-            {
334
-                msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
335
-            }
336
-        }
337
-    }
338
-
339
-    dmsg(D_TEST_FILE, "TEST FILE '%s' [%d]",
340
-         filename ? filename : "UNDEF",
341
-         ret);
342
-
343
-    return ret;
344
-}
345
-
346
-/* create a temporary filename in directory */
347
-const char *
348
-create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
349
-{
350
-    int fd;
351
-    const char *retfname = NULL;
352
-    unsigned int attempts = 0;
353
-    char fname[256] = { 0 };
354
-    const char *fname_fmt = PACKAGE "_%.*s_%08lx%08lx.tmp";
355
-    const int max_prefix_len = sizeof(fname) - (sizeof(PACKAGE) + 7 + (2 * 8));
356
-
357
-    while (attempts < 6)
358
-    {
359
-        ++attempts;
360
-
361
-        if (!openvpn_snprintf(fname, sizeof(fname), fname_fmt, max_prefix_len,
362
-                              prefix, (unsigned long) get_random(),
363
-                              (unsigned long) get_random()))
364
-        {
365
-            msg(M_WARN, "ERROR: temporary filename too long");
366
-            return NULL;
367
-        }
368
-
369
-        retfname = gen_path(directory, fname, gc);
370
-        if (!retfname)
371
-        {
372
-            msg(M_WARN, "Failed to create temporary filename and path");
373
-            return NULL;
374
-        }
375
-
376
-        /* Atomically create the file.  Errors out if the file already
377
-         * exists.  */
378
-        fd = platform_open(retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
379
-        if (fd != -1)
380
-        {
381
-            close(fd);
382
-            return retfname;
383
-        }
384
-        else if (fd == -1 && errno != EEXIST)
385
-        {
386
-            /* Something else went wrong, no need to retry.  */
387
-            msg(M_WARN | M_ERRNO, "Could not create temporary file '%s'",
388
-                retfname);
389
-            return NULL;
390
-        }
391
-    }
392
-
393
-    msg(M_WARN, "Failed to create temporary file after %i attempts", attempts);
394
-    return NULL;
395
-}
396
-
397 316
 /*
398 317
  * Prepend a random string to hostname to prevent DNS caching.
399 318
  * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
... ...
@@ -416,73 +335,6 @@ hostname_randomize(const char *hostname, struct gc_arena *gc)
416 416
 }
417 417
 
418 418
 /*
419
- * Put a directory and filename together.
420
- */
421
-const char *
422
-gen_path(const char *directory, const char *filename, struct gc_arena *gc)
423
-{
424
-#ifdef _WIN32
425
-    const int CC_PATH_RESERVED = CC_LESS_THAN|CC_GREATER_THAN|CC_COLON
426
-                                 |CC_DOUBLE_QUOTE|CC_SLASH|CC_BACKSLASH|CC_PIPE|CC_QUESTION_MARK|CC_ASTERISK;
427
-#else
428
-    const int CC_PATH_RESERVED = CC_SLASH;
429
-#endif
430
-
431
-    if (!gc)
432
-    {
433
-        return NULL; /* Would leak memory otherwise */
434
-    }
435
-
436
-    const char *safe_filename = string_mod_const(filename, CC_PRINT, CC_PATH_RESERVED, '_', gc);
437
-
438
-    if (safe_filename
439
-        && strcmp(safe_filename, ".")
440
-        && strcmp(safe_filename, "..")
441
-#ifdef _WIN32
442
-        && win_safe_filename(safe_filename)
443
-#endif
444
-        )
445
-    {
446
-        const size_t outsize = strlen(safe_filename) + (directory ? strlen(directory) : 0) + 16;
447
-        struct buffer out = alloc_buf_gc(outsize, gc);
448
-        char dirsep[2];
449
-
450
-        dirsep[0] = OS_SPECIFIC_DIRSEP;
451
-        dirsep[1] = '\0';
452
-
453
-        if (directory)
454
-        {
455
-            buf_printf(&out, "%s%s", directory, dirsep);
456
-        }
457
-        buf_printf(&out, "%s", safe_filename);
458
-
459
-        return BSTR(&out);
460
-    }
461
-    else
462
-    {
463
-        return NULL;
464
-    }
465
-}
466
-
467
-bool
468
-absolute_pathname(const char *pathname)
469
-{
470
-    if (pathname)
471
-    {
472
-        const int c = pathname[0];
473
-#ifdef _WIN32
474
-        return c == '\\' || (isalpha(c) && pathname[1] == ':' && pathname[2] == '\\');
475
-#else
476
-        return c == '/';
477
-#endif
478
-    }
479
-    else
480
-    {
481
-        return false;
482
-    }
483
-}
484
-
485
-/*
486 419
  * Get and store a username/password
487 420
  */
488 421
 
... ...
@@ -79,18 +79,6 @@ const char **make_extended_arg_array(char **p, struct gc_arena *gc);
79 79
 /* an analogue to the random() function, but use OpenSSL functions if available */
80 80
 long int get_random(void);
81 81
 
82
-/* return true if filename can be opened for read */
83
-bool test_file(const char *filename);
84
-
85
-/* create a temporary file in directory, returns the filename of the created file */
86
-const char *create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc);
87
-
88
-/* put a directory and filename together */
89
-const char *gen_path(const char *directory, const char *filename, struct gc_arena *gc);
90
-
91
-/* return true if pathname is absolute */
92
-bool absolute_pathname(const char *pathname);
93
-
94 82
 /* prepend a random prefix to hostname */
95 83
 const char *hostname_randomize(const char *hostname, struct gc_arena *gc);
96 84
 
... ...
@@ -1642,7 +1642,7 @@ multi_client_connect_post(struct multi_context *m,
1642 1642
                           unsigned int *option_types_found)
1643 1643
 {
1644 1644
     /* Did script generate a dynamic config file? */
1645
-    if (test_file(dc_file))
1645
+    if (platform_test_file(dc_file))
1646 1646
     {
1647 1647
         options_server_import(&mi->context.options,
1648 1648
                               dc_file,
... ...
@@ -1829,12 +1829,13 @@ multi_connection_established(struct multi_context *m, struct multi_instance *mi)
1829 1829
         {
1830 1830
             const char *ccd_file;
1831 1831
 
1832
-            ccd_file = gen_path(mi->context.options.client_config_dir,
1833
-                                tls_common_name(mi->context.c2.tls_multi, false),
1834
-                                &gc);
1832
+            ccd_file = platform_gen_path(mi->context.options.client_config_dir,
1833
+                                         tls_common_name(mi->context.c2.tls_multi,
1834
+                                                         false),
1835
+                                         &gc);
1835 1836
 
1836 1837
             /* try common-name file */
1837
-            if (test_file(ccd_file))
1838
+            if (platform_test_file(ccd_file))
1838 1839
             {
1839 1840
                 options_server_import(&mi->context.options,
1840 1841
                                       ccd_file,
... ...
@@ -1845,11 +1846,11 @@ multi_connection_established(struct multi_context *m, struct multi_instance *mi)
1845 1845
             }
1846 1846
             else /* try default file */
1847 1847
             {
1848
-                ccd_file = gen_path(mi->context.options.client_config_dir,
1849
-                                    CCD_DEFAULT,
1850
-                                    &gc);
1848
+                ccd_file = platform_gen_path(mi->context.options.client_config_dir,
1849
+                                             CCD_DEFAULT,
1850
+                                             &gc);
1851 1851
 
1852
-                if (test_file(ccd_file))
1852
+                if (platform_test_file(ccd_file))
1853 1853
                 {
1854 1854
                     options_server_import(&mi->context.options,
1855 1855
                                           ccd_file,
... ...
@@ -1879,7 +1880,8 @@ multi_connection_established(struct multi_context *m, struct multi_instance *mi)
1879 1879
         if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT))
1880 1880
         {
1881 1881
             struct argv argv = argv_new();
1882
-            const char *dc_file = create_temp_file(mi->context.options.tmp_dir, "cc", &gc);
1882
+            const char *dc_file = platform_create_temp_file(mi->context.options.tmp_dir,
1883
+                                                            "cc", &gc);
1883 1884
 
1884 1885
             if (!dc_file)
1885 1886
             {
... ...
@@ -1941,7 +1943,8 @@ script_depr_failed:
1941 1941
 
1942 1942
             setenv_str(mi->context.c2.es, "script_type", "client-connect");
1943 1943
 
1944
-            dc_file = create_temp_file(mi->context.options.tmp_dir, "cc", &gc);
1944
+            dc_file = platform_create_temp_file(mi->context.options.tmp_dir,
1945
+                                                "cc", &gc);
1945 1946
             if (!dc_file)
1946 1947
             {
1947 1948
                 cc_succeeded = false;
... ...
@@ -621,8 +621,8 @@ pf_init_context(struct context *c)
621 621
 #ifdef PLUGIN_PF
622 622
     if (plugin_defined(c->plugins, OPENVPN_PLUGIN_ENABLE_PF))
623 623
     {
624
-        c->c2.pf.filename = create_temp_file(c->options.tmp_dir, "pf",
625
-                                             &c->c2.gc);
624
+        c->c2.pf.filename = platform_create_temp_file(c->options.tmp_dir, "pf",
625
+                                                      &c->c2.gc);
626 626
         if (c->c2.pf.filename)
627 627
         {
628 628
             setenv_str(c->c2.es, "pf_file", c->c2.pf.filename);
... ...
@@ -31,6 +31,7 @@
31 31
 
32 32
 #include "buffer.h"
33 33
 #include "error.h"
34
+#include "misc.h"
34 35
 #include "win32.h"
35 36
 
36 37
 #include "memdbg.h"
... ...
@@ -335,3 +336,150 @@ platform_stat(const char *path, platform_stat_t *buf)
335 335
 #endif
336 336
 }
337 337
 
338
+/* create a temporary filename in directory */
339
+const char *
340
+platform_create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
341
+{
342
+    int fd;
343
+    const char *retfname = NULL;
344
+    unsigned int attempts = 0;
345
+    char fname[256] = { 0 };
346
+    const char *fname_fmt = PACKAGE "_%.*s_%08lx%08lx.tmp";
347
+    const int max_prefix_len = sizeof(fname) - (sizeof(PACKAGE) + 7 + (2 * 8));
348
+
349
+    while (attempts < 6)
350
+    {
351
+        ++attempts;
352
+
353
+        if (!openvpn_snprintf(fname, sizeof(fname), fname_fmt, max_prefix_len,
354
+                              prefix, (unsigned long) get_random(),
355
+                              (unsigned long) get_random()))
356
+        {
357
+            msg(M_WARN, "ERROR: temporary filename too long");
358
+            return NULL;
359
+        }
360
+
361
+        retfname = platform_gen_path(directory, fname, gc);
362
+        if (!retfname)
363
+        {
364
+            msg(M_WARN, "Failed to create temporary filename and path");
365
+            return NULL;
366
+        }
367
+
368
+        /* Atomically create the file.  Errors out if the file already
369
+         * exists.  */
370
+        fd = platform_open(retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
371
+        if (fd != -1)
372
+        {
373
+            close(fd);
374
+            return retfname;
375
+        }
376
+        else if (fd == -1 && errno != EEXIST)
377
+        {
378
+            /* Something else went wrong, no need to retry.  */
379
+            msg(M_WARN | M_ERRNO, "Could not create temporary file '%s'",
380
+                retfname);
381
+            return NULL;
382
+        }
383
+    }
384
+
385
+    msg(M_WARN, "Failed to create temporary file after %i attempts", attempts);
386
+    return NULL;
387
+}
388
+
389
+/*
390
+ * Put a directory and filename together.
391
+ */
392
+const char *
393
+platform_gen_path(const char *directory, const char *filename,
394
+                  struct gc_arena *gc)
395
+{
396
+#ifdef _WIN32
397
+    const int CC_PATH_RESERVED = CC_LESS_THAN|CC_GREATER_THAN|CC_COLON
398
+                                 |CC_DOUBLE_QUOTE|CC_SLASH|CC_BACKSLASH|CC_PIPE|CC_QUESTION_MARK|CC_ASTERISK;
399
+#else
400
+    const int CC_PATH_RESERVED = CC_SLASH;
401
+#endif
402
+
403
+    if (!gc)
404
+    {
405
+        return NULL; /* Would leak memory otherwise */
406
+    }
407
+
408
+    const char *safe_filename = string_mod_const(filename, CC_PRINT, CC_PATH_RESERVED, '_', gc);
409
+
410
+    if (safe_filename
411
+        && strcmp(safe_filename, ".")
412
+        && strcmp(safe_filename, "..")
413
+#ifdef _WIN32
414
+        && win_safe_filename(safe_filename)
415
+#endif
416
+        )
417
+    {
418
+        const size_t outsize = strlen(safe_filename) + (directory ? strlen(directory) : 0) + 16;
419
+        struct buffer out = alloc_buf_gc(outsize, gc);
420
+        char dirsep[2];
421
+
422
+        dirsep[0] = OS_SPECIFIC_DIRSEP;
423
+        dirsep[1] = '\0';
424
+
425
+        if (directory)
426
+        {
427
+            buf_printf(&out, "%s%s", directory, dirsep);
428
+        }
429
+        buf_printf(&out, "%s", safe_filename);
430
+
431
+        return BSTR(&out);
432
+    }
433
+    else
434
+    {
435
+        return NULL;
436
+    }
437
+}
438
+
439
+bool
440
+platform_absolute_pathname(const char *pathname)
441
+{
442
+    if (pathname)
443
+    {
444
+        const int c = pathname[0];
445
+#ifdef _WIN32
446
+        return c == '\\' || (isalpha(c) && pathname[1] == ':' && pathname[2] == '\\');
447
+#else
448
+        return c == '/';
449
+#endif
450
+    }
451
+    else
452
+    {
453
+        return false;
454
+    }
455
+}
456
+
457
+/* return true if filename can be opened for read */
458
+bool
459
+platform_test_file(const char *filename)
460
+{
461
+    bool ret = false;
462
+    if (filename)
463
+    {
464
+        FILE *fp = platform_fopen(filename, "r");
465
+        if (fp)
466
+        {
467
+            fclose(fp);
468
+            ret = true;
469
+        }
470
+        else
471
+        {
472
+            if (openvpn_errno() == EACCES)
473
+            {
474
+                msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
475
+            }
476
+        }
477
+    }
478
+
479
+    dmsg(D_TEST_FILE, "TEST FILE '%s' [%d]",
480
+         filename ? filename : "UNDEF",
481
+         ret);
482
+
483
+    return ret;
484
+}
... ...
@@ -49,6 +49,7 @@
49 49
 #endif
50 50
 
51 51
 #include "basic.h"
52
+#include "buffer.h"
52 53
 
53 54
 /* Get/Set UID of process */
54 55
 
... ...
@@ -143,4 +144,21 @@ typedef struct stat platform_stat_t;
143 143
 #endif
144 144
 int platform_stat(const char *path, platform_stat_t *buf);
145 145
 
146
+/**
147
+ * Create a temporary file in directory, returns the filename of the created
148
+ * file.
149
+ */
150
+const char *platform_create_temp_file(const char *directory, const char *prefix,
151
+                                      struct gc_arena *gc);
152
+
153
+/** Put a directory and filename together. */
154
+const char *platform_gen_path(const char *directory, const char *filename,
155
+                              struct gc_arena *gc);
156
+
157
+/** Return true if pathname is absolute. */
158
+bool platform_absolute_pathname(const char *pathname);
159
+
160
+/** Return true if filename can be opened for read. */
161
+bool platform_test_file(const char *filename);
162
+
146 163
 #endif /* ifndef PLATFORM_H */
... ...
@@ -249,7 +249,7 @@ plugin_init_item(struct plugin *p, const struct plugin_option *o)
249 249
      * was parsed.
250 250
      *
251 251
      */
252
-    if (!absolute_pathname(p->so_pathname)
252
+    if (!platform_absolute_pathname(p->so_pathname)
253 253
         && p->so_pathname[0] != '.')
254 254
     {
255 255
         char full[PATH_MAX];
... ...
@@ -259,7 +259,7 @@ plugin_init_item(struct plugin *p, const struct plugin_option *o)
259 259
     }
260 260
     else
261 261
     {
262
-        rel = !absolute_pathname(p->so_pathname);
262
+        rel = !platform_absolute_pathname(p->so_pathname);
263 263
         p->handle = dlopen(p->so_pathname, RTLD_NOW);
264 264
     }
265 265
     if (!p->handle)
... ...
@@ -271,7 +271,7 @@ plugin_init_item(struct plugin *p, const struct plugin_option *o)
271 271
 
272 272
 #else  /* ifndef _WIN32 */
273 273
 
274
-    rel = !absolute_pathname(p->so_pathname);
274
+    rel = !platform_absolute_pathname(p->so_pathname);
275 275
     p->module = LoadLibraryW(wide_string(p->so_pathname, &gc));
276 276
     if (!p->module)
277 277
     {
... ...
@@ -547,7 +547,7 @@ verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, stru
547 547
 
548 548
     /* create tmp file to store peer cert */
549 549
     if (!tmp_dir
550
-        || !(peercert_filename = create_temp_file(tmp_dir, "pcf", gc)))
550
+        || !(peercert_filename = platform_create_temp_file(tmp_dir, "pcf", gc)))
551 551
     {
552 552
         msg(M_NONFATAL, "Failed to create peer cert file");
553 553
         return NULL;
... ...
@@ -890,7 +890,7 @@ key_state_gen_auth_control_file(struct key_state *ks, const struct tls_options *
890 890
     struct gc_arena gc = gc_new();
891 891
 
892 892
     key_state_rm_auth_control_file(ks);
893
-    const char *acf = create_temp_file(opt->tmp_dir, "acf", &gc);
893
+    const char *acf = platform_create_temp_file(opt->tmp_dir, "acf", &gc);
894 894
     if (acf)
895 895
     {
896 896
         ks->auth_control_file = string_alloc(acf, NULL);
... ...
@@ -1103,7 +1103,8 @@ verify_user_pass_script(struct tls_session *session, const struct user_pass *up)
1103 1103
         {
1104 1104
             struct status_output *so;
1105 1105
 
1106
-            tmp_file = create_temp_file(session->opt->tmp_dir, "up", &gc);
1106
+            tmp_file = platform_create_temp_file(session->opt->tmp_dir, "up",
1107
+                                                 &gc);
1107 1108
             if (tmp_file)
1108 1109
             {
1109 1110
                 so = status_open(tmp_file, 0, -1, NULL, STATUS_OUTPUT_WRITE);
... ...
@@ -1513,8 +1514,9 @@ verify_final_auth_checks(struct tls_multi *multi, struct tls_session *session)
1513 1513
         struct gc_arena gc = gc_new();
1514 1514
 
1515 1515
         const char *cn = session->common_name;
1516
-        const char *path = gen_path(session->opt->client_config_dir_exclusive, cn, &gc);
1517
-        if (!cn || !strcmp(cn, CCD_DEFAULT) || !test_file(path))
1516
+        const char *path = platform_gen_path(session->opt->client_config_dir_exclusive,
1517
+                                             cn, &gc);
1518
+        if (!cn || !strcmp(cn, CCD_DEFAULT) || !platform_test_file(path))
1518 1519
         {
1519 1520
             ks->authenticated = false;
1520 1521
             wipe_auth_token(multi);
... ...
@@ -19,6 +19,7 @@ argv_testdriver_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir) -I$(compat_srcdir) \
19 19
 argv_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(openvpn_srcdir) -Wl,--wrap=parse_line \
20 20
 	$(OPTIONAL_CRYPTO_LIBS)
21 21
 argv_testdriver_SOURCES = test_argv.c mock_msg.c \
22
+	mock_get_random.c \
22 23
 	$(openvpn_srcdir)/platform.c \
23 24
 	$(openvpn_srcdir)/buffer.c \
24 25
 	$(openvpn_srcdir)/argv.c
... ...
@@ -26,6 +27,7 @@ argv_testdriver_SOURCES = test_argv.c mock_msg.c \
26 26
 buffer_testdriver_CFLAGS  = @TEST_CFLAGS@ -I$(openvpn_srcdir) -I$(compat_srcdir)
27 27
 buffer_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(openvpn_srcdir) -Wl,--wrap=parse_line
28 28
 buffer_testdriver_SOURCES = test_buffer.c mock_msg.c \
29
+	mock_get_random.c \
29 30
 	$(openvpn_srcdir)/buffer.c \
30 31
 	$(openvpn_srcdir)/platform.c
31 32
 
... ...
@@ -35,6 +37,7 @@ packet_id_testdriver_CFLAGS  = @TEST_CFLAGS@ \
35 35
 packet_id_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
36 36
 	$(OPTIONAL_CRYPTO_LIBS)
37 37
 packet_id_testdriver_SOURCES = test_packet_id.c mock_msg.c \
38
+	mock_get_random.c \
38 39
 	$(openvpn_srcdir)/buffer.c \
39 40
 	$(openvpn_srcdir)/otime.c \
40 41
 	$(openvpn_srcdir)/packet_id.c \
... ...
@@ -46,6 +49,7 @@ tls_crypt_testdriver_CFLAGS  = @TEST_CFLAGS@ \
46 46
 tls_crypt_testdriver_LDFLAGS = @TEST_LDFLAGS@ \
47 47
 	$(OPTIONAL_CRYPTO_LIBS)
48 48
 tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \
49
+	$(openvpn_srcdir)/base64.c \
49 50
 	$(openvpn_srcdir)/buffer.c \
50 51
 	$(openvpn_srcdir)/crypto.c \
51 52
 	$(openvpn_srcdir)/crypto_mbedtls.c \
52 53
new file mode 100644
... ...
@@ -0,0 +1,36 @@
0
+/*
1
+ *  OpenVPN -- An application to securely tunnel IP networks
2
+ *             over a single 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) 2017 Fox Crypto B.V. <openvpn@fox-it.com>
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 along
19
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
20
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
+ */
22
+
23
+#include <stdarg.h>
24
+#include <stddef.h>
25
+#include <stdio.h>
26
+#include <stdlib.h>
27
+#include <setjmp.h>
28
+#include <cmocka.h>
29
+
30
+unsigned long
31
+get_random(void)
32
+{
33
+    /* rand() is not very random, but it's C99 and this is just for testing */
34
+    return rand();
35
+}