[tor-commits] [tor/master] hs-v3: Return descriptor decoding status when storing as client

asn at torproject.org asn at torproject.org
Mon Nov 18 17:12:15 UTC 2019


commit 7bba8bf72f20aa2ac71ac381a7fdf66fadbd473f
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue May 28 13:32:15 2019 -0400

    hs-v3: Return descriptor decoding status when storing as client
    
    This will allow us to callback into the HS subsytem depending on the decoding
    status and return an extended SOCKS5 error code depending on the decoding
    issue.
    
    This is how we'll be able to tell the SocksPort connection if we are missing
    or have bad client authorization for a service.
    
    Part of #30382
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/feature/dirclient/dirclient.c |  5 ++++-
 src/feature/hs/hs_cache.c         | 34 +++++++++++++++++++++++++++-------
 src/feature/hs/hs_cache.h         |  4 ++--
 src/test/test_hs_client.c         | 11 ++++++-----
 4 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index 1ea50fd35..3b506317b 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -2722,6 +2722,7 @@ handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
   const char *reason = args->reason;
   const char *body = args->body;
   const size_t body_len = args->body_len;
+  hs_desc_decode_status_t decode_status;
 
   tor_assert(conn->hs_ident);
 
@@ -2731,7 +2732,9 @@ handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
   switch (status_code) {
   case 200:
     /* We got something: Try storing it in the cache. */
-    if (hs_cache_store_as_client(body, &conn->hs_ident->identity_pk) < 0) {
+    decode_status = hs_cache_store_as_client(body,
+                                             &conn->hs_ident->identity_pk);
+    if (decode_status != HS_DESC_DECODE_OK) {
       log_info(LD_REND, "Failed to store hidden service descriptor");
       /* Fire control port FAILED event. */
       hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest,
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index 39c226746..59b05d8f0 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -395,7 +395,8 @@ lookup_v3_desc_as_client(const uint8_t *key)
  * hs_cache_client_descriptor_t object. In case of error, return NULL. */
 static hs_cache_client_descriptor_t *
 cache_client_desc_new(const char *desc_str,
-                      const ed25519_public_key_t *service_identity_pk)
+                      const ed25519_public_key_t *service_identity_pk,
+                      hs_desc_decode_status_t *decode_status_out)
 {
   hs_desc_decode_status_t ret;
   hs_descriptor_t *desc = NULL;
@@ -435,6 +436,9 @@ cache_client_desc_new(const char *desc_str,
   client_desc->encoded_desc = tor_strdup(desc_str);
 
  end:
+  if (decode_status_out) {
+    *decode_status_out = ret;
+  }
   return client_desc;
 }
 
@@ -796,19 +800,34 @@ hs_cache_lookup_as_client(const ed25519_public_key_t *key)
   return NULL;
 }
 
-/** Public API: Given an encoded descriptor, store it in the client HS
- *  cache. Return -1 on error, 0 on success .*/
-int
+/** Public API: Given an encoded descriptor, store it in the client HS cache.
+ *  Return a decode status which changes how we handle the SOCKS connection
+ *  depending on its value:
+ *
+ *  HS_DESC_DECODE_OK: Returned on success. Descriptor was properly decoded
+ *                     and is now stored.
+ *
+ *  HS_DESC_DECODE_NEED_CLIENT_AUTH: Client authorization is needed but the
+ *                                   descriptor was still stored.
+ *
+ *  HS_DESC_DECODE_BAD_CLIENT_AUTH: Client authorization for this descriptor
+ *                                  was not usable but the descriptor was
+ *                                  still stored.
+ *
+ *  Any other codes means indicate where the error occured and the descriptor
+ *  was not stored. */
+hs_desc_decode_status_t
 hs_cache_store_as_client(const char *desc_str,
                          const ed25519_public_key_t *identity_pk)
 {
+  hs_desc_decode_status_t ret;
   hs_cache_client_descriptor_t *client_desc = NULL;
 
   tor_assert(desc_str);
   tor_assert(identity_pk);
 
   /* Create client cache descriptor object */
-  client_desc = cache_client_desc_new(desc_str, identity_pk);
+  client_desc = cache_client_desc_new(desc_str, identity_pk, &ret);
   if (!client_desc) {
     log_warn(LD_GENERAL, "HSDesc parsing failed!");
     log_debug(LD_GENERAL, "Failed to parse HSDesc: %s.", escaped(desc_str));
@@ -817,14 +836,15 @@ hs_cache_store_as_client(const char *desc_str,
 
   /* Push it to the cache */
   if (cache_store_as_client(client_desc) < 0) {
+    ret = HS_DESC_DECODE_GENERIC_ERROR;
     goto err;
   }
 
-  return 0;
+  return ret;
 
  err:
   cache_client_desc_free(client_desc);
-  return -1;
+  return ret;
 }
 
 /** Clean all client caches using the current time now. */
diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h
index 5df7e54fc..e7729f204 100644
--- a/src/feature/hs/hs_cache.h
+++ b/src/feature/hs/hs_cache.h
@@ -83,8 +83,8 @@ const hs_descriptor_t *
 hs_cache_lookup_as_client(const struct ed25519_public_key_t *key);
 const char *
 hs_cache_lookup_encoded_as_client(const struct ed25519_public_key_t *key);
-int hs_cache_store_as_client(const char *desc_str,
-                             const struct ed25519_public_key_t *identity_pk);
+hs_desc_decode_status_t hs_cache_store_as_client(const char *desc_str,
+                           const struct ed25519_public_key_t *identity_pk);
 void hs_cache_clean_as_client(time_t now);
 void hs_cache_purge_as_client(void);
 
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index b777dafdf..e5735ba02 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -393,7 +393,8 @@ test_client_pick_intro(void *arg)
     tt_assert(encoded);
 
     /* store it */
-    hs_cache_store_as_client(encoded, &service_kp.pubkey);
+    ret = hs_cache_store_as_client(encoded, &service_kp.pubkey);
+    tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
 
     /* fetch it to make sure it works */
     const hs_descriptor_t *fetched_desc =
@@ -852,7 +853,7 @@ test_desc_has_arrived_cleanup(void *arg)
 
   /* Store in the client cache. */
   ret = hs_cache_store_as_client(desc_str, &signing_kp.pubkey);
-  tt_int_op(ret, OP_EQ, 0);
+  tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
   cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey);
   tt_assert(cached_desc);
   hs_helper_desc_equal(desc, cached_desc);
@@ -953,7 +954,7 @@ test_close_intro_circuits_new_desc(void *arg)
 
     /* Store it */
     ret = hs_cache_store_as_client(encoded, &service_kp.pubkey);
-    tt_int_op(ret, OP_EQ, 0);
+    tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
     tor_free(encoded);
     tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
   }
@@ -988,8 +989,8 @@ test_close_intro_circuits_new_desc(void *arg)
     tt_int_op(ret, OP_EQ, 0);
     tt_assert(encoded);
 
-    hs_cache_store_as_client(encoded, &service_kp.pubkey);
-    tt_int_op(ret, OP_EQ, 0);
+    ret = hs_cache_store_as_client(encoded, &service_kp.pubkey);
+    tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
     tor_free(encoded);
     tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
   }





More information about the tor-commits mailing list