19#define EXT_ORPORT_PRIVATE
72 if (bodylen > UINT16_MAX)
76 connection_buf_add(header, 4, conn);
79 connection_buf_add(body, bodylen, conn);
98#define EXT_OR_PORT_AUTH_COOKIE_LEN 32
100#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
102#define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
104#define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
106#define EXT_OR_PORT_AUTH_NONCE_LEN 32
108#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
109 "ExtORPort authentication server-to-client hash"
110#define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
111 "ExtORPort authentication client-to-server hash"
114#define EXT_OR_AUTHTYPE_SAFECOOKIE 0x01
134 return get_datadir_fname(
"extended_orport_auth_cookie");
142init_ext_or_cookie_authentication(
int is_enabled)
155 get_options()->ExtORPortCookieAuthFileGroupReadable,
172 char authtype[1] = {0};
174 if (connection_get_inbuf_len(conn) < 1)
180 log_debug(
LD_GENERAL,
"Client wants us to use %d auth type", authtype[0]);
181 if (authtype[0] != EXT_OR_AUTHTYPE_SAFECOOKIE) {
192handle_client_auth_nonce(
const char *client_nonce,
size_t client_nonce_len,
193 char **client_hash_out,
194 char **reply_out,
size_t *reply_len_out)
210 size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
213 char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
214 char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
227 EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
228 strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
229 memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
231 memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
249 *client_hash_out = correct_client_hash;
251 memwipe(hmac_s_msg, 0, hmac_s_msg_len);
252 memwipe(hmac_c_msg, 0, hmac_c_msg_len);
263 base16_encode(server_hash_encoded,
sizeof(server_hash_encoded),
264 server_hash,
sizeof(server_hash));
265 base16_encode(server_nonce_encoded,
sizeof(server_nonce_encoded),
266 server_nonce,
sizeof(server_nonce));
267 base16_encode(client_nonce_encoded,
sizeof(client_nonce_encoded),
271 "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
272 server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
274 memwipe(server_hash_encoded, 0,
sizeof(server_hash_encoded));
275 memwipe(server_nonce_encoded, 0,
sizeof(server_nonce_encoded));
276 memwipe(client_nonce_encoded, 0,
sizeof(client_nonce_encoded));
282 reply = tor_malloc_zero(reply_len);
289 *reply_len_out = reply_len;
308 log_warn(
LD_BUG,
"Extended ORPort authentication cookie was not set. "
309 "That's weird since we should have done that on startup. "
310 "This might be a Tor bug, please file a bug report. ");
327 if (handle_client_auth_nonce(client_nonce,
sizeof(client_nonce),
328 &
TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
329 &reply, &reply_len) < 0)
332 connection_buf_add(reply, reply_len, conn);
337 log_debug(
LD_GENERAL,
"Got client nonce, and sent our own nonce and hash.");
343#define connection_ext_or_auth_send_result_success(c) \
344 connection_ext_or_auth_send_result(c, 1)
345#define connection_ext_or_auth_send_result_fail(c) \
346 connection_ext_or_auth_send_result(c, 0)
354 connection_buf_add(
"\x01", 1, conn);
356 connection_buf_add(
"\x00", 1, conn);
380 log_warn(
LD_GENERAL,
"Incorrect client hash. Authentication failed.");
381 connection_ext_or_auth_send_result_fail(conn);
385 log_debug(
LD_GENERAL,
"Got client's hash and it was legit.");
388 connection_ext_or_auth_send_result_success(conn);
411 switch (conn->
state) {
422 log_warn(
LD_BUG,
"Encountered unexpected connection state %d while trying "
423 "to process Extended ORPort authentication data.", conn->
state);
429#define EXT_OR_CMD_TB_DONE 0x0000
430#define EXT_OR_CMD_TB_USERADDR 0x0001
431#define EXT_OR_CMD_TB_TRANSPORT 0x0002
434#define EXT_OR_CMD_BT_OKAY 0x1000
435#define EXT_OR_CMD_BT_DENY 0x1001
436#define EXT_OR_CMD_BT_CONTROL 0x1002
447 const char *payload, uint16_t len)
453 char *address_part=NULL;
455 if (memchr(payload,
'\0', len)) {
456 log_fn(LOG_PROTOCOL_WARN,
LD_NET,
"Unexpected NUL in ExtORPort UserAddr");
460 addr_str = tor_memdup_nulterm(payload, len);
467 log_warn(
LD_GENERAL,
"Server transport proxy gave us an empty port "
468 "in ExtORPort UserAddr command.");
481 log_debug(
LD_NET,
"Received USERADDR."
482 "We rewrite our address from '%s:%u' to '%s:%u'.",
483 safe_str(old_address), conn->
port, safe_str(new_address), port);
513 const char *payload, uint16_t len)
516 if (memchr(payload,
'\0', len)) {
517 log_fn(LOG_PROTOCOL_WARN,
LD_NET,
"Unexpected NUL in ExtORPort Transport");
521 transport_str = tor_memdup_nulterm(payload, len);
539#define EXT_OR_CONN_STATE_IS_AUTHENTICATING(st) \
540 ((st) <= EXT_OR_CONN_STATE_AUTH_MAX)
554 while (EXT_OR_CONN_STATE_IS_AUTHENTICATING(conn->
state)) {
555 log_debug(
LD_GENERAL,
"Got Extended ORPort authentication data (%u).",
556 (
unsigned int) connection_get_inbuf_len(conn));
559 connection_mark_for_close(conn);
568 log_debug(
LD_GENERAL,
"Got Extended ORPort data.");
580 if (connection_get_inbuf_len(conn)) {
585 log_debug(
LD_NET,
"Received DONE.");
600 }
else if (
command->cmd == EXT_OR_CMD_TB_USERADDR) {
604 }
else if (
command->cmd == EXT_OR_CMD_TB_TRANSPORT) {
609 log_notice(
LD_NET,
"Got Extended ORPort command we don't recognize (%u).",
620 connection_mark_for_close(conn);
643 const uint8_t authtypes[] = {
645 EXT_OR_AUTHTYPE_SAFECOOKIE,
651 "ExtORPort authentication: Sending supported authentication types");
653 connection_buf_add((
const char *)authtypes,
sizeof(authtypes), conn);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
int tor_addr_parse(tor_addr_t *addr, const char *src)
int tor_addr_port_split(int severity, const char *addrport, char **address_out, uint16_t *port_out)
char * tor_addr_to_str_dup(const tor_addr_t *addr)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
static void set_uint16(void *cp, uint16_t v)
const or_options_t * get_options(void)
tor_cmdline_mode_t command
int init_cookie_authentication(const char *fname, const char *header, int cookie_len, int group_readable, uint8_t **cookie_out, int *cookie_is_set_out)
Header file for config.c.
int connection_buf_get_bytes(char *string, size_t len, connection_t *conn)
Header file for connection.c.
void connection_or_event_status(or_connection_t *conn, or_conn_status_event_t tp, int reason)
or_connection_t * TO_OR_CONN(connection_t *c)
int connection_tls_start_handshake(or_connection_t *conn, int receiving)
Header file for connection_or.c.
Header file for control_events.c.
void crypto_hmac_sha256(char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
#define tor_memneq(a, b, sz)
static void connection_ext_or_transition(or_connection_t *conn)
static int connection_ext_or_auth_handle_client_hash(connection_t *conn)
#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST
STATIC uint8_t * ext_or_auth_cookie
static int connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
STATIC int ext_or_auth_cookie_is_set
static void connection_ext_or_auth_send_result(connection_t *conn, int success)
char * get_ext_or_auth_cookie_file_name(void)
#define EXT_OR_PORT_AUTH_HASH_LEN
#define EXT_OR_PORT_AUTH_COOKIE_HEADER
static int connection_ext_or_auth_handle_client_nonce(connection_t *conn)
void ext_or_cmd_free_(ext_or_cmd_t *cmd)
static int connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
static int connection_ext_or_handle_cmd_transport(or_connection_t *conn, const char *payload, uint16_t len)
#define EXT_OR_PORT_AUTH_NONCE_LEN
int connection_ext_or_process_inbuf(or_connection_t *or_conn)
int connection_ext_or_start_auth(or_connection_t *or_conn)
static int connection_ext_or_auth_neg_auth_type(connection_t *conn)
static int connection_ext_or_handle_cmd_useraddr(connection_t *conn, const char *payload, uint16_t len)
#define EXT_OR_PORT_AUTH_COOKIE_LEN
#define EXT_OR_CMD_BT_OKAY
void ext_orport_free_all(void)
int connection_ext_or_finished_flushing(or_connection_t *conn)
ext_or_cmd_t * ext_or_cmd_new(uint16_t len)
STATIC int connection_write_ext_or_command(connection_t *conn, uint16_t command, const char *body, size_t bodylen)
#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
#define EXT_OR_CMD_TB_DONE
#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH
#define EXT_OR_CONN_STATE_OPEN
#define EXT_OR_CONN_STATE_FLUSHING
#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE
#define EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE
#define log_fn(severity, domain, args,...)
void connection_stop_reading(connection_t *conn)
void connection_start_reading(connection_t *conn)
Header file for mainloop.c.
Master header file for Tor-specific functionality.
int fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out)
Header for proto_ext_or.c.
unsigned int always_rate_limit_as_remote
char * ExtORPortCookieAuthFile
int string_is_C_identifier(const char *string)