paramiko.server

Package paramiko :: Module server |
[frames] | no frames]

# Source Code for Module paramiko.server

      1  # Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com>
      2  #
      3  # This file is part of paramiko.
      4  #
      5  # Paramiko is free software; you can redistribute it and/or modify it under the
      6  # terms of the GNU Lesser General Public License as published by the Free
      7  # Software Foundation; either version 2.1 of the License, or (at your option)
      8  # any later version.
      9  #
     10  # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
     11  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
     13  # details.
     14  #
     15  # You should have received a copy of the GNU Lesser General Public License
     16  # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
     17  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
     18
     19  """
     20  L{ServerInterface} is an interface to override for server support.
     21  """
     22
     23  import threading
     24  from paramiko.common import *
     25  from paramiko import util
     26
     27
     28 -class InteractiveQuery (object):
     29      """
     30      A query (set of prompts) for a user during interactive authentication.
     31      """
     32
     33 -    def __init__(self, name='', instructions='', *prompts):
     34          """
     35          Create a new interactive query to send to the client.  The name and
     36          instructions are optional, but are generally displayed to the end
     37          user.  A list of prompts may be included, or they may be added via
     38          the L{add_prompt} method.
     39
     40          @param name: name of this query
     41          @type name: str
     42          @param instructions: user instructions (usually short) about this query
     43          @type instructions: str
     44          @param prompts: one or more authentication prompts
     45          @type prompts: str
     46          """
     47          self.name = name
     48          self.instructions = instructions
     49          self.prompts = []
     50          for x in prompts:
     51              if (type(x) is str) or (type(x) is unicode):
     52                  self.add_prompt(x)
     53              else:
     54                  self.add_prompt(x[0], x[1])
     55
     56 -    def add_prompt(self, prompt, echo=True):
     57          """
     58          Add a prompt to this query.  The prompt should be a (reasonably short)
     59          string.  Multiple prompts can be added to the same query.
     60
     61          @param prompt: the user prompt
     62          @type prompt: str
     63          @param echo: C{True} (default) if the user's response should be echoed;
     64              C{False} if not (for a password or similar)
     65          @type echo: bool
     66          """
     67          self.prompts.append((prompt, echo))
     68
     69
     70 -class ServerInterface (object):
     71      """
     72      This class defines an interface for controlling the behavior of paramiko
     73      in server mode.
     74
     75      Methods on this class are called from paramiko's primary thread, so you
     76      shouldn't do too much work in them.  (Certainly nothing that blocks or
     77      sleeps.)
     78      """
     79
     80 -    def check_channel_request(self, kind, chanid):
     81          """
     82          Determine if a channel request of a given type will be granted, and
     83          return C{OPEN_SUCCEEDED} or an error code.  This method is
     84          called in server mode when the client requests a channel, after
     85          authentication is complete.
     86
     87          If you allow channel requests (and an ssh server that didn't would be
     88          useless), you should also override some of the channel request methods
     89          below, which are used to determine which services will be allowed on
     90          a given channel:
     91              - L{check_channel_pty_request}
     92              - L{check_channel_shell_request}
     93              - L{check_channel_subsystem_request}
     94              - L{check_channel_window_change_request}
     95              - L{check_channel_x11_request}
     96
     97          The C{chanid} parameter is a small number that uniquely identifies the
     98          channel within a L{Transport}.  A L{Channel} object is not created
     99          unless this method returns C{OPEN_SUCCEEDED} -- once a
    100          L{Channel} object is created, you can call L{Channel.get_id} to
    101          retrieve the channel ID.
    102
    103          The return value should either be C{OPEN_SUCCEEDED} (or
    104          C{0}) to allow the channel request, or one of the following error
    105          codes to reject it:
    106              - C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}
    107              - C{OPEN_FAILED_CONNECT_FAILED}
    108              - C{OPEN_FAILED_UNKNOWN_CHANNEL_TYPE}
    109              - C{OPEN_FAILED_RESOURCE_SHORTAGE}
    110
    111          The default implementation always returns
    112          C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}.
    113
    114          @param kind: the kind of channel the client would like to open
    115              (usually C{"session"}).
    116          @type kind: str
    117          @param chanid: ID of the channel
    118          @type chanid: int
    119          @return: a success or failure code (listed above)
    120          @rtype: int
    121          """
    122          return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
    123
    124 -    def get_allowed_auths(self, username):
    125          """
    126          Return a list of authentication methods supported by the server.
    127          This list is sent to clients attempting to authenticate, to inform them
    128          of authentication methods that might be successful.
    129
    130          The "list" is actually a string of comma-separated names of types of
    131          authentication.  Possible values are C{"password"}, C{"publickey"},
    132          and C{"none"}.
    133
    134          The default implementation always returns C{"password"}.
    135
    136          @param username: the username requesting authentication.
    137          @type username: str
    138          @return: a comma-separated list of authentication types
    139          @rtype: str
    140          """
    141          return 'password'
    142
    143 -    def check_auth_none(self, username):
    144          """
    145          Determine if a client may open channels with no (further)
    146          authentication.
    147
    148          Return L{AUTH_FAILED} if the client must authenticate, or
    149          L{AUTH_SUCCESSFUL} if it's okay for the client to not
    150          authenticate.
    151
    152          The default implementation always returns L{AUTH_FAILED}.
    153
    154          @param username: the username of the client.
    155          @type username: str
    156          @return: L{AUTH_FAILED} if the authentication fails;
    157              L{AUTH_SUCCESSFUL} if it succeeds.
    158          @rtype: int
    159          """
    160          return AUTH_FAILED
    161
    162 -    def check_auth_password(self, username, password):
    163          """
    164          Determine if a given username and password supplied by the client is
    165          acceptable for use in authentication.
    166
    167          Return L{AUTH_FAILED} if the password is not accepted,
    168          L{AUTH_SUCCESSFUL} if the password is accepted and completes
    169          the authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
    170          authentication is stateful, and this key is accepted for
    171          authentication, but more authentication is required.  (In this latter
    172          case, L{get_allowed_auths} will be called to report to the client what
    173          options it has for continuing the authentication.)
    174
    175          The default implementation always returns L{AUTH_FAILED}.
    176
    177          @param username: the username of the authenticating client.
    178          @type username: str
    179          @param password: the password given by the client.
    180          @type password: str
    181          @return: L{AUTH_FAILED} if the authentication fails;
    182              L{AUTH_SUCCESSFUL} if it succeeds;
    183              L{AUTH_PARTIALLY_SUCCESSFUL} if the password auth is
    184              successful, but authentication must continue.
    185          @rtype: int
    186          """
    187          return AUTH_FAILED
    188
    189 -    def check_auth_publickey(self, username, key):
    190          """
    191          Determine if a given key supplied by the client is acceptable for use
    192          in authentication.  You should override this method in server mode to
    193          check the username and key and decide if you would accept a signature
    194          made using this key.
    195
    196          Return L{AUTH_FAILED} if the key is not accepted,
    197          L{AUTH_SUCCESSFUL} if the key is accepted and completes the
    198          authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
    199          authentication is stateful, and this password is accepted for
    200          authentication, but more authentication is required.  (In this latter
    201          case, L{get_allowed_auths} will be called to report to the client what
    202          options it has for continuing the authentication.)
    203
    204          Note that you don't have to actually verify any key signtature here.
    205          If you're willing to accept the key, paramiko will do the work of
    206          verifying the client's signature.
    207
    208          The default implementation always returns L{AUTH_FAILED}.
    209
    210          @param username: the username of the authenticating client
    211          @type username: str
    212          @param key: the key object provided by the client
    213          @type key: L{PKey <pkey.PKey>}
    214          @return: L{AUTH_FAILED} if the client can't authenticate
    215              with this key; L{AUTH_SUCCESSFUL} if it can;
    216              L{AUTH_PARTIALLY_SUCCESSFUL} if it can authenticate with
    217              this key but must continue with authentication
    218          @rtype: int
    219          """
    220          return AUTH_FAILED
    221
    222 -    def check_auth_interactive(self, username, submethods):
    223          """
    224          Begin an interactive authentication challenge, if supported.  You
    225          should override this method in server mode if you want to support the
    226          C{"keyboard-interactive"} auth type, which requires you to send a
    227          series of questions for the client to answer.
    228
    229          Return L{AUTH_FAILED} if this auth method isn't supported.  Otherwise,
    230          you should return an L{InteractiveQuery} object containing the prompts
    231          and instructions for the user.  The response will be sent via a call
    232          to L{check_auth_interactive_response}.
    233
    234          The default implementation always returns L{AUTH_FAILED}.
    235
    236          @param username: the username of the authenticating client
    237          @type username: str
    238          @param submethods: a comma-separated list of methods preferred by the
    239              client (usually empty)
    240          @type submethods: str
    241          @return: L{AUTH_FAILED} if this auth method isn't supported; otherwise
    242              an object containing queries for the user
    243          @rtype: int or L{InteractiveQuery}
    244          """
    245          return AUTH_FAILED
    246
    247 -    def check_auth_interactive_response(self, responses):
    248          """
    249          Continue or finish an interactive authentication challenge, if
    250          supported.  You should override this method in server mode if you want
    251          to support the C{"keyboard-interactive"} auth type.
    252
    253          Return L{AUTH_FAILED} if the responses are not accepted,
    254          L{AUTH_SUCCESSFUL} if the responses are accepted and complete
    255          the authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
    256          authentication is stateful, and this set of responses is accepted for
    257          authentication, but more authentication is required.  (In this latter
    258          case, L{get_allowed_auths} will be called to report to the client what
    259          options it has for continuing the authentication.)
    260
    261          If you wish to continue interactive authentication with more questions,
    262          you may return an L{InteractiveQuery} object, which should cause the
    263          client to respond with more answers, calling this method again.  This
    264          cycle can continue indefinitely.
    265
    266          The default implementation always returns L{AUTH_FAILED}.
    267
    268          @param responses: list of responses from the client
    269          @type responses: list(str)
    270          @return: L{AUTH_FAILED} if the authentication fails;
    271              L{AUTH_SUCCESSFUL} if it succeeds;
    272              L{AUTH_PARTIALLY_SUCCESSFUL} if the interactive auth is
    273              successful, but authentication must continue; otherwise an object
    274              containing queries for the user
    275          @rtype: int or L{InteractiveQuery}
    276          """
    277          return AUTH_FAILED
    278
    279 -    def check_port_forward_request(self, address, port):
    280          """
    281          Handle a request for port forwarding.  The client is asking that
    282          connections to the given address and port be forwarded back across
    283          this ssh connection.  An address of C{"0.0.0.0"} indicates a global
    284          address (any address associated with this server) and a port of C{0}
    285          indicates that no specific port is requested (usually the OS will pick
    286          a port).
    287
    288          The default implementation always returns C{False}, rejecting the
    289          port forwarding request.  If the request is accepted, you should return
    290          the port opened for listening.
    291
    292          @param address: the requested address
    293          @type address: str
    294          @param port: the requested port
    295          @type port: int
    296          @return: the port number that was opened for listening, or C{False} to
    297              reject
    298          @rtype: int
    299          """
    300          return False
    301
    302 -    def cancel_port_forward_request(self, address, port):
    303          """
    304          The client would like to cancel a previous port-forwarding request.
    305          If the given address and port is being forwarded across this ssh
    306          connection, the port should be closed.
    307
    308          @param address: the forwarded address
    309          @type address: str
    310          @param port: the forwarded port
    311          @type port: int
    312          """
    313          pass
    314
    315 -    def check_global_request(self, kind, msg):
    316          """
    317          Handle a global request of the given C{kind}.  This method is called
    318          in server mode and client mode, whenever the remote host makes a global
    319          request.  If there are any arguments to the request, they will be in
    320          C{msg}.
    321
    322          There aren't any useful global requests defined, aside from port
    323          forwarding, so usually this type of request is an extension to the
    324          protocol.
    325
    326          If the request was successful and you would like to return contextual
    327          data to the remote host, return a tuple.  Items in the tuple will be
    328          sent back with the successful result.  (Note that the items in the
    329          tuple can only be strings, ints, longs, or bools.)
    330
    331          The default implementation always returns C{False}, indicating that it
    332          does not support any global requests.
    333
    334          @note: Port forwarding requests are handled separately, in
    335              L{check_port_forward_request}.
    336
    337          @param kind: the kind of global request being made.
    338          @type kind: str
    339          @param msg: any extra arguments to the request.
    340          @type msg: L{Message}
    341          @return: C{True} or a tuple of data if the request was granted;
    342              C{False} otherwise.
    343          @rtype: bool
    344          """
    345          return False
    346
    347
    348      ###  Channel requests
    349
    350
    351 -    def check_channel_pty_request(self, channel, term, width, height, pixelwidth, pixelheight,
    352                                    modes):
    353          """
    354          Determine if a pseudo-terminal of the given dimensions (usually
    355          requested for shell access) can be provided on the given channel.
    356
    357          The default implementation always returns C{False}.
    358
    359          @param channel: the L{Channel} the pty request arrived on.
    360          @type channel: L{Channel}
    361          @param term: type of terminal requested (for example, C{"vt100"}).
    362          @type term: str
    363          @param width: width of screen in characters.
    364          @type width: int
    365          @param height: height of screen in characters.
    366          @type height: int
    367          @param pixelwidth: width of screen in pixels, if known (may be C{0} if
    368              unknown).
    369          @type pixelwidth: int
    370          @param pixelheight: height of screen in pixels, if known (may be C{0}
    371              if unknown).
    372          @type pixelheight: int
    373          @return: C{True} if the psuedo-terminal has been allocated; C{False}
    374              otherwise.
    375          @rtype: bool
    376          """
    377          return False
    378
    379 -    def check_channel_shell_request(self, channel):
    380          """
    381          Determine if a shell will be provided to the client on the given
    382          channel.  If this method returns C{True}, the channel should be
    383          connected to the stdin/stdout of a shell (or something that acts like
    384          a shell).
    385
    386          The default implementation always returns C{False}.
    387
    388          @param channel: the L{Channel} the request arrived on.
    389          @type channel: L{Channel}
    390          @return: C{True} if this channel is now hooked up to a shell; C{False}
    391              if a shell can't or won't be provided.
    392          @rtype: bool
    393          """
    394          return False
    395
    396 -    def check_channel_exec_request(self, channel, command):
    397          """
    398          Determine if a shell command will be executed for the client.  If this
    399          method returns C{True}, the channel should be connected to the stdin,
    400          stdout, and stderr of the shell command.
    401
    402          The default implementation always returns C{False}.
    403
    404          @param channel: the L{Channel} the request arrived on.
    405          @type channel: L{Channel}
    406          @param command: the command to execute.
    407          @type command: str
    408          @return: C{True} if this channel is now hooked up to the stdin,
    409              stdout, and stderr of the executing command; C{False} if the
    410              command will not be executed.
    411          @rtype: bool
    412
    413          @since: 1.1
    414          """
    415          return False
    416
    417 -    def check_channel_subsystem_request(self, channel, name):
    418          """
    419          Determine if a requested subsystem will be provided to the client on
    420          the given channel.  If this method returns C{True}, all future I/O
    421          through this channel will be assumed to be connected to the requested
    422          subsystem.  An example of a subsystem is C{sftp}.
    423
    424          The default implementation checks for a subsystem handler assigned via
    425          L{Transport.set_subsystem_handler}.
    426          If one has been set, the handler is invoked and this method returns
    427          C{True}.  Otherwise it returns C{False}.
    428
    429          @note: Because the default implementation uses the L{Transport} to
    430              identify valid subsystems, you probably won't need to override this
    431              method.
    432
    433          @param channel: the L{Channel} the pty request arrived on.
    434          @type channel: L{Channel}
    435          @param name: name of the requested subsystem.
    436          @type name: str
    437          @return: C{True} if this channel is now hooked up to the requested
    438              subsystem; C{False} if that subsystem can't or won't be provided.
    439          @rtype: bool
    440          """
    441          handler_class, larg, kwarg = channel.get_transport()._get_subsystem_handler(name)
    442          if handler_class is None:
    443              return False
    444          handler = handler_class(channel, name, self, *larg, **kwarg)
    445          handler.start()
    446          return True
    447
    448 -    def check_channel_window_change_request(self, channel, width, height, pixelwidth, pixelheight):
    449          """
    450          Determine if the pseudo-terminal on the given channel can be resized.
    451          This only makes sense if a pty was previously allocated on it.
    452
    453          The default implementation always returns C{False}.
    454
    455          @param channel: the L{Channel} the pty request arrived on.
    456          @type channel: L{Channel}
    457          @param width: width of screen in characters.
    458          @type width: int
    459          @param height: height of screen in characters.
    460          @type height: int
    461          @param pixelwidth: width of screen in pixels, if known (may be C{0} if
    462              unknown).
    463          @type pixelwidth: int
    464          @param pixelheight: height of screen in pixels, if known (may be C{0}
    465              if unknown).
    466          @type pixelheight: int
    467          @return: C{True} if the terminal was resized; C{False} if not.
    468          @rtype: bool
    469          """
    470          return False
    471
    472 -    def check_channel_x11_request(self, channel, single_connection, auth_protocol, auth_cookie, screen_number):
    473          """
    474          Determine if the client will be provided with an X11 session.  If this
    475          method returns C{True}, X11 applications should be routed through new
    476          SSH channels, using L{Transport.open_x11_channel}.
    477
    478          The default implementation always returns C{False}.
    479
    480          @param channel: the L{Channel} the X11 request arrived on
    481          @type channel: L{Channel}
    482          @param single_connection: C{True} if only a single X11 channel should
    483              be opened
    484          @type single_connection: bool
    485          @param auth_protocol: the protocol used for X11 authentication
    486          @type auth_protocol: str
    487          @param auth_cookie: the cookie used to authenticate to X11
    488          @type auth_cookie: str
    489          @param screen_number: the number of the X11 screen to connect to
    490          @type screen_number: int
    491          @return: C{True} if the X11 session was opened; C{False} if not
    492          @rtype: bool
    493          """
    494          return False
    495
    496 -    def check_channel_direct_tcpip_request(self, chanid, origin, destination):
    497          """
    498          Determine if a local port forwarding channel will be granted, and
    499          return C{OPEN_SUCCEEDED} or an error code.  This method is
    500          called in server mode when the client requests a channel, after
    501          authentication is complete.
    502
    503          The C{chanid} parameter is a small number that uniquely identifies the
    504          channel within a L{Transport}.  A L{Channel} object is not created
    505          unless this method returns C{OPEN_SUCCEEDED} -- once a
    506          L{Channel} object is created, you can call L{Channel.get_id} to
    507          retrieve the channel ID.
    508
    509          The origin and destination parameters are (ip_address, port) tuples
    510          that correspond to both ends of the TCP connection in the forwarding
    511          tunnel.
    512
    513          The return value should either be C{OPEN_SUCCEEDED} (or
    514          C{0}) to allow the channel request, or one of the following error
    515          codes to reject it:
    516              - C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}
    517              - C{OPEN_FAILED_CONNECT_FAILED}
    518              - C{OPEN_FAILED_UNKNOWN_CHANNEL_TYPE}
    519              - C{OPEN_FAILED_RESOURCE_SHORTAGE}
    520
    521          The default implementation always returns
    522          C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}.
    523
    524          @param chanid: ID of the channel
    525          @type chanid: int
    526          @param origin: 2-tuple containing the IP address and port of the
    527              originator (client side)
    528          @type origin: tuple
    529          @param destination: 2-tuple containing the IP address and port of the
    530              destination (server side)
    531          @type destination: tuple
    532          @return: a success or failure code (listed above)
    533          @rtype: int
    534          """
    535          return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
    536
    537
    538 -class SubsystemHandler (threading.Thread):
    539      """
    540      Handler for a subsytem in server mode.  If you create a subclass of this
    541      class and pass it to
    542      L{Transport.set_subsystem_handler},
    543      an object of this
    544      class will be created for each request for this subsystem.  Each new object
    545      will be executed within its own new thread by calling L{start_subsystem}.
    546      When that method completes, the channel is closed.
    547
    548      For example, if you made a subclass C{MP3Handler} and registered it as the
    549      handler for subsystem C{"mp3"}, then whenever a client has successfully
    550      authenticated and requests subsytem C{"mp3"}, an object of class
    551      C{MP3Handler} will be created, and L{start_subsystem} will be called on
    552      it from a new thread.
    553      """
    554 -    def __init__(self, channel, name, server):
    555          """
    556          Create a new handler for a channel.  This is used by L{ServerInterface}
    557          to start up a new handler when a channel requests this subsystem.  You
    558          don't need to override this method, but if you do, be sure to pass the
    559          C{channel} and C{name} parameters through to the original C{__init__}
    560          method here.
    561
    562          @param channel: the channel associated with this subsystem request.
    563          @type channel: L{Channel}
    564          @param name: name of the requested subsystem.
    565          @type name: str
    566          @param server: the server object for the session that started this
    567              subsystem
    568          @type server: L{ServerInterface}
    569          """
    570          threading.Thread.__init__(self, target=self._run)
    571          self.__channel = channel
    572          self.__transport = channel.get_transport()
    573          self.__name = name
    574          self.__server = server
    575
    576 -    def get_server(self):
    577          """
    578          Return the L{ServerInterface} object associated with this channel and
    579          subsystem.
    580
    581          @rtype: L{ServerInterface}
    582          """
    583          return self.__server
    584
    585 -    def _run(self):
    586          try:
    587              self.__transport._log(DEBUG, 'Starting handler for subsystem %s' % self.__name)
    588              self.start_subsystem(self.__name, self.__transport, self.__channel)
    589          except Exception, e:
    590              self.__transport._log(ERROR, 'Exception in subsystem handler for "%s": %s' %
    591                                    (self.__name, str(e)))
    592              self.__transport._log(ERROR, util.tb_strings())
    593          try:
    594              self.finish_subsystem()
    595          except:
    596              pass
    597
    598 -    def start_subsystem(self, name, transport, channel):
    599          """
    600          Process an ssh subsystem in server mode.  This method is called on a
    601          new object (and in a new thread) for each subsystem request.  It is
    602          assumed that all subsystem logic will take place here, and when the
    603          subsystem is finished, this method will return.  After this method
    604          returns, the channel is closed.
    605
    606          The combination of C{transport} and C{channel} are unique; this handler
    607          corresponds to exactly one L{Channel} on one L{Transport}.
    608
    609          @note: It is the responsibility of this method to exit if the
    610              underlying L{Transport} is closed.  This can be done by checking
    611              L{Transport.is_active} or noticing an EOF
    612              on the L{Channel}.  If this method loops forever without checking
    613              for this case, your python interpreter may refuse to exit because
    614              this thread will still be running.
    615
    616          @param name: name of the requested subsystem.
    617          @type name: str
    618          @param transport: the server-mode L{Transport}.
    619          @type transport: L{Transport}
    620          @param channel: the channel associated with this subsystem request.
    621          @type channel: L{Channel}
    622          """
    623          pass
    624
    625 -    def finish_subsystem(self):
    626          """
    627          Perform any cleanup at the end of a subsystem.  The default
    628          implementation just closes the channel.
    629
    630          @since: 1.1
    631          """
    632          self.__channel.close()
    633