Skip to content

File not found in ScpShell by using user.setHomeDirectory() #677

@araneolus

Description

@araneolus

Version

2.15.0

Bug description

I have enable the scpShell to my ScpCommandFactory so the scp will works with winscp, too.
Now I have a Problem, if I am working with chroot home Directory.

Lets show the complete debug way to find out the error.
My chroot Home Directory is '/home/guest' with the file 'abc.txt'
And now, I want to download it with winscp.

The Function doScp(... in the class ScpShell.class will resolve the local Path of the File

   protected void doScp(
            String command, String path, boolean optR, boolean optT, boolean optF, boolean optD, boolean optP)
            throws Exception {
        try {
            ChannelSession channel = getServerChannelSession();
            ScpHelper helper = new ScpHelper(
                    channel.getSession(), getInputStream(), getOutputStream(),
                    fileSystem, opener, listener);
            Path localPath = currentDir.resolve(path);  <----------------------
            if (optT) {
                helper.receive(command, localPath, optR, optD, optP, receiveBufferSize);
            } else {
                helper.send(Collections.singletonList(localPath.toString()), optR, optP, sendBufferSize);
            }
...

The function "public void send(Collection paths, boolean recursive, boolean preserve, int bufferSize) throws IOException "
enables hard coded the check of LinkOptions

    public void send(Collection<String> paths, boolean recursive, boolean preserve, int bufferSize) throws IOException {
        boolean debugEnabled = log.isDebugEnabled();
        readAndValidateOperationAck("send", "Paths");

        LinkOption[] options = IoUtils.getLinkOptions(true);   <----------------------

and now by calling the function

   protected void send(Path local, boolean recursive, boolean preserve, int bufferSize, LinkOption... options)
            throws IOException {
        Path localPath = Objects.requireNonNull(local, "No local path").normalize().toAbsolutePath();
        Session session = getSession();
        Path file = opener.resolveOutgoingFilePath(session, localPath, options);

The resolveOutgoingFilePath(... checks, if the File exists.

   default Path resolveOutgoingFilePath(
            Session session, Path localPath, LinkOption... options)
            throws IOException {
        Boolean status = IoUtils.checkFileExists(localPath, options);   <----------------------
   public static Boolean checkFileExists(Path path, LinkOption... options) {
        boolean followLinks = followLinks(options);  

        try {
            if (followLinks) {
                path.getFileSystem().provider().checkAccess(path);   <----------------------

and now the RootedFilesystem.class wíll check the Access of the file. The Call of unroot(path) will extend the localPath from '/home/guest/abc.txt' to '/home/guest/home/guest/abc.txt'

   @Override
    public void checkAccess(Path path, AccessMode... modes) throws IOException {
        Path r = unroot(path);  <----------------------
        FileSystemProvider p = provider(r);
        try {
            p.checkAccess(r, modes);
        } catch (IOException ex) {
            throw translateIoException(ex, path);
        }
    }

Actual behavior

The Directory "/home/guest/" will be extend to '/home/guest/home/guest'

Expected behavior

The Directory “/home/guest/” should remain '/home/guest', or the path should not be replaced by the local path.

Relevant log output

Other information

No response

Metadata

Metadata

Assignees

Labels

bugAn issue describing a bug in the code

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions