ext_orport.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  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. /* Code to indicate cookie authentication */
  97. #define EXT_OR_AUTHTYPE_SAFECOOKIE 0x01
  98. /** If true, we've set ext_or_auth_cookie to a secret code and stored
  99. * it to disk. */
  100. STATIC int ext_or_auth_cookie_is_set = 0;
  101. /** If ext_or_auth_cookie_is_set, a secret cookie that we've stored to disk
  102. * and which we're using to authenticate controllers. (If the controller can
  103. * read it off disk, it has permission to connect.) */
  104. STATIC char ext_or_auth_cookie[EXT_OR_PORT_AUTH_COOKIE_LEN] = {0};
  105. /** Helper: Return a newly allocated string containing a path to the
  106. * file where we store our authentication cookie. */
  107. char *
  108. get_ext_or_auth_cookie_file_name(void)
  109. {
  110. const or_options_t *options = get_options();
  111. if (options->ExtORPortCookieAuthFile &&
  112. strlen(options->ExtORPortCookieAuthFile)) {
  113. return tor_strdup(options->ExtORPortCookieAuthFile);
  114. } else {
  115. return get_datadir_fname("extended_orport_auth_cookie");
  116. }
  117. }
  118. /** Choose a random authentication cookie and write it to disk.
  119. * Anybody who can read the cookie from disk will be considered
  120. * authorized to use the control connection. Return -1 if we can't
  121. * write the file, or 0 on success. */
  122. int
  123. init_ext_or_cookie_authentication(int is_enabled)
  124. {
  125. char *fname;
  126. char cookie_file_string[EXT_OR_PORT_AUTH_COOKIE_FILE_LEN];
  127. if (!is_enabled) {
  128. ext_or_auth_cookie_is_set = 0;
  129. return 0;
  130. }
  131. /* We don't want to generate a new cookie every time we call
  132. * options_act(). One should be enough. */
  133. if (ext_or_auth_cookie_is_set)
  134. return 0; /* all set */
  135. if (crypto_rand(ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN) < 0)
  136. return -1;
  137. ext_or_auth_cookie_is_set = 1;
  138. memcpy(cookie_file_string, EXT_OR_PORT_AUTH_COOKIE_HEADER,
  139. EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN);
  140. memcpy(cookie_file_string+EXT_OR_PORT_AUTH_COOKIE_HEADER_LEN,
  141. ext_or_auth_cookie, EXT_OR_PORT_AUTH_COOKIE_LEN);
  142. fname = get_ext_or_auth_cookie_file_name();
  143. if (write_bytes_to_file(fname, cookie_file_string,
  144. EXT_OR_PORT_AUTH_COOKIE_FILE_LEN, 1)) {
  145. log_warn(LD_FS,"Error writing authentication cookie to %s.",
  146. escaped(fname));
  147. tor_free(fname);
  148. return -1;
  149. }
  150. log_info(LD_GENERAL, "Generated Extended ORPort cookie file in '%s'.",
  151. fname);
  152. memwipe(cookie_file_string, 0, sizeof(cookie_file_string));
  153. tor_free(fname);
  154. return 0;
  155. }
  156. /** Read data from <b>conn</b> and see if the client sent us the
  157. * authentication type that she prefers to use in this session.
  158. *
  159. * Return -1 if we received corrupted data or if we don't support the
  160. * authentication type. Return 0 if we need more data in
  161. * <b>conn</b>. Return 1 if the authentication type negotiation was
  162. * successful. */
  163. static int
  164. connection_ext_or_auth_neg_auth_type(connection_t *conn)
  165. {
  166. char authtype[1] = {0};
  167. if (connection_get_inbuf_len(conn) < 1)
  168. return 0;
  169. if (connection_fetch_from_buf(authtype, 1, conn) < 0)
  170. return -1;
  171. log_debug(LD_GENERAL, "Client wants us to use %d auth type", authtype[0]);
  172. if (authtype[0] != EXT_OR_AUTHTYPE_SAFECOOKIE) {
  173. /* '1' is the only auth type supported atm */
  174. return -1;
  175. }
  176. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE;
  177. return 1;
  178. }
  179. /** DOCDOC */
  180. STATIC int
  181. handle_client_auth_nonce(const char *client_nonce, size_t client_nonce_len,
  182. char **client_hash_out,
  183. char **reply_out, size_t *reply_len_out)
  184. {
  185. char server_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
  186. char server_nonce[EXT_OR_PORT_AUTH_NONCE_LEN] = {0};
  187. char *reply;
  188. size_t reply_len;
  189. if (client_nonce_len != EXT_OR_PORT_AUTH_NONCE_LEN)
  190. return -1;
  191. /* Get our nonce */
  192. if (crypto_rand(server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN) < 0)
  193. return -1;
  194. { /* set up macs */
  195. size_t hmac_s_msg_len = strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
  196. 2*EXT_OR_PORT_AUTH_NONCE_LEN;
  197. size_t hmac_c_msg_len = strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
  198. 2*EXT_OR_PORT_AUTH_NONCE_LEN;
  199. char *hmac_s_msg = tor_malloc_zero(hmac_s_msg_len);
  200. char *hmac_c_msg = tor_malloc_zero(hmac_c_msg_len);
  201. char *correct_client_hash = tor_malloc_zero(EXT_OR_PORT_AUTH_HASH_LEN);
  202. memcpy(hmac_s_msg,
  203. EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST,
  204. strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST));
  205. memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST),
  206. client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  207. memcpy(hmac_s_msg + strlen(EXT_OR_PORT_AUTH_SERVER_TO_CLIENT_CONST) +
  208. EXT_OR_PORT_AUTH_NONCE_LEN,
  209. server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  210. memcpy(hmac_c_msg,
  211. EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST,
  212. strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST));
  213. memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST),
  214. client_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  215. memcpy(hmac_c_msg + strlen(EXT_OR_PORT_AUTH_CLIENT_TO_SERVER_CONST) +
  216. EXT_OR_PORT_AUTH_NONCE_LEN,
  217. server_nonce, EXT_OR_PORT_AUTH_NONCE_LEN);
  218. crypto_hmac_sha256(server_hash,
  219. ext_or_auth_cookie,
  220. EXT_OR_PORT_AUTH_COOKIE_LEN,
  221. hmac_s_msg,
  222. hmac_s_msg_len);
  223. crypto_hmac_sha256(correct_client_hash,
  224. ext_or_auth_cookie,
  225. EXT_OR_PORT_AUTH_COOKIE_LEN,
  226. hmac_c_msg,
  227. hmac_c_msg_len);
  228. /* Store the client hash we generated. We will need to compare it
  229. with the hash sent by the client. */
  230. *client_hash_out = correct_client_hash;
  231. memwipe(hmac_s_msg, 0, hmac_s_msg_len);
  232. memwipe(hmac_c_msg, 0, hmac_c_msg_len);
  233. tor_free(hmac_s_msg);
  234. tor_free(hmac_c_msg);
  235. }
  236. { /* debug logging */ /* XXX disable this codepath if not logging on debug?*/
  237. char server_hash_encoded[(2*EXT_OR_PORT_AUTH_HASH_LEN) + 1];
  238. char server_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
  239. char client_nonce_encoded[(2*EXT_OR_PORT_AUTH_NONCE_LEN) + 1];
  240. base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
  241. server_hash, sizeof(server_hash));
  242. base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
  243. server_nonce, sizeof(server_nonce));
  244. base16_encode(client_nonce_encoded, sizeof(client_nonce_encoded),
  245. client_nonce, sizeof(client_nonce));
  246. log_debug(LD_GENERAL,
  247. "server_hash: '%s'\nserver_nonce: '%s'\nclient_nonce: '%s'",
  248. server_hash_encoded, server_nonce_encoded, client_nonce_encoded);
  249. memwipe(server_hash_encoded, 0, sizeof(server_hash_encoded));
  250. memwipe(server_nonce_encoded, 0, sizeof(server_nonce_encoded));
  251. memwipe(client_nonce_encoded, 0, sizeof(client_nonce_encoded));
  252. }
  253. { /* write reply: (server_hash, server_nonce) */
  254. reply_len = EXT_OR_PORT_AUTH_COOKIE_LEN+EXT_OR_PORT_AUTH_NONCE_LEN;
  255. reply = tor_malloc_zero(reply_len);
  256. memcpy(reply, server_hash, EXT_OR_PORT_AUTH_HASH_LEN);
  257. memcpy(reply + EXT_OR_PORT_AUTH_HASH_LEN, server_nonce,
  258. EXT_OR_PORT_AUTH_NONCE_LEN);
  259. }
  260. *reply_out = reply;
  261. *reply_len_out = reply_len;
  262. return 0;
  263. }
  264. /** Read the client's nonce out of <b>conn</b>, setup the safe-cookie
  265. * crypto, and then send our own hash and nonce to the client
  266. *
  267. * Return -1 if there was an error; return 0 if we need more data in
  268. * <b>conn</b>, and return 1 if we successfully retrieved the
  269. * client's nonce and sent our own. */
  270. static int
  271. connection_ext_or_auth_handle_client_nonce(connection_t *conn)
  272. {
  273. char client_nonce[EXT_OR_PORT_AUTH_NONCE_LEN];
  274. char *reply=NULL;
  275. size_t reply_len=0;
  276. if (!ext_or_auth_cookie_is_set) { /* this should not happen */
  277. log_warn(LD_BUG, "Extended ORPort authentication cookie was not set. "
  278. "That's weird since we should have done that on startup. "
  279. "This might be a Tor bug, please file a bug report. ");
  280. return -1;
  281. }
  282. if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_NONCE_LEN)
  283. return 0;
  284. if (connection_fetch_from_buf(client_nonce,
  285. EXT_OR_PORT_AUTH_NONCE_LEN, conn) < 0)
  286. return -1;
  287. /* We extract the ClientNonce from the received data, and use it to
  288. calculate ServerHash and ServerNonce according to proposal 217.
  289. We also calculate our own ClientHash value and save it in the
  290. connection state. We validate it later against the ClientHash
  291. sent by the client. */
  292. if (handle_client_auth_nonce(client_nonce, sizeof(client_nonce),
  293. &TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
  294. &reply, &reply_len) < 0)
  295. return -1;
  296. connection_write_to_buf(reply, reply_len, conn);
  297. memwipe(reply, 0, reply_len);
  298. tor_free(reply);
  299. log_debug(LD_GENERAL, "Got client nonce, and sent our own nonce and hash.");
  300. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH;
  301. return 1;
  302. }
  303. #define connection_ext_or_auth_send_result_success(c) \
  304. connection_ext_or_auth_send_result(c, 1)
  305. #define connection_ext_or_auth_send_result_fail(c) \
  306. connection_ext_or_auth_send_result(c, 0)
  307. /** Send authentication results to <b>conn</b>. Successful results if
  308. * <b>success</b> is set; failure results otherwise. */
  309. static void
  310. connection_ext_or_auth_send_result(connection_t *conn, int success)
  311. {
  312. if (success)
  313. connection_write_to_buf("\x01", 1, conn);
  314. else
  315. connection_write_to_buf("\x00", 1, conn);
  316. }
  317. /** Receive the client's hash from <b>conn</b>, validate that it's
  318. * correct, and then send the authentication results to the client.
  319. *
  320. * Return -1 if there was an error during validation; return 0 if we
  321. * need more data in <b>conn</b>, and return 1 if we successfully
  322. * validated the client's hash and sent a happy authentication
  323. * result. */
  324. static int
  325. connection_ext_or_auth_handle_client_hash(connection_t *conn)
  326. {
  327. char provided_client_hash[EXT_OR_PORT_AUTH_HASH_LEN] = {0};
  328. if (connection_get_inbuf_len(conn) < EXT_OR_PORT_AUTH_HASH_LEN)
  329. return 0;
  330. if (connection_fetch_from_buf(provided_client_hash,
  331. EXT_OR_PORT_AUTH_HASH_LEN, conn) < 0)
  332. return -1;
  333. if (tor_memneq(TO_OR_CONN(conn)->ext_or_auth_correct_client_hash,
  334. provided_client_hash, EXT_OR_PORT_AUTH_HASH_LEN)) {
  335. log_warn(LD_GENERAL, "Incorrect client hash. Authentication failed.");
  336. connection_ext_or_auth_send_result_fail(conn);
  337. return -1;
  338. }
  339. log_debug(LD_GENERAL, "Got client's hash and it was legit.");
  340. /* send positive auth result */
  341. connection_ext_or_auth_send_result_success(conn);
  342. conn->state = EXT_OR_CONN_STATE_OPEN;
  343. return 1;
  344. }
  345. /** Handle data from <b>or_conn</b> received on Extended ORPort.
  346. * Return -1 on error. 0 on unsufficient data. 1 on correct. */
  347. static int
  348. connection_ext_or_auth_process_inbuf(or_connection_t *or_conn)
  349. {
  350. connection_t *conn = TO_CONN(or_conn);
  351. /* State transitions of the Extended ORPort authentication protocol:
  352. EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE (start state) ->
  353. EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE ->
  354. EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH ->
  355. EXT_OR_CONN_STATE_OPEN
  356. During EXT_OR_CONN_STATE_OPEN, data is handled by
  357. connection_ext_or_process_inbuf().
  358. */
  359. switch (conn->state) { /* Functionify */
  360. case EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE:
  361. return connection_ext_or_auth_neg_auth_type(conn);
  362. case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_NONCE:
  363. return connection_ext_or_auth_handle_client_nonce(conn);
  364. case EXT_OR_CONN_STATE_AUTH_WAIT_CLIENT_HASH:
  365. return connection_ext_or_auth_handle_client_hash(conn);
  366. default:
  367. log_warn(LD_BUG, "Encountered unexpected connection state %d while trying "
  368. "to process Extended ORPort authentication data.", conn->state);
  369. return -1;
  370. }
  371. }
  372. /** Extended ORPort commands (Transport-to-Bridge) */
  373. #define EXT_OR_CMD_TB_DONE 0x0000
  374. #define EXT_OR_CMD_TB_USERADDR 0x0001
  375. #define EXT_OR_CMD_TB_TRANSPORT 0x0002
  376. /** Extended ORPort commands (Bridge-to-Transport) */
  377. #define EXT_OR_CMD_BT_OKAY 0x1000
  378. #define EXT_OR_CMD_BT_DENY 0x1001
  379. #define EXT_OR_CMD_BT_CONTROL 0x1002
  380. /** Process a USERADDR command from the Extended
  381. * ORPort. <b>payload</b> is a payload of size <b>len</b>.
  382. *
  383. * If the USERADDR command was well formed, change the address of
  384. * <b>conn</b> to the address on the USERADDR command.
  385. *
  386. * Return 0 on success and -1 on error. */
  387. static int
  388. connection_ext_or_handle_cmd_useraddr(connection_t *conn,
  389. const char *payload, uint16_t len)
  390. {
  391. /* Copy address string. */
  392. tor_addr_t addr;
  393. uint16_t port;
  394. char *addr_str;
  395. char *address_part=NULL;
  396. int res;
  397. if (memchr(payload, '\0', len)) {
  398. log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort UserAddr");
  399. return -1;
  400. }
  401. addr_str = tor_memdup_nulterm(payload, len);
  402. res = tor_addr_port_split(LOG_INFO, addr_str, &address_part, &port);
  403. tor_free(addr_str);
  404. if (res<0)
  405. return -1;
  406. res = tor_addr_parse(&addr, address_part);
  407. tor_free(address_part);
  408. if (res<0)
  409. return -1;
  410. { /* do some logging */
  411. char *old_address = tor_dup_addr(&conn->addr);
  412. char *new_address = tor_dup_addr(&addr);
  413. log_debug(LD_NET, "Received USERADDR."
  414. "We rewrite our address from '%s:%u' to '%s:%u'.",
  415. safe_str(old_address), conn->port, safe_str(new_address), port);
  416. tor_free(old_address);
  417. tor_free(new_address);
  418. }
  419. /* record the address */
  420. tor_addr_copy(&conn->addr, &addr);
  421. conn->port = port;
  422. return 0;
  423. }
  424. /** Process a TRANSPORT command from the Extended
  425. * ORPort. <b>payload</b> is a payload of size <b>len</b>.
  426. *
  427. * If the TRANSPORT command was well formed, register the name of the
  428. * transport on <b>conn</b>.
  429. *
  430. * Return 0 on success and -1 on error. */
  431. static int
  432. connection_ext_or_handle_cmd_transport(or_connection_t *conn,
  433. const char *payload, uint16_t len)
  434. {
  435. char *transport_str;
  436. if (memchr(payload, '\0', len)) {
  437. log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unexpected NUL in ExtORPort Transport");
  438. return -1;
  439. }
  440. transport_str = tor_memdup_nulterm(payload, len);
  441. /* Transport names MUST be C-identifiers. */
  442. if (!string_is_C_identifier(transport_str)) {
  443. tor_free(transport_str);
  444. return -1;
  445. }
  446. /* If ext_or_transport is already occupied (because the PT sent two
  447. * TRANSPORT commands), deallocate the old name and keep the new
  448. * one */
  449. if (conn->ext_or_transport)
  450. tor_free(conn->ext_or_transport);
  451. conn->ext_or_transport = transport_str;
  452. return 0;
  453. }
  454. #define EXT_OR_CONN_STATE_IS_AUTHENTICATING(st) \
  455. ((st) <= EXT_OR_CONN_STATE_AUTH_MAX)
  456. /** Process Extended ORPort messages from <b>or_conn</b>. */
  457. int
  458. connection_ext_or_process_inbuf(or_connection_t *or_conn)
  459. {
  460. connection_t *conn = TO_CONN(or_conn);
  461. ext_or_cmd_t *command;
  462. int r;
  463. /* DOCDOC Document the state machine and transitions in this function */
  464. /* If we are still in the authentication stage, process traffic as
  465. authentication data: */
  466. while (EXT_OR_CONN_STATE_IS_AUTHENTICATING(conn->state)) {
  467. log_debug(LD_GENERAL, "Got Extended ORPort authentication data (%u).",
  468. (unsigned int) connection_get_inbuf_len(conn));
  469. r = connection_ext_or_auth_process_inbuf(or_conn);
  470. if (r < 0) {
  471. connection_mark_for_close(conn);
  472. return -1;
  473. } else if (r == 0) {
  474. return 0;
  475. }
  476. /* if r > 0, loop and process more data (if any). */
  477. }
  478. while (1) {
  479. log_debug(LD_GENERAL, "Got Extended ORPort data.");
  480. command = NULL;
  481. r = connection_fetch_ext_or_cmd_from_buf(conn, &command);
  482. if (r < 0)
  483. goto err;
  484. else if (r == 0)
  485. return 0; /* need to wait for more data */
  486. /* Got a command! */
  487. tor_assert(command);
  488. if (command->cmd == EXT_OR_CMD_TB_DONE) {
  489. if (connection_get_inbuf_len(conn)) {
  490. /* The inbuf isn't empty; the client is misbehaving. */
  491. goto err;
  492. }
  493. log_debug(LD_NET, "Received DONE.");
  494. /* If the transport proxy did not use the TRANSPORT command to
  495. * specify the transport name, mark this as unknown transport. */
  496. if (!or_conn->ext_or_transport) {
  497. /* We write this string this way to avoid ??>, which is a C
  498. * trigraph. */
  499. or_conn->ext_or_transport = tor_strdup("<?" "?>");
  500. }
  501. connection_write_ext_or_command(conn, EXT_OR_CMD_BT_OKAY, NULL, 0);
  502. /* can't transition immediately; need to flush first. */
  503. conn->state = EXT_OR_CONN_STATE_FLUSHING;
  504. connection_stop_reading(conn);
  505. } else if (command->cmd == EXT_OR_CMD_TB_USERADDR) {
  506. if (connection_ext_or_handle_cmd_useraddr(conn,
  507. command->body, command->len) < 0)
  508. goto err;
  509. } else if (command->cmd == EXT_OR_CMD_TB_TRANSPORT) {
  510. if (connection_ext_or_handle_cmd_transport(or_conn,
  511. command->body, command->len) < 0)
  512. goto err;
  513. } else {
  514. log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
  515. command->cmd);
  516. }
  517. ext_or_cmd_free(command);
  518. }
  519. return 0;
  520. err:
  521. ext_or_cmd_free(command);
  522. connection_mark_for_close(conn);
  523. return -1;
  524. }
  525. /** <b>conn</b> finished flushing Extended ORPort messages to the
  526. * network, and is now ready to accept OR traffic. This function
  527. * does the transition. */
  528. int
  529. connection_ext_or_finished_flushing(or_connection_t *conn)
  530. {
  531. if (conn->base_.state == EXT_OR_CONN_STATE_FLUSHING) {
  532. connection_start_reading(TO_CONN(conn));
  533. connection_ext_or_transition(conn);
  534. }
  535. return 0;
  536. }
  537. /** Initiate Extended ORPort authentication, by sending the list of
  538. * supported authentication types to the client. */
  539. int
  540. connection_ext_or_start_auth(or_connection_t *or_conn)
  541. {
  542. connection_t *conn = TO_CONN(or_conn);
  543. const uint8_t authtypes[] = {
  544. /* We only support authtype '1' for now. */
  545. EXT_OR_AUTHTYPE_SAFECOOKIE,
  546. /* Marks the end of the list. */
  547. 0
  548. };
  549. log_debug(LD_GENERAL,
  550. "ExtORPort authentication: Sending supported authentication types");
  551. connection_write_to_buf((const char *)authtypes, sizeof(authtypes), conn);
  552. conn->state = EXT_OR_CONN_STATE_AUTH_WAIT_AUTH_TYPE;
  553. return 0;
  554. }