diff --git a/conf/log4j2.xml b/conf/log4j2.xml
index 6b237ca..f0fde93 100644
--- a/conf/log4j2.xml
+++ b/conf/log4j2.xml
@@ -26,10 +26,10 @@
-
+
-
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3986876..4a91e89 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.example.sshd
echo-sshd-server
- 1.1.0
+ 1.1.1
ECHO SSH SERVER
Learning Apache Mina SSHD library
diff --git a/src/main/java/com/example/sshd/config/AppConfig.java b/src/main/java/com/example/sshd/config/AppConfig.java
new file mode 100644
index 0000000..cbc418a
--- /dev/null
+++ b/src/main/java/com/example/sshd/config/AppConfig.java
@@ -0,0 +1,21 @@
+package com.example.sshd.config;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sshd.common.Session;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+
+@Configuration
+public class AppConfig {
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public Map remoteSessionMapping() {
+ return Collections.synchronizedMap(new HashMap<>());
+ }
+}
diff --git a/src/main/java/com/example/sshd/config/SshConfig.java b/src/main/java/com/example/sshd/config/SshConfig.java
index 14ad355..710291b 100644
--- a/src/main/java/com/example/sshd/config/SshConfig.java
+++ b/src/main/java/com/example/sshd/config/SshConfig.java
@@ -4,9 +4,9 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
import java.util.Properties;
-import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.SshServer;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
@@ -21,6 +21,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
+import com.example.sshd.core.EchoSessionListener;
import com.example.sshd.core.EchoShellFactory;
import com.example.sshd.core.OnetimeCommand;
@@ -35,8 +36,8 @@ public class SshConfig {
@Value("${ssh-server.private-key.location}")
private String pkLocation;
- @Value("${ssh-server.root.username:root}")
- private String rootUsername;
+ @Value("${ssh-server.login.usernames:root}")
+ private String[] usernames;
@Value("${ssh-server.hash-replies.location}")
private String hashReplies;
@@ -57,12 +58,14 @@ public class SshConfig {
@Override
public boolean authenticate(final String username, final String password, final ServerSession session) {
logger.info("Login Attempt: username = {}, password = {}", username, password);
- return StringUtils.equals(username, rootUsername);
+ return Arrays.asList(usernames).contains(username);
}
});
sshd.setShellFactory(applicationContext.getBean(EchoShellFactory.class));
sshd.setCommandFactory(command -> applicationContext.getBean(OnetimeCommand.class, command));
+
sshd.start();
+ sshd.getSessionFactory().addListener(applicationContext.getBean(EchoSessionListener.class));
return sshd;
}
diff --git a/src/main/java/com/example/sshd/core/EchoSessionListener.java b/src/main/java/com/example/sshd/core/EchoSessionListener.java
new file mode 100644
index 0000000..7fd14ed
--- /dev/null
+++ b/src/main/java/com/example/sshd/core/EchoSessionListener.java
@@ -0,0 +1,46 @@
+package com.example.sshd.core;
+
+import java.net.InetSocketAddress;
+import java.util.Map;
+
+import org.apache.sshd.common.Session;
+import org.apache.sshd.common.SessionListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EchoSessionListener implements SessionListener {
+
+ private static final Logger logger = LoggerFactory.getLogger(EchoSessionListener.class);
+
+ @Autowired
+ Map remoteSessionMapping;
+
+ @Override
+ public void sessionCreated(Session session) {
+ logger.info("sessionCreated: {}", session);
+ if (session.getIoSession().getRemoteAddress() instanceof InetSocketAddress) {
+ InetSocketAddress remoteAddress = (InetSocketAddress) session.getIoSession().getRemoteAddress();
+ String remoteIpAddress = remoteAddress.getAddress().getHostAddress();
+ if (remoteSessionMapping.containsKey(remoteIpAddress)) {
+ logger.info("kill old session: {} -> {}", remoteIpAddress, remoteSessionMapping.get(remoteIpAddress));
+ remoteSessionMapping.get(remoteIpAddress).close(false);
+ }
+ logger.info("new session: {} -> {}", remoteIpAddress, session);
+ remoteSessionMapping.put(remoteIpAddress, session);
+ }
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ logger.info("sessionEvent: {}, event: {}", session, event);
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ logger.info("sessionCreated: {}", session);
+ }
+
+}