From 8215ea28fa2f699499b64d6f2c712e068b199390 Mon Sep 17 00:00:00 2001
From: Hans Nilsson
Date: Fri, 11 Nov 2016 16:59:08 +0100
Subject: ssh: Add fun and fingerprint to option 'silently_accept_host'
---
lib/ssh/doc/src/ssh.xml | 14 ++++++++++++--
lib/ssh/src/ssh.erl | 9 +++++++++
lib/ssh/src/ssh_transport.erl | 16 ++++++++++------
3 files changed, 31 insertions(+), 8 deletions(-)
(limited to 'lib/ssh')
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index ef9f7cbd9b..6b49f89449 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -175,11 +175,21 @@
supplied with this option.
-
+
+
+ boolean()]]>
+
-
When true, hosts are added to the
file without asking the user.
- Defaults to false.
+ Defaults to false which will give a user question on stdio of whether to accept or reject a previously
+ unseen host.
+ If the option value is has an accept_fun(), that fun will called with the arguments
+ (PeerName, PeerHostKeyFingerPrint). The fingerprint is calculated on the Peer's Host Key with
+ public_key:ssh_hostkey_fingerprint/1.
+
+ If the crypto:digest_type() is present, the fingerprint is calculated with that digest type by the function
+ public_key:ssh_hostkey_fingerprint/2.
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index 1d7be3547b..31e343e81b 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -617,6 +617,15 @@ handle_ssh_option({user_dir_fun, Value} = Opt) when is_function(Value) ->
Opt;
handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_boolean(Value) ->
Opt;
+handle_ssh_option({silently_accept_hosts, Value} = Opt) when is_function(Value,2) ->
+ Opt;
+handle_ssh_option({silently_accept_hosts, {DigestAlg,Value}} = Opt) when is_function(Value,2) ->
+ case lists:member(DigestAlg, [md5, sha, sha224, sha256, sha384, sha512]) of
+ true ->
+ Opt;
+ false ->
+ throw({error, {eoptions, Opt}})
+ end;
handle_ssh_option({user_interaction, Value} = Opt) when is_boolean(Value) ->
Opt;
handle_ssh_option({preferred_algorithms,[_|_]} = Opt) ->
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 15b80de30a..21ba34506a 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -734,12 +734,16 @@ public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
-accepted_host(Ssh, PeerName, Opts) ->
+accepted_host(Ssh, PeerName, Public, Opts) ->
case proplists:get_value(silently_accept_hosts, Opts, false) of
+ F when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(Public)));
+ {DigestAlg,F} when is_function(F,2) ->
+ true == (catch F(PeerName, public_key:ssh_hostkey_fingerprint(DigestAlg,Public)));
true ->
- yes;
+ true;
false ->
- yes_no(Ssh, "New host " ++ PeerName ++ " accept")
+ yes == yes_no(Ssh, "New host " ++ PeerName ++ " accept")
end.
known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
@@ -749,10 +753,10 @@ known_host_key(#ssh{opts = Opts, key_cb = Mod, peer = Peer} = Ssh,
true ->
ok;
false ->
- case accepted_host(Ssh, PeerName, Opts) of
- yes ->
+ case accepted_host(Ssh, PeerName, Public, Opts) of
+ true ->
Mod:add_host_key(PeerName, Public, Opts);
- no ->
+ false ->
{error, rejected}
end
end.
--
cgit v1.2.3