Programming and So

Tips and tricks in Java

SFTP in Java

with 9 comments

There are several free libraries to perform connections via FTP in Java (such as Sun SDK, Apache Commons Net, …). However, these ones doesn’t support SSH connections. In order to use this kind of connections, few alternatives can be found.

I’m using J2SSH project which is an abandoned software which later evolved in J2SSH-Maverick commercial package.

Connecting a server through ip address and port 22 with user/password authentication can be done as follows.

import java.util.List;

import com.sshtools.j2ssh.SftpClient;
import com.sshtools.j2ssh.SshClient;
import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;
import com.sshtools.j2ssh.sftp.SftpFile;

private static final String LOGS_APPS = "/logs";
private static final String USERNAME = "user";
private static final String PASSWORD = "pass";

// Connect
SshClient ssh = new SshClient();
ssh.connect("127.0.0.1", 22, new AlwaysAllowingConsoleKnownHostsKeyVerification());

// Authenticate
PasswordAuthenticationClient passwordAuthenticationClient =
    new PasswordAuthenticationClient();
passwordAuthenticationClient.setUsername(USERNAME);
passwordAuthenticationClient.setPassword(PASSWORD);

int result = ssh.authenticate(passwordAuthenticationClient);
if(result != AuthenticationProtocolState.COMPLETE){
     throw new Exception("Login failed");
}

// Open the SFTP channel
SftpClient client = ssh.openSftpClient();

// List log directory
client.cd(LOGS_APPS);
List<?> ls = client.ls();

...

I’ve also included AlwaysAllowingConsoleKnownHostsKeyVerification class in order to avoid user interaction required to accept connections to unknown hosts.

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();
        }
    } 

}
  • FTPS is ftp over a SSL (secure sockets layer) connection.
  • SFTP is not ftp but SCP (secure copy) commands (or similar) over a SSH2 (secure shell) connection.

In j2ssh 0.2.9 com.sshtools.j2ssh.transport.IgnoreHostKeyVerification class can be used to perform the same operation described in the given example ( AlwaysAllowingConsoleKnownHostsKeyVerification)

Written by angelborroy

July 28, 2008 at 9:48 am

Posted in java

Tagged with ,

9 Responses

Subscribe to comments with RSS.

  1. You are right, surprisingly there are only a few options…

    Your solutions is for “SFTP” (FTP over SSH), but if you would want to implement an “FTPS” client (FTP over SSL), the best option is Apache Commons Net, but changing the Socket Factory (it has a method for stablising it).

    P.S: Great blog! ;-)

    Server Performance

    July 30, 2008 at 10:10 am

  2. Thanks for your remark.
    I’ve corrected the errata in the post.

    angelborroy

    July 30, 2008 at 12:07 pm

  3. Hi,

    I would like to know the server setup. For me the FTP server is behind a Firewall. I need to do a SSH connection to firewall and then do a FTP connect. I am using setProxyHost setProxyUsername and setProxyPassword. But I am getting connection refused reply always. I am using PasswordAuthenticationClient for Host password authentication.

    The below is the code

    public void verifySSHConnection() throws IOException {
    SshClient client = new SshClient();
    SshConnectionProperties connectionProperties = new SshConnectionProperties();
    connectionProperties.setProxyHost(PROX_HOST);
    connectionProperties.setProxyPort(22);
    connectionProperties.setProxyUsername(PROXY_UNAME);
    connectionProperties.setProxyPassword(PROXY_PWD);
    client.connect(connectionProperties, new IgnoreHostKeyVerification());
    //this is behind the firewall and proxy has got access to it
    connectionProperties.setHost(HOST_NAME);
    PasswordAuthenticationClient authenticationClient = new PasswordAuthenticationClient();
    authenticationClient.setUsername(HOST_UNAME);
    authenticationClient.setPassword(HOST_PWD);
    int result = client.authenticate(authenticationClient);
    if (result == AuthenticationProtocolState.COMPLETE)
    System.out.println(“success Authentication”);
    else
    System.out.println(“failed Authentication”);
    System.out.println(client.isConnected());
    SftpClient sftpClient = client.openSftpClient();
    sftpClient.cd(“/”);
    }

    Venu Madhav

    March 30, 2009 at 4:56 pm

  4. It seems your proxy server is not accepting connections thought port 22. Try connecting proxy on port 80 and then do the FTP connection on port 22.

    Luck!

    angelborroy

    March 31, 2009 at 8:35 am

  5. When I set proxy settings and just do a
    client.connect() – it is sucessful
    When I set the HOST and PasswordAuthentication it says connection refused. Is there any exact way to find the exact rejection during authentication. The connection refused exception I am getting is printed in the JUnit console.

    Venu Madhav

    April 1, 2009 at 10:56 am

  6. Also I would like to know if the SSH and FTP server should reside on the same server for JSSH to work or can they be on a different server IP’s.

    Venu Madhav

    April 1, 2009 at 11:00 am

  7. Maybe your proxy does not have user authentication?
    However this library is just a Beta version. You can try with http://www.sshtools.com/en/j2ssh-maverick/. If this software works, it seems to be a bug in j2ssh.

    On the other hand, JSSH can be located on any computer.

    angelborroy

    April 2, 2009 at 8:50 pm

  8. I was evaluating this SFTP package from http://www.zehon.com. I thought it worked great and pretty easy to use and it’s free. I’m wondering if you are packaging this into some sort of an API.

    Skip Johnson

    July 1, 2009 at 9:07 pm

  9. I didn’t know Zehon, but it sounds interesting. Thanks for the info, Skip.

    angelborroy

    July 2, 2009 at 7:26 am


Leave a Reply