You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Documentation suggesting incorrect flags for sftp.open() #13
Data is copied from the remote file to the local file.
Actual behaviour:
No data is ever written to <file to write>. The size parameter is set by libssh2 to LIBSSH2_ERROR_SFTP_PROTOCOL (-31) and the calling sftp.last_error() will report LIBSSH2_FX_FAILURE (4). remote_fh.fstat() will succeed without issues (reporting correct data).
Additional info:
Version ssh2-python 0.6.0 with bundled libssh2.
This seems to happen because (at least up to libssh2 1.8.0) 0 and LIBSSH2_FXF_READ are not synonyms, like it is (in my understanding) incorrectly suggested in the documentation and the examples (sftp_read.py, for example). This may be tested using libssh2 directly by changing line 251 of the sftp.c example from:
At the moment I am not able to replicate this. Can you please show complete example code that replicates the issue?
Tested with the example sftp_read.py with no changes and size was non-negative. Also modified it to write to a local file like in the readme, as per below:
with sftp.open(args.file, 0, 0) as fh, \
open('test.copy', 'wb') as local_fh:
for size, data in fh:
local_fh.write(data)
I got back access to this particular server today, so I had the possibility to play around with it a little and investigate this further. It's a proprietary implementation and not OpenSSH, and I can confirm that using 0 with OpenSSH works correctly.
Which is kind of strange, since the SFTP specification I'm looking at does not mention a valid flag with the value 0 though, and libssh2 does not do any conversion.
I digged in and the reason it works in OpenSSH seem to be the way the portable flags from the specification (SSH_FXP_READ and so on) gets converted to the system specific flags by the SFTP server upon getting received (libssh2 leaves the value untouched on the client side). The flags_from_portable function returns from a value of 0 (which is the value we sent) the value of 0, which is (luckily!) the value for O_RDONLY in fcntl.h and everything ends up working smoothly :)
I suspect either the proprietary SSH implementation (I have no access to the server it's running on or the source code unfortunately) it's not so forgiving on the values of the flags (but should be returning an error and apparently it's not...) or it's running on a system where O_RDONLY != 0 (and so trying to read from a file which you did not open from reading does not work properly, and that's exactly what I'm seeing).
This seems to be a portability issue at the end of the day.
Thanks for checking and the great investigation! That all sounds reasonable, I have only ever integration tested with OpenSSH (or compatible) servers so is quite likely that other servers do not follow the 0 == read convention.
So documentation, API and readthedocs both, as well as example code need updating to use the LIBSSH2_FXF_READ.
If you'd like to take that on I would be very happy to accept a PR for it. Thanks again for the report.
Activity
pkittenis commentedon Nov 18, 2017
Hi there,
Thank you for the interest and the report!
At the moment I am not able to replicate this. Can you please show complete example code that replicates the issue?
Tested with the example sftp_read.py with no changes and size was non-negative. Also modified it to write to a local file like in the readme, as per below:
No errors. Copied file is identical.
Same code is also integration tested here with
0used as argument.All tests with libssh2
1.8.0-1.gvialetto commentedon Jan 2, 2018
Hi there,
I got back access to this particular server today, so I had the possibility to play around with it a little and investigate this further. It's a proprietary implementation and not OpenSSH, and I can confirm that using 0 with OpenSSH works correctly.
Which is kind of strange, since the SFTP specification I'm looking at does not mention a valid flag with the value 0 though, and libssh2 does not do any conversion.
I digged in and the reason it works in OpenSSH seem to be the way the portable flags from the specification (
SSH_FXP_READand so on) gets converted to the system specific flags by the SFTP server upon getting received (libssh2 leaves the value untouched on the client side). Theflags_from_portablefunction returns from a value of 0 (which is the value we sent) the value of 0, which is (luckily!) the value forO_RDONLYinfcntl.hand everything ends up working smoothly :)I suspect either the proprietary SSH implementation (I have no access to the server it's running on or the source code unfortunately) it's not so forgiving on the values of the flags (but should be returning an error and apparently it's not...) or it's running on a system where O_RDONLY != 0 (and so trying to read from a file which you did not open from reading does not work properly, and that's exactly what I'm seeing).
This seems to be a portability issue at the end of the day.
pkittenis commentedon Jan 3, 2018
Hi there,
Thanks for checking and the great investigation! That all sounds reasonable, I have only ever integration tested with OpenSSH (or compatible) servers so is quite likely that other servers do not follow the
0 == readconvention.So documentation, API and readthedocs both, as well as example code need updating to use the
LIBSSH2_FXF_READ.If you'd like to take that on I would be very happy to accept a PR for it. Thanks again for the report.