Back to index

tor  0.2.3.18-rc
command.c
Go to the documentation of this file.
00001 /* Copyright (c) 2001 Matej Pfajfar.
00002  * Copyright (c) 2001-2004, Roger Dingledine.
00003  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
00004  * Copyright (c) 2007-2012, The Tor Project, Inc. */
00005 /* See LICENSE for licensing information */
00006 
00012 /* In-points to command.c:
00013  *
00014  * - command_process_cell(), called from
00015  *   connection_or_process_cells_from_inbuf() in connection_or.c
00016  */
00017 
00018 #include "or.h"
00019 #include "circuitbuild.h"
00020 #include "circuitlist.h"
00021 #include "command.h"
00022 #include "connection.h"
00023 #include "connection_or.h"
00024 #include "config.h"
00025 #include "control.h"
00026 #include "cpuworker.h"
00027 #include "hibernate.h"
00028 #include "nodelist.h"
00029 #include "onion.h"
00030 #include "relay.h"
00031 #include "router.h"
00032 #include "routerlist.h"
00033 
00035 uint64_t stats_n_padding_cells_processed = 0;
00037 uint64_t stats_n_create_cells_processed = 0;
00039 uint64_t stats_n_created_cells_processed = 0;
00041 uint64_t stats_n_relay_cells_processed = 0;
00043 uint64_t stats_n_destroy_cells_processed = 0;
00045 uint64_t stats_n_versions_cells_processed = 0;
00047 uint64_t stats_n_netinfo_cells_processed = 0;
00048 
00050 uint64_t stats_n_vpadding_cells_processed = 0;
00052 uint64_t stats_n_certs_cells_processed = 0;
00054 uint64_t stats_n_auth_challenge_cells_processed = 0;
00056 uint64_t stats_n_authenticate_cells_processed = 0;
00058 uint64_t stats_n_authorize_cells_processed = 0;
00059 
00060 /* These are the main functions for processing cells */
00061 static void command_process_create_cell(cell_t *cell, or_connection_t *conn);
00062 static void command_process_created_cell(cell_t *cell, or_connection_t *conn);
00063 static void command_process_relay_cell(cell_t *cell, or_connection_t *conn);
00064 static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn);
00065 static void command_process_versions_cell(var_cell_t *cell,
00066                                           or_connection_t *conn);
00067 static void command_process_netinfo_cell(cell_t *cell, or_connection_t *conn);
00068 static void command_process_certs_cell(var_cell_t *cell,
00069                                       or_connection_t *conn);
00070 static void command_process_auth_challenge_cell(var_cell_t *cell,
00071                                           or_connection_t *conn);
00072 static void command_process_authenticate_cell(var_cell_t *cell,
00073                                           or_connection_t *conn);
00074 static int enter_v3_handshake_with_cell(var_cell_t *cell,
00075                                         or_connection_t *conn);
00076 
00077 #ifdef KEEP_TIMING_STATS
00078 
00082 static void
00083 command_time_process_cell(cell_t *cell, or_connection_t *conn, int *time,
00084                                void (*func)(cell_t *, or_connection_t *))
00085 {
00086   struct timeval start, end;
00087   long time_passed;
00088 
00089   tor_gettimeofday(&start);
00090 
00091   (*func)(cell, conn);
00092 
00093   tor_gettimeofday(&end);
00094   time_passed = tv_udiff(&start, &end) ;
00095 
00096   if (time_passed > 10000) { /* more than 10ms */
00097     log_debug(LD_OR,"That call just took %ld ms.",time_passed/1000);
00098   }
00099   if (time_passed < 0) {
00100     log_info(LD_GENERAL,"That call took us back in time!");
00101     time_passed = 0;
00102   }
00103   *time += time_passed;
00104 }
00105 #endif
00106 
00112 void
00113 command_process_cell(cell_t *cell, or_connection_t *conn)
00114 {
00115   int handshaking = (conn->_base.state != OR_CONN_STATE_OPEN);
00116 #ifdef KEEP_TIMING_STATS
00117   /* how many of each cell have we seen so far this second? needs better
00118    * name. */
00119   static int num_create=0, num_created=0, num_relay=0, num_destroy=0;
00120   /* how long has it taken to process each type of cell? */
00121   static int create_time=0, created_time=0, relay_time=0, destroy_time=0;
00122   static time_t current_second = 0; /* from previous calls to time */
00123 
00124   time_t now = time(NULL);
00125 
00126   if (now > current_second) { /* the second has rolled over */
00127     /* print stats */
00128     log_info(LD_OR,
00129          "At end of second: %d creates (%d ms), %d createds (%d ms), "
00130          "%d relays (%d ms), %d destroys (%d ms)",
00131          num_create, create_time/1000,
00132          num_created, created_time/1000,
00133          num_relay, relay_time/1000,
00134          num_destroy, destroy_time/1000);
00135 
00136     /* zero out stats */
00137     num_create = num_created = num_relay = num_destroy = 0;
00138     create_time = created_time = relay_time = destroy_time = 0;
00139 
00140     /* remember which second it is, for next time */
00141     current_second = now;
00142   }
00143 #endif
00144 
00145 #ifdef KEEP_TIMING_STATS
00146 #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN {                   \
00147     ++num ## tp;                                                \
00148     command_time_process_cell(cl, cn, & tp ## time ,            \
00149                               command_process_ ## tp ## _cell);  \
00150   } STMT_END
00151 #else
00152 #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
00153 #endif
00154 
00155   if (conn->_base.marked_for_close)
00156     return;
00157 
00158   /* Reject all but VERSIONS and NETINFO when handshaking. */
00159   /* (VERSIONS should actually be impossible; it's variable-length.) */
00160   if (handshaking && cell->command != CELL_VERSIONS &&
00161       cell->command != CELL_NETINFO) {
00162     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00163            "Received unexpected cell command %d in state %s; closing the "
00164            "connection.",
00165            (int)cell->command,
00166            conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
00167     connection_mark_for_close(TO_CONN(conn));
00168     return;
00169   }
00170 
00171   if (conn->_base.state == OR_CONN_STATE_OR_HANDSHAKING_V3)
00172     or_handshake_state_record_cell(conn->handshake_state, cell, 1);
00173 
00174   switch (cell->command) {
00175     case CELL_PADDING:
00176       ++stats_n_padding_cells_processed;
00177       /* do nothing */
00178       break;
00179     case CELL_CREATE:
00180     case CELL_CREATE_FAST:
00181       ++stats_n_create_cells_processed;
00182       PROCESS_CELL(create, cell, conn);
00183       break;
00184     case CELL_CREATED:
00185     case CELL_CREATED_FAST:
00186       ++stats_n_created_cells_processed;
00187       PROCESS_CELL(created, cell, conn);
00188       break;
00189     case CELL_RELAY:
00190     case CELL_RELAY_EARLY:
00191       ++stats_n_relay_cells_processed;
00192       PROCESS_CELL(relay, cell, conn);
00193       break;
00194     case CELL_DESTROY:
00195       ++stats_n_destroy_cells_processed;
00196       PROCESS_CELL(destroy, cell, conn);
00197       break;
00198     case CELL_VERSIONS:
00199       tor_fragile_assert();
00200       break;
00201     case CELL_NETINFO:
00202       ++stats_n_netinfo_cells_processed;
00203       PROCESS_CELL(netinfo, cell, conn);
00204       break;
00205     default:
00206       log_fn(LOG_INFO, LD_PROTOCOL,
00207              "Cell of unknown type (%d) received. Dropping.", cell->command);
00208       break;
00209   }
00210 }
00211 
00214 static int
00215 command_allowed_before_handshake(uint8_t command)
00216 {
00217   switch (command) {
00218     case CELL_VERSIONS:
00219     case CELL_VPADDING:
00220     case CELL_AUTHORIZE:
00221       return 1;
00222     default:
00223       return 0;
00224   }
00225 }
00226 
00232 void
00233 command_process_var_cell(var_cell_t *cell, or_connection_t *conn)
00234 {
00235 #ifdef KEEP_TIMING_STATS
00236   /* how many of each cell have we seen so far this second? needs better
00237    * name. */
00238   static int num_versions=0, num_certs=0;
00239 
00240   time_t now = time(NULL);
00241 
00242   if (now > current_second) { /* the second has rolled over */
00243     /* print stats */
00244     log_info(LD_OR,
00245              "At end of second: %d versions (%d ms), %d certs (%d ms)",
00246              num_versions, versions_time/1000,
00247              num_certs, certs_time/1000);
00248 
00249     num_versions = num_certs = 0;
00250     versions_time = certs_time = 0;
00251 
00252     /* remember which second it is, for next time */
00253     current_second = now;
00254   }
00255 #endif
00256 
00257   if (conn->_base.marked_for_close)
00258     return;
00259 
00260   switch (conn->_base.state)
00261   {
00262     case OR_CONN_STATE_OR_HANDSHAKING_V2:
00263       if (cell->command != CELL_VERSIONS) {
00264         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00265                "Received a cell with command %d in state %s; "
00266                "closing the connection.",
00267                (int)cell->command,
00268                conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
00269         connection_mark_for_close(TO_CONN(conn));
00270         return;
00271       }
00272       break;
00273     case OR_CONN_STATE_TLS_HANDSHAKING:
00274       /* If we're using bufferevents, it's entirely possible for us to
00275        * notice "hey, data arrived!" before we notice "hey, the handshake
00276        * finished!" And we need to be accepting both at once to handle both
00277        * the v2 and v3 handshakes. */
00278 
00279       /* fall through */
00280     case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
00281       if (! command_allowed_before_handshake(cell->command)) {
00282         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00283                "Received a cell with command %d in state %s; "
00284                "closing the connection.",
00285                (int)cell->command,
00286                conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
00287         connection_mark_for_close(TO_CONN(conn));
00288         return;
00289       } else {
00290         if (enter_v3_handshake_with_cell(cell, conn)<0)
00291           return;
00292       }
00293       break;
00294     case OR_CONN_STATE_OR_HANDSHAKING_V3:
00295       if (cell->command != CELL_AUTHENTICATE)
00296         or_handshake_state_record_var_cell(conn->handshake_state, cell, 1);
00297       break; /* Everything is allowed */
00298     case OR_CONN_STATE_OPEN:
00299       if (conn->link_proto < 3) {
00300         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00301                "Received a variable-length cell with command %d in state %s "
00302                "with link protocol %d; ignoring it.",
00303                (int)cell->command,
00304                conn_state_to_string(CONN_TYPE_OR,conn->_base.state),
00305                (int)conn->link_proto);
00306         return;
00307       }
00308       break;
00309     default:
00310       log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00311              "Received var-length cell with command %d in unexpected state "
00312              "%s [%d]; ignoring it.",
00313              (int)cell->command,
00314              conn_state_to_string(CONN_TYPE_OR,conn->_base.state),
00315              (int)conn->_base.state);
00316       return;
00317   }
00318 
00319   switch (cell->command) {
00320     case CELL_VERSIONS:
00321       ++stats_n_versions_cells_processed;
00322       PROCESS_CELL(versions, cell, conn);
00323       break;
00324     case CELL_VPADDING:
00325       ++stats_n_vpadding_cells_processed;
00326       /* Do nothing */
00327       break;
00328     case CELL_CERTS:
00329       ++stats_n_certs_cells_processed;
00330       PROCESS_CELL(certs, cell, conn);
00331       break;
00332     case CELL_AUTH_CHALLENGE:
00333       ++stats_n_auth_challenge_cells_processed;
00334       PROCESS_CELL(auth_challenge, cell, conn);
00335       break;
00336     case CELL_AUTHENTICATE:
00337       ++stats_n_authenticate_cells_processed;
00338       PROCESS_CELL(authenticate, cell, conn);
00339       break;
00340     case CELL_AUTHORIZE:
00341       ++stats_n_authorize_cells_processed;
00342       /* Ignored so far. */
00343       break;
00344     default:
00345       log_fn(LOG_INFO, LD_PROTOCOL,
00346                "Variable-length cell of unknown type (%d) received.",
00347                cell->command);
00348       break;
00349   }
00350 }
00351 
00357 static void
00358 command_process_create_cell(cell_t *cell, or_connection_t *conn)
00359 {
00360   or_circuit_t *circ;
00361   const or_options_t *options = get_options();
00362   int id_is_high;
00363 
00364   if (we_are_hibernating()) {
00365     log_info(LD_OR,
00366              "Received create cell but we're shutting down. Sending back "
00367              "destroy.");
00368     connection_or_send_destroy(cell->circ_id, conn,
00369                                END_CIRC_REASON_HIBERNATING);
00370     return;
00371   }
00372 
00373   if (!server_mode(options) ||
00374       (!public_server_mode(options) && conn->is_outgoing)) {
00375     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00376            "Received create cell (type %d) from %s:%d, but we're connected "
00377            "to it as a client. "
00378            "Sending back a destroy.",
00379            (int)cell->command, conn->_base.address, conn->_base.port);
00380     connection_or_send_destroy(cell->circ_id, conn,
00381                                END_CIRC_REASON_TORPROTOCOL);
00382     return;
00383   }
00384 
00385   /* If the high bit of the circuit ID is not as expected, close the
00386    * circ. */
00387   id_is_high = cell->circ_id & (1<<15);
00388   if ((id_is_high && conn->circ_id_type == CIRC_ID_TYPE_HIGHER) ||
00389       (!id_is_high && conn->circ_id_type == CIRC_ID_TYPE_LOWER)) {
00390     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00391            "Received create cell with unexpected circ_id %d. Closing.",
00392            cell->circ_id);
00393     connection_or_send_destroy(cell->circ_id, conn,
00394                                END_CIRC_REASON_TORPROTOCOL);
00395     return;
00396   }
00397 
00398   if (circuit_id_in_use_on_orconn(cell->circ_id, conn)) {
00399     const node_t *node = node_get_by_id(conn->identity_digest);
00400     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00401            "Received CREATE cell (circID %d) for known circ. "
00402            "Dropping (age %d).",
00403            cell->circ_id, (int)(time(NULL) - conn->_base.timestamp_created));
00404     if (node) {
00405       char *p = esc_for_log(node_get_platform(node));
00406       log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
00407              "Details: router %s, platform %s.",
00408              node_describe(node), p);
00409       tor_free(p);
00410     }
00411     return;
00412   }
00413 
00414   circ = or_circuit_new(cell->circ_id, conn);
00415   circ->_base.purpose = CIRCUIT_PURPOSE_OR;
00416   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_ONIONSKIN_PENDING);
00417   if (cell->command == CELL_CREATE) {
00418     char *onionskin = tor_malloc(ONIONSKIN_CHALLENGE_LEN);
00419     memcpy(onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN);
00420 
00421     /* hand it off to the cpuworkers, and then return. */
00422     if (assign_onionskin_to_cpuworker(NULL, circ, onionskin) < 0) {
00423 #define WARN_HANDOFF_FAILURE_INTERVAL (6*60*60)
00424       static ratelim_t handoff_warning =
00425         RATELIM_INIT(WARN_HANDOFF_FAILURE_INTERVAL);
00426       char *m;
00427       if ((m = rate_limit_log(&handoff_warning, approx_time()))) {
00428         log_warn(LD_GENERAL,"Failed to hand off onionskin. Closing.%s",m);
00429         tor_free(m);
00430       }
00431       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
00432       return;
00433     }
00434     log_debug(LD_OR,"success: handed off onionskin.");
00435   } else {
00436     /* This is a CREATE_FAST cell; we can handle it immediately without using
00437      * a CPU worker. */
00438     char keys[CPATH_KEY_MATERIAL_LEN];
00439     char reply[DIGEST_LEN*2];
00440 
00441     tor_assert(cell->command == CELL_CREATE_FAST);
00442 
00443     /* Make sure we never try to use the OR connection on which we
00444      * received this cell to satisfy an EXTEND request,  */
00445     conn->is_connection_with_client = 1;
00446 
00447     if (fast_server_handshake(cell->payload, (uint8_t*)reply,
00448                               (uint8_t*)keys, sizeof(keys))<0) {
00449       log_warn(LD_OR,"Failed to generate key material. Closing.");
00450       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
00451       return;
00452     }
00453     if (onionskin_answer(circ, CELL_CREATED_FAST, reply, keys)<0) {
00454       log_warn(LD_OR,"Failed to reply to CREATE_FAST cell. Closing.");
00455       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
00456       return;
00457     }
00458   }
00459 }
00460 
00469 static void
00470 command_process_created_cell(cell_t *cell, or_connection_t *conn)
00471 {
00472   circuit_t *circ;
00473 
00474   circ = circuit_get_by_circid_orconn(cell->circ_id, conn);
00475 
00476   if (!circ) {
00477     log_info(LD_OR,
00478              "(circID %d) unknown circ (probably got a destroy earlier). "
00479              "Dropping.", cell->circ_id);
00480     return;
00481   }
00482 
00483   if (circ->n_circ_id != cell->circ_id) {
00484     log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,
00485            "got created cell from Tor client? Closing.");
00486     circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
00487     return;
00488   }
00489 
00490   if (CIRCUIT_IS_ORIGIN(circ)) { /* we're the OP. Handshake this. */
00491     origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
00492     int err_reason = 0;
00493     log_debug(LD_OR,"at OP. Finishing handshake.");
00494     if ((err_reason = circuit_finish_handshake(origin_circ, cell->command,
00495                                                cell->payload)) < 0) {
00496       log_warn(LD_OR,"circuit_finish_handshake failed.");
00497       circuit_mark_for_close(circ, -err_reason);
00498       return;
00499     }
00500     log_debug(LD_OR,"Moving to next skin.");
00501     if ((err_reason = circuit_send_next_onion_skin(origin_circ)) < 0) {
00502       log_info(LD_OR,"circuit_send_next_onion_skin failed.");
00503       /* XXX push this circuit_close lower */
00504       circuit_mark_for_close(circ, -err_reason);
00505       return;
00506     }
00507   } else { /* pack it into an extended relay cell, and send it. */
00508     log_debug(LD_OR,
00509               "Converting created cell to extended relay cell, sending.");
00510     relay_send_command_from_edge(0, circ, RELAY_COMMAND_EXTENDED,
00511                                  (char*)cell->payload, ONIONSKIN_REPLY_LEN,
00512                                  NULL);
00513   }
00514 }
00515 
00520 static void
00521 command_process_relay_cell(cell_t *cell, or_connection_t *conn)
00522 {
00523   circuit_t *circ;
00524   int reason, direction;
00525 
00526   circ = circuit_get_by_circid_orconn(cell->circ_id, conn);
00527 
00528   if (!circ) {
00529     log_debug(LD_OR,
00530               "unknown circuit %d on connection from %s:%d. Dropping.",
00531               cell->circ_id, conn->_base.address, conn->_base.port);
00532     return;
00533   }
00534 
00535   if (circ->state == CIRCUIT_STATE_ONIONSKIN_PENDING) {
00536     log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit in create_wait. Closing.");
00537     circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
00538     return;
00539   }
00540 
00541   if (CIRCUIT_IS_ORIGIN(circ)) {
00542     /* if we're a relay and treating connections with recent local
00543      * traffic better, then this is one of them. */
00544     conn->client_used = time(NULL);
00545   }
00546 
00547   if (!CIRCUIT_IS_ORIGIN(circ) &&
00548       cell->circ_id == TO_OR_CIRCUIT(circ)->p_circ_id)
00549     direction = CELL_DIRECTION_OUT;
00550   else
00551     direction = CELL_DIRECTION_IN;
00552 
00553   /* If we have a relay_early cell, make sure that it's outbound, and we've
00554    * gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
00555   if (cell->command == CELL_RELAY_EARLY) {
00556     if (direction == CELL_DIRECTION_IN) {
00557       /* Allow an unlimited number of inbound relay_early cells,
00558        * for hidden service compatibility. There isn't any way to make
00559        * a long circuit through inbound relay_early cells anyway. See
00560        * bug 1038. -RD */
00561     } else {
00562       or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
00563       if (or_circ->remaining_relay_early_cells == 0) {
00564         log_fn(LOG_PROTOCOL_WARN, LD_OR,
00565                "Received too many RELAY_EARLY cells on circ %d from %s:%d."
00566                "  Closing circuit.",
00567                cell->circ_id, safe_str(conn->_base.address),
00568                conn->_base.port);
00569         circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
00570         return;
00571       }
00572       --or_circ->remaining_relay_early_cells;
00573     }
00574   }
00575 
00576   if ((reason = circuit_receive_relay_cell(cell, circ, direction)) < 0) {
00577     log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit_receive_relay_cell "
00578            "(%s) failed. Closing.",
00579            direction==CELL_DIRECTION_OUT?"forward":"backward");
00580     circuit_mark_for_close(circ, -reason);
00581   }
00582 }
00583 
00597 static void
00598 command_process_destroy_cell(cell_t *cell, or_connection_t *conn)
00599 {
00600   circuit_t *circ;
00601   int reason;
00602 
00603   circ = circuit_get_by_circid_orconn(cell->circ_id, conn);
00604   if (!circ) {
00605     log_info(LD_OR,"unknown circuit %d on connection from %s:%d. Dropping.",
00606              cell->circ_id, conn->_base.address, conn->_base.port);
00607     return;
00608   }
00609   log_debug(LD_OR,"Received for circID %d.",cell->circ_id);
00610 
00611   reason = (uint8_t)cell->payload[0];
00612 
00613   if (!CIRCUIT_IS_ORIGIN(circ) &&
00614       cell->circ_id == TO_OR_CIRCUIT(circ)->p_circ_id) {
00615     /* the destroy came from behind */
00616     circuit_set_p_circid_orconn(TO_OR_CIRCUIT(circ), 0, NULL);
00617     circuit_mark_for_close(circ, reason|END_CIRC_REASON_FLAG_REMOTE);
00618   } else { /* the destroy came from ahead */
00619     circuit_set_n_circid_orconn(circ, 0, NULL);
00620     if (CIRCUIT_IS_ORIGIN(circ)) {
00621       circuit_mark_for_close(circ, reason|END_CIRC_REASON_FLAG_REMOTE);
00622     } else {
00623       char payload[1];
00624       log_debug(LD_OR, "Delivering 'truncated' back.");
00625       payload[0] = (char)reason;
00626       relay_send_command_from_edge(0, circ, RELAY_COMMAND_TRUNCATED,
00627                                    payload, sizeof(payload), NULL);
00628     }
00629   }
00630 }
00631 
00639 static int
00640 enter_v3_handshake_with_cell(var_cell_t *cell, or_connection_t *conn)
00641 {
00642   const int started_here = connection_or_nonopen_was_started_here(conn);
00643 
00644   tor_assert(conn->_base.state == OR_CONN_STATE_TLS_HANDSHAKING ||
00645              conn->_base.state == OR_CONN_STATE_TLS_SERVER_RENEGOTIATING);
00646 
00647   if (started_here) {
00648     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00649            "Received a cell while TLS-handshaking, not in "
00650            "OR_HANDSHAKING_V3, on a connection we originated.");
00651   }
00652   conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
00653   if (connection_init_or_handshake_state(conn, started_here) < 0) {
00654     connection_mark_for_close(TO_CONN(conn));
00655     return -1;
00656   }
00657   or_handshake_state_record_var_cell(conn->handshake_state, cell, 1);
00658   return 0;
00659 }
00660 
00667 static void
00668 command_process_versions_cell(var_cell_t *cell, or_connection_t *conn)
00669 {
00670   int highest_supported_version = 0;
00671   const uint8_t *cp, *end;
00672   const int started_here = connection_or_nonopen_was_started_here(conn);
00673   if (conn->link_proto != 0 ||
00674       (conn->handshake_state && conn->handshake_state->received_versions)) {
00675     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00676            "Received a VERSIONS cell on a connection with its version "
00677            "already set to %d; dropping", (int) conn->link_proto);
00678     return;
00679   }
00680   switch (conn->_base.state)
00681     {
00682     case OR_CONN_STATE_OR_HANDSHAKING_V2:
00683     case OR_CONN_STATE_OR_HANDSHAKING_V3:
00684       break;
00685     case OR_CONN_STATE_TLS_HANDSHAKING:
00686     case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
00687     default:
00688       log_fn(LOG_PROTOCOL_WARN, LD_OR,
00689              "VERSIONS cell while in unexpected state");
00690       return;
00691   }
00692 
00693   tor_assert(conn->handshake_state);
00694   end = cell->payload + cell->payload_len;
00695   for (cp = cell->payload; cp+1 < end; ++cp) {
00696     uint16_t v = ntohs(get_uint16(cp));
00697     if (is_or_protocol_version_known(v) && v > highest_supported_version)
00698       highest_supported_version = v;
00699   }
00700   if (!highest_supported_version) {
00701     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00702            "Couldn't find a version in common between my version list and the "
00703            "list in the VERSIONS cell; closing connection.");
00704     connection_mark_for_close(TO_CONN(conn));
00705     return;
00706   } else if (highest_supported_version == 1) {
00707     /* Negotiating version 1 makes no sense, since version 1 has no VERSIONS
00708      * cells. */
00709     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00710            "Used version negotiation protocol to negotiate a v1 connection. "
00711            "That's crazily non-compliant. Closing connection.");
00712     connection_mark_for_close(TO_CONN(conn));
00713     return;
00714   } else if (highest_supported_version < 3 &&
00715              conn->_base.state ==  OR_CONN_STATE_OR_HANDSHAKING_V3) {
00716     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00717            "Negotiated link protocol 2 or lower after doing a v3 TLS "
00718            "handshake. Closing connection.");
00719     connection_mark_for_close(TO_CONN(conn));
00720     return;
00721   }
00722 
00723   conn->link_proto = highest_supported_version;
00724   conn->handshake_state->received_versions = 1;
00725 
00726   if (conn->link_proto == 2) {
00727     log_info(LD_OR, "Negotiated version %d with %s:%d; sending NETINFO.",
00728              highest_supported_version,
00729              safe_str_client(conn->_base.address),
00730              conn->_base.port);
00731 
00732     if (connection_or_send_netinfo(conn) < 0) {
00733       connection_mark_for_close(TO_CONN(conn));
00734       return;
00735     }
00736   } else {
00737     const int send_versions = !started_here;
00738     /* If we want to authenticate, send a CERTS cell */
00739     const int send_certs = !started_here || public_server_mode(get_options());
00740     /* If we're a relay that got a connection, ask for authentication. */
00741     const int send_chall = !started_here && public_server_mode(get_options());
00742     /* If our certs cell will authenticate us, we can send a netinfo cell
00743      * right now. */
00744     const int send_netinfo = !started_here;
00745     const int send_any =
00746       send_versions || send_certs || send_chall || send_netinfo;
00747     tor_assert(conn->link_proto >= 3);
00748 
00749     log_info(LD_OR, "Negotiated version %d with %s:%d; %s%s%s%s%s",
00750              highest_supported_version,
00751              safe_str_client(conn->_base.address),
00752              conn->_base.port,
00753              send_any ? "Sending cells:" : "Waiting for CERTS cell",
00754              send_versions ? " VERSIONS" : "",
00755              send_certs ? " CERTS" : "",
00756              send_chall ? " AUTH_CHALLENGE" : "",
00757              send_netinfo ? " NETINFO" : "");
00758 
00759 #ifdef DISABLE_V3_LINKPROTO_SERVERSIDE
00760     if (1) {
00761       connection_mark_for_close(TO_CONN(conn));
00762       return;
00763     }
00764 #endif
00765 
00766     if (send_versions) {
00767       if (connection_or_send_versions(conn, 1) < 0) {
00768         log_warn(LD_OR, "Couldn't send versions cell");
00769         connection_mark_for_close(TO_CONN(conn));
00770         return;
00771       }
00772     }
00773     if (send_certs) {
00774       if (connection_or_send_certs_cell(conn) < 0) {
00775         log_warn(LD_OR, "Couldn't send certs cell");
00776         connection_mark_for_close(TO_CONN(conn));
00777         return;
00778       }
00779     }
00780     if (send_chall) {
00781       if (connection_or_send_auth_challenge_cell(conn) < 0) {
00782         log_warn(LD_OR, "Couldn't send auth_challenge cell");
00783         connection_mark_for_close(TO_CONN(conn));
00784         return;
00785       }
00786     }
00787     if (send_netinfo) {
00788       if (connection_or_send_netinfo(conn) < 0) {
00789         log_warn(LD_OR, "Couldn't send netinfo cell");
00790         connection_mark_for_close(TO_CONN(conn));
00791         return;
00792       }
00793     }
00794   }
00795 }
00796 
00799 static void
00800 command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
00801 {
00802   time_t timestamp;
00803   uint8_t my_addr_type;
00804   uint8_t my_addr_len;
00805   const uint8_t *my_addr_ptr;
00806   const uint8_t *cp, *end;
00807   uint8_t n_other_addrs;
00808   time_t now = time(NULL);
00809 
00810   long apparent_skew = 0;
00811   uint32_t my_apparent_addr = 0;
00812 
00813   if (conn->link_proto < 2) {
00814     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00815            "Received a NETINFO cell on %s connection; dropping.",
00816            conn->link_proto == 0 ? "non-versioned" : "a v1");
00817     return;
00818   }
00819   if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING_V2 &&
00820       conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING_V3) {
00821     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00822            "Received a NETINFO cell on non-handshaking connection; dropping.");
00823     return;
00824   }
00825   tor_assert(conn->handshake_state &&
00826              conn->handshake_state->received_versions);
00827 
00828   if (conn->_base.state == OR_CONN_STATE_OR_HANDSHAKING_V3) {
00829     tor_assert(conn->link_proto >= 3);
00830     if (conn->handshake_state->started_here) {
00831       if (!conn->handshake_state->authenticated) {
00832         log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got a NETINFO cell from server, "
00833                "but no authentication.  Closing the connection.");
00834         connection_mark_for_close(TO_CONN(conn));
00835         return;
00836       }
00837     } else {
00838       /* we're the server.  If the client never authenticated, we have
00839          some housekeeping to do.*/
00840       if (!conn->handshake_state->authenticated) {
00841         tor_assert(tor_digest_is_zero(
00842                   (const char*)conn->handshake_state->authenticated_peer_id));
00843         connection_or_set_circid_type(conn, NULL);
00844 
00845         connection_or_init_conn_from_address(conn,
00846                   &conn->_base.addr,
00847                   conn->_base.port,
00848                   (const char*)conn->handshake_state->authenticated_peer_id,
00849                   0);
00850       }
00851     }
00852   }
00853 
00854   /* Decode the cell. */
00855   timestamp = ntohl(get_uint32(cell->payload));
00856   if (labs(now - conn->handshake_state->sent_versions_at) < 180) {
00857     apparent_skew = now - timestamp;
00858   }
00859 
00860   my_addr_type = (uint8_t) cell->payload[4];
00861   my_addr_len = (uint8_t) cell->payload[5];
00862   my_addr_ptr = (uint8_t*) cell->payload + 6;
00863   end = cell->payload + CELL_PAYLOAD_SIZE;
00864   cp = cell->payload + 6 + my_addr_len;
00865   if (cp >= end) {
00866     log_fn(LOG_PROTOCOL_WARN, LD_OR,
00867            "Addresses too long in netinfo cell; closing connection.");
00868     connection_mark_for_close(TO_CONN(conn));
00869     return;
00870   } else if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
00871     my_apparent_addr = ntohl(get_uint32(my_addr_ptr));
00872   }
00873 
00874   n_other_addrs = (uint8_t) *cp++;
00875   while (n_other_addrs && cp < end-2) {
00876     /* Consider all the other addresses; if any matches, this connection is
00877      * "canonical." */
00878     tor_addr_t addr;
00879     const uint8_t *next =
00880       decode_address_from_payload(&addr, cp, (int)(end-cp));
00881     if (next == NULL) {
00882       log_fn(LOG_PROTOCOL_WARN,  LD_OR,
00883              "Bad address in netinfo cell; closing connection.");
00884       connection_mark_for_close(TO_CONN(conn));
00885       return;
00886     }
00887     if (tor_addr_eq(&addr, &conn->real_addr)) {
00888       conn->is_canonical = 1;
00889       break;
00890     }
00891     cp = next;
00892     --n_other_addrs;
00893   }
00894 
00895   /* Act on apparent skew. */
00897 #define NETINFO_NOTICE_SKEW 3600
00898   if (labs(apparent_skew) > NETINFO_NOTICE_SKEW &&
00899       router_get_by_id_digest(conn->identity_digest)) {
00900     char dbuf[64];
00901     int severity;
00902     /*XXXX be smarter about when everybody says we are skewed. */
00903     if (router_digest_is_trusted_dir(conn->identity_digest))
00904       severity = LOG_WARN;
00905     else
00906       severity = LOG_INFO;
00907     format_time_interval(dbuf, sizeof(dbuf), apparent_skew);
00908     log_fn(severity, LD_GENERAL, "Received NETINFO cell with skewed time from "
00909            "server at %s:%d.  It seems that our clock is %s by %s, or "
00910            "that theirs is %s. Tor requires an accurate clock to work: "
00911            "please check your time and date settings.",
00912            conn->_base.address, (int)conn->_base.port,
00913            apparent_skew>0 ? "ahead" : "behind", dbuf,
00914            apparent_skew>0 ? "behind" : "ahead");
00915     if (severity == LOG_WARN) /* only tell the controller if an authority */
00916       control_event_general_status(LOG_WARN,
00917                           "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
00918                           apparent_skew,
00919                           conn->_base.address, conn->_base.port);
00920   }
00921 
00922   /* XXX maybe act on my_apparent_addr, if the source is sufficiently
00923    * trustworthy. */
00924   (void)my_apparent_addr;
00925 
00926   if (connection_or_set_state_open(conn)<0) {
00927     log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got good NETINFO cell from %s:%d; but "
00928            "was unable to make the OR connection become open.",
00929            safe_str_client(conn->_base.address),
00930            conn->_base.port);
00931     connection_mark_for_close(TO_CONN(conn));
00932   } else {
00933     log_info(LD_OR, "Got good NETINFO cell from %s:%d; OR connection is now "
00934              "open, using protocol version %d. Its ID digest is %s",
00935              safe_str_client(conn->_base.address),
00936              conn->_base.port, (int)conn->link_proto,
00937              hex_str(conn->identity_digest, DIGEST_LEN));
00938   }
00939   assert_connection_ok(TO_CONN(conn),time(NULL));
00940 }
00941 
00953 static void
00954 command_process_certs_cell(var_cell_t *cell, or_connection_t *conn)
00955 {
00956 #define ERR(s)                                                  \
00957   do {                                                          \
00958     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
00959            "Received a bad CERTS cell from %s:%d: %s",          \
00960            safe_str(conn->_base.address), conn->_base.port, (s)); \
00961     connection_mark_for_close(TO_CONN(conn));                   \
00962     goto err;                                                   \
00963   } while (0)
00964 
00965   tor_cert_t *link_cert = NULL;
00966   tor_cert_t *id_cert = NULL;
00967   tor_cert_t *auth_cert = NULL;
00968 
00969   uint8_t *ptr;
00970   int n_certs, i;
00971   int send_netinfo = 0;
00972 
00973   if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
00974     ERR("We're not doing a v3 handshake!");
00975   if (conn->link_proto < 3)
00976     ERR("We're not using link protocol >= 3");
00977   if (conn->handshake_state->received_certs_cell)
00978     ERR("We already got one");
00979   if (conn->handshake_state->authenticated) {
00980     /* Should be unreachable, but let's make sure. */
00981     ERR("We're already authenticated!");
00982   }
00983   if (cell->payload_len < 1)
00984     ERR("It had no body");
00985   if (cell->circ_id)
00986     ERR("It had a nonzero circuit ID");
00987 
00988   n_certs = cell->payload[0];
00989   ptr = cell->payload + 1;
00990   for (i = 0; i < n_certs; ++i) {
00991     uint8_t cert_type;
00992     uint16_t cert_len;
00993     if (ptr + 3 > cell->payload + cell->payload_len) {
00994       goto truncated;
00995     }
00996     cert_type = *ptr;
00997     cert_len = ntohs(get_uint16(ptr+1));
00998     if (ptr + 3 + cert_len > cell->payload + cell->payload_len) {
00999       goto truncated;
01000     }
01001     if (cert_type == OR_CERT_TYPE_TLS_LINK ||
01002         cert_type == OR_CERT_TYPE_ID_1024 ||
01003         cert_type == OR_CERT_TYPE_AUTH_1024) {
01004       tor_cert_t *cert = tor_cert_decode(ptr + 3, cert_len);
01005       if (!cert) {
01006         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
01007                "Received undecodable certificate in CERTS cell from %s:%d",
01008                safe_str(conn->_base.address), conn->_base.port);
01009       } else {
01010         if (cert_type == OR_CERT_TYPE_TLS_LINK) {
01011           if (link_cert) {
01012             tor_cert_free(cert);
01013             ERR("Too many TLS_LINK certificates");
01014           }
01015           link_cert = cert;
01016         } else if (cert_type == OR_CERT_TYPE_ID_1024) {
01017           if (id_cert) {
01018             tor_cert_free(cert);
01019             ERR("Too many ID_1024 certificates");
01020           }
01021           id_cert = cert;
01022         } else if (cert_type == OR_CERT_TYPE_AUTH_1024) {
01023           if (auth_cert) {
01024             tor_cert_free(cert);
01025             ERR("Too many AUTH_1024 certificates");
01026           }
01027           auth_cert = cert;
01028         } else {
01029           tor_cert_free(cert);
01030         }
01031       }
01032     }
01033     ptr += 3 + cert_len;
01034     continue;
01035 
01036   truncated:
01037     ERR("It ends in the middle of a certificate");
01038   }
01039 
01040   if (conn->handshake_state->started_here) {
01041     int severity;
01042     if (! (id_cert && link_cert))
01043       ERR("The certs we wanted were missing");
01044     /* Okay. We should be able to check the certificates now. */
01045     if (! tor_tls_cert_matches_key(conn->tls, link_cert)) {
01046       ERR("The link certificate didn't match the TLS public key");
01047     }
01048     /* Note that this warns more loudly about time and validity if we were
01049     * _trying_ to connect to an authority, not necessarily if we _did_ connect
01050     * to one. */
01051     if (router_digest_is_trusted_dir(conn->identity_digest))
01052       severity = LOG_WARN;
01053     else
01054       severity = LOG_PROTOCOL_WARN;
01055 
01056     if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, 0))
01057       ERR("The link certificate was not valid");
01058     if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, 1))
01059       ERR("The ID certificate was not valid");
01060 
01061     conn->handshake_state->authenticated = 1;
01062     {
01063       const digests_t *id_digests = tor_cert_get_id_digests(id_cert);
01064       crypto_pk_t *identity_rcvd;
01065       if (!id_digests)
01066         ERR("Couldn't compute digests for key in ID cert");
01067 
01068       identity_rcvd = tor_tls_cert_get_key(id_cert);
01069       if (!identity_rcvd)
01070         ERR("Internal error: Couldn't get RSA key from ID cert.");
01071       memcpy(conn->handshake_state->authenticated_peer_id,
01072              id_digests->d[DIGEST_SHA1], DIGEST_LEN);
01073       connection_or_set_circid_type(conn, identity_rcvd);
01074       crypto_pk_free(identity_rcvd);
01075     }
01076 
01077     if (connection_or_client_learned_peer_id(conn,
01078                       conn->handshake_state->authenticated_peer_id) < 0)
01079       ERR("Problem setting or checking peer id");
01080 
01081     log_info(LD_OR, "Got some good certificates from %s:%d: Authenticated it.",
01082              safe_str(conn->_base.address), conn->_base.port);
01083 
01084     conn->handshake_state->id_cert = id_cert;
01085     id_cert = NULL;
01086 
01087     if (!public_server_mode(get_options())) {
01088       /* If we initiated the connection and we are not a public server, we
01089        * aren't planning to authenticate at all.  At this point we know who we
01090        * are talking to, so we can just send a netinfo now. */
01091       send_netinfo = 1;
01092     }
01093   } else {
01094     if (! (id_cert && auth_cert))
01095       ERR("The certs we wanted were missing");
01096 
01097     /* Remember these certificates so we can check an AUTHENTICATE cell */
01098     if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, auth_cert, id_cert, 1))
01099       ERR("The authentication certificate was not valid");
01100     if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, 1))
01101       ERR("The ID certificate was not valid");
01102 
01103     log_info(LD_OR, "Got some good certificates from %s:%d: "
01104              "Waiting for AUTHENTICATE.",
01105              safe_str(conn->_base.address), conn->_base.port);
01106     /* XXXX check more stuff? */
01107 
01108     conn->handshake_state->id_cert = id_cert;
01109     conn->handshake_state->auth_cert = auth_cert;
01110     id_cert = auth_cert = NULL;
01111   }
01112 
01113   conn->handshake_state->received_certs_cell = 1;
01114 
01115   if (send_netinfo) {
01116     if (connection_or_send_netinfo(conn) < 0) {
01117       log_warn(LD_OR, "Couldn't send netinfo cell");
01118       connection_mark_for_close(TO_CONN(conn));
01119       goto err;
01120     }
01121   }
01122 
01123  err:
01124   tor_cert_free(id_cert);
01125   tor_cert_free(link_cert);
01126   tor_cert_free(auth_cert);
01127 #undef ERR
01128 }
01129 
01137 static void
01138 command_process_auth_challenge_cell(var_cell_t *cell, or_connection_t *conn)
01139 {
01140   int n_types, i, use_type = -1;
01141   uint8_t *cp;
01142 
01143 #define ERR(s)                                                  \
01144   do {                                                          \
01145     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
01146            "Received a bad AUTH_CHALLENGE cell from %s:%d: %s", \
01147            safe_str(conn->_base.address), conn->_base.port, (s));       \
01148     connection_mark_for_close(TO_CONN(conn));                   \
01149     return;                                                     \
01150   } while (0)
01151 
01152   if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
01153     ERR("We're not currently doing a v3 handshake");
01154   if (conn->link_proto < 3)
01155     ERR("We're not using link protocol >= 3");
01156   if (! conn->handshake_state->started_here)
01157     ERR("We didn't originate this connection");
01158   if (conn->handshake_state->received_auth_challenge)
01159     ERR("We already received one");
01160   if (! conn->handshake_state->received_certs_cell)
01161     ERR("We haven't gotten a CERTS cell yet");
01162   if (cell->payload_len < OR_AUTH_CHALLENGE_LEN + 2)
01163     ERR("It was too short");
01164   if (cell->circ_id)
01165     ERR("It had a nonzero circuit ID");
01166 
01167   n_types = ntohs(get_uint16(cell->payload + OR_AUTH_CHALLENGE_LEN));
01168   if (cell->payload_len < OR_AUTH_CHALLENGE_LEN + 2 + 2*n_types)
01169     ERR("It looks truncated");
01170 
01171   /* Now see if there is an authentication type we can use */
01172   cp=cell->payload+OR_AUTH_CHALLENGE_LEN+2;
01173   for (i=0; i < n_types; ++i, cp += 2) {
01174     uint16_t authtype = ntohs(get_uint16(cp));
01175     if (authtype == AUTHTYPE_RSA_SHA256_TLSSECRET)
01176       use_type = authtype;
01177   }
01178 
01179   conn->handshake_state->received_auth_challenge = 1;
01180 
01181   if (! public_server_mode(get_options())) {
01182     /* If we're not a public server then we don't want to authenticate on a
01183        connection we originated, and we already sent a NETINFO cell when we
01184        got the CERTS cell. We have nothing more to do. */
01185     return;
01186   }
01187 
01188   if (use_type >= 0) {
01189     log_info(LD_OR, "Got an AUTH_CHALLENGE cell from %s:%d: Sending "
01190              "authentication",
01191              safe_str(conn->_base.address), conn->_base.port);
01192 
01193     if (connection_or_send_authenticate_cell(conn, use_type) < 0) {
01194       log_warn(LD_OR, "Couldn't send authenticate cell");
01195       connection_mark_for_close(TO_CONN(conn));
01196       return;
01197     }
01198   } else {
01199     log_info(LD_OR, "Got an AUTH_CHALLENGE cell from %s:%d, but we don't "
01200              "know any of its authentication types. Not authenticating.",
01201              safe_str(conn->_base.address), conn->_base.port);
01202   }
01203 
01204   if (connection_or_send_netinfo(conn) < 0) {
01205     log_warn(LD_OR, "Couldn't send netinfo cell");
01206     connection_mark_for_close(TO_CONN(conn));
01207     return;
01208   }
01209 
01210 #undef ERR
01211 }
01212 
01221 static void
01222 command_process_authenticate_cell(var_cell_t *cell, or_connection_t *conn)
01223 {
01224   uint8_t expected[V3_AUTH_FIXED_PART_LEN];
01225   const uint8_t *auth;
01226   int authlen;
01227 
01228 #define ERR(s)                                                  \
01229   do {                                                          \
01230     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
01231            "Received a bad AUTHENTICATE cell from %s:%d: %s",   \
01232            safe_str(conn->_base.address), conn->_base.port, (s));       \
01233     connection_mark_for_close(TO_CONN(conn));                   \
01234     return;                                                     \
01235   } while (0)
01236 
01237   if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
01238     ERR("We're not doing a v3 handshake");
01239   if (conn->link_proto < 3)
01240     ERR("We're not using link protocol >= 3");
01241   if (conn->handshake_state->started_here)
01242     ERR("We originated this connection");
01243   if (conn->handshake_state->received_authenticate)
01244     ERR("We already got one!");
01245   if (conn->handshake_state->authenticated) {
01246     /* Should be impossible given other checks */
01247     ERR("The peer is already authenticated");
01248   }
01249   if (! conn->handshake_state->received_certs_cell)
01250     ERR("We never got a certs cell");
01251   if (conn->handshake_state->auth_cert == NULL)
01252     ERR("We never got an authentication certificate");
01253   if (conn->handshake_state->id_cert == NULL)
01254     ERR("We never got an identity certificate");
01255   if (cell->payload_len < 4)
01256     ERR("Cell was way too short");
01257 
01258   auth = cell->payload;
01259   {
01260     uint16_t type = ntohs(get_uint16(auth));
01261     uint16_t len = ntohs(get_uint16(auth+2));
01262     if (4 + len > cell->payload_len)
01263       ERR("Authenticator was truncated");
01264 
01265     if (type != AUTHTYPE_RSA_SHA256_TLSSECRET)
01266       ERR("Authenticator type was not recognized");
01267 
01268     auth += 4;
01269     authlen = len;
01270   }
01271 
01272   if (authlen < V3_AUTH_BODY_LEN + 1)
01273     ERR("Authenticator was too short");
01274 
01275   if (connection_or_compute_authenticate_cell_body(
01276                         conn, expected, sizeof(expected), NULL, 1) < 0)
01277     ERR("Couldn't compute expected AUTHENTICATE cell body");
01278 
01279   if (tor_memneq(expected, auth, sizeof(expected)))
01280     ERR("Some field in the AUTHENTICATE cell body was not as expected");
01281 
01282   {
01283     crypto_pk_t *pk = tor_tls_cert_get_key(
01284                                    conn->handshake_state->auth_cert);
01285     char d[DIGEST256_LEN];
01286     char *signed_data;
01287     size_t keysize;
01288     int signed_len;
01289 
01290     if (!pk)
01291       ERR("Internal error: couldn't get RSA key from AUTH cert.");
01292     crypto_digest256(d, (char*)auth, V3_AUTH_BODY_LEN, DIGEST_SHA256);
01293 
01294     keysize = crypto_pk_keysize(pk);
01295     signed_data = tor_malloc(keysize);
01296     signed_len = crypto_pk_public_checksig(pk, signed_data, keysize,
01297                                            (char*)auth + V3_AUTH_BODY_LEN,
01298                                            authlen - V3_AUTH_BODY_LEN);
01299     crypto_pk_free(pk);
01300     if (signed_len < 0) {
01301       tor_free(signed_data);
01302       ERR("Signature wasn't valid");
01303     }
01304     if (signed_len < DIGEST256_LEN) {
01305       tor_free(signed_data);
01306       ERR("Not enough data was signed");
01307     }
01308     /* Note that we deliberately allow *more* than DIGEST256_LEN bytes here,
01309      * in case they're later used to hold a SHA3 digest or something. */
01310     if (tor_memneq(signed_data, d, DIGEST256_LEN)) {
01311       tor_free(signed_data);
01312       ERR("Signature did not match data to be signed.");
01313     }
01314     tor_free(signed_data);
01315   }
01316 
01317   /* Okay, we are authenticated. */
01318   conn->handshake_state->received_authenticate = 1;
01319   conn->handshake_state->authenticated = 1;
01320   conn->handshake_state->digest_received_data = 0;
01321   {
01322     crypto_pk_t *identity_rcvd =
01323       tor_tls_cert_get_key(conn->handshake_state->id_cert);
01324     const digests_t *id_digests =
01325       tor_cert_get_id_digests(conn->handshake_state->id_cert);
01326 
01327     /* This must exist; we checked key type when reading the cert. */
01328     tor_assert(id_digests);
01329 
01330     memcpy(conn->handshake_state->authenticated_peer_id,
01331            id_digests->d[DIGEST_SHA1], DIGEST_LEN);
01332 
01333     connection_or_set_circid_type(conn, identity_rcvd);
01334     crypto_pk_free(identity_rcvd);
01335 
01336     connection_or_init_conn_from_address(conn,
01337                   &conn->_base.addr,
01338                   conn->_base.port,
01339                   (const char*)conn->handshake_state->authenticated_peer_id,
01340                   0);
01341 
01342     log_info(LD_OR, "Got an AUTHENTICATE cell from %s:%d: Looks good.",
01343              safe_str(conn->_base.address), conn->_base.port);
01344   }
01345 
01346 #undef ERR
01347 }
01348