From 2da14af988d563b5c53f42334e990f4c9021dd7a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 26 Mar 2014 16:30:50 +0100 Subject: ssh: Added option negotiation_timeout for ssh:daemon This option is for closing a connection where the client connects, but then do nothing except keeping server resources. --- lib/ssh/doc/src/ssh.xml | 7 +++++++ lib/ssh/src/ssh.erl | 6 +++++- lib/ssh/src/ssh_acceptor.erl | 5 ++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index eaf96d0230..45bc62d8dd 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -304,6 +304,13 @@ if the password is valid and otherwise.

+ + + +

Max time in milliseconds for the authentication negotiation. The default value is 2 minutes. +

+
+

Module implementing the behaviour ssh_server_key_api. diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index d50d5a0cb3..6f21ff843f 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -1,4 +1,4 @@ -%% +% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2004-2013. All Rights Reserved. @@ -332,6 +332,8 @@ handle_option([{idle_time, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions). @@ -360,6 +362,8 @@ handle_ssh_option({pref_public_key_algs, Value} = Opt) when is_list(Value), leng end; handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value == infinity -> Opt; +handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity -> + Opt; handle_ssh_option({user, Value} = Opt) when is_list(Value) -> Opt; handle_ssh_option({dsa_pass_phrase, Value} = Opt) when is_list(Value) -> diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl index 91905b2eaf..e57b07cee8 100644 --- a/lib/ssh/src/ssh_acceptor.erl +++ b/lib/ssh/src/ssh_acceptor.erl @@ -84,11 +84,14 @@ handle_connection(_Callback, Address, Port, Options, Socket) -> SystemSup = ssh_system_sup:system_supervisor(Address, Port), {ok, SubSysSup} = ssh_system_sup:start_subsystem(SystemSup, Options), ConnectionSup = ssh_subsystem_sup:connection_supervisor(SubSysSup), + Timeout = proplists:get_value(negotiation_timeout, + proplists:get_value(ssh_opts, Options, []), + 2*60*1000), ssh_connection_handler:start_connection(server, Socket, [{supervisors, [{system_sup, SystemSup}, {subsystem_sup, SubSysSup}, {connection_sup, ConnectionSup}]} - | Options], infinity). + | Options], Timeout). handle_error(timeout) -> ok; -- cgit v1.2.3 From fb908b7ceccaef70a46bb14db8da3e6e373a9810 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 26 Mar 2014 17:24:51 +0100 Subject: ssh: added daemon option 'parallel_login', default false --- lib/ssh/doc/src/ssh.xml | 10 ++++++++++ lib/ssh/src/ssh.erl | 6 ++++++ lib/ssh/src/ssh_connection_handler.erl | 12 ++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index 45bc62d8dd..7fbd70c87e 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -311,6 +311,16 @@

+ + +

If set to false (the default value), only one login is handled a time. If set to true, an unlimited logins will be allowed simultanously. Note that this affects only the connections with authentication in progress, not the already authenticated connections. +

+ +

Do not enable parallel_logins without protecting the server by other means like a firewall. If set to true, there is no protection against dos attacs.

+
+ +
+

Module implementing the behaviour ssh_server_key_api. diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index 6f21ff843f..de6e8cc421 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -334,6 +334,10 @@ handle_option([{rekey_limit, _} = Opt|Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{negotiation_timeout, _} = Opt|Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +handle_option([{parallel_login, _} = Opt|Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +handle_option([parallel_login|Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option({parallel_login,true}) | SshOptions]); handle_option([Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions). @@ -364,6 +368,8 @@ handle_ssh_option({connect_timeout, Value} = Opt) when is_integer(Value); Value Opt; handle_ssh_option({negotiation_timeout, Value} = Opt) when is_integer(Value); Value == infinity -> Opt; +handle_ssh_option({parallel_login, Value} = Opt) when Value==true ; Value==false -> + Opt; handle_ssh_option({user, Value} = Opt) when is_list(Value) -> Opt; handle_ssh_option({dsa_pass_phrase, Value} = Opt) when is_list(Value) -> diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index d7fff14f92..322da50f21 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -110,8 +110,16 @@ start_connection(server = Role, Socket, Options, Timeout) -> {ok, Pid} = ssh_connection_sup:start_child(ConnectionSup, [Role, Socket, Opts]), {_, Callback, _} = proplists:get_value(transport, Options, {tcp, gen_tcp, tcp_closed}), socket_control(Socket, Pid, Callback), - Ref = erlang:monitor(process, Pid), - handshake(Pid, Ref, Timeout) + case proplists:get_value(parallel_login, Opts, false) of + true -> + spawn(fun() -> + Ref = erlang:monitor(process, Pid), + handshake(Pid, Ref, Timeout) + end); + false -> + Ref = erlang:monitor(process, Pid), + handshake(Pid, Ref, Timeout) + end catch exit:{noproc, _} -> {error, ssh_not_started}; -- cgit v1.2.3