ext_orport.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /* Copyright (c) 2012, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file ext_orport.c
  5. * \brief Code implementing the Extended ORPort.
  6. */
  7. #define EXT_ORPORT_PRIVATE
  8. #include "or.h"
  9. #include "connection.h"
  10. #include "connection_or.h"
  11. #include "ext_orport.h"
  12. #include "control.h"
  13. #include "config.h"
  14. #include "util.h"
  15. #include "main.h"
  16. /** Allocate and return a structure capable of holding an Extended
  17. * ORPort message of body length <b>len</b>. */
  18. ext_or_cmd_t *
  19. ext_or_cmd_new(uint16_t len)
  20. {
  21. size_t size = STRUCT_OFFSET(ext_or_cmd_t, body) + len;
  22. ext_or_cmd_t *cmd = tor_malloc(size);
  23. cmd->len = len;
  24. return cmd;
  25. }
  26. /** Deallocate the Extended ORPort message in <b>cmd</b>. */
  27. void
  28. ext_or_cmd_free(ext_or_cmd_t *cmd)
  29. {
  30. tor_free(cmd);
  31. }
  32. /** Get an Extended ORPort message from <b>conn</b>, and place it in
  33. * <b>out</b>. Return -1 on fail, 0 if we need more data, and 1 if we
  34. * successfully extracted an Extended ORPort command from the
  35. * buffer. */
  36. static int
  37. connection_fetch_ext_or_cmd_from_buf(connection_t *conn, ext_or_cmd_t **out)
  38. {
  39. IF_HAS_BUFFEREVENT(conn, {
  40. struct evbuffer *input = bufferevent_get_input(conn->bufev);
  41. return fetch_ext_or_command_from_evbuffer(input, out);
  42. }) ELSE_IF_NO_BUFFEREVENT {
  43. return fetch_ext_or_command_from_buf(conn->inbuf, out);
  44. }
  45. }
  46. /** Write an Extended ORPort message to <b>conn</b>. Use
  47. * <b>command</b> as the command type, <b>bodylen</b> as the body
  48. * length, and <b>body</b>, if it's present, as the body of the
  49. * message. */
  50. STATIC int
  51. connection_write_ext_or_command(connection_t *conn,
  52. uint16_t command,
  53. const char *body,
  54. size_t bodylen)
  55. {
  56. char header[4];
  57. if (bodylen > UINT16_MAX)
  58. return -1;
  59. set_uint16(header, htons(command));
  60. set_uint16(header+2, htons(bodylen));
  61. connection_write_to_buf(header, 4, conn);
  62. if (bodylen) {
  63. tor_assert(body);
  64. connection_write_to_buf(body, bodylen, conn);
  65. }
  66. return 0;
  67. }
  68. /** Transition from an Extended ORPort which accepts Extended ORPort
  69. * messages, to an Extended ORport which accepts OR traffic. */
  70. static void
  71. connection_ext_or_transition(or_connection_t *conn)
  72. {
  73. tor_assert(conn->base_.type == CONN_TYPE_EXT_OR);
  74. conn->base_.type = CONN_TYPE_OR;
  75. control_event_or_conn_status(conn, OR_CONN_EVENT_NEW, 0);
  76. connection_tls_start_handshake(conn, 1);
  77. }
  78. /** Length of authentication cookie. */
  79. #define EXT_OR_PORT_AUTH_COOKIE_LEN 32
  80. /** Length of the header of the cookie file. */
  81. #define EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN 32
  82. /** Total length of the cookie file. */
  83. #define EXT_OR_PORT_AUTH_COOKIE_FILE_LEN \
  84. EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN
  85. /** Static cookie file header. */
  86. #define EXT_OR_PORT_AUTH_COOKIE_HEADER "! Extended ORPort Auth Cookie !\x0a"
  87. /** Length of safe-cookie protocol hashes. */
  88. #define EXT_OR_PORT_AUTH_HASH_LEN DIGEST256_LEN
  89. /** Length of safe-cookie protocol nonces. */
  90. #define EXT_OR_PORT_AUTH_NONCE_LEN 32
  91. /** Safe-cookie protocol constants. */
  92. #define EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST \
  93. "ExtORPort authentication server-to-client hash"
  94. #define EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST \
  95. "ExtORPort authentication client-to-server hash"
  96. /** If true, we've set ext_or_auth_cookie to a secret code and stored
  97. * it to disk. */
  98. static int ext_or_auth_cookie_is_set = 0;
  99. /** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
  100. * and which we're using to authenticate controllers. (If the controller can
  101. * read it off disk, it has permission to connect.) */
  102. static char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
  103. /** Helper: Return a newly allocated string containing a path to the
  104. * file where we store our authentication cookie. */
  105. char *
  106. get_ext_or_auth_cookie_file_name(void)
  107. {
  108. const or_options_t *options = get_options();
  109. if (options->ExtORPortCookieAuthFile &&
  110. strlen(options->ExtORPortCookieAuthFile)) {
  111. return tor_strdup(options->ExtORPortCookieAuthFile);
  112. } else {
  113. return get_datadir_fname("extended_orport_auth_cookie");
  114. }
  115. }
  116. /** Choose a random authentication cookie and write it to disk.
  117. * Anybody who can read the cookie from disk will be considered
  118. * authorized to use the control connection. Return -1 if we can't
  119. * write the file, or 0 on success. */
  120. int
  121. init_ext_or_cookie_authentication(int is_enabled)
  122. {
  123. char *fname;
  124. char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
  125. if (!is_enabled) {
  126. ext_or_auth_cookie_is_set = 0;
  127. return 0;
  128. }
  129. /* We don't want to generate a new cookie every time we call
  130. * options_act(). One should be enough. */
  131. if (ext_or_auth_cookie_is_set)
  132. return 0; /* all set */
  133. if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
  134. return -1;
  135. ext_or_auth_cookie_is_set = 1;
  136. memcpy(cookie_file_string, EXT_OR_PORT_AUTH_COOKIE_HEADER,
  137. EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN);
  138. memcpy(cookie_file_string+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN,
  139. ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
  140. fname = get_ext_or_auth_cookie_file_name();
  141. if (write_bytes_to_file(fname, cookie_file_string,
  142. EXT_OR_PORT_AUTH_COOKIE_FILE_LEN, 1)) {
  143. log_warn(LD_FS,"Error writing authentication cookie to %s.",
  144. escaped(fname));
  145. tor_free(fname);
  146. return -1;
  147. }
  148. log_info(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
  149. fname);
  150. memwipe(cookie_file_string, 0, sizeof(cookie_file_string));
  151. tor_free(fname);
  152. return 0;
  153. }
  154. /** Read data from <b>conn</b> and see if the client sent us the
  155. * authentication type that she prefers to use in this session.
  156. *
  157. * Return -1 if we received corrupted data or if we don't support the
  158. * authentication type. Return 0 if we need more data in
  159. * <b>conn</b>. Return 1 if the authentication type negotiation was
  160. * successful. */
  161. static int
  162. connection_ext_or_auth_neg_auth_type(connection_t *conn)
  163. {
  164. char authtype[1] = {0};
  165. if (connection_get_inbuf_len(conn) < 1)
  166. return 0;
  167. if (connection_fetch_from_buf(authtype, 1, conn) < 0)
  168. return -1;
  169. log_debug(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
  170. if (authtype[0] != 1) /* '1' is the only auth type supported atm */
  171. return -1;
  172. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
  173. return 1;
  174. }
  175. /** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
  176. * crypto, and then send our own hash and nonce to the client
  177. *
  178. * Return -1 if there was an error; return 0 if we need more data in
  179. * <b>conn</b>, and return 1 if we successfully retrieved the
  180. * client's nonce and sent our own. */
  181. static int
  182. connection_ext_or_auth_handle_client_nonce(connection_t *conn)
  183. {
  184. char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
  185. char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
  186. char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
  187. char reply[EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
  188. if (!ext_or_auth_cookie_is_set) { /* this should not happen */
  189. log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
  190. "That's weird since we should have done that on startup. "
  191. "This might be a Tor bug, please file a bug report. ");
  192. return -1;
  193. }
  194. if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
  195. return 0;
  196. if (connection_fetch_from_buf(client_nonce,
  197. EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0)
  198. return -1;
  199. /* DOCDOC comment this function more, with comments about what the
  200. * protocol is. */
  201. /* Get our nonce */
  202. if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
  203. return -1;
  204. { /* set up macs */
  205. size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
  206. 2*EXT_OR_PORT_AUTH_NONCE_LEN;
  207. size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
  208. 2*EXT_OR_PORT_AUTH_NONCE_LEN;
  209. char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
  210. char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
  211. char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
  212. memcpy(hmac_s_msg,
  213. EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
  214. strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
  215. memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
  216. client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  217. memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
  218. EXT_OR_PORT_AUTH_NONCE_LEN,
  219. server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  220. memcpy(hmac_c_msg,
  221. EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
  222. strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
  223. memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
  224. client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  225. memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
  226. EXT_OR_PORT_AUTH_NONCE_LEN,
  227. server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  228. crypto_hmac_sha256(server_hash,
  229. ext_or_auth_cookie,
  230. EXT_OR_PORT_AUTH_COOKIE_LEN,
  231. hmac_s_msg,
  232. hmac_s_msg_len);
  233. crypto_hmac_sha256(correct_client_hash,
  234. ext_or_auth_cookie,
  235. EXT_OR_PORT_AUTH_COOKIE_LEN,
  236. hmac_c_msg,
  237. hmac_c_msg_len);
  238. /* Store the client hash we generated. We will need to compare it
  239. with the hash sent by the client. */
  240. TO_OR_CONN(conn)->ext_or_auth_correct_client_hash = correct_client_hash;
  241. memwipe(hmac_s_msg, 0, hmac_s_msg_len);
  242. memwipe(hmac_c_msg, 0, hmac_c_msg_len);
  243. tor_free(hmac_s_msg);
  244. tor_free(hmac_c_msg);
  245. }
  246. { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
  247. char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
  248. char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
  249. char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
  250. base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
  251. server_hash, sizeof(server_hash));
  252. base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
  253. server_nonce, sizeof(server_nonce));
  254. base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
  255. client_nonce, sizeof(client_nonce));
  256. log_debug(LD_GENERAL,
  257. "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
  258. server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
  259. memwipe(server_hash_encoded, 0, sizeof(server_hash_encoded));
  260. memwipe(server_nonce_encoded, 0, sizeof(server_nonce_encoded));
  261. memwipe(client_nonce_encoded, 0, sizeof(client_nonce_encoded));
  262. }
  263. { /* write reply: (server_hash, server_nonce) */
  264. memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
  265. memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
  266. EXT_OR_PORT_AUTH_NONCE_LEN);
  267. connection_write_to_buf(reply, sizeof(reply), conn);
  268. memwipe(reply, 0, sizeof(reply));
  269. }
  270. log_debug(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
  271. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
  272. return 1;
  273. }
  274. #define connection_ext_or_auth_send_result_success(c) \
  275. connection_ext_or_auth_send_result(c, 1)
  276. #define connection_ext_or_auth_send_result_fail(c) \
  277. connection_ext_or_auth_send_result(c, 0)
  278. /** Send authentication results to <b>conn</b>. Successful results if
  279. * <b>success</b> is set; failure results otherwise. */
  280. static void
  281. connection_ext_or_auth_send_result(connection_t *conn, int success)
  282. {
  283. if (success)
  284. connection_write_to_buf("\x01", 1, conn);
  285. else
  286. connection_write_to_buf("\x00", 1, conn);
  287. }
  288. /** Receive the client's hash from <b>conn</b>, validate that it's
  289. * correct, and then send the authentication results to the client.
  290. *
  291. * Return -1 if there was an error during validation; return 0 if we
  292. * need more data in <b>conn</b>, and return 1 if we successfully
  293. * validated the client's hash and sent a happy authentication
  294. * result. */
  295. static int
  296. connection_ext_or_auth_handle_client_hash(connection_t *conn)
  297. {
  298. char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
  299. if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
  300. return 0;
  301. if (connection_fetch_from_buf(provided_client_hash,
  302. EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
  303. return -1;
  304. if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
  305. provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
  306. log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
  307. connection_ext_or_auth_send_result_fail(conn);
  308. return -1;
  309. }
  310. log_debug(LD_GENERAL, "Got client's hash and it was legit.");
  311. /* send positive auth result */
  312. connection_ext_or_auth_send_result_success(conn);
  313. conn->state = EXT_OR_CONN_STATE_OPEN;
  314. return 1;
  315. }
  316. /** Handle data from <b>or_conn</b> received on Extended ORPort.
  317. * Return -1 on error. 0 on unsufficient data. 1 on correct. */
  318. static int
  319. connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
  320. {
  321. connection_t *conn = TO_CONN(or_conn);
  322. /* DOCDOC Document the state machine here! */
  323. switch (conn->state) { /* Functionify */
  324. case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
  325. return connection_ext_or_auth_neg_auth_type(conn);
  326. case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
  327. return connection_ext_or_auth_handle_client_nonce(conn);
  328. case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
  329. return connection_ext_or_auth_handle_client_hash(conn);
  330. default:
  331. log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
  332. "to process Extended ORPort authentication data.", conn->state);
  333. return -1;
  334. }
  335. }
  336. /** Extended ORPort commands (Transport-to-Bridge) */
  337. #define EXT_OR_CMD_TB_DONE 0x0000
  338. #define EXT_OR_CMD_TB_USERADDR 0x0001
  339. #define EXT_OR_CMD_TB_TRANSPORT 0x0002
  340. /** Extended ORPort commands (Bridge-to-Transport) */
  341. #define EXT_OR_CMD_BT_OKAY 0x1000
  342. #define EXT_OR_CMD_BT_DENY 0x1001
  343. #define EXT_OR_CMD_BT_CONTROL 0x1002
  344. /** Process a USERADDR command from the Extended
  345. * ORPort. <b>payload</b> is a payload of size <b>len</b>.
  346. *
  347. * If the USERADDR command was well formed, change the address of
  348. * <b>conn</b> to the address on the USERADDR command.
  349. *
  350. * Return 0 on success and -1 on error. */
  351. static int
  352. connection_ext_or_handle_cmd_useraddr(connection_t *conn,
  353. const char *payload, uint16_t len)
  354. {
  355. /* Copy address string. */
  356. tor_addr_t addr;
  357. uint16_t port;
  358. char *addr_str;
  359. char *address_part=NULL;
  360. int res;
  361. if (memchr(payload, '\0', len)) {
  362. log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort UserAddr");
  363. return -1;
  364. }
  365. addr_str = tor_memdup_nulterm(payload, len);
  366. res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
  367. tor_free(addr_str);
  368. if (res<0)
  369. return -1;
  370. res = tor_addr_parse(&addr, address_part);
  371. tor_free(address_part);
  372. if (res<0)
  373. return -1;
  374. { /* do some logging */
  375. char *old_address = tor_dup_addr(&conn->addr);
  376. char *new_address = tor_dup_addr(&addr);
  377. log_debug(LD_NET, "Received USERADDR."
  378. "We rewrite our address from '%s:%u' to '%s:%u'.",
  379. safe_str(old_address), conn->port, safe_str(new_address), port);
  380. tor_free(old_address);
  381. tor_free(new_address);
  382. }
  383. /* record the address */
  384. tor_addr_copy(&conn->addr, &addr);
  385. conn->port = port;
  386. return 0;
  387. }
  388. /** Process a TRANSPORT command from the Extended
  389. * ORPort. <b>payload</b> is a payload of size <b>len</b>.
  390. *
  391. * If the TRANSPORT command was well formed, register the name of the
  392. * transport on <b>conn</b>.
  393. *
  394. * Return 0 on success and -1 on error. */
  395. static int
  396. connection_ext_or_handle_cmd_transport(or_connection_t *conn,
  397. const char *payload, uint16_t len)
  398. {
  399. char *transport_str;
  400. if (memchr(payload, '\0', len)) {
  401. log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort Transport");
  402. return -1;
  403. }
  404. transport_str = tor_memdup_nulterm(payload, len);
  405. /* Transport names MUST be C-identifiers. */
  406. if (!string_is_C_identifier(transport_str)) {
  407. tor_free(transport_str);
  408. return -1;
  409. }
  410. /* If ext_or_transport is already occupied (because the PT sent two
  411. * TRANSPORT commands), deallocate the old name and keep the new
  412. * one */
  413. if (conn->ext_or_transport)
  414. tor_free(conn->ext_or_transport);
  415. conn->ext_or_transport = transport_str;
  416. return 0;
  417. }
  418. #define EXT_OR_CONN_STATE_IS_AUTHENTICATING(st) \
  419. ((st) <= EXT_OR_CONN_STATE_AUTH_MAX)
  420. /** Process Extended ORPort messages from <b>or_conn</b>. */
  421. int
  422. connection_ext_or_process_inbuf(or_connection_t *or_conn)
  423. {
  424. connection_t *conn = TO_CONN(or_conn);
  425. ext_or_cmd_t *command;
  426. int r;
  427. /* DOCDOC Document the state machine and transitions in this function */
  428. /* If we are still in the authentication stage, process traffic as
  429. authentication data: */
  430. while (EXT_OR_CONN_STATE_IS_AUTHENTICATING(conn->state)) {
  431. log_debug(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
  432. (unsigned int) connection_get_inbuf_len(conn));
  433. r = connection_ext_or_auth_process_inbuf(or_conn);
  434. if (r < 0) {
  435. connection_mark_for_close(conn);
  436. return -1;
  437. } else if (r == 0) {
  438. return 0;
  439. }
  440. /* if r > 0, loop and process more data (if any). */
  441. }
  442. while (1) {
  443. log_debug(LD_GENERAL, "Got Extended ORPort data.");
  444. command = NULL;
  445. r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
  446. if (r < 0)
  447. goto err;
  448. else if (r == 0)
  449. return 0; /* need to wait for more data */
  450. /* Got a command! */
  451. tor_assert(command);
  452. if (command->cmd == EXT_OR_CMD_TB_DONE) {
  453. if (connection_get_inbuf_len(conn)) {
  454. /* The inbuf isn't empty; the client is misbehaving. */
  455. goto err;
  456. }
  457. log_debug(LD_NET, "Received DONE.");
  458. /* If the transport proxy did not use the TRANSPORT command to
  459. * specify the transport name, mark this as unknown transport. */
  460. if (!or_conn->ext_or_transport) {
  461. /* We write this string this way to avoid ??>, which is a C
  462. * trigraph. */
  463. or_conn->ext_or_transport = tor_strdup("<?" "?>");
  464. }
  465. connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
  466. /* can't transition immediately; need to flush first. */
  467. conn->state = EXT_OR_CONN_STATE_FLUSHING;
  468. connection_stop_reading(conn);
  469. } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
  470. if (connection_ext_or_handle_cmd_useraddr(conn,
  471. command->body, command->len) < 0)
  472. goto err;
  473. } else if (command->cmd == EXT_OR_CMD_TB_TRANSPORT) {
  474. if (connection_ext_or_handle_cmd_transport(or_conn,
  475. command->body, command->len) < 0)
  476. goto err;
  477. } else {
  478. log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
  479. command->cmd);
  480. }
  481. ext_or_cmd_free(command);
  482. }
  483. return 0;
  484. err:
  485. ext_or_cmd_free(command);
  486. connection_mark_for_close(conn);
  487. return -1;
  488. }
  489. /** <b>conn</b> finished flushing Extended ORPort messages to the
  490. * network, and is now ready to accept OR traffic. This function
  491. * does the transition. */
  492. int
  493. connection_ext_or_finished_flushing(or_connection_t *conn)
  494. {
  495. if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
  496. connection_start_reading(TO_CONN(conn));
  497. connection_ext_or_transition(conn);
  498. }
  499. return 0;
  500. }
  501. /** Initiate Extended ORPort authentication, by sending the list of
  502. * supported authentication types to the client. */
  503. int
  504. connection_ext_or_start_auth(or_connection_t *or_conn)
  505. {
  506. connection_t *conn = TO_CONN(or_conn);
  507. char authtypes[2] = "\x01\x00"; /* We only support authtype '1' for now. */
  508. log_debug(LD_GENERAL,
  509. "ExtORPort authentication: Sending supported authentication types");
  510. connection_write_to_buf(authtypes, sizeof(authtypes), conn);
  511. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
  512. return 0;
  513. }