diff options
Diffstat (limited to 'src/test')
195 files changed, 2964 insertions, 4329 deletions
diff --git a/src/test/bench.c b/src/test/bench.c index 7a8c04e802..a76ea67eb8 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py index dcc0a7c25a..abc9a1de7f 100644 --- a/src/test/ed25519_exts_ref.py +++ b/src/test/ed25519_exts_ref.py @@ -42,7 +42,7 @@ def blindESK(esk, param): s_prime = (s * mult) % ell k = esk[32:] assert(len(k) == 32) - k_prime = H("Derive temporary signing key hash input" + k)[:32] + k_prime = H(b"Derive temporary signing key hash input" + k)[:32] return encodeint(s_prime) + k_prime def blindPK(pk, param): @@ -170,6 +170,8 @@ RAND_INPUTS = [ '5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433', 'eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86', '4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d', + 'c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b', + 'c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b', 'c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b'] # From pprint.pprint([ binascii.b2a_hex(os.urandom(32)) for _ in xrange(8) ]) @@ -181,7 +183,9 @@ BLINDING_PARAMS = [ 'b1fe79d1dec9bc108df69f6612c72812755751f21ecc5af99663b30be8b9081f', '81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084', '97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818', - '3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0'] + '3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0', + '0000000000000000000000000000000000000000000000000000000000000000', + '1111111111111111111111111111111111111111111111111111111111111111'] PREFIX = "ED25519_" @@ -193,9 +197,9 @@ def writeArray(name, array): if len(h) > 70: h1 = h[:70] h2 = h[70:] - print(' "{0}"\n "{1}",'.format(h1,h2)) + print(' "{0}"\n "{1}",'.format(h1.decode('utf-8'),h2.decode('utf-8'))) else: - print(' "{0}",'.format(h)) + print(' "{0}",'.format(h.decode('utf-8'))) print("};\n") def comment(text, initial="/**"): diff --git a/src/test/ed25519_vectors.inc b/src/test/ed25519_vectors.inc index 60c863beba..3813282e00 100644 --- a/src/test/ed25519_vectors.inc +++ b/src/test/ed25519_vectors.inc @@ -16,6 +16,8 @@ static const char *ED25519_SECRET_KEYS[] = { "eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86", "4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d", "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b", + "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b", + "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b", }; /** @@ -39,6 +41,10 @@ static const char *ED25519_EXPANDED_SECRET_KEYS[] = { "e5fd7ac43794394507ad440ecfdf59c4c255f19b768a273109e06d7d8e", "b003077c1e52a62308eef7950b2d532e1d4a7eea50ad22d8ac11b892851f1c40ffb9c9" "ff8dcd0c6c233f665a2e176324d92416bfcfcd1f787424c0c667452d86", + "b003077c1e52a62308eef7950b2d532e1d4a7eea50ad22d8ac11b892851f1c40ffb9c9" + "ff8dcd0c6c233f665a2e176324d92416bfcfcd1f787424c0c667452d86", + "b003077c1e52a62308eef7950b2d532e1d4a7eea50ad22d8ac11b892851f1c40ffb9c9" + "ff8dcd0c6c233f665a2e176324d92416bfcfcd1f787424c0c667452d86", }; /** @@ -53,6 +59,8 @@ static const char *ED25519_PUBLIC_KEYS[] = { "d21c294db0e64cb2d8976625786ede1d9754186ae8197a64d72f68c792eecc19", "c4d58b4cf85a348ff3d410dd936fa460c4f18da962c01b1963792b9dcc8a6ea6", "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a", + "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a", + "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a", }; /** @@ -69,6 +77,8 @@ static const char *ED25519_CURVE25519_PUBLIC_KEYS[] = { "59e20dcb691c4a345fe86c8a79ac817e5b514d84bbf0512a842a08e43f7f087e", "9e43b820b320eda35f66f122c155b2bf8e2192c468617b7115bf067d19e08369", "861f33296cb57f8f01e4a5e8a7e5d5d7043a6247586ab36dea8a1a3c4403ee30", + "861f33296cb57f8f01e4a5e8a7e5d5d7043a6247586ab36dea8a1a3c4403ee30", + "861f33296cb57f8f01e4a5e8a7e5d5d7043a6247586ab36dea8a1a3c4403ee30", }; /** @@ -83,6 +93,8 @@ static const char *ED25519_BLINDING_PARAMS[] = { "81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084", "97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818", "3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0", + "0000000000000000000000000000000000000000000000000000000000000000", + "1111111111111111111111111111111111111111111111111111111111111111", }; /** @@ -107,6 +119,10 @@ static const char *ED25519_BLINDED_SECRET_KEYS[] = { "8f8e556d78f4bdcb9a13b6f6066fe81d3134ae965dc48cd0785b3af2b8", "288cbfd923cb286d48c084555b5bdd06c05e92fb81acdb45271367f57515380e053d9c" "00c81e1331c06ab50087be8cfc7dc11691b132614474f1aa9c2503cccd", + "e5cd03eb4cc456e11bc36724b558873df0045729b22d8b748360067a7770ac02053d9c" + "00c81e1331c06ab50087be8cfc7dc11691b132614474f1aa9c2503cccd", + "2cf7ed8b163f5af960d2fc62e1883aa422a6090736b4f18a5456ddcaf78ede0c053d9c" + "00c81e1331c06ab50087be8cfc7dc11691b132614474f1aa9c2503cccd", }; /** @@ -123,6 +139,8 @@ static const char *ED25519_BLINDED_PUBLIC_KEYS[] = { "2b946a484344eb1c17c89dd8b04196a84f3b7222c876a07a4cece85f676f87d9", "c6b585129b135f8769df2eba987e76e089e80ba3a2a6729134d3b28008ac098e", "0eefdc795b59cabbc194c6174e34ba9451e8355108520554ec285acabebb34ac", + "312404d06a0a9de489904b18d5233e83a50b225977fa8734f2c897a73c067952", + "952a908a4a9e0e5176a2549f8f328955aca6817a9fdc59e3acec5dec50838108", }; /** @@ -146,5 +164,9 @@ static const char *ED25519_SELF_SIGNATURES[] = { "4867daa60f2a82d09ba9652d41e8dde292b624afc8d2c26441b95e3c0e", "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0" "afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d", + "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0" + "afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d", + "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0" + "afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d", }; diff --git a/src/test/fakechans.h b/src/test/fakechans.h index c3accb1637..e84e0233f6 100644 --- a/src/test/fakechans.h +++ b/src/test/fakechans.h @@ -1,4 +1,4 @@ - /* Copyright (c) 2014-2020, The Tor Project, Inc. */ + /* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_FAKECHANS_H diff --git a/src/test/fakecircs.c b/src/test/fakecircs.c index 4d5b97197e..cca3b43483 100644 --- a/src/test/fakecircs.c +++ b/src/test/fakecircs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2020, The Tor Project, Inc. */ +/* Copyright (c) 2019-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/fakecircs.h b/src/test/fakecircs.h index ed8a150a3f..61359e9bab 100644 --- a/src/test/fakecircs.h +++ b/src/test/fakecircs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2020, The Tor Project, Inc. */ +/* Copyright (c) 2019-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** 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_consensus.c b/src/test/fuzz/fuzz_consensus.c index f2bf29ea78..bf5a2b69e3 100644 --- a/src/test/fuzz/fuzz_consensus.c +++ b/src/test/fuzz/fuzz_consensus.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define SIGCOMMON_PRIVATE #include "core/or/or.h" diff --git a/src/test/fuzz/fuzz_descriptor.c b/src/test/fuzz/fuzz_descriptor.c index eb4d4d507f..db1e921995 100644 --- a/src/test/fuzz/fuzz_descriptor.c +++ b/src/test/fuzz/fuzz_descriptor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define SIGCOMMON_PRIVATE #include "core/or/or.h" diff --git a/src/test/fuzz/fuzz_diff.c b/src/test/fuzz/fuzz_diff.c index 9cd2116245..9b9b1c706f 100644 --- a/src/test/fuzz/fuzz_diff.c +++ b/src/test/fuzz/fuzz_diff.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONSDIFF_PRIVATE diff --git a/src/test/fuzz/fuzz_diff_apply.c b/src/test/fuzz/fuzz_diff_apply.c index a819c73338..f145bd2625 100644 --- a/src/test/fuzz/fuzz_diff_apply.c +++ b/src/test/fuzz/fuzz_diff_apply.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONSDIFF_PRIVATE diff --git a/src/test/fuzz/fuzz_extrainfo.c b/src/test/fuzz/fuzz_extrainfo.c index ad21254e3e..0cdc3d7ebf 100644 --- a/src/test/fuzz/fuzz_extrainfo.c +++ b/src/test/fuzz/fuzz_extrainfo.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define SIGCOMMON_PRIVATE #include "core/or/or.h" diff --git a/src/test/fuzz/fuzz_hsdescv2.c b/src/test/fuzz/fuzz_hsdescv2.c deleted file mode 100644 index 81d9e5f00e..0000000000 --- a/src/test/fuzz/fuzz_hsdescv2.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ -#include "core/or/or.h" -#include "feature/dirparse/unparseable.h" -#include "feature/rend/rendcommon.h" -#include "feature/rend/rendparse.h" -#include "lib/crypt_ops/crypto_ed25519.h" -#include "test/fuzz/fuzzing.h" - -static void -mock_dump_desc__nodump(const char *desc, const char *type) -{ - (void)desc; - (void)type; -} - -int -fuzz_init(void) -{ - disable_signature_checking(); - MOCK(dump_desc, mock_dump_desc__nodump); - ed25519_init(); - return 0; -} - -int -fuzz_cleanup(void) -{ - return 0; -} - -int -fuzz_main(const uint8_t *data, size_t sz) -{ - rend_service_descriptor_t *desc = NULL; - char desc_id[64]; - char *ipts = NULL; - size_t ipts_size, esize; - const char *next; - char *str = tor_memdup_nulterm(data, sz); - (void) rend_parse_v2_service_descriptor(&desc, desc_id, &ipts, &ipts_size, - &esize, &next, str, 1); - if (desc) { - log_debug(LD_GENERAL, "Parsing okay"); - rend_service_descriptor_free(desc); - } else { - log_debug(LD_GENERAL, "Parsing failed"); - } - tor_free(ipts); - tor_free(str); - return 0; -} diff --git a/src/test/fuzz/fuzz_hsdescv3.c b/src/test/fuzz/fuzz_hsdescv3.c index 8d7eab1a8d..73e509469a 100644 --- a/src/test/fuzz/fuzz_hsdescv3.c +++ b/src/test/fuzz/fuzz_hsdescv3.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define HS_DESCRIPTOR_PRIVATE 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/fuzz_http.c b/src/test/fuzz/fuzz_http.c index a4fd182f1e..cf5e995ef3 100644 --- a/src/test/fuzz/fuzz_http.c +++ b/src/test/fuzz/fuzz_http.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/fuzz/fuzz_http_connect.c b/src/test/fuzz/fuzz_http_connect.c index 9e5a48ba4d..c71ccb5c1e 100644 --- a/src/test/fuzz/fuzz_http_connect.c +++ b/src/test/fuzz/fuzz_http_connect.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/fuzz/fuzz_iptsv2.c b/src/test/fuzz/fuzz_iptsv2.c index bc51ffcdb8..259be437f0 100644 --- a/src/test/fuzz/fuzz_iptsv2.c +++ b/src/test/fuzz/fuzz_iptsv2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/fuzz/fuzz_microdesc.c b/src/test/fuzz/fuzz_microdesc.c index 3fc709183b..d77f137b2b 100644 --- a/src/test/fuzz/fuzz_microdesc.c +++ b/src/test/fuzz/fuzz_microdesc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/fuzz/fuzz_socks.c b/src/test/fuzz/fuzz_socks.c index 4e7cb4d48d..eeb989994d 100644 --- a/src/test/fuzz/fuzz_socks.c +++ b/src/test/fuzz/fuzz_socks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/fuzz/fuzz_strops.c b/src/test/fuzz/fuzz_strops.c index 05d9101e72..02a74d1d8c 100644 --- a/src/test/fuzz/fuzz_strops.c +++ b/src/test/fuzz/fuzz_strops.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/fuzz/fuzz_vrs.c b/src/test/fuzz/fuzz_vrs.c index d6e88e59e7..e1bb28801a 100644 --- a/src/test/fuzz/fuzz_vrs.c +++ b/src/test/fuzz/fuzz_vrs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define NS_PARSE_PRIVATE #define NETWORKSTATUS_PRIVATE diff --git a/src/test/fuzz/fuzzing.h b/src/test/fuzz/fuzzing.h index 6cbcdc41ad..b9bec84ce4 100644 --- a/src/test/fuzz/fuzzing.h +++ b/src/test/fuzz/fuzzing.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef FUZZING_H #define FUZZING_H diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c index d9719074ad..d64d20e0ba 100644 --- a/src/test/fuzz/fuzzing_common.c +++ b/src/test/fuzz/fuzzing_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CRYPTO_ED25519_PRIVATE #define CONFIG_PRIVATE diff --git a/src/test/fuzz/include.am b/src/test/fuzz/include.am index ef952c3812..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 @@ -84,16 +102,6 @@ src_test_fuzz_fuzz_extrainfo_LDADD = $(FUZZING_LIBS) endif if UNITTESTS_ENABLED -src_test_fuzz_fuzz_hsdescv2_SOURCES = \ - src/test/fuzz/fuzzing_common.c \ - src/test/fuzz/fuzz_hsdescv2.c -src_test_fuzz_fuzz_hsdescv2_CPPFLAGS = $(FUZZING_CPPFLAGS) -src_test_fuzz_fuzz_hsdescv2_CFLAGS = $(FUZZING_CFLAGS) -src_test_fuzz_fuzz_hsdescv2_LDFLAGS = $(FUZZING_LDFLAG) -src_test_fuzz_fuzz_hsdescv2_LDADD = $(FUZZING_LIBS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_fuzz_hsdescv3_SOURCES = \ src/test/fuzz/fuzzing_common.c \ src/test/fuzz/fuzz_hsdescv3.c @@ -104,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 @@ -124,16 +154,6 @@ src_test_fuzz_fuzz_http_connect_LDADD = $(FUZZING_LIBS) endif if UNITTESTS_ENABLED -src_test_fuzz_fuzz_iptsv2_SOURCES = \ - src/test/fuzz/fuzzing_common.c \ - src/test/fuzz/fuzz_iptsv2.c -src_test_fuzz_fuzz_iptsv2_CPPFLAGS = $(FUZZING_CPPFLAGS) -src_test_fuzz_fuzz_iptsv2_CFLAGS = $(FUZZING_CFLAGS) -src_test_fuzz_fuzz_iptsv2_LDFLAGS = $(FUZZING_LDFLAG) -src_test_fuzz_fuzz_iptsv2_LDADD = $(FUZZING_LIBS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_fuzz_microdesc_SOURCES = \ src/test/fuzz/fuzzing_common.c \ src/test/fuzz/fuzz_microdesc.c @@ -175,16 +195,18 @@ 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-hsdescv2 \ 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-iptsv2 \ src/test/fuzz/fuzz-microdesc \ src/test/fuzz/fuzz-socks \ src/test/fuzz/fuzz-strops \ @@ -195,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) @@ -240,15 +280,6 @@ src_test_fuzz_lf_fuzz_extrainfo_LDADD = $(LIBFUZZER_LIBS) endif if UNITTESTS_ENABLED -src_test_fuzz_lf_fuzz_hsdescv2_SOURCES = \ - $(src_test_fuzz_fuzz_hsdescv2_SOURCES) -src_test_fuzz_lf_fuzz_hsdescv2_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) -src_test_fuzz_lf_fuzz_hsdescv2_CFLAGS = $(LIBFUZZER_CFLAGS) -src_test_fuzz_lf_fuzz_hsdescv2_LDFLAGS = $(LIBFUZZER_LDFLAG) -src_test_fuzz_lf_fuzz_hsdescv2_LDADD = $(LIBFUZZER_LIBS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_lf_fuzz_hsdescv3_SOURCES = \ $(src_test_fuzz_fuzz_hsdescv3_SOURCES) src_test_fuzz_lf_fuzz_hsdescv3_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) @@ -258,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) @@ -276,15 +326,6 @@ src_test_fuzz_lf_fuzz_http_connect_LDADD = $(LIBFUZZER_LIBS) endif if UNITTESTS_ENABLED -src_test_fuzz_lf_fuzz_iptsv2_SOURCES = \ - $(src_test_fuzz_fuzz_iptsv2_SOURCES) -src_test_fuzz_lf_fuzz_iptsv2_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) -src_test_fuzz_lf_fuzz_iptsv2_CFLAGS = $(LIBFUZZER_CFLAGS) -src_test_fuzz_lf_fuzz_iptsv2_LDFLAGS = $(LIBFUZZER_LDFLAG) -src_test_fuzz_lf_fuzz_iptsv2_LDADD = $(LIBFUZZER_LIBS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_lf_fuzz_microdesc_SOURCES = \ $(src_test_fuzz_fuzz_microdesc_SOURCES) src_test_fuzz_lf_fuzz_microdesc_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) @@ -321,16 +362,18 @@ 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-hsdescv2 \ 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-iptsv2 \ src/test/fuzz/lf-fuzz-microdesc \ src/test/fuzz/lf-fuzz-socks \ src/test/fuzz/lf-fuzz-strops \ @@ -344,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) @@ -379,13 +436,6 @@ src_test_fuzz_liboss_fuzz_extrainfo_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) endif if UNITTESTS_ENABLED -src_test_fuzz_liboss_fuzz_hsdescv2_a_SOURCES = \ - $(src_test_fuzz_fuzz_hsdescv2_SOURCES) -src_test_fuzz_liboss_fuzz_hsdescv2_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) -src_test_fuzz_liboss_fuzz_hsdescv2_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_liboss_fuzz_hsdescv3_a_SOURCES = \ $(src_test_fuzz_fuzz_hsdescv3_SOURCES) src_test_fuzz_liboss_fuzz_hsdescv3_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) @@ -393,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) @@ -407,13 +471,6 @@ src_test_fuzz_liboss_fuzz_http_connect_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) endif if UNITTESTS_ENABLED -src_test_fuzz_liboss_fuzz_iptsv2_a_SOURCES = \ - $(src_test_fuzz_fuzz_iptsv2_SOURCES) -src_test_fuzz_liboss_fuzz_iptsv2_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) -src_test_fuzz_liboss_fuzz_iptsv2_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) -endif - -if UNITTESTS_ENABLED src_test_fuzz_liboss_fuzz_microdesc_a_SOURCES = \ $(src_test_fuzz_fuzz_microdesc_SOURCES) src_test_fuzz_liboss_fuzz_microdesc_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) @@ -442,16 +499,18 @@ 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-hsdescv2.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-iptsv2.a \ src/test/fuzz/liboss-fuzz-microdesc.a \ src/test/fuzz/liboss-fuzz-socks.a \ src/test/fuzz/liboss-fuzz-strops.a \ diff --git a/src/test/hs_build_address.py b/src/test/hs_build_address.py index 91864eabcb..216b7626bf 100644 --- a/src/test/hs_build_address.py +++ b/src/test/hs_build_address.py @@ -10,17 +10,21 @@ import base64 # Python 3.6+, the SHA3 is available in hashlib natively. Else this requires # the pysha3 package (pip install pysha3). +TEST_INPUT = b"Hello World" if sys.version_info < (3, 6): import sha3 + m = sha3.sha3_256(TEST_INPUT) +else: + m = hashlib.sha3_256(TEST_INPUT) # Test vector to make sure the right sha3 version will be used. pysha3 < 1.0 # used the old Keccak implementation. During the finalization of SHA3, NIST # changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function # stayed the same. pysha3 1.0 provides the previous Keccak hash, too. TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51" -if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest(): +if TEST_VALUE != m.hexdigest(): print("pysha3 version is < 1.0. Please install from:") - print("https://github.com/tiran/pysha3https://github.com/tiran/pysha3") + print("https://github.com/tiran/pysha3") sys.exit(1) # Checksum is built like so: @@ -28,7 +32,11 @@ if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest(): PREFIX = ".onion checksum".encode() # 32 bytes ed25519 pubkey from first test vector of # https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02#section-6 -PUBKEY = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".decode('hex') +PUBKEY_STRING = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a" +if sys.version_info < (3, 0): + PUBKEY = PUBKEY_STRING.decode('hex') +else: + PUBKEY = bytes.fromhex(PUBKEY_STRING) # Version 3 is proposal224 VERSION = 3 diff --git a/src/test/hs_test_helpers.c b/src/test/hs_test_helpers.c index e9aafa4760..20b225ba4a 100644 --- a/src/test/hs_test_helpers.c +++ b/src/test/hs_test_helpers.c @@ -1,9 +1,10 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define HS_CLIENT_PRIVATE #include "core/or/or.h" +#include "core/or/versions.h" #include "lib/crypt_ops/crypto_ed25519.h" #include "test/test.h" #include "feature/nodelist/torcert.h" @@ -134,7 +135,8 @@ hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now, * points are added. */ static hs_descriptor_t * hs_helper_build_hs_desc_impl(unsigned int no_ip, - const ed25519_keypair_t *signing_kp) + const ed25519_keypair_t *signing_kp, + uint64_t rev_counter) { int ret; int i; @@ -161,7 +163,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip, &signing_kp->pubkey, now, 3600, CERT_FLAG_INCLUDE_SIGNING_KEY); tt_assert(desc->plaintext_data.signing_key_cert); - desc->plaintext_data.revision_counter = 42; + desc->plaintext_data.revision_counter = rev_counter; desc->plaintext_data.lifetime_sec = 3 * 60 * 60; hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey, @@ -185,6 +187,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip, desc->encrypted_data.create2_ntor = 1; desc->encrypted_data.intro_auth_types = smartlist_new(); desc->encrypted_data.single_onion_service = 1; + desc->encrypted_data.flow_control_pv = tor_strdup("FlowCtrl=1-2"); smartlist_add(desc->encrypted_data.intro_auth_types, tor_strdup("ed25519")); desc->encrypted_data.intro_points = smartlist_new(); if (!no_ip) { @@ -226,18 +229,26 @@ hs_helper_get_subcred_from_identity_keypair(ed25519_keypair_t *signing_kp, subcred_out); } +/* Build a descriptor with a specific rev counter. */ +hs_descriptor_t * +hs_helper_build_hs_desc_with_rev_counter(const ed25519_keypair_t *signing_kp, + uint64_t revision_counter) +{ + return hs_helper_build_hs_desc_impl(0, signing_kp, revision_counter); +} + /* Build a descriptor with introduction points. */ hs_descriptor_t * hs_helper_build_hs_desc_with_ip(const ed25519_keypair_t *signing_kp) { - return hs_helper_build_hs_desc_impl(0, signing_kp); + return hs_helper_build_hs_desc_impl(0, signing_kp, 42); } /* Build a descriptor without any introduction points. */ hs_descriptor_t * hs_helper_build_hs_desc_no_ip(const ed25519_keypair_t *signing_kp) { - return hs_helper_build_hs_desc_impl(1, signing_kp); + return hs_helper_build_hs_desc_impl(1, signing_kp, 42); } hs_descriptor_t * @@ -247,7 +258,7 @@ hs_helper_build_hs_desc_with_client_auth( const ed25519_keypair_t *signing_kp) { curve25519_keypair_t auth_ephemeral_kp; - hs_descriptor_t *desc = hs_helper_build_hs_desc_impl(0, signing_kp); + hs_descriptor_t *desc = hs_helper_build_hs_desc_impl(0, signing_kp, 42); hs_desc_authorized_client_t *desc_client; /* The number of client authorized auth has tobe a multiple of @@ -323,6 +334,10 @@ hs_helper_desc_equal(const hs_descriptor_t *desc1, /* Encrypted data section. */ tt_uint_op(desc1->encrypted_data.create2_ntor, OP_EQ, desc2->encrypted_data.create2_ntor); + tt_uint_op(desc1->encrypted_data.single_onion_service, OP_EQ, + desc2->encrypted_data.single_onion_service); + tt_str_op(desc1->encrypted_data.flow_control_pv, OP_EQ, + desc2->encrypted_data.flow_control_pv); /* Authentication type. */ tt_int_op(!!desc1->encrypted_data.intro_auth_types, OP_EQ, diff --git a/src/test/hs_test_helpers.h b/src/test/hs_test_helpers.h index 23d11f2a4a..ec9ee60116 100644 --- a/src/test/hs_test_helpers.h +++ b/src/test/hs_test_helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_HS_TEST_HELPERS_H @@ -17,6 +17,10 @@ hs_descriptor_t *hs_helper_build_hs_desc_no_ip( const ed25519_keypair_t *signing_kp); hs_descriptor_t *hs_helper_build_hs_desc_with_ip( const ed25519_keypair_t *signing_kp); +hs_descriptor_t * +hs_helper_build_hs_desc_with_rev_counter(const ed25519_keypair_t *signing_kp, + uint64_t revision_counter); + hs_descriptor_t *hs_helper_build_hs_desc_with_client_auth( const uint8_t *descriptor_cookie, const curve25519_public_key_t *client_pk, diff --git a/src/test/include.am b/src/test/include.am index ba802e7b04..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 \ @@ -82,7 +73,8 @@ TEST_CHUTNEY_FLAVOR_QUICK_IPV6 = single-onion-v3-ipv6-md TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v3-min single-onion-v3 # only run if we can ping ::1 (localhost) -TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v3-ipv6 single-onion-v3-ipv6-md +TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v3-ipv6 \ + single-onion-v3-ipv6-md # only run if we can find a stable (or simply another) version of tor TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v3 @@ -129,7 +121,6 @@ src_test_test_SOURCES += \ src/test/log_test_helpers.c \ src/test/hs_test_helpers.c \ src/test/opts_test_helpers.c \ - src/test/rend_test_helpers.c \ src/test/resolve_test_helpers.c \ src/test/rng_test_helpers.c \ src/test/test.c \ @@ -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 \ @@ -180,7 +172,6 @@ src_test_test_SOURCES += \ src/test/test_geoip.c \ src/test/test_guardfraction.c \ src/test/test_extorport.c \ - src/test/test_hs.c \ src/test/test_hs_common.c \ src/test/test_hs_config.c \ src/test/test_hs_cell.c \ @@ -195,7 +186,6 @@ src_test_test_SOURCES += \ src/test/test_hs_descriptor.c \ src/test/test_hs_dos.c \ src/test/test_hs_metrics.c \ - src/test/test_introduce.c \ src/test/test_keypin.c \ src/test/test_link_handshake.c \ src/test/test_logging.c \ @@ -205,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 \ @@ -226,12 +217,12 @@ src_test_test_SOURCES += \ src/test/test_relay.c \ src/test/test_relaycell.c \ src/test/test_relaycrypt.c \ - src/test/test_rendcache.c \ src/test/test_replay.c \ src/test/test_router.c \ 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 \ @@ -306,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@ @@ -314,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@ \ @@ -343,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@ \ @@ -353,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@ \ @@ -365,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@ \ @@ -379,7 +365,6 @@ noinst_HEADERS+= \ src/test/hs_test_helpers.h \ src/test/log_test_helpers.h \ src/test/opts_test_helpers.h \ - src/test/rend_test_helpers.h \ src/test/resolve_test_helpers.h \ src/test/rng_test_helpers.h \ src/test/test.h \ @@ -402,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@ @@ -425,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@ @@ -447,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 \ @@ -471,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/log_test_helpers.c b/src/test/log_test_helpers.c index 5e60d6b282..8928f39634 100644 --- a/src/test/log_test_helpers.c +++ b/src/test/log_test_helpers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define LOG_PRIVATE #include "lib/log/log.h" diff --git a/src/test/log_test_helpers.h b/src/test/log_test_helpers.h index c2d71c6bcd..e7de9b6015 100644 --- a/src/test/log_test_helpers.h +++ b/src/test/log_test_helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" 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/opts_test_helpers.c b/src/test/opts_test_helpers.c index 619ca40733..2c0f8dbd82 100644 --- a/src/test/opts_test_helpers.c +++ b/src/test/opts_test_helpers.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/opts_test_helpers.h b/src/test/opts_test_helpers.h index f925194e63..a6d31551a4 100644 --- a/src/test/opts_test_helpers.h +++ b/src/test/opts_test_helpers.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/prob_distr_mpfr_ref.c b/src/test/prob_distr_mpfr_ref.c index de4179c4e0..060cdf74ae 100644 --- a/src/test/prob_distr_mpfr_ref.c +++ b/src/test/prob_distr_mpfr_ref.c @@ -1,4 +1,4 @@ -/* Copyright 2012-2020, The Tor Project, Inc +/* Copyright 2012-2021, The Tor Project, Inc * See LICENSE for licensing information */ /** prob_distr_mpfr_ref.c diff --git a/src/test/ptr_helpers.c b/src/test/ptr_helpers.c index 0e0995df7c..536006be5d 100644 --- a/src/test/ptr_helpers.c +++ b/src/test/ptr_helpers.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "test/ptr_helpers.h" diff --git a/src/test/ptr_helpers.h b/src/test/ptr_helpers.h index 0999fdf5d2..a283c525eb 100644 --- a/src/test/ptr_helpers.h +++ b/src/test/ptr_helpers.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_PTR_HELPERS_H diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c deleted file mode 100644 index 8e40167aeb..0000000000 --- a/src/test/rend_test_helpers.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -#include "core/or/or.h" -#include "core/or/extendinfo.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "test/test.h" -#include "feature/rend/rendcommon.h" -#include "test/rend_test_helpers.h" - -#include "core/or/extend_info_st.h" -#include "feature/rend/rend_intro_point_st.h" -#include "feature/rend/rend_service_descriptor_st.h" - -void -generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, - char **service_id, int intro_points) -{ - rend_service_descriptor_t *generated = NULL; - smartlist_t *descs = smartlist_new(); - time_t now; - - now = time(NULL) + time_diff; - create_descriptor(&generated, service_id, intro_points); - generated->timestamp = now; - - rend_encode_v2_descriptors(descs, generated, now, 0, REND_NO_AUTH, NULL, - NULL); - tor_assert(smartlist_len(descs) > 1); - *desc = smartlist_get(descs, 0); - smartlist_set(descs, 0, NULL); - - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - rend_service_descriptor_free(generated); -} - -void -create_descriptor(rend_service_descriptor_t **generated, char **service_id, - int intro_points) -{ - crypto_pk_t *pk1 = NULL; - crypto_pk_t *pk2 = NULL; - int i; - - *service_id = tor_malloc(REND_SERVICE_ID_LEN_BASE32+1); - pk1 = pk_generate(0); - pk2 = pk_generate(1); - - *generated = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - (*generated)->pk = crypto_pk_dup_key(pk1); - rend_get_service_id((*generated)->pk, *service_id); - - (*generated)->version = 2; - (*generated)->protocols = 42; - (*generated)->intro_nodes = smartlist_new(); - - for (i = 0; i < intro_points; i++) { - rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t)); - crypto_pk_t *okey = pk_generate(2 + i); - intro->extend_info = - extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); - intro->extend_info->onion_key = okey; - crypto_pk_get_digest(intro->extend_info->onion_key, - intro->extend_info->identity_digest); - intro->extend_info->nickname[0] = '$'; - base16_encode(intro->extend_info->nickname + 1, - sizeof(intro->extend_info->nickname) - 1, - intro->extend_info->identity_digest, DIGEST_LEN); - tor_addr_t addr; - uint16_t port; - /* Does not cover all IP addresses. */ - tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1); - port = 1 + crypto_rand_int(65535); - extend_info_add_orport(intro->extend_info, &addr, port); - intro->intro_key = crypto_pk_dup_key(pk2); - smartlist_add((*generated)->intro_nodes, intro); - } - - crypto_pk_free(pk1); - crypto_pk_free(pk2); -} - -rend_data_t * -mock_rend_data(const char *onion_address) -{ - rend_data_v2_t *v2_data = tor_malloc_zero(sizeof(*v2_data)); - rend_data_t *rend_query = &v2_data->base_; - rend_query->version = 2; - - strlcpy(v2_data->onion_address, onion_address, - sizeof(v2_data->onion_address)); - v2_data->auth_type = REND_NO_AUTH; - rend_query->hsdirs_fp = smartlist_new(); - smartlist_add(rend_query->hsdirs_fp, tor_memdup("aaaaaaaaaaaaaaaaaaaaaaaa", - DIGEST_LEN)); - return rend_query; -} diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h deleted file mode 100644 index b1078ce866..0000000000 --- a/src/test/rend_test_helpers.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -#include "core/or/or.h" - -#ifndef TOR_REND_TEST_HELPERS_H -#define TOR_REND_TEST_HELPERS_H - -void generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc, - char **service_id, int intro_points); -void create_descriptor(rend_service_descriptor_t **generated, - char **service_id, int intro_points); -rend_data_t *mock_rend_data(const char *onion_address); - -#endif /* !defined(TOR_REND_TEST_HELPERS_H) */ - diff --git a/src/test/resolve_test_helpers.c b/src/test/resolve_test_helpers.c index ed5853c359..6be5ab0b9f 100644 --- a/src/test/resolve_test_helpers.c +++ b/src/test/resolve_test_helpers.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/resolve_test_helpers.h b/src/test/resolve_test_helpers.h index ca642d6c63..c7d610379f 100644 --- a/src/test/resolve_test_helpers.h +++ b/src/test/resolve_test_helpers.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/rng_test_helpers.c b/src/test/rng_test_helpers.c index b7d7cb0dfa..058c5e0ccd 100644 --- a/src/test/rng_test_helpers.c +++ b/src/test/rng_test_helpers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/rng_test_helpers.h b/src/test/rng_test_helpers.h index 6fcdaa2653..a6ca7d792f 100644 --- a/src/test/rng_test_helpers.h +++ b/src/test/rng_test_helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_RNG_TEST_HELPERS_H diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c index 5e4cc7678e..192fa9ec31 100644 --- a/src/test/test-memwipe.c +++ b/src/test/test-memwipe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test-process.c b/src/test/test-process.c index f5a1f1a54e..a1e37b119a 100644 --- a/src/test/test-process.c +++ b/src/test/test-process.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2020, The Tor Project, Inc. */ +/* Copyright (c) 2011-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test-timers.c b/src/test/test-timers.c index 18e2191a09..b2ba58b9dd 100644 --- a/src/test/test-timers.c +++ b/src/test/test-timers.c @@ -1,4 +1,4 @@ -/* Copyright 2016-2020, The Tor Project, Inc. */ +/* Copyright 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test.c b/src/test/test.c index ffea158141..6b7e0b6442 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1,6 +1,5 @@ /* Copyright (c) 2001-2004, Roger Dingledine. -->a * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -45,9 +44,6 @@ #include "app/config/config.h" #include "core/or/connection_edge.h" #include "core/or/extendinfo.h" -#include "feature/rend/rendcommon.h" -#include "feature/rend/rendcache.h" -#include "feature/rend/rendparse.h" #include "test/test.h" #include "core/mainloop/mainloop.h" #include "lib/memarea/memarea.h" @@ -56,14 +52,13 @@ #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" #include "core/or/extend_info_st.h" #include "core/or/or_circuit_st.h" -#include "feature/rend/rend_encoded_v2_service_descriptor_st.h" -#include "feature/rend/rend_intro_point_st.h" -#include "feature/rend/rend_service_descriptor_st.h" #include "feature/relay/onion_queue.h" /** Run unit tests for the onion handshake code. */ @@ -355,6 +350,227 @@ test_onion_queues(void *arg) tor_free(onionskin); } +/** + * Test onion queue priority, separation, and resulting + * ordering. + * + * create and add a mix of TAP, NTOR2, and NTORv3. Ensure + * they all end up in the right queue. In particular, ntorv2 + * and ntorv3 should share a queue, but TAP should be separate, + * and lower prioritt. + * + * We test this by way of adding TAP first, and then an interleaving + * order of ntor2 and ntor3, and check that the ntor2 and ntor3 are + * still interleaved, but TAP comes last. */ +static void +test_onion_queue_order(void *arg) +{ + uint8_t buf_tap[TAP_ONIONSKIN_CHALLENGE_LEN] = {0}; + uint8_t buf_ntor[NTOR_ONIONSKIN_LEN] = {0}; + uint8_t buf_ntor3[CELL_PAYLOAD_SIZE] = {0}; + + or_circuit_t *circ_tap = or_circuit_new(0, NULL); + or_circuit_t *circ_ntor = or_circuit_new(0, NULL); + or_circuit_t *circ_ntor3 = or_circuit_new(0, NULL); + + create_cell_t *onionskin = NULL; + create_cell_t *create_tap1 = tor_malloc_zero(sizeof(create_cell_t)); + create_cell_t *create_ntor1 = tor_malloc_zero(sizeof(create_cell_t)); + create_cell_t *create_ntor2 = tor_malloc_zero(sizeof(create_cell_t)); + create_cell_t *create_v3ntor1 = tor_malloc_zero(sizeof(create_cell_t)); + create_cell_t *create_v3ntor2 = tor_malloc_zero(sizeof(create_cell_t)); + (void)arg; + + create_cell_init(create_tap1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP, + TAP_ONIONSKIN_CHALLENGE_LEN, buf_tap); + create_cell_init(create_ntor1, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR, + NTOR_ONIONSKIN_LEN, buf_ntor); + create_cell_init(create_ntor2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR, + NTOR_ONIONSKIN_LEN, buf_ntor); + create_cell_init(create_v3ntor1, CELL_CREATE2, ONION_HANDSHAKE_TYPE_NTOR_V3, + NTOR_ONIONSKIN_LEN, buf_ntor3); + create_cell_init(create_v3ntor2, CELL_CREATE2, ONION_HANDSHAKE_TYPE_NTOR_V3, + NTOR_ONIONSKIN_LEN, buf_ntor3); + + /* sanity check queue init */ + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + /* Add tap first so we can ensure it comes out last */ + tt_int_op(0,OP_EQ, onion_pending_add(circ_tap, create_tap1)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + /* Now add interleaving ntor2 and ntor3, to ensure they share + * the same queue and come out in this order */ + tt_int_op(0,OP_EQ, onion_pending_add(circ_ntor, create_ntor1)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + tt_int_op(0,OP_EQ, onion_pending_add(circ_ntor3, create_v3ntor1)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(2,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(2,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + tt_int_op(0,OP_EQ, onion_pending_add(circ_ntor, create_ntor2)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(3,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(3,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + tt_int_op(0,OP_EQ, onion_pending_add(circ_ntor3, create_v3ntor2)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(4,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(4,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + + /* Now remove 5 tasks, ensuring order and queue sizes */ + tt_ptr_op(circ_ntor, OP_EQ, onion_next_task(&onionskin)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(3,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(3,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + tt_ptr_op(onionskin, OP_EQ, create_ntor1); + + tt_ptr_op(circ_ntor3, OP_EQ, onion_next_task(&onionskin)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(2,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(2,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + tt_ptr_op(onionskin, OP_EQ, create_v3ntor1); + + tt_ptr_op(circ_ntor, OP_EQ, onion_next_task(&onionskin)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + tt_ptr_op(onionskin, OP_EQ, create_ntor2); + + tt_ptr_op(circ_ntor3, OP_EQ, onion_next_task(&onionskin)); + tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + tt_ptr_op(onionskin, OP_EQ, create_v3ntor2); + + tt_ptr_op(circ_tap, OP_EQ, onion_next_task(&onionskin)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3)); + tt_ptr_op(onionskin, OP_EQ, create_tap1); + + clear_pending_onions(); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + + done: + circuit_free_(TO_CIRCUIT(circ_tap)); + circuit_free_(TO_CIRCUIT(circ_ntor)); + circuit_free_(TO_CIRCUIT(circ_ntor3)); + tor_free(create_tap1); + tor_free(create_ntor1); + tor_free(create_ntor2); + tor_free(create_v3ntor1); + tor_free(create_v3ntor2); +} + +static int32_t cbtnummodes = 10; + +static int32_t +mock_xm_networkstatus_get_param( + const networkstatus_t *ns, const char *param_name, int32_t default_val, + int32_t min_val, int32_t max_val) +{ + (void)ns; + (void)default_val; + (void)min_val; + (void)max_val; + // only support cbtnummodes right now + tor_assert(strcmp(param_name, "cbtnummodes")==0); + return cbtnummodes; +} + +static void +test_circuit_timeout_xm_alpha(void *arg) +{ + circuit_build_times_t cbt; + build_time_t Xm; + int alpha_ret; + circuit_build_times_init(&cbt); + (void)arg; + + /* Plan: + * 1. Create array of build times with 10 modes. + * 2. Make sure Xm calc is sane for 1,3,5,10,15,20 modes. + * 3. Make sure alpha calc is sane for 1,3,5,10,15,20 modes. + */ + + /* 110 build times, 9 modes, 8 mode ties, 10 abandoned */ + build_time_t circuit_build_times[] = { + 100, 20, 1000, 500, 200, 5000, 30, 600, 200, 300, CBT_BUILD_ABANDONED, + 101, 21, 1001, 501, 201, 5001, 31, 601, 201, 301, CBT_BUILD_ABANDONED, + 102, 22, 1002, 502, 202, 5002, 32, 602, 202, 302, CBT_BUILD_ABANDONED, + 103, 23, 1003, 503, 203, 5003, 33, 603, 203, 303, CBT_BUILD_ABANDONED, + 104, 24, 1004, 504, 204, 5004, 34, 604, 204, 304, CBT_BUILD_ABANDONED, + 105, 25, 1005, 505, 205, 5005, 35, 605, 205, 305, CBT_BUILD_ABANDONED, + 106, 26, 1006, 506, 206, 5006, 36, 606, 206, 306, CBT_BUILD_ABANDONED, + 107, 27, 1007, 507, 207, 5007, 37, 607, 207, 307, CBT_BUILD_ABANDONED, + 108, 28, 1008, 508, 208, 5008, 38, 608, 208, 308, CBT_BUILD_ABANDONED, + 109, 29, 1009, 509, 209, 5009, 39, 609, 209, 309, CBT_BUILD_ABANDONED + }; + + memcpy(cbt.circuit_build_times, circuit_build_times, + sizeof(circuit_build_times)); + cbt.total_build_times = 110; + + MOCK(networkstatus_get_param, mock_xm_networkstatus_get_param); + +#define CBT_ALPHA_PRECISION 0.00001 + cbtnummodes = 1; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 205); + tt_assert(fabs(cbt.alpha - 1.394401) < CBT_ALPHA_PRECISION); + + cbtnummodes = 3; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 117); + tt_assert(fabs(cbt.alpha - 0.902313) < CBT_ALPHA_PRECISION); + + cbtnummodes = 5; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 146); + tt_assert(fabs(cbt.alpha - 1.049032) < CBT_ALPHA_PRECISION); + + cbtnummodes = 10; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 800); + tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION); + + cbtnummodes = 15; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 800); + tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION); + + cbtnummodes = 20; + Xm = circuit_build_times_get_xm(&cbt); + alpha_ret = circuit_build_times_update_alpha(&cbt); + tt_int_op(alpha_ret, OP_EQ, 1); + tt_int_op(Xm, OP_EQ, 800); + tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION); + + done: +#undef CBT_ALPHA_PRECISION + UNMOCK(networkstatus_get_param); + circuit_build_times_free_timeouts(&cbt); +} + static void test_circuit_timeout(void *arg) { @@ -373,7 +589,6 @@ test_circuit_timeout(void *arg) double timeout1, timeout2; or_state_t *state=NULL; int i, runs; - double close_ms; (void)arg; initialize_periodic_events(); @@ -394,18 +609,11 @@ test_circuit_timeout(void *arg) circuit_build_times_initial_alpha(&initial, CBT_DEFAULT_QUANTILE_CUTOFF/100.0, timeout0); - close_ms = MAX(circuit_build_times_calculate_timeout(&initial, - CBT_DEFAULT_CLOSE_QUANTILE/100.0), - CBT_DEFAULT_TIMEOUT_INITIAL_VALUE); do { for (i=0; i < CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE; i++) { build_time_t sample = circuit_build_times_generate_sample(&initial,0,1); - if (sample > close_ms) { - circuit_build_times_add_time(&estimate, CBT_BUILD_ABANDONED); - } else { - circuit_build_times_add_time(&estimate, sample); - } + circuit_build_times_add_time(&estimate, sample); } circuit_build_times_update_alpha(&estimate); timeout1 = circuit_build_times_calculate_timeout(&estimate, @@ -526,127 +734,6 @@ test_circuit_timeout(void *arg) testing_disable_deterministic_rng(); } -/** Test encoding and parsing of rendezvous service descriptors. */ -static void -test_rend_fns(void *arg) -{ - rend_service_descriptor_t *generated = NULL, *parsed = NULL; - char service_id[DIGEST_LEN]; - char service_id_base32[REND_SERVICE_ID_LEN_BASE32+1]; - const char *next_desc; - smartlist_t *descs = smartlist_new(); - char computed_desc_id[DIGEST_LEN]; - char parsed_desc_id[DIGEST_LEN]; - crypto_pk_t *pk1 = NULL, *pk2 = NULL; - time_t now; - char *intro_points_encrypted = NULL; - size_t intro_points_size; - size_t encoded_size; - int i; - - (void)arg; - - /* Initialize the service cache. */ - rend_cache_init(); - - pk1 = pk_generate(0); - pk2 = pk_generate(1); - generated = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - generated->pk = crypto_pk_dup_key(pk1); - crypto_pk_get_digest(generated->pk, service_id); - base32_encode(service_id_base32, REND_SERVICE_ID_LEN_BASE32+1, - service_id, REND_SERVICE_ID_LEN); - now = time(NULL); - generated->timestamp = now; - generated->version = 2; - generated->protocols = 42; - generated->intro_nodes = smartlist_new(); - - for (i = 0; i < 3; i++) { - rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t)); - crypto_pk_t *okey = pk_generate(2 + i); - intro->extend_info = - extend_info_new(NULL, NULL, NULL, NULL, NULL, NULL, 0); - intro->extend_info->onion_key = okey; - crypto_pk_get_digest(intro->extend_info->onion_key, - intro->extend_info->identity_digest); - //crypto_rand(info->identity_digest, DIGEST_LEN); /* Would this work? */ - intro->extend_info->nickname[0] = '$'; - base16_encode(intro->extend_info->nickname + 1, - sizeof(intro->extend_info->nickname) - 1, - intro->extend_info->identity_digest, DIGEST_LEN); - tor_addr_t addr; - uint16_t port; - /* Does not cover all IP addresses. */ - tor_addr_from_ipv4h(&addr, crypto_rand_int(65536) + 1); - port = 1 + crypto_rand_int(65535); - extend_info_add_orport(intro->extend_info, &addr, port); - intro->intro_key = crypto_pk_dup_key(pk2); - smartlist_add(generated->intro_nodes, intro); - } - int rv = rend_encode_v2_descriptors(descs, generated, now, 0, - REND_NO_AUTH, NULL, NULL); - tt_int_op(rv, OP_GT, 0); - rv = rend_compute_v2_desc_id(computed_desc_id, service_id_base32, NULL, - now, 0); - tt_int_op(rv, OP_EQ, 0); - tt_mem_op(((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0))->desc_id, OP_EQ, - computed_desc_id, DIGEST_LEN); - rv = rend_parse_v2_service_descriptor(&parsed, parsed_desc_id, - &intro_points_encrypted, &intro_points_size, &encoded_size, - &next_desc, - ((rend_encoded_v2_service_descriptor_t *)smartlist_get(descs, 0)) - ->desc_str, 1); - tt_int_op(rv, OP_EQ, 0); - tt_assert(parsed); - tt_mem_op(((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0))->desc_id,OP_EQ, parsed_desc_id, DIGEST_LEN); - tt_int_op(rend_parse_introduction_points(parsed, intro_points_encrypted, - intro_points_size),OP_EQ, 3); - tt_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk)); - tt_int_op(parsed->timestamp,OP_EQ, now); - tt_int_op(parsed->version,OP_EQ, 2); - tt_int_op(parsed->protocols,OP_EQ, 42); - tt_int_op(smartlist_len(parsed->intro_nodes),OP_EQ, 3); - for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) { - rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i), - *gen_intro = smartlist_get(generated->intro_nodes, i); - extend_info_t *par_info = par_intro->extend_info; - extend_info_t *gen_info = gen_intro->extend_info; - tt_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key)); - tt_mem_op(gen_info->identity_digest,OP_EQ, par_info->identity_digest, - DIGEST_LEN); - tt_str_op(gen_info->nickname,OP_EQ, par_info->nickname); - const tor_addr_port_t *a1, *a2; - a1 = extend_info_get_orport(gen_info, AF_INET); - a2 = extend_info_get_orport(par_info, AF_INET); - tt_assert(a1 && a2); - tt_assert(tor_addr_eq(&a1->addr, &a2->addr)); - tt_int_op(a2->port,OP_EQ, a2->port); - } - - rend_service_descriptor_free(parsed); - rend_service_descriptor_free(generated); - parsed = generated = NULL; - - done: - if (descs) { - for (i = 0; i < smartlist_len(descs); i++) - rend_encoded_v2_service_descriptor_free_(smartlist_get(descs, i)); - smartlist_free(descs); - } - if (parsed) - rend_service_descriptor_free(parsed); - if (generated) - rend_service_descriptor_free(generated); - if (pk1) - crypto_pk_free(pk1); - if (pk2) - crypto_pk_free(pk2); - tor_free(intro_points_encrypted); -} - #define ENT(name) \ { #name, test_ ## name , 0, NULL, NULL } #define FORK(name) \ @@ -656,10 +743,11 @@ static struct testcase_t test_array[] = { ENT(onion_handshake), { "bad_onion_handshake", test_bad_onion_handshake, 0, NULL, NULL }, ENT(onion_queues), + ENT(onion_queue_order), { "ntor_handshake", test_ntor_handshake, 0, NULL, NULL }, { "fast_handshake", test_fast_handshake, 0, NULL, NULL }, FORK(circuit_timeout), - FORK(rend_fns), + FORK(circuit_timeout_xm_alpha), END_OF_TESTCASES }; @@ -707,6 +795,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}, @@ -734,15 +823,14 @@ struct testgroup_t testgroups[] = { { "hs_ntor/", hs_ntor_tests }, { "hs_ob/", hs_ob_tests }, { "hs_service/", hs_service_tests }, - { "introduce/", introduce_tests }, { "keypin/", keypin_tests }, - { "legacy_hs/", hs_tests }, { "link-handshake/", link_handshake_tests }, { "mainloop/", mainloop_tests }, { "metrics/", metrics_tests }, { "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 }, @@ -762,12 +850,14 @@ struct testgroup_t testgroups[] = { { "relay/" , relay_tests }, { "relaycell/", relaycell_tests }, { "relaycrypt/", relaycrypt_tests }, - { "rend_cache/", rend_cache_tests }, { "replaycache/", replaycache_tests }, { "router/", router_tests }, { "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 56037648d3..e17bce427c 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2003, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_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[]; @@ -145,8 +146,6 @@ extern struct testcase_t hs_metrics_tests[]; extern struct testcase_t hs_ntor_tests[]; extern struct testcase_t hs_ob_tests[]; extern struct testcase_t hs_service_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[]; @@ -156,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[]; @@ -179,12 +179,12 @@ extern struct testcase_t pubsub_msg_tests[]; extern struct testcase_t relay_tests[]; extern struct testcase_t relaycell_tests[]; extern struct testcase_t relaycrypt_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 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_accounting.c b/src/test/test_accounting.c index 7933df5e35..4cc2c0733c 100644 --- a/src/test/test_accounting.c +++ b/src/test/test_accounting.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_addr.c b/src/test/test_addr.c index dbc581288d..f368326902 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ADDRESSMAP_PRIVATE diff --git a/src/test/test_address.c b/src/test/test_address.c index e7007f22f3..015ca0807c 100644 --- a/src/test/test_address.c +++ b/src/test/test_address.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ADDRESS_PRIVATE @@ -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_address_set.c b/src/test/test_address_set.c index 37688f4c1d..6860906791 100644 --- a/src/test/test_address_set.c +++ b/src/test/test_address_set.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_bridges.c b/src/test/test_bridges.c index 1942a8cb89..f778710e1b 100644 --- a/src/test/test_bridges.c +++ b/src/test/test_bridges.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c index 5f9a88705c..fd3778d801 100644 --- a/src/test/test_bt_cl.c +++ b/src/test/test_bt_cl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Tor Project, Inc. */ +/* Copyright (c) 2012-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_btrack.c b/src/test/test_btrack.c index 2b2f34fc23..16fe7c4bd7 100644 --- a/src/test/test_btrack.c +++ b/src/test/test_btrack.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c index fbaa628fd7..888adb4956 100644 --- a/src/test/test_buffers.c +++ b/src/test/test_buffers.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define BUFFERS_PRIVATE diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c index 4cf83e45d0..a034c369d1 100644 --- a/src/test/test_bwmgt.c +++ b/src/test/test_bwmgt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c index cae25d00ec..b7b149cd66 100644 --- a/src/test/test_cell_formats.c +++ b/src/test/test_cell_formats.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c index b778c07802..d9a002c594 100644 --- a/src/test/test_cell_queue.c +++ b/src/test/test_cell_queue.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITLIST_PRIVATE diff --git a/src/test/test_channel.c b/src/test/test_channel.c index d43f6e010a..a74d69fefc 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CHANNEL_OBJECT_PRIVATE diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c index 63a591583d..261e1f8a37 100644 --- a/src/test/test_channelpadding.c +++ b/src/test/test_channelpadding.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CHANNEL_OBJECT_PRIVATE diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 0227779e8b..ca7fee2c53 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -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_checkdir.c b/src/test/test_checkdir.c index 186a55cc8c..5579be7206 100644 --- a/src/test/test_checkdir.c +++ b/src/test/test_checkdir.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c index 299908ce82..0a5c3530bd 100644 --- a/src/test/test_circuitbuild.c +++ b/src/test/test_circuitbuild.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITBUILD_PRIVATE @@ -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_circuitlist.c b/src/test/test_circuitlist.c index 63c4418f29..4bcff57fc3 100644 --- a/src/test/test_circuitlist.c +++ b/src/test/test_circuitlist.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CHANNEL_OBJECT_PRIVATE @@ -203,6 +203,10 @@ test_rend_token_maps(void *arg) c4 = or_circuit_new(0, NULL); c5 = origin_circuit_new(); + ed25519_public_key_t intro_pk1 = { {1} }; /* Junk, not important. */ + ed25519_public_key_t intro_pk2 = { {2} }; /* Junk, not important. */ + ed25519_public_key_t intro_pk3 = { {3} }; /* Junk, not important. */ + /* Make sure we really filled up the tok* variables */ tt_int_op(tok1[REND_TOKEN_LEN-1], OP_EQ, 'y'); tt_int_op(tok2[REND_TOKEN_LEN-1], OP_EQ, ' '); @@ -210,31 +214,37 @@ test_rend_token_maps(void *arg) /* No maps; nothing there. */ tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok1)); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok1)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk1)); hs_circuitmap_register_rend_circ_relay_side(c1, tok1); - hs_circuitmap_register_intro_circ_v2_relay_side(c2, tok2); + hs_circuitmap_register_intro_circ_v3_relay_side(c2, &intro_pk2); tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok3)); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok3)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk3)); tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok2)); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok1)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); /* Without purpose set, we don't get the circuits */ tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok1)); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); c1->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; c2->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT; /* Okay, make sure they show up now. */ tt_ptr_op(c1, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok1)); - tt_ptr_op(c2, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2)); + tt_ptr_op(c2, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); /* Two items at the same place with the same token. */ c3->base_.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; hs_circuitmap_register_rend_circ_relay_side(c3, tok2); - tt_ptr_op(c2, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2)); + tt_ptr_op(c2, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); tt_ptr_op(c3, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok2)); /* Marking a circuit makes it not get returned any more */ @@ -246,31 +256,36 @@ test_rend_token_maps(void *arg) /* Freeing a circuit makes it not get returned any more. */ circuit_free_(TO_CIRCUIT(c2)); c2 = NULL; - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); /* c3 -- are you still there? */ tt_ptr_op(c3, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok2)); /* Change its cookie. This never happens in Tor per se, but hey. */ c3->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT; - hs_circuitmap_register_intro_circ_v2_relay_side(c3, tok3); + hs_circuitmap_register_intro_circ_v3_relay_side(c3, &intro_pk3); tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok2)); - tt_ptr_op(c3, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok3)); + tt_ptr_op(c3, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk3)); /* Now replace c3 with c4. */ c4->base_.purpose = CIRCUIT_PURPOSE_INTRO_POINT; - hs_circuitmap_register_intro_circ_v2_relay_side(c4, tok3); + hs_circuitmap_register_intro_circ_v3_relay_side(c4, &intro_pk3); - tt_ptr_op(c4, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok3)); + tt_ptr_op(c4, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk3)); tt_ptr_op(TO_CIRCUIT(c3)->hs_token, OP_EQ, NULL); tt_ptr_op(TO_CIRCUIT(c4)->hs_token, OP_NE, NULL); - tt_mem_op(TO_CIRCUIT(c4)->hs_token->token, OP_EQ, tok3, REND_TOKEN_LEN); + tt_mem_op(TO_CIRCUIT(c4)->hs_token->token, OP_EQ, &intro_pk3, + REND_TOKEN_LEN); /* Now clear c4's cookie. */ hs_circuitmap_remove_circuit(TO_CIRCUIT(c4)); tt_ptr_op(TO_CIRCUIT(c4)->hs_token, OP_EQ, NULL); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok3)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk3)); /* Now let's do a check for the client-side rend circuitmap */ c5->base_.purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND; @@ -401,6 +416,9 @@ test_hs_circuitmap_isolation(void *arg) hs_circuitmap_init(); + ed25519_public_key_t intro_pk1 = { {1} }; /* Junk, not important. */ + ed25519_public_key_t intro_pk2 = { {2} }; /* Junk, not important. */ + { const uint8_t tok1[REND_TOKEN_LEN] = "bet i got some of th"; @@ -416,7 +434,8 @@ test_hs_circuitmap_isolation(void *arg) /* check that service-side getters don't work */ tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_service_side(tok1)); - tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_service_side(tok1)); + tt_ptr_op(NULL, OP_EQ, + hs_circuitmap_get_intro_circ_v3_service_side(&intro_pk1)); /* Check that the right getter works. */ tt_ptr_op(circ1, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok1)); @@ -436,17 +455,18 @@ test_hs_circuitmap_isolation(void *arg) circ4->base_.purpose = CIRCUIT_PURPOSE_S_ESTABLISH_INTRO; /* Register circ2 with tok2 as service-side intro v2 circ */ - hs_circuitmap_register_intro_circ_v2_service_side(circ2, tok2); + hs_circuitmap_register_intro_circ_v3_service_side(circ2, &intro_pk2); /* Register circ3 with tok2 again but for different purpose */ - hs_circuitmap_register_intro_circ_v2_relay_side(circ3, tok2); + hs_circuitmap_register_intro_circ_v3_relay_side(circ3, &intro_pk2); /* Check that the getters work */ tt_ptr_op(circ2, OP_EQ, - hs_circuitmap_get_intro_circ_v2_service_side(tok2)); - tt_ptr_op(circ3, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2)); + hs_circuitmap_get_intro_circ_v3_service_side(&intro_pk2)); + tt_ptr_op(circ3, OP_EQ, + hs_circuitmap_get_intro_circ_v3_relay_side(&intro_pk2)); /* Register circ4 with tok2: it should override circ2 */ - hs_circuitmap_register_intro_circ_v2_service_side(circ4, tok2); + hs_circuitmap_register_intro_circ_v3_service_side(circ4, &intro_pk2); /* check that relay-side getters don't work */ tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok2)); @@ -454,7 +474,7 @@ test_hs_circuitmap_isolation(void *arg) /* Check that the getter returns circ4; the last circuit registered with * that token. */ tt_ptr_op(circ4, OP_EQ, - hs_circuitmap_get_intro_circ_v2_service_side(tok2)); + hs_circuitmap_get_intro_circ_v3_service_side(&intro_pk2)); } done: diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c index d6e3300a30..43f0af3f5f 100644 --- a/src/test/test_circuitmux.c +++ b/src/test/test_circuitmux.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CHANNEL_OBJECT_PRIVATE diff --git a/src/test/test_circuitmux_ewma.c b/src/test/test_circuitmux_ewma.c index 27601e0c7d..2a1e14eea2 100644 --- a/src/test/test_circuitmux_ewma.c +++ b/src/test/test_circuitmux_ewma.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITMUX_PRIVATE diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c index 86baf54f40..63b7136a11 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 */ @@ -1611,7 +1609,7 @@ simulate_single_hop_extend(circuit_t *client, circuit_t *mid_relay, hop->extend_info = extend_info_new( padding ? "padding" : "non-padding", digest, NULL, NULL, NULL, - &addr, padding); + &addr, padding, NULL, false); cpath_init_circuit_crypto(hop, whatevs_key, sizeof(whatevs_key), 0, 0); diff --git a/src/test/test_circuitstats.c b/src/test/test_circuitstats.c index 00ca1b544c..889adc1523 100644 --- a/src/test/test_circuitstats.c +++ b/src/test/test_circuitstats.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITBUILD_PRIVATE diff --git a/src/test/test_circuituse.c b/src/test/test_circuituse.c index 49438d9d3b..b6e945c36e 100644 --- a/src/test/test_circuituse.c +++ b/src/test/test_circuituse.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITLIST_PRIVATE diff --git a/src/test/test_compat_libevent.c b/src/test/test_compat_libevent.c index 5376e08fb3..7295550e13 100644 --- a/src/test/test_compat_libevent.c +++ b/src/test/test_compat_libevent.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define COMPAT_LIBEVENT_PRIVATE diff --git a/src/test/test_config.c b/src/test/test_config.c index 1654968705..3ebe095a6a 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -41,8 +41,6 @@ #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "core/or/policies.h" -#include "feature/rend/rendclient.h" -#include "feature/rend/rendservice.h" #include "feature/relay/relay_find_addr.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" @@ -1217,7 +1215,7 @@ get_interface_address6_replacement(int severity, sa_family_t family, return 0; } -#endif +#endif /* 0 */ static int n_get_interface_address6_failure = 0; @@ -6043,7 +6041,7 @@ test_config_include_wildcards(void *data) tt_ptr_op(result, OP_EQ, NULL); tt_int_op(include_used, OP_EQ, 1); config_free_lines(result); -#endif +#endif /* !defined(_WIN32) */ // test pattern *.conf tor_snprintf(torrc_contents, sizeof(torrc_contents), @@ -6183,9 +6181,9 @@ test_config_include_hidden(void *data) len++; } tt_int_op(len, OP_EQ, 1); -#else +#else /* !defined(_WIN32) */ tt_ptr_op(result, OP_EQ, NULL); -#endif +#endif /* defined(_WIN32) */ config_free_lines(result); // test wildcards match hidden folders when explicitly in the pattern @@ -6995,7 +6993,7 @@ test_config_multifamily_port(void *arg) #define CONFIG_TEST_SETUP(suffix, name, flags, setup, setup_data) \ { #name#suffix, test_config_ ## name, flags, setup, setup_data } -#endif +#endif /* !defined(COCCI) */ struct testcase_t config_tests[] = { CONFIG_TEST(adding_trusted_dir_server, TT_FORK), diff --git a/src/test/test_confmgr.c b/src/test/test_confmgr.c index a647b92e0a..00e24f6123 100644 --- a/src/test/test_confmgr.c +++ b/src/test/test_confmgr.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c index abd53dea68..391f6241da 100644 --- a/src/test/test_confparse.c +++ b/src/test/test_confparse.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* diff --git a/src/test/test_connection.c b/src/test/test_connection.c index cf5626ead7..fbf9d6a5ab 100644 --- a/src/test/test_connection.c +++ b/src/test/test_connection.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -19,7 +19,6 @@ #include "feature/nodelist/microdesc.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/networkstatus.h" -#include "feature/rend/rendcache.h" #include "feature/dircommon/directory.h" #include "core/or/connection_or.h" #include "lib/net/resolve.h" @@ -38,10 +37,6 @@ static void * test_conn_get_basic_setup(const struct testcase_t *tc); static int test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg); -static void * test_conn_get_rend_setup(const struct testcase_t *tc); -static int test_conn_get_rend_teardown(const struct testcase_t *tc, - void *arg); - static void * test_conn_get_rsrc_setup(const struct testcase_t *tc); static int test_conn_get_rsrc_teardown(const struct testcase_t *tc, void *arg); @@ -179,52 +174,6 @@ test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg) return 0; } -static void * -test_conn_get_rend_setup(const struct testcase_t *tc) -{ - dir_connection_t *conn = DOWNCAST(dir_connection_t, - test_conn_get_connection( - TEST_CONN_STATE, - TEST_CONN_TYPE, - TEST_CONN_REND_PURPOSE)); - tt_assert(conn); - assert_connection_ok(&conn->base_, time(NULL)); - - rend_cache_init(); - - /* TODO: use directory_initiate_request() to do this - maybe? */ - tor_assert(strlen(TEST_CONN_REND_ADDR) == REND_SERVICE_ID_LEN_BASE32); - conn->rend_data = rend_data_client_create(TEST_CONN_REND_ADDR, NULL, NULL, - REND_NO_AUTH); - assert_connection_ok(&conn->base_, time(NULL)); - return conn; - - /* On failure */ - done: - test_conn_get_rend_teardown(tc, conn); - /* Returning NULL causes the unit test to fail */ - return NULL; -} - -static int -test_conn_get_rend_teardown(const struct testcase_t *tc, void *arg) -{ - dir_connection_t *conn = DOWNCAST(dir_connection_t, arg); - int rv = 0; - - tt_assert(conn); - assert_connection_ok(&conn->base_, time(NULL)); - - /* avoid a last-ditch attempt to refetch the descriptor */ - conn->base_.purpose = TEST_CONN_REND_PURPOSE_SUCCESSFUL; - - /* connection_free_() cleans up rend_data */ - rv = test_conn_get_basic_teardown(tc, arg); - done: - rend_cache_free_all(); - return rv; -} - static dir_connection_t * test_conn_download_status_add_a_connection(const char *resource) { @@ -369,10 +318,6 @@ static struct testcase_setup_t test_conn_get_basic_st = { test_conn_get_basic_setup, test_conn_get_basic_teardown }; -static struct testcase_setup_t test_conn_get_rend_st = { - test_conn_get_rend_setup, test_conn_get_rend_teardown -}; - static struct testcase_setup_t test_conn_get_rsrc_st = { test_conn_get_rsrc_setup, test_conn_get_rsrc_teardown }; @@ -489,37 +434,6 @@ test_conn_get_basic(void *arg) ; } -static void -test_conn_get_rend(void *arg) -{ - dir_connection_t *conn = DOWNCAST(dir_connection_t, arg); - tt_assert(conn); - assert_connection_ok(&conn->base_, time(NULL)); - - tt_assert(connection_get_by_type_state_rendquery( - conn->base_.type, - conn->base_.state, - rend_data_get_address( - conn->rend_data)) - == TO_CONN(conn)); - tt_assert(connection_get_by_type_state_rendquery( - TEST_CONN_TYPE, - TEST_CONN_STATE, - TEST_CONN_REND_ADDR) - == TO_CONN(conn)); - tt_assert(connection_get_by_type_state_rendquery(TEST_CONN_REND_TYPE_2, - !conn->base_.state, - "") - == NULL); - tt_assert(connection_get_by_type_state_rendquery(TEST_CONN_REND_TYPE_2, - !TEST_CONN_STATE, - TEST_CONN_REND_ADDR_2) - == NULL); - - done: - ; -} - #define sl_is_conn_assert(sl_input, conn) \ do { \ the_sl = (sl_input); \ @@ -912,6 +826,7 @@ test_failed_orconn_tracker(void *arg) /* Prepare the OR connection that will be used in this test */ or_connection_t or_conn; + memset(&or_conn, 0, sizeof(or_conn)); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.canonical_orport.addr, "18.0.0.1")); tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&or_conn.base_.addr, "18.0.0.1")); @@ -1078,12 +993,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; @@ -1091,17 +1006,16 @@ static const unsigned int PROXY_HAPROXY_ARG = PROXY_HAPROXY; struct testcase_t connection_tests[] = { CONNECTION_TESTCASE(get_basic, TT_FORK, test_conn_get_basic_st), - CONNECTION_TESTCASE(get_rend, TT_FORK, test_conn_get_rend_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_connection.h b/src/test/test_connection.h index bf327c0a3d..dc20c500dc 100644 --- a/src/test/test_connection.h +++ b/src/test/test_connection.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TEST_CONNECTION_H diff --git a/src/test/test_conscache.c b/src/test/test_conscache.c index c805774fa3..5254efbf00 100644 --- a/src/test/test_conscache.c +++ b/src/test/test_conscache.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_consdiff.c b/src/test/test_consdiff.c index 242e2f7818..4527a6df3e 100644 --- a/src/test/test_consdiff.c +++ b/src/test/test_consdiff.c @@ -1,5 +1,5 @@ /* Copyright (c) 2014, Daniel Martà - * Copyright (c) 2014-2020, The Tor Project, Inc. */ + * Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONSDIFF_PRIVATE diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c index f4adf43549..808d6f55b6 100644 --- a/src/test/test_consdiffmgr.c +++ b/src/test/test_consdiffmgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONSDIFFMGR_PRIVATE diff --git a/src/test/test_containers.c b/src/test/test_containers.c index 6072148d1b..6d390c9584 100644 --- a/src/test/test_containers.c +++ b/src/test/test_containers.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_controller.c b/src/test/test_controller.c index 49efeb5f88..85042e9ec2 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONTROL_CMD_PRIVATE @@ -16,7 +16,6 @@ #include "feature/dircache/dirserv.h" #include "feature/hs/hs_common.h" #include "feature/nodelist/networkstatus.h" -#include "feature/rend/rendservice.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/nodelist.h" #include "feature/stats/rephist.h" @@ -317,110 +316,6 @@ test_add_onion_helper_keyarg_v3(void *arg) } static void -test_add_onion_helper_keyarg_v2(void *arg) -{ - int ret, hs_version; - add_onion_secret_key_t pk; - crypto_pk_t *pk1 = NULL; - const char *key_new_alg = NULL; - char *key_new_blob = NULL; - char *encoded = NULL; - char *arg_str = NULL; - - (void) arg; - MOCK(control_write_reply, mock_control_write_reply); - - memset(&pk, 0, sizeof(pk)); - - /* Test explicit RSA1024 key generation. */ - tor_free(reply_str); - ret = add_onion_helper_keyarg("NEW:RSA1024", 0, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, 0); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(pk.v2); - tt_str_op(key_new_alg, OP_EQ, "RSA1024"); - tt_assert(key_new_blob); - tt_ptr_op(reply_str, OP_EQ, NULL); - - /* Test discarding the private key. */ - crypto_pk_free(pk.v2); pk.v2 = NULL; - tor_free(key_new_blob); - ret = add_onion_helper_keyarg("NEW:RSA1024", 1, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, 0); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(pk.v2); - tt_ptr_op(key_new_alg, OP_EQ, NULL); - tt_ptr_op(key_new_blob, OP_EQ, NULL); - tt_ptr_op(reply_str, OP_EQ, NULL); - - /* Test generating a invalid key type. */ - crypto_pk_free(pk.v2); pk.v2 = NULL; - ret = add_onion_helper_keyarg("NEW:RSA512", 0, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, -1); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(!pk.v2); - tt_ptr_op(key_new_alg, OP_EQ, NULL); - tt_ptr_op(key_new_blob, OP_EQ, NULL); - tt_assert(reply_str); - - /* Test loading a RSA1024 key. */ - tor_free(reply_str); - pk1 = pk_generate(0); - tt_int_op(0, OP_EQ, crypto_pk_base64_encode_private(pk1, &encoded)); - tor_asprintf(&arg_str, "RSA1024:%s", encoded); - ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, 0); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(pk.v2); - tt_ptr_op(key_new_alg, OP_EQ, NULL); - tt_ptr_op(key_new_blob, OP_EQ, NULL); - tt_ptr_op(reply_str, OP_EQ, NULL); - tt_int_op(crypto_pk_cmp_keys(pk1, pk.v2), OP_EQ, 0); - - /* Test loading a invalid key type. */ - tor_free(arg_str); - crypto_pk_free(pk1); pk1 = NULL; - crypto_pk_free(pk.v2); pk.v2 = NULL; - tor_asprintf(&arg_str, "RSA512:%s", encoded); - ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, -1); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(!pk.v2); - tt_ptr_op(key_new_alg, OP_EQ, NULL); - tt_ptr_op(key_new_blob, OP_EQ, NULL); - tt_assert(reply_str); - - /* Test loading a invalid key. */ - tor_free(arg_str); - crypto_pk_free(pk.v2); pk.v2 = NULL; - tor_free(reply_str); - encoded[strlen(encoded)/2] = '\0'; - tor_asprintf(&arg_str, "RSA1024:%s", encoded); - ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob, - &pk, &hs_version, NULL); - tt_int_op(ret, OP_EQ, -1); - tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO); - tt_assert(!pk.v2); - tt_ptr_op(key_new_alg, OP_EQ, NULL); - tt_ptr_op(key_new_blob, OP_EQ, NULL); - tt_assert(reply_str); - - done: - crypto_pk_free(pk1); - crypto_pk_free(pk.v2); - tor_free(key_new_blob); - tor_free(reply_str); - tor_free(encoded); - tor_free(arg_str); - UNMOCK(control_write_reply); -} - -static void test_getinfo_helper_onion(void *arg) { (void)arg; @@ -460,50 +355,50 @@ test_getinfo_helper_onion(void *arg) } static void -test_rend_service_parse_port_config(void *arg) +test_hs_parse_port_config(void *arg) { const char *sep = ","; - rend_service_port_config_t *cfg = NULL; + hs_port_config_t *cfg = NULL; char *err_msg = NULL; (void)arg; /* Test "VIRTPORT" only. */ - cfg = rend_service_parse_port_config("80", sep, &err_msg); + cfg = hs_parse_port_config("80", sep, &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); /* Test "VIRTPORT,TARGET" (Target is port). */ - rend_service_port_config_free(cfg); - cfg = rend_service_parse_port_config("80,8080", sep, &err_msg); + hs_port_config_free(cfg); + cfg = hs_parse_port_config("80,8080", sep, &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); /* Test "VIRTPORT,TARGET" (Target is IPv4:port). */ - rend_service_port_config_free(cfg); - cfg = rend_service_parse_port_config("80,192.0.2.1:8080", sep, &err_msg); + hs_port_config_free(cfg); + cfg = hs_parse_port_config("80,192.0.2.1:8080", sep, &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); /* Test "VIRTPORT,TARGET" (Target is IPv6:port). */ - rend_service_port_config_free(cfg); - cfg = rend_service_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg); + hs_port_config_free(cfg); + cfg = hs_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); - rend_service_port_config_free(cfg); + hs_port_config_free(cfg); cfg = NULL; /* XXX: Someone should add tests for AF_UNIX targets if supported. */ /* Test empty config. */ - rend_service_port_config_free(cfg); - cfg = rend_service_parse_port_config("", sep, &err_msg); + hs_port_config_free(cfg); + cfg = hs_parse_port_config("", sep, &err_msg); tt_ptr_op(cfg, OP_EQ, NULL); tt_assert(err_msg); /* Test invalid port. */ tor_free(err_msg); - cfg = rend_service_parse_port_config("90001", sep, &err_msg); + cfg = hs_parse_port_config("90001", sep, &err_msg); tt_ptr_op(cfg, OP_EQ, NULL); tt_assert(err_msg); tor_free(err_msg); @@ -513,24 +408,24 @@ test_rend_service_parse_port_config(void *arg) /* quoted unix port */ tor_free(err_msg); - cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"", + cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar\"", " ", &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); - rend_service_port_config_free(cfg); + hs_port_config_free(cfg); cfg = NULL; /* quoted unix port */ tor_free(err_msg); - cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"", + cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar\"", " ", &err_msg); tt_assert(cfg); tt_ptr_op(err_msg, OP_EQ, NULL); - rend_service_port_config_free(cfg); + hs_port_config_free(cfg); cfg = NULL; /* quoted unix port, missing end quote */ - cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar", + cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar", " ", &err_msg); tt_ptr_op(cfg, OP_EQ, NULL); tt_str_op(err_msg, OP_EQ, "Couldn't process address <unix:\"/tmp/foo bar> " @@ -539,7 +434,7 @@ test_rend_service_parse_port_config(void *arg) /* bogus IP address */ MOCK(tor_addr_lookup, mock_tor_addr_lookup__fail_on_bad_addrs); - cfg = rend_service_parse_port_config("100 foo!!.example.com:9000", + cfg = hs_parse_port_config("100 foo!!.example.com:9000", " ", &err_msg); UNMOCK(tor_addr_lookup); tt_ptr_op(cfg, OP_EQ, NULL); @@ -548,7 +443,7 @@ test_rend_service_parse_port_config(void *arg) tor_free(err_msg); /* bogus port port */ - cfg = rend_service_parse_port_config("100 99999", + cfg = hs_parse_port_config("100 99999", " ", &err_msg); tt_ptr_op(cfg, OP_EQ, NULL); tt_str_op(err_msg, OP_EQ, "Unparseable or out-of-range port \"99999\" " @@ -556,69 +451,17 @@ test_rend_service_parse_port_config(void *arg) tor_free(err_msg); /* Wrong target address and port separation */ - cfg = rend_service_parse_port_config("80,127.0.0.1 1234", sep, + cfg = hs_parse_port_config("80,127.0.0.1 1234", sep, &err_msg); tt_ptr_op(cfg, OP_EQ, NULL); tt_assert(err_msg); tor_free(err_msg); done: - rend_service_port_config_free(cfg); + hs_port_config_free(cfg); tor_free(err_msg); } -static void -test_add_onion_helper_clientauth(void *arg) -{ - rend_authorized_client_t *client = NULL; - int created = 0; - - (void)arg; - - MOCK(control_write_reply, mock_control_write_reply); - /* Test "ClientName" only. */ - tor_free(reply_str); - client = add_onion_helper_clientauth("alice", &created, NULL); - tt_assert(client); - tt_assert(created); - tt_ptr_op(reply_str, OP_EQ, NULL); - rend_authorized_client_free(client); - - /* Test "ClientName:Blob" */ - tor_free(reply_str); - client = add_onion_helper_clientauth("alice:475hGBHPlq7Mc0cRZitK/B", - &created, NULL); - tt_assert(client); - tt_assert(!created); - tt_ptr_op(reply_str, OP_EQ, NULL); - rend_authorized_client_free(client); - - /* Test invalid client names */ - tor_free(reply_str); - client = add_onion_helper_clientauth("no*asterisks*allowed", &created, - NULL); - tt_ptr_op(client, OP_EQ, NULL); - tt_assert(reply_str); - - /* Test invalid auth cookie */ - tor_free(reply_str); - client = add_onion_helper_clientauth("alice:12345", &created, NULL); - tt_ptr_op(client, OP_EQ, NULL); - tt_assert(reply_str); - - /* Test invalid syntax */ - tor_free(reply_str); - client = add_onion_helper_clientauth(":475hGBHPlq7Mc0cRZitK/B", &created, - NULL); - tt_ptr_op(client, OP_EQ, NULL); - tt_assert(reply_str); - - done: - rend_authorized_client_free(client); - tor_free(reply_str); - UNMOCK(control_write_reply); -} - /* Mocks and data/variables used for GETINFO download status tests */ static const download_status_t dl_status_default = @@ -2209,15 +2052,11 @@ struct testcase_t controller_tests[] = { PARSER_TEST(no_args_one_obj), PARSER_TEST(no_args_kwargs), PARSER_TEST(one_arg_kwargs), - { "add_onion_helper_keyarg_v2", test_add_onion_helper_keyarg_v2, 0, - NULL, NULL }, { "add_onion_helper_keyarg_v3", test_add_onion_helper_keyarg_v3, 0, NULL, NULL }, { "getinfo_helper_onion", test_getinfo_helper_onion, 0, NULL, NULL }, - { "rend_service_parse_port_config", test_rend_service_parse_port_config, 0, + { "hs_parse_port_config", test_hs_parse_port_config, 0, NULL, NULL }, - { "add_onion_helper_clientauth", test_add_onion_helper_clientauth, 0, NULL, - NULL }, { "download_status_consensus", test_download_status_consensus, 0, NULL, NULL }, {"getinfo_helper_current_consensus_from_cache", diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c index 3cd529fa10..8abe89dc24 100644 --- a/src/test/test_controller_events.c +++ b/src/test/test_controller_events.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONNECTION_PRIVATE diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index ffd6a25bd5..87e309f25a 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_crypto_ope.c b/src/test/test_crypto_ope.c index 119ebc114a..a17af181db 100644 --- a/src/test/test_crypto_ope.c +++ b/src/test/test_crypto_ope.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_crypto_openssl.c b/src/test/test_crypto_openssl.c index 989f4a56ca..56428f2e8c 100644 --- a/src/test/test_crypto_openssl.c +++ b/src/test/test_crypto_openssl.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_crypto_rng.c b/src/test/test_crypto_rng.c index b0dc4c117c..3ae97bd499 100644 --- a/src/test/test_crypto_rng.c +++ b/src/test/test_crypto_rng.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c index 1702427b08..bcfea10cf6 100644 --- a/src/test/test_crypto_slow.c +++ b/src/test/test_crypto_slow.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_data.c b/src/test/test_data.c index 30c14fcfff..de333f1211 100644 --- a/src/test/test_data.c +++ b/src/test/test_data.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "test/test.h" diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 63cc621964..186e09f236 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -4848,9 +4848,6 @@ test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg) tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL)); tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, "foobar")); - tt_int_op(1, OP_EQ, - purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2, - ROUTER_PURPOSE_BRIDGE, NULL)); done: ; } @@ -4865,21 +4862,6 @@ test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg) } static void -test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg) -{ - (void)arg; - - tt_int_op(1, OP_EQ, purpose_needs_anonymity( - DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2, - ROUTER_PURPOSE_GENERAL, NULL)); - tt_int_op(1, OP_EQ, purpose_needs_anonymity( - DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0, NULL)); - tt_int_op(1, OP_EQ, purpose_needs_anonymity( - DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL)); - done: ; -} - -static void test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg) { (void)arg; @@ -4937,12 +4919,6 @@ test_dir_fetch_type(void *arg) tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, MICRODESC_DIRINFO); - /* This will give a warning, because this function isn't supposed to be - * used for HS descriptors. */ - setup_full_capture_of_logs(LOG_WARN); - tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_RENDDESC_V2, - ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, NO_DIRINFO); - expect_single_log_msg_containing("Unexpected purpose"); done: teardown_capture_of_logs(); } @@ -5300,10 +5276,6 @@ test_dir_conn_purpose_to_string(void *data) EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch"); EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, "consensus signature fetch"); - EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_RENDDESC_V2, - "hidden-service v2 descriptor fetch"); - EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_RENDDESC_V2, - "hidden-service v2 descriptor upload"); EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch"); /* This will give a warning, because there is no purpose 1024. */ @@ -6680,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); @@ -7286,7 +7252,6 @@ struct testcase_t dir_tests[] = { DIR(purpose_needs_anonymity_returns_true_for_bridges, 0), DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0), DIR(purpose_needs_anonymity_returns_true_by_default, 0), - DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0), DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0), DIR(post_parsing, 0), DIR(fetch_type, 0), diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c index 77e3851183..201ea900ff 100644 --- a/src/test/test_dir_common.c +++ b/src/test/test_dir_common.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_dir_common.h b/src/test/test_dir_common.h index d37496465c..12dd654812 100644 --- a/src/test/test_dir_common.h +++ b/src/test/test_dir_common.h @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TEST_DIR_COMMON_H diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 95339160c3..a7f9fa1d7b 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define RENDCOMMON_PRIVATE @@ -18,14 +18,11 @@ #include "feature/dircache/dircache.h" #include "test/test.h" #include "lib/compress/compress.h" -#include "feature/rend/rendcommon.h" -#include "feature/rend/rendcache.h" #include "feature/relay/relay_config.h" #include "feature/relay/router.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/routerlist.h" -#include "test/rend_test_helpers.h" #include "feature/nodelist/microdesc.h" #include "test/test_helpers.h" #include "feature/nodelist/nodelist.h" @@ -44,7 +41,6 @@ #include "feature/dircommon/dir_connection_st.h" #include "feature/dirclient/dir_server_st.h" #include "feature/nodelist/networkstatus_st.h" -#include "feature/rend/rend_encoded_v2_service_descriptor_st.h" #include "feature/nodelist/routerinfo_st.h" #include "feature/nodelist/routerlist_st.h" @@ -261,125 +257,6 @@ test_dir_handle_get_robots_txt(void *data) tor_free(body); } -#define RENDEZVOUS2_GET(descid) GET("/tor/rendezvous2/" descid) -static void -test_dir_handle_get_rendezvous2_not_found_if_not_encrypted(void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - (void) data; - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - - conn = new_dir_conn(); - - // connection is not encrypted - tt_assert(!connection_dir_is_encrypted(conn)); - - tt_int_op(directory_handle_command_get(conn, RENDEZVOUS2_GET(), NULL, 0), - OP_EQ, 0); - fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, - NULL, NULL, 1, 0); - - tt_str_op(NOT_FOUND, OP_EQ, header); - - done: - UNMOCK(connection_write_to_buf_impl_); - connection_free_minimal(TO_CONN(conn)); - tor_free(header); -} - -static void -test_dir_handle_get_rendezvous2_on_encrypted_conn_with_invalid_desc_id( - void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - (void) data; - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - conn = new_dir_conn(); - - // connection is encrypted - TO_CONN(conn)->linked = 1; - tt_assert(connection_dir_is_encrypted(conn)); - - tt_int_op(directory_handle_command_get(conn, - RENDEZVOUS2_GET("invalid-desc-id"), NULL, 0), OP_EQ, 0); - fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, - NULL, NULL, 1, 0); - - tt_str_op(header, OP_EQ, NOT_FOUND); - - done: - UNMOCK(connection_write_to_buf_impl_); - connection_free_minimal(TO_CONN(conn)); - tor_free(header); -} - -static void -test_dir_handle_get_rendezvous2_on_encrypted_conn_not_well_formed(void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - (void) data; - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - conn = new_dir_conn(); - - // connection is encrypted - TO_CONN(conn)->linked = 1; - tt_assert(connection_dir_is_encrypted(conn)); - - //TODO: this can't be reached because rend_valid_descriptor_id() prevents - //this case to happen. This test is the same as - //test_dir_handle_get_rendezvous2_on_encrypted_conn_with_invalid_desc_id We - //should refactor to remove the case from the switch. - - const char *req = RENDEZVOUS2_GET("1bababababababababababababababab"); - 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, - NULL, NULL, 1, 0); - - tt_str_op(header, OP_EQ, NOT_FOUND); - - done: - UNMOCK(connection_write_to_buf_impl_); - connection_free_minimal(TO_CONN(conn)); - tor_free(header); -} - -static void -test_dir_handle_get_rendezvous2_not_found(void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - (void) data; - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - conn = new_dir_conn(); - - rend_cache_init(); - - // connection is encrypted - TO_CONN(conn)->linked = 1; - tt_assert(connection_dir_is_encrypted(conn)); - - const char *req = RENDEZVOUS2_GET("3xqunszqnaolrrfmtzgaki7mxelgvkje"); - 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, - NULL, NULL, 1, 0); - - tt_str_op(NOT_FOUND, OP_EQ, header); - - done: - UNMOCK(connection_write_to_buf_impl_); - connection_free_minimal(TO_CONN(conn)); - tor_free(header); - rend_cache_free_all(); -} - static const routerinfo_t * dhg_tests_router_get_my_routerinfo(void); ATTR_UNUSED static int dhg_tests_router_get_my_routerinfo_called = 0; @@ -2864,10 +2741,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(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), - DIR_HANDLE_CMD(rendezvous2_on_encrypted_conn_not_well_formed, 0), DIR_HANDLE_CMD(micro_d_not_found, 0), DIR_HANDLE_CMD(micro_d_server_busy, 0), DIR_HANDLE_CMD(micro_d, 0), 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_dirvote.c b/src/test/test_dirvote.c index b5e57ad071..2b53955107 100644 --- a/src/test/test_dirvote.c +++ b/src/test/test_dirvote.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, The Tor Project, Inc. */ +/* Copyright (c) 2020-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -656,6 +656,30 @@ done: ROUTER_FREE(pppp); } +static void +test_dirvote_parse_param_buggy(void *arg) +{ + (void)arg; + + /* Tests for behavior with bug emulation to migrate away from bug 19011. */ + tt_i64_op(extract_param_buggy("blah blah", "bwweightscale", 10000), + OP_EQ, 10000); + tt_i64_op(extract_param_buggy("bwweightscale=7", "bwweightscale", 10000), + OP_EQ, 7); + tt_i64_op(extract_param_buggy("bwweightscale=7 foo=9", + "bwweightscale", 10000), + OP_EQ, 10000); + tt_i64_op(extract_param_buggy("foo=7 bwweightscale=777 bar=9", + "bwweightscale", 10000), + OP_EQ, 10000); + tt_i64_op(extract_param_buggy("foo=7 bwweightscale=1234", + "bwweightscale", 10000), + OP_EQ, 1234); + + done: + ; +} + #define NODE(name, flags) \ { \ #name, test_dirvote_##name, (flags), NULL, NULL \ @@ -668,4 +692,5 @@ struct testcase_t dirvote_tests[] = { NODE(get_sybil_by_ip_version_ipv4, TT_FORK), NODE(get_sybil_by_ip_version_ipv6, TT_FORK), NODE(get_all_possible_sybil, TT_FORK), + NODE(parse_param_buggy, 0), END_OF_TESTCASES}; diff --git a/src/test/test_dispatch.c b/src/test/test_dispatch.c index f7f8ecdc03..902029a85c 100644 --- a/src/test/test_dispatch.c +++ b/src/test/test_dispatch.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DISPATCH_NEW_PRIVATE diff --git a/src/test/test_dns.c b/src/test/test_dns.c index d2b0777d6b..6612391127 100644 --- a/src/test/test_dns.c +++ b/src/test/test_dns.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_dos.c b/src/test/test_dos.c index 850bbef59b..a34420024f 100644 --- a/src/test/test_dos.c +++ b/src/test/test_dos.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DOS_PRIVATE @@ -79,6 +79,9 @@ test_dos_conn_creation(void *arg) { /* Register many conns from this client but not enough to get it blocked */ unsigned int i; for (i = 0; i < max_concurrent_conns; i++) { + /* Don't trigger the connect() rate limitation so advance the clock 1 + * second for each connection. */ + update_approx_time(++now); dos_new_client_conn(&or_conn, NULL); } } @@ -470,7 +473,7 @@ test_known_relay(void *arg) GEOIP_CLIENT_CONNECT); tt_assert(entry); /* We should have a count of 0. */ - tt_uint_op(entry->dos_stats.concurrent_count, OP_EQ, 0); + tt_uint_op(entry->dos_stats.conn_stats.concurrent_count, OP_EQ, 0); /* To make sure that his is working properly, make a unknown client * connection and see if we do get it. */ @@ -483,7 +486,7 @@ test_known_relay(void *arg) GEOIP_CLIENT_CONNECT); tt_assert(entry); /* We should have a count of 2. */ - tt_uint_op(entry->dos_stats.concurrent_count, OP_EQ, 2); + tt_uint_op(entry->dos_stats.conn_stats.concurrent_count, OP_EQ, 2); done: routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md); @@ -496,11 +499,69 @@ test_known_relay(void *arg) UNMOCK(get_param_cc_enabled); } +/** Test that the connection tracker of the DoS subsystem will block clients + * who try to establish too many connections */ +static void +test_dos_conn_rate(void *arg) +{ + (void) arg; + + MOCK(get_param_cc_enabled, mock_enable_dos_protection); + MOCK(get_param_conn_enabled, mock_enable_dos_protection); + + /* Initialize test data */ + or_connection_t or_conn; + time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ + tt_int_op(AF_INET,OP_EQ, tor_addr_parse(&TO_CONN(&or_conn)->addr, + "18.0.0.1")); + tor_addr_t *addr = &TO_CONN(&or_conn)->addr; + update_approx_time(now); + + /* Get DoS subsystem limits */ + dos_init(); + uint32_t burst_conn = get_param_conn_connect_burst(NULL); + + /* Introduce new client */ + geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now); + { /* Register many conns from this client but not enough to get it blocked */ + unsigned int i; + for (i = 0; i < burst_conn - 1; i++) { + dos_new_client_conn(&or_conn, NULL); + } + } + + /* Check that new conns are still permitted */ + tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ, + dos_conn_addr_get_defense_type(addr)); + + /* Register another conn and check that new conns are not allowed anymore. + * We should have reached our burst. */ + dos_new_client_conn(&or_conn, NULL); + tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ, + dos_conn_addr_get_defense_type(addr)); + + /* Advance the time 12 hours. It should still be blocked. */ + update_approx_time(now + (12 * 60 * 60)); + tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ, + dos_conn_addr_get_defense_type(addr)); + + /* Advance the time 24 hours plus 13 hours. It should be unblocked. + * Remember, we had a random value between 24 hours and rand(24/2) thus + * adding 13 hours is safe. */ + update_approx_time(now + (37 * 60 * 60)); + tt_int_op(DOS_CONN_DEFENSE_NONE, OP_EQ, + dos_conn_addr_get_defense_type(addr)); + + done: + dos_free_all(); +} + struct testcase_t dos_tests[] = { { "conn_creation", test_dos_conn_creation, TT_FORK, NULL, NULL }, { "circuit_creation", test_dos_circuit_creation, TT_FORK, NULL, NULL }, { "bucket_refill", test_dos_bucket_refill, TT_FORK, NULL, NULL }, { "known_relay" , test_known_relay, TT_FORK, NULL, NULL }, + { "conn_rate", test_dos_conn_rate, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index 75018260f7..9ab43a90ad 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -17,7 +17,6 @@ #include "feature/nodelist/nodelist.h" #include "feature/hs/hs_cache.h" -#include "feature/rend/rendcache.h" #include "core/or/entry_connection_st.h" #include "core/or/socks_request_st.h" @@ -307,7 +306,7 @@ test_entryconn_rewrite_cached_dns_ipv4(void *arg) tor_strdup("240.240.241.241"), expires, ADDRMAPSRC_DNS, - 0, 0); + 0, 0, 0); strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); @@ -359,7 +358,7 @@ test_entryconn_rewrite_cached_dns_ipv6(void *arg) tor_strdup("[::f00f]"), expires, ADDRMAPSRC_DNS, - 0, 0); + 0, 0, 0); strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); @@ -748,7 +747,6 @@ test_entryconn_rewrite_onion_v3(void *arg) /* Make an onion connection using the SOCKS request */ conn->entry_cfg.onion_traffic = 1; ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_SOCKS_WAIT; - tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data); tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident); /* Handle SOCKS and rewrite! */ @@ -763,7 +761,6 @@ test_entryconn_rewrite_onion_v3(void *arg) "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid"); /* check that HS information got attached to the connection */ tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident); - tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data); done: hs_free_all(); diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index 589876db2a..118b66dfa7 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -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_extorport.c b/src/test/test_extorport.c index 7935530653..201a702d19 100644 --- a/src/test/test_extorport.c +++ b/src/test/test_extorport.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONNECTION_PRIVATE @@ -24,60 +24,6 @@ #include <sys/stat.h> #endif -/* Test connection_or_remove_from_ext_or_id_map and - * connection_or_set_ext_or_identifier */ -static void -test_ext_or_id_map(void *arg) -{ - or_connection_t *c1 = NULL, *c2 = NULL, *c3 = NULL; - char *idp = NULL, *idp2 = NULL; - (void)arg; - - /* pre-initialization */ - tt_ptr_op(NULL, OP_EQ, - connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx")); - - c1 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); - c2 = or_connection_new(CONN_TYPE_EXT_OR, AF_INET); - c3 = or_connection_new(CONN_TYPE_OR, AF_INET); - - tt_ptr_op(c1->ext_or_conn_id, OP_NE, NULL); - tt_ptr_op(c2->ext_or_conn_id, OP_NE, NULL); - tt_ptr_op(c3->ext_or_conn_id, OP_EQ, NULL); - - tt_ptr_op(c1, OP_EQ, connection_or_get_by_ext_or_id(c1->ext_or_conn_id)); - tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(c2->ext_or_conn_id)); - tt_ptr_op(NULL, OP_EQ, - connection_or_get_by_ext_or_id("xxxxxxxxxxxxxxxxxxxx")); - - idp = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); - - /* Give c2 a new ID. */ - connection_or_set_ext_or_identifier(c2); - tt_mem_op(idp, OP_NE, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); - idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); - tt_assert(!tor_digest_is_zero(idp2)); - - tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp)); - tt_ptr_op(c2, OP_EQ, connection_or_get_by_ext_or_id(idp2)); - - /* Now remove it. */ - connection_or_remove_from_ext_or_id_map(c2); - tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp)); - tt_ptr_op(NULL, OP_EQ, connection_or_get_by_ext_or_id(idp2)); - - done: - if (c1) - connection_free_minimal(TO_CONN(c1)); - if (c2) - connection_free_minimal(TO_CONN(c2)); - if (c3) - connection_free_minimal(TO_CONN(c3)); - tor_free(idp); - tor_free(idp2); - connection_or_clear_ext_or_id_map(); -} - /* Simple connection_write_to_buf_impl_ replacement that unconditionally * writes to outbuf. */ static void @@ -527,7 +473,7 @@ test_ext_or_handshake(void *arg) tt_int_op(handshake_start_called,OP_EQ,1); tt_int_op(TO_CONN(conn)->type, OP_EQ, CONN_TYPE_OR); tt_int_op(TO_CONN(conn)->state, OP_EQ, 0); - close_closeable_connections(); + connection_free_(TO_CONN(conn)); conn = NULL; /* Okay, this time let's succeed the handshake but fail the USERADDR @@ -581,7 +527,6 @@ test_ext_or_handshake(void *arg) } struct testcase_t extorport_tests[] = { - { "id_map", test_ext_or_id_map, TT_FORK, NULL, NULL }, { "write_command", test_ext_or_write_command, TT_FORK, NULL, NULL }, { "init_auth", test_ext_or_init_auth, TT_FORK, NULL, NULL }, { "cookie_auth", test_ext_or_cookie_auth, TT_FORK, NULL, NULL }, diff --git a/src/test/test_geoip.c b/src/test/test_geoip.c index 95afe4d6c4..b980f10096 100644 --- a/src/test/test_geoip.c +++ b/src/test/test_geoip.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c index 6019dfc2b1..77a5425cd0 100644 --- a/src/test/test_guardfraction.c +++ b/src/test/test_guardfraction.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define GUARDFRACTION_PRIVATE diff --git a/src/test/test_handles.c b/src/test/test_handles.c index dbb5b1a18e..52274558ec 100644 --- a/src/test/test_handles.c +++ b/src/test/test_handles.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index 20d4582e74..2edaa746f1 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h index f02ecbb0ac..e9695c55d5 100644 --- a/src/test/test_helpers.h +++ b/src/test/test_helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TOR_TEST_HELPERS_H diff --git a/src/test/test_hs.c b/src/test/test_hs.c deleted file mode 100644 index 46b4493a3d..0000000000 --- a/src/test/test_hs.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* Copyright (c) 2007-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file test_hs.c - * \brief Unit tests for hidden service. - **/ - -#define CONTROL_EVENTS_PRIVATE -#define CIRCUITBUILD_PRIVATE -#define RENDCOMMON_PRIVATE -#define RENDSERVICE_PRIVATE -#define HS_SERVICE_PRIVATE - -#include "core/or/or.h" -#include "test/test.h" -#include "feature/control/control.h" -#include "feature/control/control_events.h" -#include "feature/control/control_fmt.h" -#include "app/config/config.h" -#include "feature/hs/hs_common.h" -#include "feature/rend/rendcommon.h" -#include "feature/rend/rendservice.h" -#include "feature/nodelist/routerlist.h" -#include "feature/nodelist/routerset.h" -#include "core/or/circuitbuild.h" - -#include "feature/nodelist/node_st.h" -#include "feature/rend/rend_encoded_v2_service_descriptor_st.h" -#include "feature/rend/rend_intro_point_st.h" -#include "feature/nodelist/routerinfo_st.h" - -#include "test/test_helpers.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -/* mock ID digest and longname for node that's in nodelist */ -#define HSDIR_EXIST_ID "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \ - "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" -#define STR_HSDIR_EXIST_LONGNAME \ - "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=TestDir" -/* mock ID digest and longname for node that's not in nodelist */ -#define HSDIR_NONE_EXIST_ID "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" \ - "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" -#define STR_HSDIR_NONE_EXIST_LONGNAME \ - "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - -/* DuckDuckGo descriptor as an example. This one has extra "\r" at the end so - * the control port is happy. */ -static const char *hs_desc_content_control = "\ -rendezvous-service-descriptor g5ojobzupf275beh5ra72uyhb3dkpxwg\r\n\ -version 2\r\n\ -permanent-key\r\n\ ------BEGIN RSA PUBLIC KEY-----\r\n\ -MIGJAoGBAJ/SzzgrXPxTlFrKVhXh3buCWv2QfcNgncUpDpKouLn3AtPH5Ocys0jE\r\n\ -aZSKdvaiQ62md2gOwj4x61cFNdi05tdQjS+2thHKEm/KsB9BGLSLBNJYY356bupg\r\n\ -I5gQozM65ENelfxYlysBjJ52xSDBd8C4f/p9umdzaaaCmzXG/nhzAgMBAAE=\r\n\ ------END RSA PUBLIC KEY-----\r\n\ -secret-id-part anmjoxxwiupreyajjt5yasimfmwcnxlf\r\n\ -publication-time 2015-03-11 19:00:00\r\n\ -protocol-versions 2,3\r\n\ -introduction-points\r\n\ ------BEGIN MESSAGE-----\r\n\ -aW50cm9kdWN0aW9uLXBvaW50IDd1bnd4cmg2dG5kNGh6eWt1Z3EzaGZzdHduc2ll\r\n\ -cmhyCmlwLWFkZHJlc3MgMTg4LjEzOC4xMjEuMTE4Cm9uaW9uLXBvcnQgOTAwMQpv\r\n\ -bmlvbi1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dC\r\n\ -QUxGRVVyeVpDbk9ROEhURmV5cDVjMTRObWVqL1BhekFLTTBxRENTNElKUWh0Y3g1\r\n\ -NXpRSFdOVWIKQ2hHZ0JqR1RjV3ZGRnA0N3FkdGF6WUZhVXE2c0lQKzVqeWZ5b0Q4\r\n\ -UmJ1bzBwQmFWclJjMmNhYUptWWM0RDh6Vgpuby9sZnhzOVVaQnZ1cWY4eHIrMDB2\r\n\ -S0JJNmFSMlA2OE1WeDhrMExqcUpUU2RKOE9idm9yQWdNQkFBRT0KLS0tLS1FTkQg\r\n\ -UlNBIFBVQkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQ\r\n\ -VUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTnJHb0ozeTlHNXQzN2F2ekI1cTlwN1hG\r\n\ -VUplRUVYMUNOaExnWmJXWGJhVk5OcXpoZFhyL0xTUQppM1Z6dW5OaUs3cndUVnE2\r\n\ -K2QyZ1lRckhMMmIvMXBBY3ZKWjJiNSs0bTRRc0NibFpjRENXTktRbHJnRWN5WXRJ\r\n\ -CkdscXJTbFFEaXA0ZnNrUFMvNDVkWTI0QmJsQ3NGU1k3RzVLVkxJck4zZFpGbmJr\r\n\ -NEZIS1hBZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJv\r\n\ -ZHVjdGlvbi1wb2ludCBiNGM3enlxNXNheGZzN2prNXFibG1wN3I1b3pwdHRvagpp\r\n\ -cC1hZGRyZXNzIDEwOS4xNjkuNDUuMjI2Cm9uaW9uLXBvcnQgOTAwMQpvbmlvbi1r\r\n\ -ZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dCQU8xSXpw\r\n\ -WFFUTUY3RXZUb1NEUXpzVnZiRVFRQUQrcGZ6NzczMVRXZzVaUEJZY1EyUkRaeVp4\r\n\ -OEQKNUVQSU1FeUE1RE83cGd0ak5LaXJvYXJGMC8yempjMkRXTUlSaXZyU29YUWVZ\r\n\ -ZXlMM1pzKzFIajJhMDlCdkYxZAp6MEswblRFdVhoNVR5V3lyMHdsbGI1SFBnTlI0\r\n\ -MS9oYkprZzkwZitPVCtIeGhKL1duUml2QWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBV\r\n\ -QkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQVUJMSUMg\r\n\ -S0VZLS0tLS0KTUlHSkFvR0JBSzNWZEJ2ajFtQllLL3JrcHNwcm9Ub0llNUtHVmth\r\n\ -QkxvMW1tK1I2YUVJek1VZFE1SjkwNGtyRwpCd3k5NC8rV0lGNFpGYXh5Z2phejl1\r\n\ -N2pKY1k3ZGJhd1pFeG1hYXFCRlRwL2h2ZG9rcHQ4a1ByRVk4OTJPRHJ1CmJORUox\r\n\ -N1FPSmVMTVZZZk5Kcjl4TWZCQ3JQai8zOGh2RUdrbWVRNmRVWElvbVFNaUJGOVRB\r\n\ -Z01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJvZHVjdGlv\r\n\ -bi1wb2ludCBhdjVtcWl0Y2Q3cjJkandsYmN0c2Jlc2R3eGt0ZWtvegppcC1hZGRy\r\n\ -ZXNzIDE0NC43Ni44LjczCm9uaW9uLXBvcnQgNDQzCm9uaW9uLWtleQotLS0tLUJF\r\n\ -R0lOIFJTQSBQVUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTzVweVZzQmpZQmNmMXBE\r\n\ -dklHUlpmWXUzQ05nNldka0ZLMGlvdTBXTGZtejZRVDN0NWhzd3cyVwpjejlHMXhx\r\n\ -MmN0Nkd6VWkrNnVkTDlITTRVOUdHTi9BbW8wRG9GV1hKWHpBQkFXd2YyMVdsd1lW\r\n\ -eFJQMHRydi9WCkN6UDkzcHc5OG5vSmdGUGRUZ05iMjdKYmVUZENLVFBrTEtscXFt\r\n\ -b3NveUN2RitRa25vUS9BZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0t\r\n\ -LS0tCnNlcnZpY2Uta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpN\r\n\ -SUdKQW9HQkFMVjNKSmtWN3lTNU9jc1lHMHNFYzFQOTVRclFRR3ZzbGJ6Wi9zRGxl\r\n\ -RlpKYXFSOUYvYjRUVERNClNGcFMxcU1GbldkZDgxVmRGMEdYRmN2WVpLamRJdHU2\r\n\ -SndBaTRJeEhxeXZtdTRKdUxrcXNaTEFLaXRLVkx4eGsKeERlMjlDNzRWMmJrOTRJ\r\n\ -MEgybTNKS2tzTHVwc3VxWWRVUmhOVXN0SElKZmgyZmNIalF0bEFnTUJBQUU9Ci0t\r\n\ -LS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0KCg==\r\n\ ------END MESSAGE-----\r\n\ -signature\r\n\ ------BEGIN SIGNATURE-----\r\n\ -d4OuCE5OLAOnRB6cQN6WyMEmg/BHem144Vec+eYgeWoKwx3MxXFplUjFxgnMlmwN\r\n\ -PcftsZf2ztN0sbNCtPgDL3d0PqvxY3iHTQAI8EbaGq/IAJUZ8U4y963dD5+Bn6JQ\r\n\ -myE3ctmh0vy5+QxSiRjmQBkuEpCyks7LvWvHYrhnmcg=\r\n\ ------END SIGNATURE-----"; - -/* DuckDuckGo descriptor as an example. */ -static const char *hs_desc_content = "\ -rendezvous-service-descriptor g5ojobzupf275beh5ra72uyhb3dkpxwg\n\ -version 2\n\ -permanent-key\n\ ------BEGIN RSA PUBLIC KEY-----\n\ -MIGJAoGBAJ/SzzgrXPxTlFrKVhXh3buCWv2QfcNgncUpDpKouLn3AtPH5Ocys0jE\n\ -aZSKdvaiQ62md2gOwj4x61cFNdi05tdQjS+2thHKEm/KsB9BGLSLBNJYY356bupg\n\ -I5gQozM65ENelfxYlysBjJ52xSDBd8C4f/p9umdzaaaCmzXG/nhzAgMBAAE=\n\ ------END RSA PUBLIC KEY-----\n\ -secret-id-part anmjoxxwiupreyajjt5yasimfmwcnxlf\n\ -publication-time 2015-03-11 19:00:00\n\ -protocol-versions 2,3\n\ -introduction-points\n\ ------BEGIN MESSAGE-----\n\ -aW50cm9kdWN0aW9uLXBvaW50IDd1bnd4cmg2dG5kNGh6eWt1Z3EzaGZzdHduc2ll\n\ -cmhyCmlwLWFkZHJlc3MgMTg4LjEzOC4xMjEuMTE4Cm9uaW9uLXBvcnQgOTAwMQpv\n\ -bmlvbi1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dC\n\ -QUxGRVVyeVpDbk9ROEhURmV5cDVjMTRObWVqL1BhekFLTTBxRENTNElKUWh0Y3g1\n\ -NXpRSFdOVWIKQ2hHZ0JqR1RjV3ZGRnA0N3FkdGF6WUZhVXE2c0lQKzVqeWZ5b0Q4\n\ -UmJ1bzBwQmFWclJjMmNhYUptWWM0RDh6Vgpuby9sZnhzOVVaQnZ1cWY4eHIrMDB2\n\ -S0JJNmFSMlA2OE1WeDhrMExqcUpUU2RKOE9idm9yQWdNQkFBRT0KLS0tLS1FTkQg\n\ -UlNBIFBVQkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQ\n\ -VUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTnJHb0ozeTlHNXQzN2F2ekI1cTlwN1hG\n\ -VUplRUVYMUNOaExnWmJXWGJhVk5OcXpoZFhyL0xTUQppM1Z6dW5OaUs3cndUVnE2\n\ -K2QyZ1lRckhMMmIvMXBBY3ZKWjJiNSs0bTRRc0NibFpjRENXTktRbHJnRWN5WXRJ\n\ -CkdscXJTbFFEaXA0ZnNrUFMvNDVkWTI0QmJsQ3NGU1k3RzVLVkxJck4zZFpGbmJr\n\ -NEZIS1hBZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJv\n\ -ZHVjdGlvbi1wb2ludCBiNGM3enlxNXNheGZzN2prNXFibG1wN3I1b3pwdHRvagpp\n\ -cC1hZGRyZXNzIDEwOS4xNjkuNDUuMjI2Cm9uaW9uLXBvcnQgOTAwMQpvbmlvbi1r\n\ -ZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dCQU8xSXpw\n\ -WFFUTUY3RXZUb1NEUXpzVnZiRVFRQUQrcGZ6NzczMVRXZzVaUEJZY1EyUkRaeVp4\n\ -OEQKNUVQSU1FeUE1RE83cGd0ak5LaXJvYXJGMC8yempjMkRXTUlSaXZyU29YUWVZ\n\ -ZXlMM1pzKzFIajJhMDlCdkYxZAp6MEswblRFdVhoNVR5V3lyMHdsbGI1SFBnTlI0\n\ -MS9oYkprZzkwZitPVCtIeGhKL1duUml2QWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBV\n\ -QkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQVUJMSUMg\n\ -S0VZLS0tLS0KTUlHSkFvR0JBSzNWZEJ2ajFtQllLL3JrcHNwcm9Ub0llNUtHVmth\n\ -QkxvMW1tK1I2YUVJek1VZFE1SjkwNGtyRwpCd3k5NC8rV0lGNFpGYXh5Z2phejl1\n\ -N2pKY1k3ZGJhd1pFeG1hYXFCRlRwL2h2ZG9rcHQ4a1ByRVk4OTJPRHJ1CmJORUox\n\ -N1FPSmVMTVZZZk5Kcjl4TWZCQ3JQai8zOGh2RUdrbWVRNmRVWElvbVFNaUJGOVRB\n\ -Z01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJvZHVjdGlv\n\ -bi1wb2ludCBhdjVtcWl0Y2Q3cjJkandsYmN0c2Jlc2R3eGt0ZWtvegppcC1hZGRy\n\ -ZXNzIDE0NC43Ni44LjczCm9uaW9uLXBvcnQgNDQzCm9uaW9uLWtleQotLS0tLUJF\n\ -R0lOIFJTQSBQVUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTzVweVZzQmpZQmNmMXBE\n\ -dklHUlpmWXUzQ05nNldka0ZLMGlvdTBXTGZtejZRVDN0NWhzd3cyVwpjejlHMXhx\n\ -MmN0Nkd6VWkrNnVkTDlITTRVOUdHTi9BbW8wRG9GV1hKWHpBQkFXd2YyMVdsd1lW\n\ -eFJQMHRydi9WCkN6UDkzcHc5OG5vSmdGUGRUZ05iMjdKYmVUZENLVFBrTEtscXFt\n\ -b3NveUN2RitRa25vUS9BZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0t\n\ -LS0tCnNlcnZpY2Uta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpN\n\ -SUdKQW9HQkFMVjNKSmtWN3lTNU9jc1lHMHNFYzFQOTVRclFRR3ZzbGJ6Wi9zRGxl\n\ -RlpKYXFSOUYvYjRUVERNClNGcFMxcU1GbldkZDgxVmRGMEdYRmN2WVpLamRJdHU2\n\ -SndBaTRJeEhxeXZtdTRKdUxrcXNaTEFLaXRLVkx4eGsKeERlMjlDNzRWMmJrOTRJ\n\ -MEgybTNKS2tzTHVwc3VxWWRVUmhOVXN0SElKZmgyZmNIalF0bEFnTUJBQUU9Ci0t\n\ -LS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0KCg==\n\ ------END MESSAGE-----\n\ -signature\n\ ------BEGIN SIGNATURE-----\n\ -d4OuCE5OLAOnRB6cQN6WyMEmg/BHem144Vec+eYgeWoKwx3MxXFplUjFxgnMlmwN\n\ -PcftsZf2ztN0sbNCtPgDL3d0PqvxY3iHTQAI8EbaGq/IAJUZ8U4y963dD5+Bn6JQ\n\ -myE3ctmh0vy5+QxSiRjmQBkuEpCyks7LvWvHYrhnmcg=\n\ ------END SIGNATURE-----"; - -/* Helper global variable for hidden service descriptor event test. - * It's used as a pointer to dynamically created message buffer in - * send_control_event_string_replacement function, which mocks - * send_control_event_string function. - * - * Always free it after use! */ -static char *received_msg = NULL; - -/** Mock function for send_control_event_string - */ -static void -queue_control_event_string_replacement(uint16_t event, char *msg) -{ - (void) event; - tor_free(received_msg); - received_msg = msg; -} - -/** Mock function for node_describe_longname_by_id, it returns either - * STR_HSDIR_EXIST_LONGNAME or STR_HSDIR_NONE_EXIST_LONGNAME - */ -static const char * -node_describe_longname_by_id_replacement(const char *id_digest) -{ - if (!strcmp(id_digest, HSDIR_EXIST_ID)) { - return STR_HSDIR_EXIST_LONGNAME; - } else { - return STR_HSDIR_NONE_EXIST_LONGNAME; - } -} - -/** Test that we can parse a hardcoded v2 HS desc. */ -static void -test_hs_parse_static_v2_desc(void *arg) -{ - int ret; - rend_encoded_v2_service_descriptor_t desc; - - (void) arg; - - /* Test an obviously not parseable string */ - desc.desc_str = tor_strdup("ceci n'est pas un HS descriptor"); - ret = rend_desc_v2_is_parsable(&desc); - tor_free(desc.desc_str); - tt_int_op(ret, OP_EQ, 0); - - /* Test an actual descriptor */ - desc.desc_str = tor_strdup(hs_desc_content); - ret = rend_desc_v2_is_parsable(&desc); - tor_free(desc.desc_str); - tt_int_op(ret, OP_EQ, 1); - - done: ; -} - -/** Make sure each hidden service descriptor async event generation - * - * function generates the message in expected format. - */ -static void -test_hs_desc_event(void *arg) -{ - #define STR_HS_ADDR "ajhb7kljbiru65qo" - #define STR_HS_CONTENT_DESC_ID "g5ojobzupf275beh5ra72uyhb3dkpxwg" - #define STR_DESC_ID_BASE32 "hba3gmcgpfivzfhx5rtfqkfdhv65yrj3" - - int ret; - rend_data_v2_t rend_query; - const char *expected_msg; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - - (void) arg; - MOCK(queue_control_event_string, - queue_control_event_string_replacement); - MOCK(node_describe_longname_by_id, - node_describe_longname_by_id_replacement); - - /* setup rend_query struct */ - memset(&rend_query, 0, sizeof(rend_query)); - rend_query.base_.version = 2; - strncpy(rend_query.onion_address, STR_HS_ADDR, - REND_SERVICE_ID_LEN_BASE32+1); - rend_query.auth_type = REND_NO_AUTH; - rend_query.base_.hsdirs_fp = smartlist_new(); - smartlist_add(rend_query.base_.hsdirs_fp, tor_memdup(HSDIR_EXIST_ID, - DIGEST_LEN)); - - /* Compute descriptor ID for replica 0, should be STR_DESC_ID_BASE32. */ - ret = rend_compute_v2_desc_id(rend_query.descriptor_id[0], - rend_query.onion_address, - NULL, 0, 0); - tt_int_op(ret, OP_EQ, 0); - base32_encode(desc_id_base32, sizeof(desc_id_base32), - rend_query.descriptor_id[0], DIGEST_LEN); - /* Make sure rend_compute_v2_desc_id works properly. */ - tt_mem_op(desc_id_base32, OP_EQ, STR_DESC_ID_BASE32, - sizeof(desc_id_base32)); - - /* test request event */ - control_event_hs_descriptor_requested(rend_query.onion_address, - rend_query.auth_type, HSDIR_EXIST_ID, - STR_DESC_ID_BASE32, NULL); - expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\ - STR_HSDIR_EXIST_LONGNAME " " STR_DESC_ID_BASE32 "\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* test received event */ - rend_query.auth_type = REND_BASIC_AUTH; - control_event_hsv2_descriptor_received(rend_query.onion_address, - &rend_query.base_, HSDIR_EXIST_ID); - expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\ - STR_HSDIR_EXIST_LONGNAME " " STR_DESC_ID_BASE32"\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* test failed event */ - rend_query.auth_type = REND_STEALTH_AUTH; - control_event_hsv2_descriptor_failed(&rend_query.base_, - HSDIR_NONE_EXIST_ID, - "QUERY_REJECTED"); - expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\ - STR_HSDIR_NONE_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* test invalid auth type */ - rend_query.auth_type = 999; - control_event_hsv2_descriptor_failed(&rend_query.base_, - HSDIR_EXIST_ID, - "QUERY_REJECTED"); - expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\ - STR_HSDIR_EXIST_LONGNAME " " STR_DESC_ID_BASE32\ - " REASON=QUERY_REJECTED\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* test no HSDir fingerprint type */ - rend_query.auth_type = REND_NO_AUTH; - control_event_hsv2_descriptor_failed(&rend_query.base_, NULL, - "QUERY_NO_HSDIR"); - expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" NO_AUTH " \ - "UNKNOWN REASON=QUERY_NO_HSDIR\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* test HSDir rate limited */ - rend_query.auth_type = REND_NO_AUTH; - control_event_hsv2_descriptor_failed(&rend_query.base_, NULL, - "QUERY_RATE_LIMITED"); - expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" NO_AUTH " \ - "UNKNOWN REASON=QUERY_RATE_LIMITED\r\n"; - tt_assert(received_msg); - tt_str_op(received_msg,OP_EQ, expected_msg); - tor_free(received_msg); - - /* Test invalid content with no HSDir fingerprint. */ - char *exp_msg; - control_event_hs_descriptor_content(rend_query.onion_address, - STR_HS_CONTENT_DESC_ID, NULL, NULL); - tor_asprintf(&exp_msg, "650+HS_DESC_CONTENT " STR_HS_ADDR " "\ - STR_HS_CONTENT_DESC_ID " UNKNOWN" \ - "\r\n\r\n.\r\n650 OK\r\n"); - tt_assert(received_msg); - tt_str_op(received_msg, OP_EQ, exp_msg); - tor_free(received_msg); - tor_free(exp_msg); - - /* test valid content. */ - control_event_hs_descriptor_content(rend_query.onion_address, - STR_HS_CONTENT_DESC_ID, HSDIR_EXIST_ID, - hs_desc_content_control); - tor_asprintf(&exp_msg, "650+HS_DESC_CONTENT " STR_HS_ADDR " "\ - STR_HS_CONTENT_DESC_ID " " STR_HSDIR_EXIST_LONGNAME\ - "\r\n%s\r\n.\r\n650 OK\r\n", hs_desc_content_control); - - tt_assert(received_msg); - tt_str_op(received_msg, OP_EQ, exp_msg); - tor_free(received_msg); - tor_free(exp_msg); - SMARTLIST_FOREACH(rend_query.base_.hsdirs_fp, char *, d, tor_free(d)); - smartlist_free(rend_query.base_.hsdirs_fp); - - done: - UNMOCK(queue_control_event_string); - UNMOCK(node_describe_longname_by_id); - tor_free(received_msg); -} - -/* Make sure rend_data_t is valid at creation, destruction and when - * duplicated. */ -static void -test_hs_rend_data(void *arg) -{ - int rep; - rend_data_t *client = NULL, *client_dup = NULL; - /* Binary format of a descriptor ID. */ - char desc_id[DIGEST_LEN]; - char client_cookie[REND_DESC_COOKIE_LEN]; - time_t now = time(NULL); - rend_data_t *service_dup = NULL; - rend_data_t *service = NULL; - - (void)arg; - - base32_decode(desc_id, sizeof(desc_id), STR_DESC_ID_BASE32, - REND_DESC_ID_V2_LEN_BASE32); - memset(client_cookie, 'e', sizeof(client_cookie)); - - client = rend_data_client_create(STR_HS_ADDR, desc_id, client_cookie, - REND_NO_AUTH); - tt_assert(client); - rend_data_v2_t *client_v2 = TO_REND_DATA_V2(client); - tt_int_op(client_v2->auth_type, OP_EQ, REND_NO_AUTH); - tt_str_op(client_v2->onion_address, OP_EQ, STR_HS_ADDR); - tt_mem_op(client_v2->desc_id_fetch, OP_EQ, desc_id, sizeof(desc_id)); - tt_mem_op(client_v2->descriptor_cookie, OP_EQ, client_cookie, - sizeof(client_cookie)); - tt_assert(client->hsdirs_fp); - tt_int_op(smartlist_len(client->hsdirs_fp), OP_EQ, 0); - for (rep = 0; rep < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; rep++) { - int ret = rend_compute_v2_desc_id(desc_id, client_v2->onion_address, - client_v2->descriptor_cookie, now, rep); - /* That shouldn't never fail. */ - tt_int_op(ret, OP_EQ, 0); - tt_mem_op(client_v2->descriptor_id[rep], OP_EQ, desc_id, - sizeof(desc_id)); - } - /* The rest should be zeroed because this is a client request. */ - tt_int_op(tor_digest_is_zero(client_v2->rend_pk_digest), OP_EQ, 1); - tt_int_op(tor_digest_is_zero(client->rend_cookie), OP_EQ, 1); - - /* Test dup(). */ - client_dup = rend_data_dup(client); - tt_assert(client_dup); - rend_data_v2_t *client_dup_v2 = TO_REND_DATA_V2(client_dup); - tt_int_op(client_dup_v2->auth_type, OP_EQ, client_v2->auth_type); - tt_str_op(client_dup_v2->onion_address, OP_EQ, client_v2->onion_address); - tt_mem_op(client_dup_v2->desc_id_fetch, OP_EQ, client_v2->desc_id_fetch, - sizeof(client_dup_v2->desc_id_fetch)); - tt_mem_op(client_dup_v2->descriptor_cookie, OP_EQ, - client_v2->descriptor_cookie, - sizeof(client_dup_v2->descriptor_cookie)); - - tt_assert(client_dup->hsdirs_fp); - tt_int_op(smartlist_len(client_dup->hsdirs_fp), OP_EQ, 0); - for (rep = 0; rep < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; rep++) { - tt_mem_op(client_dup_v2->descriptor_id[rep], OP_EQ, - client_v2->descriptor_id[rep], DIGEST_LEN); - } - /* The rest should be zeroed because this is a client request. */ - tt_int_op(tor_digest_is_zero(client_dup_v2->rend_pk_digest), OP_EQ, 1); - tt_int_op(tor_digest_is_zero(client_dup->rend_cookie), OP_EQ, 1); - rend_data_free(client); - client = NULL; - rend_data_free(client_dup); - client_dup = NULL; - - /* Reset state. */ - base32_decode(desc_id, sizeof(desc_id), STR_DESC_ID_BASE32, - REND_DESC_ID_V2_LEN_BASE32); - memset(client_cookie, 'e', sizeof(client_cookie)); - - /* Try with different parameters here for which some content should be - * zeroed out. */ - client = rend_data_client_create(NULL, desc_id, NULL, REND_BASIC_AUTH); - tt_assert(client); - client_v2 = TO_REND_DATA_V2(client); - tt_int_op(client_v2->auth_type, OP_EQ, REND_BASIC_AUTH); - tt_int_op(strlen(client_v2->onion_address), OP_EQ, 0); - tt_mem_op(client_v2->desc_id_fetch, OP_EQ, desc_id, sizeof(desc_id)); - tt_int_op(fast_mem_is_zero(client_v2->descriptor_cookie, - sizeof(client_v2->descriptor_cookie)), OP_EQ, 1); - tt_assert(client->hsdirs_fp); - tt_int_op(smartlist_len(client->hsdirs_fp), OP_EQ, 0); - for (rep = 0; rep < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; rep++) { - tt_int_op(tor_digest_is_zero(client_v2->descriptor_id[rep]), OP_EQ, 1); - } - /* The rest should be zeroed because this is a client request. */ - tt_int_op(tor_digest_is_zero(client_v2->rend_pk_digest), OP_EQ, 1); - tt_int_op(tor_digest_is_zero(client->rend_cookie), OP_EQ, 1); - rend_data_free(client); - client = NULL; - - /* Let's test the service object now. */ - char rend_pk_digest[DIGEST_LEN]; - uint8_t rend_cookie[DIGEST_LEN]; - memset(rend_pk_digest, 'f', sizeof(rend_pk_digest)); - memset(rend_cookie, 'g', sizeof(rend_cookie)); - - service = rend_data_service_create(STR_HS_ADDR, rend_pk_digest, - rend_cookie, REND_NO_AUTH); - tt_assert(service); - rend_data_v2_t *service_v2 = TO_REND_DATA_V2(service); - tt_int_op(service_v2->auth_type, OP_EQ, REND_NO_AUTH); - tt_str_op(service_v2->onion_address, OP_EQ, STR_HS_ADDR); - tt_mem_op(service_v2->rend_pk_digest, OP_EQ, rend_pk_digest, - sizeof(rend_pk_digest)); - tt_mem_op(service->rend_cookie, OP_EQ, rend_cookie, sizeof(rend_cookie)); - tt_assert(service->hsdirs_fp); - tt_int_op(smartlist_len(service->hsdirs_fp), OP_EQ, 0); - for (rep = 0; rep < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; rep++) { - tt_int_op(tor_digest_is_zero(service_v2->descriptor_id[rep]), OP_EQ, 1); - } - /* The rest should be zeroed because this is a service request. */ - tt_int_op(tor_digest_is_zero(service_v2->descriptor_cookie), OP_EQ, 1); - tt_int_op(tor_digest_is_zero(service_v2->desc_id_fetch), OP_EQ, 1); - - /* Test dup(). */ - service_dup = rend_data_dup(service); - rend_data_v2_t *service_dup_v2 = TO_REND_DATA_V2(service_dup); - tt_assert(service_dup); - tt_int_op(service_dup_v2->auth_type, OP_EQ, service_v2->auth_type); - tt_str_op(service_dup_v2->onion_address, OP_EQ, service_v2->onion_address); - tt_mem_op(service_dup_v2->rend_pk_digest, OP_EQ, service_v2->rend_pk_digest, - sizeof(service_dup_v2->rend_pk_digest)); - tt_mem_op(service_dup->rend_cookie, OP_EQ, service->rend_cookie, - sizeof(service_dup->rend_cookie)); - tt_assert(service_dup->hsdirs_fp); - tt_int_op(smartlist_len(service_dup->hsdirs_fp), OP_EQ, 0); - for (rep = 0; rep < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; rep++) { - tt_assert(tor_digest_is_zero(service_dup_v2->descriptor_id[rep])); - } - /* The rest should be zeroed because this is a service request. */ - tt_int_op(tor_digest_is_zero(service_dup_v2->descriptor_cookie), OP_EQ, 1); - tt_int_op(tor_digest_is_zero(service_dup_v2->desc_id_fetch), OP_EQ, 1); - - done: - rend_data_free(service); - rend_data_free(service_dup); - rend_data_free(client); - 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 = NULL; - uint8_t raw_cookie[REND_DESC_COOKIE_LEN]; - rend_auth_type_t auth_type; - char *err_msg = NULL; - 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_ptr_op(err_msg, OP_EQ, NULL); - 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_ptr_op(err_msg, OP_EQ, NULL); - 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_ptr_op(err_msg, OP_EQ, NULL); - 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: - tor_free(encoded_cookie); - tor_free(err_msg); - - return; -} - -static int mock_get_options_calls = 0; -static or_options_t *mock_options = NULL; - -static void -reset_options(or_options_t *options, int *get_options_calls) -{ - memset(options, 0, sizeof(or_options_t)); - options->TestingTorNetwork = 1; - - *get_options_calls = 0; -} - -static const or_options_t * -mock_get_options(void) -{ - ++mock_get_options_calls; - tor_assert(mock_options); - return mock_options; -} - -/* arg can't be 0 (the test fails) or 2 (the test is skipped) */ -#define CREATE_HS_DIR_NONE ((intptr_t)0x04) -#define CREATE_HS_DIR1 ((intptr_t)0x08) -#define CREATE_HS_DIR2 ((intptr_t)0x10) - -/* Test that single onion poisoning works. */ -static void -test_single_onion_poisoning(void *arg) -{ - or_options_t opt; - mock_options = &opt; - reset_options(mock_options, &mock_get_options_calls); - MOCK(get_options, mock_get_options); - - int ret = -1; - intptr_t create_dir_mask = (intptr_t)arg; - /* Get directories with a random suffix so we can repeat the tests */ - mock_options->DataDirectory = tor_strdup(get_fname_rnd("test_data_dir")); - rend_service_t *service_1 = tor_malloc_zero(sizeof(rend_service_t)); - char *dir1 = tor_strdup(get_fname_rnd("test_hs_dir1")); - rend_service_t *service_2 = tor_malloc_zero(sizeof(rend_service_t)); - char *dir2 = tor_strdup(get_fname_rnd("test_hs_dir2")); - smartlist_t *services = smartlist_new(); - char *poison_path = NULL; - char *err_msg = NULL; - - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - - /* Create the data directory, and, if the correct bit in arg is set, - * create a directory for that service. - * The data directory is required for the lockfile, which is used when - * loading keys. */ - ret = check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL); - tt_int_op(ret, OP_EQ, 0); - if (create_dir_mask & CREATE_HS_DIR1) { - ret = check_private_dir(dir1, CPD_CREATE, NULL); - tt_int_op(ret, OP_EQ, 0); - } - if (create_dir_mask & CREATE_HS_DIR2) { - ret = check_private_dir(dir2, CPD_CREATE, NULL); - tt_int_op(ret, OP_EQ, 0); - } - - service_1->directory = dir1; - service_2->directory = dir2; - /* The services own the directory pointers now */ - dir1 = dir2 = NULL; - /* Add port to service 1 */ - service_1->ports = smartlist_new(); - service_2->ports = smartlist_new(); - rend_service_port_config_t *port1 = rend_service_parse_port_config("80", " ", - &err_msg); - tt_assert(port1); - tt_ptr_op(err_msg, OP_EQ, NULL); - smartlist_add(service_1->ports, port1); - - rend_service_port_config_t *port2 = rend_service_parse_port_config("90", " ", - &err_msg); - /* Add port to service 2 */ - tt_assert(port2); - tt_ptr_op(err_msg, OP_EQ, NULL); - smartlist_add(service_2->ports, port2); - - /* No services, a service to verify, no problem! */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Either way, no problem. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Add the first service */ - ret = hs_check_service_private_dir(mock_options->User, service_1->directory, - service_1->dir_group_readable, 1); - tt_int_op(ret, OP_EQ, 0); - smartlist_add(services, service_1); - /* But don't add the second service yet. */ - - /* Service directories, but no previous keys, no problem! */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Either way, no problem. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Poison! Poison! Poison! - * This can only be done in HiddenServiceSingleHopMode. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - /* Poisoning twice is a no-op. */ - ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Poisoned service directories, but no previous keys, no problem! */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Either way, no problem. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Now add some keys, and we'll have a problem. */ - ret = rend_service_load_all_keys(services); - tt_int_op(ret, OP_EQ, 0); - - /* Poisoned service directories with previous keys are not allowed. */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_LT, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* But they are allowed if we're in non-anonymous mode. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Re-poisoning directories with existing keys is a no-op, because - * directories with existing keys are ignored. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - /* And it keeps the poison. */ - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Now add the second service: it has no key and no poison file */ - ret = hs_check_service_private_dir(mock_options->User, service_2->directory, - service_2->dir_group_readable, 1); - tt_int_op(ret, OP_EQ, 0); - smartlist_add(services, service_2); - - /* A new service, and an existing poisoned service. Not ok. */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_LT, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* But ok to add in non-anonymous mode. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Now remove the poisoning from the first service, and we have the opposite - * problem. */ - poison_path = rend_service_sos_poison_path(service_1); - tt_assert(poison_path); - ret = unlink(poison_path); - tt_int_op(ret, OP_EQ, 0); - - /* Unpoisoned service directories with previous keys are ok, as are empty - * directories. */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* But the existing unpoisoned key is not ok in non-anonymous mode, even if - * there is an empty service. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_LT, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Poisoning directories with existing keys is a no-op, because directories - * with existing keys are ignored. But the new directory should poison. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_poison_new_single_onion_dir(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - /* And the old directory remains unpoisoned. */ - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_LT, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* And the new directory should be ignored, because it has no key. */ - mock_options->HiddenServiceSingleHopMode = 0; - mock_options->HiddenServiceNonAnonymousMode = 0; - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - /* Re-poisoning directories without existing keys is a no-op. */ - mock_options->HiddenServiceSingleHopMode = 1; - mock_options->HiddenServiceNonAnonymousMode = 1; - ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); - tt_int_op(ret, OP_EQ, 0); - ret = rend_service_poison_new_single_onion_dir(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - /* And the old directory remains unpoisoned. */ - ret = rend_service_verify_single_onion_poison(service_1, mock_options); - tt_int_op(ret, OP_LT, 0); - ret = rend_service_verify_single_onion_poison(service_2, mock_options); - tt_int_op(ret, OP_EQ, 0); - - done: - /* The test harness deletes the directories at exit */ - tor_free(poison_path); - tor_free(dir1); - tor_free(dir2); - smartlist_free(services); - rend_service_free(service_1); - rend_service_free(service_2); - UNMOCK(get_options); - tor_free(mock_options->DataDirectory); - tor_free(err_msg); -} - -static rend_service_t * -helper_create_rend_service(const char *path) -{ - rend_service_t *s = tor_malloc_zero(sizeof(rend_service_t)); - s->ports = smartlist_new(); - s->intro_nodes = smartlist_new(); - s->expiring_nodes = smartlist_new(); - if (path) { - s->directory = tor_strdup(path); - } - return s; -} - -static void -test_prune_services_on_reload(void *arg) -{ - smartlist_t *new = smartlist_new(), *old = smartlist_new(); - /* Non ephemeral service. */ - rend_service_t *s1 = helper_create_rend_service("SomePath"); - /* Create a non ephemeral service with the _same_ path as so we can test the - * transfer of introduction point between the same services on reload. */ - rend_service_t *s2 = helper_create_rend_service(s1->directory); - /* Ephemeral service (directory is NULL). */ - rend_service_t *e1 = helper_create_rend_service(NULL); - rend_service_t *e2 = helper_create_rend_service(NULL); - - (void) arg; - - { - /* Add both services to the old list. */ - smartlist_add(old, s1); - smartlist_add(old, e1); - /* Only put the non ephemeral in the new list. */ - smartlist_add(new, s1); - set_rend_service_list(old); - set_rend_rend_service_staging_list(new); - rend_service_prune_list_impl_(); - /* We expect that the ephemeral one is in the new list but removed from - * the old one. */ - tt_int_op(smartlist_len(old), OP_EQ, 1); - tt_assert(smartlist_get(old, 0) == s1); - tt_int_op(smartlist_len(new), OP_EQ, 2); - tt_assert(smartlist_get(new, 0) == s1); - tt_assert(smartlist_get(new, 1) == e1); - /* Cleanup for next test. */ - smartlist_clear(new); - smartlist_clear(old); - } - - { - /* This test will make sure that only the ephemeral service is kept if the - * new list is empty. The old list should contain only the non ephemeral - * one. */ - smartlist_add(old, s1); - smartlist_add(old, e1); - set_rend_service_list(old); - set_rend_rend_service_staging_list(new); - rend_service_prune_list_impl_(); - tt_int_op(smartlist_len(old), OP_EQ, 1); - tt_assert(smartlist_get(old, 0) == s1); - tt_int_op(smartlist_len(new), OP_EQ, 1); - tt_assert(smartlist_get(new, 0) == e1); - /* Cleanup for next test. */ - smartlist_clear(new); - smartlist_clear(old); - } - - { - /* This test makes sure that the new list stays the same even from the old - * list being completely different. */ - smartlist_add(new, s1); - smartlist_add(new, e1); - set_rend_service_list(old); - set_rend_rend_service_staging_list(new); - rend_service_prune_list_impl_(); - tt_int_op(smartlist_len(old), OP_EQ, 0); - tt_int_op(smartlist_len(new), OP_EQ, 2); - tt_assert(smartlist_get(new, 0) == s1); - tt_assert(smartlist_get(new, 1) == e1); - /* Cleanup for next test. */ - smartlist_clear(new); - } - - { - rend_intro_point_t ip1; - /* This IP should be found in the s2 service after pruning. */ - smartlist_add(s1->intro_nodes, &ip1); - /* Setup our list. */ - smartlist_add(old, s1); - smartlist_add(new, s2); - set_rend_service_list(old); - set_rend_rend_service_staging_list(new); - rend_service_prune_list_impl_(); - tt_int_op(smartlist_len(old), OP_EQ, 1); - /* Intro nodes have been moved to the s2 in theory so it must be empty. */ - tt_int_op(smartlist_len(s1->intro_nodes), OP_EQ, 0); - tt_int_op(smartlist_len(new), OP_EQ, 1); - rend_service_t *elem = smartlist_get(new, 0); - tt_assert(elem); - tt_assert(elem == s2); - tt_int_op(smartlist_len(elem->intro_nodes), OP_EQ, 1); - tt_assert(smartlist_get(elem->intro_nodes, 0) == &ip1); - smartlist_clear(s1->intro_nodes); - smartlist_clear(s2->intro_nodes); - /* Cleanup for next test. */ - smartlist_clear(new); - smartlist_clear(old); - } - - { - /* Test two ephemeral services. */ - smartlist_add(old, e1); - smartlist_add(old, e2); - set_rend_service_list(old); - set_rend_rend_service_staging_list(new); - rend_service_prune_list_impl_(); - /* Check if they've all been transferred. */ - tt_int_op(smartlist_len(old), OP_EQ, 0); - tt_int_op(smartlist_len(new), OP_EQ, 2); - } - - done: - rend_service_free(s1); - rend_service_free(s2); - rend_service_free(e1); - rend_service_free(e2); - smartlist_free(new); - smartlist_free(old); -} - -struct testcase_t hs_tests[] = { - { "hs_rend_data", test_hs_rend_data, TT_FORK, - NULL, NULL }, - { "hs_parse_static_v2_desc", test_hs_parse_static_v2_desc, TT_FORK, - NULL, NULL }, - { "hs_desc_event", test_hs_desc_event, TT_FORK, - NULL, NULL }, - { "hs_auth_cookies", test_hs_auth_cookies, TT_FORK, - NULL, NULL }, - { "single_onion_poisoning_create_dir_none", test_single_onion_poisoning, - TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR_NONE) }, - { "single_onion_poisoning_create_dir1", test_single_onion_poisoning, - TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR1) }, - { "single_onion_poisoning_create_dir2", test_single_onion_poisoning, - TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR2) }, - { "single_onion_poisoning_create_dir_both", test_single_onion_poisoning, - TT_FORK, &passthrough_setup, (void*)(CREATE_HS_DIR1 | CREATE_HS_DIR2) }, - { "prune_services_on_reload", test_prune_services_on_reload, TT_FORK, - NULL, NULL }, - - END_OF_TESTCASES -}; diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index df96b2c791..25d98fa819 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,7 +14,6 @@ #include "trunnel/ed25519_cert.h" #include "feature/hs/hs_cache.h" -#include "feature/rend/rendcache.h" #include "feature/dircache/dircache.h" #include "feature/dirclient/dirclient.h" #include "feature/nodelist/networkstatus.h" @@ -51,8 +50,6 @@ init_test(void) { /* Always needed. Initialize the subsystem. */ hs_cache_init(); - /* We need the v2 cache since our OOM and cache cleanup does poke at it. */ - rend_cache_init(); } static void diff --git a/src/test/test_hs_cell.c b/src/test/test_hs_cell.c index 5406339276..cf7af8a38a 100644 --- a/src/test/test_hs_cell.c +++ b/src/test/test_hs_cell.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -20,7 +20,7 @@ #include "feature/hs/hs_service.h" /* Trunnel. */ -#include "trunnel/hs/cell_common.h" +#include "trunnel/extension.h" #include "trunnel/hs/cell_establish_intro.h" /** We simulate the creation of an outgoing ESTABLISH_INTRO cell, and then we @@ -132,7 +132,7 @@ test_gen_establish_intro_dos_ext(void *arg) ssize_t ret; hs_service_config_t config; hs_service_intro_point_t *ip = NULL; - trn_cell_extension_t *extensions = NULL; + trn_extension_t *extensions = NULL; trn_cell_extension_dos_t *dos = NULL; (void) arg; @@ -144,8 +144,8 @@ test_gen_establish_intro_dos_ext(void *arg) /* Case 1: No DoS parameters so no extension to be built. */ extensions = build_establish_intro_extensions(&config, ip); - tt_int_op(trn_cell_extension_get_num(extensions), OP_EQ, 0); - trn_cell_extension_free(extensions); + tt_int_op(trn_extension_get_num(extensions), OP_EQ, 0); + trn_extension_free(extensions); extensions = NULL; /* Case 2: Enable the DoS extension. Parameter set to 0 should indicate to @@ -153,15 +153,15 @@ test_gen_establish_intro_dos_ext(void *arg) * nonetheless in the cell. */ config.has_dos_defense_enabled = 1; extensions = build_establish_intro_extensions(&config, ip); - tt_int_op(trn_cell_extension_get_num(extensions), OP_EQ, 1); + tt_int_op(trn_extension_get_num(extensions), OP_EQ, 1); /* Validate the extension. */ - const trn_cell_extension_field_t *field = - trn_cell_extension_getconst_fields(extensions, 0); - tt_int_op(trn_cell_extension_field_get_field_type(field), OP_EQ, + const trn_extension_field_t *field = + trn_extension_getconst_fields(extensions, 0); + tt_int_op(trn_extension_field_get_field_type(field), OP_EQ, TRUNNEL_CELL_EXTENSION_TYPE_DOS); ret = trn_cell_extension_dos_parse(&dos, - trn_cell_extension_field_getconstarray_field(field), - trn_cell_extension_field_getlen_field(field)); + trn_extension_field_getconstarray_field(field), + trn_extension_field_getlen_field(field)); tt_int_op(ret, OP_EQ, 19); /* Rate per sec param. */ const trn_cell_extension_dos_param_t *param = @@ -175,21 +175,21 @@ test_gen_establish_intro_dos_ext(void *arg) TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC); tt_u64_op(trn_cell_extension_dos_param_get_value(param), OP_EQ, 0); trn_cell_extension_dos_free(dos); dos = NULL; - trn_cell_extension_free(extensions); extensions = NULL; + trn_extension_free(extensions); extensions = NULL; /* Case 3: Enable the DoS extension. Parameter set to some normal values. */ config.has_dos_defense_enabled = 1; config.intro_dos_rate_per_sec = 42; config.intro_dos_burst_per_sec = 250; extensions = build_establish_intro_extensions(&config, ip); - tt_int_op(trn_cell_extension_get_num(extensions), OP_EQ, 1); + tt_int_op(trn_extension_get_num(extensions), OP_EQ, 1); /* Validate the extension. */ - field = trn_cell_extension_getconst_fields(extensions, 0); - tt_int_op(trn_cell_extension_field_get_field_type(field), OP_EQ, + field = trn_extension_getconst_fields(extensions, 0); + tt_int_op(trn_extension_field_get_field_type(field), OP_EQ, TRUNNEL_CELL_EXTENSION_TYPE_DOS); ret = trn_cell_extension_dos_parse(&dos, - trn_cell_extension_field_getconstarray_field(field), - trn_cell_extension_field_getlen_field(field)); + trn_extension_field_getconstarray_field(field), + trn_extension_field_getlen_field(field)); tt_int_op(ret, OP_EQ, 19); /* Rate per sec param. */ param = trn_cell_extension_dos_getconst_params(dos, 0); @@ -202,12 +202,12 @@ test_gen_establish_intro_dos_ext(void *arg) TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC); tt_u64_op(trn_cell_extension_dos_param_get_value(param), OP_EQ, 250); trn_cell_extension_dos_free(dos); dos = NULL; - trn_cell_extension_free(extensions); extensions = NULL; + trn_extension_free(extensions); extensions = NULL; done: service_intro_point_free(ip); trn_cell_extension_dos_free(dos); - trn_cell_extension_free(extensions); + trn_extension_free(extensions); } struct testcase_t hs_cell_tests[] = { diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index f59b3a59cd..11a5589d21 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -19,7 +19,6 @@ #include "test/test.h" #include "test/test_helpers.h" #include "test/log_test_helpers.h" -#include "test/rend_test_helpers.h" #include "test/hs_test_helpers.h" #include "app/config/config.h" @@ -38,7 +37,6 @@ #include "feature/hs/hs_config.h" #include "feature/hs/hs_ident.h" #include "feature/hs/hs_cache.h" -#include "feature/rend/rendcache.h" #include "core/or/circuitlist.h" #include "core/or/circuitbuild.h" #include "core/or/extendinfo.h" @@ -56,6 +54,9 @@ #include "core/or/origin_circuit_st.h" #include "core/or/socks_request_st.h" +#define TOR_CONGESTION_CONTROL_PRIVATE +#include "core/or/congestion_control_common.h" + static int mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn) { @@ -137,12 +138,9 @@ helper_add_random_client_auth(const ed25519_public_key_t *service_pk) * hidden service. */ static int helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, - connection_t **conn_out, - int is_legacy) + connection_t **conn_out) { - int retval; channel_tls_t *n_chan=NULL; - rend_data_t *conn_rend_data = NULL; origin_circuit_t *or_circ = NULL; connection_t *conn = NULL; ed25519_public_key_t service_pk; @@ -151,20 +149,13 @@ helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, conn = test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT, CONN_TYPE_AP /* ??? */, 0); - if (is_legacy) { - /* Legacy: Setup rend_data of stream */ - char service_id[REND_SERVICE_ID_LEN_BASE32+1] = {0}; - TO_EDGE_CONN(conn)->rend_data = mock_rend_data(service_id); - conn_rend_data = TO_EDGE_CONN(conn)->rend_data; - } else { - /* prop224: Setup hs conn identifier on the stream */ - ed25519_secret_key_t sk; - tt_int_op(0, OP_EQ, ed25519_secret_key_generate(&sk, 0)); - tt_int_op(0, OP_EQ, ed25519_public_key_generate(&service_pk, &sk)); - - /* Setup hs_conn_identifier of stream */ - TO_EDGE_CONN(conn)->hs_ident = hs_ident_edge_conn_new(&service_pk); - } + /* prop224: Setup hs conn identifier on the stream */ + ed25519_secret_key_t sk; + tt_int_op(0, OP_EQ, ed25519_secret_key_generate(&sk, 0)); + tt_int_op(0, OP_EQ, ed25519_public_key_generate(&service_pk, &sk)); + + /* Setup hs_conn_identifier of stream */ + TO_EDGE_CONN(conn)->hs_ident = hs_ident_edge_conn_new(&service_pk); /* Make it wait for circuit */ connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn)); @@ -184,23 +175,8 @@ helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, or_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t)); or_circ->build_state->is_internal = 1; - if (is_legacy) { - /* Legacy: Setup rend data and final cpath */ - or_circ->build_state->pending_final_cpath = - tor_malloc_zero(sizeof(crypt_path_t)); - or_circ->build_state->pending_final_cpath->magic = CRYPT_PATH_MAGIC; - or_circ->build_state->pending_final_cpath->rend_dh_handshake_state = - crypto_dh_new(DH_TYPE_REND); - tt_assert( - or_circ->build_state->pending_final_cpath->rend_dh_handshake_state); - retval = crypto_dh_generate_public( - or_circ->build_state->pending_final_cpath->rend_dh_handshake_state); - tt_int_op(retval, OP_EQ, 0); - or_circ->rend_data = rend_data_dup(conn_rend_data); - } else { - /* prop224: Setup hs ident on the circuit */ - or_circ->hs_ident = hs_ident_circuit_new(&service_pk); - } + /* prop224: Setup hs ident on the circuit */ + or_circ->hs_ident = hs_ident_circuit_new(&service_pk); TO_CIRCUIT(or_circ)->state = CIRCUIT_STATE_OPEN; @@ -219,91 +195,6 @@ helper_get_circ_and_stream_for_test(origin_circuit_t **circ_out, return -1; } -/* Test: Ensure that setting up legacy e2e rendezvous circuits works - * correctly. */ -static void -test_e2e_rend_circuit_setup_legacy(void *arg) -{ - ssize_t retval; - origin_circuit_t *or_circ = NULL; - connection_t *conn = NULL; - - (void) arg; - - /** In this test we create a v2 legacy HS stream and a circuit with the same - * hidden service destination. We make the stream wait for circuits to be - * established to the hidden service, and then we complete the circuit using - * the hs_circuit_setup_e2e_rend_circ_legacy_client() function. We then - * check that the end-to-end cpath was setup correctly and that the stream - * was attached to the circuit as expected. */ - - MOCK(connection_ap_handshake_send_begin, - mock_connection_ap_handshake_send_begin); - - /* Setup */ - retval = helper_get_circ_and_stream_for_test( &or_circ, &conn, 1); - tt_int_op(retval, OP_EQ, 0); - tt_assert(or_circ); - tt_assert(conn); - - /* Check number of hops */ - retval = cpath_get_n_hops(&or_circ->cpath); - tt_int_op(retval, OP_EQ, 0); - - /* Check that our stream is not attached on any circuits */ - tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, NULL); - - /********************************************** */ - - /* Make a good RENDEZVOUS1 cell body because it needs to pass key exchange - * digest verification... */ - uint8_t rend_cell_body[DH1024_KEY_LEN+DIGEST_LEN] = {2}; - { - char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN]; - crypto_dh_t *dh_state = - or_circ->build_state->pending_final_cpath->rend_dh_handshake_state; - /* compute and overwrite digest of cell body with the right value */ - retval = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh_state, - (char*)rend_cell_body, DH1024_KEY_LEN, - keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN); - tt_int_op(retval, OP_GT, 0); - memcpy(rend_cell_body+DH1024_KEY_LEN, keys, DIGEST_LEN); - } - - /* Setup the circuit */ - retval = hs_circuit_setup_e2e_rend_circ_legacy_client(or_circ, - rend_cell_body); - tt_int_op(retval, OP_EQ, 0); - - /**********************************************/ - - /* See that a hop was added to the circuit's cpath */ - retval = cpath_get_n_hops(&or_circ->cpath); - tt_int_op(retval, OP_EQ, 1); - - /* Check the digest algo */ - tt_int_op( - crypto_digest_get_algorithm(or_circ->cpath->pvt_crypto.f_digest), - OP_EQ, DIGEST_SHA1); - tt_int_op( - crypto_digest_get_algorithm(or_circ->cpath->pvt_crypto.b_digest), - OP_EQ, DIGEST_SHA1); - tt_assert(or_circ->cpath->pvt_crypto.f_crypto); - tt_assert(or_circ->cpath->pvt_crypto.b_crypto); - - /* Ensure that circ purpose was changed */ - tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_REND_JOINED); - - /* Test that stream got attached */ - tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, TO_CIRCUIT(or_circ)); - - done: - connection_free_minimal(conn); - if (or_circ) - tor_free(TO_CIRCUIT(or_circ)->n_chan); - circuit_free_(TO_CIRCUIT(or_circ)); -} - /* Test: Ensure that setting up v3 rendezvous circuits works correctly. */ static void test_e2e_rend_circuit_setup(void *arg) @@ -326,7 +217,7 @@ test_e2e_rend_circuit_setup(void *arg) mock_connection_ap_handshake_send_begin); /* Setup */ - retval = helper_get_circ_and_stream_for_test(&or_circ, &conn, 0); + retval = helper_get_circ_and_stream_for_test(&or_circ, &conn); tt_int_op(retval, OP_EQ, 0); tt_assert(or_circ); tt_assert(conn); @@ -883,6 +774,7 @@ test_desc_has_arrived_cleanup(void *arg) (void) arg; hs_init(); + congestion_control_set_cc_enabled(); MOCK(networkstatus_get_reasonably_live_consensus, mock_networkstatus_get_reasonably_live_consensus); @@ -974,7 +866,6 @@ test_close_intro_circuits_new_desc(void *arg) (void) arg; hs_init(); - rend_cache_init(); /* This is needed because of the client cache expiration timestamp is based * on having a consensus. See cached_client_descriptor_has_expired(). */ @@ -1120,7 +1011,6 @@ test_close_intro_circuits_cache_clean(void *arg) (void) arg; hs_init(); - rend_cache_init(); /* This is needed because of the client cache expiration timestamp is based * on having a consensus. See cached_client_descriptor_has_expired(). */ @@ -1189,7 +1079,6 @@ test_close_intro_circuits_cache_clean(void *arg) circuit_free(circ); hs_descriptor_free(desc1); hs_free_all(); - rend_cache_free_all(); UNMOCK(networkstatus_get_reasonably_live_consensus); } @@ -1301,7 +1190,7 @@ test_socks_hs_errors(void *arg) /* Code path will log this exit so build it. */ ocirc->build_state->chosen_exit = extend_info_new("TestNickname", digest, NULL, NULL, NULL, &addr, - 4242); + 4242, NULL, false); /* Attach socks connection to this rendezvous circuit. */ ocirc->p_streams = ENTRY_TO_EDGE_CONN(socks_conn); /* Trigger the rendezvous failure. Timeout the circuit and free. */ @@ -1396,7 +1285,7 @@ test_close_intro_circuit_failure(void *arg) /* Code path will log this exit so build it. */ ocirc->build_state->chosen_exit = extend_info_new("TestNickname", digest, NULL, NULL, NULL, &addr, - 4242); + 4242, NULL, false); ed25519_pubkey_copy(ô->hs_ident->intro_auth_pk, &intro_kp.pubkey); /* We'll make for close the circuit for a timeout failure. It should _NOT_ @@ -1423,7 +1312,7 @@ test_close_intro_circuit_failure(void *arg) /* Code path will log this exit so build it. */ ocirc->build_state->chosen_exit = extend_info_new("TestNickname", digest, NULL, NULL, NULL, &addr, - 4242); + 4242, NULL, false); ed25519_pubkey_copy(ô->hs_ident->intro_auth_pk, &intro_kp.pubkey); /* On free, we should get an unreachable failure. */ @@ -1446,7 +1335,7 @@ test_close_intro_circuit_failure(void *arg) /* Code path will log this exit so build it. */ ocirc->build_state->chosen_exit = extend_info_new("TestNickname", digest, NULL, NULL, NULL, &addr, - 4242); + 4242, NULL, false); ed25519_pubkey_copy(ô->hs_ident->intro_auth_pk, &intro_kp.pubkey); circuit_mark_for_close(circ, END_CIRC_REASON_TIMEOUT); @@ -1554,8 +1443,6 @@ test_purge_ephemeral_client_auth(void *arg) } struct testcase_t hs_client_tests[] = { - { "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy, - TT_FORK, NULL, NULL }, { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK, NULL, NULL }, { "client_pick_intro", test_client_pick_intro, diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index fccf638a07..347a5b7174 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -787,7 +787,6 @@ test_parse_extended_hostname(void *arg) hostname_type_t type; char address1[] = "fooaddress.onion"; - char address2[] = "aaaaaaaaaaaaaaaa.onion"; char address3[] = "fooaddress.exit"; char address4[] = "www.torproject.org"; char address5[] = "foo.abcdefghijklmnop.onion"; @@ -803,9 +802,6 @@ test_parse_extended_hostname(void *arg) tt_assert(!parse_extended_hostname(address1, &type)); tt_int_op(type, OP_EQ, BAD_HOSTNAME); - tt_assert(!parse_extended_hostname(address2, &type)); - tt_int_op(type, OP_EQ, BAD_HOSTNAME); - tt_assert(parse_extended_hostname(address3, &type)); tt_int_op(type, OP_EQ, EXIT_HOSTNAME); diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c index 20e6b014ee..74f823f897 100644 --- a/src/test/test_hs_config.c +++ b/src/test/test_hs_config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -18,7 +18,6 @@ #include "feature/hs/hs_common.h" #include "feature/hs/hs_config.h" #include "feature/hs/hs_service.h" -#include "feature/rend/rendservice.h" static int helper_config_service(const char *conf, int validate_only) @@ -53,18 +52,6 @@ test_invalid_service(void *arg) teardown_capture_of_logs(); } - /* Version 2 not accepted anymore. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n"; - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, 1); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("HiddenServiceVersion must be 3, not 2"); - teardown_capture_of_logs(); - } - /* Bad value of HiddenServiceAllowUnknownPorts. */ { const char *conf = @@ -194,7 +181,6 @@ test_valid_service(void *arg) (void) arg; - /* v3. */ { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n" @@ -342,8 +328,6 @@ test_staging_service_v3(void *arg) tt_int_op(ret, OP_EQ, 0); /* Ok, we have a service in our map! Registration went well. */ tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1); - /* Make sure we don't have a magic v2 service out of this. */ - tt_int_op(rend_num_services(), OP_EQ, 0); done: hs_free_all(); diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c index 6e41c4994f..c32803b380 100644 --- a/src/test/test_hs_control.c +++ b/src/test/test_hs_control.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -7,15 +7,17 @@ **/ #define CONTROL_EVENTS_PRIVATE +#define CONTROL_CMD_PRIVATE #define HS_CLIENT_PRIVATE +#define HS_SERVICE_PRIVATE #include "core/or/or.h" #include "test/test.h" #include "test/test_helpers.h" #include "core/mainloop/connection.h" #include "feature/control/control.h" -#include "feature/control/control_events.h" #include "feature/control/control_cmd.h" +#include "feature/control/control_events.h" #include "feature/control/control_fmt.h" #include "feature/control/control_connection_st.h" #include "app/config/config.h" @@ -26,6 +28,7 @@ #include "feature/nodelist/node_st.h" #include "feature/nodelist/routerstatus_st.h" +#include "lib/container/smartlist.h" #include "lib/crypt_ops/crypto_format.h" #ifdef HAVE_SYS_STAT_H @@ -735,6 +738,130 @@ test_hs_control_add_onion_with_bad_pubkey(void *arg) tor_free(conn.current_cmd); } +/** Test that we can add the service via the control port. */ +static void +test_hs_control_add_auth_onion_service(void *arg) +{ + control_connection_t conn; + char *args = NULL, *cp1 = NULL; + size_t sz; + + (void) arg; + + hs_init(); + + memset(&conn, 0, sizeof(control_connection_t)); + TO_CONN(&conn)->outbuf = buf_new(); + conn.current_cmd = tor_strdup("ADD_ONION"); + args = tor_strdup("ED25519-V3:KLMQ4CLKwlDCHuMPn8j3od33cU5LhnrLNoZh7CWChl3VkY" + "pNAkeP5dGW8xeKR9HxQBWQ/w7Kr12lA/U8Pd/oxw== " + "ClientAuthV3=dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja " + "Flags=V3Auth Port=9735,127.0.0.1"); + handle_control_command(&conn, (uint32_t) strlen(args), args); + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, + "250-ServiceID=n35etu3yjxrqjpntmfziom5sjwspoydchmelc4xleoy4jk2u4lziz2yd\r\n" + "250-ClientAuthV3=dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja\r\n" + "250 OK\r\n"); + tor_free(args); + tor_free(cp1); + + args = tor_strdup("ED25519-V3:iIU8EBi71qE7G6UTsROU1kWN0JMrRP/YukC0Xk5WLGyil3" + "gm4u3wEBXr+/TaCpXS+65Pcdqz+PG+4+oWHLN05A== " + "ClientAuthV3=dummy Flags=V3Auth Port=9735,127.0.0.1"); + handle_control_command(&conn, (uint32_t) strlen(args), args); + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, "512 Cannot decode v3 client auth key\r\n"); + + done: + tor_free(args); + tor_free(cp1); + tor_free(conn.current_cmd); + buf_free(TO_CONN(&conn)->outbuf); + SMARTLIST_FOREACH(conn.ephemeral_onion_services, char *, + service, tor_free(service)); + smartlist_free(conn.ephemeral_onion_services); + hs_client_free_all(); +} + +/** Test that add_onion_helper_add_service can add the service. */ +static void +test_hs_control_add_onion_helper_add_service(void *arg) +{ + int hs_version_good, hs_version_bad; + add_onion_secret_key_t sk_good, sk_bad; + ed25519_public_key_t pk_good, pk_bad; + char *key_new_blob_good = NULL, *key_new_blob_bad = NULL; + const char *key_new_alg_good = NULL, *key_new_alg_bad = NULL; + hs_service_authorized_client_t *client_good, *client_bad; + smartlist_t *list_good, *list_bad; + hs_service_ht *global_map; + hs_port_config_t *portcfg; + smartlist_t *portcfgs; + char *address_out_good = NULL, *address_out_bad = NULL; + hs_service_t *service_good = NULL; + hs_service_t *service_bad = NULL; + + (void) arg; + + hs_init(); + global_map = get_hs_service_map(); + + portcfg = hs_parse_port_config("8080", ",", NULL); + portcfgs = smartlist_new(); + smartlist_add(portcfgs, portcfg); + + memset(&sk_good, 0, sizeof(sk_good)); + memset(&sk_bad, 0, sizeof(sk_bad)); + + add_onion_helper_keyarg("NEW:ED25519-V3", 0, &key_new_alg_good, + &key_new_blob_good, &sk_good, &hs_version_good, NULL); + add_onion_helper_keyarg("NEW:ED25519-V3", 0, &key_new_alg_bad, + &key_new_blob_bad, &sk_bad, &hs_version_bad, NULL); + + ed25519_public_key_generate(&pk_good, sk_good.v3); + ed25519_public_key_generate(&pk_bad, sk_bad.v3); + + client_good = parse_authorized_client_key( + "N2NU7BSRL6YODZCYPN4CREB54TYLKGIE2KYOQWLFYC23ZJVCE5DQ", LOG_INFO); + client_bad = parse_authorized_client_key("dummy", LOG_INFO); + + list_good = smartlist_new(); + smartlist_add(list_good, client_good); + + add_onion_helper_add_service(HS_VERSION_THREE, &sk_good, portcfgs, 1, 1, + list_good, &address_out_good); + + service_good = find_service(global_map, &pk_good); + tt_int_op(smartlist_len(service_good->config.clients), OP_EQ, 1); + + remove_service(global_map, service_good); + hs_service_free(service_good); + + list_bad = smartlist_new(); + smartlist_add(list_bad, client_bad); + + portcfg = hs_parse_port_config("8080", ",", NULL); + portcfgs = smartlist_new(); + smartlist_add(portcfgs, portcfg); + + add_onion_helper_add_service(HS_VERSION_THREE, &sk_bad, portcfgs, 1, 1, + list_bad, &address_out_bad); + + service_bad = find_service(global_map, &pk_bad); + + tt_int_op(smartlist_len(service_bad->config.clients), OP_EQ, 0); + + done: + tor_free(key_new_blob_good); + tor_free(key_new_blob_bad); + tor_free(address_out_good); + tor_free(address_out_bad); + + hs_service_free(service_good); + hs_service_free(service_bad); +} + struct testcase_t hs_control_tests[] = { { "hs_desc_event", test_hs_desc_event, TT_FORK, NULL, NULL }, @@ -748,6 +875,10 @@ struct testcase_t hs_control_tests[] = { test_hs_control_store_permanent_creds, TT_FORK, NULL, NULL }, { "hs_control_add_onion_with_bad_pubkey", test_hs_control_add_onion_with_bad_pubkey, TT_FORK, NULL, NULL }, + { "hs_control_add_auth_onion_service", + test_hs_control_add_auth_onion_service, TT_FORK, NULL, NULL}, + { "hs_control_add_onion_helper_add_service", + test_hs_control_add_onion_helper_add_service, TT_FORK, NULL, NULL}, END_OF_TESTCASES }; diff --git a/src/test/test_hs_descriptor.c b/src/test/test_hs_descriptor.c index b6e13c79a8..469e3c39f9 100644 --- a/src/test/test_hs_descriptor.c +++ b/src/test/test_hs_descriptor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -24,6 +24,9 @@ #include "test/log_test_helpers.h" #include "test/rng_test_helpers.h" +#define TOR_CONGESTION_CONTROL_PRIVATE +#include "core/or/congestion_control_common.h" + #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS DISABLE_GCC_WARNING("-Woverlength-strings") /* We allow huge string constants in the unit tests, but not in the code @@ -247,6 +250,8 @@ test_decode_descriptor(void *arg) (void) arg; + congestion_control_set_cc_enabled(); + ret = ed25519_keypair_generate(&signing_kp, 0); tt_int_op(ret, OP_EQ, 0); desc = hs_helper_build_hs_desc_with_ip(&signing_kp); @@ -835,6 +840,44 @@ test_build_authorized_client(void *arg) testing_disable_prefilled_rng(); } +static void +test_validate_sendme(void *arg) +{ + (void)arg; + + /* Test basic operation: factors of 2X in either direction are OK */ + cc_sendme_inc = 31; + tt_assert(congestion_control_validate_sendme_increment(15)); + tt_assert(congestion_control_validate_sendme_increment(62)); + + /* Test basic operation: Exceeding 2X fails */ + cc_sendme_inc = 31; + tt_assert(!congestion_control_validate_sendme_increment(14)); + tt_assert(!congestion_control_validate_sendme_increment(63)); + + /* Test potential overflow conditions */ + cc_sendme_inc = 129; + tt_assert(congestion_control_validate_sendme_increment(255)); + tt_assert(congestion_control_validate_sendme_increment(64)); + tt_assert(!congestion_control_validate_sendme_increment(63)); + + cc_sendme_inc = 127; + tt_assert(!congestion_control_validate_sendme_increment(255)); + tt_assert(congestion_control_validate_sendme_increment(254)); + + cc_sendme_inc = 255; + tt_assert(congestion_control_validate_sendme_increment(255)); + tt_assert(congestion_control_validate_sendme_increment(127)); + tt_assert(!congestion_control_validate_sendme_increment(126)); + + /* Test 0 case */ + cc_sendme_inc = 1; + tt_assert(!congestion_control_validate_sendme_increment(0)); + +done: + ; +} + struct testcase_t hs_descriptor[] = { /* Encoding tests. */ { "cert_encoding", test_cert_encoding, TT_FORK, @@ -855,6 +898,8 @@ struct testcase_t hs_descriptor[] = { NULL, NULL }, { "decode_bad_signature", test_decode_bad_signature, TT_FORK, NULL, NULL }, + { "validate_sendme", test_validate_sendme, TT_FORK, + NULL, NULL }, /* Misc. */ { "version", test_supported_version, TT_FORK, diff --git a/src/test/test_hs_dos.c b/src/test/test_hs_dos.c index 642513efce..70f2ef412f 100644 --- a/src/test/test_hs_dos.c +++ b/src/test/test_hs_dos.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index 5f7dfc4f84..cbcdeade92 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -21,7 +21,6 @@ #include "core/or/circuituse.h" #include "ht.h" #include "core/or/relay.h" -#include "feature/rend/rendservice.h" #include "feature/hs/hs_cell.h" #include "feature/hs/hs_circuitmap.h" @@ -34,9 +33,9 @@ #include "core/or/or_circuit_st.h" /* Trunnel. */ +#include "trunnel/extension.h" #include "trunnel/hs/cell_establish_intro.h" #include "trunnel/hs/cell_introduce1.h" -#include "trunnel/hs/cell_common.h" static size_t new_establish_intro_cell(const char *circ_nonce, @@ -160,8 +159,8 @@ helper_create_introduce1_cell(void) /* Set the cell extensions to none. */ { - trn_cell_extension_t *ext = trn_cell_extension_new(); - trn_cell_extension_set_num(ext, 0); + trn_extension_t *ext = trn_extension_new(); + trn_extension_set_num(ext, 0); trn_cell_introduce1_set_extensions(cell, ext); } @@ -535,7 +534,7 @@ test_circuitmap_free_all(void) ; } -/** Successfully register a v2 intro point and a v3 intro point. Ensure that HS +/** Successfully register a v3 intro point. Ensure that HS * circuitmap is maintained properly. */ static void test_intro_point_registration(void *arg) @@ -656,31 +655,6 @@ test_introduce1_suitable_circuit(void *arg) } static void -test_introduce1_is_legacy(void *arg) -{ - int ret; - uint8_t request[256]; - - (void) arg; - - /* For a cell to be considered legacy, according to the specification, the - * first 20 bytes MUST BE non-zero else it's a v3 cell. */ - memset(request, 'a', DIGEST_LEN); - memset(request + DIGEST_LEN, 0, sizeof(request) - DIGEST_LEN); - ret = introduce1_cell_is_legacy(request); - tt_int_op(ret, OP_EQ, 1); - - /* This is a NON legacy cell. */ - memset(request, 0, DIGEST_LEN); - memset(request + DIGEST_LEN, 'a', sizeof(request) - DIGEST_LEN); - ret = introduce1_cell_is_legacy(request); - tt_int_op(ret, OP_EQ, 0); - - done: - ; -} - -static void test_introduce1_validation(void *arg) { int ret; @@ -693,20 +667,6 @@ test_introduce1_validation(void *arg) cell = helper_create_introduce1_cell(); tt_assert(cell); -#ifndef ALL_BUGS_ARE_FATAL - /* It should NOT be a legacy cell which will trigger a BUG(). */ - memset(cell->legacy_key_id, 'a', sizeof(cell->legacy_key_id)); - tor_capture_bugs_(1); - ret = validate_introduce1_parsed_cell(cell); - tor_end_capture_bugs_(); - tt_int_op(ret, OP_EQ, -1); -#endif /* !defined(ALL_BUGS_ARE_FATAL) */ - - /* Reset legacy ID and make sure it's correct. */ - memset(cell->legacy_key_id, 0, sizeof(cell->legacy_key_id)); - ret = validate_introduce1_parsed_cell(cell); - tt_int_op(ret, OP_EQ, 0); - /* Non existing auth key type. */ cell->auth_key_type = 42; ret = validate_introduce1_parsed_cell(cell); @@ -813,35 +773,6 @@ test_received_introduce1_handling(void *arg) tt_int_op(ret, OP_EQ, 0); } - /* Valid legacy cell. */ - { - tor_free(request); - trn_cell_introduce1_free(cell); - cell = helper_create_introduce1_cell(); - uint8_t *legacy_key_id = trn_cell_introduce1_getarray_legacy_key_id(cell); - memset(legacy_key_id, 'a', DIGEST_LEN); - /* Add an arbitrary amount of data for the payload of a v2 cell. */ - size_t request_len = trn_cell_introduce1_encoded_len(cell) + 256; - tt_size_op(request_len, OP_GT, 0); - request = tor_malloc_zero(request_len + 256); - ssize_t encoded_len = - trn_cell_introduce1_encode(request, request_len, cell); - tt_int_op((int)encoded_len, OP_GT, 0); - - circ = helper_create_intro_circuit(); - or_circuit_t *service_circ = helper_create_intro_circuit(); - circuit_change_purpose(TO_CIRCUIT(service_circ), - CIRCUIT_PURPOSE_INTRO_POINT); - /* Register the circuit in the map for the auth key of the cell. */ - uint8_t token[REND_TOKEN_LEN]; - memcpy(token, legacy_key_id, sizeof(token)); - hs_circuitmap_register_intro_circ_v2_relay_side(service_circ, token); - ret = hs_intro_received_introduce1(circ, request, request_len); - circuit_free_(TO_CIRCUIT(circ)); - circuit_free_(TO_CIRCUIT(service_circ)); - tt_int_op(ret, OP_EQ, 0); - } - done: trn_cell_introduce1_free(cell); tor_free(request); @@ -1045,9 +976,6 @@ struct testcase_t hs_intropoint_tests[] = { { "introduce1_suitable_circuit", test_introduce1_suitable_circuit, TT_FORK, NULL, &test_setup}, - { "introduce1_is_legacy", - test_introduce1_is_legacy, TT_FORK, NULL, &test_setup}, - { "introduce1_validation", test_introduce1_validation, TT_FORK, NULL, &test_setup}, diff --git a/src/test/test_hs_metrics.c b/src/test/test_hs_metrics.c index 326212ae1d..8625933df7 100644 --- a/src/test/test_hs_metrics.c +++ b/src/test/test_hs_metrics.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, The Tor Project, Inc. */ +/* Copyright (c) 2020-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_hs_ntor.c b/src/test/test_hs_ntor.c index 7867740a1a..c507b95a60 100644 --- a/src/test/test_hs_ntor.c +++ b/src/test/test_hs_ntor.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_hs_ntor_cl.c b/src/test/test_hs_ntor_cl.c index 3acd7ef0bc..cbce9c45b5 100644 --- a/src/test/test_hs_ntor_cl.c +++ b/src/test/test_hs_ntor_cl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** This is a wrapper over the little-t-tor HS ntor functions. The wrapper is diff --git a/src/test/test_hs_ob.c b/src/test/test_hs_ob.c index 7f40187b5f..2f69bf31e0 100644 --- a/src/test/test_hs_ob.c +++ b/src/test/test_hs_ob.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, The Tor Project, Inc. */ +/* Copyright (c) 2020-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -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_hs_service.c b/src/test/test_hs_service.c index 287d25f825..482ee1a014 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -26,7 +26,6 @@ #include "test/test.h" #include "test/test_helpers.h" #include "test/log_test_helpers.h" -#include "test/rend_test_helpers.h" #include "test/hs_test_helpers.h" #include "core/or/or.h" @@ -58,7 +57,6 @@ #include "feature/hs/hs_service.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "feature/rend/rendservice.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/fs/dir.h" @@ -343,7 +341,6 @@ helper_create_service_with_clients(int num_clients) int i; hs_service_t *service = helper_create_service(); tt_assert(service); - service->config.is_client_auth_enabled = 1; service->config.clients = smartlist_new(); for (i = 0; i < num_clients; i++) { @@ -383,14 +380,13 @@ test_load_keys(void *arg) { int ret; char *conf = NULL; - char *hsdir_v2 = tor_strdup(get_fname("hs2")); char *hsdir_v3 = tor_strdup(get_fname("hs3")); char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1]; (void) arg; - /* We'll register two services, a v2 and a v3, then we'll load keys and - * validate that both are in a correct state. */ + /* We'll register one service then we'll load keys and validate that both + * are in a correct state. */ hs_init(); @@ -399,12 +395,6 @@ test_load_keys(void *arg) "HiddenServiceVersion %d\n" \ "HiddenServicePort 65535\n" - /* v2 service. */ - tor_asprintf(&conf, conf_fmt, hsdir_v2, HS_VERSION_TWO); - ret = helper_config_service(conf); - tor_free(conf); - tt_int_op(ret, OP_EQ, -1); - /* v3 service. */ tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE); ret = helper_config_service(conf); @@ -434,11 +424,7 @@ test_load_keys(void *arg) tt_int_op(hs_address_is_valid(addr), OP_EQ, 1); tt_str_op(addr, OP_EQ, s->onion_address); - /* Check that the is_client_auth_enabled is not set. */ - tt_assert(!s->config.is_client_auth_enabled); - done: - tor_free(hsdir_v2); tor_free(hsdir_v3); hs_free_all(); } @@ -587,9 +573,6 @@ test_load_keys_with_client_auth(void *arg) tt_int_op(smartlist_len(service->config.clients), OP_EQ, smartlist_len(pubkey_b32_list)); - /* Test that the is_client_auth_enabled flag is set. */ - tt_assert(service->config.is_client_auth_enabled); - /* Test that the keys in clients are correct. */ SMARTLIST_FOREACH_BEGIN(pubkey_b32_list, char *, pubkey_b32) { @@ -631,8 +614,8 @@ test_access_service(void *arg) (void) arg; - /* We'll register two services, a v2 and a v3, then we'll load keys and - * validate that both are in a correct state. */ + /* We'll register one service then we'll load keys and validate that both + * are in a correct state. */ hs_init(); @@ -2347,6 +2330,7 @@ test_intro2_handling(void *arg) intro_circ->cpath->prev = intro_circ->cpath; intro_circ->hs_ident = tor_malloc_zero(sizeof(*intro_circ->hs_ident)); origin_circuit_t rend_circ; + TO_CIRCUIT(&rend_circ)->ccontrol = NULL; rend_circ.hs_ident = tor_malloc_zero(sizeof(*rend_circ.hs_ident)); curve25519_keypair_generate(&rend_circ.hs_ident->rendezvous_client_kp, 0); memset(rend_circ.hs_ident->rendezvous_cookie, 'r', HS_REND_COOKIE_LEN); diff --git a/src/test/test_include.sh b/src/test/test_include.sh index 6cf695fe44..10d3bc502d 100755 --- a/src/test/test_include.sh +++ b/src/test/test_include.sh @@ -48,6 +48,9 @@ if "${TOR_BINARY}" --list-modules | grep -q "relay: no"; then fi tmpdir= +# For some reasons, shellcheck is not seeing that we can call this +# function from the trap below. +# shellcheck disable=SC2317 clean () { if [ -n "$tmpdir" ] && [ -d "$tmpdir" ]; then rm -rf "$tmpdir" diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c deleted file mode 100644 index 0ae78496b2..0000000000 --- a/src/test/test_introduce.c +++ /dev/null @@ -1,539 +0,0 @@ -/* Copyright (c) 2012-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -#include "orconfig.h" -#include "lib/crypt_ops/crypto_cipher.h" -#include "core/or/or.h" -#include "test/test.h" - -#define RENDSERVICE_PRIVATE -#include "feature/rend/rendservice.h" - -static uint8_t v0_test_plaintext[] = - /* 20 bytes of rendezvous point nickname */ - { 0x4e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* 20 bytes dummy rendezvous cookie */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 128 bytes dummy DH handshake data */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; - -static uint8_t v1_test_plaintext[] = - /* Version byte */ - { 0x01, - /* 42 bytes of dummy rendezvous point hex digest */ - 0x24, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, - 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, - 0x37, 0x30, 0x38, 0x30, 0x39, 0x30, 0x41, 0x30, - 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x45, 0x30, - 0x46, 0x31, 0x30, 0x31, 0x31, 0x31, 0x32, 0x31, - 0x33, 0x00, - /* 20 bytes dummy rendezvous cookie */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 128 bytes dummy DH handshake data */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; - -static uint8_t v2_test_plaintext[] = - /* Version byte */ - { 0x02, - /* 4 bytes rendezvous point's IP address */ - 0xc0, 0xa8, 0x00, 0x01, - /* 2 bytes rendezvous point's OR port */ - 0x23, 0x5a, - /* 20 bytes dummy rendezvous point's identity digest */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 2 bytes length of onion key */ - 0x00, 0x8c, - /* Onion key (140 bytes taken from live test) */ - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb1, - 0xcd, 0x46, 0xa9, 0x18, 0xd2, 0x0f, 0x01, 0xf8, - 0xb2, 0xad, 0xa4, 0x79, 0xb4, 0xbb, 0x4b, 0xf4, - 0x54, 0x1e, 0x3f, 0x03, 0x54, 0xcf, 0x7c, 0xb6, - 0xb5, 0xf0, 0xfe, 0xed, 0x4b, 0x7d, 0xd7, 0x61, - 0xdb, 0x6d, 0xd9, 0x19, 0xe2, 0x72, 0x04, 0xaa, - 0x3e, 0x89, 0x26, 0x14, 0x62, 0x9a, 0x6c, 0x11, - 0x0b, 0x35, 0x99, 0x2c, 0x9f, 0x2c, 0x64, 0xa1, - 0xd9, 0xe2, 0x88, 0xce, 0xf6, 0x54, 0xfe, 0x1d, - 0x37, 0x5e, 0x6d, 0x73, 0x95, 0x54, 0x90, 0xf0, - 0x7b, 0xfa, 0xd4, 0x44, 0xac, 0xb2, 0x23, 0x9f, - 0x75, 0x36, 0xe2, 0x78, 0x62, 0x82, 0x80, 0xa4, - 0x23, 0x22, 0xc9, 0xbf, 0xc4, 0x36, 0xd1, 0x31, - 0x33, 0x8e, 0x64, 0xb4, 0xa9, 0x74, 0xa1, 0xcb, - 0x42, 0x8d, 0x60, 0xc7, 0xbb, 0x8e, 0x6e, 0x0f, - 0x36, 0x74, 0x8e, 0xf4, 0x08, 0x99, 0x06, 0x92, - 0xb1, 0x3f, 0xb3, 0xdd, 0xed, 0xf7, 0xc9, 0x02, - 0x03, 0x01, 0x00, 0x01, - /* 20 bytes dummy rendezvous cookie */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 128 bytes dummy DH handshake data */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; - -static uint8_t v3_no_auth_test_plaintext[] = - /* Version byte */ - { 0x03, - /* Auth type (0 for no auth len/auth data) */ - 0x00, - /* Timestamp */ - 0x50, 0x0b, 0xb5, 0xaa, - /* 4 bytes rendezvous point's IP address */ - 0xc0, 0xa8, 0x00, 0x01, - /* 2 bytes rendezvous point's OR port */ - 0x23, 0x5a, - /* 20 bytes dummy rendezvous point's identity digest */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 2 bytes length of onion key */ - 0x00, 0x8c, - /* Onion key (140 bytes taken from live test) */ - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb1, - 0xcd, 0x46, 0xa9, 0x18, 0xd2, 0x0f, 0x01, 0xf8, - 0xb2, 0xad, 0xa4, 0x79, 0xb4, 0xbb, 0x4b, 0xf4, - 0x54, 0x1e, 0x3f, 0x03, 0x54, 0xcf, 0x7c, 0xb6, - 0xb5, 0xf0, 0xfe, 0xed, 0x4b, 0x7d, 0xd7, 0x61, - 0xdb, 0x6d, 0xd9, 0x19, 0xe2, 0x72, 0x04, 0xaa, - 0x3e, 0x89, 0x26, 0x14, 0x62, 0x9a, 0x6c, 0x11, - 0x0b, 0x35, 0x99, 0x2c, 0x9f, 0x2c, 0x64, 0xa1, - 0xd9, 0xe2, 0x88, 0xce, 0xf6, 0x54, 0xfe, 0x1d, - 0x37, 0x5e, 0x6d, 0x73, 0x95, 0x54, 0x90, 0xf0, - 0x7b, 0xfa, 0xd4, 0x44, 0xac, 0xb2, 0x23, 0x9f, - 0x75, 0x36, 0xe2, 0x78, 0x62, 0x82, 0x80, 0xa4, - 0x23, 0x22, 0xc9, 0xbf, 0xc4, 0x36, 0xd1, 0x31, - 0x33, 0x8e, 0x64, 0xb4, 0xa9, 0x74, 0xa1, 0xcb, - 0x42, 0x8d, 0x60, 0xc7, 0xbb, 0x8e, 0x6e, 0x0f, - 0x36, 0x74, 0x8e, 0xf4, 0x08, 0x99, 0x06, 0x92, - 0xb1, 0x3f, 0xb3, 0xdd, 0xed, 0xf7, 0xc9, 0x02, - 0x03, 0x01, 0x00, 0x01, - /* 20 bytes dummy rendezvous cookie */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 128 bytes dummy DH handshake data */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; - -static uint8_t v3_basic_auth_test_plaintext[] = - /* Version byte */ - { 0x03, - /* Auth type (1 for REND_BASIC_AUTH) */ - 0x01, - /* Auth len (must be 16 bytes for REND_BASIC_AUTH) */ - 0x00, 0x10, - /* Auth data (a 16-byte dummy descriptor cookie) */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - /* Timestamp */ - 0x50, 0x0b, 0xb5, 0xaa, - /* 4 bytes rendezvous point's IP address */ - 0xc0, 0xa8, 0x00, 0x01, - /* 2 bytes rendezvous point's OR port */ - 0x23, 0x5a, - /* 20 bytes dummy rendezvous point's identity digest */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 2 bytes length of onion key */ - 0x00, 0x8c, - /* Onion key (140 bytes taken from live test) */ - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb1, - 0xcd, 0x46, 0xa9, 0x18, 0xd2, 0x0f, 0x01, 0xf8, - 0xb2, 0xad, 0xa4, 0x79, 0xb4, 0xbb, 0x4b, 0xf4, - 0x54, 0x1e, 0x3f, 0x03, 0x54, 0xcf, 0x7c, 0xb6, - 0xb5, 0xf0, 0xfe, 0xed, 0x4b, 0x7d, 0xd7, 0x61, - 0xdb, 0x6d, 0xd9, 0x19, 0xe2, 0x72, 0x04, 0xaa, - 0x3e, 0x89, 0x26, 0x14, 0x62, 0x9a, 0x6c, 0x11, - 0x0b, 0x35, 0x99, 0x2c, 0x9f, 0x2c, 0x64, 0xa1, - 0xd9, 0xe2, 0x88, 0xce, 0xf6, 0x54, 0xfe, 0x1d, - 0x37, 0x5e, 0x6d, 0x73, 0x95, 0x54, 0x90, 0xf0, - 0x7b, 0xfa, 0xd4, 0x44, 0xac, 0xb2, 0x23, 0x9f, - 0x75, 0x36, 0xe2, 0x78, 0x62, 0x82, 0x80, 0xa4, - 0x23, 0x22, 0xc9, 0xbf, 0xc4, 0x36, 0xd1, 0x31, - 0x33, 0x8e, 0x64, 0xb4, 0xa9, 0x74, 0xa1, 0xcb, - 0x42, 0x8d, 0x60, 0xc7, 0xbb, 0x8e, 0x6e, 0x0f, - 0x36, 0x74, 0x8e, 0xf4, 0x08, 0x99, 0x06, 0x92, - 0xb1, 0x3f, 0xb3, 0xdd, 0xed, 0xf7, 0xc9, 0x02, - 0x03, 0x01, 0x00, 0x01, - /* 20 bytes dummy rendezvous cookie */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, - /* 128 bytes dummy DH handshake data */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; - -static void do_decrypt_test(uint8_t *plaintext, size_t plaintext_len); -static void do_early_parse_test(uint8_t *plaintext, size_t plaintext_len); -static void do_late_parse_test(uint8_t *plaintext, size_t plaintext_len); -static void do_parse_test(uint8_t *plaintext, size_t plaintext_len, int phase); -static ssize_t make_intro_from_plaintext( - void *buf, size_t len, crypto_pk_t *key, void **cell_out); - -#define EARLY_PARSE_ONLY 1 -#define DECRYPT_ONLY 2 -#define ALL_PARSING 3 - -static void -do_early_parse_test(uint8_t *plaintext, size_t plaintext_len) -{ - do_parse_test(plaintext, plaintext_len, EARLY_PARSE_ONLY); -} - -static void -do_decrypt_test(uint8_t *plaintext, size_t plaintext_len) -{ - do_parse_test(plaintext, plaintext_len, DECRYPT_ONLY); -} - -static void -do_late_parse_test(uint8_t *plaintext, size_t plaintext_len) -{ - do_parse_test(plaintext, plaintext_len, ALL_PARSING); -} - -/** Test utility function: checks that the <b>plaintext_len</b>-byte string at - * <b>plaintext</b> is at least superficially parseable. - */ -static void -do_parse_test(uint8_t *plaintext, size_t plaintext_len, int phase) -{ - crypto_pk_t *k = NULL; - ssize_t r; - uint8_t *cell = NULL; - size_t cell_len; - rend_intro_cell_t *parsed_req = NULL; - char *err_msg = NULL; - char digest[DIGEST_LEN]; - - /* Get a key */ - k = crypto_pk_new(); - tt_assert(k); - r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_1, -1); - tt_assert(!r); - - /* Get digest for future comparison */ - r = crypto_pk_get_digest(k, digest); - tt_assert(r >= 0); - - /* Make a cell out of it */ - r = make_intro_from_plaintext( - plaintext, plaintext_len, - k, (void **)(&cell)); - tt_assert(r > 0); - tt_assert(cell); - cell_len = r; - - /* Do early parsing */ - parsed_req = rend_service_begin_parse_intro(cell, cell_len, 2, &err_msg); - tt_assert(parsed_req); - tt_ptr_op(err_msg, OP_EQ, NULL); - tt_mem_op(parsed_req->pk,OP_EQ, digest, DIGEST_LEN); - tt_assert(parsed_req->ciphertext); - tt_assert(parsed_req->ciphertext_len > 0); - - if (phase == EARLY_PARSE_ONLY) - goto done; - - /* Do decryption */ - r = rend_service_decrypt_intro(parsed_req, k, &err_msg); - tt_assert(!r); - tt_ptr_op(err_msg, OP_EQ, NULL); - tt_assert(parsed_req->plaintext); - tt_assert(parsed_req->plaintext_len > 0); - - if (phase == DECRYPT_ONLY) - goto done; - - /* Do late parsing */ - r = rend_service_parse_intro_plaintext(parsed_req, &err_msg); - tt_assert(!r); - tt_ptr_op(err_msg, OP_EQ, NULL); - tt_assert(parsed_req->parsed); - - done: - tor_free(cell); - crypto_pk_free(k); - rend_service_free_intro(parsed_req); - tor_free(err_msg); -} - -/** Given the plaintext of the encrypted part of an INTRODUCE1/2 and a key, - * construct the encrypted cell for testing. - */ - -static ssize_t -make_intro_from_plaintext( - void *buf, size_t len, crypto_pk_t *key, void **cell_out) -{ - char *cell = NULL; - ssize_t cell_len = -1, r; - /* Assemble key digest and ciphertext, then construct the cell */ - ssize_t ciphertext_size; - - if (!(buf && key && len > 0 && cell_out)) goto done; - - /* - * Figure out an upper bound on how big the ciphertext will be - * (see crypto_pk_obsolete_public_hybrid_encrypt()) - */ - ciphertext_size = PKCS1_OAEP_PADDING_OVERHEAD; - ciphertext_size += crypto_pk_keysize(key); - ciphertext_size += CIPHER_KEY_LEN; - ciphertext_size += len; - - /* - * Allocate space for the cell - */ - cell = tor_malloc(DIGEST_LEN + ciphertext_size); - - /* Compute key digest (will be first DIGEST_LEN octets of cell) */ - r = crypto_pk_get_digest(key, cell); - tt_assert(r >= 0); - - /* Do encryption */ - r = crypto_pk_obsolete_public_hybrid_encrypt( - key, cell + DIGEST_LEN, ciphertext_size, - buf, len, - PK_PKCS1_OAEP_PADDING, 0); - tt_assert(r >= 0); - - /* Figure out cell length */ - cell_len = DIGEST_LEN + r; - - /* Output the cell */ - *cell_out = cell; - cell = NULL; - - done: - tor_free(cell); - return cell_len; -} - -/** Test v0 INTRODUCE2 parsing through decryption only - */ - -static void -test_introduce_decrypt_v0(void *arg) -{ - (void)arg; - do_decrypt_test(v0_test_plaintext, sizeof(v0_test_plaintext)); -} - -/** Test v1 INTRODUCE2 parsing through decryption only - */ - -static void -test_introduce_decrypt_v1(void *arg) -{ - (void)arg; - do_decrypt_test(v1_test_plaintext, sizeof(v1_test_plaintext)); -} - -/** Test v2 INTRODUCE2 parsing through decryption only - */ - -static void -test_introduce_decrypt_v2(void *arg) -{ - (void)arg; - do_decrypt_test(v2_test_plaintext, sizeof(v2_test_plaintext)); -} - -/** Test v3 INTRODUCE2 parsing through decryption only - */ - -static void -test_introduce_decrypt_v3(void *arg) -{ - (void)arg; - do_decrypt_test( - v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); - do_decrypt_test( - v3_basic_auth_test_plaintext, sizeof(v3_basic_auth_test_plaintext)); -} - -/** Test v0 INTRODUCE2 parsing through early parsing only - */ - -static void -test_introduce_early_parse_v0(void *arg) -{ - (void)arg; - do_early_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext)); -} - -/** Test v1 INTRODUCE2 parsing through early parsing only - */ - -static void -test_introduce_early_parse_v1(void *arg) -{ - (void)arg; - do_early_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext)); -} - -/** Test v2 INTRODUCE2 parsing through early parsing only - */ - -static void -test_introduce_early_parse_v2(void *arg) -{ - (void)arg; - do_early_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext)); -} - -/** Test v3 INTRODUCE2 parsing through early parsing only - */ - -static void -test_introduce_early_parse_v3(void *arg) -{ - (void)arg; - do_early_parse_test( - v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); - do_early_parse_test( - v3_basic_auth_test_plaintext, sizeof(v3_basic_auth_test_plaintext)); -} - -/** Test v0 INTRODUCE2 parsing - */ - -static void -test_introduce_late_parse_v0(void *arg) -{ - (void)arg; - do_late_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext)); -} - -/** Test v1 INTRODUCE2 parsing - */ - -static void -test_introduce_late_parse_v1(void *arg) -{ - (void)arg; - do_late_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext)); -} - -/** Test v2 INTRODUCE2 parsing - */ - -static void -test_introduce_late_parse_v2(void *arg) -{ - (void)arg; - do_late_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext)); -} - -/** Test v3 INTRODUCE2 parsing - */ - -static void -test_introduce_late_parse_v3(void *arg) -{ - (void)arg; - do_late_parse_test( - v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); - do_late_parse_test( - v3_basic_auth_test_plaintext, sizeof(v3_basic_auth_test_plaintext)); -} - -#define INTRODUCE_LEGACY(name) \ - { #name, test_introduce_ ## name , 0, NULL, NULL } - -struct testcase_t introduce_tests[] = { - INTRODUCE_LEGACY(early_parse_v0), - INTRODUCE_LEGACY(early_parse_v1), - INTRODUCE_LEGACY(early_parse_v2), - INTRODUCE_LEGACY(early_parse_v3), - INTRODUCE_LEGACY(decrypt_v0), - INTRODUCE_LEGACY(decrypt_v1), - INTRODUCE_LEGACY(decrypt_v2), - INTRODUCE_LEGACY(decrypt_v3), - INTRODUCE_LEGACY(late_parse_v0), - INTRODUCE_LEGACY(late_parse_v1), - INTRODUCE_LEGACY(late_parse_v2), - INTRODUCE_LEGACY(late_parse_v3), - END_OF_TESTCASES -}; diff --git a/src/test/test_key_expiration.sh b/src/test/test_key_expiration.sh index 1ba8179aa1..2e2745e0a3 100755 --- a/src/test/test_key_expiration.sh +++ b/src/test/test_key_expiration.sh @@ -107,7 +107,7 @@ TOR="${TOR_BINARY} --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort 12345 --Ex # Step 1: Start Tor with --list-fingerprint --quiet. Make sure everything is there. echo "Setup step #1" -${TOR} --list-fingerprint ${SILENTLY} > /dev/null +${TOR} ${SILENTLY} --list-fingerprint > /dev/null check_dir "${DATA_DIR}/keys" check_file "${DATA_DIR}/keys/ed25519_master_id_public_key" diff --git a/src/test/test_keygen.sh b/src/test/test_keygen.sh index 6812f8883d..be1fde9e32 100755 --- a/src/test/test_keygen.sh +++ b/src/test/test_keygen.sh @@ -120,7 +120,7 @@ TOR="${TOR_BINARY} ${QUIETLY} --DisableNetwork 1 --ShutdownWaitLength 0 --ORPort # Step 1: Start Tor with --list-fingerprint --quiet. Make sure everything is there. mkdir "${DATA_DIR}/orig" -${TOR} --DataDirectory "${DATA_DIR}/orig" --list-fingerprint ${SILENTLY} > /dev/null +${TOR} --DataDirectory "${DATA_DIR}/orig" ${SILENTLY} --list-fingerprint > /dev/null check_dir "${DATA_DIR}/orig/keys" check_file "${DATA_DIR}/orig/keys/ed25519_master_id_public_key" @@ -206,7 +206,7 @@ SRC="${DATA_DIR}/orig" mkdir -p "${ME}/keys" cp "${SRC}/keys/ed25519_master_id_"* "${ME}/keys/" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Tor failed when starting with only master key" +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Tor failed when starting with only master key" check_files_eq "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/ed25519_master_id_public_key" check_files_eq "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/ed25519_master_id_secret_key" check_file "${ME}/keys/ed25519_signing_cert" @@ -264,11 +264,11 @@ SRC="${DATA_DIR}/orig" mkdir -p "${ME}/keys" cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} > "${ME}/fp1" || die "Tor wouldn't start with only unencrypted secret key" +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint > "${ME}/fp1" || die "Tor wouldn't start with only unencrypted secret key" check_file "${ME}/keys/ed25519_master_id_public_key" check_file "${ME}/keys/ed25519_signing_cert" check_file "${ME}/keys/ed25519_signing_secret_key" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} > "${ME}/fp2" || die "Tor wouldn't start again after starting once with only unencrypted secret key." +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint > "${ME}/fp2" || die "Tor wouldn't start again after starting once with only unencrypted secret key." check_files_eq "${ME}/fp1" "${ME}/fp2" @@ -330,7 +330,7 @@ cp "${SRC}/keys/ed25519_master_id_secret_key" "${ME}/keys/" cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/" cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with missing public key" +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with missing public key" check_keys_eq ed25519_master_id_secret_key check_keys_eq ed25519_master_id_public_key check_keys_eq ed25519_signing_secret_key @@ -352,7 +352,7 @@ cp "${SRC}/keys/ed25519_master_id_public_key" "${ME}/keys/" cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/" cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with offline secret key" +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with offline secret key" check_no_file "${ME}/keys/ed25519_master_id_secret_key" check_keys_eq ed25519_master_id_public_key check_keys_eq ed25519_signing_secret_key @@ -373,7 +373,7 @@ mkdir -p "${ME}/keys" cp "${SRC}/keys/ed25519_signing_cert" "${ME}/keys/" cp "${SRC}/keys/ed25519_signing_secret_key" "${ME}/keys/" -${TOR} --DataDirectory "${ME}" --list-fingerprint ${SILENTLY} >/dev/null || die "Failed when starting with only signing material" +${TOR} --DataDirectory "${ME}" ${SILENTLY} --list-fingerprint >/dev/null || die "Failed when starting with only signing material" check_no_file "${ME}/keys/ed25519_master_id_secret_key" check_file "${ME}/keys/ed25519_master_id_public_key" check_keys_eq ed25519_signing_secret_key diff --git a/src/test/test_keypin.c b/src/test/test_keypin.c index ff6397f8c7..7b73e94b3a 100644 --- a/src/test/test_keypin.c +++ b/src/test/test_keypin.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c index 06af299056..c9ddc843ac 100644 --- a/src/test/test_link_handshake.c +++ b/src/test/test_link_handshake.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_logging.c b/src/test/test_logging.c index 58d0f24bd3..a77136deec 100644 --- a/src/test/test_logging.c +++ b/src/test/test_logging.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONFIG_PRIVATE diff --git a/src/test/test_mainloop.c b/src/test/test_mainloop.c index c4e60d9da5..ccd3378be5 100644 --- a/src/test/test_mainloop.c +++ b/src/test/test_mainloop.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -231,6 +231,8 @@ test_mainloop_check_participation(void *arg) const time_t start = 1542658829; const time_t ONE_DAY = 24*60*60; + options->DormantTimeoutEnabled = 1; + // Suppose we've been idle for a day or two reset_user_activity(start - 2*ONE_DAY); set_network_participation(true); diff --git a/src/test/test_metrics.c b/src/test/test_metrics.c index 58628e8483..ba1a763f0c 100644 --- a/src/test/test_metrics.c +++ b/src/test/test_metrics.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, The Tor Project, Inc. */ +/* Copyright (c) 2020-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 6bd1f56859..c564805ecf 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_namemap.c b/src/test/test_namemap.c index e93d3fbc3c..4397784170 100644 --- a/src/test/test_namemap.c +++ b/src/test/test_namemap.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "test/test.h" diff --git a/src/test/test_netinfo.c b/src/test/test_netinfo.c index 93892978dc..03a7a8a905 100644 --- a/src/test/test_netinfo.c +++ b/src/test/test_netinfo.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c index 96fb5a65ad..250db9a964 100644 --- a/src/test/test_nodelist.c +++ b/src/test/test_nodelist.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_ntor_cl.c b/src/test/test_ntor_cl.c index a1508d0afc..94270f1fd6 100644 --- a/src/test/test_ntor_cl.c +++ b/src/test/test_ntor_cl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Tor Project, Inc. */ +/* Copyright (c) 2012-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_ntor_v3.c b/src/test/test_ntor_v3.c new file mode 100644 index 0000000000..1d06403076 --- /dev/null +++ b/src/test/test_ntor_v3.c @@ -0,0 +1,311 @@ +/* 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" +#include "core/crypto/onion_crypto.h" +#include "core/or/extend_info_st.h" +#include "core/or/crypt_path_st.h" +#define TOR_CONGESTION_CONTROL_PRIVATE +#include "core/or/congestion_control_common.h" +#include "app/config/config.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); +} + +static void +run_full_handshake(circuit_params_t *serv_params_in, + circuit_params_t *client_params_out, + circuit_params_t *serv_params_out) +{ + extend_info_t info = {0}; + uint8_t onionskin[CELL_PAYLOAD_SIZE]; + int onionskin_len = 0; + int reply_len = 0; + onion_handshake_state_t handshake_state = {0}; + server_onion_keys_t server_keys = {0}; + curve25519_keypair_t relay_onion_key; + uint8_t serv_reply[CELL_PAYLOAD_SIZE]; + uint8_t serv_keys[100]; + uint8_t rend_nonce[DIGEST_LEN]; + uint8_t client_keys[CELL_PAYLOAD_SIZE]; + uint8_t rend_auth[DIGEST_LEN]; + + info.exit_supports_congestion_control = 1; + + unhex(relay_onion_key.seckey.secret_key, + "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a"); + unhex(relay_onion_key.pubkey.public_key, + "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d"); + + memcpy(&info.curve25519_onion_key, + &relay_onion_key.pubkey, sizeof(info.curve25519_onion_key)); + unhex(info.ed_identity.pubkey, + "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2"); + + memcpy(&server_keys.my_ed_identity, &info.ed_identity, + sizeof(server_keys.my_ed_identity)); + + dimap_add_entry(&server_keys.curve25519_key_map, + relay_onion_key.pubkey.public_key, + &relay_onion_key); + + onionskin_len = onion_skin_create(ONION_HANDSHAKE_TYPE_NTOR_V3, &info, + &handshake_state, onionskin, + sizeof(onionskin)); + tt_int_op(onionskin_len, OP_NE, -1); + + server_keys.junk_keypair = &handshake_state.u.ntor3->client_keypair; + + reply_len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3, + onionskin, onionskin_len, + &server_keys, serv_params_in, + serv_reply, sizeof(serv_reply), + serv_keys, sizeof(serv_keys), + rend_nonce, serv_params_out); + tt_int_op(reply_len, OP_NE, -1); + + tt_int_op(onion_skin_client_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3, + &handshake_state, + serv_reply, reply_len, + client_keys, sizeof(client_keys), + rend_auth, client_params_out, + NULL), OP_EQ, 0); + + done: + dimap_free(server_keys.curve25519_key_map, NULL); + ntor3_handshake_state_free(handshake_state.u.ntor3); + + return; +} + +/** + * Test congestion control negotiation logic. + * + * This tests that congestion control is only enabled when both + * client and server agree, via consensus param or torrc. + * + * It also tests that when they agree, they agree on the server's + * version of sendme_inc. + */ +static void +test_ntor3_handshake(void *arg) +{ + (void)arg; + circuit_params_t client_params, serv_params, serv_ns_params; + + serv_ns_params.sendme_inc_cells = congestion_control_sendme_inc(); + + /* client off, serv off -> off */ + serv_ns_params.cc_enabled = 0; + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 0); + tt_int_op(serv_params.cc_enabled, OP_EQ, 0); + + /* client off, serv on -> off */ + serv_ns_params.cc_enabled = 1; + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 0); + tt_int_op(serv_params.cc_enabled, OP_EQ, 0); + + /* client off + param, serv on -> on */ + serv_ns_params.cc_enabled = 1; + get_options_mutable()->AlwaysCongestionControl = 1; + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 1); + tt_int_op(serv_params.cc_enabled, OP_EQ, 1); + + /* client on, serv off -> off */ + serv_ns_params.cc_enabled = 0; + congestion_control_set_cc_enabled(); + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 0); + tt_int_op(serv_params.cc_enabled, OP_EQ, 0); + + /* client on, serv on -> on */ + serv_ns_params.cc_enabled = 1; + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 1); + tt_int_op(serv_params.cc_enabled, OP_EQ, 1); + + /* client on, serv on, sendme_inc diff -> serv sendme_inc */ + serv_ns_params.cc_enabled = 1; + serv_ns_params.sendme_inc_cells += 1; + run_full_handshake(&serv_ns_params, &client_params, &serv_params); + tt_int_op(client_params.cc_enabled, OP_EQ, 1); + tt_int_op(serv_params.cc_enabled, OP_EQ, 1); + tt_int_op(serv_params.sendme_inc_cells, OP_EQ, + client_params.sendme_inc_cells); + tt_int_op(client_params.sendme_inc_cells, OP_EQ, + serv_ns_params.sendme_inc_cells); + tt_int_op(client_params.sendme_inc_cells, OP_NE, + congestion_control_sendme_inc()); + + done: + return; +} + +struct testcase_t ntor_v3_tests[] = { + { "testvecs", test_ntor3_testvecs, 0, NULL, NULL, }, + { "handshake_negtotiation", test_ntor3_handshake, 0, NULL, NULL, }, + END_OF_TESTCASES, +}; diff --git a/src/test/test_oom.c b/src/test/test_oom.c index 51c237ec2e..7cab0933f7 100644 --- a/src/test/test_oom.c +++ b/src/test/test_oom.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for OOM handling logic */ diff --git a/src/test/test_oos.c b/src/test/test_oos.c index f8c712a6b6..157f3aa9b3 100644 --- a/src/test/test_oos.c +++ b/src/test/test_oos.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for OOS handler */ diff --git a/src/test/test_options.c b/src/test/test_options.c index 714ee4767f..182e6dd572 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONFIG_PRIVATE @@ -302,8 +302,6 @@ test_options_validate(void *arg) "ServerTransportOptions did not parse", LOG_WARN, "\"slingsnappy\" is not a k=v", PH_VALIDATE); - WANT_ERR("DirPort 8080\nDirCache 0", - "DirPort configured but DirCache disabled.", PH_VALIDATE); WANT_ERR("BridgeRelay 1\nDirCache 0", "We're a bridge but DirCache is disabled.", PH_VALIDATE); @@ -1932,18 +1930,6 @@ test_options_validate__publish_server_descriptor(void *ignored) "PublishServerDescriptor line."); tor_free(msg); - free_options_test_data(tdata); - tdata = get_options_test_data("BridgeRelay 1\n" - "DirPort 999\n"); - - mock_clean_saved_logs(); - ret = options_validate(NULL, tdata->opt, &msg); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg("Can't set a DirPort on a bridge " - "relay; disabling DirPort\n"); - tt_assert(!tdata->opt->DirPort_lines); - tt_assert(!tdata->opt->DirPort_set); - done: teardown_capture_of_logs(); policies_free_all(); @@ -2389,14 +2375,6 @@ test_options_validate__rend(void *ignored) "Failed to configure rendezvous options. See logs for details."); tor_free(msg); - free_options_test_data(tdata); - tdata = get_options_test_data("HidServAuth failed\n"); - ret = options_validate(NULL, tdata->opt, &msg); - tt_int_op(ret, OP_EQ, -1); - tt_str_op(msg, OP_EQ, "Failed to configure client authorization for hidden " - "services. See logs for details."); - tor_free(msg); - done: policies_free_all(); teardown_capture_of_logs(); @@ -3464,35 +3442,6 @@ test_options_validate__constrained_sockets(void *ignored) "between 2048 and 262144 in 1024 byte increments."); tor_free(msg); - free_options_test_data(tdata); - tdata = get_options_test_data("ConstrainedSockets 1\n" - "ConstrainedSockSize 2048\n" - "DirPort 999\n" - "DirCache 1\n" - ); - mock_clean_saved_logs(); - ret = options_validate(NULL, tdata->opt, &msg); - tt_int_op(ret, OP_EQ, 0); - expect_log_msg("You have requested constrained " - "socket buffers while also serving directory entries via DirPort." - " It is strongly suggested that you disable serving directory" - " requests when system TCP buffer resources are scarce.\n"); - tor_free(msg); - - free_options_test_data(tdata); - tdata = get_options_test_data("ConstrainedSockets 1\n" - "ConstrainedSockSize 2048\n" - ); - mock_clean_saved_logs(); - ret = options_validate(NULL, tdata->opt, &msg); - tt_int_op(ret, OP_EQ, 0); - expect_no_log_msg( - "You have requested constrained socket buffers while also serving" - " directory entries via DirPort. It is strongly suggested that " - "you disable serving directory requests when system TCP buffer " - "resources are scarce.\n"); - tor_free(msg); - done: policies_free_all(); teardown_capture_of_logs(); diff --git a/src/test/test_options_act.c b/src/test/test_options_act.c index 942584bffd..0044598962 100644 --- a/src/test/test_options_act.c +++ b/src/test/test_options_act.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONFIG_PRIVATE diff --git a/src/test/test_parsecommon.c b/src/test/test_parsecommon.c index 9c22266da1..b32840264e 100644 --- a/src/test/test_parsecommon.c +++ b/src/test/test_parsecommon.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" @@ -326,18 +326,15 @@ test_parsecommon_get_next_token_parse_keys(void *arg) const char *end2 = str2 + strlen(str2); const char **s2 = (const char **)&str2; - token_rule_t rule2 = T01("client-key", C_CLIENT_KEY, NO_ARGS, - NEED_SKEY_1024); - + token_rule_t rule2 = T01("client-key", C_CLIENT_KEY, NO_ARGS, OBJ_OK); token2 = get_next_token(area, s2, end2, &rule2); tt_assert(token2); - tt_int_op(token2->tp, OP_EQ, C_CLIENT_KEY); tt_int_op(token2->n_args, OP_EQ, 0); tt_str_op(token2->object_type, OP_EQ, "RSA PRIVATE KEY"); tt_int_op(token2->object_size, OP_EQ, 608); tt_assert(token2->object_body); - tt_assert(token2->key); + tt_assert(token2->key == NULL); tt_assert(!token->error); done: diff --git a/src/test/test_pem.c b/src/test/test_pem.c index 9772be124b..6397cbddfa 100644 --- a/src/test/test_pem.c +++ b/src/test/test_pem.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_periodic_event.c b/src/test/test_periodic_event.c index d3bc89673b..6a9569ae89 100644 --- a/src/test/test_periodic_event.c +++ b/src/test/test_periodic_event.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 0a0548d161..97606476a6 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Tor Project, Inc. */ +/* Copyright (c) 2013-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CONFIG_PRIVATE diff --git a/src/test/test_prob_distr.c b/src/test/test_prob_distr.c index da65a0f26d..0eca435ab5 100644 --- a/src/test/test_prob_distr.c +++ b/src/test/test_prob_distr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_process.c b/src/test/test_process.c index b5185242d3..fcfbc13431 100644 --- a/src/test/test_process.c +++ b/src/test/test_process.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_process_descs.c b/src/test/test_process_descs.c index 5c2301f873..abcb6ae2fe 100644 --- a/src/test/test_process_descs.c +++ b/src/test/test_process_descs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2020, The Tor Project, Inc. */ +/* Copyright (c) 2019-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -21,9 +21,9 @@ test_process_descs_versions(void *arg) // a non-tor program: don't reject. { "Wombat 0.1.2.3-alpha", false }, // some unsupported versions: reject. + { "Tor 0.2.9.100", true }, { "Tor 0.2.9.4-alpha", true }, { "Tor 0.2.9.5-alpha", true }, - { "Tor 0.2.9.100", true }, { "Tor 0.3.0.0-alpha-dev", true }, { "Tor 0.3.0.2-alpha", true }, { "Tor 0.3.0.5", true }, @@ -34,17 +34,34 @@ test_process_descs_versions(void *arg) { "Tor 0.3.4.100", true }, { "Tor 0.3.5.1-alpha", true }, { "Tor 0.3.5.6-rc", true}, + { "Tor 0.3.5.7", true }, + { "Tor 0.3.5.8", true }, { "Tor 0.4.0.1-alpha", true }, { "Tor 0.4.0.5", true }, { "Tor 0.4.1.1-alpha", true }, { "Tor 0.4.1.4-rc", true }, { "Tor 0.4.1.5", 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.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 }, + + /* The 0.4.5.x series stable is supported. */ + { "Tor 0.4.5.5-rc", true }, + { "Tor 0.4.5.6", false }, + { "Tor 0.4.5.15", false }, + + { "Tor 0.4.6.0-alpha-dev", true }, + { "Tor 0.4.6.1-alpha", true }, + { "Tor 0.4.6.5", true }, + { "Tor 0.4.6.50", true }, /* Non existing one in the 0.4.6 series */ + + { "Tor 0.4.7.0-alpha-dev", false }, + { "Tor 0.4.7.3-alpha", false }, + { "Tor 0.4.7.12", false }, + // Very far in the future { "Tor 100.100.1.5", false }, }; diff --git a/src/test/test_process_slow.c b/src/test/test_process_slow.c index f74d4adc9a..6cb1b01b50 100644 --- a/src/test/test_process_slow.c +++ b/src/test/test_process_slow.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_procmon.c b/src/test/test_procmon.c index 1752008f63..3e459edecc 100644 --- a/src/test/test_procmon.c +++ b/src/test/test_procmon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_proto_haproxy.c b/src/test/test_proto_haproxy.c index 040354ec1f..dade0d77ca 100644 --- a/src/test/test_proto_haproxy.c +++ b/src/test/test_proto_haproxy.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2020, The Tor Project, Inc. */ +/* Copyright (c) 2019-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_proto_http.c b/src/test/test_proto_http.c index 481d78b2c1..6c859c0cb0 100644 --- a/src/test/test_proto_http.c +++ b/src/test/test_proto_http.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_proto_misc.c b/src/test/test_proto_misc.c index 64bf5c4993..d575b8b3da 100644 --- a/src/test/test_proto_misc.c +++ b/src/test/test_proto_misc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_protover.c b/src/test/test_protover.c index 16f0279871..9d14fd678a 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define PROTOVER_PRIVATE @@ -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_(); @@ -370,6 +356,8 @@ test_protover_supports_version(void *arg) #define PROTOVER_FLOWCTRL_V1 1 +#define PROTOVER_RELAY_NTOR_V3 4 + /* Make sure we haven't forgotten any supported protocols */ static void test_protover_supported_protocols(void *arg) @@ -641,7 +629,7 @@ test_protover_vote_roundtrip_ours(void *args) */ #define PROTOVER(proto_string, version_macro) \ (proto_string "=" STR(version_macro)) -#endif +#endif /* defined(COCCI) */ #define DEBUG_PROTOVER(flags) \ STMT_BEGIN \ @@ -658,7 +646,8 @@ test_protover_vote_roundtrip_ours(void *args) "supports_establish_intro_dos_extension: %d,\n" \ "supports_v3_hsdir: %d,\n" \ "supports_v3_rendezvous_point: %d,\n" \ - "supports_hs_setup_padding: %d.", \ + "supports_hs_setup_padding: %d,\n" \ + "supports_congestion_control: %d.", \ (flags).protocols_known, \ (flags).supports_extend2_cells, \ (flags).supports_accepting_ipv6_extends, \ @@ -670,7 +659,8 @@ test_protover_vote_roundtrip_ours(void *args) (flags).supports_establish_intro_dos_extension, \ (flags).supports_v3_hsdir, \ (flags).supports_v3_rendezvous_point, \ - (flags).supports_hs_setup_padding); \ + (flags).supports_hs_setup_padding, \ + (flags).supports_congestion_control); \ STMT_END /* Test that the proto_string version version_macro sets summary_flag. */ diff --git a/src/test/test_pt.c b/src/test/test_pt.c index 893fec3674..07c5032933 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -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_ptr_slow.c b/src/test/test_ptr_slow.c index 25b893c4c0..7f72f0a578 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_pubsub_build.c b/src/test/test_pubsub_build.c index 5f9005926c..288e075144 100644 --- a/src/test/test_pubsub_build.c +++ b/src/test/test_pubsub_build.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DISPATCH_PRIVATE diff --git a/src/test/test_pubsub_msg.c b/src/test/test_pubsub_msg.c index 3054db885d..566038dd28 100644 --- a/src/test/test_pubsub_msg.c +++ b/src/test/test_pubsub_msg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define DISPATCH_PRIVATE diff --git a/src/test/test_rebind.sh b/src/test/test_rebind.sh index 879008c1c1..aae2a9a6a0 100755 --- a/src/test/test_rebind.sh +++ b/src/test/test_rebind.sh @@ -46,6 +46,9 @@ if "${TOR_BINARY}" --list-modules | grep -q "relay: no"; then fi tmpdir= +# For some reasons, shellcheck is not seeing that we can call this +# function from the trap below. +# shellcheck disable=SC2317 clean () { if [ -n "$tmpdir" ] && [ -d "$tmpdir" ]; then rm -rf "$tmpdir" diff --git a/src/test/test_relay.c b/src/test/test_relay.c index 8ed29b6282..dbedc021e4 100644 --- a/src/test/test_relay.c +++ b/src/test/test_relay.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CIRCUITBUILD_PRIVATE diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c index 6f5bc7e770..05e2b2e347 100644 --- a/src/test/test_relaycell.c +++ b/src/test/test_relaycell.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for handling different kinds of relay cell */ diff --git a/src/test/test_relaycrypt.c b/src/test/test_relaycrypt.c index 737c243e2d..3a615c53a3 100644 --- a/src/test/test_relaycrypt.c +++ b/src/test/test_relaycrypt.c @@ -1,6 +1,6 @@ /* Copyright 2001-2004 Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CRYPT_PATH_PRIVATE diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c deleted file mode 100644 index 06167635c1..0000000000 --- a/src/test/test_rendcache.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -#include "orconfig.h" -#include "core/or/or.h" - -#include "test/test.h" -#define RENDCACHE_PRIVATE -#include "feature/rend/rendcache.h" -#include "feature/relay/router.h" -#include "feature/nodelist/routerlist.h" -#include "app/config/config.h" -#include "feature/hs/hs_common.h" - -#include "core/or/extend_info_st.h" -#include "feature/rend/rend_encoded_v2_service_descriptor_st.h" -#include "feature/rend/rend_intro_point_st.h" -#include "feature/rend/rend_service_descriptor_st.h" -#include "feature/nodelist/routerinfo_st.h" - -#include "test/rend_test_helpers.h" -#include "test/log_test_helpers.h" - -static const int RECENT_TIME = -10; -static const int TIME_IN_THE_PAST = -(REND_CACHE_MAX_AGE + \ - REND_CACHE_MAX_SKEW + 60); -static const int TIME_IN_THE_FUTURE = REND_CACHE_MAX_SKEW + 60; - -static void -test_rend_cache_lookup_entry(void *data) -{ - int ret; - rend_data_t *mock_rend_query = NULL; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - rend_cache_entry_t *entry = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder = NULL; - char *service_id = NULL; - (void)data; - - rend_cache_init(); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - - ret = rend_cache_lookup_entry("abababababababab", 0, NULL); - tt_int_op(ret, OP_EQ, -ENOENT); - - ret = rend_cache_lookup_entry("invalid query", 2, NULL); - tt_int_op(ret, OP_EQ, -EINVAL); - - ret = rend_cache_lookup_entry("abababababababab", 2, NULL); - tt_int_op(ret, OP_EQ, -ENOENT); - - ret = rend_cache_lookup_entry("abababababababab", 4224, NULL); - tt_int_op(ret, OP_EQ, -ENOENT); - - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, - mock_rend_query, NULL); - - ret = rend_cache_lookup_entry(service_id, 2, NULL); - tt_int_op(ret, OP_EQ, 0); - - ret = rend_cache_lookup_entry(service_id, 2, &entry); - tt_int_op(ret, OP_EQ, 0); - tt_assert(entry); - tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); - tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); - - done: - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_cache_free_all(); - rend_data_free(mock_rend_query); -} - -static void -test_rend_cache_store_v2_desc_as_client(void *data) -{ - int ret; - rend_data_t *mock_rend_query; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - rend_cache_entry_t *entry = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder = NULL; - char *service_id = NULL; - char client_cookie[REND_DESC_COOKIE_LEN]; - (void)data; - - rend_cache_init(); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - - // Test success - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - &entry); - - tt_int_op(ret, OP_EQ, 0); - tt_assert(entry); - tt_int_op(entry->len, OP_EQ, strlen(desc_holder->desc_str)); - tt_str_op(entry->desc, OP_EQ, desc_holder->desc_str); - - // Test various failure modes - - // TODO: a too long desc_id_base32 argument crashes the function - /* ret = rend_cache_store_v2_desc_as_client( */ - /* desc_holder->desc_str, */ - /* "3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG3TOOLONG", */ - /* &mock_rend_query, NULL); */ - /* tt_int_op(ret, OP_EQ, -1); */ - - // Test bad base32 failure - // This causes an assertion failure if we're running with assertions. - // But when building without asserts, we can test it. -#ifdef DISABLE_ASSERTS_IN_UNIT_TESTS - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - "!xqunszqnaolrrfmtzgaki7mxelgvkj", mock_rend_query, NULL); - tt_int_op(ret, OP_EQ, -1); -#endif - - // Test invalid descriptor - ret = rend_cache_store_v2_desc_as_client("invalid descriptor", - "3xqunszqnaolrrfmtzgaki7mxelgvkje", mock_rend_query, NULL); - tt_int_op(ret, OP_EQ, -1); - - // TODO: it doesn't seem to be possible to test invalid service ID condition. - // that means it is likely not possible to have that condition without - // earlier conditions failing first (such as signature checking of the desc) - - rend_cache_free_all(); - - // Test mismatch between service ID and onion address - rend_cache_init(); - strncpy(TO_REND_DATA_V2(mock_rend_query)->onion_address, "abc", - REND_SERVICE_ID_LEN_BASE32+1); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, - mock_rend_query, NULL); - tt_int_op(ret, OP_EQ, -1); - rend_cache_free_all(); - rend_data_free(mock_rend_query); - - // Test incorrect descriptor ID - rend_cache_init(); - mock_rend_query = mock_rend_data(service_id); - char orig = desc_id_base32[0]; - if (desc_id_base32[0] == 'a') - desc_id_base32[0] = 'b'; - else - desc_id_base32[0] = 'a'; - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, -1); - desc_id_base32[0] = orig; - rend_cache_free_all(); - - // Test too old descriptor - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, - mock_rend_query, NULL); - tt_int_op(ret, OP_EQ, -1); - rend_cache_free_all(); - - // Test too new descriptor (in the future) - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, -1); - rend_cache_free_all(); - - // Test when a descriptor is already in the cache - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - - rend_cache_store_v2_desc_as_client(desc_holder->desc_str, desc_id_base32, - mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, 0); - - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - &entry); - tt_int_op(ret, OP_EQ, 0); - tt_assert(entry); - rend_cache_free_all(); - - // Test unsuccessful decrypting of introduction points - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - mock_rend_query = mock_rend_data(service_id); - TO_REND_DATA_V2(mock_rend_query)->auth_type = REND_BASIC_AUTH; - client_cookie[0] = 'A'; - memcpy(TO_REND_DATA_V2(mock_rend_query)->descriptor_cookie, client_cookie, - REND_DESC_COOKIE_LEN); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, 0); - rend_cache_free_all(); - - // Test successful run when we have REND_BASIC_AUTH but not cookie - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - mock_rend_query = mock_rend_data(service_id); - TO_REND_DATA_V2(mock_rend_query)->auth_type = REND_BASIC_AUTH; - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, 0); - - rend_cache_free_all(); - - // Test when we have no introduction points - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, 0); - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, -1); - rend_cache_free_all(); - - // Test when we have too many intro points - rend_cache_init(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_data_free(mock_rend_query); - - generate_desc(RECENT_TIME, &desc_holder, &service_id, MAX_INTRO_POINTS+1); - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_store_v2_desc_as_client(desc_holder->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, -1); - - done: - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_cache_free_all(); - rend_data_free(mock_rend_query); -} - -static void -test_rend_cache_store_v2_desc_as_client_with_different_time(void *data) -{ - int ret; - rend_data_t *mock_rend_query; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - rend_service_descriptor_t *generated = NULL; - smartlist_t *descs = smartlist_new(); - time_t t; - char *service_id = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder_newer; - rend_encoded_v2_service_descriptor_t *desc_holder_older; - - t = time(NULL); - rend_cache_init(); - - create_descriptor(&generated, &service_id, 3); - - generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - descs = smartlist_new(); - - generated->timestamp = (t + RECENT_TIME) - 20; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - (void)data; - - // Test when a descriptor is already in the cache and it is newer than the - // one we submit - mock_rend_query = mock_rend_data(service_id); - base32_encode(desc_id_base32, sizeof(desc_id_base32), - desc_holder_newer->desc_id, DIGEST_LEN); - rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, - desc_id_base32, mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, 0); - - rend_cache_free_all(); - - // Test when an old descriptor is in the cache and we submit a newer one - rend_cache_init(); - rend_cache_store_v2_desc_as_client(desc_holder_older->desc_str, - desc_id_base32, mock_rend_query, NULL); - ret = rend_cache_store_v2_desc_as_client(desc_holder_newer->desc_str, - desc_id_base32, mock_rend_query, - NULL); - tt_int_op(ret, OP_EQ, 0); - - done: - rend_encoded_v2_service_descriptor_free(desc_holder_newer); - rend_encoded_v2_service_descriptor_free(desc_holder_older); - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - rend_service_descriptor_free(generated); - tor_free(service_id); - rend_cache_free_all(); - rend_data_free(mock_rend_query); -} - -static const routerinfo_t *rcache_lookup_v2_as_dir_get_my_routerinfo(void); - -static routerinfo_t *mock_routerinfo; - -static const routerinfo_t * -rcache_lookup_v2_as_dir_get_my_routerinfo(void) -{ - if (!mock_routerinfo) { - mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); - } - - return mock_routerinfo; -} - -static void -test_rend_cache_lookup_v2_desc_as_dir(void *data) -{ - int ret; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - rend_encoded_v2_service_descriptor_t *desc_holder = NULL; - char *service_id = NULL; - const char *ret_desc = NULL; - - (void)data; - - MOCK(router_get_my_routerinfo, - rcache_lookup_v2_as_dir_get_my_routerinfo); - - rend_cache_init(); - - // Test invalid base32 - ret = rend_cache_lookup_v2_desc_as_dir("!bababababababab", NULL); - tt_int_op(ret, OP_EQ, -1); - - // Test non-existent descriptor but well formed - ret = rend_cache_lookup_v2_desc_as_dir("3xqunszqnaolrrfmtzgaki7mxelgvkje", - NULL); - tt_int_op(ret, OP_EQ, 0); - - // Test existing descriptor - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - ret = rend_cache_lookup_v2_desc_as_dir(desc_id_base32, &ret_desc); - tt_int_op(ret, OP_EQ, 1); - tt_assert(ret_desc); - - done: - UNMOCK(router_get_my_routerinfo); - tor_free(mock_routerinfo); - rend_cache_free_all(); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); -} - -static const routerinfo_t *rcache_store_v2_as_dir_get_my_routerinfo(void); - -static const routerinfo_t * -rcache_store_v2_as_dir_get_my_routerinfo(void) -{ - return mock_routerinfo; -} - -static void -test_rend_cache_store_v2_desc_as_dir(void *data) -{ - (void)data; - int ret; - rend_encoded_v2_service_descriptor_t *desc_holder = NULL; - char *service_id = NULL; - - MOCK(router_get_my_routerinfo, - rcache_store_v2_as_dir_get_my_routerinfo); - - rend_cache_init(); - - // Test when we can't parse the descriptor - mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); - ret = rend_cache_store_v2_desc_as_dir("unparseable"); - tt_int_op(ret, OP_EQ, -1); - - // Test when we have an old descriptor - generate_desc(TIME_IN_THE_PAST, &desc_holder, &service_id, 3); - ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - tt_int_op(ret, OP_EQ, 0); - - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - - // Test when we have a descriptor in the future - generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); - ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - tt_int_op(ret, OP_EQ, 0); - - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - - // Test when two descriptors - generate_desc(TIME_IN_THE_FUTURE, &desc_holder, &service_id, 3); - ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - tt_int_op(ret, OP_EQ, 0); - - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - - // Test when asking for hidden service statistics HiddenServiceStatistics - rend_cache_purge(); - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - get_options_mutable()->HiddenServiceStatistics = 1; - ret = rend_cache_store_v2_desc_as_dir(desc_holder->desc_str); - tt_int_op(ret, OP_EQ, 0); - - done: - UNMOCK(router_get_my_routerinfo); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_cache_free_all(); - tor_free(mock_routerinfo); -} - -static void -test_rend_cache_store_v2_desc_as_dir_with_different_time(void *data) -{ - (void)data; - - int ret; - rend_service_descriptor_t *generated = NULL; - smartlist_t *descs = smartlist_new(); - time_t t; - char *service_id = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder_newer; - rend_encoded_v2_service_descriptor_t *desc_holder_older; - - MOCK(router_get_my_routerinfo, - rcache_store_v2_as_dir_get_my_routerinfo); - - rend_cache_init(); - - t = time(NULL); - - create_descriptor(&generated, &service_id, 3); - generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_newer = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - descs = smartlist_new(); - - generated->timestamp = (t + RECENT_TIME) - 20; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_older = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - - // Test when we have a newer descriptor stored - mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); - rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); - ret = rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); - tt_int_op(ret, OP_EQ, 0); - - // Test when we have an old descriptor stored - rend_cache_purge(); - rend_cache_store_v2_desc_as_dir(desc_holder_older->desc_str); - ret = rend_cache_store_v2_desc_as_dir(desc_holder_newer->desc_str); - tt_int_op(ret, OP_EQ, 0); - - done: - UNMOCK(router_get_my_routerinfo); - rend_cache_free_all(); - rend_service_descriptor_free(generated); - tor_free(service_id); - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - rend_encoded_v2_service_descriptor_free(desc_holder_newer); - rend_encoded_v2_service_descriptor_free(desc_holder_older); - tor_free(mock_routerinfo); -} - -static void -test_rend_cache_store_v2_desc_as_dir_with_different_content(void *data) -{ - (void)data; - - int ret; - rend_service_descriptor_t *generated = NULL; - smartlist_t *descs = smartlist_new(); - time_t t; - char *service_id = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder_one = NULL; - rend_encoded_v2_service_descriptor_t *desc_holder_two = NULL; - - MOCK(router_get_my_routerinfo, - rcache_store_v2_as_dir_get_my_routerinfo); - - rend_cache_init(); - - t = time(NULL); - - create_descriptor(&generated, &service_id, 3); - generated->timestamp = t + RECENT_TIME; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_one = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - descs = smartlist_new(); - - generated->timestamp = t + RECENT_TIME; - generated->protocols = 41; - rend_encode_v2_descriptors(descs, generated, t + RECENT_TIME, 0, - REND_NO_AUTH, NULL, NULL); - desc_holder_two = ((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0)); - smartlist_set(descs, 0, NULL); - - // Test when we have another descriptor stored, with a different descriptor - mock_routerinfo = tor_malloc(sizeof(routerinfo_t)); - rend_cache_store_v2_desc_as_dir(desc_holder_one->desc_str); - ret = rend_cache_store_v2_desc_as_dir(desc_holder_two->desc_str); - tt_int_op(ret, OP_EQ, 0); - - done: - UNMOCK(router_get_my_routerinfo); - rend_cache_free_all(); - rend_service_descriptor_free(generated); - tor_free(service_id); - SMARTLIST_FOREACH(descs, rend_encoded_v2_service_descriptor_t *, d, - rend_encoded_v2_service_descriptor_free(d)); - smartlist_free(descs); - rend_encoded_v2_service_descriptor_free(desc_holder_one); - rend_encoded_v2_service_descriptor_free(desc_holder_two); -} - -static void -test_rend_cache_init(void *data) -{ - (void)data; - - tt_assert_msg(!rend_cache, "rend_cache should be NULL when starting"); - tt_assert_msg(!rend_cache_v2_dir, "rend_cache_v2_dir should be NULL " - "when starting"); - tt_assert_msg(!rend_cache_failure, "rend_cache_failure should be NULL when " - "starting"); - - rend_cache_init(); - - tt_assert_msg(rend_cache, "rend_cache should not be NULL after initing"); - tt_assert_msg(rend_cache_v2_dir, "rend_cache_v2_dir should not be NULL " - "after initing"); - tt_assert_msg(rend_cache_failure, "rend_cache_failure should not be NULL " - "after initing"); - - tt_int_op(strmap_size(rend_cache), OP_EQ, 0); - tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_decrement_allocation(void *data) -{ - (void)data; - - // Test when the cache has enough allocations - rend_cache_total_allocation = 10; - rend_cache_decrement_allocation(3); - tt_int_op(rend_cache_total_allocation, OP_EQ, 7); - - // Test when there are not enough allocations - rend_cache_total_allocation = 1; - setup_full_capture_of_logs(LOG_WARN); - rend_cache_decrement_allocation(2); - tt_int_op(rend_cache_total_allocation, OP_EQ, 0); - expect_single_log_msg_containing( - "Underflow in rend_cache_decrement_allocation"); - teardown_capture_of_logs(); - - // And again - rend_cache_decrement_allocation(2); - tt_int_op(rend_cache_total_allocation, OP_EQ, 0); - - done: - teardown_capture_of_logs(); -} - -static void -test_rend_cache_increment_allocation(void *data) -{ - (void)data; - - // Test when the cache is not overflowing - rend_cache_total_allocation = 5; - rend_cache_increment_allocation(3); - tt_int_op(rend_cache_total_allocation, OP_EQ, 8); - - // Test when there are too many allocations - rend_cache_total_allocation = SIZE_MAX-1; - setup_full_capture_of_logs(LOG_WARN); - rend_cache_increment_allocation(2); - tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); - expect_single_log_msg_containing( - "Overflow in rend_cache_increment_allocation"); - teardown_capture_of_logs(); - - // And again - rend_cache_increment_allocation(2); - tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX); - - done: - teardown_capture_of_logs(); -} - -static void -test_rend_cache_failure_intro_entry_new(void *data) -{ - time_t now; - rend_cache_failure_intro_t *entry; - rend_intro_point_failure_t failure; - - (void)data; - - failure = INTRO_POINT_FAILURE_TIMEOUT; - now = time(NULL); - entry = rend_cache_failure_intro_entry_new(failure); - - tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); - tt_int_op(entry->created_ts, OP_GE, now-5); - tt_int_op(entry->created_ts, OP_LE, now+5); - - done: - tor_free(entry); -} - -static void -test_rend_cache_failure_intro_lookup(void *data) -{ - (void)data; - int ret; - rend_cache_failure_t *failure; - rend_cache_failure_intro_t *ip; - rend_cache_failure_intro_t *entry; - const char key_ip_one[DIGEST_LEN] = "ip1"; - const char key_ip_two[DIGEST_LEN] = "ip2"; - const char key_foo[DIGEST_LEN] = "foo1"; - - rend_cache_init(); - - failure = rend_cache_failure_entry_new(); - ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - digestmap_set(failure->intro_failures, key_ip_one, ip); - strmap_set_lc(rend_cache_failure, "foo1", failure); - - // Test not found - ret = cache_failure_intro_lookup((const uint8_t *) key_foo, "foo2", NULL); - tt_int_op(ret, OP_EQ, 0); - - // Test found with no intro failures in it - ret = cache_failure_intro_lookup((const uint8_t *) key_ip_two, "foo1", NULL); - tt_int_op(ret, OP_EQ, 0); - - // Test found - ret = cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", NULL); - tt_int_op(ret, OP_EQ, 1); - - // Test found and asking for entry - cache_failure_intro_lookup((const uint8_t *) key_ip_one, "foo1", &entry); - tt_assert(entry); - tt_assert(entry == ip); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_clean(void *data) -{ - rend_cache_entry_t *one, *two; - rend_service_descriptor_t *desc_one, *desc_two; - strmap_iter_t *iter = NULL; - const char *key; - void *val; - - (void)data; - - rend_cache_init(); - - // Test with empty rendcache - rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); - tt_int_op(strmap_size(rend_cache), OP_EQ, 0); - - // Test with two old entries - one = tor_malloc_zero(sizeof(rend_cache_entry_t)); - two = tor_malloc_zero(sizeof(rend_cache_entry_t)); - desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - one->parsed = desc_one; - two->parsed = desc_two; - - desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; - desc_two->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; - desc_one->pk = pk_generate(0); - desc_two->pk = pk_generate(1); - - strmap_set_lc(rend_cache, "foo1", one); - rend_cache_increment_allocation(rend_cache_entry_allocation(one)); - strmap_set_lc(rend_cache, "foo2", two); - rend_cache_increment_allocation(rend_cache_entry_allocation(two)); - - rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); - tt_int_op(strmap_size(rend_cache), OP_EQ, 0); - - // Test with one old entry and one newer entry - one = tor_malloc_zero(sizeof(rend_cache_entry_t)); - two = tor_malloc_zero(sizeof(rend_cache_entry_t)); - desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - desc_two = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - one->parsed = desc_one; - two->parsed = desc_two; - - desc_one->timestamp = (time(NULL) + TIME_IN_THE_PAST) - 10; - desc_two->timestamp = time(NULL) - 100; - desc_one->pk = pk_generate(0); - desc_two->pk = pk_generate(1); - - rend_cache_increment_allocation(rend_cache_entry_allocation(one)); - strmap_set_lc(rend_cache, "foo1", one); - rend_cache_increment_allocation(rend_cache_entry_allocation(two)); - strmap_set_lc(rend_cache, "foo2", two); - - rend_cache_clean(time(NULL), REND_CACHE_TYPE_CLIENT); - tt_int_op(strmap_size(rend_cache), OP_EQ, 1); - - iter = strmap_iter_init(rend_cache); - strmap_iter_get(iter, &key, &val); - tt_str_op(key, OP_EQ, "foo2"); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_failure_entry_new(void *data) -{ - rend_cache_failure_t *failure; - - (void)data; - - failure = rend_cache_failure_entry_new(); - tt_assert(failure); - tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 0); - - done: - rend_cache_failure_entry_free(failure); -} - -static void -test_rend_cache_failure_entry_free(void *data) -{ - (void)data; - - // Test that it can deal with a NULL argument - rend_cache_failure_entry_free_(NULL); - - /* done: */ - /* (void)0; */ -} - -static void -test_rend_cache_failure_clean(void *data) -{ - rend_cache_failure_t *failure; - rend_cache_failure_intro_t *ip_one, *ip_two; - - const char key_one[DIGEST_LEN] = "ip1"; - const char key_two[DIGEST_LEN] = "ip2"; - - (void)data; - - rend_cache_init(); - - // Test with empty failure cache - rend_cache_failure_clean(time(NULL)); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - - // Test with one empty failure entry - failure = rend_cache_failure_entry_new(); - strmap_set_lc(rend_cache_failure, "foo1", failure); - rend_cache_failure_clean(time(NULL)); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - - // Test with one new intro point - failure = rend_cache_failure_entry_new(); - ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - digestmap_set(failure->intro_failures, key_one, ip_one); - strmap_set_lc(rend_cache_failure, "foo1", failure); - rend_cache_failure_clean(time(NULL)); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); - - // Test with one old intro point - rend_cache_failure_purge(); - failure = rend_cache_failure_entry_new(); - ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - ip_one->created_ts = time(NULL) - 7*60; - digestmap_set(failure->intro_failures, key_one, ip_one); - strmap_set_lc(rend_cache_failure, "foo1", failure); - rend_cache_failure_clean(time(NULL)); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - - // Test with one old intro point and one new one - rend_cache_failure_purge(); - failure = rend_cache_failure_entry_new(); - ip_one = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - ip_one->created_ts = time(NULL) - 7*60; - digestmap_set(failure->intro_failures, key_one, ip_one); - ip_two = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - ip_two->created_ts = time(NULL) - 2*60; - digestmap_set(failure->intro_failures, key_two, ip_two); - strmap_set_lc(rend_cache_failure, "foo1", failure); - rend_cache_failure_clean(time(NULL)); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 1); - tt_int_op(digestmap_size(failure->intro_failures), OP_EQ, 1); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_failure_remove(void *data) -{ - rend_service_descriptor_t *desc; - (void)data; - - rend_cache_init(); - - // Test that it deals well with a NULL desc - rend_cache_failure_remove(NULL); - - // Test a descriptor that isn't in the cache - desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - desc->pk = pk_generate(0); - rend_cache_failure_remove(desc); - - // There seems to not exist any way of getting rend_cache_failure_remove() - // to fail because of a problem with rend_get_service_id from here - rend_cache_free_all(); - - rend_service_descriptor_free(desc); - /* done: */ - /* (void)0; */ -} - -static void -test_rend_cache_free_all(void *data) -{ - rend_cache_failure_t *failure; - rend_cache_entry_t *one; - rend_service_descriptor_t *desc_one; - - (void)data; - - rend_cache_init(); - - failure = rend_cache_failure_entry_new(); - strmap_set_lc(rend_cache_failure, "foo1", failure); - - one = tor_malloc_zero(sizeof(rend_cache_entry_t)); - desc_one = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - one->parsed = desc_one; - desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST; - desc_one->pk = pk_generate(0); - rend_cache_increment_allocation(rend_cache_entry_allocation(one)); - strmap_set_lc(rend_cache, "foo1", one); - - rend_cache_free_all(); - - tt_ptr_op(rend_cache, OP_EQ, NULL); - tt_ptr_op(rend_cache_v2_dir, OP_EQ, NULL); - tt_ptr_op(rend_cache_failure, OP_EQ, NULL); - tt_assert(!rend_cache_total_allocation); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_entry_free(void *data) -{ - (void)data; - rend_cache_entry_t *e; - - // Handles NULL correctly - rend_cache_entry_free_(NULL); - - // Handles NULL descriptor correctly - e = tor_malloc_zero(sizeof(rend_cache_entry_t)); - rend_cache_increment_allocation(rend_cache_entry_allocation(e)); - rend_cache_entry_free(e); - - // Handles non-NULL descriptor correctly - e = tor_malloc_zero(sizeof(rend_cache_entry_t)); - e->desc = tor_malloc(10); - rend_cache_increment_allocation(rend_cache_entry_allocation(e)); - rend_cache_entry_free(e); - - /* done: */ - /* (void)0; */ -} - -static void -test_rend_cache_purge(void *data) -{ - (void)data; - - // Deals with a NULL rend_cache - rend_cache_purge(); - tt_assert(rend_cache); - tt_assert(strmap_size(rend_cache) == 0); - - // Deals with existing rend_cache - rend_cache_free_all(); - rend_cache_init(); - tt_assert(rend_cache); - tt_assert(strmap_size(rend_cache) == 0); - - rend_cache_purge(); - tt_assert(rend_cache); - tt_assert(strmap_size(rend_cache) == 0); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_failure_intro_add(void *data) -{ - (void)data; - rend_cache_failure_t *fail_entry; - rend_cache_failure_intro_t *entry; - const char identity[DIGEST_LEN] = "foo1"; - - rend_cache_init(); - - // Adds non-existing entry - cache_failure_intro_add((const uint8_t *) identity, "foo2", - INTRO_POINT_FAILURE_TIMEOUT); - fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); - tt_assert(fail_entry); - tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); - entry = digestmap_get(fail_entry->intro_failures, identity); - tt_assert(entry); - - // Adds existing entry - cache_failure_intro_add((const uint8_t *) identity, "foo2", - INTRO_POINT_FAILURE_TIMEOUT); - fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); - tt_assert(fail_entry); - tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); - entry = digestmap_get(fail_entry->intro_failures, identity); - tt_assert(entry); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_intro_failure_note(void *data) -{ - (void)data; - rend_cache_failure_t *fail_entry; - rend_cache_failure_intro_t *entry; - const char key[DIGEST_LEN] = "foo1"; - - rend_cache_init(); - - // Test not found - rend_cache_intro_failure_note(INTRO_POINT_FAILURE_TIMEOUT, - (const uint8_t *) key, "foo2"); - fail_entry = strmap_get_lc(rend_cache_failure, "foo2"); - tt_assert(fail_entry); - tt_int_op(digestmap_size(fail_entry->intro_failures), OP_EQ, 1); - entry = digestmap_get(fail_entry->intro_failures, key); - tt_assert(entry); - tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_TIMEOUT); - - // Test found - rend_cache_intro_failure_note(INTRO_POINT_FAILURE_UNREACHABLE, - (const uint8_t *) key, "foo2"); - tt_int_op(entry->failure_type, OP_EQ, INTRO_POINT_FAILURE_UNREACHABLE); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_clean_v2_descs_as_dir(void *data) -{ - rend_cache_entry_t *e; - time_t now, cutoff; - rend_service_descriptor_t *desc; - now = time(NULL); - cutoff = now - (REND_CACHE_MAX_AGE + REND_CACHE_MAX_SKEW); - const char key[DIGEST_LEN] = "abcde"; - - (void)data; - - rend_cache_init(); - - // Test running with an empty cache - rend_cache_clean_v2_descs_as_dir(cutoff); - tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); - - // Test with only one new entry - e = tor_malloc_zero(sizeof(rend_cache_entry_t)); - e->last_served = now; - desc = tor_malloc_zero(sizeof(rend_service_descriptor_t)); - desc->timestamp = now; - desc->pk = pk_generate(0); - e->parsed = desc; - rend_cache_increment_allocation(rend_cache_entry_allocation(e)); - digestmap_set(rend_cache_v2_dir, key, e); - - /* Set the cutoff to minus 10 seconds. */ - rend_cache_clean_v2_descs_as_dir(cutoff - 10); - tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 1); - - // Test with one old entry - desc->timestamp = cutoff - 1000; - rend_cache_clean_v2_descs_as_dir(cutoff); - tt_int_op(digestmap_size(rend_cache_v2_dir), OP_EQ, 0); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_entry_allocation(void *data) -{ - (void)data; - - size_t ret; - rend_cache_entry_t *e = NULL; - - // Handles a null argument - ret = rend_cache_entry_allocation(NULL); - tt_int_op(ret, OP_EQ, 0); - - // Handles a non-null argument - e = tor_malloc_zero(sizeof(rend_cache_entry_t)); - ret = rend_cache_entry_allocation(e); - tt_int_op(ret, OP_GT, sizeof(rend_cache_entry_t)); - - done: - tor_free(e); -} - -static void -test_rend_cache_failure_intro_entry_free(void *data) -{ - (void)data; - rend_cache_failure_intro_t *entry; - - // Handles a null argument - rend_cache_failure_intro_entry_free_(NULL); - - // Handles a non-null argument - entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - rend_cache_failure_intro_entry_free(entry); -} - -static void -test_rend_cache_failure_purge(void *data) -{ - (void)data; - - // Handles a null failure cache - strmap_free(rend_cache_failure, rend_cache_failure_entry_free_void); - rend_cache_failure = NULL; - - rend_cache_failure_purge(); - - tt_ptr_op(rend_cache_failure, OP_NE, NULL); - tt_int_op(strmap_size(rend_cache_failure), OP_EQ, 0); - - done: - rend_cache_free_all(); -} - -static void -test_rend_cache_validate_intro_point_failure(void *data) -{ - (void)data; - rend_service_descriptor_t *desc = NULL; - char *service_id = NULL; - rend_intro_point_t *intro = NULL; - const char *identity = NULL; - rend_cache_failure_t *failure; - rend_cache_failure_intro_t *ip; - - rend_cache_init(); - - create_descriptor(&desc, &service_id, 3); - desc->timestamp = time(NULL) + RECENT_TIME; - - intro = (rend_intro_point_t *)smartlist_get(desc->intro_nodes, 0); - identity = intro->extend_info->identity_digest; - - failure = rend_cache_failure_entry_new(); - ip = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT); - digestmap_set(failure->intro_failures, identity, ip); - strmap_set_lc(rend_cache_failure, service_id, failure); - - // Test when we have an intro point in our cache - validate_intro_point_failure(desc, service_id); - tt_int_op(smartlist_len(desc->intro_nodes), OP_EQ, 2); - - done: - rend_cache_free_all(); - rend_service_descriptor_free(desc); - tor_free(service_id); -} - -struct testcase_t rend_cache_tests[] = { - { "init", test_rend_cache_init, 0, NULL, NULL }, - { "decrement_allocation", test_rend_cache_decrement_allocation, 0, - NULL, NULL }, - { "increment_allocation", test_rend_cache_increment_allocation, 0, - NULL, NULL }, - { "clean", test_rend_cache_clean, TT_FORK, NULL, NULL }, - { "clean_v2_descs_as_dir", test_rend_cache_clean_v2_descs_as_dir, 0, - NULL, NULL }, - { "entry_allocation", test_rend_cache_entry_allocation, 0, NULL, NULL }, - { "entry_free", test_rend_cache_entry_free, 0, NULL, NULL }, - { "failure_intro_entry_free", test_rend_cache_failure_intro_entry_free, 0, - NULL, NULL }, - { "free_all", test_rend_cache_free_all, 0, NULL, NULL }, - { "purge", test_rend_cache_purge, 0, NULL, NULL }, - { "failure_clean", test_rend_cache_failure_clean, 0, NULL, NULL }, - { "failure_entry_new", test_rend_cache_failure_entry_new, 0, NULL, NULL }, - { "failure_entry_free", test_rend_cache_failure_entry_free, 0, NULL, NULL }, - { "failure_intro_add", test_rend_cache_failure_intro_add, 0, NULL, NULL }, - { "failure_intro_entry_new", test_rend_cache_failure_intro_entry_new, 0, - NULL, NULL }, - { "failure_intro_lookup", test_rend_cache_failure_intro_lookup, 0, - NULL, NULL }, - { "failure_purge", test_rend_cache_failure_purge, 0, NULL, NULL }, - { "failure_remove", test_rend_cache_failure_remove, 0, NULL, NULL }, - { "intro_failure_note", test_rend_cache_intro_failure_note, 0, NULL, NULL }, - { "lookup", test_rend_cache_lookup_entry, 0, NULL, NULL }, - { "lookup_v2_desc_as_dir", test_rend_cache_lookup_v2_desc_as_dir, 0, - NULL, NULL }, - { "store_v2_desc_as_client", test_rend_cache_store_v2_desc_as_client, 0, - NULL, NULL }, - { "store_v2_desc_as_client_with_different_time", - test_rend_cache_store_v2_desc_as_client_with_different_time, 0, - NULL, NULL }, - { "store_v2_desc_as_dir", test_rend_cache_store_v2_desc_as_dir, 0, - NULL, NULL }, - { "store_v2_desc_as_dir_with_different_time", - test_rend_cache_store_v2_desc_as_dir_with_different_time, 0, NULL, NULL }, - { "store_v2_desc_as_dir_with_different_content", - test_rend_cache_store_v2_desc_as_dir_with_different_content, 0, - NULL, NULL }, - { "validate_intro_point_failure", - test_rend_cache_validate_intro_point_failure, 0, NULL, NULL }, - END_OF_TESTCASES -}; diff --git a/src/test/test_replay.c b/src/test/test_replay.c index 1487b0a29d..e21ab5eca3 100644 --- a/src/test/test_replay.c +++ b/src/test/test_replay.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Tor Project, Inc. */ +/* Copyright (c) 2012-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define REPLAYCACHE_PRIVATE diff --git a/src/test/test_rng.c b/src/test/test_rng.c index ebaffb74f5..6b830eda15 100644 --- a/src/test/test_rng.c +++ b/src/test/test_rng.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* diff --git a/src/test/test_router.c b/src/test/test_router.c index 895178f788..15cc93fbfc 100644 --- a/src/test/test_router.c +++ b/src/test/test_router.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* Copyright (c) 2017, isis agora lovecruft */ /* See LICENSE for licensing information */ diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c index e5314046b9..1ff05d57c3 100644 --- a/src/test/test_routerkeys.c +++ b/src/test/test_routerkeys.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c index c7b65006f0..aaa647710a 100644 --- a/src/test/test_routerlist.c +++ b/src/test/test_routerlist.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c index d00eefa23f..aff6bcb9c2 100644 --- a/src/test/test_routerset.c +++ b/src/test/test_routerset.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define ROUTERSET_PRIVATE 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_scheduler.c b/src/test/test_scheduler.c index 9ec15948e8..7e41a4be25 100644 --- a/src/test/test_scheduler.c +++ b/src/test/test_scheduler.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_sendme.c b/src/test/test_sendme.c index b34c7ae143..ea7ccd0b3c 100644 --- a/src/test/test_sendme.c +++ b/src/test/test_sendme.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /* Unit tests for handling different kinds of relay cell */ @@ -348,6 +348,50 @@ test_package_payload_len(void *arg) tor_free(c); } +/* Check that circuit_sendme_is_next works with a window of 1000, + * and a sendme_inc of 100 (old school tor compat) */ +static void +test_sendme_is_next1000(void *arg) +{ + (void)arg; + tt_int_op(circuit_sendme_cell_is_next(1000, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(999, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(901, 100), OP_EQ, 1); + + tt_int_op(circuit_sendme_cell_is_next(900, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(899, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(801, 100), OP_EQ, 1); + + tt_int_op(circuit_sendme_cell_is_next(101, 100), OP_EQ, 1); + tt_int_op(circuit_sendme_cell_is_next(100, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(99, 100), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(1, 100), OP_EQ, 1); + tt_int_op(circuit_sendme_cell_is_next(0, 100), OP_EQ, 0); + +done: + ; +} + +/* Check that circuit_sendme_is_next works with a window of 31 */ +static void +test_sendme_is_next(void *arg) +{ + (void)arg; + tt_int_op(circuit_sendme_cell_is_next(1000, 31), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(970, 31), OP_EQ, 1); + tt_int_op(circuit_sendme_cell_is_next(969, 31), OP_EQ, 0); + + /* deliver_window should never get this low, but test anyway */ + tt_int_op(circuit_sendme_cell_is_next(9, 31), OP_EQ, 1); + tt_int_op(circuit_sendme_cell_is_next(8, 31), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(7, 31), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(1, 31), OP_EQ, 0); + tt_int_op(circuit_sendme_cell_is_next(0, 31), OP_EQ, 0); + + done: + ; +} + struct testcase_t sendme_tests[] = { { "v1_record_digest", test_v1_record_digest, TT_FORK, NULL, NULL }, @@ -360,6 +404,8 @@ struct testcase_t sendme_tests[] = { { "cell_version_validation", test_cell_version_validation, TT_FORK, NULL, NULL }, { "package_payload_len", test_package_payload_len, 0, NULL, NULL }, + { "sendme_is_next1000", test_sendme_is_next1000, 0, NULL, NULL }, + { "sendme_is_next", test_sendme_is_next, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c index 678f53234f..c28d5920a3 100644 --- a/src/test/test_shared_random.c +++ b/src/test/test_shared_random.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Tor Project, Inc. */ +/* Copyright (c) 2016-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define SHARED_RANDOM_PRIVATE diff --git a/src/test/test_slow.c b/src/test/test_slow.c index 49b1066dac..5f42b43103 100644 --- a/src/test/test_slow.c +++ b/src/test/test_slow.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_socks.c b/src/test/test_socks.c index 4a465c7361..94c772419b 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_statefile.c b/src/test/test_statefile.c index dc9ecfee3e..aedf76a694 100644 --- a/src/test/test_statefile.c +++ b/src/test/test_statefile.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_stats.c b/src/test/test_stats.c index d45afc7b15..22d65b1e54 100644 --- a/src/test/test_stats.c +++ b/src/test/test_stats.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -12,6 +12,8 @@ #include "lib/crypt_ops/crypto_rand.h" #include "app/config/or_state_st.h" #include "test/rng_test_helpers.h" +#include "feature/hs/hs_cache.h" +#include "test/hs_test_helpers.h" #include <stdio.h> @@ -31,6 +33,7 @@ #define MAINLOOP_PRIVATE #define STATEFILE_PRIVATE #define BWHIST_PRIVATE +#define REPHIST_PRIVATE #define ROUTER_PRIVATE #include "core/or/or.h" @@ -48,6 +51,8 @@ #include "feature/stats/bw_array_st.h" #include "feature/relay/router.h" +#include <event2/dns.h> + /** Run unit tests for some stats code. */ static void test_stats(void *arg) @@ -495,6 +500,133 @@ test_get_bandwidth_lines(void *arg) bwhist_free_all(); } +static bool +mock_should_collect_v3_stats(void) +{ + return true; +} + +/* Test v3 metrics */ +static void +test_rephist_v3_onions(void *arg) +{ + int ret; + + char *stats_string = NULL; + char *desc1_str = NULL; + ed25519_keypair_t signing_kp1; + hs_descriptor_t *desc1 = NULL; + + const hs_v3_stats_t *hs_v3_stats = NULL; + + (void) arg; + + MOCK(should_collect_v3_stats, mock_should_collect_v3_stats); + + get_options_mutable()->HiddenServiceStatistics = 1; + + /* Initialize the subsystems */ + hs_cache_init(); + rep_hist_hs_stats_init(0); + + /* Change time to 03-01-2002 23:36 UTC */ + update_approx_time(1010101010); + + /* HS stats should be zero here */ + hs_v3_stats = rep_hist_get_hs_v3_stats(); + tt_int_op(digest256map_size(hs_v3_stats->v3_onions_seen_this_period), + OP_EQ, 0); + + /* Generate a valid descriptor */ + ret = ed25519_keypair_generate(&signing_kp1, 0); + tt_int_op(ret, OP_EQ, 0); + desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 42); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str); + tt_int_op(ret, OP_EQ, 0); + + /* Store descriptor and check that stats got updated */ + ret = hs_cache_store_as_dir(desc1_str); + tt_int_op(ret, OP_EQ, 0); + hs_v3_stats = rep_hist_get_hs_v3_stats(); + tt_int_op(digest256map_size(hs_v3_stats->v3_onions_seen_this_period), + OP_EQ, 1); + + /* cleanup */ + hs_descriptor_free(desc1); + tor_free(desc1_str); + + /* Generate another valid descriptor */ + ret = ed25519_keypair_generate(&signing_kp1, 0); + tt_int_op(ret, OP_EQ, 0); + desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 42); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str); + tt_int_op(ret, OP_EQ, 0); + + /* Store descriptor and check that stats are updated */ + ret = hs_cache_store_as_dir(desc1_str); + tt_int_op(ret, OP_EQ, 0); + hs_v3_stats = rep_hist_get_hs_v3_stats(); + tt_int_op(digest256map_size(hs_v3_stats->v3_onions_seen_this_period), + OP_EQ, 2); + + /* Check that storing the same descriptor twice does not work */ + ret = hs_cache_store_as_dir(desc1_str); + tt_int_op(ret, OP_EQ, -1); + + /* cleanup */ + hs_descriptor_free(desc1); + tor_free(desc1_str); + + /* Create a descriptor with the same identity key but diff rev counter and + same blinded key */ + desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 43); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str); + tt_int_op(ret, OP_EQ, 0); + + /* Store descriptor and check that stats are updated */ + ret = hs_cache_store_as_dir(desc1_str); + tt_int_op(ret, OP_EQ, 0); + tt_int_op(digest256map_size(hs_v3_stats->v3_onions_seen_this_period), + OP_EQ, 2); + + /* cleanup */ + hs_descriptor_free(desc1); + tor_free(desc1_str); + + /* Now let's skip to four days forward so that the blinded key rolls + forward */ + update_approx_time(approx_time() + 345600); + + /* Now create a descriptor with the same identity key but diff rev counter + and different blinded key */ + desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 44); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str); + tt_int_op(ret, OP_EQ, 0); + + /* Store descriptor and check that stats are updated */ + ret = hs_cache_store_as_dir(desc1_str); + tt_int_op(ret, OP_EQ, 0); + tt_int_op(digest256map_size(hs_v3_stats->v3_onions_seen_this_period), + OP_EQ, 3); + + /* cleanup */ + hs_descriptor_free(desc1); + tor_free(desc1_str); + + /* Because of differential privacy we can't actually check the stat value, + but let's just check that it's formatted correctly. */ + stats_string = rep_hist_format_hs_stats(approx_time(), true); + tt_assert(strstr(stats_string, "hidserv-dir-v3-onions-seen")); + + done: + UNMOCK(should_collect_v3_stats); + tor_free(stats_string); +} + static void test_load_stats_file(void *arg) { @@ -573,6 +705,227 @@ test_load_stats_file(void *arg) tor_free(content); } +/** Test the overload stats logic. */ +static void +test_overload_stats(void *arg) +{ + time_t current_time = 1010101010; + char *stats_str = NULL; + (void) arg; + + /* Change time to 03-01-2002 23:36 UTC */ + /* This should make the extrainfo timestamp be "2002-01-03 23:00:00" */ + update_approx_time(current_time); + + /* With an empty rephist we shouldn't get anything back */ + stats_str = rep_hist_get_overload_stats_lines(); + tt_assert(!stats_str); + + /* Note an overload */ + rep_hist_note_overload(OVERLOAD_GENERAL); + + /* Move the time forward one hour */ + current_time += 3600; + update_approx_time(current_time); + + /* Now check the string */ + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-03 23:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward 72 hours: see that the line has disappeared. */ + current_time += 3600*72; + update_approx_time(current_time); + + stats_str = rep_hist_get_overload_general_line(); + tt_assert(!stats_str); + + /* Now the time should be 2002-01-07 00:00:00 */ + + /* Note an overload */ + rep_hist_note_overload(OVERLOAD_GENERAL); + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Also note an fd exhaustion event */ + rep_hist_note_overload(OVERLOAD_FD_EXHAUSTED); + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-fd-exhausted 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward. Register overload. See that the time changed */ + current_time += 3600*2; + update_approx_time(current_time); + + rep_hist_note_overload(OVERLOAD_GENERAL); + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 02:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-fd-exhausted 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward. Register a bandwidth ratelimit event. See that the + string is added */ + current_time += 3600*2; + update_approx_time(current_time); + + /* Register the rate limit event */ + rep_hist_note_overload(OVERLOAD_READ); + /* Also set some rate limiting values that should be reflected on the log */ + get_options_mutable()->BandwidthRate = 1000; + get_options_mutable()->BandwidthBurst = 2000; + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 02:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-ratelimits 1 2002-01-07 04:00:00 1000 2000 1 0\n" + "overload-fd-exhausted 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward 24 hours: no rate limit line anymore. */ + current_time += 3600*24; + update_approx_time(current_time); + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 02:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-fd-exhausted 1 2002-01-07 00:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward 44 hours: no fd exhausted line anymore. */ + current_time += 3600*44; + update_approx_time(current_time); + + stats_str = rep_hist_get_overload_general_line(); + tt_str_op("overload-general 1 2002-01-07 02:00:00\n", OP_EQ, stats_str); + tor_free(stats_str); + + /* Move the time forward 2 hours: there is nothing left. */ + current_time += 3600*2; + update_approx_time(current_time); + + stats_str = rep_hist_get_overload_general_line(); + tt_assert(!stats_str); + + stats_str = rep_hist_get_overload_stats_lines(); + tt_assert(!stats_str); + + /* Now test the rate-limit rate-limiter ;) */ + for (int i = 0; i < 10; i++) { + rep_hist_note_overload(OVERLOAD_READ); + } + /* We already have an event registered from the previous tests. We just + * registered ten more overload events, but only one should have been counted + * because of the rate limiter */ + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-ratelimits 1 2002-01-10 02:00:00 1000 2000 2 0\n", + OP_EQ, stats_str); + tor_free(stats_str); + + /* Increment time by 59 secs and try again. No additional events should + register */ + current_time += 59; + update_approx_time(current_time); + + for (int i = 0; i < 10; i++) { + rep_hist_note_overload(OVERLOAD_READ); + } + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-ratelimits 1 2002-01-10 02:00:00 1000 2000 2 0\n", + OP_EQ, stats_str); + tor_free(stats_str); + + /* Now increment time by 2 secs -- taking it after the minute rate limiting + and see that events will register again */ + current_time += 2; + update_approx_time(current_time); + + for (int i = 0; i < 10; i++) { + rep_hist_note_overload(OVERLOAD_READ); + rep_hist_note_overload(OVERLOAD_WRITE); + } + stats_str = rep_hist_get_overload_stats_lines(); + tt_str_op("overload-ratelimits 1 2002-01-10 02:00:00 1000 2000 3 1\n", + OP_EQ, stats_str); + tor_free(stats_str); + + done: + tor_free(stats_str); +} + +/** Test the overload stats logic. */ +static void +test_overload_onionskin_ntor(void *arg) +{ + char *stats_str = NULL; + (void) arg; + uint16_t type = ONION_HANDSHAKE_TYPE_NTOR_V3; + + /* Lets simulate a series of timeouts but below our default 1% threshold. */ + + for (int i = 0; i < 1000; i++) { + rep_hist_note_circuit_handshake_requested(type); + /* This should trigger 9 drop which is just below 1% (10) */ + if (i > 0 && !(i % 100)) { + rep_hist_note_circuit_handshake_dropped(type); + } + } + + /* No overload yet. */ + stats_str = rep_hist_get_overload_general_line(); + tt_assert(!stats_str); + + /* Move it 6 hours in the future and see if we get a general overload. */ + update_approx_time(approx_time() + 21600); + + /* This request should NOT trigger the general overload because we are below + * our default of 1%. */ + rep_hist_note_circuit_handshake_requested(type); + stats_str = rep_hist_get_overload_general_line(); + tt_assert(!stats_str); + + /* We'll now go above our 1% threshold. */ + for (int i = 0; i < 1000; i++) { + rep_hist_note_circuit_handshake_requested(type); + /* This should trigger 10 timeouts which is our threshold of 1% (10) */ + if (!(i % 10)) { + rep_hist_note_circuit_handshake_dropped(type); + } + } + + /* Move it 6 hours in the future and see if we get a general overload. */ + update_approx_time(approx_time() + 21600); + + /* This request should trigger the general overload because above 1%. */ + rep_hist_note_circuit_handshake_requested(type); + stats_str = rep_hist_get_overload_general_line(); + tt_assert(stats_str); + tor_free(stats_str); + + /* Move 72h in the future, we should NOT get an overload anymore. */ + update_approx_time(approx_time() + (72 * 3600)); + + stats_str = rep_hist_get_overload_general_line(); + tt_assert(!stats_str); + + done: + tor_free(stats_str); +} + #define ENT(name) \ { #name, test_ ## name , 0, NULL, NULL } #define FORK(name) \ @@ -586,7 +939,10 @@ struct testcase_t stats_tests[] = { FORK(add_obs), FORK(fill_bandwidth_history), FORK(get_bandwidth_lines), + FORK(rephist_v3_onions), FORK(load_stats_file), + FORK(overload_stats), + FORK(overload_onionskin_ntor), END_OF_TESTCASES }; diff --git a/src/test/test_status.c b/src/test/test_status.c index b938b86326..1d371645ae 100644 --- a/src/test/test_status.c +++ b/src/test/test_status.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2020, The Tor Project, Inc. */ +/* Copyright (c) 2014-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define STATUS_PRIVATE @@ -359,8 +359,10 @@ test_status_hb_not_in_consensus(void *arg) "initiated 0 and received 0 v3 connections; " "initiated 0 and received 0 v4 connections; " "initiated 0 and received 0 v5 connections.\n"); - expect_log_msg("DoS mitigation since startup: 0 circuits killed with " - "too many cells. [cc not enabled] [conn not enabled] " + expect_log_msg("Heartbeat: DoS mitigation since startup: 0 circuits killed " + "with too many cells, [DoSCircuitCreationEnabled disabled], " + "[DoSConnectionEnabled disabled], " + "[DoSRefuseSingleHopClientRendezvous disabled], " "0 INTRODUCE2 rejected.\n"); tt_int_op(mock_saved_log_n_entries(), OP_EQ, 6); diff --git a/src/test/test_storagedir.c b/src/test/test_storagedir.c index eb3779cfee..16ff4da0b3 100644 --- a/src/test/test_storagedir.c +++ b/src/test/test_storagedir.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Tor Project, Inc. */ +/* Copyright (c) 2017-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_switch_id.c b/src/test/test_switch_id.c index f97af55d17..9b3edb55ef 100644 --- a/src/test/test_switch_id.c +++ b/src/test/test_switch_id.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2020, The Tor Project, Inc. */ +/* Copyright (c) 2015-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_threads.c b/src/test/test_threads.c index d5a1834aef..cc27e455b8 100644 --- a/src/test/test_threads.c +++ b/src/test/test_threads.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_token_bucket.c b/src/test/test_token_bucket.c index cf315f2944..097c5a156b 100644 --- a/src/test/test_token_bucket.c +++ b/src/test/test_token_bucket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c index 12ba873650..99c759e276 100644 --- a/src/test/test_tortls.c +++ b/src/test/test_tortls.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TORTLS_PRIVATE diff --git a/src/test/test_tortls.h b/src/test/test_tortls.h index 21c6fa0a8f..c14aba417b 100644 --- a/src/test/test_tortls.h +++ b/src/test/test_tortls.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #ifndef TEST_TORTLS_H diff --git a/src/test/test_tortls_openssl.c b/src/test/test_tortls_openssl.c index c1a87fbb4f..010e09c8eb 100644 --- a/src/test/test_tortls_openssl.c +++ b/src/test/test_tortls_openssl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TORTLS_PRIVATE diff --git a/src/test/test_util.c b/src/test/test_util.c index f567a18367..1dae2c617e 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -4554,7 +4554,7 @@ test_util_glob(void *ptr) #else const char *results_test3[] = {"dir1", "dir2", "file1", "file2", "forbidden"}; -#endif +#endif /* defined(_WIN32) */ TEST("*i*"); EXPECT(results_test3); @@ -4584,15 +4584,8 @@ test_util_glob(void *ptr) TEST("file1"); EXPECT(results_test9); -#if defined(__APPLE__) || defined(__darwin__) || \ - defined(__FreeBSD__) || defined(__NetBSD__) || defined(OpenBSD) TEST("file1"PATH_SEPARATOR); EXPECT_EMPTY(); -#else - const char *results_test10[] = {"file1"}; - TEST("file1"PATH_SEPARATOR); - EXPECT(results_test10); -#endif // test path separator at end - with wildcards and linux path separator const char *results_test11[] = {"dir1", "dir2", "forbidden"}; @@ -4606,7 +4599,7 @@ test_util_glob(void *ptr) #else const char *results_test12[] = {"dir1", "dir2", "empty", "file1", "file2", "forbidden"}; -#endif +#endif /* defined(_WIN32) */ TEST("*"); EXPECT(results_test12); @@ -4653,7 +4646,7 @@ test_util_glob(void *ptr) tor_free(pattern); tt_assert(!results); } -#endif +#endif /* !defined(_WIN32) */ #undef TEST #undef EXPECT @@ -4665,7 +4658,7 @@ test_util_glob(void *ptr) (void) chmod(dir1_forbidden, 0700); (void) chmod(dir2_forbidden, 0700); (void) chmod(forbidden_forbidden, 0700); -#endif +#endif /* !defined(_WIN32) */ tor_free(dir1); tor_free(dir2); tor_free(forbidden); @@ -4679,11 +4672,11 @@ test_util_glob(void *ptr) SMARTLIST_FOREACH(results, char *, f, tor_free(f)); smartlist_free(results); } -#else +#else /* !defined(HAVE_GLOB) */ tt_skip(); done: return; -#endif +#endif /* defined(HAVE_GLOB) */ } static void @@ -4791,7 +4784,7 @@ test_util_get_glob_opened_files(void *ptr) // dot files are not special on windows const char *results_test3[] = {"", ".test-hidden", "dir1", "dir2", "empty", "file1", "file2", "forbidden"}; -#endif +#endif /* !defined(_WIN32) */ TEST("*"PATH_SEPARATOR"*"); EXPECT(results_test3); @@ -4803,7 +4796,7 @@ test_util_get_glob_opened_files(void *ptr) // dot files are not special on windows const char *results_test4[] = {"", ".test-hidden", "dir1", "dir2", "empty", "file1", "file2", "forbidden"}; -#endif +#endif /* !defined(_WIN32) */ TEST("*"PATH_SEPARATOR"*"PATH_SEPARATOR); EXPECT(results_test4); @@ -4868,7 +4861,7 @@ test_util_get_glob_opened_files(void *ptr) TT_FAIL(("unable to chmod a file on cleanup: %s", strerror(errno))); } } -#endif +#endif /* !defined(_WIN32) */ tor_free(dir1); tor_free(dir2); tor_free(forbidden); @@ -4882,11 +4875,11 @@ test_util_get_glob_opened_files(void *ptr) SMARTLIST_FOREACH(results, char *, f, tor_free(f)); smartlist_free(results); } -#else +#else /* !defined(HAVE_GLOB) */ tt_skip(); done: return; -#endif +#endif /* defined(HAVE_GLOB) */ } static void @@ -4994,7 +4987,7 @@ test_util_num_cpus(void *arg) tt_skip(); tt_int_op(num, OP_GE, 1); - tt_int_op(num, OP_LE, 16); + tt_int_op(num, OP_LE, 128); done: ; @@ -5949,7 +5942,7 @@ static int fd_is_cloexec(tor_socket_t fd) { int flags = fcntl(fd, F_GETFD, 0); - return (flags & FD_CLOEXEC) == FD_CLOEXEC; + return (flags & FD_CLOEXEC) != 0; } #endif /* defined(FD_CLOEXEC) */ @@ -5959,7 +5952,7 @@ static int fd_is_nonblocking(tor_socket_t fd) { int flags = fcntl(fd, F_GETFL, 0); - return (flags & O_NONBLOCK) == O_NONBLOCK; + return (flags & O_NONBLOCK) != 0; } #endif /* !defined(_WIN32) */ diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c index 726e8e7427..f0ee58a445 100644 --- a/src/test/test_util_format.c +++ b/src/test/test_util_format.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_util_process.c b/src/test/test_util_process.c index fc79fe9b1f..28d5737cad 100644 --- a/src/test/test_util_process.c +++ b/src/test/test_util_process.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_voting_flags.c b/src/test/test_voting_flags.c index 72f70b9865..457b0fa796 100644 --- a/src/test/test_voting_flags.c +++ b/src/test/test_voting_flags.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -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); diff --git a/src/test/test_voting_schedule.c b/src/test/test_voting_schedule.c index df64b79167..6baf9e2e2e 100644 --- a/src/test/test_voting_schedule.c +++ b/src/test/test_voting_schedule.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020, The Tor Project, Inc. */ +/* Copyright (c) 2018-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c index 3734c08e48..19f8934f3c 100644 --- a/src/test/test_workqueue.c +++ b/src/test/test_workqueue.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "core/or/or.h" diff --git a/src/test/test_x509.c b/src/test/test_x509.c index 94e7db33de..ff21debb64 100644 --- a/src/test/test_x509.c +++ b/src/test/test_x509.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2020, The Tor Project, Inc. */ +/* Copyright (c) 2010-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define TOR_X509_PRIVATE diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 9b50de07a8..2fd424c07e 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** diff --git a/src/test/testing_rsakeys.c b/src/test/testing_rsakeys.c index e058f72d01..7d3c7301dc 100644 --- a/src/test/testing_rsakeys.c +++ b/src/test/testing_rsakeys.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2020, The Tor Project, Inc. */ + * Copyright (c) 2007-2021, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "lib/crypt_ops/crypto_rand.h" |