commit c7c9899bc4d4d1b0ff6df31fe0526133b23cd8bd Author: George Kadianakis <desnac...@riseup.net> Date: Mon Nov 25 15:55:47 2019 +0200
hsv3: Add tests for permanently storing auth credentials. Remove Permanent flag from old tests, and make a new test that does all the permanent things. --- src/test/test_hs_control.c | 157 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 3 deletions(-) diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c index 927908032..0de2bca04 100644 --- a/src/test/test_hs_control.c +++ b/src/test/test_hs_control.c @@ -30,6 +30,17 @@ #include "test/test_helpers.h" +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef _WIN32 +/* For mkdir() */ +#include <direct.h> +#else +#include <dirent.h> +#endif /* defined(_WIN32) */ + /* mock ID digest and longname for node that's in nodelist */ #define HSDIR_EXIST_ID \ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \ @@ -235,7 +246,7 @@ test_hs_control_good_onion_client_auth_add(void *arg) /* Register first service */ args = tor_strdup("2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd " "x25519:iJ1tjKCrMAbiFT2bVrCjhbfMDnE1fpaRbIS5ZHKUvEQ= " - "ClientName=bob Flags=Permanent"); + "ClientName=bob"); retval = handle_control_command(&conn, (uint32_t) strlen(args), args); tt_int_op(retval, OP_EQ, 0); @@ -267,7 +278,7 @@ test_hs_control_good_onion_client_auth_add(void *arg) digest256map_get(client_auths, service_identity_pk_2fv.pubkey); tt_assert(client_2fv); tt_str_op(client_2fv->nickname, OP_EQ, "bob"); - tt_int_op(client_2fv->flags, OP_EQ, CLIENT_AUTH_FLAG_IS_PERMANENT); + tt_int_op(client_2fv->flags, OP_EQ, 0); hs_client_service_authorization_t *client_jt4 = digest256map_get(client_auths, service_identity_pk_jt4.pubkey); @@ -286,7 +297,7 @@ test_hs_control_good_onion_client_auth_add(void *arg) #define VIEW_CORRECT_REPLY_NO_ADDR "250-ONION_CLIENT_AUTH_VIEW\r\n" \ "250-CLIENT x25519:eIIdIGoSZwI2Q/lSzpf92akGki5I+PZIDz37MA5BhlA=\r\n"\ "250-CLIENT x25519:iJ1tjKCrMAbiFT2bVrCjhbfMDnE1fpaRbIS5ZHKUvEQ= " \ - "ClientName=bob Flags=Permanent\r\n" \ + "ClientName=bob\r\n" \ "250 OK\r\n" retval = handle_control_command(&conn, (uint32_t) strlen(args), args); @@ -466,6 +477,144 @@ test_hs_control_bad_onion_client_auth_add(void *arg) hs_client_free_all(); } +/** Test that we can correctly add permanent client auth credentials using the + * control port. */ +static void +test_hs_control_store_permanent_creds(void *arg) +{ + (void) arg; + + MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); + + int retval; + ed25519_public_key_t service_identity_pk_2fv; + control_connection_t conn; + char *args = NULL; + char *cp1 = NULL; + char *creds_file_str = NULL; + char *creds_fname = NULL; + + size_t sz; + + { /* Setup the control conn */ + memset(&conn, 0, sizeof(control_connection_t)); + TO_CONN(&conn)->outbuf = buf_new(); + conn.current_cmd = tor_strdup("ONION_CLIENT_AUTH_ADD"); + } + + { /* Setup the services */ + retval = hs_parse_address( + "2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd", + &service_identity_pk_2fv, + NULL, NULL); + tt_int_op(retval, OP_EQ, 0); + } + + digest256map_t *client_auths = get_hs_client_auths_map(); + tt_assert(!client_auths); + + /* Try registering first service with no ClientOnionAuthDir set */ + args = tor_strdup("2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd " + "x25519:iJ1tjKCrMAbiFT2bVrCjhbfMDnE1fpaRbIS5ZHKUvEQ= " + "ClientName=bob Flags=Permanent"); + + retval = handle_control_command(&conn, (uint32_t) strlen(args), args); + tt_int_op(retval, OP_EQ, 0); + + /* Check control port response. This one should fail. */ + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, "553 Unable to store creds for " + "\"2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd\"\r\n"); + + { /* Setup ClientOnionAuthDir */ + int ret; + char *perm_creds_dir = tor_strdup(get_fname("permanent_credentials")); + + #ifdef _WIN32 + ret = mkdir(perm_creds_dir); + #else + ret = mkdir(perm_creds_dir, 0700); + #endif + tt_int_op(ret, OP_EQ, 0); + + get_options_mutable()->ClientOnionAuthDir = perm_creds_dir; + } + + tor_free(args); + tor_free(cp1); + + /* Try the control port command again. This time it should work! */ + args = tor_strdup("2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd " + "x25519:iJ1tjKCrMAbiFT2bVrCjhbfMDnE1fpaRbIS5ZHKUvEQ= " + "ClientName=bob Flags=Permanent"); + retval = handle_control_command(&conn, (uint32_t) strlen(args), args); + tt_int_op(retval, OP_EQ, 0); + + /* Check control port response */ + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, "250 OK\r\n"); + + /* Check file contents! */ + creds_fname = tor_strdup(get_fname("permanent_credentials/" + "2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd.auth_private")); + creds_file_str = read_file_to_str(creds_fname, RFTS_BIN, NULL); + + tt_assert(creds_file_str); + tt_str_op(creds_file_str, OP_EQ, + "2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd:descriptor:" + /* This is the base32 represenation of the base64 iJ1t... key above */ + "x25519:rcow3dfavmyanyqvhwnvnmfdqw34ydtrgv7jnelmqs4wi4uuxrca"); + + tor_free(args); + tor_free(cp1); + + /* Overwrite the credentials and check that they got overwrited. */ + args = tor_strdup("2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd " + "x25519:UDRvZLvcJo0QRLvDfkpgbtsqbkhIUQZyeo2FNBrgS18= " + "ClientName=fab Flags=Permanent"); + retval = handle_control_command(&conn, (uint32_t) strlen(args), args); + tt_int_op(retval, OP_EQ, 0); + + /* Check control port response: we replaced! */ + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, "251 Client for onion existed and replaced\r\n"); + + tor_free(creds_file_str); + + /* Check creds file contents again. See that the key got updated */ + creds_file_str = read_file_to_str(creds_fname, RFTS_BIN, NULL); + tt_assert(creds_file_str); + tt_str_op(creds_file_str, OP_EQ, + "2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd:descriptor:" + /* This is the base32 represenation of the base64 UDRv... key above */ + "x25519:ka2g6zf33qti2ecexpbx4stan3nsu3sijbiqm4t2rwctigxajnpq"); + + /* Now for our final act!!! Actually get the HS client subsystem to parse the + * whole directory and make sure that it extracted the right credential! */ + hs_config_client_authorization(get_options(), 0); + + client_auths = get_hs_client_auths_map(); + tt_assert(client_auths); + tt_uint_op(digest256map_size(client_auths), OP_EQ, 1); + + hs_client_service_authorization_t *client_2fv = + digest256map_get(client_auths, service_identity_pk_2fv.pubkey); + tt_assert(client_2fv); + tt_assert(!client_2fv->nickname); + tt_int_op(client_2fv->flags, OP_EQ, CLIENT_AUTH_FLAG_IS_PERMANENT); + tt_str_op(hex_str((char*)client_2fv->enc_seckey.secret_key, 32), OP_EQ, + "50346F64BBDC268D1044BBC37E4A606EDB2A6E48485106727A8D85341AE04B5F"); + + done: + tor_free(args); + tor_free(cp1); + buf_free(TO_CONN(&conn)->outbuf); + tor_free(conn.current_cmd); + tor_free(creds_fname); + tor_free(creds_file_str); + hs_client_free_all(); +} + struct testcase_t hs_control_tests[] = { { "hs_desc_event", test_hs_desc_event, TT_FORK, NULL, NULL }, @@ -475,6 +624,8 @@ struct testcase_t hs_control_tests[] = { { "hs_control_bad_onion_client_auth_add", test_hs_control_bad_onion_client_auth_add, TT_FORK, NULL, NULL }, + { "hs_control_store_permanent_creds", + test_hs_control_store_permanent_creds, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; _______________________________________________ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits