Пример #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
Пример #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 /')
Пример #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 /')
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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)
Пример #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. ")
Пример #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))
Пример #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))
Пример #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))
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #26
0
 def test_providesISession(self):
     # ExecOnlySession must provide ISession.
     self.assertTrue(ISession.providedBy(self.session),
                     "ExecOnlySession doesn't implement ISession")
Пример #27
0
 def test_providesISession(self):
     # DoNothingSession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "DoNothingSession doesn't implement ISession")
Пример #28
0
 def test_providesISession(self):
     # ExecOnlySession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "ExecOnlySession doesn't implement ISession")
Пример #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)
Пример #30
0
 def test_providesISession(self):
     # DoNothingSession must provide ISession.
     self.failUnless(ISession.providedBy(self.session),
                     "DoNothingSession doesn't implement ISession")