aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2010-02-17 15:49:22 +0000
committerErlang/OTP <[email protected]>2010-02-17 16:55:20 +0100
commitf29538e8002cf0e37fa4f988fbf5484c46513bf4 (patch)
tree494a29d8a00cd872194ea3f2128a3364aa732866
parent8b39d0582bee5d4071b7ae4c7407d6662c0414a9 (diff)
downloadotp-f29538e8002cf0e37fa4f988fbf5484c46513bf4.tar.gz
otp-f29538e8002cf0e37fa4f988fbf5484c46513bf4.tar.bz2
otp-f29538e8002cf0e37fa4f988fbf5484c46513bf4.zip
OTP-8459 Do a controlled shutdown if a non ssl packet arrives as the first
packet.
-rw-r--r--lib/ssl/src/ssl_connection.erl14
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl43
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl69
-rw-r--r--lib/ssl/test/ssl_test_lib.erl56
4 files changed, 147 insertions, 35 deletions
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index bbffa1e564..eaa022ed29 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -1429,12 +1429,10 @@ encode_handshake(HandshakeRec, SigAlg, Version, ConnectionStates0, Hashes0) ->
encode_packet(Data, #socket_options{packet=Packet}) ->
case Packet of
- 0 -> Data;
1 -> encode_size_packet(Data, 8, (1 bsl 8) - 1);
2 -> encode_size_packet(Data, 16, (1 bsl 16) - 1);
4 -> encode_size_packet(Data, 32, (1 bsl 32) - 1);
- _ ->
- throw({error, {badarg, {eoptions, {packet, Packet}}}})
+ _ -> Data
end.
encode_size_packet(Bin, Size, Max) ->
@@ -1732,9 +1730,13 @@ handle_own_alert(Alert, Version, StateName,
role = Role,
connection_states = ConnectionStates,
log_alert = Log}) ->
- {BinMsg, _} =
- encode_alert(Alert, Version, ConnectionStates),
- Transport:send(Socket, BinMsg),
+ try
+ {BinMsg, _} =
+ encode_alert(Alert, Version, ConnectionStates),
+ Transport:send(Socket, BinMsg)
+ catch _:_ -> %% Can crash if we are in a uninitialized state
+ ignore
+ end,
log_alert(Log, StateName, Alert),
alert_user(User, Alert, Role).
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 22a0fb1ee1..3d9cec43dd 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -150,8 +150,8 @@ all(doc) ->
all(suite) ->
[app, connection_info, controlling_process, controller_dies,
peercert, connect_dist,
- peername, sockname, socket_options, versions, cipher_suites, upgrade,
- upgrade_with_timeout,
+ peername, sockname, socket_options, versions, cipher_suites,
+ upgrade, upgrade_with_timeout, tcp_connect,
ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown,
shutdown_write, shutdown_both, shutdown_error, ciphers,
send_close,
@@ -754,6 +754,45 @@ upgrade_with_timeout(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+tcp_connect(doc) ->
+ ["Test what happens when a tcp tries to connect, i,e. a bad (ssl) packet is sent first"];
+
+tcp_connect(suite) ->
+ [];
+
+tcp_connect(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, should_close, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ {ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
+ test_server:format("Testcase ~p connected to Server ~p ~n", [self(), Server]),
+ gen_tcp:send(Socket, "<SOME GARBLED NON SSL MESSAGE>"),
+
+ ssl_test_lib:check_result(Server, {error,esslerrssl}, tcp_closed, Socket),
+
+ ssl_test_lib:close(Server).
+
+
+should_close(Socket) ->
+ receive
+ {ssl, Socket, closed} ->
+ server_closed;
+ Other ->
+ exit({?LINE, Other})
+ end.
+
%%--------------------------------------------------------------------
ipv6(doc) ->
["Test ipv6."];
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
index 3f8a560be9..f031552457 100644
--- a/lib/ssl/test/ssl_packet_SUITE.erl
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -143,7 +143,8 @@ all(suite) ->
packet_send_to_large,
packet_wait_passive, packet_wait_active,
packet_baddata_passive, packet_baddata_active,
- packet_size_passive, packet_size_active
+ packet_size_passive, packet_size_active,
+ packet_erl_decode
].
%% Test cases starts here.
@@ -1400,6 +1401,72 @@ packet_size_passive(Config) when is_list(Config) ->
ssl_test_lib:close(Server),
ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_erl_decode(doc) ->
+ ["Test that packets of sent to erlang:decode_packet works, i.e. currently"
+ "asn1 | cdr | sunrm | fcgi | tpkt | line | http | http_bin"
+ ];
+packet_erl_decode(suite) ->
+ [];
+
+packet_erl_decode(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ %% A valid cdr packet
+ Data = <<71,73,79,80,1,2,2,1,0,0,0,41,0,0,0,0,0,0,0,0,0,0,0,1,78,
+ 69,79,0,0,0,0,2,0,10,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,4,49>>,
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, server_packet_decode ,[Data]}},
+ {options, [{active, true}, binary, {packet, cdr}|ServerOpts]}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, client_packet_decode, [Data]}},
+ {options, [{active, true}, binary | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_packet_decode(Socket, CDR) ->
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ ok = ssl:send(Socket, CDR),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok = ssl:send(Socket, CDR),
+ ok.
+
+client_packet_decode(Socket, CDR) ->
+ <<P1:10/binary, P2/binary>> = CDR,
+ ok = ssl:send(Socket, P1),
+ ok = ssl:send(Socket, P2),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other1 -> exit({?LINE, Other1})
+ end,
+ ssl:setopts(Socket, [{packet, cdr}]),
+ ok = ssl:send(Socket, CDR),
+ receive
+ {ssl, Socket, CDR} -> ok;
+ Other2 -> exit({?LINE, Other2})
+ end,
+ ok.
+
+
%%--------------------------------------------------------------------
%% Internal functions
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index 7ed19b3a05..2df2e70679 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -278,10 +278,10 @@ run_upgrade_server(Opts) ->
TcpOptions = proplists:get_value(tcp_options, Opts),
SslOptions = proplists:get_value(ssl_options, Opts),
Pid = proplists:get_value(from, Opts),
-
+
test_server:format("gen_tcp:listen(~p, ~p)~n", [Port, TcpOptions]),
{ok, ListenSocket} = rpc:call(Node, gen_tcp, listen, [Port, TcpOptions]),
-
+
case Port of
0 ->
{ok, {_, NewPort}} = inet:sockname(ListenSocket),
@@ -292,25 +292,29 @@ run_upgrade_server(Opts) ->
test_server:format("gen_tcp:accept(~p)~n", [ListenSocket]),
{ok, AcceptSocket} = rpc:call(Node, gen_tcp, accept, [ListenSocket]),
-
- {ok, SslAcceptSocket} = case TimeOut of
- infinity ->
- test_server:format("ssl:ssl_accept(~p, ~p)~n",
- [AcceptSocket, SslOptions]),
- rpc:call(Node, ssl, ssl_accept,
- [AcceptSocket, SslOptions]);
- _ ->
- test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n",
- [AcceptSocket, SslOptions, TimeOut]),
- rpc:call(Node, ssl, ssl_accept,
- [AcceptSocket, SslOptions, TimeOut])
- end,
- {Module, Function, Args} = proplists:get_value(mfa, Opts),
- Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
- Pid ! {self(), Msg},
- receive
- close ->
- ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+
+ try
+ {ok, SslAcceptSocket} = case TimeOut of
+ infinity ->
+ test_server:format("ssl:ssl_accept(~p, ~p)~n",
+ [AcceptSocket, SslOptions]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions]);
+ _ ->
+ test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n",
+ [AcceptSocket, SslOptions, TimeOut]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions, TimeOut])
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+ end
+ catch error:{badmatch, Error} ->
+ Pid ! {self(), Error}
end.
start_upgrade_client(Args) ->