aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/fuzz/fuzz_address.c26
-rw-r--r--src/test/fuzz/fuzz_addressPTR.c32
-rw-r--r--src/test/fuzz/fuzz_hsdescv3_inner.c119
-rw-r--r--src/test/fuzz/fuzz_hsdescv3_middle.c116
-rw-r--r--src/test/fuzz/include.am125
-rw-r--r--src/test/include.am26
-rwxr-xr-xsrc/test/ntor_v3_ref.py308
-rw-r--r--src/test/test.c7
-rw-r--r--src/test/test.h3
-rw-r--r--src/test/test_address.c37
-rw-r--r--src/test/test_channeltls.c3
-rw-r--r--src/test/test_circuitbuild.c2
-rw-r--r--src/test/test_circuitpadding.c6
-rw-r--r--src/test/test_connection.c18
-rw-r--r--src/test/test_dir.c8
-rw-r--r--src/test/test_dirauth_ports.c152
-rw-r--r--src/test/test_entrynodes.c40
-rw-r--r--src/test/test_hs_common.c10
-rw-r--r--src/test/test_hs_control.c2
-rw-r--r--src/test/test_hs_ob.c1
-rw-r--r--src/test/test_ntor_v3.c172
-rw-r--r--src/test/test_process_descs.c14
-rw-r--r--src/test/test_protover.c18
-rw-r--r--src/test/test_pt.c4
-rwxr-xr-xsrc/test/test_rust.sh28
-rw-r--r--src/test/test_sandbox.c349
-rw-r--r--src/test/test_stats.c6
-rw-r--r--src/test/test_voting_flags.c3
28 files changed, 1528 insertions, 107 deletions
diff --git a/src/test/fuzz/fuzz_address.c b/src/test/fuzz/fuzz_address.c
new file mode 100644
index 0000000000..6dccd65e9d
--- /dev/null
+++ b/src/test/fuzz/fuzz_address.c
@@ -0,0 +1,26 @@
+#include "lib/net/address.h"
+#include "lib/malloc/malloc.h"
+
+#include "test/fuzz/fuzzing.h"
+
+int
+fuzz_init(void)
+{
+ return 0;
+}
+
+int
+fuzz_cleanup(void)
+{
+ return 0;
+}
+
+int
+fuzz_main(const uint8_t *data, size_t sz)
+{
+ tor_addr_t addr;
+ char *fuzzing_data = tor_memdup_nulterm(data, sz);
+ tor_addr_parse(&addr, fuzzing_data);
+ tor_free(fuzzing_data);
+ return 0;
+}
diff --git a/src/test/fuzz/fuzz_addressPTR.c b/src/test/fuzz/fuzz_addressPTR.c
new file mode 100644
index 0000000000..b503d53666
--- /dev/null
+++ b/src/test/fuzz/fuzz_addressPTR.c
@@ -0,0 +1,32 @@
+#include "lib/net/address.h"
+#include "lib/net/socket.h"
+#include "lib/cc/ctassert.h"
+#include "lib/container/smartlist.h"
+#include "lib/ctime/di_ops.h"
+#include "lib/log/log.h"
+#include "lib/log/escape.h"
+#include "lib/malloc/malloc.h"
+#include "lib/net/address.h"
+#include "test/fuzz/fuzzing.h"
+
+int
+fuzz_init(void)
+{
+ return 0;
+}
+
+int
+fuzz_cleanup(void)
+{
+ return 0;
+}
+
+int
+fuzz_main(const uint8_t *data, size_t sz)
+{
+ tor_addr_t addr_result;
+ char *fuzzing_data = tor_memdup_nulterm(data, sz);
+ tor_addr_parse_PTR_name(&addr_result, fuzzing_data, AF_UNSPEC, 1);
+ tor_free(fuzzing_data);
+ return 0;
+}
diff --git a/src/test/fuzz/fuzz_hsdescv3_inner.c b/src/test/fuzz/fuzz_hsdescv3_inner.c
new file mode 100644
index 0000000000..5aa719f5c3
--- /dev/null
+++ b/src/test/fuzz/fuzz_hsdescv3_inner.c
@@ -0,0 +1,119 @@
+/* Copyright (c) 2017-2021, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define HS_DESCRIPTOR_PRIVATE
+
+#include "core/or/or.h"
+#include "trunnel/ed25519_cert.h" /* Trunnel interface. */
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "feature/hs/hs_descriptor.h"
+#include "feature/dirparse/unparseable.h"
+
+#include "test/fuzz/fuzzing.h"
+
+static void
+mock_dump_desc__nodump(const char *desc, const char *type)
+{
+ (void)desc;
+ (void)type;
+}
+
+static int
+mock_rsa_ed25519_crosscert_check(const uint8_t *crosscert,
+ const size_t crosscert_len,
+ const crypto_pk_t *rsa_id_key,
+ const ed25519_public_key_t *master_key,
+ const time_t reject_if_expired_before)
+{
+ (void) crosscert;
+ (void) crosscert_len;
+ (void) rsa_id_key;
+ (void) master_key;
+ (void) reject_if_expired_before;
+ return 0;
+}
+
+static size_t
+mock_decrypt_desc_layer(const hs_descriptor_t *desc,
+ const uint8_t *descriptor_cookie,
+ bool is_superencrypted_layer,
+ char **decrypted_out)
+{
+ (void)is_superencrypted_layer;
+ (void)desc;
+ (void)descriptor_cookie;
+ const size_t overhead = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN;
+ const uint8_t *encrypted_blob = (is_superencrypted_layer)
+ ? desc->plaintext_data.superencrypted_blob
+ : desc->superencrypted_data.encrypted_blob;
+ size_t encrypted_blob_size = (is_superencrypted_layer)
+ ? desc->plaintext_data.superencrypted_blob_size
+ : desc->superencrypted_data.encrypted_blob_size;
+
+ if (encrypted_blob_size < overhead)
+ return 0;
+ *decrypted_out = tor_memdup_nulterm(
+ encrypted_blob + HS_DESC_ENCRYPTED_SALT_LEN,
+ encrypted_blob_size - overhead);
+ size_t result = strlen(*decrypted_out);
+ if (result) {
+ return result;
+ } else {
+ tor_free(*decrypted_out);
+ return 0;
+ }
+}
+
+static const uint8_t *decrypted_data = NULL;
+static size_t decrypted_len = 0;
+static size_t
+mock_desc_decrypt_encrypted(const hs_descriptor_t *desc,
+ const curve25519_secret_key_t *client_auth_sk,
+ char **decrypted_out)
+{
+ (void)desc;
+ (void)client_auth_sk;
+ *decrypted_out = (char*)tor_memdup_nulterm(decrypted_data, decrypted_len);
+ return decrypted_len;
+}
+
+int
+fuzz_init(void)
+{
+ disable_signature_checking();
+ MOCK(dump_desc, mock_dump_desc__nodump);
+ MOCK(rsa_ed25519_crosscert_check, mock_rsa_ed25519_crosscert_check);
+ MOCK(decrypt_desc_layer, mock_decrypt_desc_layer);
+ MOCK(desc_decrypt_encrypted, mock_desc_decrypt_encrypted);
+ ed25519_init();
+ return 0;
+}
+
+int
+fuzz_cleanup(void)
+{
+ return 0;
+}
+
+int
+fuzz_main(const uint8_t *data, size_t sz)
+{
+ decrypted_data = data;
+ decrypted_len = sz;
+
+ hs_descriptor_t *desc = tor_malloc_zero(sizeof(hs_descriptor_t));
+ hs_desc_encrypted_data_t *output = tor_malloc_zero(sizeof(*output));
+ curve25519_secret_key_t *client_auth_sk = NULL;
+ hs_desc_decode_status_t status;
+
+ status = desc_decode_encrypted_v3(desc, client_auth_sk, output);
+ if (status == HS_DESC_DECODE_OK) {
+ log_debug(LD_GENERAL, "Decoding okay");
+ } else {
+ log_debug(LD_GENERAL, "Decoding failed");
+ }
+
+ hs_descriptor_free(desc);
+ hs_desc_encrypted_data_free(output);
+ return 0;
+}
diff --git a/src/test/fuzz/fuzz_hsdescv3_middle.c b/src/test/fuzz/fuzz_hsdescv3_middle.c
new file mode 100644
index 0000000000..66a9d52cf3
--- /dev/null
+++ b/src/test/fuzz/fuzz_hsdescv3_middle.c
@@ -0,0 +1,116 @@
+/* Copyright (c) 2017-2021, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define HS_DESCRIPTOR_PRIVATE
+
+#include "core/or/or.h"
+#include "trunnel/ed25519_cert.h" /* Trunnel interface. */
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "feature/hs/hs_descriptor.h"
+#include "feature/dirparse/unparseable.h"
+
+#include "test/fuzz/fuzzing.h"
+
+static void
+mock_dump_desc__nodump(const char *desc, const char *type)
+{
+ (void)desc;
+ (void)type;
+}
+
+static int
+mock_rsa_ed25519_crosscert_check(const uint8_t *crosscert,
+ const size_t crosscert_len,
+ const crypto_pk_t *rsa_id_key,
+ const ed25519_public_key_t *master_key,
+ const time_t reject_if_expired_before)
+{
+ (void) crosscert;
+ (void) crosscert_len;
+ (void) rsa_id_key;
+ (void) master_key;
+ (void) reject_if_expired_before;
+ return 0;
+}
+
+static size_t
+mock_decrypt_desc_layer(const hs_descriptor_t *desc,
+ const uint8_t *descriptor_cookie,
+ bool is_superencrypted_layer,
+ char **decrypted_out)
+{
+ (void)is_superencrypted_layer;
+ (void)desc;
+ (void)descriptor_cookie;
+ const size_t overhead = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN;
+ const uint8_t *encrypted_blob = (is_superencrypted_layer)
+ ? desc->plaintext_data.superencrypted_blob
+ : desc->superencrypted_data.encrypted_blob;
+ size_t encrypted_blob_size = (is_superencrypted_layer)
+ ? desc->plaintext_data.superencrypted_blob_size
+ : desc->superencrypted_data.encrypted_blob_size;
+
+ if (encrypted_blob_size < overhead)
+ return 0;
+ *decrypted_out = tor_memdup_nulterm(
+ encrypted_blob + HS_DESC_ENCRYPTED_SALT_LEN,
+ encrypted_blob_size - overhead);
+ size_t result = strlen(*decrypted_out);
+ if (result) {
+ return result;
+ } else {
+ tor_free(*decrypted_out);
+ return 0;
+ }
+}
+
+static const uint8_t *decrypted_data = NULL;
+static size_t decrypted_len = 0;
+static size_t
+mock_desc_decrypt_superencrypted(const hs_descriptor_t *desc,
+ char **decrypted_out)
+{
+ (void)desc;
+ *decrypted_out = (char*)tor_memdup_nulterm(decrypted_data, decrypted_len);
+ return decrypted_len;
+}
+
+int
+fuzz_init(void)
+{
+ disable_signature_checking();
+ MOCK(dump_desc, mock_dump_desc__nodump);
+ MOCK(rsa_ed25519_crosscert_check, mock_rsa_ed25519_crosscert_check);
+ MOCK(decrypt_desc_layer, mock_decrypt_desc_layer);
+ MOCK(desc_decrypt_superencrypted, mock_desc_decrypt_superencrypted);
+ ed25519_init();
+ return 0;
+}
+
+int
+fuzz_cleanup(void)
+{
+ return 0;
+}
+
+int
+fuzz_main(const uint8_t *data, size_t sz)
+{
+ decrypted_data = data;
+ decrypted_len = sz;
+
+ hs_descriptor_t *desc = tor_malloc_zero(sizeof(hs_descriptor_t));
+ hs_desc_superencrypted_data_t *output = tor_malloc_zero(sizeof(*output));
+ hs_desc_decode_status_t status;
+
+ status = desc_decode_superencrypted_v3(desc, output);
+ if (status == HS_DESC_DECODE_OK) {
+ log_debug(LD_GENERAL, "Decoding okay");
+ } else {
+ log_debug(LD_GENERAL, "Decoding failed");
+ }
+
+ hs_descriptor_free(desc);
+ hs_desc_superencrypted_data_free(output);
+ return 0;
+}
diff --git a/src/test/fuzz/include.am b/src/test/fuzz/include.am
index 9bdced9e6f..9fece7d004 100644
--- a/src/test/fuzz/include.am
+++ b/src/test/fuzz/include.am
@@ -8,7 +8,6 @@ FUZZING_LDFLAG = \
@TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) @TOR_LDFLAGS_libevent@
FUZZING_LIBS = \
src/test/libtor-testing.a \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
@TOR_LIBEVENT_LIBS@ $(TOR_LIBS_CRYPTLIB) \
@TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@ \
@@ -23,17 +22,36 @@ oss-fuzz-prereqs: \
noinst_HEADERS += \
src/test/fuzz/fuzzing.h
-LIBFUZZER = -lFuzzer
LIBFUZZER_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
LIBFUZZER_CFLAGS = $(FUZZING_CFLAGS)
-LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG)
-LIBFUZZER_LIBS = $(FUZZING_LIBS) $(LIBFUZZER) -lstdc++
+LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG) -fsanitize=fuzzer
+LIBFUZZER_LIBS = $(FUZZING_LIBS) -lstdc++
LIBOSS_FUZZ_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
LIBOSS_FUZZ_CFLAGS = $(FUZZING_CFLAGS)
# ===== AFL fuzzers
if UNITTESTS_ENABLED
+src_test_fuzz_fuzz_address_SOURCES = \
+ src/test/fuzz/fuzzing_common.c \
+ src/test/fuzz/fuzz_address.c
+src_test_fuzz_fuzz_address_CPPFLAGS = $(FUZZING_CPPFLAGS)
+src_test_fuzz_fuzz_address_CFLAGS = $(FUZZING_CFLAGS)
+src_test_fuzz_fuzz_address_LDFLAGS = $(FUZZING_LDFLAG)
+src_test_fuzz_fuzz_address_LDADD = $(FUZZING_LIBS)
+endif
+
+if UNITTESTS_ENABLED
+src_test_fuzz_fuzz_addressPTR_SOURCES = \
+ src/test/fuzz/fuzzing_common.c \
+ src/test/fuzz/fuzz_addressPTR.c
+src_test_fuzz_fuzz_addressPTR_CPPFLAGS = $(FUZZING_CPPFLAGS)
+src_test_fuzz_fuzz_addressPTR_CFLAGS = $(FUZZING_CFLAGS)
+src_test_fuzz_fuzz_addressPTR_LDFLAGS = $(FUZZING_LDFLAG)
+src_test_fuzz_fuzz_addressPTR_LDADD = $(FUZZING_LIBS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_consensus_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_consensus.c
@@ -94,6 +112,28 @@ src_test_fuzz_fuzz_hsdescv3_LDADD = $(FUZZING_LIBS)
endif
if UNITTESTS_ENABLED
+src_test_fuzz_fuzz_hsdescv3_inner_SOURCES = \
+ src/test/fuzz/fuzzing_common.c \
+ src/test/fuzz/fuzz_hsdescv3_inner.c
+src_test_fuzz_fuzz_hsdescv3_inner_CPPFLAGS = $(FUZZING_CPPFLAGS)
+src_test_fuzz_fuzz_hsdescv3_inner_CFLAGS = $(FUZZING_CFLAGS)
+src_test_fuzz_fuzz_hsdescv3_inner_LDFLAGS = $(FUZZING_LDFLAG)
+src_test_fuzz_fuzz_hsdescv3_inner_LDADD = $(FUZZING_LIBS)
+endif
+
+
+if UNITTESTS_ENABLED
+src_test_fuzz_fuzz_hsdescv3_middle_SOURCES = \
+ src/test/fuzz/fuzzing_common.c \
+ src/test/fuzz/fuzz_hsdescv3_middle.c
+src_test_fuzz_fuzz_hsdescv3_middle_CPPFLAGS = $(FUZZING_CPPFLAGS)
+src_test_fuzz_fuzz_hsdescv3_middle_CFLAGS = $(FUZZING_CFLAGS)
+src_test_fuzz_fuzz_hsdescv3_middle_LDFLAGS = $(FUZZING_LDFLAG)
+src_test_fuzz_fuzz_hsdescv3_middle_LDADD = $(FUZZING_LIBS)
+endif
+
+
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_http_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_http.c
@@ -155,12 +195,16 @@ endif
if UNITTESTS_ENABLED
FUZZERS = \
+ src/test/fuzz/fuzz-address \
+ src/test/fuzz/fuzz-addressPTR \
src/test/fuzz/fuzz-consensus \
src/test/fuzz/fuzz-descriptor \
src/test/fuzz/fuzz-diff \
src/test/fuzz/fuzz-diff-apply \
src/test/fuzz/fuzz-extrainfo \
src/test/fuzz/fuzz-hsdescv3 \
+ src/test/fuzz/fuzz-hsdescv3-inner \
+ src/test/fuzz/fuzz-hsdescv3-middle \
src/test/fuzz/fuzz-http \
src/test/fuzz/fuzz-http-connect \
src/test/fuzz/fuzz-microdesc \
@@ -173,6 +217,24 @@ endif
if LIBFUZZER_ENABLED
if UNITTESTS_ENABLED
+src_test_fuzz_lf_fuzz_address_SOURCES = \
+ $(src_test_fuzz_fuzz_address_SOURCES)
+src_test_fuzz_lf_fuzz_address_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
+src_test_fuzz_lf_fuzz_address_CFLAGS = $(LIBFUZZER_CFLAGS)
+src_test_fuzz_lf_fuzz_address_LDFLAGS = $(LIBFUZZER_LDFLAG)
+src_test_fuzz_lf_fuzz_address_LDADD = $(LIBFUZZER_LIBS)
+endif
+
+if UNITTESTS_ENABLED
+src_test_fuzz_lf_fuzz_addressPTR_SOURCES = \
+ $(src_test_fuzz_fuzz_addressPTR_SOURCES)
+src_test_fuzz_lf_fuzz_addressPTR_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
+src_test_fuzz_lf_fuzz_addressPTR_CFLAGS = $(LIBFUZZER_CFLAGS)
+src_test_fuzz_lf_fuzz_addressPTR_LDFLAGS = $(LIBFUZZER_LDFLAG)
+src_test_fuzz_lf_fuzz_addressPTR_LDADD = $(LIBFUZZER_LIBS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_consensus_SOURCES = \
$(src_test_fuzz_fuzz_consensus_SOURCES)
src_test_fuzz_lf_fuzz_consensus_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
@@ -227,6 +289,25 @@ src_test_fuzz_lf_fuzz_hsdescv3_LDADD = $(LIBFUZZER_LIBS)
endif
if UNITTESTS_ENABLED
+src_test_fuzz_lf_fuzz_hsdescv3_inner_SOURCES = \
+ $(src_test_fuzz_fuzz_hsdescv3_inner_SOURCES)
+src_test_fuzz_lf_fuzz_hsdescv3_inner_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
+src_test_fuzz_lf_fuzz_hsdescv3_inner_CFLAGS = $(LIBFUZZER_CFLAGS)
+src_test_fuzz_lf_fuzz_hsdescv3_inner_LDFLAGS = $(LIBFUZZER_LDFLAG)
+src_test_fuzz_lf_fuzz_hsdescv3_inner_LDADD = $(LIBFUZZER_LIBS)
+endif
+
+if UNITTESTS_ENABLED
+src_test_fuzz_lf_fuzz_hsdescv3_middle_SOURCES = \
+ $(src_test_fuzz_fuzz_hsdescv3_middle_SOURCES)
+src_test_fuzz_lf_fuzz_hsdescv3_middle_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
+src_test_fuzz_lf_fuzz_hsdescv3_middle_CFLAGS = $(LIBFUZZER_CFLAGS)
+src_test_fuzz_lf_fuzz_hsdescv3_middle_LDFLAGS = $(LIBFUZZER_LDFLAG)
+src_test_fuzz_lf_fuzz_hsdescv3_middle_LDADD = $(LIBFUZZER_LIBS)
+endif
+
+
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_http_SOURCES = \
$(src_test_fuzz_fuzz_http_SOURCES)
src_test_fuzz_lf_fuzz_http_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
@@ -281,12 +362,16 @@ src_test_fuzz_lf_fuzz_vrs_LDADD = $(LIBFUZZER_LIBS)
endif
LIBFUZZER_FUZZERS = \
+ src/test/fuzz/lf-fuzz-address \
+ src/test/fuzz/lf-fuzz-addressPTR \
src/test/fuzz/lf-fuzz-consensus \
src/test/fuzz/lf-fuzz-descriptor \
src/test/fuzz/lf-fuzz-diff \
src/test/fuzz/lf-fuzz-diff-apply \
src/test/fuzz/lf-fuzz-extrainfo \
src/test/fuzz/lf-fuzz-hsdescv3 \
+ src/test/fuzz/lf-fuzz-hsdescv3-inner \
+ src/test/fuzz/lf-fuzz-hsdescv3-middle \
src/test/fuzz/lf-fuzz-http \
src/test/fuzz/lf-fuzz-http-connect \
src/test/fuzz/lf-fuzz-microdesc \
@@ -302,6 +387,20 @@ endif
if OSS_FUZZ_ENABLED
if UNITTESTS_ENABLED
+src_test_fuzz_liboss_fuzz_address_a_SOURCES = \
+ $(src_test_fuzz_fuzz_address_SOURCES)
+src_test_fuzz_liboss_fuzz_address_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
+src_test_fuzz_liboss_fuzz_address_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+
+if UNITTESTS_ENABLED
+src_test_fuzz_liboss_fuzz_addressPTR_a_SOURCES = \
+ $(src_test_fuzz_fuzz_addressPTR_SOURCES)
+src_test_fuzz_liboss_fuzz_addressPTR_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
+src_test_fuzz_liboss_fuzz_addressPTR_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_consensus_a_SOURCES = \
$(src_test_fuzz_fuzz_consensus_SOURCES)
src_test_fuzz_liboss_fuzz_consensus_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
@@ -344,6 +443,20 @@ src_test_fuzz_liboss_fuzz_hsdescv3_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
endif
if UNITTESTS_ENABLED
+src_test_fuzz_liboss_fuzz_hsdescv3_inner_a_SOURCES = \
+ $(src_test_fuzz_fuzz_hsdescv3_inner_SOURCES)
+src_test_fuzz_liboss_fuzz_hsdescv3_inner_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
+src_test_fuzz_liboss_fuzz_hsdescv3_inner_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+
+if UNITTESTS_ENABLED
+src_test_fuzz_liboss_fuzz_hsdescv3_middle_a_SOURCES = \
+ $(src_test_fuzz_fuzz_hsdescv3_middle_SOURCES)
+src_test_fuzz_liboss_fuzz_hsdescv3_middle_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
+src_test_fuzz_liboss_fuzz_hsdescv3_middle_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_http_a_SOURCES = \
$(src_test_fuzz_fuzz_http_SOURCES)
src_test_fuzz_liboss_fuzz_http_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
@@ -386,12 +499,16 @@ src_test_fuzz_liboss_fuzz_vrs_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
endif
OSS_FUZZ_FUZZERS = \
+ src/test/fuzz/liboss-fuzz-address.a \
+ src/test/fuzz/liboss-fuzz-addressPTR.a \
src/test/fuzz/liboss-fuzz-consensus.a \
src/test/fuzz/liboss-fuzz-descriptor.a \
src/test/fuzz/liboss-fuzz-diff.a \
src/test/fuzz/liboss-fuzz-diff-apply.a \
src/test/fuzz/liboss-fuzz-extrainfo.a \
src/test/fuzz/liboss-fuzz-hsdescv3.a \
+ src/test/fuzz/liboss-fuzz-hsdescv3-inner.a \
+ src/test/fuzz/liboss-fuzz-hsdescv3-middle.a \
src/test/fuzz/liboss-fuzz-http.a \
src/test/fuzz/liboss-fuzz-http-connect.a \
src/test/fuzz/liboss-fuzz-microdesc.a \
diff --git a/src/test/include.am b/src/test/include.am
index d5dcebfaea..2765cf27d0 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -8,11 +8,7 @@ TESTS_ENVIRONMENT = \
export abs_top_builddir="$(abs_top_builddir)"; \
export builddir="$(builddir)"; \
export TESTING_TOR_BINARY="$(TESTING_TOR_BINARY)"; \
- export CARGO="$(CARGO)"; \
- export EXTRA_CARGO_OPTIONS="$(EXTRA_CARGO_OPTIONS)"; \
- export CARGO_ONLINE="$(CARGO_ONLINE)"; \
- export CCLD="$(CCLD)"; \
- export RUSTFLAGS="-C linker=`echo '$(CC)' | cut -d' ' -f 1` $(RUST_LINKER_OPTIONS)";
+ export CCLD="$(CCLD)";
TESTSCRIPTS = \
src/test/fuzz_static_testcases.sh \
@@ -35,11 +31,6 @@ TESTSCRIPTS = \
src/test/unittest_part7.sh \
src/test/unittest_part8.sh
-if USE_RUST
-TESTSCRIPTS += \
- src/test/test_rust.sh
-endif
-
if USEPYTHON
TESTSCRIPTS += \
src/test/test_ntor.sh \
@@ -170,6 +161,7 @@ src_test_test_SOURCES += \
src/test/test_crypto_rng.c \
src/test/test_data.c \
src/test/test_dir.c \
+ src/test/test_dirauth_ports.c \
src/test/test_dirvote.c \
src/test/test_dir_common.c \
src/test/test_dir_handle_get.c \
@@ -203,6 +195,7 @@ src_test_test_SOURCES += \
src/test/test_namemap.c \
src/test/test_netinfo.c \
src/test/test_nodelist.c \
+ src/test/test_ntor_v3.c \
src/test/test_oom.c \
src/test/test_oos.c \
src/test/test_options.c \
@@ -229,6 +222,7 @@ src_test_test_SOURCES += \
src/test/test_routerkeys.c \
src/test/test_routerlist.c \
src/test/test_routerset.c \
+ src/test/test_sandbox.c \
src/test/test_scheduler.c \
src/test/test_sendme.c \
src/test/test_shared_random.c \
@@ -303,7 +297,6 @@ 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 = \
$(TOR_UTIL_TESTING_LIBS) \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
@TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_USERENV@ \
@TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@ @TOR_TRACE_LIBS@
@@ -311,7 +304,6 @@ src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_test_LDADD = \
src/test/libtor-testing.a \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
$(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@@ -340,7 +332,6 @@ src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_bench_LDADD = \
libtor.a \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
$(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@@ -350,7 +341,6 @@ src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_test_workqueue_LDADD = \
src/test/libtor-testing.a \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
$(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@@ -362,7 +352,6 @@ src_test_test_timers_LDADD = \
src/lib/libtor-evloop-testing.a \
$(TOR_CRYPTO_TESTING_LIBS) \
$(TOR_UTIL_TESTING_LIBS) \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
$(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@@ -398,7 +387,6 @@ src_test_test_ntor_cl_SOURCES = src/test/test_ntor_cl.c
src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
src_test_test_ntor_cl_LDADD = \
libtor.a \
- $(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
$(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ @TOR_LZMA_LIBS@ @TOR_TRACE_LIBS@
@@ -421,7 +409,6 @@ 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 = \
$(TOR_UTIL_TESTING_LIBS) \
- $(rust_ldadd) \
@TOR_LIB_MATH@ \
@TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_SHLWAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@TOR_TRACE_LIBS@
@@ -443,13 +430,11 @@ EXTRA_DIST += \
src/test/test_include.py \
src/test/zero_length_keys.sh \
scripts/maint/run_check_subsystem_order.sh \
- src/test/rust_supp.txt \
src/test/test_keygen.sh \
src/test/test_key_expiration.sh \
src/test/test_zero_length_keys.sh \
src/test/test_ntor.sh src/test/test_hs_ntor.sh src/test/test_bt.sh \
src/test/test-network.sh \
- src/test/test_rust.sh \
src/test/test_switch_id.sh \
src/test/test_workqueue_cancel.sh \
src/test/test_workqueue_efd.sh \
@@ -467,6 +452,3 @@ EXTRA_DIST += \
src/test/unittest_part6.sh \
src/test/unittest_part7.sh \
src/test/unittest_part8.sh
-
-test-rust:
- $(TESTS_ENVIRONMENT) "$(abs_top_srcdir)/src/test/test_rust.sh"
diff --git a/src/test/ntor_v3_ref.py b/src/test/ntor_v3_ref.py
new file mode 100755
index 0000000000..28bc077105
--- /dev/null
+++ b/src/test/ntor_v3_ref.py
@@ -0,0 +1,308 @@
+#!/usr/bin/python
+
+import binascii
+import hashlib
+import os
+import struct
+
+import donna25519
+from Crypto.Cipher import AES
+from Crypto.Util import Counter
+
+# Define basic wrappers.
+
+DIGEST_LEN = 32
+ENC_KEY_LEN = 32
+PUB_KEY_LEN = 32
+SEC_KEY_LEN = 32
+IDENTITY_LEN = 32
+
+def sha3_256(s):
+ d = hashlib.sha3_256(s).digest()
+ assert len(d) == DIGEST_LEN
+ return d
+
+def shake_256(s):
+ # Note: In reality, you wouldn't want to generate more bytes than needed.
+ MAX_KEY_BYTES = 1024
+ return hashlib.shake_256(s).digest(MAX_KEY_BYTES)
+
+def curve25519(pk, sk):
+ assert len(pk) == PUB_KEY_LEN
+ assert len(sk) == SEC_KEY_LEN
+ private = donna25519.PrivateKey.load(sk)
+ public = donna25519.PublicKey(pk)
+ return private.do_exchange(public)
+
+def keygen():
+ private = donna25519.PrivateKey()
+ public = private.get_public()
+ return (private.private, public.public)
+
+def aes256_ctr(k, s):
+ assert len(k) == ENC_KEY_LEN
+ cipher = AES.new(k, AES.MODE_CTR, counter=Counter.new(128, initial_value=0))
+ return cipher.encrypt(s)
+
+# Byte-oriented helper. We use this for decoding keystreams and messages.
+
+class ByteSeq:
+ def __init__(self, data):
+ self.data = data
+
+ def take(self, n):
+ assert n <= len(self.data)
+ result = self.data[:n]
+ self.data = self.data[n:]
+ return result
+
+ def exhausted(self):
+ return len(self.data) == 0
+
+ def remaining(self):
+ return len(self.data)
+
+# Low-level functions
+
+MAC_KEY_LEN = 32
+MAC_LEN = DIGEST_LEN
+
+hash_func = sha3_256
+
+def encapsulate(s):
+ """encapsulate `s` with a length prefix.
+
+ We use this whenever we need to avoid message ambiguities in
+ cryptographic inputs.
+ """
+ assert len(s) <= 0xffffffff
+ header = b"\0\0\0\0" + struct.pack("!L", len(s))
+ assert len(header) == 8
+ return header + s
+
+def h(s, tweak):
+ return hash_func(encapsulate(tweak) + s)
+
+def mac(s, key, tweak):
+ return hash_func(encapsulate(tweak) + encapsulate(key) + s)
+
+def kdf(s, tweak):
+ data = shake_256(encapsulate(tweak) + s)
+ return ByteSeq(data)
+
+def enc(s, k):
+ return aes256_ctr(k, s)
+
+# Tweaked wrappers
+
+PROTOID = b"ntor3-curve25519-sha3_256-1"
+T_KDF_PHASE1 = PROTOID + b":kdf_phase1"
+T_MAC_PHASE1 = PROTOID + b":msg_mac"
+T_KDF_FINAL = PROTOID + b":kdf_final"
+T_KEY_SEED = PROTOID + b":key_seed"
+T_VERIFY = PROTOID + b":verify"
+T_AUTH = PROTOID + b":auth_final"
+
+def kdf_phase1(s):
+ return kdf(s, T_KDF_PHASE1)
+
+def kdf_final(s):
+ return kdf(s, T_KDF_FINAL)
+
+def mac_phase1(s, key):
+ return mac(s, key, T_MAC_PHASE1)
+
+def h_key_seed(s):
+ return h(s, T_KEY_SEED)
+
+def h_verify(s):
+ return h(s, T_VERIFY)
+
+def h_auth(s):
+ return h(s, T_AUTH)
+
+# Handshake.
+
+def client_phase1(msg, verification, B, ID):
+ assert len(B) == PUB_KEY_LEN
+ assert len(ID) == IDENTITY_LEN
+
+ (x,X) = keygen()
+ p(["x", "X"], locals())
+ p(["msg", "verification"], locals())
+ Bx = curve25519(B, x)
+ secret_input_phase1 = Bx + ID + X + B + PROTOID + encapsulate(verification)
+
+ phase1_keys = kdf_phase1(secret_input_phase1)
+ enc_key = phase1_keys.take(ENC_KEY_LEN)
+ mac_key = phase1_keys.take(MAC_KEY_LEN)
+ p(["enc_key", "mac_key"], locals())
+
+ msg_0 = ID + B + X + enc(msg, enc_key)
+ mac = mac_phase1(msg_0, mac_key)
+ p(["mac"], locals())
+
+ client_handshake = msg_0 + mac
+ state = dict(x=x, X=X, B=B, ID=ID, Bx=Bx, mac=mac, verification=verification)
+
+ p(["client_handshake"], locals())
+
+ return (client_handshake, state)
+
+# server.
+
+class Reject(Exception):
+ pass
+
+def server_part1(cmsg, verification, b, B, ID):
+ assert len(B) == PUB_KEY_LEN
+ assert len(ID) == IDENTITY_LEN
+ assert len(b) == SEC_KEY_LEN
+
+ if len(cmsg) < (IDENTITY_LEN + PUB_KEY_LEN * 2 + MAC_LEN):
+ raise Reject()
+
+ mac_covered_portion = cmsg[0:-MAC_LEN]
+ cmsg = ByteSeq(cmsg)
+ cmsg_id = cmsg.take(IDENTITY_LEN)
+ cmsg_B = cmsg.take(PUB_KEY_LEN)
+ cmsg_X = cmsg.take(PUB_KEY_LEN)
+ cmsg_msg = cmsg.take(cmsg.remaining() - MAC_LEN)
+ cmsg_mac = cmsg.take(MAC_LEN)
+
+ assert cmsg.exhausted()
+
+ # XXXX for real purposes, you would use constant-time checks here
+ if cmsg_id != ID or cmsg_B != B:
+ raise Reject()
+
+ Xb = curve25519(cmsg_X, b)
+ secret_input_phase1 = Xb + ID + cmsg_X + B + PROTOID + encapsulate(verification)
+
+ phase1_keys = kdf_phase1(secret_input_phase1)
+ enc_key = phase1_keys.take(ENC_KEY_LEN)
+ mac_key = phase1_keys.take(MAC_KEY_LEN)
+
+ mac_received = mac_phase1(mac_covered_portion, mac_key)
+ if mac_received != cmsg_mac:
+ raise Reject()
+
+ client_msg = enc(cmsg_msg, enc_key)
+ state = dict(
+ b=b,
+ B=B,
+ X=cmsg_X,
+ mac_received=mac_received,
+ Xb=Xb,
+ ID=ID,
+ verification=verification)
+
+ return (client_msg, state)
+
+def server_part2(state, server_msg):
+ X = state['X']
+ Xb = state['Xb']
+ B = state['B']
+ b = state['b']
+ ID = state['ID']
+ mac_received = state['mac_received']
+ verification = state['verification']
+
+ p(["server_msg"], locals())
+
+ (y,Y) = keygen()
+ p(["y", "Y"], locals())
+ Xy = curve25519(X, y)
+
+ secret_input = Xy + Xb + ID + B + X + Y + PROTOID + encapsulate(verification)
+ key_seed = h_key_seed(secret_input)
+ verify = h_verify(secret_input)
+ p(["key_seed", "verify"], locals())
+
+ keys = kdf_final(key_seed)
+ server_enc_key = keys.take(ENC_KEY_LEN)
+ p(["server_enc_key"], locals())
+
+ smsg_msg = enc(server_msg, server_enc_key)
+
+ auth_input = verify + ID + B + Y + X + mac_received + encapsulate(smsg_msg) + PROTOID + b"Server"
+
+ auth = h_auth(auth_input)
+ server_handshake = Y + auth + smsg_msg
+ p(["auth", "server_handshake"], locals())
+
+ return (server_handshake, keys)
+
+def client_phase2(state, smsg):
+ x = state['x']
+ X = state['X']
+ B = state['B']
+ ID = state['ID']
+ Bx = state['Bx']
+ mac_sent = state['mac']
+ verification = state['verification']
+
+ if len(smsg) < PUB_KEY_LEN + DIGEST_LEN:
+ raise Reject()
+
+ smsg = ByteSeq(smsg)
+ Y = smsg.take(PUB_KEY_LEN)
+ auth_received = smsg.take(DIGEST_LEN)
+ server_msg = smsg.take(smsg.remaining())
+
+ Yx = curve25519(Y,x)
+
+ secret_input = Yx + Bx + ID + B + X + Y + PROTOID + encapsulate(verification)
+ key_seed = h_key_seed(secret_input)
+ verify = h_verify(secret_input)
+
+ auth_input = verify + ID + B + Y + X + mac_sent + encapsulate(server_msg) + PROTOID + b"Server"
+
+ auth = h_auth(auth_input)
+ if auth != auth_received:
+ raise Reject()
+
+ keys = kdf_final(key_seed)
+ enc_key = keys.take(ENC_KEY_LEN)
+
+ server_msg_decrypted = enc(server_msg, enc_key)
+
+ return (keys, server_msg_decrypted)
+
+def p(varnames, localvars):
+ for v in varnames:
+ label = v
+ val = localvars[label]
+ print('{} = "{}"'.format(label, binascii.b2a_hex(val).decode("ascii")))
+
+def test():
+ (b,B) = keygen()
+ ID = os.urandom(IDENTITY_LEN)
+
+ p(["b", "B", "ID"], locals())
+
+ print("# ============")
+ (c_handshake, c_state) = client_phase1(b"hello world", b"xyzzy", B, ID)
+
+ print("# ============")
+
+ (c_msg_got, s_state) = server_part1(c_handshake, b"xyzzy", b, B, ID)
+
+ #print(repr(c_msg_got))
+
+ (s_handshake, s_keys) = server_part2(s_state, b"Hola Mundo")
+
+ print("# ============")
+
+ (c_keys, s_msg_got) = client_phase2(c_state, s_handshake)
+
+ #print(repr(s_msg_got))
+
+ c_keys_256 = c_keys.take(256)
+ p(["c_keys_256"], locals())
+
+ assert (c_keys_256 == s_keys.take(256))
+
+
+if __name__ == '__main__':
+ test()
diff --git a/src/test/test.c b/src/test/test.c
index 40c053a660..c38d78da30 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1,5 +1,4 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
-->a * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2021, The Tor Project, Inc. */
/* See LICENSE for licensing information */
@@ -53,6 +52,7 @@
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_tap.h"
#include "core/or/policies.h"
+#include "lib/sandbox/sandbox.h"
#include "app/config/statefile.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "feature/nodelist/networkstatus.h"
@@ -673,6 +673,7 @@ struct testgroup_t testgroups[] = {
{ "crypto/pem/", pem_tests },
{ "crypto/rng/", crypto_rng_tests },
{ "dir/", dir_tests },
+ { "dir/auth/ports/", dirauth_port_tests },
{ "dir/auth/process_descs/", process_descs_tests },
{ "dir/md/", microdesc_tests },
{ "dirauth/dirvote/", dirvote_tests},
@@ -707,6 +708,7 @@ struct testgroup_t testgroups[] = {
{ "netinfo/", netinfo_tests },
{ "nodelist/", nodelist_tests },
{ "oom/", oom_tests },
+ { "onion-handshake/ntor-v3/", ntor_v3_tests },
{ "oos/", oos_tests },
{ "options/", options_tests },
{ "options/act/", options_act_tests },
@@ -731,6 +733,9 @@ struct testgroup_t testgroups[] = {
{ "routerkeys/", routerkeys_tests },
{ "routerlist/", routerlist_tests },
{ "routerset/" , routerset_tests },
+#ifdef USE_LIBSECCOMP
+ { "sandbox/" , sandbox_tests },
+#endif
{ "scheduler/", scheduler_tests },
{ "sendme/", sendme_tests },
{ "shared-random/", sr_tests },
diff --git a/src/test/test.h b/src/test/test.h
index f88bc98498..e17bce427c 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -120,6 +120,7 @@ extern struct testcase_t crypto_ope_tests[];
extern struct testcase_t crypto_openssl_tests[];
extern struct testcase_t crypto_rng_tests[];
extern struct testcase_t crypto_tests[];
+extern struct testcase_t dirauth_port_tests[];
extern struct testcase_t dir_handle_get_tests[];
extern struct testcase_t dir_tests[];
extern struct testcase_t dirvote_tests[];
@@ -154,6 +155,7 @@ extern struct testcase_t microdesc_tests[];
extern struct testcase_t namemap_tests[];
extern struct testcase_t netinfo_tests[];
extern struct testcase_t nodelist_tests[];
+extern struct testcase_t ntor_v3_tests[];
extern struct testcase_t oom_tests[];
extern struct testcase_t oos_tests[];
extern struct testcase_t options_tests[];
@@ -182,6 +184,7 @@ 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 sandbox_tests[];
extern struct testcase_t scheduler_tests[];
extern struct testcase_t sendme_tests[];
extern struct testcase_t socks_tests[];
diff --git a/src/test/test_address.c b/src/test/test_address.c
index 9c1415419c..015ca0807c 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -1326,6 +1326,42 @@ test_address_dirserv_router_addr_private(void *opt_dir_allow_private)
UNMOCK(get_options);
}
+static void
+test_address_parse_port_range(void *arg)
+{
+ int ret;
+ uint16_t min_out = 0;
+ uint16_t max_out = 0;
+
+ (void) arg;
+
+ /* Invalid. */
+ ret = parse_port_range("0x00", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, -1);
+ ret = parse_port_range("0x01", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, -1);
+ ret = parse_port_range("1817161", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, -1);
+ ret = parse_port_range("65536", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, -1);
+ ret = parse_port_range("1-65536", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, -1);
+
+ /* Valid. */
+ ret = parse_port_range("65535", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(min_out, OP_EQ, 65535);
+ tt_int_op(max_out, OP_EQ, 65535);
+
+ ret = parse_port_range("1-65535", &min_out, &max_out);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(min_out, OP_EQ, 1);
+ tt_int_op(max_out, OP_EQ, 65535);
+
+ done:
+ ;
+}
+
#define ADDRESS_TEST(name, flags) \
{ #name, test_address_ ## name, flags, NULL, NULL }
#define ADDRESS_TEST_STR_ARG(name, flags, str_arg) \
@@ -1364,5 +1400,6 @@ struct testcase_t address_tests[] = {
ADDRESS_TEST(tor_node_in_same_network_family, 0),
ADDRESS_TEST(dirserv_router_addr_private, 0),
ADDRESS_TEST_STR_ARG(dirserv_router_addr_private, 0, "allow_private"),
+ ADDRESS_TEST(parse_port_range, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c
index 5219c86097..ca7fee2c53 100644
--- a/src/test/test_channeltls.c
+++ b/src/test/test_channeltls.c
@@ -20,6 +20,7 @@
#include "lib/tls/tortls.h"
#include "core/or/or_connection_st.h"
+#include "core/or/congestion_control_common.h"
/* Test suite stuff */
#include "test/test.h"
@@ -155,7 +156,7 @@ test_channeltls_num_bytes_queued(void *arg)
* - 2 cells.
*/
n = ch->num_cells_writeable(ch);
- tt_int_op(n, OP_EQ, CEIL_DIV(OR_CONN_HIGHWATER, 512) - 2);
+ tt_int_op(n, OP_EQ, CEIL_DIV(or_conn_highwatermark(), 512) - 2);
UNMOCK(buf_datalen);
tlschan_buf_datalen_mock_target = NULL;
tlschan_buf_datalen_mock_size = 0;
diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c
index 873391a84f..0a5c3530bd 100644
--- a/src/test/test_circuitbuild.c
+++ b/src/test/test_circuitbuild.c
@@ -113,7 +113,7 @@ test_new_route_len_safe_exit(void *arg)
/* hidden service connecting to introduction point */
r = new_route_len(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, &dummy_ei,
&dummy_nodes);
- tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
+ tt_int_op(DEFAULT_ROUTE_LEN+1, OP_EQ, r);
/* router testing its own reachability */
r = new_route_len(CIRCUIT_PURPOSE_TESTING, &dummy_ei, &dummy_nodes);
diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c
index 86baf54f40..6ced3f4111 100644
--- a/src/test/test_circuitpadding.c
+++ b/src/test/test_circuitpadding.c
@@ -1367,7 +1367,7 @@ test_circuitpadding_wronghop(void *arg)
tt_ptr_op(client_side->padding_info[0], OP_NE, NULL);
tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL);
tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL);
- tt_int_op(n_relay_cells, OP_EQ, 3);
+ tt_int_op(n_relay_cells, OP_EQ, 2);
tt_int_op(n_client_cells, OP_EQ, 2);
/* 6. Sending negotiated command to relay does nothing */
@@ -1396,11 +1396,9 @@ test_circuitpadding_wronghop(void *arg)
/* verify no padding was negotiated */
tt_ptr_op(relay_side->padding_machine[0], OP_EQ, NULL);
tt_ptr_op(client_side->padding_machine[0], OP_EQ, NULL);
- tt_int_op(n_relay_cells, OP_EQ, 3);
- tt_int_op(n_client_cells, OP_EQ, 2);
/* verify no echo was sent */
- tt_int_op(n_relay_cells, OP_EQ, 3);
+ tt_int_op(n_relay_cells, OP_EQ, 2);
tt_int_op(n_client_cells, OP_EQ, 2);
/* Finish circuit */
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index 9c726c07f8..87940f71e6 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -992,12 +992,12 @@ test_conn_describe(void *arg)
#define STR(x) #x
/* where arg is an expression (constant, variable, compound expression) */
-#define CONNECTION_TESTCASE_ARG(name, fork, setup, arg) \
- { #name "_" STR(x), \
+#define CONNECTION_TESTCASE_ARG(name, extra, fork, setup, arg) \
+ { STR(name)"/"extra, \
test_conn_##name, \
- fork, \
- &setup, \
- (void *)arg }
+ (fork), \
+ &(setup), \
+ (void *)(arg) }
#endif /* !defined(COCCI) */
static const unsigned int PROXY_CONNECT_ARG = PROXY_CONNECT;
@@ -1007,14 +1007,14 @@ struct testcase_t connection_tests[] = {
CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st),
CONNECTION_TESTCASE(get_rsrc, TT_FORK, test_conn_get_rsrc_st),
- CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
+ CONNECTION_TESTCASE_ARG(download_status, "microdesc", TT_FORK,
test_conn_download_status_st, "microdesc"),
- CONNECTION_TESTCASE_ARG(download_status, TT_FORK,
+ CONNECTION_TESTCASE_ARG(download_status, "ns", TT_FORK,
test_conn_download_status_st, "ns"),
- CONNECTION_TESTCASE_ARG(https_proxy_connect, TT_FORK,
+ CONNECTION_TESTCASE_ARG(https_proxy_connect, "https", TT_FORK,
test_conn_proxy_connect_st, &PROXY_CONNECT_ARG),
- CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, TT_FORK,
+ CONNECTION_TESTCASE_ARG(haproxy_proxy_connect, "haproxy", TT_FORK,
test_conn_proxy_connect_st, &PROXY_HAPROXY_ARG),
//CONNECTION_TESTCASE(func_suffix, TT_FORK, setup_func_pair),
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 0d2d6800ba..186e09f236 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -6652,13 +6652,7 @@ test_dir_find_dl_min_delay(void* data)
dls.schedule = DL_SCHED_BRIDGE;
/* client */
- mock_options->ClientOnly = 1;
- mock_options->UseBridges = 1;
- if (num_bridges_usable(0) > 0) {
- tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
- } else {
- tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
- }
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
done:
UNMOCK(networkstatus_consensus_is_bootstrapping);
diff --git a/src/test/test_dirauth_ports.c b/src/test/test_dirauth_ports.c
new file mode 100644
index 0000000000..5dc0b0b631
--- /dev/null
+++ b/src/test/test_dirauth_ports.c
@@ -0,0 +1,152 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2021, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define CONFIG_PRIVATE
+
+#include "core/or/or.h"
+#include "feature/dirclient/dir_server_st.h"
+#include "feature/nodelist/dirlist.h"
+#include "app/config/config.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+static void
+test_dirauth_port_parsing(void *arg)
+{
+ (void)arg;
+
+ // This one is okay.
+ int rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=http://128.31.0.39:9131/ "
+ "download=http://128.31.0.39:9131 "
+ "vote=http://128.31.0.39:9131/ "
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,0);
+
+ // These have bad syntax.
+ setup_capture_of_logs(LOG_WARN);
+ rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "uploadx=http://128.31.0.39:9131/ "
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,0);
+ expect_log_msg_containing("Unrecognized flag");
+ mock_clean_saved_logs();
+
+ rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=https://128.31.0.39:9131/ " // https is not recognized
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,-1);
+ expect_log_msg_containing("Unsupported URL scheme");
+ mock_clean_saved_logs();
+
+ rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=http://128.31.0.39:9131/tor " // suffix is not supported
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,-1);
+ expect_log_msg_containing("Unsupported URL prefix");
+ mock_clean_saved_logs();
+
+ rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=http://128.31.0.256:9131/ " // "256" is not ipv4.
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,-1);
+ expect_log_msg_containing("Unable to parse address");
+
+ rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=http://xyz.example.com/ " // hostnames not supported.
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 1);
+ tt_int_op(rv,OP_EQ,-1);
+ expect_log_msg_containing("Unable to parse address");
+
+ done:
+ teardown_capture_of_logs();
+}
+
+static void
+test_dirauth_port_lookup(void *arg)
+{
+ (void)arg;
+
+ clear_dir_servers();
+
+ int rv = parse_dir_authority_line(
+ "moria1 orport=9101 "
+ "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+ "upload=http://128.31.0.40:9132/ "
+ "download=http://128.31.0.41:9133 "
+ "vote=http://128.31.0.42:9134/ "
+ "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 0);
+ tt_int_op(rv,OP_EQ,0);
+
+ rv = parse_dir_authority_line(
+ "morgoth orport=9101 "
+ "v3ident=D586D18309DED4CDFFFFFFFFDB97EFA96D330566 "
+ "upload=http://128.31.0.43:9140/ "
+ "128.31.0.44:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+ NO_DIRINFO, 0);
+ tt_int_op(rv,OP_EQ,0);
+
+ const smartlist_t *servers = router_get_trusted_dir_servers();
+ tt_assert(servers);
+ tt_int_op(smartlist_len(servers), OP_EQ, 2);
+ const dir_server_t *moria = smartlist_get(servers, 0);
+ const dir_server_t *morgoth = smartlist_get(servers, 1);
+ tt_str_op(moria->nickname, OP_EQ, "moria1");
+ tt_str_op(morgoth->nickname, OP_EQ, "morgoth");
+
+ const tor_addr_port_t *dirport;
+
+ dirport = trusted_dir_server_get_dirport(moria,
+ AUTH_USAGE_UPLOAD, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9132);
+ dirport = trusted_dir_server_get_dirport(moria,
+ AUTH_USAGE_DOWNLOAD, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9133);
+ dirport = trusted_dir_server_get_dirport(moria,
+ AUTH_USAGE_VOTING, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9134);
+
+ dirport = trusted_dir_server_get_dirport(morgoth,
+ AUTH_USAGE_UPLOAD, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9140);
+ dirport = trusted_dir_server_get_dirport(morgoth,
+ AUTH_USAGE_DOWNLOAD, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9131); // fallback
+ dirport = trusted_dir_server_get_dirport(morgoth,
+ AUTH_USAGE_VOTING, AF_INET);
+ tt_int_op(dirport->port, OP_EQ, 9131); // fallback
+
+ done:
+ ;
+}
+
+#define T(name) \
+ { #name, test_dirauth_port_ ## name, TT_FORK, NULL, NULL }
+
+struct testcase_t dirauth_port_tests[] = {
+ T(parsing),
+ T(lookup),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index c94b5d6a23..118b66dfa7 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -92,6 +92,12 @@ bfn_mock_node_get_by_id(const char *id)
return NULL;
}
+static int
+mock_router_have_minimum_dir_info(void)
+{
+ return 1;
+}
+
/* Helper function to free a test node. */
static void
test_node_free(node_t *n)
@@ -3087,6 +3093,38 @@ test_entry_guard_vanguard_path_selection(void *arg)
circuit_free_(circ);
}
+static void
+test_entry_guard_layer2_guards(void *arg)
+{
+ (void) arg;
+ MOCK(router_have_minimum_dir_info, mock_router_have_minimum_dir_info);
+
+ /* First check the enable/disable switch */
+ get_options_mutable()->VanguardsLiteEnabled = 0;
+ tt_int_op(vanguards_lite_is_enabled(), OP_EQ, 0);
+
+ get_options_mutable()->VanguardsLiteEnabled = 1;
+ tt_int_op(vanguards_lite_is_enabled(), OP_EQ, 1);
+
+ get_options_mutable()->VanguardsLiteEnabled = -1;
+ tt_int_op(vanguards_lite_is_enabled(), OP_EQ, 1);
+
+ /* OK now let's move to actual testing */
+
+ /* Remove restrictions to route around Big Fake Network restrictions */
+ get_options_mutable()->EnforceDistinctSubnets = 0;
+
+ /* Create the L2 guardset */
+ maintain_layer2_guards();
+
+ const routerset_t *l2_guards = get_layer2_guards();
+ tt_assert(l2_guards);
+ tt_int_op(routerset_len(l2_guards), OP_EQ, 4);
+
+ done:
+ UNMOCK(router_have_minimum_dir_info);
+}
+
static const struct testcase_setup_t big_fake_network = {
big_fake_network_setup, big_fake_network_cleanup
};
@@ -3152,6 +3190,8 @@ struct testcase_t entrynodes_tests[] = {
BFN_TEST(manage_primary),
BFN_TEST(correct_cascading_order),
+ BFN_TEST(layer2_guards),
+
EN_TEST_FORK(guard_preferred),
BFN_TEST(select_for_circuit_no_confirmed),
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index 7cb6a36f8e..347a5b7174 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -808,13 +808,11 @@ test_parse_extended_hostname(void *arg)
tt_assert(parse_extended_hostname(address4, &type));
tt_int_op(type, OP_EQ, NORMAL_HOSTNAME);
- tt_assert(parse_extended_hostname(address5, &type));
- tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
- tt_str_op(address5, OP_EQ, "abcdefghijklmnop");
+ tt_assert(!parse_extended_hostname(address5, &type));
+ tt_int_op(type, OP_EQ, BAD_HOSTNAME);
- tt_assert(parse_extended_hostname(address6, &type));
- tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME);
- tt_str_op(address6, OP_EQ, "abcdefghijklmnop");
+ tt_assert(!parse_extended_hostname(address6, &type));
+ tt_int_op(type, OP_EQ, BAD_HOSTNAME);
tt_assert(!parse_extended_hostname(address7, &type));
tt_int_op(type, OP_EQ, BAD_HOSTNAME);
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
index b036c5eada..c32803b380 100644
--- a/src/test/test_hs_control.c
+++ b/src/test/test_hs_control.c
@@ -798,7 +798,7 @@ test_hs_control_add_onion_helper_add_service(void *arg)
hs_service_ht *global_map;
hs_port_config_t *portcfg;
smartlist_t *portcfgs;
- char *address_out_good, *address_out_bad;
+ char *address_out_good = NULL, *address_out_bad = NULL;
hs_service_t *service_good = NULL;
hs_service_t *service_bad = NULL;
diff --git a/src/test/test_hs_ob.c b/src/test/test_hs_ob.c
index 3485655c2e..2f69bf31e0 100644
--- a/src/test/test_hs_ob.c
+++ b/src/test/test_hs_ob.c
@@ -174,6 +174,7 @@ test_get_subcredentials(void *arg)
hs_subcredential_t *subcreds = NULL;
(void) arg;
+ memset(&config, 0, sizeof(config));
MOCK(networkstatus_get_live_consensus,
mock_networkstatus_get_live_consensus);
diff --git a/src/test/test_ntor_v3.c b/src/test/test_ntor_v3.c
new file mode 100644
index 0000000000..096ac6668f
--- /dev/null
+++ b/src/test/test_ntor_v3.c
@@ -0,0 +1,172 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2021, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#define ONION_NTOR_V3_PRIVATE
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "core/crypto/onion_ntor_v3.h"
+
+#define unhex(arry, s) \
+ { tt_int_op(sizeof(arry), OP_EQ, \
+ base16_decode((char*)arry, sizeof(arry), s, strlen(s))); \
+ }
+
+static void
+test_ntor3_testvecs(void *arg)
+{
+ (void)arg;
+ char *mem_op_hex_tmp = NULL; // temp val to make test_memeq_hex work.
+
+ ntor3_server_handshake_state_t *relay_state = NULL;
+ uint8_t *onion_skin = NULL;
+ size_t onion_skin_len;
+ ntor3_handshake_state_t *client_state = NULL;
+ uint8_t *cm = NULL, *sm = NULL;
+ size_t cm_len, sm_len;
+ di_digest256_map_t *private_keys = NULL;
+ uint8_t *server_handshake = NULL;
+ size_t server_handshake_len;
+
+ // Test vectors from python implementation, confirmed with rust
+ // implementation.
+ curve25519_keypair_t relay_keypair_b;
+ curve25519_keypair_t client_keypair_x;
+ curve25519_keypair_t relay_keypair_y;
+ ed25519_public_key_t relay_id;
+
+ unhex(relay_keypair_b.seckey.secret_key,
+ "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
+ unhex(relay_keypair_b.pubkey.public_key,
+ "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
+ unhex(relay_id.pubkey,
+ "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
+ unhex(client_keypair_x.seckey.secret_key,
+ "b825a3719147bcbe5fb1d0b0fcb9c09e51948048e2e3283d2ab7b45b5ef38b49");
+ unhex(client_keypair_x.pubkey.public_key,
+ "252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995184f7d11d5da4f46");
+ unhex(relay_keypair_y.seckey.secret_key,
+ "4865a5b7689dafd978f529291c7171bc159be076b92186405d13220b80e2a053");
+ unhex(relay_keypair_y.pubkey.public_key,
+ "4bf4814326fdab45ad5184f5518bd7fae25dc59374062698201a50a22954246d");
+
+ uint8_t client_message[11];
+ uint8_t verification[5];
+ unhex(client_message, "68656c6c6f20776f726c64");
+ unhex(verification, "78797a7a79");
+
+ // ========= Client handshake 1.
+
+ onion_skin_ntor3_create_nokeygen(
+ &client_keypair_x,
+ &relay_id,
+ &relay_keypair_b.pubkey,
+ verification,
+ sizeof(verification),
+ client_message,
+ sizeof(client_message),
+ &client_state,
+ &onion_skin,
+ &onion_skin_len);
+
+ const char expect_client_handshake[] = "9fad2af287ef942632833d21f946c6260c"
+ "33fae6172b60006e86e4a6911753a2f8307a2bc1870b00b828bb74dbb8fd88e632a6375"
+ "ab3bcd1ae706aaa8b6cdd1d252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995"
+ "184f7d11d5da4f463bebd9151fd3b47c180abc9e044d53565f04d82bbb3bebed3d06cea"
+ "65db8be9c72b68cd461942088502f67";
+
+ tt_int_op(onion_skin_len, OP_EQ, strlen(expect_client_handshake)/2);
+ test_memeq_hex(onion_skin, expect_client_handshake);
+
+ // ========= Relay handshake.
+
+ dimap_add_entry(&private_keys,
+ relay_keypair_b.pubkey.public_key,
+ &relay_keypair_b);
+
+ int r = onion_skin_ntor3_server_handshake_part1(
+ private_keys,
+ &client_keypair_x,
+ &relay_id,
+ onion_skin,
+ onion_skin_len,
+ verification,
+ sizeof(verification),
+ &cm,
+ &cm_len,
+ &relay_state);
+ tt_int_op(r, OP_EQ, 0);
+ tt_int_op(cm_len, OP_EQ, sizeof(client_message));
+ tt_mem_op(cm, OP_EQ, client_message, cm_len);
+
+ uint8_t server_message[10];
+ unhex(server_message, "486f6c61204d756e646f");
+
+ uint8_t server_keys[256];
+ onion_skin_ntor3_server_handshake_part2_nokeygen(
+ &relay_keypair_y,
+ relay_state,
+ verification,
+ sizeof(verification),
+ server_message,
+ sizeof(server_message),
+ &server_handshake,
+ &server_handshake_len,
+ server_keys,
+ sizeof(server_keys));
+
+ const char expect_server_handshake[] = "4bf4814326fdab45ad5184f5518bd7fae25"
+ "dc59374062698201a50a22954246d2fc5f8773ca824542bc6cf6f57c7c29bbf4e5476461"
+ "ab130c5b18ab0a91276651202c3e1e87c0d32054c";
+ tt_int_op(server_handshake_len, OP_EQ, strlen(expect_server_handshake)/2);
+ test_memeq_hex(server_handshake, expect_server_handshake);
+
+ uint8_t expect_keys[256];
+ unhex(expect_keys, "9c19b631fd94ed86a817e01f6c80b0743a43f5faebd39cfaa8b00f"
+ "a8bcc65c3bfeaa403d91acbd68a821bf6ee8504602b094a254392a07737d5662768"
+ "c7a9fb1b2814bb34780eaee6e867c773e28c212ead563e98a1cd5d5b4576f5ee61c"
+ "59bde025ff2851bb19b721421694f263818e3531e43a9e4e3e2c661e2ad547d8984"
+ "caa28ebecd3e4525452299be26b9185a20a90ce1eac20a91f2832d731b54502b097"
+ "49b5a2a2949292f8cfcbeffb790c7790ed935a9d251e7e336148ea83b063a5618fc"
+ "ff674a44581585fd22077ca0e52c59a24347a38d1a1ceebddbf238541f226b8f88d"
+ "0fb9c07a1bcd2ea764bbbb5dacdaf5312a14c0b9e4f06309b0333b4a");
+ tt_mem_op(server_keys, OP_EQ, expect_keys, 256);
+
+ // ===== Client handshake 2
+
+ uint8_t client_keys[256];
+ r = onion_ntor3_client_handshake(
+ client_state,
+ server_handshake,
+ server_handshake_len,
+ verification,
+ sizeof(verification),
+ client_keys,
+ sizeof(client_keys),
+ &sm,
+ &sm_len);
+
+ tt_int_op(r, OP_EQ, 0);
+ tt_int_op(sm_len, OP_EQ, sizeof(server_message));
+ tt_mem_op(sm, OP_EQ, server_message, sizeof(server_message));
+ tt_mem_op(client_keys, OP_EQ, server_keys, 256);
+
+ done:
+ tor_free(onion_skin);
+ tor_free(server_handshake);
+ tor_free(mem_op_hex_tmp);
+ ntor3_handshake_state_free(client_state);
+ ntor3_server_handshake_state_free(relay_state);
+ tor_free(cm);
+ tor_free(sm);
+ dimap_free(private_keys, NULL);
+}
+
+struct testcase_t ntor_v3_tests[] = {
+ { "testvecs", test_ntor3_testvecs, 0, NULL, NULL, },
+ END_OF_TESTCASES,
+};
diff --git a/src/test/test_process_descs.c b/src/test/test_process_descs.c
index fa2657f6c2..5503fc69ee 100644
--- a/src/test/test_process_descs.c
+++ b/src/test/test_process_descs.c
@@ -39,12 +39,20 @@ test_process_descs_versions(void *arg)
{ "Tor 0.4.1.1-alpha", true },
{ "Tor 0.4.1.4-rc", true },
{ "Tor 0.4.1.5", true },
+ { "Tor 0.4.2.1-alpha", true },
+ { "Tor 0.4.2.4-rc", true },
+ { "Tor 0.4.2.5", true },
+ { "Tor 0.4.3.0-alpha-dev", true },
+ { "Tor 0.4.3.8", true },
+ { "Tor 0.4.4.9", true },
+ { "Tor 0.4.5.5-rc", true },
// new enough to be supported
{ "Tor 0.3.5.7", false },
{ "Tor 0.3.5.8", false },
- { "Tor 0.4.2.1-alpha", false },
- { "Tor 0.4.2.4-rc", false },
- { "Tor 0.4.3.0-alpha-dev", false },
+ { "Tor 0.4.5.6", false },
+ { "Tor 0.4.6.0-alpha-dev", false },
+ { "Tor 0.4.6.5", false },
+ { "Tor 0.4.7.0-alpha-dev", false },
// Very far in the future
{ "Tor 100.100.1.5", false },
};
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index 4b25a86e26..8cc3bcf0e5 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -23,13 +23,6 @@ static void
test_protover_parse(void *arg)
{
(void) arg;
-#ifdef HAVE_RUST
- /** This test is disabled on rust builds, because it only exists to test
- * internal C functions. */
- tt_skip();
- done:
- ;
-#else /* !defined(HAVE_RUST) */
char *re_encoded = NULL;
const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16";
@@ -64,18 +57,12 @@ test_protover_parse(void *arg)
SMARTLIST_FOREACH(elts, proto_entry_t *, ent, proto_entry_free(ent));
smartlist_free(elts);
tor_free(re_encoded);
-#endif /* defined(HAVE_RUST) */
}
static void
test_protover_parse_fail(void *arg)
{
(void)arg;
-#ifdef HAVE_RUST
- /** This test is disabled on rust builds, because it only exists to test
- * internal C functions. */
- tt_skip();
-#else
smartlist_t *elts;
/* random junk */
@@ -108,7 +95,6 @@ test_protover_parse_fail(void *arg)
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
tt_ptr_op(elts, OP_EQ, NULL);
-#endif /* defined(HAVE_RUST) */
done:
;
}
@@ -265,7 +251,7 @@ test_protover_all_supported(void *arg)
#endif /* !defined(ALL_BUGS_ARE_FATAL) */
/* Protocol name too long */
-#if !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL)
+#if !defined(ALL_BUGS_ARE_FATAL)
tor_capture_bugs_(1);
tt_assert(protover_all_supported(
"DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -273,7 +259,7 @@ test_protover_all_supported(void *arg)
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaa=1-65536", &msg));
tor_end_capture_bugs_();
-#endif /* !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL) */
+#endif /* !defined(ALL_BUGS_ARE_FATAL) */
done:
tor_end_capture_bugs_();
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 27e74d5ebf..07c5032933 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -233,6 +233,10 @@ test_pt_protocol(void *arg)
handle_proxy_line(line, mp);
tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+ strlcpy(line,"CMETHOD-ERROR fakename not supported",sizeof(line));
+ handle_proxy_line(line, mp);
+ tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);
+
strlcpy(line,"CMETHODS DONE",sizeof(line));
handle_proxy_line(line, mp);
tt_assert(mp->conf_state == PT_PROTO_CONFIGURED);
diff --git a/src/test/test_rust.sh b/src/test/test_rust.sh
deleted file mode 100755
index 804d2ada36..0000000000
--- a/src/test/test_rust.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-# Test all Rust crates
-
-set -e
-
-export LSAN_OPTIONS=suppressions=${abs_top_srcdir:-../../..}/src/test/rust_supp.txt
-
-# When testing Cargo we pass a number of very specific linker flags down
-# through Cargo. We do not, however, want these flags to affect things like
-# build scripts, only the tests that we're compiling. To ensure this happens
-# we unconditionally pass `--target` into Cargo, ensuring that `RUSTFLAGS` in
-# the environment won't make their way into build scripts.
-rustc_host=$(rustc -vV | grep host | sed 's/host: //')
-
-for cargo_toml_dir in "${abs_top_srcdir:-../../..}"/src/rust/*; do
- if [ -e "${cargo_toml_dir}/Cargo.toml" ]; then
- # shellcheck disable=SC2086
- cd "${abs_top_builddir:-../../..}/src/rust" && \
- CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
- "${CARGO:-cargo}" test "${CARGO_ONLINE-'--frozen'}" \
- --features "test_linking_hack" \
- --target "$rustc_host" \
- ${EXTRA_CARGO_OPTIONS} \
- --manifest-path "${cargo_toml_dir}/Cargo.toml" || exitcode=1
- fi
-done
-
-exit $exitcode
diff --git a/src/test/test_sandbox.c b/src/test/test_sandbox.c
new file mode 100644
index 0000000000..7ec08a3546
--- /dev/null
+++ b/src/test/test_sandbox.c
@@ -0,0 +1,349 @@
+/* Copyright (c) 2021, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef _LARGEFILE64_SOURCE
+/**
+ * Temporarily required for O_LARGEFILE flag. Needs to be removed
+ * with the libevent fix.
+ */
+#define _LARGEFILE64_SOURCE
+#endif /* !defined(_LARGEFILE64_SOURCE) */
+
+#include "orconfig.h"
+
+#include "lib/sandbox/sandbox.h"
+
+#ifdef USE_LIBSECCOMP
+
+#include <dirent.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "core/or/or.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+typedef struct {
+ sandbox_cfg_t *cfg;
+
+ char *file_ops_allowed;
+ char *file_ops_blocked;
+
+ char *file_rename_target_allowed;
+
+ char *dir_ops_allowed;
+ char *dir_ops_blocked;
+} sandbox_data_t;
+
+/* All tests are skipped when coverage support is enabled (see further below)
+ * as the sandbox interferes with the use of gcov. Prevent a compiler warning
+ * by omitting these definitions in that case. */
+#ifndef ENABLE_COVERAGE
+static void *
+setup_sandbox(const struct testcase_t *testcase)
+{
+ sandbox_data_t *data = tor_malloc_zero(sizeof(*data));
+
+ (void)testcase;
+
+ /* Establish common file and directory names within the test suite's
+ * temporary directory. */
+ data->file_ops_allowed = tor_strdup(get_fname("file_ops_allowed"));
+ data->file_ops_blocked = tor_strdup(get_fname("file_ops_blocked"));
+
+ data->file_rename_target_allowed =
+ tor_strdup(get_fname("file_rename_target_allowed"));
+
+ data->dir_ops_allowed = tor_strdup(get_fname("dir_ops_allowed"));
+ data->dir_ops_blocked = tor_strdup(get_fname("dir_ops_blocked"));
+
+ /* Create the corresponding filesystem objects. */
+ creat(data->file_ops_allowed, S_IRWXU);
+ creat(data->file_ops_blocked, S_IRWXU);
+ mkdir(data->dir_ops_allowed, S_IRWXU);
+ mkdir(data->dir_ops_blocked, S_IRWXU);
+
+ /* Create the sandbox configuration. */
+ data->cfg = sandbox_cfg_new();
+
+ sandbox_cfg_allow_open_filename(&data->cfg,
+ tor_strdup(data->file_ops_allowed));
+ sandbox_cfg_allow_open_filename(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+
+ sandbox_cfg_allow_chmod_filename(&data->cfg,
+ tor_strdup(data->file_ops_allowed));
+ sandbox_cfg_allow_chmod_filename(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+ sandbox_cfg_allow_chown_filename(&data->cfg,
+ tor_strdup(data->file_ops_allowed));
+ sandbox_cfg_allow_chown_filename(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+
+ sandbox_cfg_allow_rename(&data->cfg, tor_strdup(data->file_ops_allowed),
+ tor_strdup(data->file_rename_target_allowed));
+
+ sandbox_cfg_allow_openat_filename(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+
+ sandbox_cfg_allow_opendir_dirname(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+
+ sandbox_cfg_allow_stat_filename(&data->cfg,
+ tor_strdup(data->file_ops_allowed));
+ sandbox_cfg_allow_stat_filename(&data->cfg,
+ tor_strdup(data->dir_ops_allowed));
+
+ /* Activate the sandbox, which will remain in effect until the process
+ * terminates. */
+ sandbox_init(data->cfg);
+
+ return data;
+}
+
+static int
+cleanup_sandbox(const struct testcase_t *testcase, void *data_)
+{
+ sandbox_data_t *data = data_;
+
+ (void)testcase;
+
+ tor_free(data->dir_ops_blocked);
+ tor_free(data->dir_ops_allowed);
+ tor_free(data->file_rename_target_allowed);
+ tor_free(data->file_ops_blocked);
+ tor_free(data->file_ops_allowed);
+
+ tor_free(data);
+
+ return 1;
+}
+
+static const struct testcase_setup_t sandboxed_testcase_setup = {
+ .setup_fn = setup_sandbox,
+ .cleanup_fn = cleanup_sandbox
+};
+#endif /* !defined(ENABLE_COVERAGE) */
+
+static void
+test_sandbox_is_active(void *ignored)
+{
+ (void)ignored;
+
+ tt_assert(!sandbox_is_active());
+
+ sandbox_init(sandbox_cfg_new());
+ tt_assert(sandbox_is_active());
+
+ done:
+ (void)0;
+}
+
+static void
+test_sandbox_open_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ int fd, errsv;
+
+ fd = open(sandbox_intern_string(data->file_ops_allowed), O_RDONLY);
+ if (fd == -1)
+ tt_abort_perror("open");
+ close(fd);
+
+ /* It might be nice to use sandbox_intern_string() in the line below as well
+ * (and likewise in the test cases that follow) but this would require
+ * capturing the warning message it logs, and the mechanism for doing so
+ * relies on system calls that are normally blocked by the sandbox and may
+ * vary across architectures. */
+ fd = open(data->file_ops_blocked, O_RDONLY);
+ errsv = errno;
+ tt_int_op(fd, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ if (fd >= 0)
+ close(fd);
+}
+
+static void
+test_sandbox_chmod_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ int rc, errsv;
+
+ if (chmod(sandbox_intern_string(data->file_ops_allowed),
+ S_IRUSR | S_IWUSR) != 0)
+ tt_abort_perror("chmod");
+
+ rc = chmod(data->file_ops_blocked, S_IRUSR | S_IWUSR);
+ errsv = errno;
+ tt_int_op(rc, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ (void)0;
+}
+
+static void
+test_sandbox_chown_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ int rc, errsv;
+
+ if (chown(sandbox_intern_string(data->file_ops_allowed), -1, -1) != 0)
+ tt_abort_perror("chown");
+
+ rc = chown(data->file_ops_blocked, -1, -1);
+ errsv = errno;
+ tt_int_op(rc, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ (void)0;
+}
+
+static void
+test_sandbox_rename_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ const char *fname_old = sandbox_intern_string(data->file_ops_allowed),
+ *fname_new = sandbox_intern_string(data->file_rename_target_allowed);
+ int rc, errsv;
+
+ if (rename(fname_old, fname_new) != 0)
+ tt_abort_perror("rename");
+
+ rc = rename(fname_new, fname_old);
+ errsv = errno;
+ tt_int_op(rc, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ (void)0;
+}
+
+static void
+test_sandbox_openat_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ int flags = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY | O_CLOEXEC;
+ int fd, errsv;
+
+ fd = openat(AT_FDCWD, sandbox_intern_string(data->dir_ops_allowed), flags);
+ if (fd < 0)
+ tt_abort_perror("openat");
+ close(fd);
+
+ fd = openat(AT_FDCWD, data->dir_ops_blocked, flags);
+ errsv = errno;
+ tt_int_op(fd, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ if (fd >= 0)
+ close(fd);
+}
+
+static void
+test_sandbox_opendir_dirname(void *arg)
+{
+ sandbox_data_t *data = arg;
+ DIR *dir;
+ int errsv;
+
+ dir = opendir(sandbox_intern_string(data->dir_ops_allowed));
+ if (dir == NULL)
+ tt_abort_perror("opendir");
+ closedir(dir);
+
+ dir = opendir(data->dir_ops_blocked);
+ errsv = errno;
+ tt_ptr_op(dir, OP_EQ, NULL);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ if (dir)
+ closedir(dir);
+}
+
+static void
+test_sandbox_stat_filename(void *arg)
+{
+ sandbox_data_t *data = arg;
+ struct stat st;
+
+ if (stat(sandbox_intern_string(data->file_ops_allowed), &st) != 0)
+ tt_abort_perror("stat");
+
+ int rc = stat(data->file_ops_blocked, &st);
+ int errsv = errno;
+ tt_int_op(rc, OP_EQ, -1);
+ tt_int_op(errsv, OP_EQ, EPERM);
+
+ done:
+ (void)0;
+}
+
+#define SANDBOX_TEST_SKIPPED(name) \
+ { #name, test_sandbox_ ## name, TT_SKIP, NULL, NULL }
+
+/* Skip all tests when coverage support is enabled, as the sandbox interferes
+ * with gcov and prevents it from producing any results. */
+#ifdef ENABLE_COVERAGE
+#define SANDBOX_TEST(name, flags) SANDBOX_TEST_SKIPPED(name)
+#define SANDBOX_TEST_IN_SANDBOX(name) SANDBOX_TEST_SKIPPED(name)
+#else
+#define SANDBOX_TEST(name, flags) \
+ { #name, test_sandbox_ ## name, flags, NULL, NULL }
+#define SANDBOX_TEST_IN_SANDBOX(name) \
+ { #name, test_sandbox_ ## name, TT_FORK, &sandboxed_testcase_setup, NULL }
+#endif /* defined(ENABLE_COVERAGE) */
+
+struct testcase_t sandbox_tests[] = {
+ SANDBOX_TEST(is_active, TT_FORK),
+
+/* When Tor is built with fragile compiler-hardening the sandbox is unable to
+ * filter requests to open files or directories (on systems where glibc uses
+ * the "open" system call to provide this functionality), as doing so would
+ * interfere with the address sanitizer as it retrieves information about the
+ * running process via the filesystem. Skip these tests in that case as the
+ * corresponding functions are likely to have no effect and this will cause the
+ * tests to fail. */
+#ifdef ENABLE_FRAGILE_HARDENING
+ SANDBOX_TEST_SKIPPED(open_filename),
+ SANDBOX_TEST_SKIPPED(opendir_dirname),
+#else
+ SANDBOX_TEST_IN_SANDBOX(open_filename),
+ SANDBOX_TEST_IN_SANDBOX(opendir_dirname),
+#endif /* defined(ENABLE_FRAGILE_HARDENING) */
+
+ SANDBOX_TEST_IN_SANDBOX(openat_filename),
+ SANDBOX_TEST_IN_SANDBOX(chmod_filename),
+ SANDBOX_TEST_IN_SANDBOX(chown_filename),
+ SANDBOX_TEST_IN_SANDBOX(rename_filename),
+
+/* Currently the sandbox is unable to filter stat() calls on systems where
+ * glibc implements this function using either of the legacy "stat" or "stat64"
+ * system calls, or (in glibc version 2.33 and later) either of the newer
+ * "newfstatat" or "statx" syscalls.
+ *
+ * Skip testing sandbox_cfg_allow_stat_filename() if it seems the likely the
+ * function will have no effect and the test will therefore not succeed. */
+#if !defined(__NR_stat) && !defined(__NR_stat64) && !defined(__NR_newfstatat) \
+ && !(defined(__i386__) && defined(__NR_statx))
+ SANDBOX_TEST_IN_SANDBOX(stat_filename),
+#else
+ SANDBOX_TEST_SKIPPED(stat_filename),
+#endif
+ END_OF_TESTCASES
+};
+
+#endif /* defined(USE_SECCOMP) */
diff --git a/src/test/test_stats.c b/src/test/test_stats.c
index af035ae54c..c7e0c10845 100644
--- a/src/test/test_stats.c
+++ b/src/test/test_stats.c
@@ -51,7 +51,7 @@
#include "feature/stats/bw_array_st.h"
#include "feature/relay/router.h"
-#include "event2/dns.h"
+#include <event2/dns.h>
/** Run unit tests for some stats code. */
static void
@@ -721,7 +721,7 @@ test_overload_stats(void *arg)
stats_str = rep_hist_get_overload_stats_lines();
tt_assert(!stats_str);
- /* Note a overload */
+ /* Note an overload */
rep_hist_note_overload(OVERLOAD_GENERAL);
/* Move the time forward one hour */
@@ -742,7 +742,7 @@ test_overload_stats(void *arg)
/* Now the time should be 2002-01-07 00:00:00 */
- /* Note a overload */
+ /* Note an overload */
rep_hist_note_overload(OVERLOAD_GENERAL);
stats_str = rep_hist_get_overload_general_line();
diff --git a/src/test/test_voting_flags.c b/src/test/test_voting_flags.c
index 4c5f3a3270..457b0fa796 100644
--- a/src/test/test_voting_flags.c
+++ b/src/test/test_voting_flags.c
@@ -62,7 +62,8 @@ check_result(flag_vote_test_cfg_t *c)
bool result = false;
routerstatus_t rs;
memset(&rs, 0, sizeof(rs));
- dirauth_set_routerstatus_from_routerinfo(&rs, &c->node, &c->ri, c->now, 0);
+ dirauth_set_routerstatus_from_routerinfo(&rs, &c->node, &c->ri, c->now,
+ 0, 0);
tt_i64_op(rs.published_on, OP_EQ, c->expected.published_on);
tt_str_op(rs.nickname, OP_EQ, c->expected.nickname);