]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Stop accepting milliseconds in various directory contexts
authorNick Mathewson <nickm@torproject.org>
Fri, 19 Jul 2013 03:45:40 +0000 (23:45 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 7 Jan 2015 15:05:55 +0000 (10:05 -0500)
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 [new file with mode: 0644]
src/common/util.c
src/common/util.h
src/or/rendcommon.c
src/or/routerparse.c
src/or/routerparse.h
src/test/test.c
src/test/test_util.c

diff --git a/changes/bug9286 b/changes/bug9286
new file mode 100644 (file)
index 0000000..062a7a0
--- /dev/null
@@ -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
index 50097dac93a9a4d8d08caaa57fbed397e0642f5a..481f96bb0f673ca1ab42aa9b454795a6d0c3ba74 100644 (file)
@@ -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
index 921dd79da00334317ce5524dcf1e1a1ae796b126..a3a79a928d59248460bacd0306b7879644819f4a 100644 (file)
@@ -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);
index df74b745a2915369f401979722e8b757f5f8fe1e..837bd2b5a13df292071084ad0eed3bd1d280fadf 100644 (file)
@@ -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;
   }
index bc3b00226a0f332c2ff53ea513f76631a49ecf56..a944e35c2206af8b638fe932ffdb9645c62bb0fb 100644 (file)
@@ -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;
   }
index e950548f8c18856a5b5986c6c9bbe95781447ea7..6629b6d4bc1bccc428cbac537990a500fd5ef288 100644 (file)
@@ -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,
index 07901ab107e4ed6789b0c1a7951b87a215df4b65..032a9d766e72962d64f764ba50cfae62d36a3da4 100644 (file)
@@ -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);
index b952bb2596ab1b5dec13c7c413b400dabb862ca6..94671f94302fbb27eb0b58aa7e0998b2df2df9d5 100644 (file)
@@ -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 */