|
20 | 20 |
|
21 | 21 | # [Version 2.9.1 to 2.9.2](./docs/changes/2.9.2.md)
|
22 | 22 |
|
23 |
| -# Planned for next version |
24 |
| - |
25 |
| -## Bug fixes |
26 |
| - |
27 |
| -* [GH-268](https://github.com/apache/mina-sshd/issues/268) (Regression in 2.9.0) Heartbeat should throw an exception if no reply arrives within the timeout. |
28 |
| -* [GH-275](https://github.com/apache/mina-sshd/issues/275) SFTP: be more lenient when reading `SSH_FXP_STATUS` replies. |
29 |
| -* [GH-281](https://github.com/apache/mina-sshd/issues/281) Use OpenSSH first-match semantics for processing HostConfigEntries. |
30 |
| -* [GH-282](https://github.com/apache/mina-sshd/issues/282) Correct setting file permissions on newly written host key files on Windows. |
31 |
| -* [GH-283](https://github.com/apache/mina-sshd/issues/283) Fix handling of `CoreModuleProperties.PASSWORD_PROMPTS`. |
32 |
| -* [GH-285](https://github.com/apache/mina-sshd/issues/285) Fix compilation failure on Java 19. |
33 |
| -* [GH-293](https://github.com/apache/mina-sshd/issues/293) Handle SFTP buffer sizes larger than the server limit better. |
34 |
| -* [GH-294](https://github.com/apache/mina-sshd/issues/294) Fix memory leak in `SftpFileSystemProvider`. |
35 |
| -* [GH-297](https://github.com/apache/mina-sshd/issues/297) Auto-configure file password provider for reading encrypted SSH keys. |
36 |
| -* [GH-298](https://github.com/apache/mina-sshd/issues/298) Server side heartbeat not working. |
37 |
| -* [GH-300](https://github.com/apache/mina-sshd/issues/300) Read the channel id in `SSH_MSG_CHANNEL_OPEN_CONFIRMATION` as unsigned int. |
38 |
| -* [GH-313](https://github.com/apache/mina-sshd/issues/313) Log exceptions in the SFTP subsystem before sending a failure status reply. |
39 |
| -* [GH-322](https://github.com/apache/mina-sshd/issues/322) Add basic Android O/S awareness. |
40 |
| -* [GH-325](https://github.com/apache/mina-sshd/issues/325) `SftpFileSystemProvider`: fix deletions of symlinks through `Files.delete()`. |
41 |
| -* [GH-364](https://github.com/apache/mina-sshd/issues/364) `AbstractAgentClient`: respect flags for RSA signature requests. |
42 |
| - |
43 |
| - |
44 |
| -* [SSHD-1295](https://issues.apache.org/jira/browse/SSHD-1295) Fix cancellation of futures and add options to cancel futures on time-outs. |
45 |
| -* [SSHD-1315](https://issues.apache.org/jira/browse/SSHD-1315) Do not log sensitive data at log level `TRACE`. |
46 |
| -* [SSHD-1316](https://issues.apache.org/jira/browse/SSHD-1316) Possible OOM in `ChannelPipedInputStream` (fix channel window). |
47 |
| -* [SSHD-1319](https://issues.apache.org/jira/browse/SSHD-1319) Use position in `SftpRemotePathChannel.transferFrom()`. |
48 |
| - |
49 |
| -## Major code re-factoring |
50 |
| - |
51 |
| -## Potential compatibility issues |
52 |
| - |
53 |
| -### Futures and cancellation or time-outs |
54 |
| - |
55 |
| -Apache MINA sshd is an asynchronous framework: for long-running operations, and |
56 |
| -in particular operations involving network communication, the API returns a |
57 |
| -future that client code can use to wait until the operation is complete. Waiting |
58 |
| -on a future is usually done with a `future.verify()` or `future.verify(timeout)` |
59 |
| -call. Futures can also be canceled. |
60 |
| - |
61 |
| -Previous versions did not implement cancellation correctly: while the future |
62 |
| -object itself was marked as "canceled", the underlying operation was not. The |
63 |
| -same problem also existed for time-outs: when `future.verify(timeout)` timed out, |
64 |
| -the underlying operation still continued to run asynchronously. This could |
65 |
| -lead to problems because if the underlying operation eventually succeeded, |
66 |
| -application code would be completely unaware. For instance in |
67 |
| - |
68 |
| -``` |
69 |
| - ClientSession session = client.connect(user, host, port).verify(timeout).getSession(); |
70 |
| -``` |
71 |
| - |
72 |
| -the application might get a time-out, but the underlying connect operation |
73 |
| -would continue to run, might succeed eventually, and then there would in fact |
74 |
| -be a `ClientSession` (and thus also a network connection, and a socket used up). |
75 |
| -But the application had no way to access that session to shut it down. The net |
76 |
| -effect was a socket leak. |
77 |
| - |
78 |
| -In this version, this has been corrected. By default, the future is canceled |
79 |
| -when a time-out occurs, and `future.cancel()` is propagated to the underlying |
80 |
| -operation and cancels it. |
81 |
| - |
82 |
| -Canceling an operation itself may not be possible immediately. For instance, |
83 |
| -an authentication attempt is a message exchange with the server. If the |
84 |
| -authentication request has already been sent when cancellation is requested, |
85 |
| -the sending of that request cannot be undone. The authentication can only be |
86 |
| -cancelled after the reply from the server has been received, and if that reply |
87 |
| -is an authentication success, cancellation isn't even possible anymore. Or |
88 |
| -consider requesting a port forwarding: that, too, is a request-reply message |
89 |
| -exchange. Once the request has been sent, there are two cases: if the server |
90 |
| -replies with a failure message, the port forwarding failed and since there is |
91 |
| -nothing to cancel, cancellation is not possible. If the reply indicates the |
92 |
| -tunnel was established, but `future.cancel()` had already been called, we have |
93 |
| -two options: either we shut down the just established tunnel again and say |
94 |
| -cancellation succeeded, or we say cancellation failed and report a successfully |
95 |
| -established tunnel. Because cancellations may be caused by time-outs, Apache |
96 |
| -MINA sshd chooses the first option and shuts down the tunnel again. Otherwise |
97 |
| -an application might get a time-out but still be left with an established |
98 |
| -tunnel. |
99 |
| - |
100 |
| -Cancellation is only possible while the operation has not completed yet. If |
101 |
| -a future is already done, it cannot be canceled anymore. |
| 23 | +# [Version 2.9.2 to 2.10.0](./docs/changes/2.10.0.md) |
102 | 24 |
|
103 |
| -The `cancel()` operation on a future is thus a _request_ to cancel the |
104 |
| -operation; it may or may not result in actually cancelling the operation. |
105 |
| -`cancel()` itself therefore returns a `CancelFuture` that client code can use |
106 |
| -to wait for the request having been handled, and then learn whether the |
107 |
| -operation was indeed canceled. |
108 |
| - |
109 |
| -Calls to `verify()` throw an `SshException` with a |
110 |
| -`java.util.concurrent.CancellationException` as cause if cancelled asynchronously |
111 |
| -via the `cancel()` method. |
112 |
| - |
113 |
| -Application code can control the behavior on time-outs. The `verify()` method |
114 |
| -takes besides a time-out duration newly also a number of `CancelOption`s as |
115 |
| -parameters. |
116 |
| - |
117 |
| -There are three possible values to cancel on a time-out, to cancel on an |
118 |
| -interruption, or not to cancel at all when either occurs. For backwards |
119 |
| -compatibility, the default behavior of `AuthFuture` and of `OpenFuture` is |
120 |
| -unchanged: to cancel on a time-out, client code must pass the |
121 |
| -`CancelOption.CANCEL_ON_TIMEOUT` flag. |
122 |
| - |
123 |
| -The default behavior of `ConnectFuture` _has_ been changed: by default, it _does_ |
124 |
| -cancel the connection attempt if a time-out occurs. To avoid this, client code |
125 |
| -would have to pass the `CancelOption.NO_CANCELLATION` flag expressly. This change |
126 |
| -in behavior was done to avoid socket leaks, and it was deemed acceptable since |
127 |
| -a difference in behavior could only occur if existing client code called |
128 |
| -`AuthFuture.verify()` in different threads on the same future instance, or |
129 |
| -sequentially on the same future instance again after the first time-out. Both |
130 |
| -cases are highly unlikely to occur in existing client code. If existing code |
131 |
| -needs this behavior, it needs to be adapted to pass `CancelOption`s as may be |
132 |
| -appropriate for the precise use case. |
133 |
| - |
134 |
| -## Minor code helpers |
135 |
| - |
136 |
| -## Behavioral changes and enhancements |
137 |
| - |
138 |
| -* Support for reading SSH keys from PEM files containing encrypted private keys |
139 |
| - [RFC 5958, EncryptedPrivateKeyInfo](https://www.rfc-editor.org/rfc/rfc5958) has |
140 |
| - been added. Such PEM files start with `-----BEGIN ENCRYPTED PRIVATE KEY-----`. |
141 |
| - Reading and decrypting keys from such files requires Bouncy Castle to be |
142 |
| - present. |
143 |
| -* Support reading SSH keys from PEM files starting with |
144 |
| - `-----BEGIN ED25519 PRIVATE KEY-----`. Some OpenSSL versions could produce such |
145 |
| - files when the user specified "traditional" PEM output. (Encrypted keys written |
146 |
| - using [RFC 1421](https://www.rfc-editor.org/rfc/rfc1421) encryption.) Modern |
147 |
| - OpenSSL refuses to create such PEM files; it always uses PKCS#8 (RFC 5958) style |
148 |
| - PEM files for EdDSA keys. |
149 |
| -* Support reading encrypted private keys in openSSH format that have been |
150 |
| - encrypted with an AEAD cipher. |
151 |
| -* `CoreModuleProperties.PASSWORD_PROMPTS` is now also used for password |
152 |
| - authentication. Previous versions used it only for keyboard-interactive |
153 |
| - authentication. The semantics has been clarified to be the equivalent |
154 |
| - of the OpenSSH configuration `NumberOfPasswordPrompts`, which is actually |
155 |
| - the number of authentication *attempts*. (In keyboard-interactive |
156 |
| - authentication, there may be several prompts per authentication attempt.) |
157 |
| - Only interactive authentication attempts using `UserInteraction` count |
158 |
| - towards the limit. Attempts fulfilled by explicitly provided passwords |
159 |
| - (via `session.addPasswordIdentity()` or `session.setPasswordIdentityProvider()`) |
160 |
| - are *not* counted. The default value of the property is unchanged and is |
161 |
| - 3, as in OpenSSH. The limit is applied independently for both authentication |
162 |
| - mechanisms: with the default setting, there can be three keyboard-interactive |
163 |
| - authentication attempts, plus three more password authentication attempts if |
164 |
| - both methods are configured and applicable. |
165 |
| - |
166 |
| -### Connection time-outs |
167 |
| - |
168 |
| -Connection time-outs are normally handled in Apache MINA SSHD at the application |
169 |
| -level by passing a time-out to `ConnectFuture.verify()`: |
170 |
| - |
171 |
| -``` |
172 |
| -ClientSession session = client.connect(user, host, port).verify(MY_TIMEOUT).getSession(); |
173 |
| -``` |
174 |
| - |
175 |
| -However, the actual I/O library used might have its own connection time-out. |
176 |
| -With large time-outs, the behavior depended on the actual implementation of |
177 |
| -the I/O back-end used: |
178 |
| - |
179 |
| -* The default NIO2 back-end has no default connection time-out at all, so the |
180 |
| - `verify(MY_TIMEOUT)` call would always time-out after `MY_TIMEOUT` had elapsed. |
181 |
| -* Apache MINA has a default connection time-out of one minute, so even if |
182 |
| - `MY_TIMEOUT` was larger, the time-out would still occur after one minute. |
183 |
| -* Netty has a default connection time-out of 30 seconds. |
184 |
| - |
185 |
| -In this version, a new property `CoreModuleProperties.IO_CONNECTION_TIMEOUT` |
186 |
| -can be set to control this I/O connection time-out. It can be set on an |
187 |
| -`SshClient` or `SshServer`; if set (and > 0), the I/O back-end is configured |
188 |
| -to use that value as its I/O connection time-out, and |
189 |
| -`ConnectFuture.verify(MY_TIMEOUT)` will always time-out at |
190 |
| -`Math.min(CoreModuleProperties.IO_CONNECTION_TIMEOUT, MY_TIMEOUT)`. The property |
191 |
| -is also effective for the NIO2 back-end; the default value is 1 minute. |
192 |
| - |
193 |
| -`verify()` throws an `SshException` if it fails or times out. The _cause_ of |
194 |
| -that exception is a `java.net.ConnectException` if the I/O connection time-out |
195 |
| -expired, and a `java.util.concurrent.TimeoutException` if the application |
196 |
| -time-out expired. (And if the future was canceled explicitly before any |
197 |
| -time-out was reached, the cause is a `java.util.concurrent.CancellationException`; |
198 |
| -see above.) |
| 25 | +# Planned for next version |
199 | 26 |
|
200 |
| -The new `CancelOption`s discussed above apply only if the application |
201 |
| -time-out expires. If the connection attempt times out at I/O level, it is |
202 |
| -the responsibility of the I/O library to ensure no resources such as |
203 |
| -sockets are consumed, and there is no SSH session created either. |
0 commit comments