Skip to content

Async method call in MySFTPServer __init__ method #695

Closed
@mertpp

Description

@mertpp

Hello
I need to get the path of the chroot of the user from the database. This is how I use my sftp server to create server.

    await asyncssh.create_server(
        MySSHServer, '', PORT,
        server_host_keys=['/Users/mertpolat/.ssh/id_rsa'],
        process_factory=lambda: None,  # No shell support
        sftp_factory=lambda chan: MySFTPServer(chan, db),  
        allow_scp=True,
        kex_algs=[
            'curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256',
            'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521', 'diffie-hellman-group14-sha1'
        ],
        encryption_algs=[
            'aes128-ctr', 'aes192-ctr', 'aes256-ctr'
        ],
        mac_algs=[
            'hmac-sha2-256', 'hmac-sha2-512'
        ],
        compression_algs=['none']
    )

This is how I implemented sftp server. the problem is at the get account by username method. That method should be asynchronous. I couldn't make init method asynchronous.

Copilot suggested me to create a create factory method that returns the instance of mysftpserver. But in that case the code block above doesn't work.

class MySFTPServer(asyncssh.SFTPServer):
    def __init__(self, chan: asyncssh.SSHServerChannel, db: 'Database'):
        self._chan = chan
        self._db = db
        self._username = chan.get_extra_info('username')
        super().__init__(chan)
        username = self._username
        logger.debug(f"Fetching account data for username: {username}")
        home_folder = await self._db.get_account_by_username(username)
        print(f"Account data: {home_folder}")
        if home_folder:
            os.makedirs(home_folder, exist_ok=True)
            logger.info(f"Establishing root_folder for {username} at: {home_folder}")
            self.set_chroot(home_folder)
        else:
            logger.error(f"Account for username {username} not found in the database or data is incomplete.")
            raise ValueError(f"Account for username {username} not found in the database or data is incomplete.")   

How can I change chroot of the sftp user retrieved from the database during the initialization?

I see ssh classes has connection_made method but SFTP subclasses doesn't, so I cannot change the users chroot after initialization.

thank you for your help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions