summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-10-01 20:50:11 +0000
committerNick Mathewson <nickm@torproject.org>2006-10-01 20:50:11 +0000
commitce72a9914e5e996f3c47cc9ec368309e0f1c861e (patch)
tree785572be5289ef84e5f846007a62713494d4ea68 /src/or
parent7ed921708f94b23653a65173a5b61ddeff6e9125 (diff)
downloadtor-ce72a9914e5e996f3c47cc9ec368309e0f1c861e.tar.gz
tor-ce72a9914e5e996f3c47cc9ec368309e0f1c861e.zip
r8822@totoro: nickm | 2006-10-01 16:24:22 -0400
Fix bug 303: reject attempts to use Tor as a one-hop proxy. svn:r8566
Diffstat (limited to 'src/or')
-rw-r--r--src/or/circuitbuild.c2
-rw-r--r--src/or/circuitlist.c15
-rw-r--r--src/or/connection_edge.c9
-rw-r--r--src/or/control.c10
-rw-r--r--src/or/or.h8
5 files changed, 42 insertions, 2 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 23bcf4e4ad..586a6704a6 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -925,6 +925,8 @@ onionskin_answer(or_circuit_t *circ, uint8_t cell_type, char *payload,
else
memcpy(circ->handshake_digest, cell.payload+DIGEST_LEN, DIGEST_LEN);
+ circ->is_first_hop = (cell_type == CELL_CREATED_FAST);
+
connection_or_write_cell_to_buf(&cell, circ->p_conn);
log_debug(LD_CIRC,"Finished sending 'created' cell.");
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index dba7864861..8efe199f70 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -770,6 +770,21 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
return best;
}
+/** Return the number of hops in circuit's path. */
+int
+circuit_get_cpath_len(origin_circuit_t *circ)
+{
+ int n = 0;
+ if (circ && circ->cpath) {
+ crypt_path_t *cpath, *cpath_next = NULL;
+ for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
+ cpath_next = cpath->next;
+ ++n;
+ }
+ }
+ return n;
+}
+
/** Go through the circuitlist; mark-for-close each circuit that starts
* at us but has not yet been used. */
void
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index c02999affb..9692edaadc 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1877,6 +1877,15 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
return 0;
}
#endif
+ if (!CIRCUIT_IS_ORIGIN(circ) && TO_OR_CIRCUIT(circ)->is_first_hop) {
+ /* Don't let clients use us as a single-hop proxy; it attracts attackers
+ * and users who'd be better off with, well, single-hop proxies.
+ */
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Attempt to open a stream on first hop of circuit. Rejecting.");
+ tor_free(address);
+ return 0;
+ }
} else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
or_options_t *options = get_options();
address = tor_strdup("127.0.0.1");
diff --git a/src/or/control.c b/src/or/control.c
index d479c06003..d75a4e47a6 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1997,6 +1997,16 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
conn);
return 0;
}
+ if (circ && circuit_get_cpath_len(circ) < 2) {
+ if (STATE_IS_V0(conn->_base.state))
+ send_control0_error(conn, ERR_INTERNAL,
+ "Refuse to attach stream to one-hop circuit.");
+ else
+ connection_write_str_to_buf(
+ "551 Can't attach stream to one-hop circuit.\r\n",
+ conn);
+ return 0;
+ }
if (connection_ap_handshake_rewrite_and_attach(ap_conn, circ) < 0) {
if (STATE_IS_V0(conn->_base.state))
send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
diff --git a/src/or/or.h b/src/or/or.h
index 0cce2b592f..f434f53098 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1232,8 +1232,6 @@ typedef struct origin_circuit_t {
* for this circuit. This includes ciphers for each hop,
* integrity-checking digests for each hop, and package/delivery
* windows for each hop.
- *
- * The cpath field is defined only when we are the circuit's origin.
*/
crypt_path_t *cpath;
@@ -1307,10 +1305,15 @@ typedef struct or_circuit_t {
/** A hash of location-hidden service's PK if purpose is INTRO_POINT, or a
* rendezvous cookie if purpose is REND_POINT_WAITING. Filled with zeroes
* otherwise.
+ * ???? move to a subtype or adjunct structure? Wastes 20 bytes. -NM
*/
char rend_token[REND_TOKEN_LEN];
+ /* ???? move to a subtype or adjunct structure? Wastes 20 bytes -NM */
char handshake_digest[DIGEST_LEN]; /**< Stores KH for the handshake. */
+
+ /** True iff this circuit was made with a CREATE_FAST cell. */
+ unsigned int is_first_hop : 1;
} or_circuit_t;
/** Convert a circuit subtype to a circuit_t.*/
@@ -1751,6 +1754,7 @@ void circuit_mark_all_unused_circs(void);
void circuit_expire_all_dirty_circs(void);
void _circuit_mark_for_close(circuit_t *circ, int reason,
int line, const char *file);
+int circuit_get_cpath_len(origin_circuit_t *circ);
#define circuit_mark_for_close(c, reason) \
_circuit_mark_for_close((c), (reason), __LINE__, _SHORT_FILE_)