mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
9461336639
commit
6b4c5ede6a
@ -86,7 +86,9 @@ public class GanymedSession implements Session {
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
@ -99,7 +101,9 @@ public class GanymedSession implements Session {
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
@ -116,7 +120,7 @@ public class GanymedSession implements Session {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
if(null == this.localPortForwarderMap){
|
||||
if (null == this.localPortForwarderMap) {
|
||||
this.localPortForwarderMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@ -133,12 +137,12 @@ public class GanymedSession implements Session {
|
||||
* @throws IORuntimeException 端口解绑失败异常
|
||||
*/
|
||||
public void unBindLocalPort(final int localPort) throws IORuntimeException {
|
||||
if(MapUtil.isEmpty(this.localPortForwarderMap)){
|
||||
if (MapUtil.isEmpty(this.localPortForwarderMap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalPortForwarder localPortForwarder = this.localPortForwarderMap.remove(localPort);
|
||||
if(null != localPortForwarder){
|
||||
if (null != localPortForwarder) {
|
||||
try {
|
||||
localPortForwarder.close();
|
||||
} catch (final IOException e) {
|
||||
|
@ -76,7 +76,9 @@ public class JschSession implements Session {
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
@ -89,7 +91,9 @@ public class JschSession implements Session {
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
|
@ -13,15 +13,26 @@
|
||||
package org.dromara.hutool.extra.ssh.engine.sshj;
|
||||
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
import net.schmizz.sshj.connection.channel.direct.Parameters;
|
||||
import net.schmizz.sshj.connection.channel.forwarded.RemotePortForwarder;
|
||||
import net.schmizz.sshj.connection.channel.forwarded.SocketForwardingConnectListener;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.net.Ipv4Util;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
import org.dromara.hutool.extra.ssh.Session;
|
||||
import org.dromara.hutool.extra.ssh.SshException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 基于SSHJ(https://github.com/hierynomus/sshj)的Session封装
|
||||
@ -33,6 +44,8 @@ public class SshjSession implements Session {
|
||||
private SSHClient ssh;
|
||||
private final net.schmizz.sshj.connection.channel.direct.Session raw;
|
||||
|
||||
private Map<Integer, ServerSocket> localPortForwarderMap;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
@ -56,15 +69,6 @@ public class SshjSession implements Session {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param raw {@link net.schmizz.sshj.connection.channel.direct.Session}
|
||||
*/
|
||||
public SshjSession(final net.schmizz.sshj.connection.channel.direct.Session raw) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.schmizz.sshj.connection.channel.direct.Session getRaw() {
|
||||
return raw;
|
||||
@ -85,6 +89,121 @@ public class SshjSession implements Session {
|
||||
IoUtil.closeQuietly(this.ssh);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开SFTP会话
|
||||
*
|
||||
* @param charset 编码
|
||||
* @return {@link SshjSftp}
|
||||
*/
|
||||
public SshjSftp openSftp(final Charset charset) {
|
||||
return new SshjSftp(this.ssh, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws SshException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final int localPort) throws SshException {
|
||||
return bindLocalPort(remoteHost, remotePort, Ipv4Util.LOCAL_IP, localPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口<br>
|
||||
* 当请求localHost:localPort时,通过SSH到服务器,转发请求到remoteHost:remotePort<br>
|
||||
* 此方法用于访问本地无法访问但是服务器可以访问的地址,如内网数据库库等
|
||||
*
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localHost 本地主机
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws IORuntimeException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindLocalPort(final String remoteHost, final int remotePort, final String localHost, final int localPort) throws IORuntimeException {
|
||||
final Parameters params = new Parameters(localHost, localPort, remoteHost, remotePort);
|
||||
final ServerSocket ss;
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.setReuseAddress(true);
|
||||
ss.bind(new InetSocketAddress(params.getLocalHost(), params.getLocalPort()));
|
||||
ssh.newLocalPortForwarder(params, ss).listen();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
||||
if (null == this.localPortForwarderMap) {
|
||||
this.localPortForwarderMap = new HashMap<>();
|
||||
}
|
||||
|
||||
//加入记录
|
||||
this.localPortForwarderMap.put(localPort, ss);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除本地端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
* @throws IORuntimeException 端口解绑失败异常
|
||||
*/
|
||||
public void unBindLocalPort(final int localPort) throws IORuntimeException {
|
||||
if (MapUtil.isEmpty(this.localPortForwarderMap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
IoUtil.closeQuietly(this.localPortForwarderMap.remove(localPort));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定ssh服务端的serverPort端口, 到host主机的port端口上. <br>
|
||||
* 即数据从ssh服务端的serverPort端口, 流经ssh客户端, 达到host:port上.
|
||||
*
|
||||
* @param bindPort ssh服务端上要被绑定的端口
|
||||
* @param host 转发到的host
|
||||
* @param port host上的端口
|
||||
* @return 成功与否
|
||||
* @throws IORuntimeException 端口绑定失败异常
|
||||
*/
|
||||
public boolean bindRemotePort(final int bindPort, final String host, final int port) throws IORuntimeException {
|
||||
try {
|
||||
this.ssh.getRemotePortForwarder().bind(
|
||||
new RemotePortForwarder.Forward(bindPort),
|
||||
new SocketForwardingConnectListener(new InetSocketAddress(host, port))
|
||||
);
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除远程端口映射
|
||||
*
|
||||
* @param localPort 需要解除的本地端口
|
||||
*/
|
||||
public void unBindRemotePort(final int localPort) {
|
||||
final RemotePortForwarder remotePortForwarder = this.ssh.getRemotePortForwarder();
|
||||
final Set<RemotePortForwarder.Forward> activeForwards = remotePortForwarder.getActiveForwards();
|
||||
for (final RemotePortForwarder.Forward activeForward : activeForwards) {
|
||||
if (localPort == activeForward.getPort()) {
|
||||
try {
|
||||
remotePortForwarder.cancel(activeForward);
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Shell命令(使用EXEC方式)
|
||||
* <p>
|
||||
|
@ -12,19 +12,19 @@
|
||||
|
||||
package org.dromara.hutool.extra.ssh.engine.sshj;
|
||||
|
||||
import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.extra.ftp.AbstractFtp;
|
||||
import org.dromara.hutool.extra.ftp.FtpConfig;
|
||||
import org.dromara.hutool.extra.ftp.FtpException;
|
||||
import net.schmizz.sshj.SSHClient;
|
||||
import net.schmizz.sshj.connection.channel.direct.Session;
|
||||
import net.schmizz.sshj.sftp.RemoteResourceInfo;
|
||||
import net.schmizz.sshj.sftp.SFTPClient;
|
||||
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
|
||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||
import org.dromara.hutool.core.collection.CollUtil;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.extra.ftp.AbstractFtp;
|
||||
import org.dromara.hutool.extra.ftp.FtpConfig;
|
||||
import org.dromara.hutool.extra.ftp.FtpException;
|
||||
import org.dromara.hutool.extra.ssh.Connector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -99,11 +99,22 @@ public class SshjSftp extends AbstractFtp {
|
||||
* @param config FTP配置
|
||||
* @since 5.3.3
|
||||
*/
|
||||
protected SshjSftp(final FtpConfig config) {
|
||||
public SshjSftp(final FtpConfig config) {
|
||||
super(config);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param sshClient {@link SSHClient}
|
||||
* @param charset 编码
|
||||
*/
|
||||
public SshjSftp(final SSHClient sshClient, final Charset charset) {
|
||||
super(FtpConfig.of().setCharset(charset));
|
||||
this.ssh = sshClient;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* SSH 初始化并创建一个sftp客户端.
|
||||
*
|
||||
@ -111,11 +122,14 @@ public class SshjSftp extends AbstractFtp {
|
||||
* @since 5.7.18
|
||||
*/
|
||||
public void init() {
|
||||
this.ssh = new SSHClient();
|
||||
ssh.addHostKeyVerifier(new PromiscuousVerifier());
|
||||
this.ssh = SshjUtil.openClient(new Connector(
|
||||
ftpConfig.getHost(),
|
||||
ftpConfig.getPort(),
|
||||
ftpConfig.getUser(),
|
||||
ftpConfig.getPassword(),
|
||||
ftpConfig.getConnectionTimeout()));
|
||||
|
||||
try {
|
||||
ssh.connect(ftpConfig.getHost(), ftpConfig.getPort());
|
||||
ssh.authPassword(ftpConfig.getUser(), ftpConfig.getPassword());
|
||||
ssh.setRemoteCharset(ftpConfig.getCharset());
|
||||
this.sftp = ssh.newSFTPClient();
|
||||
} catch (final IOException e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user