[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