aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/src/ssh_transport.erl50
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl9
-rw-r--r--lib/ssh/vsn.mk2
3 files changed, 44 insertions, 17 deletions
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 8669be570e..d6414bab6c 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -240,20 +240,30 @@ key_exchange_first_msg('diffie-hellman-group-exchange-sha1', Ssh0) ->
handle_kexdh_init(#ssh_msg_kexdh_init{e = E}, Ssh0) ->
{G, P} = dh_group1(),
- {Private, Public} = dh_gen_key(G, P, 1024),
- K = ssh_math:ipow(E, Private, P),
- Key = get_host_key(Ssh0),
- H = kex_h(Ssh0, Key, E, Public, K),
- H_SIG = sign_host_key(Ssh0, Key, H),
- {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
- f = Public,
- h_sig = H_SIG
- }, Ssh0),
-
- {ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
- shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh1, H)}}.
+ if
+ 1=<E, E=<(P-1) ->
+ {Private, Public} = dh_gen_key(G, P, 1024),
+ K = ssh_math:ipow(E, Private, P),
+ Key = get_host_key(Ssh0),
+ H = kex_h(Ssh0, Key, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, Key, H),
+ {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
+ f = Public,
+ h_sig = H_SIG
+ }, Ssh0),
+
+ {ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
+ shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh1, H)}};
+ true ->
+ Error = {error,bad_e_from_peer},
+ Disconnect = #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = "en"},
+ throw({Error, Disconnect})
+ end.
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
{Private, Public} = dh_gen_key(G,P,1024),
@@ -277,7 +287,7 @@ handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
%% %% Select algorithms
handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) ->
+ #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) when 1=<F, F=<(P-1)->
K = ssh_math:ipow(F, Private, P),
H = kex_h(Ssh0, HostKey, Public, F, K),
@@ -293,7 +303,15 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
description = "Key exchange failed",
language = "en"},
throw({Error, Disconnect})
- end.
+ end;
+handle_kexdh_reply(#ssh_msg_kexdh_reply{}, _SSH) ->
+ Error = {error,bad_f_from_peer},
+ Disconnect = #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = "en"},
+ throw({Error, Disconnect}).
+
handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = _Min,
n = _NBits,
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index d99123f871..a61fd2dd41 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -545,6 +545,7 @@ receive_hej() ->
receive_logout() ->
receive
<<"logout">> ->
+ extra_logout(),
receive
<<"Connection closed">> ->
ok
@@ -564,6 +565,14 @@ receive_normal_exit(Shell) ->
ct:fail({unexpected_msg, Other})
end.
+extra_logout() ->
+ receive
+ <<"logout">> ->
+ ok
+ after 500 ->
+ ok
+ end.
+
%%--------------------------------------------------------------------
%%--------------------------------------------------------------------
%% Check if we have a "newer" ssh client that supports these test cases
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 40bda0c19f..cef9992f1b 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,4 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 3.2.3
+SSH_VSN = 4.0
APP_VSN = "ssh-$(SSH_VSN)"