aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/doc/src/notes.xml15
-rw-r--r--lib/ssh/doc/src/ssh.xml1
-rw-r--r--lib/ssh/src/ssh.hrl3
-rw-r--r--lib/ssh/src/ssh_cli.erl19
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl7
-rw-r--r--lib/ssh/src/ssh_file.erl9
-rw-r--r--lib/ssh/src/ssh_transport.erl37
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl23
8 files changed, 99 insertions, 15 deletions
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 8e112433c1..299dd5058a 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -195,8 +195,6 @@
</item>
</list>
</section>
-
-
<section><title>Improvements and New Features</title>
<list>
<item>
@@ -251,7 +249,20 @@
</section>
</section>
+<section><title>Ssh 2.1.2.1</title>
+<section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Removed error report in ssh_connection_handler triggered
+ by badmatch failure.</p>
+ <p>
+ Own Id: OTP-11188</p>
+ </item>
+ </list>
+ </section>
+</section>
<section><title>Ssh 2.1.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index bd0d3d49dd..141d3df38e 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -88,6 +88,7 @@
number for SSH.</d>
<v>Options = [{Option, Value}]</v>
<v>Timeout = infinity | integer(milliseconds)</v>
+ <d>Negotiation timeout, for connection timeout use the option <c>{connect_timeout, timeout()}</c>.</d>
</type>
<desc>
<p>Connects to an SSH server. No channel is started. This is done
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index da5750b6c3..4fd347ba8f 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -127,7 +127,8 @@
userauth_supported_methods , %
userauth_methods,
userauth_preference,
- available_host_keys
+ available_host_keys,
+ authenticated = false
}).
-record(alg,
diff --git a/lib/ssh/src/ssh_cli.erl b/lib/ssh/src/ssh_cli.erl
index 69b1ab186f..54911e757c 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -68,7 +68,8 @@ init([Shell]) ->
handle_ssh_msg({ssh_cm, _ConnectionManager,
{data, _ChannelId, _Type, Data}},
#state{group = Group} = State) ->
- Group ! {self(), {data, binary_to_list(Data)}},
+ List = binary_to_list(Data),
+ to_group(List, Group),
{ok, State};
handle_ssh_msg({ssh_cm, ConnectionManager,
@@ -188,6 +189,22 @@ terminate(_Reason, _State) ->
%%% Internal functions
%%--------------------------------------------------------------------
+to_group([], _Group) ->
+ ok;
+to_group([$\^C | Tail], Group) ->
+ exit(Group, interrupt),
+ to_group(Tail, Group);
+to_group(Data, Group) ->
+ Func = fun(C) -> C /= $\^C end,
+ Tail = case lists:splitwith(Func, Data) of
+ {[], Right} ->
+ Right;
+ {Left, Right} ->
+ Group ! {self(), {data, Left}},
+ Right
+ end,
+ to_group(Tail, Group).
+
exec(Cmd) ->
case eval(parse(scan(Cmd))) of
{error, _} ->
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 1c4477aeb3..9de4dd5967 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -426,10 +426,10 @@ userauth(#ssh_msg_userauth_info_response{} = Msg,
language = "en"}, State)
end;
-userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client},
+userauth(#ssh_msg_userauth_success{}, #state{ssh_params = #ssh{role = client} = Ssh,
manager = Pid} = State) ->
Pid ! ssh_connected,
- {next_state, connected, next_packet(State)};
+ {next_state, connected, next_packet(State#state{ssh_params = Ssh#ssh{authenticated = true}})};
userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client,
@@ -451,11 +451,12 @@ userauth(#ssh_msg_userauth_failure{authentications = Methodes},
case ssh_auth:userauth_request_msg(Ssh1) of
{disconnect, DisconnectMsg, {Msg, Ssh}} ->
send_msg(Msg, State),
- handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
+ handle_disconnect(DisconnectMsg, State#state{ssh_params = Ssh});
{Msg, Ssh} ->
send_msg(Msg, State),
{next_state, userauth, next_packet(State#state{ssh_params = Ssh})}
end;
+
%% The prefered authentication method failed try next method
userauth(#ssh_msg_userauth_failure{},
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index f115a32710..21cdedc156 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -315,5 +315,12 @@ default_user_dir()->
{ok,[[Home|_]]} = init:get_argument(home),
UserDir = filename:join(Home, ".ssh"),
ok = filelib:ensure_dir(filename:join(UserDir, "dummy")),
- ok = file:change_mode(UserDir, ?PERM_700),
+ {ok,Info} = file:read_file_info(UserDir),
+ #file_info{mode=Mode} = Info,
+ case (Mode band 8#777) of
+ ?PERM_700 ->
+ ok;
+ _Other ->
+ ok = file:change_mode(UserDir, ?PERM_700)
+ end,
UserDir.
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index beaffdc025..682d766d99 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -206,6 +206,7 @@ key_exchange_init_msg(Ssh0) ->
kex_init(#ssh{role = Role, opts = Opts, available_host_keys = HostKeyAlgs}) ->
Random = ssh_bits:random(16),
Compression = case proplists:get_value(compression, Opts, none) of
+ openssh_zlib -> ["[email protected]", "none"];
zlib -> ["zlib", "none"];
none -> ["none", "zlib"]
end,
@@ -855,13 +856,14 @@ decrypt(#ssh{decrypt = 'aes128-cbc', decrypt_keys = Key,
IV = crypto:next_iv(aes_cbc, Data),
{Ssh#ssh{decrypt_ctx = IV}, Dec}.
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compression
%%
-%% none REQUIRED no compression
-%% zlib OPTIONAL ZLIB (LZ77) compression
+%% none REQUIRED no compression
+%% zlib OPTIONAL ZLIB (LZ77) compression
+%% openssh_zlib OPTIONAL ZLIB (LZ77) compression
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
compress_init(SSH) ->
compress_init(SSH, 1).
@@ -870,19 +872,32 @@ compress_init(#ssh{compress = none} = Ssh, _) ->
compress_init(#ssh{compress = zlib} = Ssh, Level) ->
Zlib = zlib:open(),
ok = zlib:deflateInit(Zlib, Level),
+ {ok, Ssh#ssh{compress_ctx = Zlib}};
+compress_init(#ssh{compress = '[email protected]'} = Ssh, Level) ->
+ Zlib = zlib:open(),
+ ok = zlib:deflateInit(Zlib, Level),
{ok, Ssh#ssh{compress_ctx = Zlib}}.
-
compress_final(#ssh{compress = none} = Ssh) ->
{ok, Ssh};
compress_final(#ssh{compress = zlib, compress_ctx = Context} = Ssh) ->
zlib:close(Context),
+ {ok, Ssh#ssh{compress = none, compress_ctx = undefined}};
+compress_final(#ssh{compress = '[email protected]', authenticated = false} = Ssh) ->
+ {ok, Ssh};
+compress_final(#ssh{compress = '[email protected]', compress_ctx = Context, authenticated = true} = Ssh) ->
+ zlib:close(Context),
{ok, Ssh#ssh{compress = none, compress_ctx = undefined}}.
compress(#ssh{compress = none} = Ssh, Data) ->
{Ssh, Data};
compress(#ssh{compress = zlib, compress_ctx = Context} = Ssh, Data) ->
Compressed = zlib:deflate(Context, Data, sync),
+ {Ssh, list_to_binary(Compressed)};
+compress(#ssh{compress = '[email protected]', authenticated = false} = Ssh, Data) ->
+ {Ssh, Data};
+compress(#ssh{compress = '[email protected]', compress_ctx = Context, authenticated = true} = Ssh, Data) ->
+ Compressed = zlib:deflate(Context, Data, sync),
{Ssh, list_to_binary(Compressed)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -894,18 +909,32 @@ decompress_init(#ssh{decompress = none} = Ssh) ->
decompress_init(#ssh{decompress = zlib} = Ssh) ->
Zlib = zlib:open(),
ok = zlib:inflateInit(Zlib),
+ {ok, Ssh#ssh{decompress_ctx = Zlib}};
+decompress_init(#ssh{decompress = '[email protected]'} = Ssh) ->
+ Zlib = zlib:open(),
+ ok = zlib:inflateInit(Zlib),
{ok, Ssh#ssh{decompress_ctx = Zlib}}.
decompress_final(#ssh{decompress = none} = Ssh) ->
{ok, Ssh};
decompress_final(#ssh{decompress = zlib, decompress_ctx = Context} = Ssh) ->
zlib:close(Context),
+ {ok, Ssh#ssh{decompress = none, decompress_ctx = undefined}};
+decompress_final(#ssh{decompress = '[email protected]', authenticated = false} = Ssh) ->
+ {ok, Ssh};
+decompress_final(#ssh{decompress = '[email protected]', decompress_ctx = Context, authenticated = true} = Ssh) ->
+ zlib:close(Context),
{ok, Ssh#ssh{decompress = none, decompress_ctx = undefined}}.
decompress(#ssh{decompress = none} = Ssh, Data) ->
{Ssh, Data};
decompress(#ssh{decompress = zlib, decompress_ctx = Context} = Ssh, Data) ->
Decompressed = zlib:inflate(Context, Data),
+ {Ssh, list_to_binary(Decompressed)};
+decompress(#ssh{decompress = '[email protected]', authenticated = false} = Ssh, Data) ->
+ {Ssh, Data};
+decompress(#ssh{decompress = '[email protected]', decompress_ctx = Context, authenticated = true} = Ssh, Data) ->
+ Decompressed = zlib:inflate(Context, Data),
{Ssh, list_to_binary(Decompressed)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 93029c5038..0aa60624bf 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -48,8 +48,8 @@ all() ->
close].
groups() ->
- [{dsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]},
- {rsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey]},
+ [{dsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey, openssh_zlib_basic_test]},
+ {rsa_key, [], [send, exec, exec_compressed, shell, known_hosts, idle_time, rekey, openssh_zlib_basic_test]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
{internal_error, [], [internal_error]}
@@ -493,7 +493,24 @@ close(Config) when is_list(Config) ->
exit(CM, {shutdown, normal}),
ok = ssh:close(CM).
-
+
+openssh_zlib_basic_test() ->
+ [{doc, "Test basic connection with openssh_zlib"}].
+openssh_zlib_basic_test(Config) ->
+ SystemDir = filename:join(?config(priv_dir, Config), system),
+ UserDir = ?config(priv_dir, Config),
+
+ {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]),
+ ConnectionRef =
+ ssh_test_lib:connect(Host, Port, [{silently_accept_hosts, true},
+ {user_dir, UserDir},
+ {user_interaction, false},
+ {compression, openssh_zlib}]),
+ ok = ssh:close(ConnectionRef),
+ ssh:stop_daemon(Pid).
+
%%--------------------------------------------------------------------
%% Internal functions ------------------------------------------------
%%--------------------------------------------------------------------