summaryrefslogtreecommitdiff
path: root/src/test/test_dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test_dir.c')
-rw-r--r--src/test/test_dir.c246
1 files changed, 203 insertions, 43 deletions
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 4e5876fa3c..a9d9cba7df 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -1,12 +1,13 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2016, The Tor Project, Inc. */
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#include <math.h>
#define CONFIG_PRIVATE
+#define CONTROL_PRIVATE
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
#define ROUTER_PRIVATE
@@ -19,6 +20,7 @@
#include "or.h"
#include "confparse.h"
#include "config.h"
+#include "control.h"
#include "crypto_ed25519.h"
#include "directory.h"
#include "dirserv.h"
@@ -329,7 +331,7 @@ test_dir_formats(void *arg)
ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
&kp1.pubkey,
r2->cache_info.published_on,
- MIN_ONION_KEY_LIFETIME,
+ get_onion_key_lifetime(),
&ntor_cc_sign);
tt_assert(ntor_cc);
base64_encode(cert_buf, sizeof(cert_buf),
@@ -910,6 +912,23 @@ mock_get_by_ei_desc_digest(const char *d)
}
}
+static signed_descriptor_t *
+mock_ei_get_by_ei_digest(const char *d)
+{
+ char hex[HEX_DIGEST_LEN+1];
+ base16_encode(hex, sizeof(hex), d, DIGEST_LEN);
+ signed_descriptor_t *sd = &sd_ei_minimal;
+
+ if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) {
+ sd->signed_descriptor_body = (char *)EX_EI_MINIMAL;
+ sd->signed_descriptor_len = sizeof(EX_EI_MINIMAL);
+ sd->annotations_len = 0;
+ sd->saved_location = SAVED_NOWHERE;
+ return sd;
+ }
+ return NULL;
+}
+
static smartlist_t *mock_ei_insert_list = NULL;
static was_router_added_t
mock_ei_insert(routerlist_t *rl, extrainfo_t *ei, int warn_if_incompatible)
@@ -999,6 +1018,37 @@ test_dir_load_extrainfo(void *arg)
}
static void
+test_dir_getinfo_extra(void *arg)
+{
+ int r;
+ char *answer = NULL;
+ const char *errmsg = NULL;
+
+ (void)arg;
+ MOCK(extrainfo_get_by_descriptor_digest, mock_ei_get_by_ei_digest);
+ r = getinfo_helper_dir(NULL, "extra-info/digest/"
+ "11E0EDF526950739F7769810FCACAB8C882FAEEE", &answer,
+ &errmsg);
+ tt_int_op(0, OP_EQ, r);
+ tt_ptr_op(NULL, OP_EQ, errmsg);
+ tt_str_op(answer, OP_EQ, EX_EI_MINIMAL);
+ tor_free(answer);
+
+ answer = NULL;
+ r = getinfo_helper_dir(NULL, "extra-info/digest/"
+ "NOTAVALIDHEXSTRINGNOTAVALIDHEXSTRINGNOTA", &answer,
+ &errmsg);
+ tt_int_op(0, OP_EQ, r);
+ /* getinfo_helper_dir() should maybe return an error here but doesn't */
+ tt_ptr_op(NULL, OP_EQ, errmsg);
+ /* In any case, there should be no answer for an invalid hex string. */
+ tt_ptr_op(NULL, OP_EQ, answer);
+
+ done:
+ UNMOCK(extrainfo_get_by_descriptor_digest);
+}
+
+static void
test_dir_versions(void *arg)
{
tor_version_t ver1;
@@ -1065,6 +1115,7 @@ test_dir_versions(void *arg)
tt_int_op(0, OP_EQ, ver1.patchlevel);
tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
tt_str_op("alpha", OP_EQ, ver1.status_tag);
+ /* Go through the full set of status tags */
tt_int_op(0, OP_EQ, tor_version_parse("2.1.700-alpha", &ver1));
tt_int_op(2, OP_EQ, ver1.major);
tt_int_op(1, OP_EQ, ver1.minor);
@@ -1079,6 +1130,60 @@ test_dir_versions(void *arg)
tt_int_op(0, OP_EQ, ver1.patchlevel);
tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
tt_str_op("alpha-dev", OP_EQ, ver1.status_tag);
+ tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.5-rc", &ver1));
+ tt_int_op(0, OP_EQ, ver1.major);
+ tt_int_op(2, OP_EQ, ver1.minor);
+ tt_int_op(9, OP_EQ, ver1.micro);
+ tt_int_op(5, OP_EQ, ver1.patchlevel);
+ tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
+ tt_str_op("rc", OP_EQ, ver1.status_tag);
+ tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.6-rc-dev", &ver1));
+ tt_int_op(0, OP_EQ, ver1.major);
+ tt_int_op(2, OP_EQ, ver1.minor);
+ tt_int_op(9, OP_EQ, ver1.micro);
+ tt_int_op(6, OP_EQ, ver1.patchlevel);
+ tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
+ tt_str_op("rc-dev", OP_EQ, ver1.status_tag);
+ tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.8", &ver1));
+ tt_int_op(0, OP_EQ, ver1.major);
+ tt_int_op(2, OP_EQ, ver1.minor);
+ tt_int_op(9, OP_EQ, ver1.micro);
+ tt_int_op(8, OP_EQ, ver1.patchlevel);
+ tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
+ tt_str_op("", OP_EQ, ver1.status_tag);
+ tt_int_op(0, OP_EQ, tor_version_parse("0.2.9.9-dev", &ver1));
+ tt_int_op(0, OP_EQ, ver1.major);
+ tt_int_op(2, OP_EQ, ver1.minor);
+ tt_int_op(9, OP_EQ, ver1.micro);
+ tt_int_op(9, OP_EQ, ver1.patchlevel);
+ tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
+ tt_str_op("dev", OP_EQ, ver1.status_tag);
+ /* In #21450, we fixed an inconsistency in parsing versions > INT32_MAX
+ * between i386 and x86_64, as we used tor_parse_long, and then cast to int
+ */
+ tt_int_op(0, OP_EQ, tor_version_parse("0.2147483647.0", &ver1));
+ tt_int_op(0, OP_EQ, ver1.major);
+ tt_int_op(2147483647, OP_EQ, ver1.minor);
+ tt_int_op(0, OP_EQ, ver1.micro);
+ tt_int_op(0, OP_EQ, ver1.patchlevel);
+ tt_int_op(VER_RELEASE, OP_EQ, ver1.status);
+ tt_str_op("", OP_EQ, ver1.status_tag);
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.2147483648.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.4294967295.0", &ver1));
+ /* In #21278, we reject negative version components */
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.-1.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.-2147483648.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.-4294967295.0", &ver1));
+ /* In #21507, we reject version components with non-numeric prefixes */
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.-0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("+1.0.0", &ver1));
+ /* use the list in isspace() */
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.\t0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.\n0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.\v0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.\f0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0.\r0.0", &ver1));
+ tt_int_op(-1, OP_EQ, tor_version_parse("0. 0.0", &ver1));
#define tt_versionstatus_op(vs1, op, vs2) \
tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \
@@ -1098,6 +1203,7 @@ test_dir_versions(void *arg)
test_v_i_o(VS_RECOMMENDED, "0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8");
test_v_i_o(VS_OLD, "0.0.5.0", "0.0.5.1-cvs");
test_v_i_o(VS_NEW_IN_SERIES, "0.0.5.1-cvs", "0.0.5, 0.0.6");
+ test_v_i_o(VS_NEW, "0.2.9.9-dev", "0.2.9.9");
/* Not on list, but newer than any in same series. */
test_v_i_o(VS_NEW_IN_SERIES, "0.1.0.3",
"Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0");
@@ -1136,6 +1242,70 @@ test_dir_versions(void *arg)
"Tor 0.2.1.0-dev (r99)"));
tt_int_op(1,OP_EQ, tor_version_as_new_as("Tor 0.2.1.1",
"Tor 0.2.1.0-dev (r99)"));
+ /* And git revisions */
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-56788a2489127072)",
+ "Tor 0.2.9.9 (git-56788a2489127072)"));
+ /* a git revision is newer than no git revision */
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-56788a2489127072)",
+ "Tor 0.2.9.9"));
+ /* a longer git revision is newer than a shorter git revision
+ * this should be true if they prefix-match, but if they don't, they are
+ * incomparable, because hashes aren't ordered (but we compare their bytes
+ * anyway) */
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-56788a2489127072d513cf4baf35a8ff475f3c7b)",
+ "Tor 0.2.9.9 (git-56788a2489127072)"));
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-0102)",
+ "Tor 0.2.9.9 (git-03)"));
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-0102)",
+ "Tor 0.2.9.9 (git-00)"));
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-01)",
+ "Tor 0.2.9.9 (git-00)"));
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2.9.9 (git-00)",
+ "Tor 0.2.9.9 (git-01)"));
+ /* In #21278, we comapre without integer overflows.
+ * But since #21450 limits version components to [0, INT32_MAX], it is no
+ * longer possible to cause an integer overflow in tor_version_compare() */
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.0.0.0",
+ "Tor 2147483647.0.0.0"));
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 2147483647.0.0.0",
+ "Tor 0.0.0.0"));
+ /* These versions used to cause an overflow, now they don't parse
+ * (and authorities reject their descriptors), and log a BUG message */
+ setup_full_capture_of_logs(LOG_WARN);
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.0.0.0",
+ "Tor 0.-2147483648.0.0"));
+ expect_single_log_msg_containing("unparseable");
+ mock_clean_saved_logs();
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2147483647.0.0",
+ "Tor 0.-1.0.0"));
+ expect_single_log_msg_containing("unparseable");
+ mock_clean_saved_logs();
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.2147483647.0.0",
+ "Tor 0.-2147483648.0.0"));
+ expect_single_log_msg_containing("unparseable");
+ mock_clean_saved_logs();
+ tt_int_op(1,OP_EQ, tor_version_as_new_as(
+ "Tor 4294967295.0.0.0",
+ "Tor 0.0.0.0"));
+ expect_no_log_entry();
+ tt_int_op(0,OP_EQ, tor_version_as_new_as(
+ "Tor 0.4294967295.0.0",
+ "Tor 0.-4294967295.0.0"));
+ expect_single_log_msg_containing("unparseable");
+ mock_clean_saved_logs();
+ teardown_capture_of_logs();
/* Now try git revisions */
tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1));
@@ -1145,11 +1315,24 @@ test_dir_versions(void *arg)
tt_int_op(7,OP_EQ, ver1.patchlevel);
tt_int_op(3,OP_EQ, ver1.git_tag_len);
tt_mem_op(ver1.git_tag,OP_EQ, "\xff\x00\xff", 3);
+ /* reject bad hex digits */
tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1));
+ /* reject odd hex digit count */
tt_int_op(-1,OP_EQ, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1));
+ /* ignore "git " */
tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1));
+ /* standard length is 16 hex digits */
+ tt_int_op(0,OP_EQ, tor_version_parse("0.5.6.7 (git-0010203040506070)",
+ &ver1));
+ /* length limit is 40 hex digits */
+ tt_int_op(0,OP_EQ, tor_version_parse(
+ "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f10111213)",
+ &ver1));
+ tt_int_op(-1,OP_EQ, tor_version_parse(
+ "0.5.6.7 (git-000102030405060708090a0b0c0d0e0f1011121314)",
+ &ver1));
done:
- ;
+ teardown_capture_of_logs();
}
/** Run unit tests for directory fp_pair functions. */
@@ -4399,15 +4582,7 @@ test_dir_should_use_directory_guards(void *data)
}
NS_DECL(void,
-directory_initiate_command_routerstatus, (const routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- dir_indirection_t indirection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since,
- circuit_guard_state_t *guardstate));
+directory_initiate_request, (directory_request_t *req));
static void
test_dir_should_not_init_request_to_ourselves(void *data)
@@ -4417,7 +4592,7 @@ test_dir_should_not_init_request_to_ourselves(void *data)
crypto_pk_t *key = pk_generate(2);
(void) data;
- NS_MOCK(directory_initiate_command_routerstatus);
+ NS_MOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
@@ -4432,15 +4607,15 @@ test_dir_should_not_init_request_to_ourselves(void *data)
dir_server_add(ourself);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
done:
- NS_UNMOCK(directory_initiate_command_routerstatus);
+ NS_UNMOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
crypto_pk_free(key);
@@ -4454,7 +4629,7 @@ test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
| MICRODESC_DIRINFO;
(void) data;
- NS_MOCK(directory_initiate_command_routerstatus);
+ NS_MOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
@@ -4465,14 +4640,14 @@ test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
dir_server_add(ds);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 0);
done:
- NS_UNMOCK(directory_initiate_command_routerstatus);
+ NS_UNMOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
}
@@ -4483,7 +4658,7 @@ test_dir_should_init_request_to_dir_auths(void *data)
dir_server_t *ds = NULL;
(void) data;
- NS_MOCK(directory_initiate_command_routerstatus);
+ NS_MOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
@@ -4494,39 +4669,23 @@ test_dir_should_init_request_to_dir_auths(void *data)
dir_server_add(ds);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 1);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 1);
directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
NULL);
- tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 2);
+ tt_int_op(CALLED(directory_initiate_request), OP_EQ, 2);
done:
- NS_UNMOCK(directory_initiate_command_routerstatus);
+ NS_UNMOCK(directory_initiate_request);
clear_dir_servers();
routerlist_free_all();
}
void
-NS(directory_initiate_command_routerstatus)(const routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- dir_indirection_t indirection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since,
- circuit_guard_state_t *guardstate)
+NS(directory_initiate_request)(directory_request_t *req)
{
- (void)status;
- (void)dir_purpose;
- (void)router_purpose;
- (void)indirection;
- (void)resource;
- (void)payload;
- (void)payload_len;
- (void)if_modified_since;
- (void)guardstate;
- CALLED(directory_initiate_command_routerstatus)++;
+ (void)req;
+ CALLED(directory_initiate_request)++;
}
static void
@@ -5837,6 +5996,7 @@ struct testcase_t dir_tests[] = {
DIR(parse_router_list, TT_FORK),
DIR(load_routers, TT_FORK),
DIR(load_extrainfo, TT_FORK),
+ DIR(getinfo_extra, 0),
DIR_LEGACY(versions),
DIR_LEGACY(fp_pairs),
DIR(split_fps, 0),