V1.1.1 Only one session is allowed. New session will override the old.

master
Ng Yat Yan 1 month ago
parent 53e9f25a1d
commit d56240cb41

@ -26,10 +26,10 @@
</Appenders> </Appenders>
<Loggers> <Loggers>
<Logger name="not_found" level="info" additivity="false"> <Logger name="not_found" level="info" additivity="false">
<AppenderRef ref="LogToNotFound" /> <AppenderRef ref="LogToConsole" />
</Logger> </Logger>
<Root level="info"> <Root level="info">
<AppenderRef ref="LogToFile" /> <AppenderRef ref="LogToConsole" />
</Root> </Root>
</Loggers> </Loggers>
</Configuration> </Configuration>

@ -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.1.0</version> <version>1.1.1</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>

@ -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<String, Session> remoteSessionMapping() {
return Collections.synchronizedMap(new HashMap<>());
}
}

@ -4,9 +4,9 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Properties; import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.sshd.SshServer; import org.apache.sshd.SshServer;
import org.apache.sshd.server.PasswordAuthenticator; import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; 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.Configuration;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import com.example.sshd.core.EchoSessionListener;
import com.example.sshd.core.EchoShellFactory; import com.example.sshd.core.EchoShellFactory;
import com.example.sshd.core.OnetimeCommand; import com.example.sshd.core.OnetimeCommand;
@ -35,8 +36,8 @@ public class SshConfig {
@Value("${ssh-server.private-key.location}") @Value("${ssh-server.private-key.location}")
private String pkLocation; private String pkLocation;
@Value("${ssh-server.root.username:root}") @Value("${ssh-server.login.usernames:root}")
private String rootUsername; private String[] usernames;
@Value("${ssh-server.hash-replies.location}") @Value("${ssh-server.hash-replies.location}")
private String hashReplies; private String hashReplies;
@ -57,12 +58,14 @@ public class SshConfig {
@Override @Override
public boolean authenticate(final String username, final String password, final ServerSession session) { public boolean authenticate(final String username, final String password, final ServerSession session) {
logger.info("Login Attempt: username = {}, password = {}", username, password); 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.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();
sshd.getSessionFactory().addListener(applicationContext.getBean(EchoSessionListener.class));
return sshd; return sshd;
} }

@ -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<String, Session> 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);
}
}
Loading…
Cancel
Save