Log in

Shelless SSH Server with Twisted - c y l i

Ying Li
Date: 2008-04-11 11:39
Subject: Shelless SSH Server with Twisted
Security: Public
Tags:python, twisted
I needed a shelless SSH server that would not honor shell requests or exec commands, because I wanted to provide SFTP access without allowing shell access. I'm only posting this because this may be useful to people - I don't know Twisted very well, and there may be a better way to do it, but this works:
from zope import interface
from twisted.cred import portal
from twisted.python import log
from twisted.conch.avatar import ConchUser
from twisted.conch.ssh import session

class ShelllessSSHRealm:

    def requestAvatar(self, avatarID, mind, *interfaces):
        user = ShelllessUser()
        return interfaces[0], user, user.logout

class ShelllessUser(ConchUser):
    A shell-less user that does not answer any global requests.
    def __init__(self, root=None):
        self.channelLookup["session"] = ShelllessSession

    def logout(self):
        pass   # nothing to do

class ShelllessSession(session.SSHSession):
    name = 'shellessSession'

    def __init__(self, *args, **kw):
        session.SSHSession.__init__(self, *args, **kw)
    def _noshell(self):
        if not self.closing:
            self.write("This server does not provide shells "
                       "or allow command execution.\n")
        return 0

    def request_shell(self, data):
        log.msg("shell request rejected")
        return self._noshell()

    def request_exec(self, data):
        log.msg("execution request rejected")
        return self._noshell()

    def request_pty_req(self, data):
        log.msg("pty request rejected")
        return self._noshell()

    def request_window_change(self, data):
        log.msg("window change request rejected")
        return 0

I have tests for it and everything - I can post those if someone wants them.
Post A Comment | 2 Comments | Share | Link

User: ext_138641
Date: 2008-12-17 20:07 (UTC)
Subject: where is the SFTP implementation
(and where is the

if __name__ == '__main__':

I would love to try reusing this code but need more of this example.
Reply | Thread | Link

User: (Anonymous)
Date: 2008-12-23 11:11 (UTC)
Subject: ...
Nice one, it kind of helped me.

Looks like you forgot about SSH tunneling. Here's how you allow it:

self.channelLookup['direct-tcpip'] = twisted.conch.ssh.forwarding.openConnectForwardingClient

Now set a function that raises an exception, and you are done (=> connection gets closed). I have not yet figured out how to send an error message to the client.

Tests would be nice.
Reply | Thread | Link

my journal
May 2009