It is relatively hard to find code examples in Internet regarding SFTP and SSH in java.
Here I have written an example to demonstrate its usage.
Key points
- I make use of J2SSH v0.2.2
- The demonstration program is capable of
- acting as a ssh mini shell
- run a batch of simple sftp commands stored in a specified file
- run a batch of simple ssh command stored in a specified file (not yet finished)
Remark:
- Please note that the crew who made J2SSH has already totally rewritten all of its functions and make it available at commercial market
- Please do test the speed of the prototype before you decide on whether to use this package. We have tested that it is generally at least 10% slower than sftp version in Unix.
Usage
Application :Sftp/SSH client |
Code snippet
Mini Shell Code Segment
public static void miniShell()
{
try {
// JDK > 1.4 ONLY
/*Handler fh = new FileHandler("example.log");
fh.setFormatter(new SimpleFormatter());
Logger.getLogger("com.sshtools").setUseParentHandlers(false);
Logger.getLogger("com.sshtools").addHandler(fh);
Logger.getLogger("com.sshtools").setLevel(Level.ALL);*/
// Configure J2SSH (This will attempt to install the bouncycastle provider
// under jdk 1.3.1)
ConfigurationLoader.initialize(false);
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("Connect to host? ");
String hostname = reader.readLine();
// Make a client connection
SshClient ssh = new SshClient();
ssh.setSocketTimeout(30000);
SshConnectionProperties properties = new SshConnectionProperties();
properties.setHost(hostname);
properties.setPrefPublicKey("ssh-dss");
// Connect to the host
ssh.connect(properties);
// Create a password authentication instance
PasswordAuthenticationClient pwd = new PasswordAuthenticationClient();
// Get the users name
System.out.print("Username? ");
// Read the password
String username = reader.readLine();
pwd.setUsername(username);
// Get the password
System.out.print("Password? ");
String password = reader.readLine();
pwd.setPassword(password);
// Try the authentication
int result = ssh.authenticate(pwd);
// Evaluate the result
if (result == AuthenticationProtocolState.COMPLETE) {
System.out.println("Successful login");
// The connection is authenticated we can now do some real work!
SessionChannelClient session = ssh.openSessionChannel();
if(!session.requestPseudoTerminal("ANSI", 80, 24, 0, 0, ""))
System.out.println("Failed to allocate a pseudo terminal");
if (session.startShell()) {
System.out.println("Shell started");
IOStreamConnector input =
new IOStreamConnector();
IOStreamConnector output =
new IOStreamConnector();
IOStreamConnector error =
new IOStreamConnector();
output.setCloseOutput(false);
input.setCloseInput(false);
error.setCloseOutput(false);
input.connect(System.in, session.getOutputStream());
//FileOutputStream fos1=new FileOutputStream("mylog1.log");
//FileOutputStream fos2=new FileOutputStream("mylog2.log");
output.connect(session.getInputStream(), System.out);
//output.connect(session.getInputStream(), fos1);
error.connect(session.getStderrInputStream(), System.out);
//error.connect(session.getStderrInputStream(), fos2);
session.getState().waitForState(ChannelState.CHANNEL_CLOSED);
}else
System.out.println("Failed to start the users shell");
ssh.disconnect();
} else
{
System.out.println("Authentication fail");
} //end if
}
catch (Exception e) {
e.printStackTrace();
}
Connect to SFTP
public static SshClient getSSHClient(String _host,String username,String password)
{
try
{
ConfigurationLoader.initialize(false);
String hostname = _host;
SshClient ssh = new SshClient();
ssh.connect(hostname,new AlwaysAllowingConsoleKnownHostsKeyVerification());
PasswordAuthenticationClient pwd = new PasswordAuthenticationClient();
pwd.setUsername(username);
pwd.setPassword(password);
// Try the authentication
int result = ssh.authenticate(pwd);
// Evaluate the result
if (result == AuthenticationProtocolState.COMPLETE)
{
return ssh;
}else
{
return null;
}
} catch(Exception ex)
{
System.out.println(ex.getMessage());
return null;
}
}//end function
public static void batchSFTP(String filename) throws Exception
{
SshClient ssh=getSSHClient(host,username,password);
if(ssh==null)
{
System.out.println("Authentication fail");
return;
}
SftpClient sftp=ssh.openSftpClient();
if(sftp==null)
{
System.out.println("Connection fail or no such service!");
return;
}
File file=new File(".");
String current_path=file.getCanonicalPath();
sftp.lcd(current_path);
//Read the command list in filename
Vector vLine=HF.readLine(filename);
for(int i=0;i<vLine.size();i++)
{
String command=(String)vLine.get(i);
System.out.println("The command is:"+command);
CommandParser.runCommand(command,sftp);
}//end for
sftp.quit();
ssh.disconnect();
System.out.println("Finished");
//determine the current path
/*
File file=new File(".");
String current_path=file.getCanonicalPath();
sftp.lcd(current_path);
//sftp.put("run.bat");
sftp.put("cron.rar");
sftp.quit();
ssh.disconnect();
System.out.println("Finished");
*/
}//end function
Full class code of AlwaysAllowingConsoleKnownHostsKeyVerification
I think this part is a bit tricky and it takes me sometimes to figure it out in Internet that we can actually override the class to password the interactive login
package net;
import com.sshtools.j2ssh.transport.ConsoleKnownHostsKeyVerification;
import com.sshtools.j2ssh.transport.InvalidHostFileException;
import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
public class AlwaysAllowingConsoleKnownHostsKeyVerification extends
ConsoleKnownHostsKeyVerification {
public AlwaysAllowingConsoleKnownHostsKeyVerification()
throws InvalidHostFileException {
super();
// Don't not do anything else
}
@Override
public void onHostKeyMismatch(String s, SshPublicKey sshpublickey,
SshPublicKey sshpublickey1) {
try
{
System.out.println("The host key supplied by " + s + " is: " + sshpublickey1.getFingerprint());
System.out.println("The current allowed key for " + s + " is: " + sshpublickey.getFingerprint());
System.out.println("~~~Using Custom Key verification, allowing to pass through~~~");
allowHost(s, sshpublickey, false);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
@Override
public void onUnknownHost(String s, SshPublicKey sshpublickey) {
try
{
System.out.println("The host " + s + " is currently unknown to the system");
System.out.println("The host key fingerprint is: " + sshpublickey.getFingerprint());
System.out.println("~~~Using Custom Key verification, allowing to pass through~~~");
allowHost(s, sshpublickey, false);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
}
Download:
Full source code with build script can be downloaded at
留言
張貼留言