Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Core
Tor
Commits
9068ac3c
Commit
9068ac3c
authored
May 16, 2018
by
rl1987
Committed by
Nick Mathewson
Jul 12, 2018
Browse files
Implement SOCKS5 user/pass handling
parent
75106a26
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/or/proto_socks.c
View file @
9068ac3c
...
@@ -293,7 +293,7 @@ parse_socks5_methods_request(const uint8_t *raw_data, socks_request_t *req,
...
@@ -293,7 +293,7 @@ parse_socks5_methods_request(const uint8_t *raw_data, socks_request_t *req,
*
have_no_auth
=
1
;
*
have_no_auth
=
1
;
}
}
}
}
end:
end:
socks5_client_version_free
(
trunnel_req
);
socks5_client_version_free
(
trunnel_req
);
...
@@ -338,10 +338,10 @@ process_socks5_methods_request(socks_request_t *req, int have_user_pass,
...
@@ -338,10 +338,10 @@ process_socks5_methods_request(socks_request_t *req, int have_user_pass,
errmsg
);
errmsg
);
res
=
-
1
;
res
=
-
1
;
}
else
{
}
else
{
ssize_t
encoded
=
ssize_t
encoded
=
socks5_server_method_encode
(
req
->
reply
,
sizeof
(
req
->
reply
),
socks5_server_method_encode
(
req
->
reply
,
sizeof
(
req
->
reply
),
trunnel_resp
);
trunnel_resp
);
if
(
encoded
<
0
)
{
if
(
encoded
<
0
)
{
log_warn
(
LD_APP
,
"socks5: method selection encoding failed"
);
log_warn
(
LD_APP
,
"socks5: method selection encoding failed"
);
res
=
-
1
;
res
=
-
1
;
...
@@ -354,6 +354,105 @@ process_socks5_methods_request(socks_request_t *req, int have_user_pass,
...
@@ -354,6 +354,105 @@ process_socks5_methods_request(socks_request_t *req, int have_user_pass,
return
res
;
return
res
;
}
}
static
int
parse_socks5_userpass_auth
(
const
uint8_t
*
raw_data
,
socks_request_t
*
req
,
size_t
datalen
,
size_t
*
drain_out
)
{
int
res
=
1
;
socks5_client_userpass_auth_t
*
trunnel_req
=
NULL
;
ssize_t
parsed
=
socks5_client_userpass_auth_parse
(
&
trunnel_req
,
raw_data
,
datalen
);
tor_assert
(
drain_out
);
*
drain_out
=
0
;
if
(
parsed
==
-
1
)
{
log_warn
(
LD_APP
,
"socks5: parsing failed - invalid user/pass "
"authentication message."
);
res
=
-
1
;
goto
end
;
}
else
if
(
parsed
==
-
2
)
{
res
=
0
;
goto
end
;
}
tor_assert
(
parsed
>=
0
);
*
drain_out
=
(
size_t
)
parsed
;
uint8_t
usernamelen
=
socks5_client_userpass_auth_get_username_len
(
trunnel_req
);
uint8_t
passwordlen
=
socks5_client_userpass_auth_get_passwd_len
(
trunnel_req
);
const
char
*
username
=
socks5_client_userpass_auth_getconstarray_username
(
trunnel_req
);
const
char
*
password
=
socks5_client_userpass_auth_getconstarray_passwd
(
trunnel_req
);
if
(
usernamelen
&&
username
)
{
req
->
username
=
tor_memdup_nulterm
(
username
,
usernamelen
);
req
->
usernamelen
=
usernamelen
;
req
->
got_auth
=
1
;
}
if
(
passwordlen
&&
password
)
{
req
->
password
=
tor_memdup_nulterm
(
password
,
passwordlen
);
req
->
passwordlen
=
passwordlen
;
req
->
got_auth
=
1
;
}
end:
socks5_client_userpass_auth_free
(
trunnel_req
);
return
res
;
}
static
int
process_socks5_userpass_auth
(
socks_request_t
*
req
)
{
int
res
=
1
;
socks5_server_userpass_auth_t
*
trunnel_resp
=
socks5_server_userpass_auth_new
();
if
(
req
->
socks_version
!=
5
)
{
res
=
-
1
;
goto
end
;
}
if
(
req
->
auth_type
!=
SOCKS_USER_PASS
&&
req
->
auth_type
!=
SOCKS_NO_AUTH
)
{
res
=
-
1
;
goto
end
;
}
socks5_server_userpass_auth_set_version
(
trunnel_resp
,
1
);
socks5_server_userpass_auth_set_status
(
trunnel_resp
,
0
);
// auth OK
const
char
*
errmsg
=
socks5_server_userpass_auth_check
(
trunnel_resp
);
if
(
errmsg
)
{
log_warn
(
LD_APP
,
"socks5: server userpass auth validation failed: %s"
,
errmsg
);
res
=
-
1
;
goto
end
;
}
ssize_t
encoded
=
socks5_server_userpass_auth_encode
(
req
->
reply
,
sizeof
(
req
->
reply
),
trunnel_resp
);
if
(
encoded
<
0
)
{
log_warn
(
LD_APP
,
"socks5: server userpass auth encoding failed"
);
res
=
-
1
;
goto
end
;
}
req
->
replylen
=
(
size_t
)
encoded
;
end:
socks5_server_userpass_auth_free
(
trunnel_resp
);
return
res
;
}
static
int
static
int
handle_socks_message
(
const
uint8_t
*
raw_data
,
size_t
datalen
,
socks_request_t
*
req
,
handle_socks_message
(
const
uint8_t
*
raw_data
,
size_t
datalen
,
socks_request_t
*
req
,
int
log_sockstype
,
int
safe_socks
,
size_t
*
drain_out
)
int
log_sockstype
,
int
safe_socks
,
size_t
*
drain_out
)
...
@@ -362,6 +461,9 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
...
@@ -362,6 +461,9 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
uint8_t
socks_version
=
raw_data
[
0
];
uint8_t
socks_version
=
raw_data
[
0
];
if
(
socks_version
==
1
)
socks_version
=
5
;
// SOCKS5 username/pass subnegotiation
if
(
socks_version
==
4
)
{
if
(
socks_version
==
4
)
{
if
(
datalen
<
SOCKS4_NETWORK_LEN
)
{
if
(
datalen
<
SOCKS4_NETWORK_LEN
)
{
res
=
0
;
res
=
0
;
...
@@ -394,12 +496,26 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
...
@@ -394,12 +496,26 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
res
=
0
;
res
=
0
;
goto
end
;
goto
end
;
}
}
/* RFC1929 SOCKS5 username/password subnegotiation. */
if
((
!
req
->
got_auth
&&
raw_data
[
0
]
==
1
)
||
req
->
auth_type
==
SOCKS_USER_PASS
)
{
int
parse_status
=
parse_socks5_userpass_auth
(
raw_data
,
req
,
datalen
,
drain_out
);
if
(
!
req
->
got_auth
)
{
if
(
parse_status
!=
1
)
{
res
=
parse_status
;
goto
end
;
}
}
int
process_status
=
process_socks5_userpass_auth
(
req
);
if
(
process_status
!=
1
)
{
res
=
process_status
;
goto
end
;
}
if
(
req
->
socks_version
!=
5
)
{
res
=
0
;
goto
end
;
}
else
if
(
req
->
socks_version
!=
5
)
{
int
have_user_pass
,
have_no_auth
;
int
have_user_pass
,
have_no_auth
;
int
parse_status
=
parse_socks5_methods_request
(
raw_data
,
int
parse_status
=
parse_socks5_methods_request
(
raw_data
,
req
,
req
,
...
@@ -425,6 +541,9 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
...
@@ -425,6 +541,9 @@ handle_socks_message(const uint8_t *raw_data, size_t datalen, socks_request_t *r
res
=
0
;
res
=
0
;
goto
end
;
goto
end
;
}
}
}
else
{
*
drain_out
=
datalen
;
res
=
-
1
;
}
}
end:
end:
...
@@ -562,8 +681,8 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
...
@@ -562,8 +681,8 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
socksver
=
get_uint8
(
data
);
socksver
=
get_uint8
(
data
);
if
(
(
socksver
==
5
&&
req
->
socks
_
ver
sion
!=
5
)
||
if
(
socksver
==
5
||
socksver
==
4
||
socksver
==
4
)
{
socksver
==
1
)
{
// XXX: RFC 1929
*
want_length_out
=
128
;
// TODO remove this arg later
*
want_length_out
=
128
;
// TODO remove this arg later
return
handle_socks_message
((
const
uint8_t
*
)
data
,
datalen
,
req
,
return
handle_socks_message
((
const
uint8_t
*
)
data
,
datalen
,
req
,
log_sockstype
,
safe_socks
,
drain_out
);
log_sockstype
,
safe_socks
,
drain_out
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment