[tor-commits] [tor/master] Merge branch 'feature15588_squashed'

nickm at torproject.org nickm at torproject.org
Mon May 9 18:41:48 UTC 2016


commit 33d3572a1d61d81cd3f26778cd137eb2271f5e3c
Merge: 6938003 162aa14e
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon May 9 14:41:36 2016 -0400

    Merge branch 'feature15588_squashed'

 src/or/connection_edge.c   |   4 +-
 src/or/control.c           | 173 +++++++++++++++++++++++++++++++++++++++------
 src/or/control.h           |   2 +
 src/or/or.h                |   4 +-
 src/or/rendclient.c        |  34 ++-------
 src/or/rendcommon.c        | 127 +++++++++++++++++++++++++++++++++
 src/or/rendcommon.h        |   9 +++
 src/or/rendservice.c       |  86 +++++++++++-----------
 src/or/rendservice.h       |   5 ++
 src/or/routerparse.c       |  31 +++-----
 src/test/test_controller.c |  51 +++++++++++++
 src/test/test_hs.c         |  63 +++++++++++++++++
 12 files changed, 469 insertions(+), 120 deletions(-)

diff --cc src/or/rendcommon.c
index b927486,dfa6c1e..56c49fe
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@@ -906,38 -952,113 +922,149 @@@ rend_data_client_create(const char *oni
    return NULL;
  }
  
 +/** Determine the routers that are responsible for <b>id</b> (binary) and
 + * add pointers to those routers' routerstatus_t to <b>responsible_dirs</b>.
 + * Return -1 if we're returning an empty smartlist, else return 0.
 + */
 +int
 +hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
 +                                     const char *id)
 +{
 +  int start, found, n_added = 0, i;
 +  networkstatus_t *c = networkstatus_get_latest_consensus();
 +  if (!c || !smartlist_len(c->routerstatus_list)) {
 +    log_warn(LD_REND, "We don't have a consensus, so we can't perform v2 "
 +             "rendezvous operations.");
 +    return -1;
 +  }
 +  tor_assert(id);
 +  start = networkstatus_vote_find_entry_idx(c, id, &found);
 +  if (start == smartlist_len(c->routerstatus_list)) start = 0;
 +  i = start;
 +  do {
 +    routerstatus_t *r = smartlist_get(c->routerstatus_list, i);
 +    if (r->is_hs_dir) {
 +      smartlist_add(responsible_dirs, r);
 +      if (++n_added == REND_NUMBER_OF_CONSECUTIVE_REPLICAS)
 +        return 0;
 +    }
 +    if (++i == smartlist_len(c->routerstatus_list))
 +      i = 0;
 +  } while (i != start);
 +
 +  /* Even though we don't have the desired number of hidden service
 +   * directories, be happy if we got any. */
 +  return smartlist_len(responsible_dirs) ? 0 : -1;
 +}
 +
+ /* Length of the 'extended' auth cookie used to encode auth type before
+  * base64 encoding. */
+ #define REND_DESC_COOKIE_LEN_EXT (REND_DESC_COOKIE_LEN + 1)
+ /* Length of the zero-padded auth cookie when base64 encoded. These two
+  * padding bytes always (A=) are stripped off of the returned cookie. */
+ #define REND_DESC_COOKIE_LEN_EXT_BASE64 (REND_DESC_COOKIE_LEN_BASE64 + 2)
+ 
+ /** Encode a client authorization descriptor cookie.
+  * The result of this function is suitable for use in the HidServAuth
+  * option.  The trailing padding characters are removed, and the
+  * auth type is encoded into the cookie.
+  *
+  * Returns a new base64-encoded cookie. This function cannot fail.
+  * The caller is responsible for freeing the returned value.
+  */
+ char *
+ rend_auth_encode_cookie(const uint8_t *cookie_in, rend_auth_type_t auth_type)
+ {
+   uint8_t extended_cookie[REND_DESC_COOKIE_LEN_EXT];
+   char *cookie_out = tor_malloc_zero(REND_DESC_COOKIE_LEN_EXT_BASE64 + 1);
+   int re;
+ 
+   tor_assert(cookie_in);
+ 
+   memcpy(extended_cookie, cookie_in, REND_DESC_COOKIE_LEN);
+   extended_cookie[REND_DESC_COOKIE_LEN] = ((int)auth_type - 1) << 4;
+   re = base64_encode(cookie_out, REND_DESC_COOKIE_LEN_EXT_BASE64 + 1,
+                      (const char *) extended_cookie, REND_DESC_COOKIE_LEN_EXT,
+                      0);
+   tor_assert(re == REND_DESC_COOKIE_LEN_EXT_BASE64);
+ 
+   /* Remove the trailing 'A='.  Auth type is encoded in the high bits
+    * of the last byte, so the last base64 character will always be zero
+    * (A).  This is subtly different behavior from base64_encode_nopad. */
+   cookie_out[REND_DESC_COOKIE_LEN_BASE64] = '\0';
+   memwipe(extended_cookie, 0, sizeof(extended_cookie));
+   return cookie_out;
+ }
+ 
+ /** Decode a base64-encoded client authorization descriptor cookie.
+  * The descriptor_cookie can be truncated to REND_DESC_COOKIE_LEN_BASE64
+  * characters (as given to clients), or may include the two padding
+  * characters (as stored by the service).
+  *
+  * The result is stored in REND_DESC_COOKIE_LEN bytes of cookie_out.
+  * The rend_auth_type_t decoded from the cookie is stored in the
+  * optional auth_type_out parameter.
+  *
+  * Return 0 on success, or -1 on error.  The caller is responsible for
+  * freeing the returned err_msg.
+  */
+ int
+ rend_auth_decode_cookie(const char *cookie_in, uint8_t *cookie_out,
+                         rend_auth_type_t *auth_type_out, char **err_msg_out)
+ {
+   uint8_t descriptor_cookie_decoded[REND_DESC_COOKIE_LEN_EXT + 1] = { 0 };
+   char descriptor_cookie_base64ext[REND_DESC_COOKIE_LEN_EXT_BASE64 + 1];
+   const char *descriptor_cookie = cookie_in;
+   char *err_msg = NULL;
+   int auth_type_val = 0;
+   int res = -1;
+   int decoded_len;
+ 
+   size_t len = strlen(descriptor_cookie);
+   if (len == REND_DESC_COOKIE_LEN_BASE64) {
+     /* Add a trailing zero byte to make base64-decoding happy. */
+     tor_snprintf(descriptor_cookie_base64ext,
+                  sizeof(descriptor_cookie_base64ext),
+                  "%sA=", descriptor_cookie);
+     descriptor_cookie = descriptor_cookie_base64ext;
+   } else if (len != REND_DESC_COOKIE_LEN_EXT_BASE64) {
+     tor_asprintf(&err_msg, "Authorization cookie has wrong length: %s",
+                  escaped(cookie_in));
+     goto err;
+   }
+ 
+   decoded_len = base64_decode((char *) descriptor_cookie_decoded,
+                               sizeof(descriptor_cookie_decoded),
+                               descriptor_cookie,
+                               REND_DESC_COOKIE_LEN_EXT_BASE64);
+   if (decoded_len != REND_DESC_COOKIE_LEN &&
+       decoded_len != REND_DESC_COOKIE_LEN_EXT) {
+     tor_asprintf(&err_msg, "Authorization cookie has invalid characters: %s",
+                  escaped(cookie_in));
+     goto err;
+   }
+ 
+   if (auth_type_out) {
+     auth_type_val = (descriptor_cookie_decoded[REND_DESC_COOKIE_LEN] >> 4) + 1;
+     if (auth_type_val < 1 || auth_type_val > 2) {
+       tor_asprintf(&err_msg, "Authorization cookie type is unknown: %s",
+                    escaped(cookie_in));
+       goto err;
+     }
+     *auth_type_out = auth_type_val == 1 ? REND_BASIC_AUTH : REND_STEALTH_AUTH;
+   }
+ 
+   memcpy(cookie_out, descriptor_cookie_decoded, REND_DESC_COOKIE_LEN);
+   res = 0;
+  err:
+   if (err_msg_out) {
+     *err_msg_out = err_msg;
+   } else {
+     tor_free(err_msg);
+   }
+   memwipe(descriptor_cookie_decoded, 0, sizeof(descriptor_cookie_decoded));
+   memwipe(descriptor_cookie_base64ext, 0, sizeof(descriptor_cookie_base64ext));
+   return res;
+ }
+ 
++



More information about the tor-commits mailing list