Skip to content

Commit 3e04fd7

Browse files
author
Lyor Goldstein
committed
[apacheGH-445] Added StrictKexTest
1 parent 1c11e3a commit 3e04fd7

File tree

9 files changed

+435
-6
lines changed

9 files changed

+435
-6
lines changed

CHANGES.md

+7
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,12 @@ Provide (read-only) public access to internal session state values related to KE
5858

5959
## Potential compatibility issues
6060

61+
### Added finite wait time for default implementation of `ClientSession#executeRemoteCommand`
62+
63+
* `CoreModuleProperties#EXEC_CHANNEL_OPEN_TIMEOUT` - default = 30 seconds.
64+
* `CoreModuleProperties#EXEC_CHANNEL_CMD_TIMEOUT` - default = 30 seconds.
65+
66+
This may cause failures for code that was running long execution commands using the default method implementations.
67+
6168
## Major Code Re-factoring
6269

sshd-common/src/test/java/org/apache/sshd/util/test/JUnitTestSupport.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ public static void outputDebugMessage(String format, Object o) {
703703

704704
public static void outputDebugMessage(String format, Object... args) {
705705
if (OUTPUT_DEBUG_MESSAGES) {
706-
outputDebugMessage(String.format(format, args));
706+
outputDebugMessage(GenericUtils.isEmpty(args) ? format : String.format(format, args));
707707
}
708708
}
709709

@@ -713,6 +713,24 @@ public static void outputDebugMessage(Object message) {
713713
}
714714
}
715715

716+
public static void failWithWrittenErrorMessage(String format, Object... args) {
717+
failWithWrittenErrorMessage(GenericUtils.isEmpty(args) ? format : String.format(format, args));
718+
}
719+
720+
public static void failWithWrittenErrorMessage(Object message) {
721+
writeErrorMessage(message);
722+
fail(Objects.toString(message));
723+
}
724+
725+
public static void writeErrorMessage(String format, Object... args) {
726+
writeErrorMessage(GenericUtils.isEmpty(args) ? format : String.format(format, args));
727+
}
728+
729+
public static void writeErrorMessage(Object message) {
730+
System.err.append("===[ERROR]=== ").println(message);
731+
System.err.flush();
732+
}
733+
716734
/* ---------------------------------------------------------------------------- */
717735

718736
public static void replaceJULLoggers() {

sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.apache.sshd.common.util.io.output.NoCloseOutputStream;
6060
import org.apache.sshd.common.util.io.output.NullOutputStream;
6161
import org.apache.sshd.common.util.net.SshdSocketAddress;
62+
import org.apache.sshd.core.CoreModuleProperties;
6263

6364
/**
6465
* <P>
@@ -304,10 +305,15 @@ default void executeRemoteCommand(
304305
ClientChannel channel = createExecChannel(command)) {
305306
channel.setOut(channelOut);
306307
channel.setErr(channelErr);
307-
channel.open().await(); // TODO use verify and a configurable timeout
308308

309-
// TODO use a configurable timeout
310-
Collection<ClientChannelEvent> waitMask = channel.waitFor(REMOTE_COMMAND_WAIT_EVENTS, 0L);
309+
Duration openTimeout =
310+
CoreModuleProperties.EXEC_CHANNEL_OPEN_TIMEOUT.getRequired(channel);
311+
channel.open().verify(openTimeout);
312+
313+
Duration execTimeout =
314+
CoreModuleProperties.EXEC_CHANNEL_CMD_TIMEOUT.getRequired(channel);
315+
Collection<ClientChannelEvent> waitMask =
316+
channel.waitFor(REMOTE_COMMAND_WAIT_EVENTS, execTimeout);
311317
if (waitMask.contains(ClientChannelEvent.TIMEOUT)) {
312318
throw new SocketTimeoutException("Failed to retrieve command result in time: " + command);
313319
}

sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java

+14
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ public final class CoreModuleProperties {
6161
public static final Property<Duration> CHANNEL_OPEN_TIMEOUT
6262
= Property.duration("ssh-agent-server-channel-open-timeout", Duration.ofSeconds(30));
6363

64+
/**
65+
* Value that can be set on the {@link org.apache.sshd.common.FactoryManager} the session or the channel to configure the
66+
* channel open timeout value (millis) for executing a remote command using default implementation.
67+
*/
68+
public static final Property<Duration> EXEC_CHANNEL_OPEN_TIMEOUT
69+
= Property.duration("ssh-exec-channel-open-timeout", Duration.ofSeconds(30));
70+
71+
/**
72+
* Value that can be set on the {@link org.apache.sshd.common.FactoryManager} the session or the channel to configure the
73+
* channel command execution timeout value (millis) for executing a remote command using default implementation.
74+
*/
75+
public static final Property<Duration> EXEC_CHANNEL_CMD_TIMEOUT
76+
= Property.duration("ssh-exec-channel-cmd-timeout", Duration.ofSeconds(30));
77+
6478
/**
6579
* Value used to configure the type of proxy forwarding channel to be used. See also
6680
* https://tools.ietf.org/html/draft-ietf-secsh-agent-02

sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,6 @@ public void testKeyboardInteractiveInSessionUserInteractiveFailure() throws Exce
15101510
CoreModuleProperties.PASSWORD_PROMPTS.set(client, maxPrompts);
15111511
AtomicInteger numberOfRequests = new AtomicInteger();
15121512
UserAuthKeyboardInteractiveFactory auth = new UserAuthKeyboardInteractiveFactory() {
1513-
15141513
@Override
15151514
public UserAuthKeyboardInteractive createUserAuth(ClientSession session) throws IOException {
15161515
return new UserAuthKeyboardInteractive() {

0 commit comments

Comments
 (0)