mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
make connection_tls_finish_handshake() more plausible.
now we accept connections from unknown routers. svn:r2074
This commit is contained in:
parent
334de84cbe
commit
e547ab293b
@ -957,7 +957,7 @@ static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir)
|
||||
}
|
||||
|
||||
/** Allocate a cpath_build_state_t, populate it based on
|
||||
* <b>purpose</b> and <b>exit_nickname</b> (if specified), and
|
||||
* <b>purpose</b> and <b>exit_digest</b> (if specified), and
|
||||
* return it.
|
||||
*/
|
||||
static cpath_build_state_t *
|
||||
|
@ -941,7 +941,7 @@ int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
|
||||
if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE) {
|
||||
/* 0.0.7 servers and earlier don't support DNS resolution. There are no
|
||||
* ORs running code before 0.0.7, so we only worry about 0.0.7. Once all
|
||||
* servers are running 0.0.8, remove this check. */
|
||||
* servers are running 0.0.8, remove this check. XXX */
|
||||
return strncmp(exit->platform, "Tor 0.0.7", 9) ? 1 : 0;
|
||||
}
|
||||
addr = client_dns_lookup_entry(conn->socks_request->address);
|
||||
|
@ -245,6 +245,12 @@ int connection_tls_continue_handshake(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int digest_is_nonzero(const char *id) {
|
||||
char ZERO_DIGEST[DIGEST_LEN];
|
||||
memset(ZERO_DIGEST, 0, DIGEST_LEN);
|
||||
return !memcmp(ZERO_DIGEST, id, DIGEST_LEN);
|
||||
}
|
||||
|
||||
/** The tls handshake is finished.
|
||||
*
|
||||
* Make sure we are happy with the person we just handshaked with:
|
||||
@ -270,6 +276,7 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
char nickname[MAX_NICKNAME_LEN+1];
|
||||
connection_t *c;
|
||||
crypto_pk_env_t *identity_rcvd=NULL;
|
||||
char digest_rcvd[DIGEST_LEN];
|
||||
|
||||
conn->state = OR_CONN_STATE_OPEN;
|
||||
connection_watch_events(conn, POLLIN);
|
||||
@ -291,32 +298,24 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
}
|
||||
log_fn(LOG_DEBUG, "Other side (%s:%d) claims to be '%s'", conn->address,
|
||||
conn->port, nickname);
|
||||
router = router_get_by_nickname(nickname);
|
||||
/* XXX008 here we need to tolerate unknown routers, so ORs can
|
||||
* connect to us even when we don't know they're verified. This
|
||||
* should probably be a call to router_get_by_digest() now, since
|
||||
* we can't trust the nickname some guy shows up with. */
|
||||
if (!router) {
|
||||
log_fn(LOG_INFO, "Unrecognized router with nickname '%s' at %s:%d",
|
||||
nickname, conn->address, conn->port);
|
||||
return -1;
|
||||
}
|
||||
if(tor_tls_verify(conn->tls, &identity_rcvd)<0) {
|
||||
|
||||
if(tor_tls_verify(conn->tls, &identity_rcvd) < 0) {
|
||||
log_fn(LOG_WARN,"Other side '%s' (%s:%d) has a cert but it's invalid. Closing.",
|
||||
nickname, conn->address, conn->port);
|
||||
return -1;
|
||||
}
|
||||
log_fn(LOG_DEBUG,"The router's cert is valid.");
|
||||
if(crypto_pk_cmp_keys(identity_rcvd, router->identity_pkey) != 0) {
|
||||
crypto_free_pk_env(identity_rcvd);
|
||||
crypto_pk_get_digest(identity_rcvd, digest_rcvd);
|
||||
crypto_free_pk_env(identity_rcvd);
|
||||
|
||||
router = router_get_by_nickname(nickname);
|
||||
if(router && /* we know this nickname; make sure it's the right guy */
|
||||
memcmp(digest_rcvd, router->identity_digest, DIGEST_LEN) != 0) {
|
||||
log_fn(LOG_WARN, "Identity key not as expected for %s", nickname);
|
||||
return -1;
|
||||
}
|
||||
crypto_free_pk_env(identity_rcvd);
|
||||
|
||||
/* XXXX008 This isn't right; fix this one we launch by identity digest
|
||||
* XXXX008 rather than by nickname */
|
||||
if (conn->nickname) {
|
||||
if (digest_is_nonzero(conn->identity_digest)) {
|
||||
/* I initiated this connection. */
|
||||
if (strcasecmp(conn->nickname, nickname)) {
|
||||
log_fn(options.DirPort ? LOG_WARN : LOG_INFO,
|
||||
@ -325,11 +324,11 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if((c=connection_get_by_identity_digest(router->identity_digest, CONN_TYPE_OR))) {
|
||||
log_fn(LOG_INFO,"Router %s is already connected on fd %d. Dropping fd %d.", router->nickname, c->s, conn->s);
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
connection_or_init_conn_from_router(conn,router);
|
||||
connection_or_init_conn_from_address(conn,conn->addr,conn->port,digest_rcvd);
|
||||
}
|
||||
|
||||
if (!server_mode()) { /* If I'm an OP... */
|
||||
|
Loading…
Reference in New Issue
Block a user