Search code examples
javasftppublic-key-encryptionapache-commons-vfs

How to use apache vfs2 for sftp with public-private-key and without password


Currently I am using apache vfs2 to download files from a sftp. For authentication I use user-name and password.

Is there a way to use vfs2 only with public-private-keys and without a password?

I think I have use this function,but how? Set it only to "yes"?

SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");

This is my current code (snippet):

private boolean downloadFile(){

    StandardFileSystemManager sysManager = new StandardFileSystemManager();

    //download der Datei
    try {
        sysManager.init();

        FileObject localFile = sysManager.resolveFile(localFilePath);

        FileObject remoteFile = sysManager.resolveFile(createConnectionString(host, user, password, fileName, port),createDefaultOptions());

        //Selectors.SELECT_FILES --> A FileSelector that selects only the base file/folder.
        localFile.copyFrom(remoteFile, Selectors.SELECT_FILES);


    } catch (Exception e) {
        logger.error("Downloading file failed: " + e.toString());
        return false;
    }finally{
        sysManager.close();
    }
    return true;
}

and

private FileSystemOptions createDefaultOptions() throws FileSystemException{

    //create options for sftp
    FileSystemOptions options = new FileSystemOptions();
    //ssh key
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");
    //set root directory to user home
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, true);
    //timeout
    SftpFileSystemConfigBuilder.getInstance().setTimeout(options, timeout);

    return options;
}

Solution

  • Taking your code and wrapping it into a runnable example. Notice the IdentityInfo implementation. This can work with a key-with-passphrase by changing the obvious lines.

    $ javac -cp 'jsch-0.1.51.jar;commons-vfs2-2.0.jar' SftpGet.java
    $ java -cp 'jsch-0.1.51.jar;commons-vfs2-2.0.jar;commons-logging-1.1.1.jar;.' SftpGet
    

    with

    import java.io.File;
    
    import com.jcraft.jsch.UserInfo;
    
    import org.apache.commons.vfs2.FileObject;
    import org.apache.commons.vfs2.FileSystemException;
    import org.apache.commons.vfs2.FileSystemManager;
    import org.apache.commons.vfs2.FileSystemOptions;
    import org.apache.commons.vfs2.Selectors;
    import org.apache.commons.vfs2.impl.StandardFileSystemManager;
    import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
    import org.apache.commons.vfs2.provider.sftp.IdentityInfo;
    
    
        public class SftpGet {
    
            public static void main(String[] args) {
                downloadFile();
            }
    
    
            private static boolean downloadFile(){
    
                String host = "HOSTNAMEHERE";
                String user = "USERNAMEHERE";
                String password = "";
                String fileName = "/lines.txt";
                String localFilePath = "c:/cygwin64/home/woddle/wrote_lines.txt";
    
                // without passphrase
                String keyPath = "c:/cygwin64/home/woddle/.ssh/id_dsa_nopass";
                String passphrase = null;
    
                // with passphrase
                // String keyPath = "c:/cygwin64/home/woddle/.ssh/id_dsa_withpass";
                // String passphrase = "super-secrets";
    
                StandardFileSystemManager sysManager = new StandardFileSystemManager();
    
                //download der Datei
                try {
                    sysManager.init();
    
                    FileObject localFile = sysManager.resolveFile(localFilePath);
    
                    FileObject remoteFile = sysManager.resolveFile(createConnectionString(host, user, password, keyPath, passphrase, fileName), createDefaultOptions(keyPath, passphrase));
    
                    //Selectors.SELECT_FILES --> A FileSelector that selects only the base file/folder.
                    localFile.copyFrom(remoteFile, Selectors.SELECT_FILES);
    
    
                } catch (Exception e) {
                    System.out.println("Downloading file failed: " + e.toString());
                    return false;
                }finally{
                    sysManager.close();
                }
                return true;
            }
    
    
            public static String createConnectionString(String hostName, String username, String password, String keyPath, String passphrase, String remoteFilePath) {
    
                if (keyPath != null) {
                    return "sftp://" + username + "@" + hostName + "/" + remoteFilePath;
                } else {
                    return "sftp://" + username + ":" + password + "@" + hostName + "/" + remoteFilePath;
                }
            }
    
    
    
            private static FileSystemOptions createDefaultOptions(final String keyPath, final String passphrase) throws FileSystemException{
    
                //create options for sftp
                FileSystemOptions options = new FileSystemOptions();
                //ssh key
                SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");
                //set root directory to user home
                SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, true);
                //timeout
                SftpFileSystemConfigBuilder.getInstance().setTimeout(options, 10000);
    
                if (keyPath != null) {
                    IdentityInfo identityInfo = null;
                    if(passPhrase!=null){
                        identityInfo = new IdentityInfo(new File(keyPath), passPhrase.getBytes());
                    }else{
                        identityInfo =  new IdentityInfo(new File(keyPath));
                    }
              SftpFileSystemConfigBuilder.getInstance().setIdentityInfo(options, identityInfo);
                }
    
    
                return options;
            }
    
    
        }