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 8e24d0d82a21fc99c6ca9de21c4fc1c794ff9b4e Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Fri Jan 8 07:37:00 2021 +0200 [SSHD-1097] Added capability to send peer identification via ReservedSessionMessagesHandler --- CHANGES.md | 1 + .../sshd/client/session/AbstractClientSession.java | 3 +-- .../session/ReservedSessionMessagesHandler.java | 28 +++++++++++++++++++- .../ReservedSessionMessagesHandlerAdapter.java | 20 +++++++++++++++ .../sshd/common/session/helpers/SessionHelper.java | 30 +++++++++++++++++----- .../sshd/server/session/AbstractServerSession.java | 8 +----- .../sshd/server/session/ServerSessionImpl.java | 2 +- 7 files changed, 75 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7d2b02c..5dada51 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -27,6 +27,7 @@ * [SSHD-1085](https://issues.apache.org/jira/browse/SSHD-1085) Added more notifications related to channel state change for detecting channel closing or closed earlier. * [SSHD-1091](https://issues.apache.org/jira/browse/SSHD-1091) Renamed `sshd-contrib` top-level package in order to align naming convention. * [SSHD-1097](https://issues.apache.org/jira/browse/SSHD-1097) Added more `SessionListener` callbacks related to the initial version and key exchange +* [SSHD-1097](https://issues.apache.org/jira/browse/SSHD-1097) Added more capability to send peer identification via `ReservedSessionMessagesHandler` * [SSHD-1109](https://issues.apache.org/jira/browse/SSHD-1109) Replace log4j with logback as the slf4j logger implementation for tests * [SSHD-1114](https://issues.apache.org/jira/browse/SSHD-1114) Added callbacks for client-side password authentication progress * [SSHD-1114](https://issues.apache.org/jira/browse/SSHD-1114) Added callbacks for client-side public key authentication progress 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 ce8e529..3bab23a 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 @@ -356,8 +356,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C clientVersion = resolveIdentificationString(CoreModuleProperties.CLIENT_IDENTIFICATION.getName()); // Note: we intentionally use an unmodifiable list in order to enforce the fact that client cannot send header lines signalSendIdentification(clientVersion, Collections.emptyList()); - - return sendIdentification(clientVersion); + return sendIdentification(clientVersion, Collections.emptyList()); } @Override diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java index e73e5d9..ecc49f1 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java @@ -19,17 +19,43 @@ package org.apache.sshd.common.session; +import java.util.List; + +import org.apache.sshd.common.io.IoWriteFuture; import org.apache.sshd.common.util.SshdEventListener; import org.apache.sshd.common.util.buffer.Buffer; /** * Provides a way to listen and handle the {@code SSH_MSG_IGNORE} and {@code SSH_MSG_DEBUG} messages that are received - * by a session, as well as proprietary and/or extension messages. + * by a session, as well as proprietary and/or extension messages and behavior. * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ public interface ReservedSessionMessagesHandler extends SshdEventListener { /** + * Send the initial version exchange identification in and independent manner + * + * @param session The {@code Session} through which the version is exchange is being managed + * @param version The version line that was resolved - <B>Note:</B> since this string is part of the KEX and is + * <U>cached</U> in the calling session, any changes to it require updating the session's cached + * value. + * @param extraLines Extra lines to be sent - valid only for server sessions. <B>Note:/B> the handler may modify + * these lines and return {@code null} thus signaling the session to proceed with sending the + * identification + * @return A {@link IoWriteFuture} that can be used to wait for the data to be sent successfully. If + * {@code null} then the session will send the identification, otherwise it is assumed that the + * handler has sent it. + * @throws Exception + * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253 - section 4.2 - Protocol + * Version Exchange</A> + */ + default IoWriteFuture sendIdentification( + Session session, String version, List<String> extraLines) + throws Exception { + return null; + } + + /** * Invoked when an {@code SSH_MSG_IGNORE} packet is received * * @param session The {@code Session} through which the message was received diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java index a394612..6b97b01 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java @@ -19,9 +19,13 @@ package org.apache.sshd.common.session.helpers; +import java.util.List; + import org.apache.sshd.common.SshConstants; +import org.apache.sshd.common.io.IoWriteFuture; import org.apache.sshd.common.session.ReservedSessionMessagesHandler; import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.buffer.BufferUtils; import org.apache.sshd.common.util.logging.AbstractLoggingBean; @@ -41,6 +45,22 @@ public class ReservedSessionMessagesHandlerAdapter } @Override + public IoWriteFuture sendIdentification(Session session, String version, List<String> extraLines) throws Exception { + if (log.isDebugEnabled()) { + log.debug("sendIdentification({}) version={} linesCount={}", + session, version, GenericUtils.size(extraLines)); + } + + if (log.isTraceEnabled() && GenericUtils.isNotEmpty(extraLines)) { + for (String line : extraLines) { + log.trace("sendIdentification({}) {}", session, line); + } + } + + return null; + } + + @Override public void handleIgnoreMessage(Session session, Buffer buffer) throws Exception { handleIgnoreMessage(session, buffer.getBytes(), buffer); } 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 7c0e74d..a5d7542 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 @@ -832,13 +832,31 @@ public abstract class SessionHelper extends AbstractKexFactoryManager implements /** * Send our identification. * - * @param ident our identification to send - * @return {@link IoWriteFuture} that can be used to wait for notification that identification has been - * send - * @throws IOException If failed to send the packet + * @param version our identification to send + * @param extraLines Extra lines to send - used only by server sessions + * @return {@link IoWriteFuture} that can be used to wait for notification that identification has been + * send + * @throws Exception If failed to send the packet */ - protected IoWriteFuture sendIdentification(String ident) throws IOException { - if (log.isDebugEnabled()) { + protected IoWriteFuture sendIdentification(String version, List<String> extraLines) throws Exception { + ReservedSessionMessagesHandler handler = getReservedSessionMessagesHandler(); + IoWriteFuture future = (handler == null) ? null : handler.sendIdentification(this, version, extraLines); + boolean debugEnabled = log.isDebugEnabled(); + if (future != null) { + if (debugEnabled) { + log.debug("sendIdentification({})[{}] sent {} lines via reserved handler", + this, version, GenericUtils.size(extraLines)); + } + + return future; + } + + String ident = version; + if (GenericUtils.size(extraLines) > 0) { + ident = GenericUtils.join(extraLines, "\r\n") + "\r\n" + version; + } + + if (debugEnabled) { log.debug("sendIdentification({}): {}", this, ident.replace('\r', '|').replace('\n', '|')); } 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 d663c10..b388a6c 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 @@ -225,13 +225,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S protected IoWriteFuture sendServerIdentification(List<String> headerLines) throws Exception { serverVersion = resolveIdentificationString(CoreModuleProperties.SERVER_IDENTIFICATION.getName()); signalSendIdentification(serverVersion, headerLines); - - String ident = serverVersion; - if (GenericUtils.size(headerLines) > 0) { - ident = GenericUtils.join(headerLines, "\r\n") + "\r\n" + serverVersion; - } - - return sendIdentification(ident); + return sendIdentification(serverVersion, headerLines); } @Override diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java index 9fee875..0b4a588 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java @@ -39,7 +39,7 @@ public class ServerSessionImpl extends AbstractServerSession { String headerConfig = CoreModuleProperties.SERVER_EXTRA_IDENTIFICATION_LINES.getOrNull(this); String[] headers = GenericUtils.split(headerConfig, CoreModuleProperties.SERVER_EXTRA_IDENT_LINES_SEPARATOR); - // We intentionally create a modifiable array so as to allow users to modify it via SessionListener + // We intentionally create a modifiable array so as to allow users to modify it via SessionListener or ReservedSessionMessagesHandler List<String> extraLines = GenericUtils.isEmpty(headers) ? new ArrayList<>() : new ArrayList<>(Arrays.asList(headers));