commit b311f82026d51141a2ef6dd4a709d41a0dd3c388 Author: teor (Tim Wilson-Brown) teor2345@gmail.com Date: Fri Apr 1 00:22:17 2016 +1100
Check non-onion hostnames & IP addresses against client port flags
Check NoDNSRequest, NoIPv4Traffic, and NoIPv6Traffic before attaching a stream.
NoDNSRequest refuses connections to all non-onion hostnames, but permits IP addresses. NoIPv4Traffic refuses connections to IPv4 addresses, but resolves hostnames. NoIPv6Traffic refuses connections to IPv6 addresses, but resolves hostnames.
Combined, they refuse all non-onion hostnames and IP addresses. --- src/or/connection_edge.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 15b521b..32272ec 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1474,6 +1474,53 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, } #endif
+ /* socks->address is a non-onion hostname or IP address. + * If we can't do any non-onion requests, refuse the connection. + * If we have a hostname but can't do DNS, refuse the connection. + * If we have an IP address, but we can't use that address family, + * refuse the connection. + * + * If we can do DNS requests, and we can use at least one address family, + * then we have to resolve the address first. Then we'll know if it + * resolves to a usable address family. */ + + /* First, check if all non-onion traffic is disabled */ + if (!conn->entry_cfg.dns_request && !conn->entry_cfg.ipv4_traffic + && !conn->entry_cfg.ipv6_traffic) { + log_warn(LD_APP, "Refusing to connect to non-hidden-service hostname " + "or IP address %s because Port has OnionTrafficOnly set (or " + "NoDNSRequest, NoIPv4Traffic, and NoIPv6Traffic).", + safe_str_client(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); + return -1; + } + + /* Then check if we have a hostname or IP address, and whether DNS or + * the IP address family are permitted */ + tor_addr_t dummy_addr; + int socks_family = tor_addr_parse(&dummy_addr, socks->address); + /* family will be -1 for a non-onion hostname that's not an IP */ + if (socks_family == -1 && !conn->entry_cfg.dns_request) { + log_warn(LD_APP, "Refusing to connect to hostname %s " + "because Port has NoDNSRequest set.", + safe_str_client(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); + return -1; + } else if (socks_family == AF_INET && !conn->entry_cfg.ipv4_traffic) { + log_warn(LD_APP, "Refusing to connect to IPv4 address %s because " + "Port has NoIPv4Traffic set.", + safe_str_client(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); + return -1; + } else if (socks_family == AF_INET6 && !conn->entry_cfg.ipv6_traffic) { + log_warn(LD_APP, "Refusing to connect to IPv6 address %s because " + "Port has NoIPv6Traffic set.", + safe_str_client(socks->address)); + connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY); + return -1; + } + /* No else, we've covered all possible returned value. */ + /* See if this is a hostname lookup that we can answer immediately. * (For example, an attempt to look up the IP address for an IP address.) */
tor-commits@lists.torproject.org