[or-cvs] r12623: Add support to get a callback invoked when the client renego (in tor/trunk: . doc src/common src/or)
nickm at seul.org
nickm at seul.org
Sat Dec 1 08:09:49 UTC 2007
Author: nickm
Date: 2007-12-01 03:09:48 -0500 (Sat, 01 Dec 2007)
New Revision: 12623
Modified:
tor/trunk/
tor/trunk/doc/TODO
tor/trunk/src/common/tortls.c
tor/trunk/src/common/tortls.h
tor/trunk/src/or/connection.c
tor/trunk/src/or/connection_or.c
tor/trunk/src/or/or.h
Log:
r15088 at tombo: nickm | 2007-11-30 23:47:29 -0500
Add support to get a callback invoked when the client renegotiate a connection. Also, make clients renegotiate. (not enabled yet, until they detect that the server acted like a v2 server)
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r15088] on d9e39d38-0f13-419c-a857-e10a0ce2aa0c
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/doc/TODO 2007-12-01 08:09:48 UTC (rev 12623)
@@ -39,7 +39,7 @@
- Clients only send certificates when asked for them.
o Servers disable callback once negotiation is finished, so
that renegotiation happens according to the old rules.
- - Clients initiate renegotiation immediately on completing
+ o Clients initiate renegotiation immediately on completing
a v2 connection.
- Servers detect renegotiation, and if there is now a client
cert, they adust the client ID.
Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/common/tortls.c 2007-12-01 08:09:48 UTC (rev 12623)
@@ -70,6 +70,8 @@
* time. */
unsigned long last_write_count;
unsigned long last_read_count;
+ void (*negotiated_callback)(tor_tls_t *tls, void *arg);
+ void *callback_arg;
};
static void tor_tls_context_decref(tor_tls_context_t *ctx);
@@ -606,6 +608,16 @@
return result;
}
+/**DOCDOC*/
+void
+tor_tls_set_renegotiate_callback(tor_tls_t *tls,
+ void (*cb)(tor_tls_t *, void *arg),
+ void *arg)
+{
+ tls->negotiated_callback = cb;
+ tls->callback_arg = arg;
+}
+
/** Return whether this tls initiated the connect (client) or
* received it (server). */
int
@@ -624,6 +636,7 @@
tor_assert(tls && tls->ssl);
SSL_free(tls->ssl);
tls->ssl = NULL;
+ tls->negotiated_callback = NULL;
if (tls->context)
tor_tls_context_decref(tls->context);
tor_free(tls);
@@ -648,7 +661,8 @@
tls->hadCert = 1;
/* New certificate! */
log_info(LD_NET, "Got a TLS renegotiation.");
- /* XXXX020 call some kind of 'there was a renegotiation' callback. */
+ if (tls->negotiated_callback)
+ tls->negotiated_callback(tls, tls->callback_arg);
}
#endif
return r;
Modified: tor/trunk/src/common/tortls.h
===================================================================
--- tor/trunk/src/common/tortls.h 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/common/tortls.h 2007-12-01 08:09:48 UTC (rev 12623)
@@ -52,6 +52,9 @@
int tor_tls_context_new(crypto_pk_env_t *rsa,
const char *nickname, unsigned int key_lifetime);
tor_tls_t *tor_tls_new(int sock, int is_server);
+void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
+ void (*cb)(tor_tls_t *, void *arg),
+ void *arg);
int tor_tls_is_server(tor_tls_t *tls);
void tor_tls_free(tor_tls_t *tls);
int tor_tls_peer_has_cert(tor_tls_t *tls);
Modified: tor/trunk/src/or/connection.c
===================================================================
--- tor/trunk/src/or/connection.c 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/connection.c 2007-12-01 08:09:48 UTC (rev 12623)
@@ -89,6 +89,7 @@
case OR_CONN_STATE_PROXY_FLUSHING: return "proxy flushing";
case OR_CONN_STATE_PROXY_READING: return "proxy reading";
case OR_CONN_STATE_TLS_HANDSHAKING: return "handshaking (TLS)";
+ case OR_CONN_STATE_TLS_RENEGOTIATING: return "renegotiating (TLS)";
case OR_CONN_STATE_OR_HANDSHAKING: return "handshaking (Tor)";
case OR_CONN_STATE_OPEN: return "open";
}
@@ -1893,7 +1894,8 @@
conn->state > OR_CONN_STATE_PROXY_READING) {
int pending;
or_connection_t *or_conn = TO_OR_CONN(conn);
- if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
+ if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
+ conn->state == OR_CONN_STATE_TLS_RENEGOTIATING) {
/* continue handshaking even if global token bucket is empty */
return connection_tls_continue_handshake(or_conn);
}
@@ -2115,7 +2117,8 @@
if (connection_speaks_cells(conn) &&
conn->state > OR_CONN_STATE_PROXY_READING) {
or_connection_t *or_conn = TO_OR_CONN(conn);
- if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING) {
+ if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
+ conn->state == OR_CONN_STATE_TLS_RENEGOTIATING) {
connection_stop_writing(conn);
if (connection_tls_continue_handshake(or_conn) < 0) {
/* Don't flush; connection is dead. */
Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/connection_or.c 2007-12-01 08:09:48 UTC (rev 12623)
@@ -583,13 +583,23 @@
{
int result;
check_no_tls_errors();
- result = tor_tls_handshake(conn->tls);
+ again:
+ if (conn->_base.state == OR_CONN_STATE_TLS_RENEGOTIATING)
+ result = tor_tls_renegotiate(conn->tls);
+ else
+ result = tor_tls_handshake(conn->tls);
switch (result) {
CASE_TOR_TLS_ERROR_ANY:
log_info(LD_OR,"tls error [%s]. breaking connection.",
tor_tls_err_to_string(result));
return -1;
case TOR_TLS_DONE:
+ if (!tor_tls_is_server(conn->tls) &&
+ !tor_tls_used_v1_handshake(conn->tls) &&
+ conn->_base.state == OR_CONN_STATE_TLS_HANDSHAKING) {
+ conn->_base.state = OR_CONN_STATE_TLS_RENEGOTIATING;
+ goto again;
+ }
return connection_tls_finish_handshake(conn);
case TOR_TLS_WANTWRITE:
connection_start_writing(TO_CONN(conn));
@@ -652,16 +662,9 @@
const char *safe_address =
started_here ? conn->_base.address : safe_str(conn->_base.address);
const char *conn_type = started_here ? "outgoing" : "incoming";
- int has_cert = 0, has_identity = 0;
- int v1 = (conn->link_proto == 1);
+ int has_cert = 0, has_identity=0;
check_no_tls_errors();
- if (v1) {
- has_cert = tor_tls_peer_has_cert(conn->tls);
- } else {
- tor_assert(conn->handshake_state);
- has_cert = !tor_digest_is_zero(conn->handshake_state->cert_id_digest);
- }
has_cert = tor_tls_peer_has_cert(conn->tls);
if (started_here && !has_cert) {
log_info(LD_PROTOCOL,"Tried connecting to router at %s:%d, but it didn't "
@@ -674,33 +677,26 @@
}
check_no_tls_errors();
- if (v1) {
- if (has_cert) {
- int v = tor_tls_verify_v1(started_here?severity:LOG_INFO,
- conn->tls, &identity_rcvd);
- if (started_here && v<0) {
- log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
- " has a cert but it's invalid. Closing.",
- safe_address, conn->_base.port);
+ if (has_cert) {
+ int v = tor_tls_verify_v1(started_here?severity:LOG_INFO,
+ conn->tls, &identity_rcvd);
+ if (started_here && v<0) {
+ log_fn(severity,LD_OR,"Tried connecting to router at %s:%d: It"
+ " has a cert but it's invalid. Closing.",
+ safe_address, conn->_base.port);
return -1;
- } else if (v<0) {
- log_info(LD_PROTOCOL,"Incoming connection gave us an invalid cert "
- "chain; ignoring.");
- } else {
- log_debug(LD_OR,"The certificate seems to be valid on %s connection "
- "with %s:%d", conn_type, safe_address, conn->_base.port);
- }
- check_no_tls_errors();
+ } else if (v<0) {
+ log_info(LD_PROTOCOL,"Incoming connection gave us an invalid cert "
+ "chain; ignoring.");
+ } else {
+ log_debug(LD_OR,"The certificate seems to be valid on %s connection "
+ "with %s:%d", conn_type, safe_address, conn->_base.port);
}
- } else {
- if (conn->handshake_state->authenticated &&
- conn->handshake_state->identity_key) {
- identity_rcvd = crypto_pk_dup_key(conn->handshake_state->identity_key);
- }
+ check_no_tls_errors();
}
if (identity_rcvd) {
- has_identity=1;
+ has_identity = 1;
crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd)<0) {
conn->circ_id_type = CIRC_ID_TYPE_LOWER;
@@ -759,6 +755,7 @@
return 0;
}
+#if 0
/** DOCDOC */
int
connection_or_finish_or_handshake(or_connection_t *conn)
@@ -781,6 +778,7 @@
return -1;
return connection_or_set_state_open(conn);
}
+#endif
/** The tls handshake is finished.
*
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2007-12-01 08:09:46 UTC (rev 12622)
+++ tor/trunk/src/or/or.h 2007-12-01 08:09:48 UTC (rev 12623)
@@ -236,13 +236,15 @@
#define OR_CONN_STATE_PROXY_READING 3
/** State for a connection to an OR: SSL is handshaking, not done yet. */
#define OR_CONN_STATE_TLS_HANDSHAKING 4
+/** DOCDOC */
+#define OR_CONN_STATE_TLS_RENEGOTIATING 5
/** State for a connection to an OR: We're done with our SSL handshake, but we
* haven't yet negotiated link protocol versions and finished authenticating.
*/
-#define OR_CONN_STATE_OR_HANDSHAKING 5
+#define OR_CONN_STATE_OR_HANDSHAKING 6
/** State for a connection to an OR: Ready to send/receive cells. */
-#define OR_CONN_STATE_OPEN 6
-#define _OR_CONN_STATE_MAX 6
+#define OR_CONN_STATE_OPEN 7
+#define _OR_CONN_STATE_MAX 7
#define _EXIT_CONN_STATE_MIN 1
/** State for an exit connection: waiting for response from dns farm. */
@@ -924,6 +926,7 @@
* connection, which half of the space should
* we use? */
unsigned int is_canonical:1; /**< DOCDOC */
+ unsigned int have_renegotiated:1; /**DOCDOC */
uint8_t link_proto; /**< What protocol version are we using? 0 for
* "none negotiated yet." */
uint16_t next_circ_id; /**< Which circ_id do we try to use next on
@@ -2775,7 +2778,9 @@
int connection_or_flushed_some(or_connection_t *conn);
int connection_or_finished_flushing(or_connection_t *conn);
int connection_or_finished_connecting(or_connection_t *conn);
+#if 0
int connection_or_finish_or_handshake(or_connection_t *conn);
+#endif
or_connection_t *connection_or_connect(uint32_t addr, uint16_t port,
const char *id_digest);
More information about the tor-commits
mailing list