summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ssh/doc/src/ssh_agent.xml6
-rw-r--r--lib/ssh/doc/src/ssh_client_key_api.xml24
-rw-r--r--lib/ssh/doc/src/ssh_file.xml16
-rw-r--r--lib/ssh/src/ssh_agent.erl47
-rw-r--r--lib/ssh/src/ssh_client_key_api.erl8
-rw-r--r--lib/ssh/src/ssh_file.erl57
6 files changed, 91 insertions, 67 deletions
diff --git a/lib/ssh/doc/src/ssh_agent.xml b/lib/ssh/doc/src/ssh_agent.xml
index 5f151959d3..034b6b3b66 100644
--- a/lib/ssh/doc/src/ssh_agent.xml
+++ b/lib/ssh/doc/src/ssh_agent.xml
@@ -102,20 +102,22 @@
<funcs>
<func>
<name since="" name="add_host_key" arity="3"/>
+ <name since="" name="add_host_key" arity="4"/>
<fsummary></fsummary>
<desc>
<p>
- This callback is delegated to the <seealso marker="ssh:ssh_file#add_host_key-3">ssh_file</seealso> module.
+ This callback is delegated to the <seealso marker="ssh:ssh_file#add_host_key-4">ssh_file</seealso> module.
</p>
</desc>
</func>
<func>
<name since="" name="is_host_key" arity="4"/>
+ <name since="" name="is_host_key" arity="5"/>
<fsummary></fsummary>
<desc>
<p>
- This callback is delegated to the <seealso marker="ssh:ssh_file#is_host_key-4">ssh_file</seealso> module.
+ This callback is delegated to the <seealso marker="ssh:ssh_file#is_host_key-5">ssh_file</seealso> module.
</p>
</desc>
</func>
diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml
index c3dc4a12fc..a61d43a818 100644
--- a/lib/ssh/doc/src/ssh_client_key_api.xml
+++ b/lib/ssh/doc/src/ssh_client_key_api.xml
@@ -69,7 +69,9 @@
<v>ConnectOptions = <seealso marker="#type-client_key_cb_options">client_key_cb_options()</seealso></v>
</type>
<desc>
- <p>This function is retired in favour for <c>Module:add_host_key/4</c> which is the prefered API function.</p>
+ <p>This function is retired in favour for <c>Module:add_host_key/4</c> which is the prefered API function.
+ The calling SSH application will still try the <c>add_host_key/3</c> if the call to <c>add_host_key/4</c> failed.
+ </p>
<p>Adds a host key to the set of trusted host keys.</p>
</desc>
</func>
@@ -94,6 +96,10 @@
</type>
<desc>
<p>Adds a host key to the set of trusted host keys.</p>
+ <p>This function is prefered to the old <c>Module:add_host_key/3</c> since it also uses
+ the peer host port number and may return an error message.</p>
+ <p>The OTP/SSH application first calls this function in the callback module, and then
+ the old <c>Module:add_host_key/3</c> for compatibilty.</p>
</desc>
</func>
@@ -115,7 +121,9 @@
<v>Result = boolean()</v>
</type>
<desc>
- <p>This function is retired in favour for <c>Module:is_host_key/5</c> which is the prefered API function.</p>
+ <p>This function is retired in favour for <c>Module:is_host_key/5</c> which is the prefered API function.
+ The calling SSH application will still try the <c>is_host_key/4</c> if the call to <c>is_host_key/5</c> failed.
+ </p>
<p>Checks if a host key is trusted.</p>
</desc>
</func>
@@ -155,8 +163,7 @@
</func>
<func>
- <name since="OTP R16B">Module:user_key(Algorithm, ConnectOptions) ->
- {ok, PrivateKey} | {error, Reason}</name>
+ <name since="OTP R16B">Module:user_key(Algorithm, ConnectOptions) -> Result</name>
<fsummary>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</fsummary>
<type>
<v>Algorithm = <seealso marker="ssh#type-pubkey_alg">ssh:pubkey_alg()</seealso></v>
@@ -164,14 +171,15 @@
<v>ConnectOptions = <seealso marker="#type-client_key_cb_options">client_key_cb_options()</seealso></v>
- <v>PrivateKey = <seealso marker="public_key:public_key#type-private_key">public_key:private_key()</seealso></v>
- <d>Private key of the user matching the <c>Algorithm</c>.</d>
- <v>Reason = term()</v>
+ <v>Result = {ok, <seealso marker="public_key:public_key#type-private_key">public_key:private_key()</seealso>} |
+ {ok, {ssh2_pubkey, PubKeyBlob :: binary()}} |
+ {error, term()}</v>
</type>
<desc>
- <p>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</p>
+ <p>Fetches the users <em>public key</em> matching the <c>Algorithm</c>. Some key callback modules
+ may return <c>{ssh2_pubkey, PubKeyBlob :: binary()}</c>.</p>
<note><p>The private key contains the public key.</p></note>
</desc>
diff --git a/lib/ssh/doc/src/ssh_file.xml b/lib/ssh/doc/src/ssh_file.xml
index 02807bb29f..6315bcbdbd 100644
--- a/lib/ssh/doc/src/ssh_file.xml
+++ b/lib/ssh/doc/src/ssh_file.xml
@@ -173,8 +173,8 @@
</p>
<p>To set it, set the
option <c>{key_cb, {ssh_file, [{optimize,TimeOrSpace}]}</c> in the call of
- <seealso marker="ssh:connect/3">"ssh:connect/3</seealso>,
- <seealso marker="ssh:daemon/2">ssh:daemon/2</seealso>
+ <seealso marker="ssh#connect-3">"ssh:connect/3</seealso>,
+ <seealso marker="ssh#daemon-2">ssh:daemon/2</seealso>
or similar function call that initiates an ssh connection.
</p>
</desc>
@@ -238,7 +238,12 @@
<desc>
<p><strong>Types and description</strong></p>
<p>See the api description in
- <seealso marker="ssh:ssh_client_key_api#Module:add_host_key-3">ssh_client_key_api, Module:add_host_key/3</seealso>.
+ <seealso marker="ssh:ssh_client_key_api#Module:add_host_key-4">ssh_client_key_api, Module:add_host_key/4</seealso>.
+ </p>
+ <marker id="add_host_key-3"/>
+ <p>Note that the alternative, the old
+ <seealso marker="ssh:ssh_client_key_api#Module:add_host_key-3">Module:add_host_key/3</seealso>
+ is no longer supported by <c>ssh_file</c>.
</p>
<p><strong>Option</strong></p>
<list>
@@ -259,6 +264,11 @@
<p>See the api description in
<seealso marker="ssh:ssh_client_key_api#Module:is_host_key-5">ssh_client_key_api, Module:is_host_key/5</seealso>.
</p>
+ <marker id="is_host_key-4"/>
+ <p>Note that the alternative, the old
+ <seealso marker="ssh:ssh_client_key_api#Module:is_host_key-4">Module:is_host_key/4</seealso>
+ is no longer supported by <c>ssh_file</c>.
+ </p>
<p><strong>Option</strong></p>
<list>
<item><seealso marker="#type-user_dir_common_option">user_dir</seealso></item>
diff --git a/lib/ssh/src/ssh_agent.erl b/lib/ssh/src/ssh_agent.erl
index 4d81937c79..4b3ce956e2 100644
--- a/lib/ssh/src/ssh_agent.erl
+++ b/lib/ssh/src/ssh_agent.erl
@@ -39,9 +39,10 @@
%% Old (compatibility) version
-spec add_host_key(string(),
public_key:public_key(),
- ssh_client_key_api:client_key_cb_options(call_ssh_file_option())
+ Options
) ->
- ok | {error, Error :: term()}.
+ ok | {error, Error :: term()} when
+ Options :: ssh_client_key_api:client_key_cb_options(call_ssh_file_option()).
add_host_key(Host, PublicKey, Options) ->
KeyCbOpts = proplists:get_value(key_cb_private, Options, []),
@@ -52,9 +53,10 @@ add_host_key(Host, PublicKey, Options) ->
-spec is_host_key(Key :: public_key:public_key(),
Host :: string(),
Algorithm :: ssh:pubkey_alg(),
- Options :: ssh_client_key_api:client_key_cb_options(call_ssh_file_option())
+ Options
) ->
- boolean().
+ boolean() when
+ Options :: ssh_client_key_api:client_key_cb_options(call_ssh_file_option()) .
is_host_key(Key, PeerName, Algorithm, Opts) ->
KeyCbOpts = proplists:get_value(key_cb_private, Opts, []),
@@ -62,12 +64,14 @@ is_host_key(Key, PeerName, Algorithm, Opts) ->
SshFileCb:is_host_key(Key, PeerName, Algorithm, Opts).
%% New version
--spec add_host_key(inet:ip_address() | inet:hostname() | [inet:ip_address() | inet:hostname()],
+-spec add_host_key(Host,
inet:port_number(),
public_key:public_key(),
- ssh_client_key_api:client_key_cb_options(call_ssh_file_option())
- ) ->
- ok | {error, Error :: term()}.
+ Options
+ ) -> Result when
+ Host :: inet:ip_address() | inet:hostname() | [inet:ip_address() | inet:hostname()],
+ Options :: ssh_client_key_api:client_key_cb_options(call_ssh_file_option()),
+ Result :: ok | {error, Error :: term()}.
add_host_key(Host, Port, PublicKey, Options) ->
KeyCbOpts = proplists:get_value(key_cb_private, Options, []),
@@ -76,12 +80,14 @@ add_host_key(Host, Port, PublicKey, Options) ->
-spec is_host_key(public_key:public_key(),
- inet:ip_address() | inet:hostname() | [inet:ip_address() | inet:hostname()],
+ Host,
inet:port_number(),
ssh:pubkey_alg(),
- ssh_client_key_api:client_key_cb_options(call_ssh_file_option())
+ Options
) ->
- boolean().
+ boolean() when
+ Host :: inet:ip_address() | inet:hostname() | [inet:ip_address() | inet:hostname()],
+ Options :: ssh_client_key_api:client_key_cb_options(call_ssh_file_option()).
is_host_key(Key, PeerName, Port, Algorithm, Opts) ->
KeyCbOpts = proplists:get_value(key_cb_private, Opts, []),
@@ -90,12 +96,12 @@ is_host_key(Key, PeerName, Port, Algorithm, Opts) ->
-spec user_key(Algorithm :: ssh:pubkey_alg(),
- Options :: ssh_client_key_api:client_key_cb_options(socket_path_option()
- | timeout_option())
- ) ->
- {ok, PrivateKey :: public_key:private_key()} |
- {ok, {ssh2_pubkey, PubKeyBlob :: binary()}} |
- {error, string()}.
+ Options) -> Result when
+ Result :: {ok, public_key:private_key()} |
+ {ok, {ssh2_pubkey, PubKeyBlob :: binary()}} |
+ {error, string()},
+ Options :: ssh_client_key_api:client_key_cb_options(socket_path_option()
+ | timeout_option()).
user_key(Algorithm, Opts) ->
KeyCbOpts = proplists:get_value(key_cb_private, Opts, []),
@@ -121,10 +127,11 @@ user_key(Algorithm, Opts) ->
-spec sign(binary(),
binary(),
- ssh_client_key_api:client_key_cb_options(socket_path_option()
- | timeout_option())
+ Options
) ->
- Blob :: binary().
+ Blob :: binary() when
+ Options :: ssh_client_key_api:client_key_cb_options(socket_path_option()
+ | timeout_option()).
sign(PubKeyBlob, SigData, Opts) ->
KeyCbOpts = proplists:get_value(key_cb_private, Opts, []),
diff --git a/lib/ssh/src/ssh_client_key_api.erl b/lib/ssh/src/ssh_client_key_api.erl
index c94cb05f79..c1b43e04eb 100644
--- a/lib/ssh/src/ssh_client_key_api.erl
+++ b/lib/ssh/src/ssh_client_key_api.erl
@@ -49,7 +49,7 @@
Algorithm :: ssh:pubkey_alg(),
Options :: client_key_cb_options(any())
) ->
- boolean() | {error, Error::term()} .
+ boolean() | {error, term()} .
%%% is_host_key/4 is an old variant which is kept for compatibility.
%%% Use is_host_key/5 in new programs.
@@ -72,7 +72,7 @@
-callback user_key(Algorithm :: ssh:pubkey_alg(),
Options :: client_key_cb_options(any())
) ->
- {ok, PrivateKey :: public_key:private_key()} |
+ {ok, public_key:private_key()} |
{ok, {ssh2_pubkey, PubKeyBlob :: binary()}} |
{error, string()}.
@@ -90,7 +90,7 @@
PublicKey :: public_key:public_key(),
Options :: client_key_cb_options(any())
) ->
- ok | {error, Error::term()}.
+ ok | {error, term()}.
%%% is_host_key/3 is an old variant which is kept for compatibility.
%%% Use is_host_key/4 in new constructions.
@@ -99,7 +99,7 @@
PublicKey :: public_key:public_key(),
Options :: client_key_cb_options(any())
) ->
- ok | {error, Error :: term()}.
+ ok | {error, term()}.
-optional_callbacks(
[add_host_key/3, add_host_key/4 % One in the pair be defined
diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl
index 45874ed1d3..bd8c276822 100644
--- a/lib/ssh/src/ssh_file.erl
+++ b/lib/ssh/src/ssh_file.erl
@@ -62,20 +62,19 @@
%%%
%%%---------------- SERVER API ------------------------------------
--spec host_key(ssh:pubkey_alg(),
- ssh_server_key_api:daemon_key_cb_options(none())
- ) ->
- {ok, PrivateKey :: public_key:private_key()} | {error, term()}.
+-spec host_key(Algorithm, Options) -> Result when
+ Algorithm :: ssh:pubkey_alg(),
+ Result :: {ok, public_key:private_key()} | {error, term()},
+ Options :: ssh_server_key_api:daemon_key_cb_options(none()).
host_key(Algorithm, Opts) ->
read_ssh_key_file(system, private, Algorithm, Opts).
%%%................................................................
--spec is_auth_key(Key :: public_key:public_key(),
- string(),
- ssh_server_key_api:daemon_key_cb_options(optimize_key_lookup())
- ) ->
- boolean().
+-spec is_auth_key(Key, User, Options) -> boolean() when
+ Key :: public_key:public_key(),
+ User :: string(),
+ Options :: ssh_server_key_api:daemon_key_cb_options(optimize_key_lookup()).
is_auth_key(Key0, User, Opts) ->
Dir = ssh_dir({remoteuser,User}, Opts),
@@ -88,26 +87,24 @@ is_auth_key(Key0, User, Opts) ->
lookup_auth_keys(KeyType, Key, filename:join(Dir,"authorized_keys2"), Opts).
%%%---------------- CLIENT API ------------------------------------
--spec user_key(ssh:pubkey_alg(),
- ssh_client_key_api:client_key_cb_options(none())
- ) ->
- {ok, PrivateKey :: public_key:private_key()} |
- {ok, {ssh2_pubkey, PubKeyBlob :: binary()}} |
- {error, string()}.
+-spec user_key(Algorithm, Options) -> Result when
+ Algorithm :: ssh:pubkey_alg(),
+ Result :: {ok, public_key:private_key()} |
+ {error, string()},
+ Options :: ssh_client_key_api:client_key_cb_options(none()).
user_key(Algorithm, Opts) ->
read_ssh_key_file(user, private, Algorithm, Opts).
%%%................................................................
%%% New style (with port number)
--spec is_host_key(Key :: public_key:public_key(),
- Host :: inet:ip_address() | inet:hostname()
- | [inet:ip_address() | inet:hostname()],
- inet:port_number(),
- ssh:pubkey_alg(),
- ssh_client_key_api:client_key_cb_options(optimize_key_lookup())
- ) ->
- boolean() | {error, Error::term()} .
+-spec is_host_key(Key, Host, Port, Algorithm, Options) -> Result when
+ Key :: public_key:public_key(),
+ Host :: inet:ip_address() | inet:hostname() | [inet:ip_address() | inet:hostname()],
+ Port :: inet:port_number(),
+ Algorithm :: ssh:pubkey_alg(),
+ Options :: ssh_client_key_api:client_key_cb_options(optimize_key_lookup()),
+ Result :: boolean() | {error, term()} .
is_host_key(Key0, Hosts0, Port, Algorithm, Opts) ->
Dir = ssh_dir(user, Opts),
@@ -119,13 +116,13 @@ is_host_key(Key0, Hosts0, Port, Algorithm, Opts) ->
lookup_host_keys(Hosts, KeyType, Key, File, Opts).
%%%----------------------------------------------------------------
--spec add_host_key(Host :: inet:ip_address() | inet:hostname()
- | [inet:ip_address() | inet:hostname()],
- inet:port_number(),
- public_key:public_key(),
- ssh_client_key_api:client_key_cb_options(none())
- ) ->
- ok | {error, Error::term()}.
+-spec add_host_key(Host, Port, Key, Options) -> Result when
+ Host :: inet:ip_address() | inet:hostname()
+ | [inet:ip_address() | inet:hostname()],
+ Port :: inet:port_number(),
+ Key :: public_key:public_key(),
+ Options :: ssh_client_key_api:client_key_cb_options(none()),
+ Result :: ok | {error, term()}.
add_host_key(Hosts0, Port, Key, Opts) ->
File = file_name(user, "known_hosts", Opts),