control.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /* Copyright 2004 Nick Mathewson */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. #define CONTROL_CMD_ERROR 0x0000
  6. #define CONTROL_CMD_DONE 0x0001
  7. #define CONTROL_CMD_SETCONF 0x0002
  8. #define CONTROL_CMD_GETCONF 0x0003
  9. #define CONTROL_CMD_CONFVALUE 0x0004
  10. #define CONTROL_CMD_SETEVENTS 0x0005
  11. #define CONTROL_CMD_EVENT 0x0006
  12. #define CONTROL_CMD_AUTHENTICATE 0x0007
  13. #define _CONTROL_CMD_MAX_RECOGNIZED 0x0007
  14. #define ERR_UNSPECIFIED 0x0000
  15. #define ERR_UNRECOGNIZED_TYPE 0x0001
  16. #define ERR_UNRECOGNIZED_CONFIG_KEY 0x0002
  17. #define ERR_INVALID_CONFIG_VALUE 0x0003
  18. #define ERR_UNRECOGNIZED_EVENT_CODE 0x0004
  19. #define ERR_UNAUTHORIZED_USER 0x0005
  20. #define ERR_FAILED_AUTHENTICATION 0x0006
  21. #define _EVENT_MIN 0x0001
  22. #define EVENT_CIRCUIT_STATUS 0x0001
  23. #define EVENT_STREAM_STATUS 0x0002
  24. #define EVENT_OR_CONN_STATUS 0x0003
  25. #define EVENT_BANDWIDTH_USED 0x0004
  26. #define EVENT_WARNING 0x0005
  27. #define _EVENT_MAX 0x0005
  28. #define EVENT_IS_INTERESTING(e) (global_event_mask & (1<<(e)))
  29. static const char *CONTROL_COMMANDS[] = {
  30. "error",
  31. "done",
  32. "setconf",
  33. "getconf",
  34. "confvalue",
  35. "setevents",
  36. "events",
  37. "authenticate",
  38. };
  39. extern or_options_t options;
  40. static uint32_t global_event_mask = 0;
  41. #define AUTHENTICATION_COOKIE_LEN 32
  42. static int authentication_cookie_is_set = 0;
  43. static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
  44. static void update_global_event_mask(void);
  45. static void send_control_message(connection_t *conn, uint16_t type,
  46. uint16_t len, const char *body);
  47. static void send_control_done(connection_t *conn);
  48. static void send_control_error(connection_t *conn, uint16_t error,
  49. const char *message);
  50. static void send_control_event(uint16_t event, uint16_t len, const char *body);
  51. static int handle_control_setconf(connection_t *conn, uint16_t len,
  52. const char *body);
  53. static int handle_control_getconf(connection_t *conn, uint16_t len,
  54. const char *body);
  55. static int handle_control_setevents(connection_t *conn, uint16_t len,
  56. const char *body);
  57. static int handle_control_authenticate(connection_t *conn, uint16_t len,
  58. const char *body);
  59. static INLINE const char *
  60. control_cmd_to_string(uint16_t cmd)
  61. {
  62. return (cmd<=_CONTROL_CMD_MAX_RECOGNIZED) ? CONTROL_COMMANDS[cmd] : "Unknown";
  63. }
  64. static void update_global_event_mask(void)
  65. {
  66. connection_t **conns;
  67. int n_conns, i;
  68. global_event_mask = 0;
  69. get_connection_array(&conns, &n_conns);
  70. for (i = 0; i < n_conns; ++i) {
  71. if (conns[i]->type == CONN_TYPE_CONTROL &&
  72. conns[i]->state == CONTROL_CONN_STATE_OPEN) {
  73. global_event_mask |= conns[i]->event_mask;
  74. }
  75. }
  76. }
  77. static void
  78. send_control_message(connection_t *conn, uint16_t type, uint16_t len,
  79. const char *body)
  80. {
  81. char buf[4];
  82. tor_assert(conn);
  83. tor_assert(len || !body);
  84. tor_assert(type <= _CONTROL_CMD_MAX_RECOGNIZED);
  85. set_uint32(buf, htons(len));
  86. set_uint32(buf+2, htons(type));
  87. connection_write_to_buf(buf, 4, conn);
  88. if (len)
  89. connection_write_to_buf(body, len, conn);
  90. }
  91. static void
  92. send_control_done(connection_t *conn)
  93. {
  94. send_control_message(conn, CONTROL_CMD_DONE, 0, NULL);
  95. }
  96. static void
  97. send_control_error(connection_t *conn, uint16_t error, const char *message)
  98. {
  99. char buf[256];
  100. size_t len;
  101. set_uint16(buf, htons(error));
  102. len = strlen(message);
  103. tor_assert(len < (256-2));
  104. memcpy(buf+2, message, len);
  105. send_control_message(conn, CONTROL_CMD_ERROR, (uint16_t)(len+2), buf);
  106. }
  107. static void
  108. send_control_event(uint16_t event, uint16_t len, const char *body)
  109. {
  110. connection_t **conns;
  111. int n_conns, i;
  112. get_connection_array(&conns, &n_conns);
  113. for (i = 0; i < n_conns; ++i) {
  114. if (conns[i]->type == CONN_TYPE_CONTROL &&
  115. conns[i]->state == CONTROL_CONN_STATE_OPEN &&
  116. conns[i]->event_mask & (1<<event)) {
  117. send_control_message(conns[i], CONTROL_CMD_EVENT, len, body);
  118. }
  119. }
  120. }
  121. static int
  122. handle_control_setconf(connection_t *conn, uint16_t len,
  123. const char *body)
  124. {
  125. /* XXXX009 NM */
  126. return 0;
  127. }
  128. static int handle_control_getconf(connection_t *conn, uint16_t body_len,
  129. const char *body)
  130. {
  131. smartlist_t *answer_elements = NULL;
  132. char *msg = NULL;
  133. size_t msg_len;
  134. if (body[body_len-1] != '\0') {
  135. send_control_error(conn, ERR_UNSPECIFIED,
  136. "getconf message body not nul-terminated.");
  137. return 0;
  138. }
  139. /* Now we can be sure that body will end in a nul-terminated string. */
  140. answer_elements = smartlist_create();
  141. while (body_len) {
  142. size_t question_len = strlen(body);
  143. struct config_line_t *answer = config_get_assigned_option(&options,body);
  144. if (!answer) {
  145. send_control_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
  146. goto done;
  147. } else {
  148. while (answer) {
  149. struct config_line_t *next;
  150. smartlist_add(answer_elements, answer->key);
  151. smartlist_add(answer_elements, answer->value);
  152. next = answer->next;
  153. tor_free(answer);
  154. answer = next;
  155. }
  156. }
  157. body += question_len+1;
  158. body_len -= question_len+1;
  159. }
  160. msg = smartlist_join_strings2(answer_elements, "\0", 1, 0, &msg_len);
  161. send_control_message(conn, CONTROL_CMD_CONFVALUE,
  162. (uint16_t)msg_len, msg);
  163. done:
  164. SMARTLIST_FOREACH(answer_elements, char *, cp, tor_free(cp));
  165. smartlist_free(answer_elements);
  166. tor_free(msg);
  167. return 0;
  168. }
  169. static int handle_control_setevents(connection_t *conn, uint16_t len,
  170. const char *body)
  171. {
  172. uint16_t event_code;
  173. uint32_t event_mask = 0;
  174. if (len % 2) {
  175. send_control_error(conn, ERR_UNSPECIFIED,
  176. "Odd number of bytes in setevents message");
  177. return 0;
  178. }
  179. for (; len; len -= 2, body += 2) {
  180. event_code = ntohs(get_uint16(body));
  181. if (event_code < _EVENT_MIN || event_code > _EVENT_MAX) {
  182. send_control_error(conn, ERR_UNRECOGNIZED_EVENT_CODE,
  183. "Unrecognized event code");
  184. return 0;
  185. }
  186. event_mask |= (1 << event_code);
  187. }
  188. conn->event_mask = event_mask;
  189. update_global_event_mask();
  190. send_control_done(conn);
  191. return 0;
  192. }
  193. static int handle_control_authenticate(connection_t *conn, uint16_t len,
  194. const char *body)
  195. {
  196. if (len == AUTHENTICATION_COOKIE_LEN &&
  197. authentication_cookie_is_set &&
  198. !memcmp(authentication_cookie, body, len)) {
  199. goto ok;
  200. } else if (options.HashedControlPassword) {
  201. char expected[S2K_SPECIFIER_LEN+DIGEST_LEN];
  202. char received[DIGEST_LEN];
  203. if (base64_decode(expected,sizeof(expected),
  204. options.HashedControlPassword,
  205. strlen(options.HashedControlPassword))<0) {
  206. /* XXXX009 NM we should warn sooner. */
  207. log_fn(LOG_WARN,"Couldn't decode HashedControlPassword: invalid base64");
  208. goto err;
  209. }
  210. secret_to_key(received,DIGEST_LEN,body,len,expected);
  211. if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
  212. goto ok;
  213. }
  214. err:
  215. send_control_error(conn, ERR_FAILED_AUTHENTICATION,"Authentication failed");
  216. return 0;
  217. ok:
  218. log_fn(LOG_INFO, "Authenticated control connection (%d)", conn->s);
  219. send_control_done(conn);
  220. conn->state = CONTROL_CONN_STATE_OPEN;
  221. return 0;
  222. }
  223. int connection_control_finished_flushing(connection_t *conn) {
  224. tor_assert(conn);
  225. tor_assert(conn->type == CONN_TYPE_CONTROL);
  226. connection_stop_writing(conn);
  227. return 0;
  228. }
  229. int connection_control_process_inbuf(connection_t *conn) {
  230. uint16_t body_len, command_type;
  231. char *body;
  232. tor_assert(conn);
  233. tor_assert(conn->type == CONN_TYPE_CONTROL);
  234. again:
  235. switch(fetch_from_buf_control(conn->inbuf, &body_len, &command_type, &body))
  236. {
  237. case -1:
  238. log_fn(LOG_WARN, "Error in control command. Failing.");
  239. return -1;
  240. case 0:
  241. /* Control command not all here yet. Wait. */
  242. return 0;
  243. case 1:
  244. /* We got a command. Process it. */
  245. break;
  246. default:
  247. tor_assert(0);
  248. }
  249. /* We got a command. If we need authentication, only authentication
  250. * commands will be considered. */
  251. if (conn->state == CONTROL_CONN_STATE_NEEDAUTH &&
  252. command_type != CONTROL_CMD_AUTHENTICATE) {
  253. log_fn(LOG_WARN, "Rejecting '%s' command; authentication needed.",
  254. control_cmd_to_string(command_type));
  255. send_control_error(conn, ERR_UNAUTHORIZED_USER, "Authentication required");
  256. tor_free(body);
  257. goto again;
  258. }
  259. switch(command_type)
  260. {
  261. case CONTROL_CMD_SETCONF:
  262. if (handle_control_setconf(conn, body_len, body))
  263. return -1;
  264. break;
  265. case CONTROL_CMD_GETCONF:
  266. if (handle_control_getconf(conn, body_len, body))
  267. return -1;
  268. break;
  269. case CONTROL_CMD_SETEVENTS:
  270. if (handle_control_setevents(conn, body_len, body))
  271. return -1;
  272. break;
  273. case CONTROL_CMD_AUTHENTICATE:
  274. if (handle_control_authenticate(conn, body_len, body))
  275. return -1;
  276. break;
  277. case CONTROL_CMD_ERROR:
  278. case CONTROL_CMD_DONE:
  279. case CONTROL_CMD_CONFVALUE:
  280. case CONTROL_CMD_EVENT:
  281. log_fn(LOG_WARN, "Received client-only '%s' command; ignoring.",
  282. control_cmd_to_string(command_type));
  283. send_control_error(conn, ERR_UNRECOGNIZED_TYPE,
  284. "Command type only valid from server to tor client");
  285. break;
  286. default:
  287. log_fn(LOG_WARN, "Received unrecognized command type %d; ignoring.",
  288. (int)command_type);
  289. send_control_error(conn, ERR_UNRECOGNIZED_TYPE,
  290. "Unrecognized command type");
  291. break;
  292. }
  293. tor_free(body);
  294. goto again; /* There might be more data. */
  295. }
  296. int control_event_circuit_status(circuit_t *circ, circuit_status_event_t tp)
  297. {
  298. char *path, *msg;
  299. size_t path_len;
  300. if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
  301. return 0;
  302. tor_assert(circ);
  303. tor_assert(CIRCUIT_IS_ORIGIN(circ));
  304. path = circuit_list_path(circ);
  305. path_len = strlen(path);
  306. msg = tor_malloc(1+4+path_len+1); /* event, circid, path, NUL. */
  307. msg[0] = (uint8_t) tp;
  308. set_uint32(msg+1, htonl(circ->global_identifier));
  309. strlcpy(msg+5,path,path_len+1);
  310. send_control_event(EVENT_STREAM_STATUS, (uint16_t)(path_len+6), msg);
  311. tor_free(path);
  312. tor_free(msg);
  313. return 0;
  314. }
  315. int control_event_stream_status(connection_t *conn, stream_status_event_t tp)
  316. {
  317. char *msg;
  318. size_t len;
  319. tor_assert(conn->type == CONN_TYPE_AP);
  320. tor_assert(conn->socks_request);
  321. if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
  322. return 0;
  323. len = strlen(conn->socks_request->address);
  324. msg = tor_malloc(5+len+1);
  325. msg[0] = (uint8_t) tp;
  326. set_uint32(msg+1, htonl(conn->s)); /* ???? Is this a security problem? */
  327. strlcpy(msg+5, conn->socks_request->address, len+1);
  328. send_control_event(EVENT_STREAM_STATUS, (uint16_t)(5+len+1), msg);
  329. tor_free(msg);
  330. return 0;
  331. }
  332. int control_event_or_conn_status(connection_t *conn,or_conn_status_event_t tp)
  333. {
  334. char buf[HEX_DIGEST_LEN+3]; /* status, dollar, identity, NUL */
  335. size_t len;
  336. tor_assert(conn->type == CONN_TYPE_OR);
  337. if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
  338. return 0;
  339. buf[0] = (uint8_t)tp;
  340. strlcpy(buf+1,conn->nickname,sizeof(buf)-1);
  341. len = strlen(buf+1);
  342. send_control_event(EVENT_OR_CONN_STATUS, (uint16_t)(len+1), buf);
  343. return 0;
  344. }
  345. int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
  346. {
  347. char buf[8];
  348. if (!EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED))
  349. return 0;
  350. set_uint32(buf, htonl(n_read));
  351. set_uint32(buf+4, htonl(n_read));
  352. send_control_event(EVENT_BANDWIDTH_USED, 8, buf);
  353. return 0;
  354. }
  355. void control_event_logmsg(int severity, const char *msg)
  356. {
  357. size_t len;
  358. if (severity > LOG_WARN) /* Less important than warning? ignore for now. */
  359. return;
  360. if (!EVENT_IS_INTERESTING(EVENT_WARNING))
  361. return;
  362. len = strlen(msg);
  363. send_control_event(EVENT_WARNING, (uint16_t)(len+1), msg);
  364. }
  365. int init_cookie_authentication(void)
  366. {
  367. char fname[512];
  368. /* XXXX009 NM add config option to disable this. */
  369. tor_snprintf(fname, sizeof(fname), "%s/control_auth_cookie",
  370. get_data_directory(&options));
  371. crypto_rand(authentication_cookie, AUTHENTICATION_COOKIE_LEN);
  372. authentication_cookie_is_set = 1;
  373. if (write_bytes_to_file(fname, authentication_cookie,
  374. AUTHENTICATION_COOKIE_LEN, 1)) {
  375. log_fn(LOG_WARN,"Error writing authentication cookie.");
  376. return -1;
  377. }
  378. return 0;
  379. }
  380. /*
  381. Local Variabls:
  382. mode:c
  383. indent-tabs-mode:nil
  384. c-basic-offset:2
  385. End:
  386. */