From 67aa3b66c520183f7b195f9cdc63ffa19670688e Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Mon, 15 Nov 2004 07:50:15 +0000 Subject: [PATCH] clean up socks handling, refuse connections to port 0 svn:r2888 --- src/or/connection.c | 19 ++++++++++--------- src/or/connection_edge.c | 21 ++++++++++----------- src/or/relay.c | 1 - 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/or/connection.c b/src/or/connection.c index d1dbf0cfc8..ceadfb6ed5 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -180,6 +180,15 @@ void connection_free_all(void) { connection_free(carray[i]); } +/** Do any cleanup needed: + * - Directory conns that failed to fetch a rendezvous descriptor + * need to inform pending rendezvous streams. + * - OR conns need to call rep_hist_note_*() to record status. + * - AP conns need to send a socks reject if necessary. + * - Exit conns need to call connection_dns_remove() if necessary. + * - AP and Exit conns need to send an end cell if they can. + * - DNS conns need to fail any resolves that are pending on them. + */ void connection_about_to_close_connection(connection_t *conn) { @@ -268,15 +277,7 @@ void connection_close_immediate(connection_t *conn) } /** Mark conn to be closed next time we loop through - * conn_close_if_marked() in main.c. Do any cleanup needed: - * - Directory conns that fail to fetch a rendezvous descriptor need - * to inform pending rendezvous streams. - * - OR conns need to call rep_hist_note_*() to record status. - * - AP conns need to send a socks reject if necessary. - * - Exit conns need to call connection_dns_remove() if necessary. - * - AP and Exit conns need to send an end cell if they can. - * - DNS conns need to fail any resolves that are pending on them. - */ + * conn_close_if_marked() in main.c. */ int _connection_mark_for_close(connection_t *conn) { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 533c8c4242..e4fc159a9b 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -379,18 +379,14 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { uint32_t answer; /* Reply to resolves immediately if we can. */ if (strlen(socks->address) > RELAY_PAYLOAD_SIZE) { + log_fn(LOG_WARN,"Address to be resolved is too large. Failing."); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL); - conn->socks_request->has_finished = 1; - conn->has_sent_end = 1; - connection_mark_for_close(conn); - conn->hold_open_until_flushed = 1; - return 0; + return -1; } answer = htonl(client_dns_lookup_entry(socks->address)); if (answer) { connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4, (char*)&answer); - conn->socks_request->has_finished = 1; conn->has_sent_end = 1; connection_mark_for_close(conn); conn->hold_open_until_flushed = 1; @@ -401,6 +397,10 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { /* this call _modifies_ socks->address iff it's a hidden-service request */ if (rend_parse_rendezvous_address(socks->address) < 0) { /* normal request */ + if (socks->port == 0) { + log_fn(LOG_WARN,"Application asked to connect to port 0. Refusing."); + return -1; + } conn->state = AP_CONN_STATE_CIRCUIT_WAIT; return connection_ap_handshake_attach_circuit(conn); } else { @@ -411,12 +411,9 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { if (socks->command == SOCKS_COMMAND_RESOLVE) { /* if it's a resolve request, fail it right now, rather than * building all the circuits and then realizing it won't work. */ + log_fn(LOG_WARN,"Resolve requests to hidden services not allowed. Failing."); connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,0,NULL); - conn->socks_request->has_finished = 1; - conn->has_sent_end = 1; - connection_mark_for_close(conn); - conn->hold_open_until_flushed = 1; - return 0; + return -1; } strlcpy(conn->rend_query, socks->address, sizeof(conn->rend_query)); @@ -626,6 +623,7 @@ int connection_ap_make_bridge(char *address, uint16_t port) { return fd[1]; } +/* DOCDOC */ void connection_ap_handshake_socks_resolved(connection_t *conn, int answer_type, size_t answer_len, @@ -678,6 +676,7 @@ void connection_ap_handshake_socks_resolved(connection_t *conn, connection_ap_handshake_socks_reply(conn, buf, replylen, (answer_type == RESOLVED_TYPE_IPV4 || answer_type == RESOLVED_TYPE_IPV6) ? 1 : -1); + conn->socks_request->has_finished = 1; } /** Send a socks reply to stream conn, using the appropriate diff --git a/src/or/relay.c b/src/or/relay.c index 5de3c3efd6..5ce9eaa35e 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -613,7 +613,6 @@ connection_edge_process_relay_cell_not_open( cell->payload[RELAY_HEADER_SIZE], /*answer_type*/ cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/ cell->payload+RELAY_HEADER_SIZE+2); /* answer */ - conn->socks_request->has_finished = 1; conn->has_sent_end = 1; connection_mark_for_close(conn); conn->hold_open_until_flushed = 1;