asyncssh icon indicating copy to clipboard operation
asyncssh copied to clipboard

Async SSH sftp returning error 0x00000010

Open rgutierrezarana opened this issue 2 years ago • 9 comments

when I try to connect to a server with async_ssh with the sftp command then I get the following error

`from asyncssh import connect import asyncio

sftp_conn_options = { "host": "EXAMPLE HOST", "username": "EXAMPLE USER", "password": "EXAMPLE PASS", "known_hosts": None, "port": 22, }

async def main(): async with connect(**sftp_conn_options) as conn: async with conn.start_sftp_client() as sftp: listed_files = await sftp.listdir(".") print(listed_files)

if name == "main": loop = asyncio.get_event_loop() loop.run_until_complete(main())

ERROR raise SFTPBadMessage('Unsupported attribute flags: 0x%08x' % asyncssh.sftp.SFTPBadMessage: Unsupported attribute flags: 0x00000010`

rgutierrezarana avatar Aug 10 '23 10:08 rgutierrezarana

Which version of AsyncSSH are you running? This sounds a lot like a known issue where some SFTP servers violate the spec (see #530 for details), but there should be a workaround included in AsyncSSH 2.13.0 and later.

ronf avatar Aug 10 '23 13:08 ronf

Hi I am using the asyncssh==2.13.2 version with python 3.7.9 on windows

DEBUG:asyncssh:[conn=0] Sending version SSH-2.0-AsyncSSH_2.13.2 DEBUG:asyncssh:[conn=0] Received version SSH-2.0-WS_FTP-SSH_8.8.1.33

rgutierrezarana avatar Aug 10 '23 13:08 rgutierrezarana

Ok - that version should include the workaround, but the workaround only applied when FILEXFER_ATTR_MODIFYTIME was set at the same time as FILEXFER_ATTR_ACMODTIME, and only when using SFTP version 3. Do you know the type of SSH server you are connecting to?

ronf avatar Aug 11 '23 01:08 ronf

I got this stack trace DEBUG:asyncio:Using selector: SelectSelector INFO:asyncssh:Opening SSH connection to "sftp host" , port 22 INFO:asyncssh:[conn=0] Connected to SSH server at "sftp host", port 22 INFO:asyncssh:[conn=0] Local address: 192.168.18.71, port 15718 INFO:asyncssh:[conn=0] Peer address: 3.212.185.206, port 22 DEBUG:asyncssh:[conn=0] Sending version SSH-2.0-AsyncSSH_2.13.2 DEBUG:asyncssh:[conn=0] Received version SSH-2.0-WS_FTP-SSH_8.8.1.33 DEBUG:asyncssh:[conn=0] Requesting key exchange DEBUG:asyncssh:[conn=0] Key exchange algs: curve25519-sha256,[email protected],curve448-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,ecdh-sha2-1.3.132.0.10,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group15-sha512,diffie-hellman-group16-sha512,diffie-hellman-group17-sha512,diffie-hellman-group18-sha512,[email protected],diffie-hellman-group14-sha1,rsa2048-sha256,ext-info-c DEBUG:asyncssh:[conn=0] Host key algs: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],ssh-ed25519,ssh-ed448,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256,ecdsa-sha2-1.3.132.0.10,rsa-sha2-256,rsa-sha2-512,[email protected],[email protected],[email protected],[email protected],ssh-rsa DEBUG:asyncssh:[conn=0] Encryption algs: [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
DEBUG:asyncssh:[conn=0] MAC algs: [email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1,[email protected],[email protected],[email protected],[email protected],[email protected] DEBUG:asyncssh:[conn=0] Compression algs: [email protected],none DEBUG:asyncssh:[conn=0] Received key exchange request DEBUG:asyncssh:[conn=0] Key exchange algs: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256 DEBUG:asyncssh:[conn=0] Host key algs: rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss DEBUG:asyncssh:[conn=0] Client to server: DEBUG:asyncssh:[conn=0] Encryption algs: blowfish-cbc,aes128-ctr,aes192-ctr,aes256-ctr DEBUG:asyncssh:[conn=0] MAC algs: hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96,hmac-sha2-256,hmac-sha2-384,hmac-sha2-512 DEBUG:asyncssh:[conn=0] Compression algs: none DEBUG:asyncssh:[conn=0] Server to client: DEBUG:asyncssh:[conn=0] Encryption algs: blowfish-cbc,aes128-ctr,aes192-ctr,aes256-ctr DEBUG:asyncssh:[conn=0] MAC algs: hmac-md5,hmac-sha1,hmac-sha1-96,hmac-md5-96,hmac-sha2-256,hmac-sha2-384,hmac-sha2-512 DEBUG:asyncssh:[conn=0] Compression algs: none DEBUG:asyncssh:[conn=0] Beginning key exchange DEBUG:asyncssh:[conn=0] Key exchange alg: diffie-hellman-group-exchange-sha256 DEBUG:asyncssh:[conn=0] Client to server: DEBUG:asyncssh:[conn=0] Encryption alg: aes256-ctr DEBUG:asyncssh:[conn=0] MAC alg: hmac-sha2-256 DEBUG:asyncssh:[conn=0] Compression alg: none DEBUG:asyncssh:[conn=0] Server to client: DEBUG:asyncssh:[conn=0] Encryption alg: aes256-ctr DEBUG:asyncssh:[conn=0] MAC alg: hmac-sha2-256 DEBUG:asyncssh:[conn=0] Compression alg: none DEBUG:asyncssh:[conn=0] Requesting service ssh-userauth DEBUG:asyncssh:[conn=0] Completed key exchange DEBUG:asyncssh:[conn=0] Request for service ssh-userauth accepted INFO:asyncssh:[conn=0] Beginning auth for user REDACTED DEBUG:asyncssh:[conn=0] Remaining auth methods: publickey,password DEBUG:asyncssh:[conn=0] Preferred auth methods: gssapi-keyex,gssapi-with-mic,hostbased,publickey,keyboard-interactive,password DEBUG:asyncssh:[conn=0] Trying public key auth with ssh-rsa key DEBUG:asyncssh:[conn=0] Remaining auth methods: publickey,password DEBUG:asyncssh:[conn=0] Preferred auth methods: gssapi-keyex,gssapi-with-mic,hostbased,publickey,keyboard-interactive,password DEBUG:asyncssh:[conn=0] Trying password auth INFO:asyncssh:[conn=0] Auth for user REDACTED succeeded CONNECTEd DEBUG:asyncssh:[conn=0, chan=0] Set write buffer limits: low-water=16384, high-water=65536 INFO:asyncssh:[conn=0, chan=0] Requesting new SSH session DEBUG:asyncssh:[conn=0, chan=0] Initial recv window 2097152, packet size 32768 DEBUG:asyncssh:[conn=0, chan=0] Initial send window 30000000, packet size 3000000 INFO:asyncssh:[conn=0, chan=0] Subsystem: sftp INFO:asyncssh.sftp:[conn=0, chan=0] Starting SFTP client DEBUG:asyncssh.sftp:[conn=0, chan=0] Sending init, version=3 DEBUG:asyncssh:[conn=0, chan=0] Sending 9 data bytes DEBUG:asyncssh:[conn=0, chan=0] Reading from channel started DEBUG:asyncssh:[conn=0, chan=0] Received 9 data bytes DEBUG:asyncssh.sftp:[conn=0, chan=0] Received version=3

DEBUG:asyncssh.sftp:[conn=0, chan=0] Sending opendir for . DEBUG:asyncssh:[conn=0, chan=0] Sending 14 data bytes DEBUG:asyncssh:[conn=0, chan=0] Received 16 data bytes DEBUG:asyncssh.sftp:[conn=0, chan=0] Received handle 323436 DEBUG:asyncssh.sftp:[conn=0, chan=0] Sending readdir for handle 323436 DEBUG:asyncssh:[conn=0, chan=0] Sending 16 data bytes DEBUG:asyncssh:[conn=0, chan=0] Received 32709 data bytes DEBUG:asyncssh.sftp:[conn=0, chan=0] Sending close for handle 323436 DEBUG:asyncssh:[conn=0, chan=0] Sending 16 data bytes DEBUG:asyncssh:[conn=0, chan=0] Received 21 data bytes DEBUG:asyncssh.sftp:[conn=0, chan=0] Received OK DEBUG:asyncssh:[conn=0, chan=0] Sending EOF INFO:asyncssh:[conn=0, chan=0] Received channel close INFO:asyncssh:[conn=0, chan=0] Channel closed INFO:asyncssh.sftp:[conn=0, chan=0] SFTP client exited INFO:asyncssh:[conn=0, chan=0] Closing channel INFO:asyncssh:[conn=0] Closing connection INFO:asyncssh:[conn=0] Sending disconnect: Disconnected by application (11) INFO:asyncssh:[conn=0] Connection closed SFTP operation failed: Unsupported attribute flags: 0x00000010

rgutierrezarana avatar Aug 11 '23 12:08 rgutierrezarana

Ok, so the server is WS_FTP. I haven't seen this problem on that server before. It looks like you're negotiating SFTP version 3 (which is the usual default), but the server is sending an attribute value that's only legal in SFTP version 4 and higher. AsyncSSH supports those higher versions, so you could try requesting that to see if that work around the server issue.

Do you still see a problem if you set sftp_version=6 in the call to start_sftp_client()? If so, what about setting the version to 4, which should be enough to allow this attribute?

If that doesn't work, the next step would probably be to turn up the debug level to 3 so we can see the exact response the server is sending for the SFTPAttrs in the readdir response, To avoid sharing potentially sensitive data you'll probably want to only post the output after the "Sending readdir" message (specifically the packet corresponding to the "Received 32709 data bytes" in the output above), and even there feel free to redact any filenames you see if that's a concern. It's the attribute data after each filename/longname that I really need to see.

ronf avatar Aug 11 '23 13:08 ronf

I took a closer look at this today, and it looks like the server is sending FILEXFER_ATTR_CREATETIME in its response, where my previous workaround was for servers sending FILEXFER_ATTR_MODIFYTIME when using SFTP version 3. Neither of these is legal in SFTP version 3. According to https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt, only the following flags are defined:

   	#define SSH_FILEXFER_ATTR_SIZE          0x00000001
   	#define SSH_FILEXFER_ATTR_UIDGID        0x00000002
   	#define SSH_FILEXFER_ATTR_PERMISSIONS   0x00000004
   	#define SSH_FILEXFER_ATTR_ACMODTIME     0x00000008
   	#define SSH_FILEXFER_ATTR_EXTENDED      0x80000000

To make matters worse, it's not clear what order additional fields would be in if they were included. New flags can only be added by either using the extension mechanism or by an SFTP version change, such as what happens with SFTP version 4 documented at https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-03.txt, which defines the following:

   	#define SSH_FILEXFER_ATTR_SIZE            0x00000001
   	#define SSH_FILEXFER_ATTR_PERMISSIONS     0x00000004
   	#define SSH_FILEXFER_ATTR_ACCESSTIME      0x00000008
   	#define SSH_FILEXFER_ATTR_CREATETIME      0x00000010
   	#define SSH_FILEXFER_ATTR_MODIFYTIME      0x00000020
   	#define SSH_FILEXFER_ATTR_ACL             0x00000040
   	#define SSH_FILEXFER_ATTR_OWNERGROUP      0x00000080
   	#define SSH_FILEXFER_ATTR_EXTENDED        0x80000000

With SFTP version 3, there's a single flag (ACMODTIME) which went set will cause both access time and modify time to be sent in that order. With SFTP version 4, the ACMODTIME flag is replaced with ACCESSTIME and new flags are created for CREATETIME and MODIFYTIME. with the order being access time followed by create time followed by modify time if all three flags are set. So, if SFTP version is 3, would the value 8 in flags mean ACMODTIME (send both access & modify time) or ACCESSTIME, and if MODIFYTIME and/or CREATETIME are set, what order do they go in?

ronf avatar Aug 13 '23 13:08 ronf

For your specific case, it would be good to see the actual flags value in each of the SFTPAttrs being returned in the directory listing, along with how many additional fields are present. By looking at the timestamps, we can probably also get a sense of the order of these timestamps.

ronf avatar Aug 13 '23 13:08 ronf

@ronf

just to add my findings, without sftp_version=6 below code will throw SFTP operation failed: Unsupported attribute flags: 0x00000010

import asyncio, asyncssh, sys

async def run_client() -> None:
    async with asyncssh.connect(in_sftp_server,username=in_sftp_user, password=in_sftp_pwd, known_hosts=None) as conn:
        async with conn.start_sftp_client(sftp_version=6) as sftp:
            await sftp.get(fpath,preserve=False)

try:
    asyncio.get_event_loop().run_until_complete(run_client())
except (OSError, asyncssh.Error) as exc:
    sys.exit('SFTP operation failed: ' + str(exc))

Server: Windows server 2019, Progress WS_SFTP server 8.7.3 Client: asyncssh 2.13.2, Python 3.10.12 on Ubuntu 22.04

hemanthactionfi avatar Sep 13 '23 11:09 hemanthactionfi

Ok - that suggests that the server you are using doesn't actually support SFTP versions greater than 3. If that's the case, though, it is definitely a bug for it to be sending attributes with the 0x00000010 bit set. However, without knowing what exactly the rest of the packet looks like, it's hard for me to suggest possible workarounds.

ronf avatar Sep 13 '23 14:09 ronf

Closing due to inactivity. Feel free to reopen this or open a new issue if you need anything else.

ronf avatar Jul 03 '24 15:07 ronf