Last active
September 19, 2018 08:53
-
-
Save jeffbicca/1e7a9341b0f1b5f32afb to your computer and use it in GitHub Desktop.
A class that describes a simple SSH client, which allows remote commands and file upload through SFTP.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package utils; | |
import java.io.ByteArrayInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import net.sf.expectit.Expect; | |
import net.sf.expectit.ExpectBuilder; | |
import net.sf.expectit.matcher.Matchers; | |
import com.jcraft.jsch.Channel; | |
import com.jcraft.jsch.ChannelSftp; | |
import com.jcraft.jsch.JSch; | |
import com.jcraft.jsch.JSchException; | |
import com.jcraft.jsch.Session; | |
import com.jcraft.jsch.SftpException; | |
/** | |
* These 2 dependencies are required to run/compile this class: | |
* <dependency> | |
* <groupId>com.jcraft</groupId> | |
* <artifactId>jsch</artifactId> | |
* <version>0.1.51</version> | |
* </dependency> | |
* <dependency> | |
* <groupId>net.sf.expectit</groupId> | |
* <artifactId>expectit-core</artifactId> | |
* <version>0.5.0</version> | |
* </dependency> | |
**/ | |
public class SSH { | |
public enum ChannelType { | |
SHELL, SFTP; | |
public boolean isSftp() { | |
return this.equals(SFTP); | |
} | |
}; | |
private static final String HOST = "HOST"; | |
private static final String USERNAME = "USERNAME"; | |
private static final String PASSWORD = "PASSWD"; | |
public static final String FILENAME = "FILE"; | |
private Session session; | |
private Channel channel; | |
private ChannelType channelType = ChannelType.SHELL; | |
private Expect expect; | |
public SSH() throws JSchException, IOException { | |
initialize(); | |
} | |
public SSH(ChannelType channelType) throws JSchException, IOException { | |
this.channelType = channelType; | |
initialize(); | |
} | |
public String runCmd(String cmd, boolean... fetchResult) throws JSchException, IOException { | |
if (channelType.isSftp()) { | |
throw new UnsupportedOperationException("For the RUN operation, ChannelType must be SHELL."); | |
} | |
reconnectSSHIfNecessary(); | |
expect.sendLine(cmd).expect(Matchers.contains("$")); | |
return fetchResult.length > 0 && fetchResult[0] ? printResult() : ""; | |
} | |
public boolean put(byte[] file) throws FileNotFoundException, SftpException { | |
if (!channelType.isSftp()) { | |
throw new UnsupportedOperationException("For the PUT operation, ChannelType must be SFTP."); | |
} | |
ByteArrayInputStream bis = new ByteArrayInputStream(file); | |
((ChannelSftp) channel).put(bis, FILENAME + ".tar.gz"); | |
return true; | |
} | |
public void disconnect() throws JSchException, IOException { | |
if (channelType.isSftp()) { | |
((ChannelSftp) channel).exit(); | |
} else { | |
expect.sendLine("exit"); | |
expect.close(); | |
} | |
channel.disconnect(); | |
session.disconnect(); | |
} | |
private void initialize() throws JSchException, IOException { | |
JSch jSch = new JSch(); | |
session = jSch.getSession(USERNAME, HOST); | |
session.setPassword(PASSWORD); | |
session.setConfig("StrictHostKeyChecking", "no"); | |
session.connect(); | |
channel = session.openChannel(channelType.toString().toLowerCase()); | |
expect = new ExpectBuilder() | |
.withOutput(channel.getOutputStream()) | |
.withInputs(channel.getInputStream(), channel.getExtInputStream()) | |
.build(); | |
channel.connect(); | |
if (!channelType.isSftp()) { | |
runCmd("stty -echo"); | |
} | |
} | |
private void reconnectSSHIfNecessary() throws JSchException, IOException { | |
if (!session.isConnected() || channel.isClosed()) { | |
initialize(); | |
} | |
} | |
private String printResult() throws IOException { | |
expect.sendLine("exit"); | |
InputStream in = channel.getInputStream(); | |
int c; | |
String result = ""; | |
while ((c = in.read()) != -1) { | |
result += (char) c; | |
} | |
return result.substring(0, result.length()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.junit.Assert.assertTrue; | |
import java.io.IOException; | |
import java.io.RandomAccessFile; | |
import org.junit.Test; | |
import br.gov.infoseg.carga.desaparecidos.util.SSH; | |
import br.gov.infoseg.carga.desaparecidos.util.SSH.ChannelType; | |
import com.jcraft.jsch.JSchException; | |
import com.jcraft.jsch.SftpException; | |
public class SSHTest { | |
@Test | |
public void shouldConnectToSSHServerWithShell() throws JSchException, IOException { | |
SSH ssh = new SSH(); | |
String result = ssh.runCmd("pwd", true); | |
System.out.println(result); | |
String result2 = ssh.runCmd("ls -a -l", true); | |
System.out.println(result2); | |
ssh.disconnect(); | |
} | |
@Test | |
public void shouldConnectToTheServerWithSFTP() throws JSchException, SftpException, IOException { | |
SSH ssh = new SSH(ChannelType.SFTP); | |
RandomAccessFile file = new RandomAccessFile("file.tar.gz", "r"); | |
byte[] fileArray = new byte[(int) file.length()]; | |
file.read(fileArray); | |
file.close(); | |
assertTrue(ssh.put(fileArray)); | |
ssh.disconnect(); | |
ssh = new SSH(); | |
String result = ssh.runCmd(String.format("set -e; gzip -d %s.tar.gz; tar -xf %s.tar; rm %s.tar; echo \"SUCCESS\"", SSH.FILENAME, SSH.FILENAME, SSH.FILENAME), true); | |
System.out.println(result); | |
ssh.disconnect(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment