Commit d1d0813c authored by Roger Dingledine's avatar Roger Dingledine
Browse files

Allow non-printable characters for exit streams (both for

connecting and for resolving). Now we tolerate applications
that don't follow the RFCs. But continue to block malformed
names at the socks side.


svn:r6193
parent 726e825b
......@@ -774,7 +774,7 @@ connection_connect(connection_t *conn, char *address,
} else if (!SOCKET_IS_POLLABLE(s)) {
log_warn(LD_NET,
"Too many connections; can't create pollable connection to %s",
safe_str(address));
escaped_safe_str(address));
tor_close_socket(s);
return -1;
}
......@@ -804,15 +804,15 @@ connection_connect(connection_t *conn, char *address,
dest_addr.sin_port = htons(port);
dest_addr.sin_addr.s_addr = htonl(addr);
log_debug(LD_NET,"Connecting to %s:%u.",safe_str(address),port);
log_debug(LD_NET,"Connecting to %s:%u.",escaped_safe_str(address),port);
if (connect(s,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) {
int e = tor_socket_errno(s);
if (!ERRNO_IS_CONN_EINPROGRESS(e)) {
/* yuck. kill it. */
log_info(LD_NET,
"connect() to %s:%u failed: %s",safe_str(address),port,
tor_socket_strerror(e));
"connect() to %s:%u failed: %s",escaped_safe_str(address),
port, tor_socket_strerror(e));
tor_close_socket(s);
return -1;
} else {
......@@ -825,8 +825,8 @@ connection_connect(connection_t *conn, char *address,
/* it succeeded. we're connected. */
log_fn(inprogress?LOG_DEBUG:LOG_INFO, LD_NET,
"Connection to %s:%u %s (sock %d).",safe_str(address),port,
inprogress?"in progress":"established",s);
"Connection to %s:%u %s (sock %d).",escaped_safe_str(address),
port, inprogress?"in progress":"established", s);
conn->s = s;
if (connection_add(conn) < 0) /* no space, forget it */
return -1;
......
......@@ -281,7 +281,7 @@ connection_edge_finished_connecting(connection_t *conn)
in.s_addr = htonl(conn->addr);
tor_inet_ntoa(&in,valbuf,sizeof(valbuf));
log_info(LD_EXIT,"Exit connection to %s:%u (%s) established.",
safe_str(conn->address),conn->port,safe_str(valbuf));
escaped_safe_str(conn->address),conn->port,safe_str(valbuf));
conn->state = EXIT_CONN_STATE_OPEN;
connection_watch_events(conn, EV_READ); /* stop writing, continue reading */
......@@ -1533,6 +1533,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
tor_free(address);
return 0;
}
#if 0
if (!tor_strisprint(address)) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Non-printing characters in address %s in relay "
......@@ -1540,6 +1541,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
tor_free(address);
return 0;
}
#endif
log_debug(LD_EXIT,"Creating new exit connection.");
n_stream = connection_new(CONN_TYPE_EXIT);
......@@ -1685,7 +1687,7 @@ connection_exit_connect(connection_t *conn)
if (!connection_edge_is_rendezvous_stream(conn) &&
router_compare_to_my_exit_policy(conn)) {
log_info(LD_EXIT,"%s:%d failed exit policy. Closing.",
safe_str(conn->address), conn->port);
escaped_safe_str(conn->address), conn->port);
connection_edge_end(conn, END_STREAM_REASON_EXITPOLICY, conn->cpath_layer);
circuit_detach_stream(circuit_get_by_edge_conn(conn), conn);
connection_free(conn);
......@@ -1707,7 +1709,7 @@ connection_exit_connect(connection_t *conn)
in.s_addr = htonl(addr);
tor_inet_ntoa(&in, tmpbuf, sizeof(tmpbuf));
log_debug(LD_EXIT, "Redirecting connection from %s:%d to %s:%d",
safe_str(conn->address), conn->port,
escaped_safe_str(conn->address), conn->port,
safe_str(tmpbuf), port);
}
break;
......
......@@ -162,11 +162,12 @@ purge_expired_resolves(uint32_t now)
resolve = oldest_cached_resolve;
log_debug(LD_EXIT,
"Forgetting old cached resolve (address %s, expires %lu)",
safe_str(resolve->address), (unsigned long)resolve->expire);
escaped_safe_str(resolve->address),
(unsigned long)resolve->expire);
if (resolve->state == CACHE_STATE_PENDING) {
log_debug(LD_EXIT,
"Bug: Expiring a dns resolve ('%s') that's still pending."
" Forgot to cull it?", safe_str(resolve->address));
"Bug: Expiring a dns resolve %s that's still pending."
" Forgot to cull it?", escaped_safe_str(resolve->address));
tor_fragile_assert();
}
if (resolve->pending_connections) {
......@@ -300,20 +301,20 @@ dns_resolve(connection_t *exitconn)
pending_connection->next = resolve->pending_connections;
resolve->pending_connections = pending_connection;
log_debug(LD_EXIT,"Connection (fd %d) waiting for pending DNS "
"resolve of '%s'",
exitconn->s, safe_str(exitconn->address));
"resolve of %s",
exitconn->s, escaped_safe_str(exitconn->address));
exitconn->state = EXIT_CONN_STATE_RESOLVING;
return 0;
case CACHE_STATE_VALID:
exitconn->addr = resolve->addr;
log_debug(LD_EXIT,"Connection (fd %d) found cached answer for '%s'",
exitconn->s, safe_str(exitconn->address));
log_debug(LD_EXIT,"Connection (fd %d) found cached answer for %s",
exitconn->s, escaped_safe_str(exitconn->address));
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_IPV4);
return 1;
case CACHE_STATE_FAILED:
log_debug(LD_EXIT,"Connection (fd %d) found cached error for '%s'",
exitconn->s, safe_str(exitconn->address));
log_debug(LD_EXIT,"Connection (fd %d) found cached error for %s",
exitconn->s, escaped_safe_str(exitconn->address));
if (exitconn->purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, RESOLVED_TYPE_ERROR);
circ = circuit_get_by_edge_conn(exitconn);
......@@ -369,9 +370,9 @@ assign_to_dnsworker(connection_t *exitconn)
}
log_debug(LD_EXIT,
"Connection (fd %d) needs to resolve '%s'; assigning "
"to DNSWorker (fd %d)",
exitconn->s, safe_str(exitconn->address), dnsconn->s);
"Connection (fd %d) needs to resolve %s; assigning "
"to DNSWorker (fd %d)", exitconn->s,
escaped_safe_str(exitconn->address), dnsconn->s);
tor_free(dnsconn->address);
dnsconn->address = tor_strdup(exitconn->address);
......@@ -404,9 +405,8 @@ connection_dns_remove(connection_t *conn)
resolve = HT_FIND(cache_map, &cache_root, &search);
if (!resolve) {
/* XXXX RD This *is* a bug, right? -NM */
log_notice(LD_BUG, "Address '%s' is not pending. Dropping.",
safe_str(conn->address));
log_notice(LD_BUG, "Address %s is not pending. Dropping.",
escaped_safe_str(conn->address));
return;
}
......@@ -419,8 +419,8 @@ connection_dns_remove(connection_t *conn)
resolve->pending_connections = pend->next;
tor_free(pend);
log_debug(LD_EXIT, "First connection (fd %d) no longer waiting "
"for resolve of '%s'",
conn->s, safe_str(conn->address));
"for resolve of %s",
conn->s, escaped_safe_str(conn->address));
return;
} else {
for ( ; pend->next; pend = pend->next) {
......@@ -429,8 +429,8 @@ connection_dns_remove(connection_t *conn)
pend->next = victim->next;
tor_free(victim);
log_debug(LD_EXIT,
"Connection (fd %d) no longer waiting for resolve of '%s'",
conn->s, safe_str(conn->address));
"Connection (fd %d) no longer waiting for resolve of %s",
conn->s, escaped_safe_str(conn->address));
return; /* more are pending */
}
}
......@@ -491,17 +491,16 @@ dns_cancel_pending_resolve(char *address)
resolve = HT_FIND(cache_map, &cache_root, &search);
if (!resolve) {
/* XXXX RD This *is* a bug, right? -NM */
log_notice(LD_BUG,"Address '%s' is not pending. Dropping.",
safe_str(address));
log_notice(LD_BUG,"Address %s is not pending. Dropping.",
escaped_safe_str(address));
return;
}
if (!resolve->pending_connections) {
/* XXX this should never trigger, but sometimes it does */
log_warn(LD_BUG,
"Bug: Address '%s' is pending but has no pending connections!",
safe_str(address));
"Bug: Address %s is pending but has no pending connections!",
escaped_safe_str(address));
tor_fragile_assert();
return;
}
......@@ -509,8 +508,8 @@ dns_cancel_pending_resolve(char *address)
/* mark all pending connections to fail */
log_debug(LD_EXIT,
"Failing all connections waiting on DNS resolve of '%s'",
safe_str(address));
"Failing all connections waiting on DNS resolve of %s",
escaped_safe_str(address));
while (resolve->pending_connections) {
pend = resolve->pending_connections;
pend->conn->state = EXIT_CONN_STATE_RESOLVEFAILED;
......@@ -581,8 +580,8 @@ dns_found_answer(char *address, uint32_t addr, char outcome)
resolve = HT_FIND(cache_map, &cache_root, &search);
if (!resolve) {
log_info(LD_EXIT,"Resolved unasked address '%s'; caching anyway.",
safe_str(address));
log_info(LD_EXIT,"Resolved unasked address %s; caching anyway.",
escaped_safe_str(address));
resolve = tor_malloc_zero(sizeof(cached_resolve_t));
resolve->state = (outcome == DNS_RESOLVE_SUCCEEDED) ?
CACHE_STATE_VALID : CACHE_STATE_FAILED;
......@@ -595,8 +594,8 @@ dns_found_answer(char *address, uint32_t addr, char outcome)
if (resolve->state != CACHE_STATE_PENDING) {
/* XXXX Maybe update addr? or check addr for consistency? Or let
* VALID replace FAILED? */
log_notice(LD_EXIT, "Resolved '%s' which was already resolved; ignoring",
safe_str(address));
log_notice(LD_EXIT, "Resolved %s which was already resolved; ignoring",
escaped_safe_str(address));
tor_assert(resolve->pending_connections == NULL);
return;
}
......@@ -715,8 +714,8 @@ connection_dns_process_inbuf(connection_t *conn)
if (conn->state != DNSWORKER_STATE_BUSY && buf_datalen(conn->inbuf)) {
log_warn(LD_BUG,
"Bug: read data (%d bytes) from an idle dns worker (fd %d, "
"address '%s'). Please report.",
(int)buf_datalen(conn->inbuf), conn->s, safe_str(conn->address));
"address %s). Please report.", (int)buf_datalen(conn->inbuf),
conn->s, escaped_safe_str(conn->address));
tor_fragile_assert();
/* Pull it off the buffer anyway, or it will just stay there.
......@@ -738,8 +737,8 @@ connection_dns_process_inbuf(connection_t *conn)
connection_fetch_from_buf(&success,1,conn);
connection_fetch_from_buf((char *)&addr,sizeof(uint32_t),conn);
log_debug(LD_EXIT, "DNSWorker (fd %d) returned answer for '%s'",
conn->s, safe_str(conn->address));
log_debug(LD_EXIT, "DNSWorker (fd %d) returned answer for %s",
conn->s, escaped_safe_str(conn->address));
tor_assert(success >= DNS_RESOLVE_FAILED_TRANSIENT);
tor_assert(success <= DNS_RESOLVE_SUCCEEDED);
......@@ -796,6 +795,7 @@ dnsworker_main(void *data)
{
char address[MAX_ADDRESSLEN];
unsigned char address_len;
char *log_address;
char answer[5];
uint32_t ip;
int *fdarray = data;
......@@ -840,6 +840,7 @@ dnsworker_main(void *data)
}
address[address_len] = 0; /* null terminate it */
log_address = esc_for_log(safe_str(address));
result = tor_lookup_hostname(address, &ip);
/* Make 0.0.0.0 an error, so that we can use "0" to mean "no addr") */
if (!ip)
......@@ -848,19 +849,20 @@ dnsworker_main(void *data)
case 1:
/* XXX result can never be 1, because we set it to -1 above on error */
log_info(LD_NET,"Could not resolve dest addr %s (transient).",
safe_str(address));
log_address);
answer[0] = DNS_RESOLVE_FAILED_TRANSIENT;
break;
case -1:
log_info(LD_NET,"Could not resolve dest addr %s (permanent).",
safe_str(address));
log_address);
answer[0] = DNS_RESOLVE_FAILED_PERMANENT;
break;
case 0:
log_info(LD_NET,"Resolved address '%s'.",safe_str(address));
log_info(LD_NET,"Resolved address %s.", log_address);
answer[0] = DNS_RESOLVE_SUCCEEDED;
break;
}
tor_free(log_address);
set_uint32(answer+1, ip);
if (write_all(fd, answer, 5, 1) != 5) {
log_err(LD_NET,"writing answer failed. Child exiting.");
......
......@@ -479,8 +479,8 @@ conn_close_if_marked(int i)
log_info(LD_NET,
"Conn (addr %s, fd %d, type %s, state %d) marked, but wants "
"to flush %d bytes. (Marked at %s:%d)",
conn->address, conn->s, conn_type_to_string(conn->type),
conn->state,
escaped_safe_str(conn->address),
conn->s, conn_type_to_string(conn->type), conn->state,
(int)conn->outbuf_flushlen,
conn->marked_for_close_file, conn->marked_for_close);
if (connection_speaks_cells(conn)) {
......@@ -514,8 +514,8 @@ conn_close_if_marked(int i)
"We tried to write %d bytes to addr %s (fd %d, type %s, state %d)"
" but timed out. (Marked at %s:%d)",
(int)buf_datalen(conn->outbuf),
safe_str(conn->address), conn->s, conn_type_to_string(conn->type),
conn->state,
escaped_safe_str(conn->address), conn->s,
conn_type_to_string(conn->type), conn->state,
conn->marked_for_close_file,
conn->marked_for_close);
}
......@@ -1346,7 +1346,8 @@ dumpstats(int severity)
(int)(now - conn->timestamp_created));
if (!connection_is_listener(conn)) {
log(severity,LD_GENERAL,
"Conn %d is to '%s:%d'.",i,safe_str(conn->address), conn->port);
"Conn %d is to '%s:%d'.", i,
escaped_safe_str(conn->address), conn->port);
log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
i,
......
......@@ -1020,7 +1020,7 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
}
if (tor_inet_aton(tok->args[5], &in) == 0) {
log_warn(LD_DIR, "Error parsing address '%s'", escaped(tok->args[5]));
log_warn(LD_DIR, "Error parsing address %s", escaped(tok->args[5]));
goto err;
}
rs->addr = ntohl(in.s_addr);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment