[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-157]
change SubsystemHandler/SFTPServerInterface API change the API of SubsystemHandler to accept a reference to the ServerInstance object during construction. this will break all code that currently creates subsystem handlers (like sftp servers) -- sorry! lots of little doc fixups (mostly indenting).
This commit is contained in:
parent
5d8d1938fa
commit
71a337ee08
|
@ -72,10 +72,10 @@ class ServerInterface (object):
|
|||
C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}.
|
||||
|
||||
@param kind: the kind of channel the client would like to open
|
||||
(usually C{"session"}).
|
||||
(usually C{"session"}).
|
||||
@type kind: str
|
||||
@param chanid: ID of the channel, required to create a new L{Channel}
|
||||
object.
|
||||
object.
|
||||
@type chanid: int
|
||||
@return: a success or failure code (listed above).
|
||||
@rtype: int
|
||||
|
@ -115,7 +115,7 @@ class ServerInterface (object):
|
|||
@param username: the username of the client.
|
||||
@type username: str
|
||||
@return: L{AUTH_FAILED} if the authentication fails;
|
||||
L{AUTH_SUCCESSFUL} if it succeeds.
|
||||
L{AUTH_SUCCESSFUL} if it succeeds.
|
||||
@rtype: int
|
||||
"""
|
||||
return AUTH_FAILED
|
||||
|
@ -140,9 +140,9 @@ class ServerInterface (object):
|
|||
@param password: the password given by the client.
|
||||
@type password: str
|
||||
@return: L{AUTH_FAILED} if the authentication fails;
|
||||
L{AUTH_SUCCESSFUL} if it succeeds;
|
||||
L{AUTH_PARTIALLY_SUCCESSFUL} if the password auth is
|
||||
successful, but authentication must continue.
|
||||
L{AUTH_SUCCESSFUL} if it succeeds;
|
||||
L{AUTH_PARTIALLY_SUCCESSFUL} if the password auth is
|
||||
successful, but authentication must continue.
|
||||
@rtype: int
|
||||
"""
|
||||
return AUTH_FAILED
|
||||
|
@ -173,9 +173,9 @@ class ServerInterface (object):
|
|||
@param key: the key object provided by the client.
|
||||
@type key: L{PKey <pkey.PKey>}
|
||||
@return: L{AUTH_FAILED} if the client can't authenticate
|
||||
with this key; L{AUTH_SUCCESSFUL} if it can;
|
||||
L{AUTH_PARTIALLY_SUCCESSFUL} if it can authenticate with
|
||||
this key but must continue with authentication.
|
||||
with this key; L{AUTH_SUCCESSFUL} if it can;
|
||||
L{AUTH_PARTIALLY_SUCCESSFUL} if it can authenticate with
|
||||
this key but must continue with authentication.
|
||||
@rtype: int
|
||||
"""
|
||||
return AUTH_FAILED
|
||||
|
@ -230,13 +230,13 @@ class ServerInterface (object):
|
|||
@param height: height of screen in characters.
|
||||
@type height: int
|
||||
@param pixelwidth: width of screen in pixels, if known (may be C{0} if
|
||||
unknown).
|
||||
unknown).
|
||||
@type pixelwidth: int
|
||||
@param pixelheight: height of screen in pixels, if known (may be C{0}
|
||||
if unknown).
|
||||
if unknown).
|
||||
@type pixelheight: int
|
||||
@return: C{True} if the psuedo-terminal has been allocated; C{False}
|
||||
otherwise.
|
||||
otherwise.
|
||||
@rtype: bool
|
||||
"""
|
||||
return False
|
||||
|
@ -253,7 +253,7 @@ class ServerInterface (object):
|
|||
@param channel: the L{Channel} the pty request arrived on.
|
||||
@type channel: L{Channel}
|
||||
@return: C{True} if this channel is now hooked up to a shell; C{False}
|
||||
if a shell can't or won't be provided.
|
||||
if a shell can't or won't be provided.
|
||||
@rtype: bool
|
||||
"""
|
||||
return False
|
||||
|
@ -292,21 +292,21 @@ class ServerInterface (object):
|
|||
C{True}. Otherwise it returns C{False}.
|
||||
|
||||
@note: Because the default implementation uses the L{Transport} to
|
||||
identify valid subsystems, you probably won't need to override this
|
||||
method.
|
||||
identify valid subsystems, you probably won't need to override this
|
||||
method.
|
||||
|
||||
@param channel: the L{Channel} the pty request arrived on.
|
||||
@type channel: L{Channel}
|
||||
@param name: name of the requested subsystem.
|
||||
@type name: str
|
||||
@return: C{True} if this channel is now hooked up to the requested
|
||||
subsystem; C{False} if that subsystem can't or won't be provided.
|
||||
subsystem; C{False} if that subsystem can't or won't be provided.
|
||||
@rtype: bool
|
||||
"""
|
||||
handler_class, larg, kwarg = channel.get_transport()._get_subsystem_handler(name)
|
||||
if handler_class is None:
|
||||
return False
|
||||
handler = handler_class(channel, name, *larg, **kwarg)
|
||||
handler = handler_class(channel, name, self, *larg, **kwarg)
|
||||
handler.start()
|
||||
return True
|
||||
|
||||
|
@ -324,10 +324,10 @@ class ServerInterface (object):
|
|||
@param height: height of screen in characters.
|
||||
@type height: int
|
||||
@param pixelwidth: width of screen in pixels, if known (may be C{0} if
|
||||
unknown).
|
||||
unknown).
|
||||
@type pixelwidth: int
|
||||
@param pixelheight: height of screen in pixels, if known (may be C{0}
|
||||
if unknown).
|
||||
if unknown).
|
||||
@type pixelheight: int
|
||||
@return: C{True} if the terminal was resized; C{False} if not.
|
||||
@rtype: bool
|
||||
|
@ -353,7 +353,7 @@ class SubsystemHandler (threading.Thread):
|
|||
|
||||
@since: ivysaur
|
||||
"""
|
||||
def __init__(self, channel, name):
|
||||
def __init__(self, channel, name, server):
|
||||
"""
|
||||
Create a new handler for a channel. This is used by L{ServerInterface}
|
||||
to start up a new handler when a channel requests this subsystem. You
|
||||
|
@ -365,11 +365,24 @@ class SubsystemHandler (threading.Thread):
|
|||
@type channel: L{Channel}
|
||||
@param name: name of the requested subsystem.
|
||||
@type name: str
|
||||
@param server: the server object for the session that started this
|
||||
subsystem
|
||||
@rtype server: L{ServerInterface}
|
||||
"""
|
||||
threading.Thread.__init__(self, target=self._run)
|
||||
self.__channel = channel
|
||||
self.__transport = channel.get_transport()
|
||||
self.__name = name
|
||||
self.__server = server
|
||||
|
||||
def get_server(self):
|
||||
"""
|
||||
Return the L{ServerInterface} object associated with this channel and
|
||||
subsystem.
|
||||
|
||||
@rtype: L{ServerInterface}
|
||||
"""
|
||||
return self.__server
|
||||
|
||||
def _run(self):
|
||||
try:
|
||||
|
@ -396,12 +409,11 @@ class SubsystemHandler (threading.Thread):
|
|||
corresponds to exactly one L{Channel} on one L{Transport}.
|
||||
|
||||
@note: It is the responsibility of this method to exit if the
|
||||
underlying L{Transport} is closed. This can be done by checking
|
||||
L{Transport.is_active <BaseTransport.is_active>} or noticing an EOF
|
||||
on the L{Channel}.
|
||||
If this method loops forever without checking for this case, your
|
||||
python interpreter may refuse to exit because this thread will still
|
||||
be running.
|
||||
underlying L{Transport} is closed. This can be done by checking
|
||||
L{Transport.is_active <BaseTransport.is_active>} or noticing an EOF
|
||||
on the L{Channel}. If this method loops forever without checking
|
||||
for this case, your python interpreter may refuse to exit because
|
||||
this thread will still be running.
|
||||
|
||||
@param name: name of the requested subsystem.
|
||||
@type name: str
|
||||
|
|
|
@ -37,37 +37,35 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
Use L{Transport.set_subsystem_handler} to activate this class.
|
||||
"""
|
||||
|
||||
def __init__(self, channel, name, server=SFTPServerInterface, server_args=None):
|
||||
def __init__(self, channel, name, server, sftp_si=SFTPServerInterface, *largs, **kwargs):
|
||||
"""
|
||||
The constructor for SFTPServer is meant to be called from within the
|
||||
L{Transport} as a subsystem handler. The C{server} and C{server_args}
|
||||
parameters are passed from the original call to
|
||||
L{Transport} as a subsystem handler. C{server} and any additional
|
||||
parameters or keyword parameters are passed from the original call to
|
||||
L{Transport.set_subsystem_handler}.
|
||||
|
||||
@param channel: channel passed from the L{Transport}.
|
||||
@type channel: L{Channel}
|
||||
@param name: name of the requested subsystem.
|
||||
@type name: str
|
||||
@param server: a subclass of L{SFTPServerInterface} to use for handling
|
||||
individual requests.
|
||||
@type server: class
|
||||
@param server_args: keyword parameters to pass to C{server} when it's
|
||||
constructed.
|
||||
@type server_args: dict
|
||||
"""
|
||||
@param server: the server object associated with this channel and
|
||||
subsystem
|
||||
@type server: L{ServerInterface}
|
||||
@param sftp_si: a subclass of L{SFTPServerInterface} to use for handling
|
||||
individual requests.
|
||||
@type sftp_si: class
|
||||
"""
|
||||
BaseSFTP.__init__(self)
|
||||
SubsystemHandler.__init__(self, channel, name)
|
||||
SubsystemHandler.__init__(self, channel, name, server)
|
||||
transport = channel.get_transport()
|
||||
self.logger = util.get_logger(transport.get_log_channel() + '.' +
|
||||
channel.get_name() + '.sftp')
|
||||
channel.get_name() + '.sftp')
|
||||
self.ultra_debug = transport.ultra_debug
|
||||
self.next_handle = 1
|
||||
# map of handle-string to SFTPHandle for files & folders:
|
||||
self.file_table = { }
|
||||
self.folder_table = { }
|
||||
if server_args is None:
|
||||
server_args = {}
|
||||
self.server = server(**server_args)
|
||||
self.server = sftp_si(server, *largs, **kwargs)
|
||||
|
||||
def start_subsystem(self, name, transport, channel):
|
||||
self.sock = channel
|
||||
|
|
|
@ -37,6 +37,17 @@ class SFTPServerInterface (object):
|
|||
session to abruptly end, so you will usually want to catch exceptions and
|
||||
return an appropriate error code.
|
||||
"""
|
||||
|
||||
def __init__ (self, server, *largs, **kwargs):
|
||||
"""
|
||||
Create a new SFTPServerInterface object. This method does nothing by
|
||||
default and is meant to be overridden by subclasses.
|
||||
|
||||
@param server: the server object associated with this channel and
|
||||
SFTP subsystem
|
||||
@type server: L{ServerInterface}
|
||||
"""
|
||||
super(SFTPServerInterface, self).__init__(*largs, **kwargs)
|
||||
|
||||
def session_started(self):
|
||||
"""
|
||||
|
@ -80,13 +91,13 @@ class SFTPServerInterface (object):
|
|||
the client didn't specify them.
|
||||
|
||||
@note: The SFTP protocol defines all files to be in "binary" mode.
|
||||
There is no equivalent to python's "text" mode.
|
||||
There is no equivalent to python's "text" mode.
|
||||
|
||||
@param path: the requested path (relative or absolute) of the file
|
||||
to be opened.
|
||||
to be opened.
|
||||
@type path: str
|
||||
@param flags: flags or'd together from the C{os} module indicating the
|
||||
requested mode for opening the file.
|
||||
requested mode for opening the file.
|
||||
@type flags: int
|
||||
@param attr: requested attributes of the file if it is newly created.
|
||||
@type attr: L{SFTPAttributes}
|
||||
|
@ -114,7 +125,7 @@ class SFTPServerInterface (object):
|
|||
@param path: the requested path (relative or absolute) to be listed.
|
||||
@type path: str
|
||||
@return: a list of the files in the given folder, using
|
||||
L{SFTPAttributes} objects.
|
||||
L{SFTPAttributes} objects.
|
||||
@rtype: list of L{SFTPAttributes} I{or error code}
|
||||
|
||||
@note: You should normalize the given C{path} first (see the
|
||||
|
@ -133,10 +144,10 @@ class SFTPServerInterface (object):
|
|||
call that doesn't follow symlinks/aliases.)
|
||||
|
||||
@param path: the requested path (relative or absolute) to fetch
|
||||
file statistics for.
|
||||
file statistics for.
|
||||
@type path: str
|
||||
@return: an attributes object for the given file, or an SFTP error
|
||||
code (like L{SFTP_PERMISSION_DENIED}).
|
||||
code (like L{SFTP_PERMISSION_DENIED}).
|
||||
@rtype: L{SFTPAttributes} I{or error code}
|
||||
"""
|
||||
return SFTP_OP_UNSUPPORTED
|
||||
|
@ -150,10 +161,10 @@ class SFTPServerInterface (object):
|
|||
corresponding call that follows symlinks/aliases.)
|
||||
|
||||
@param path: the requested path (relative or absolute) to fetch
|
||||
file statistics for.
|
||||
file statistics for.
|
||||
@type path: str
|
||||
@return: an attributes object for the given file, or an SFTP error
|
||||
code (like L{SFTP_PERMISSION_DENIED}).
|
||||
code (like L{SFTP_PERMISSION_DENIED}).
|
||||
@rtype: L{SFTPAttributes} I{or error code}
|
||||
"""
|
||||
return SFTP_OP_UNSUPPORTED
|
||||
|
@ -163,7 +174,7 @@ class SFTPServerInterface (object):
|
|||
Delete a file, if possible.
|
||||
|
||||
@param path: the requested path (relative or absolute) of the file
|
||||
to delete.
|
||||
to delete.
|
||||
@type path: str
|
||||
@return: an SFTP error code like L{SFTP_OK}.
|
||||
@rtype: int
|
||||
|
@ -179,11 +190,11 @@ class SFTPServerInterface (object):
|
|||
files that cross disk partition boundaries, if at all possible.
|
||||
|
||||
@note: You should return an error if a file with the same name as
|
||||
C{newpath} already exists. (The rename operation should be
|
||||
non-desctructive.)
|
||||
C{newpath} already exists. (The rename operation should be
|
||||
non-desctructive.)
|
||||
|
||||
@param oldpath: the requested path (relative or absolute) of the
|
||||
existing file.
|
||||
existing file.
|
||||
@type oldpath: str
|
||||
@param newpath: the requested new path of the file.
|
||||
@type newpath: str
|
||||
|
@ -203,7 +214,7 @@ class SFTPServerInterface (object):
|
|||
object may be completely empty.
|
||||
|
||||
@param path: requested path (relative or absolute) of the new
|
||||
folder.
|
||||
folder.
|
||||
@type path: str
|
||||
@param attr: requested attributes of the new folder.
|
||||
@type attr: L{SFTPAttributes}
|
||||
|
@ -219,7 +230,7 @@ class SFTPServerInterface (object):
|
|||
error.
|
||||
|
||||
@param path: requested path (relative or absolute) of the folder
|
||||
to remove.
|
||||
to remove.
|
||||
@type path: str
|
||||
@return: an SFTP error code like L{SFTP_OK}.
|
||||
@rtype: int
|
||||
|
@ -233,7 +244,7 @@ class SFTPServerInterface (object):
|
|||
should check for the presence of fields before using them.
|
||||
|
||||
@param path: requested path (relative or absolute) of the file to
|
||||
change.
|
||||
change.
|
||||
@type path: str
|
||||
@param attr: requested attributes to change on the file.
|
||||
@type attr: L{SFTPAttributes}
|
||||
|
|
|
@ -762,7 +762,7 @@ class BaseTransport (threading.Thread):
|
|||
|
||||
def set_subsystem_handler(self, name, handler, *larg, **kwarg):
|
||||
"""
|
||||
Set the handler class for a subsystem in server mode. If a reqeuest
|
||||
Set the handler class for a subsystem in server mode. If a request
|
||||
for this subsystem is made on an open ssh channel later, this handler
|
||||
will be constructed and called -- see L{SubsystemHandler} for more
|
||||
detailed documentation.
|
||||
|
@ -773,7 +773,7 @@ class BaseTransport (threading.Thread):
|
|||
@param name: name of the subsystem.
|
||||
@type name: str
|
||||
@param handler: subclass of L{SubsystemHandler} that handles this
|
||||
subsystem.
|
||||
subsystem.
|
||||
@type handler: class
|
||||
"""
|
||||
try:
|
||||
|
|
|
@ -56,7 +56,7 @@ class StubSFTPServer (SFTPServerInterface):
|
|||
# assume current folder is a fine root
|
||||
# (the tests always create and eventualy delete a subfolder, so there shouldn't be any mess)
|
||||
ROOT = os.getcwd()
|
||||
|
||||
|
||||
def _realpath(self, path):
|
||||
return self.ROOT + self.canonicalize(path)
|
||||
|
||||
|
|
Loading…
Reference in New Issue