Tor  0.4.6.0-alpha-dev
ext_orport.c
Go to the documentation of this file.
1 /* Copyright (c) 2012-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /**
5  * \file ext_orport.c
6  * \brief Code implementing the Extended ORPort.
7  *
8  * The Extended ORPort interface is used by pluggable transports to
9  * communicate additional information to a Tor bridge, including
10  * address information. For more information on this interface,
11  * see pt-spec.txt in torspec.git.
12  *
13  * There is no separate structure for extended ORPort connections; they use
14  * or_connection_t objects, and share most of their implementation with
15  * connection_or.c. Once the handshake is done, an extended ORPort connection
16  * turns into a regular OR connection, using connection_ext_or_transition().
17  */
18 
19 #define EXT_ORPORT_PRIVATE
20 #include "core/or/or.h"
22 #include "core/or/connection_or.h"
24 #include "app/config/config.h"
28 #include "core/mainloop/mainloop.h"
30 
32 
33 /** Allocate and return a structure capable of holding an Extended
34  * ORPort message of body length <b>len</b>. */
36 ext_or_cmd_new(uint16_t len)
37 {
38  size_t size = offsetof(ext_or_cmd_t, body) + len;
39  ext_or_cmd_t *cmd = tor_malloc(size);
40  cmd->len = len;
41  return cmd;
42 }
43 
44 /** Deallocate the Extended ORPort message in <b>cmd</b>. */
45 void
47 {
48  tor_free(cmd);
49 }
50 
51 /** Get an Extended ORPort message from <b>conn</b>, and place it in
52  * <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
53  * successfully extracted an Extended ORPort command from the
54  * buffer. */
55 static int
57 {
58  return fetch_ext_or_command_from_buf(conn->inbuf, out);
59 }
60 
61 /** Write an Extended ORPort message to <b>conn</b>. Use
62  * <b>command</b> as the command type, <b>bodylen</b> as the body
63  * length, and <b>body</b>, if it's present, as the body of the
64  * message. */
65 STATIC int
67  uint16_t command,
68  const char *body,
69  size_t bodylen)
70 {
71  char header[4];
72  if (bodylen > UINT16_MAX)
73  return -1;
74  set_uint16(header, htons(command));
75  set_uint16(header+2, htons(bodylen));
76  connection_buf_add(header, 4, conn);
77  if (bodylen) {
78  tor_assert(body);
79  connection_buf_add(body, bodylen, conn);
80  }
81  return 0;
82 }
83 
84 /** Transition from an Extended ORPort which accepts Extended ORPort
85  * messages, to an Extended ORport which accepts OR traffic. */
86 static void
88 {
89  tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
90 
91  conn->base_.type = CONN_TYPE_OR;
92  TO_CONN(conn)->state = 0; // set the state to a neutral value
93  connection_or_event_status(conn, OR_CONN_EVENT_NEW, 0);
95 }
96 
97 /** Length of authentication cookie. */
98 #define EXT_OR_PORT_AUTH_COOKIE_LEN 32
99 /** Length of the header of the cookie file. */
100 #define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
101 /** Static cookie file header. */
102 #define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
103 /** Length of safe-cookie protocol hashes. */
104 #define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
105 /** Length of safe-cookie protocol nonces. */
106 #define EXT_OR_PORT_AUTH_NONCE_LEN 32
107 /** Safe-cookie protocol constants. */
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"
112 
113 /* Code to indicate cookie authentication */
114 #define EXT_OR_AUTHTYPE_SAFECOOKIE 0x01
115 
116 /** If true, we've set ext_or_auth_cookie to a secret code and stored
117  * it to disk. */
119 /** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
120  * and which we're using to authenticate controllers. (If the controller can
121  * read it off disk, it has permission to connect.) */
122 STATIC uint8_t *ext_or_auth_cookie = NULL;
123 
124 /** Helper: Return a newly allocated string containing a path to the
125  * file where we store our authentication cookie. */
126 char *
128 {
129  const or_options_t *options = get_options();
130  if (options->ExtORPortCookieAuthFile &&
131  strlen(options->ExtORPortCookieAuthFile)) {
132  return tor_strdup(options->ExtORPortCookieAuthFile);
133  } else {
134  return get_datadir_fname("extended_orport_auth_cookie");
135  }
136 }
137 
138 /* Initialize the cookie-based authentication system of the
139  * Extended ORPort. If <b>is_enabled</b> is 0, then disable the cookie
140  * authentication system. */
141 int
142 init_ext_or_cookie_authentication(int is_enabled)
143 {
144  char *fname = NULL;
145  int retval;
146 
147  if (!is_enabled) {
149  return 0;
150  }
151 
155  get_options()->ExtORPortCookieAuthFileGroupReadable,
158  tor_free(fname);
159  return retval;
160 }
161 
162 /** Read data from <b>conn</b> and see if the client sent us the
163  * authentication type that they prefer to use in this session.
164  *
165  * Return -1 if we received corrupted data or if we don't support the
166  * authentication type. Return 0 if we need more data in
167  * <b>conn</b>. Return 1 if the authentication type negotiation was
168  * successful. */
169 static int
171 {
172  char authtype[1] = {0};
173 
174  if (connection_get_inbuf_len(conn) < 1)
175  return 0;
176 
177  if (connection_buf_get_bytes(authtype, 1, conn) < 0)
178  return -1;
179 
180  log_debug(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
181  if (authtype[0] != EXT_OR_AUTHTYPE_SAFECOOKIE) {
182  /* '1' is the only auth type supported atm */
183  return -1;
184  }
185 
187  return 1;
188 }
189 
190 /* DOCDOC */
191 STATIC int
192 handle_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)
195 {
196  char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
197  char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
198  char *reply;
199  size_t reply_len;
200 
201  if (client_nonce_len != EXT_OR_PORT_AUTH_NONCE_LEN)
202  return -1;
203 
204  /* Get our nonce */
206 
207  { /* set up macs */
208  size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
210  size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
212 
213  char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
214  char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
215  char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
216 
217  memcpy(hmac_s_msg,
220  memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
221  client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
222  memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
224  server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
225 
226  memcpy(hmac_c_msg,
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),
230  client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
231  memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
233  server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
234 
235  crypto_hmac_sha256(server_hash,
236  (char*)ext_or_auth_cookie,
238  hmac_s_msg,
239  hmac_s_msg_len);
240 
241  crypto_hmac_sha256(correct_client_hash,
242  (char*)ext_or_auth_cookie,
244  hmac_c_msg,
245  hmac_c_msg_len);
246 
247  /* Store the client hash we generated. We will need to compare it
248  with the hash sent by the client. */
249  *client_hash_out = correct_client_hash;
250 
251  memwipe(hmac_s_msg, 0, hmac_s_msg_len);
252  memwipe(hmac_c_msg, 0, hmac_c_msg_len);
253 
254  tor_free(hmac_s_msg);
255  tor_free(hmac_c_msg);
256  }
257 
258  { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
259  char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
260  char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
261  char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
262 
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),
268  client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
269 
270  log_debug(LD_GENERAL,
271  "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
272  server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
273 
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));
277  }
278 
279  { /* write reply: (server_hash, server_nonce) */
280 
282  reply = tor_malloc_zero(reply_len);
283  memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
284  memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
286  }
287 
288  *reply_out = reply;
289  *reply_len_out = reply_len;
290 
291  return 0;
292 }
293 
294 /** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
295  * crypto, and then send our own hash and nonce to the client
296  *
297  * Return -1 if there was an error; return 0 if we need more data in
298  * <b>conn</b>, and return 1 if we successfully retrieved the
299  * client's nonce and sent our own. */
300 static int
302 {
303  char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN];
304  char *reply=NULL;
305  size_t reply_len=0;
306 
307  if (!ext_or_auth_cookie_is_set) { /* this should not happen */
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. ");
311  return -1;
312  }
313 
314  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
315  return 0;
316 
317  if (connection_buf_get_bytes(client_nonce,
318  EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0)
319  return -1;
320 
321  /* We extract the ClientNonce from the received data, and use it to
322  calculate ServerHash and ServerNonce according to proposal 217.
323 
324  We also calculate our own ClientHash value and save it in the
325  connection state. We validate it later against the ClientHash
326  sent by the client. */
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)
330  return -1;
331 
332  connection_buf_add(reply, reply_len, conn);
333 
334  memwipe(reply, 0, reply_len);
335  tor_free(reply);
336 
337  log_debug(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
338 
340  return 1;
341 }
342 
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)
347 
348 /** Send authentication results to <b>conn</b>. Successful results if
349  * <b>success</b> is set; failure results otherwise. */
350 static void
352 {
353  if (success)
354  connection_buf_add("\x01", 1, conn);
355  else
356  connection_buf_add("\x00", 1, conn);
357 }
358 
359 /** Receive the client's hash from <b>conn</b>, validate that it's
360  * correct, and then send the authentication results to the client.
361  *
362  * Return -1 if there was an error during validation; return 0 if we
363  * need more data in <b>conn</b>, and return 1 if we successfully
364  * validated the client's hash and sent a happy authentication
365  * result. */
366 static int
368 {
369  char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
370 
371  if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
372  return 0;
373 
374  if (connection_buf_get_bytes(provided_client_hash,
375  EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
376  return -1;
377 
378  if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
379  provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
380  log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
381  connection_ext_or_auth_send_result_fail(conn);
382  return -1;
383  }
384 
385  log_debug(LD_GENERAL, "Got client's hash and it was legit.");
386 
387  /* send positive auth result */
388  connection_ext_or_auth_send_result_success(conn);
390  return 1;
391 }
392 
393 /** Handle data from <b>or_conn</b> received on Extended ORPort.
394  * Return -1 on error. 0 on insufficient data. 1 on correct. */
395 static int
397 {
398  connection_t *conn = TO_CONN(or_conn);
399 
400  /* State transitions of the Extended ORPort authentication protocol:
401 
402  EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE (start state) ->
403  EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE ->
404  EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH ->
405  EXT_OR_CONN_STATE_OPEN
406 
407  During EXT_OR_CONN_STATE_OPEN, data is handled by
408  connection_ext_or_process_inbuf().
409  */
410 
411  switch (conn->state) { /* Functionify */
414 
417 
420 
421  default:
422  log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
423  "to process Extended ORPort authentication data.", conn->state);
424  return -1;
425  }
426 }
427 
428 /** Extended ORPort commands (Transport-to-Bridge) */
429 #define EXT_OR_CMD_TB_DONE 0x0000
430 #define EXT_OR_CMD_TB_USERADDR 0x0001
431 #define EXT_OR_CMD_TB_TRANSPORT 0x0002
432 
433 /** Extended ORPort commands (Bridge-to-Transport) */
434 #define EXT_OR_CMD_BT_OKAY 0x1000
435 #define EXT_OR_CMD_BT_DENY 0x1001
436 #define EXT_OR_CMD_BT_CONTROL 0x1002
437 
438 /** Process a USERADDR command from the Extended
439  * ORPort. <b>payload</b> is a payload of size <b>len</b>.
440  *
441  * If the USERADDR command was well formed, change the address of
442  * <b>conn</b> to the address on the USERADDR command.
443  *
444  * Return 0 on success and -1 on error. */
445 static int
447  const char *payload, uint16_t len)
448 {
449  /* Copy address string. */
450  tor_addr_t addr;
451  uint16_t port;
452  char *addr_str;
453  char *address_part=NULL;
454  int res;
455  if (memchr(payload, '\0', len)) {
456  log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort UserAddr");
457  return -1;
458  }
459 
460  addr_str = tor_memdup_nulterm(payload, len);
461 
462  res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
463  tor_free(addr_str);
464  if (res<0)
465  return -1;
466  if (port == 0) {
467  log_warn(LD_GENERAL, "Server transport proxy gave us an empty port "
468  "in ExtORPort UserAddr command.");
469  // return -1; // enable this if nothing breaks after a while.
470  }
471 
472  res = tor_addr_parse(&addr, address_part);
473  tor_free(address_part);
474  if (res<0)
475  return -1;
476 
477  { /* do some logging */
478  char *old_address = tor_addr_to_str_dup(&conn->addr);
479  char *new_address = tor_addr_to_str_dup(&addr);
480 
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);
484 
485  tor_free(old_address);
486  tor_free(new_address);
487  }
488 
489  /* record the address */
490  tor_addr_copy(&conn->addr, &addr);
491  conn->port = port;
492  if (conn->address) {
493  tor_free(conn->address);
494  }
495  conn->address = tor_addr_to_str_dup(&addr);
496 
497  /* Now that we know the address, we don't have to manually override rate
498  * limiting. */
499  conn->always_rate_limit_as_remote = 0;
500 
501  return 0;
502 }
503 
504 /** Process a TRANSPORT command from the Extended
505  * ORPort. <b>payload</b> is a payload of size <b>len</b>.
506  *
507  * If the TRANSPORT command was well formed, register the name of the
508  * transport on <b>conn</b>.
509  *
510  * Return 0 on success and -1 on error. */
511 static int
513  const char *payload, uint16_t len)
514 {
515  char *transport_str;
516  if (memchr(payload, '\0', len)) {
517  log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort Transport");
518  return -1;
519  }
520 
521  transport_str = tor_memdup_nulterm(payload, len);
522 
523  /* Transport names MUST be C-identifiers. */
524  if (!string_is_C_identifier(transport_str)) {
525  tor_free(transport_str);
526  return -1;
527  }
528 
529  /* If ext_or_transport is already occupied (because the PT sent two
530  * TRANSPORT commands), deallocate the old name and keep the new
531  * one */
532  if (conn->ext_or_transport)
533  tor_free(conn->ext_or_transport);
534 
535  conn->ext_or_transport = transport_str;
536  return 0;
537 }
538 
539 #define EXT_OR_CONN_STATE_IS_AUTHENTICATING(st) \
540  ((st) <= EXT_OR_CONN_STATE_AUTH_MAX)
541 
542 /** Process Extended ORPort messages from <b>or_conn</b>. */
543 int
545 {
546  connection_t *conn = TO_CONN(or_conn);
548  int r;
549 
550  /* DOCDOC Document the state machine and transitions in this function */
551 
552  /* If we are still in the authentication stage, process traffic as
553  authentication data: */
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));
558  if (r < 0) {
559  connection_mark_for_close(conn);
560  return -1;
561  } else if (r == 0) {
562  return 0;
563  }
564  /* if r > 0, loop and process more data (if any). */
565  }
566 
567  while (1) {
568  log_debug(LD_GENERAL, "Got Extended ORPort data.");
569  command = NULL;
571  if (r < 0)
572  goto err;
573  else if (r == 0)
574  return 0; /* need to wait for more data */
575 
576  /* Got a command! */
578 
579  if (command->cmd == EXT_OR_CMD_TB_DONE) {
580  if (connection_get_inbuf_len(conn)) {
581  /* The inbuf isn't empty; the client is misbehaving. */
582  goto err;
583  }
584 
585  log_debug(LD_NET, "Received DONE.");
586 
587  /* If the transport proxy did not use the TRANSPORT command to
588  * specify the transport name, mark this as unknown transport. */
589  if (!or_conn->ext_or_transport) {
590  /* We write this string this way to avoid ??>, which is a C
591  * trigraph. */
592  or_conn->ext_or_transport = tor_strdup("<?" "?>");
593  }
594 
596 
597  /* can't transition immediately; need to flush first. */
600  } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
602  command->body, command->len) < 0)
603  goto err;
604  } else if (command->cmd == EXT_OR_CMD_TB_TRANSPORT) {
606  command->body, command->len) < 0)
607  goto err;
608  } else {
609  log_notice(LD_NET,"Got Extended ORPort command we don't recognize (%u).",
610  command->cmd);
611  }
612 
613  ext_or_cmd_free(command);
614  }
615 
616  return 0;
617 
618  err:
619  ext_or_cmd_free(command);
620  connection_mark_for_close(conn);
621  return -1;
622 }
623 
624 /** <b>conn</b> finished flushing Extended ORPort messages to the
625  * network, and is now ready to accept OR traffic. This function
626  * does the transition. */
627 int
629 {
630  if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
633  }
634  return 0;
635 }
636 
637 /** Initiate Extended ORPort authentication, by sending the list of
638  * supported authentication types to the client. */
639 int
641 {
642  connection_t *conn = TO_CONN(or_conn);
643  const uint8_t authtypes[] = {
644  /* We only support authtype '1' for now. */
645  EXT_OR_AUTHTYPE_SAFECOOKIE,
646  /* Marks the end of the list. */
647  0
648  };
649 
650  log_debug(LD_GENERAL,
651  "ExtORPort authentication: Sending supported authentication types");
652 
653  connection_buf_add((const char *)authtypes, sizeof(authtypes), conn);
655 
656  return 0;
657 }
658 
659 /** Global map between Extended ORPort identifiers and OR
660  * connections. */
661 static digestmap_t *orconn_ext_or_id_map = NULL;
662 
663 /** Remove the Extended ORPort identifier of <b>conn</b> from the
664  * global identifier list. Also, clear the identifier from the
665  * connection itself. */
666 void
668 {
669  or_connection_t *tmp;
671  return;
672  if (!conn->ext_or_conn_id)
673  return;
674 
675  tmp = digestmap_remove(orconn_ext_or_id_map, conn->ext_or_conn_id);
677  tor_assert(tmp == conn);
678 
679  memset(conn->ext_or_conn_id, 0, EXT_OR_CONN_ID_LEN);
680 }
681 
682 #ifdef TOR_UNIT_TESTS
683 /** Return the connection whose ext_or_id is <b>id</b>. Return NULL if no such
684  * connection is found. */
686 connection_or_get_by_ext_or_id(const char *id)
687 {
689  return NULL;
690  return digestmap_get(orconn_ext_or_id_map, id);
691 }
692 #endif /* defined(TOR_UNIT_TESTS) */
693 
694 /** Deallocate the global Extended ORPort identifier list */
695 void
697 {
698  digestmap_free(orconn_ext_or_id_map, NULL);
699  orconn_ext_or_id_map = NULL;
700 }
701 
702 /** Creates an Extended ORPort identifier for <b>conn</b> and deposits
703  * it into the global list of identifiers. */
704 void
706 {
707  char random_id[EXT_OR_CONN_ID_LEN];
708  or_connection_t *tmp;
709 
711  orconn_ext_or_id_map = digestmap_new();
712 
713  /* Remove any previous identifiers: */
714  if (conn->ext_or_conn_id && !tor_digest_is_zero(conn->ext_or_conn_id))
716 
717  do {
718  crypto_rand(random_id, sizeof(random_id));
719  } while (digestmap_get(orconn_ext_or_id_map, random_id));
720 
721  if (!conn->ext_or_conn_id)
722  conn->ext_or_conn_id = tor_malloc_zero(EXT_OR_CONN_ID_LEN);
723 
724  memcpy(conn->ext_or_conn_id, random_id, EXT_OR_CONN_ID_LEN);
725 
726  tmp = digestmap_set(orconn_ext_or_id_map, random_id, conn);
727  tor_assert(!tmp);
728 }
729 
730 /** Free any leftover allocated memory of the ext_orport.c subsystem. */
731 void
733 {
734  if (ext_or_auth_cookie) /* Free the auth cookie */
736 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:283
or_options_t::ExtORPortCookieAuthFile
char * ExtORPortCookieAuthFile
Definition: or_options_st.h:536
EXT_OR_CMD_BT_OKAY
#define EXT_OR_CMD_BT_OKAY
Definition: ext_orport.c:434
connection_or_remove_from_ext_or_id_map
void connection_or_remove_from_ext_or_id_map(or_connection_t *conn)
Definition: ext_orport.c:667
tor_free
#define tor_free(p)
Definition: malloc.h:52
connection_t::always_rate_limit_as_remote
unsigned int always_rate_limit_as_remote
Definition: connection_st.h:74
connection_fetch_ext_or_cmd_from_buf
static int connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
Definition: ext_orport.c:56
EXT_OR_PORT_AUTH_NONCE_LEN
#define EXT_OR_PORT_AUTH_NONCE_LEN
Definition: ext_orport.c:106
memwipe
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
tor_addr_t
Definition: address.h:69
connection_t::address
char * address
Definition: connection_st.h:166
connection_ext_or_finished_flushing
int connection_ext_or_finished_flushing(or_connection_t *conn)
Definition: ext_orport.c:628
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
LD_BUG
#define LD_BUG
Definition: log.h:86
CONN_TYPE_EXT_OR
#define CONN_TYPE_EXT_OR
Definition: connection.h:71
LD_GENERAL
#define LD_GENERAL
Definition: log.h:62
string_is_C_identifier
int string_is_C_identifier(const char *string)
Definition: util_string.c:423
base16_encode
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
proto_ext_or.h
Header for proto_ext_or.c.
ext_or_cmd_new
ext_or_cmd_t * ext_or_cmd_new(uint16_t len)
Definition: ext_orport.c:36
connection_ext_or_auth_handle_client_hash
static int connection_ext_or_auth_handle_client_hash(connection_t *conn)
Definition: ext_orport.c:367
connection_write_ext_or_command
STATIC int connection_write_ext_or_command(connection_t *conn, uint16_t command, const char *body, size_t bodylen)
Definition: ext_orport.c:66
connection_stop_reading
void connection_stop_reading(connection_t *conn)
Definition: mainloop.c:611
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE
#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE
Definition: ext_orport.h:22
or_connection_t
Definition: or_connection_st.h:22
connection_t::port
uint16_t port
Definition: connection_st.h:146
connection_start_reading
void connection_start_reading(connection_t *conn)
Definition: mainloop.c:633
ext_or_cmd_free_
void ext_or_cmd_free_(ext_or_cmd_t *cmd)
Definition: ext_orport.c:46
EXT_OR_CMD_TB_DONE
#define EXT_OR_CMD_TB_DONE
Definition: ext_orport.c:429
crypto_util.h
Common functions for cryptographic routines.
EXT_OR_CONN_ID_LEN
#define EXT_OR_CONN_ID_LEN
Definition: or.h:713
mainloop.h
Header file for mainloop.c.
orconn_ext_or_id_map
static digestmap_t * orconn_ext_or_id_map
Definition: ext_orport.c:661
connection_or_event_status
void connection_or_event_status(or_connection_t *conn, or_conn_status_event_t tp, int reason)
Definition: connection_or.c:371
EXT_OR_CONN_STATE_OPEN
#define EXT_OR_CONN_STATE_OPEN
Definition: ext_orport.h:28
EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE
#define EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE
Definition: ext_orport.h:20
EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST
#define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST
Definition: ext_orport.c:108
tor_memneq
#define tor_memneq(a, b, sz)
Definition: di_ops.h:21
EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH
#define EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH
Definition: ext_orport.h:24
ext_or_cmd_t
Definition: proto_ext_or.h:18
connection_ext_or_transition
static void connection_ext_or_transition(or_connection_t *conn)
Definition: ext_orport.c:87
CONN_TYPE_OR
#define CONN_TYPE_OR
Definition: connection.h:44
tor_digest_is_zero
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96
EXT_OR_CONN_STATE_FLUSHING
#define EXT_OR_CONN_STATE_FLUSHING
Definition: ext_orport.h:31
connection_ext_or_auth_handle_client_nonce
static int connection_ext_or_auth_handle_client_nonce(connection_t *conn)
Definition: ext_orport.c:301
connection_t::inbuf
struct buf_t * inbuf
Definition: connection_st.h:101
connection_ext_or_auth_send_result
static void connection_ext_or_auth_send_result(connection_t *conn, int success)
Definition: ext_orport.c:351
connection_tls_start_handshake
int connection_tls_start_handshake(or_connection_t *conn, int receiving)
Definition: connection_or.c:1638
ext_orport_free_all
void ext_orport_free_all(void)
Definition: ext_orport.c:732
connection_ext_or_start_auth
int connection_ext_or_start_auth(or_connection_t *or_conn)
Definition: ext_orport.c:640
connection_t::addr
tor_addr_t addr
Definition: connection_st.h:145
tor_addr_to_str_dup
char * tor_addr_to_str_dup(const tor_addr_t *addr)
Definition: address.c:1164
EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
#define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
Definition: ext_orport.c:100
command
tor_cmdline_mode_t command
Definition: config.c:2467
connection_t
Definition: connection_st.h:45
tor_addr_parse
int tor_addr_parse(tor_addr_t *addr, const char *src)
Definition: address.c:1349
connection_t::type
unsigned int type
Definition: connection_st.h:50
ext_orport.h
Header for ext_orport.c.
LOG_INFO
#define LOG_INFO
Definition: log.h:45
crypto_rand.h
Common functions for using (pseudo-)random number generators.
control_events.h
Header file for control_events.c.
get_options
const or_options_t * get_options(void)
Definition: config.c:932
or_connection_t::ext_or_transport
char * ext_or_transport
Definition: or_connection_st.h:40
connection_ext_or_handle_cmd_transport
static int connection_ext_or_handle_cmd_transport(or_connection_t *conn, const char *payload, uint16_t len)
Definition: ext_orport.c:512
connection.h
Header file for connection.c.
connection_buf_get_bytes
int connection_buf_get_bytes(char *string, size_t len, connection_t *conn)
Definition: connection.c:4198
connection_ext_or_auth_neg_auth_type
static int connection_ext_or_auth_neg_auth_type(connection_t *conn)
Definition: ext_orport.c:170
or_connection_st.h
OR connection structure.
get_ext_or_auth_cookie_file_name
char * get_ext_or_auth_cookie_file_name(void)
Definition: ext_orport.c:127
connection_ext_or_auth_process_inbuf
static int connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
Definition: ext_orport.c:396
crypto_hmac_sha256
void crypto_hmac_sha256(char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
Definition: crypto_digest_nss.c:508
EXT_OR_PORT_AUTH_COOKIE_HEADER
#define EXT_OR_PORT_AUTH_COOKIE_HEADER
Definition: ext_orport.c:102
ext_or_auth_cookie_is_set
STATIC int ext_or_auth_cookie_is_set
Definition: ext_orport.c:118
config.h
Header file for config.c.
or_connection_t::ext_or_conn_id
char * ext_or_conn_id
Definition: or_connection_st.h:30
EXT_OR_PORT_AUTH_HASH_LEN
#define EXT_OR_PORT_AUTH_HASH_LEN
Definition: ext_orport.c:104
connection_or_set_ext_or_identifier
void connection_or_set_ext_or_identifier(or_connection_t *conn)
Definition: ext_orport.c:705
LD_NET
#define LD_NET
Definition: log.h:66
connection_t::state
uint8_t state
Definition: connection_st.h:49
or_options_t
Definition: or_options_st.h:64
crypto_rand
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:477
TO_CONN
#define TO_CONN(c)
Definition: or.h:736
set_uint16
static void set_uint16(void *cp, uint16_t v)
Definition: bytes.h:78
STATIC
#define STATIC
Definition: testsupport.h:32
EXT_OR_PORT_AUTH_COOKIE_LEN
#define EXT_OR_PORT_AUTH_COOKIE_LEN
Definition: ext_orport.c:98
connection_or_clear_ext_or_id_map
void connection_or_clear_ext_or_id_map(void)
Definition: ext_orport.c:696
connection_ext_or_handle_cmd_useraddr
static int connection_ext_or_handle_cmd_useraddr(connection_t *conn, const char *payload, uint16_t len)
Definition: ext_orport.c:446
fetch_ext_or_command_from_buf
int fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out)
Definition: proto_ext_or.c:27
ext_or_auth_cookie
STATIC uint8_t * ext_or_auth_cookie
Definition: ext_orport.c:122
TO_OR_CONN
or_connection_t * TO_OR_CONN(connection_t *c)
Definition: connection_or.c:108
tor_addr_port_split
int tor_addr_port_split(int severity, const char *addrport, char **address_out, uint16_t *port_out)
Definition: address.c:1916
init_cookie_authentication
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)
Definition: config.c:7348
connection_or.h
Header file for connection_or.c.
tor_addr_copy
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
Definition: address.c:933
ext_or_cmd_t::len
uint16_t len
Definition: proto_ext_or.h:20
or.h
Master header file for Tor-specific functionality.
connection_ext_or_process_inbuf
int connection_ext_or_process_inbuf(or_connection_t *or_conn)
Definition: ext_orport.c:544