[tor-commits] [tor/master] Create the Extended ORPort authentication cookie file.

nickm at torproject.org nickm at torproject.org
Thu Aug 15 16:16:46 UTC 2013


commit d303228ecae1d4c5d9a242b12a4546366544a170
Author: George Kadianakis <desnacked at riseup.net>
Date:   Wed Dec 5 18:19:44 2012 +0200

    Create the Extended ORPort authentication cookie file.
---
 src/or/config.c        |   10 ++++--
 src/or/connection.c    |    9 ++++-
 src/or/connection_or.c |   92 +++++++++++++++++++++++++++++++++++++++++-------
 src/or/connection_or.h |    3 ++
 src/or/control.c       |    2 +-
 src/or/control.h       |    2 +-
 src/or/transports.c    |   20 ++++++++++-
 7 files changed, 120 insertions(+), 18 deletions(-)

diff --git a/src/or/config.c b/src/or/config.c
index afdee3d..6dad019 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1474,8 +1474,14 @@ options_act(const or_options_t *old_options)
     return -1;
   }
 
-  if (init_cookie_authentication(options->CookieAuthentication) < 0) {
-    log_warn(LD_CONFIG,"Error creating cookie authentication file.");
+  if (init_control_auth_cookie_authentication(options->CookieAuthentication) < 0) {
+    log_warn(LD_CONFIG,"Error creating control cookie authentication file.");
+    return -1;
+  }
+
+  /* If we have an ExtORPort, initialize its auth cookie. */
+  if (init_ext_or_auth_cookie_authentication(!!options->ExtORPort_lines) < 0) {
+    log_warn(LD_CONFIG,"Error creating Extended ORPort cookie file.");
     return -1;
   }
 
diff --git a/src/or/connection.c b/src/or/connection.c
index 130b1ec..ad8e39c 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -592,8 +592,10 @@ connection_free_(connection_t *conn)
     log_warn(LD_BUG, "called on OR conn with non-zeroed identity_digest");
     connection_or_remove_from_identity_map(TO_OR_CONN(conn));
   }
-  if (conn->type == CONN_TYPE_OR || conn->type == CONN_TYPE_EXT_OR)
+  if (conn->type == CONN_TYPE_OR || conn->type == CONN_TYPE_EXT_OR) {
     connection_or_remove_from_ext_or_id_map(TO_OR_CONN(conn));
+    tor_free(TO_OR_CONN(conn)->ext_or_conn_id);
+  }
 
 #ifdef USE_BUFFEREVENTS
   if (conn->type == CONN_TYPE_OR && TO_OR_CONN(conn)->bucket_cfg) {
@@ -4343,6 +4345,7 @@ assert_connection_ok(connection_t *conn, time_t now)
 
   switch (conn->type) {
     case CONN_TYPE_OR:
+    case CONN_TYPE_EXT_OR:
       tor_assert(conn->magic == OR_CONNECTION_MAGIC);
       break;
     case CONN_TYPE_AP:
@@ -4447,6 +4450,9 @@ assert_connection_ok(connection_t *conn, time_t now)
     case CONN_TYPE_OR:
       tor_assert(conn->state >= OR_CONN_STATE_MIN_);
       tor_assert(conn->state <= OR_CONN_STATE_MAX_);
+    case CONN_TYPE_EXT_OR:
+      tor_assert(conn->state >= EXT_OR_CONN_STATE_MIN_);
+      tor_assert(conn->state <= EXT_OR_CONN_STATE_MAX_);
       break;
     case CONN_TYPE_EXIT:
       tor_assert(conn->state >= EXIT_CONN_STATE_MIN_);
@@ -4580,6 +4586,7 @@ connection_free_all(void)
 
   /* Unlink everything from the identity map. */
   connection_or_clear_identity_map();
+  connection_or_clear_ext_or_id_map();
 
   /* Clear out our list of broken connections */
   clear_broken_connection_map(0);
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index ec5733f..e6fbb79 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -185,8 +185,10 @@ void
 connection_or_remove_from_ext_or_id_map(or_connection_t *conn)
 {
   or_connection_t *tmp;
-  if (!orconn_identity_map)
-    orconn_identity_map = digestmap_new();
+  if (!orconn_ext_or_id_map)
+    return;
+  if (!conn->ext_or_conn_id)
+    return;
 
   tmp = digestmap_remove(orconn_ext_or_id_map, conn->ext_or_conn_id);
   if (!tor_digest_is_zero(conn->ext_or_conn_id))
@@ -200,6 +202,7 @@ void
 connection_or_clear_ext_or_id_map(void)
 {
   digestmap_free(orconn_ext_or_id_map, NULL);
+  orconn_ext_or_id_map = NULL;
 }
 
 /** Creates an Extended ORPort identifier for <b>conn<b/> and deposits
@@ -214,13 +217,16 @@ connection_or_set_ext_or_identifier(or_connection_t *conn)
     orconn_ext_or_id_map = digestmap_new();
 
   /* Remove any previous identifiers: */
-  if (!tor_digest_is_zero(conn->ext_or_conn_id))
+  if (conn->ext_or_conn_id && !tor_digest_is_zero(conn->ext_or_conn_id))
       connection_or_remove_from_ext_or_id_map(conn);
 
   do {
     crypto_rand(random_id, sizeof(random_id));
   } while (digestmap_get(orconn_ext_or_id_map, random_id));
 
+  if (!conn->ext_or_conn_id)
+    conn->ext_or_conn_id = tor_malloc_zero(EXT_OR_CONN_ID_LEN);
+
   memcpy(conn->ext_or_conn_id, random_id, EXT_OR_CONN_ID_LEN);
 
   tmp = digestmap_set(orconn_ext_or_id_map, random_id, conn);
@@ -2484,7 +2490,75 @@ connection_ext_or_transition(or_connection_t *conn)
   connection_tls_start_handshake(conn, 1);
 }
 
-#define EXT_OR_CMD_WANT_CONTROL 0x0003
+/** DOCDOCDOC */
+#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
+#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
+
+/** If true, we've set ext_or_auth_cookie to a secret code and stored
+ * it to disk. */
+static int ext_or_auth_cookie_is_set = 0;
+/** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
+ * and which we're using to authenticate controllers.  (If the controller can
+ * read it off disk, it has permission to connect.) */
+static char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
+
+/** Helper: Return a newly allocated string containing a path to the
+ * file where we store our authentication cookie. */
+char *
+get_ext_or_auth_cookie_file(void)
+{
+  const or_options_t *options = get_options();
+  if (options->ExtORPortCookieAuthFile && strlen(options->ExtORPortCookieAuthFile)) {
+    return tor_strdup(options->ExtORPortCookieAuthFile);
+  } else {
+    return get_datadir_fname("extended_orport_auth_cookie");
+  }
+}
+
+/** Choose a random authentication cookie and write it to disk.
+ * Anybody who can read the cookie from disk will be considered
+ * authorized to use the control connection. Return -1 if we can't
+ * write the file, or 0 on success. */
+int
+init_ext_or_auth_cookie_authentication(int is_enabled)
+{
+  char *fname;
+  char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
+
+  if (!is_enabled) {
+    ext_or_auth_cookie_is_set = 0;
+    return 0;
+  }
+
+  /* We don't want to generate a new cookie every time we call
+   * options_act(). One should be enough. */
+  if (ext_or_auth_cookie_is_set)
+    return 0; /* all set */
+
+  fname = get_ext_or_auth_cookie_file();
+  crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
+  ext_or_auth_cookie_is_set = 1;
+
+  memcpy(cookie_file_string, EXT_OR_PORT_AUTH_COOKIE_HEADER, EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN);
+  memcpy(cookie_file_string+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN,
+         ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
+
+  if (write_bytes_to_file(fname, cookie_file_string,
+                          EXT_OR_PORT_AUTH_COOKIE_FILE_LEN, 1)) {
+    log_warn(LD_FS,"Error writing authentication cookie to %s.",
+             escaped(fname));
+    tor_free(fname);
+    return -1;
+  }
+
+  log_warn(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
+           fname);
+
+  tor_free(fname);
+  return 0;
+}
 
 /** Extended ORPort commands (Transport-to-Bridge) */
 #define EXT_OR_CMD_TB_DONE 0x0000
@@ -2553,14 +2627,6 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
       /* record the address */
       tor_addr_copy(&conn->addr, &addr);
       conn->port = port;
-    } else if (command->cmd == EXT_OR_CMD_WANT_CONTROL) {
-      char response[128];
-      char *cp;
-      memcpy(response, or_conn->ext_or_conn_id, EXT_OR_CONN_ID_LEN);
-      cp = response+EXT_OR_CONN_ID_LEN;
-      /* XXXX write the TransportControlPort; advance cp. */
-      connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, response,
-                                      cp-response);
     } else {
       log_notice(LD_NET, "Got an Extended ORPort command we don't understand (%u).",
                  command->cmd);
@@ -2569,6 +2635,8 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
     ext_or_cmd_free(command);
   }
 
+  return 0;
+
  err:
   ext_or_cmd_free(command);
   return -1;
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index a80871d..1e9a652 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -104,5 +104,8 @@ void connection_or_clear_ext_or_id_map(void);
 int connection_ext_or_finished_flushing(or_connection_t *conn);
 int connection_ext_or_process_inbuf(or_connection_t *or_conn);
 
+int init_ext_or_auth_cookie_authentication(int is_enabled);
+char *get_ext_or_auth_cookie_file(void);
+
 #endif
 
diff --git a/src/or/control.c b/src/or/control.c
index 3f8d47c..e83a8e0 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -4451,7 +4451,7 @@ get_cookie_file(void)
  * authorized to use the control connection. Return -1 if we can't
  * write the file, or 0 on success. */
 int
-init_cookie_authentication(int enabled)
+init_control_auth_cookie_authentication(int enabled)
 {
   char *fname;
   if (!enabled) {
diff --git a/src/or/control.h b/src/or/control.h
index d0f6820..663824c 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -77,7 +77,7 @@ int control_event_buildtimeout_set(const circuit_build_times_t *cbt,
                                    buildtimeout_set_event_t type);
 int control_event_signal(uintptr_t signal);
 
-int init_cookie_authentication(int enabled);
+int init_control_auth_cookie_authentication(int enabled);
 smartlist_t *decode_hashed_passwords(config_line_t *passwords);
 void disable_control_logging(void);
 void enable_control_logging(void);
diff --git a/src/or/transports.c b/src/or/transports.c
index 15faa98..877dc0c 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -96,6 +96,7 @@
 #include "router.h"
 #include "statefile.h"
 #include "entrynodes.h"
+#include "connection_or.h"
 
 static process_environment_t *
 create_managed_proxy_environment(const managed_proxy_t *mp);
@@ -1194,6 +1195,8 @@ get_bindaddr_for_server_proxy(const managed_proxy_t *mp)
 static process_environment_t *
 create_managed_proxy_environment(const managed_proxy_t *mp)
 {
+  const or_options_t *options = get_options();
+
   /* Environment variables to be added to or set in mp's environment. */
   smartlist_t *envs = smartlist_new();
   /* XXXX The next time someone touches this code, shorten the name of
@@ -1257,7 +1260,22 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
      * (If we remove this line entirely, some joker will stick this
      * variable in Tor's environment and crash PTs that try to parse
      * it even when not run in server mode.) */
-    smartlist_add(envs, tor_strdup("TOR_PT_EXTENDED_SERVER_PORT="));
+
+    if (options->ExtORPort) {
+      char *ext_or_addrport_tmp =
+        get_first_listener_addrport_string(CONN_TYPE_EXT_OR_LISTENER);
+      char *cookie_file_loc = get_ext_or_auth_cookie_file();
+
+      smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=%s",
+                             ext_or_addrport_tmp);
+      smartlist_add_asprintf(envs, "TOR_PT_AUTH_COOKIE_FILE=%s", cookie_file_loc);
+
+      tor_free(ext_or_addrport_tmp);
+      tor_free(cookie_file_loc);
+
+    } else {
+      smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=");
+    }
   }
 
   SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {





More information about the tor-commits mailing list