/paramiko/transport.py
Python | 1243 lines | 1196 code | 14 blank | 33 comment | 19 complexity | c46ffbd7e677ac07630651095602327c MD5 | raw file
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"""
20L{Transport} handles the core SSH2 protocol.
21"""
22
23import os
24import socket
25import string
26import struct
27import sys
28import threading
29import time
30import weakref
31
32from paramiko import util
33from paramiko.auth_handler import AuthHandler
34from paramiko.channel import Channel
35from paramiko.common import *
36from paramiko.compress import ZlibCompressor, ZlibDecompressor
37from paramiko.dsskey import DSSKey
38from paramiko.kex_gex import KexGex
39from paramiko.kex_group1 import KexGroup1
40from paramiko.message import Message
41from paramiko.packet import Packetizer, NeedRekeyException
42from paramiko.primes import ModulusPack
43from paramiko.rsakey import RSAKey
44from paramiko.server import ServerInterface
45from paramiko.sftp_client import SFTPClient
46from paramiko.ssh_exception import SSHException, BadAuthenticationType, ChannelException
47
48from Crypto import Random
49from Crypto.Cipher import Blowfish, AES, DES3, ARC4
50from Crypto.Hash import SHA, MD5
51try:
52 from Crypto.Util import Counter
53except ImportError:
54 from paramiko.util import Counter
55
56
57# for thread cleanup
58_active_threads = []
59def _join_lingering_threads():
60 for thr in _active_threads:
61 thr.stop_thread()
62import atexit
63atexit.register(_join_lingering_threads)
64
65
66class SecurityOptions (object):
67 """
68 Simple object containing the security preferences of an ssh transport.
69 These are tuples of acceptable ciphers, digests, key types, and key
70 exchange algorithms, listed in order of preference.
71
72 Changing the contents and/or order of these fields affects the underlying
73 L{Transport} (but only if you change them before starting the session).
74 If you try to add an algorithm that paramiko doesn't recognize,
75 C{ValueError} will be raised. If you try to assign something besides a
76 tuple to one of the fields, C{TypeError} will be raised.
77 """
78 __slots__ = [ 'ciphers', 'digests', 'key_types', 'kex', 'compression', '_transport' ]
79
80 def __init__(self, transport):
81 self._transport = transport
82
83 def __repr__(self):
84 """
85 Returns a string representation of this object, for debugging.
86
87 @rtype: str
88 """
89 return '<paramiko.SecurityOptions for %s>' % repr(self._transport)
90
91 def _get_ciphers(self):
92 return self._transport._preferred_ciphers
93
94 def _get_digests(self):
95 return self._transport._preferred_macs
96
97 def _get_key_types(self):
98 return self._transport._preferred_keys
99
100 def _get_kex(self):
101 return self._transport._preferred_kex
102
103 def _get_compression(self):
104 return self._transport._preferred_compression
105
106 def _set(self, name, orig, x):
107 if type(x) is list:
108 x = tuple(x)
109 if type(x) is not tuple:
110 raise TypeError('expected tuple or list')
111 possible = getattr(self._transport, orig).keys()
112 forbidden = filter(lambda n: n not in possible, x)
113 if len(forbidden) > 0:
114 raise ValueError('unknown cipher')
115 setattr(self._transport, name, x)
116
117 def _set_ciphers(self, x):
118 self._set('_preferred_ciphers', '_cipher_info', x)
119
120 def _set_digests(self, x):
121 self._set('_preferred_macs', '_mac_info', x)
122
123 def _set_key_types(self, x):
124 self._set('_preferred_keys', '_key_info', x)
125
126 def _set_kex(self, x):
127 self._set('_preferred_kex', '_kex_info', x)
128
129 def _set_compression(self, x):
130 self._set('_preferred_compression', '_compression_info', x)
131
132 ciphers = property(_get_ciphers, _set_ciphers, None,
133 "Symmetric encryption ciphers")
134 digests = property(_get_digests, _set_digests, None,
135 "Digest (one-way hash) algorithms")
136 key_types = property(_get_key_types, _set_key_types, None,
137 "Public-key algorithms")
138 kex = property(_get_kex, _set_kex, None, "Key exchange algorithms")
139 compression = property(_get_compression, _set_compression, None,
140 "Compression algorithms")
141
142
143class ChannelMap (object):
144 def __init__(self):
145 # (id -> Channel)
146 self._map = weakref.WeakValueDictionary()
147 self._lock = threading.Lock()
148
149 def put(self, chanid, chan):
150 self._lock.acquire()
151 try:
152 self._map[chanid] = chan
153 finally:
154 self._lock.release()
155
156 def get(self, chanid):
157 self._lock.acquire()
158 try:
159 return self._map.get(chanid, None)
160 finally:
161 self._lock.release()
162
163 def delete(self, chanid):
164 self._lock.acquire()
165 try:
166 try:
167 del self._map[chanid]
168 except KeyError:
169 pass
170 finally:
171 self._lock.release()
172
173 def values(self):
174 self._lock.acquire()
175 try:
176 return self._map.values()
177 finally:
178 self._lock.release()
179
180 def __len__(self):
181 self._lock.acquire()
182 try:
183 return len(self._map)
184 finally:
185 self._lock.release()
186
187
188class Transport (threading.Thread):
189 """
190 An SSH Transport attaches to a stream (usually a socket), negotiates an
191 encrypted session, authenticates, and then creates stream tunnels, called
192 L{Channel}s, across the session. Multiple channels can be multiplexed
193 across a single session (and often are, in the case of port forwardings).
194 """
195
196 _PROTO_ID = '2.0'
197 _CLIENT_ID = 'paramiko_1.7.7.1'
198
199 _preferred_ciphers = ( 'aes128-ctr', 'aes256-ctr', 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc',
200 'arcfour128', 'arcfour256' )
201 _preferred_macs = ( 'hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96' )
202 _preferred_keys = ( 'ssh-rsa', 'ssh-dss' )
203 _preferred_kex = ( 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' )
204 _preferred_compression = ( 'none', )
205
206 _cipher_info = {
207 'aes128-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16 },
208 'aes256-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32 },
209 'blowfish-cbc': { 'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16 },
210 'aes128-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 16 },
211 'aes256-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 32 },
212 '3des-cbc': { 'class': DES3, 'mode': DES3.MODE_CBC, 'block-size': 8, 'key-size': 24 },
213 'arcfour128': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 16 },
214 'arcfour256': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 32 },
215 }
216
217 _mac_info = {
218 'hmac-sha1': { 'class': SHA, 'size': 20 },
219 'hmac-sha1-96': { 'class': SHA, 'size': 12 },
220 'hmac-md5': { 'class': MD5, 'size': 16 },
221 'hmac-md5-96': { 'class': MD5, 'size': 12 },
222 }
223
224 _key_info = {
225 'ssh-rsa': RSAKey,
226 'ssh-dss': DSSKey,
227 }
228
229 _kex_info = {
230 'diffie-hellman-group1-sha1': KexGroup1,
231 'diffie-hellman-group-exchange-sha1': KexGex,
232 }
233
234 _compression_info = {
235 # zlib@openssh.com is just zlib, but only turned on after a successful
236 # authentication. openssh servers may only offer this type because
237 # they've had troubles with security holes in zlib in the past.
238 'zlib@openssh.com': ( ZlibCompressor, ZlibDecompressor ),
239 'zlib': ( ZlibCompressor, ZlibDecompressor ),
240 'none': ( None, None ),
241 }
242
243
244 _modulus_pack = None
245
246 def __init__(self, sock):
247 """
248 Create a new SSH session over an existing socket, or socket-like
249 object. This only creates the Transport object; it doesn't begin the
250 SSH session yet. Use L{connect} or L{start_client} to begin a client
251 session, or L{start_server} to begin a server session.
252
253 If the object is not actually a socket, it must have the following
254 methods:
255 - C{send(str)}: Writes from 1 to C{len(str)} bytes, and
256 returns an int representing the number of bytes written. Returns
257 0 or raises C{EOFError} if the stream has been closed.
258 - C{recv(int)}: Reads from 1 to C{int} bytes and returns them as a
259 string. Returns 0 or raises C{EOFError} if the stream has been
260 closed.
261 - C{close()}: Closes the socket.
262 - C{settimeout(n)}: Sets a (float) timeout on I/O operations.
263
264 For ease of use, you may also pass in an address (as a tuple) or a host
265 string as the C{sock} argument. (A host string is a hostname with an
266 optional port (separated by C{":"}) which will be converted into a
267 tuple of C{(hostname, port)}.) A socket will be connected to this
268 address and used for communication. Exceptions from the C{socket} call
269 may be thrown in this case.
270
271 @param sock: a socket or socket-like object to create the session over.
272 @type sock: socket
273 """
274 if isinstance(sock, (str, unicode)):
275 # convert "host:port" into (host, port)
276 hl = sock.split(':', 1)
277 if len(hl) == 1:
278 sock = (hl[0], 22)
279 else:
280 sock = (hl[0], int(hl[1]))
281 if type(sock) is tuple:
282 # connect to the given (host, port)
283 hostname, port = sock
284 reason = 'No suitable address family'
285 for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
286 if socktype == socket.SOCK_STREAM:
287 af = family
288 addr = sockaddr
289 sock = socket.socket(af, socket.SOCK_STREAM)
290 try:
291 sock.connect((hostname, port))
292 except socket.error, e:
293 reason = str(e)
294 else:
295 break
296 else:
297 raise SSHException(
298 'Unable to connect to %s: %s' % (hostname, reason))
299 # okay, normal socket-ish flow here...
300 threading.Thread.__init__(self)
301 self.setDaemon(True)
302 self.rng = rng
303 self.sock = sock
304 # Python < 2.3 doesn't have the settimeout method - RogerB
305 try:
306 # we set the timeout so we can check self.active periodically to
307 # see if we should bail. socket.timeout exception is never
308 # propagated.
309 self.sock.settimeout(0.1)
310 except AttributeError:
311 pass
312
313 # negotiated crypto parameters
314 self.packetizer = Packetizer(sock)
315 self.local_version = 'SSH-' + self._PROTO_ID + '-' + self._CLIENT_ID
316 self.remote_version = ''
317 self.local_cipher = self.remote_cipher = ''
318 self.local_kex_init = self.remote_kex_init = None
319 self.local_mac = self.remote_mac = None
320 self.local_compression = self.remote_compression = None
321 self.session_id = None
322 self.host_key_type = None
323 self.host_key = None
324
325 # state used during negotiation
326 self.kex_engine = None
327 self.H = None
328 self.K = None
329
330 self.active = False
331 self.initial_kex_done = False
332 self.in_kex = False
333 self.authenticated = False
334 self._expected_packet = tuple()
335 self.lock = threading.Lock() # synchronization (always higher level than write_lock)
336
337 # tracking open channels
338 self._channels = ChannelMap()
339 self.channel_events = { } # (id -> Event)
340 self.channels_seen = { } # (id -> True)
341 self._channel_counter = 1
342 self.window_size = 65536
343 self.max_packet_size = 34816
344 self._x11_handler = None
345 self._tcp_handler = None
346
347 self.saved_exception = None
348 self.clear_to_send = threading.Event()
349 self.clear_to_send_lock = threading.Lock()
350 self.clear_to_send_timeout = 30.0
351 self.log_name = 'paramiko.transport'
352 self.logger = util.get_logger(self.log_name)
353 self.packetizer.set_log(self.logger)
354 self.auth_handler = None
355 self.global_response = None # response Message from an arbitrary global request
356 self.completion_event = None # user-defined event callbacks
357 self.banner_timeout = 15 # how long (seconds) to wait for the SSH banner
358
359 # server mode:
360 self.server_mode = False
361 self.server_object = None
362 self.server_key_dict = { }
363 self.server_accepts = [ ]
364 self.server_accept_cv = threading.Condition(self.lock)
365 self.subsystem_table = { }
366
367 def __repr__(self):
368 """
369 Returns a string representation of this object, for debugging.
370
371 @rtype: str
372 """
373 out = '<paramiko.Transport at %s' % hex(long(id(self)) & 0xffffffffL)
374 if not self.active:
375 out += ' (unconnected)'
376 else:
377 if self.local_cipher != '':
378 out += ' (cipher %s, %d bits)' % (self.local_cipher,
379 self._cipher_info[self.local_cipher]['key-size'] * 8)
380 if self.is_authenticated():
381 out += ' (active; %d open channel(s))' % len(self._channels)
382 elif self.initial_kex_done:
383 out += ' (connected; awaiting auth)'
384 else:
385 out += ' (connecting)'
386 out += '>'
387 return out
388
389 def atfork(self):
390 """
391 Terminate this Transport without closing the session. On posix
392 systems, if a Transport is open during process forking, both parent
393 and child will share the underlying socket, but only one process can
394 use the connection (without corrupting the session). Use this method
395 to clean up a Transport object without disrupting the other process.
396
397 @since: 1.5.3
398 """
399 self.sock.close()
400 self.close()
401
402 def get_security_options(self):
403 """
404 Return a L{SecurityOptions} object which can be used to tweak the
405 encryption algorithms this transport will permit, and the order of
406 preference for them.
407
408 @return: an object that can be used to change the preferred algorithms
409 for encryption, digest (hash), public key, and key exchange.
410 @rtype: L{SecurityOptions}
411 """
412 return SecurityOptions(self)
413
414 def start_client(self, event=None):
415 """
416 Negotiate a new SSH2 session as a client. This is the first step after
417 creating a new L{Transport}. A separate thread is created for protocol
418 negotiation.
419
420 If an event is passed in, this method returns immediately. When
421 negotiation is done (successful or not), the given C{Event} will
422 be triggered. On failure, L{is_active} will return C{False}.
423
424 (Since 1.4) If C{event} is C{None}, this method will not return until
425 negotation is done. On success, the method returns normally.
426 Otherwise an SSHException is raised.
427
428 After a successful negotiation, you will usually want to authenticate,
429 calling L{auth_password <Transport.auth_password>} or
430 L{auth_publickey <Transport.auth_publickey>}.
431
432 @note: L{connect} is a simpler method for connecting as a client.
433
434 @note: After calling this method (or L{start_server} or L{connect}),
435 you should no longer directly read from or write to the original
436 socket object.
437
438 @param event: an event to trigger when negotiation is complete
439 (optional)
440 @type event: threading.Event
441
442 @raise SSHException: if negotiation fails (and no C{event} was passed
443 in)
444 """
445 self.active = True
446 if event is not None:
447 # async, return immediately and let the app poll for completion
448 self.completion_event = event
449 self.start()
450 return
451
452 # synchronous, wait for a result
453 self.completion_event = event = threading.Event()
454 self.start()
455 Random.atfork()
456 while True:
457 event.wait(0.1)
458 if not self.active:
459 e = self.get_exception()
460 if e is not None:
461 raise e
462 raise SSHException('Negotiation failed.')
463 if event.isSet():
464 break
465
466 def start_server(self, event=None, server=None):
467 """
468 Negotiate a new SSH2 session as a server. This is the first step after
469 creating a new L{Transport} and setting up your server host key(s). A
470 separate thread is created for protocol negotiation.
471
472 If an event is passed in, this method returns immediately. When
473 negotiation is done (successful or not), the given C{Event} will
474 be triggered. On failure, L{is_active} will return C{False}.
475
476 (Since 1.4) If C{event} is C{None}, this method will not return until
477 negotation is done. On success, the method returns normally.
478 Otherwise an SSHException is raised.
479
480 After a successful negotiation, the client will need to authenticate.
481 Override the methods
482 L{get_allowed_auths <ServerInterface.get_allowed_auths>},
483 L{check_auth_none <ServerInterface.check_auth_none>},
484 L{check_auth_password <ServerInterface.check_auth_password>}, and
485 L{check_auth_publickey <ServerInterface.check_auth_publickey>} in the
486 given C{server} object to control the authentication process.
487
488 After a successful authentication, the client should request to open
489 a channel. Override
490 L{check_channel_request <ServerInterface.check_channel_request>} in the
491 given C{server} object to allow channels to be opened.
492
493 @note: After calling this method (or L{start_client} or L{connect}),
494 you should no longer directly read from or write to the original
495 socket object.
496
497 @param event: an event to trigger when negotiation is complete.
498 @type event: threading.Event
499 @param server: an object used to perform authentication and create
500 L{Channel}s.
501 @type server: L{server.ServerInterface}
502
503 @raise SSHException: if negotiation fails (and no C{event} was passed
504 in)
505 """
506 if server is None:
507 server = ServerInterface()
508 self.server_mode = True
509 self.server_object = server
510 self.active = True
511 if event is not None:
512 # async, return immediately and let the app poll for completion
513 self.completion_event = event
514 self.start()
515 return
516
517 # synchronous, wait for a result
518 self.completion_event = event = threading.Event()
519 self.start()
520 while True:
521 event.wait(0.1)
522 if not self.active:
523 e = self.get_exception()
524 if e is not None:
525 raise e
526 raise SSHException('Negotiation failed.')
527 if event.isSet():
528 break
529
530 def add_server_key(self, key):
531 """
532 Add a host key to the list of keys used for server mode. When behaving
533 as a server, the host key is used to sign certain packets during the
534 SSH2 negotiation, so that the client can trust that we are who we say
535 we are. Because this is used for signing, the key must contain private
536 key info, not just the public half. Only one key of each type (RSA or
537 DSS) is kept.
538
539 @param key: the host key to add, usually an L{RSAKey <rsakey.RSAKey>} or
540 L{DSSKey <dsskey.DSSKey>}.
541 @type key: L{PKey <pkey.PKey>}
542 """
543 self.server_key_dict[key.get_name()] = key
544
545 def get_server_key(self):
546 """
547 Return the active host key, in server mode. After negotiating with the
548 client, this method will return the negotiated host key. If only one
549 type of host key was set with L{add_server_key}, that's the only key
550 that will ever be returned. But in cases where you have set more than
551 one type of host key (for example, an RSA key and a DSS key), the key
552 type will be negotiated by the client, and this method will return the
553 key of the type agreed on. If the host key has not been negotiated
554 yet, C{None} is returned. In client mode, the behavior is undefined.
555
556 @return: host key of the type negotiated by the client, or C{None}.
557 @rtype: L{PKey <pkey.PKey>}
558 """
559 try:
560 return self.server_key_dict[self.host_key_type]
561 except KeyError:
562 pass
563 return None
564
565 def load_server_moduli(filename=None):
566 """
567 I{(optional)}
568 Load a file of prime moduli for use in doing group-exchange key
569 negotiation in server mode. It's a rather obscure option and can be
570 safely ignored.
571
572 In server mode, the remote client may request "group-exchange" key
573 negotiation, which asks the server to send a random prime number that
574 fits certain criteria. These primes are pretty difficult to compute,
575 so they can't be generated on demand. But many systems contain a file
576 of suitable primes (usually named something like C{/etc/ssh/moduli}).
577 If you call C{load_server_moduli} and it returns C{True}, then this
578 file of primes has been loaded and we will support "group-exchange" in
579 server mode. Otherwise server mode will just claim that it doesn't
580 support that method of key negotiation.
581
582 @param filename: optional path to the moduli file, if you happen to
583 know that it's not in a standard location.
584 @type filename: str
585 @return: True if a moduli file was successfully loaded; False
586 otherwise.
587 @rtype: bool
588
589 @note: This has no effect when used in client mode.
590 """
591 Transport._modulus_pack = ModulusPack(rng)
592 # places to look for the openssh "moduli" file
593 file_list = [ '/etc/ssh/moduli', '/usr/local/etc/moduli' ]
594 if filename is not None:
595 file_list.insert(0, filename)
596 for fn in file_list:
597 try:
598 Transport._modulus_pack.read_file(fn)
599 return True
600 except IOError:
601 pass
602 # none succeeded
603 Transport._modulus_pack = None
604 return False
605 load_server_moduli = staticmethod(load_server_moduli)
606
607 def close(self):
608 """
609 Close this session, and any open channels that are tied to it.
610 """
611 if not self.active:
612 return
613 self.active = False
614 self.packetizer.close()
615 self.join()
616 for chan in self._channels.values():
617 chan._unlink()
618
619 def get_remote_server_key(self):
620 """
621 Return the host key of the server (in client mode).
622
623 @note: Previously this call returned a tuple of (key type, key string).
624 You can get the same effect by calling
625 L{PKey.get_name <pkey.PKey.get_name>} for the key type, and
626 C{str(key)} for the key string.
627
628 @raise SSHException: if no session is currently active.
629
630 @return: public key of the remote server
631 @rtype: L{PKey <pkey.PKey>}
632 """
633 if (not self.active) or (not self.initial_kex_done):
634 raise SSHException('No existing session')
635 return self.host_key
636
637 def is_active(self):
638 """
639 Return true if this session is active (open).
640
641 @return: True if the session is still active (open); False if the
642 session is closed
643 @rtype: bool
644 """
645 return self.active
646
647 def open_session(self):
648 """
649 Request a new channel to the server, of type C{"session"}. This
650 is just an alias for C{open_channel('session')}.
651
652 @return: a new L{Channel}
653 @rtype: L{Channel}
654
655 @raise SSHException: if the request is rejected or the session ends
656 prematurely
657 """
658 return self.open_channel('session')
659
660 def open_x11_channel(self, src_addr=None):
661 """
662 Request a new channel to the client, of type C{"x11"}. This
663 is just an alias for C{open_channel('x11', src_addr=src_addr)}.
664
665 @param src_addr: the source address of the x11 server (port is the
666 x11 port, ie. 6010)
667 @type src_addr: (str, int)
668 @return: a new L{Channel}
669 @rtype: L{Channel}
670
671 @raise SSHException: if the request is rejected or the session ends
672 prematurely
673 """
674 return self.open_channel('x11', src_addr=src_addr)
675
676 def open_forwarded_tcpip_channel(self, (src_addr, src_port), (dest_addr, dest_port)):
677 """
678 Request a new channel back to the client, of type C{"forwarded-tcpip"}.
679 This is used after a client has requested port forwarding, for sending
680 incoming connections back to the client.
681
682 @param src_addr: originator's address
683 @param src_port: originator's port
684 @param dest_addr: local (server) connected address
685 @param dest_port: local (server) connected port
686 """
687 return self.open_channel('forwarded-tcpip', (dest_addr, dest_port), (src_addr, src_port))
688
689 def open_channel(self, kind, dest_addr=None, src_addr=None):
690 """
691 Request a new channel to the server. L{Channel}s are socket-like
692 objects used for the actual transfer of data across the session.
693 You may only request a channel after negotiating encryption (using
694 L{connect} or L{start_client}) and authenticating.
695
696 @param kind: the kind of channel requested (usually C{"session"},
697 C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"})
698 @type kind: str
699 @param dest_addr: the destination address of this port forwarding,
700 if C{kind} is C{"forwarded-tcpip"} or C{"direct-tcpip"} (ignored
701 for other channel types)
702 @type dest_addr: (str, int)
703 @param src_addr: the source address of this port forwarding, if
704 C{kind} is C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"}
705 @type src_addr: (str, int)
706 @return: a new L{Channel} on success
707 @rtype: L{Channel}
708
709 @raise SSHException: if the request is rejected or the session ends
710 prematurely
711 """
712 if not self.active:
713 raise SSHException('SSH session not active')
714 self.lock.acquire()
715 try:
716 chanid = self._next_channel()
717 m = Message()
718 m.add_byte(chr(MSG_CHANNEL_OPEN))
719 m.add_string(kind)
720 m.add_int(chanid)
721 m.add_int(self.window_size)
722 m.add_int(self.max_packet_size)
723 if (kind == 'forwarded-tcpip') or (kind == 'direct-tcpip'):
724 m.add_string(dest_addr[0])
725 m.add_int(dest_addr[1])
726 m.add_string(src_addr[0])
727 m.add_int(src_addr[1])
728 elif kind == 'x11':
729 m.add_string(src_addr[0])
730 m.add_int(src_addr[1])
731 chan = Channel(chanid)
732 self._channels.put(chanid, chan)
733 self.channel_events[chanid] = event = threading.Event()
734 self.channels_seen[chanid] = True
735 chan._set_transport(self)
736 chan._set_window(self.window_size, self.max_packet_size)
737 finally:
738 self.lock.release()
739 self._send_user_message(m)
740 while True:
741 event.wait(0.1);
742 if not self.active:
743 e = self.get_exception()
744 if e is None:
745 e = SSHException('Unable to open channel.')
746 raise e
747 if event.isSet():
748 break
749 chan = self._channels.get(chanid)
750 if chan is not None:
751 return chan
752 e = self.get_exception()
753 if e is None:
754 e = SSHException('Unable to open channel.')
755 raise e
756
757 def request_port_forward(self, address, port, handler=None):
758 """
759 Ask the server to forward TCP connections from a listening port on
760 the server, across this SSH session.
761
762 If a handler is given, that handler is called from a different thread
763 whenever a forwarded connection arrives. The handler parameters are::
764
765 handler(channel, (origin_addr, origin_port), (server_addr, server_port))
766
767 where C{server_addr} and C{server_port} are the address and port that
768 the server was listening on.
769
770 If no handler is set, the default behavior is to send new incoming
771 forwarded connections into the accept queue, to be picked up via
772 L{accept}.
773
774 @param address: the address to bind when forwarding
775 @type address: str
776 @param port: the port to forward, or 0 to ask the server to allocate
777 any port
778 @type port: int
779 @param handler: optional handler for incoming forwarded connections
780 @type handler: function(Channel, (str, int), (str, int))
781 @return: the port # allocated by the server
782 @rtype: int
783
784 @raise SSHException: if the server refused the TCP forward request
785 """
786 if not self.active:
787 raise SSHException('SSH session not active')
788 address = str(address)
789 port = int(port)
790 response = self.global_request('tcpip-forward', (address, port), wait=True)
791 if response is None:
792 raise SSHException('TCP forwarding request denied')
793 if port == 0:
794 port = response.get_int()
795 if handler is None:
796 def default_handler(channel, (src_addr, src_port), (dest_addr, dest_port)):
797 self._queue_incoming_channel(channel)
798 handler = default_handler
799 self._tcp_handler = handler
800 return port
801
802 def cancel_port_forward(self, address, port):
803 """
804 Ask the server to cancel a previous port-forwarding request. No more
805 connections to the given address & port will be forwarded across this
806 ssh connection.
807
808 @param address: the address to stop forwarding
809 @type address: str
810 @param port: the port to stop forwarding
811 @type port: int
812 """
813 if not self.active:
814 return
815 self._tcp_handler = None
816 self.global_request('cancel-tcpip-forward', (address, port), wait=True)
817
818 def open_sftp_client(self):
819 """
820 Create an SFTP client channel from an open transport. On success,
821 an SFTP session will be opened with the remote host, and a new
822 SFTPClient object will be returned.
823
824 @return: a new L{SFTPClient} object, referring to an sftp session
825 (channel) across this transport
826 @rtype: L{SFTPClient}
827 """
828 return SFTPClient.from_transport(self)
829
830 def send_ignore(self, bytes=None):
831 """
832 Send a junk packet across the encrypted link. This is sometimes used
833 to add "noise" to a connection to confuse would-be attackers. It can
834 also be used as a keep-alive for long lived connections traversing
835 firewalls.
836
837 @param bytes: the number of random bytes to send in the payload of the
838 ignored packet -- defaults to a random number from 10 to 41.
839 @type bytes: int
840 """
841 m = Message()
842 m.add_byte(chr(MSG_IGNORE))
843 if bytes is None:
844 bytes = (ord(rng.read(1)) % 32) + 10
845 m.add_bytes(rng.read(bytes))
846 self._send_user_message(m)
847
848 def renegotiate_keys(self):
849 """
850 Force this session to switch to new keys. Normally this is done
851 automatically after the session hits a certain number of packets or
852 bytes sent or received, but this method gives you the option of forcing
853 new keys whenever you want. Negotiating new keys causes a pause in
854 traffic both ways as the two sides swap keys and do computations. This
855 method returns when the session has switched to new keys.
856
857 @raise SSHException: if the key renegotiation failed (which causes the
858 session to end)
859 """
860 self.completion_event = threading.Event()
861 self._send_kex_init()
862 while True:
863 self.completion_event.wait(0.1)
864 if not self.active:
865 e = self.get_exception()
866 if e is not None:
867 raise e
868 raise SSHException('Negotiation failed.')
869 if self.completion_event.isSet():
870 break
871 return
872
873 def set_keepalive(self, interval):
874 """
875 Turn on/off keepalive packets (default is off). If this is set, after
876 C{interval} seconds without sending any data over the connection, a
877 "keepalive" packet will be sent (and ignored by the remote host). This
878 can be useful to keep connections alive over a NAT, for example.
879
880 @param interval: seconds to wait before sending a keepalive packet (or
881 0 to disable keepalives).
882 @type interval: int
883 """
884 self.packetizer.set_keepalive(interval,
885 lambda x=weakref.proxy(self): x.global_request('keepalive@lag.net', wait=False))
886
887 def global_request(self, kind, data=None, wait=True):
888 """
889 Make a global request to the remote host. These are normally
890 extensions to the SSH2 protocol.
891
892 @param kind: name of the request.
893 @type kind: str
894 @param data: an optional tuple containing additional data to attach
895 to the request.
896 @type data: tuple
897 @param wait: C{True} if this method should not return until a response
898 is received; C{False} otherwise.
899 @type wait: bool
900 @return: a L{Message} containing possible additional data if the
901 request was successful (or an empty L{Message} if C{wait} was
902 C{False}); C{None} if the request was denied.
903 @rtype: L{Message}
904 """
905 if wait:
906 self.completion_event = threading.Event()
907 m = Message()
908 m.add_byte(chr(MSG_GLOBAL_REQUEST))
909 m.add_string(kind)
910 m.add_boolean(wait)
911 if data is not None:
912 m.add(*data)
913 self._log(DEBUG, 'Sending global request "%s"' % kind)
914 self._send_user_message(m)
915 if not wait:
916 return None
917 while True:
918 self.completion_event.wait(0.1)
919 if not self.active:
920 return None
921 if self.completion_event.isSet():
922 break
923 return self.global_response
924
925 def accept(self, timeout=None):
926 """
927 Return the next channel opened by the client over this transport, in
928 server mode. If no channel is opened before the given timeout, C{None}
929 is returned.
930
931 @param timeout: seconds to wait for a channel, or C{None} to wait
932 forever
933 @type timeout: int
934 @return: a new Channel opened by the client
935 @rtype: L{Channel}
936 """
937 self.lock.acquire()
938 try:
939 if len(self.server_accepts) > 0:
940 chan = self.server_accepts.pop(0)
941 else:
942 self.server_accept_cv.wait(timeout)
943 if len(self.server_accepts) > 0:
944 chan = self.server_accepts.pop(0)
945 else:
946 # timeout
947 chan = None
948 finally:
949 self.lock.release()
950 return chan
951
952 def connect(self, hostkey=None, username='', password=None, pkey=None):
953 """
954 Negotiate an SSH2 session, and optionally verify the server's host key
955 and authenticate using a password or private key. This is a shortcut
956 for L{start_client}, L{get_remote_server_key}, and
957 L{Transport.auth_password} or L{Transport.auth_publickey}. Use those
958 methods if you want more control.
959
960 You can use this method immediately after creating a Transport to
961 negotiate encryption with a server. If it fails, an exception will be
962 thrown. On success, the method will return cleanly, and an encrypted
963 session exists. You may immediately call L{open_channel} or
964 L{open_session} to get a L{Channel} object, which is used for data
965 transfer.
966
967 @note: If you fail to supply a password or private key, this method may
968 succeed, but a subsequent L{open_channel} or L{open_session} call may
969 fail because you haven't authenticated yet.
970
971 @param hostkey: the host key expected from the server, or C{None} if
972 you don't want to do host key verification.
973 @type hostkey: L{PKey<pkey.PKey>}
974 @param username: the username to authenticate as.
975 @type username: str
976 @param password: a password to use for authentication, if you want to
977 use password authentication; otherwise C{None}.
978 @type password: str
979 @param pkey: a private key to use for authentication, if you want to
980 use private key authentication; otherwise C{None}.
981 @type pkey: L{PKey<pkey.PKey>}
982
983 @raise SSHException: if the SSH2 negotiation fails, the host key
984 supplied by the server is incorrect, or authentication fails.
985 """
986 if hostkey is not None:
987 self._preferred_keys = [ hostkey.get_name() ]
988
989 self.start_client()
990
991 # check host key if we were given one
992 if (hostkey is not None):
993 key = self.get_remote_server_key()
994 if (key.get_name() != hostkey.get_name()) or (str(key) != str(hostkey)):
995 self._log(DEBUG, 'Bad host key from server')
996 self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(str(hostkey))))
997 self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(str(key))))
998 raise SSHException('Bad host key from server')
999 self._log(DEBUG, 'Host key verified (%s)' % hostkey.get_name())
1000
1001 if (pkey is not None) or (password is not None):
1002 if password is not None:
1003 self._log(DEBUG, 'Attempting password auth...')
1004 self.auth_password(username, password)
1005 else:
1006 self._log(DEBUG, 'Attempting public-key auth...')
1007 self.auth_publickey(username, pkey)
1008
1009 return
1010
1011 def get_exception(self):
1012 """
1013 Return any exception that happened during the last server request.
1014 This can be used to fetch more specific error information after using
1015 calls like L{start_client}. The exception (if any) is cleared after
1016 this call.
1017
1018 @return: an exception, or C{None} if there is no stored exception.
1019 @rtype: Exception
1020
1021 @since: 1.1
1022 """
1023 self.lock.acquire()
1024 try:
1025 e = self.saved_exception
1026 self.saved_exception = None
1027 return e
1028 finally:
1029 self.lock.release()
1030
1031 def set_subsystem_handler(self, name, handler, *larg, **kwarg):
1032 """
1033 Set the handler class for a subsystem in server mode. If a request
1034 for this subsystem is made on an open ssh channel later, this handler
1035 will be constructed and called -- see L{SubsystemHandler} for more
1036 detailed documentation.
1037
1038 Any extra parameters (including keyword arguments) are saved and
1039 passed to the L{SubsystemHandler} constructor later.
1040
1041 @param name: name of the subsystem.
1042 @type name: str
1043 @param handler: subclass of L{SubsystemHandler} that handles this
1044 subsystem.
1045 @type handler: class
1046 """
1047 try:
1048 self.lock.acquire()
1049 self.subsystem_table[name] = (handler, larg, kwarg)
1050 finally:
1051 self.lock.release()
1052
1053 def is_authenticated(self):
1054 """
1055 Return true if this session is active and authenticated.
1056
1057 @return: True if the session is still open and has been authenticated
1058 successfully; False if authentication failed and/or the session is
1059 closed.
1060 @rtype: bool
1061 """
1062 return self.active and (self.auth_handler is not None) and self.auth_handler.is_authenticated()
1063
1064 def get_username(self):
1065 """
1066 Return the username this connection is authenticated for. If the
1067 session is not authenticated (or authentication failed), this method
1068 returns C{None}.
1069
1070 @return: username that was authenticated, or C{None}.
1071 @rtype: string
1072 """
1073 if not self.active or (self.auth_handler is None):
1074 return None
1075 return self.auth_handler.get_username()
1076
1077 def auth_none(self, username):
1078 """
1079 Try to authenticate to the server using no authentication at all.
1080 This will almost always fail. It may be useful for determining the
1081 list of authentication types supported by the server, by catching the
1082 L{BadAuthenticationType} exception raised.
1083
1084 @param username: the username to authenticate as
1085 @type username: string
1086 @return: list of auth types permissible for the next stage of
1087 authentication (normally empty)
1088 @rtype: list
1089
1090 @raise BadAuthenticationType: if "none" authentication isn't allowed
1091 by the server for this user
1092 @raise SSHException: if the authentication failed due to a network
1093 error
1094
1095 @since: 1.5
1096 """
1097 if (not self.active) or (not self.initial_kex_done):
1098 raise SSHException('No existing session')
1099 my_event = threading.Event()
1100 self.auth_handler = AuthHandler(self)
1101 self.auth_handler.auth_none(username, my_event)
1102 return self.auth_handler.wait_for_response(my_event)
1103
1104 def auth_password(self, username, password, event=None, fallback=True):
1105 """
1106 Authenticate to the server using a password. The username and password
1107 are sent over an encrypted link.
1108
1109 If an C{event} is passed in, this method will return immediately, and
1110 the event will be triggered once authentication succeeds or fails. On
1111 success, L{is_authenticated} will return C{True}. On failure, you may
1112 use L{get_exception} to get more detailed error information.
1113
1114 Since 1.1, if no event is passed, this method will block until the
1115 authentication succeeds or fails. On failure, an exception is raised.
1116 Otherwise, the method simply returns.
1117
1118 Since 1.5, if no event is passed and C{fallback} is C{True} (the
1119 default), if the server doesn't support plain password authentication
1120 but does support so-called "keyboard-interactive" mode, an attempt
1121 will be made to authenticate using this interactive mode. If it fails,
1122 the normal exception will be thrown as if the attempt had never been
1123 made. This is useful for some recent Gentoo and Debian distributions,
1124 which turn off plain password authentication in a misguided belief
1125 that interactive authentication is "more secure". (It's not.)
1126
1127 If the server requires multi-step authentication (which is very rare),
1128 this method will return a list of auth types permissible for the next
1129 step. Otherwise, in the normal case, an empty list is returned.
1130
1131 @param username: the username to authenticate as
1132 @type username: str
1133 @param password: the password to authenticate with
1134 @type password: str or unicode
1135 @param event: an event to trigger when the authentication attempt is
1136 complete (whether it was successful or not)
1137 @type event: threading.Event
1138 @param fallback: C{True} if an attempt at an automated "interactive"
1139 password auth should be made if the server doesn't support normal
1140 password auth
1141 @type fallback: bool
1142 @return: list of auth types permissible for the next stage of
1143 authentication (normally empty)
1144 @rtype: list
1145
1146 @raise BadAuthenticationType: if password authentication isn't
1147 allowed by the server for this user (and no event was passed in)
1148 @raise AuthenticationException: if the authentication failed (and no
1149 event was passed in)
1150 @raise SSHException: if there was a network error
1151 """
1152 if (not self.active) or (not self.initial_kex_done):
1153 # we should never try to send the password unless we're on a secure link
1154 raise SSHException('No existing session')
1155 if event is None:
1156 my_event = threading.Event()
1157 else:
1158 my_event = event
1159 self.auth_handler = AuthHandler(self)
1160 self.auth_handler.auth_password(username, password, my_event)
1161 if event is not None:
1162 # caller wants to wait for event themselves
1163 return []
1164 try:
1165 return self.auth_handler.wait_for_response(my_event)
1166 except BadAuthenticationType, x:
1167 # if password auth isn't allowed, but keyboard-interactive *is*, try to fudge it
1168 if not fallback or ('keyboard-interactive' not in x.allowed_types):
1169 raise
1170 try:
1171 def handler(title, instructions, fields):
1172 if len(fields) > 1:
1173 raise SSHException('Fallback authentication failed.')
1174 if len(fields) == 0:
1175 # for some reason, at least on os x, a 2nd request will
1176 # be made with zero fields requested. maybe it's just
1177 # to try to fake out automated scripting of the exact
1178 # type we're doing here. *shrug* :)
1179 return []
1180 return [ password ]
1181 return self.auth_interactive(username, handler)
1182 except SSHException, ignored:
1183 # attempt failed; just raise the original exception
1184 raise x
1185 return None
1186
1187 def auth_publickey(self, username, key, event=None):
1188 """
1189 Authenticate to the server using a private key. The key is used to
1190 sign data from the server, so it must include the private part.
1191
1192 If an C{event} is passed in, this method will return immediately, and
1193 the event will be triggered once authentication succeeds or fails. On
1194 success, L{is_authenticated} will return C{True}. On failure, you may
1195 use L{get_exception} to get more detailed error information.
1196
1197 Since 1.1, if no event is passed, this method will block until the
1198 authentication succeeds or fails. On failure, an exception is raised.
1199 Otherwise, the method simply returns.
1200
1201 If the server requires multi-step authentication (which is very rare),
1202 this method will return a list of auth types permissible for the next
1203 step. Otherwise, in the normal case, an empty list is returned.
1204
1205 @param username: the username to authenticate as
1206 @type username: string
1207 @param key: the private key to authenticate with
1208 @type key: L{PKey <pkey.PKey>}
1209 @param event: an event to trigger when the authentication attempt is
1210 complete (whether it was successful or not)
1211 @type event: threading.Event
1212 @return: list of auth types permissible for the next stage of
1213 authentication (normally empty)
1214 @rtype: list
1215
1216 @raise BadAuthenticationType: if public-key authentication isn't
1217 allowed by the server for this user (and no event was passed in)
1218 @raise AuthenticationException: if the authentication failed (and no
1219 event was passed in)
1220 @raise SSHException: if there was a network error
1221 """
1222 if (not self.active) or (not self.initial_kex_done):
1223 # we should never try to authenticate unless we're on a secure link
1224 raise SSHException('No existing session')
1225 if event is None:
1226 my_event = threading.Event()
1227 else:
1228 my_event = event
1229 self.auth_handler = AuthHandler(self)
1230 self.auth_handler.auth_publickey(username, key, my_event)
1231 if event is not None:
1232 # caller wants to wait for event themselves
1233 return []
1234 return self.auth_handler.wait_for_response(my_event)
1235
1236 def auth_interactive(self, username, handler, submethods=''):
1237 """
1238 Authenticate to the server interactively. A handler is used to answer
1239 arbitrary questions from the server. On many servers, this is just a
1240 dumb wrapper around PAM.
1241
1242 This method will block until the authentication succeeds or fails,
1243 peroidically calling the handler asynchronously to get answers to