diff --git a/conf/echo-component.json b/conf/echo-component.json
new file mode 100644
index 0000000..426306d
--- /dev/null
+++ b/conf/echo-component.json
@@ -0,0 +1,8 @@
+{
+ "subdomainPrefix": "echo",
+ "domain": "vidconnect.cyou",
+ "host": "localhost",
+ "port": 5270,
+ "secretKey": "user-admin_secret",
+ "startEncrypted": false
+}
\ No newline at end of file
diff --git a/conf/springboot.yml b/conf/springboot.yml
index 70f792f..3bbd273 100644
--- a/conf/springboot.yml
+++ b/conf/springboot.yml
@@ -6,7 +6,8 @@ ssh-server:
location: "conf/hash-replies.properties"
regex-mapping:
location: "conf/regex-mapping.properties"
-
+xmpp-component:
+ config-json: "conf/echo-component.json"
spring:
datasource:
url: "jdbc:h2:file:./data/remote-ip-info-db"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d0f4e0d..e1e09c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.example.sshd
echo-sshd-server
- 1.5.0
+ 2.0.0
ECHO SSH SERVER
Learning Apache Mina SSHD library
@@ -16,10 +16,23 @@
17
2.0.25
0.14.0
+ 2.0.1
+ 2.17.1
2.17.0
1.4.0
3.17.0
+
+
+
+ com.fasterxml.jackson
+ jackson-bom
+ 2.16.1
+ import
+ pom
+
+
+
org.springframework.boot
@@ -31,6 +44,18 @@
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
org.springframework.boot
spring-boot-starter-log4j2
@@ -45,13 +70,13 @@
runtime
- org.apache.commons
- commons-exec
- ${commons-exec.version}
+ org.apache.commons
+ commons-exec
+ ${commons-exec.version}
- org.apache.commons
- commons-lang3
+ org.apache.commons
+ commons-lang3
commons-codec
@@ -73,12 +98,13 @@
${commons-io.version}
- org.apache.commons
- commons-lang3
+ org.apache.httpcomponents.client5
+ httpclient5
- org.apache.httpcomponents.client5
- httpclient5
+ org.igniterealtime.whack
+ core
+ ${whack.version}
junit
diff --git a/src/main/java/com/example/sshd/Boot.java b/src/main/java/com/example/sshd/Boot.java
index 35947ce..74bb9ef 100644
--- a/src/main/java/com/example/sshd/Boot.java
+++ b/src/main/java/com/example/sshd/Boot.java
@@ -10,22 +10,22 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Boot {
- private static final Logger logger = LoggerFactory.getLogger(Boot.class);
+ private static final Logger logger = LoggerFactory.getLogger(Boot.class);
- @Autowired
- protected SshServer sshd;
+ @Autowired
+ protected SshServer sshd;
- public static void main(String[] args) throws Exception {
- String configDirectory = "conf";
- if (args.length > 0) {
- configDirectory = args[0];
- }
- logger.info("config directory: {}", configDirectory);
+ public static void main(String[] args) throws Exception {
+ String configDirectory = "conf";
+ if (args.length > 0) {
+ configDirectory = args[0];
+ }
+ logger.info("config directory: {}", configDirectory);
- if (new java.io.File(configDirectory).exists() && new java.io.File(configDirectory).isDirectory()) {
- System.setProperty("spring.config.location", configDirectory + "/springboot.yml");
- System.setProperty("logging.config", configDirectory + "/log4j2.xml");
- }
- SpringApplication.run(Boot.class, args);
+ if (new java.io.File(configDirectory).exists() && new java.io.File(configDirectory).isDirectory()) {
+ System.setProperty("spring.config.location", configDirectory + "/springboot.yml");
+ System.setProperty("logging.config", configDirectory + "/log4j2.xml");
}
+ SpringApplication.run(Boot.class, args);
+ }
}
diff --git a/src/main/java/com/example/sshd/config/AppConfig.java b/src/main/java/com/example/sshd/config/AppConfig.java
index 0ed9afb..e13ac8d 100644
--- a/src/main/java/com/example/sshd/config/AppConfig.java
+++ b/src/main/java/com/example/sshd/config/AppConfig.java
@@ -1,5 +1,6 @@
package com.example.sshd.config;
+import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -9,36 +10,50 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.sshd.common.Session;
+import org.springframework.beans.factory.annotation.Value;
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;
+import com.fasterxml.jackson.core.exc.StreamReadException;
+import com.fasterxml.jackson.databind.DatabindException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
@Configuration
public class AppConfig {
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
- public Map remoteSessionMapping() {
- return new ConcurrentHashMap<>();
- }
-
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
- public Map ipInfoMapping() {
- return new ConcurrentHashMap<>();
- }
-
- @Bean
- public CloseableHttpAsyncClient asyncClient() {
- final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().build();
- final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setIOReactorConfig(ioReactorConfig).build();
- client.start();
- return client;
- }
-
- @Bean
- public CloseableHttpClient httpClient() {
- return HttpClients.createDefault();
- }
+ @Value("${xmpp-component.config-json}")
+ private String xmppComponentConfigJson;
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public XmppComponentConfig xmppComponentConfig() throws StreamReadException, DatabindException, IOException {
+ return new ObjectMapper().readValue(new java.io.File(xmppComponentConfigJson), XmppComponentConfig.class);
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public Map remoteSessionMapping() {
+ return new ConcurrentHashMap<>();
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public Map ipInfoMapping() {
+ return new ConcurrentHashMap<>();
+ }
+
+ @Bean
+ public CloseableHttpAsyncClient asyncClient() {
+ final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().build();
+ final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setIOReactorConfig(ioReactorConfig).build();
+ client.start();
+ return client;
+ }
+
+ @Bean
+ public CloseableHttpClient httpClient() {
+ return HttpClients.createDefault();
+ }
}
diff --git a/src/main/java/com/example/sshd/config/SshConfig.java b/src/main/java/com/example/sshd/config/SshConfig.java
index e8b2259..a68ad48 100644
--- a/src/main/java/com/example/sshd/config/SshConfig.java
+++ b/src/main/java/com/example/sshd/config/SshConfig.java
@@ -29,72 +29,72 @@ import com.example.sshd.core.OnetimeCommand;
@Configuration
public class SshConfig {
- private static final Logger loginLogger = LoggerFactory.getLogger("login");
-
- @Value("${ssh-server.port}")
- private int port;
-
- @Value("${ssh-server.private-key.location}")
- private String pkLocation;
-
- @Value("${ssh-server.login.usernames:root}")
- private String[] usernames;
-
- @Value("${ssh-server.hash-replies.location}")
- private String hashReplies;
-
- @Value("${ssh-server.regex-mapping.location}")
- private String regexMapping;
-
- @Autowired
- ApplicationContext applicationContext;
-
- @Bean
- public SshServer sshd() throws IOException, NoSuchAlgorithmException {
- SshServer sshd = SshServer.setUpDefaultServer();
- sshd.setPort(port);
- sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File(pkLocation).getPath(), "RSA", 2048));
-
- sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- if (session.getIoSession().getRemoteAddress() instanceof InetSocketAddress) {
- InetSocketAddress remoteAddress = (InetSocketAddress) session.getIoSession().getRemoteAddress();
- String remoteIpAddress = remoteAddress.getAddress().getHostAddress();
- loginLogger.info("[{}] Login Attempt: username = {}, password = {}", remoteIpAddress, username,
- password);
- } else {
- loginLogger.info("[{}] Login Attempt: username = {}, password = {}",
- session.getIoSession().getRemoteAddress(), username, password);
- }
- 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;
- }
-
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
- public Properties hashReplies() throws IOException {
- Properties prop = new Properties();
- File configFile = new File(hashReplies);
- FileInputStream stream = new FileInputStream(configFile);
- prop.load(stream);
- return prop;
- }
-
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
- public Properties regexMapping() throws IOException {
- Properties prop = new Properties();
- File configFile = new File(regexMapping);
- FileInputStream stream = new FileInputStream(configFile);
- prop.load(stream);
- return prop;
- }
+ private static final Logger loginLogger = LoggerFactory.getLogger("login");
+
+ @Value("${ssh-server.port}")
+ private int port;
+
+ @Value("${ssh-server.private-key.location}")
+ private String pkLocation;
+
+ @Value("${ssh-server.login.usernames:root}")
+ private String[] usernames;
+
+ @Value("${ssh-server.hash-replies.location}")
+ private String hashReplies;
+
+ @Value("${ssh-server.regex-mapping.location}")
+ private String regexMapping;
+
+ @Autowired
+ ApplicationContext applicationContext;
+
+ @Bean
+ public SshServer sshd() throws IOException, NoSuchAlgorithmException {
+ SshServer sshd = SshServer.setUpDefaultServer();
+ sshd.setPort(port);
+ sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File(pkLocation).getPath(), "RSA", 2048));
+
+ sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
+ @Override
+ public boolean authenticate(final String username, final String password, final ServerSession session) {
+ if (session.getIoSession().getRemoteAddress() instanceof InetSocketAddress) {
+ InetSocketAddress remoteAddress = (InetSocketAddress) session.getIoSession().getRemoteAddress();
+ String remoteIpAddress = remoteAddress.getAddress().getHostAddress();
+ loginLogger.info("[{}] Login Attempt: username = {}, password = {}", remoteIpAddress, username,
+ password);
+ } else {
+ loginLogger.info("[{}] Login Attempt: username = {}, password = {}",
+ session.getIoSession().getRemoteAddress(), username, password);
+ }
+ 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;
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public Properties hashReplies() throws IOException {
+ Properties prop = new Properties();
+ File configFile = new File(hashReplies);
+ FileInputStream stream = new FileInputStream(configFile);
+ prop.load(stream);
+ return prop;
+ }
+
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+ public Properties regexMapping() throws IOException {
+ Properties prop = new Properties();
+ File configFile = new File(regexMapping);
+ FileInputStream stream = new FileInputStream(configFile);
+ prop.load(stream);
+ return prop;
+ }
}
diff --git a/src/main/java/com/example/sshd/config/XmppComponentConfig.java b/src/main/java/com/example/sshd/config/XmppComponentConfig.java
new file mode 100644
index 0000000..8b63476
--- /dev/null
+++ b/src/main/java/com/example/sshd/config/XmppComponentConfig.java
@@ -0,0 +1,78 @@
+package com.example.sshd.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class XmppComponentConfig {
+
+ private static final Logger logger = LoggerFactory.getLogger(XmppComponentConfig.class);
+
+ private String subdomainPrefix;
+ private String domain;
+ private String host;
+ private int port;
+ private String secretKey;
+ private boolean startEncrypted;
+
+ public String getSubdomainPrefix() {
+ return subdomainPrefix;
+ }
+
+ public void setSubdomainPrefix(String subdomainPrefix) {
+ this.subdomainPrefix = subdomainPrefix;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+
+ public boolean isStartEncrypted() {
+ return startEncrypted;
+ }
+
+ public void setStartEncrypted(boolean startEncrypted) {
+ this.startEncrypted = startEncrypted;
+ }
+
+ @Override
+ @JsonIgnore
+ public String toString() {
+ try {
+ return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
+ } catch (JsonProcessingException e) {
+ logger.error("convert to json error!", e);
+ }
+ return "{}";
+ }
+}
diff --git a/src/main/java/com/example/sshd/core/EchoSessionListener.java b/src/main/java/com/example/sshd/core/EchoSessionListener.java
index aecf521..244382a 100644
--- a/src/main/java/com/example/sshd/core/EchoSessionListener.java
+++ b/src/main/java/com/example/sshd/core/EchoSessionListener.java
@@ -17,66 +17,66 @@ import com.example.sshd.service.JdbcService;
@Component
public class EchoSessionListener implements SessionListener {
- private static final Logger logger = LoggerFactory.getLogger(EchoSessionListener.class);
- private static final Logger ipInfoLogger = LoggerFactory.getLogger("ip_info");
+ private static final Logger logger = LoggerFactory.getLogger(EchoSessionListener.class);
+ private static final Logger ipInfoLogger = LoggerFactory.getLogger("ip_info");
- @Autowired
- Map remoteSessionMapping;
+ @Autowired
+ Map remoteSessionMapping;
- @Autowired
- Map ipInfoMapping;
+ @Autowired
+ Map ipInfoMapping;
- @Autowired
- GeoIpLocator geoIpLocator;
+ @Autowired
+ GeoIpLocator geoIpLocator;
- @Autowired
- JdbcService jdbcService;
+ @Autowired
+ JdbcService jdbcService;
- @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);
- if (!ipInfoMapping.containsKey(remoteIpAddress)) {
- List