[tor-commits] [tor/master] control-port: Implement ONION_CLIENT_AUTH_VIEW.
dgoulet at torproject.org
dgoulet at torproject.org
Tue Nov 19 14:32:30 UTC 2019
commit db6a48b6bf65f817cfe9318f60616a67d4a8adfe
Author: George Kadianakis <desnacked at riseup.net>
Date: Mon Jun 3 14:25:38 2019 +0300
control-port: Implement ONION_CLIENT_AUTH_VIEW.
---
src/feature/control/control_cmd.c | 1 +
src/feature/control/control_hs.c | 117 ++++++++++++++++++++++++++++++++++++++
src/feature/control/control_hs.h | 5 ++
src/feature/hs/hs_client.c | 14 +++--
src/feature/hs/hs_client.h | 3 +-
5 files changed, 133 insertions(+), 7 deletions(-)
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
index fcd0d8b29..656ddf5ca 100644
--- a/src/feature/control/control_cmd.c
+++ b/src/feature/control/control_cmd.c
@@ -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),
};
/**
diff --git a/src/feature/control/control_hs.c b/src/feature/control/control_hs.c
index 93e66261e..aa7400c0c 100644
--- a/src/feature/control/control_hs.c
+++ b/src/feature/control/control_hs.c
@@ -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;
+}
diff --git a/src/feature/control/control_hs.h b/src/feature/control/control_hs.h
index 067c7dc47..35ac1b22d 100644
--- a/src/feature/control/control_hs.h
+++ b/src/feature/control/control_hs.h
@@ -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
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index bbe7b87a6..9edfd1367 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -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) */
+
diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h
index 459c19db5..b0122aa14 100644
--- a/src/feature/hs/hs_client.h
+++ b/src/feature/hs/hs_client.h
@@ -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) */
More information about the tor-commits
mailing list