mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Merge remote-tracking branch 'origin/maint-0.2.4'
This commit is contained in:
commit
3dfd1ebf12
6 changed files with 57 additions and 7 deletions
13
changes/bug8117
Normal file
13
changes/bug8117
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
o Major bugfixes:
|
||||||
|
|
||||||
|
- Many SOCKS5 clients, when configured to offer a username/password,
|
||||||
|
offer both username/password authentication and "no authentication".
|
||||||
|
Tor had previously preferred no authentication, but this was
|
||||||
|
problematic when trying to make applications get proper stream
|
||||||
|
isolation with IsolateSOCKSAuth. Now, on any SOCKS port with
|
||||||
|
IsolateSOCKSAuth turned on (which is the default), Tor selects
|
||||||
|
username/password authentication if it's offered. If this confuses your
|
||||||
|
application, you can disable it on a per-SOCKSPort basis via
|
||||||
|
PreferSOCKSNoAuth. Fixes bug 8117; bugfix on 0.2.3.3-alpha.
|
||||||
|
|
||||||
|
|
|
@ -972,6 +972,15 @@ The following options are useful only for clients (that is, if
|
||||||
should get automapped (according to AutomapHostsOnResove),
|
should get automapped (according to AutomapHostsOnResove),
|
||||||
if we could return either an IPv4 or an IPv6 answer, prefer
|
if we could return either an IPv4 or an IPv6 answer, prefer
|
||||||
an IPv6 answer. (On by default.)
|
an IPv6 answer. (On by default.)
|
||||||
|
**PreferSOCKSNoAuth**;;
|
||||||
|
Ordinarily, when an application offers both "username/password
|
||||||
|
authentication" and "no authentication" to Tor via SOCKS5, Tor
|
||||||
|
selects username/password authentication so that IsolateSOCKSAuth can
|
||||||
|
work. This can confuse some applications, if they offer a
|
||||||
|
username/password combination then get confused when asked for
|
||||||
|
one. You can disable this behavior, so that Tor will select "No
|
||||||
|
authentication" when IsolateSOCKSAuth is disabled, or when this
|
||||||
|
option is set.
|
||||||
|
|
||||||
**SOCKSListenAddress** __IP__[:__PORT__]::
|
**SOCKSListenAddress** __IP__[:__PORT__]::
|
||||||
Bind to this address to listen for connections from Socks-speaking
|
Bind to this address to listen for connections from Socks-speaking
|
||||||
|
|
|
@ -1781,6 +1781,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||||
|
|
||||||
if (req->socks_version != 5) { /* we need to negotiate a method */
|
if (req->socks_version != 5) { /* we need to negotiate a method */
|
||||||
unsigned char nummethods = (unsigned char)*(data+1);
|
unsigned char nummethods = (unsigned char)*(data+1);
|
||||||
|
int have_user_pass, have_no_auth;
|
||||||
int r=0;
|
int r=0;
|
||||||
tor_assert(!req->socks_version);
|
tor_assert(!req->socks_version);
|
||||||
if (datalen < 2u+nummethods) {
|
if (datalen < 2u+nummethods) {
|
||||||
|
@ -1791,19 +1792,21 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||||
return -1;
|
return -1;
|
||||||
req->replylen = 2; /* 2 bytes of response */
|
req->replylen = 2; /* 2 bytes of response */
|
||||||
req->reply[0] = 5; /* socks5 reply */
|
req->reply[0] = 5; /* socks5 reply */
|
||||||
if (memchr(data+2, SOCKS_NO_AUTH, nummethods)) {
|
have_user_pass = (memchr(data+2, SOCKS_USER_PASS, nummethods) !=NULL);
|
||||||
req->reply[1] = SOCKS_NO_AUTH; /* tell client to use "none" auth
|
have_no_auth = (memchr(data+2, SOCKS_NO_AUTH, nummethods) !=NULL);
|
||||||
method */
|
if (have_user_pass && !(have_no_auth && req->socks_prefer_no_auth)) {
|
||||||
req->socks_version = 5; /* remember we've already negotiated auth */
|
|
||||||
log_debug(LD_APP,"socks5: accepted method 0 (no authentication)");
|
|
||||||
r=0;
|
|
||||||
} else if (memchr(data+2, SOCKS_USER_PASS, nummethods)) {
|
|
||||||
req->auth_type = SOCKS_USER_PASS;
|
req->auth_type = SOCKS_USER_PASS;
|
||||||
req->reply[1] = SOCKS_USER_PASS; /* tell client to use "user/pass"
|
req->reply[1] = SOCKS_USER_PASS; /* tell client to use "user/pass"
|
||||||
auth method */
|
auth method */
|
||||||
req->socks_version = 5; /* remember we've already negotiated auth */
|
req->socks_version = 5; /* remember we've already negotiated auth */
|
||||||
log_debug(LD_APP,"socks5: accepted method 2 (username/password)");
|
log_debug(LD_APP,"socks5: accepted method 2 (username/password)");
|
||||||
r=0;
|
r=0;
|
||||||
|
} else if (have_no_auth) {
|
||||||
|
req->reply[1] = SOCKS_NO_AUTH; /* tell client to use "none" auth
|
||||||
|
method */
|
||||||
|
req->socks_version = 5; /* remember we've already negotiated auth */
|
||||||
|
log_debug(LD_APP,"socks5: accepted method 0 (no authentication)");
|
||||||
|
r=0;
|
||||||
} else {
|
} else {
|
||||||
log_warn(LD_APP,
|
log_warn(LD_APP,
|
||||||
"socks5: offered methods don't include 'no auth' or "
|
"socks5: offered methods don't include 'no auth' or "
|
||||||
|
|
|
@ -5097,6 +5097,7 @@ parse_port_config(smartlist_t *out,
|
||||||
int port;
|
int port;
|
||||||
int sessiongroup = SESSION_GROUP_UNSET;
|
int sessiongroup = SESSION_GROUP_UNSET;
|
||||||
unsigned isolation = ISO_DEFAULT;
|
unsigned isolation = ISO_DEFAULT;
|
||||||
|
int prefer_no_auth = 0;
|
||||||
|
|
||||||
char *addrport;
|
char *addrport;
|
||||||
uint16_t ptmp=0;
|
uint16_t ptmp=0;
|
||||||
|
@ -5264,6 +5265,9 @@ parse_port_config(smartlist_t *out,
|
||||||
} else if (!strcasecmp(elt, "PreferIPv6Automap")) {
|
} else if (!strcasecmp(elt, "PreferIPv6Automap")) {
|
||||||
prefer_ipv6_automap = ! no;
|
prefer_ipv6_automap = ! no;
|
||||||
continue;
|
continue;
|
||||||
|
} else if (!strcasecmp(elt, "PreferSOCKSNoAuth")) {
|
||||||
|
prefer_no_auth = ! no;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmpend(elt, "s"))
|
if (!strcasecmpend(elt, "s"))
|
||||||
|
@ -5323,6 +5327,9 @@ parse_port_config(smartlist_t *out,
|
||||||
cfg->use_cached_ipv4_answers = use_cached_ipv4;
|
cfg->use_cached_ipv4_answers = use_cached_ipv4;
|
||||||
cfg->use_cached_ipv6_answers = use_cached_ipv6;
|
cfg->use_cached_ipv6_answers = use_cached_ipv6;
|
||||||
cfg->prefer_ipv6_virtaddr = prefer_ipv6_automap;
|
cfg->prefer_ipv6_virtaddr = prefer_ipv6_automap;
|
||||||
|
cfg->socks_prefer_no_auth = prefer_no_auth;
|
||||||
|
if (! (isolation & ISO_SOCKSAUTH))
|
||||||
|
cfg->socks_prefer_no_auth = 1;
|
||||||
|
|
||||||
smartlist_add(out, cfg);
|
smartlist_add(out, cfg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1146,6 +1146,7 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
||||||
lis_conn->use_cached_ipv4_answers = port_cfg->use_cached_ipv4_answers;
|
lis_conn->use_cached_ipv4_answers = port_cfg->use_cached_ipv4_answers;
|
||||||
lis_conn->use_cached_ipv6_answers = port_cfg->use_cached_ipv6_answers;
|
lis_conn->use_cached_ipv6_answers = port_cfg->use_cached_ipv6_answers;
|
||||||
lis_conn->prefer_ipv6_virtaddr = port_cfg->prefer_ipv6_virtaddr;
|
lis_conn->prefer_ipv6_virtaddr = port_cfg->prefer_ipv6_virtaddr;
|
||||||
|
lis_conn->socks_prefer_no_auth = port_cfg->socks_prefer_no_auth;
|
||||||
|
|
||||||
if (connection_add(conn) < 0) { /* no space, forget it */
|
if (connection_add(conn) < 0) { /* no space, forget it */
|
||||||
log_warn(LD_NET,"connection_add for listener failed. Giving up.");
|
log_warn(LD_NET,"connection_add for listener failed. Giving up.");
|
||||||
|
@ -1326,6 +1327,11 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
||||||
newconn->port = port;
|
newconn->port = port;
|
||||||
newconn->address = tor_dup_addr(&addr);
|
newconn->address = tor_dup_addr(&addr);
|
||||||
|
|
||||||
|
if (new_type == CONN_TYPE_AP) {
|
||||||
|
TO_ENTRY_CONN(newconn)->socks_request->socks_prefer_no_auth =
|
||||||
|
TO_LISTENER_CONN(conn)->socks_prefer_no_auth;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (conn->socket_family == AF_UNIX) {
|
} else if (conn->socket_family == AF_UNIX) {
|
||||||
/* For now only control ports can be Unix domain sockets
|
/* For now only control ports can be Unix domain sockets
|
||||||
* and listeners at the same time */
|
* and listeners at the same time */
|
||||||
|
|
12
src/or/or.h
12
src/or/or.h
|
@ -1249,6 +1249,10 @@ typedef struct listener_connection_t {
|
||||||
/** One or more ISO_ flags to describe how to isolate streams. */
|
/** One or more ISO_ flags to describe how to isolate streams. */
|
||||||
uint8_t isolation_flags;
|
uint8_t isolation_flags;
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
/** For SOCKS connections only: If this is set, we will choose "no
|
||||||
|
* authentication" instead of "username/password" authentication if both
|
||||||
|
* are offered. Used as input to parse_socks. */
|
||||||
|
unsigned int socks_prefer_no_auth : 1;
|
||||||
|
|
||||||
/** For a SOCKS listeners, these fields describe whether we should
|
/** For a SOCKS listeners, these fields describe whether we should
|
||||||
* allow IPv4 and IPv6 addresses from our exit nodes, respectively.
|
* allow IPv4 and IPv6 addresses from our exit nodes, respectively.
|
||||||
|
@ -3241,6 +3245,10 @@ typedef struct port_cfg_t {
|
||||||
uint8_t isolation_flags; /**< Zero or more isolation flags */
|
uint8_t isolation_flags; /**< Zero or more isolation flags */
|
||||||
int session_group; /**< A session group, or -1 if this port is not in a
|
int session_group; /**< A session group, or -1 if this port is not in a
|
||||||
* session group. */
|
* session group. */
|
||||||
|
/* Socks only: */
|
||||||
|
/** When both no-auth and user/pass are advertised by a SOCKS client, select
|
||||||
|
* no-auth. */
|
||||||
|
unsigned int socks_prefer_no_auth : 1;
|
||||||
|
|
||||||
/* Server port types (or, dir) only: */
|
/* Server port types (or, dir) only: */
|
||||||
unsigned int no_advertise : 1;
|
unsigned int no_advertise : 1;
|
||||||
|
@ -4157,6 +4165,10 @@ struct socks_request_t {
|
||||||
* make sure we send back a socks reply for
|
* make sure we send back a socks reply for
|
||||||
* every connection. */
|
* every connection. */
|
||||||
unsigned int got_auth : 1; /**< Have we received any authentication data? */
|
unsigned int got_auth : 1; /**< Have we received any authentication data? */
|
||||||
|
/** If this is set, we will choose "no authentication" instead of
|
||||||
|
* "username/password" authentication if both are offered. Used as input to
|
||||||
|
* parse_socks. */
|
||||||
|
unsigned int socks_prefer_no_auth : 1;
|
||||||
|
|
||||||
/** Number of bytes in username; 0 if username is NULL */
|
/** Number of bytes in username; 0 if username is NULL */
|
||||||
size_t usernamelen;
|
size_t usernamelen;
|
||||||
|
|
Loading…
Add table
Reference in a new issue