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