mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Validate SOCKS arguments.
This commit is contained in:
parent
757b03aacb
commit
faf4f6c6d1
@ -4025,6 +4025,40 @@ options_init_logs(or_options_t *options, int validate_only)
|
|||||||
return ok?0:-1;
|
return ok?0:-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Given a smartlist of SOCKS arguments to be passed to a transport
|
||||||
|
* proxy in <b>args</b>, validate them and return -1 if they are
|
||||||
|
* corrupted. Return 0 if they seem OK. */
|
||||||
|
static int
|
||||||
|
validate_transport_socks_arguments(const smartlist_t *args)
|
||||||
|
{
|
||||||
|
char *socks_string = NULL;
|
||||||
|
size_t socks_string_len;
|
||||||
|
|
||||||
|
tor_assert(args);
|
||||||
|
tor_assert(smartlist_len(args) > 0);
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH_BEGIN(args, const char *, s) {
|
||||||
|
if (!string_is_key_value(s)) /* arguments should be k=v items */
|
||||||
|
return -1;
|
||||||
|
} SMARTLIST_FOREACH_END(s);
|
||||||
|
|
||||||
|
socks_string = pt_stringify_socks_args(args);
|
||||||
|
if (!socks_string)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
socks_string_len = strlen(socks_string);
|
||||||
|
tor_free(socks_string);
|
||||||
|
|
||||||
|
if (socks_string_len > MAX_SOCKS5_AUTH_SIZE_TOTAL) {
|
||||||
|
log_warn(LD_CONFIG, "SOCKS arguments can't be more than %u bytes (%lu).",
|
||||||
|
MAX_SOCKS5_AUTH_SIZE_TOTAL,
|
||||||
|
(unsigned long) socks_string_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Read the contents of a Bridge line from <b>line</b>. Return 0
|
/** Read the contents of a Bridge line from <b>line</b>. Return 0
|
||||||
* if the line is well-formed, and -1 if it isn't. If
|
* if the line is well-formed, and -1 if it isn't. If
|
||||||
* <b>validate_only</b> is 0, and the line is well-formed, then add
|
* <b>validate_only</b> is 0, and the line is well-formed, then add
|
||||||
@ -4143,6 +4177,11 @@ parse_bridge_line(const char *line, int validate_only)
|
|||||||
bridge_add_from_config(&addr, port,
|
bridge_add_from_config(&addr, port,
|
||||||
fingerprint ? digest : NULL,
|
fingerprint ? digest : NULL,
|
||||||
transport_name, socks_args);
|
transport_name, socks_args);
|
||||||
|
} else {
|
||||||
|
if (socks_args) {
|
||||||
|
if (validate_transport_socks_arguments(socks_args) < 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
@ -89,6 +89,14 @@ int connection_connect(connection_t *conn, const char *address,
|
|||||||
const tor_addr_t *addr,
|
const tor_addr_t *addr,
|
||||||
uint16_t port, int *socket_error);
|
uint16_t port, int *socket_error);
|
||||||
|
|
||||||
|
/** Maximum size of information that we can fit into SOCKS5 username
|
||||||
|
or password fields. */
|
||||||
|
#define MAX_SOCKS5_AUTH_FIELD_SIZE 255
|
||||||
|
|
||||||
|
/** Total maximum size of information that we can fit into SOCKS5
|
||||||
|
username and password fields. */
|
||||||
|
#define MAX_SOCKS5_AUTH_SIZE_TOTAL 2*MAX_SOCKS5_AUTH_FIELD_SIZE
|
||||||
|
|
||||||
int connection_proxy_connect(connection_t *conn, int type);
|
int connection_proxy_connect(connection_t *conn, int type);
|
||||||
int connection_read_proxy_handshake(connection_t *conn);
|
int connection_read_proxy_handshake(connection_t *conn);
|
||||||
void log_failed_proxy_connection(connection_t *conn);
|
void log_failed_proxy_connection(connection_t *conn);
|
||||||
|
@ -1424,6 +1424,41 @@ pt_get_extra_info_descriptor_string(void)
|
|||||||
return the_string;
|
return the_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Stringify the SOCKS arguments in <b>socks_args</b> according to
|
||||||
|
* 180_pluggable_transport.txt. The string is allocated on the heap
|
||||||
|
* and it's the responsibility of the caller to free it after use. */
|
||||||
|
char *
|
||||||
|
pt_stringify_socks_args(const smartlist_t *socks_args)
|
||||||
|
{
|
||||||
|
/* tmp place to store escaped socks arguments, so that we can
|
||||||
|
concatenate them up afterwards */
|
||||||
|
smartlist_t *sl_tmp = NULL;
|
||||||
|
char *escaped_string = NULL;
|
||||||
|
char *new_string = NULL;
|
||||||
|
|
||||||
|
tor_assert(socks_args);
|
||||||
|
tor_assert(smartlist_len(socks_args) > 0);
|
||||||
|
|
||||||
|
sl_tmp = smartlist_new();
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) {
|
||||||
|
/* Escape ';' and '\'. */
|
||||||
|
escaped_string = tor_escape_str_for_socks_arg(s);
|
||||||
|
if (!escaped_string)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
smartlist_add(sl_tmp, escaped_string);
|
||||||
|
} SMARTLIST_FOREACH_END(s);
|
||||||
|
|
||||||
|
new_string = smartlist_join_strings(sl_tmp, ";", 0, NULL);
|
||||||
|
|
||||||
|
done:
|
||||||
|
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
|
||||||
|
smartlist_free(sl_tmp);
|
||||||
|
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
/** The tor config was read.
|
/** The tor config was read.
|
||||||
* Destroy all managed proxies that were marked by a previous call to
|
* Destroy all managed proxies that were marked by a previous call to
|
||||||
* prepare_proxy_list_for_config_read() and are not used by the new
|
* prepare_proxy_list_for_config_read() and are not used by the new
|
||||||
|
@ -55,6 +55,7 @@ void pt_prepare_proxy_list_for_config_read(void);
|
|||||||
void sweep_proxy_list(void);
|
void sweep_proxy_list(void);
|
||||||
|
|
||||||
smartlist_t *get_transport_proxy_ports(void);
|
smartlist_t *get_transport_proxy_ports(void);
|
||||||
|
char *pt_stringify_socks_args(const smartlist_t *socks_args);
|
||||||
|
|
||||||
#ifdef PT_PRIVATE
|
#ifdef PT_PRIVATE
|
||||||
/** State of the managed proxy configuration protocol. */
|
/** State of the managed proxy configuration protocol. */
|
||||||
|
Loading…
Reference in New Issue
Block a user