mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
test: Add prop224 directory fetch/upload unit tests
Signed-off-by: David Goulet <dgoulet@torproject.org> Signed-off-by: George Kadianakis <desnacked@riseup.net>
This commit is contained in:
parent
f59990f24d
commit
a8efd087bd
@ -3532,7 +3532,7 @@ parse_hs_version_from_post(const char *url, const char *prefix,
|
|||||||
/* Handle the POST request for a hidden service descripror. The request is in
|
/* Handle the POST request for a hidden service descripror. The request is in
|
||||||
* <b>url</b>, the body of the request is in <b>body</b>. Return 200 on success
|
* <b>url</b>, the body of the request is in <b>body</b>. Return 200 on success
|
||||||
* else return 400 indicating a bad request. */
|
* else return 400 indicating a bad request. */
|
||||||
static int
|
STATIC int
|
||||||
handle_post_hs_descriptor(const char *url, const char *body)
|
handle_post_hs_descriptor(const char *url, const char *body)
|
||||||
{
|
{
|
||||||
int version;
|
int version;
|
||||||
|
@ -157,6 +157,8 @@ STATIC int download_status_schedule_get_delay(download_status_t *dls,
|
|||||||
int min_delay, int max_delay,
|
int min_delay, int max_delay,
|
||||||
time_t now);
|
time_t now);
|
||||||
|
|
||||||
|
STATIC int handle_post_hs_descriptor(const char *url, const char *body);
|
||||||
|
|
||||||
STATIC char* authdir_type_to_string(dirinfo_type_t auth);
|
STATIC char* authdir_type_to_string(dirinfo_type_t auth);
|
||||||
STATIC const char * dir_conn_purpose_to_string(int purpose);
|
STATIC const char * dir_conn_purpose_to_string(int purpose);
|
||||||
STATIC int should_use_directory_guards(const or_options_t *options);
|
STATIC int should_use_directory_guards(const or_options_t *options);
|
||||||
|
@ -50,19 +50,6 @@ ENABLE_GCC_WARNING(overlength-strings)
|
|||||||
|
|
||||||
#define NS_MODULE dir_handle_get
|
#define NS_MODULE dir_handle_get
|
||||||
|
|
||||||
static void
|
|
||||||
connection_write_to_buf_mock(const char *string, size_t len,
|
|
||||||
connection_t *conn, int zlib)
|
|
||||||
{
|
|
||||||
(void) zlib;
|
|
||||||
|
|
||||||
tor_assert(string);
|
|
||||||
tor_assert(conn);
|
|
||||||
|
|
||||||
write_to_buf(string, len, conn->outbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET(path) "GET " path " HTTP/1.0\r\n\r\n"
|
|
||||||
#define NOT_FOUND "HTTP/1.0 404 Not found\r\n\r\n"
|
#define NOT_FOUND "HTTP/1.0 404 Not found\r\n\r\n"
|
||||||
#define BAD_REQUEST "HTTP/1.0 400 Bad request\r\n\r\n"
|
#define BAD_REQUEST "HTTP/1.0 400 Bad request\r\n\r\n"
|
||||||
#define SERVER_BUSY "HTTP/1.0 503 Directory busy, try again later\r\n\r\n"
|
#define SERVER_BUSY "HTTP/1.0 503 Directory busy, try again later\r\n\r\n"
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "routerlist.h"
|
#include "routerlist.h"
|
||||||
#include "nodelist.h"
|
#include "nodelist.h"
|
||||||
|
#include "buffers.h"
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "test_helpers.h"
|
#include "test_helpers.h"
|
||||||
@ -92,3 +93,15 @@ helper_setup_fake_routerlist(void)
|
|||||||
UNMOCK(router_descriptor_is_older_than);
|
UNMOCK(router_descriptor_is_older_than);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
connection_write_to_buf_mock(const char *string, size_t len,
|
||||||
|
connection_t *conn, int zlib)
|
||||||
|
{
|
||||||
|
(void) zlib;
|
||||||
|
|
||||||
|
tor_assert(string);
|
||||||
|
tor_assert(conn);
|
||||||
|
|
||||||
|
write_to_buf(string, len, conn->outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@ const char *get_yesterday_date_str(void);
|
|||||||
|
|
||||||
void helper_setup_fake_routerlist(void);
|
void helper_setup_fake_routerlist(void);
|
||||||
|
|
||||||
|
#define GET(path) "GET " path " HTTP/1.0\r\n\r\n"
|
||||||
|
void connection_write_to_buf_mock(const char *string, size_t len,
|
||||||
|
connection_t *conn, int zlib);
|
||||||
|
|
||||||
extern const char TEST_DESCRIPTORS[];
|
extern const char TEST_DESCRIPTORS[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#include "ed25519_cert.h"
|
#include "ed25519_cert.h"
|
||||||
#include "hs_cache.h"
|
#include "hs_cache.h"
|
||||||
#include "rendcache.h"
|
#include "rendcache.h"
|
||||||
|
#include "directory.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
#include "test_helpers.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
/* Build an intro point using a blinded key and an address. */
|
/* Build an intro point using a blinded key and an address. */
|
||||||
@ -282,12 +286,197 @@ test_clean_as_dir(void *arg)
|
|||||||
tor_free(desc1_str);
|
tor_free(desc1_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test helper: Fetch an HS descriptor from an HSDir (for the hidden service
|
||||||
|
with <b>blinded_key</b>. Return the received descriptor string. */
|
||||||
|
static char *
|
||||||
|
helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
char *received_desc = NULL;
|
||||||
|
char *hsdir_query_str = NULL;
|
||||||
|
|
||||||
|
/* The dir conn we are going to simulate */
|
||||||
|
dir_connection_t *conn = NULL;
|
||||||
|
tor_addr_t mock_tor_addr;
|
||||||
|
|
||||||
|
/* First extract the blinded public key that we are going to use in our
|
||||||
|
query, and then build the actual query string. */
|
||||||
|
{
|
||||||
|
char hsdir_cache_key[ED25519_BASE64_LEN+1];
|
||||||
|
|
||||||
|
retval = ed25519_public_to_base64(hsdir_cache_key,
|
||||||
|
blinded_key);
|
||||||
|
tt_int_op(retval, ==, 0);
|
||||||
|
tor_asprintf(&hsdir_query_str, GET("/tor/hs/3/%s"), hsdir_cache_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate an HTTP GET request to the HSDir */
|
||||||
|
conn = dir_connection_new(tor_addr_family(&mock_tor_addr));
|
||||||
|
TO_CONN(conn)->linked = 1;/* Pretend the conn is encrypted :) */
|
||||||
|
retval = directory_handle_command_get(conn, hsdir_query_str,
|
||||||
|
NULL, 0);
|
||||||
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
|
|
||||||
|
/* Read the descriptor that the HSDir just served us */
|
||||||
|
{
|
||||||
|
char *headers = NULL;
|
||||||
|
size_t body_used = 0;
|
||||||
|
|
||||||
|
fetch_from_buf_http(TO_CONN(conn)->outbuf, &headers, MAX_HEADERS_SIZE,
|
||||||
|
&received_desc, &body_used, 10000, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_free(hsdir_query_str);
|
||||||
|
|
||||||
|
return received_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Publish a descriptor to the HSDir, then fetch it. Check that the received
|
||||||
|
descriptor matches the published one. */
|
||||||
|
static void
|
||||||
|
test_upload_and_download_hs_desc(void *arg)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
hs_descriptor_t *published_desc;
|
||||||
|
|
||||||
|
char *published_desc_str = NULL;
|
||||||
|
char *received_desc_str = NULL;
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
/* Initialize HSDir cache subsystem */
|
||||||
|
init_test();
|
||||||
|
|
||||||
|
/* Generate a valid descriptor with normal values. */
|
||||||
|
{
|
||||||
|
published_desc = helper_build_hs_desc(42, 3 * 60 * 60, NULL);
|
||||||
|
tt_assert(published_desc);
|
||||||
|
retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
|
||||||
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Publish descriptor to the HSDir */
|
||||||
|
{
|
||||||
|
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
|
||||||
|
tt_int_op(retval, ==, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simulate a fetch of the previously published descriptor */
|
||||||
|
{
|
||||||
|
const ed25519_public_key_t *blinded_key;
|
||||||
|
blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
|
||||||
|
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify we received the exact same descriptor we published earlier */
|
||||||
|
tt_str_op(received_desc_str, OP_EQ, published_desc_str);
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_free(received_desc_str);
|
||||||
|
tor_free(published_desc_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that HSDirs reject outdated descriptors based on their revision
|
||||||
|
* counter. Also test that HSDirs correctly replace old descriptors with newer
|
||||||
|
* descriptors. */
|
||||||
|
static void
|
||||||
|
test_hsdir_revision_counter_check(void *arg)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
hs_descriptor_t *published_desc;
|
||||||
|
char *published_desc_str = NULL;
|
||||||
|
|
||||||
|
char *received_desc_str = NULL;
|
||||||
|
hs_descriptor_t *received_desc = NULL;
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
/* Initialize HSDir cache subsystem */
|
||||||
|
init_test();
|
||||||
|
|
||||||
|
/* Generate a valid descriptor with normal values. */
|
||||||
|
{
|
||||||
|
published_desc = helper_build_hs_desc(1312, 3 * 60 * 60, NULL);
|
||||||
|
tt_assert(published_desc);
|
||||||
|
retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
|
||||||
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Publish descriptor to the HSDir */
|
||||||
|
{
|
||||||
|
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
|
||||||
|
tt_int_op(retval, ==, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try publishing again with the same revision counter: Should fail. */
|
||||||
|
{
|
||||||
|
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
|
||||||
|
tt_int_op(retval, ==, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch the published descriptor and validate the revision counter. */
|
||||||
|
{
|
||||||
|
const ed25519_public_key_t *blinded_key;
|
||||||
|
|
||||||
|
blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
|
||||||
|
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
|
||||||
|
|
||||||
|
retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc);
|
||||||
|
tt_int_op(retval, ==, 0);
|
||||||
|
tt_assert(received_desc);
|
||||||
|
|
||||||
|
/* Check that the revision counter is correct */
|
||||||
|
tt_int_op(received_desc->plaintext_data.revision_counter, ==, 1312);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the revision counter and try again. Should work. */
|
||||||
|
{
|
||||||
|
published_desc->plaintext_data.revision_counter = 1313;
|
||||||
|
tor_free(published_desc_str);
|
||||||
|
retval = hs_desc_encode_descriptor(published_desc, &published_desc_str);
|
||||||
|
tt_int_op(retval, OP_EQ, 0);
|
||||||
|
|
||||||
|
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
|
||||||
|
tt_int_op(retval, ==, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Again, fetch the published descriptor and perform the revision counter
|
||||||
|
validation. The revision counter must have changed. */
|
||||||
|
{
|
||||||
|
const ed25519_public_key_t *blinded_key;
|
||||||
|
|
||||||
|
blinded_key = &published_desc->plaintext_data.blinded_kp.pubkey;
|
||||||
|
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
|
||||||
|
|
||||||
|
retval = hs_desc_decode_descriptor(received_desc_str,NULL, &received_desc);
|
||||||
|
tt_int_op(retval, ==, 0);
|
||||||
|
tt_assert(received_desc);
|
||||||
|
|
||||||
|
/* Check that the revision counter is the latest */
|
||||||
|
tt_int_op(received_desc->plaintext_data.revision_counter, ==, 1313);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
hs_descriptor_free(published_desc);
|
||||||
|
hs_descriptor_free(received_desc);
|
||||||
|
tor_free(received_desc_str);
|
||||||
|
tor_free(published_desc_str);
|
||||||
|
}
|
||||||
|
|
||||||
struct testcase_t hs_cache[] = {
|
struct testcase_t hs_cache[] = {
|
||||||
/* Encoding tests. */
|
/* Encoding tests. */
|
||||||
{ "directory", test_directory, TT_FORK,
|
{ "directory", test_directory, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
{ "clean_as_dir", test_clean_as_dir, TT_FORK,
|
{ "clean_as_dir", test_clean_as_dir, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
|
{ "hsdir_revision_counter_check", test_hsdir_revision_counter_check, TT_FORK,
|
||||||
|
NULL, NULL },
|
||||||
|
{ "upload_and_download_hs_desc", test_upload_and_download_hs_desc, TT_FORK,
|
||||||
|
NULL, NULL },
|
||||||
|
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user