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.
This commit is contained in:
George Kadianakis 2019-11-25 15:55:47 +02:00 committed by David Goulet
parent 70572b9abd
commit c7c9899bc4

View File

@ -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
};