aboutsummaryrefslogtreecommitdiff
path: root/src/or/channeltls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/channeltls.c')
-rw-r--r--src/or/channeltls.c76
1 files changed, 60 insertions, 16 deletions
diff --git a/src/or/channeltls.c b/src/or/channeltls.c
index 92e51b21a..632bc328b 100644
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@ -56,6 +56,8 @@ static const char * channel_tls_describe_transport_method(channel_t *chan);
static void channel_tls_free_method(channel_t *chan);
static int
channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out);
+static int
+channel_tls_get_transport_name_method(channel_t *chan, char **transport_out);
static const char *
channel_tls_get_remote_descr_method(channel_t *chan, int flags);
static int channel_tls_has_queued_writes_method(channel_t *chan);
@@ -116,6 +118,7 @@ channel_tls_common_init(channel_tls_t *tlschan)
chan->free = channel_tls_free_method;
chan->get_remote_addr = channel_tls_get_remote_addr_method;
chan->get_remote_descr = channel_tls_get_remote_descr_method;
+ chan->get_transport_name = channel_tls_get_transport_name_method;
chan->has_queued_writes = channel_tls_has_queued_writes_method;
chan->is_canonical = channel_tls_is_canonical_method;
chan->matches_extend_info = channel_tls_matches_extend_info_method;
@@ -286,8 +289,8 @@ channel_tls_handle_incoming(or_connection_t *orconn)
if (is_local_addr(&(TO_CONN(orconn)->addr))) channel_mark_local(chan);
channel_mark_incoming(chan);
- /* If we got one, we should register it */
- if (chan) channel_register(chan);
+ /* Register it */
+ channel_register(chan);
return chan;
}
@@ -435,6 +438,30 @@ channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out)
}
/**
+ * Get the name of the pluggable transport used by a channel_tls_t.
+ *
+ * This implements the get_transport_name for channel_tls_t. If the
+ * channel uses a pluggable transport, copy its name to
+ * <b>transport_out</b> and return 0. If the channel did not use a
+ * pluggable transport, return -1. */
+
+static int
+channel_tls_get_transport_name_method(channel_t *chan, char **transport_out)
+{
+ channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+
+ tor_assert(tlschan);
+ tor_assert(transport_out);
+ tor_assert(tlschan->conn);
+
+ if (!tlschan->conn->ext_or_transport)
+ return -1;
+
+ *transport_out = tor_strdup(tlschan->conn->ext_or_transport);
+ return 0;
+}
+
+/**
* Get endpoint description of a channel_tls_t
*
* This implements the get_remote_descr method for channel_tls_t; it returns
@@ -1255,13 +1282,20 @@ static void
channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
{
int highest_supported_version = 0;
- const uint8_t *cp, *end;
int started_here = 0;
tor_assert(cell);
tor_assert(chan);
tor_assert(chan->conn);
+ if ((cell->payload_len % 2) == 1) {
+ log_fn(LOG_PROTOCOL_WARN, LD_OR,
+ "Received a VERSION cell with odd payload length %d; "
+ "closing connection.",cell->payload_len);
+ connection_or_close_for_error(chan->conn, 0);
+ return;
+ }
+
started_here = connection_or_nonopen_was_started_here(chan->conn);
if (chan->conn->link_proto != 0 ||
@@ -1287,11 +1321,15 @@ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
}
tor_assert(chan->conn->handshake_state);
- end = cell->payload + cell->payload_len;
- for (cp = cell->payload; cp+1 < end; cp += 2) {
- uint16_t v = ntohs(get_uint16(cp));
- if (is_or_protocol_version_known(v) && v > highest_supported_version)
- highest_supported_version = v;
+
+ {
+ int i;
+ const uint8_t *cp = cell->payload;
+ for (i = 0; i < cell->payload_len / 2; ++i, cp += 2) {
+ uint16_t v = ntohs(get_uint16(cp));
+ if (is_or_protocol_version_known(v) && v > highest_supported_version)
+ highest_supported_version = v;
+ }
}
if (!highest_supported_version) {
log_fn(LOG_PROTOCOL_WARN, LD_OR,
@@ -1489,12 +1527,14 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
my_addr_ptr = (uint8_t*) cell->payload + 6;
end = cell->payload + CELL_PAYLOAD_SIZE;
cp = cell->payload + 6 + my_addr_len;
- if (cp >= end) {
- log_fn(LOG_PROTOCOL_WARN, LD_OR,
- "Addresses too long in netinfo cell; closing connection.");
- connection_or_close_for_error(chan->conn, 0);
- return;
- } else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
+
+ /* We used to check:
+ * if (my_addr_len >= CELL_PAYLOAD_SIZE - 6) {
+ *
+ * This is actually never going to happen, since my_addr_len is at most 255,
+ * and CELL_PAYLOAD_LEN - 6 is 503. So we know that cp is < end. */
+
+ if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
tor_addr_from_ipv4n(&my_apparent_addr, get_uint32(my_addr_ptr));
} else if (my_addr_type == RESOLVED_TYPE_IPV6 && my_addr_len == 16) {
tor_addr_from_ipv6_bytes(&my_apparent_addr, (const char *) my_addr_ptr);
@@ -1648,12 +1688,16 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
for (i = 0; i < n_certs; ++i) {
uint8_t cert_type;
uint16_t cert_len;
- if (ptr + 3 > cell->payload + cell->payload_len) {
+ if (cell->payload_len < 3)
+ goto truncated;
+ if (ptr > cell->payload + cell->payload_len - 3) {
goto truncated;
}
cert_type = *ptr;
cert_len = ntohs(get_uint16(ptr+1));
- if (ptr + 3 + cert_len > cell->payload + cell->payload_len) {
+ if (cell->payload_len < 3 + cert_len)
+ goto truncated;
+ if (ptr > cell->payload + cell->payload_len - cert_len - 3) {
goto truncated;
}
if (cert_type == OR_CERT_TYPE_TLS_LINK ||