mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Ensure that only GZip and Zlib compression is handled for anonymous connections.
See: https://bugs.torproject.org/22305
This commit is contained in:
parent
2b26ac1390
commit
5a0eab68e1
@ -2219,6 +2219,10 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
|
conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
|
||||||
conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
|
conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
|
||||||
size_t received_bytes;
|
size_t received_bytes;
|
||||||
|
const int anonymized_connection =
|
||||||
|
purpose_needs_anonymity(conn->base_.purpose,
|
||||||
|
conn->router_purpose,
|
||||||
|
conn->requested_resource);
|
||||||
|
|
||||||
received_bytes = connection_get_inbuf_len(TO_CONN(conn));
|
received_bytes = connection_get_inbuf_len(TO_CONN(conn));
|
||||||
|
|
||||||
@ -2347,13 +2351,29 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
description2,
|
description2,
|
||||||
(compression>0 && guessed>0)?" Trying both.":"");
|
(compression>0 && guessed>0)?" Trying both.":"");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try declared compression first if we can.
|
/* Try declared compression first if we can.
|
||||||
* tor_compress_supports_method() also returns true for NO_METHOD. */
|
* 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)) {
|
||||||
|
rv = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (tor_compress_supports_method(compression))
|
if (tor_compress_supports_method(compression))
|
||||||
tor_uncompress(&new_body, &new_len, body, body_len, compression,
|
tor_uncompress(&new_body, &new_len, body, body_len, compression,
|
||||||
!allow_partial, LOG_PROTOCOL_WARN);
|
!allow_partial, LOG_PROTOCOL_WARN);
|
||||||
|
|
||||||
/* Okay, if that didn't work, and we think that it was compressed
|
/* Okay, if that didn't work, and we think that it was compressed
|
||||||
* differently, try that. */
|
* differently, try that. */
|
||||||
|
if (anonymized_connection &&
|
||||||
|
! allowed_anonymous_connection_compression_method(guessed)) {
|
||||||
|
rv = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (!new_body && tor_compress_supports_method(guessed) &&
|
if (!new_body && tor_compress_supports_method(guessed) &&
|
||||||
compression != guessed)
|
compression != guessed)
|
||||||
tor_uncompress(&new_body, &new_len, body, body_len, guessed,
|
tor_uncompress(&new_body, &new_len, body, body_len, guessed,
|
||||||
@ -3339,6 +3359,14 @@ static compress_method_t srv_meth_pref_streaming_compression[] = {
|
|||||||
NO_METHOD
|
NO_METHOD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Array of allowed compression methods to use (if supported) when receiving a
|
||||||
|
* response from a request that was required to be anonymous. */
|
||||||
|
static compress_method_t client_meth_allowed_anonymous_compression[] = {
|
||||||
|
ZLIB_METHOD,
|
||||||
|
GZIP_METHOD,
|
||||||
|
NO_METHOD
|
||||||
|
};
|
||||||
|
|
||||||
/** Parse the compression methods listed in an Accept-Encoding header <b>h</b>,
|
/** Parse the compression methods listed in an Accept-Encoding header <b>h</b>,
|
||||||
* and convert them to a bitfield where compression method x is supported if
|
* and convert them to a bitfield where compression method x is supported if
|
||||||
* and only if 1 << x is set in the bitfield. */
|
* and only if 1 << x is set in the bitfield. */
|
||||||
@ -3838,6 +3866,29 @@ find_best_compression_method(unsigned compression_methods, int stream)
|
|||||||
return NO_METHOD;
|
return NO_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if the given compression method is allowed for a connection that is
|
||||||
|
* supposed to be anonymous. Returns 1 if the compression method is allowed,
|
||||||
|
* otherwise 0. */
|
||||||
|
STATIC int
|
||||||
|
allowed_anonymous_connection_compression_method(compress_method_t method)
|
||||||
|
{
|
||||||
|
unsigned u;
|
||||||
|
|
||||||
|
for (u = 0; u < ARRAY_LENGTH(client_meth_allowed_anonymous_compression);
|
||||||
|
++u) {
|
||||||
|
compress_method_t allowed_method =
|
||||||
|
client_meth_allowed_anonymous_compression[u];
|
||||||
|
|
||||||
|
if (! tor_compress_supports_method(allowed_method))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (method == allowed_method)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Encodes the results of parsing a consensus request to figure out what
|
/** Encodes the results of parsing a consensus request to figure out what
|
||||||
* consensus, and possibly what diffs, the user asked for. */
|
* consensus, and possibly what diffs, the user asked for. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -161,6 +161,7 @@ STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn,
|
|||||||
const struct get_handler_args_t *args);
|
const struct get_handler_args_t *args);
|
||||||
STATIC int directory_handle_command(dir_connection_t *conn);
|
STATIC int directory_handle_command(dir_connection_t *conn);
|
||||||
STATIC char *accept_encoding_header(void);
|
STATIC char *accept_encoding_header(void);
|
||||||
|
STATIC int allowed_anonymous_connection_compression_method(compress_method_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user