https://bz.apache.org/bugzilla/show_bug.cgi?id=70268
Bug ID: 70268
Summary: Regression] <scp> task fails with UnknownHostException
when destination path contains a Windows drive letter
(caused by Bug 59160 / PR #213)
Product: Ant
Version: 1.10.15
Hardware: PC
Status: NEW
Severity: major
Priority: P2
Component: Optional Tasks
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Description of Problem:
Since the merge of PR #213 (fixing Bug 59160: "scp task does not support
ipv6"), the <scp> task fails when copying files to or from a Windows host where
the remote path contains a drive letter (e.g. C:/... or /C:/...).
Steps to Reproduce:
Execute an <scp> upload task targeting a remote Windows SSH server:
<scp todir="[email protected]:/C:/path/to/dir"
password="secret"
sftp="true">
<fileset dir="target/upload" includes="*" />
</scp>
Actual Result:
The task fails immediately during connection establishment:
[scp] Connecting to 172.18.5.231:/C:22
[scp] Connecting to 172.18.5.231:/C port 22
com.jcraft.jsch.JSchException: java.net.UnknownHostException: 172.18.5.231:/C
Expected Result:
The host should be parsed as 172.18.5.231 and the remote path as
/C:/path/to/dir (as was the case in Ant 1.10.13 and earlier).
Root Cause Analysis:
In org.apache.tools.ant.taskdefs.optional.ssh.Scp#parseUri(String uri):
Before PR #213 (Ant <= 1.10.13):
final int indexOfPath = uri.indexOf(':', indexOfAt + 1);
Here, the colon immediately following the hostname was matched.
With PR #213 (commit 7c6c127 / Ant >= 1.10.15):
// For IPv6 addresses, the host part may contain more than one ":",
// look for the last occurrence
final int indexOfPath = uri.lastIndexOf(':');
if (indexOfPath <= indexOfAt) {
throw new BuildException("no remote path in %s", uri);
}
setHost(uri.substring(indexOfAt + 1, indexOfPath));
PR #213 assumed that any extra : in the URI must belong to an IPv6 address.
However, when connecting to Windows systems (e.g. OpenSSH for Windows or SFTP),
remote paths commonly include drive letters (e.g. user@host:/C:/deploy or
user@host:C:/deploy).
uri.lastIndexOf(':') matches the colon of the drive letter (C:), causing Ant to
extract:
Host: 172.18.5.231:/C
Path: /path/to/dir
JSch then tries to resolve 172.18.5.231:/C as a DNS hostname, throwing
UnknownHostException.
Suggested Fix:
IPv6 addresses in URIs should either be enclosed in brackets (per RFC 3986 /
OpenSSH standard, e.g. [2001:db8::1]:/path), or Ant should check if the last
colon belongs to a Windows drive letter before splitting:
int indexOfPath;
if (uri.charAt(indexOfAt + 1) == '[') {
// Standard IPv6 notation: user@[ipv6]:/path
int closingBracket = uri.indexOf(']', indexOfAt + 1);
if (closingBracket != -1 && uri.indexOf(':', closingBracket) != -1) {
indexOfPath = uri.indexOf(':', closingBracket);
} else {
indexOfPath = uri.lastIndexOf(':');
}
} else {
// If not enclosed in brackets, check if last colon is part of a Windows
drive letter (:/?([A-Za-z]):)
// or locate the first colon after host
int firstColon = uri.indexOf(':', indexOfAt + 1);
int lastColon = uri.lastIndexOf(':');
if (firstColon != lastColon) {
// Disambiguate between IPv6 host and Windows drive letter in path
String potentialDrive = uri.substring(firstColon + 1, lastColon);
if (potentialDrive.matches("^[A-Za-z]$") ||
potentialDrive.matches("^/[A-Za-z]$")) {
// Last colon is a drive letter (e.g., host:C: or host:/C:); use
first colon
indexOfPath = firstColon;
} else {
indexOfPath = lastColon;
}
} else {
indexOfPath = firstColon;
}
}
--
You are receiving this mail because:
You are the assignee for the bug.