mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Record username/password data in socks_request_t
This change also requires us to add and use a pair of allocator/deallocator functions for socks_request_t, instead of using tor_malloc_zero/tor_free directly.
This commit is contained in:
parent
204bce7e3c
commit
2e6604f42e
@ -1475,6 +1475,25 @@ log_unsafe_socks_warning(int socks_protocol, const char *address,
|
||||
socks_protocol, address, (int)port);
|
||||
}
|
||||
|
||||
/** Return a new socks_request_t. */
|
||||
socks_request_t *
|
||||
socks_request_new(void)
|
||||
{
|
||||
return tor_malloc_zero(sizeof(socks_request_t));
|
||||
}
|
||||
|
||||
/** Free all storage held in the socks_request_t <b>req</b>. */
|
||||
void
|
||||
socks_request_free(socks_request_t *req)
|
||||
{
|
||||
if (!req)
|
||||
return;
|
||||
tor_free(req->username);
|
||||
tor_free(req->password);
|
||||
memset(req, 0xCC, sizeof(socks_request_t));
|
||||
tor_free(req);
|
||||
}
|
||||
|
||||
/** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
|
||||
* of the forms
|
||||
* - socks4: "socksheader username\\0"
|
||||
@ -1631,7 +1650,6 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
tor_addr_t destaddr;
|
||||
uint32_t destip;
|
||||
uint8_t socksver;
|
||||
enum {socks4, socks4a} socks4_prot = socks4a;
|
||||
char *next, *startaddr;
|
||||
unsigned char usernamelen, passlen;
|
||||
struct in_addr in;
|
||||
@ -1662,6 +1680,14 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
req->reply[1] = 0; /* authentication successful */
|
||||
log_debug(LD_APP,
|
||||
"socks5: Accepted username/password without checking.");
|
||||
if (usernamelen) {
|
||||
req->username = tor_memdup(data+2u, usernamelen);
|
||||
req->usernamelen = usernamelen;
|
||||
}
|
||||
if (passlen) {
|
||||
req->password = tor_memdup(data+3u+usernamelen, passlen);
|
||||
req->passwordlen = passlen;
|
||||
}
|
||||
*drain_out = 2u + usernamelen + 1u + passlen;
|
||||
req->got_auth = 1;
|
||||
return 0;
|
||||
@ -1813,7 +1839,9 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
return -1;
|
||||
}
|
||||
tor_assert(0);
|
||||
case 4: /* socks4 */
|
||||
case 4: { /* socks4 */
|
||||
enum {socks4, socks4a} socks4_prot = socks4a;
|
||||
const char *authstart, *authend;
|
||||
/* http://ss5.sourceforge.net/socks4.protocol.txt */
|
||||
/* http://ss5.sourceforge.net/socks4A.protocol.txt */
|
||||
|
||||
@ -1854,7 +1882,8 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
socks4_prot = socks4;
|
||||
}
|
||||
|
||||
next = memchr(data+SOCKS4_NETWORK_LEN, 0,
|
||||
authstart = data + SOCKS4_NETWORK_LEN;
|
||||
next = memchr(authstart, 0,
|
||||
datalen-SOCKS4_NETWORK_LEN);
|
||||
if (!next) {
|
||||
if (datalen >= 1024) {
|
||||
@ -1865,6 +1894,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
*want_length_out = datalen+1024; /* ???? */
|
||||
return 0;
|
||||
}
|
||||
authend = next;
|
||||
tor_assert(next < data+datalen);
|
||||
|
||||
startaddr = NULL;
|
||||
@ -1914,10 +1944,15 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
|
||||
req->port, escaped(req->address));
|
||||
return -1;
|
||||
}
|
||||
if (authend != authstart) {
|
||||
req->got_auth = 1;
|
||||
req->usernamelen = authend - authstart;
|
||||
req->username = tor_memdup(authstart, authend - authstart);
|
||||
}
|
||||
/* next points to the final \0 on inbuf */
|
||||
*drain_out = next - data + 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
case 'G': /* get */
|
||||
case 'H': /* head */
|
||||
case 'P': /* put/post */
|
||||
|
@ -41,6 +41,8 @@ int fetch_from_buf_http(buf_t *buf,
|
||||
char **headers_out, size_t max_headerlen,
|
||||
char **body_out, size_t *body_used, size_t max_bodylen,
|
||||
int force_complete);
|
||||
socks_request_t *socks_request_new(void);
|
||||
void socks_request_free(socks_request_t *req);
|
||||
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
|
||||
int log_sockstype, int safe_socks);
|
||||
int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason);
|
||||
|
@ -246,7 +246,7 @@ edge_connection_new(int type, int socket_family)
|
||||
tor_assert(type == CONN_TYPE_EXIT || type == CONN_TYPE_AP);
|
||||
connection_init(time(NULL), TO_CONN(edge_conn), type, socket_family);
|
||||
if (type == CONN_TYPE_AP)
|
||||
edge_conn->socks_request = tor_malloc_zero(sizeof(socks_request_t));
|
||||
edge_conn->socks_request = socks_request_new();
|
||||
return edge_conn;
|
||||
}
|
||||
|
||||
@ -440,10 +440,8 @@ _connection_free(connection_t *conn)
|
||||
if (CONN_IS_EDGE(conn)) {
|
||||
edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
|
||||
tor_free(edge_conn->chosen_exit_name);
|
||||
if (edge_conn->socks_request) {
|
||||
memset(edge_conn->socks_request, 0xcc, sizeof(socks_request_t));
|
||||
tor_free(edge_conn->socks_request);
|
||||
}
|
||||
if (edge_conn->socks_request)
|
||||
socks_request_free(edge_conn->socks_request);
|
||||
|
||||
rend_data_free(edge_conn->rend_data);
|
||||
}
|
||||
|
12
src/or/or.h
12
src/or/or.h
@ -3109,6 +3109,18 @@ struct socks_request_t {
|
||||
* make sure we send back a socks reply for
|
||||
* every connection. */
|
||||
unsigned int got_auth : 1; /**< Have we received any authentication data? */
|
||||
|
||||
/** Number of bytes in username; 0 if username is NULL */
|
||||
uint8_t usernamelen;
|
||||
/** Number of bytes in password; 0 if password is NULL */
|
||||
uint8_t passwordlen;
|
||||
/** The negotiated username value if any (for socks5), or the entire
|
||||
* authentication string (for socks4). This value is NOT nul-terminated;
|
||||
* see usernamelen for its length. */
|
||||
char *username;
|
||||
/** The negotiated password value if any (for socks5). This value is NOT
|
||||
* nul-terminated; see usernamelen for its length. */
|
||||
char *password;
|
||||
};
|
||||
|
||||
/********************************* circuitbuild.c **********************/
|
||||
|
@ -627,54 +627,54 @@ test_buffers(void)
|
||||
|
||||
/* Test fetch_from_buf_socks() */
|
||||
buf = buf_new_with_capacity(256);
|
||||
socks = tor_malloc_zero(sizeof(socks_request_t));;
|
||||
socks = socks_request_new();
|
||||
config_register_addressmaps(get_options());
|
||||
|
||||
/* Sending auth credentials before we've negotiated a method */
|
||||
test_buffers_socks5_auth_before_negotiation_helper(cp, buf, socks);
|
||||
|
||||
tor_free(socks);
|
||||
socks_request_free(socks);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
buf = buf_new_with_capacity(256);
|
||||
socks = tor_malloc_zero(sizeof(socks_request_t));;
|
||||
socks = socks_request_new();
|
||||
|
||||
/* A SOCKS 5 client that only supports authentication */
|
||||
test_buffers_socks5_authenticate_helper(cp, buf, socks);
|
||||
test_buffers_socks5_supported_commands_helper(cp, buf, socks);
|
||||
test_buffers_socks5_unsupported_commands_helper(cp, buf, socks);
|
||||
|
||||
tor_free(socks);
|
||||
socks_request_free(socks);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
buf = buf_new_with_capacity(256);
|
||||
socks = tor_malloc_zero(sizeof(socks_request_t));;
|
||||
socks = socks_request_new();
|
||||
|
||||
/* A SOCKS 5 client that sends credentials and data in one go */
|
||||
test_buffers_socks5_authenticate_with_data_helper(cp, buf, socks);
|
||||
|
||||
tor_free(socks);
|
||||
socks_request_free(socks);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
buf = buf_new_with_capacity(256);
|
||||
socks = tor_malloc_zero(sizeof(socks_request_t));;
|
||||
socks = socks_request_new();
|
||||
|
||||
/* A SOCKS 5 client that doesn't want authentication */
|
||||
test_buffers_socks5_no_authenticate_helper(cp, buf, socks);
|
||||
test_buffers_socks5_supported_commands_helper(cp, buf, socks);
|
||||
test_buffers_socks5_unsupported_commands_helper(cp, buf, socks);
|
||||
|
||||
tor_free(socks);
|
||||
socks_request_free(socks);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
buf = buf_new_with_capacity(256);
|
||||
socks = tor_malloc_zero(sizeof(socks_request_t));;
|
||||
socks = socks_request_new();
|
||||
|
||||
/* A SOCKS 4(a) client */
|
||||
test_buffers_socks4_supported_commands_helper(cp, buf, socks);
|
||||
test_buffers_socks4_unsupported_commands_helper(cp, buf, socks);
|
||||
|
||||
tor_free(socks);
|
||||
socks_request_free(socks);
|
||||
buf_free(buf);
|
||||
buf = NULL;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user