diff options
Diffstat (limited to 'lib/ssh')
-rw-r--r-- | lib/ssh/doc/src/notes.xml | 93 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh.xml | 48 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_client_channel.xml | 32 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_client_key_api.xml | 8 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_connection.xml | 36 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_file.xml | 12 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_server_channel.xml | 10 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_server_key_api.xml | 6 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftp.xml | 108 | ||||
-rw-r--r-- | lib/ssh/doc/src/ssh_sftpd.xml | 4 | ||||
-rw-r--r-- | lib/ssh/src/ssh.erl | 60 | ||||
-rw-r--r-- | lib/ssh/src/ssh_sftpd.erl | 7 | ||||
-rw-r--r-- | lib/ssh/test/ssh_basic_SUITE.erl | 22 | ||||
-rw-r--r-- | lib/ssh/test/ssh_compat_SUITE.erl | 18 | ||||
-rw-r--r-- | lib/ssh/test/ssh_connection_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/ssh/test/ssh_engine_SUITE.erl | 11 | ||||
-rw-r--r-- | lib/ssh/vsn.mk | 2 |
17 files changed, 319 insertions, 162 deletions
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 1012c80fb1..0bc4baf5eb 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -30,6 +30,84 @@ <file>notes.xml</file> </header> +<section><title>Ssh 4.7.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed port leakage if a ssh:daemon call failed.</p> + <p> + Own Id: OTP-15397 Aux Id: ERL-801 </p> + </item> + </list> + </section> + +</section> + +<section><title>Ssh 4.7.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Incompatibility with newer OpenSSH fixed. Previously + versions 7.8 and later could cause Erlang SSH to exit.</p> + <p> + Own Id: OTP-15413</p> + </item> + <item> + <p> + The '<c>exec</c>' option for ssh daemons had wrong format + in the documentation.</p> + <p> + Own Id: OTP-15416</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Added public key methods ssh-ed25519 and ssh-ed448.</p> + <p> + Requires OpenSSL 1.1.1 or higher as cryptolib under the + OTP application <c>crypto</c>.</p> + <p> + Own Id: OTP-15094 Aux Id: OTP-15419 </p> + </item> + <item> + <p> + The SSH property tests are now adapted to the PropEr + testing tool.</p> + <p> + Own Id: OTP-15312</p> + </item> + <item> + <p> + The term "user" was not documented in the SSH app. A new + chapter with terminology is added to the User's Manual + where the term "user" is defined.</p> + <p> + A reference manual page about the module <c>ssh_file</c> + is also added. This is the default callback module for + user's keys, host keys etc.</p> + <p> + Own Id: OTP-15314</p> + </item> + <item> + <p> + Host and user key checking is made more robust.</p> + <p> + Own Id: OTP-15424</p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 4.7.1</title> <section><title>Improvements and New Features</title> @@ -230,6 +308,21 @@ </section> </section> +<section><title>Ssh 4.6.9.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed port leakage if a ssh:daemon call failed.</p> + <p> + Own Id: OTP-15397 Aux Id: ERL-801 </p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 4.6.9.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml index fcf79969d3..3fd6eae423 100644 --- a/lib/ssh/doc/src/ssh.xml +++ b/lib/ssh/doc/src/ssh.xml @@ -28,7 +28,7 @@ <date>2007-10-06</date> <rev></rev> </header> - <module>ssh</module> + <module since="">ssh</module> <modulesummary>Main API of the ssh application</modulesummary> <description> <p>This is the interface module for the <c>SSH</c> application. @@ -1059,17 +1059,17 @@ <!-- CLOSE/1 --> <func> - <name name="close" arity="1"/> + <name name="close" arity="1" since=""/> <fsummary>Closes an SSH connection.</fsummary> <desc><p>Closes an SSH connection.</p></desc> </func> <!-- CONNECT/2 etc --> <func> - <name>connect(Host, Port, Options) -> Result </name> - <name>connect(Host, Port, Options, NegotiationTimeout) -> Result </name> - <name>connect(TcpSocket, Options) -> Result</name> - <name>connect(TcpSocket, Options, NegotiationTimeout) -> Result</name> + <name since="">connect(Host, Port, Options) -> Result </name> + <name since="">connect(Host, Port, Options, NegotiationTimeout) -> Result </name> + <name since="OTP 19.0">connect(TcpSocket, Options) -> Result</name> + <name since="">connect(TcpSocket, Options, NegotiationTimeout) -> Result</name> <fsummary>Connects to an SSH server.</fsummary> <type> <v>Host = <seealso marker="#type-host">host()</seealso></v> @@ -1098,7 +1098,7 @@ <!-- CONNECTION_INFO/1, CONNECTION_INFO/2 --> <func> - <name name="connection_info" arity="2"/> + <name name="connection_info" arity="2" since=""/> <fsummary>Retrieves information about a connection.</fsummary> <desc> <p>Retrieves information about a connection. The list <c>Keys</c> defines which information that @@ -1108,9 +1108,9 @@ <!-- DEAMON/1,2,3 --> <func> - <name>daemon(Port | TcpSocket) -> Result</name> - <name>daemon(Port | TcpSocket, Options) -> Result</name> - <name>daemon(HostAddress, Port, Options) -> Result</name> + <name since="">daemon(Port | TcpSocket) -> Result</name> + <name since="">daemon(Port | TcpSocket, Options) -> Result</name> + <name since="">daemon(HostAddress, Port, Options) -> Result</name> <fsummary>Starts a server listening for SSH connections.</fsummary> <type> <v>Port = integer()</v> @@ -1154,7 +1154,7 @@ <!-- DAEMON_INFO/1 --> <func> - <name name="daemon_info" arity="1"/> + <name name="daemon_info" arity="1" since="OTP 19.0"/> <fsummary>Get info about a daemon</fsummary> <desc> <p>Returns a key-value list with information about the daemon.</p> @@ -1164,7 +1164,7 @@ <!-- DEFAULT_ALGORITHMS/0 --> <func> - <name name="default_algorithms" arity="0"/> + <name name="default_algorithms" arity="0" since="OTP 18.0"/> <fsummary>Get a list declaring the supported algorithms</fsummary> <desc> <p>Returns a key-value list, where the keys are the different types of algorithms and the values are the @@ -1176,9 +1176,9 @@ <!-- SHELL/1,2,3 --> <func> - <name>shell(Host | TcpSocket) -> Result </name> - <name>shell(Host | TcpSocket, Options) -> Result </name> - <name>shell(Host, Port, Options) -> Result </name> + <name since="">shell(Host | TcpSocket) -> Result </name> + <name since="">shell(Host | TcpSocket, Options) -> Result </name> + <name since="">shell(Host, Port, Options) -> Result </name> <fsummary>Starts an interactive shell on a remote SSH server.</fsummary> <type> <v>Host = <seealso marker="#type-host">host()</seealso></v> @@ -1203,8 +1203,8 @@ </func> <func> - <name name="start" arity="0"/> - <name name="start" arity="1"/> + <name name="start" arity="0" since=""/> + <name name="start" arity="1" since=""/> <fsummary>Starts the SSH application.</fsummary> <desc> <p>Utility function that starts the applications <c>crypto</c>, <c>public_key</c>, @@ -1215,7 +1215,7 @@ </func> <func> - <name name="stop" arity="0"/> + <name name="stop" arity="0" since=""/> <fsummary>Stops the <c>ssh</c> application.</fsummary> <desc> <p>Stops the <c>ssh</c> application. @@ -1225,9 +1225,9 @@ </func> <func> - <name name="stop_daemon" arity="1"/> - <name name="stop_daemon" arity="2"/> - <name name="stop_daemon" arity="3"/> + <name name="stop_daemon" arity="1" since=""/> + <name name="stop_daemon" arity="2" since=""/> + <name name="stop_daemon" arity="3" since="OTP 21.0"/> <fsummary>Stops the listener and all connections started by the listener.</fsummary> <desc> <p>Stops the listener and all connections started by the listener.</p> @@ -1235,9 +1235,9 @@ </func> <func> - <name name="stop_listener" arity="1"/> - <name name="stop_listener" arity="2"/> - <name name="stop_listener" arity="3"/> + <name name="stop_listener" arity="1" since=""/> + <name name="stop_listener" arity="2" since=""/> + <name name="stop_listener" arity="3" since="OTP 21.0"/> <fsummary>Stops the listener, but leaves existing connections started by the listener operational.</fsummary> <desc> <p>Stops the listener, but leaves existing connections started by the listener operational.</p> diff --git a/lib/ssh/doc/src/ssh_client_channel.xml b/lib/ssh/doc/src/ssh_client_channel.xml index 9be4007c68..cd28b95fd3 100644 --- a/lib/ssh/doc/src/ssh_client_channel.xml +++ b/lib/ssh/doc/src/ssh_client_channel.xml @@ -29,7 +29,7 @@ <date></date> <rev></rev> </header> - <module>ssh_client_channel</module> + <module since="OTP 21.0">ssh_client_channel</module> <modulesummary>-behaviour(ssh_client_channel). (Replaces ssh_channel) </modulesummary> <description> @@ -68,8 +68,8 @@ <funcs> <func> - <name>call(ChannelRef, Msg) -></name> - <name>call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason}</name> + <name since="OTP 21.0">call(ChannelRef, Msg) -></name> + <name since="OTP 21.0">call(ChannelRef, Msg, Timeout) -> Reply | {error, Reason}</name> <fsummary>Makes a synchronous call to a channel.</fsummary> <type> <v>ChannelRef = pid() </v> @@ -92,7 +92,7 @@ </func> <func> - <name>cast(ChannelRef, Msg) -> ok </name> + <name since="OTP 21.0">cast(ChannelRef, Msg) -> ok </name> <fsummary>Sends an asynchronous message to the channel ChannelRef and returns ok.</fsummary> <type> @@ -111,7 +111,7 @@ </func> <func> - <name>enter_loop(State) -> _ </name> + <name since="OTP 21.0">enter_loop(State) -> _ </name> <fsummary>Makes an existing process an ssh_client_channel (replaces ssh_channel) process.</fsummary> <type> <v>State = term()</v> @@ -131,7 +131,7 @@ </func> <func> - <name>init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name> + <name since="OTP 21.0">init(Options) -> {ok, State} | {ok, State, Timeout} | {stop, Reason} </name> <fsummary>Initiates an <c>ssh_client_channel</c> process.</fsummary> <type> <v>Options = [{Option, Value}]</v> @@ -173,7 +173,7 @@ </func> <func> - <name>reply(Client, Reply) -> _</name> + <name since="OTP 21.0">reply(Client, Reply) -> _</name> <fsummary>Sends a reply to a client.</fsummary> <type> <v>Client = opaque()</v> @@ -193,8 +193,8 @@ </func> <func> - <name>start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name> - <name>start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> + <name since="OTP 21.0">start(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> </name> + <name since="OTP 21.0">start_link(SshConnection, ChannelId, ChannelCb, CbInitArgs) -> {ok, ChannelRef} | {error, Reason}</name> <fsummary>Starts a process that handles an SSH channel.</fsummary> <type> @@ -244,7 +244,7 @@ <funcs> <func> - <name>Module:code_change(OldVsn, State, Extra) -> {ok, + <name since="OTP 21.0">Module:code_change(OldVsn, State, Extra) -> {ok, NewState}</name> <fsummary>Converts process state when code is changed.</fsummary> <type> @@ -287,7 +287,7 @@ </func> <func> - <name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} | + <name since="OTP 21.0">Module:init(Args) -> {ok, State} | {ok, State, timeout()} | {stop, Reason}</name> <fsummary>Makes necessary initializations and returns the initial channel state if the initializations succeed.</fsummary> @@ -307,7 +307,7 @@ </func> <func> - <name>Module:handle_call(Msg, From, State) -> Result</name> + <name since="OTP 21.0">Module:handle_call(Msg, From, State) -> Result</name> <fsummary>Handles messages sent by calling <c>call/[2,3]</c>.</fsummary> <type> @@ -334,7 +334,7 @@ </func> <func> - <name>Module:handle_cast(Msg, State) -> Result</name> + <name since="OTP 21.0">Module:handle_cast(Msg, State) -> Result</name> <fsummary>Handles messages sent by calling <c>cast/2</c>.</fsummary> <type> @@ -355,7 +355,7 @@ </func> <func> - <name>Module:handle_msg(Msg, State) -> {ok, State} | + <name since="OTP 21.0">Module:handle_msg(Msg, State) -> {ok, State} | {stop, ChannelId, State}</name> <fsummary>Handles other messages than SSH connection protocol, @@ -389,7 +389,7 @@ </func> <func> - <name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, + <name since="OTP 21.0">Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, ChannelId, State}</name> <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary> <type> @@ -416,7 +416,7 @@ </func> <func> - <name>Module:terminate(Reason, State) -> _</name> + <name since="OTP 21.0">Module:terminate(Reason, State) -> _</name> <fsummary>Does cleaning up before channel process termination. </fsummary> <type> diff --git a/lib/ssh/doc/src/ssh_client_key_api.xml b/lib/ssh/doc/src/ssh_client_key_api.xml index bc77756147..9f2f3013e5 100644 --- a/lib/ssh/doc/src/ssh_client_key_api.xml +++ b/lib/ssh/doc/src/ssh_client_key_api.xml @@ -29,7 +29,7 @@ <date></date> <rev></rev> </header> - <module>ssh_client_key_api</module> + <module since="OTP R16B">ssh_client_key_api</module> <modulesummary> -behaviour(ssh_client_key_api). </modulesummary> @@ -86,7 +86,7 @@ <funcs> <func> - <name>Module:add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name> + <name since="OTP R16B">Module:add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name> <fsummary>Adds a host key to the set of trusted host keys.</fsummary> <type> <v>HostNames = string()</v> @@ -103,7 +103,7 @@ </func> <func> - <name>Module:is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name> + <name since="OTP R16B">Module:is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name> <fsummary>Checks if a host key is trusted.</fsummary> <type> <v>Key = <seealso marker="public_key:public_key#type-public_key">public_key:public_key()</seealso></v> @@ -125,7 +125,7 @@ </func> <func> - <name>Module:user_key(Algorithm, ConnectOptions) -> + <name since="OTP R16B">Module:user_key(Algorithm, ConnectOptions) -> {ok, PrivateKey} | {error, Reason}</name> <fsummary>Fetches the users <em>public key</em> matching the <c>Algorithm</c>.</fsummary> <type> diff --git a/lib/ssh/doc/src/ssh_connection.xml b/lib/ssh/doc/src/ssh_connection.xml index 8e1cf156a8..2a701929f6 100644 --- a/lib/ssh/doc/src/ssh_connection.xml +++ b/lib/ssh/doc/src/ssh_connection.xml @@ -30,7 +30,7 @@ <date></date> <rev></rev> </header> - <module>ssh_connection</module> + <module since="">ssh_connection</module> <modulesummary> This module provides API functions to send SSH Connection Protocol events to the other side of an SSH channel. @@ -201,7 +201,7 @@ <funcs> <func> - <name>adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok</name> + <name since="">adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok</name> <fsummary>Adjusts the SSH flow control window.</fsummary> <type> <v>ConnectionRef = connection_ref()</v> @@ -221,7 +221,7 @@ </func> <func> - <name>close(ConnectionRef, ChannelId) -> ok</name> + <name since="">close(ConnectionRef, ChannelId) -> ok</name> <fsummary>Sends a close message on the channel <c>ChannelId</c>.</fsummary> <type> <v>ConnectionRef = connection_ref()</v> @@ -240,7 +240,7 @@ </func> <func> - <name>exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | + <name since="">exec(ConnectionRef, ChannelId, Command, TimeOut) -> ssh_request_status() | {error, reason()}</name> <fsummary>Requests that the server starts the execution of the given command.</fsummary> <type> @@ -284,7 +284,7 @@ </func> <func> - <name>exit_status(ConnectionRef, ChannelId, Status) -> ok</name> + <name since="">exit_status(ConnectionRef, ChannelId, Status) -> ok</name> <fsummary>Sends the exit status of a command to the client.</fsummary> <type> <v>ConnectionRef = connection_ref() </v> @@ -298,8 +298,8 @@ </func> <func> - <name>ptty_alloc(ConnectionRef, ChannelId, Options) -></name> - <name>ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | + <name since="OTP 17.5">ptty_alloc(ConnectionRef, ChannelId, Options) -></name> + <name since="OTP 17.4">ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> > ssh_request_status() | {error, reason()}</name> <fsummary>Sends an SSH Connection Protocol <c>pty_req</c>, to allocate a pseudo-terminal.</fsummary> @@ -339,7 +339,7 @@ </func> <func> - <name>reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name> + <name since="">reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok</name> <fsummary>Sends status replies to requests that want such replies.</fsummary> <type> <v>ConnectionRef = connection_ref()</v> @@ -357,10 +357,10 @@ </func> <func> - <name>send(ConnectionRef, ChannelId, Data) -></name> - <name>send(ConnectionRef, ChannelId, Data, Timeout) -></name> - <name>send(ConnectionRef, ChannelId, Type, Data) -></name> - <name>send(ConnectionRef, ChannelId, Type, Data, TimeOut) -> + <name since="">send(ConnectionRef, ChannelId, Data) -></name> + <name since="">send(ConnectionRef, ChannelId, Data, Timeout) -></name> + <name since="">send(ConnectionRef, ChannelId, Type, Data) -></name> + <name since="">send(ConnectionRef, ChannelId, Type, Data, TimeOut) -> ok | {error, timeout} | {error, closed}</name> <fsummary>Sends channel data.</fsummary> <type> @@ -380,7 +380,7 @@ </func> <func> - <name>send_eof(ConnectionRef, ChannelId) -> ok | {error, closed}</name> + <name since="">send_eof(ConnectionRef, ChannelId) -> ok | {error, closed}</name> <fsummary>Sends EOF on channel <c>ChannelId</c>.</fsummary> <type> <v>ConnectionRef = connection_ref()</v> @@ -392,8 +392,8 @@ </func> <func> - <name>session_channel(ConnectionRef, Timeout) -></name> - <name>session_channel(ConnectionRef, InitialWindowSize, + <name since="">session_channel(ConnectionRef, Timeout) -></name> + <name since="">session_channel(ConnectionRef, InitialWindowSize, MaxPacketSize, Timeout) -> {ok, channel_id()} | {error, reason()}</name> <fsummary>Opens a channel for an SSH session.</fsummary> <type> @@ -410,7 +410,7 @@ </func> <func> - <name>setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | + <name since="">setenv(ConnectionRef, ChannelId, Var, Value, TimeOut) -> ssh_request_status() | {error, reason()}</name> <fsummary>Environment variables can be passed to the shell/command to be started later.</fsummary> @@ -428,7 +428,7 @@ </func> <func> - <name>shell(ConnectionRef, ChannelId) -> ok | failure | {error, closed} + <name since="">shell(ConnectionRef, ChannelId) -> ok | failure | {error, closed} </name> <fsummary>Requests that the user default shell (typically defined in /etc/passwd in Unix systems) is to be executed at the server end.</fsummary> @@ -448,7 +448,7 @@ </func> <func> - <name>subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | + <name since="">subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> ssh_request_status() | {error, reason()}</name> <fsummary>Requests to execute a predefined subsystem on the server.</fsummary> <type> diff --git a/lib/ssh/doc/src/ssh_file.xml b/lib/ssh/doc/src/ssh_file.xml index 6681d9c306..f1fef09083 100644 --- a/lib/ssh/doc/src/ssh_file.xml +++ b/lib/ssh/doc/src/ssh_file.xml @@ -28,7 +28,7 @@ <date></date> <rev></rev> </header> - <module>ssh_file</module> + <module since="OTP 21.2">ssh_file</module> <modulesummary>Default callback module for the client's and server's database operations in the ssh application</modulesummary> <description> <p>This module is the default callback handler for the client's and the server's user and host "database" operations. @@ -169,7 +169,7 @@ <funcs> <func> - <name>host_key(Algorithm, DaemonOptions) -> {ok, Key} | {error, Reason}</name> + <name since="OTP 21.2">host_key(Algorithm, DaemonOptions) -> {ok, Key} | {error, Reason}</name> <fsummary></fsummary> <desc> <p><strong>Types and description</strong></p> @@ -195,7 +195,7 @@ </func> <func> - <name>is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name> + <name since="OTP 21.2">is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name> <fsummary></fsummary> <desc> <p><strong>Types and description</strong></p> @@ -216,7 +216,7 @@ </func> <func> - <name>add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name> + <name since="OTP 21.2">add_host_key(HostNames, PublicHostKey, ConnectOptions) -> ok | {error, Reason}</name> <fsummary></fsummary> <desc> <p><strong>Types and description</strong></p> @@ -235,7 +235,7 @@ </func> <func> - <name>is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name> + <name since="OTP 21.2">is_host_key(Key, Host, Algorithm, ConnectOptions) -> Result</name> <fsummary></fsummary> <desc> <p><strong>Types and description</strong></p> @@ -254,7 +254,7 @@ </func> <func> - <name>user_key(Algorithm, ConnectOptions) -> {ok, PrivateKey} | {error, Reason}</name> + <name since="OTP 21.2">user_key(Algorithm, ConnectOptions) -> {ok, PrivateKey} | {error, Reason}</name> <fsummary></fsummary> <desc> <p><strong>Types and description</strong></p> diff --git a/lib/ssh/doc/src/ssh_server_channel.xml b/lib/ssh/doc/src/ssh_server_channel.xml index 31ba9a3231..a4e18bbfbf 100644 --- a/lib/ssh/doc/src/ssh_server_channel.xml +++ b/lib/ssh/doc/src/ssh_server_channel.xml @@ -29,7 +29,7 @@ <date></date> <rev></rev> </header> - <module>ssh_server_channel</module> + <module since="OTP 21.0">ssh_server_channel</module> <modulesummary>-behaviour(ssh_server_channel). (Replaces ssh_daemon_channel) </modulesummary> <description> @@ -70,7 +70,7 @@ <funcs> <func> - <name>Module:init(Args) -> {ok, State} | {ok, State, timeout()} | + <name since="OTP 21.0">Module:init(Args) -> {ok, State} | {ok, State, timeout()} | {stop, Reason}</name> <fsummary>Makes necessary initializations and returns the initial channel state if the initializations succeed.</fsummary> @@ -93,7 +93,7 @@ </func> <func> - <name>Module:handle_msg(Msg, State) -> {ok, State} | + <name since="OTP 21.0">Module:handle_msg(Msg, State) -> {ok, State} | {stop, ChannelId, State}</name> <fsummary>Handles other messages than SSH connection protocol, @@ -125,7 +125,7 @@ </func> <func> - <name>Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, + <name since="OTP 21.0">Module:handle_ssh_msg(Msg, State) -> {ok, State} | {stop, ChannelId, State}</name> <fsummary>Handles <c>ssh</c> connection protocol messages.</fsummary> <type> @@ -152,7 +152,7 @@ </func> <func> - <name>Module:terminate(Reason, State) -> _</name> + <name since="OTP 21.0">Module:terminate(Reason, State) -> _</name> <fsummary>Does cleaning up before channel process termination. </fsummary> <type> diff --git a/lib/ssh/doc/src/ssh_server_key_api.xml b/lib/ssh/doc/src/ssh_server_key_api.xml index e2a31bd5f5..013a788a4a 100644 --- a/lib/ssh/doc/src/ssh_server_key_api.xml +++ b/lib/ssh/doc/src/ssh_server_key_api.xml @@ -29,7 +29,7 @@ <date></date> <rev></rev> </header> - <module>ssh_server_key_api</module> + <module since="OTP R16B">ssh_server_key_api</module> <modulesummary> -behaviour(ssh_server_key_api). </modulesummary> @@ -87,7 +87,7 @@ <funcs> <func> - <name>Module:host_key(Algorithm, DaemonOptions) -> + <name since="OTP R16B">Module:host_key(Algorithm, DaemonOptions) -> {ok, Key} | {error, Reason}</name> <fsummary>Fetches the host’s private key.</fsummary> <type> @@ -111,7 +111,7 @@ </func> <func> - <name>Module:is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name> + <name since="OTP R16B">Module:is_auth_key(PublicUserKey, User, DaemonOptions) -> Result</name> <fsummary>Checks if the user key is authorized.</fsummary> <type> <v>PublicUserKey = <seealso marker="public_key:public_key#type-public_key">public_key:public_key()</seealso></v> diff --git a/lib/ssh/doc/src/ssh_sftp.xml b/lib/ssh/doc/src/ssh_sftp.xml index 8c105147d6..c89092798d 100644 --- a/lib/ssh/doc/src/ssh_sftp.xml +++ b/lib/ssh/doc/src/ssh_sftp.xml @@ -29,7 +29,7 @@ <rev></rev> <file>ssh_sftp.sgml</file> </header> - <module>ssh_sftp</module> + <module since="">ssh_sftp</module> <modulesummary>SFTP client.</modulesummary> <description> <p>This module implements an SSH FTP (SFTP) client. SFTP is a @@ -82,7 +82,7 @@ <funcs> <func> - <name>apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, reason()}</name> + <name since="">apread(ChannelPid, Handle, Position, Len) -> {async, N} | {error, reason()}</name> <fsummary>Reads asynchronously from an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -98,7 +98,7 @@ </func> <func> - <name>apwrite(ChannelPid, Handle, Position, Data) -> {async, N} | {error, reason()}</name> + <name since="">apwrite(ChannelPid, Handle, Position, Data) -> {async, N} | {error, reason()}</name> <fsummary>Writes asynchronously to an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -116,7 +116,7 @@ </func> <func> - <name>aread(ChannelPid, Handle, Len) -> {async, N} | {error, reason()}</name> + <name since="">aread(ChannelPid, Handle, Len) -> {async, N} | {error, reason()}</name> <fsummary>Reads asynchronously from an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -137,7 +137,7 @@ </func> <func> - <name>awrite(ChannelPid, Handle, Data) -> {async, N} | {error, reason()}</name> + <name since="">awrite(ChannelPid, Handle, Data) -> {async, N} | {error, reason()}</name> <fsummary>Writes asynchronously to an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -159,8 +159,8 @@ </func> <func> - <name>close(ChannelPid, Handle) -></name> - <name>close(ChannelPid, Handle, Timeout) -> ok | {error, reason()}</name> + <name since="">close(ChannelPid, Handle) -></name> + <name since="">close(ChannelPid, Handle, Timeout) -> ok | {error, reason()}</name> <fsummary>Closes an open handle.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -173,8 +173,8 @@ </func> <func> - <name>delete(ChannelPid, Name) -></name> - <name>delete(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> + <name since="">delete(ChannelPid, Name) -></name> + <name since="">delete(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> <fsummary>Deletes a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -188,8 +188,8 @@ </func> <func> - <name>del_dir(ChannelPid, Name) -></name> - <name>del_dir(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> + <name since="">del_dir(ChannelPid, Name) -></name> + <name since="">del_dir(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> <fsummary>Deletes an empty directory.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -204,8 +204,8 @@ </func> <func> - <name>list_dir(ChannelPid, Path) -></name> - <name>list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, reason()}</name> + <name since="">list_dir(ChannelPid, Path) -></name> + <name since="">list_dir(ChannelPid, Path, Timeout) -> {ok, Filenames} | {error, reason()}</name> <fsummary>Lists the directory.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -221,8 +221,8 @@ </func> <func> - <name>make_dir(ChannelPid, Name) -></name> - <name>make_dir(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> + <name since="">make_dir(ChannelPid, Name) -></name> + <name since="">make_dir(ChannelPid, Name, Timeout) -> ok | {error, reason()}</name> <fsummary>Creates a directory.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -237,8 +237,8 @@ </func> <func> - <name>make_symlink(ChannelPid, Name, Target) -></name> - <name>make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, reason()}</name> + <name since="">make_symlink(ChannelPid, Name, Target) -></name> + <name since="">make_symlink(ChannelPid, Name, Target, Timeout) -> ok | {error, reason()}</name> <fsummary>Creates a symbolic link.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -253,8 +253,8 @@ </func> <func> - <name>open(ChannelPid, File, Mode) -></name> - <name>open(ChannelPid, File, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> + <name since="">open(ChannelPid, File, Mode) -></name> + <name since="">open(ChannelPid, File, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> <fsummary>Opens a file and returns a handle.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -270,8 +270,8 @@ </desc> </func> <func> - <name>opendir(ChannelPid, Path) -></name> - <name>opendir(ChannelPid, Path, Timeout) -> {ok, Handle} | {error, reason()}</name> + <name since="">opendir(ChannelPid, Path) -></name> + <name since="">opendir(ChannelPid, Path, Timeout) -> {ok, Handle} | {error, reason()}</name> <fsummary>Opens a directory and returns a handle.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -285,8 +285,8 @@ </func> <func> - <name>open_tar(ChannelPid, Path, Mode) -></name> - <name>open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> + <name since="OTP 17.4">open_tar(ChannelPid, Path, Mode) -></name> + <name since="OTP 17.4">open_tar(ChannelPid, Path, Mode, Timeout) -> {ok, Handle} | {error, reason()}</name> <fsummary>Opens a tar file on the server to which <c>ChannelPid</c> is connected and returns a handle.</fsummary> <type> @@ -339,8 +339,8 @@ </func> <func> - <name>position(ChannelPid, Handle, Location) -></name> - <name>position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition | {error, reason()}</name> + <name since="">position(ChannelPid, Handle, Location) -></name> + <name since="">position(ChannelPid, Handle, Location, Timeout) -> {ok, NewPosition | {error, reason()}</name> <fsummary>Sets the file position of a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -384,8 +384,8 @@ </func> <func> - <name>pread(ChannelPid, Handle, Position, Len) -></name> - <name>pread(ChannelPid, Handle, Position, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</name> + <name since="">pread(ChannelPid, Handle, Position, Len) -></name> + <name since="">pread(ChannelPid, Handle, Position, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</name> <fsummary>Reads from an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -402,8 +402,8 @@ </func> <func> - <name>pwrite(ChannelPid, Handle, Position, Data) -> ok</name> - <name>pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, reason()}</name> + <name since="">pwrite(ChannelPid, Handle, Position, Data) -> ok</name> + <name since="">pwrite(ChannelPid, Handle, Position, Data, Timeout) -> ok | {error, reason()}</name> <fsummary>Writes to an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -419,8 +419,8 @@ </func> <func> - <name>read(ChannelPid, Handle, Len) -></name> - <name>read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</name> + <name since="">read(ChannelPid, Handle, Len) -></name> + <name since="">read(ChannelPid, Handle, Len, Timeout) -> {ok, Data} | eof | {error, reason()}</name> <fsummary>Reads from an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -441,8 +441,8 @@ </func> <func> - <name>read_file(ChannelPid, File) -></name> - <name>read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, reason()}</name> + <name since="">read_file(ChannelPid, File) -></name> + <name since="">read_file(ChannelPid, File, Timeout) -> {ok, Data} | {error, reason()}</name> <fsummary>Reads a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -456,8 +456,8 @@ </func> <func> - <name>read_file_info(ChannelPid, Name) -></name> - <name>read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, reason()}</name> + <name since="">read_file_info(ChannelPid, Name) -></name> + <name since="">read_file_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, reason()}</name> <fsummary>Gets information about a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -481,8 +481,8 @@ </func> <func> - <name>read_link(ChannelPid, Name) -></name> - <name>read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, reason()}</name> + <name since="">read_link(ChannelPid, Name) -></name> + <name since="">read_link(ChannelPid, Name, Timeout) -> {ok, Target} | {error, reason()}</name> <fsummary>Reads symbolic link.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -496,8 +496,8 @@ </func> <func> - <name>read_link_info(ChannelPid, Name) -> {ok, FileInfo} | {error, reason()}</name> - <name>read_link_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, reason()}</name> + <name since="">read_link_info(ChannelPid, Name) -> {ok, FileInfo} | {error, reason()}</name> + <name since="">read_link_info(ChannelPid, Name, Timeout) -> {ok, FileInfo} | {error, reason()}</name> <fsummary>Gets information about a symbolic link.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -517,8 +517,8 @@ </func> <func> - <name>rename(ChannelPid, OldName, NewName) -> </name> - <name>rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, reason()}</name> + <name since="">rename(ChannelPid, OldName, NewName) -> </name> + <name since="">rename(ChannelPid, OldName, NewName, Timeout) -> ok | {error, reason()}</name> <fsummary>Renames a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -534,16 +534,16 @@ </func> <func> - <name>start_channel(ConnectionRef) -></name> - <name>start_channel(ConnectionRef, Options) -> + <name since="">start_channel(ConnectionRef) -></name> + <name since="">start_channel(ConnectionRef, Options) -> {ok, Pid} | {error, reason()|term()}</name> - <name>start_channel(Host, Options) -></name> - <name>start_channel(Host, Port, Options) -> + <name since="">start_channel(Host, Options) -></name> + <name since="">start_channel(Host, Port, Options) -> {ok, Pid, ConnectionRef} | {error, reason()|term()}</name> - <name>start_channel(TcpSocket) -></name> - <name>start_channel(TcpSocket, Options) -> + <name since="">start_channel(TcpSocket) -></name> + <name since="">start_channel(TcpSocket, Options) -> {ok, Pid, ConnectionRef} | {error, reason()|term()}</name> <fsummary>Starts an SFTP client.</fsummary> @@ -594,7 +594,7 @@ </func> <func> - <name>stop_channel(ChannelPid) -> ok</name> + <name since="">stop_channel(ChannelPid) -> ok</name> <fsummary>Stops the SFTP client channel.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -606,8 +606,8 @@ </func> <func> - <name>write(ChannelPid, Handle, Data) -></name> - <name>write(ChannelPid, Handle, Data, Timeout) -> ok | {error, reason()}</name> + <name since="">write(ChannelPid, Handle, Data) -></name> + <name since="">write(ChannelPid, Handle, Data, Timeout) -> ok | {error, reason()}</name> <fsummary>Writes to an open file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -625,8 +625,8 @@ </func> <func> - <name>write_file(ChannelPid, File, Iolist) -></name> - <name>write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, reason()}</name> + <name since="">write_file(ChannelPid, File, Iolist) -></name> + <name since="">write_file(ChannelPid, File, Iolist, Timeout) -> ok | {error, reason()}</name> <fsummary>Writes a file.</fsummary> <type> <v>ChannelPid = pid()</v> @@ -641,8 +641,8 @@ </func> <func> - <name>write_file_info(ChannelPid, Name, Info) -></name> - <name>write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, reason()}</name> + <name since="">write_file_info(ChannelPid, Name, Info) -></name> + <name since="">write_file_info(ChannelPid, Name, Info, Timeout) -> ok | {error, reason()}</name> <fsummary>Writes information for a file.</fsummary> <type> <v>ChannelPid = pid()</v> diff --git a/lib/ssh/doc/src/ssh_sftpd.xml b/lib/ssh/doc/src/ssh_sftpd.xml index 3b34150e98..ee72784add 100644 --- a/lib/ssh/doc/src/ssh_sftpd.xml +++ b/lib/ssh/doc/src/ssh_sftpd.xml @@ -29,7 +29,7 @@ <rev></rev> <file>ssh_sftpd.sgml</file> </header> - <module>ssh_sftpd</module> + <module since="">ssh_sftpd</module> <modulesummary>Specifies the channel process to handle an SFTP subsystem.</modulesummary> <description> <p>Specifies a channel process to handle an SFTP subsystem.</p> @@ -51,7 +51,7 @@ </section> <funcs> <func> - <name>subsystem_spec(Options) -> subsystem_spec()</name> + <name since="">subsystem_spec(Options) -> subsystem_spec()</name> <fsummary>Returns the subsystem specification that allows an SSH daemon to handle the subsystem "sftp".</fsummary> <type> <v>Options = [{Option, Value}]</v> diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index 086fa6e5f8..9281bf84a7 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -270,25 +270,38 @@ daemon(Host0, Port0, UserOptions0) when 0 =< Port0, Port0 =< 65535, try {Host1, UserOptions} = handle_daemon_args(Host0, UserOptions0), #{} = Options0 = ssh_options:handle_options(server, UserOptions), - - {{Host,Port}, ListenSocket} = - open_listen_socket(Host1, Port0, Options0), - - %% Now Host,Port is what to use for the supervisor to register its name, - %% and ListenSocket is for listening on connections. But it is still owned - %% by self()... - - finalize_start(Host, Port, ?GET_OPT(profile, Options0), - ?PUT_INTERNAL_OPT({lsocket,{ListenSocket,self()}}, Options0), - fun(Opts, Result) -> - {_, Callback, _} = ?GET_OPT(transport, Opts), - receive - {request_control, ListenSocket, ReqPid} -> - ok = Callback:controlling_process(ListenSocket, ReqPid), - ReqPid ! {its_yours,ListenSocket}, - Result - end - end) + {open_listen_socket(Host1, Port0, Options0), Options0} + of + {{{Host,Port}, ListenSocket}, Options1} -> + try + %% Now Host,Port is what to use for the supervisor to register its name, + %% and ListenSocket is for listening on connections. But it is still owned + %% by self()... + finalize_start(Host, Port, ?GET_OPT(profile, Options1), + ?PUT_INTERNAL_OPT({lsocket,{ListenSocket,self()}}, Options1), + fun(Opts, Result) -> + {_, Callback, _} = ?GET_OPT(transport, Opts), + receive + {request_control, ListenSocket, ReqPid} -> + ok = Callback:controlling_process(ListenSocket, ReqPid), + ReqPid ! {its_yours,ListenSocket}, + Result + end + end) + of + {error,Err} -> + close_listen_socket(ListenSocket, Options1), + {error,Err}; + OK -> + OK + catch + error:Error -> + close_listen_socket(ListenSocket, Options1), + error(Error); + exit:Exit -> + close_listen_socket(ListenSocket, Options1), + exit(Exit) + end catch throw:bad_fd -> {error,bad_fd}; @@ -524,6 +537,15 @@ open_listen_socket(_Host0, Port0, Options0) -> {{LHost,LPort}, LSock}. %%%---------------------------------------------------------------- +close_listen_socket(ListenSocket, Options) -> + try + {_, Callback, _} = ?GET_OPT(transport, Options), + Callback:close(ListenSocket) + catch + _C:_E -> ok + end. + +%%%---------------------------------------------------------------- finalize_start(Host, Port, Profile, Options0, F) -> try %% throws error:Error if no usable hostkey is found diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl index 278f6a9780..aa9ba0f9bb 100644 --- a/lib/ssh/src/ssh_sftpd.erl +++ b/lib/ssh/src/ssh_sftpd.erl @@ -508,11 +508,8 @@ close_our_file({_,Fd}, FileMod, FS0) -> FS1. %%% stat: do the stat -stat(Vsn, ReqId, Data, State, F) when Vsn =< 3-> - <<?UINT32(BLen), BPath:BLen/binary>> = Data, - stat(ReqId, unicode:characters_to_list(BPath), State, F); -stat(Vsn, ReqId, Data, State, F) when Vsn >= 4-> - <<?UINT32(BLen), BPath:BLen/binary, ?UINT32(_Flags)>> = Data, +stat(Vsn, ReqId, Data, State, F) -> + <<?UINT32(BLen), BPath:BLen/binary, _/binary>> = Data, stat(ReqId, unicode:characters_to_list(BPath), State, F). fstat(Vsn, ReqId, Data, State) when Vsn =< 3-> diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index da94b5722f..5de6d52092 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -43,7 +43,9 @@ suite() -> {timetrap,{seconds,40}}]. all() -> - [{group, all_tests}]. + [{group, all_tests}, + daemon_already_started + ]. groups() -> [{all_tests, [parallel], [{group, ssh_renegotiate_SUITE}, @@ -801,6 +803,24 @@ daemon_already_started(Config) when is_list(Config) -> ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- +%%% Test that a failed daemon start does not leave the port open +daemon_error_closes_port(Config) -> + GoodSystemDir = proplists:get_value(data_dir, Config), + Port = ssh_test_lib:inet_port(), + {error,_} = ssh_test_lib:daemon(Port, []), % No system dir + case ssh_test_lib:daemon(Port, [{system_dir, GoodSystemDir}]) of + {error,eaddrinuse} -> + {fail, "Port leakage"}; + {error,Error} -> + ct:log("Strange error: ~p",[Error]), + {fail, "Strange error"}; + {Pid, _Host, Port} -> + %% Ok + ssh:stop_daemon(Pid) + end. + + +%%-------------------------------------------------------------------- %%% check that known_hosts is updated correctly known_hosts(Config) when is_list(Config) -> SystemDir = proplists:get_value(data_dir, Config), diff --git a/lib/ssh/test/ssh_compat_SUITE.erl b/lib/ssh/test/ssh_compat_SUITE.erl index f4eef2dc77..8e82527c6e 100644 --- a/lib/ssh/test/ssh_compat_SUITE.erl +++ b/lib/ssh/test/ssh_compat_SUITE.erl @@ -1126,7 +1126,24 @@ prepare_local_directory(ServerRootDir) -> "chmod 222 unreadable_file", "exit"]. + check_local_directory(ServerRootDir) -> + TimesToTry = 3, % sleep 0.5, 1, 2 and then 4 secs (7.5s in total) + check_local_directory(ServerRootDir, 500, TimesToTry-1). + +check_local_directory(ServerRootDir, SleepTime, N) -> + case do_check_local_directory(ServerRootDir) of + {error,Error} when N>0 -> + %% Could be that the erlang side is faster and the docker's operations + %% are not yet finalized. + %% Sleep for a while and retry a few times: + timer:sleep(SleepTime), + check_local_directory(ServerRootDir, 2*SleepTime, N-1); + Other -> + Other + end. + +do_check_local_directory(ServerRootDir) -> case lists:sort(ok(file:list_dir(ServerRootDir)) -- [".",".."]) of ["ex_tst1","mydir","tst2"] -> {ok,Expect} = file:read_file(filename:join(ServerRootDir,"ex_tst1")), @@ -1161,6 +1178,7 @@ check_local_directory(ServerRootDir) -> {error,{bad_dir_contents,"/"}} end. + call_sftp_in_docker(Config, ServerIP, ServerPort, Cmnds, UserDir) -> {DockerIP,DockerPort} = ip_port(Config), {ok,C} = ssh:connect(DockerIP, DockerPort, diff --git a/lib/ssh/test/ssh_connection_SUITE.erl b/lib/ssh/test/ssh_connection_SUITE.erl index 778e4a5fc8..6aa587dc7f 100644 --- a/lib/ssh/test/ssh_connection_SUITE.erl +++ b/lib/ssh/test/ssh_connection_SUITE.erl @@ -1124,12 +1124,12 @@ start_our_shell(_User, _Peer) -> ssh_exec_echo(Cmd) -> spawn(fun() -> - io:format("echo "++Cmd ++ "\n") + io:format("echo ~s\n", [Cmd]) end). ssh_exec_echo(Cmd, User) -> spawn(fun() -> - io:format(io_lib:format("echo ~s ~s\n",[User,Cmd])) + io:format("echo ~s ~s\n",[User,Cmd]) end). ssh_exec_echo(Cmd, User, _PeerAddr) -> ssh_exec_echo(Cmd,User). diff --git a/lib/ssh/test/ssh_engine_SUITE.erl b/lib/ssh/test/ssh_engine_SUITE.erl index c2e6ac1fee..3adb23acdb 100644 --- a/lib/ssh/test/ssh_engine_SUITE.erl +++ b/lib/ssh/test/ssh_engine_SUITE.erl @@ -126,10 +126,17 @@ simple_connect(Config) -> load_engine() -> case crypto:get_test_engine() of {ok, Engine} -> - try crypto:engine_load(<<"dynamic">>, + try + %% The test engine has it's own fake rsa sign/verify that + %% you don't want to use, so exclude it from methods to load: + Methods = + crypto:engine_get_all_methods() -- [engine_method_rsa], + crypto:engine_load(<<"dynamic">>, [{<<"SO_PATH">>, Engine}, <<"LOAD">>], - []) + [], + Methods + ) catch error:notsup -> {error, notsup} diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index ae7b4cf3f2..2890d7fe5b 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,4 +1,4 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.7.1 +SSH_VSN = 4.7.3 APP_VSN = "ssh-$(SSH_VSN)" |