Skip to content

Commit

Permalink
Clean ShellFactoryImpl logging, add a test (fixes #1060) (#1094)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet authored Oct 15, 2024
1 parent 275cca8 commit 130e764
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 30 deletions.
6 changes: 6 additions & 0 deletions remote-ssh/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,23 @@
import org.jline.terminal.Size;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* SSHD {@link org.apache.sshd.server.command.Command} factory which provides access to
* Shell.
*/
public class ShellFactoryImpl implements ShellFactory {

private static final Logger LOGGER = LoggerFactory.getLogger(ShellFactoryImpl.class);

private final Consumer<Ssh.ShellParams> shell;

public ShellFactoryImpl(Consumer<Ssh.ShellParams> shell) {
this.shell = shell;
}

private static void flush(OutputStream... streams) {
for (OutputStream s : streams) {
try {
s.flush();
} catch (IOException e) {
// Ignore
}
}
}

static void close(Closeable... closeables) {
for (Closeable c : closeables) {
try {
c.close();
} catch (IOException e) {
// Ignore
}
}
}

public Command createShell(ChannelSession session) {
return new ShellImpl();
}
Expand Down Expand Up @@ -95,20 +80,13 @@ public void setExitCallback(ExitCallback callback) {

public void start(final ChannelSession session, final Environment env) throws IOException {
try {
new Thread(() -> {
try {
ShellImpl.this.run(session, env);
} catch (Throwable t) {
t.printStackTrace();
}
})
.start();
new Thread(() -> ShellImpl.this.run(session, env)).start();
} catch (Exception e) {
throw new IOException("Unable to start shell", e);
}
}

public void run(ChannelSession session, Environment env) throws Exception {
public void run(ChannelSession session, Environment env) {
try {
Attributes attributes = new Attributes();
for (Map.Entry<PtyMode, Integer> e : env.getPtyModes().entrySet()) {
Expand Down Expand Up @@ -222,7 +200,9 @@ public void run(ChannelSession session, Environment env) throws Exception {

shell.accept(new Ssh.ShellParams(env.getEnv(), session.getSession(), terminal, () -> destroy(session)));
} catch (Throwable t) {
t.printStackTrace();
if (!closed) {
LOGGER.error("Error occured while executing shell", t);
}
}
}

Expand All @@ -235,4 +215,24 @@ public void destroy(ChannelSession session) {
}
}
}

static void flush(OutputStream... streams) {
for (OutputStream s : streams) {
try {
s.flush();
} catch (IOException e) {
LOGGER.debug("Error flushing " + s, e);
}
}
}

static void close(Closeable... closeables) {
for (Closeable c : closeables) {
try {
c.close();
} catch (IOException e) {
LOGGER.debug("Error closing " + c, e);
}
}
}
}
70 changes: 70 additions & 0 deletions remote-ssh/src/test/java/org/jline/builtins/ssh/SshdTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2002-2024, the original author(s).
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* https://opensource.org/licenses/BSD-3-Clause
*/
package org.jline.builtins.ssh;

import java.nio.file.Paths;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.UserInterruptException;
import org.junit.jupiter.api.Test;

public class SshdTest {

@Test
void test() throws Exception {
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(0);
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Paths.get("target/hostkey.ser")));
sshd.setPasswordAuthenticator((username, password, session) -> true);
sshd.setShellFactory(new ShellFactoryImpl(shellParams -> {
LineReader reader = LineReaderBuilder.builder()
.terminal(shellParams.getTerminal())
.build();

try {
String line;
reader.printAbove("Welcome to SSH Server");
while ((line = reader.readLine("sshTest > ")) != null) {
System.out.println(line);
}
} catch (UserInterruptException e) {
// Ignore
} catch (EndOfFileException e) {
// Ignore
} catch (Exception e) {
// ignore OTHER EXCEPTIONS
}
}));

// Start the server
sshd.start();
System.out.println("SSH Server started on port 2222");

SshClient client = SshClient.setUpDefaultClient();
client.start();
ClientSession session =
client.connect("test", "localhost", sshd.getPort()).verify().getClientSession();
session.addPasswordIdentity("foo");
session.auth().verify();
ChannelShell shell = session.createShellChannel();
shell.open().verify();
shell.getInvertedIn().write("echo foo\n".getBytes());
shell.close();
client.close();

Thread.sleep(1000);
}
}

0 comments on commit 130e764

Please sign in to comment.