You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2017/08/07 08:31:16 UTC
mina-sshd git commit: Do not modify SCP file permissions if timestamp
attribute should be preserved
Repository: mina-sshd
Updated Branches:
refs/heads/master b2240515a -> 862f4f029
Do not modify SCP file permissions if timestamp attribute should be preserved
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/862f4f02
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/862f4f02
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/862f4f02
Branch: refs/heads/master
Commit: 862f4f0294268e7b496c5127596694eec4df2a25
Parents: b224051
Author: Goldstein Lyor <ly...@c-b4.com>
Authored: Mon Aug 7 11:30:15 2017 +0300
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Mon Aug 7 11:31:08 2017 +0300
----------------------------------------------------------------------
.../sshd/client/scp/DefaultScpClient.java | 15 +++---
.../subsystem/sftp/SftpFileSystemProvider.java | 6 +--
.../org/apache/sshd/common/scp/ScpHelper.java | 16 ++++---
.../org/apache/sshd/client/scp/ScpTest.java | 50 +++++++++++++-------
4 files changed, 54 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/862f4f02/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
index 854929a..d69252c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
@@ -114,21 +114,22 @@ public class DefaultScpClient extends AbstractScpClient {
}
@Override
- public void upload(final InputStream local, final String remote, final long size, final Collection<PosixFilePermission> perms, final ScpTimestamp time) throws IOException {
+ public void upload(InputStream local, String remote, long size, Collection<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
int namePos = ValidateUtils.checkNotNullAndNotEmpty(remote, "No remote location specified").lastIndexOf('/');
- final String name = (namePos < 0)
- ? remote
- : ValidateUtils.checkNotNullAndNotEmpty(remote.substring(namePos + 1), "No name value in remote=%s", remote);
- final String cmd = ScpClient.createSendCommand(remote, (time != null) ? EnumSet.of(Option.PreserveAttributes) : Collections.emptySet());
+ String name = (namePos < 0)
+ ? remote
+ : ValidateUtils.checkNotNullAndNotEmpty(remote.substring(namePos + 1), "No name value in remote=%s", remote);
+ Collection<Option> options = (time != null) ? EnumSet.of(Option.PreserveAttributes) : Collections.emptySet();
+ String cmd = ScpClient.createSendCommand(remote, options);
ClientSession session = getClientSession();
ChannelExec channel = openCommandChannel(session, cmd);
try (InputStream invOut = channel.getInvertedOut();
OutputStream invIn = channel.getInvertedIn()) {
// NOTE: we use a mock file system since we expect no invocations for it
ScpHelper helper = new ScpHelper(session, invOut, invIn, new MockFileSystem(remote), opener, listener);
- final Path mockPath = new MockPath(remote);
+ Path mockPath = new MockPath(remote);
helper.sendStream(new DefaultScpStreamResolver(name, mockPath, perms, time, size, local, cmd),
- time != null, ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
+ options.contains(Option.PreserveAttributes), ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
handleCommandExitStatus(cmd, channel);
} finally {
channel.close(false);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/862f4f02/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
index fb24d73..f8af4f5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
@@ -60,7 +60,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -1089,11 +1088,12 @@ public class SftpFileSystemProvider extends FileSystemProvider {
}
public static String getOctalPermissions(int perms) {
- return getOctalPermissions(permissionsToAttributes(perms));
+ Collection<PosixFilePermission> attrs = permissionsToAttributes(perms);
+ return getOctalPermissions(attrs);
}
public static Set<PosixFilePermission> permissionsToAttributes(int perms) {
- Set<PosixFilePermission> p = new HashSet<>();
+ Set<PosixFilePermission> p = EnumSet.noneOf(PosixFilePermission.class);
if ((perms & SftpConstants.S_IRUSR) == SftpConstants.S_IRUSR) {
p.add(PosixFilePermission.OWNER_READ);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/862f4f02/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
index 56f03de..3f584d2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
@@ -97,6 +97,9 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
public static final int S_IWOTH = 0000002;
public static final int S_IXOTH = 0000001;
+ public static final String DEFAULT_DIR_OCTAL_PERMISSIONS = "0755";
+ public static final String DEFAULT_FILE_OCTAL_PERMISSIONS = "0644";
+
protected final InputStream in;
protected final OutputStream out;
protected final FileSystem fileSystem;
@@ -120,7 +123,7 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
return sessionInstance;
}
- public void receiveFileStream(final OutputStream local, final int bufferSize) throws IOException {
+ public void receiveFileStream(OutputStream local, int bufferSize) throws IOException {
receive((line, isDir, timestamp) -> {
if (isDir) {
throw new StreamCorruptedException("Cannot download a directory into a file stream: " + line);
@@ -161,7 +164,7 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
});
}
- public void receive(Path local, final boolean recursive, boolean shouldBeDir, final boolean preserve, final int bufferSize) throws IOException {
+ public void receive(Path local, boolean recursive, boolean shouldBeDir, boolean preserve, final int bufferSize) throws IOException {
Path path = Objects.requireNonNull(local, "No local path").normalize().toAbsolutePath();
if (shouldBeDir) {
LinkOption[] options = IoUtils.getLinkOptions(true);
@@ -602,7 +605,7 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
}
Set<PosixFilePermission> perms = EnumSet.copyOf(resolver.getPermissions());
- String octalPerms = preserve ? getOctalPermissions(perms) : "0644";
+ String octalPerms = GenericUtils.isEmpty(perms) ? DEFAULT_FILE_OCTAL_PERMISSIONS : getOctalPermissions(perms);
String fileName = resolver.getFileName();
String cmd = "C" + octalPerms + " " + fileSize + " " + fileName;
if (log.isDebugEnabled()) {
@@ -697,8 +700,8 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
LinkOption[] options = IoUtils.getLinkOptions(true);
Set<PosixFilePermission> perms = IoUtils.getPermissions(path, options);
- String cmd = "D" + (preserve ? getOctalPermissions(perms) : "0755") + " "
- + "0" + " " + path.getFileName().toString();
+ String octalPerms = GenericUtils.isEmpty(perms) ? DEFAULT_DIR_OCTAL_PERMISSIONS : getOctalPermissions(perms);
+ String cmd = "D" + octalPerms + " " + "0" + " " + Objects.toString(path.getFileName(), null);
if (log.isDebugEnabled()) {
log.debug("sendDir({})[{}] send 'D' command: {}", this, path, cmd);
}
@@ -747,7 +750,8 @@ public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Sess
}
public static String getOctalPermissions(Path path, LinkOption... options) throws IOException {
- return getOctalPermissions(IoUtils.getPermissions(path, options));
+ Collection<PosixFilePermission> perms = IoUtils.getPermissions(path, options);
+ return getOctalPermissions(perms);
}
public static String getOctalPermissions(Collection<PosixFilePermission> perms) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/862f4f02/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index bbe1166..42907d6 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -901,24 +901,24 @@ public class ScpTest extends BaseTestSupport {
File target = new File(unixPath);
Utils.deleteRecursive(root);
root.mkdirs();
- assertTrue(root.exists());
+ assertTrue("Failed to ensure existence of " + root, root.exists());
target.delete();
- assertFalse(target.exists());
- sendFile(session, unixPath, fileName, data);
+ assertFalse("Failed to delete 1st time: " + target, target.exists());
+ sendFile(session, unixPath, target, data);
assertFileLength(target, data.length(), TimeUnit.SECONDS.toMillis(5L));
target.delete();
- assertFalse(target.exists());
- sendFile(session, unixDir, fileName, data);
+ assertFalse("Failed to delete 2nd time: " + target, target.exists());
+ sendFile(session, unixDir, target, data);
assertFileLength(target, data.length(), TimeUnit.SECONDS.toMillis(5L));
sendFileError(session, "target", ScpHelper.SCP_COMMAND_PREFIX, data);
readFileError(session, unixDir);
- assertEquals("Mismatched file data", data, readFile(session, unixPath, target.length()));
- assertEquals("Mismatched dir data", data, readDir(session, unixDir, fileName, target.length()));
+ assertEquals("Mismatched file data", data, readFile(session, unixPath, target));
+ assertEquals("Mismatched dir data", data, readDir(session, unixDir, target));
target.delete();
root.delete();
@@ -989,22 +989,26 @@ public class ScpTest extends BaseTestSupport {
}
}
- protected String readFile(com.jcraft.jsch.Session session, String path, long expectedSize) throws Exception {
+ protected String readFile(com.jcraft.jsch.Session session, String path, File target) throws Exception {
ChannelExec c = (ChannelExec) session.openChannel(Channel.CHANNEL_EXEC);
c.setCommand("scp -f " + path);
c.connect();
- int namePos = path.lastIndexOf('/');
- String fileName = (namePos >= 0) ? path.substring(namePos + 1) : path;
+ String fileName = target.getName();
try (OutputStream os = c.getOutputStream();
InputStream is = c.getInputStream()) {
os.write(0);
os.flush();
+
String header = readLine(is);
- assertEquals("Mismatched header for " + path, "C0644 " + expectedSize + " " + fileName, header);
+ Collection<PosixFilePermission> perms = IoUtils.getPermissions(target.toPath());
+ String octalPerms = ScpHelper.getOctalPermissions(perms);
+ String expHeader = "C" + octalPerms + " " + target.length() + " " + fileName;
+ assertEquals("Mismatched header for " + path, expHeader, header);
- int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
+ String lenValue = header.substring(6, header.indexOf(' ', 6));
+ int length = Integer.parseInt(lenValue);
os.write(0);
os.flush();
@@ -1022,7 +1026,7 @@ public class ScpTest extends BaseTestSupport {
}
}
- protected String readDir(com.jcraft.jsch.Session session, String path, String fileName, long expectedSize) throws Exception {
+ protected String readDir(com.jcraft.jsch.Session session, String path, File target) throws Exception {
ChannelExec c = (ChannelExec) session.openChannel(Channel.CHANNEL_EXEC);
c.setCommand("scp -r -f " + path);
c.connect();
@@ -1033,12 +1037,19 @@ public class ScpTest extends BaseTestSupport {
os.flush();
String header = readLine(is);
- assertTrue("Bad header prefix for " + path + ": " + header, header.startsWith("D0755 0 "));
+ File parent = target.getParentFile();
+ Collection<PosixFilePermission> perms = IoUtils.getPermissions(parent.toPath());
+ String octalPerms = ScpHelper.getOctalPermissions(perms);
+ String expPrefix = "D" + octalPerms + " 0 ";
+ assertTrue("Bad header prefix for " + path + ": " + header, header.startsWith(expPrefix));
os.write(0);
os.flush();
header = readLine(is);
- assertEquals("Mismatched dir header for " + path, "C0644 " + expectedSize + " " + fileName, header);
+ perms = IoUtils.getPermissions(target.toPath());
+ octalPerms = ScpHelper.getOctalPermissions(perms);
+ String expHeader = "C" + octalPerms + " " + target.length() + " " + target.getName();
+ assertEquals("Mismatched dir header for " + path, expHeader, header);
int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
os.write(0);
os.flush();
@@ -1079,7 +1090,7 @@ public class ScpTest extends BaseTestSupport {
}
}
- protected void sendFile(com.jcraft.jsch.Session session, String path, String name, String data) throws Exception {
+ protected void sendFile(com.jcraft.jsch.Session session, String path, File target, String data) throws Exception {
ChannelExec c = (ChannelExec) session.openChannel(Channel.CHANNEL_EXEC);
String command = "scp -t " + path;
c.setCommand(command);
@@ -1089,7 +1100,12 @@ public class ScpTest extends BaseTestSupport {
InputStream is = c.getInputStream()) {
assertAckReceived(is, command);
- assertAckReceived(os, is, "C7777 " + data.length() + " " + name);
+
+ File parent = target.getParentFile();
+ Collection<PosixFilePermission> perms = IoUtils.getPermissions(parent.toPath());
+ String octalPerms = ScpHelper.getOctalPermissions(perms);
+ String name = target.getName();
+ assertAckReceived(os, is, "C" + octalPerms + " " + data.length() + " " + name);
os.write(data.getBytes(StandardCharsets.UTF_8));
os.flush();