tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 1db13809c6f4aa1bc9b240a4bda54066730ee75f
parent 4d642100907cb2125c23f3404d2ab907543433b6
Author: Nick Mathewson <nickm@torproject.org>
Date:   Mon, 10 Feb 2025 16:42:52 -0500

Parse microdesc family-ids lines.

Diffstat:
Msrc/feature/dirparse/microdesc_parse.c | 11+++++++++++
Msrc/feature/dirparse/parsecommon.h | 1+
Msrc/test/test_microdesc.c | 39+++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/src/feature/dirparse/microdesc_parse.c b/src/feature/dirparse/microdesc_parse.c @@ -35,6 +35,7 @@ static token_rule_t microdesc_token_table[] = { T0N("id", K_ID, GE(2), NO_OBJ ), T0N("a", K_A, GE(1), NO_OBJ ), T01("family", K_FAMILY, CONCAT_ARGS, NO_OBJ ), + T01("family-ids", K_FAMILY_IDS, CONCAT_ARGS, NO_OBJ ), T01("p", K_P, CONCAT_ARGS, NO_OBJ ), T01("p6", K_P6, CONCAT_ARGS, NO_OBJ ), A01("@last-listed", A_LAST_LISTED, CONCAT_ARGS, NO_OBJ ), @@ -252,6 +253,16 @@ microdesc_parse_fields(microdesc_t *md, NULL, NF_WARN_MALFORMED); } + if ((tok = find_opt_by_keyword(tokens, K_FAMILY_IDS))) { + smartlist_t *ids = smartlist_new(); + smartlist_split_string(ids, tok->args[0], " ", + SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); + if (smartlist_len(ids) > 0) { + md->family_ids = ids; + } else { + smartlist_free(ids); + } + } if ((tok = find_opt_by_keyword(tokens, K_P))) { md->exit_policy = parse_short_policy(tok->args[0]); diff --git a/src/feature/dirparse/parsecommon.h b/src/feature/dirparse/parsecommon.h @@ -45,6 +45,7 @@ typedef enum { K_UPTIME, K_DIR_SIGNING_KEY, K_FAMILY, + K_FAMILY_KEYS, K_FINGERPRINT, K_HIBERNATING, K_READ_HISTORY, diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c @@ -789,6 +789,44 @@ test_md_parse_no_onion_key(void *arg) teardown_capture_of_logs(); } +static void +test_md_parse_family_ids(void *arg) +{ + (void)arg; + + const char GOOD_MDS[] = + "onion-key\n" + "ntor-onion-key VHlycmFueSwgbGlrZSBoZWxsLCBpcyBub3QgZWFzaWw\n" + "id ed25519 eSBjb25xdWVyZWQ7IHlldCB3ZSBoYXZlIHRoaXMgY28\n" + "family-ids\n" + "onion-key\n" + "ntor-onion-key bnNvbGF0aW9uIHdpdGggdXMsIHRoYXQgdGhlIGhhcmQ\n" + "id ed25519 ZXIgdGhlIGNvbmZsaWN0LCB0aGUgbW9yZSBnbG9yaW8\n" + "family-ids ed25519:dXMgdGhlIHRyaXVtcGguICAgIC1UaG9tYXMgUGFpbmU " + "other:Example\n"; + smartlist_t *mds = NULL; + mds = microdescs_parse_from_string(GOOD_MDS, NULL, 1, SAVED_NOWHERE, NULL); + tt_assert(mds); + tt_int_op(smartlist_len(mds), OP_EQ, 2); + + const microdesc_t *md1 = smartlist_get(mds, 0); + tt_ptr_op(md1->family_ids, OP_EQ, NULL); + + const microdesc_t *md2 = smartlist_get(mds, 1); + tt_ptr_op(md2->family_ids, OP_NE, NULL); + tt_int_op(smartlist_len(md2->family_ids), OP_EQ, 2); + tt_str_op(smartlist_get(md2->family_ids, 0), OP_EQ, + "ed25519:dXMgdGhlIHRyaXVtcGguICAgIC1UaG9tYXMgUGFpbmU"); + tt_str_op(smartlist_get(md2->family_ids, 1), OP_EQ, + "other:Example"); + + done: + if (mds) { + SMARTLIST_FOREACH(mds, microdesc_t *, m, microdesc_free(m)); + smartlist_free(mds); + } +} + static int mock_rgsbd_called = 0; static routerstatus_t *mock_rgsbd_val_a = NULL; static routerstatus_t *mock_rgsbd_val_b = NULL; @@ -924,6 +962,7 @@ struct testcase_t microdesc_tests[] = { { "parse", test_md_parse, 0, NULL, NULL }, { "parse_id_ed25519", test_md_parse_id_ed25519, 0, NULL, NULL }, { "parse_no_onion_key", test_md_parse_no_onion_key, 0, NULL, NULL }, + { "parse_family_ids", test_md_parse_family_ids, 0, NULL, NULL }, { "reject_cache", test_md_reject_cache, TT_FORK, NULL, NULL }, { "corrupt_desc", test_md_corrupt_desc, TT_FORK, NULL, NULL }, END_OF_TESTCASES