summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2019-10-24 17:00:21 +0200
committerJaikiran Pai <jaikiran@apache.org>2019-10-25 13:47:14 +0530
commitb6143efab2f45ff11c980438c60d79f6db0da868 (patch)
tree99b7bf820cacf4c1ae44091ffd7f28fd9c66560e
parentcd17a660b7f053e185686a72f7d6e89abdd82d83 (diff)
downloadant-b6143efab2f45ff11c980438c60d79f6db0da868.tar.gz
Support the SSH configuration file (~/.ssh/config) in the sshexec, sshsession and scp tasks
This closes #106 pull request at github/apache/ant repo
-rw-r--r--WHATSNEW4
-rw-r--r--manual/Tasks/scp.html8
-rw-r--r--manual/Tasks/sshexec.html8
-rw-r--r--manual/Tasks/sshsession.html8
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java55
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java3
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java3
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java17
8 files changed, 99 insertions, 7 deletions
diff --git a/WHATSNEW b/WHATSNEW
index ad4ac9eba..29dedcf60 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -14,6 +14,10 @@ Fixed bugs:
files.
Bugzilla Report 63874
+ * sshexec, sshsession and scp now support a new sshConfig parameter.
+ It specified the SSH configuration file (typically ${user.home}/.ssh/config)
+ defining the username and keyfile to be used per host.
+
Other changes:
--------------
diff --git a/manual/Tasks/scp.html b/manual/Tasks/scp.html
index c353879a3..a9a95a12d 100644
--- a/manual/Tasks/scp.html
+++ b/manual/Tasks/scp.html
@@ -143,6 +143,14 @@ information. This task has been tested with <code>jsch-0.1.2</code> and later.<
<td>No; defaults to an empty string</td>
</tr>
<tr>
+ <td>sshConfig</td>
+ <td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
+ The username and the key file are read from the configuration file,
+ unless they are already specified in the task parameters.
+ <em>since Ant 1.10.8</em></td>
+ <td>No</td>
+ </tr>
+ <tr>
<td>verbose</td>
<td>Determines whether SCP outputs verbosely to the user. Currently this means outputting
dots/stars showing the progress of a file transfer. <em>since Ant 1.6.2</em></td>
diff --git a/manual/Tasks/sshexec.html b/manual/Tasks/sshexec.html
index c30b4a5e2..6437b4608 100644
--- a/manual/Tasks/sshexec.html
+++ b/manual/Tasks/sshexec.html
@@ -105,6 +105,14 @@ JSCh earlier than 0.1.28.</p>
<td>No; defaults to an empty string</td>
</tr>
<tr>
+ <td>sshConfig</td>
+ <td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
+ The username and the key file are read from the configuration file,
+ unless they are already specified in the task parameters.
+ <em>since Ant 1.10.8</em></td>
+ <td>No</td>
+ </tr>
+ <tr>
<td>suppresssystemout</td>
<td>Whether to suppress system out. <em>since Ant 1.9.0</em></td>
<td>No; defaults to <q>false</q></td>
diff --git a/manual/Tasks/sshsession.html b/manual/Tasks/sshsession.html
index bf8d80ac2..6f557bb72 100644
--- a/manual/Tasks/sshsession.html
+++ b/manual/Tasks/sshsession.html
@@ -111,6 +111,14 @@ JSCh earlier than 0.1.28.</p>
<td>No; defaults to an empty string</td>
</tr>
<tr>
+ <td>sshConfig</td>
+ <td>Location of the file holding the OpenSSH style configuration (e.g. <code>${user.home}/.ssh/config</code>).
+ The username and the key file are read from the configuration file,
+ unless they are already specified in the task parameters.
+ <em>since Ant 1.10.8</em></td>
+ <td>No</td>
+ </tr>
+ <tr>
<td>timeout</td>
<td>Give up if the connection cannot be established within the specified time (given in
milliseconds).</td>
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
index 338a11a38..edee9a8ec 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
@@ -18,6 +18,11 @@
package org.apache.tools.ant.taskdefs.optional.ssh;
+import java.io.File;
+import java.io.IOException;
+
+import com.jcraft.jsch.ConfigRepository;
+import com.jcraft.jsch.OpenSSHConfig;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
@@ -42,6 +47,7 @@ public abstract class SSHBase extends Task implements LogListener {
private boolean failOnError = true;
private boolean verbose;
private final SSHUserInfo userInfo;
+ private String sshConfig;
private int serverAliveCountMax = 3;
private int serverAliveIntervalSeconds = 0;
@@ -107,6 +113,24 @@ public abstract class SSHBase extends Task implements LogListener {
}
/**
+ * Get the OpenSSH config file (~/.ssh/config).
+ * @return the OpenSSH config file
+ * @since Ant 1.10.8
+ */
+ public String getSshConfig() {
+ return sshConfig;
+ }
+
+ /**
+ * Set the OpenSSH config file (~/.ssh/config).
+ * @param sshConfig the OpenSSH config file
+ * @since Ant 1.10.8
+ */
+ public void setSshConfig(String sshConfig) {
+ this.sshConfig = sshConfig;
+ }
+
+ /**
* Set the serverAliveCountMax value.
* @param countMax int
* @since Ant 1.9.7
@@ -236,6 +260,37 @@ public abstract class SSHBase extends Task implements LogListener {
}
/**
+ * Load the SSH configuration file.
+ * @throws BuildException on error
+ */
+ protected void loadSshConfig() throws BuildException {
+ if (sshConfig != null && (userInfo.getName() == null || userInfo.getKeyfile() == null)) {
+ if (!new File(sshConfig).exists()) {
+ throw new BuildException("The SSH configuration file specified doesn't exist: " + sshConfig);
+ }
+
+ log("Loading SSH configuration file " + sshConfig, Project.MSG_DEBUG);
+ ConfigRepository.Config config = null;
+ try {
+ config = OpenSSHConfig.parseFile(sshConfig).getConfig(host);
+ } catch (IOException e) {
+ throw new BuildException("Failed to load the SSH configuration file " + sshConfig, e);
+ }
+
+ host = config.getHostname();
+
+ if (userInfo.getName() == null) {
+ userInfo.setName(config.getUser());
+ }
+
+ if (userInfo.getKeyfile() == null) {
+ log("Using SSH key file " + config.getValue("IdentityFile") + " for host " + host, Project.MSG_INFO);
+ userInfo.setKeyfile(config.getValue("IdentityFile"));
+ }
+ }
+ }
+
+ /**
* Open an ssh session.
* @return the opened session
* @throws JSchException on error
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
index 1cd273b54..17dd4313b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
@@ -284,6 +284,9 @@ public class SSHExec extends SSHBase {
if (getHost() == null) {
throw new BuildException("Host is required.");
}
+
+ loadSshConfig();
+
if (getUserInfo().getName() == null) {
throw new BuildException("Username is required.");
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
index 6b7c33ef6..5c5224658 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
@@ -132,6 +132,9 @@ public class SSHSession extends SSHBase {
if (getHost() == null) {
throw new BuildException("Host is required.");
}
+
+ loadSshConfig();
+
if (getUserInfo().getName() == null) {
throw new BuildException("Username is required.");
}
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 f954a72f4..3d181d30e 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
@@ -435,19 +435,22 @@ public class Scp extends SSHBase {
throw new BuildException("no username was given. Can't authenticate.");
}
- if (getUserInfo().getPassword() == null
- && getUserInfo().getKeyfile() == null) {
- throw new BuildException(
- "neither password nor keyfile for user %s has been given. Can't authenticate.",
- getUserInfo().getName());
- }
-
final int indexOfPath = uri.indexOf(':', indexOfAt + 1);
if (indexOfPath == -1) {
throw new BuildException("no remote path in %s", uri);
}
setHost(uri.substring(indexOfAt + 1, indexOfPath));
+
+ loadSshConfig();
+
+ if (getUserInfo().getPassword() == null
+ && getUserInfo().getKeyfile() == null) {
+ throw new BuildException(
+ "neither password nor keyfile for user %s has been given. Can't authenticate.",
+ getUserInfo().getName());
+ }
+
String remotePath = uri.substring(indexOfPath + 1);
if (remotePath.isEmpty()) {
remotePath = ".";