I’m writing custom filesystem classes for Apache SSHd. I’ve hit an issue when the client tries to get a file that doesn’t exist.
My object returns doesExist() == false.
This causes the server to send an SSH_FX_NO_SUCH_FILE packet in response to a SSH_FXP_STAT.
Using an the OpenSSH client, this works fine : the client reports “File ‘/foo’ not found”.
However, PSFTP (the Putty SFTP client) pipelines its requests, so it sends an OPEN packet regardless of the response to STAT. It then sends a READ on the resulting filehandle, which currently causes an exception in my code, which results in the whole session terminating.
What should the server response be when there is an attempt to read a file which does not exist?
With apologies for verbosity, here’s the Apache code in question. I’d prefer not to modify it — my class is the SshFile “file” here. But if the Apache code is definitely buggy, I guess I’ll have to give them a patch.
if (version <= 4) {
String path = buffer.getString();
int pflags = buffer.getInt();
// attrs
try {
SshFile file = resolveFile(path);
if (file.doesExist()) {
if (((pflags & SSH_FXF_CREAT) != 0) && ((pflags & SSH_FXF_EXCL) != 0)) {
sendStatus(id, SSH_FX_FILE_ALREADY_EXISTS, path);
return;
}
} else {
if (((pflags & SSH_FXF_CREAT) != 0)) {
if (!file.isWritable()) {
sendStatus(id, SSH_FX_FAILURE, "Can not create " + path);
return;
}
file.create();
}
}
String acc = ((pflags & (SSH_FXF_READ | SSH_FXF_WRITE)) != 0 ? "r" : "") +
((pflags & SSH_FXF_WRITE) != 0 ? "w" : "");
if ((pflags & SSH_FXF_TRUNC) != 0) {
file.truncate();
}
String handle = UUID.randomUUID().toString();
handles.put(handle, new FileHandle(file, pflags)); // handle flags conversion
sendHandle(id, handle);
} catch (IOException e) {
sendStatus(id, SSH_FX_FAILURE, e.getMessage());
}
Reply to the
SSH_FXP_OPENrequest also with aSSH_FX_NO_SUCH_FILEstatus code. That should solve the problem withpsftp.Anyway, you have to keep a register of the active file and directory handles. When the remote side request an operation for a handle that is not active or that is not of the right type, respond with a
SSH_FX_FAILUREstatus message. Use theerror messageslot on theSSH_FXP_STATUSpacket to include a more informative and user friendly error as just the code is not very useful.