[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r16567: {tor} Some code cleanups. (tor/branches/121-hs-authorization/src/or)



Author: kloesing
Date: 2008-08-16 09:21:17 -0400 (Sat, 16 Aug 2008)
New Revision: 16567

Modified:
   tor/branches/121-hs-authorization/src/or/or.h
   tor/branches/121-hs-authorization/src/or/rendcommon.c
   tor/branches/121-hs-authorization/src/or/rendservice.c
   tor/branches/121-hs-authorization/src/or/routerparse.c
   tor/branches/121-hs-authorization/src/or/test.c
Log:
Some code cleanups.

Modified: tor/branches/121-hs-authorization/src/or/or.h
===================================================================
--- tor/branches/121-hs-authorization/src/or/or.h	2008-08-16 11:36:09 UTC (rev 16566)
+++ tor/branches/121-hs-authorization/src/or/or.h	2008-08-16 13:21:17 UTC (rev 16567)
@@ -651,8 +651,22 @@
  * exchanging client authorization between hidden service and client. */
 #define REND_DESC_COOKIE_LEN_BASE64 22
 
+/** Length of client identifier in encrypted introduction points for hidden
+ * service authorization type 'basic'. */
+#define REND_BASIC_AUTH_CLIENT_ID_LEN 4
+
+/** Multiple of the number of clients to which the real number of clients
+ * is padded with fake clients for hidden service authorization type
+ * 'basic'. */
+#define REND_BASIC_AUTH_CLIENT_MULTIPLE 16
+
+/** Length of client entry consisting of client identifier and encrypted
+ * session key for hidden service authorization type 'basic'. */
+#define REND_BASIC_AUTH_CLIENT_ENTRY_LEN (REND_BASIC_AUTH_CLIENT_ID_LEN \
+                                          + CIPHER_KEY_LEN)
+
 /** Maximum size of v2 hidden service descriptors. */
-#define REND_DESC_MAX_SIZE 20 * 1024
+#define REND_DESC_MAX_SIZE (20 * 1024)
 
 /** Legal characters for use in authorized client names for a hidden
  * service. */
@@ -3952,15 +3966,15 @@
                             rend_cache_entry_t **entry_out);
 int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc);
 int rend_cache_store(const char *desc, size_t desc_len, int published);
-int rend_cache_store_v2_desc_as_client(const char *desc, int auth_type,
+int rend_cache_store_v2_desc_as_client(const char *desc, rend_auth_type_t auth_type,
                                        const char *descriptor_cookie);
 int rend_cache_store_v2_desc_as_dir(const char *desc);
 int rend_cache_size(void);
 int rend_encode_v2_descriptors(smartlist_t *descs_out,
                                rend_service_descriptor_t *desc, time_t now,
-                               crypto_pk_env_t *service_key, int auth_type,
-                               const char *descriptor_cookie,
-                               smartlist_t *client_cookies, uint8_t period);
+                               uint8_t period, rend_auth_type_t auth_type,
+                               crypto_pk_env_t *client_key,
+                               smartlist_t *client_cookies);
 int rend_compute_v2_desc_id(char *desc_id_out, const char *service_id,
                             const char *descriptor_cookie,
                             time_t now, uint8_t replica);
@@ -4355,8 +4369,8 @@
                                      const char *ipos_encrypted,
                                      size_t ipos_encrypted_size);
 int rend_parse_introduction_points(rend_service_descriptor_t *parsed,
-                                     const char *intro_content,
-                                     size_t intro_size);
+                                   const char *intro_points_encoded,
+                                   size_t intro_points_encoded_size);
 int rend_parse_client_keys(strmap_t *parsed_clients, const char *str);
 
 #endif

Modified: tor/branches/121-hs-authorization/src/or/rendcommon.c
===================================================================
--- tor/branches/121-hs-authorization/src/or/rendcommon.c	2008-08-16 11:36:09 UTC (rev 16566)
+++ tor/branches/121-hs-authorization/src/or/rendcommon.c	2008-08-16 13:21:17 UTC (rev 16567)
@@ -156,14 +156,14 @@
 static int
 rend_encode_v2_intro_points(char **encoded, rend_service_descriptor_t *desc)
 {
-  size_t enc_len;
-  char *enc = NULL;
-  size_t enc_written = 0;
+  size_t unenc_len;
+  char *unenc = NULL;
+  size_t unenc_written = 0;
   int i;
   int r = -1;
-  /* Assemble list of introduction points. */
-  enc_len = smartlist_len(desc->intro_nodes) * 1000; /* too long, but ok. */
-  enc = tor_malloc_zero(enc_len);
+  /* Assemble unencrypted list of introduction points. */
+  unenc_len = smartlist_len(desc->intro_nodes) * 1000; /* too long, but ok. */
+  unenc = tor_malloc_zero(unenc_len);
   for (i = 0; i < smartlist_len(desc->intro_nodes); i++) {
     char id_base32[REND_INTRO_POINT_ID_LEN_BASE32 + 1];
     char *onion_key = NULL;
@@ -196,7 +196,7 @@
     }
     /* Assemble everything for this introduction point. */
     address = tor_dup_addr(&info->addr);
-    res = tor_snprintf(enc + enc_written, enc_len - enc_written,
+    res = tor_snprintf(unenc + unenc_written, unenc_len - unenc_written,
                          "introduction-point %s\n"
                          "ip-address %s\n"
                          "onion-port %d\n"
@@ -215,72 +215,63 @@
                         "string.");
       goto done;
     }
-    /* Update total number of written bytes for intro points. */
-    enc_written += res;
+    /* Update total number of written bytes for unencrypted intro points. */
+    unenc_written += res;
   }
-  /* Finalize encrypted introduction points. */
-  if (enc_len < enc_written + 2) {
+  /* Finalize unencrypted introduction points. */
+  if (unenc_len < unenc_written + 2) {
     log_warn(LD_REND, "Not enough space for finalizing introduction point "
                       "string.");
     goto done;
   }
-  enc[enc_written++] = '\n';
-  enc[enc_written++] = 0;
-  *encoded = enc;
+  unenc[unenc_written++] = '\n';
+  unenc[unenc_written++] = 0;
+  *encoded = unenc;
   r = 0;
  done:
   if (r<0)
-    tor_free(enc);
+    tor_free(unenc);
   return r;
 }
 
 /** Encrypt the encoded introduction points in <b>encoded</b> using
- * <b>descriptor_cookie</b> of length REND_DESC_COOKIE_LEN and write the
- * result to <b>encrypted</b> of length <b>encrypted_len</b>. Return 0 for
- * success, -1 otherwise. */
+ * authorization type  'basic' with <b>client_cookies</b> and write the
+ * result to a newly allocated string pointed to by <b>encrypted</b> of
+ * length <b>encrypted_len</b>. Return 0 for success, -1 otherwise. */
 static int
-rend_encrypt_v2_intro_points_auth1(char **encrypted, size_t *encrypted_len,
+rend_encrypt_v2_intro_points_basic(char **encrypted, size_t *encrypted_len,
                                    const char *encoded,
                                    smartlist_t *client_cookies)
 {
-  int r = -1, i, pos;
+  int r = -1, i, pos, enclen, client_blocks;
   size_t len, client_entries_len;
-  int enclen, client_blocks;
-  char *enc = NULL;
+  char *enc = NULL, iv[CIPHER_IV_LEN], *client_part = NULL,
+       session_key[CIPHER_KEY_LEN];
   smartlist_t *encrypted_session_keys = NULL;
-  char iv[CIPHER_IV_LEN];
-  char *client_part = NULL;
   crypto_digest_env_t *digest;
   crypto_cipher_env_t *cipher;
+  tor_assert(encoded);
+  tor_assert(client_cookies && smartlist_len(client_cookies) > 0);
 
   /* Generate session key. */
-  char session_key[CIPHER_IV_LEN];
-  log_debug(LD_REND, "Encoding (hopefully a string) '%s'", encoded);
-
-  if (crypto_rand(session_key, CIPHER_IV_LEN) < 0) {
+  if (crypto_rand(session_key, CIPHER_KEY_LEN) < 0) {
     log_warn(LD_REND, "Unable to generate random session key to encrypt "
-             "introduction point string.");
+                      "introduction point string.");
     goto done;
   }
-  log_debug(LD_REND, "Generated session key is '%s'",
-            hex_str(session_key, CIPHER_IV_LEN));
 
   /* Determine length of encrypted introduction points including session
    * keys. */
-  client_blocks = 1 + (smartlist_len(client_cookies) - 1) / 16;
-  client_entries_len = client_blocks * 16 * 20;
+  client_blocks = 1 + ((smartlist_len(client_cookies) - 1) /
+                       REND_BASIC_AUTH_CLIENT_MULTIPLE);
+  client_entries_len = client_blocks * REND_BASIC_AUTH_CLIENT_MULTIPLE *
+                       REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
   len = 2 + client_entries_len + CIPHER_IV_LEN + strlen(encoded);
   enc = tor_malloc_zero(len);
   enc[0] = 0x01;
-  enc[1] = (uint8_t) client_blocks;
-  log_debug(LD_REND, "We have %d clients which means the introduction "
-                     "point part will be 2 + 320 * (1 + (%d - 1) / 16) "
-                     "+ %d + %d = %d octets long.",
-           smartlist_len(client_cookies), smartlist_len(client_cookies),
-           CIPHER_IV_LEN, strlen(encoded), len);
-  /* Encrypt with random session key (instead of descriptor cookie). */
-  log_debug(LD_REND, "Writing encrypted part beginning at %d",
-           2 + client_entries_len);
+  enc[1] = (uint8_t)client_blocks;
+
+  /* Encrypt with random session key. */
   cipher = crypto_create_init_cipher(session_key, 1);
   enclen = crypto_cipher_encrypt_with_iv(cipher,
       enc + 2 + client_entries_len,
@@ -288,53 +279,56 @@
   crypto_free_cipher_env(cipher);
   if (enclen < 0) {
     log_warn(LD_REND, "Could not encrypt introduction point string.");
-    tor_free(enc);
     goto done;
   }
-  memcpy(iv, enc + 2 + client_entries_len, sizeof(iv));
-  log_debug(LD_REND, "Initialization vector: '%s'", hex_str(iv, 16));
+  memcpy(iv, enc + 2 + client_entries_len, CIPHER_IV_LEN);
+
   /* Encrypt session key for cookies, determine client IDs, and put both
    * in a smartlist. */
   encrypted_session_keys = smartlist_create();
   SMARTLIST_FOREACH(client_cookies, char *, cookie, {
-    client_part = tor_malloc_zero(4 + 16);
+    client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
     /* Encrypt session key. */
     cipher = crypto_create_init_cipher(cookie, 1);
-    if (crypto_cipher_encrypt(cipher, client_part + 4, session_key, 16) < 0) {
+    if (crypto_cipher_encrypt(cipher, client_part +
+                                  REND_BASIC_AUTH_CLIENT_ID_LEN,
+                              session_key, CIPHER_KEY_LEN) < 0) {
       log_warn(LD_REND, "Could not encrypt session key for client.");
       crypto_free_cipher_env(cipher);
       tor_free(client_part);
       goto done;
     }
     crypto_free_cipher_env(cipher);
+
     /* Determine client ID. */
     digest = crypto_new_digest_env();
-    crypto_digest_add_bytes(digest, cookie, 16);
+    crypto_digest_add_bytes(digest, cookie, REND_DESC_COOKIE_LEN);
     crypto_digest_add_bytes(digest, iv, CIPHER_IV_LEN);
-    crypto_digest_get_digest(digest, client_part, 4);
+    crypto_digest_get_digest(digest, client_part,
+                             REND_BASIC_AUTH_CLIENT_ID_LEN);
     crypto_free_digest_env(digest);
+
     /* Put both together. */
-    log_debug(LD_REND, "Adding client part '%s'", hex_str(client_part, 20));
     smartlist_add(encrypted_session_keys, client_part);
   });
   /* Add some fake client IDs and encrypted session keys. */
-  for (i = (smartlist_len(client_cookies) - 1) % 16; i < 15; i++) {
-    client_part = tor_malloc_zero(4 + 16);
-    if (crypto_rand(client_part, 20) < 0) {
+  for (i = (smartlist_len(client_cookies) - 1) %
+           REND_BASIC_AUTH_CLIENT_MULTIPLE;
+       i < REND_BASIC_AUTH_CLIENT_MULTIPLE - 1; i++) {
+    client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
+    if (crypto_rand(client_part, REND_BASIC_AUTH_CLIENT_ENTRY_LEN) < 0) {
       log_warn(LD_REND, "Unable to generate fake client entry.");
+      tor_free(client_part);
       goto done;
     }
     smartlist_add(encrypted_session_keys, client_part);
-    log_debug(LD_REND, "Fake client part '%s'", hex_str(client_part, 20));
   }
-  /* Sort smartlist. */
+  /* Sort smartlist and put elements in result in order. */
   smartlist_sort_digests(encrypted_session_keys);
-  /* put elements in results in order. */
   pos = 2;
   SMARTLIST_FOREACH(encrypted_session_keys, char *, entry, {
-    memcpy(enc + pos, entry, 20);
-    pos += 20;
-    log_debug(LD_REND, "Putting in client part '%s'", hex_str(entry, 20));
+    memcpy(enc + pos, entry, REND_BASIC_AUTH_CLIENT_ENTRY_LEN);
+    pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
   });
   *encrypted = enc;
   *encrypted_len = len;
@@ -342,35 +336,41 @@
  done:
   if (r<0)
     tor_free(enc);
-  if (encrypted_session_keys)
+  if (encrypted_session_keys) {
     SMARTLIST_FOREACH(encrypted_session_keys, char *, d, tor_free(d););
-  tor_free(encrypted_session_keys);
+    smartlist_free(encrypted_session_keys);
+  }
   return r;
 }
 
 /** Encrypt the encoded introduction points in <b>encoded</b> using
- * <b>descriptor_cookie</b> of length REND_DESC_COOKIE_LEN and write the
- * result to <b>encrypted</b> of length <b>encrypted_len</b>. Return 0 for
- * success, -1 otherwise. */
+ * authorization type 'stealth' with <b>descriptor_cookie</b> of length
+ * REND_DESC_COOKIE_LEN and write the result to a newly allocated string
+ * pointed to by <b>encrypted</b> of length <b>encrypted_len</b>. Return 0
+ * for success, -1 otherwise. */
 static int
-rend_encrypt_v2_intro_points_auth2(char **encrypted, size_t *encrypted_len,
-                                   const char *encoded,
-                                   const char *descriptor_cookie)
+rend_encrypt_v2_intro_points_stealth(char **encrypted,
+                                     size_t *encrypted_len,
+                                     const char *encoded,
+                                     const char *descriptor_cookie)
 {
-  int r = -1;
-  char *enc = tor_malloc_zero(1 + CIPHER_IV_LEN + strlen(encoded));
-  crypto_cipher_env_t *cipher =
-      crypto_create_init_cipher(descriptor_cookie, 1);
-  int enclen = crypto_cipher_encrypt_with_iv(cipher, enc + 1,
-                                             CIPHER_IV_LEN + strlen(encoded),
-                                             encoded, strlen(encoded));
+  int r = -1, enclen;
+  crypto_cipher_env_t *cipher;
+  char *enc;
+  tor_assert(encoded);
+  tor_assert(descriptor_cookie);
+
+  enc = tor_malloc_zero(1 + CIPHER_IV_LEN + strlen(encoded));
+  enc[0] = 0x02;
+  cipher = crypto_create_init_cipher(descriptor_cookie, 1);
+  enclen = crypto_cipher_encrypt_with_iv(cipher, enc + 1,
+                                         CIPHER_IV_LEN+strlen(encoded),
+                                         encoded, strlen(encoded));
   crypto_free_cipher_env(cipher);
   if (enclen < 0) {
     log_warn(LD_REND, "Could not encrypt introduction point string.");
-    tor_free(enc);
     goto done;
   }
-  enc[0] = 0x02;
   *encrypted = enc;
   *encrypted_len = enclen;
   r = 0;
@@ -423,24 +423,34 @@
 }
 
 /** Encode a set of rend_encoded_v2_service_descriptor_t's for <b>desc</b>
- * at time <b>now</b> using <b>service_key</b>, <b>descriptor_cookie</b>
- * (may be <b>NULL</b>), and <b>period</b> (e.g. 0 for the current period, 1
- * for the next period, etc.) and add them to the existing list
+ * at time <b>now</b> using <b>service_key</b>, depending on
+ * <b>auth_type</b> a <b>descriptor_cookie</b> and a list of
+ * <b>client_cookies</b> (which are both <b>NULL</b> if no client
+ * authorization is performed), and <b>period</b> (e.g. 0 for the current
+ * period, 1 for the next period, etc.) and add them to the existing list
  * <b>descs_out</b>; return the number of seconds that the descriptors will
  * be found by clients, or -1 if the encoding was not successful. */
 int
 rend_encode_v2_descriptors(smartlist_t *descs_out,
                            rend_service_descriptor_t *desc, time_t now,
-                           crypto_pk_env_t *service_key, int auth_type,
-                           const char *descriptor_cookie,
-                           smartlist_t *client_cookies, uint8_t period)
+                           uint8_t period, rend_auth_type_t auth_type,
+                           crypto_pk_env_t *client_key,
+                           smartlist_t *client_cookies)
 {
   char service_id[DIGEST_LEN];
   uint32_t time_period;
-  char *ipos_base64 = NULL, *ipos = NULL, *ipos_encrypted = NULL;
+  char *ipos_base64 = NULL, *ipos = NULL, *ipos_encrypted = NULL,
+       *descriptor_cookie = NULL;
   size_t ipos_len = 0, ipos_encrypted_len = 0;
   int k;
   uint32_t seconds_valid;
+  crypto_pk_env_t *service_key = auth_type == REND_STEALTH_AUTH ?
+                                 client_key : desc->pk;
+  tor_assert(service_key);
+  if (auth_type == REND_STEALTH_AUTH) {
+    descriptor_cookie = smartlist_get(client_cookies, 0);
+    tor_assert(descriptor_cookie);
+  }
   if (!desc) {
     log_warn(LD_REND, "Could not encode v2 descriptor: No desc given.");
     return -1;
@@ -458,40 +468,47 @@
       log_warn(LD_REND, "Encoding of introduction points did not succeed.");
       return -1;
     }
-    ipos_len = strlen(ipos);
-    if (auth_type == 1) {
-      if (rend_encrypt_v2_intro_points_auth1(&ipos_encrypted,
-                                             &ipos_encrypted_len,
-                                             ipos, client_cookies) < 0) {
-        log_warn(LD_REND, "Encrypting of introduction points did not "
-                 "succeed.");
+    switch (auth_type) {
+      case REND_NO_AUTH:
+        ipos_len = strlen(ipos);
+        break;
+      case REND_BASIC_AUTH:
+        if (rend_encrypt_v2_intro_points_basic(&ipos_encrypted,
+                                               &ipos_encrypted_len, ipos,
+                                               client_cookies) < 0) {
+          log_warn(LD_REND, "Encrypting of introduction points did not "
+                            "succeed.");
+          tor_free(ipos);
+          return -1;
+        }
         tor_free(ipos);
-        return -1;
-      }
-      tor_free(ipos);
-      ipos = ipos_encrypted;
-      ipos_len = ipos_encrypted_len;
-    } else if (auth_type == 2) {
-      if (rend_encrypt_v2_intro_points_auth2(&ipos_encrypted,
-                                             &ipos_encrypted_len,
-                                             ipos, descriptor_cookie) < 0) {
-        log_warn(LD_REND, "Encrypting of introduction points did not "
-                 "succeed.");
+        ipos = ipos_encrypted;
+        ipos_len = ipos_encrypted_len;
+        break;
+      case REND_STEALTH_AUTH:
+        if (rend_encrypt_v2_intro_points_stealth(&ipos_encrypted,
+                                                 &ipos_encrypted_len, ipos,
+                                                 descriptor_cookie) < 0) {
+          log_warn(LD_REND, "Encrypting of introduction points did not "
+                            "succeed.");
+          tor_free(ipos);
+          return -1;
+        }
         tor_free(ipos);
-        return -1;
-      }
-      tor_free(ipos);
-      ipos = ipos_encrypted;
-      ipos_len = ipos_encrypted_len;
+        ipos = ipos_encrypted;
+        ipos_len = ipos_encrypted_len;
+        break;
     }
     /* Base64-encode introduction points. */
     ipos_base64 = tor_malloc_zero(ipos_len * 2);
     if (base64_encode(ipos_base64, ipos_len * 2, ipos, ipos_len)<0) {
       log_warn(LD_REND, "Could not encode introduction point string to "
                "base64. length=%d", ipos_len);
+      tor_free(ipos_base64);
       tor_free(ipos);
       return -1;
     }
+    tor_free(ipos);
   }
   /* Encode REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS descriptors. */
   for (k = 0; k < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; k++) {
@@ -1207,7 +1224,8 @@
  * than one we've already got; return 1 if it's novel.
  */
 int
-rend_cache_store_v2_desc_as_client(const char *desc, int auth_type,
+rend_cache_store_v2_desc_as_client(const char *desc,
+                                   rend_auth_type_t auth_type,
                                    const char *descriptor_cookie)
 {
   /*XXXX this seems to have a bit of duplicate code with

Modified: tor/branches/121-hs-authorization/src/or/rendservice.c
===================================================================
--- tor/branches/121-hs-authorization/src/or/rendservice.c	2008-08-16 11:36:09 UTC (rev 16566)
+++ tor/branches/121-hs-authorization/src/or/rendservice.c	2008-08-16 13:21:17 UTC (rev 16567)
@@ -495,10 +495,8 @@
   d->timestamp = time(NULL);
   d->version = service->descriptor_version;
   d->intro_nodes = smartlist_create();
-  /* Whoever understands descriptor version 2 also understands intro
-   * protocol 2. So we only support 2, not 0 anymore. */
-  /* And now we also support version 3. */
-  d->protocols = (1<<2) + (1<<3);
+  /* Support intro protocols 2 and 3. */
+  d->protocols = (1 << 2) + (1 << 3);
 
   for (i = 0; i < smartlist_len(service->intro_nodes); ++i) {
     rend_intro_point_t *intro_svc = smartlist_get(service->intro_nodes, i);
@@ -1586,42 +1584,43 @@
       get_options()->PublishHidServDescriptors) {
     networkstatus_t *c = networkstatus_get_latest_consensus();
     if (c && smartlist_len(c->routerstatus_list) > 0) {
-      int seconds_valid;
+      int seconds_valid, i, j, num_descs;
       smartlist_t *descs = smartlist_create();
       smartlist_t *client_cookies = smartlist_create();
-      int i, j;
-      /* Either upload a single descriptors (including replicas) or one
-       * descriptor for each authorized client. */
-      int num_descs = (service->auth_type == 2 ?
-                       smartlist_len(service->clients) : 1);
+      /* Either upload a single descriptor (including replicas) or one
+       * descriptor for each authorized client in case of authorization
+       * type 'stealth'. */
+      num_descs = service->auth_type == REND_STEALTH_AUTH ?
+                      smartlist_len(service->clients) : 1;
       for (j = 0; j < num_descs; j++) {
-        char *descriptor_cookie = NULL;
-        crypto_pk_env_t *service_key = NULL;
-        if (service->auth_type == 1) {
-          service_key = service->private_key;
-          descriptor_cookie = NULL;
-          SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, cl, {
-            smartlist_add(client_cookies, cl->descriptor_cookie);
-          });
-        } else if (service->auth_type == 2) {
-          rend_authorized_client_t *client =
-            smartlist_get(service->clients, j);
-          service_key = client->client_key;
-          descriptor_cookie = client->descriptor_cookie;
-        } else {
-          service_key = service->private_key;
-          descriptor_cookie = NULL;
+        crypto_pk_env_t *client_key = NULL;
+        rend_authorized_client_t *client = NULL;
+        smartlist_clear(client_cookies);
+        switch (service->auth_type) {
+          case REND_NO_AUTH:
+            /* Do nothing here. */
+            break;
+          case REND_BASIC_AUTH:
+            SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *,
+                cl, smartlist_add(client_cookies, cl->descriptor_cookie));
+            break;
+          case REND_STEALTH_AUTH:
+            client = smartlist_get(service->clients, j);
+            client_key = client->client_key;
+            smartlist_add(client_cookies, client->descriptor_cookie);
+            break;
         }
         /* Encode the current descriptor. */
         seconds_valid = rend_encode_v2_descriptors(descs, service->desc,
-                                                   now, service_key,
+                                                   now, 0,
                                                    service->auth_type,
-                                                   descriptor_cookie,
-                                                   client_cookies, 0);
+                                                   client_key,
+                                                   client_cookies);
         if (seconds_valid < 0) {
           log_warn(LD_BUG, "Internal error: couldn't encode service "
                    "descriptor; not uploading.");
           smartlist_free(descs);
+          smartlist_free(client_cookies);
           return;
         }
         /* Post the current descriptors to the hidden service directories. */
@@ -1645,14 +1644,15 @@
         /* Post also the next descriptors, if necessary. */
         if (seconds_valid < REND_TIME_PERIOD_OVERLAPPING_V2_DESCS) {
           seconds_valid = rend_encode_v2_descriptors(descs, service->desc,
-                                                     now, service_key,
+                                                     now, 1,
                                                      service->auth_type,
-                                                     descriptor_cookie,
-                                                     client_cookies, 1);
+                                                     client_key,
+                                                     client_cookies);
           if (seconds_valid < 0) {
             log_warn(LD_BUG, "Internal error: couldn't encode service "
                      "descriptor; not uploading.");
             smartlist_free(descs);
+            smartlist_free(client_cookies);
             return;
           }
           directory_post_to_hs_dir(descs, serviceid, seconds_valid);
@@ -1663,6 +1663,7 @@
         }
       }
       smartlist_free(descs);
+      smartlist_free(client_cookies);
       uploaded = 1;
       log_info(LD_REND, "Successfully uploaded v2 rend descriptors!");
     }

Modified: tor/branches/121-hs-authorization/src/or/routerparse.c
===================================================================
--- tor/branches/121-hs-authorization/src/or/routerparse.c	2008-08-16 11:36:09 UTC (rev 16566)
+++ tor/branches/121-hs-authorization/src/or/routerparse.c	2008-08-16 13:21:17 UTC (rev 16567)
@@ -3463,7 +3463,7 @@
   /* Check length. */
   if (strlen(desc) > REND_DESC_MAX_SIZE) {
     log_warn(LD_REND, "Descriptor length is %i which exceeds "
-             "maximum descriptor size of %i kilobytes.",
+             "maximum rendezvous descriptor size of %i kilobytes.",
              strlen(desc), REND_DESC_MAX_SIZE);
     goto err;
   }
@@ -3606,11 +3606,11 @@
   return -1;
 }
 
-/** Decrypt the encoded introduction points in <b>ipos_encrypted</b> of
+/** Decrypt the encrypted introduction points in <b>ipos_encrypted</b> of
  * length <b>ipos_encrypted_size</b> using <b>descriptor_cookie</b> and
- * write the result to <b>ipos_decrypted</b> and its length to
- * <b>ipos_decrypted_size</b>; return 0 if decryption was successful and -1
- * otherwise. */
+ * write the result to a newly allocated string that is pointed to by
+ * <b>ipos_decrypted</b> and its length to <b>ipos_decrypted_size</b>.
+ * Return 0 if decryption was successful and -1 otherwise. */
 int
 rend_decrypt_introduction_points(char **ipos_decrypted,
                                  size_t *ipos_decrypted_size,
@@ -3618,51 +3618,49 @@
                                  const char *ipos_encrypted,
                                  size_t ipos_encrypted_size)
 {
-  size_t client_entries_len;
+  tor_assert(ipos_encrypted);
+  tor_assert(descriptor_cookie);
   if (ipos_encrypted_size < 2) {
     log_warn(LD_REND, "Size of encrypted introduction points is too "
-             "small.");
+                      "small.");
     return -1;
   }
-  if (ipos_encrypted[0] == 1) {
-    char iv[CIPHER_IV_LEN], client_id[4], session_key[16], *dec;
-    int declen;
-    size_t pos = 0, len;
+  if (ipos_encrypted[0] == (int)REND_BASIC_AUTH) {
+    char iv[CIPHER_IV_LEN], client_id[REND_BASIC_AUTH_CLIENT_ID_LEN],
+         session_key[CIPHER_KEY_LEN], *dec;
+    int declen, client_blocks;
+    size_t pos = 0, len, client_entries_len;
     crypto_digest_env_t *digest;
     crypto_cipher_env_t *cipher;
-    log_debug(LD_REND, "Introduction points are encrypted for "
-             "authorization type 1. There are %d client blocks containing "
-             "16 client entries each.", (int) ipos_encrypted[1]);
-    client_entries_len = (int)ipos_encrypted[1] * 16 * 20;
-    if (ipos_encrypted_size < 2 + client_entries_len + 17) {
+    client_blocks = (int) ipos_encrypted[1];
+    client_entries_len = client_blocks * REND_BASIC_AUTH_CLIENT_MULTIPLE *
+                         REND_BASIC_AUTH_CLIENT_ENTRY_LEN;
+    if (ipos_encrypted_size < 2 + client_entries_len + CIPHER_IV_LEN + 1) {
       log_warn(LD_REND, "Size of encrypted introduction points is too "
-               "small.");
+                        "small.");
       return -1;
     }
-    memcpy(iv, ipos_encrypted + 2 + client_entries_len, sizeof(iv));
+    memcpy(iv, ipos_encrypted + 2 + client_entries_len, CIPHER_IV_LEN);
     digest = crypto_new_digest_env();
-    crypto_digest_add_bytes(digest, descriptor_cookie, 16);
+    crypto_digest_add_bytes(digest, descriptor_cookie, REND_DESC_COOKIE_LEN);
     crypto_digest_add_bytes(digest, iv, CIPHER_IV_LEN);
-    crypto_digest_get_digest(digest, client_id, 4);
+    crypto_digest_get_digest(digest, client_id,
+                             REND_BASIC_AUTH_CLIENT_ID_LEN);
     crypto_free_digest_env(digest);
-    log_debug(LD_REND, "Our client ID with this initialization vector "
-              "is '%s'.", hex_str(client_id, 4));
-    for (pos = 2; pos < 2 + client_entries_len; pos += 20) {
-      log_debug(LD_REND, "Comparing with client ID '%s'...",
-               hex_str(ipos_encrypted + pos, 4));
-      if (!memcmp(ipos_encrypted + pos, client_id, 4)) {
+    for (pos = 2; pos < 2 + client_entries_len;
+         pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN) {
+      if (!memcmp(ipos_encrypted + pos, client_id,
+                  REND_BASIC_AUTH_CLIENT_ID_LEN)) {
+        /* Attempt to decrypt introduction points. */
         cipher = crypto_create_init_cipher(descriptor_cookie, 0);
-        log_debug(LD_REND, "Match found!");
         if (crypto_cipher_decrypt(cipher, session_key, ipos_encrypted
-                                  + pos + 4, 16) < 0) {
+                                  + pos + REND_BASIC_AUTH_CLIENT_ID_LEN,
+                                  CIPHER_KEY_LEN) < 0) {
           log_warn(LD_REND, "Could not decrypt session key for client.");
           crypto_free_cipher_env(cipher);
           return -1;
         }
         crypto_free_cipher_env(cipher);
-        log_debug(LD_REND, "Decrypted session key is '%s'",
-                  hex_str(session_key, 16));
-        /* Attempt to decrypt introduction points. */
         cipher = crypto_create_init_cipher(session_key, 0);
         len = ipos_encrypted_size - 2 - client_entries_len - CIPHER_IV_LEN;
         dec = tor_malloc_zero(len);
@@ -3675,15 +3673,12 @@
           tor_free(dec);
           return -1;
         }
-        log_debug(LD_REND, "Decrypted %d bytes, resulting in "
-                  "(hopefully a string) '%s'.",
-                  declen, dec);
         if (strcmpstart(dec, "introduction-point ")) {
           log_warn(LD_REND, "Decrypted introduction points don't "
                             "look like we could parse them.");
+          tor_free(dec);
           continue;
         }
-        log_debug(LD_REND, "Decrypted introduction points look good.");
         *ipos_decrypted = dec;
         *ipos_decrypted_size = declen;
         return 0;
@@ -3692,42 +3687,41 @@
     log_warn(LD_REND, "Could not decrypt introduction points. Please "
              "check your authorization for this service!");
     return -1;
-  } else if (ipos_encrypted[0] == 2) {
+  } else if (ipos_encrypted[0] == (int)REND_STEALTH_AUTH) {
     crypto_cipher_env_t *cipher;
     char *dec;
     int declen;
-    log_debug(LD_REND, "Introduction points are encrypted for "
-                       "authorization type 2.");
-    dec = tor_malloc_zero(ipos_encrypted_size - 16 - 1);
+    dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1);
     cipher = crypto_create_init_cipher(descriptor_cookie, 0);
     declen = crypto_cipher_decrypt_with_iv(cipher, dec,
-                                           ipos_encrypted_size - 16 - 1,
+                                           ipos_encrypted_size -
+                                               CIPHER_IV_LEN - 1,
                                            ipos_encrypted + 1,
                                            ipos_encrypted_size - 1);
     crypto_free_cipher_env(cipher);
     if (declen < 0) {
       log_warn(LD_REND, "Decrypting introduction points failed!");
-      tor_free(ipos_decrypted);
+      tor_free(dec);
       return -1;
     }
     *ipos_decrypted = dec;
     *ipos_decrypted_size = declen;
     return 0;
   } else {
-    log_warn(LD_REND, "Unknown authorization type: %d", ipos_encrypted[0]);
+    log_warn(LD_REND, "Unknown authorization type number: %d",
+             ipos_encrypted[0]);
     return -1;
   }
 }
 
-/** Parse the encoded introduction points in <b>ipos_encoded</b> of length
- * <b>ipos_encoded_size</b> and write the result to <b>parsed</b>; return
- * the number of successfully parsed introduction points or -1 in case of a
- * failure.
- */
+/** Parse the encoded introduction points in <b>intro_points_encoded</b> of
+ * length <b>intro_points_encoded_size</b> and write the result to the
+ * descriptor in <b>parsed</b>; return the number of successfully parsed
+ * introduction points or -1 in case of a failure. */
 int
 rend_parse_introduction_points(rend_service_descriptor_t *parsed,
-                               const char *ipos_encoded,
-                               size_t ipos_encoded_size)
+                               const char *intro_points_encoded,
+                               size_t intro_points_encoded_size)
 {
   const char **current_ipo;
   smartlist_t *tokens;
@@ -3739,10 +3733,10 @@
   tor_assert(parsed);
   /** Function may only be invoked once. */
   tor_assert(!parsed->intro_nodes);
-  tor_assert(ipos_encoded);
-  tor_assert(ipos_encoded_size > 0);
+  tor_assert(intro_points_encoded);
+  tor_assert(intro_points_encoded_size > 0);
   /* Consider one intro point after the other. */
-  current_ipo = &ipos_encoded;
+  current_ipo = &intro_points_encoded;
   tokens = smartlist_create();
   parsed->intro_nodes = smartlist_create();
   area = memarea_new(4096);
@@ -3798,6 +3792,7 @@
       rend_intro_point_free(intro);
       goto err;
     }
+
     /* Parse onion port. */
     tok = find_first_by_keyword(tokens, R_IPO_ONION_PORT);
     info->port = (uint16_t) tor_parse_long(tok->args[0],10,1,65535,
@@ -3853,7 +3848,7 @@
   /* Begin parsing with first entry, skipping comments or whitespace at the
    * beginning. */
   area = memarea_new(4096);
-  current_entry = strstr(ckstr, "client-name ");
+  current_entry = eat_whitespace(ckstr);
   while (!strcmpstart(current_entry, "client-name ")) {
     rend_authorized_client_t *parsed_entry;
     size_t len;

Modified: tor/branches/121-hs-authorization/src/or/test.c
===================================================================
--- tor/branches/121-hs-authorization/src/or/test.c	2008-08-16 11:36:09 UTC (rev 16566)
+++ tor/branches/121-hs-authorization/src/or/test.c	2008-08-16 13:21:17 UTC (rev 16567)
@@ -4049,9 +4049,8 @@
     intro->intro_key = crypto_pk_dup_key(pk2);
     smartlist_add(generated->intro_nodes, intro);
   }
-  test_assert(rend_encode_v2_descriptors(descs, generated, now,
-                                         generated->pk, 0, NULL, NULL,
-                                         0) > 0);
+  test_assert(rend_encode_v2_descriptors(descs, generated, now, 0,
+                                         REND_NO_AUTH, NULL, NULL) > 0);
   test_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32,
                                       NULL, now, 0) == 0);
   test_memeq(((rend_encoded_v2_service_descriptor_t *)