commit 6eb9de1b8c2ede739ebcd3514201c07365fadb18 Author: George Kadianakis desnacked@riseup.net Date: Thu Jun 1 14:35:39 2017 +0300
test: Add tests for fetching descs and handling SOCKS conns.
- Add tests that ensure that SOCKS requests for v2/v3 addresses get intercepted and handled.
- Add test that stores and lookups an HS descriptor in the client-side cache.
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/directory.c | 10 ------ src/or/directory.h | 12 ++++++- src/test/test_entryconn.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ src/test/test_hs_cache.c | 66 +++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 11 deletions(-)
diff --git a/src/or/directory.c b/src/or/directory.c index 698ee9013..9268c3ca2 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2203,16 +2203,6 @@ load_downloaded_routers(const char *body, smartlist_t *which, return added; }
-/** A structure to hold arguments passed into each directory response - * handler */ -typedef struct response_handler_args_t { - int status_code; - const char *reason; - const char *body; - size_t body_len; - const char *headers; -} response_handler_args_t; - static int handle_response_fetch_consensus(dir_connection_t *, const response_handler_args_t *); static int handle_response_fetch_certificate(dir_connection_t *, diff --git a/src/or/directory.h b/src/or/directory.h index 92d9b266d..1acdff346 100644 --- a/src/or/directory.h +++ b/src/or/directory.h @@ -168,6 +168,16 @@ int purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
#ifdef DIRECTORY_PRIVATE
+/** A structure to hold arguments passed into each directory response + * handler */ +typedef struct response_handler_args_t { + int status_code; + const char *reason; + const char *body; + size_t body_len; + const char *headers; +} response_handler_args_t; + struct get_handler_args_t; STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn, const struct get_handler_args_t *args); @@ -183,7 +193,7 @@ STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn, #endif
#ifdef TOR_UNIT_TESTS -/* Used only by test_dir.c */ +/* Used only by test_dir.c and test_hs_cache.c */
STATIC int parse_http_url(const char *headers, char **url); STATIC dirinfo_type_t dir_fetch_type(int dir_purpose, int router_purpose, diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index 12a631630..9fe3db26f 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -14,6 +14,10 @@ #include "confparse.h" #include "connection.h" #include "connection_edge.h" +#include "nodelist.h" + +#include "hs_cache.h" +#include "rendcache.h"
static void * entryconn_rewrite_setup(const struct testcase_t *tc) @@ -743,6 +747,87 @@ test_entryconn_rewrite_mapaddress_automap_onion4(void *arg) test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1); }
+/** Test that rewrite functions can handle v2 addresses */ +static void +test_entryconn_rewrite_onion_v2(void *arg) +{ + int retval; + entry_connection_t *conn = arg; + + (void) arg; + + rend_cache_init(); + + /* Make a SOCKS request */ + conn->socks_request->command = SOCKS_COMMAND_CONNECT; + strlcpy(conn->socks_request->address, + "pqeed46efnwmfuid.onion", + sizeof(conn->socks_request->address)); + + /* 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); + + /* Handle SOCKS and rewrite! */ + retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL); + tt_int_op(retval, OP_EQ, 0); + + /* Check connection state after rewrite */ + tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT); + /* check that the address got rewritten */ + tt_str_op(conn->socks_request->address, OP_EQ, + "pqeed46efnwmfuid"); + /* check that HS information got attached to the connection */ + tt_assert(ENTRY_TO_EDGE_CONN(conn)->rend_data); + tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident); + + done: + rend_cache_free_all(); + /* 'conn' is cleaned by handler */ +} + +/** Test that rewrite functions can handle v3 onion addresses */ +static void +test_entryconn_rewrite_onion_v3(void *arg) +{ + int retval; + entry_connection_t *conn = arg; + + (void) arg; + + hs_cache_init(); + + /* Make a SOCKS request */ + conn->socks_request->command = SOCKS_COMMAND_CONNECT; + strlcpy(conn->socks_request->address, + "git.p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad.onion", + sizeof(conn->socks_request->address)); + + /* 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! */ + retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL); + tt_int_op(retval, OP_EQ, 0); + + /* Check connection state after rewrite */ + tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT); + /* check that the address got rewritten */ + tt_str_op(conn->socks_request->address, OP_EQ, + "p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad"); + /* 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(); + /* 'conn' is cleaned by handler */ +} + #define REWRITE(name) \ { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
@@ -763,6 +848,8 @@ struct testcase_t entryconn_tests[] = { REWRITE(rewrite_mapaddress_automap_onion2), REWRITE(rewrite_mapaddress_automap_onion3), REWRITE(rewrite_mapaddress_automap_onion4), + REWRITE(rewrite_onion_v2), + REWRITE(rewrite_onion_v3),
END_OF_TESTCASES }; diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index 6c2addef9..d3950c0c2 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -7,6 +7,7 @@ */
#define CONNECTION_PRIVATE +#define DIRECTORY_PRIVATE #define HS_CACHE_PRIVATE
#include "ed25519_cert.h" @@ -431,6 +432,69 @@ test_hsdir_revision_counter_check(void *arg) tor_free(published_desc_str); }
+/** Test that we can store HS descriptors in the client HS cache. */ +static void +test_client_cache(void *arg) +{ + int retval; + ed25519_keypair_t signing_kp; + hs_descriptor_t *published_desc = NULL; + char *published_desc_str = NULL; + + response_handler_args_t *args = NULL; + dir_connection_t *conn = NULL; + + (void) arg; + + /* Initialize HSDir cache subsystem */ + init_test(); + + /* Generate a valid descriptor with normal values. */ + { + retval = ed25519_keypair_generate(&signing_kp, 0); + tt_int_op(retval, ==, 0); + published_desc = hs_helper_build_hs_desc_with_ip(&signing_kp); + tt_assert(published_desc); + retval = hs_desc_encode_descriptor(published_desc, &signing_kp, + &published_desc_str); + tt_int_op(retval, OP_EQ, 0); + } + + /* Test handle_response_fetch_hsdesc_v3() */ + { + args = tor_malloc_zero(sizeof(response_handler_args_t)); + args->status_code = 200; + args->reason = NULL; + args->body = published_desc_str; + args->body_len = strlen(published_desc_str); + + conn = tor_malloc_zero(sizeof(dir_connection_t)); + conn->hs_ident = tor_malloc_zero(sizeof(hs_ident_dir_conn_t)); + ed25519_pubkey_copy(&conn->hs_ident->identity_pk, &signing_kp.pubkey); + } + + /* store the descriptor! */ + retval = handle_response_fetch_hsdesc_v3(conn, args); + tt_int_op(retval, == , 0); + + /* fetch the descriptor and make sure it's there */ + { + hs_cache_client_descriptor_t *cached_desc = NULL; + cached_desc = lookup_v3_desc_as_client(signing_kp.pubkey.pubkey); + tt_assert(cached_desc); + tt_str_op(cached_desc->encoded_desc, OP_EQ, published_desc_str); + } + + done: + tor_free(args); + hs_descriptor_free(published_desc); + tor_free(published_desc_str); + if (conn) { + tor_free(conn->hs_ident); + tor_free(conn); + } +} + struct testcase_t hs_cache[] = { /* Encoding tests. */ { "directory", test_directory, TT_FORK, @@ -441,6 +505,8 @@ struct testcase_t hs_cache[] = { NULL, NULL }, { "upload_and_download_hs_desc", test_upload_and_download_hs_desc, TT_FORK, NULL, NULL }, + { "client_cache", test_client_cache, TT_FORK, + NULL, NULL },
END_OF_TESTCASES };
tor-commits@lists.torproject.org