29 #define AUTHENTICATION_COOKIE_LEN 32
39 #define SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT \
40 "Tor safe cookie authentication server-to-controller hash"
41 #define SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT \
42 "Tor safe cookie authentication controller-to-server hash"
43 #define SAFECOOKIE_SERVER_NONCE_LEN DIGEST256_LEN
54 return get_datadir_fname(
"control_auth_cookie");
62 init_control_cookie_authentication(
int enabled)
96 for (cl = passwords; cl; cl = cl->next) {
97 const char *hashed = cl->value;
100 if (
base16_decode(decoded,
sizeof(decoded), hashed+3, strlen(hashed+3))
106 if (
base64_decode(decoded,
sizeof(decoded), hashed, strlen(hashed))
126 .accept_keywords=
true,
127 .kvline_flags=KV_OMIT_KEYS|KV_QUOTED_QSTRING,
137 size_t client_nonce_len;
140 char server_nonce[SAFECOOKIE_SERVER_NONCE_LEN];
141 char server_nonce_encoded[(2*SAFECOOKIE_SERVER_NONCE_LEN) + 1];
143 if (strcasecmp(smartlist_get(args->
args, 0),
"SAFECOOKIE")) {
145 "AUTHCHALLENGE only supports SAFECOOKIE "
153 if (args->
kwargs == NULL || args->
kwargs->next != NULL) {
155 "Wrong number of arguments for AUTHCHALLENGE");
158 if (strcmp(args->
kwargs->key,
"")) {
160 "AUTHCHALLENGE does not accept keyword "
165 bool contains_quote = strchr(args->
raw_body,
'\"');
166 if (contains_quote) {
168 client_nonce = tor_strdup(args->
kwargs->value);
169 client_nonce_len = strlen(client_nonce);
172 const char *hex_nonce = args->
kwargs->value;
173 client_nonce_len = strlen(hex_nonce) / 2;
174 client_nonce = tor_malloc(client_nonce_len);
176 strlen(hex_nonce)) != (
int)client_nonce_len) {
183 crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
192 SAFECOOKIE_SERVER_NONCE_LEN);
193 char *tmp = tor_malloc_zero(tmp_len);
198 server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
201 SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT,
202 strlen(SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT),
207 SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT,
208 strlen(SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT),
217 base16_encode(server_hash_encoded,
sizeof(server_hash_encoded),
218 server_hash,
sizeof(server_hash));
219 base16_encode(server_nonce_encoded,
sizeof(server_nonce_encoded),
220 server_nonce,
sizeof(server_nonce));
223 "AUTHCHALLENGE SERVERHASH=%s SERVERNONCE=%s",
225 server_nonce_encoded);
230 connection_mark_for_close(
TO_CONN(conn));
236 .accept_keywords=
true,
237 .kvline_flags=KV_OMIT_KEYS|KV_QUOTED_QSTRING,
249 bool used_quoted_string =
false;
251 const char *errstr =
"Unknown error";
254 int bad_cookie=0, bad_password=0;
257 if (args->
kwargs == NULL) {
258 password = tor_strdup(
"");
260 }
else if (args->
kwargs->next) {
262 connection_mark_for_close(
TO_CONN(conn));
264 }
else if (strcmp(args->
kwargs->key,
"")) {
266 "AUTHENTICATE does not accept keyword arguments.");
267 connection_mark_for_close(
TO_CONN(conn));
269 }
else if (strchr(args->
raw_body,
'\"')) {
270 used_quoted_string =
true;
271 password = tor_strdup(args->
kwargs->value);
272 password_len = strlen(password);
274 const char *hex_passwd = args->
kwargs->value;
275 password_len = strlen(hex_passwd) / 2;
276 password = tor_malloc(password_len+1);
277 if (
base16_decode(password, password_len+1, hex_passwd, strlen(hex_passwd))
278 != (
int) password_len) {
280 "Invalid hexadecimal encoding. Maybe you tried a plain text "
281 "password? If so, the standard requires that you put it in "
283 connection_mark_for_close(
TO_CONN(conn));
298 "Got safe cookie authentication response with wrong length "
299 "(%d)", (
int)password_len);
300 errstr =
"Wrong length for safe cookie response.";
306 "Got incorrect safe cookie authentication response");
307 errstr =
"Safe cookie response did not match expected value.";
326 if (!also_password) {
327 log_warn(
LD_CONTROL,
"Got authentication cookie with wrong length "
328 "(%d)", (
int)password_len);
329 errstr =
"Wrong length on authentication cookie.";
334 if (!also_password) {
335 log_warn(
LD_CONTROL,
"Got mismatched authentication cookie");
336 errstr =
"Authentication cookie did not match expected value.";
358 smartlist_free(sl_tmp);
367 smartlist_free(sl_tmp);
373 "Couldn't decode HashedControlPassword: invalid base16");
374 errstr=
"Couldn't decode HashedControlPassword value in configuration.";
385 password,password_len,expected);
394 if (used_quoted_string)
395 errstr =
"Password did not match HashedControlPassword value from "
398 errstr =
"Password did not match HashedControlPassword value from "
399 "configuration. Maybe you tried a plain text password? "
400 "If so, the standard requires that you put it in double quotes.";
409 log_warn(
LD_CONTROL,
"Bad password or authentication cookie on controller.");
410 errstr =
"Password did not match HashedControlPassword *or* authentication "
416 connection_mark_for_close(
TO_CONN(conn));
423 log_info(
LD_CONTROL,
"Authenticated control connection ("TOR_SOCKET_T_FORMAT
436 control_auth_free_all(
void)
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
const or_options_t * get_options(void)
int init_cookie_authentication(const char *fname, const char *header, int cookie_len, int group_readable, uint8_t **cookie_out, int *cookie_is_set_out)
Header file for config.c.
Header file for connection.c.
Header file for control.c.
#define CONTROL_CONN_STATE_OPEN
static uint8_t * authentication_cookie
int handle_control_authchallenge(control_connection_t *conn, const control_cmd_args_t *args)
char * get_controller_cookie_file_name(void)
#define AUTHENTICATION_COOKIE_LEN
smartlist_t * decode_hashed_passwords(config_line_t *passwords)
int handle_control_authenticate(control_connection_t *conn, const control_cmd_args_t *args)
static int authentication_cookie_is_set
Header file for control_auth.c.
Header file for control_cmd.c.
Definition for control_cmd_args_t.
Controller connection structure.
void control_write_endreply(control_connection_t *conn, int code, const char *s)
void send_control_done(control_connection_t *conn)
void control_printf_endreply(control_connection_t *conn, int code, const char *fmt,...)
Header file for control_proto.c.
#define HEX_DIGEST256_LEN
void crypto_hmac_sha256(char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
void secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret, size_t secret_len, const char *s2k_specifier)
#define S2K_RFC2440_SPECIFIER_LEN
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
#define tor_memneq(a, b, sz)
Master header file for Tor-specific functionality.
void smartlist_add_all(smartlist_t *s1, const smartlist_t *s2)
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
struct smartlist_t * args
struct config_line_t * kwargs
char * safecookie_client_hash
struct config_line_t * HashedControlPassword
struct config_line_t * HashedControlSessionPassword
int strcmpstart(const char *s1, const char *s2)