Esempio n. 1
0
    def request_env(self, data):
        """
        Process a request to pass an environment variable.

        @param data: The environment variable name and value, each encoded
            as an SSH protocol string and concatenated.
        @type data: L{bytes}
        @return: A true value if the request to pass this environment
            variable was accepted, otherwise a false value.
        """
        if not self.session:
            self.session = ISession(self.avatar)
        if not ISessionSetEnv.providedBy(self.session):
            log.warn(
                "Can't handle environment variables for SSH avatar {avatar}: "
                "{session} does not provide ISessionSetEnv interface. "
                "It should be decorated with @implementer(ISession, "
                "ISessionSetEnv) to support env variables.",
                avatar=self.avatar,
                session=self.session,
            )
            return 0
        name, value, data = common.getNS(data, 2)
        try:
            self.session.setEnv(name, value)
        except EnvironmentVariableNotPermitted:
            return 0
        except Exception:
            log.failure("Error setting environment variable {name}", name=name)
            return 0
        else:
            return 1
Esempio n. 2
0
    def test_avatarAdaptsToRestrictedExecOnlySession(self):
        # When Conch tries to adapt the SSH server avatar to ISession, it
        # adapts to a RestrictedExecOnlySession. This means that a
        # RestrictedExecOnlySession handles any requests to execute a command.
        session = ISession(self.avatar)
        self.assertTrue(
            isinstance(session, RestrictedExecOnlySession),
            "ISession(avatar) doesn't adapt to ExecOnlySession. "
            "Got %r instead." % (session, ))
        self.assertEqual(get_BZR_PLUGIN_PATH_for_subprocess(),
                         session.environment['BZR_PLUGIN_PATH'])
        self.assertEqual('*****@*****.**' % self.avatar.username,
                         session.environment['BZR_EMAIL'])

        executable, arguments = session.getCommandToRun(
            'bzr serve --inet --directory=/ --allow-writes')
        interpreter = '%s/bin/py' % config.root
        self.assertEqual(interpreter, executable)
        self.assertEqual([
            interpreter,
            get_bzr_path(), 'lp-serve', '--inet',
            str(self.avatar.user_id)
        ], list(arguments))
        self.assertRaises(ForbiddenCommand, session.getCommandToRun,
                          'rm -rf /')
Esempio n. 3
0
    def test_avatarAdaptsToRestrictedExecOnlySession(self):
        # When Conch tries to adapt the SSH server avatar to ISession, it
        # adapts to a RestrictedExecOnlySession. This means that a
        # RestrictedExecOnlySession handles any requests to execute a command.
        session = ISession(self.avatar)
        self.failUnless(
            isinstance(session, RestrictedExecOnlySession),
            "ISession(avatar) doesn't adapt to ExecOnlySession. "
            "Got %r instead." % (session,))
        self.assertEqual(
            get_BZR_PLUGIN_PATH_for_subprocess(),
            session.environment['BZR_PLUGIN_PATH'])
        self.assertEqual(
            '*****@*****.**' % self.avatar.username,
            session.environment['BZR_EMAIL'])

        executable, arguments = session.getCommandToRun(
            'bzr serve --inet --directory=/ --allow-writes')
        interpreter = '%s/bin/py' % config.root
        self.assertEqual(interpreter, executable)
        self.assertEqual(
            [interpreter, get_bzr_path(), 'lp-serve',
             '--inet', str(self.avatar.user_id)],
            list(arguments))
        self.assertRaises(
            ForbiddenCommand, session.getCommandToRun, 'rm -rf /')
Esempio n. 4
0
 def request_window_change(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     winSize = parseRequest_window_change(data)
     try:
         self.session.windowChanged(winSize)
     except Exception:
         log.failure("Error changing window size")
         return 0
     else:
         return 1
Esempio n. 5
0
 def request_window_change(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     winSize = parseRequest_window_change(data)
     try:
         self.session.windowChanged(winSize)
     except:
         log.msg('error changing window size')
         log.err()
         return 0
     else:
         return 1
Esempio n. 6
0
 def request_pty_req(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     term, windowSize, modes = parseRequest_pty_req(data)
     log.msg('pty request: %s %s' % (term, windowSize))
     try:
         self.session.getPty(term, windowSize, modes) 
     except:
         log.err()
         return 0
     else:
         return 1
Esempio n. 7
0
 def request_shell(self, data):
     log.msg('getting shell')
     if not self.session:
         self.session = ISession(self.avatar)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.openShell(pp)
     except:
         log.deferr()
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 8
0
 def request_shell(self, data):
     log.info("Getting shell")
     if not self.session:
         self.session = ISession(self.avatar)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.openShell(pp)
     except Exception:
         log.failure("Error getting shell")
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 9
0
 def request_exec(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     f,data = common.getNS(data)
     log.msg('executing command "%s"' % f)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.execCommand(pp, f)
     except:
         log.deferr()
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 10
0
 def request_pty_req(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     term, windowSize, modes = parseRequest_pty_req(data)
     log.info('Handling pty request: {term!r} {windowSize!r}',
              term=term,
              windowSize=windowSize)
     try:
         self.session.getPty(term, windowSize, modes)
     except Exception:
         log.failure('Error handling pty request')
         return 0
     else:
         return 1
Esempio n. 11
0
 def request_exec(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     f, data = common.getNS(data)
     log.info('Executing command "{f}"', f=f)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.execCommand(pp, f)
     except Exception:
         log.failure('Error executing command "{f}"', f=f)
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 12
0
    def test_openShell(self):
        """
        The L{ISession} adapter of the L{IConchUser} powerup implements
        C{openShell} so as to associate the given L{IProcessProtocol} with a
        transport.
        """
        proto = ProcessProtocol()
        session = ISession(IConchUser(self.store))

        # XXX See Twisted ticket #3864
        proto.session = session
        proto.write = lambda bytes: None

        # XXX See #2895.
        session.getPty(None, (123, 456, 789, 1000), None)
        session.openShell(proto)
        self.assertNotIdentical(proto.transport, None)
Esempio n. 13
0
 def test_avatarAdaptsToOnlyRestrictedSession(self):
     config.push('codehosting-no-forking',
         "[codehosting]\nuse_forking_daemon: False\n")
     self.addCleanup(config.pop, 'codehosting-no-forking')
     session = ISession(self.avatar)
     self.failIf(isinstance(session, ForkingRestrictedExecOnlySession),
         "ISession(avatar) shouldn't adapt to "
         " ForkingRestrictedExecOnlySession when forking is disabled. ")
Esempio n. 14
0
 def test_avatarAdaptsToForkingRestrictedExecOnlySession(self):
     config.push('codehosting-forking',
                 "[codehosting]\nuse_forking_daemon: True\n")
     self.addCleanup(config.pop, 'codehosting-forking')
     session = ISession(self.avatar)
     self.assertTrue(
         isinstance(session, ForkingRestrictedExecOnlySession),
         "ISession(avatar) doesn't adapt to "
         " ForkingRestrictedExecOnlySession. "
         "Got %r instead." % (session, ))
     executable, arguments = session.getCommandToRun(
         'bzr serve --inet --directory=/ --allow-writes')
     executable, arguments, env = session.getCommandToFork(
         executable, arguments, session.environment)
     self.assertEqual('bzr', executable)
     self.assertEqual(
         ['bzr', 'lp-serve', '--inet',
          str(self.avatar.user_id)], list(arguments))
Esempio n. 15
0
 def test_interfaces(self):
     """
     L{ShellAccount} powers up the item on which it is installed for
     L{IConchUser} and the L{IConchUser} powerup is adaptable to
     L{ISession}.
     """
     avatar = IConchUser(self.store)
     self.assertTrue(verifyObject(IConchUser, avatar))
     session = ISession(avatar)
     self.assertTrue(verifyObject(ISession, session))
Esempio n. 16
0
 def test_avatarAdaptsToForkingRestrictedExecOnlySession(self):
     config.push('codehosting-forking',
         "[codehosting]\nuse_forking_daemon: True\n")
     self.addCleanup(config.pop, 'codehosting-forking')
     session = ISession(self.avatar)
     self.failUnless(
         isinstance(session, ForkingRestrictedExecOnlySession),
         "ISession(avatar) doesn't adapt to "
         " ForkingRestrictedExecOnlySession. "
         "Got %r instead." % (session,))
     executable, arguments = session.getCommandToRun(
         'bzr serve --inet --directory=/ --allow-writes')
     executable, arguments, env = session.getCommandToFork(
         executable, arguments, session.environment)
     self.assertEqual('bzr', executable)
     self.assertEqual(
          ['bzr', 'lp-serve',
           '--inet', str(self.avatar.user_id)],
          list(arguments))
Esempio n. 17
0
 def request_pty_req(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     term, windowSize, modes = parseRequest_pty_req(data)
     log.msg('pty request: %s %s' % (term, windowSize))
     try:
         self.session.getPty(term, windowSize, modes)
     except:
         log.err()
         return 0
     else:
         return 1
Esempio n. 18
0
 def request_window_change(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     winSize = parseRequest_window_change(data)
     try:
         self.session.windowChanged(winSize)
     except:
         log.msg('error changing window size')
         log.err()
         return 0
     else:
         return 1
Esempio n. 19
0
 def request_shell(self, data):
     log.msg('getting shell')
     if not self.session:
         self.session = ISession(self.avatar)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.openShell(pp)
     except:
         log.deferr()
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 20
0
 def request_exec(self, data):
     if not self.session:
         self.session = ISession(self.avatar)
     f,data = common.getNS(data)
     log.msg('executing command "%s"' % f)
     try:
         pp = SSHSessionProcessProtocol(self)
         self.session.execCommand(pp, f)
     except:
         log.deferr()
         return 0
     else:
         self.client = pp
         return 1
Esempio n. 21
0
    def request_env(self, data):
        """
        data should contain two netstrings.
        The first is an env var name, the second its requested value.
        """
        name, rest = getNS(data)
        value, rest = getNS(rest)
        if rest:
            raise ValueError("Bad data given in env request.")

        if name in ENV_WHITELIST:
            log.msg("env request: %s=%s" % (name, value))

            if not self.session:
                self.session = ISession(self.avatar)

            self.session.environ[name] = value
            return True
        else:
            log.msg("env request REJECTED: %s=%s" % (name, value))
            return False
Esempio n. 22
0
    def test_openShell(self):
        """
        The L{ISession} adapter of the L{IConchUser} powerup implements
        C{openShell} so as to associate the given L{IProcessProtocol} with a
        transport.
        """
        proto = ProcessProtocol()
        session = ISession(IConchUser(self.store))

        # XXX See Twisted ticket #3864
        proto.session = session
        proto.write = lambda bytes: None

        # XXX See #2895.
        session.getPty(None, (123, 456, 789, 1000), None)
        session.openShell(proto)
        self.assertNotIdentical(proto.transport, None)
Esempio n. 23
0
class SSHSession(channel.SSHChannel):

    name = 'session'
    def __init__(self, *args, **kw):
        channel.SSHChannel.__init__(self, *args, **kw)
        self.buf = ''
        self.client = None
        self.session = None

    def request_subsystem(self, data):
        subsystem, ignored= common.getNS(data)
        log.msg('asking for subsystem "%s"' % subsystem)
        client = self.avatar.lookupSubsystem(subsystem, data)
        if client:
            pp = SSHSessionProcessProtocol(self)
            proto = wrapProcessProtocol(pp)
            client.makeConnection(proto)
            pp.makeConnection(wrapProtocol(client))
            self.client = pp
            return 1
        else:
            log.msg('failed to get subsystem')
            return 0

    def request_shell(self, data):
        log.msg('getting shell')
        if not self.session:
            self.session = ISession(self.avatar)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.openShell(pp)
        except:
            log.deferr()
            return 0
        else:
            self.client = pp
            return 1

    def request_exec(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        f,data = common.getNS(data)
        log.msg('executing command "%s"' % f)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.execCommand(pp, f)
        except:
            log.deferr()
            return 0
        else:
            self.client = pp
            return 1

    def request_pty_req(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        term, windowSize, modes = parseRequest_pty_req(data)
        log.msg('pty request: %s %s' % (term, windowSize))
        try:
            self.session.getPty(term, windowSize, modes)
        except:
            log.err()
            return 0
        else:
            return 1

    def request_window_change(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        winSize = parseRequest_window_change(data)
        try:
            self.session.windowChanged(winSize)
        except:
            log.msg('error changing window size')
            log.err()
            return 0
        else:
            return 1

    def dataReceived(self, data):
        if not self.client:
            #self.conn.sendClose(self)
            self.buf += data
            return
        self.client.transport.write(data)

    def extReceived(self, dataType, data):
        if dataType == connection.EXTENDED_DATA_STDERR:
            if self.client and hasattr(self.client.transport, 'writeErr'):
                self.client.transport.writeErr(data)
        else:
            log.msg('weird extended data: %s'%dataType)

    def eofReceived(self):
        if self.session:
            self.session.eofReceived()
        elif self.client:
            self.conn.sendClose(self)

    def closed(self):
        if self.session:
            self.session.closed()
        elif self.client:
            self.client.transport.loseConnection()

    #def closeReceived(self):
    #    self.loseConnection() # don't know what to do with this

    def loseConnection(self):
        if self.client:
            self.client.transport.loseConnection()
        channel.SSHChannel.loseConnection(self)
Esempio n. 24
0
class SSHSession(channel.SSHChannel):
    """
    A generalized implementation of an SSH session.

    See RFC 4254, section 6.

    The precise implementation of the various operations that the remote end
    can send is left up to the avatar, usually via an adapter to an
    interface such as L{ISession}.

    @ivar buf: a buffer for data received before making a connection to a
        client.
    @type buf: L{bytes}
    @ivar client: a protocol for communication with a shell, an application
        program, or a subsystem (see RFC 4254, section 6.5).
    @type client: L{SSHSessionProcessProtocol}
    @ivar session: an object providing concrete implementations of session
        operations.
    @type session: L{ISession}
    @ivar _sessionSetEnv: an object providing a concrete implementation of
        the C{setEnv} session operation.
    @type _sessionSetEnv: L{ISessionSetEnv}
    """

    name = b'session'

    def __init__(self, *args, **kw):
        channel.SSHChannel.__init__(self, *args, **kw)
        self.buf = b''
        self.client = None
        self.session = None
        self._sessionSetEnv = None

    def request_subsystem(self, data):
        subsystem, ignored = common.getNS(data)
        log.info('Asking for subsystem "{subsystem}"', subsystem=subsystem)
        client = self.avatar.lookupSubsystem(subsystem, data)
        if client:
            pp = SSHSessionProcessProtocol(self)
            proto = wrapProcessProtocol(pp)
            client.makeConnection(proto)
            pp.makeConnection(wrapProtocol(client))
            self.client = pp
            return 1
        else:
            log.error('Failed to get subsystem')
            return 0

    def request_shell(self, data):
        log.info('Getting shell')
        if not self.session:
            self.session = ISession(self.avatar)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.openShell(pp)
        except Exception:
            log.failure('Error getting shell')
            return 0
        else:
            self.client = pp
            return 1

    def request_exec(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        f, data = common.getNS(data)
        log.info('Executing command "{f}"', f=f)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.execCommand(pp, f)
        except Exception:
            log.failure('Error executing command "{f}"', f=f)
            return 0
        else:
            self.client = pp
            return 1

    def request_pty_req(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        term, windowSize, modes = parseRequest_pty_req(data)
        log.info('Handling pty request: {term!r} {windowSize!r}',
                 term=term,
                 windowSize=windowSize)
        try:
            self.session.getPty(term, windowSize, modes)
        except Exception:
            log.failure('Error handling pty request')
            return 0
        else:
            return 1

    def request_env(self, data):
        """
        Process a request to pass an environment variable.

        @param data: The environment variable name and value, each encoded
            as an SSH protocol string and concatenated.
        @type data: L{bytes}
        @return: A true value if the request to pass this environment
            variable was accepted, otherwise a false value.
        """
        if not self._sessionSetEnv:
            self._sessionSetEnv = ISessionSetEnv(self.avatar, None)
            if self._sessionSetEnv is None:
                log.info(
                    "Can't handle setting environment variables for "
                    "SSH avatar {avatar}",
                    avatar=self.avatar)
                return 0
        name, value, data = common.getNS(data, 2)
        try:
            self._sessionSetEnv.setEnv(name, value)
        except EnvironmentVariableNotPermitted:
            return 0
        except Exception:
            log.failure('Error setting environment variable {name}', name=name)
            return 0
        else:
            return 1

    def request_window_change(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        winSize = parseRequest_window_change(data)
        try:
            self.session.windowChanged(winSize)
        except Exception:
            log.failure('Error changing window size')
            return 0
        else:
            return 1

    def dataReceived(self, data):
        if not self.client:
            #self.conn.sendClose(self)
            self.buf += data
            return
        self.client.transport.write(data)

    def extReceived(self, dataType, data):
        if dataType == connection.EXTENDED_DATA_STDERR:
            if self.client and hasattr(self.client.transport, 'writeErr'):
                self.client.transport.writeErr(data)
        else:
            log.warn('Weird extended data: {dataType}', dataType=dataType)

    def eofReceived(self):
        if self.session:
            self.session.eofReceived()
        elif self.client:
            self.conn.sendClose(self)

    def closed(self):
        if self.session:
            self.session.closed()
        elif self.client:
            self.client.transport.loseConnection()

    #def closeReceived(self):
    #    self.loseConnection() # don't know what to do with this

    def loseConnection(self):
        if self.client:
            self.client.transport.loseConnection()
        channel.SSHChannel.loseConnection(self)
Esempio n. 25
0
class SSHSession(channel.SSHChannel):
    """
    A generalized implementation of an SSH session.

    See RFC 4254, section 6.

    The precise implementation of the various operations that the remote end
    can send is left up to the avatar, usually via an adapter to an
    interface such as L{ISession}.

    @ivar buf: a buffer for data received before making a connection to a
        client.
    @type buf: L{bytes}
    @ivar client: a protocol for communication with a shell, an application
        program, or a subsystem (see RFC 4254, section 6.5).
    @type client: L{SSHSessionProcessProtocol}
    @ivar session: an object providing concrete implementations of session
        operations.
    @type session: L{ISession}
    """

    name = b"session"

    def __init__(self, *args, **kw):
        channel.SSHChannel.__init__(self, *args, **kw)
        self.buf = b""
        self.client = None
        self.session = None

    def request_subsystem(self, data):
        subsystem, ignored = common.getNS(data)
        log.info('Asking for subsystem "{subsystem}"', subsystem=subsystem)
        client = self.avatar.lookupSubsystem(subsystem, data)
        if client:
            pp = SSHSessionProcessProtocol(self)
            proto = wrapProcessProtocol(pp)
            client.makeConnection(proto)
            pp.makeConnection(wrapProtocol(client))
            self.client = pp
            return 1
        else:
            log.error("Failed to get subsystem")
            return 0

    def request_shell(self, data):
        log.info("Getting shell")
        if not self.session:
            self.session = ISession(self.avatar)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.openShell(pp)
        except Exception:
            log.failure("Error getting shell")
            return 0
        else:
            self.client = pp
            return 1

    def request_exec(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        f, data = common.getNS(data)
        log.info('Executing command "{f}"', f=f)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.execCommand(pp, f)
        except Exception:
            log.failure('Error executing command "{f}"', f=f)
            return 0
        else:
            self.client = pp
            return 1

    def request_pty_req(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        term, windowSize, modes = parseRequest_pty_req(data)
        log.info(
            "Handling pty request: {term!r} {windowSize!r}",
            term=term,
            windowSize=windowSize,
        )
        try:
            self.session.getPty(term, windowSize, modes)
        except Exception:
            log.failure("Error handling pty request")
            return 0
        else:
            return 1

    def request_env(self, data):
        """
        Process a request to pass an environment variable.

        @param data: The environment variable name and value, each encoded
            as an SSH protocol string and concatenated.
        @type data: L{bytes}
        @return: A true value if the request to pass this environment
            variable was accepted, otherwise a false value.
        """
        if not self.session:
            self.session = ISession(self.avatar)
        if not ISessionSetEnv.providedBy(self.session):
            log.warn(
                "Can't handle environment variables for SSH avatar {avatar}: "
                "{session} does not provide ISessionSetEnv interface. "
                "It should be decorated with @implementer(ISession, "
                "ISessionSetEnv) to support env variables.",
                avatar=self.avatar,
                session=self.session,
            )
            return 0
        name, value, data = common.getNS(data, 2)
        try:
            self.session.setEnv(name, value)
        except EnvironmentVariableNotPermitted:
            return 0
        except Exception:
            log.failure("Error setting environment variable {name}", name=name)
            return 0
        else:
            return 1

    def request_window_change(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        winSize = parseRequest_window_change(data)
        try:
            self.session.windowChanged(winSize)
        except Exception:
            log.failure("Error changing window size")
            return 0
        else:
            return 1

    def dataReceived(self, data):
        if not self.client:
            # self.conn.sendClose(self)
            self.buf += data
            return
        self.client.transport.write(data)

    def extReceived(self, dataType, data):
        if dataType == connection.EXTENDED_DATA_STDERR:
            if self.client and hasattr(self.client.transport, "writeErr"):
                self.client.transport.writeErr(data)
        else:
            log.warn("Weird extended data: {dataType}", dataType=dataType)

    def eofReceived(self):
        # If we have a session, tell it that EOF has been received and
        # expect it to send a close message (it may need to send other
        # messages such as exit-status or exit-signal first).  If we don't
        # have a session, then just send a close message directly.
        if self.session:
            self.session.eofReceived()
        elif self.client:
            self.conn.sendClose(self)

    def closed(self):
        if self.client and self.client.transport:
            self.client.transport.loseConnection()
        if self.session:
            self.session.closed()

    # def closeReceived(self):
    #    self.loseConnection() # don't know what to do with this

    def loseConnection(self):
        if self.client:
            self.client.transport.loseConnection()
        channel.SSHChannel.loseConnection(self)
Esempio n. 26
0
 def test_providesISession(self):
     # ExecOnlySession must provide ISession.
     self.assertTrue(ISession.providedBy(self.session),
                     "ExecOnlySession doesn't implement ISession")
Esempio n. 27
0
 def test_providesISession(self):
     # DoNothingSession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "DoNothingSession doesn't implement ISession")
Esempio n. 28
0
 def test_providesISession(self):
     # ExecOnlySession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "ExecOnlySession doesn't implement ISession")
Esempio n. 29
0
class SSHSession(channel.SSHChannel):

    name = 'session'
    def __init__(self, *args, **kw):
        channel.SSHChannel.__init__(self, *args, **kw)
        self.buf = ''
        self.client = None
        self.session = None

    def request_subsystem(self, data):
        subsystem, ignored= common.getNS(data)
        log.msg('asking for subsystem "%s"' % subsystem)
        client = self.avatar.lookupSubsystem(subsystem, data)
        if client:
            pp = SSHSessionProcessProtocol(self)
            proto = wrapProcessProtocol(pp)
            client.makeConnection(proto)
            pp.makeConnection(wrapProtocol(client))
            self.client = pp
            return 1
        else:
            log.msg('failed to get subsystem')
            return 0

    def request_shell(self, data):
        log.msg('getting shell')
        if not self.session:
            self.session = ISession(self.avatar)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.openShell(pp)
        except:
            log.deferr()
            return 0
        else:
            self.client = pp
            return 1

    def request_exec(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        f,data = common.getNS(data)
        log.msg('executing command "%s"' % f)
        try:
            pp = SSHSessionProcessProtocol(self)
            self.session.execCommand(pp, f)
        except:
            log.deferr()
            return 0
        else:
            self.client = pp
            return 1

    def request_pty_req(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        term, windowSize, modes = parseRequest_pty_req(data)
        log.msg('pty request: %s %s' % (term, windowSize))
        try:
            self.session.getPty(term, windowSize, modes) 
        except:
            log.err()
            return 0
        else:
            return 1

    def request_window_change(self, data):
        if not self.session:
            self.session = ISession(self.avatar)
        import fcntl, tty
        winSize = parseRequest_window_change(data)
        try:
            self.session.windowChanged(winSize)
        except:
            log.msg('error changing window size')
            log.err()
            return 0
        else:
            return 1

    def dataReceived(self, data):
        if not self.client:
            #self.conn.sendClose(self)
            self.buf += data
            return
        self.client.transport.write(data)

    def extReceived(self, dataType, data):
        if dataType == connection.EXTENDED_DATA_STDERR:
            if self.client and hasattr(self.client.transport, 'writeErr'):
                self.client.transport.writeErr(data)
        else:
            log.msg('weird extended data: %s'%dataType)

    def eofReceived(self):
        if self.session:
            self.session.eofReceived()
        elif self.client:
            self.conn.sendClose(self)

    def closed(self):
        if self.session:
            self.session.closed()

    #def closeReceived(self):
    #    self.loseConnection() # don't know what to do with this

    def loseConnection(self):
        if self.client:
            self.client.transport.loseConnection()
        channel.SSHChannel.loseConnection(self)
Esempio n. 30
0
 def test_providesISession(self):
     # DoNothingSession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "DoNothingSession doesn't implement ISession")