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 e88c1a769dbb0a10ba9be3c9c0bd54c2eda3737f Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Fri Feb 26 06:54:43 2021 +0200 [SSHD-1125] Added option to require immediate close of channel in command ExitCallback invocation --- CHANGES.md | 5 ++-- .../java/org/apache/sshd/server/ExitCallback.java | 27 ++++++++++++++++++++-- .../apache/sshd/server/channel/ChannelSession.java | 10 ++++---- .../apache/sshd/util/test/BogusExitCallback.java | 12 +++++++--- .../org/apache/sshd/sftp/server/SftpSubsystem.java | 4 +++- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4bf9e41..942ed01 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,13 +16,14 @@ ## Minor code helpers +* [SSHD-525](https://issues.apache.org/jira/browse/SSHD-525) Added support for SFTP **client-side** ["posix-ren...@openssh.com" + extension](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=1.28&content-type=text/x-cvsweb-markup) - see section 3.3 * [SSHD-1085](https://issues.apache.org/jira/browse/SSHD-1085) Added `CliLogger` + more verbosity on `SshClientMain` * [SSHD-1109](https://issues.apache.org/jira/browse/SSHD-1109) Route tests JUL logging via SLF4JBridgeHandler * [SSHD-1109](https://issues.apache.org/jira/browse/SSHD-1109) Provide full slf4j logger capabilities to CliLogger + use it in all CLI classes * [SSHD-1110](https://issues.apache.org/jira/browse/SSHD-1110) Replace `Class#newInstance()` calls with `Class#getDefaultConstructor().newInstance()` * [SSHD-1111](https://issues.apache.org/jira/browse/SSHD-1111) Fixed SshClientCliSupport compression option detection -* [SSHD-525](https://issues.apache.org/jira/browse/SSHD-525) Added support for SFTP **client-side** ["posix-ren...@openssh.com" - extension](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=1.28&content-type=text/x-cvsweb-markup) - see section 3.3 +* [SSHD-1125](https://issues.apache.org/jira/browse/SSHD-1125) Added option to require immediate close of channel in command `ExitCallback` invocation * [SSHD-1127](https://issues.apache.org/jira/browse/SSHD-1127) Consolidated `SftpSubsystem` support implementations into `SftpSubsystemConfigurator` ## Behavioral changes and enhancements diff --git a/sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java b/sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java index dfa55be..eb1bca1 100644 --- a/sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java +++ b/sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java @@ -30,7 +30,17 @@ public interface ExitCallback { * @param exitValue the exit value */ default void onExit(int exitValue) { - onExit(exitValue, ""); + onExit(exitValue, false); + } + + /** + * Informs the SSH server that the shell has exited + * + * @param exitValue the exit value + * @param closeImmediately whether to also terminate the channel immediately or do a graceful close. + */ + default void onExit(int exitValue, boolean closeImmediately) { + onExit(exitValue, "", closeImmediately); } /** @@ -39,5 +49,18 @@ public interface ExitCallback { * @param exitValue the exit value * @param exitMessage exit value description */ - void onExit(int exitValue, String exitMessage); + default void onExit(int exitValue, String exitMessage) { + onExit(exitValue, exitMessage, false); + } + + /** + * + * Informs the SSH client/server that the shell has exited + * + * @param exitValue the exit value + * @param exitMessage exit value description + * @param closeImmediately whether to also terminate the channel immediately or do a graceful close. + */ + void onExit(int exitValue, String exitMessage, boolean closeImmediately); + } diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java index cfd3dad..86b4bbf 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java @@ -771,9 +771,9 @@ public class ChannelSession extends AbstractServerChannel { doWriteExtendedData(buffer.array(), buffer.rpos(), buffer.available()); } - command.setExitCallback((exitValue, exitMessage) -> { + command.setExitCallback((exitValue, exitMessage, closeImmediately) -> { try { - closeShell(exitValue); + closeShell(exitValue, closeImmediately); if (log.isDebugEnabled()) { log.debug("onExit({}) code={} message='{}' shell closed", ChannelSession.this, exitValue, exitMessage); @@ -898,9 +898,9 @@ public class ChannelSession extends AbstractServerChannel { return env; } - protected void closeShell(int exitValue) throws IOException { + protected void closeShell(int exitValue, boolean closeImmediately) throws IOException { if (log.isDebugEnabled()) { - log.debug("closeShell({}) exit code={}", this, exitValue); + log.debug("closeShell({}) exit code={}, immediate={}", this, exitValue, closeImmediately); } if (!isClosing()) { @@ -910,7 +910,7 @@ public class ChannelSession extends AbstractServerChannel { sendEof(); sendExitStatus(exitValue); commandExitFuture.setClosed(); - close(false); + close(closeImmediately); } else { commandExitFuture.setClosed(); } diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java index a4f1ff6..9de602a 100644 --- a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java +++ b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java @@ -25,21 +25,23 @@ public class BogusExitCallback implements ExitCallback { private boolean exited; private int exitValue; private String exitMessage; + private boolean closeImmediately; public BogusExitCallback() { super(); } @Override - public void onExit(int exitValue) { - onExit(exitValue, String.valueOf(exitValue)); + public void onExit(int exitValue, boolean closeImmediately) { + onExit(exitValue, String.valueOf(exitValue), closeImmediately); } @Override - public void onExit(int exitValue, String exitMessage) { + public void onExit(int exitValue, String exitMessage, boolean closeImmediately) { this.exited = true; this.exitValue = exitValue; this.exitMessage = exitMessage; + this.closeImmediately = closeImmediately; } public boolean isExited() { @@ -53,4 +55,8 @@ public class BogusExitCallback implements ExitCallback { public String getExitMessage() { return exitMessage; } + + public boolean isCloseImmediately() { + return closeImmediately; + } } diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpSubsystem.java index 2c79d23..03c8936 100644 --- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpSubsystem.java +++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/server/SftpSubsystem.java @@ -289,6 +289,7 @@ public class SftpSubsystem @Override public void run() { + int exitCode = 0; try { while (true) { Buffer buffer = requests.take(); @@ -305,10 +306,11 @@ public class SftpSubsystem Session session = getServerSession(); error("run({}) {} caught in SFTP subsystem: {}", session, t.getClass().getSimpleName(), t.getMessage(), t); + exitCode = -1; } } finally { closeAllHandles(); - callback.onExit(0); + callback.onExit(exitCode, exitCode != 0); } }