Selaa lähdekoodia

finish enabling begin-dir cells. require one-hop circs for
socks-command-connect-dir streams, so we don't open new anonymity
questions.


svn:r9099

Roger Dingledine 17 vuotta sitten
vanhempi
commit
97c83a4c09
9 muutettua tiedostoa jossa 82 lisäystä ja 39 poistoa
  1. 5 0
      ChangeLog
  2. 5 3
      doc/TODO
  3. 18 11
      src/or/circuitbuild.c
  4. 36 17
      src/or/circuituse.c
  5. 3 0
      src/or/connection_edge.c
  6. 1 1
      src/or/control.c
  7. 10 3
      src/or/or.h
  8. 3 3
      src/or/rendservice.c
  9. 1 1
      src/or/router.c

+ 5 - 0
ChangeLog

@@ -1,4 +1,9 @@
 Changes in version 0.1.2.5-xxxx - 200?-??-??
+  o Major features:
+    - Enable "BEGIN_DIR" cells: prefer to connect to the directory
+      server via TLS so we do encrypted directory requests rather than
+      plaintext. Only used if you enable the TunnelDirConns config option.
+
   o Minor features:
     - Start using the state file to store bandwidth accounting data:
       the bw_accounting file is now obsolete. We'll keep generating it

+ 5 - 3
doc/TODO

@@ -48,12 +48,12 @@ R   - Actually list all the events (notice and warn log messages are a good
 R   - Specify general event system
 R   - Specify actual events.
 
-N . Have (and document) a BEGIN_DIR relay cell that means "Connect to your
+  o Have (and document) a BEGIN_DIR relay cell that means "Connect to your
     directory port."
     o Specify
     o Implement
-    - Use for something, so we can be sure it works.
-    - Test and debug
+    o Use for something, so we can be sure it works.
+    o Test and debug
 
 N - Document .noconnect addresses... but where?
 
@@ -446,3 +446,5 @@ R - make a page with the hidden service diagrams.
 
   - ask Jan to be the translation coordinator? add to volunteer page.
 
+  - add a page for localizing all tor's components.
+

+ 18 - 11
src/or/circuitbuild.c

@@ -273,13 +273,14 @@ again:
 /** Create and return a new origin circuit. Initialize its purpose and
  * build-state based on our arguments. */
 origin_circuit_t *
-origin_circuit_init(uint8_t purpose, int need_uptime, int need_capacity,
-                    int internal)
+origin_circuit_init(uint8_t purpose, int onehop_tunnel,
+                    int need_uptime, int need_capacity, int internal)
 {
   /* sets circ->p_circ_id and circ->p_conn */
   origin_circuit_t *circ = origin_circuit_new();
   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OR_WAIT);
   circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+  circ->build_state->onehop_tunnel = onehop_tunnel;
   circ->build_state->need_uptime = need_uptime;
   circ->build_state->need_capacity = need_capacity;
   circ->build_state->is_internal = internal;
@@ -295,13 +296,15 @@ origin_circuit_init(uint8_t purpose, int need_uptime, int need_capacity,
  * it's not open already.
  */
 origin_circuit_t *
-circuit_establish_circuit(uint8_t purpose, extend_info_t *info,
+circuit_establish_circuit(uint8_t purpose, int onehop_tunnel,
+                          extend_info_t *info,
                           int need_uptime, int need_capacity, int internal)
 {
   origin_circuit_t *circ;
   int err_reason = 0;
 
-  circ = origin_circuit_init(purpose, need_uptime, need_capacity, internal);
+  circ = origin_circuit_init(purpose, onehop_tunnel,
+                             need_uptime, need_capacity, internal);
 
   if (onion_pick_cpath_exit(circ, info) < 0 ||
       onion_populate_cpath(circ) < 0) {
@@ -601,7 +604,7 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
       circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
       log_info(LD_CIRC,"circuit built!");
       circuit_reset_failure_count(0);
-      if (!has_completed_circuit) {
+      if (!has_completed_circuit && !circ->build_state->onehop_tunnel) {
         or_options_t *options = get_options();
         has_completed_circuit=1;
         /* FFFF Log a count of known routers here */
@@ -1340,13 +1343,17 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit)
 {
   cpath_build_state_t *state = circ->build_state;
   routerlist_t *rl = router_get_routerlist();
-  int r;
 
-  r = new_route_len(get_options()->PathlenCoinWeight, circ->_base.purpose,
-                    exit, rl->routers);
-  if (r < 1) /* must be at least 1 */
-    return -1;
-  state->desired_path_len = r;
+  if (state->onehop_tunnel) {
+    log_debug(LD_CIRC, "Launching a one-hop circuit for dir tunnel.");
+    state->desired_path_len = 1;
+  } else {
+    int r = new_route_len(get_options()->PathlenCoinWeight,
+                          circ->_base.purpose, exit, rl->routers);
+    if (r < 1) /* must be at least 1 */
+      return -1;
+    state->desired_path_len = r;
+  }
 
   if (exit) { /* the circuit-builder pre-requested one */
     log_info(LD_CIRC,"Using requested exit node '%s'", exit->nickname);

+ 36 - 17
src/or/circuituse.c

@@ -86,6 +86,18 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
       return 0; /* this circuit is screwed and doesn't know it yet,
                  * or is a rendezvous circuit. */
     }
+    if (build_state->onehop_tunnel) {
+      if (conn->socks_request->command != SOCKS_COMMAND_CONNECT_DIR) {
+        log_debug(LD_CIRC,"Skipping one-hop circuit.");
+        return 0;
+      }
+    } else {
+      if (conn->socks_request->command == SOCKS_COMMAND_CONNECT_DIR) {
+        /* don't use three-hop circuits -- that could hurt our anonymity. */
+        log_debug(LD_CIRC,"Skipping multi-hop circuit for CONNECT_DIR.");
+        return 0;
+      }
+    }
     if (!connection_ap_can_use_exit(conn, exitrouter)) {
       /* can't exit from this router */
       return 0;
@@ -313,7 +325,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
         (!circ->timestamp_dirty ||
          circ->timestamp_dirty + get_options()->MaxCircuitDirtiness > now)) {
       cpath_build_state_t *build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
-      if (build_state->is_internal)
+      if (build_state->is_internal || build_state->onehop_tunnel)
         continue;
 
       exitrouter = build_state_get_exit_router(build_state);
@@ -363,8 +375,10 @@ circuit_predict_and_launch_new(void)
       continue; /* only count clean circs */
     if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL)
       continue; /* only pay attention to general-purpose circs */
-    num++;
     build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
+    if (build_state->onehop_tunnel)
+      continue;
+    num++;
     if (build_state->is_internal)
       num_internal++;
     if (build_state->need_uptime && build_state->is_internal)
@@ -383,7 +397,7 @@ circuit_predict_and_launch_new(void)
     log_info(LD_CIRC,
              "Have %d clean circs (%d internal), need another exit circ.",
              num, num_internal);
-    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
+    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
                              port_needs_uptime, port_needs_capacity, 0);
     return;
   }
@@ -394,7 +408,7 @@ circuit_predict_and_launch_new(void)
              "Have %d clean circs (%d internal), need another internal "
              "circ for my hidden service.",
              num, num_internal);
-    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
+    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
                              1, 1, 1);
     return;
   }
@@ -408,7 +422,7 @@ circuit_predict_and_launch_new(void)
              "Have %d clean circs (%d uptime-internal, %d internal), need"
              " another hidserv circ.",
              num, num_uptime_internal, num_internal);
-    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL,
+    circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL,
                              hidserv_needs_uptime, hidserv_needs_capacity, 1);
     return;
   }
@@ -447,7 +461,7 @@ circuit_build_needed_circs(time_t now)
         circ &&
         circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
       log_fn(LOG_INFO,"Creating a new testing circuit.");
-      circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, 0, 0, 0);
+      circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, 0, NULL, 0, 0, 0);
     }
 #endif
   }
@@ -764,7 +778,7 @@ static int did_circs_fail_last_period = 0;
 /** Launch a new circuit; see circuit_launch_by_extend_info() for
  * details on arguments. */
 origin_circuit_t *
-circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
+circuit_launch_by_router(uint8_t purpose, int onehop_tunnel, routerinfo_t *exit,
                          int need_uptime, int need_capacity, int internal)
 {
   origin_circuit_t *circ;
@@ -772,7 +786,7 @@ circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
   if (exit)
     info = extend_info_from_router(exit);
   circ = circuit_launch_by_extend_info(
-    purpose, info, need_uptime, need_capacity, internal);
+    purpose, onehop_tunnel, info, need_uptime, need_capacity, internal);
   if (info)
     extend_info_free(info);
   return circ;
@@ -785,19 +799,20 @@ circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
  * last hop need not be an exit node. Return the newly allocated circuit on
  * success, or NULL on failure. */
 origin_circuit_t *
-circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info,
-               int need_uptime, int need_capacity, int internal)
+circuit_launch_by_extend_info(uint8_t purpose, int onehop_tunnel,
+                              extend_info_t *extend_info, int need_uptime,
+                              int need_capacity, int internal)
 {
   origin_circuit_t *circ;
 
-  if (!router_have_minimum_dir_info()) {
+  if (!onehop_tunnel && !router_have_minimum_dir_info()) {
     log_debug(LD_CIRC,"Haven't fetched enough directory info yet; canceling "
               "circuit launch.");
     return NULL;
   }
 
   if ((extend_info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
-      purpose != CIRCUIT_PURPOSE_TESTING) {
+      purpose != CIRCUIT_PURPOSE_TESTING && !onehop_tunnel) {
     /* see if there are appropriate circs available to cannibalize. */
     circ = circuit_find_to_cannibalize(CIRCUIT_PURPOSE_C_GENERAL, extend_info,
                                        need_uptime, need_capacity, internal);
@@ -842,14 +857,15 @@ circuit_launch_by_extend_info(uint8_t purpose, extend_info_t *extend_info,
 
   /* try a circ. if it fails, circuit_mark_for_close will increment
    * n_circuit_failures */
-  return circuit_establish_circuit(purpose, extend_info,
+  return circuit_establish_circuit(purpose, onehop_tunnel, extend_info,
                                    need_uptime, need_capacity, internal);
 }
 
 /** Launch a new circuit; see circuit_launch_by_extend_info() for
  * details on arguments. */
 origin_circuit_t *
-circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname,
+circuit_launch_by_nickname(uint8_t purpose, int onehop_tunnel,
+                           const char *exit_nickname,
                            int need_uptime, int need_capacity, int internal)
 {
   routerinfo_t *router = NULL;
@@ -862,7 +878,7 @@ circuit_launch_by_nickname(uint8_t purpose, const char *exit_nickname,
       return NULL;
     }
   }
-  return circuit_launch_by_router(purpose, router,
+  return circuit_launch_by_router(purpose, onehop_tunnel, router,
                                   need_uptime, need_capacity, internal);
 }
 
@@ -904,6 +920,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
   origin_circuit_t *circ;
   int check_exit_policy;
   int need_uptime, need_internal;
+  int want_onehop;
 
   tor_assert(conn);
   tor_assert(circp);
@@ -911,6 +928,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
   check_exit_policy =
       (conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
       !connection_edge_is_rendezvous_stream(conn);
+  want_onehop = conn->socks_request->command == SOCKS_COMMAND_CONNECT_DIR;
 
   need_uptime = (conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
                 smartlist_string_num_isin(get_options()->LongLivedPorts,
@@ -925,7 +943,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
     return 1; /* we're happy */
   }
 
-  if (!router_have_minimum_dir_info()) {
+  if (!want_onehop && !router_have_minimum_dir_info()) {
     if (!connection_get_by_type(CONN_TYPE_DIR)) {
       log_notice(LD_APP|LD_DIR,
                  "Application request when we're believed to be "
@@ -1010,7 +1028,8 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
       new_circ_purpose = desired_circuit_purpose;
 
     circ = circuit_launch_by_extend_info(
-              new_circ_purpose, extend_info, need_uptime, 1, need_internal);
+              new_circ_purpose, want_onehop, extend_info,
+              need_uptime, 1, need_internal);
     if (extend_info)
       extend_info_free(extend_info);
 

+ 3 - 0
src/or/connection_edge.c

@@ -1647,6 +1647,9 @@ connection_ap_handshake_send_begin(edge_connection_t *ap_conn,
 
   begin_type = ap_conn->socks_request->command == SOCKS_COMMAND_CONNECT ?
                  RELAY_COMMAND_BEGIN : RELAY_COMMAND_BEGIN_DIR;
+  if (begin_type == RELAY_COMMAND_BEGIN) {
+    tor_assert(circ->build_state->onehop_tunnel == 0);
+  }
 
   if (connection_edge_send_command(ap_conn, TO_CIRCUIT(circ),
                                    begin_type, payload, payload_len,

+ 1 - 1
src/or/control.c

@@ -2045,7 +2045,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
 
   if (zero_circ) {
     /* start a new circuit */
-    circ = origin_circuit_init(intended_purpose, 0, 0, 0);
+    circ = origin_circuit_init(intended_purpose, 0, 0, 0, 0);
   }
 
   /* now circ refers to something that is ready to be extended */

+ 10 - 3
src/or/or.h

@@ -1185,6 +1185,8 @@ typedef struct {
   int need_capacity;
   /** Whether the last hop was picked with exiting in mind. */
   int is_internal;
+  /** Did we pick this as a one-hop tunnel (not safe for other conns)? */
+  int onehop_tunnel;
   /** The crypt_path_t to append after rendezvous: used for rendezvous. */
   crypt_path_t *pending_final_cpath;
   /** How many times has building a circuit for this task failed? */
@@ -1779,10 +1781,11 @@ char *circuit_list_path_for_controller(origin_circuit_t *circ);
 void circuit_log_path(int severity, unsigned int domain,
                       origin_circuit_t *circ);
 void circuit_rep_hist_note_result(origin_circuit_t *circ);
-origin_circuit_t *origin_circuit_init(uint8_t purpose, int need_uptime,
+origin_circuit_t *origin_circuit_init(uint8_t purpose, int onehop_tunnel,
+                                      int need_uptime,
                                       int need_capacity, int internal);
 origin_circuit_t *circuit_establish_circuit(uint8_t purpose,
-                                     extend_info_t *exit,
+                                     int onehop_tunnel, extend_info_t *exit,
                                      int need_uptime, int need_capacity,
                                      int internal);
 int circuit_handle_first_hop(origin_circuit_t *circ);
@@ -1877,14 +1880,18 @@ int circuit_enough_testing_circs(void);
 void circuit_has_opened(origin_circuit_t *circ);
 void circuit_build_failed(origin_circuit_t *circ);
 origin_circuit_t *circuit_launch_by_nickname(uint8_t purpose,
+                                      int onehop_tunnel,
                                       const char *exit_nickname,
                                       int need_uptime, int need_capacity,
                                       int is_internal);
 origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
+                                         int onehop_tunnel,
                                          extend_info_t *info,
                                          int need_uptime, int need_capacity,
                                          int is_internal);
-origin_circuit_t *circuit_launch_by_router(uint8_t purpose, routerinfo_t *exit,
+origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
+                                    int onehop_tunnel,
+                                    routerinfo_t *exit,
                                     int need_uptime, int need_capacity,
                                     int is_internal);
 void circuit_reset_failure_count(int timeout);

+ 3 - 3
src/or/rendservice.c

@@ -582,7 +582,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
    */
   for (i=0;i<MAX_REND_FAILURES;i++) {
     launched = circuit_launch_by_extend_info(
-          CIRCUIT_PURPOSE_S_CONNECT_REND, extend_info,
+          CIRCUIT_PURPOSE_S_CONNECT_REND, 0, extend_info,
           circ_needs_uptime, 1, 1);
 
     if (launched)
@@ -661,7 +661,7 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
   log_info(LD_REND,"Reattempting rendezvous circuit to '%s'",
            oldstate->chosen_exit->nickname);
 
-  newcirc = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND,
+  newcirc = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_CONNECT_REND, 0,
                                oldstate->chosen_exit, 0, 1, 1);
   if (!newcirc) {
     log_warn(LD_REND,"Couldn't relaunch rendezvous circuit to '%s'.",
@@ -698,7 +698,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
   rep_hist_note_used_internal(time(NULL), 1, 0);
 
   ++service->n_intro_circuits_launched;
-  launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
+  launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, 0,
                                         nickname, 1, 0, 1);
   if (!launched) {
     log_info(LD_REND,

+ 1 - 1
src/or/router.c

@@ -447,7 +447,7 @@ consider_testing_reachability(int test_or, int test_dir)
     log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
              !orport_reachable ? "reachability" : "bandwidth",
              me->address, me->or_port);
-    circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me, 0, 1, 1);
+    circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, 0, me, 0, 1, 1);
   }
 
   if (test_dir && !check_whether_dirport_reachable() &&