diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-11-14 20:01:12 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-11-14 20:01:12 +0000 |
commit | d483d3144aa20b316578a37cf6a8b74343ca7dba (patch) | |
tree | 70b867f30db38a077e466775dd2008326d047564 /src/or/command.c | |
parent | bbb34846b4df194e25304a84a3fe95634e01bc0d (diff) | |
download | tor-d483d3144aa20b316578a37cf6a8b74343ca7dba.tar.gz tor-d483d3144aa20b316578a37cf6a8b74343ca7dba.zip |
r16669@catbus: nickm | 2007-11-14 14:50:03 -0500
When we complete an OR handshake, set up all the internal fields and mark the connection as open.
svn:r12495
Diffstat (limited to 'src/or/command.c')
-rw-r--r-- | src/or/command.c | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/src/or/command.c b/src/or/command.c index 8e8aa4abdc..9dc8408a87 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -475,18 +475,20 @@ command_process_versions_cell(var_cell_t *cell, or_connection_t *conn) } if (!highest_supported_version) { log_fn(LOG_PROTOCOL_WARN, LD_OR, - "Couldn't find a version in common; defaulting to v1."); - /*XXXX020 just break the connection! */ - conn->link_proto = 1; + "Couldn't find a version in common between my version list and the " + "list in the VERSIONS cell; closing connection."); + connection_mark_for_close(TO_CONN(conn)); return; } conn->link_proto = highest_supported_version; conn->handshake_state->received_versions = 1; if (highest_supported_version >= 2) { - /*XXXX020 check return values. */ - connection_or_send_netinfo(conn); - connection_or_send_cert(conn); + if (connection_or_send_netinfo(conn) < 0 || + connection_or_send_cert(conn) < 0) { + connection_mark_for_close(TO_CONN(conn)); + return; + } if (conn->handshake_state->started_here) connection_or_send_link_auth(conn); } else { @@ -536,8 +538,8 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) cp = cell->payload + 6 + my_addr_len; if (cp >= end) { log_fn(LOG_PROTOCOL_WARN, LD_OR, - "Address too long in netinfo cell; dropping."); - /*XXXX020 reject and break OR conn! */ + "Addresses too long in netinfo cell; closing connection."); + connection_mark_for_close(TO_CONN(conn)); return; } else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) { conn->handshake_state->my_apparent_addr = ntohl(get_uint32(my_addr_ptr)); @@ -549,8 +551,12 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) * "canonical." */ uint8_t other_addr_type = (uint8_t) *cp++; uint8_t other_addr_len = (uint8_t) *cp++; - if (cp + other_addr_len >= end) - break; /*XXXX020 protocol warn. */ + if (cp + other_addr_len >= end) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Address too long in netinfo cell; closing connection."); + connection_mark_for_close(TO_CONN(conn)); + return; + } if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) { uint32_t addr = ntohl(get_uint32(cp)); if (addr == conn->real_addr) { @@ -568,12 +574,12 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) /*XXXX020 move to connection_or.c */ /** DOCDOC Called when we're done authenticating; act on stuff we * learned in netinfo. */ -void +int connection_or_act_on_netinfo(or_connection_t *conn) { long delta; if (!conn->handshake_state) - return; + return -1; tor_assert(conn->handshake_state->authenticated != 0); @@ -601,6 +607,8 @@ connection_or_act_on_netinfo(or_connection_t *conn) if (conn->handshake_state->apparently_canonical) { conn->is_canonical = 1; } + + return 0; } /*DOCDOC*/ @@ -611,16 +619,25 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn) uint16_t conn_cert_len = 0, id_cert_len = 0; const char *conn_cert = NULL, *id_cert = NULL; const char *cp, *end; - int authenticated = 0; + int done = 0; - /*XXXX020 log messages*/ - if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) - goto err; + if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got CERT cell when not handshaking. " + "Ignoring."); + return; + } tor_assert(conn->handshake_state); if (!conn->handshake_state->received_versions || - !conn->handshake_state->received_netinfo || - conn->handshake_state->received_certs) + !conn->handshake_state->received_netinfo) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got CERT cell before VERSIONS and " + "NETINFO. Closing the connection."); + goto err; + } + if (conn->handshake_state->received_certs) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got duplicate CERT cell. " + "Closing the connection."); goto err; + } cp = cell->payload; end = cell->payload + cell->payload_len; @@ -651,6 +668,7 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn) /* Now we have 0, 1, or 2 certs. */ if (n_certs == 0) { /* The other side is unauthenticated. */ + done = 1; } else { int r; r = tor_tls_verify_certs_v2(LOG_PROTOCOL_WARN, conn->tls, @@ -660,23 +678,27 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn) (conn->handshake_state->started_here ? conn->handshake_state->server_cert_digest : conn->handshake_state->client_cert_digest), + &conn->handshake_state->identity_key, conn->handshake_state->cert_id_digest); if (r < 0) goto err; - if (r == 1) - authenticated = 1; + if (r == 1) { + done = 1; + conn->handshake_state->authenticated = 1; + } } conn->handshake_state->received_certs = 1; - if (authenticated) { - /* XXXX020 make the connection open. */ + if (done) { + if (connection_or_finish_or_handshake(conn) < 0) + goto err; } if (! conn->handshake_state->signing_key) goto err; return; err: - /*XXXX020 close the connection */; + connection_mark_for_close(TO_CONN(conn)); } #define LINK_AUTH_STRING "Tor initiator certificate verification" @@ -746,11 +768,12 @@ command_process_link_auth_cell(cell_t *cell, or_connection_t *conn) goto err; } - /* Okay, we're authenticated. */ s->authenticated = 1; - /* XXXX020 act on being authenticated: Open the connection. */ + if (connection_or_finish_or_handshake(conn)<0) + goto err; + tor_free(checked); return; err: tor_free(checked); |