V1.0.3 One-time command reply and shell reply will use the same logic

master
Ng Yat Yan 1 month ago
parent e42de3b92a
commit 2af24c044e

@ -1,4 +1,4 @@
hello=hello prompt=$
5BAABD7C4581F90088133C0E945302C2=\t0\t0\t0 - 5BAABD7C4581F90088133C0E945302C2=\t0\t0\t0 -
uname=Linux uname=Linux
9DD46246144D353C914D7572AEDF8EA6=Linux mail.vidconnect.cyou 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:10 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux 9DD46246144D353C914D7572AEDF8EA6=Linux mail.vidconnect.cyou 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:10 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.example.sshd</groupId> <groupId>com.example.sshd</groupId>
<artifactId>echo-sshd-server</artifactId> <artifactId>echo-sshd-server</artifactId>
<version>1.0.2</version> <version>1.0.3</version>
<name>ECHO SSH SERVER</name> <name>ECHO SSH SERVER</name>
<description>Learning Apache Mina SSHD library</description> <description>Learning Apache Mina SSHD library</description>
<parent> <parent>

@ -5,23 +5,35 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Properties;
import java.util.UUID; import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.common.Factory; import org.apache.sshd.common.Factory;
import org.apache.sshd.server.Command; import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment; import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback; import org.apache.sshd.server.ExitCallback;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import com.example.sshd.util.ReplyUtil;
@Component
public class EchoShellFactory implements Factory<Command> { public class EchoShellFactory implements Factory<Command> {
private static final Logger logger = LoggerFactory.getLogger(EchoShellFactory.class); private static final Logger logger = LoggerFactory.getLogger(EchoShellFactory.class);
@Autowired
Properties repliesProperties;
@Autowired
ApplicationContext applicationContext;
@Override @Override
public Command create() { public Command create() {
return new EchoShell(); return new EchoShell(repliesProperties);
} }
public static class EchoShell implements Command, Runnable { public static class EchoShell implements Command, Runnable {
@ -32,6 +44,11 @@ public class EchoShellFactory implements Factory<Command> {
private ExitCallback callback; private ExitCallback callback;
private Environment environment; private Environment environment;
private Thread thread; private Thread thread;
private Properties repliesProperties;
public EchoShell(Properties repliesProperties) {
this.repliesProperties = repliesProperties;
}
public InputStream getIn() { public InputStream getIn() {
return in; return in;
@ -83,8 +100,9 @@ public class EchoShellFactory implements Factory<Command> {
@Override @Override
public void run() { public void run() {
String prompt = repliesProperties.getProperty("prompt","$ ");
try { try {
out.write("$ ".getBytes()); out.write(prompt.getBytes());
out.flush(); out.flush();
BufferedReader r = new BufferedReader(new InputStreamReader(in)); BufferedReader r = new BufferedReader(new InputStreamReader(in));
@ -93,16 +111,8 @@ public class EchoShellFactory implements Factory<Command> {
while (!Thread.currentThread().isInterrupted()) { while (!Thread.currentThread().isInterrupted()) {
int s = r.read(); int s = r.read();
if (s == 13 || s == 10) { if (s == 13 || s == 10) {
if (!ReplyUtil.replyToCommand(repliesProperties, command, out, prompt)) {
if (StringUtils.isBlank(command)) {
logger.info("Blank command detected: {}", command);
out.write(("\r\n$ ").getBytes());
} else if (StringUtils.equals(command, "exit")) {
logger.info("Exiting command detected: {}", command);
return; return;
} else {
logger.info("Command not found: {}", command);
out.write(("\r\nCommand '" + command + "' not found. Try 'exit'.\r\n$ ").getBytes());
} }
command = ""; command = "";
} else { } else {

@ -5,24 +5,20 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Properties; import java.util.Properties;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.server.Command; import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment; import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback; import org.apache.sshd.server.ExitCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.example.sshd.util.ReplyUtil;
@Component @Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class OnetimeCommand implements Command { public class OnetimeCommand implements Command {
private static final Logger logger = LoggerFactory.getLogger(OnetimeCommand.class);
@Autowired @Autowired
Properties repliesProperties; Properties repliesProperties;
@ -76,26 +72,7 @@ public class OnetimeCommand implements Command {
@Override @Override
public void start(Environment env) throws IOException { public void start(Environment env) throws IOException {
environment = env; environment = env;
String cmdHash = DigestUtils.md5Hex(command).toUpperCase(); ReplyUtil.replyToCommand(repliesProperties, command, out, "");
logger.info("command = {}, cmdHash = {}", command, cmdHash);
if (StringUtils.equals(command, "exit")) {
logger.info("Exiting command detected: {}", command);
out.write(("\r\nExiting...\r\n").getBytes());
} else if (repliesProperties.containsKey(command)) {
logger.info("Known command detected: {}", command);
String reply = repliesProperties.getProperty(command).replace("\\r", "\r").replace("\\n", "\n")
.replace("\\t", "\t");
out.write(("\r\n" + reply + "\r\n").getBytes());
} else if (repliesProperties.containsKey(cmdHash)) {
logger.info("Known command-hash detected: {}", cmdHash);
String reply = repliesProperties.getProperty(cmdHash).replace("\\r", "\r").replace("\\n", "\n")
.replace("\\t", "\t");
out.write(("\r\n" + reply + "\r\n").getBytes());
} else {
logger.info("Command not found: {}", command);
out.write(("\r\nCommand '" + command + "' not found. Try 'exit'.\r\n").getBytes());
}
out.flush(); out.flush();
callback.onExit(0); callback.onExit(0);
} }

@ -54,7 +54,7 @@ public class SshConfig {
return StringUtils.equals(username, rootUsername); return StringUtils.equals(username, rootUsername);
} }
}); });
sshd.setShellFactory(new EchoShellFactory()); sshd.setShellFactory(applicationContext.getBean(EchoShellFactory.class));
sshd.setCommandFactory(command -> applicationContext.getBean(OnetimeCommand.class, command)); sshd.setCommandFactory(command -> applicationContext.getBean(OnetimeCommand.class, command));
sshd.start(); sshd.start();
return sshd; return sshd;

@ -0,0 +1,41 @@
package com.example.sshd.util;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ReplyUtil {
private static final Logger logger = LoggerFactory.getLogger(ReplyUtil.class);
public static boolean replyToCommand(Properties repliesProperties, String command, OutputStream out, String prompt)
throws IOException {
String cmdHash = DigestUtils.md5Hex(command.trim()).toUpperCase();
if (StringUtils.equals(command.trim(), "exit")) {
logger.info("[{}] Exiting command detected: {}", cmdHash, command.trim());
out.write(("\r\nExiting...\r\n").getBytes());
return false;
} else if (repliesProperties.containsKey(command.trim())) {
logger.info("[{}] Known command detected: {}", cmdHash, command.trim());
String reply = repliesProperties.getProperty(command.trim()).replace("\\r", "\r").replace("\\n", "\n")
.replace("\\t", "\t");
out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes());
} else if (repliesProperties.containsKey(cmdHash)) {
logger.info("[{}] Known command-hash detected: {}", cmdHash, command.trim());
String reply = repliesProperties.getProperty(cmdHash).replace("\\r", "\r").replace("\\n", "\n")
.replace("\\t", "\t");
out.write(String.format("\r\n%s\r\n%s", reply, prompt).getBytes());
} else {
logger.info("[{}] Command not found: {}", cmdHash, command.trim());
out.write(String.format("\r\nCommand '%s' not found. Try 'exit'.\r\n%s", command.trim(), prompt).getBytes());
}
return true;
}
}
Loading…
Cancel
Save