aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src')
-rw-r--r--lib/ssh/src/ssh.hrl3
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl47
-rw-r--r--lib/ssh/src/ssh_file.erl9
-rw-r--r--lib/ssh/src/ssh_transport.erl16
4 files changed, 56 insertions, 19 deletions
diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl
index 7cebec1c74..da5750b6c3 100644
--- a/lib/ssh/src/ssh.hrl
+++ b/lib/ssh/src/ssh.hrl
@@ -126,7 +126,8 @@
userauth_quiet_mode, % boolean()
userauth_supported_methods , %
userauth_methods,
- userauth_preference
+ userauth_preference,
+ available_host_keys
}).
-record(alg,
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 00b30e5434..a9bf23953d 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -637,16 +637,18 @@ init_ssh(client = Role, Vsn, Version, Options, Socket) ->
{ok, PeerAddr} = inet:peername(Socket),
PeerName = proplists:get_value(host, Options),
+ KeyCb = proplists:get_value(key_cb, Options, ssh_file),
#ssh{role = Role,
c_vsn = Vsn,
c_version = Version,
- key_cb = proplists:get_value(key_cb, Options, ssh_file),
+ key_cb = KeyCb,
io_cb = IOCb,
userauth_quiet_mode = proplists:get_value(quiet_mode, Options, false),
opts = Options,
userauth_supported_methods = AuthMethods,
- peer = {PeerName, PeerAddr}
+ peer = {PeerName, PeerAddr},
+ available_host_keys = supported_host_keys(Role, KeyCb, Options)
};
init_ssh(server = Role, Vsn, Version, Options, Socket) ->
@@ -654,17 +656,50 @@ init_ssh(server = Role, Vsn, Version, Options, Socket) ->
AuthMethods = proplists:get_value(auth_methods, Options,
?SUPPORTED_AUTH_METHODS),
{ok, PeerAddr} = inet:peername(Socket),
-
+ KeyCb = proplists:get_value(key_cb, Options, ssh_file),
+
#ssh{role = Role,
s_vsn = Vsn,
s_version = Version,
- key_cb = proplists:get_value(key_cb, Options, ssh_file),
+ key_cb = KeyCb,
io_cb = proplists:get_value(io_cb, Options, ssh_io),
opts = Options,
userauth_supported_methods = AuthMethods,
- peer = {undefined, PeerAddr}
+ peer = {undefined, PeerAddr},
+ available_host_keys = supported_host_keys(Role, KeyCb, Options)
}.
+supported_host_keys(client, _, _) ->
+ ["ssh-rsa", "ssh-dss"];
+supported_host_keys(server, KeyCb, Options) ->
+ lists:foldl(fun(Type, Acc) ->
+ case available_host_key(KeyCb, Type, Options) of
+ {error, _} ->
+ Acc;
+ Alg ->
+ [Alg | Acc]
+ end
+ end, [],
+ %% Prefered alg last so no need to reverse
+ ["ssh-dss", "ssh-rsa"]).
+
+available_host_key(KeyCb, "ssh-dss"= Alg, Opts) ->
+ Scope = proplists:get_value(key_scope, Opts, system),
+ case KeyCb:private_host_dsa_key(Scope, Opts) of
+ {ok, _} ->
+ Alg;
+ Other ->
+ Other
+ end;
+available_host_key(KeyCb, "ssh-rsa" = Alg, Opts) ->
+ Scope = proplists:get_value(key_scope, Opts, system),
+ case KeyCb:private_host_rsa_key(Scope, Opts) of
+ {ok, _} ->
+ Alg;
+ Other ->
+ Other
+ end.
+
send_msg(Msg, #state{socket = Socket, transport_cb = Transport}) ->
Transport:send(Socket, Msg).
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 49106ccdb3..d5cacc3294 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -30,7 +30,8 @@
-export([public_host_dsa_key/2,private_host_dsa_key/2,
public_host_rsa_key/2,private_host_rsa_key/2,
- public_host_key/2,private_host_key/2,
+ %%public_host_key/2,
+ private_host_key/2,
lookup_host_key/3, add_host_key/3,
lookup_user_key/4, ssh_dir/2, file_name/3]).
@@ -62,9 +63,9 @@ private_host_rsa_key(Type, Opts) ->
Password = proplists:get_value(password, Opts, ignore),
decode(File, Password).
-public_host_key(Type, Opts) ->
- File = file_name(Type, "ssh_host_key", Opts),
- decode(File, public_key).
+%% public_host_key(Type, Opts) ->
+%% File = file_name(Type, "ssh_host_key", Opts),
+%% decode(File, public_key).
private_host_key(Type, Opts) ->
File = file_name(Type, "ssh_host_key", Opts),
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 3fef42a1ac..f99b9c9ca7 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -203,24 +203,24 @@ key_exchange_init_msg(Ssh0) ->
{SshPacket, Ssh} = ssh_packet(Msg, Ssh0),
{Msg, SshPacket, Ssh}.
-kex_init(#ssh{role = Role, opts = Opts}) ->
+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
zlib -> ["zlib", "none"];
none -> ["none", "zlib"]
end,
- kexinit_messsage(Role, Random, Compression).
+ kexinit_messsage(Role, Random, Compression, HostKeyAlgs).
key_init(client, Ssh, Value) ->
Ssh#ssh{c_keyinit = Value};
key_init(server, Ssh, Value) ->
Ssh#ssh{s_keyinit = Value}.
-kexinit_messsage(client, Random, Compression) ->
+kexinit_messsage(client, Random, Compression, HostKeyAlgs) ->
#ssh_msg_kexinit{
cookie = Random,
kex_algorithms = ["diffie-hellman-group1-sha1"],
- server_host_key_algorithms = ["ssh-rsa", "ssh-dss"],
+ server_host_key_algorithms = HostKeyAlgs,
encryption_algorithms_client_to_server = ["aes128-cbc","3des-cbc"],
encryption_algorithms_server_to_client = ["aes128-cbc","3des-cbc"],
mac_algorithms_client_to_server = ["hmac-sha1"],
@@ -231,11 +231,11 @@ kexinit_messsage(client, Random, Compression) ->
languages_server_to_client = []
};
-kexinit_messsage(server, Random, Compression) ->
+kexinit_messsage(server, Random, Compression, HostKeyAlgs) ->
#ssh_msg_kexinit{
cookie = Random,
kex_algorithms = ["diffie-hellman-group1-sha1"],
- server_host_key_algorithms = ["ssh-dss"],
+ server_host_key_algorithms = HostKeyAlgs,
encryption_algorithms_client_to_server = ["aes128-cbc","3des-cbc"],
encryption_algorithms_server_to_client = ["aes128-cbc","3des-cbc"],
mac_algorithms_client_to_server = ["hmac-sha1"],
@@ -426,8 +426,8 @@ get_host_key(SSH) ->
Error ->
exit(Error)
end;
- _ ->
- exit({error, bad_key_type})
+ Foo ->
+ exit({error, {Foo, bad_key_type}})
end.
sign_host_key(_Ssh, #'RSAPrivateKey'{} = Private, H) ->