aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh')
-rw-r--r--lib/ssh/doc/src/notes.xml16
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl6
-rw-r--r--lib/ssh/src/ssh_transport.erl40
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl41
-rw-r--r--lib/ssh/vsn.mk1
5 files changed, 97 insertions, 7 deletions
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 012d7051eb..010b1b15c7 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -30,6 +30,22 @@
<file>notes.xml</file>
</header>
+<section><title>Ssh 4.1.3</title>
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>
+ SSH_MSG_KEX_DH_GEX_REQUEST_OLD implemented to make PuTTY
+ work with erl server.</p>
+ <p>
+ Own Id: OTP-13140</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Ssh 4.1.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 68062209fc..516a09bf6a 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -433,6 +433,12 @@ key_exchange(#ssh_msg_kex_dh_gex_request{} = Msg,
send_msg(GexGroup, State),
{next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+key_exchange(#ssh_msg_kex_dh_gex_request_old{} = Msg,
+ #state{ssh_params = #ssh{role = server} = Ssh0} = State) ->
+ {ok, GexGroup, Ssh} = ssh_transport:handle_kex_dh_gex_request(Msg, Ssh0),
+ send_msg(GexGroup, State),
+ {next_state, key_exchange_dh_gex_init, next_packet(State#state{ssh_params = Ssh})};
+
key_exchange(#ssh_msg_kex_dh_gex_group{} = Msg,
#state{ssh_params = #ssh{role = client} = Ssh0} = State) ->
{ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, Ssh0),
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 041e86bae1..67a0d29bb8 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -433,6 +433,40 @@ handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
language = ""})
end;
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request_old{n = NBits},
+ Ssh0=#ssh{opts=Opts}) ->
+ %% server
+ %%
+ %% This message was in the draft-00 of rfc4419
+ %% (https://tools.ietf.org/html/draft-ietf-secsh-dh-group-exchange-00)
+ %% In later drafts and the rfc is "is used for backward compatibility".
+ %% Unfortunatly the rfc does not specify how to treat the parameter n
+ %% if there is no group of that modulus length :(
+ %% The draft-00 however specifies that n is the "... number of bits
+ %% the subgroup should have at least".
+ %% Further, it says that "Servers and clients SHOULD support groups
+ %% with a modulus length of k bits, where 1024 <= k <= 8192."
+ %%
+ Min0 = NBits,
+ Max0 = 8192,
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {-1, -1, NBits} % flag for kex_h hash calc
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
handle_kex_dh_gex_request(_, _) ->
throw({{error,bad_ssh_msg_kex_dh_gex_request},
#ssh_msg_disconnect{
@@ -1571,8 +1605,11 @@ kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = if Min==-1; Max==-1 ->
- KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
+ %% flag from 'ssh_msg_kex_dh_gex_request_old'
+ %% It was like this before that message was supported,
+ %% why?
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
@@ -1581,7 +1618,6 @@ kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
- KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
Ts = [string,string,binary,binary,binary,
uint32,uint32,uint32,
mpint,mpint,mpint,mpint,mpint],
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index 3a7f47c2dd..4639904061 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -69,7 +69,9 @@ groups() ->
gex_client_init_option_groups,
gex_server_gex_limit,
gex_client_init_option_groups_moduli_file,
- gex_client_init_option_groups_file
+ gex_client_init_option_groups_file,
+ gex_client_old_request_exact,
+ gex_client_old_request_noexact
]},
{service_requests, [], [bad_service_name,
bad_long_service_name,
@@ -94,7 +96,9 @@ init_per_testcase(no_common_alg_server_disconnects, Config) ->
init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
TC == gex_client_init_option_groups_moduli_file ;
TC == gex_client_init_option_groups_file ;
- TC == gex_server_gex_limit ->
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
Opts = case TC of
gex_client_init_option_groups ->
[{dh_gex_groups, [{2345, 3, 41}]}];
@@ -106,8 +110,10 @@ init_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
DataDir = ?config(data_dir, Config),
F = filename:join(DataDir, "dh_group_test.moduli"),
[{dh_gex_groups, {ssh_moduli_file,F}}];
- gex_server_gex_limit ->
- [{dh_gex_groups, [{ 500, 3, 18},
+ _ when TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
+ [{dh_gex_groups, [{ 500, 3, 17},
{1000, 7, 91},
{3000, 5, 61}]},
{dh_gex_limits,{500,1500}}
@@ -126,7 +132,9 @@ end_per_testcase(no_common_alg_server_disconnects, Config) ->
end_per_testcase(TC, Config) when TC == gex_client_init_option_groups ;
TC == gex_client_init_option_groups_moduli_file ;
TC == gex_client_init_option_groups_file ;
- TC == gex_server_gex_limit ->
+ TC == gex_server_gex_limit ;
+ TC == gex_client_old_request_exact ;
+ TC == gex_client_old_request_noexact ->
stop_std_daemon(Config);
end_per_testcase(_TestCase, Config) ->
check_std_daemon_works(Config, ?LINE).
@@ -381,6 +389,29 @@ do_gex_client_init(Config, {Min,N,Max}, {G,P}) ->
]
).
+%%%--------------------------------------------------------------------
+gex_client_old_request_exact(Config) -> do_gex_client_init_old(Config, 500, {3,17}).
+gex_client_old_request_noexact(Config) -> do_gex_client_init_old(Config, 800, {7,91}).
+
+do_gex_client_init_old(Config, N, {G,P}) ->
+ {ok,_} =
+ ssh_trpt_test_lib:exec(
+ [{set_options, [print_ops, print_seqnums, print_messages]},
+ {connect,
+ server_host(Config),server_port(Config),
+ [{silently_accept_hosts, true},
+ {user_dir, user_dir(Config)},
+ {user_interaction, false},
+ {preferred_algorithms,[{kex,['diffie-hellman-group-exchange-sha1']}]}
+ ]},
+ receive_hello,
+ {send, hello},
+ {send, ssh_msg_kexinit},
+ {match, #ssh_msg_kexinit{_='_'}, receive_msg},
+ {send, #ssh_msg_kex_dh_gex_request_old{n = N}},
+ {match, #ssh_msg_kex_dh_gex_group{p=P, g=G, _='_'}, receive_msg}
+ ]
+ ).
%%%--------------------------------------------------------------------
bad_service_name(Config) ->
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index d828bccd29..25b19133b1 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,4 +1,5 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
SSH_VSN = 4.2
+
APP_VSN = "ssh-$(SSH_VSN)"