V2.0.0 Extend this SSH server to be a XMPP Component

master
Ng Yat Yan 2 months ago
parent 9b10cbe9b7
commit 10ff309803

@ -0,0 +1,8 @@
{
"subdomainPrefix": "echo",
"domain": "vidconnect.cyou",
"host": "localhost",
"port": 5270,
"secretKey": "user-admin_secret",
"startEncrypted": false
}

@ -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"

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.sshd</groupId>
<artifactId>echo-sshd-server</artifactId>
<version>1.5.0</version>
<version>2.0.0</version>
<name>ECHO SSH SERVER</name>
<description>Learning Apache Mina SSHD library</description>
<parent>
@ -16,10 +16,23 @@
<java.version>17</java.version>
<mina.version>2.0.25</mina.version>
<sshd.version>0.14.0</sshd.version>
<whack.version>2.0.1</whack.version>
<jackson.version>2.17.1</jackson.version>
<commons-io.version>2.17.0</commons-io.version>
<commons-exec.version>1.4.0</commons-exec.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.16.1</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -31,6 +44,18 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
@ -72,14 +97,15 @@
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
<groupId>org.igniterealtime.whack</groupId>
<artifactId>core</artifactId>
<version>${whack.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

@ -1,5 +1,6 @@
package com.example.sshd.config;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -9,14 +10,28 @@ 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 {
@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<String, Session> remoteSessionMapping() {

@ -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 "{}";
}
}

@ -0,0 +1,66 @@
package com.example.sshd.service;
import org.apache.commons.lang3.StringUtils;
import org.jivesoftware.whack.ExternalComponentManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xmpp.component.AbstractComponent;
import org.xmpp.component.ComponentException;
import org.xmpp.packet.Message;
import com.example.sshd.config.XmppComponentConfig;
import jakarta.annotation.PostConstruct;
@Component
public class EchoComponent extends AbstractComponent {
private static final Logger logger = LoggerFactory.getLogger(EchoComponent.class);
@Autowired
XmppComponentConfig xmppComponentConfig;
ExternalComponentManager externalComponentManager = null;
@PostConstruct
public void init() throws ComponentException {
logger.info("Starting up {} ...", xmppComponentConfig);
externalComponentManager = new ExternalComponentManager(xmppComponentConfig.getHost(),
xmppComponentConfig.getPort(), xmppComponentConfig.isStartEncrypted());
externalComponentManager.setMultipleAllowed(xmppComponentConfig.getSubdomainPrefix(), false);
externalComponentManager.setServerName(xmppComponentConfig.getDomain());
externalComponentManager.setSecretKey(xmppComponentConfig.getSubdomainPrefix(),
xmppComponentConfig.getSecretKey());
externalComponentManager.addComponent(xmppComponentConfig.getSubdomainPrefix(), this,
xmppComponentConfig.getPort());
}
@Override
public String getDescription() {
return "XMPP component for doing ECHO";
}
@Override
public String getName() {
return this.getClass().getName();
}
protected void handleMessage(final Message inMsg) {
logger.info("-- RECEIVED -- {}", inMsg);
Message outMsg = new Message();
outMsg.setType(inMsg.getType());
outMsg.setFrom(inMsg.getTo());
if (StringUtils.endsWith(inMsg.getSubject(), "@" + xmppComponentConfig.getDomain())) {
outMsg.setTo(inMsg.getSubject());
} else {
outMsg.setTo(inMsg.getFrom());
}
outMsg.setSubject(inMsg.getSubject());
outMsg.setBody(inMsg.getBody());
externalComponentManager.sendPacket(this, outMsg);
logger.info("-- SENT -- {}", outMsg);
}
}

@ -65,7 +65,8 @@ public class JmxClientService {
}
jmxc.close();
} else {
output.append("Example: jmx_client service:jmx:rmi:///jndi/rmi://127.0.0.1:2020/jmxrmi java.lang:type=Memory HeapMemoryUsage\r\n");
output.append(
"Example: jmx_client service:jmx:rmi:///jndi/rmi://127.0.0.1:2020/jmxrmi java.lang:type=Memory HeapMemoryUsage\r\n");
}
} catch (Exception e) {
logger.error("process cmd failed: {}", Arrays.asList(args), e);

Loading…
Cancel
Save