[tor-commits] [tor/master] Stop accepting milliseconds in various directory contexts

nickm at torproject.org nickm at torproject.org
Wed Jan 7 15:08:23 UTC 2015


commit 7984fc153112baa5c370215f2205025a7648d7b4
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jul 18 23:45:40 2013 -0400

    Stop accepting milliseconds in various directory contexts
    
    Have clients and authorities both have new behavior, since the
    fix for bug 11243 has gone in.  But make clients still accept
    accept old bogus HSDir descriptors, to avoid fingerprinting trickery.
    
    Fixes bug 9286.
---
 changes/bug9286      |    4 ++++
 src/common/util.c    |   23 ++++++++++++++++++-----
 src/common/util.h    |    1 +
 src/or/rendcommon.c  |    6 +++---
 src/or/routerparse.c |   10 ++++++++--
 src/or/routerparse.h |    3 ++-
 src/test/test.c      |   12 ++++++------
 src/test/test_util.c |   16 +++++++++-------
 8 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/changes/bug9286 b/changes/bug9286
new file mode 100644
index 0000000..062a7a0
--- /dev/null
+++ b/changes/bug9286
@@ -0,0 +1,4 @@
+  o Minor bugfixes (parsing):
+    - Stop accepting milliseconds (or other junk) at the end of
+      descriptor publication times. Fixes bug 9286; bugfix on
+      0.0.2pre25.
\ No newline at end of file
diff --git a/src/common/util.c b/src/common/util.c
index 50097da..481f96b 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1656,15 +1656,18 @@ format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
 
 /** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
  * parse it and store its value in *<b>t</b>.  Return 0 on success, -1 on
- * failure.  Ignore extraneous stuff in <b>cp</b> separated by whitespace from
- * the end of the time string. */
+ * failure.  Ignore extraneous stuff in <b>cp</b> after the end of the time
+ * string, unless <b>strict</b> is set. */
 int
-parse_iso_time(const char *cp, time_t *t)
+parse_iso_time_(const char *cp, time_t *t, int strict)
 {
   struct tm st_tm;
   unsigned int year=0, month=0, day=0, hour=0, minute=0, second=0;
-  if (tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u", &year, &month,
-                &day, &hour, &minute, &second) < 6) {
+  int n_fields;
+  char extra_char;
+  n_fields = tor_sscanf(cp, "%u-%2u-%2u %2u:%2u:%2u%c", &year, &month,
+                        &day, &hour, &minute, &second, &extra_char);
+  if (strict ? (n_fields != 6) : (n_fields < 6)) {
     char *esc = esc_for_log(cp);
     log_warn(LD_GENERAL, "ISO time %s was unparseable", esc);
     tor_free(esc);
@@ -1693,6 +1696,16 @@ parse_iso_time(const char *cp, time_t *t)
   return tor_timegm(&st_tm, t);
 }
 
+/** Given an ISO-formatted UTC time value (after the epoch) in <b>cp</b>,
+ * parse it and store its value in *<b>t</b>.  Return 0 on success, -1 on
+ * failure. Reject the string if any characters are present after the time.
+ */
+int
+parse_iso_time(const char *cp, time_t *t)
+{
+  return parse_iso_time_(cp, t, 1);
+}
+
 /** Given a <b>date</b> in one of the three formats allowed by HTTP (ugh),
  * parse it into <b>tm</b>.  Return 0 on success, negative on failure. */
 int
diff --git a/src/common/util.h b/src/common/util.h
index 921dd79..a3a79a9 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -270,6 +270,7 @@ void format_local_iso_time(char *buf, time_t t);
 void format_iso_time(char *buf, time_t t);
 void format_iso_time_nospace(char *buf, time_t t);
 void format_iso_time_nospace_usec(char *buf, const struct timeval *tv);
+int parse_iso_time_(const char *cp, time_t *t, int strict);
 int parse_iso_time(const char *buf, time_t *t);
 int parse_http_time(const char *buf, struct tm *tm);
 int format_time_interval(char *out, size_t out_len, long interval);
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index df74b74..837bd2b 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -411,7 +411,7 @@ rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc)
                                          &test_intro_content,
                                          &test_intro_size,
                                          &test_encoded_size,
-                                         &test_next, desc->desc_str);
+                                         &test_next, desc->desc_str, 1);
   rend_service_descriptor_free(test_parsed);
   tor_free(test_intro_content);
   return (res >= 0);
@@ -945,7 +945,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
   }
   while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
                                           &intro_size, &encoded_size,
-                                          &next_desc, current_desc) >= 0) {
+                                          &next_desc, current_desc, 1) >= 0) {
     number_parsed++;
     /* We don't care about the introduction points. */
     tor_free(intro_content);
@@ -1084,7 +1084,7 @@ rend_cache_store_v2_desc_as_client(const char *desc,
   /* Parse the descriptor. */
   if (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
                                        &intro_size, &encoded_size,
-                                       &next_desc, desc) < 0) {
+                                       &next_desc, desc, 0) < 0) {
     log_warn(LD_REND, "Could not parse descriptor.");
     goto err;
   }
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index bc3b002..a944e35 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -4417,6 +4417,9 @@ sort_version_list(smartlist_t *versions, int remove_duplicates)
  * to *<b>encoded_size_out</b>, and a pointer to the possibly next
  * descriptor to *<b>next_out</b>; return 0 for success (including validation)
  * and -1 for failure.
+ *
+ * If <b>as_hsdir</b> is 1, we're parsing this as an HSDir, and we should
+ * be strict about time formats.
  */
 int
 rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
@@ -4424,7 +4427,8 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
                                  char **intro_points_encrypted_out,
                                  size_t *intro_points_encrypted_size_out,
                                  size_t *encoded_size_out,
-                                 const char **next_out, const char *desc)
+                                 const char **next_out, const char *desc,
+                                 int as_hsdir)
 {
   rend_service_descriptor_t *result =
                             tor_malloc_zero(sizeof(rend_service_descriptor_t));
@@ -4438,6 +4442,8 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
   char public_key_hash[DIGEST_LEN];
   char test_desc_id[DIGEST_LEN];
   memarea_t *area = NULL;
+  const int strict_time_fmt = as_hsdir;
+
   tor_assert(desc);
   /* Check if desc starts correctly. */
   if (strncmp(desc, "rendezvous-service-descriptor ",
@@ -4532,7 +4538,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
    * descriptor. */
   tok = find_by_keyword(tokens, R_PUBLICATION_TIME);
   tor_assert(tok->n_args == 1);
-  if (parse_iso_time(tok->args[0], &result->timestamp) < 0) {
+  if (parse_iso_time_(tok->args[0], &result->timestamp, strict_time_fmt) < 0) {
     log_warn(LD_REND, "Invalid publication time: '%s'", tok->args[0]);
     goto err;
   }
diff --git a/src/or/routerparse.h b/src/or/routerparse.h
index e950548..6629b6d 100644
--- a/src/or/routerparse.h
+++ b/src/or/routerparse.h
@@ -73,7 +73,8 @@ int rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
                                      char **intro_points_encrypted_out,
                                      size_t *intro_points_encrypted_size_out,
                                      size_t *encoded_size_out,
-                                     const char **next_out, const char *desc);
+                                     const char **next_out, const char *desc,
+                                     int as_hsdir);
 int rend_decrypt_introduction_points(char **ipos_decrypted,
                                      size_t *ipos_decrypted_size,
                                      const char *descriptor_cookie,
diff --git a/src/test/test.c b/src/test/test.c
index 07901ab..032a9d7 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -696,12 +696,12 @@ test_rend_fns(void *arg)
              smartlist_get(descs, 0))->desc_id, OP_EQ,
             computed_desc_id, DIGEST_LEN);
   tt_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id,
-                                               &intro_points_encrypted,
-                                               &intro_points_size,
-                                               &encoded_size,
-                                               &next_desc,
-                                     ((rend_encoded_v2_service_descriptor_t *)
-                                     smartlist_get(descs, 0))->desc_str) == 0);
+                                             &intro_points_encrypted,
+                                             &intro_points_size,
+                                             &encoded_size,
+                                              &next_desc,
+                             ((rend_encoded_v2_service_descriptor_t *)
+                                 smartlist_get(descs, 0))->desc_str, 1) == 0);
   tt_assert(parsed);
   tt_mem_op(((rend_encoded_v2_service_descriptor_t *)
          smartlist_get(descs, 0))->desc_id,OP_EQ, parsed_desc_id, DIGEST_LEN);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b952bb2..94671f9 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -589,15 +589,17 @@ test_util_time(void *arg)
   i = parse_iso_time("2004-8-4 0:48:22", &t_res);
   tt_int_op(0,OP_EQ, i);
   tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
-  tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res));
-  tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59", &t_res));
   tt_int_op(-1,OP_EQ, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
   tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res));
+  tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res));
 
   /* Test tor_gettimeofday */
 





More information about the tor-commits mailing list