mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
When we connect and finish TLS negotiation with address:port, it is obvious that any other key or nickname we might know about (as an authdirserver) does not actually exist at address:port.
svn:r4036
This commit is contained in:
@@ -498,7 +498,13 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
#endif
|
||||
|
||||
if (connection_or_nonopen_was_started_here(conn)) {
|
||||
/* I initiated this connection. */
|
||||
if (authdir_mode(options)) {
|
||||
/* We initiated this connection to address:port. Drop all routers
|
||||
* with the same address:port and a different key or nickname.
|
||||
*/
|
||||
dirserv_orconn_tls_done(conn->address, conn->port,
|
||||
digest_rcvd, nickname);
|
||||
}
|
||||
if (conn->nickname[0] == '$') {
|
||||
/* I was aiming for a particular digest. Did I get it? */
|
||||
char d[HEX_DIGEST_LEN+1];
|
||||
@@ -508,7 +514,6 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
"Identity key not as expected for router at %s:%d: wanted %s but got %s",
|
||||
conn->address, conn->port, conn->nickname, d);
|
||||
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
|
||||
// XXX if we're an authdir_mode, forget about nickname's descriptor
|
||||
return -1;
|
||||
}
|
||||
} else if (strcasecmp(conn->nickname, nickname)) {
|
||||
@@ -517,14 +522,8 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
"Other side (%s:%d) is '%s', but we tried to connect to '%s'",
|
||||
conn->address, conn->port, nickname, conn->nickname);
|
||||
control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
|
||||
// XXX if we're an authdir_mode, forget about nickname's descriptor
|
||||
return -1;
|
||||
}
|
||||
if (authdir_mode(options)) {
|
||||
/* I got exactly the guy I wanted. Now go through and blow away
|
||||
* descriptors for exactly this Address:ORPort that aren't this guy. */
|
||||
//XXX
|
||||
}
|
||||
} else {
|
||||
if ((c=connection_get_by_identity_digest(digest_rcvd, CONN_TYPE_OR))) {
|
||||
log_fn(LOG_INFO,"Router '%s' is already connected on fd %d. Dropping fd %d.", nickname, c->s, conn->s);
|
||||
|
||||
@@ -993,6 +993,53 @@ size_t dirserv_get_runningrouters(const char **rr, int compress)
|
||||
return compress ? the_runningrouters_z_len : the_runningrouters_len;
|
||||
}
|
||||
|
||||
/** Called when a TLS handshake has completed successfully with a
|
||||
* router listening at <b>address</b>:<b>or_port</b>, and has yielded
|
||||
* a certificate with digest <b>digest_rcvd</b> and nickname
|
||||
* <b>nickname_rcvd</b>. When this happens, it's clear that any other
|
||||
* descriptors for that address/port combination must be unusable:
|
||||
* delete them if they are not verified.
|
||||
*/
|
||||
void
|
||||
dirserv_orconn_tls_done(const char *address,
|
||||
uint16_t or_port,
|
||||
const char *digest_rcvd,
|
||||
const char *nickname_rcvd)
|
||||
{
|
||||
int i;
|
||||
tor_assert(address);
|
||||
tor_assert(digest_rcvd);
|
||||
tor_assert(nickname_rcvd);
|
||||
|
||||
if (!descriptor_list)
|
||||
return;
|
||||
|
||||
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
|
||||
routerinfo_t *ri = smartlist_get(descriptor_list, i);
|
||||
int drop = 0;
|
||||
if (ri->is_verified)
|
||||
continue;
|
||||
if (!strcasecmp(address, ri->address) &&
|
||||
or_port == ri->or_port) {
|
||||
/* We have a router at the same address! */
|
||||
if (strcasecmp(ri->nickname, nickname_rcvd)) {
|
||||
log_fn(LOG_WARN, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
|
||||
ri->nickname, nickname_rcvd, address, or_port);
|
||||
drop = 1;
|
||||
} else if (memcmp(ri->identity_digest, digest_rcvd, DIGEST_LEN)) {
|
||||
log_fn(LOG_WARN, "Dropping descriptor: identity key does not match key in cert from %s:%d",
|
||||
address, or_port);
|
||||
drop = 1;
|
||||
}
|
||||
if (drop) {
|
||||
routerinfo_free(ri);
|
||||
smartlist_del(descriptor_list, i--);
|
||||
directory_set_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dirserv_free_all(void)
|
||||
{
|
||||
|
||||
@@ -1480,6 +1480,10 @@ size_t dirserv_get_directory(const char **cp, int compress);
|
||||
size_t dirserv_get_runningrouters(const char **rr, int compress);
|
||||
void dirserv_set_cached_directory(const char *directory, time_t when,
|
||||
int is_running_routers);
|
||||
void dirserv_orconn_tls_done(const char *address,
|
||||
uint16_t or_port,
|
||||
const char *digest_rcvd,
|
||||
const char *nickname);
|
||||
void dirserv_free_all(void);
|
||||
|
||||
/********************************* dns.c ***************************/
|
||||
|
||||
Reference in New Issue
Block a user