diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
new file mode 100644
index 000000000..d2fbbeccd
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
@@ -0,0 +1,213 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import com.jcraft.jsch.*;
+
+import java.io.*;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * Base class for Ant tasks using jsch.
+ *
+ * @author charliehubbard76@yahoo.com
+ * @author riznob@hotmail.com
+ * @since Ant 1.6
+ */
+public abstract class SSHBase extends Task implements LogListener {
+
+ private String host;
+ private String keyfile;
+ private String knownHosts;
+ private boolean trust = false;
+ private int port = 22;
+ private boolean failOnError = true;
+ private SSHUserInfo userInfo;
+
+ /**
+ * Constructor for SSHBase.
+ */
+ public SSHBase() {
+ super();
+ userInfo = new SSHUserInfo();
+ }
+
+ /**
+ * Remote host, either DNS name or IP.
+ *
+ * @param host The new host value
+ */
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+
+ public void setFailonerror( boolean failure ) {
+ failOnError = failure;
+ }
+
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+
+ /**
+ * Username known to remote host.
+ *
+ * @param username The new username value
+ */
+ public void setUsername(String username) {
+ userInfo.setName(username);
+ }
+
+
+ /**
+ * Sets the password for the user.
+ *
+ * @param password The new password value
+ */
+ public void setPassword(String password) {
+ userInfo.setPassword(password);
+ }
+
+ /**
+ * Sets the keyfile for the user.
+ *
+ * @param keyfile The new keyfile value
+ */
+ public void setKeyfile(String keyfile) {
+ userInfo.setKeyfile(keyfile);
+ }
+
+ /**
+ * Sets the passphrase for the users key.
+ *
+ * @param passphrase The new passphrase value
+ */
+ public void setPassphrase(String passphrase) {
+ userInfo.setPassphrase(passphrase);
+ }
+
+ /**
+ * Sets the path to the file that has the identities of
+ * all known hosts. This is used by SSH protocol to validate
+ * the identity of the host. The default is
+ * ${user.home}/.ssh/known_hosts.
+ *
+ * @param knownHosts a path to the known hosts file.
+ */
+ public void setKnownhosts( String knownHosts ) {
+ this.knownHosts = knownHosts;
+ }
+
+ /**
+ * Setting this to true trusts hosts whose identity is unknown.
+ *
+ * @param yesOrNo if true trust the identity of unknown hosts.
+ */
+ public void setTrust( boolean yesOrNo ) {
+ userInfo.setTrust(yesOrNo);
+ }
+
+ /**
+ * Changes the port used to connect to the remote host.
+ *
+ * @param port port number of remote host.
+ */
+ public void setPort( int port ) {
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void init() throws BuildException{
+ super.init();
+ this.knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts";
+ this.trust = false;
+ this.port = 22;
+ }
+
+ protected Session openSession() throws JSchException {
+ JSch jsch = new JSch();
+ if (null != userInfo.getKeyfile()) {
+ jsch.addIdentity(userInfo.getKeyfile(), "passphrase");
+ }
+
+ if( knownHosts != null ) {
+ log( "Using known hosts: " + knownHosts, Project.MSG_DEBUG );
+ jsch.setKnownHosts( knownHosts );
+ }
+
+ Session session = jsch.getSession( userInfo.getName(), host, port );
+ session.setUserInfo(userInfo);
+ log("Connecting to " + host + ":" + port );
+ session.connect();
+ return session;
+ }
+
+ protected SSHUserInfo getUserInfo() {
+ return userInfo;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
new file mode 100644
index 000000000..e3833f2bd
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
@@ -0,0 +1,208 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import com.jcraft.jsch.UserInfo;
+import org.apache.tools.ant.Project;
+
+/**
+ * @author rhanderson
+ */
+public class SSHUserInfo implements UserInfo {
+
+ private String name;
+ private String password = null;
+ private String keyfile;
+ private String passphrase = null;
+ private boolean firstTime = true;
+ private boolean trustAllCertificates;
+
+ public SSHUserInfo() {
+ super();
+ this.trustAllCertificates = true;
+ }
+
+ public SSHUserInfo(String password, boolean trustAllCertificates) {
+ super();
+ this.password = password;
+ this.trustAllCertificates = trustAllCertificates;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#getPassphrase(String)
+ */
+ public String getPassphrase(String message) {
+ return passphrase;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#getPassword()
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#prompt(String)
+ */
+ public boolean prompt(String str) {
+ return false;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#retry()
+ */
+ public boolean retry() {
+ return false;
+ }
+
+ /**
+ * Sets the name.
+ * @param name The name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Sets the passphrase.
+ * @param passphrase The passphrase to set
+ */
+ public void setPassphrase(String passphrase) {
+ this.passphrase = passphrase;
+ }
+
+ /**
+ * Sets the password.
+ * @param password The password to set
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Sets the trust.
+ * @param boolean
+ */
+ public void setTrust(boolean trust) {
+ this.trustAllCertificates = trust;
+ }
+
+ /**
+ * Returns the passphrase.
+ * @return String
+ */
+ public String getPassphrase() {
+ return passphrase;
+ }
+
+ /**
+ * Returns the keyfile.
+ * @return String
+ */
+ public String getKeyfile() {
+ return keyfile;
+ }
+
+ /**
+ * Sets the keyfile.
+ * @param keyfile The keyfile to set
+ */
+ public void setKeyfile(String keyfile) {
+ this.keyfile = keyfile;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#promptPassphrase(String)
+ */
+ public boolean promptPassphrase(String message) {
+ return true;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#promptPassword(String)
+ */
+ public boolean promptPassword( String passwordPrompt ) {
+ //log( passwordPrompt, Project.MSG_DEBUG );
+ if( firstTime ) {
+ firstTime = false;
+ return true;
+ }
+ return firstTime;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#promptYesNo(String)
+ */
+ public boolean promptYesNo(String message) {
+ //log( prompt, Project.MSG_DEBUG );
+ return trustAllCertificates;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#showMessage(String)
+ */
+ public void showMessage(String message) {
+ //log( message, Project.MSG_DEBUG );
+ }
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
index 77558ac31..463e519c0 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
@@ -74,19 +74,11 @@ import org.apache.tools.ant.types.FileSet;
* @author charliehubbard76@yahoo.com
* @since Ant 1.6
*/
-public class Scp extends Task implements LogListener {
+public class Scp extends SSHBase {
private String fromUri;
private String toUri;
- private String knownHosts;
- private boolean trust = false;
- private int port = 22;
private List fileSets = null;
- private boolean failOnError = true;
-
- public void setFailonerror( boolean failure ) {
- failOnError = failure;
- }
/**
* Sets the file to be transferred. This can either be a remote
@@ -114,35 +106,7 @@ public class Scp extends Task implements LogListener {
this.toUri = aToUri;
}
- /**
- * Sets the path to the file that has the identities of
- * all known hosts. This is used by SSH protocol to validate
- * the identity of the host. The default is
- * ${user.home}/.ssh/known_hosts.
- * @param knownHosts a path to the known hosts file.
- */
- public void setKnownhosts( String knownHosts ) {
- this.knownHosts = knownHosts;
- }
-
- /**
- * Setting this to true trusts hosts whose identity is unknown.
- *
- * @param yesOrNo if true trust the identity of unknown hosts.
- */
- public void setTrust( boolean yesOrNo ) {
- this.trust = yesOrNo;
- }
-
- /**
- * Changes the port used to connect to the remote host.
- *
- * @param port port number of remote host.
- */
- public void setPort( int port ) {
- this.port = port;
- }
/**
* Adds a FileSet tranfer to remote host. NOTE: Either
@@ -161,9 +125,6 @@ public class Scp extends Task implements LogListener {
super.init();
this.toUri = null;
this.fromUri = null;
- this.knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts";
- this.trust = false;
- this.port = 22;
this.fileSets = null;
}
@@ -174,12 +135,13 @@ public class Scp extends Task implements LogListener {
if ( fromUri == null && fileSets == null ) {
throw new BuildException("Either the 'file' attribute or one " +
- "FileSet is required.");
+ "FileSet is required.");
}
boolean isFromRemote = false;
- if( fromUri != null )
+ if( fromUri != null ) {
isFromRemote = isRemoteUri(fromUri);
+ }
boolean isToRemote = isRemoteUri(toUri);
try {
if (isFromRemote && !isToRemote) {
@@ -194,11 +156,11 @@ public class Scp extends Task implements LogListener {
// not implemented yet.
} else {
throw new BuildException("'todir' and 'file' attributes " +
- "must have syntax like the following: " +
- "user:password@host:/path");
+ "must have syntax like the following: " +
+ "user:password@host:/path");
}
} catch (Exception e) {
- if( failOnError ) {
+ if(getFailonerror()) {
throw new BuildException(e);
} else {
log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
@@ -207,20 +169,17 @@ public class Scp extends Task implements LogListener {
}
private void download( String fromSshUri, String toPath )
- throws JSchException, IOException {
- String[] fromValues = parseUri(fromSshUri);
+ throws JSchException, IOException {
+ String file = parseUri(fromSshUri);
Session session = null;
try {
- session = openSession(fromValues[0],
- fromValues[1],
- fromValues[2],
- port );
+ session = openSession();
ScpFromMessage message = new ScpFromMessage( session,
- fromValues[3],
- new File( toPath ),
- fromSshUri.endsWith("*") );
- log("Receiving file: " + fromValues[3] );
+ file,
+ new File( toPath ),
+ fromSshUri.endsWith("*") );
+ log("Receiving file: " + file );
message.setLogListener( this );
message.execute();
} finally {
@@ -230,23 +189,20 @@ public class Scp extends Task implements LogListener {
}
private void upload( List fileSet, String toSshUri )
- throws IOException, JSchException {
- String[] toValues = parseUri(toSshUri);
+ throws IOException, JSchException {
+ String file = parseUri(toSshUri);
Session session = null;
try {
- session = openSession( toValues[0],
- toValues[1],
- toValues[2],
- port );
+ session = openSession();
List list = new ArrayList( fileSet.size() );
for( Iterator i = fileSet.iterator(); i.hasNext(); ) {
FileSet set = (FileSet) i.next();
list.add( createDirectory( set ) );
}
ScpToMessage message = new ScpToMessage( session,
- list,
- toValues[3] );
+ list,
+ file);
message.setLogListener( this );
message.execute();
} finally {
@@ -256,18 +212,15 @@ public class Scp extends Task implements LogListener {
}
private void upload( String fromPath, String toSshUri )
- throws IOException, JSchException {
- String[] toValues = parseUri(toSshUri);
+ throws IOException, JSchException {
+ String file = parseUri(toSshUri);
Session session = null;
try {
- session = openSession( toValues[0],
- toValues[1],
- toValues[2],
- port );
+ session = openSession();
ScpToMessage message = new ScpToMessage( session,
- new File( fromPath ),
- toValues[3] );
+ new File( fromPath ),
+ file );
message.setLogListener( this );
message.execute();
} finally {
@@ -276,35 +229,32 @@ public class Scp extends Task implements LogListener {
}
}
- private Session openSession( String user, String password,
- String host, int port )
- throws JSchException {
- JSch jsch = new JSch();
- if( knownHosts != null ) {
- log( "Using known hosts: " + knownHosts, Project.MSG_DEBUG );
- jsch.setKnownHosts( knownHosts );
- }
- Session session = jsch.getSession( user, host, port );
-
- UserInfo userInfo = new DefaultUserInfo( password, trust );
- session.setUserInfo(userInfo);
- log("Connecting to " + host + ":" + port );
- session.connect();
- return session;
- }
-
- private String[] parseUri(String uri) {
+ private String parseUri(String uri) {
int indexOfAt = uri.indexOf('@');
int indexOfColon = uri.indexOf(':');
- int indexOfPath = uri.indexOf(':', indexOfColon + 1);
+ if (indexOfColon > -1 && indexOfColon < indexOfAt) {
+ // user:password@host:/path notation
+ setUsername(uri.substring(0, indexOfColon));
+ setPassword(uri.substring(indexOfColon + 1, indexOfAt));
+ } else {
+ // no password, will require passphrase
+ setUsername(uri.substring(0, indexOfAt));
+ }
- String[] values = new String[4];
- values[0] = uri.substring(0, indexOfColon);
- values[1] = uri.substring(indexOfColon + 1, indexOfAt);
- values[2] = uri.substring(indexOfAt + 1, indexOfPath);
- values[3] = uri.substring(indexOfPath + 1);
+ if (getUserInfo().getPassword() == null
+ && getUserInfo().getPassphrase() == null) {
+ throw new BuildException("neither password nor passphrase for user "
+ + getUserInfo().getName() + " has been "
+ + "given. Can't authenticate.");
+ }
- return values;
+ int indexOfPath = uri.indexOf(':', indexOfAt + 1);
+ if (indexOfPath == -1) {
+ throw new BuildException("no remote path in " + uri);
+ }
+
+ setHost(uri.substring(indexOfAt + 1, indexOfPath));
+ return uri.substring(indexOfPath + 1);
}
private boolean isRemoteUri(String uri) {
@@ -338,46 +288,4 @@ public class Scp extends Task implements LogListener {
return root;
}
-
-
- public class DefaultUserInfo implements UserInfo {
- private String password = null;
- private boolean firstTime = true;
- private boolean trustAllCertificates;
-
- public DefaultUserInfo(String password, boolean trustAllCertificates) {
- this.password = password;
- this.trustAllCertificates = trustAllCertificates;
- }
-
- public String getPassphrase() {
- return null;
- }
-
- public String getPassword() {
- return password;
- }
-
- public boolean promptPassword( String passwordPrompt ) {
- log( passwordPrompt, Project.MSG_DEBUG );
- if( firstTime ) {
- firstTime = false;
- return true;
- }
- return firstTime;
- }
-
- public boolean promptPassphrase( String passPhrasePrompt ) {
- return true;
- }
-
- public boolean promptYesNo( String prompt ) {
- log( prompt, Project.MSG_DEBUG );
- return trustAllCertificates;
- }
-
- public void showMessage( String message ) {
- log( message, Project.MSG_DEBUG );
- }
- }
}