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