mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Merge branch 'maint-0.3.1'
This commit is contained in:
commit
3781678a3c
4
changes/bug22670
Normal file
4
changes/bug22670
Normal file
@ -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.
|
4
changes/bug22670_02
Normal file
4
changes/bug22670_02
Normal file
@ -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.
|
6
changes/bug22670_03
Normal file
6
changes/bug22670_03
Normal file
@ -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.
|
@ -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,91 +2441,12 @@ 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);
|
||||
if (dir_client_decompress_response_body(&body, &body_len,
|
||||
conn, compression, anonymized_connection) < 0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
response_handler_args_t args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.status_code = status_code;
|
||||
|
Loading…
Reference in New Issue
Block a user