aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-09-16 12:57:03 +0200
committerLoïc Hoguin <[email protected]>2019-09-22 16:46:34 +0200
commit74ab050f546ed94860da6f809617a6986a962ef5 (patch)
treed2334384190739697e8c1faddfa3b647814f9fe0
parent92fd84f61f95a0ecb8aea75c28207d81a9c6f94d (diff)
downloadgun-74ab050f546ed94860da6f809617a6986a962ef5.tar.gz
gun-74ab050f546ed94860da6f809617a6986a962ef5.tar.bz2
gun-74ab050f546ed94860da6f809617a6986a962ef5.zip
Add test for username_password auth
-rw-r--r--src/gun_socks.erl4
-rw-r--r--test/socks_SUITE.erl24
2 files changed, 22 insertions, 6 deletions
diff --git a/src/gun_socks.erl b/src/gun_socks.erl
index 6c3e6fc..74f1767 100644
--- a/src/gun_socks.erl
+++ b/src/gun_socks.erl
@@ -97,9 +97,9 @@ handle(<<5, 0>>, State=#socks_state{version=5, status=auth_method_select}) ->
send_socks5_connect(State),
{state, State#socks_state{status=connect}};
%% Username/password authentication.
-handle(<<5, 2>>, State=#socks_state{socket=Socket, transport=Transport, opts=Opts,
+handle(<<5, 2>>, State=#socks_state{socket=Socket, transport=Transport, opts=#{auth := AuthMethods},
version=5, status=auth_method_select}) ->
- #{auth := {username_password, Username, Password}} = Opts,
+ [{username_password, Username, Password}] = [Method || Method <- AuthMethods],
ULen = byte_size(Username),
PLen = byte_size(Password),
Transport:send(Socket, <<1, ULen, Username/binary, PLen, Password/binary>>),
diff --git a/test/socks_SUITE.erl b/test/socks_SUITE.erl
index 01bc760..b0c84b0 100644
--- a/test/socks_SUITE.erl
+++ b/test/socks_SUITE.erl
@@ -73,12 +73,16 @@ do_proxy_init(Parent, Transport, Auth) ->
2 -> username_password
end || <<A>> <= Auths0],
Parent ! {self(), {auth_methods, NumAuths, Auths}},
- ok = case {Auth, lists:member(Auth, Auths)} of
+ AuthMethod = do_auth_method(Auth),
+ ok = case {AuthMethod, lists:member(AuthMethod, Auths)} of
{none, true} ->
Transport:send(ClientSocket, <<5, 0>>);
{username_password, true} ->
- %% @todo
- ok;
+ Transport:send(ClientSocket, <<5, 2>>),
+ {ok, <<1, ULen, User:ULen/binary, PLen, Pass:PLen/binary>>} = Recv(ClientSocket, 0, 1000),
+ Parent ! {self(), {username_password, User, Pass}},
+ %% @todo Test errors too (byte 2).
+ Transport:send(ClientSocket, <<1, 0>>);
{_, false} ->
%% @todo
not_ok
@@ -135,12 +139,19 @@ do_proxy_loop(Transport, ClientSocket, OriginSocket) ->
error(Msg)
end.
+do_auth_method(none) -> none;
+do_auth_method({username_password, _, _}) -> username_password.
+
%% Tests.
socks5_tcp_http_none(_) ->
doc("Use Socks5 over TCP and without authentication to connect to an HTTP server."),
do_socks5_tcp_http(<<"http">>, tcp, tcp, none).
+socks5_tcp_http_username_password(_) ->
+ doc("Use Socks5 over TCP and without authentication to connect to an HTTP server."),
+ do_socks5_tcp_http(<<"http">>, tcp, tcp, {username_password, <<"user">>, <<"password">>}).
+
do_socks5_tcp_http(OriginScheme, OriginTransport, ProxyTransport, SocksAuth) ->
{ok, OriginPid, OriginPort} = init_origin(OriginTransport, http),
{ok, ProxyPid, ProxyPort} = do_proxy_start(ProxyTransport, SocksAuth),
@@ -157,7 +168,12 @@ do_socks5_tcp_http(OriginScheme, OriginTransport, ProxyTransport, SocksAuth) ->
{ok, socks} = gun:await_up(ConnPid),
{ok, http} = gun:await_up(ConnPid),
%% The proxy received two packets.
- {auth_methods, 1, [SocksAuth]} = receive_from(ProxyPid),
+ AuthMethod = do_auth_method(SocksAuth),
+ {auth_methods, 1, [AuthMethod]} = receive_from(ProxyPid),
+ _ = case AuthMethod of
+ none -> ok;
+ username_password -> SocksAuth = receive_from(ProxyPid)
+ end,
{connect, <<"localhost">>, OriginPort} = receive_from(ProxyPid),
_ = gun:get(ConnPid, "/proxied"),
Data = receive_from(OriginPid),