aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/hipe/doc/src/hipe_app.xml2
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/ssh/src/ssh.appup.src3
-rw-r--r--lib/ssh/src/ssh_sftp.erl2
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl68
-rw-r--r--lib/ssh/test/ssh_connection_SUITE.erl22
-rw-r--r--lib/ssh/test/ssh_echo_server.erl4
-rw-r--r--lib/ssh/test/ssh_sftp_SUITE.erl98
-rw-r--r--lib/ssh/test/ssh_sftpd_SUITE.erl65
-rw-r--r--lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl29
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl60
-rw-r--r--lib/ssh/vsn.mk2
-rw-r--r--lib/ssl/src/ssl.erl9
-rw-r--r--lib/ssl/src/ssl_connection.erl17
-rw-r--r--lib/ssl/src/ssl_handshake.erl21
-rw-r--r--lib/ssl/src/ssl_record.erl12
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl63
-rw-r--r--lib/ssl/test/ssl_npn_handshake_SUITE.erl54
-rw-r--r--lib/stdlib/vsn.mk2
19 files changed, 337 insertions, 198 deletions
diff --git a/lib/hipe/doc/src/hipe_app.xml b/lib/hipe/doc/src/hipe_app.xml
index 56729d4cc4..9a1aa943d4 100644
--- a/lib/hipe/doc/src/hipe_app.xml
+++ b/lib/hipe/doc/src/hipe_app.xml
@@ -21,7 +21,7 @@
</legalnotice>
- <title>snmp</title>
+ <title>HiPE</title>
<prepared></prepared>
<responsible></responsible>
<docno></docno>
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index b6cf4407d2..49404196dd 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.16.1
+KERNEL_VSN = 2.16.2
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index c4b5aa256b..f4986410ab 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,6 +19,7 @@
{"%VSN%",
[
+ {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
{<<"2.1.3">>, [{restart_application, ssh}]},
{<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
@@ -27,7 +28,7 @@
{<<"1\\.*">>, [{restart_application, ssh}]}
],
[
- {<<"2.1.3">>, [{restart_application, ssh}]},
+ {<<"2.1.4">>, [{load_module, ssh_sftp, soft_purge, soft_purge, []}]},
{<<"2.1.2">>, [{restart_application, ssh}]},
{<<"2.1.1">>, [{restart_application, ssh}]},
{<<"2.1">>,[{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh_sftp.erl b/lib/ssh/src/ssh_sftp.erl
index f3afbe01bf..10167a9223 100644
--- a/lib/ssh/src/ssh_sftp.erl
+++ b/lib/ssh/src/ssh_sftp.erl
@@ -403,7 +403,7 @@ init([Cm, ChannelId, Timeout]) ->
rep_buf = <<>>,
inf = new_inf()}};
failure ->
- {stop, {error, "server failed to start sftp subsystem"}};
+ {stop, "server failed to start sftp subsystem"};
Error ->
{stop, Error}
end.
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index efcb11f88f..dceec52464 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2013. 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
@@ -137,16 +137,16 @@ end_per_testcase(_Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-app_test(doc) ->
- ["Application consistency test."];
+app_test() ->
+ [{doc, "App lication consistency test."}].
app_test(Config) when is_list(Config) ->
?t:app_test(ssh),
ok.
%%--------------------------------------------------------------------
-misc_ssh_options(doc) ->
- ["Test that we can set some misc options not tested elsewhere, "
- "some options not yet present are not decided if we should support or "
- "if they need thier own test case."];
+misc_ssh_options() ->
+ [{doc, "Test that we can set some misc options not tested elsewhere, "
+ "some options not yet present are not decided if we should support or "
+ "if they need thier own test case."}].
misc_ssh_options(Config) when is_list(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -163,8 +163,8 @@ misc_ssh_options(Config) when is_list(Config) ->
basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]).
%%--------------------------------------------------------------------
-exec(doc) ->
- ["Test api function ssh_connection:exec"];
+exec() ->
+ [{doc, "Test api function ssh_connection:exec"}].
exec(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -205,8 +205,8 @@ exec(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-exec_compressed(doc) ->
- ["Test that compression option works"];
+exec_compressed() ->
+ [{doc, "Test that compression option works"}].
exec_compressed(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -234,8 +234,8 @@ exec_compressed(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-idle_time(doc) ->
- ["Idle timeout test"];
+idle_time() ->
+ [{doc, "Idle timeout test"}].
idle_time(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -256,8 +256,8 @@ idle_time(Config) ->
end,
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-rekey(doc) ->
- ["Idle timeout test"];
+rekey() ->
+ [{doc, "Idle timeout test"}].
rekey(Config) ->
SystemDir = filename:join(?config(priv_dir, Config), system),
UserDir = ?config(priv_dir, Config),
@@ -278,8 +278,8 @@ rekey(Config) ->
ssh:stop_daemon(Pid)
end.
%%--------------------------------------------------------------------
-shell(doc) ->
- ["Test that ssh:shell/2 works"];
+shell() ->
+ [{doc, "Test that ssh:shell/2 works"}].
shell(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -300,9 +300,9 @@ shell(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-daemon_already_started(doc) ->
- ["Test that get correct error message if you try to start a daemon",
- "on an adress that already runs a daemon see also seq10667" ];
+daemon_already_started() ->
+ [{doc, "Test that get correct error message if you try to start a daemon",
+ "on an adress that already runs a daemon see also seq10667"}].
daemon_already_started(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
UserDir = ?config(priv_dir, Config),
@@ -317,8 +317,8 @@ daemon_already_started(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-server_password_option(doc) ->
- ["validate to server that uses the 'password' option"];
+server_password_option() ->
+ [{doc, "validate to server that uses the 'password' option"}].
server_password_option(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
@@ -351,8 +351,8 @@ server_password_option(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-server_userpassword_option(doc) ->
- ["validate to server that uses the 'password' option"];
+server_userpassword_option() ->
+ [{doc, "validate to server that uses the 'password' option"}].
server_userpassword_option(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
UserDir = filename:join(PrivDir, nopubkey), % to make sure we don't use public-key-auth
@@ -387,8 +387,8 @@ server_userpassword_option(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-known_hosts(doc) ->
- ["check that known_hosts is updated correctly"];
+known_hosts() ->
+ [{doc, "check that known_hosts is updated correctly"}].
known_hosts(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -414,8 +414,8 @@ known_hosts(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-pass_phrase(doc) ->
- ["Test that we can use keyes protected by pass phrases"];
+pass_phrase() ->
+ [{doc, "Test that we can use keyes protected by pass phrases"}].
pass_phrase(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -435,8 +435,8 @@ pass_phrase(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-internal_error(doc) ->
- ["Test that client does not hang if disconnects due to internal error"];
+internal_error() ->
+ [{doc,"Test that client does not hang if disconnects due to internal error"}].
internal_error(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -452,8 +452,8 @@ internal_error(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-send(doc) ->
- ["Test ssh_connection:send/3"];
+send() ->
+ [{doc, "Test ssh_connection:send/3"}].
send(Config) when is_list(Config) ->
process_flag(trap_exit, true),
SystemDir = filename:join(?config(priv_dir, Config), system),
@@ -473,8 +473,8 @@ send(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-close(doc) ->
- ["Simulate that we try to close an already closed connection"];
+close() ->
+ [{doc, "Simulate that we try to close an already closed connection"}].
close(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl
index acaf3d6eeb..6c781e0e91 100644
--- a/lib/ssh/test/ssh_connection_SUITE.erl
+++ b/lib/ssh/test/ssh_connection_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2013. 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
@@ -82,8 +82,8 @@ end_per_testcase(_Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-simple_exec(doc) ->
- ["Simple openssh connectivity test for ssh_connection:exec"];
+simple_exec() ->
+ [{doc, "Simple openssh connectivity test for ssh_connection:exec"}].
simple_exec(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -113,8 +113,8 @@ simple_exec(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-small_cat(doc) ->
- ["Use 'cat' to echo small data block back to us."];
+small_cat() ->
+ [{doc, "Use 'cat' to echo small data block back to us."}].
small_cat(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -148,8 +148,8 @@ small_cat(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-big_cat(doc) ->
- ["Use 'cat' to echo large data block back to us."];
+big_cat() ->
+ [{doc,"Use 'cat' to echo large data block back to us."}].
big_cat(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -197,8 +197,8 @@ big_cat(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-send_after_exit(doc) ->
- ["Send channel data after the channel has been closed."];
+send_after_exit() ->
+ [{doc, "Send channel data after the channel has been closed."}].
send_after_exit(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -236,8 +236,8 @@ send_after_exit(Config) when is_list(Config) ->
ok
end.
%%--------------------------------------------------------------------
-interrupted_send(doc) ->
- ["Use a subsystem that echos n char and then sends eof to cause a channel exit partway through a large send."];
+interrupted_send() ->
+ [{doc, "Use a subsystem that echos n char and then sends eof to cause a channel exit partway through a large send."}].
interrupted_send(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
diff --git a/lib/ssh/test/ssh_echo_server.erl b/lib/ssh/test/ssh_echo_server.erl
index 007b00c373..315ffecfd7 100644
--- a/lib/ssh/test/ssh_echo_server.erl
+++ b/lib/ssh/test/ssh_echo_server.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2013. 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
@@ -21,7 +21,7 @@
%%% Description: Example ssh server
-module(ssh_echo_server).
--behaviour(ssh_subsytem).
+-behaviour(ssh_daemon_channel).
-record(state, {
n,
id,
diff --git a/lib/ssh/test/ssh_sftp_SUITE.erl b/lib/ssh/test/ssh_sftp_SUITE.erl
index 232161d029..56b1363b7a 100644
--- a/lib/ssh/test/ssh_sftp_SUITE.erl
+++ b/lib/ssh/test/ssh_sftp_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2013. 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
@@ -41,7 +41,9 @@ suite() ->
all() ->
[{group, erlang_server},
- {group, openssh_server}].
+ {group, openssh_server},
+ sftp_nonexistent_subsystem
+ ].
init_per_suite(Config) ->
@@ -76,9 +78,7 @@ init_per_group(erlang_server, Config) ->
ssh_test_lib:daemon([{system_dir, SysDir},
{user_dir, PrivDir},
{user_passwords,
- [{?USER, ?PASSWD}]},
- {failfun,
- fun ssh_test_lib:failfun/2}]),
+ [{?USER, ?PASSWD}]}]),
[{group, erlang_server}, {sftpd, Sftpd} | Config];
init_per_group(openssh_server, Config) ->
@@ -100,6 +100,17 @@ end_per_group(_, Config) ->
%%--------------------------------------------------------------------
+init_per_testcase(sftp_nonexistent_subsystem, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ SysDir = ?config(data_dir, Config),
+ Sftpd = ssh_test_lib:daemon([{system_dir, SysDir},
+ {user_dir, PrivDir},
+ {subsystems, []},
+ {user_passwords,
+ [{?USER, ?PASSWD}]}
+ ]),
+ [{sftpd, Sftpd} | Config];
+
init_per_testcase(Case, Config) ->
prep(Config),
TmpConfig0 = lists:keydelete(watchdog, 1, Config),
@@ -129,6 +140,8 @@ init_per_testcase(Case, Config) ->
[{sftp, Sftp}, {watchdog, Dog} | TmpConfig]
end.
+end_per_testcase(sftp_nonexistent_subsystem, Config) ->
+ Config;
end_per_testcase(rename_file, Config) ->
PrivDir = ?config(priv_dir, Config),
NewFileName = filename:join(PrivDir, "test.txt"),
@@ -145,8 +158,8 @@ end_per_testcase(Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-open_close_file(doc) ->
- ["Test API functions open/3 and close/2"];
+open_close_file() ->
+ [{doc, "Test API functions open/3 and close/2"}].
open_close_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -165,8 +178,8 @@ open_close_file(Server, File, Mode) ->
ok = ssh_sftp:close(Server, Handle).
%%--------------------------------------------------------------------
-open_close_dir(doc) ->
- ["Test API functions opendir/2 and close/2"];
+open_close_dir() ->
+ [{doc, "Test API functions opendir/2 and close/2"}].
open_close_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
@@ -177,8 +190,8 @@ open_close_dir(Config) when is_list(Config) ->
{error, _} = ssh_sftp:opendir(Sftp, FileName).
%%--------------------------------------------------------------------
-read_file(doc) ->
- ["Test API funtion read_file/2"];
+read_file() ->
+ [{doc, "Test API funtion read_file/2"}].
read_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -187,8 +200,8 @@ read_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
-read_dir(doc) ->
- ["Test API function list_dir/2"];
+read_dir() ->
+ [{doc,"Test API function list_dir/2"}].
read_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
@@ -196,8 +209,8 @@ read_dir(Config) when is_list(Config) ->
ct:pal("sftp list dir: ~p~n", [Files]).
%%--------------------------------------------------------------------
-write_file(doc) ->
- ["Test API function write_file/2"];
+write_file() ->
+ [{doc, "Test API function write_file/2"}].
write_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -208,8 +221,8 @@ write_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
-remove_file(doc) ->
- ["Test API function delete/2"];
+remove_file() ->
+ [{doc,"Test API function delete/2"}].
remove_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -222,8 +235,8 @@ remove_file(Config) when is_list(Config) ->
false = lists:member(filename:basename(FileName), NewFiles),
{error, _} = ssh_sftp:delete(Sftp, FileName).
%%--------------------------------------------------------------------
-rename_file(doc) ->
- ["Test API function rename_file/2"];
+rename_file() ->
+ [{doc, "Test API function rename_file/2"}].
rename_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -242,8 +255,8 @@ rename_file(Config) when is_list(Config) ->
true = lists:member(filename:basename(NewFileName), NewFiles).
%%--------------------------------------------------------------------
-mk_rm_dir(doc) ->
- ["Test API functions make_dir/2, del_dir/2"];
+mk_rm_dir() ->
+ [{doc,"Test API functions make_dir/2, del_dir/2"}].
mk_rm_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Sftp, _} = ?config(sftp, Config),
@@ -256,8 +269,8 @@ mk_rm_dir(Config) when is_list(Config) ->
{error, _} = ssh_sftp:del_dir(Sftp, PrivDir).
%%--------------------------------------------------------------------
-links(doc) ->
- ["Tests API function make_symlink/3"];
+links() ->
+ [{doc,"Tests API function make_symlink/3"}].
links(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
@@ -273,8 +286,8 @@ links(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-retrieve_attributes(doc) ->
- ["Test API function read_file_info/3"];
+retrieve_attributes() ->
+ [{doc, "Test API function read_file_info/3"}].
retrieve_attributes(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "sftp.txt"),
@@ -287,8 +300,8 @@ retrieve_attributes(Config) when is_list(Config) ->
ct:pal("SFTP: ~p FILE: ~p~n", [FileInfo, NewFileInfo]).
%%--------------------------------------------------------------------
-set_attributes(doc) ->
- ["Test API function write_file_info/3"];
+set_attributes() ->
+ [{doc,"Test API function write_file_info/3"}].
set_attributes(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -303,8 +316,8 @@ set_attributes(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-async_read(doc) ->
- ["Test API aread/3"];
+async_read() ->
+ [{doc,"Test API aread/3"}].
async_read(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
PrivDir = ?config(priv_dir, Config),
@@ -321,8 +334,8 @@ async_read(Config) when is_list(Config) ->
ct:fail(Msg)
end.
%%--------------------------------------------------------------------
-async_write(doc) ->
- ["Test API awrite/3"];
+async_write() ->
+ [{doc,"Test API awrite/3"}].
async_write(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
PrivDir = ?config(priv_dir, Config),
@@ -340,8 +353,8 @@ async_write(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-position(doc) ->
- ["Test API functions position/3"];
+position() ->
+ [{doc, "Test API functions position/3"}].
position(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -370,8 +383,8 @@ position(Config) when is_list(Config) ->
{ok, "2"} = ssh_sftp:read(Sftp, Handle, 1).
%%--------------------------------------------------------------------
-pos_read(doc) ->
- ["Test API functions pread/3 and apread/3"];
+pos_read() ->
+ [{doc,"Test API functions pread/3 and apread/3"}].
pos_read(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -396,8 +409,8 @@ pos_read(Config) when is_list(Config) ->
{ok, NewData1} = ssh_sftp:pread(Sftp, Handle, {bof, 4}, 4).
%%--------------------------------------------------------------------
-pos_write(doc) ->
- ["Test API functions pwrite/4 and apwrite/4"];
+pos_write() ->
+ [{doc,"Test API functions pwrite/4 and apwrite/4"}].
pos_write(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -423,6 +436,17 @@ pos_write(Config) when is_list(Config) ->
{ok, NewData1} = ssh_sftp:read_file(Sftp, FileName).
%%--------------------------------------------------------------------
+sftp_nonexistent_subsystem() ->
+ [{doc, "Try to execute sftp subsystem on a server that does not support it"}].
+sftp_nonexistent_subsystem(Config) when is_list(Config) ->
+ {_,Host, Port} = ?config(sftpd, Config),
+ {error,"server failed to start sftp subsystem"} =
+ ssh_sftp:start_channel(Host, Port,
+ [{user_interaction, false},
+ {user, ?USER}, {password, ?PASSWD},
+ {silently_accept_hosts, true}]).
+
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
prep(Config) ->
diff --git a/lib/ssh/test/ssh_sftpd_SUITE.erl b/lib/ssh/test/ssh_sftpd_SUITE.erl
index 5aa46872ee..7b22e45d5e 100644
--- a/lib/ssh/test/ssh_sftpd_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2013. 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
@@ -163,8 +163,8 @@ end_per_testcase(_TestCase, Config) ->
%%--------------------------------------------------------------------
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-open_close_file(doc) ->
- ["Test SSH_FXP_OPEN and SSH_FXP_CLOSE commands"];
+open_close_file() ->
+ [{doc, "Test SSH_FXP_OPEN and SSH_FXP_CLOSE commands"}].
open_close_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -194,8 +194,8 @@ open_close_file(Config) when is_list(Config) ->
?SSH_FXF_OPEN_EXISTING).
%%--------------------------------------------------------------------
-open_close_dir(doc) ->
- ["Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"];
+open_close_dir() ->
+ [{doc,"Test SSH_FXP_OPENDIR and SSH_FXP_CLOSE commands"}].
open_close_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Cm, Channel} = ?config(sftp, Config),
@@ -221,8 +221,8 @@ open_close_dir(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-read_file(doc) ->
- ["Test SSH_FXP_READ command"];
+read_file() ->
+ [{doc, "Test SSH_FXP_READ command"}].
read_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -244,8 +244,8 @@ read_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
-read_dir(doc) ->
- ["Test SSH_FXP_READDIR command"];
+read_dir() ->
+ [{doc,"Test SSH_FXP_READDIR command"}].
read_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Cm, Channel} = ?config(sftp, Config),
@@ -255,8 +255,8 @@ read_dir(Config) when is_list(Config) ->
ok = read_dir(Handle, Cm, Channel, ReqId).
%%--------------------------------------------------------------------
-write_file(doc) ->
- ["Test SSH_FXP_WRITE command"];
+write_file() ->
+ [{doc, "Test SSH_FXP_WRITE command"}].
write_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -279,8 +279,8 @@ write_file(Config) when is_list(Config) ->
{ok, Data} = file:read_file(FileName).
%%--------------------------------------------------------------------
-remove_file(doc) ->
- ["Test SSH_FXP_REMOVE command"];
+remove_file() ->
+ [{doc, "Test SSH_FXP_REMOVE command"}].
remove_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -300,8 +300,8 @@ remove_file(Config) when is_list(Config) ->
remove(PrivDir, Cm, Channel, NewReqId).
%%--------------------------------------------------------------------
-rename_file(doc) ->
- ["Test SSH_FXP_RENAME command"];
+rename_file() ->
+ [{doc, "Test SSH_FXP_RENAME command"}].
rename_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -337,8 +337,8 @@ rename_file(Config) when is_list(Config) ->
?SSH_FXP_RENAME_ATOMIC).
%%--------------------------------------------------------------------
-mk_rm_dir(doc) ->
- ["Test SSH_FXP_MKDIR and SSH_FXP_RMDIR command"];
+mk_rm_dir() ->
+ [{doc, "Test SSH_FXP_MKDIR and SSH_FXP_RMDIR command"}].
mk_rm_dir(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
{Cm, Channel} = ?config(sftp, Config),
@@ -360,8 +360,8 @@ mk_rm_dir(Config) when is_list(Config) ->
_/binary>>, _} = rmdir(DirName, Cm, Channel, NewReqId2).
%%--------------------------------------------------------------------
-real_path(doc) ->
- ["Test SSH_FXP_REALPATH command"];
+real_path() ->
+ [{doc, "Test SSH_FXP_REALPATH command"}].
real_path(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
@@ -388,8 +388,6 @@ real_path(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-links(doc) ->
- [];
links(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
@@ -417,8 +415,8 @@ links(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-retrieve_attributes(doc) ->
- ["Test SSH_FXP_STAT, SSH_FXP_LSTAT AND SSH_FXP_FSTAT commands"];
+retrieve_attributes() ->
+ [{"Test SSH_FXP_STAT, SSH_FXP_LSTAT AND SSH_FXP_FSTAT commands"}].
retrieve_attributes(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -482,8 +480,8 @@ retrieve_attributes(Config) when is_list(Config) ->
end, AttrValues).
%%--------------------------------------------------------------------
-set_attributes(doc) ->
- ["Test SSH_FXP_SETSTAT AND SSH_FXP_FSETSTAT commands"];
+set_attributes() ->
+ [{doc, "Test SSH_FXP_SETSTAT AND SSH_FXP_FSETSTAT commands"}].
set_attributes(Config) when is_list(Config) ->
case os:type() of
{win32, _} ->
@@ -540,8 +538,8 @@ set_attributes(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-ver3_rename(doc) ->
- ["Test that ver3 rename message is handled OTP 6352"];
+ver3_rename() ->
+ [{doc, "Test that ver3 rename message is handled OTP 6352"}].
ver3_rename(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -554,8 +552,8 @@ ver3_rename(Config) when is_list(Config) ->
rename(FileName, NewFileName, Cm, Channel, ReqId, 3, 0).
%%--------------------------------------------------------------------
-relpath(doc) ->
- ["Check that realpath works ok seq10670"];
+relpath() ->
+ [{doc, "Check that realpath works ok seq10670"}].
relpath(Config) when is_list(Config) ->
ReqId = 0,
{Cm, Channel} = ?config(sftp, Config),
@@ -577,8 +575,8 @@ relpath(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-sshd_read_file(doc) ->
- ["Test SSH_FXP_READ command, using sshd-server"];
+sshd_read_file() ->
+ [{doc,"Test SSH_FXP_READ command, using sshd-server"}].
sshd_read_file(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
FileName = filename:join(PrivDir, "test.txt"),
@@ -598,8 +596,9 @@ sshd_read_file(Config) when is_list(Config) ->
read_file(Handle, 100, 0, Cm, Channel, NewReqId),
{ok, Data} = file:read_file(FileName).
-ver6_basic(doc) ->
- ["Test SFTP Version 6"];
+%%--------------------------------------------------------------------
+ver6_basic() ->
+ [{doc, "Test SFTP Version 6"}].
ver6_basic(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
%FileName = filename:join(PrivDir, "test.txt"),
diff --git a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
index 8f722941d4..cc34cc0793 100644
--- a/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
+++ b/lib/ssh/test/ssh_sftpd_erlclient_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2013. 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
@@ -145,9 +145,9 @@ end_per_testcase(_TestCase, Config) ->
%%--------------------------------------------------------------------
%% Test cases starts here. -------------------------------------------
%%--------------------------------------------------------------------
-close_file(doc) ->
- ["Test that sftpd closes its fildescriptors after compleating the "
- "transfer OTP-6350"];
+close_file() ->
+ [{doc, "Test that sftpd closes its fildescriptors after compleating the "
+ "transfer OTP-6350"}].
close_file(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
@@ -165,10 +165,10 @@ close_file(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-quit(doc) ->
- [" When the sftp client ends the session the "
+quit() ->
+ [{doc, " When the sftp client ends the session the "
"server will now behave correctly and not leave the "
- "client hanging. OTP-6349"];
+ "client hanging. OTP-6349"}].
quit(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
@@ -197,9 +197,9 @@ quit(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-file_cb(doc) ->
- ["Test that it is possible to change the callback module for"
- " the sftpds filehandling. OTP-6356"];
+file_cb() ->
+ [{"Test that it is possible to change the callback module for"
+ " the sftpds filehandling. OTP-6356"}].
file_cb(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
@@ -245,8 +245,6 @@ file_cb(Config) when is_list(Config) ->
alt_file_handler_check(alt_del_dir).
%%--------------------------------------------------------------------
-root_dir(doc) ->
- [""];
root_dir(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
FileName = "test.txt",
@@ -258,16 +256,15 @@ root_dir(Config) when is_list(Config) ->
ct:pal("Listing: ~p~n", [Listing]).
%%--------------------------------------------------------------------
-list_dir_limited(doc) ->
- [""];
list_dir_limited(Config) when is_list(Config) ->
{Sftp, _} = ?config(sftp, Config),
{ok, Listing} =
ssh_sftp:list_dir(Sftp, "."),
ct:pal("Listing: ~p~n", [Listing]).
-ver6_basic(doc) ->
- ["Test some version 6 features"];
+%%--------------------------------------------------------------------
+ver6_basic() ->
+ [{doc, "Test some version 6 features"}].
ver6_basic(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
NewDir = filename:join(PrivDir, "testdir2"),
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index 99dc76e12d..8b5343cecc 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2013. 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
@@ -49,7 +49,9 @@ groups() ->
erlang_client_openssh_server_setenv,
erlang_client_openssh_server_publickey_rsa,
erlang_client_openssh_server_publickey_dsa,
- erlang_client_openssh_server_password]},
+ erlang_client_openssh_server_password,
+ erlang_client_openssh_server_nonexistent_subsystem
+ ]},
{erlang_server, [], [erlang_server_openssh_client_exec,
erlang_server_openssh_client_exec_compressed,
erlang_server_openssh_client_pulic_key_dsa]}
@@ -99,8 +101,8 @@ end_per_testcase(_TestCase, _Config) ->
%% Test Cases --------------------------------------------------------
%%--------------------------------------------------------------------
-erlang_shell_client_openssh_server(doc) ->
- ["Test that ssh:shell/2 works"];
+erlang_shell_client_openssh_server() ->
+ [{doc, "Test that ssh:shell/2 works"}].
erlang_shell_client_openssh_server(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -126,8 +128,8 @@ erlang_shell_client_openssh_server(Config) when is_list(Config) ->
end.
%--------------------------------------------------------------------
-erlang_client_openssh_server_exec(doc) ->
- ["Test api function ssh_connection:exec"];
+erlang_client_openssh_server_exec() ->
+ [{doc, "Test api function ssh_connection:exec"}].
erlang_client_openssh_server_exec(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -165,8 +167,8 @@ erlang_client_openssh_server_exec(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-erlang_client_openssh_server_exec_compressed(doc) ->
- ["Test that compression option works"];
+erlang_client_openssh_server_exec_compressed() ->
+ [{doc, "Test that compression option works"}].
erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) ->
ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT, [{silently_accept_hosts, true},
@@ -188,8 +190,8 @@ erlang_client_openssh_server_exec_compressed(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec(doc) ->
- ["Test that exec command works."];
+erlang_server_openssh_client_exec() ->
+ [{doc, "Test that exec command works."}].
erlang_server_openssh_client_exec(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
@@ -219,8 +221,8 @@ erlang_server_openssh_client_exec(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-erlang_server_openssh_client_exec_compressed(doc) ->
- ["Test that exec command works."];
+erlang_server_openssh_client_exec_compressed() ->
+ [{doc, "Test that exec command works."}].
erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
@@ -247,8 +249,8 @@ erlang_server_openssh_client_exec_compressed(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-erlang_client_openssh_server_setenv(doc) ->
- ["Test api function ssh_connection:setenv"];
+erlang_client_openssh_server_setenv() ->
+ [{doc, "Test api function ssh_connection:setenv"}].
erlang_client_openssh_server_setenv(Config) when is_list(Config) ->
ConnectionRef =
@@ -290,8 +292,8 @@ erlang_client_openssh_server_setenv(Config) when is_list(Config) ->
%% setenv not meaningfull on erlang ssh daemon!
%%--------------------------------------------------------------------
-erlang_client_openssh_server_publickey_rsa(doc) ->
- ["Validate using rsa publickey."];
+erlang_client_openssh_server_publickey_rsa() ->
+ [{doc, "Validate using rsa publickey."}].
erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) ->
{ok,[[Home]]} = init:get_argument(home),
KeyFile = filename:join(Home, ".ssh/id_rsa"),
@@ -317,8 +319,8 @@ erlang_client_openssh_server_publickey_rsa(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
-erlang_client_openssh_server_publickey_dsa(doc) ->
- ["Validate using dsa publickey."];
+erlang_client_openssh_server_publickey_dsa() ->
+ [{doc, "Validate using dsa publickey."}].
erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
{ok,[[Home]]} = init:get_argument(home),
KeyFile = filename:join(Home, ".ssh/id_dsa"),
@@ -342,8 +344,8 @@ erlang_client_openssh_server_publickey_dsa(Config) when is_list(Config) ->
{skip, "no ~/.ssh/id_dsa"}
end.
%%--------------------------------------------------------------------
-erlang_server_openssh_client_pulic_key_dsa(doc) ->
- ["Validate using dsa publickey."];
+erlang_server_openssh_client_pulic_key_dsa() ->
+ [{doc, "Validate using dsa publickey."}].
erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
SystemDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
@@ -369,8 +371,8 @@ erlang_server_openssh_client_pulic_key_dsa(Config) when is_list(Config) ->
ssh:stop_daemon(Pid).
%%--------------------------------------------------------------------
-erlang_client_openssh_server_password(doc) ->
- ["Test client password option"];
+erlang_client_openssh_server_password() ->
+ [{doc, "Test client password option"}].
erlang_client_openssh_server_password(Config) when is_list(Config) ->
%% to make sure we don't public-key-auth
UserDir = ?config(data_dir, Config),
@@ -402,6 +404,20 @@ erlang_client_openssh_server_password(Config) when is_list(Config) ->
end.
%%--------------------------------------------------------------------
+
+erlang_client_openssh_server_nonexistent_subsystem() ->
+ [{doc, "Test client password option"}].
+erlang_client_openssh_server_nonexistent_subsystem(Config) when is_list(Config) ->
+
+ ConnectionRef = ssh_test_lib:connect(?SSH_DEFAULT_PORT,
+ [{user_interaction, false},
+ silently_accept_hosts]),
+
+ {ok, ChannelId} = ssh_connection:session_channel(ConnectionRef, infinity),
+
+ failure = ssh_connection:subsystem(ConnectionRef, ChannelId, "foo", infinity).
+
+%%--------------------------------------------------------------------
%
%% Not possible to send password with openssh without user interaction
%%
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 9fc4b0522e..8f6aac1f5d 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,5 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 2.1.4
+SSH_VSN = 2.1.5
APP_VSN = "ssh-$(SSH_VSN)"
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 0ba59cede2..fc06b5f1b0 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -612,8 +612,15 @@ handle_options(Opts0, _Role) ->
CertFile = handle_option(certfile, Opts, <<>>),
+ Versions = case handle_option(versions, Opts, []) of
+ [] ->
+ ssl_record:supported_protocol_versions();
+ Vsns ->
+ [ssl_record:protocol_version(Vsn) || Vsn <- Vsns]
+ end,
+
SSLOptions = #ssl_options{
- versions = handle_option(versions, Opts, []),
+ versions = Versions,
verify = validate_option(verify, Verify),
verify_fun = VerifyFun,
fail_if_no_peer_cert = FailIfNoPeerCert,
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index 8f4fd88d42..4d29ecce7a 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -73,7 +73,6 @@
session_cache, %
session_cache_cb, %
negotiated_version, % tls_version()
- supported_protocol_versions, % [atom()]
client_certificate_requested = false,
key_algorithm, % atom as defined by cipher_suite
hashsign_algorithm, % atom as defined by cipher_suite
@@ -472,6 +471,13 @@ abbreviated(#finished{verify_data = Data} = Finished,
handle_own_alert(Alert, Version, abbreviated, State)
end;
+%% only allowed to send next_protocol message after change cipher spec
+%% & before finished message and it is not allowed during renegotiation
+abbreviated(#next_protocol{selected_protocol = SelectedProtocol},
+ #state{role = server, expecting_next_protocol_negotiation = true} = State0) ->
+ {Record, State} = next_record(State0#state{next_protocol = SelectedProtocol}),
+ next_state(abbreviated, abbreviated, Record, State);
+
abbreviated(timeout, State) ->
{ next_state, abbreviated, State, hibernate };
@@ -656,11 +662,10 @@ cipher(#certificate_verify{signature = Signature, hashsign_algorithm = CertHashS
handle_own_alert(Alert, Version, cipher, State0)
end;
-% client must send a next protocol message if we are expecting it
+%% client must send a next protocol message if we are expecting it
cipher(#finished{}, #state{role = server, expecting_next_protocol_negotiation = true,
next_protocol = undefined, negotiated_version = Version} = State0) ->
- handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, cipher, State0),
- {stop, normal, State0};
+ handle_own_alert(?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), Version, cipher, State0);
cipher(#finished{verify_data = Data} = Finished,
#state{negotiated_version = Version,
@@ -682,8 +687,8 @@ cipher(#finished{verify_data = Data} = Finished,
handle_own_alert(Alert, Version, cipher, State)
end;
-% only allowed to send next_protocol message after change cipher spec
-% & before finished message and it is not allowed during renegotiation
+%% only allowed to send next_protocol message after change cipher spec
+%% & before finished message and it is not allowed during renegotiation
cipher(#next_protocol{selected_protocol = SelectedProtocol},
#state{role = server, expecting_next_protocol_negotiation = true} = State0) ->
{Record, State} = next_record(State0#state{next_protocol = SelectedProtocol}),
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 1929370991..889d310ca8 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2013. 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
@@ -61,11 +61,7 @@ client_hello(Host, Port, ConnectionStates,
ciphers = UserSuites
} = SslOpts,
Cache, CacheCb, Renegotiation, OwnCert) ->
-
- Fun = fun(Version) ->
- ssl_record:protocol_version(Version)
- end,
- Version = ssl_record:highest_protocol_version(lists:map(Fun, Versions)),
+ Version = ssl_record:highest_protocol_version(Versions),
Pending = ssl_record:pending_connection_state(ConnectionStates, read),
SecParams = Pending#connection_state.security_parameters,
Ciphers = available_suites(UserSuites, Version),
@@ -139,10 +135,11 @@ hello(#server_hello{cipher_suite = CipherSuite, server_version = Version,
compression_method = Compression, random = Random,
session_id = SessionId, renegotiation_info = Info,
hash_signs = _HashSigns} = Hello,
- #ssl_options{secure_renegotiate = SecureRenegotation, next_protocol_selector = NextProtocolSelector},
+ #ssl_options{secure_renegotiate = SecureRenegotation, next_protocol_selector = NextProtocolSelector,
+ versions = SupportedVersions},
ConnectionStates0, Renegotiation) ->
%%TODO: select hash and signature algorigthm
- case ssl_record:is_acceptable_version(Version) of
+ case ssl_record:is_acceptable_version(Version, SupportedVersions) of
true ->
case handle_renegotiation_info(client, Info, ConnectionStates0,
Renegotiation, SecureRenegotation, []) of
@@ -171,7 +168,7 @@ hello(#client_hello{client_version = ClientVersion, random = Random,
{Port, Session0, Cache, CacheCb, ConnectionStates0, Cert}, Renegotiation) ->
%% TODO: select hash and signature algorithm
Version = select_version(ClientVersion, Versions),
- case ssl_record:is_acceptable_version(Version) of
+ case ssl_record:is_acceptable_version(Version, Versions) of
true ->
{Type, #session{cipher_suite = CipherSuite,
compression_method = Compression} = Session}
@@ -869,11 +866,7 @@ hello_security_parameters(server, Version, ConnectionState, CipherSuite, Random,
}.
select_version(ClientVersion, Versions) ->
- Fun = fun(Version) ->
- ssl_record:protocol_version(Version)
- end,
- ServerVersion = ssl_record:highest_protocol_version(lists:map(Fun,
- Versions)),
+ ServerVersion = ssl_record:highest_protocol_version(Versions),
ssl_record:lowest_protocol_version(ClientVersion, ServerVersion).
select_cipher_suite([], _) ->
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index 173b9611c6..26aca56739 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2013. 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
@@ -56,7 +56,7 @@
%% Misc.
-export([protocol_version/1, lowest_protocol_version/2,
highest_protocol_version/1, supported_protocol_versions/0,
- is_acceptable_version/1]).
+ is_acceptable_version/1, is_acceptable_version/2]).
-export([compressions/0]).
@@ -475,8 +475,10 @@ supported_protocol_versions([_|_] = Vsns) ->
%%--------------------------------------------------------------------
-spec is_acceptable_version(tls_version()) -> boolean().
+-spec is_acceptable_version(tls_version(), Supported :: [tls_version()]) -> boolean().
%%
%% Description: ssl version 2 is not acceptable security risks are too big.
+%%
%%--------------------------------------------------------------------
is_acceptable_version({N,_})
when N >= ?LOWEST_MAJOR_SUPPORTED_VERSION ->
@@ -484,6 +486,12 @@ is_acceptable_version({N,_})
is_acceptable_version(_) ->
false.
+is_acceptable_version({N,_} = Version, Versions)
+ when N >= ?LOWEST_MAJOR_SUPPORTED_VERSION ->
+ lists:member(Version, Versions);
+is_acceptable_version(_,_) ->
+ false.
+
%%--------------------------------------------------------------------
-spec compressions() -> [binary()].
%%
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index b5c6a1da49..6b8f226a77 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -126,7 +126,8 @@ api_tests() ->
hibernate,
listen_socket,
ssl_accept_timeout,
- ssl_recv_timeout
+ ssl_recv_timeout,
+ versions_option
].
session_tests() ->
@@ -1194,12 +1195,12 @@ tcp_connect(Config) when is_list(Config) ->
{_, 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, dummy, []}},
- {tcp_options, TcpOpts},
- {ssl_options, ServerOpts}]),
+ Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
{ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
@@ -1222,12 +1223,12 @@ tcp_connect_big(Config) when is_list(Config) ->
{_, 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, dummy, []}},
- {tcp_options, TcpOpts},
- {ssl_options, ServerOpts}]),
+ Server = ssl_test_lib:start_upgrade_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE, dummy, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
Port = ssl_test_lib:inet_port(Server),
{ok, Socket} = gen_tcp:connect(Hostname, Port, [binary, {packet, 0}]),
@@ -2659,6 +2660,42 @@ session_cache_process_mnesia(Config) when is_list(Config) ->
session_cache_process(mnesia,Config).
%%--------------------------------------------------------------------
+
+versions_option() ->
+ [{doc,"Test API versions option to connect/listen."}].
+versions_option(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ Supported = proplists:get_value(supported, ssl:versions()),
+ Available = proplists:get_value(available, ssl:versions()),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, [{versions, Supported} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, send_recv_result_active, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ Server ! listen,
+
+ ErrClient = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{versions , Available -- Supported} | ClientOpts]}]),
+ receive
+ {Server, _} ->
+ ok
+ end,
+
+ ssl_test_lib:check_result(ErrClient, {error, {tls_alert, "protocol version"}}).
+%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
diff --git a/lib/ssl/test/ssl_npn_handshake_SUITE.erl b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
index 862690cd7b..8c1b22cf5e 100644
--- a/lib/ssl/test/ssl_npn_handshake_SUITE.erl
+++ b/lib/ssl/test/ssl_npn_handshake_SUITE.erl
@@ -24,6 +24,7 @@
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
+-define(SLEEP, 500).
%%--------------------------------------------------------------------
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
@@ -55,7 +56,8 @@ next_protocol_tests() ->
fallback_npn_handshake_server_preference,
client_negotiate_server_does_not_support,
no_client_negotiate_but_server_supports_npn,
- renegotiate_from_client_after_npn_handshake
+ renegotiate_from_client_after_npn_handshake,
+ npn_handshake_session_reused
].
next_protocol_not_supported() ->
@@ -231,6 +233,56 @@ npn_not_supported_server(Config) when is_list(Config)->
{error, {options, {not_supported_in_sslv3, AdvProtocols}}} = ssl:listen(0, ServerOpts).
+%--------------------------------------------------------------------------------
+npn_handshake_session_reused(Config) when is_list(Config)->
+ ClientOpts0 = ?config(client_opts, Config),
+ ClientOpts = [{client_preferred_next_protocols,
+ {client, [<<"http/1.0">>], <<"http/1.1">>}}] ++ ClientOpts0,
+ ServerOpts0 = ?config(server_opts, Config),
+ ServerOpts =[{next_protocols_advertised,
+ [<<"spdy/2">>, <<"http/1.1">>, <<"http/1.0">>]}] ++ ServerOpts0,
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl_test_lib, no_result_msg, []}},
+ {options, ClientOpts}]),
+
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! {listen, {mfa, {ssl_test_lib, no_result, []}}},
+
+ %% Make sure session is registered
+ ct:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ ct:fail(Other)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ ssl_test_lib:close(Client1).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index c1467697e3..fbb838c686 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 1.19.1
+STDLIB_VSN = 1.19.2