control_auth.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  2. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. /**
  5. * \file control_auth.c
  6. * \brief Authentication for Tor's control-socket interface.
  7. **/
  8. #include "core/or/or.h"
  9. #include "app/config/config.h"
  10. #include "core/mainloop/connection.h"
  11. #include "feature/control/control.h"
  12. #include "feature/control/control_cmd.h"
  13. #include "feature/control/control_auth.h"
  14. #include "feature/control/control_cmd_args_st.h"
  15. #include "feature/control/control_connection_st.h"
  16. #include "feature/control/control_proto.h"
  17. #include "lib/crypt_ops/crypto_rand.h"
  18. #include "lib/crypt_ops/crypto_util.h"
  19. #include "lib/encoding/confline.h"
  20. #include "lib/encoding/kvline.h"
  21. #include "lib/encoding/qstring.h"
  22. #include "lib/crypt_ops/crypto_s2k.h"
  23. /** If we're using cookie-type authentication, how long should our cookies be?
  24. */
  25. #define AUTHENTICATION_COOKIE_LEN 32
  26. /** If true, we've set authentication_cookie to a secret code and
  27. * stored it to disk. */
  28. static int authentication_cookie_is_set = 0;
  29. /** If authentication_cookie_is_set, a secret cookie that we've stored to disk
  30. * and which we're using to authenticate controllers. (If the controller can
  31. * read it off disk, it has permission to connect.) */
  32. static uint8_t *authentication_cookie = NULL;
  33. #define SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT \
  34. "Tor safe cookie authentication server-to-controller hash"
  35. #define SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT \
  36. "Tor safe cookie authentication controller-to-server hash"
  37. #define SAFECOOKIE_SERVER_NONCE_LEN DIGEST256_LEN
  38. /** Helper: Return a newly allocated string containing a path to the
  39. * file where we store our authentication cookie. */
  40. char *
  41. get_controller_cookie_file_name(void)
  42. {
  43. const or_options_t *options = get_options();
  44. if (options->CookieAuthFile && strlen(options->CookieAuthFile)) {
  45. return tor_strdup(options->CookieAuthFile);
  46. } else {
  47. return get_datadir_fname("control_auth_cookie");
  48. }
  49. }
  50. /* Initialize the cookie-based authentication system of the
  51. * ControlPort. If <b>enabled</b> is 0, then disable the cookie
  52. * authentication system. */
  53. int
  54. init_control_cookie_authentication(int enabled)
  55. {
  56. char *fname = NULL;
  57. int retval;
  58. if (!enabled) {
  59. authentication_cookie_is_set = 0;
  60. return 0;
  61. }
  62. fname = get_controller_cookie_file_name();
  63. retval = init_cookie_authentication(fname, "", /* no header */
  64. AUTHENTICATION_COOKIE_LEN,
  65. get_options()->CookieAuthFileGroupReadable,
  66. &authentication_cookie,
  67. &authentication_cookie_is_set);
  68. tor_free(fname);
  69. return retval;
  70. }
  71. /** Decode the hashed, base64'd passwords stored in <b>passwords</b>.
  72. * Return a smartlist of acceptable passwords (unterminated strings of
  73. * length S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on
  74. * failure.
  75. */
  76. smartlist_t *
  77. decode_hashed_passwords(config_line_t *passwords)
  78. {
  79. char decoded[64];
  80. config_line_t *cl;
  81. smartlist_t *sl = smartlist_new();
  82. tor_assert(passwords);
  83. for (cl = passwords; cl; cl = cl->next) {
  84. const char *hashed = cl->value;
  85. if (!strcmpstart(hashed, "16:")) {
  86. if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))
  87. != S2K_RFC2440_SPECIFIER_LEN + DIGEST_LEN
  88. || strlen(hashed+3) != (S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN)*2) {
  89. goto err;
  90. }
  91. } else {
  92. if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
  93. != S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) {
  94. goto err;
  95. }
  96. }
  97. smartlist_add(sl,
  98. tor_memdup(decoded, S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN));
  99. }
  100. return sl;
  101. err:
  102. SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
  103. smartlist_free(sl);
  104. return NULL;
  105. }
  106. const control_cmd_syntax_t authchallenge_syntax = {
  107. .min_args = 1,
  108. .max_args = 1,
  109. .accept_keywords=true,
  110. .kvline_flags=KV_OMIT_KEYS|KV_QUOTED_QSTRING,
  111. .store_raw_body=true
  112. };
  113. /** Called when we get an AUTHCHALLENGE command. */
  114. int
  115. handle_control_authchallenge(control_connection_t *conn,
  116. const control_cmd_args_t *args)
  117. {
  118. char *client_nonce;
  119. size_t client_nonce_len;
  120. char server_hash[DIGEST256_LEN];
  121. char server_hash_encoded[HEX_DIGEST256_LEN+1];
  122. char server_nonce[SAFECOOKIE_SERVER_NONCE_LEN];
  123. char server_nonce_encoded[(2*SAFECOOKIE_SERVER_NONCE_LEN) + 1];
  124. if (strcasecmp(smartlist_get(args->args, 0), "SAFECOOKIE")) {
  125. control_write_endreply(conn, 513,
  126. "AUTHCHALLENGE only supports SAFECOOKIE " "authentication");
  127. goto fail;
  128. }
  129. if (!authentication_cookie_is_set) {
  130. control_write_endreply(conn, 515, "Cookie authentication is disabled");
  131. goto fail;
  132. }
  133. if (args->kwargs == NULL || args->kwargs->next != NULL) {
  134. /* connection_write_str_to_buf("512 AUTHCHALLENGE requires exactly "
  135. "2 arguments.\r\n", conn);
  136. */
  137. control_printf_endreply(conn, 512,
  138. "AUTHCHALLENGE dislikes argument list %s",
  139. escaped(args->raw_body));
  140. goto fail;
  141. }
  142. if (strcmp(args->kwargs->key, "")) {
  143. control_write_endreply(conn, 512,
  144. "AUTHCHALLENGE does not accept keyword " "arguments.");
  145. goto fail;
  146. }
  147. bool contains_quote = strchr(args->raw_body, '\"');
  148. if (contains_quote) {
  149. /* The nonce was quoted */
  150. client_nonce = tor_strdup(args->kwargs->value);
  151. client_nonce_len = strlen(client_nonce);
  152. } else {
  153. /* The nonce was should be in hex. */
  154. const char *hex_nonce = args->kwargs->value;
  155. client_nonce_len = strlen(hex_nonce) / 2;
  156. client_nonce = tor_malloc(client_nonce_len);
  157. if (base16_decode(client_nonce, client_nonce_len, hex_nonce,
  158. strlen(hex_nonce)) != (int)client_nonce_len) {
  159. control_write_endreply(conn, 513, "Invalid base16 client nonce");
  160. tor_free(client_nonce);
  161. goto fail;
  162. }
  163. }
  164. crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
  165. /* Now compute and send the server-to-controller response, and the
  166. * server's nonce. */
  167. tor_assert(authentication_cookie != NULL);
  168. {
  169. size_t tmp_len = (AUTHENTICATION_COOKIE_LEN +
  170. client_nonce_len +
  171. SAFECOOKIE_SERVER_NONCE_LEN);
  172. char *tmp = tor_malloc_zero(tmp_len);
  173. char *client_hash = tor_malloc_zero(DIGEST256_LEN);
  174. memcpy(tmp, authentication_cookie, AUTHENTICATION_COOKIE_LEN);
  175. memcpy(tmp + AUTHENTICATION_COOKIE_LEN, client_nonce, client_nonce_len);
  176. memcpy(tmp + AUTHENTICATION_COOKIE_LEN + client_nonce_len,
  177. server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
  178. crypto_hmac_sha256(server_hash,
  179. SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT,
  180. strlen(SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT),
  181. tmp,
  182. tmp_len);
  183. crypto_hmac_sha256(client_hash,
  184. SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT,
  185. strlen(SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT),
  186. tmp,
  187. tmp_len);
  188. conn->safecookie_client_hash = client_hash;
  189. tor_free(tmp);
  190. }
  191. base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
  192. server_hash, sizeof(server_hash));
  193. base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
  194. server_nonce, sizeof(server_nonce));
  195. control_printf_endreply(conn, 250,
  196. "AUTHCHALLENGE SERVERHASH=%s " "SERVERNONCE=%s",
  197. server_hash_encoded,
  198. server_nonce_encoded);
  199. tor_free(client_nonce);
  200. return 0;
  201. fail:
  202. connection_mark_for_close(TO_CONN(conn));
  203. return -1;
  204. }
  205. const control_cmd_syntax_t authenticate_syntax = {
  206. .max_args = 0,
  207. .accept_keywords=true,
  208. .kvline_flags=KV_OMIT_KEYS|KV_QUOTED_QSTRING,
  209. .store_raw_body=true
  210. };
  211. /** Called when we get an AUTHENTICATE message. Check whether the
  212. * authentication is valid, and if so, update the connection's state to
  213. * OPEN. Reply with DONE or ERROR.
  214. */
  215. int
  216. handle_control_authenticate(control_connection_t *conn,
  217. const control_cmd_args_t *args)
  218. {
  219. bool used_quoted_string = false;
  220. const or_options_t *options = get_options();
  221. const char *errstr = "Unknown error";
  222. char *password;
  223. size_t password_len;
  224. int bad_cookie=0, bad_password=0;
  225. smartlist_t *sl = NULL;
  226. if (args->kwargs == NULL) {
  227. password = tor_strdup("");
  228. password_len = 0;
  229. } else if (args->kwargs->next) {
  230. control_write_endreply(conn, 512, "Too many arguments to AUTHENTICATE.");
  231. connection_mark_for_close(TO_CONN(conn));
  232. return 0;
  233. } else if (strcmp(args->kwargs->key, "")) {
  234. control_write_endreply(conn, 512,
  235. "AUTHENTICATE does not accept keyword arguments.");
  236. connection_mark_for_close(TO_CONN(conn));
  237. return 0;
  238. } else if (strchr(args->raw_body, '\"')) {
  239. used_quoted_string = true;
  240. password = tor_strdup(args->kwargs->value);
  241. password_len = strlen(password);
  242. } else {
  243. const char *hex_passwd = args->kwargs->value;
  244. password_len = strlen(hex_passwd) / 2;
  245. password = tor_malloc(password_len+1);
  246. if (base16_decode(password, password_len+1, hex_passwd, strlen(hex_passwd))
  247. != (int) password_len) {
  248. control_write_endreply(conn, 551,
  249. "Invalid hexadecimal encoding. Maybe you tried a plain text " "password? If so, the standard requires that you put it in " "double quotes.");
  250. connection_mark_for_close(TO_CONN(conn));
  251. tor_free(password);
  252. return 0;
  253. }
  254. }
  255. if (conn->safecookie_client_hash != NULL) {
  256. /* The controller has chosen safe cookie authentication; the only
  257. * acceptable authentication value is the controller-to-server
  258. * response. */
  259. tor_assert(authentication_cookie_is_set);
  260. if (password_len != DIGEST256_LEN) {
  261. log_warn(LD_CONTROL,
  262. "Got safe cookie authentication response with wrong length "
  263. "(%d)", (int)password_len);
  264. errstr = "Wrong length for safe cookie response.";
  265. goto err;
  266. }
  267. if (tor_memneq(conn->safecookie_client_hash, password, DIGEST256_LEN)) {
  268. log_warn(LD_CONTROL,
  269. "Got incorrect safe cookie authentication response");
  270. errstr = "Safe cookie response did not match expected value.";
  271. goto err;
  272. }
  273. tor_free(conn->safecookie_client_hash);
  274. goto ok;
  275. }
  276. if (!options->CookieAuthentication && !options->HashedControlPassword &&
  277. !options->HashedControlSessionPassword) {
  278. /* if Tor doesn't demand any stronger authentication, then
  279. * the controller can get in with anything. */
  280. goto ok;
  281. }
  282. if (options->CookieAuthentication) {
  283. int also_password = options->HashedControlPassword != NULL ||
  284. options->HashedControlSessionPassword != NULL;
  285. if (password_len != AUTHENTICATION_COOKIE_LEN) {
  286. if (!also_password) {
  287. log_warn(LD_CONTROL, "Got authentication cookie with wrong length "
  288. "(%d)", (int)password_len);
  289. errstr = "Wrong length on authentication cookie.";
  290. goto err;
  291. }
  292. bad_cookie = 1;
  293. } else if (tor_memneq(authentication_cookie, password, password_len)) {
  294. if (!also_password) {
  295. log_warn(LD_CONTROL, "Got mismatched authentication cookie");
  296. errstr = "Authentication cookie did not match expected value.";
  297. goto err;
  298. }
  299. bad_cookie = 1;
  300. } else {
  301. goto ok;
  302. }
  303. }
  304. if (options->HashedControlPassword ||
  305. options->HashedControlSessionPassword) {
  306. int bad = 0;
  307. smartlist_t *sl_tmp;
  308. char received[DIGEST_LEN];
  309. int also_cookie = options->CookieAuthentication;
  310. sl = smartlist_new();
  311. if (options->HashedControlPassword) {
  312. sl_tmp = decode_hashed_passwords(options->HashedControlPassword);
  313. if (!sl_tmp)
  314. bad = 1;
  315. else {
  316. smartlist_add_all(sl, sl_tmp);
  317. smartlist_free(sl_tmp);
  318. }
  319. }
  320. if (options->HashedControlSessionPassword) {
  321. sl_tmp = decode_hashed_passwords(options->HashedControlSessionPassword);
  322. if (!sl_tmp)
  323. bad = 1;
  324. else {
  325. smartlist_add_all(sl, sl_tmp);
  326. smartlist_free(sl_tmp);
  327. }
  328. }
  329. if (bad) {
  330. if (!also_cookie) {
  331. log_warn(LD_BUG,
  332. "Couldn't decode HashedControlPassword: invalid base16");
  333. errstr="Couldn't decode HashedControlPassword value in configuration.";
  334. goto err;
  335. }
  336. bad_password = 1;
  337. SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
  338. smartlist_free(sl);
  339. sl = NULL;
  340. } else {
  341. SMARTLIST_FOREACH(sl, char *, expected,
  342. {
  343. secret_to_key_rfc2440(received,DIGEST_LEN,
  344. password,password_len,expected);
  345. if (tor_memeq(expected + S2K_RFC2440_SPECIFIER_LEN,
  346. received, DIGEST_LEN))
  347. goto ok;
  348. });
  349. SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
  350. smartlist_free(sl);
  351. sl = NULL;
  352. if (used_quoted_string)
  353. errstr = "Password did not match HashedControlPassword value from "
  354. "configuration";
  355. else
  356. errstr = "Password did not match HashedControlPassword value from "
  357. "configuration. Maybe you tried a plain text password? "
  358. "If so, the standard requires that you put it in double quotes.";
  359. bad_password = 1;
  360. if (!also_cookie)
  361. goto err;
  362. }
  363. }
  364. /** We only get here if both kinds of authentication failed. */
  365. tor_assert(bad_password && bad_cookie);
  366. log_warn(LD_CONTROL, "Bad password or authentication cookie on controller.");
  367. errstr = "Password did not match HashedControlPassword *or* authentication "
  368. "cookie.";
  369. err:
  370. tor_free(password);
  371. control_printf_endreply(conn, 515, "Authentication failed: %s", errstr);
  372. connection_mark_for_close(TO_CONN(conn));
  373. if (sl) { /* clean up */
  374. SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
  375. smartlist_free(sl);
  376. }
  377. return 0;
  378. ok:
  379. log_info(LD_CONTROL, "Authenticated control connection ("TOR_SOCKET_T_FORMAT
  380. ")", conn->base_.s);
  381. send_control_done(conn);
  382. conn->base_.state = CONTROL_CONN_STATE_OPEN;
  383. tor_free(password);
  384. if (sl) { /* clean up */
  385. SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
  386. smartlist_free(sl);
  387. }
  388. return 0;
  389. }
  390. void
  391. control_auth_free_all(void)
  392. {
  393. if (authentication_cookie) /* Free the auth cookie */
  394. tor_free(authentication_cookie);
  395. authentication_cookie_is_set = 0;
  396. }