summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-06-29 11:34:06 -0400
committerNick Mathewson <nickm@torproject.org>2017-06-29 11:34:06 -0400
commit31a08ba26fc5eaa12de6d3c5efa3aac4d00509d0 (patch)
tree7c9566c79bdccdf705fd19941201901378109b98
parent0ac8f0bde92ef60d8863bbbcae42a6dc7c726b01 (diff)
parent5537e1fc45b683f10b3702f00e0b1280d4a5c87a (diff)
downloadtor-31a08ba26fc5eaa12de6d3c5efa3aac4d00509d0.tar.gz
tor-31a08ba26fc5eaa12de6d3c5efa3aac4d00509d0.zip
Merge remote-tracking branch 'public/bug22670_031' into maint-0.3.1
-rw-r--r--changes/bug226704
-rw-r--r--changes/bug22670_024
-rw-r--r--changes/bug22670_036
-rw-r--r--src/or/directory.c205
4 files changed, 135 insertions, 84 deletions
diff --git a/changes/bug22670 b/changes/bug22670
new file mode 100644
index 0000000000..47403277d2
--- /dev/null
+++ b/changes/bug22670
@@ -0,0 +1,4 @@
+ o Minor bugfixes (logging, compression):
+ - When decompressing, do not warn if we fail to decompress using a
+ compression method that we merely guessed. Fixes part of
+ bug 22670; bugfix on 0.1.1.14-alpha.
diff --git a/changes/bug22670_02 b/changes/bug22670_02
new file mode 100644
index 0000000000..3e7a428faf
--- /dev/null
+++ b/changes/bug22670_02
@@ -0,0 +1,4 @@
+ o Minor bugfixes (logging, compression):
+ - When decompressing, treat mismatch between content-encoding and
+ actual compression type as a protocol warning. Fixes part of bug
+ 22670; bugfix on 0.1.1.9-alpha.
diff --git a/changes/bug22670_03 b/changes/bug22670_03
new file mode 100644
index 0000000000..8a7aa49bcd
--- /dev/null
+++ b/changes/bug22670_03
@@ -0,0 +1,6 @@
+ o Minor bugfixes (compression):
+ - When decompressing an object received over an anonymous directory
+ connection, if we have already successfully decompressed it using an
+ acceptable compression method, do not reject it for looking like an
+ unacceptable compression method. Fixes part of bug 22670; bugfix on
+ 0.3.1.1-alpha.
diff --git a/src/or/directory.c b/src/or/directory.c
index 6ce739b4f6..45fbd1dd33 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2191,6 +2191,123 @@ static int handle_response_fetch_renddesc_v2(dir_connection_t *,
static int handle_response_upload_renddesc_v2(dir_connection_t *,
const response_handler_args_t *);
+static int
+dir_client_decompress_response_body(char **bodyp, size_t *bodylenp,
+ dir_connection_t *conn,
+ compress_method_t compression,
+ int anonymized_connection)
+{
+ int rv = 0;
+ const char *body = *bodyp;
+ size_t body_len = *bodylenp;
+ int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
+ conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
+ conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
+
+ int plausible = body_is_plausible(body, body_len, conn->base_.purpose);
+
+ if (plausible && compression == NO_METHOD) {
+ return 0;
+ }
+
+ int severity = LOG_DEBUG;
+ char *new_body = NULL;
+ size_t new_len = 0;
+ const char *description1, *description2;
+ int want_to_try_both = 0;
+ int tried_both = 0;
+ compress_method_t guessed = detect_compression_method(body, body_len);
+
+ description1 = compression_method_get_human_name(compression);
+
+ if (BUG(description1 == NULL))
+ description1 = compression_method_get_human_name(UNKNOWN_METHOD);
+
+ if (guessed == UNKNOWN_METHOD && !plausible)
+ description2 = "confusing binary junk";
+ else
+ description2 = compression_method_get_human_name(guessed);
+
+ /* Tell the user if we don't believe what we're told about compression.*/
+ want_to_try_both = (compression == UNKNOWN_METHOD ||
+ guessed != compression);
+ if (want_to_try_both) {
+ severity = LOG_PROTOCOL_WARN;
+ }
+
+ tor_log(severity, LD_HTTP,
+ "HTTP body from server '%s:%d' was labeled as %s, "
+ "%s it seems to be %s.%s",
+ conn->base_.address, conn->base_.port, description1,
+ guessed != compression?"but":"and",
+ description2,
+ (compression>0 && guessed>0 && want_to_try_both)?
+ " Trying both.":"");
+
+ /* Try declared compression first if we can.
+ * tor_compress_supports_method() also returns true for NO_METHOD.
+ * Ensure that the server is not sending us data compressed using a
+ * compression method that is not allowed for anonymous connections. */
+ if (anonymized_connection &&
+ ! allowed_anonymous_connection_compression_method(compression)) {
+ warn_disallowed_anonymous_compression_method(compression);
+ rv = -1;
+ goto done;
+ }
+
+ if (tor_compress_supports_method(compression)) {
+ tor_uncompress(&new_body, &new_len, body, body_len, compression,
+ !allow_partial, LOG_PROTOCOL_WARN);
+ if (new_body) {
+ /* We succeeded with the declared compression method. Great! */
+ rv = 0;
+ goto done;
+ }
+ }
+
+ /* Okay, if that didn't work, and we think that it was compressed
+ * differently, try that. */
+ if (anonymized_connection &&
+ ! allowed_anonymous_connection_compression_method(guessed)) {
+ warn_disallowed_anonymous_compression_method(guessed);
+ rv = -1;
+ goto done;
+ }
+
+ if (tor_compress_supports_method(guessed) &&
+ compression != guessed) {
+ tor_uncompress(&new_body, &new_len, body, body_len, guessed,
+ !allow_partial, LOG_INFO);
+ tried_both = 1;
+ }
+ /* If we're pretty sure that we have a compressed directory, and
+ * we didn't manage to uncompress it, then warn and bail. */
+ if (!plausible && !new_body) {
+ log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
+ "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').",
+ description1,
+ tried_both?" and ":"",
+ tried_both?description2:"",
+ conn->base_.address, conn->base_.port);
+ rv = -1;
+ goto done;
+ }
+
+ done:
+ if (new_body) {
+ if (rv == 0) {
+ /* success! */
+ tor_free(*bodyp);
+ *bodyp = new_body;
+ *bodylenp = new_len;
+ } else {
+ tor_free(new_body);
+ }
+ }
+
+ return rv;
+}
+
/** We are a client, and we've finished reading the server's
* response. Parse it and act appropriately.
*
@@ -2211,7 +2328,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
time_t date_header = 0;
long apparent_skew;
compress_method_t compression;
- int plausible;
int skewed = 0;
int rv;
int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
@@ -2325,89 +2441,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
goto done;
}
- plausible = body_is_plausible(body, body_len, conn->base_.purpose);
- if (compression != NO_METHOD || !plausible) {
- int severity = LOG_DEBUG;
- char *new_body = NULL;
- size_t new_len = 0;
- const char *description1, *description2;
- int want_to_try_both = 0;
- int tried_both = 0;
- compress_method_t guessed = detect_compression_method(body, body_len);
-
- description1 = compression_method_get_human_name(compression);
-
- if (BUG(description1 == NULL))
- description1 = compression_method_get_human_name(UNKNOWN_METHOD);
-
- if (guessed == UNKNOWN_METHOD && !plausible)
- description2 = "confusing binary junk";
- else
- description2 = compression_method_get_human_name(guessed);
-
- /* Tell the user if we don't believe what we're told about compression.*/
- want_to_try_both = (compression == UNKNOWN_METHOD ||
- guessed != compression);
- if (want_to_try_both) {
- severity = LOG_INFO;
- }
-
- tor_log(severity, LD_HTTP,
- "HTTP body from server '%s:%d' was labeled as %s, "
- "%s it seems to be %s.%s",
- conn->base_.address, conn->base_.port, description1,
- guessed != compression?"but":"and",
- description2,
- (compression>0 && guessed>0 && want_to_try_both)?
- " Trying both.":"");
-
- /* Try declared compression first if we can.
- * tor_compress_supports_method() also returns true for NO_METHOD.
- * Ensure that the server is not sending us data compressed using a
- * compression method that is not allowed for anonymous connections. */
- if (anonymized_connection &&
- ! allowed_anonymous_connection_compression_method(compression)) {
- warn_disallowed_anonymous_compression_method(compression);
- rv = -1;
- goto done;
- }
-
- if (tor_compress_supports_method(compression))
- tor_uncompress(&new_body, &new_len, body, body_len, compression,
- !allow_partial, LOG_PROTOCOL_WARN);
-
- /* Okay, if that didn't work, and we think that it was compressed
- * differently, try that. */
- if (anonymized_connection &&
- ! allowed_anonymous_connection_compression_method(guessed)) {
- warn_disallowed_anonymous_compression_method(guessed);
- rv = -1;
- goto done;
- }
-
- if (!new_body && tor_compress_supports_method(guessed) &&
- compression != guessed) {
- tor_uncompress(&new_body, &new_len, body, body_len, guessed,
- !allow_partial, LOG_PROTOCOL_WARN);
- tried_both = 1;
- }
- /* If we're pretty sure that we have a compressed directory, and
- * we didn't manage to uncompress it, then warn and bail. */
- if (!plausible && !new_body) {
- log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
- "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').",
- description1,
- tried_both?" and ":"",
- tried_both?description2:"",
- conn->base_.address, conn->base_.port);
- rv = -1;
- goto done;
- }
- if (new_body) {
- tor_free(body);
- body = new_body;
- body_len = new_len;
- }
+ if (dir_client_decompress_response_body(&body, &body_len,
+ conn, compression, anonymized_connection) < 0) {
+ rv = -1;
+ goto done;
}
response_handler_args_t args;