You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2019/07/18 11:23:00 UTC
[mina-sshd] 03/05: [SSHD-930] Added
SessionListener#sessionPeerIdentificationReceived callback
This is an automated email from the ASF dual-hosted git repository.
lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit 57ba26d7104db555b8efa0cf23fe59f873eba38a
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Mon Jul 8 13:33:51 2019 +0300
[SSHD-930] Added SessionListener#sessionPeerIdentificationReceived callback
---
CHANGES.md | 3 ++
.../sshd/client/session/AbstractClientSession.java | 8 ++--
.../sshd/common/session/SessionListener.java | 14 +++++++
.../sshd/common/session/helpers/SessionHelper.java | 32 ++++++++++++++++
.../sshd/server/session/AbstractServerSession.java | 4 +-
.../java/org/apache/sshd/server/ServerTest.java | 43 +++++++++++++++++-----
6 files changed, 90 insertions(+), 14 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 2c7a43c..60f3b07 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,9 @@
## Minor code helpers
+* `SessionListener` supports `sessionPeerIdentificationReceived` that is invoked once successful
+peer version data is received.
+
## Behavioral changes and enhancements
* [SSHD-930](https://issues.apache.org/jira/browse/SSHD-930) - Added configuration allowing the user to specify whether client should wait
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
index 5f44b19..1d865aa 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
@@ -472,7 +472,9 @@ public abstract class AbstractClientSession extends AbstractSession implements C
return true;
}
- protected void signalExtraServerVersionInfo(String version, List<String> lines) throws IOException {
+ protected void signalExtraServerVersionInfo(String version, List<String> lines) throws Exception {
+ signalPeerIdentificationReceived(version, lines);
+
if (GenericUtils.isEmpty(lines)) {
return;
}
@@ -483,8 +485,8 @@ public abstract class AbstractClientSession extends AbstractSession implements C
ui.serverVersionInfo(this, lines);
}
} catch (Error e) {
- log.warn("signalExtraServerVersionInfo({})[{}] failed ({}) to consult interaction: {}", this, version,
- e.getClass().getSimpleName(), e.getMessage());
+ log.warn("signalExtraServerVersionInfo({})[{}] failed ({}) to consult interaction: {}",
+ this, version, e.getClass().getSimpleName(), e.getMessage());
if (log.isDebugEnabled()) {
log.debug("signalExtraServerVersionInfo(" + this + ")[" + version
+ "] interaction consultation failure details", e);
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
index 544f89c..d322f9d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
@@ -18,6 +18,7 @@
*/
package org.apache.sshd.common.session;
+import java.util.List;
import java.util.Map;
import org.apache.sshd.common.kex.KexProposalOption;
@@ -43,6 +44,19 @@ public interface SessionListener extends SshdEventListener {
}
/**
+ * The peer's identification version was received
+ *
+ * @param session The {@link Session} instance
+ * @param version The retrieved identification version
+ * @param extraLines Extra data preceding the identification
+ * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253 - section 4.2 - Protocol Version Exchange</A>
+ */
+ default void sessionPeerIdentificationReceived(
+ Session session, String version, List<String> extraLines) {
+ // ignored
+ }
+
+ /**
* Signals the start of the negotiation options handling
*
* @param session The referenced {@link Session}
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
index 914d5d6..f58ed6e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
@@ -550,6 +550,38 @@ public abstract class SessionHelper extends AbstractKexFactoryManager implements
listener.sessionCreated(this);
}
+ protected void signalPeerIdentificationReceived(String version, List<String> extraLines) throws Exception {
+ try {
+ invokeSessionSignaller(l -> {
+ signalPeerIdentificationReceived(l, version, extraLines);
+ return null;
+ });
+ } catch (Throwable err) {
+ Throwable e = GenericUtils.peelException(err);
+ if (log.isDebugEnabled()) {
+ log.debug("signalPeerIdentificationReceived({}) Failed ({}) to announce peer={}: {}",
+ this, e.getClass().getSimpleName(), version, e.getMessage());
+ }
+ if (log.isTraceEnabled()) {
+ log.trace("signalPeerIdentificationReceived(" + this + ")[" + version + "] failure details", e);
+ }
+ if (e instanceof Exception) {
+ throw (Exception) e;
+ } else {
+ throw new RuntimeSshException(e);
+ }
+ }
+
+ }
+
+ protected void signalPeerIdentificationReceived(SessionListener listener, String version, List<String> extraLines) {
+ if (listener == null) {
+ return;
+ }
+
+ listener.sessionPeerIdentificationReceived(this, version, extraLines);
+ }
+
/**
* Sends a session event to all currently registered session listeners
*
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 529b5f8..1d5eceb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -406,7 +406,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
}
@Override
- protected boolean readIdentification(Buffer buffer) throws IOException, GeneralSecurityException {
+ protected boolean readIdentification(Buffer buffer) throws Exception {
ServerProxyAcceptor acceptor = getServerProxyAcceptor();
int rpos = buffer.rpos();
boolean debugEnabled = log.isDebugEnabled();
@@ -467,6 +467,8 @@ public abstract class AbstractServerSession extends AbstractSession implements S
throw err;
}
+ signalPeerIdentificationReceived(clientVersion, ident);
+
kexState.set(KexState.INIT);
sendKexInit();
return true;
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
index ae3ce35..faebaf1 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
@@ -931,11 +931,7 @@ public class ServerTest extends BaseTestSupport {
client.addSessionListener(listener);
client.start();
- try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, sshd.getPort())
- .verify(7L, TimeUnit.SECONDS)
- .getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(9L, TimeUnit.SECONDS);
+ try (ClientSession session = createTestClientSession(sshd)) {
assertEquals("Mismatched client identification", expClientIdent, session.getClientVersion());
assertEquals("Mismatched server identification", expServerIdent, session.getServerVersion());
} finally {
@@ -980,11 +976,7 @@ public class ServerTest extends BaseTestSupport {
});
client.start();
- try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, sshd.getPort())
- .verify(7L, TimeUnit.SECONDS)
- .getSession()) {
- session.addPasswordIdentity(getCurrentTestName());
- session.auth().verify(9L, TimeUnit.SECONDS);
+ try (ClientSession session = createTestClientSession(sshd)) {
assertTrue("No signal received in time", signal.tryAcquire(11L, TimeUnit.SECONDS));
} finally {
client.stop();
@@ -995,6 +987,37 @@ public class ServerTest extends BaseTestSupport {
assertListEquals("Server information", expected, actual);
}
+ @Test // see SSHD-930
+ public void testDelayClientIdentification() throws Exception {
+ sshd.start();
+
+ PropertyResolverUtils.updateProperty(
+ client, ClientFactoryManager.SEND_IMMEDIATE_IDENTIFICATION, false);
+ AtomicReference<String> peerVersion = new AtomicReference<>();
+ client.addSessionListener(new SessionListener() {
+ @Override
+ public void sessionPeerIdentificationReceived(Session session, String version, List<String> extraLines) {
+ String clientVersion = session.getClientVersion();
+ if (GenericUtils.isNotEmpty(clientVersion)) {
+ throw new IllegalStateException("Client version already established");
+ }
+
+ String prev = peerVersion.getAndSet(version);
+ if (GenericUtils.isNotEmpty(prev)) {
+ throw new IllegalStateException("Peer version already signalled: " + prev);
+ }
+ }
+ });
+ client.start();
+
+ try (ClientSession session = createTestClientSession(sshd)) {
+ String version = peerVersion.getAndSet(null);
+ assertTrue("Peer version not signalled", GenericUtils.isNotEmpty(version));
+ } finally {
+ client.stop();
+ }
+ }
+
private ClientSession createTestClientSession(SshServer server) throws Exception {
ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, server.getPort())
.verify(7L, TimeUnit.SECONDS)