diff options
Diffstat (limited to 'src/test')
40 files changed, 1258 insertions, 302 deletions
diff --git a/src/test/bench.c b/src/test/bench.c index 5aefda5ff2..5595988f31 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -3,6 +3,7 @@ * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +extern const char tor_git_revision[]; /* Ordinarily defined in tor_main.c; this bit is just here to provide one * since we're not linking to tor_main.c */ const char tor_git_revision[] = ""; diff --git a/src/test/example_extrainfo.inc b/src/test/example_extrainfo.inc index e096afd6c4..0bf2341ef5 100644 --- a/src/test/example_extrainfo.inc +++ b/src/test/example_extrainfo.inc @@ -133,7 +133,7 @@ static const char EX_EI_BAD_NICKNAME_KEY[] = "/UBWNSyXCFDMqnddb/LZ8+VgttmxfYkpeRzSSmDijN3RbOvYJhhBAgMBAAE=\n" "-----END RSA PUBLIC KEY-----\n"; -const char EX_EI_BAD_TOKENS[] = +static const char EX_EI_BAD_TOKENS[] = "extra-info bob 6F314FB01A31162BD5E473D4977AC570DC5B86BB\n" "published 2014-10-05 20:07:00\n" "published 2014-10-05 20:07:00\n" @@ -145,8 +145,9 @@ const char EX_EI_BAD_TOKENS[] = "-----END SIGNATURE-----\n" ; -const char EX_EI_BAD_TOKENS_FP[] = "6F314FB01A31162BD5E473D4977AC570DC5B86BB"; -const char EX_EI_BAD_TOKENS_KEY[] = +static const char EX_EI_BAD_TOKENS_FP[] = + "6F314FB01A31162BD5E473D4977AC570DC5B86BB"; +static const char EX_EI_BAD_TOKENS_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAL7Z8tz45Tb4tnEFS2sAyjubBV/giSfZdmXRkDV8Jo4xqWqhWFJn7+zN\n" "AXBWBThGeVH2WXrpz5seNJXgZJPxMTMsrnSCGcRXZw0Npti2MkLuQ6+prZa+OPwE\n" @@ -210,7 +211,8 @@ static const char EX_EI_GOOD_ED_EI[] = "\n" "\n" ; -const char EX_EI_GOOD_ED_EI_FP[] = "A692FE045C32B5E3A54B52882EF678A9DAC46A73"; +static const char EX_EI_GOOD_ED_EI_FP[] = + "A692FE045C32B5E3A54B52882EF678A9DAC46A73"; static const char EX_EI_GOOD_ED_EI_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAM3jdYwjwGxDWYj/vyFkQT7RgeCNIn89Ei6D2+L/fdtFnqrMXOreFFHL\n" @@ -237,7 +239,8 @@ static const char EX_EI_ED_MISSING_SIG[] = "\n" "\n" ; -const char EX_EI_ED_MISSING_SIG_FP[] = "2A7521497B91A8437021515308A47491164EDBA1"; +static const char EX_EI_ED_MISSING_SIG_FP[] = + "2A7521497B91A8437021515308A47491164EDBA1"; static const char EX_EI_ED_MISSING_SIG_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAOOB8ccxbtk2dB5FuKFhGndDcO6STNjB6KiG0b9X2QwKrOZMfmXSigto\n" @@ -260,7 +263,8 @@ static const char EX_EI_ED_MISSING_CERT[] = "\n" "\n" ; -const char EX_EI_ED_MISSING_CERT_FP[] = "E88E43E86015345A323D93D825C33E4AD1028F65"; +static const char EX_EI_ED_MISSING_CERT_FP[] = + "E88E43E86015345A323D93D825C33E4AD1028F65"; static const char EX_EI_ED_MISSING_CERT_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBALjA/geb0TR9rp/UPvLhABQpB0XUDYuZAnLkrv+i7AAV7FemTDveEGnc\n" @@ -284,7 +288,8 @@ static const char EX_EI_ED_BAD_CERT1[] = "-----END SIGNATURE-----\n" "\n" ; -const char EX_EI_ED_BAD_CERT1_FP[] = "F78D8A655607D32281D02144817A4F1D26AE520F"; +static const char EX_EI_ED_BAD_CERT1_FP[] = + "F78D8A655607D32281D02144817A4F1D26AE520F"; static const char EX_EI_ED_BAD_CERT1_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAMlR46JhxsCmWYtmIB/JjTV2TUYIhJLmHy+X7FfkK3ZVQvvl9/3GSXFL\n" @@ -309,7 +314,8 @@ static const char EX_EI_ED_BAD_CERT2[] = "cVrtU6RVmzldSbyir8V/Z4S/Cm67gYAgjM5gfoFUqDs=\n" "-----END SIGNATURE-----\n" ; -const char EX_EI_ED_BAD_CERT2_FP[] = "7C2B42E783C4E0EB0CC3BDB37385D16737BACFBD"; +static const char EX_EI_ED_BAD_CERT2_FP[] = + "7C2B42E783C4E0EB0CC3BDB37385D16737BACFBD"; static const char EX_EI_ED_BAD_CERT2_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBALAM1F/0XJEsbxIQqb3+ObX/yGVnq9of8Q9sLsmxffD6hwVpCqnV3lTg\n" @@ -335,7 +341,8 @@ static const char EX_EI_ED_BAD_SIG1[] = "-----END SIGNATURE-----\n" "\n" ; -const char EX_EI_ED_BAD_SIG1_FP[] = "5AC3A538FEEFC6F9FCC5FA0CE64704396C30D62A"; +static const char EX_EI_ED_BAD_SIG1_FP[] = + "5AC3A538FEEFC6F9FCC5FA0CE64704396C30D62A"; static const char EX_EI_ED_BAD_SIG1_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAMvb6SuoIkPfBkJgQuo5aQDepAs1kEETZ9VXotMlhB0JJikrqBrAAz+7\n" @@ -361,7 +368,8 @@ static const char EX_EI_ED_BAD_SIG2[] = "-----END SIGNATURE-----\n" "\n" ; -const char EX_EI_ED_BAD_SIG2_FP[] = "7F1D4DD477E340C6D6B389FAC26EDC746113082F"; +static const char EX_EI_ED_BAD_SIG2_FP[] = + "7F1D4DD477E340C6D6B389FAC26EDC746113082F"; static const char EX_EI_ED_BAD_SIG2_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBALzOyfCEUZnvCyhlyMctPkdXg/XRE3Cr6QgyzdKf5kQbUiu2n0FgSHOX\n" @@ -388,7 +396,8 @@ static const char EX_EI_ED_MISPLACED_CERT[] = "-----END SIGNATURE-----\n" "\n" ; -const char EX_EI_ED_MISPLACED_CERT_FP[] = "3B788BD0CE348BC5CED48313307C78175EB6D0F3"; +static const char EX_EI_ED_MISPLACED_CERT_FP[] = + "3B788BD0CE348BC5CED48313307C78175EB6D0F3"; static const char EX_EI_ED_MISPLACED_CERT_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBALTwNqhTprg1oC6bEbDqwIYBoER6prqUXQFbwbFDn+ekXhZj8vltgGwp\n" @@ -414,7 +423,8 @@ static const char EX_EI_ED_MISPLACED_SIG[] = "-----END SIGNATURE-----\n" "\n" ; -const char EX_EI_ED_MISPLACED_SIG_FP[] = "384E40A5DEED4AB1D8A74F1FCBDB18B7C24A8284"; +static const char EX_EI_ED_MISPLACED_SIG_FP[] = + "384E40A5DEED4AB1D8A74F1FCBDB18B7C24A8284"; static const char EX_EI_ED_MISPLACED_SIG_KEY[] = "-----BEGIN RSA PUBLIC KEY-----\n" "MIGJAoGBAK0HgOCG/6433VCrwz/vhk3cKmyOfenCp0GZ4DIUwPWt4DeyP4nTbN6T\n" diff --git a/src/test/include.am b/src/test/include.am index 7d80fdf152..fa660f5302 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -17,6 +17,7 @@ endif TESTS += src/test/test src/test/test-slow src/test/test-memwipe \ src/test/test_workqueue src/test/test_keygen.sh \ + src/test/test-timers \ $(TESTSCRIPTS) # These flavors are run using automake's test-driver and test-network.sh @@ -40,7 +41,8 @@ noinst_PROGRAMS+= \ src/test/test-memwipe \ src/test/test-child \ src/test/test_workqueue \ - src/test/test-switch-id + src/test/test-switch-id \ + src/test/test-timers endif src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \ @@ -86,6 +88,7 @@ src_test_test_SOURCES = \ src/test/test_guardfraction.c \ src/test/test_extorport.c \ src/test/test_hs.c \ + src/test/test_handles.c \ src/test/test_introduce.c \ src/test/test_keypin.c \ src/test/test_link_handshake.c \ @@ -97,6 +100,7 @@ src_test_test_SOURCES = \ src/test/test_policy.c \ src/test/test_procmon.c \ src/test/test_pt.c \ + src/test/test_pubsub.c \ src/test/test_relay.c \ src/test/test_relaycell.c \ src/test/test_rendcache.c \ @@ -127,6 +131,8 @@ src_test_test_slow_SOURCES = \ src_test_test_memwipe_SOURCES = \ src/test/test-memwipe.c +src_test_test_timers_SOURCES = \ + src/test/test-timers.c src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) @@ -147,6 +153,7 @@ src_test_test_switch_id_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) src_test_test_switch_id_LDFLAGS = @TOR_LDFLAGS_zlib@ src_test_test_switch_id_LDADD = \ src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @@ -156,6 +163,7 @@ src_test_test_LDADD = src/or/libtor-testing.a \ $(LIBKECCAK_TINY) \ $(LIBDONNA) \ src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ src/common/libor-event-testing.a \ src/trunnel/libor-trunnel-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ @@ -168,13 +176,17 @@ src_test_test_slow_LDADD = $(src_test_test_LDADD) src_test_test_slow_LDFLAGS = $(src_test_test_LDFLAGS) src_test_test_memwipe_CPPFLAGS = $(src_test_test_CPPFLAGS) -src_test_test_memwipe_CFLAGS = $(src_test_test_CFLAGS) +# Don't use bugtrap cflags here: memwipe tests require memory violations. +src_test_test_memwipe_CFLAGS = $(TEST_CFLAGS) src_test_test_memwipe_LDADD = $(src_test_test_LDADD) -src_test_test_memwipe_LDFLAGS = $(src_test_test_LDFLAGS) +# The LDFLAGS need to include the bugtrap cflags, or else we won't link +# successfully with the libraries built with them. +src_test_test_memwipe_LDFLAGS = $(src_test_test_LDFLAGS) @CFLAGS_BUGTRAP@ src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @TOR_LDFLAGS_libevent@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \ + src/common/libor-ctime.a \ src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \ src/common/libor-event.a src/trunnel/libor-trunnel.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ @@ -185,11 +197,23 @@ src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @TOR_LDFLAGS_libevent@ src_test_test_workqueue_LDADD = src/or/libtor-testing.a \ src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \ src/common/libor-event-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ +src_test_test_timers_CPPFLAGS = $(src_test_test_CPPFLAGS) +src_test_test_timers_CFLAGS = $(src_test_test_CFLAGS) +src_test_test_timers_LDADD = \ + src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ + src/common/libor-event-testing.a \ + src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \ + @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ +src_test_test_timers_LDFLAGS = $(src_test_test_LDFLAGS) + noinst_HEADERS+= \ src/test/fakechans.h \ src/test/log_test_helpers.h \ @@ -208,6 +232,7 @@ noinst_PROGRAMS+= src/test/test-ntor-cl src_test_test_ntor_cl_SOURCES = src/test/test_ntor_cl.c src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ src_test_test_ntor_cl_LDADD = src/or/libtor.a src/common/libor.a \ + src/common/libor-ctime.a \ src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @@ -217,6 +242,7 @@ src_test_test_ntor_cl_AM_CPPFLAGS = \ noinst_PROGRAMS += src/test/test-bt-cl src_test_test_bt_cl_SOURCES = src/test/test_bt_cl.c src_test_test_bt_cl_LDADD = src/common/libor-testing.a \ + src/common/libor-ctime-testing.a \ @TOR_LIB_MATH@ \ @TOR_LIB_WS32@ @TOR_LIB_GDI@ src_test_test_bt_cl_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) @@ -228,7 +254,7 @@ EXTRA_DIST += \ src/test/slownacl_curve25519.py \ src/test/zero_length_keys.sh \ src/test/test_keygen.sh \ - src/test/test_zero_length_keys.sh \ - src/test/test_ntor.sh src/test/test_bt.sh \ + src/test/test_zero_length_keys.sh \ + src/test/test_ntor.sh src/test/test_bt.sh \ src/test/test-network.sh \ src/test/test_switch_id.sh diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c index 5d4fcec664..c28d5054a2 100644 --- a/src/test/test-memwipe.c +++ b/src/test/test-memwipe.c @@ -6,9 +6,6 @@ #include "crypto.h" #include "compat.h" -#undef MIN -#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) - static unsigned fill_a_buffer_memset(void) __attribute__((noinline)); static unsigned fill_a_buffer_memwipe(void) __attribute__((noinline)); static unsigned fill_a_buffer_nothing(void) __attribute__((noinline)); @@ -17,6 +14,7 @@ static unsigned fill_heap_buffer_memwipe(void) __attribute__((noinline)); static unsigned fill_heap_buffer_nothing(void) __attribute__((noinline)); static unsigned check_a_buffer(void) __attribute__((noinline)); +extern const char *s; /* Make the linkage global */ const char *s = NULL; #define BUF_LEN 2048 diff --git a/src/test/test-timers.c b/src/test/test-timers.c new file mode 100644 index 0000000000..0196ec1fef --- /dev/null +++ b/src/test/test-timers.c @@ -0,0 +1,134 @@ +/* Copyright 2016, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" + +#include <math.h> +#include <stdio.h> +#include <string.h> + +#ifdef HAVE_EVENT2_EVENT_H +#include <event2/event.h> +#else +#include <event.h> +#endif + +#include "compat.h" +#include "compat_libevent.h" +#include "crypto.h" +#include "timers.h" +#include "util.h" + +#define N_TIMERS 1000 +#define MAX_DURATION 30 +#define N_DISABLE 5 + +static struct timeval fire_at[N_TIMERS] = { {0,0} }; +static int is_disabled[N_TIMERS] = {0}; +static int fired[N_TIMERS] = {0}; +static struct timeval difference[N_TIMERS] = { {0,0} }; +static tor_timer_t *timers[N_TIMERS] = {NULL}; + +static int n_active_timers = 0; +static int n_fired = 0; + +static void +timer_cb(tor_timer_t *t, void *arg, const struct timeval *now) +{ + tor_timer_t **t_ptr = arg; + tor_assert(*t_ptr == t); + int idx = (int) (t_ptr - timers); + ++fired[idx]; + timersub(now, &fire_at[idx], &difference[idx]); + ++n_fired; + // printf("%d / %d\n",n_fired, N_TIMERS); + if (n_fired == n_active_timers) { + event_base_loopbreak(tor_libevent_get_base()); + } +} + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + tor_libevent_cfg cfg; + memset(&cfg, 0, sizeof(cfg)); + tor_libevent_initialize(&cfg); + timers_initialize(); + + int i; + int ret; + struct timeval now; + tor_gettimeofday(&now); + for (i = 0; i < N_TIMERS; ++i) { + struct timeval delay; + delay.tv_sec = crypto_rand_int_range(0,MAX_DURATION); + delay.tv_usec = crypto_rand_int_range(0,1000000); + timeradd(&now, &delay, &fire_at[i]); + timers[i] = timer_new(timer_cb, &timers[i]); + timer_schedule(timers[i], &delay); + ++n_active_timers; + } + + /* Disable some; we'll make sure they don't trigger. */ + for (i = 0; i < N_DISABLE; ++i) { + int idx = crypto_rand_int_range(0, N_TIMERS); + if (is_disabled[idx]) + continue; + is_disabled[idx] = 1; + timer_disable(timers[idx]); + --n_active_timers; + } + + event_base_loop(tor_libevent_get_base(), 0); + + int64_t total_difference = 0; + uint64_t total_square_difference = 0; + tor_assert(n_fired == n_active_timers); + for (i = 0; i < N_TIMERS; ++i) { + if (is_disabled[i]) { + tor_assert(fired[i] == 0); + continue; + } + tor_assert(fired[i] == 1); + int64_t diff = difference[i].tv_usec + difference[i].tv_sec * 1000000; + total_difference += diff; + total_square_difference += diff*diff; + } + const int64_t mean_diff = total_difference / n_active_timers; + printf("mean difference: "U64_FORMAT" usec\n", + U64_PRINTF_ARG(mean_diff)); + + const double mean_sq = ((double)total_square_difference)/ n_active_timers; + const double sq_mean = mean_diff * mean_diff; + const double stddev = sqrt(mean_sq - sq_mean); + printf("standard deviation: %lf usec\n", stddev); + +#define MAX_DIFF_USEC (500*1000) +#define MAX_STDDEV_USEC (500*1000) +#define ODD_DIFF_USEC (2000) +#define ODD_STDDEV_USEC (2000) + + if (mean_diff < 0 || mean_diff > MAX_DIFF_USEC || stddev > MAX_STDDEV_USEC) { + printf("Either your system is under ridiculous load, or the " + "timer backend is broken.\n"); + ret = 1; + } else if (mean_diff > ODD_DIFF_USEC || stddev > ODD_STDDEV_USEC) { + printf("Either your system is a bit slow or the " + "timer backend is odd.\n"); + ret = 0; + } else { + printf("Looks good enough.\n"); + ret = 0; + } + + timer_free(NULL); + + for (i = 0; i < N_TIMERS; ++i) { + timer_free(timers[i]); + } + timers_shutdown(); + return ret; +} + diff --git a/src/test/test.c b/src/test/test.c index ed167a3e67..c0faec3027 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1124,60 +1124,6 @@ static struct testcase_t test_array[] = { END_OF_TESTCASES }; -extern struct testcase_t accounting_tests[]; -extern struct testcase_t addr_tests[]; -extern struct testcase_t address_tests[]; -extern struct testcase_t buffer_tests[]; -extern struct testcase_t cell_format_tests[]; -extern struct testcase_t cell_queue_tests[]; -extern struct testcase_t channel_tests[]; -extern struct testcase_t channeltls_tests[]; -extern struct testcase_t checkdir_tests[]; -extern struct testcase_t circuitlist_tests[]; -extern struct testcase_t circuitmux_tests[]; -extern struct testcase_t compat_libevent_tests[]; -extern struct testcase_t config_tests[]; -extern struct testcase_t connection_tests[]; -extern struct testcase_t container_tests[]; -extern struct testcase_t controller_tests[]; -extern struct testcase_t controller_event_tests[]; -extern struct testcase_t crypto_tests[]; -extern struct testcase_t dir_tests[]; -extern struct testcase_t dir_handle_get_tests[]; -extern struct testcase_t entryconn_tests[]; -extern struct testcase_t entrynodes_tests[]; -extern struct testcase_t guardfraction_tests[]; -extern struct testcase_t extorport_tests[]; -extern struct testcase_t hs_tests[]; -extern struct testcase_t introduce_tests[]; -extern struct testcase_t keypin_tests[]; -extern struct testcase_t link_handshake_tests[]; -extern struct testcase_t logging_tests[]; -extern struct testcase_t microdesc_tests[]; -extern struct testcase_t nodelist_tests[]; -extern struct testcase_t oom_tests[]; -extern struct testcase_t options_tests[]; -extern struct testcase_t policy_tests[]; -extern struct testcase_t procmon_tests[]; -extern struct testcase_t pt_tests[]; -extern struct testcase_t relay_tests[]; -extern struct testcase_t relaycell_tests[]; -extern struct testcase_t rend_cache_tests[]; -extern struct testcase_t replaycache_tests[]; -extern struct testcase_t router_tests[]; -extern struct testcase_t routerkeys_tests[]; -extern struct testcase_t routerlist_tests[]; -extern struct testcase_t routerset_tests[]; -extern struct testcase_t scheduler_tests[]; -extern struct testcase_t socks_tests[]; -extern struct testcase_t status_tests[]; -extern struct testcase_t thread_tests[]; -extern struct testcase_t tortls_tests[]; -extern struct testcase_t util_tests[]; -extern struct testcase_t util_format_tests[]; -extern struct testcase_t util_process_tests[]; -extern struct testcase_t dns_tests[]; - struct testgroup_t testgroups[] = { { "", test_array }, { "accounting/", accounting_tests }, @@ -1230,7 +1176,9 @@ struct testgroup_t testgroups[] = { { "util/format/", util_format_tests }, { "util/logging/", logging_tests }, { "util/process/", util_process_tests }, + { "util/pubsub/", pubsub_tests }, { "util/thread/", thread_tests }, + { "util/handle/", handle_tests }, { "dns/", dns_tests }, END_OF_GROUPS }; diff --git a/src/test/test.h b/src/test/test.h index e618ce1224..747b61d669 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -73,7 +73,7 @@ {print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION) const char *get_fname(const char *name); -crypto_pk_t *pk_generate(int idx); +struct crypto_pk_t *pk_generate(int idx); #define US2_CONCAT_2__(a, b) a ## __ ## b #define US_CONCAT_2__(a, b) a ## _ ## b @@ -163,11 +163,86 @@ crypto_pk_t *pk_generate(int idx); #define CALLED(mock_name) US_CONCAT_2_(NS(mock_name), called) #define NS_DECL(retval, mock_fn, args) \ + extern int CALLED(mock_fn); \ static retval NS(mock_fn) args; int CALLED(mock_fn) = 0 #define NS_MOCK(name) MOCK(name, NS(name)) #define NS_UNMOCK(name) UNMOCK(name) extern const struct testcase_setup_t passthrough_setup; +extern struct testcase_t accounting_tests[]; +extern struct testcase_t addr_tests[]; +extern struct testcase_t address_tests[]; +extern struct testcase_t buffer_tests[]; +extern struct testcase_t cell_format_tests[]; +extern struct testcase_t cell_queue_tests[]; +extern struct testcase_t channel_tests[]; +extern struct testcase_t channeltls_tests[]; +extern struct testcase_t checkdir_tests[]; +extern struct testcase_t circuitlist_tests[]; +extern struct testcase_t circuitmux_tests[]; +extern struct testcase_t compat_libevent_tests[]; +extern struct testcase_t config_tests[]; +extern struct testcase_t connection_tests[]; +extern struct testcase_t container_tests[]; +extern struct testcase_t controller_tests[]; +extern struct testcase_t controller_event_tests[]; +extern struct testcase_t crypto_tests[]; +extern struct testcase_t dir_tests[]; +extern struct testcase_t dir_handle_get_tests[]; +extern struct testcase_t entryconn_tests[]; +extern struct testcase_t entrynodes_tests[]; +extern struct testcase_t guardfraction_tests[]; +extern struct testcase_t extorport_tests[]; +extern struct testcase_t hs_tests[]; +extern struct testcase_t introduce_tests[]; +extern struct testcase_t keypin_tests[]; +extern struct testcase_t link_handshake_tests[]; +extern struct testcase_t logging_tests[]; +extern struct testcase_t microdesc_tests[]; +extern struct testcase_t nodelist_tests[]; +extern struct testcase_t oom_tests[]; +extern struct testcase_t options_tests[]; +extern struct testcase_t policy_tests[]; +extern struct testcase_t procmon_tests[]; +extern struct testcase_t pubsub_tests[]; +extern struct testcase_t pt_tests[]; +extern struct testcase_t relay_tests[]; +extern struct testcase_t relaycell_tests[]; +extern struct testcase_t rend_cache_tests[]; +extern struct testcase_t replaycache_tests[]; +extern struct testcase_t router_tests[]; +extern struct testcase_t routerkeys_tests[]; +extern struct testcase_t routerlist_tests[]; +extern struct testcase_t routerset_tests[]; +extern struct testcase_t scheduler_tests[]; +extern struct testcase_t socks_tests[]; +extern struct testcase_t status_tests[]; +extern struct testcase_t thread_tests[]; +extern struct testcase_t tortls_tests[]; +extern struct testcase_t util_tests[]; +extern struct testcase_t util_format_tests[]; +extern struct testcase_t util_process_tests[]; +extern struct testcase_t dns_tests[]; +extern struct testcase_t handle_tests[]; + +extern struct testcase_t slow_crypto_tests[]; +extern struct testcase_t slow_util_tests[]; + +extern struct testgroup_t testgroups[]; + +extern const char AUTHORITY_CERT_1[]; +extern const char AUTHORITY_SIGNKEY_1[]; +extern const char AUTHORITY_SIGNKEY_A_DIGEST[]; +extern const char AUTHORITY_SIGNKEY_A_DIGEST256[]; +extern const char AUTHORITY_CERT_2[]; +extern const char AUTHORITY_SIGNKEY_2[]; +extern const char AUTHORITY_SIGNKEY_B_DIGEST[]; +extern const char AUTHORITY_SIGNKEY_B_DIGEST256[]; +extern const char AUTHORITY_CERT_3[]; +extern const char AUTHORITY_SIGNKEY_3[]; +extern const char AUTHORITY_SIGNKEY_C_DIGEST[]; +extern const char AUTHORITY_SIGNKEY_C_DIGEST256[]; + #endif diff --git a/src/test/test_bt.sh b/src/test/test_bt.sh index 033acac955..fe1781659d 100755 --- a/src/test/test_bt.sh +++ b/src/test/test_bt.sh @@ -3,8 +3,9 @@ exitcode=0 +export ASAN_OPTIONS="handle_segv=0:allow_user_segv_handler=1" "${builddir:-.}/src/test/test-bt-cl" backtraces || exit $? -"${builddir:-.}/src/test/test-bt-cl" assert | "${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/bt_test.py" || exitcode="$?" -"${builddir:-.}/src/test/test-bt-cl" crash | "${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/bt_test.py" || exitcode="$?" +"${builddir:-.}/src/test/test-bt-cl" assert 2>&1 | "${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/bt_test.py" || exitcode="$?" +"${builddir:-.}/src/test/test-bt-cl" crash 2>&1 | "${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/bt_test.py" || exitcode="$?" exit ${exitcode} diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c index 2f5e50fbf5..95b4f48f11 100644 --- a/src/test/test_bt_cl.c +++ b/src/test/test_bt_cl.c @@ -28,6 +28,9 @@ int a_tangled_web(int x) NOINLINE; int we_weave(int x) NOINLINE; static void abort_handler(int s) NORETURN; +#ifdef HAVE_CFLAG_WNULL_DEREFERENCE +DISABLE_GCC_WARNING(null-dereference) +#endif int crash(int x) { @@ -47,6 +50,9 @@ crash(int x) crashtype *= x; return crashtype; } +#ifdef HAVE_CFLAG_WNULL_DEREFERENCE +ENABLE_GCC_WARNING(null-dereference) +#endif int oh_what(int x) diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c index e5e56edf75..95584d54a8 100644 --- a/src/test/test_buffers.c +++ b/src/test/test_buffers.c @@ -695,9 +695,9 @@ test_buffers_zlib_fin_at_chunk_end(void *arg) tor_free(msg); } -const uint8_t *tls_read_ptr; -int n_remaining; -int next_reply_val[16]; +static const uint8_t *tls_read_ptr; +static int n_remaining; +static int next_reply_val[16]; static int mock_tls_read(tor_tls_t *tls, char *cp, size_t len) diff --git a/src/test/test_channel.c b/src/test/test_channel.c index 846e419fea..a9e0634d9e 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -20,9 +20,6 @@ #include "test.h" #include "fakechans.h" -/* This comes from channel.c */ -extern uint64_t estimated_total_queue_size; - static int test_chan_accept_cells = 0; static int test_chan_fixed_cells_recved = 0; static cell_t * test_chan_last_seen_fixed_cell_ptr = NULL; @@ -33,7 +30,7 @@ static int test_destroy_not_pending_calls = 0; static int test_doesnt_want_writes_count = 0; static int test_dumpstats_calls = 0; static int test_has_waiting_cells_count = 0; -static double test_overhead_estimate = 1.0f; +static double test_overhead_estimate = 1.0; static int test_releases_count = 0; static circuitmux_t *test_target_cmux = NULL; static unsigned int test_cmux_cells = 0; @@ -792,7 +789,7 @@ test_channel_incoming(void *arg) /* Accept cells to lower layer */ test_chan_accept_cells = 1; /* Use default overhead factor */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; ch = new_fake_channel(); tt_assert(ch); @@ -881,7 +878,7 @@ test_channel_lifecycle(void *arg) /* Accept cells to lower layer */ test_chan_accept_cells = 1; /* Use default overhead factor */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; ch1 = new_fake_channel(); tt_assert(ch1); @@ -989,7 +986,7 @@ test_channel_lifecycle_2(void *arg) /* Accept cells to lower layer */ test_chan_accept_cells = 1; /* Use default overhead factor */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; ch = new_fake_channel(); tt_assert(ch); @@ -1136,7 +1133,7 @@ test_channel_multi(void *arg) /* Accept cells to lower layer */ test_chan_accept_cells = 1; /* Use default overhead factor */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; ch1 = new_fake_channel(); tt_assert(ch1); @@ -1444,7 +1441,7 @@ test_channel_queue_incoming(void *arg) /* Accept cells to lower layer */ test_chan_accept_cells = 1; /* Use default overhead factor */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; ch = new_fake_channel(); tt_assert(ch); @@ -1584,16 +1581,16 @@ test_channel_queue_size(void *arg) /* One cell, times an overhead factor of 1.0 */ tt_u64_op(ch->bytes_queued_for_xmit, ==, 512); /* Try a different overhead factor */ - test_overhead_estimate = 0.5f; + test_overhead_estimate = 0.5; /* This one should be ignored since it's below 1.0 */ channel_update_xmit_queue_size(ch); tt_u64_op(ch->bytes_queued_for_xmit, ==, 512); /* Now try a larger one */ - test_overhead_estimate = 2.0f; + test_overhead_estimate = 2.0; channel_update_xmit_queue_size(ch); tt_u64_op(ch->bytes_queued_for_xmit, ==, 1024); /* Go back to 1.0 */ - test_overhead_estimate = 1.0f; + test_overhead_estimate = 1.0; channel_update_xmit_queue_size(ch); tt_u64_op(ch->bytes_queued_for_xmit, ==, 512); /* Check the global estimate too */ diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 04ae9a6da7..394612f155 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -185,7 +185,7 @@ test_channeltls_overhead_estimate(void *arg) const char test_digest[DIGEST_LEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14 }; - float r; + double r; channel_tls_t *tlschan = NULL; (void)arg; @@ -206,31 +206,31 @@ test_channeltls_overhead_estimate(void *arg) ch = channel_tls_connect(&test_addr, 567, test_digest); tt_assert(ch != NULL); - /* First case: silly low ratios should get clamped to 1.0f */ + /* First case: silly low ratios should get clamped to 1.0 */ tlschan = BASE_CHAN_TO_TLS(ch); tt_assert(tlschan != NULL); tlschan->conn->bytes_xmitted = 128; tlschan->conn->bytes_xmitted_by_tls = 64; r = ch->get_overhead_estimate(ch); - tt_assert(fabsf(r - 1.0f) < 1E-12); + tt_assert(fabs(r - 1.0) < 1E-12); tlschan->conn->bytes_xmitted_by_tls = 127; r = ch->get_overhead_estimate(ch); - tt_assert(fabsf(r - 1.0f) < 1E-12); + tt_assert(fabs(r - 1.0) < 1E-12); /* Now middle of the range */ tlschan->conn->bytes_xmitted_by_tls = 192; r = ch->get_overhead_estimate(ch); - tt_assert(fabsf(r - 1.5f) < 1E-12); + tt_assert(fabs(r - 1.5) < 1E-12); - /* Now above the 2.0f clamp */ + /* Now above the 2.0 clamp */ tlschan->conn->bytes_xmitted_by_tls = 257; r = ch->get_overhead_estimate(ch); - tt_assert(fabsf(r - 2.0f) < 1E-12); + tt_assert(fabs(r - 2.0) < 1E-12); tlschan->conn->bytes_xmitted_by_tls = 512; r = ch->get_overhead_estimate(ch); - tt_assert(fabsf(r - 2.0f) < 1E-12); + tt_assert(fabs(r - 2.0) < 1E-12); done: if (ch) { diff --git a/src/test/test_controller.c b/src/test/test_controller.c index 7f9db4312f..b276e06787 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -154,10 +154,61 @@ test_rend_service_parse_port_config(void *arg) tor_free(err_msg); } +static void +test_add_onion_helper_clientauth(void *arg) +{ + rend_authorized_client_t *client = NULL; + char *err_msg = NULL; + int created = 0; + + (void)arg; + + /* Test "ClientName" only. */ + client = add_onion_helper_clientauth("alice", &created, &err_msg); + tt_assert(client); + tt_assert(created); + tt_assert(!err_msg); + rend_authorized_client_free(client); + + /* Test "ClientName:Blob" */ + client = add_onion_helper_clientauth("alice:475hGBHPlq7Mc0cRZitK/B", + &created, &err_msg); + tt_assert(client); + tt_assert(!created); + tt_assert(!err_msg); + rend_authorized_client_free(client); + + /* Test invalid client names */ + client = add_onion_helper_clientauth("no*asterisks*allowed", &created, + &err_msg); + tt_assert(!client); + tt_assert(err_msg); + tor_free(err_msg); + + /* Test invalid auth cookie */ + client = add_onion_helper_clientauth("alice:12345", &created, &err_msg); + tt_assert(!client); + tt_assert(err_msg); + tor_free(err_msg); + + /* Test invalid syntax */ + client = add_onion_helper_clientauth(":475hGBHPlq7Mc0cRZitK/B", &created, + &err_msg); + tt_assert(!client); + tt_assert(err_msg); + tor_free(err_msg); + + done: + rend_authorized_client_free(client); + tor_free(err_msg); +} + struct testcase_t controller_tests[] = { { "add_onion_helper_keyarg", test_add_onion_helper_keyarg, 0, NULL, NULL }, { "rend_service_parse_port_config", test_rend_service_parse_port_config, 0, NULL, NULL }, + { "add_onion_helper_clientauth", test_add_onion_helper_clientauth, 0, NULL, + NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 6a95e92733..bf4b68efe2 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -18,15 +18,12 @@ #include <openssl/evp.h> #include <openssl/rand.h> -extern const char AUTHORITY_SIGNKEY_3[]; -extern const char AUTHORITY_SIGNKEY_A_DIGEST[]; -extern const char AUTHORITY_SIGNKEY_A_DIGEST256[]; - /** Run unit tests for Diffie-Hellman functionality. */ static void test_crypto_dh(void *arg) { crypto_dh_t *dh1 = crypto_dh_new(DH_TYPE_CIRCUIT); + crypto_dh_t *dh1_dup = NULL; crypto_dh_t *dh2 = crypto_dh_new(DH_TYPE_CIRCUIT); char p1[DH_BYTES]; char p2[DH_BYTES]; @@ -41,6 +38,9 @@ test_crypto_dh(void *arg) memset(p1, 0, DH_BYTES); memset(p2, 0, DH_BYTES); tt_mem_op(p1,OP_EQ, p2, DH_BYTES); + + tt_int_op(-1, OP_EQ, crypto_dh_get_public(dh1, p1, 6)); /* too short */ + tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES)); tt_mem_op(p1,OP_NE, p2, DH_BYTES); tt_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES)); @@ -54,15 +54,119 @@ test_crypto_dh(void *arg) tt_int_op(s1len,OP_EQ, s2len); tt_mem_op(s1,OP_EQ, s2, s1len); + /* test dh_dup; make sure it works the same. */ + dh1_dup = crypto_dh_dup(dh1); + s1len = crypto_dh_compute_secret(LOG_WARN, dh1_dup, p2, DH_BYTES, s1, 50); + tt_mem_op(s1,OP_EQ, s2, s1len); + { - /* XXXX Now fabricate some bad values and make sure they get caught, - * Check 0, 1, N-1, >= N, etc. - */ + /* Now fabricate some bad values and make sure they get caught. */ + + /* 1 and 0 should both fail. */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x01", 1, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x00", 1, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + memset(p1, 0, DH_BYTES); /* 0 with padding. */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + p1[DH_BYTES-1] = 1; /* 1 with padding*/ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + /* 2 is okay, though weird. */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x02", 1, s1, 50); + tt_int_op(50, OP_EQ, s1len); + + const char P[] = + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE65381FFFFFFFFFFFFFFFF"; + + /* p-1, p, and so on are not okay. */ + base16_decode(p1, sizeof(p1), P, strlen(P)); + + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + p1[DH_BYTES-1] = 0xFE; /* p-1 */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + p1[DH_BYTES-1] = 0xFD; /* p-2 works fine */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(50, OP_EQ, s1len); + + const char P_plus_one[] = + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" + "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B" + "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9" + "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6" + "49286651ECE653820000000000000000"; + + base16_decode(p1, sizeof(p1), P_plus_one, strlen(P_plus_one)); + + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + p1[DH_BYTES-1] = 0x01; /* p+2 */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + p1[DH_BYTES-1] = 0xff; /* p+256 */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + + memset(p1, 0xff, DH_BYTES), /* 2^1024-1 */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50); + tt_int_op(-1, OP_EQ, s1len); + } + + { + /* provoke an error in the openssl DH_compute_key function; make sure we + * survive. */ + tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES)); + + crypto_dh_free(dh2); + dh2= crypto_dh_new(DH_TYPE_CIRCUIT); /* no private key set */ + s1len = crypto_dh_compute_secret(LOG_WARN, dh2, + p1, DH_BYTES, + s1, 50); + tt_int_op(s1len, OP_EQ, -1); } done: crypto_dh_free(dh1); crypto_dh_free(dh2); + crypto_dh_free(dh1_dup); +} + +static void +test_crypto_openssl_version(void *arg) +{ + (void)arg; + const char *version = crypto_openssl_get_version_str(); + const char *h_version = crypto_openssl_get_header_version_str(); + tt_assert(version); + tt_assert(h_version); + tt_assert(!strcmpstart(version, h_version)); /* "-fips" suffix, etc */ + tt_assert(!strstr(version, "OpenSSL")); + int a=-1,b=-1,c=-1; + if (!strcmpstart(version, "LibreSSL") || !strcmpstart(version, "BoringSSL")) + return; + int r = tor_sscanf(version, "%d.%d.%d", &a,&b,&c); + tt_int_op(r, OP_EQ, 3); + tt_int_op(a, OP_GE, 0); + tt_int_op(b, OP_GE, 0); + tt_int_op(c, OP_GE, 0); + + done: + ; } /** Run unit tests for our random number generation function and its wrappers. @@ -73,6 +177,7 @@ test_crypto_rng(void *arg) int i, j, allok; char data1[100], data2[100]; double d; + char *h=NULL; /* Try out RNG. */ (void)arg; @@ -104,9 +209,16 @@ test_crypto_rng(void *arg) allok = 0; tor_free(host); } + + /* Make sure crypto_random_hostname clips its inputs properly. */ + h = crypto_random_hostname(20000, 9000, "www.", ".onion"); + tt_assert(! strcmpstart(h,"www.")); + tt_assert(! strcmpend(h,".onion")); + tt_int_op(63+4+6, OP_EQ, strlen(h)); + tt_assert(allok); done: - ; + tor_free(h); } static void @@ -125,14 +237,100 @@ test_crypto_rng_range(void *arg) if (x == 8) got_largest = 1; } - /* These fail with probability 1/10^603. */ tt_assert(got_smallest); tt_assert(got_largest); + + got_smallest = got_largest = 0; + const uint64_t ten_billion = 10 * ((uint64_t)1000000000000); + for (i = 0; i < 1000; ++i) { + uint64_t x = crypto_rand_uint64_range(ten_billion, ten_billion+10); + tt_u64_op(x, OP_GE, ten_billion); + tt_u64_op(x, OP_LT, ten_billion+10); + if (x == ten_billion) + got_smallest = 1; + if (x == ten_billion+9) + got_largest = 1; + } + + tt_assert(got_smallest); + tt_assert(got_largest); + + const time_t now = time(NULL); + for (i = 0; i < 2000; ++i) { + time_t x = crypto_rand_time_range(now, now+60); + tt_i64_op(x, OP_GE, now); + tt_i64_op(x, OP_LT, now+60); + if (x == now) + got_smallest = 1; + if (x == now+59) + got_largest = 1; + } + + tt_assert(got_smallest); + tt_assert(got_largest); done: ; } +static void +test_crypto_rng_strongest(void *arg) +{ + const char *how = arg; + int broken = 0; + + if (how == NULL) { + ; + } else if (!strcmp(how, "nosyscall")) { + break_strongest_rng_syscall = 1; + } else if (!strcmp(how, "nofallback")) { + break_strongest_rng_fallback = 1; + } else if (!strcmp(how, "broken")) { + broken = break_strongest_rng_syscall = break_strongest_rng_fallback = 1; + } + +#define N 128 + uint8_t combine_and[N]; + uint8_t combine_or[N]; + int i, j; + + memset(combine_and, 0xff, N); + memset(combine_or, 0, N); + + for (i = 0; i < 100; ++i) { /* 2^-100 chances just don't happen. */ + uint8_t output[N]; + memset(output, 0, N); + if (how == NULL) { + /* this one can't fail. */ + crypto_strongest_rand(output, sizeof(output)); + } else { + int r = crypto_strongest_rand_raw(output, sizeof(output)); + if (r == -1) { + if (broken) { + goto done; /* we're fine. */ + } + /* This function is allowed to break, but only if it always breaks. */ + tt_int_op(i, OP_EQ, 0); + tt_skip(); + } else { + tt_assert(! broken); + } + } + for (j = 0; j < N; ++j) { + combine_and[j] &= output[j]; + combine_or[j] |= output[j]; + } + } + + for (j = 0; j < N; ++j) { + tt_int_op(combine_and[j], OP_EQ, 0); + tt_int_op(combine_or[j], OP_EQ, 0xff); + } + done: + ; +#undef N +} + /* Test for rectifying openssl RAND engine. */ static void test_crypto_rng_engine(void *arg) @@ -312,6 +510,43 @@ test_crypto_aes(void *arg) tor_free(data3); } +static void +test_crypto_aes_ctr_testvec(void *arg) +{ + (void)arg; + char *mem_op_hex_tmp=NULL; + + /* from NIST SP800-38a, section F.5 */ + const char key16[] = "2b7e151628aed2a6abf7158809cf4f3c"; + const char ctr16[] = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + const char plaintext16[] = + "6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"; + const char ciphertext16[] = + "874d6191b620e3261bef6864990db6ce" + "9806f66b7970fdff8617187bb9fffdff" + "5ae4df3edbd5d35e5b4f09020db03eab" + "1e031dda2fbe03d1792170a0f3009cee"; + + char key[16]; + char iv[16]; + char plaintext[16*4]; + base16_decode(key, sizeof(key), key16, strlen(key16)); + base16_decode(iv, sizeof(iv), ctr16, strlen(ctr16)); + base16_decode(plaintext, sizeof(plaintext), + plaintext16, strlen(plaintext16)); + + crypto_cipher_t *c = crypto_cipher_new_with_iv(key, iv); + crypto_cipher_crypt_inplace(c, plaintext, sizeof(plaintext)); + test_memeq_hex(plaintext, ciphertext16); + + done: + tor_free(mem_op_hex_tmp); + crypto_cipher_free(c); +} + /** Run unit tests for our SHA-1 functionality */ static void test_crypto_sha(void *arg) @@ -1084,6 +1319,29 @@ test_crypto_pk_base64(void *arg) tor_free(encoded); } +#ifdef HAVE_TRUNCATE +#define do_truncate truncate +#else +static int +do_truncate(const char *fname, size_t len) +{ + struct stat st; + char *bytes; + + bytes = read_file_to_str(fname, RFTS_BIN, &st); + if (!bytes) + return -1; + /* This cast isn't so great, but it should be safe given the actual files + * and lengths we're using. */ + if (st.st_size < (off_t)len) + len = MIN(len, (size_t)st.st_size); + + int r = write_bytes_to_file(fname, bytes, len, 1); + tor_free(bytes); + return r; +} +#endif + /** Sanity check for crypto pk digests */ static void test_crypto_digests(void *arg) @@ -1114,6 +1372,33 @@ test_crypto_digests(void *arg) crypto_pk_free(k); } +static void +test_crypto_digest_names(void *arg) +{ + static const struct { + int a; const char *n; + } names[] = { + { DIGEST_SHA1, "sha1" }, + { DIGEST_SHA256, "sha256" }, + { DIGEST_SHA512, "sha512" }, + { DIGEST_SHA3_256, "sha3-256" }, + { DIGEST_SHA3_512, "sha3-512" }, + { -1, NULL } + }; + (void)arg; + + int i; + for (i = 0; names[i].n; ++i) { + tt_str_op(names[i].n, OP_EQ,crypto_digest_algorithm_get_name(names[i].a)); + tt_int_op(names[i].a, + OP_EQ,crypto_digest_algorithm_parse_name(names[i].n)); + } + tt_int_op(-1, OP_EQ, + crypto_digest_algorithm_parse_name("TimeCubeHash-4444")); + done: + ; +} + #ifndef OPENSSL_1_1_API #define EVP_ENCODE_CTX_new() tor_malloc_zero(sizeof(EVP_ENCODE_CTX)) #define EVP_ENCODE_CTX_free(ctx) tor_free(ctx) @@ -1507,13 +1792,98 @@ test_crypto_hkdf_sha256(void *arg) "b206fa34e5bc78d063fc291501beec53b36e5a0e434561200c" "5f8bd13e0f88b3459600b4dc21d69363e2895321c06184879d" "94b18f078411be70b767c7fc40679a9440a0c95ea83a23efbf"); - done: tor_free(mem_op_hex_tmp); #undef EXPAND } static void +test_crypto_hkdf_sha256_testvecs(void *arg) +{ + (void) arg; + /* Test vectors from RFC5869, sections A.1 through A.3 */ + const struct { + const char *ikm16, *salt16, *info16; + int L; + const char *okm16; + } vecs[] = { + { /* from A.1 */ + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "000102030405060708090a0b0c", + "f0f1f2f3f4f5f6f7f8f9", + 42, + "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf" + "34007208d5b887185865" + }, + { /* from A.2 */ + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f", + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + 82, + "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c" + "59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71" + "cc30c58179ec3e87c14c01d5c1f3434f1d87" + }, + { /* from A.3 */ + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "", + "", + 42, + "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d" + "9d201395faa4b61a96c8", + }, + { NULL, NULL, NULL, -1, NULL } + }; + + int i; + char *ikm = NULL; + char *salt = NULL; + char *info = NULL; + char *okm = NULL; + char *mem_op_hex_tmp = NULL; + + for (i = 0; vecs[i].ikm16; ++i) { + size_t ikm_len = strlen(vecs[i].ikm16)/2; + size_t salt_len = strlen(vecs[i].salt16)/2; + size_t info_len = strlen(vecs[i].info16)/2; + size_t okm_len = vecs[i].L; + + ikm = tor_malloc(ikm_len); + salt = tor_malloc(salt_len); + info = tor_malloc(info_len); + okm = tor_malloc(okm_len); + + base16_decode(ikm, ikm_len, vecs[i].ikm16, strlen(vecs[i].ikm16)); + base16_decode(salt, salt_len, vecs[i].salt16, strlen(vecs[i].salt16)); + base16_decode(info, info_len, vecs[i].info16, strlen(vecs[i].info16)); + + int r = crypto_expand_key_material_rfc5869_sha256( + (const uint8_t*)ikm, ikm_len, + (const uint8_t*)salt, salt_len, + (const uint8_t*)info, info_len, + (uint8_t*)okm, okm_len); + tt_int_op(r, OP_EQ, 0); + test_memeq_hex(okm, vecs[i].okm16); + tor_free(ikm); + tor_free(salt); + tor_free(info); + tor_free(okm); + } + done: + tor_free(ikm); + tor_free(salt); + tor_free(info); + tor_free(okm); + tor_free(mem_op_hex_tmp); +} + +static void test_crypto_curve25519_impl(void *arg) { /* adapted from curve25519_donna, which adapted it from test-curve25519 @@ -1605,6 +1975,47 @@ test_crypto_curve25519_basepoint(void *arg) } static void +test_crypto_curve25519_testvec(void *arg) +{ + (void)arg; + char *mem_op_hex_tmp = NULL; + + /* From RFC 7748, section 6.1 */ + /* Alice's private key, a: */ + const char a16[] = + "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"; + /* Alice's public key, X25519(a, 9): */ + const char a_pub16[] = + "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"; + /* Bob's private key, b: */ + const char b16[] = + "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"; + /* Bob's public key, X25519(b, 9): */ + const char b_pub16[] = + "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"; + /* Their shared secret, K: */ + const char k16[] = + "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"; + + uint8_t a[32], b[32], a_pub[32], b_pub[32], k1[32], k2[32]; + base16_decode((char*)a, sizeof(a), a16, strlen(a16)); + base16_decode((char*)b, sizeof(b), b16, strlen(b16)); + curve25519_basepoint_impl(a_pub, a); + curve25519_basepoint_impl(b_pub, b); + curve25519_impl(k1, a, b_pub); + curve25519_impl(k2, b, a_pub); + + test_memeq_hex(a, a16); + test_memeq_hex(b, b16); + test_memeq_hex(a_pub, a_pub16); + test_memeq_hex(b_pub, b_pub16); + test_memeq_hex(k1, k16); + test_memeq_hex(k2, k16); + done: + tor_free(mem_op_hex_tmp); +} + +static void test_crypto_curve25519_wrappers(void *arg) { curve25519_public_key_t pubkey1, pubkey2; @@ -1896,7 +2307,67 @@ test_crypto_ed25519_test_vectors(void *arg) "1fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00", "0a688e79be24f866286d4646b5d81c" }, - + /* These come from draft-irtf-cfrg-eddsa-05 section 7.1 */ + { + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b", + "" + }, + { + "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da" + "085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00", + "72" + }, + { + "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", + "0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350" + "aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03", + "08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98" + "fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d8" + "79de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d" + "658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc" + "1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4fe" + "ba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e" + "06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbef" + "efd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7" + "aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed1" + "85ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2" + "d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24" + "554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f270" + "88d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc" + "2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b07" + "07e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128ba" + "b27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51a" + "ddd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429e" + "c96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb7" + "51fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c" + "42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8" + "ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34df" + "f7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08" + "d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649" + "de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e4" + "88acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a3" + "2ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e" + "6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5f" + "b93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b5" + "0d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1" + "369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380d" + "b2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c" + "0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0" + }, + { + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + "dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b589" + "09351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" + }, { NULL, NULL, NULL, NULL} }; @@ -2183,6 +2654,54 @@ test_crypto_ed25519_fuzz_donna(void *arg) } static void +test_crypto_ed25519_storage(void *arg) +{ + (void)arg; + ed25519_keypair_t *keypair = NULL; + ed25519_public_key_t pub; + ed25519_secret_key_t sec; + char *fname_1 = tor_strdup(get_fname("ed_seckey_1")); + char *fname_2 = tor_strdup(get_fname("ed_pubkey_2")); + char *contents = NULL; + char *tag = NULL; + + keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); + tt_int_op(0,OP_EQ,ed25519_keypair_generate(keypair, 0)); + tt_int_op(0,OP_EQ, + ed25519_seckey_write_to_file(&keypair->seckey, fname_1, "foo")); + tt_int_op(0,OP_EQ, + ed25519_pubkey_write_to_file(&keypair->pubkey, fname_2, "bar")); + + tt_int_op(-1, OP_EQ, ed25519_pubkey_read_from_file(&pub, &tag, fname_1)); + tt_ptr_op(tag, OP_EQ, NULL); + tt_int_op(-1, OP_EQ, ed25519_seckey_read_from_file(&sec, &tag, fname_2)); + tt_ptr_op(tag, OP_EQ, NULL); + + tt_int_op(0, OP_EQ, ed25519_pubkey_read_from_file(&pub, &tag, fname_2)); + tt_str_op(tag, OP_EQ, "bar"); + tor_free(tag); + tt_int_op(0, OP_EQ, ed25519_seckey_read_from_file(&sec, &tag, fname_1)); + tt_str_op(tag, OP_EQ, "foo"); + tor_free(tag); + + /* whitebox test: truncated keys. */ + tt_int_op(0, ==, do_truncate(fname_1, 40)); + tt_int_op(0, ==, do_truncate(fname_2, 40)); + tt_int_op(-1, OP_EQ, ed25519_pubkey_read_from_file(&pub, &tag, fname_2)); + tt_ptr_op(tag, OP_EQ, NULL); + tor_free(tag); + tt_int_op(-1, OP_EQ, ed25519_seckey_read_from_file(&sec, &tag, fname_1)); + tt_ptr_op(tag, OP_EQ, NULL); + + done: + tor_free(fname_1); + tor_free(fname_2); + tor_free(contents); + tor_free(tag); + ed25519_keypair_free(keypair); +} + +static void test_crypto_siphash(void *arg) { /* From the reference implementation, taking @@ -2398,13 +2917,23 @@ struct testcase_t crypto_tests[] = { CRYPTO_LEGACY(rng), { "rng_range", test_crypto_rng_range, 0, NULL, NULL }, { "rng_engine", test_crypto_rng_engine, TT_FORK, NULL, NULL }, + { "rng_strongest", test_crypto_rng_strongest, TT_FORK, NULL, NULL }, + { "rng_strongest_nosyscall", test_crypto_rng_strongest, TT_FORK, + &passthrough_setup, (void*)"nosyscall" }, + { "rng_strongest_nofallback", test_crypto_rng_strongest, TT_FORK, + &passthrough_setup, (void*)"nofallback" }, + { "rng_strongest_broken", test_crypto_rng_strongest, TT_FORK, + &passthrough_setup, (void*)"broken" }, + { "openssl_version", test_crypto_openssl_version, TT_FORK, NULL, NULL }, { "aes_AES", test_crypto_aes, TT_FORK, &passthrough_setup, (void*)"aes" }, { "aes_EVP", test_crypto_aes, TT_FORK, &passthrough_setup, (void*)"evp" }, + { "aes_ctr_testvec", test_crypto_aes_ctr_testvec, 0, NULL, NULL }, CRYPTO_LEGACY(sha), CRYPTO_LEGACY(pk), { "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL }, { "pk_base64", test_crypto_pk_base64, TT_FORK, NULL, NULL }, CRYPTO_LEGACY(digests), + { "digest_names", test_crypto_digest_names, 0, NULL, NULL }, { "sha3", test_crypto_sha3, TT_FORK, NULL, NULL}, { "sha3_xof", test_crypto_sha3_xof, TT_FORK, NULL, NULL}, CRYPTO_LEGACY(dh), @@ -2415,8 +2944,10 @@ struct testcase_t crypto_tests[] = { CRYPTO_LEGACY(base32_decode), { "kdf_TAP", test_crypto_kdf_TAP, 0, NULL, NULL }, { "hkdf_sha256", test_crypto_hkdf_sha256, 0, NULL, NULL }, + { "hkdf_sha256_testvecs", test_crypto_hkdf_sha256_testvecs, 0, NULL, NULL }, { "curve25519_impl", test_crypto_curve25519_impl, 0, NULL, NULL }, { "curve25519_impl_hibit", test_crypto_curve25519_impl, 0, NULL, (void*)"y"}, + { "curve25516_testvec", test_crypto_curve25519_testvec, 0, NULL, NULL }, { "curve25519_basepoint", test_crypto_curve25519_basepoint, TT_FORK, NULL, NULL }, { "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL }, @@ -2429,6 +2960,7 @@ struct testcase_t crypto_tests[] = { ED25519_TEST(blinding, 0), ED25519_TEST(testvectors, 0), ED25519_TEST(fuzz_donna, TT_FORK), + { "ed25519_storage", test_crypto_ed25519_storage, 0, NULL, NULL }, { "siphash", test_crypto_siphash, 0, NULL, NULL }, { "failure_modes", test_crypto_failure_modes, TT_FORK, NULL, NULL }, END_OF_TESTCASES diff --git a/src/test/test_data.c b/src/test/test_data.c index 32de54bc84..788489a097 100644 --- a/src/test/test_data.c +++ b/src/test/test_data.c @@ -3,6 +3,8 @@ * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +#include "test.h" + /* Our unit test expect that the AUTHORITY_CERT_* public keys will sort * in this order. */ #define AUTHORITY_CERT_A AUTHORITY_CERT_3 diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 26b0e72a9a..74b753a1ea 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -192,7 +192,7 @@ test_dir_formats(void *arg) tt_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str, &pk2_str_len)); - /* XXXX025 router_dump_to_string should really take this from ri.*/ + /* XXXX+++ router_dump_to_string should really take this from ri.*/ options->ContactInfo = tor_strdup("Magri White " "<magri@elsewhere.example.com>"); /* Skip reachability checks for DirPort and tunnelled-dir-server */ @@ -2196,56 +2196,57 @@ test_dir_scale_bw(void *testdata) 1.0/7, 12.0, 24.0 }; - u64_dbl_t vals[8]; + double vals_dbl[8]; + uint64_t vals_u64[8]; uint64_t total; int i; (void) testdata; for (i=0; i<8; ++i) - vals[i].dbl = v[i]; + vals_dbl[i] = v[i]; - scale_array_elements_to_u64(vals, 8, &total); + scale_array_elements_to_u64(vals_u64, vals_dbl, 8, &total); tt_int_op((int)total, OP_EQ, 48); total = 0; for (i=0; i<8; ++i) { - total += vals[i].u64; + total += vals_u64[i]; } tt_assert(total >= (U64_LITERAL(1)<<60)); tt_assert(total <= (U64_LITERAL(1)<<62)); for (i=0; i<8; ++i) { /* vals[2].u64 is the scaled value of 1.0 */ - double ratio = ((double)vals[i].u64) / vals[2].u64; + double ratio = ((double)vals_u64[i]) / vals_u64[2]; tt_double_op(fabs(ratio - v[i]), OP_LT, .00001); } /* test handling of no entries */ total = 1; - scale_array_elements_to_u64(vals, 0, &total); + scale_array_elements_to_u64(vals_u64, vals_dbl, 0, &total); tt_assert(total == 0); /* make sure we don't read the array when we have no entries * may require compiler flags to catch NULL dereferences */ total = 1; - scale_array_elements_to_u64(NULL, 0, &total); + scale_array_elements_to_u64(NULL, NULL, 0, &total); tt_assert(total == 0); - scale_array_elements_to_u64(NULL, 0, NULL); + scale_array_elements_to_u64(NULL, NULL, 0, NULL); /* test handling of zero totals */ total = 1; - vals[0].dbl = 0.0; - scale_array_elements_to_u64(vals, 1, &total); + vals_dbl[0] = 0.0; + scale_array_elements_to_u64(vals_u64, vals_dbl, 1, &total); tt_assert(total == 0); - tt_assert(vals[0].u64 == 0); + tt_assert(vals_u64[0] == 0); - vals[0].dbl = 0.0; - vals[1].dbl = 0.0; - scale_array_elements_to_u64(vals, 2, NULL); - tt_assert(vals[0].u64 == 0); - tt_assert(vals[1].u64 == 0); + vals_dbl[0] = 0.0; + vals_dbl[1] = 0.0; + scale_array_elements_to_u64(vals_u64, vals_dbl, 2, NULL); + tt_assert(vals_u64[0] == 0); + tt_assert(vals_u64[1] == 0); done: ; @@ -2256,7 +2257,7 @@ test_dir_random_weighted(void *testdata) { int histogram[10]; uint64_t vals[10] = {3,1,2,4,6,0,7,5,8,9}, total=0; - u64_dbl_t inp[10]; + uint64_t inp_u64[10]; int i, choice; const int n = 50000; double max_sq_error; @@ -2266,12 +2267,12 @@ test_dir_random_weighted(void *testdata) * in a scrambled order to make sure we don't depend on order. */ memset(histogram,0,sizeof(histogram)); for (i=0; i<10; ++i) { - inp[i].u64 = vals[i]; + inp_u64[i] = vals[i]; total += vals[i]; } tt_u64_op(total, OP_EQ, 45); for (i=0; i<n; ++i) { - choice = choose_array_element_by_weight(inp, 10); + choice = choose_array_element_by_weight(inp_u64, 10); tt_int_op(choice, OP_GE, 0); tt_int_op(choice, OP_LT, 10); histogram[choice]++; @@ -2298,16 +2299,16 @@ test_dir_random_weighted(void *testdata) /* Now try a singleton; do we choose it? */ for (i = 0; i < 100; ++i) { - choice = choose_array_element_by_weight(inp, 1); + choice = choose_array_element_by_weight(inp_u64, 1); tt_int_op(choice, OP_EQ, 0); } /* Now try an array of zeros. We should choose randomly. */ memset(histogram,0,sizeof(histogram)); for (i = 0; i < 5; ++i) - inp[i].u64 = 0; + inp_u64[i] = 0; for (i = 0; i < n; ++i) { - choice = choose_array_element_by_weight(inp, 5); + choice = choose_array_element_by_weight(inp_u64, 5); tt_int_op(choice, OP_GE, 0); tt_int_op(choice, OP_LT, 5); histogram[choice]++; diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c index 0b446c2dfd..2448d307b2 100644 --- a/src/test/test_dir_common.c +++ b/src/test/test_dir_common.c @@ -21,13 +21,6 @@ networkstatus_t * dir_common_add_rs_and_parse(networkstatus_t *vote, crypto_pk_t *sign_skey, int *n_vrs, time_t now, int clear_rl); -extern const char AUTHORITY_CERT_1[]; -extern const char AUTHORITY_SIGNKEY_1[]; -extern const char AUTHORITY_CERT_2[]; -extern const char AUTHORITY_SIGNKEY_2[]; -extern const char AUTHORITY_CERT_3[]; -extern const char AUTHORITY_SIGNKEY_3[]; - /** Initialize and set auth certs and keys * Returns 0 on success, -1 on failure. Clean up handled by caller. */ diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 05657ca452..927fa8b61d 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -38,7 +38,15 @@ #include <dirent.h> #endif +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +DISABLE_GCC_WARNING(overlength-strings) +/* We allow huge string constants in the unit tests, but not in the code + * at large. */ +#endif #include "vote_descriptors.inc" +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +ENABLE_GCC_WARNING(overlength-strings) +#endif #define NS_MODULE dir_handle_get @@ -224,51 +232,6 @@ test_dir_handle_get_robots_txt(void *data) tor_free(body); } -static void -test_dir_handle_get_bytes_txt(void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - char *body = NULL; - size_t body_used = 0, body_len = 0; - char buff[30]; - char *exp_body = NULL; - (void) data; - - exp_body = directory_dump_request_log(); - body_len = strlen(exp_body); - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - - conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); - - tt_int_op(directory_handle_command_get(conn, GET("/tor/bytes.txt"), NULL, 0), - OP_EQ, 0); - fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, - &body, &body_used, body_len+1, 0); - - tt_assert(header); - tt_assert(body); - - tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header); - tt_assert(strstr(header, "Content-Type: text/plain\r\n")); - tt_assert(strstr(header, "Content-Encoding: identity\r\n")); - tt_assert(strstr(header, "Pragma: no-cache\r\n")); - - tor_snprintf(buff, sizeof(buff), "Content-Length: %ld\r\n", (long) body_len); - tt_assert(strstr(header, buff)); - - tt_int_op(body_used, OP_EQ, strlen(body)); - tt_str_op(body, OP_EQ, exp_body); - - done: - UNMOCK(connection_write_to_buf_impl_); - connection_free_(TO_CONN(conn)); - tor_free(header); - tor_free(body); - tor_free(exp_body); -} - #define RENDEZVOUS2_GET(descid) GET("/tor/rendezvous2/" descid) static void test_dir_handle_get_rendezvous2_not_found_if_not_encrypted(void *data) @@ -438,7 +401,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_success(void *data) TO_CONN(conn)->linked = 1; tt_assert(connection_dir_is_encrypted(conn)); - sprintf(req, RENDEZVOUS2_GET("%s"), desc_id_base32); + tor_snprintf(req, sizeof(req), RENDEZVOUS2_GET("%s"), desc_id_base32); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); @@ -453,7 +416,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_success(void *data) tt_assert(strstr(header, "Content-Type: text/plain\r\n")); tt_assert(strstr(header, "Content-Encoding: identity\r\n")); tt_assert(strstr(header, "Pragma: no-cache\r\n")); - sprintf(buff, "Content-Length: %ld\r\n", (long) body_len); + tor_snprintf(buff, sizeof(buff), "Content-Length: %ld\r\n", (long) body_len); tt_assert(strstr(header, buff)); tt_int_op(body_used, OP_EQ, strlen(body)); @@ -565,7 +528,7 @@ test_dir_handle_get_micro_d(void *data) /* Make the request */ conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); - sprintf(path, MICRODESC_GET("%s"), digest_base64); + tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64); tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -635,7 +598,7 @@ test_dir_handle_get_micro_d_server_busy(void *data) /* Make the request */ conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); - sprintf(path, MICRODESC_GET("%s"), digest_base64); + tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64); tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -997,7 +960,8 @@ test_dir_handle_get_server_descriptors_fp(void* data) DIGEST_LEN); char req[155]; - sprintf(req, SERVER_DESC_GET("fp/%s+" HEX1 "+" HEX2), hex_digest); + tor_snprintf(req, sizeof(req), SERVER_DESC_GET("fp/%s+" HEX1 "+" HEX2), + hex_digest); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); //TODO: Is this a BUG? @@ -1056,8 +1020,9 @@ test_dir_handle_get_server_descriptors_d(void* data) conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); - char req_header[155]; - sprintf(req_header, SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest); + char req_header[155]; /* XXX Why 155? What kind of number is that?? */ + tor_snprintf(req_header, sizeof(req_header), + SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest); tt_int_op(directory_handle_command_get(conn, req_header, NULL, 0), OP_EQ, 0); //TODO: Is this a BUG? @@ -1125,8 +1090,9 @@ test_dir_handle_get_server_descriptors_busy(void* data) #define HEX1 "Fe0daff89127389bc67558691231234551193EEE" #define HEX2 "Deadbeef99999991111119999911111111f00ba4" - char req_header[155]; - sprintf(req_header, SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest); + char req_header[155]; /* XXX 155? Why 155? */ + tor_snprintf(req_header, sizeof(req_header), + SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest); tt_int_op(directory_handle_command_get(conn, req_header, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -1204,8 +1170,6 @@ test_dir_handle_get_server_keys_all_not_found(void* data) #define TEST_CERTIFICATE AUTHORITY_CERT_3 #define TEST_SIGNING_KEY AUTHORITY_SIGNKEY_A_DIGEST -extern const char AUTHORITY_CERT_3[]; -extern const char AUTHORITY_SIGNKEY_A_DIGEST[]; static const char TEST_CERT_IDENT_KEY[] = "D867ACF56A9D229B35C25F0090BC9867E906BE69"; @@ -1237,7 +1201,7 @@ test_dir_handle_get_server_keys_all(void* data) base16_decode(ds->v3_identity_digest, DIGEST_LEN, TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); @@ -1396,11 +1360,12 @@ test_dir_handle_get_server_keys_fp(void* data) TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); char req[71]; - sprintf(req, GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY); + tor_snprintf(req, sizeof(req), + GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -1468,11 +1433,12 @@ test_dir_handle_get_server_keys_sk(void* data) routerlist_free_all(); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); char req[71]; - sprintf(req, GET("/tor/keys/sk/%s"), TEST_SIGNING_KEY); + tor_snprintf(req, sizeof(req), + GET("/tor/keys/sk/%s"), TEST_SIGNING_KEY); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -1550,13 +1516,14 @@ test_dir_handle_get_server_keys_fpsk(void* data) dir_server_add(ds); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); char req[115]; - sprintf(req, GET("/tor/keys/fp-sk/%s-%s"), - TEST_CERT_IDENT_KEY, TEST_SIGNING_KEY); + tor_snprintf(req, sizeof(req), + GET("/tor/keys/fp-sk/%s-%s"), + TEST_CERT_IDENT_KEY, TEST_SIGNING_KEY); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); @@ -1606,7 +1573,7 @@ test_dir_handle_get_server_keys_busy(void* data) dir_server_add(ds); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); MOCK(get_options, mock_get_options); MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); @@ -1617,7 +1584,7 @@ test_dir_handle_get_server_keys_busy(void* data) conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR)); char req[71]; - sprintf(req, GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY); + tor_snprintf(req, sizeof(req), GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY); tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, @@ -2344,7 +2311,7 @@ test_dir_handle_get_status_vote_next_authority(void* data) base16_decode(ds->v3_identity_digest, DIGEST_LEN, TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); init_mock_options(); mock_options->AuthoritativeDir = 1; @@ -2423,7 +2390,7 @@ test_dir_handle_get_status_vote_current_authority(void* data) TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN); tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, - TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1)); + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); init_mock_options(); mock_options->AuthoritativeDir = 1; @@ -2484,7 +2451,6 @@ struct testcase_t dir_handle_get_tests[] = { DIR_HANDLE_CMD(v1_command_not_found, 0), DIR_HANDLE_CMD(v1_command, 0), DIR_HANDLE_CMD(robots_txt, 0), - DIR_HANDLE_CMD(bytes_txt, 0), DIR_HANDLE_CMD(rendezvous2_not_found_if_not_encrypted, 0), DIR_HANDLE_CMD(rendezvous2_not_found, 0), DIR_HANDLE_CMD(rendezvous2_on_encrypted_conn_with_invalid_desc_id, 0), diff --git a/src/test/test_handles.c b/src/test/test_handles.c new file mode 100644 index 0000000000..536a478689 --- /dev/null +++ b/src/test/test_handles.c @@ -0,0 +1,95 @@ +/* Copyright (c) 2016, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" +#include "test.h" + +#include "util.h" +#include "handles.h" + +typedef struct demo_t { + HANDLE_ENTRY(demo, demo_t); + int val; +} demo_t; + +HANDLE_DECL(demo, demo_t, static) +HANDLE_IMPL(demo, demo_t, static) + +static demo_t * +demo_new(int val) +{ + demo_t *d = tor_malloc_zero(sizeof(demo_t)); + d->val = val; + return d; +} + +static void +demo_free(demo_t *d) +{ + if (d == NULL) + return; + demo_handles_clear(d); + tor_free(d); +} + +static void +test_handle_basic(void *arg) +{ + (void) arg; + demo_t *d1 = NULL, *d2 = NULL; + demo_handle_t *wr1 = NULL, *wr2 = NULL, *wr3 = NULL, *wr4 = NULL; + + d1 = demo_new(9000); + d2 = demo_new(9009); + + wr1 = demo_handle_new(d1); + wr2 = demo_handle_new(d1); + wr3 = demo_handle_new(d1); + wr4 = demo_handle_new(d2); + + tt_assert(wr1); + tt_assert(wr2); + tt_assert(wr3); + tt_assert(wr4); + + tt_ptr_op(demo_handle_get(wr1), OP_EQ, d1); + tt_ptr_op(demo_handle_get(wr2), OP_EQ, d1); + tt_ptr_op(demo_handle_get(wr3), OP_EQ, d1); + tt_ptr_op(demo_handle_get(wr4), OP_EQ, d2); + + demo_handle_free(wr1); + wr1 = NULL; + tt_ptr_op(demo_handle_get(wr2), OP_EQ, d1); + tt_ptr_op(demo_handle_get(wr3), OP_EQ, d1); + tt_ptr_op(demo_handle_get(wr4), OP_EQ, d2); + + demo_free(d1); + d1 = NULL; + tt_ptr_op(demo_handle_get(wr2), OP_EQ, NULL); + tt_ptr_op(demo_handle_get(wr3), OP_EQ, NULL); + tt_ptr_op(demo_handle_get(wr4), OP_EQ, d2); + + demo_handle_free(wr2); + wr2 = NULL; + tt_ptr_op(demo_handle_get(wr3), OP_EQ, NULL); + tt_ptr_op(demo_handle_get(wr4), OP_EQ, d2); + + demo_handle_free(wr3); + wr3 = NULL; + done: + demo_handle_free(wr1); + demo_handle_free(wr2); + demo_handle_free(wr3); + demo_handle_free(wr4); + demo_free(d1); + demo_free(d2); +} + +#define HANDLE_TEST(name, flags) \ + { #name, test_handle_ ##name, (flags), NULL, NULL } + +struct testcase_t handle_tests[] = { + HANDLE_TEST(basic, 0), + END_OF_TESTCASES +}; + diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index c6daaf220a..ae9fc7a243 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -16,7 +16,15 @@ #include "test.h" #include "test_helpers.h" +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +DISABLE_GCC_WARNING(overlength-strings) +/* We allow huge string constants in the unit tests, but not in the code + * at large. */ +#endif #include "test_descriptors.inc" +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +ENABLE_GCC_WARNING(overlength-strings) +#endif /* Return a statically allocated string representing yesterday's date * in ISO format. We use it so that state file items are not found to diff --git a/src/test/test_hs.c b/src/test/test_hs.c index 49939a53cf..1daa1552e9 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -435,6 +435,67 @@ test_hs_rend_data(void *arg) rend_data_free(client_dup); } +/* Test encoding and decoding service authorization cookies */ +static void +test_hs_auth_cookies(void *arg) +{ +#define TEST_COOKIE_RAW ((const uint8_t *) "abcdefghijklmnop") +#define TEST_COOKIE_ENCODED "YWJjZGVmZ2hpamtsbW5vcA" +#define TEST_COOKIE_ENCODED_STEALTH "YWJjZGVmZ2hpamtsbW5vcB" +#define TEST_COOKIE_ENCODED_INVALID "YWJjZGVmZ2hpamtsbW5vcD" + + char *encoded_cookie; + uint8_t raw_cookie[REND_DESC_COOKIE_LEN]; + rend_auth_type_t auth_type; + char *err_msg; + int re; + + (void)arg; + + /* Test that encoding gives the expected result */ + encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_BASIC_AUTH); + tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED); + tor_free(encoded_cookie); + + encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_STEALTH_AUTH); + tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED_STEALTH); + tor_free(encoded_cookie); + + /* Decoding should give the original value */ + re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED, raw_cookie, &auth_type, + &err_msg); + tt_assert(!re); + tt_assert(!err_msg); + tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); + tt_int_op(auth_type, OP_EQ, REND_BASIC_AUTH); + memset(raw_cookie, 0, sizeof(raw_cookie)); + + re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_STEALTH, raw_cookie, + &auth_type, &err_msg); + tt_assert(!re); + tt_assert(!err_msg); + tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); + tt_int_op(auth_type, OP_EQ, REND_STEALTH_AUTH); + memset(raw_cookie, 0, sizeof(raw_cookie)); + + /* Decoding with padding characters should also work */ + re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED "==", raw_cookie, NULL, + &err_msg); + tt_assert(!re); + tt_assert(!err_msg); + tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN); + + /* Decoding with an unknown type should fail */ + re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_INVALID, raw_cookie, + &auth_type, &err_msg); + tt_int_op(re, OP_LT, 0); + tt_assert(err_msg); + tor_free(err_msg); + + done: + return; +} + struct testcase_t hs_tests[] = { { "hs_rend_data", test_hs_rend_data, TT_FORK, NULL, NULL }, @@ -445,6 +506,8 @@ struct testcase_t hs_tests[] = { { "pick_bad_tor2web_rendezvous_node", test_pick_bad_tor2web_rendezvous_node, TT_FORK, NULL, NULL }, + { "hs_auth_cookies", test_hs_auth_cookies, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c index 9c7a86da66..810b03c93d 100644 --- a/src/test/test_introduce.c +++ b/src/test/test_introduce.c @@ -9,8 +9,6 @@ #define RENDSERVICE_PRIVATE #include "rendservice.h" -extern const char AUTHORITY_SIGNKEY_1[]; - static uint8_t v0_test_plaintext[] = /* 20 bytes of rendezvous point nickname */ { 0x4e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c index e8856c60de..4038783459 100644 --- a/src/test/test_link_handshake.c +++ b/src/test/test_link_handshake.c @@ -16,7 +16,7 @@ #include "test.h" -var_cell_t *mock_got_var_cell = NULL; +static var_cell_t *mock_got_var_cell = NULL; static void mock_write_var_cell(const var_cell_t *vc, or_connection_t *conn) diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 581f58b45f..91884e692e 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -490,6 +490,11 @@ test_md_generate(void *arg) routerinfo_free(ri); } +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +DISABLE_GCC_WARNING(overlength-strings) +/* We allow huge string constants in the unit tests, but not in the code + * at large. */ +#endif /* Taken at random from my ~/.tor/cached-microdescs file and then * hand-munged */ static const char MD_PARSE_TEST_DATA[] = @@ -645,6 +650,9 @@ static const char MD_PARSE_TEST_DATA[] = "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n" "p6 allow 80\n" ; +#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS +ENABLE_GCC_WARNING(overlength-strings) +#endif /** More tests for parsing different kinds of microdescriptors, and getting * invalid digests trackd from them. */ diff --git a/src/test/test_ntor_cl.c b/src/test/test_ntor_cl.c index 6df123162e..49c9ad76d4 100644 --- a/src/test/test_ntor_cl.c +++ b/src/test/test_ntor_cl.c @@ -153,7 +153,10 @@ main(int argc, char **argv) if (argc < 2) { fprintf(stderr, "I need arguments. Read source for more info.\n"); return 1; - } else if (!strcmp(argv[1], "client1")) { + } + + curve25519_init(); + if (!strcmp(argv[1], "client1")) { return client1(argc, argv); } else if (!strcmp(argv[1], "server1")) { return server1(argc, argv); diff --git a/src/test/test_options.c b/src/test/test_options.c index 4f24757a85..8d1d6f901e 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -12,7 +12,7 @@ #define ROUTERSET_PRIVATE #include "routerset.h" - +#include "main.h" #include "log_test_helpers.h" #include "sandbox.h" @@ -513,8 +513,9 @@ test_options_validate__nickname(void *ignored) ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg); tt_int_op(ret, OP_EQ, -1); tt_str_op(msg, OP_EQ, - "Nickname 'ThisNickNameIsABitTooLong' is wrong length or" - " contains illegal characters."); + "Nickname 'ThisNickNameIsABitTooLong', nicknames must be between " + "1 and 19 characters inclusive, and must contain only the " + "characters [a-zA-Z0-9]."); tor_free(msg); free_options_test_data(tdata); @@ -571,8 +572,6 @@ test_options_validate__contactinfo(void *ignored) tor_free(msg); } -extern int quiet_level; - static void test_options_validate__logs(void *ignored) { diff --git a/src/test/test_policy.c b/src/test/test_policy.c index a939ebf54f..913a2f303a 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -778,8 +778,8 @@ test_policies_reject_port_address(void *arg) UNMOCK(get_configured_ports); } -smartlist_t *mock_ipv4_addrs = NULL; -smartlist_t *mock_ipv6_addrs = NULL; +static smartlist_t *mock_ipv4_addrs = NULL; +static smartlist_t *mock_ipv6_addrs = NULL; /* mock get_interface_address6_list, returning a deep copy of the template * address list ipv4_interface_address_list or ipv6_interface_address_list */ diff --git a/src/test/test_pubsub.c b/src/test/test_pubsub.c new file mode 100644 index 0000000000..547d6c6b32 --- /dev/null +++ b/src/test/test_pubsub.c @@ -0,0 +1,85 @@ +/* Copyright (c) 2016, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file test_pubsub.c + * \brief Unit tests for publish-subscribe abstraction. + **/ + +#include "or.h" +#include "test.h" +#include "pubsub.h" + +DECLARE_PUBSUB_STRUCT_TYPES(foobar) +DECLARE_PUBSUB_TOPIC(foobar) +DECLARE_NOTIFY_PUBSUB_TOPIC(static, foobar) +IMPLEMENT_PUBSUB_TOPIC(static, foobar) + +struct foobar_event_data_t { + unsigned u; + const char *s; +}; + +struct foobar_subscriber_data_t { + const char *name; + long l; +}; + +static int +foobar_sub1(foobar_event_data_t *ev, foobar_subscriber_data_t *mine) +{ + ev->u += 10; + mine->l += 100; + return 0; +} + +static int +foobar_sub2(foobar_event_data_t *ev, foobar_subscriber_data_t *mine) +{ + ev->u += 5; + mine->l += 50; + return 0; +} + +static void +test_pubsub_basic(void *arg) +{ + (void)arg; + foobar_subscriber_data_t subdata1 = { "hi", 0 }; + foobar_subscriber_data_t subdata2 = { "wow", 0 }; + const foobar_subscriber_t *sub1; + const foobar_subscriber_t *sub2; + foobar_event_data_t ed = { 0, "x" }; + foobar_event_data_t ed2 = { 0, "y" }; + sub1 = foobar_subscribe(foobar_sub1, &subdata1, SUBSCRIBE_ATSTART, 100); + tt_assert(sub1); + + foobar_notify(&ed, 0); + tt_int_op(subdata1.l, OP_EQ, 100); + tt_int_op(subdata2.l, OP_EQ, 0); + tt_int_op(ed.u, OP_EQ, 10); + + sub2 = foobar_subscribe(foobar_sub2, &subdata2, 0, 5); + tt_assert(sub2); + + foobar_notify(&ed2, 0); + tt_int_op(subdata1.l, OP_EQ, 200); + tt_int_op(subdata2.l, OP_EQ, 50); + tt_int_op(ed2.u, OP_EQ, 15); + + foobar_unsubscribe(sub1); + + foobar_notify(&ed, 0); + tt_int_op(subdata1.l, OP_EQ, 200); + tt_int_op(subdata2.l, OP_EQ, 100); + tt_int_op(ed.u, OP_EQ, 15); + + done: + foobar_clear(); +} + +struct testcase_t pubsub_tests[] = { + { "pubsub_basic", test_pubsub_basic, TT_FORK, NULL, NULL }, + END_OF_TESTCASES +}; + diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c index 1cd9ff064b..fb6748965a 100644 --- a/src/test/test_relaycell.c +++ b/src/test/test_relaycell.c @@ -95,7 +95,7 @@ test_relaycell_resolved(void *arg) tt_int_op(srm_ncalls, OP_EQ, 1); \ tt_ptr_op(srm_conn, OP_EQ, entryconn); \ tt_int_op(srm_atype, OP_EQ, (atype)); \ - if (answer) { \ + if ((answer) != NULL) { \ tt_int_op(srm_alen, OP_EQ, sizeof(answer)-1); \ tt_int_op(srm_alen, OP_LT, 512); \ tt_int_op(srm_answer_is_set, OP_EQ, 1); \ diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c index d1b52649b2..eac41ecdda 100644 --- a/src/test/test_rendcache.c +++ b/src/test/test_rendcache.c @@ -20,11 +20,6 @@ static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \ REND_CACHE_MAX_SKEW + 10); static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 10; -extern strmap_t *rend_cache; -extern digestmap_t *rend_cache_v2_dir; -extern strmap_t *rend_cache_failure; -extern size_t rend_cache_total_allocation; - static rend_data_t * mock_rend_data(const char *onion_address) { diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c index 2cffa6e801..34b70ac8a8 100644 --- a/src/test/test_routerlist.c +++ b/src/test/test_routerlist.c @@ -24,13 +24,6 @@ #include "test.h" #include "test_dir_common.h" -extern const char AUTHORITY_CERT_1[]; -extern const char AUTHORITY_SIGNKEY_1[]; -extern const char AUTHORITY_CERT_2[]; -extern const char AUTHORITY_SIGNKEY_2[]; -extern const char AUTHORITY_CERT_3[]; -extern const char AUTHORITY_SIGNKEY_3[]; - void construct_consensus(char **consensus_text_md); /* 4 digests + 3 sep + pre + post + NULL */ @@ -423,7 +416,7 @@ test_router_pick_directory_server_impl(void *arg) networkstatus_vote_free(con_md); } -connection_t *mocked_connection = NULL; +static connection_t *mocked_connection = NULL; /* Mock connection_get_by_type_addr_port_purpose by returning * mocked_connection. */ diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c index 74b39c0486..1b526d430b 100644 --- a/src/test/test_routerset.c +++ b/src/test/test_routerset.c @@ -432,7 +432,7 @@ NS(test_main)(void *arg) NS_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string, (const char *s, int assume_action, int *malformed_list)); -addr_policy_t *NS(mock_addr_policy); +static addr_policy_t *NS(mock_addr_policy); static void NS(test_main)(void *arg) @@ -480,7 +480,7 @@ NS(router_parse_addr_policy_item_from_string)(const char *s, NS_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string, (const char *s, int assume_action, int *bogus)); -addr_policy_t *NS(mock_addr_policy); +static addr_policy_t *NS(mock_addr_policy); static void NS(test_main)(void *arg) @@ -527,7 +527,7 @@ NS(router_parse_addr_policy_item_from_string)(const char *s, int assume_action, NS_DECL(addr_policy_t *, router_parse_addr_policy_item_from_string, (const char *s, int assume_action, int *bad)); -addr_policy_t *NS(mock_addr_policy); +static addr_policy_t *NS(mock_addr_policy); static void NS(test_main)(void *arg) @@ -1477,7 +1477,7 @@ NS(test_main)(void *arg) * routerset or routerinfo. */ -node_t NS(mock_node); +static node_t NS(mock_node); static void NS(test_main)(void *arg) @@ -1504,7 +1504,7 @@ NS(test_main)(void *arg) * routerset and no routerinfo. */ -node_t NS(mock_node); +static node_t NS(mock_node); static void NS(test_main)(void *arg) @@ -1603,7 +1603,7 @@ NS(test_main)(void *arg) NS_DECL(const node_t *, node_get_by_nickname, (const char *nickname, int warn_if_unused)); -const char *NS(mock_nickname); +static const char *NS(mock_nickname); static void NS(test_main)(void *arg) @@ -1652,8 +1652,8 @@ NS(node_get_by_nickname)(const char *nickname, int warn_if_unused) NS_DECL(const node_t *, node_get_by_nickname, (const char *nickname, int warn_if_unused)); -const char *NS(mock_nickname); -node_t NS(mock_node); +static const char *NS(mock_nickname); +static node_t NS(mock_node); static void NS(test_main)(void *arg) @@ -1702,8 +1702,8 @@ NS(node_get_by_nickname)(const char *nickname, int warn_if_unused) NS_DECL(const node_t *, node_get_by_nickname, (const char *nickname, int warn_if_unused)); -char *NS(mock_nickname); -node_t NS(mock_node); +static char *NS(mock_nickname); +static node_t NS(mock_node); static void NS(test_main)(void *arg) @@ -1754,7 +1754,7 @@ NS(node_get_by_nickname)(const char *nickname, int warn_if_unused) NS_DECL(smartlist_t *, nodelist_get_list, (void)); -smartlist_t *NS(mock_smartlist); +static smartlist_t *NS(mock_smartlist); static void NS(test_main)(void *arg) @@ -1800,8 +1800,8 @@ NS(nodelist_get_list)(void) NS_DECL(smartlist_t *, nodelist_get_list, (void)); -smartlist_t *NS(mock_smartlist); -node_t NS(mock_node); +static smartlist_t *NS(mock_smartlist); +static node_t NS(mock_node); static void NS(test_main)(void *arg) diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c index 6e9889b48b..15fbb2d186 100644 --- a/src/test/test_scheduler.c +++ b/src/test/test_scheduler.c @@ -24,12 +24,6 @@ #include "test.h" #include "fakechans.h" -/* Statics in scheduler.c exposed to the test suite */ -extern smartlist_t *channels_pending; -extern struct event *run_sched_ev; -extern uint64_t queue_heuristic; -extern time_t queue_heuristic_timestamp; - /* Event base for scheduelr tests */ static struct event_base *mock_event_base = NULL; diff --git a/src/test/test_slow.c b/src/test/test_slow.c index c1d2e81914..7c9f0b1cc2 100644 --- a/src/test/test_slow.c +++ b/src/test/test_slow.c @@ -18,9 +18,6 @@ #include "or.h" #include "test.h" -extern struct testcase_t slow_crypto_tests[]; -extern struct testcase_t slow_util_tests[]; - struct testgroup_t testgroups[] = { { "slow/crypto/", slow_crypto_tests }, { "slow/util/", slow_util_tests }, diff --git a/src/test/test_socks.c b/src/test/test_socks.c index 6da09fd653..62ff12fe15 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -34,7 +34,7 @@ socks_test_cleanup(const struct testcase_t *testcase, void *ptr) return 1; } -const struct testcase_setup_t socks_setup = { +static const struct testcase_setup_t socks_setup = { socks_test_setup, socks_test_cleanup }; diff --git a/src/test/test_status.c b/src/test/test_status.c index 84a0f6c024..b4438aabe9 100644 --- a/src/test/test_status.c +++ b/src/test/test_status.c @@ -310,8 +310,6 @@ NS_DECL(void, logv, (int severity, log_domain_mask_t domain, NS_DECL(int, server_mode, (const or_options_t *options)); static routerinfo_t *mock_routerinfo; -extern int onion_handshakes_requested[MAX_ONION_HANDSHAKE_TYPE+1]; -extern int onion_handshakes_assigned[MAX_ONION_HANDSHAKE_TYPE+1]; static void NS(test_main)(void *arg) diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c index b9b74a1e96..52be7d4e3a 100644 --- a/src/test/test_tortls.c +++ b/src/test/test_tortls.c @@ -8,6 +8,7 @@ #ifdef _WIN32 #include <winsock2.h> #endif +#include <math.h> #ifdef __GNUC__ #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) @@ -50,9 +51,6 @@ #include "log_test_helpers.h" #define NS_MODULE tortls -extern tor_tls_context_t *server_tls_context; -extern tor_tls_context_t *client_tls_context; - #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) \ && !defined(LIBRESSL_VERSION_NUMBER) #define OPENSSL_OPAQUE @@ -277,8 +275,6 @@ test_tortls_get_state_description(void *ignored) tor_free(tls); } -extern int tor_tls_object_ex_data_index; - static void test_tortls_get_by_ssl(void *ignored) { @@ -791,8 +787,6 @@ get_cipher_by_id(uint16_t id) return NULL; } -extern uint16_t v2_cipher_list[]; - static void test_tortls_classify_client_ciphers(void *ignored) { @@ -1185,9 +1179,6 @@ test_tortls_get_forced_write_size(void *ignored) tor_free(tls); } -extern uint64_t total_bytes_written_over_tls; -extern uint64_t total_bytes_written_by_tls; - static void test_tortls_get_write_overhead_ratio(void *ignored) { @@ -1196,17 +1187,17 @@ test_tortls_get_write_overhead_ratio(void *ignored) total_bytes_written_over_tls = 0; ret = tls_get_write_overhead_ratio(); - tt_int_op(ret, OP_EQ, 1.0); + tt_double_op(fabs(ret - 1.0), OP_LT, 1E-12); total_bytes_written_by_tls = 10; total_bytes_written_over_tls = 1; ret = tls_get_write_overhead_ratio(); - tt_int_op(ret, OP_EQ, 10.0); + tt_double_op(fabs(ret - 10.0), OP_LT, 1E-12); total_bytes_written_by_tls = 10; total_bytes_written_over_tls = 2; ret = tls_get_write_overhead_ratio(); - tt_int_op(ret, OP_EQ, 5.0); + tt_double_op(fabs(ret - 5.0), OP_LT, 1E-12); done: (void)0; diff --git a/src/test/test_util.c b/src/test/test_util.c index d534cc0b52..52bc19ad27 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -30,6 +30,9 @@ #include <ctype.h> #include <float.h> +#define INFINITY_DBL ((double)INFINITY) +#define NAN_DBL ((double)NAN) + /* XXXX this is a minimal wrapper to make the unit tests compile with the * changed tor_timegm interface. */ static time_t @@ -1472,24 +1475,24 @@ test_util_strmisc(void *arg) { /* Test parse_double */ - double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL); + double d = tor_parse_double("10", 0, (double)UINT64_MAX,&i,NULL); tt_int_op(1,OP_EQ, i); tt_assert(DBL_TO_U64(d) == 10); - d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL); + d = tor_parse_double("0", 0, (double)UINT64_MAX,&i,NULL); tt_int_op(1,OP_EQ, i); tt_assert(DBL_TO_U64(d) == 0); - d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL); + d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL); tt_int_op(0,OP_EQ, i); - d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL); + d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,NULL); tt_int_op(0,OP_EQ, i); - d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp); + d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,&cp); tt_int_op(1,OP_EQ, i); - d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL); + d = tor_parse_double("-.0", 0, (double)UINT64_MAX,&i,NULL); tt_int_op(1,OP_EQ, i); tt_assert(DBL_TO_U64(d) == 0); d = tor_parse_double("-10", -100.0, 100.0,&i,NULL); tt_int_op(1,OP_EQ, i); - tt_int_op(-10.0,OP_EQ, d); + tt_double_op(fabs(d - -10.0),OP_LT, 1E-12); } { @@ -4223,21 +4226,6 @@ test_util_round_to_next_multiple_of(void *arg) tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX,2), ==, UINT64_MAX); - tt_i64_op(round_int64_to_next_multiple_of(0,1), ==, 0); - tt_i64_op(round_int64_to_next_multiple_of(0,7), ==, 0); - - tt_i64_op(round_int64_to_next_multiple_of(99,1), ==, 99); - tt_i64_op(round_int64_to_next_multiple_of(99,7), ==, 105); - tt_i64_op(round_int64_to_next_multiple_of(99,9), ==, 99); - - tt_i64_op(round_int64_to_next_multiple_of(-99,1), ==, -99); - tt_i64_op(round_int64_to_next_multiple_of(-99,7), ==, -98); - tt_i64_op(round_int64_to_next_multiple_of(-99,9), ==, -99); - - tt_i64_op(round_int64_to_next_multiple_of(INT64_MIN,2), ==, INT64_MIN); - tt_i64_op(round_int64_to_next_multiple_of(INT64_MAX,2), ==, - INT64_MAX); - tt_int_op(round_uint32_to_next_multiple_of(0,1), ==, 0); tt_int_op(round_uint32_to_next_multiple_of(0,7), ==, 0); @@ -4407,7 +4395,7 @@ test_util_clamp_double_to_int64(void *arg) { (void)arg; - tt_i64_op(INT64_MIN, ==, clamp_double_to_int64(-INFINITY)); + tt_i64_op(INT64_MIN, ==, clamp_double_to_int64(-INFINITY_DBL)); tt_i64_op(INT64_MIN, ==, clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0)); tt_i64_op(INT64_MIN, ==, @@ -4420,7 +4408,7 @@ test_util_clamp_double_to_int64(void *arg) tt_i64_op(0, ==, clamp_double_to_int64(-0.9)); tt_i64_op(0, ==, clamp_double_to_int64(-0.1)); tt_i64_op(0, ==, clamp_double_to_int64(0.0)); - tt_i64_op(0, ==, clamp_double_to_int64(NAN)); + tt_i64_op(0, ==, clamp_double_to_int64(NAN_DBL)); tt_i64_op(0, ==, clamp_double_to_int64(0.1)); tt_i64_op(0, ==, clamp_double_to_int64(0.9)); tt_i64_op(1, ==, clamp_double_to_int64(1.0)); @@ -4432,7 +4420,7 @@ test_util_clamp_double_to_int64(void *arg) clamp_double_to_int64(pow(2.0, 63.0))); tt_i64_op(INT64_MAX, ==, clamp_double_to_int64(pow(2.0, 64.0))); - tt_i64_op(INT64_MAX, ==, clamp_double_to_int64(INFINITY)); + tt_i64_op(INT64_MAX, ==, clamp_double_to_int64(INFINITY_DBL)); done: ; @@ -4819,7 +4807,7 @@ struct testcase_t util_tests[] = { UTIL_LEGACY(memarea), UTIL_LEGACY(control_formats), UTIL_LEGACY(mmap), - UTIL_LEGACY(sscanf), + UTIL_TEST(sscanf, TT_FORK), UTIL_LEGACY(format_time_interval), UTIL_LEGACY(path_is_relative), UTIL_LEGACY(strtok), diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 39c3d02ab1..ea9366305c 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -3,6 +3,8 @@ * Copyright (c) 2007-2016, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +extern const char tor_git_revision[]; + /* Ordinarily defined in tor_main.c; this bit is just here to provide one * since we're not linking to tor_main.c */ const char tor_git_revision[] = ""; @@ -215,8 +217,6 @@ const struct testcase_setup_t passthrough_setup = { passthrough_test_setup, passthrough_test_cleanup }; -extern struct testgroup_t testgroups[]; - /** Main entry point for unit test code: parse the command line, and run * some unit tests. */ int diff --git a/src/test/vote_descriptors.inc b/src/test/vote_descriptors.inc index c5ce21f744..895dc6c65c 100644 --- a/src/test/vote_descriptors.inc +++ b/src/test/vote_descriptors.inc @@ -1,4 +1,4 @@ -const char* VOTE_BODY_V3 = +static const char* VOTE_BODY_V3 = "network-status-version 3\n" "vote-status vote\n" "consensus-methods 13 14 15 16 17 18 19 20 21\n" |