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; NS_MOCK(router_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: NS_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); }
char *upnp_create_device_desc(struct upnp_device_descriptor *device_def) { char *result = NULL; struct xmldoc *doc; doc = generate_desc(device_def); if (doc != NULL) { result = xmldoc_tostring(doc); xmldoc_free(doc); } return result; }
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_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; NS_MOCK(router_get_my_routerinfo); NS_MOCK(hid_serv_responsible_for_desc_id); 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 hid_serv_responsible_for_desc_id_response = 1; 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: NS_UNMOCK(router_get_my_routerinfo); NS_UNMOCK(hid_serv_responsible_for_desc_id); tor_free(mock_routerinfo); rend_cache_free_all(); rend_encoded_v2_service_descriptor_free(desc_holder); tor_free(service_id); }
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(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); desc_id_base32[0]++; 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]--; 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); mock_rend_query->auth_type = REND_BASIC_AUTH; client_cookie[0] = 'A'; memcpy(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); 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); }