apache / mina-sshd

Apache MINA sshd is a comprehensive Java library for client- and server-side SSH.
https://mina.apache.org/sshd-project/
Apache License 2.0
892 stars 358 forks source link

org.apache.sshd.client.global.OpenSshHostKeysHandler should ignore unsupported host keys #434

Closed stasal closed 9 months ago

stasal commented 11 months ago

Version

2.9.2

Bug description

When receiving hostkeys-00@openssh.com request, client by default uses org.apache.sshd.client.global.OpenSshHostKeysHandler to process it. This handler's handleHostKeys method does nothing but logging keys when debug is enabled.

But there is no exception handling in parent org.apache.sshd.common.global.org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler class.

Therefore if the host sends two keys (one RSA and one EdDSA for example), but the client only supports RSA, the exception is being propagated from the org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler#process method and the host's request is processed as failed and the WARN message is generated in logs.

Actual behavior

Example: WARN 40340 --- []-nio2-thread-3] o.a.s.c.session.ClientConnectionService : globalRequest(ClientConnectionService[ClientSessionImpl[test@localhost/127.0.0.1:2222]])[hostkeys-00@openssh.com, want-reply=false] failed (SshException) to process: EdDSA provider not supported

Expected behavior

No warns are logged, and only the supported keys are handled by org.apache.sshd.client.global.OpenSshHostKeysHandler#handleHostKeys

Relevant log output

WARN 40340 --- []-nio2-thread-3] o.a.s.c.session.ClientConnectionService  : globalRequest(ClientConnectionService[ClientSessionImpl[test@localhost/127.0.0.1:2222]])[hostkeys-00@openssh.com, want-reply=false] failed (SshException) to process: EdDSA provider not supported

org.apache.sshd.common.SshException: EdDSA provider not supported
    at org.apache.sshd.common.util.buffer.Buffer.getRawPublicKey(Buffer.java:544) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.util.buffer.Buffer.getPublicKey(Buffer.java:519) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler.process(AbstractOpenSshHostKeysHandler.java:73) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler.process(AbstractOpenSshHostKeysHandler.java:38) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractConnectionService.globalRequest(AbstractConnectionService.java:868) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractConnectionService.process(AbstractConnectionService.java:486) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.CurrentService.process(CurrentService.java:109) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:591) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSession.lambda$handleMessage$0(AbstractSession.java:522) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.util.threads.ThreadUtils.runAsInternal(ThreadUtils.java:68) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:521) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1639) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:482) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:407) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:380) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:375) ~[sshd-core-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38) ~[sshd-core-2.9.2.jar:2.9.2]
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:318) ~[na:na]
    at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37) ~[sshd-core-2.9.2.jar:2.9.2]
    at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129) ~[na:na]
    at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:221) ~[na:na]
    at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:113) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
Caused by: java.security.NoSuchAlgorithmException: EdDSA provider not supported
    at org.apache.sshd.common.util.security.SecurityUtils.generateEDDSAPublicKey(SecurityUtils.java:627) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.util.buffer.keys.ED25519BufferPublicKeyParser.getRawPublicKey(ED25519BufferPublicKeyParser.java:46) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser$2.getRawPublicKey(BufferPublicKeyParser.java:102) ~[sshd-common-2.9.2.jar:2.9.2]
    at org.apache.sshd.common.util.buffer.Buffer.getRawPublicKey(Buffer.java:542) ~[sshd-common-2.9.2.jar:2.9.2]
    ... 25 common frames omitted

Other information

No response

tomaswolf commented 10 months ago

On the client side, it should indeed ignore unknown key types (and not do anything if it cannot deal with any of the keys).

On the server side, it should fail if it ever gets a key that it cannot handle. And it probably should even check that all the keys it gets in that request are keys the server proposed before. Otherwise some malicious or broken client is sending challenges for keys the server never proposed.

ThadHouse commented 10 months ago

Seeing this as well. The EdDSA provider from net.i2p.crypto:eddsa is extremely out of date, and doesn't work on newer versions of Java, as it uses removed internal API's. Removing that dependency causes any client connection to our host to log this error. Posting so I can be updated if/when a fix is pushed.