aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh_client_channel.erl2
-rw-r--r--lib/ssh/src/ssh_connection.erl42
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl12
-rw-r--r--lib/ssh/src/ssh_transport.erl33
4 files changed, 61 insertions, 28 deletions
diff --git a/lib/ssh/src/ssh_client_channel.erl b/lib/ssh/src/ssh_client_channel.erl
index 134d3f08bd..8b5e196412 100644
--- a/lib/ssh/src/ssh_client_channel.erl
+++ b/lib/ssh/src/ssh_client_channel.erl
@@ -180,6 +180,8 @@ init([Options]) ->
{stop, Why} ->
{stop, Why}
catch
+ _:undef ->
+ {stop, {bad_channel_callback_module,Cb}};
_:Reason ->
{stop, Reason}
end.
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index ed03b4e2ed..dad7636e3f 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -498,25 +498,24 @@ handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId,
data = Data},
#connection{channel_cache = Cache} = Connection, server) ->
<<?DEC_BIN(SsName,_SsLen)>> = Data,
-
- #channel{remote_id = RemoteId} = Channel0 =
+ #channel{remote_id=RemoteId} = Channel =
ssh_client_channel:cache_lookup(Cache, ChannelId),
-
- ReplyMsg = {subsystem, ChannelId, WantReply, binary_to_list(SsName)},
-
- try
- {ok, Pid} = start_subsystem(SsName, Connection, Channel0, ReplyMsg),
- erlang:monitor(process, Pid),
- Channel = Channel0#channel{user = Pid},
- ssh_client_channel:cache_update(Cache, Channel),
- Reply = {connection_reply,
- channel_success_msg(RemoteId)},
- {[Reply], Connection}
- catch
- _:_ ->
- ErrorReply = {connection_reply, channel_failure_msg(RemoteId)},
- {[ErrorReply], Connection}
- end;
+ Reply =
+ try
+ start_subsystem(SsName, Connection, Channel,
+ {subsystem, ChannelId, WantReply, binary_to_list(SsName)})
+ of
+ {ok, Pid} ->
+ erlang:monitor(process, Pid),
+ ssh_client_channel:cache_update(Cache, Channel#channel{user=Pid}),
+ channel_success_msg(RemoteId);
+ {error,_Error} ->
+ channel_failure_msg(RemoteId)
+ catch
+ _:_ ->
+ channel_failure_msg(RemoteId)
+ end,
+ {[{connection_reply,Reply}], Connection};
handle_msg(#ssh_msg_channel_request{request_type = "subsystem"},
Connection, client) ->
@@ -822,7 +821,12 @@ start_channel(Cb, Id, Args, SubSysSup, Exec, Opts) ->
ChannelSup = ssh_subsystem_sup:channel_supervisor(SubSysSup),
case max_num_channels_not_exceeded(ChannelSup, Opts) of
true ->
- ssh_server_channel_sup:start_child(ChannelSup, Cb, Id, Args, Exec);
+ case ssh_server_channel_sup:start_child(ChannelSup, Cb, Id, Args, Exec) of
+ {error,{Error,_Info}} ->
+ throw(Error);
+ Others ->
+ Others
+ end;
false ->
throw(max_num_channels_exceeded)
end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index f1ff3a70e2..f16aff947b 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1345,11 +1345,11 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock,
{next_event, internal, Msg}
]}
catch
- C:E ->
+ C:E:ST ->
{Shutdown, D} =
?send_disconnect(?SSH_DISCONNECT_PROTOCOL_ERROR,
io_lib:format("Bad packet: Decrypted, but can't decode~n~p:~p~n~p",
- [C,E,erlang:get_stacktrace()]),
+ [C,E,ST]),
StateName, D1),
{stop, Shutdown, D}
end;
@@ -1378,10 +1378,10 @@ handle_event(info, {Proto, Sock, NewData}, StateName, D0 = #data{socket = Sock,
StateName, D0),
{stop, Shutdown, D}
catch
- C:E ->
+ C:E:ST ->
{Shutdown, D} =
?send_disconnect(?SSH_DISCONNECT_PROTOCOL_ERROR,
- io_lib:format("Bad packet: Couldn't decrypt~n~p:~p~n~p",[C,E,erlang:get_stacktrace()]),
+ io_lib:format("Bad packet: Couldn't decrypt~n~p:~p~n~p",[C,E,ST]),
StateName, D0),
{stop, Shutdown, D}
end;
@@ -1770,6 +1770,10 @@ set_kex_overload_prefix(Msg = <<?BYTE(Op),_/binary>>, #data{ssh_params=SshParams
case catch atom_to_list(kex(SshParams)) of
"ecdh-sha2-" ++ _ ->
<<"ecdh",Msg/binary>>;
+ "curve25519-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
+ "curve448-" ++ _ ->
+ <<"ecdh",Msg/binary>>;
"diffie-hellman-group-exchange-" ++ _ ->
<<"dh_gex",Msg/binary>>;
"diffie-hellman-group" ++ _ ->
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 631c4d0213..235f09a178 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -104,7 +104,12 @@ algo_two_spec_class(_) -> false.
default_algorithms(kex) ->
supported_algorithms(kex, [
- 'diffie-hellman-group1-sha1' % Gone in OpenSSH 7.3.p1
+ %% Under devolpment:
+ 'curve25519-sha256',
+ 'curve448-sha512',
+ %% Gone in OpenSSH 7.3.p1:
+ 'diffie-hellman-group1-sha1'
]);
default_algorithms(cipher) ->
@@ -126,6 +131,11 @@ supported_algorithms(kex) ->
{'ecdh-sha2-nistp384', [{public_keys,ecdh}, {ec_curve,secp384r1}, {hashs,sha384}]},
{'ecdh-sha2-nistp521', [{public_keys,ecdh}, {ec_curve,secp521r1}, {hashs,sha512}]},
{'ecdh-sha2-nistp256', [{public_keys,ecdh}, {ec_curve,secp256r1}, {hashs,sha256}]},
+ %% https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves
+ %% Secure Shell (SSH) Key Exchange Method using Curve25519 and Curve448
+ {'curve25519-sha256', [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
+ {'[email protected]', [{public_keys,eddh}, {curves,x25519}, {hashs,sha256}]},
+ {'curve448-sha512', [{public_keys,eddh}, {curves,x448}, {hashs,sha512}]},
{'diffie-hellman-group-exchange-sha256', [{public_keys,dh}, {hashs,sha256}]},
{'diffie-hellman-group16-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1
{'diffie-hellman-group18-sha512', [{public_keys,dh}, {hashs,sha512}]}, % In OpenSSH 7.3.p1
@@ -403,7 +413,10 @@ key_exchange_first_msg(Kex, Ssh0=#ssh{opts=Opts}) when Kex == 'diffie-hellman-gr
key_exchange_first_msg(Kex, Ssh0) when Kex == 'ecdh-sha2-nistp256' ;
Kex == 'ecdh-sha2-nistp384' ;
- Kex == 'ecdh-sha2-nistp521' ->
+ Kex == 'ecdh-sha2-nistp521' ;
+ Kex == 'curve25519-sha256' ;
+ Kex == '[email protected]';
+ Kex == 'curve448-sha512' ->
Curve = ecdh_curve(Kex),
{Public, Private} = generate_key(ecdh, Curve),
{SshPacket, Ssh1} = ssh_packet(#ssh_msg_kex_ecdh_init{q_c=Public}, Ssh0),
@@ -666,8 +679,10 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
catch
Class:Error ->
?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- io_lib:format("ECDH compute key failed in server: ~p:~p",
- [Class,Error])
+ io_lib:format("ECDH compute key failed in server: ~p:~p~n"
+ "Kex: ~p, Curve: ~p~n"
+ "PeerPublic: ~p",
+ [Class,Error,Kex,Curve,PeerPublic])
)
end.
@@ -1874,6 +1889,11 @@ sha(?'secp521r1') -> sha(secp521r1);
sha('ecdh-sha2-nistp256') -> sha(secp256r1);
sha('ecdh-sha2-nistp384') -> sha(secp384r1);
sha('ecdh-sha2-nistp521') -> sha(secp521r1);
+sha('curve25519-sha256' ) -> sha256;
+sha('[email protected]' ) -> sha256;
+sha('curve448-sha512') -> sha512;
+sha(x25519) -> sha256;
+sha(x448) -> sha512;
sha(Str) when is_list(Str), length(Str)<50 -> sha(list_to_atom(Str)).
@@ -1938,7 +1958,10 @@ dh_bits(#alg{encrypt = Encrypt,
ecdh_curve('ecdh-sha2-nistp256') -> secp256r1;
ecdh_curve('ecdh-sha2-nistp384') -> secp384r1;
-ecdh_curve('ecdh-sha2-nistp521') -> secp521r1.
+ecdh_curve('ecdh-sha2-nistp521') -> secp521r1;
+ecdh_curve('curve448-sha512' ) -> x448;
+ecdh_curve('curve25519-sha256' ) -> x25519;
+ecdh_curve('[email protected]' ) -> x25519.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%