tor-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
August 2013
- 19 participants
- 1224 discussions

[tor/master] Create the Extended ORPort authentication cookie file.
by nickm@torproject.org 15 Aug '13
by nickm@torproject.org 15 Aug '13
15 Aug '13
commit d303228ecae1d4c5d9a242b12a4546366544a170
Author: George Kadianakis <desnacked(a)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) {
1
0

15 Aug '13
commit 85b7c73168eee63d81b4c1c9205e345d7aa8e773
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Sun Nov 25 16:26:16 2012 +0200
Move USERADDR handling to a dedicated function.
---
src/or/connection_or.c | 98 +++++++++++++++++++++++++-----------------------
1 file changed, 52 insertions(+), 46 deletions(-)
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index db2ac9f..4139670 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -2564,15 +2564,6 @@ init_ext_or_auth_cookie_authentication(int is_enabled)
return 0;
}
-/** Extended ORPort commands (Transport-to-Bridge) */
-#define EXT_OR_CMD_TB_DONE 0x0000
-#define EXT_OR_CMD_TB_USERADDR 0x0001
-
-/** Extended ORPort commands (Bridge-to-Transport) */
-#define EXT_OR_CMD_BT_OKAY 0x1000
-#define EXT_OR_CMD_BT_DENY 0x1001
-#define EXT_OR_CMD_BT_CONTROL 0x1002
-
/** DOCDOCDOC
Return -1 on error. 0 on unsufficient data. 1 on correct.
*/
@@ -2761,6 +2752,57 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
}
}
+/** Extended ORPort commands (Transport-to-Bridge) */
+#define EXT_OR_CMD_TB_DONE 0x0000
+#define EXT_OR_CMD_TB_USERADDR 0x0001
+
+/** Extended ORPort commands (Bridge-to-Transport) */
+#define EXT_OR_CMD_BT_OKAY 0x1000
+#define EXT_OR_CMD_BT_DENY 0x1001
+#define EXT_OR_CMD_BT_CONTROL 0x1002
+
+static int
+connection_ext_or_handle_useraddr(connection_t *conn, char *payload, uint16_t len)
+{
+ /* Copy address string. */
+ tor_addr_t addr;
+ uint16_t port;
+ char *addr_str;
+ char *address_part=NULL;
+ int res;
+ addr_str = tor_malloc(len + 1);
+ memcpy(addr_str, payload, len);
+ addr_str[len] = 0;
+
+ res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
+ tor_free(addr_str);
+ if (res<0)
+ return -1;
+
+ res = tor_addr_parse(&addr, address_part);
+ tor_free(address_part);
+ if (res<0)
+ return -1;
+
+ { /* do some logging */
+ char *old_address = tor_dup_addr(&conn->addr);
+ char *new_address = tor_dup_addr(&addr);
+
+ log_warn(LD_NET, "Received USERADDR." /* XXX FIX ALL LOG SEVERITIES AND MESSAGES */
+ "We rewrite our address from '%s:%u' to '%s:%u'.",
+ safe_str(old_address), conn->port, safe_str(new_address), port);
+
+ tor_free(old_address);
+ tor_free(new_address);
+ }
+
+ /* record the address */
+ tor_addr_copy(&conn->addr, &addr);
+ conn->port = port;
+
+ return 0;
+}
+
/** Process Extended ORPort messages from <b>or_conn</b>. */
int
connection_ext_or_process_inbuf(or_connection_t *or_conn)
@@ -2810,44 +2852,8 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
conn->state = EXT_OR_CONN_STATE_FLUSHING;
connection_stop_reading(conn);
} else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
- /* XXX Put this in a function of its own. We need to empasize
- that we change the address and port of this connection. */
-
- /* Copy address string. */
- tor_addr_t addr;
- uint16_t port;
- char *addr_str;
- char *address_part=NULL;
- int res;
- addr_str = tor_malloc(command->len + 1);
- memcpy(addr_str, command->body, command->len);
- addr_str[command->len] = 0;
-
- res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
- tor_free(addr_str);
- if (res<0)
- goto err;
-
- res = tor_addr_parse(&addr, address_part);
- tor_free(address_part);
- if (res<0)
+ if (connection_ext_or_handle_useraddr(conn, command->body, command->len) < 0)
goto err;
-
- {
- char *old_address = tor_dup_addr(&conn->addr);
- char *new_address = tor_dup_addr(&addr);
-
- log_warn(LD_NET, "Received USERADDR." /* XXX FIX ALL LOG SEVERITIES AND MESSAGES */
- "We rewrite our address from '%s:%u' to '%s:%u'.",
- safe_str(old_address), conn->port, safe_str(new_address), port);
-
- tor_free(old_address);
- tor_free(new_address);
- }
-
- /* record the address */
- tor_addr_copy(&conn->addr, &addr);
- conn->port = port;
} else {
log_notice(LD_NET, "Got an Extended ORPort command we don't understand (%u).",
command->cmd);
1
0
commit 2207525a69702a13ad0b3c0346b8c3fdb90824c0
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed Dec 5 19:16:04 2012 +0200
Satisfy check-spaces.
---
src/or/config.c | 2 +-
src/or/connection_or.c | 41 ++++++++++++++++++++++++++---------------
src/or/control.c | 2 +-
src/or/control.h | 2 +-
src/or/transports.c | 3 ++-
5 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c
index 6dad019..19da45a 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1474,7 +1474,7 @@ options_act(const or_options_t *old_options)
return -1;
}
- if (init_control_auth_cookie_authentication(options->CookieAuthentication) < 0) {
+ if (init_control_cookie_authentication(options->CookieAuthentication) < 0) {
log_warn(LD_CONFIG,"Error creating control cookie authentication file.");
return -1;
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 089bb06..d6d74a7 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -2498,7 +2498,8 @@ connection_ext_or_transition(or_connection_t *conn)
/** Length of the header of the cookie file. */
#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
/** Total length of the cookie file. */
-#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_FILE_LEN \
+ EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
/** Static cookie file header. */
#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
/** Length of safe-cookie protocol hashes. */
@@ -2506,8 +2507,10 @@ connection_ext_or_transition(or_connection_t *conn)
/** Length of safe-cookie protocol nonces. */
#define EXT_OR_PORT_AUTH_NONCE_LEN 32
/** Safe-cookie protocol constants. */
-#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST "ExtORPort authentication server-to-client hash"
-#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST "ExtORPort authentication client-to-server hash"
+#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
+ "ExtORPort authentication server-to-client hash"
+#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
+ "ExtORPort authentication client-to-server hash"
/** If true, we've set ext_or_auth_cookie to a secret code and stored
* it to disk. */
@@ -2523,7 +2526,8 @@ char *
get_ext_or_auth_cookie_file(void)
{
const or_options_t *options = get_options();
- if (options->ExtORPortCookieAuthFile && strlen(options->ExtORPortCookieAuthFile)) {
+ if (options->ExtORPortCookieAuthFile &&
+ strlen(options->ExtORPortCookieAuthFile)) {
return tor_strdup(options->ExtORPortCookieAuthFile);
} else {
return get_datadir_fname("extended_orport_auth_cookie");
@@ -2554,7 +2558,8 @@ init_ext_or_auth_cookie_authentication(int is_enabled)
return -1;
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,
+ 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);
@@ -2624,7 +2629,8 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
return 0;
- if (connection_fetch_from_buf(client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
+ if (connection_fetch_from_buf(client_nonce,
+ EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
return -1;
/* Get our nonce */
@@ -2679,7 +2685,7 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
tor_free(hmac_c_msg);
}
- { /* debug logging */ /* XXX disable this codepath if not logging on debug? */
+ { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
@@ -2691,13 +2697,15 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
client_nonce, sizeof(client_nonce));
- log_warn(LD_GENERAL, "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
+ log_warn(LD_GENERAL,
+ "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
}
{ /* write reply: (server_hash, server_nonce) */
memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
- memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+ memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
+ EXT_OR_PORT_AUTH_NONCE_LEN);
connection_write_to_buf(reply, sizeof(reply), conn);
}
@@ -2738,7 +2746,8 @@ connection_ext_or_auth_handle_client_hash(connection_t *conn)
if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
return 0;
- if (connection_fetch_from_buf(provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
+ if (connection_fetch_from_buf(provided_client_hash,
+ EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
return -1;
if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
@@ -2789,7 +2798,6 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
#define EXT_OR_CMD_BT_DENY 0x1001
#define EXT_OR_CMD_BT_CONTROL 0x1002
-
/** Process a USERADDR command from the Extended
* ORPort. <b>payload</b> is a payload of size <b>len</b>.
*
@@ -2798,7 +2806,8 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
*
* Return 0 on success and -1 on error. */
static int
-connection_ext_or_handle_useraddr(connection_t *conn, char *payload, uint16_t len)
+connection_ext_or_handle_useraddr(connection_t *conn,
+ char *payload, uint16_t len)
{
/* Copy address string. */
tor_addr_t addr;
@@ -2824,7 +2833,7 @@ connection_ext_or_handle_useraddr(connection_t *conn, char *payload, uint16_t le
char *old_address = tor_dup_addr(&conn->addr);
char *new_address = tor_dup_addr(&addr);
- log_warn(LD_NET, "Received USERADDR." /* XXX FIX ALL LOG SEVERITIES AND MESSAGES */
+ log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
"We rewrite our address from '%s:%u' to '%s:%u'.",
safe_str(old_address), conn->port, safe_str(new_address), port);
@@ -2888,10 +2897,11 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
conn->state = EXT_OR_CONN_STATE_FLUSHING;
connection_stop_reading(conn);
} else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
- if (connection_ext_or_handle_useraddr(conn, command->body, command->len) < 0)
+ if (connection_ext_or_handle_useraddr(conn,
+ command->body, command->len) < 0)
goto err;
} else {
- log_notice(LD_NET, "Got an Extended ORPort command we don't understand (%u).",
+ log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
command->cmd);
}
@@ -2935,3 +2945,4 @@ connection_ext_or_start_auth(or_connection_t *or_conn)
return 0;
}
+
diff --git a/src/or/control.c b/src/or/control.c
index e83a8e0..faf7942 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_control_auth_cookie_authentication(int enabled)
+init_control_cookie_authentication(int enabled)
{
char *fname;
if (!enabled) {
diff --git a/src/or/control.h b/src/or/control.h
index 663824c..288c286 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_control_auth_cookie_authentication(int enabled);
+int init_control_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 474a9db..8beb9a5c 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -1268,7 +1268,8 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
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);
+ smartlist_add_asprintf(envs, "TOR_PT_AUTH_COOKIE_FILE=%s",
+ cookie_file_loc);
tor_free(ext_or_addrport_tmp);
tor_free(cookie_file_loc);
1
0

15 Aug '13
commit e2e0d09dab0490724555d5c67c2a1d27fd5199c4
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed Dec 5 19:15:28 2012 +0200
Various Extended ORPort code improvements.
* Add documentation.
* Free ext_or_auth_correct_client_hash.
* Use VPORT(ExtORPort) instead of V(ExtORPOrt).
See dfe03d36c8749eb07e9bb2ea47e88ff05e9e3127 for details.
---
src/or/connection.c | 1 +
src/or/connection_or.c | 67 +++++++++++++++++++++++++++++++++++++-----------
src/or/transports.c | 2 +-
3 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/src/or/connection.c b/src/or/connection.c
index 9aea501..a2719e9 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -601,6 +601,7 @@ connection_free_(connection_t *conn)
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);
+ tor_free(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash);
}
#ifdef USE_BUFFEREVENTS
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 4139670..089bb06 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -179,8 +179,8 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
}
/** Remove the Extended ORPort identifier of <b>conn</b> from the
- global identifier list. Also, clear the identifier from the
- connection itself. */
+ * global identifier list. Also, clear the identifier from the
+ * connection itself. */
void
connection_or_remove_from_ext_or_id_map(or_connection_t *conn)
{
@@ -2443,7 +2443,10 @@ connection_or_send_authenticate_cell(or_connection_t *conn, int authtype)
return 0;
}
-/** Get an Extended ORPort message from <b>conn</b>, and place it in <b>out</b>. */
+/** Get an Extended ORPort message from <b>conn</b>, and place it in
+ * <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
+ * successfully extracted an Extended ORPort command from the
+ * buffer. */
static int
connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
{
@@ -2490,13 +2493,19 @@ connection_ext_or_transition(or_connection_t *conn)
connection_tls_start_handshake(conn, 1);
}
-/** DOCDOCDOC */
+/** Length of authentication cookie. */
#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
+/** Length of the header of the cookie file. */
#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
+/** Total length of the cookie file. */
#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
+/** Static cookie file header. */
#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
+/** Length of safe-cookie protocol hashes. */
#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
+/** Length of safe-cookie protocol nonces. */
#define EXT_OR_PORT_AUTH_NONCE_LEN 32
+/** Safe-cookie protocol constants. */
#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST "ExtORPort authentication server-to-client hash"
#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST "ExtORPort authentication client-to-server hash"
@@ -2541,14 +2550,15 @@ init_ext_or_auth_cookie_authentication(int is_enabled)
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);
+ if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
+ return -1;
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);
+ fname = get_ext_or_auth_cookie_file();
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.",
@@ -2564,11 +2574,15 @@ init_ext_or_auth_cookie_authentication(int is_enabled)
return 0;
}
-/** DOCDOCDOC
- Return -1 on error. 0 on unsufficient data. 1 on correct.
-*/
+/** Read data from <b>conn</b> and see if the client sent us the
+ * authentication type that she prefers to use in this session.
+ *
+ * Return -1 if we received corrupted data or if we don't support the
+ * authentication type. Return 0 if we need more data in
+ * <b>conn</b>. Return 1 if the authentication type negotiation was
+ * successful. */
static int
-connection_ext_or_auth_neg_auth_type(connection_t *conn) /* XXX unit tests */
+connection_ext_or_auth_neg_auth_type(connection_t *conn)
{
char authtype[1] = {0};
@@ -2582,10 +2596,16 @@ connection_ext_or_auth_neg_auth_type(connection_t *conn) /* XXX unit tests */
if (authtype[0] != 1) /* '1' is the only auth type supported atm */
return -1;
- conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE; /* XXX maybe do state transition in process_inbuf ? */
+ conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
return 1;
}
+/** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
+ * crypto, and then send our own hash and nonce to the client
+ *
+ * Return -1 if there was an error; return 0 if we need more data in
+ * <b>conn</b>, and return 1 if we successfully retrieved the
+ * client's nonce and sent our own. */
static int
connection_ext_or_auth_handle_client_nonce(connection_t *conn)
{
@@ -2692,6 +2712,8 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
#define connection_ext_or_auth_send_result_fail(c) \
connection_ext_or_auth_send_result(c, 0)
+/** Send authentication results to <b>conn</b>. Successful results if
+ * <b>success</b> is set; failure results otherwise. */
static void
connection_ext_or_auth_send_result(connection_t *conn, int success)
{
@@ -2701,6 +2723,13 @@ connection_ext_or_auth_send_result(connection_t *conn, int success)
connection_write_to_buf("\x00", 1, conn);
}
+/** Receive the client's hash from <b>conn</b>, validate that it's
+ * correct, and then send the authentication results to the client.
+ *
+ * Return -1 if there was an error during validation; return 0 if we
+ * need more data in <b>conn</b>, and return 1 if we successfully
+ * validated the client's hash and sent a happy authentication
+ * result. */
static int
connection_ext_or_auth_handle_client_hash(connection_t *conn)
{
@@ -2727,9 +2756,8 @@ connection_ext_or_auth_handle_client_hash(connection_t *conn)
return 1;
}
-/** DOCDOCDOC
- Return -1 on error. 0 on unsufficient data. 1 on correct.
-*/
+/** Handle data from <b>or_conn</b> received on Extended ORPort.
+ * Return -1 on error. 0 on unsufficient data. 1 on correct. */
static int
connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
{
@@ -2761,6 +2789,14 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
#define EXT_OR_CMD_BT_DENY 0x1001
#define EXT_OR_CMD_BT_CONTROL 0x1002
+
+/** Process a USERADDR command from the Extended
+ * ORPort. <b>payload</b> is a payload of size <b>len</b>.
+ *
+ * If the USERADDR command was well formed, change the address of
+ * <b>conn</b> to the address on the USERADDR command.
+ *
+ * Return 0 on success and -1 on error. */
static int
connection_ext_or_handle_useraddr(connection_t *conn, char *payload, uint16_t len)
{
@@ -2883,7 +2919,8 @@ connection_ext_or_finished_flushing(or_connection_t *conn)
return 0;
}
-/* DOCDOCDOC */
+/** Initiate Extended ORPort authentication, by sending the list of
+ * supported authentication types to the client. */
int
connection_ext_or_start_auth(or_connection_t *or_conn)
{
diff --git a/src/or/transports.c b/src/or/transports.c
index 877dc0c..474a9db 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -1261,7 +1261,7 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
* variable in Tor's environment and crash PTs that try to parse
* it even when not run in server mode.) */
- if (options->ExtORPort) {
+ if (options->ExtORPort_lines) {
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();
1
0

15 Aug '13
commit d8f74cc439ad025cc52aea8495705096d6538029
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed Dec 5 19:18:18 2012 +0200
Move Extended ORPort code to its own module.
Move the code from the connection_or module to ext_orport.
This commit only moves code: it shouldn't modify anything.
---
src/or/buffers.c | 1 +
src/or/config.c | 1 +
src/or/connection.c | 1 +
src/or/connection_or.c | 524 +---------------------------------------------
src/or/connection_or.h | 14 --
src/or/ext_orport.c | 537 ++++++++++++++++++++++++++++++++++++++++++++++++
src/or/ext_orport.h | 14 ++
src/or/include.am | 2 +
src/or/transports.c | 1 +
9 files changed, 558 insertions(+), 537 deletions(-)
diff --git a/src/or/buffers.c b/src/or/buffers.c
index ead6baa..50016d3 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -19,6 +19,7 @@
#include "connection_or.h"
#include "control.h"
#include "reasons.h"
+#include "ext_orport.h"
#include "../common/util.h"
#include "../common/torlog.h"
#ifdef HAVE_UNISTD_H
diff --git a/src/or/config.c b/src/or/config.c
index 19da45a..542191d 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -45,6 +45,7 @@
#include "routerset.h"
#include "statefile.h"
#include "transports.h"
+#include "ext_orport.h"
#ifdef _WIN32
#include <shlobj.h>
#endif
diff --git a/src/or/connection.c b/src/or/connection.c
index a2719e9..fcdc9ab 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -33,6 +33,7 @@
#include "dns.h"
#include "dnsserv.h"
#include "entrynodes.h"
+#include "ext_orport.h"
#include "geoip.h"
#include "main.h"
#include "policies.h"
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index d6d74a7..42127ad 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -37,7 +37,7 @@
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
-
+#include "ext_orport.h"
#ifdef USE_BUFFEREVENTS
#include <event2/bufferevent_ssl.h>
#endif
@@ -482,24 +482,6 @@ var_cell_free(var_cell_t *cell)
tor_free(cell);
}
-/** Allocate and return a structure capable of holding an Extended
- * ORPort message of body length <b>len</b>. */
-ext_or_cmd_t *
-ext_or_cmd_new(uint16_t len)
-{
- size_t size = STRUCT_OFFSET(ext_or_cmd_t, body) + len;
- ext_or_cmd_t *cmd = tor_malloc(size);
- cmd->len = len;
- return cmd;
-}
-
-/** Deallocate the Extended ORPort message in <b>cmd</b>. */
-void
-ext_or_cmd_free(ext_or_cmd_t *cmd)
-{
- tor_free(cmd);
-}
-
/** We've received an EOF from <b>conn</b>. Mark it for close and return. */
int
connection_or_reached_eof(or_connection_t *conn)
@@ -2442,507 +2424,3 @@ connection_or_send_authenticate_cell(or_connection_t *conn, int authtype)
return 0;
}
-
-/** Get an Extended ORPort message from <b>conn</b>, and place it in
- * <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
- * successfully extracted an Extended ORPort command from the
- * buffer. */
-static int
-connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
-{
- IF_HAS_BUFFEREVENT(conn, {
- struct evbuffer *input = bufferevent_get_input(conn->bufev);
- return fetch_ext_or_command_from_evbuffer(input, out);
- }) ELSE_IF_NO_BUFFEREVENT {
- return fetch_ext_or_command_from_buf(conn->inbuf, out);
- }
-}
-
-/** Write an Extended ORPort message to <b>conn</b>. Use
- * <b>command</b> as the command type, <b>bodylen</b> as the body
- * length, and <b>body</b>, if it's present, as the body of the
- * message. */
-static int
-connection_write_ext_or_command(connection_t *conn,
- uint16_t command,
- const char *body,
- size_t bodylen)
-{
- char header[4];
- if (bodylen > UINT16_MAX)
- return -1;
- set_uint16(header, htons(command));
- set_uint16(header+2, htons(bodylen));
- connection_write_to_buf(header, 4, conn);
- if (bodylen) {
- tor_assert(body);
- connection_write_to_buf(body, bodylen, conn);
- }
- return 0;
-}
-
-/** Transition from an Extended ORPort which accepts Extended ORPort
- * messages, to an Extended ORport which accepts OR traffic. */
-static void
-connection_ext_or_transition(or_connection_t *conn)
-{
- tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
-
- conn->base_.type = CONN_TYPE_OR;
- control_event_or_conn_status(conn, OR_CONN_EVENT_NEW, 0);
- connection_tls_start_handshake(conn, 1);
-}
-
-/** Length of authentication cookie. */
-#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
-/** Length of the header of the cookie file. */
-#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
-/** Total length of the cookie file. */
-#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN \
- EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
-/** Static cookie file header. */
-#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
-/** Length of safe-cookie protocol hashes. */
-#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
-/** Length of safe-cookie protocol nonces. */
-#define EXT_OR_PORT_AUTH_NONCE_LEN 32
-/** Safe-cookie protocol constants. */
-#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
- "ExtORPort authentication server-to-client hash"
-#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
- "ExtORPort authentication client-to-server hash"
-
-/** 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 */
-
- if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
- return -1;
- 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);
-
- fname = get_ext_or_auth_cookie_file();
- 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;
-}
-
-/** Read data from <b>conn</b> and see if the client sent us the
- * authentication type that she prefers to use in this session.
- *
- * Return -1 if we received corrupted data or if we don't support the
- * authentication type. Return 0 if we need more data in
- * <b>conn</b>. Return 1 if the authentication type negotiation was
- * successful. */
-static int
-connection_ext_or_auth_neg_auth_type(connection_t *conn)
-{
- char authtype[1] = {0};
-
- if (connection_get_inbuf_len(conn) < 1)
- return 0;
-
- if (connection_fetch_from_buf(authtype, 1, conn) < 0)
- return -1;
-
- log_warn(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
- if (authtype[0] != 1) /* '1' is the only auth type supported atm */
- return -1;
-
- conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
- return 1;
-}
-
-/** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
- * crypto, and then send our own hash and nonce to the client
- *
- * Return -1 if there was an error; return 0 if we need more data in
- * <b>conn</b>, and return 1 if we successfully retrieved the
- * client's nonce and sent our own. */
-static int
-connection_ext_or_auth_handle_client_nonce(connection_t *conn)
-{
- char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
- char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
- char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
- char reply[EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
-
- if (!ext_or_auth_cookie_is_set) { /* this should not happen */
- log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
- "That's weird since we should have done that on startup. "
- "This might be a Tor bug, please file a bug report. ");
- return -1;
- }
-
- if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
- return 0;
-
- if (connection_fetch_from_buf(client_nonce,
- EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
- return -1;
-
- /* Get our nonce */
- if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
- return -1;
-
- { /* set up macs */
- size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
- 2*EXT_OR_PORT_AUTH_NONCE_LEN;
- size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
- 2*EXT_OR_PORT_AUTH_NONCE_LEN;
-
- char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
- char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
- char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
-
- memcpy(hmac_s_msg,
- EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
- strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
- memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
- client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
- memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
- EXT_OR_PORT_AUTH_NONCE_LEN,
- server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-
- memcpy(hmac_c_msg,
- EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
- strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
- memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
- client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
- memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
- EXT_OR_PORT_AUTH_NONCE_LEN,
- server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
-
- crypto_hmac_sha256(server_hash,
- ext_or_auth_cookie,
- EXT_OR_PORT_AUTH_COOKIE_LEN,
- hmac_s_msg,
- hmac_s_msg_len);
-
- crypto_hmac_sha256(correct_client_hash,
- ext_or_auth_cookie,
- EXT_OR_PORT_AUTH_COOKIE_LEN,
- hmac_c_msg,
- hmac_c_msg_len);
-
- /* Store the client hash we generated. We will need to compare it
- with the hash sent by the client. */
- TO_OR_CONN(conn)->ext_or_auth_correct_client_hash = correct_client_hash;
-
- tor_free(hmac_s_msg);
- tor_free(hmac_c_msg);
- }
-
- { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
- char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
- char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
- char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
-
- base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
- server_hash, sizeof(server_hash));
- base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
- server_nonce, sizeof(server_nonce));
- base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
- client_nonce, sizeof(client_nonce));
-
- log_warn(LD_GENERAL,
- "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
- server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
- }
-
- { /* write reply: (server_hash, server_nonce) */
- memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
- memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
- EXT_OR_PORT_AUTH_NONCE_LEN);
- connection_write_to_buf(reply, sizeof(reply), conn);
- }
-
- log_warn(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
-
- conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
- return 1;
-}
-
-#define connection_ext_or_auth_send_result_success(c) \
- connection_ext_or_auth_send_result(c, 1)
-#define connection_ext_or_auth_send_result_fail(c) \
- connection_ext_or_auth_send_result(c, 0)
-
-/** Send authentication results to <b>conn</b>. Successful results if
- * <b>success</b> is set; failure results otherwise. */
-static void
-connection_ext_or_auth_send_result(connection_t *conn, int success)
-{
- if (success)
- connection_write_to_buf("\x01", 1, conn);
- else
- connection_write_to_buf("\x00", 1, conn);
-}
-
-/** Receive the client's hash from <b>conn</b>, validate that it's
- * correct, and then send the authentication results to the client.
- *
- * Return -1 if there was an error during validation; return 0 if we
- * need more data in <b>conn</b>, and return 1 if we successfully
- * validated the client's hash and sent a happy authentication
- * result. */
-static int
-connection_ext_or_auth_handle_client_hash(connection_t *conn)
-{
- char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
-
- if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
- return 0;
-
- if (connection_fetch_from_buf(provided_client_hash,
- EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
- return -1;
-
- if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
- provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
- log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
- connection_ext_or_auth_send_result_fail(conn);
- return -1;
- }
-
- log_warn(LD_GENERAL, "Got client's hash and it was legit.");
-
- /* send positive auth result */
- connection_ext_or_auth_send_result_success(conn);
- conn->state = EXT_OR_CONN_STATE_OPEN;
- return 1;
-}
-
-/** Handle data from <b>or_conn</b> received on Extended ORPort.
- * Return -1 on error. 0 on unsufficient data. 1 on correct. */
-static int
-connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
-{
- connection_t *conn = TO_CONN(or_conn);
-
- switch (conn->state) { /* Functionify */
- case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
- return connection_ext_or_auth_neg_auth_type(conn);
-
- case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
- return connection_ext_or_auth_handle_client_nonce(conn);
-
- case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
- return connection_ext_or_auth_handle_client_hash(conn);
-
- default:
- log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
- "to process Extended ORPort authentication data.", conn->state);
- return -1;
- }
-}
-
-/** Extended ORPort commands (Transport-to-Bridge) */
-#define EXT_OR_CMD_TB_DONE 0x0000
-#define EXT_OR_CMD_TB_USERADDR 0x0001
-
-/** Extended ORPort commands (Bridge-to-Transport) */
-#define EXT_OR_CMD_BT_OKAY 0x1000
-#define EXT_OR_CMD_BT_DENY 0x1001
-#define EXT_OR_CMD_BT_CONTROL 0x1002
-
-/** Process a USERADDR command from the Extended
- * ORPort. <b>payload</b> is a payload of size <b>len</b>.
- *
- * If the USERADDR command was well formed, change the address of
- * <b>conn</b> to the address on the USERADDR command.
- *
- * Return 0 on success and -1 on error. */
-static int
-connection_ext_or_handle_useraddr(connection_t *conn,
- char *payload, uint16_t len)
-{
- /* Copy address string. */
- tor_addr_t addr;
- uint16_t port;
- char *addr_str;
- char *address_part=NULL;
- int res;
- addr_str = tor_malloc(len + 1);
- memcpy(addr_str, payload, len);
- addr_str[len] = 0;
-
- res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
- tor_free(addr_str);
- if (res<0)
- return -1;
-
- res = tor_addr_parse(&addr, address_part);
- tor_free(address_part);
- if (res<0)
- return -1;
-
- { /* do some logging */
- char *old_address = tor_dup_addr(&conn->addr);
- char *new_address = tor_dup_addr(&addr);
-
- log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
- "We rewrite our address from '%s:%u' to '%s:%u'.",
- safe_str(old_address), conn->port, safe_str(new_address), port);
-
- tor_free(old_address);
- tor_free(new_address);
- }
-
- /* record the address */
- tor_addr_copy(&conn->addr, &addr);
- conn->port = port;
-
- return 0;
-}
-
-/** Process Extended ORPort messages from <b>or_conn</b>. */
-int
-connection_ext_or_process_inbuf(or_connection_t *or_conn)
-{
- connection_t *conn = TO_CONN(or_conn);
- ext_or_cmd_t *command;
- int r;
-
- /* If we are still in the authentication stage, process traffic as
- authentication data: */
- while (conn->state <= EXT_OR_CONN_STATE_AUTH_MAX) {
- log_warn(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
- (unsigned int) connection_get_inbuf_len(conn));
- r = connection_ext_or_auth_process_inbuf(or_conn);
- if (r < 0) {
- connection_mark_for_close(conn);
- return -1;
- } else if (r == 0) {
- return 0;
- }
- /* if r > 0, loop and process more data (if any). */
- }
-
- while (1) {
- log_warn(LD_GENERAL, "Got Extended ORPort data.");
- command = NULL;
- r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
- if (r < 0)
- goto err;
- else if (r == 0)
- return 0; /* need to wait for more data */
-
- /* Got a command! */
- tor_assert(command);
-
- if (command->cmd == EXT_OR_CMD_TB_DONE) {
- if (connection_get_inbuf_len(conn)) {
- /* The inbuf isn't empty; the client is misbehaving. */
- goto err;
- }
-
- log_debug(LD_NET, "Received DONE.");
-
- connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
-
- /* can't transition immediately; need to flush first. */
- conn->state = EXT_OR_CONN_STATE_FLUSHING;
- connection_stop_reading(conn);
- } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
- if (connection_ext_or_handle_useraddr(conn,
- command->body, command->len) < 0)
- goto err;
- } else {
- log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
- command->cmd);
- }
-
- ext_or_cmd_free(command);
- }
-
- return 0;
-
- err:
- ext_or_cmd_free(command);
- connection_mark_for_close(conn);
- return -1;
-}
-
-/** <b>conn</b> finished flushing Extended ORPort messages to the
- * network, and is now ready to accept OR traffic. This function
- * does the transition. */
-int
-connection_ext_or_finished_flushing(or_connection_t *conn)
-{
- if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
- connection_start_reading(TO_CONN(conn));
- connection_ext_or_transition(conn);
- }
- return 0;
-}
-
-/** Initiate Extended ORPort authentication, by sending the list of
- * supported authentication types to the client. */
-int
-connection_ext_or_start_auth(or_connection_t *or_conn)
-{
- connection_t *conn = TO_CONN(or_conn);
- char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
-
- log_warn(LD_GENERAL,
- "ExtORPort authentication: Sending supported authentication types");
-
- connection_write_to_buf(authtypes, sizeof(authtypes), conn);
- conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
-
- return 0;
-}
-
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index d420dc7..85e68f1 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -45,8 +45,6 @@ void connection_or_close_for_error(or_connection_t *orconn, int flush);
void connection_or_report_broken_states(int severity, int domain);
-int connection_ext_or_start_auth(or_connection_t *or_conn);
-
int connection_tls_start_handshake(or_connection_t *conn, int receiving);
int connection_tls_continue_handshake(or_connection_t *conn);
@@ -97,17 +95,5 @@ void var_cell_free(var_cell_t *cell);
/** DOCDOC */
#define MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS 4
-ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
-void ext_or_cmd_free(ext_or_cmd_t *cmd);
-void connection_or_set_ext_or_identifier(or_connection_t *conn);
-void connection_or_remove_from_ext_or_id_map(or_connection_t *conn);
-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/ext_orport.c b/src/or/ext_orport.c
new file mode 100644
index 0000000..18ee5ab
--- /dev/null
+++ b/src/or/ext_orport.c
@@ -0,0 +1,537 @@
+/* Copyright (c) 2012, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file ext_orport.c
+ * \brief Code implementing the Extended ORPort.
+*/
+
+#include "or.h"
+#include "connection.h"
+#include "connection_or.h"
+#include "ext_orport.h"
+#include "control.h"
+#include "config.h"
+#include "main.h"
+
+/** Allocate and return a structure capable of holding an Extended
+ * ORPort message of body length <b>len</b>. */
+ext_or_cmd_t *
+ext_or_cmd_new(uint16_t len)
+{
+ size_t size = STRUCT_OFFSET(ext_or_cmd_t, body) + len;
+ ext_or_cmd_t *cmd = tor_malloc(size);
+ cmd->len = len;
+ return cmd;
+}
+
+/** Deallocate the Extended ORPort message in <b>cmd</b>. */
+void
+ext_or_cmd_free(ext_or_cmd_t *cmd)
+{
+ tor_free(cmd);
+}
+
+/** Get an Extended ORPort message from <b>conn</b>, and place it in
+ * <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
+ * successfully extracted an Extended ORPort command from the
+ * buffer. */
+static int
+connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
+{
+ IF_HAS_BUFFEREVENT(conn, {
+ struct evbuffer *input = bufferevent_get_input(conn->bufev);
+ return fetch_ext_or_command_from_evbuffer(input, out);
+ }) ELSE_IF_NO_BUFFEREVENT {
+ return fetch_ext_or_command_from_buf(conn->inbuf, out);
+ }
+}
+
+/** Write an Extended ORPort message to <b>conn</b>. Use
+ * <b>command</b> as the command type, <b>bodylen</b> as the body
+ * length, and <b>body</b>, if it's present, as the body of the
+ * message. */
+static int
+connection_write_ext_or_command(connection_t *conn,
+ uint16_t command,
+ const char *body,
+ size_t bodylen)
+{
+ char header[4];
+ if (bodylen > UINT16_MAX)
+ return -1;
+ set_uint16(header, htons(command));
+ set_uint16(header+2, htons(bodylen));
+ connection_write_to_buf(header, 4, conn);
+ if (bodylen) {
+ tor_assert(body);
+ connection_write_to_buf(body, bodylen, conn);
+ }
+ return 0;
+}
+
+/** Transition from an Extended ORPort which accepts Extended ORPort
+ * messages, to an Extended ORport which accepts OR traffic. */
+static void
+connection_ext_or_transition(or_connection_t *conn)
+{
+ tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
+
+ conn->base_.type = CONN_TYPE_OR;
+ control_event_or_conn_status(conn, OR_CONN_EVENT_NEW, 0);
+ connection_tls_start_handshake(conn, 1);
+}
+
+/** Length of authentication cookie. */
+#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
+/** Length of the header of the cookie file. */
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
+/** Total length of the cookie file. */
+#define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN \
+ EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
+/** Static cookie file header. */
+#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
+/** Length of safe-cookie protocol hashes. */
+#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
+/** Length of safe-cookie protocol nonces. */
+#define EXT_OR_PORT_AUTH_NONCE_LEN 32
+/** Safe-cookie protocol constants. */
+#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
+ "ExtORPort authentication server-to-client hash"
+#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
+ "ExtORPort authentication client-to-server hash"
+
+/** 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 */
+
+ if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
+ return -1;
+ 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);
+
+ fname = get_ext_or_auth_cookie_file();
+ 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;
+}
+
+/** Read data from <b>conn</b> and see if the client sent us the
+ * authentication type that she prefers to use in this session.
+ *
+ * Return -1 if we received corrupted data or if we don't support the
+ * authentication type. Return 0 if we need more data in
+ * <b>conn</b>. Return 1 if the authentication type negotiation was
+ * successful. */
+static int
+connection_ext_or_auth_neg_auth_type(connection_t *conn)
+{
+ char authtype[1] = {0};
+
+ if (connection_get_inbuf_len(conn) < 1)
+ return 0;
+
+ if (connection_fetch_from_buf(authtype, 1, conn) < 0)
+ return -1;
+
+ log_warn(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
+ if (authtype[0] != 1) /* '1' is the only auth type supported atm */
+ return -1;
+
+ conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
+ return 1;
+}
+
+/** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
+ * crypto, and then send our own hash and nonce to the client
+ *
+ * Return -1 if there was an error; return 0 if we need more data in
+ * <b>conn</b>, and return 1 if we successfully retrieved the
+ * client's nonce and sent our own. */
+static int
+connection_ext_or_auth_handle_client_nonce(connection_t *conn)
+{
+ char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
+ char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+ char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+ char reply[EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
+
+ if (!ext_or_auth_cookie_is_set) { /* this should not happen */
+ log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
+ "That's weird since we should have done that on startup. "
+ "This might be a Tor bug, please file a bug report. ");
+ return -1;
+ }
+
+ if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
+ return 0;
+
+ if (connection_fetch_from_buf(client_nonce,
+ EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
+ return -1;
+
+ /* Get our nonce */
+ if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
+ return -1;
+
+ { /* set up macs */
+ size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
+ 2*EXT_OR_PORT_AUTH_NONCE_LEN;
+ size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
+ 2*EXT_OR_PORT_AUTH_NONCE_LEN;
+
+ char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
+ char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
+ char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
+
+ memcpy(hmac_s_msg,
+ EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
+ strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
+ memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
+ client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+ memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
+ EXT_OR_PORT_AUTH_NONCE_LEN,
+ server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+
+ memcpy(hmac_c_msg,
+ EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
+ strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
+ memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
+ client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+ memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
+ EXT_OR_PORT_AUTH_NONCE_LEN,
+ server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
+
+ crypto_hmac_sha256(server_hash,
+ ext_or_auth_cookie,
+ EXT_OR_PORT_AUTH_COOKIE_LEN,
+ hmac_s_msg,
+ hmac_s_msg_len);
+
+ crypto_hmac_sha256(correct_client_hash,
+ ext_or_auth_cookie,
+ EXT_OR_PORT_AUTH_COOKIE_LEN,
+ hmac_c_msg,
+ hmac_c_msg_len);
+
+ /* Store the client hash we generated. We will need to compare it
+ with the hash sent by the client. */
+ TO_OR_CONN(conn)->ext_or_auth_correct_client_hash = correct_client_hash;
+
+ tor_free(hmac_s_msg);
+ tor_free(hmac_c_msg);
+ }
+
+ { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
+ char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
+ char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
+ char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
+
+ base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
+ server_hash, sizeof(server_hash));
+ base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
+ server_nonce, sizeof(server_nonce));
+ base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
+ client_nonce, sizeof(client_nonce));
+
+ log_warn(LD_GENERAL,
+ "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
+ server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
+ }
+
+ { /* write reply: (server_hash, server_nonce) */
+ memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
+ memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
+ EXT_OR_PORT_AUTH_NONCE_LEN);
+ connection_write_to_buf(reply, sizeof(reply), conn);
+ }
+
+ log_warn(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
+
+ conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
+ return 1;
+}
+
+#define connection_ext_or_auth_send_result_success(c) \
+ connection_ext_or_auth_send_result(c, 1)
+#define connection_ext_or_auth_send_result_fail(c) \
+ connection_ext_or_auth_send_result(c, 0)
+
+/** Send authentication results to <b>conn</b>. Successful results if
+ * <b>success</b> is set; failure results otherwise. */
+static void
+connection_ext_or_auth_send_result(connection_t *conn, int success)
+{
+ if (success)
+ connection_write_to_buf("\x01", 1, conn);
+ else
+ connection_write_to_buf("\x00", 1, conn);
+}
+
+/** Receive the client's hash from <b>conn</b>, validate that it's
+ * correct, and then send the authentication results to the client.
+ *
+ * Return -1 if there was an error during validation; return 0 if we
+ * need more data in <b>conn</b>, and return 1 if we successfully
+ * validated the client's hash and sent a happy authentication
+ * result. */
+static int
+connection_ext_or_auth_handle_client_hash(connection_t *conn)
+{
+ char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
+
+ if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
+ return 0;
+
+ if (connection_fetch_from_buf(provided_client_hash,
+ EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
+ return -1;
+
+ if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
+ provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
+ log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
+ connection_ext_or_auth_send_result_fail(conn);
+ return -1;
+ }
+
+ log_warn(LD_GENERAL, "Got client's hash and it was legit.");
+
+ /* send positive auth result */
+ connection_ext_or_auth_send_result_success(conn);
+ conn->state = EXT_OR_CONN_STATE_OPEN;
+ return 1;
+}
+
+/** Handle data from <b>or_conn</b> received on Extended ORPort.
+ * Return -1 on error. 0 on unsufficient data. 1 on correct. */
+static int
+connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
+{
+ connection_t *conn = TO_CONN(or_conn);
+
+ switch (conn->state) { /* Functionify */
+ case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
+ return connection_ext_or_auth_neg_auth_type(conn);
+
+ case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
+ return connection_ext_or_auth_handle_client_nonce(conn);
+
+ case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
+ return connection_ext_or_auth_handle_client_hash(conn);
+
+ default:
+ log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
+ "to process Extended ORPort authentication data.", conn->state);
+ return -1;
+ }
+}
+
+/** Extended ORPort commands (Transport-to-Bridge) */
+#define EXT_OR_CMD_TB_DONE 0x0000
+#define EXT_OR_CMD_TB_USERADDR 0x0001
+
+/** Extended ORPort commands (Bridge-to-Transport) */
+#define EXT_OR_CMD_BT_OKAY 0x1000
+#define EXT_OR_CMD_BT_DENY 0x1001
+#define EXT_OR_CMD_BT_CONTROL 0x1002
+
+/** Process a USERADDR command from the Extended
+ * ORPort. <b>payload</b> is a payload of size <b>len</b>.
+ *
+ * If the USERADDR command was well formed, change the address of
+ * <b>conn</b> to the address on the USERADDR command.
+ *
+ * Return 0 on success and -1 on error. */
+static int
+connection_ext_or_handle_useraddr(connection_t *conn,
+ const char *payload, uint16_t len)
+{
+ /* Copy address string. */
+ tor_addr_t addr;
+ uint16_t port;
+ char *addr_str;
+ char *address_part=NULL;
+ int res;
+ addr_str = tor_malloc(len + 1);
+ memcpy(addr_str, payload, len);
+ addr_str[len] = 0;
+
+ res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
+ tor_free(addr_str);
+ if (res<0)
+ return -1;
+
+ res = tor_addr_parse(&addr, address_part);
+ tor_free(address_part);
+ if (res<0)
+ return -1;
+
+ { /* do some logging */
+ char *old_address = tor_dup_addr(&conn->addr);
+ char *new_address = tor_dup_addr(&addr);
+
+ log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
+ "We rewrite our address from '%s:%u' to '%s:%u'.",
+ safe_str(old_address), conn->port, safe_str(new_address), port);
+
+ tor_free(old_address);
+ tor_free(new_address);
+ }
+
+ /* record the address */
+ tor_addr_copy(&conn->addr, &addr);
+ conn->port = port;
+
+ return 0;
+}
+
+/** Process Extended ORPort messages from <b>or_conn</b>. */
+int
+connection_ext_or_process_inbuf(or_connection_t *or_conn)
+{
+ connection_t *conn = TO_CONN(or_conn);
+ ext_or_cmd_t *command;
+ int r;
+
+ /* If we are still in the authentication stage, process traffic as
+ authentication data: */
+ while (conn->state <= EXT_OR_CONN_STATE_AUTH_MAX) {
+ log_warn(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
+ (unsigned int) connection_get_inbuf_len(conn));
+ r = connection_ext_or_auth_process_inbuf(or_conn);
+ if (r < 0) {
+ connection_mark_for_close(conn);
+ return -1;
+ } else if (r == 0) {
+ return 0;
+ }
+ /* if r > 0, loop and process more data (if any). */
+ }
+
+ while (1) {
+ log_warn(LD_GENERAL, "Got Extended ORPort data.");
+ command = NULL;
+ r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
+ if (r < 0)
+ goto err;
+ else if (r == 0)
+ return 0; /* need to wait for more data */
+
+ /* Got a command! */
+ tor_assert(command);
+
+ if (command->cmd == EXT_OR_CMD_TB_DONE) {
+ if (connection_get_inbuf_len(conn)) {
+ /* The inbuf isn't empty; the client is misbehaving. */
+ goto err;
+ }
+
+ log_debug(LD_NET, "Received DONE.");
+
+ connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
+
+ /* can't transition immediately; need to flush first. */
+ conn->state = EXT_OR_CONN_STATE_FLUSHING;
+ connection_stop_reading(conn);
+ } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
+ if (connection_ext_or_handle_useraddr(conn,
+ command->body, command->len) < 0)
+ goto err;
+ } else {
+ log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
+ command->cmd);
+ }
+
+ ext_or_cmd_free(command);
+ }
+
+ return 0;
+
+ err:
+ ext_or_cmd_free(command);
+ connection_mark_for_close(conn);
+ return -1;
+}
+
+/** <b>conn</b> finished flushing Extended ORPort messages to the
+ * network, and is now ready to accept OR traffic. This function
+ * does the transition. */
+int
+connection_ext_or_finished_flushing(or_connection_t *conn)
+{
+ if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
+ connection_start_reading(TO_CONN(conn));
+ connection_ext_or_transition(conn);
+ }
+ return 0;
+}
+
+/** Initiate Extended ORPort authentication, by sending the list of
+ * supported authentication types to the client. */
+int
+connection_ext_or_start_auth(or_connection_t *or_conn)
+{
+ connection_t *conn = TO_CONN(or_conn);
+ char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
+
+ log_warn(LD_GENERAL,
+ "ExtORPort authentication: Sending supported authentication types");
+
+ connection_write_to_buf(authtypes, sizeof(authtypes), conn);
+ conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
+
+ return 0;
+}
+
diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h
new file mode 100644
index 0000000..fbd7ed6
--- /dev/null
+++ b/src/or/ext_orport.h
@@ -0,0 +1,14 @@
+int connection_ext_or_start_auth(or_connection_t *or_conn);
+
+ext_or_cmd_t *ext_or_cmd_new(uint16_t len);
+void ext_or_cmd_free(ext_or_cmd_t *cmd);
+void connection_or_set_ext_or_identifier(or_connection_t *conn);
+void connection_or_remove_from_ext_or_id_map(or_connection_t *conn);
+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);
+
diff --git a/src/or/include.am b/src/or/include.am
index f5002e6..8922e03 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -56,6 +56,7 @@ LIBTOR_A_SOURCES = \
src/or/fp_pair.c \
src/or/geoip.c \
src/or/entrynodes.c \
+ src/or/ext_orport.c \
src/or/hibernate.c \
src/or/main.c \
src/or/microdesc.c \
@@ -153,6 +154,7 @@ ORHEADERS = \
src/or/dns.h \
src/or/dnsserv.h \
src/or/eventdns_tor.h \
+ src/or/ext_orport.h \
src/or/fp_pair.h \
src/or/geoip.h \
src/or/entrynodes.h \
diff --git a/src/or/transports.c b/src/or/transports.c
index 8beb9a5c..196e18b 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -97,6 +97,7 @@
#include "statefile.h"
#include "entrynodes.h"
#include "connection_or.h"
+#include "ext_orport.h"
static process_environment_t *
create_managed_proxy_environment(const managed_proxy_t *mp);
1
0
commit c46f1b810dab79514d650f44ccf21ca4d24a20d5
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed Dec 5 19:19:24 2012 +0200
More Extended ORPort code improvements.
* Change name of init_ext_or_auth_cookie_authentication().
* Add a small comment.
---
src/or/config.c | 2 +-
src/or/connection.c | 1 +
src/or/ext_orport.c | 2 +-
src/or/ext_orport.h | 2 +-
4 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c
index 542191d..9c1505c 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1481,7 +1481,7 @@ options_act(const or_options_t *old_options)
}
/* If we have an ExtORPort, initialize its auth cookie. */
- if (init_ext_or_auth_cookie_authentication(!!options->ExtORPort_lines) < 0) {
+ if (init_ext_or_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 fcdc9ab..6f66f79 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1406,6 +1406,7 @@ connection_init_accepted_conn(connection_t *conn,
switch (conn->type) {
case CONN_TYPE_EXT_OR:
+ /* Initiate Extended ORPort authentication. */
return connection_ext_or_start_auth(TO_OR_CONN(conn));
case CONN_TYPE_OR:
control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW, 0);
diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
index 18ee5ab..f44a3f5 100644
--- a/src/or/ext_orport.c
+++ b/src/or/ext_orport.c
@@ -128,7 +128,7 @@ get_ext_or_auth_cookie_file(void)
* 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)
+init_ext_or_cookie_authentication(int is_enabled)
{
char *fname;
char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
diff --git a/src/or/ext_orport.h b/src/or/ext_orport.h
index fbd7ed6..a7038b9 100644
--- a/src/or/ext_orport.h
+++ b/src/or/ext_orport.h
@@ -9,6 +9,6 @@ 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);
+int init_ext_or_cookie_authentication(int is_enabled);
char *get_ext_or_auth_cookie_file(void);
1
0

[tor/master] Make the Extended ORPort understand the TRANSPORT command.
by nickm@torproject.org 15 Aug '13
by nickm@torproject.org 15 Aug '13
15 Aug '13
commit 210210f219a1773530dd117d7a48d6edc3a5e714
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Mon Feb 11 20:45:17 2013 +0100
Make the Extended ORPort understand the TRANSPORT command.
---
src/or/connection.c | 1 +
src/or/ext_orport.c | 43 ++++++++++++++++++++++++++++++++++++++++---
src/or/or.h | 3 +++
3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/src/or/connection.c b/src/or/connection.c
index 6f66f79..57a9c58 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -603,6 +603,7 @@ connection_free_(connection_t *conn)
connection_or_remove_from_ext_or_id_map(TO_OR_CONN(conn));
tor_free(TO_OR_CONN(conn)->ext_or_conn_id);
tor_free(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash);
+ tor_free(TO_OR_CONN(conn)->ext_or_transport);
}
#ifdef USE_BUFFEREVENTS
diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
index db95843..ff752f4 100644
--- a/src/or/ext_orport.c
+++ b/src/or/ext_orport.c
@@ -12,6 +12,7 @@
#include "ext_orport.h"
#include "control.h"
#include "config.h"
+#include "util.h"
#include "main.h"
/** Allocate and return a structure capable of holding an Extended
@@ -381,6 +382,7 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
/** Extended ORPort commands (Transport-to-Bridge) */
#define EXT_OR_CMD_TB_DONE 0x0000
#define EXT_OR_CMD_TB_USERADDR 0x0001
+#define EXT_OR_CMD_TB_TRANSPORT 0x0002
/** Extended ORPort commands (Bridge-to-Transport) */
#define EXT_OR_CMD_BT_OKAY 0x1000
@@ -395,8 +397,8 @@ connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
*
* Return 0 on success and -1 on error. */
static int
-connection_ext_or_handle_useraddr(connection_t *conn,
- const char *payload, uint16_t len)
+connection_ext_or_handle_cmd_useraddr(connection_t *conn,
+ const char *payload, uint16_t len)
{
/* Copy address string. */
tor_addr_t addr;
@@ -437,6 +439,32 @@ connection_ext_or_handle_useraddr(connection_t *conn,
return 0;
}
+/** Process a TRANSPORT command from the Extended
+ * ORPort. <b>payload</b> is a payload of size <b>len</b>.
+ *
+ * If the TRANSPORT command was well formed, register the name of the
+ * transport on <b>conn</b>.
+ *
+ * Return 0 on success and -1 on error. */
+static int
+connection_ext_or_handle_cmd_transport(or_connection_t *conn,
+ const char *payload, uint16_t len)
+{
+ char *transport_str = tor_malloc(len + 1); /* NUL-terminate the string */
+ memcpy(transport_str, payload, len);
+ transport_str[len] = 0;
+
+ /* Transport names MUST be C-identifiers. */
+ if (!string_is_C_identifier(transport_str)) {
+ tor_free(transport_str);
+ return -1;
+ }
+
+ conn->ext_or_transport = transport_str;
+ return 0;
+}
+
+
/** Process Extended ORPort messages from <b>or_conn</b>. */
int
connection_ext_or_process_inbuf(or_connection_t *or_conn)
@@ -480,15 +508,24 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
log_debug(LD_NET, "Received DONE.");
+ /* If the transport proxy did not use the TRANSPORT command to
+ * specify the transport name, mark this as unknown transport. */
+ if (!or_conn->ext_or_transport)
+ or_conn->ext_or_transport = tor_strdup("<?\?>");
+
connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
/* can't transition immediately; need to flush first. */
conn->state = EXT_OR_CONN_STATE_FLUSHING;
connection_stop_reading(conn);
} else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
- if (connection_ext_or_handle_useraddr(conn,
+ if (connection_ext_or_handle_cmd_useraddr(conn,
command->body, command->len) < 0)
goto err;
+ } else if (command->cmd == EXT_OR_CMD_TB_TRANSPORT) {
+ if (connection_ext_or_handle_cmd_transport(or_conn,
+ command->body, command->len) < 0)
+ goto err;
} else {
log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
command->cmd);
diff --git a/src/or/or.h b/src/or/or.h
index 63d137c..7916c47 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1452,6 +1452,9 @@ typedef struct or_connection_t {
char *ext_or_conn_id;
/** Client hash of the Extended ORPort authentication scheme */
char *ext_or_auth_correct_client_hash;
+ /** Name of the pluggable transport that is obfuscating this
+ connection. If no pluggable transports are used, it's NULL. */
+ char *ext_or_transport;
char *nickname; /**< Nickname of OR on other side (if any). */
1
0

[tor/master] Make a channel getter method to retrieve transport names.
by nickm@torproject.org 15 Aug '13
by nickm@torproject.org 15 Aug '13
15 Aug '13
commit e765d6ed8404a9df97f39846bf943217cf6a2001
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Mon Feb 11 20:52:12 2013 +0100
Make a channel getter method to retrieve transport names.
---
src/or/channel.c | 9 +++++++--
src/or/channel.h | 2 ++
src/or/channeltls.c | 27 +++++++++++++++++++++++++++
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/or/channel.c b/src/or/channel.c
index 4b6c7e1..ea5f961 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -2379,9 +2379,14 @@ channel_do_open_actions(channel_t *chan)
/* only report it to the geoip module if it's not a known router */
if (!router_get_by_id_digest(chan->identity_digest)) {
if (channel_get_addr_if_possible(chan, &remote_addr)) {
- /* XXXX 5040/4773 : Is this 'NULL' right? */
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &remote_addr, NULL,
+ char *transport_name = NULL;
+ if (chan->get_transport_name(chan, &transport_name) < 0)
+ transport_name = NULL;
+
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT,
+ &remote_addr, transport_name,
now);
+ tor_free(transport_name);
}
/* Otherwise the underlying transport can't tell us this, so skip it */
}
diff --git a/src/or/channel.h b/src/or/channel.h
index 83d7e90..bd99ebc 100644
--- a/src/or/channel.h
+++ b/src/or/channel.h
@@ -84,6 +84,8 @@ struct channel_s {
* available.
*/
int (*get_remote_addr)(channel_t *, tor_addr_t *);
+ int (*get_transport_name)(channel_t *chan, char **transport_out);
+
#define GRD_FLAG_ORIGINAL 1
#define GRD_FLAG_ADDR_ONLY 2
/*
diff --git a/src/or/channeltls.c b/src/or/channeltls.c
index 60693da..40f22c0 100644
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@ -55,6 +55,8 @@ static void channel_tls_close_method(channel_t *chan);
static const char * channel_tls_describe_transport_method(channel_t *chan);
static int
channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out);
+static int
+channel_tls_get_transport_name_method(channel_t *chan, char **transport_out);
static const char *
channel_tls_get_remote_descr_method(channel_t *chan, int flags);
static int channel_tls_has_queued_writes_method(channel_t *chan);
@@ -114,6 +116,7 @@ channel_tls_common_init(channel_tls_t *tlschan)
chan->describe_transport = channel_tls_describe_transport_method;
chan->get_remote_addr = channel_tls_get_remote_addr_method;
chan->get_remote_descr = channel_tls_get_remote_descr_method;
+ chan->get_transport_name = channel_tls_get_transport_name_method;
chan->has_queued_writes = channel_tls_has_queued_writes_method;
chan->is_canonical = channel_tls_is_canonical_method;
chan->matches_extend_info = channel_tls_matches_extend_info_method;
@@ -406,6 +409,30 @@ channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out)
}
/**
+ * Get the name of the pluggable transport used by a channel_tls_t.
+ *
+ * This implements the get_transport_name for channel_tls_t. If the
+ * channel uses a pluggable transport, copy its name to
+ * <b>transport_out</b> and return 0. If the channel did not use a
+ * pluggable transport, return -1. */
+
+static int
+channel_tls_get_transport_name_method(channel_t *chan, char **transport_out)
+{
+ channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+
+ tor_assert(tlschan);
+ tor_assert(transport_out);
+ tor_assert(tlschan->conn);
+
+ if (!tlschan->conn->ext_or_transport)
+ return -1;
+
+ *transport_out = tor_strdup(tlschan->conn->ext_or_transport);
+ return 0;
+}
+
+/**
* Get endpoint description of a channel_tls_t
*
* This implements the get_remote_descr method for channel_tls_t; it returns
1
0

15 Aug '13
commit 05306ad74f48deef8903e281544d672efcfdebd1
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Mon Feb 11 20:52:28 2013 +0100
Write extra-info bridge-ip-transports lines.
---
src/or/geoip.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/or/geoip.h | 1 +
2 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/src/or/geoip.c b/src/or/geoip.c
index b1efefd..dbb7ddd 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -782,6 +782,107 @@ geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
}
}
+/** Return the bridge-ip-transports string that should be inserted in
+ * our extra-info descriptor. Return NULL if the bridge-ip-transports
+ * line should be empty. */
+char *
+geoip_get_transport_history(void)
+{
+ unsigned granularity = IP_GRANULARITY;
+ /** String hash table <name of transport> -> <number of users>. */
+ strmap_t *transport_counts = strmap_new();
+ void *ptr;
+ intptr_t val;
+
+ /** Smartlist that contains copies of the names of the transports
+ that have been used. */
+ smartlist_t *transports_used = smartlist_new();
+
+ /* Special string to signify that no transport was used for this
+ connection. Pluggable transport names can't have symbols in their
+ names, so this string will never collide with a real transport. */
+ static const char* no_transport_str = "<OR>";
+
+ clientmap_entry_t **ent;
+ const char *transport_name = NULL;
+ smartlist_t *string_chunks = smartlist_new();
+ char *the_string = NULL;
+ int i = 0;
+
+ /* If we haven't seen any clients yet, return NULL. */
+ if (HT_EMPTY(&client_history))
+ goto done;
+
+ /** We do the following steps to form the transport history string:
+ * a) Foreach client that uses a pluggable transport, we increase the
+ * times that transport was used by one. If the client did not use
+ * a transport, we increase the number of times someone connected
+ * without obfuscation.
+ * b) Foreach transport we observed, we write its transport history
+ * string and push it to string_chunks. So, for example, if we've
+ * seen 665 obfs2 clients, we write "obfs2=665".
+ * c) We concatenate string_chunks to form the final string.
+ */
+
+ log_debug(LD_GENERAL,"Starting iteration for transport history. %d clients.",
+ HT_SIZE(&client_history));
+
+ /* Loop through all clients. */
+ HT_FOREACH(ent, clientmap, &client_history) {
+ transport_name = (*ent)->transport_name;
+ if (!transport_name)
+ transport_name = no_transport_str;
+
+ /* Increase the count for this transport name. */
+ ptr = strmap_get(transport_counts, transport_name);
+ val = (intptr_t)ptr;
+ val++;
+ ptr = (void*)val;
+ strmap_set(transport_counts, transport_name, ptr);
+
+ /* If it's the first time we see this transport, note it. */
+ if (!smartlist_contains_string(transports_used, transport_name))
+ smartlist_add(transports_used, tor_strdup(transport_name));
+
+ log_debug(LD_GENERAL, "Client from '%s' with transport '%s'. "
+ "I've now seen %d clients.",
+ safe_str_client(fmt_addr(&(*ent)->addr)),
+ transport_name ? transport_name : "<no transport>",
+ (int)val);
+ }
+
+ /* Sort the transport names (helps with unit testing). */
+ smartlist_sort_strings(transports_used);
+
+ /* Loop through all seen transports. */
+ SMARTLIST_FOREACH_BEGIN(transports_used, const char *, transport_name) {
+ void *transport_count_ptr = strmap_get(transport_counts, transport_name);
+ unsigned int transport_count = (uintptr_t) transport_count_ptr;
+ i++; /* counter so that we don't add a comma if it's the last transport. */
+
+ log_debug(LD_GENERAL, "We got %u clients with transport '%s'.",
+ transport_count, transport_name);
+
+ smartlist_add_asprintf(string_chunks, "%s=%u%s",
+ transport_name,
+ round_to_next_multiple_of(transport_count, granularity),
+ i != smartlist_len(transports_used) ? "," : "");
+ } SMARTLIST_FOREACH_END(transport_name);
+
+ the_string = smartlist_join_strings(string_chunks, "", 0, NULL);
+
+ log_debug(LD_GENERAL, "Final bridge-ip-transports string: '%s'", the_string);
+
+ done:
+ strmap_free(transport_counts, NULL);
+ SMARTLIST_FOREACH(transports_used, char *, s, tor_free(s));
+ smartlist_free(transports_used);
+ SMARTLIST_FOREACH(string_chunks, char *, s, tor_free(s));
+ smartlist_free(string_chunks);
+
+ return the_string;
+}
+
/** Return a newly allocated comma-separated string containing statistics
* on network status downloads. The string contains the number of completed
* requests, timeouts, and still running requests as well as the download
@@ -1202,6 +1303,8 @@ validate_bridge_stats(const char *stats_str, time_t now)
const char *BRIDGE_STATS_END = "bridge-stats-end ";
const char *BRIDGE_IPS = "bridge-ips ";
const char *BRIDGE_IPS_EMPTY_LINE = "bridge-ips\n";
+ const char *BRIDGE_TRANSPORTS = "bridge-ip-transports ";
+ const char *BRIDGE_TRANSPORTS_EMPTY_LINE = "bridge-ip-transports\n";
const char *tmp;
time_t stats_end_time;
int seconds;
@@ -1236,6 +1339,16 @@ validate_bridge_stats(const char *stats_str, time_t now)
return 0;
}
+ /* Parse: "bridge-ip-transports PT=N,PT=N,..." */
+ tmp = find_str_at_start_of_line(stats_str, BRIDGE_TRANSPORTS);
+ if (!tmp) {
+ /* Look if there is an empty "bridge-ip-transports" line */
+ tmp = find_str_at_start_of_line(stats_str, BRIDGE_TRANSPORTS_EMPTY_LINE);
+ if (!tmp)
+ return 0;
+ }
+
+
return 1;
}
@@ -1249,7 +1362,8 @@ static char *bridge_stats_extrainfo = NULL;
char *
geoip_format_bridge_stats(time_t now)
{
- char *out = NULL, *country_data = NULL, *ipver_data = NULL;
+ char *out = NULL;
+ char *country_data = NULL, *ipver_data = NULL, *transport_data = NULL;
long duration = now - start_of_bridge_stats_interval;
char written[ISO_TIME_LEN+1];
@@ -1260,16 +1374,20 @@ geoip_format_bridge_stats(time_t now)
format_iso_time(written, now);
geoip_get_client_history(GEOIP_CLIENT_CONNECT, &country_data, &ipver_data);
+ transport_data = geoip_get_transport_history();
tor_asprintf(&out,
"bridge-stats-end %s (%ld s)\n"
"bridge-ips %s\n"
- "bridge-ip-versions %s\n",
+ "bridge-ip-versions %s\n"
+ "bridge-ip-transports %s\n",
written, duration,
country_data ? country_data : "",
- ipver_data ? ipver_data : "");
+ ipver_data ? ipver_data : "",
+ transport_data ? transport_data : "");
tor_free(country_data);
tor_free(ipver_data);
+ tor_free(transport_data);
return out;
}
@@ -1544,5 +1662,6 @@ geoip_free_all(void)
}
clear_geoip_db();
+ tor_free(bridge_stats_extrainfo);
}
diff --git a/src/or/geoip.h b/src/or/geoip.h
index 19855c9..b9b53c3 100644
--- a/src/or/geoip.h
+++ b/src/or/geoip.h
@@ -34,6 +34,7 @@ void geoip_note_client_seen(geoip_client_action_t action,
void geoip_remove_old_clients(time_t cutoff);
void geoip_note_ns_response(geoip_ns_response_t response);
+char *geoip_get_transport_history(void);
int geoip_get_client_history(geoip_client_action_t action,
char **country_str, char **ipver_str);
char *geoip_get_request_history(void);
1
0

[tor/master] Fix logging severities and remove some trivial XXXs.
by nickm@torproject.org 15 Aug '13
by nickm@torproject.org 15 Aug '13
15 Aug '13
commit 895709db07c75c9a3bf8f2ef4e507fd410495dff
Author: George Kadianakis <desnacked(a)riseup.net>
Date: Wed Dec 5 19:26:24 2012 +0200
Fix logging severities and remove some trivial XXXs.
---
src/or/connection_or.c | 1 +
src/or/ext_orport.c | 26 +++++++++++++-------------
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 42127ad..3711cfe 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -2424,3 +2424,4 @@ connection_or_send_authenticate_cell(or_connection_t *conn, int authtype)
return 0;
}
+
diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
index f44a3f5..db95843 100644
--- a/src/or/ext_orport.c
+++ b/src/or/ext_orport.c
@@ -161,7 +161,7 @@ init_ext_or_cookie_authentication(int is_enabled)
return -1;
}
- log_warn(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
+ log_info(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
fname);
tor_free(fname);
@@ -186,7 +186,7 @@ connection_ext_or_auth_neg_auth_type(connection_t *conn)
if (connection_fetch_from_buf(authtype, 1, conn) < 0)
return -1;
- log_warn(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
+ log_debug(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
if (authtype[0] != 1) /* '1' is the only auth type supported atm */
return -1;
@@ -219,7 +219,7 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
return 0;
if (connection_fetch_from_buf(client_nonce,
- EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0) /* XXX check-spaces */
+ EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0)
return -1;
/* Get our nonce */
@@ -286,9 +286,9 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
client_nonce, sizeof(client_nonce));
- log_warn(LD_GENERAL,
- "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
- server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
+ log_debug(LD_GENERAL,
+ "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
+ server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
}
{ /* write reply: (server_hash, server_nonce) */
@@ -298,7 +298,7 @@ connection_ext_or_auth_handle_client_nonce(connection_t *conn)
connection_write_to_buf(reply, sizeof(reply), conn);
}
- log_warn(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
+ log_debug(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
return 1;
@@ -346,7 +346,7 @@ connection_ext_or_auth_handle_client_hash(connection_t *conn)
return -1;
}
- log_warn(LD_GENERAL, "Got client's hash and it was legit.");
+ log_debug(LD_GENERAL, "Got client's hash and it was legit.");
/* send positive auth result */
connection_ext_or_auth_send_result_success(conn);
@@ -422,7 +422,7 @@ connection_ext_or_handle_useraddr(connection_t *conn,
char *old_address = tor_dup_addr(&conn->addr);
char *new_address = tor_dup_addr(&addr);
- log_warn(LD_NET, "Received USERADDR." /* XXX Fix log severities/messages */
+ log_debug(LD_NET, "Received USERADDR."
"We rewrite our address from '%s:%u' to '%s:%u'.",
safe_str(old_address), conn->port, safe_str(new_address), port);
@@ -448,8 +448,8 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
/* If we are still in the authentication stage, process traffic as
authentication data: */
while (conn->state <= EXT_OR_CONN_STATE_AUTH_MAX) {
- log_warn(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
- (unsigned int) connection_get_inbuf_len(conn));
+ log_debug(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
+ (unsigned int) connection_get_inbuf_len(conn));
r = connection_ext_or_auth_process_inbuf(or_conn);
if (r < 0) {
connection_mark_for_close(conn);
@@ -461,7 +461,7 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
}
while (1) {
- log_warn(LD_GENERAL, "Got Extended ORPort data.");
+ log_debug(LD_GENERAL, "Got Extended ORPort data.");
command = NULL;
r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
if (r < 0)
@@ -526,7 +526,7 @@ connection_ext_or_start_auth(or_connection_t *or_conn)
connection_t *conn = TO_CONN(or_conn);
char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
- log_warn(LD_GENERAL,
+ log_debug(LD_GENERAL,
"ExtORPort authentication: Sending supported authentication types");
connection_write_to_buf(authtypes, sizeof(authtypes), conn);
1
0