From 23e2bfc94e6e4518272c2ac4ed3e768333bbbdc3 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Sun, 21 Nov 2010 19:16:52 -0500 Subject: [PATCH] INT-1614 refactored SftpSession and DefaultSftpSessionFactory to align with Ftp --- .../session/DefaultSftpSessionFactory.java | 85 ++++++++++++-- .../integration/sftp/session/SftpSession.java | 104 +----------------- 2 files changed, 79 insertions(+), 110 deletions(-) diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java index e4cded1c48..4211b5551f 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java @@ -22,6 +22,9 @@ import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.util.Assert; import org.springframework.util.StringUtils; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.UserInfo; + /** * Factory for creating {@link SftpSession} instances. * @@ -44,8 +47,10 @@ public class DefaultSftpSessionFactory implements SessionFactory { private volatile Resource privateKey; private volatile String privateKeyPassphrase; + + private final JSch jsch = new JSch();; - + public void setHost(String host) { this.host = host; } @@ -80,19 +85,81 @@ public class DefaultSftpSessionFactory implements SessionFactory { Assert.isTrue(this.port >= 0, "port must be a positive number"); Assert.isTrue(StringUtils.hasText(this.password) || privateKey != null || StringUtils.hasText(this.privateKeyPassphrase), "either a password or a private key and/or a private key passphrase is required"); - String privateKeyToPass = null; try { - if (privateKey != null){ - privateKeyToPass = privateKey.getFile().getAbsolutePath(); - } - SftpSession session = new SftpSession( - this.user, this.host, this.password, this.port, this.knownHosts, null, privateKeyToPass, this.privateKeyPassphrase); - session.connect(); - return session; + + com.jcraft.jsch.Session jschSession = this.initJschSession(); + SftpSession sftpSession = new SftpSession(jschSession); + sftpSession.connect(); + return sftpSession; } catch (Exception e) { throw new IllegalStateException("failed to create SFTP Session", e); } } + + private com.jcraft.jsch.Session initJschSession() throws Exception { + + if (port <= 0) { + port = 22; + } + + + if (StringUtils.hasText(this.knownHosts)) { + this.jsch.setKnownHosts(this.knownHosts); + } + + // private key + String privateKeyFilePath = this.privateKey.getFile().getAbsolutePath(); + if (privateKey != null) { + if (StringUtils.hasText(privateKeyPassphrase)) { + this.jsch.addIdentity(privateKeyFilePath, privateKeyPassphrase); + } + else { + this.jsch.addIdentity(privateKeyFilePath); + } + } + com.jcraft.jsch.Session jsSession = this.jsch.getSession(this.user, this.host, this.port); + if (StringUtils.hasText(this.password)) { + jsSession.setPassword(this.password); + } + jsSession.setUserInfo(new OptimisticUserInfoImpl(this.password)); + return jsSession; + } + + /** + * this is a simple, optimistic implementation of this interface. It simply returns in the positive where possible + * and handles interactive authentication (ie, 'Please enter your password: ' prompts are dispatched automatically using this) + */ + private static class OptimisticUserInfoImpl implements UserInfo { + + private String password; + + public OptimisticUserInfoImpl(String password) { + this.password = password; + } + + public String getPassphrase() { + return null; // pass + } + + public String getPassword() { + return password; + } + + public boolean promptPassphrase(String string) { + return true; + } + + public boolean promptPassword(String string) { + return true; + } + + public boolean promptYesNo(String string) { + return true; + } + + public void showMessage(String string) { + } + } } diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java index 0de2e1ebff..0772216aa6 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/SftpSession.java @@ -24,14 +24,11 @@ import org.apache.commons.logging.LogFactory; import org.springframework.integration.file.remote.session.Session; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp.LsEntry; -import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.SftpException; -import com.jcraft.jsch.UserInfo; /** * Default SftpSession implementation. @@ -41,7 +38,7 @@ import com.jcraft.jsch.UserInfo; * @author Mark Fisher * @since 2.0 */ -public class SftpSession implements Session { +class SftpSession implements Session { private final Log logger = LogFactory.getLog(this.getClass()); @@ -49,66 +46,9 @@ public class SftpSession implements Session { private final com.jcraft.jsch.Session jschSession; - private String privateKey; - private String privateKeyPassphrase; - - private volatile UserInfo userInfo; - - - /** - * @param userName the name of the account being logged into. - * @param hostName this should be the host. I found values like foo.com work, where - * http://foo.com don't. - * @param userPassword if you are not using key based authentication, then you are likely being prompted - * for a password each time you login. This is that password. It is not the - * passphrase for the private key! - * @param port the default is 22, and if you specify N<0 for this value we'll default it to 22 - * @param knownHostsFile this is the known hosts file. If you don't specify it, jsch does some magic to work - * without your specification. If you have it in a non well-known location, however, - * this property is for you. An example: /home/user/.ssh/known_hosts - * @param knownHostsInputStream this is the known hosts file. If you don't specify it, jsch does some magic to work - * without your specification. If you have it in a non well-known location, however, - * this property is for you. An example: /home/user/.ssh/known_hosts. Note - * that you may specify this or the #knownHostsFile - not both! - * @param privateKey this is usually used when you want passwordless automation (obviously, for this - * integration it's useless since this lets you specify a password once, anyway, but - * still good to have if required). This file might be ~/.ssh/id_dsa, or a - * .pem for your remote server (for example, on EC2) - * @param pvKeyPassPhrase sometimes, to be extra secure, the private key itself is extra encrypted. In order - * to surmount that, we need the private key passphrase. Specify that here. - * @throws Exception thrown if any of a myriad of scenarios plays out - */ - public SftpSession(String userName, String hostName, String userPassword, int port, String knownHostsFile, - InputStream knownHostsInputStream, String privateKey, String pvKeyPassPhrase) throws Exception { - - JSch jSch = new JSch(); - if (port <= 0) { - port = 22; - } - this.privateKey = privateKey; - this.privateKeyPassphrase = pvKeyPassPhrase; - if (StringUtils.hasText(knownHostsFile)) { - jSch.setKnownHosts(knownHostsFile); - } - else if (knownHostsInputStream != null) { - jSch.setKnownHosts(knownHostsInputStream); - } - // private key - if (privateKey != null) { - if (StringUtils.hasText(privateKeyPassphrase)) { - jSch.addIdentity(this.privateKey, privateKeyPassphrase); - } - else { - jSch.addIdentity(this.privateKey); - } - } - this.jschSession = jSch.getSession(userName, hostName, port); - if (StringUtils.hasText(userPassword)) { - this.jschSession.setPassword(userPassword); - } - this.userInfo = new OptimisticUserInfoImpl(userPassword); - this.jschSession.setUserInfo(userInfo); + public SftpSession(com.jcraft.jsch.Session jschSession){ + this.jschSession = jschSession; } void connect() { @@ -207,42 +147,4 @@ public class SftpSession implements Session { jschSession.disconnect(); } } - - - /** - * this is a simple, optimistic implementation of this interface. It simply returns in the positive where possible - * and handles interactive authentication (ie, 'Please enter your password: ' prompts are dispatched automatically using this) - */ - private static class OptimisticUserInfoImpl implements UserInfo { - - private String password; - - public OptimisticUserInfoImpl(String password) { - this.password = password; - } - - public String getPassphrase() { - return null; // pass - } - - public String getPassword() { - return password; - } - - public boolean promptPassphrase(String string) { - return true; - } - - public boolean promptPassword(String string) { - return true; - } - - public boolean promptYesNo(String string) { - return true; - } - - public void showMessage(String string) { - } - } - }