user2292916
user2292916

Reputation: 261

JSCH (SFTP) fails on change dir on sub folders level (second level)

JSch's SFTP channel fails to change directory when the previous directory is not in the root directory (ftp home). It happens only on some SFTP servers and not all of them.

For example the directory structure is this:

cd level-1 (OK)
cd level-2 (fails)

It throws an exception like this

4: Folder not found: /level-1/level-2
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2569)
    at com.jcraft.jsch.ChannelSftp._realpath(ChannelSftp.java:2100)
    at com.jcraft.jsch.ChannelSftp.cd(ChannelSftp.java:315)

The SFTP server with error returns / as realpath for the root. The other server that didn't fail returns full path list /usr/account.

Upvotes: 2

Views: 4033

Answers (2)

Martin Prikryl
Martin Prikryl

Reputation: 202672

I looks like a server-side problem/bug to me. The server might implement the SSH_FXP_REALPATH request incorrectly.

Is the account, you log in with, chrooted? Who does the chrooting, the SFTP server or is it system-level chrooting?

If you share log file, you may get more specific answer.

You might also try some other SFTP client that follows SFTP specification and uses the SSH_FXP_REALPATH request, when entering directory (many clients do not). It does not have to be Java library. Any client, even GUI, would do. Just for testing, if it gets into the same troubles. WinSCP for instance uses the SSH_FXP_REALPATH. Just try to connect and enter the /level-1/level-2. (I'm the author of WinSCP)

Upvotes: 1

user2292916
user2292916

Reputation: 261

I found source code for JSCH 0.1.49 and traced it. I found out there is a method named _realPath that throws exception when server fails to return the realpath. The input parameter for the method is absolute path of remote folder so I commented the exception out and instead returned the absolute path. Everything works fine.

This is the modified code. Note the original code works most of the time and the change I made is for rare situation that the server fails to return realpath on second level directory (sub folders), and there is no guarantee that it works for all servers.

//com.jcraft.jsch.ChannelSftp
private byte[] _realpath(String path) throws ... {
...
if (type == SSH_FXP_STATUS) {
  i = buf.getInt();
  /* Some servers fail to return the realPath
   on second level of directory (subfolders).
   original code is commented out and replaced with a return.*/
  //throwStatusError(buf, i);
  return (path.getBytes());
}
...

Upvotes: 1

Related Questions