mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
control-port: Implement ONION_CLIENT_AUTH_VIEW.
This commit is contained in:
parent
ee4b2287c6
commit
db6a48b6bf
@ -2321,6 +2321,7 @@ static const control_cmd_def_t CONTROL_COMMANDS[] =
|
||||
ONE_LINE(del_onion, CMD_FL_WIPE),
|
||||
ONE_LINE(onion_client_auth_add, CMD_FL_WIPE),
|
||||
ONE_LINE(onion_client_auth_remove, 0),
|
||||
ONE_LINE(onion_client_auth_view, 0),
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -209,3 +209,120 @@ handle_control_onion_client_auth_remove(control_connection_t *conn,
|
||||
err:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Helper: Return a newly allocated string with the encoding of client
|
||||
* authorization credentials */
|
||||
static char *
|
||||
encode_client_auth_cred_for_control_port(
|
||||
hs_client_service_authorization_t *cred)
|
||||
{
|
||||
smartlist_t *control_line = smartlist_new();
|
||||
char x25519_b64[128];
|
||||
char *msg_str = NULL;
|
||||
|
||||
tor_assert(cred);
|
||||
|
||||
if (base64_encode(x25519_b64, sizeof(x25519_b64),
|
||||
(char *)cred->enc_seckey.secret_key,
|
||||
sizeof(cred->enc_seckey.secret_key), 0) < 0) {
|
||||
tor_assert_nonfatal_unreached();
|
||||
goto err;
|
||||
}
|
||||
|
||||
smartlist_add_asprintf(control_line, "CLIENT x25519:%s", x25519_b64);
|
||||
|
||||
if (cred->nickname) { /* nickname is optional */
|
||||
smartlist_add_asprintf(control_line, " ClientName=%s", cred->nickname);
|
||||
}
|
||||
|
||||
if (cred->flags) { /* flags are also optional */
|
||||
if (cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) {
|
||||
smartlist_add_asprintf(control_line, " Flags=Permanent");
|
||||
}
|
||||
}
|
||||
|
||||
/* Join all the components into a single string */
|
||||
msg_str = smartlist_join_strings(control_line, "", 0, NULL);
|
||||
|
||||
err:
|
||||
SMARTLIST_FOREACH(control_line, char *, cp, tor_free(cp));
|
||||
smartlist_free(control_line);
|
||||
|
||||
return msg_str;
|
||||
}
|
||||
|
||||
/** Syntax details for ONION_CLIENT_AUTH_VIEW */
|
||||
const control_cmd_syntax_t onion_client_auth_view_syntax = {
|
||||
.max_args = 1,
|
||||
.accept_keywords = true,
|
||||
};
|
||||
|
||||
/** Called when we get an ONION_CLIENT_AUTH_VIEW command; parse the body, and
|
||||
* register the new client-side client auth credentials.
|
||||
* "ONION_CLIENT_AUTH_VIEW" [SP HSAddress] CRLF
|
||||
*/
|
||||
int
|
||||
handle_control_onion_client_auth_view(control_connection_t *conn,
|
||||
const control_cmd_args_t *args)
|
||||
{
|
||||
int retval = -1;
|
||||
const char *hsaddress = NULL;
|
||||
/* We are gonna put all the credential strings into a smartlist, and sort it
|
||||
before printing, so that we can get a guaranteed order of printing. */
|
||||
smartlist_t *creds_str_list = smartlist_new();
|
||||
|
||||
tor_assert(args);
|
||||
|
||||
int argc = smartlist_len(args->args);
|
||||
if (argc >= 1) {
|
||||
hsaddress = smartlist_get(args->args, 0);
|
||||
if (!hs_address_is_valid(hsaddress)) {
|
||||
control_printf_endreply(conn, 512, "Invalid v3 addr \"%s\"", hsaddress);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (hsaddress) {
|
||||
control_printf_midreply(conn, 250, "ONION_CLIENT_AUTH_VIEW %s", hsaddress);
|
||||
} else {
|
||||
control_printf_midreply(conn, 250, "ONION_CLIENT_AUTH_VIEW");
|
||||
}
|
||||
|
||||
/* Create an iterator out of the digest256map */
|
||||
digest256map_t *client_auths = get_hs_client_auths_map();
|
||||
digest256map_iter_t *itr = digest256map_iter_init(client_auths);
|
||||
while (!digest256map_iter_done(itr)) {
|
||||
const uint8_t *service_pubkey;
|
||||
void *valp;
|
||||
digest256map_iter_get(itr, &service_pubkey, &valp);
|
||||
tor_assert(valp);
|
||||
hs_client_service_authorization_t *cred = valp;
|
||||
|
||||
/* If a specific HS address was requested, only print creds for that one */
|
||||
if (hsaddress && strcmp(cred->onion_address, hsaddress)) {
|
||||
itr = digest256map_iter_next(client_auths, itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *encoding_str = encode_client_auth_cred_for_control_port(cred);
|
||||
tor_assert_nonfatal(encoding_str);
|
||||
smartlist_add(creds_str_list, encoding_str);
|
||||
|
||||
itr = digest256map_iter_next(client_auths, itr);
|
||||
}
|
||||
|
||||
/* We got everything: Now sort the strings and print them */
|
||||
smartlist_sort_strings(creds_str_list);
|
||||
SMARTLIST_FOREACH_BEGIN(creds_str_list, char *, c) {
|
||||
control_printf_midreply(conn, 250, "%s", c);
|
||||
} SMARTLIST_FOREACH_END(c);
|
||||
|
||||
send_control_done(conn);
|
||||
|
||||
retval = 0;
|
||||
|
||||
err:
|
||||
SMARTLIST_FOREACH(creds_str_list, char *, cp, tor_free(cp));
|
||||
smartlist_free(creds_str_list);
|
||||
return retval;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ struct control_cmd_syntax_t;
|
||||
|
||||
extern const struct control_cmd_syntax_t onion_client_auth_add_syntax;
|
||||
extern const struct control_cmd_syntax_t onion_client_auth_remove_syntax;
|
||||
extern const struct control_cmd_syntax_t onion_client_auth_view_syntax;
|
||||
|
||||
int
|
||||
handle_control_onion_client_auth_add(control_connection_t *conn,
|
||||
@ -24,5 +25,9 @@ int
|
||||
handle_control_onion_client_auth_remove(control_connection_t *conn,
|
||||
const control_cmd_args_t *args);
|
||||
|
||||
int
|
||||
handle_control_onion_client_auth_view(control_connection_t *conn,
|
||||
const control_cmd_args_t *args);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1500,6 +1500,13 @@ hs_client_remove_auth_credentials(const char *hsaddress)
|
||||
return REMOVAL_SUCCESS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/** Get the HS client auth map. */
|
||||
digest256map_t *
|
||||
get_hs_client_auths_map(void)
|
||||
{
|
||||
return client_auths;
|
||||
}
|
||||
|
||||
/* ========== */
|
||||
/* Public API */
|
||||
/* ========== */
|
||||
@ -2195,12 +2202,6 @@ hs_client_dir_info_changed(void)
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
|
||||
STATIC digest256map_t *
|
||||
get_hs_client_auths_map(void)
|
||||
{
|
||||
return client_auths;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
set_hs_client_auths_map(digest256map_t *map)
|
||||
{
|
||||
@ -2208,3 +2209,4 @@ set_hs_client_auths_map(digest256map_t *map)
|
||||
}
|
||||
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
|
||||
|
@ -76,6 +76,8 @@ hs_client_register_auth_credentials(hs_client_service_authorization_t *creds);
|
||||
hs_client_removal_auth_status_t
|
||||
hs_client_remove_auth_credentials(const char *hsaddress);
|
||||
|
||||
digest256map_t *get_hs_client_auths_map(void);
|
||||
|
||||
#define client_service_authorization_free(auth) \
|
||||
FREE_AND_NULL(hs_client_service_authorization_t, \
|
||||
client_service_authorization_free_, (auth))
|
||||
@ -156,7 +158,6 @@ STATIC void retry_all_socks_conn_waiting_for_desc(void);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
|
||||
STATIC digest256map_t *get_hs_client_auths_map(void);
|
||||
STATIC void set_hs_client_auths_map(digest256map_t *map);
|
||||
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
|
Loading…
Reference in New Issue
Block a user