1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """
20 L{Transport} handles the core SSH2 protocol.
21 """
22
23 import os
24 import socket
25 import string
26 import struct
27 import sys
28 import threading
29 import time
30 import weakref
31
32 import paramiko
33 from paramiko import util
34 from paramiko.auth_handler import AuthHandler
35 from paramiko.channel import Channel
36 from paramiko.common import *
37 from paramiko.compress import ZlibCompressor, ZlibDecompressor
38 from paramiko.dsskey import DSSKey
39 from paramiko.kex_gex import KexGex
40 from paramiko.kex_group1 import KexGroup1
41 from paramiko.message import Message
42 from paramiko.packet import Packetizer, NeedRekeyException
43 from paramiko.primes import ModulusPack
44 from paramiko.rsakey import RSAKey
45 from paramiko.ecdsakey import ECDSAKey
46 from paramiko.server import ServerInterface
47 from paramiko.sftp_client import SFTPClient
48 from paramiko.ssh_exception import (SSHException, BadAuthenticationType,
49 ChannelException, ProxyCommandFailure)
50 from paramiko.util import retry_on_signal
51
52 from Crypto import Random
53 from Crypto.Cipher import Blowfish, AES, DES3, ARC4
54 from Crypto.Hash import SHA, MD5
55 try:
56 from Crypto.Util import Counter
57 except ImportError:
58 from paramiko.util import Counter
59
60
61
62 _active_threads = []
66 import atexit
67 atexit.register(_join_lingering_threads)
68
69
71 """
72 Simple object containing the security preferences of an ssh transport.
73 These are tuples of acceptable ciphers, digests, key types, and key
74 exchange algorithms, listed in order of preference.
75
76 Changing the contents and/or order of these fields affects the underlying
77 L{Transport} (but only if you change them before starting the session).
78 If you try to add an algorithm that paramiko doesn't recognize,
79 C{ValueError} will be raised. If you try to assign something besides a
80 tuple to one of the fields, C{TypeError} will be raised.
81 """
82 __slots__ = [ 'ciphers', 'digests', 'key_types', 'kex', 'compression', '_transport' ]
83
86
88 """
89 Returns a string representation of this object, for debugging.
90
91 @rtype: str
92 """
93 return '<paramiko.SecurityOptions for %s>' % repr(self._transport)
94
97
100
103
106
109
110 - def _set(self, name, orig, x):
111 if type(x) is list:
112 x = tuple(x)
113 if type(x) is not tuple:
114 raise TypeError('expected tuple or list')
115 possible = getattr(self._transport, orig).keys()
116 forbidden = filter(lambda n: n not in possible, x)
117 if len(forbidden) > 0:
118 raise ValueError('unknown cipher')
119 setattr(self._transport, name, x)
120
122 self._set('_preferred_ciphers', '_cipher_info', x)
123
125 self._set('_preferred_macs', '_mac_info', x)
126
128 self._set('_preferred_keys', '_key_info', x)
129
131 self._set('_preferred_kex', '_kex_info', x)
132
134 self._set('_preferred_compression', '_compression_info', x)
135
136 ciphers = property(_get_ciphers, _set_ciphers, None,
137 "Symmetric encryption ciphers")
138 digests = property(_get_digests, _set_digests, None,
139 "Digest (one-way hash) algorithms")
140 key_types = property(_get_key_types, _set_key_types, None,
141 "Public-key algorithms")
142 kex = property(_get_kex, _set_kex, None, "Key exchange algorithms")
143 compression = property(_get_compression, _set_compression, None,
144 "Compression algorithms")
145
146
149
150 self._map = weakref.WeakValueDictionary()
151 self._lock = threading.Lock()
152
153 - def put(self, chanid, chan):
154 self._lock.acquire()
155 try:
156 self._map[chanid] = chan
157 finally:
158 self._lock.release()
159
160 - def get(self, chanid):
161 self._lock.acquire()
162 try:
163 return self._map.get(chanid, None)
164 finally:
165 self._lock.release()
166
168 self._lock.acquire()
169 try:
170 try:
171 del self._map[chanid]
172 except KeyError:
173 pass
174 finally:
175 self._lock.release()
176
178 self._lock.acquire()
179 try:
180 return self._map.values()
181 finally:
182 self._lock.release()
183
185 self._lock.acquire()
186 try:
187 return len(self._map)
188 finally:
189 self._lock.release()
190
191
193 """
194 An SSH Transport attaches to a stream (usually a socket), negotiates an
195 encrypted session, authenticates, and then creates stream tunnels, called
196 L{Channel}s, across the session. Multiple channels can be multiplexed
197 across a single session (and often are, in the case of port forwardings).
198 """
199
200 _PROTO_ID = '2.0'
201 _CLIENT_ID = 'paramiko_%s' % (paramiko.__version__)
202
203 _preferred_ciphers = ( 'aes128-ctr', 'aes256-ctr', 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc',
204 'arcfour128', 'arcfour256' )
205 _preferred_macs = ( 'hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96' )
206 _preferred_keys = ( 'ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256' )
207 _preferred_kex = ( 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' )
208 _preferred_compression = ( 'none', )
209
210 _cipher_info = {
211 'aes128-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16 },
212 'aes256-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32 },
213 'blowfish-cbc': { 'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16 },
214 'aes128-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 16 },
215 'aes256-cbc': { 'class': AES, 'mode': AES.MODE_CBC, 'block-size': 16, 'key-size': 32 },
216 '3des-cbc': { 'class': DES3, 'mode': DES3.MODE_CBC, 'block-size': 8, 'key-size': 24 },
217 'arcfour128': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 16 },
218 'arcfour256': { 'class': ARC4, 'mode': None, 'block-size': 8, 'key-size': 32 },
219 }
220
221 _mac_info = {
222 'hmac-sha1': { 'class': SHA, 'size': 20 },
223 'hmac-sha1-96': { 'class': SHA, 'size': 12 },
224 'hmac-md5': { 'class': MD5, 'size': 16 },
225 'hmac-md5-96': { 'class': MD5, 'size': 12 },
226 }
227
228 _key_info = {
229 'ssh-rsa': RSAKey,
230 'ssh-dss': DSSKey,
231 'ecdsa-sha2-nistp256': ECDSAKey,
232 }
233
234 _kex_info = {
235 'diffie-hellman-group1-sha1': KexGroup1,
236 'diffie-hellman-group-exchange-sha1': KexGex,
237 }
238
239 _compression_info = {
240
241
242
243 'zlib@openssh.com': ( ZlibCompressor, ZlibDecompressor ),
244 'zlib': ( ZlibCompressor, ZlibDecompressor ),
245 'none': ( None, None ),
246 }
247
248
249 _modulus_pack = None
250
252 """
253 Create a new SSH session over an existing socket, or socket-like
254 object. This only creates the Transport object; it doesn't begin the
255 SSH session yet. Use L{connect} or L{start_client} to begin a client
256 session, or L{start_server} to begin a server session.
257
258 If the object is not actually a socket, it must have the following
259 methods:
260 - C{send(str)}: Writes from 1 to C{len(str)} bytes, and
261 returns an int representing the number of bytes written. Returns
262 0 or raises C{EOFError} if the stream has been closed.
263 - C{recv(int)}: Reads from 1 to C{int} bytes and returns them as a
264 string. Returns 0 or raises C{EOFError} if the stream has been
265 closed.
266 - C{close()}: Closes the socket.
267 - C{settimeout(n)}: Sets a (float) timeout on I/O operations.
268
269 For ease of use, you may also pass in an address (as a tuple) or a host
270 string as the C{sock} argument. (A host string is a hostname with an
271 optional port (separated by C{":"}) which will be converted into a
272 tuple of C{(hostname, port)}.) A socket will be connected to this
273 address and used for communication. Exceptions from the C{socket} call
274 may be thrown in this case.
275
276 @param sock: a socket or socket-like object to create the session over.
277 @type sock: socket
278 """
279 if isinstance(sock, (str, unicode)):
280
281 hl = sock.split(':', 1)
282 if len(hl) == 1:
283 sock = (hl[0], 22)
284 else:
285 sock = (hl[0], int(hl[1]))
286 if type(sock) is tuple:
287
288 hostname, port = sock
289 reason = 'No suitable address family'
290 for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
291 if socktype == socket.SOCK_STREAM:
292 af = family
293 addr = sockaddr
294 sock = socket.socket(af, socket.SOCK_STREAM)
295 try:
296 retry_on_signal(lambda: sock.connect((hostname, port)))
297 except socket.error, e:
298 reason = str(e)
299 else:
300 break
301 else:
302 raise SSHException(
303 'Unable to connect to %s: %s' % (hostname, reason))
304
305 threading.Thread.__init__(self)
306 self.setDaemon(True)
307 self.rng = rng
308 self.sock = sock
309
310 try:
311
312
313
314 self.sock.settimeout(0.1)
315 except AttributeError:
316 pass
317
318
319 self.packetizer = Packetizer(sock)
320 self.local_version = 'SSH-' + self._PROTO_ID + '-' + self._CLIENT_ID
321 self.remote_version = ''
322 self.local_cipher = self.remote_cipher = ''
323 self.local_kex_init = self.remote_kex_init = None
324 self.local_mac = self.remote_mac = None
325 self.local_compression = self.remote_compression = None
326 self.session_id = None
327 self.host_key_type = None
328 self.host_key = None
329
330
331 self.kex_engine = None
332 self.H = None
333 self.K = None
334
335 self.active = False
336 self.initial_kex_done = False
337 self.in_kex = False
338 self.authenticated = False
339 self._expected_packet = tuple()
340 self.lock = threading.Lock()
341
342
343 self._channels = ChannelMap()
344 self.channel_events = { }
345 self.channels_seen = { }
346 self._channel_counter = 1
347 self.window_size = 65536
348 self.max_packet_size = 34816
349 self._forward_agent_handler = None
350 self._x11_handler = None
351 self._tcp_handler = None
352
353 self.saved_exception = None
354 self.clear_to_send = threading.Event()
355 self.clear_to_send_lock = threading.Lock()
356 self.clear_to_send_timeout = 30.0
357 self.log_name = 'paramiko.transport'
358 self.logger = util.get_logger(self.log_name)
359 self.packetizer.set_log(self.logger)
360 self.auth_handler = None
361 self.global_response = None
362 self.completion_event = None
363 self.banner_timeout = 15
364
365
366 self.server_mode = False
367 self.server_object = None
368 self.server_key_dict = { }
369 self.server_accepts = [ ]
370 self.server_accept_cv = threading.Condition(self.lock)
371 self.subsystem_table = { }
372
374 """
375 Returns a string representation of this object, for debugging.
376
377 @rtype: str
378 """
379 out = '<paramiko.Transport at %s' % hex(long(id(self)) & 0xffffffffL)
380 if not self.active:
381 out += ' (unconnected)'
382 else:
383 if self.local_cipher != '':
384 out += ' (cipher %s, %d bits)' % (self.local_cipher,
385 self._cipher_info[self.local_cipher]['key-size'] * 8)
386 if self.is_authenticated():
387 out += ' (active; %d open channel(s))' % len(self._channels)
388 elif self.initial_kex_done:
389 out += ' (connected; awaiting auth)'
390 else:
391 out += ' (connecting)'
392 out += '>'
393 return out
394
396 """
397 Terminate this Transport without closing the session. On posix
398 systems, if a Transport is open during process forking, both parent
399 and child will share the underlying socket, but only one process can
400 use the connection (without corrupting the session). Use this method
401 to clean up a Transport object without disrupting the other process.
402
403 @since: 1.5.3
404 """
405 self.close()
406
408 """
409 Return a L{SecurityOptions} object which can be used to tweak the
410 encryption algorithms this transport will permit, and the order of
411 preference for them.
412
413 @return: an object that can be used to change the preferred algorithms
414 for encryption, digest (hash), public key, and key exchange.
415 @rtype: L{SecurityOptions}
416 """
417 return SecurityOptions(self)
418
420 """
421 Negotiate a new SSH2 session as a client. This is the first step after
422 creating a new L{Transport}. A separate thread is created for protocol
423 negotiation.
424
425 If an event is passed in, this method returns immediately. When
426 negotiation is done (successful or not), the given C{Event} will
427 be triggered. On failure, L{is_active} will return C{False}.
428
429 (Since 1.4) If C{event} is C{None}, this method will not return until
430 negotation is done. On success, the method returns normally.
431 Otherwise an SSHException is raised.
432
433 After a successful negotiation, you will usually want to authenticate,
434 calling L{auth_password <Transport.auth_password>} or
435 L{auth_publickey <Transport.auth_publickey>}.
436
437 @note: L{connect} is a simpler method for connecting as a client.
438
439 @note: After calling this method (or L{start_server} or L{connect}),
440 you should no longer directly read from or write to the original
441 socket object.
442
443 @param event: an event to trigger when negotiation is complete
444 (optional)
445 @type event: threading.Event
446
447 @raise SSHException: if negotiation fails (and no C{event} was passed
448 in)
449 """
450 self.active = True
451 if event is not None:
452
453 self.completion_event = event
454 self.start()
455 return
456
457
458 self.completion_event = event = threading.Event()
459 self.start()
460 Random.atfork()
461 while True:
462 event.wait(0.1)
463 if not self.active:
464 e = self.get_exception()
465 if e is not None:
466 raise e
467 raise SSHException('Negotiation failed.')
468 if event.isSet():
469 break
470
472 """
473 Negotiate a new SSH2 session as a server. This is the first step after
474 creating a new L{Transport} and setting up your server host key(s). A
475 separate thread is created for protocol negotiation.
476
477 If an event is passed in, this method returns immediately. When
478 negotiation is done (successful or not), the given C{Event} will
479 be triggered. On failure, L{is_active} will return C{False}.
480
481 (Since 1.4) If C{event} is C{None}, this method will not return until
482 negotation is done. On success, the method returns normally.
483 Otherwise an SSHException is raised.
484
485 After a successful negotiation, the client will need to authenticate.
486 Override the methods
487 L{get_allowed_auths <ServerInterface.get_allowed_auths>},
488 L{check_auth_none <ServerInterface.check_auth_none>},
489 L{check_auth_password <ServerInterface.check_auth_password>}, and
490 L{check_auth_publickey <ServerInterface.check_auth_publickey>} in the
491 given C{server} object to control the authentication process.
492
493 After a successful authentication, the client should request to open
494 a channel. Override
495 L{check_channel_request <ServerInterface.check_channel_request>} in the
496 given C{server} object to allow channels to be opened.
497
498 @note: After calling this method (or L{start_client} or L{connect}),
499 you should no longer directly read from or write to the original
500 socket object.
501
502 @param event: an event to trigger when negotiation is complete.
503 @type event: threading.Event
504 @param server: an object used to perform authentication and create
505 L{Channel}s.
506 @type server: L{server.ServerInterface}
507
508 @raise SSHException: if negotiation fails (and no C{event} was passed
509 in)
510 """
511 if server is None:
512 server = ServerInterface()
513 self.server_mode = True
514 self.server_object = server
515 self.active = True
516 if event is not None:
517
518 self.completion_event = event
519 self.start()
520 return
521
522
523 self.completion_event = event = threading.Event()
524 self.start()
525 while True:
526 event.wait(0.1)
527 if not self.active:
528 e = self.get_exception()
529 if e is not None:
530 raise e
531 raise SSHException('Negotiation failed.')
532 if event.isSet():
533 break
534
536 """
537 Add a host key to the list of keys used for server mode. When behaving
538 as a server, the host key is used to sign certain packets during the
539 SSH2 negotiation, so that the client can trust that we are who we say
540 we are. Because this is used for signing, the key must contain private
541 key info, not just the public half. Only one key of each type (RSA or
542 DSS) is kept.
543
544 @param key: the host key to add, usually an L{RSAKey <rsakey.RSAKey>} or
545 L{DSSKey <dsskey.DSSKey>}.
546 @type key: L{PKey <pkey.PKey>}
547 """
548 self.server_key_dict[key.get_name()] = key
549
551 """
552 Return the active host key, in server mode. After negotiating with the
553 client, this method will return the negotiated host key. If only one
554 type of host key was set with L{add_server_key}, that's the only key
555 that will ever be returned. But in cases where you have set more than
556 one type of host key (for example, an RSA key and a DSS key), the key
557 type will be negotiated by the client, and this method will return the
558 key of the type agreed on. If the host key has not been negotiated
559 yet, C{None} is returned. In client mode, the behavior is undefined.
560
561 @return: host key of the type negotiated by the client, or C{None}.
562 @rtype: L{PKey <pkey.PKey>}
563 """
564 try:
565 return self.server_key_dict[self.host_key_type]
566 except KeyError:
567 pass
568 return None
569
571 """
572 I{(optional)}
573 Load a file of prime moduli for use in doing group-exchange key
574 negotiation in server mode. It's a rather obscure option and can be
575 safely ignored.
576
577 In server mode, the remote client may request "group-exchange" key
578 negotiation, which asks the server to send a random prime number that
579 fits certain criteria. These primes are pretty difficult to compute,
580 so they can't be generated on demand. But many systems contain a file
581 of suitable primes (usually named something like C{/etc/ssh/moduli}).
582 If you call C{load_server_moduli} and it returns C{True}, then this
583 file of primes has been loaded and we will support "group-exchange" in
584 server mode. Otherwise server mode will just claim that it doesn't
585 support that method of key negotiation.
586
587 @param filename: optional path to the moduli file, if you happen to
588 know that it's not in a standard location.
589 @type filename: str
590 @return: True if a moduli file was successfully loaded; False
591 otherwise.
592 @rtype: bool
593
594 @note: This has no effect when used in client mode.
595 """
596 Transport._modulus_pack = ModulusPack(rng)
597
598 file_list = [ '/etc/ssh/moduli', '/usr/local/etc/moduli' ]
599 if filename is not None:
600 file_list.insert(0, filename)
601 for fn in file_list:
602 try:
603 Transport._modulus_pack.read_file(fn)
604 return True
605 except IOError:
606 pass
607
608 Transport._modulus_pack = None
609 return False
610 load_server_moduli = staticmethod(load_server_moduli)
611
613 """
614 Close this session, and any open channels that are tied to it.
615 """
616 if not self.active:
617 return
618 self.stop_thread()
619 for chan in self._channels.values():
620 chan._unlink()
621 self.sock.close()
622
624 """
625 Return the host key of the server (in client mode).
626
627 @note: Previously this call returned a tuple of (key type, key string).
628 You can get the same effect by calling
629 L{PKey.get_name <pkey.PKey.get_name>} for the key type, and
630 C{str(key)} for the key string.
631
632 @raise SSHException: if no session is currently active.
633
634 @return: public key of the remote server
635 @rtype: L{PKey <pkey.PKey>}
636 """
637 if (not self.active) or (not self.initial_kex_done):
638 raise SSHException('No existing session')
639 return self.host_key
640
642 """
643 Return true if this session is active (open).
644
645 @return: True if the session is still active (open); False if the
646 session is closed
647 @rtype: bool
648 """
649 return self.active
650
652 """
653 Request a new channel to the server, of type C{"session"}. This
654 is just an alias for C{open_channel('session')}.
655
656 @return: a new L{Channel}
657 @rtype: L{Channel}
658
659 @raise SSHException: if the request is rejected or the session ends
660 prematurely
661 """
662 return self.open_channel('session')
663
665 """
666 Request a new channel to the client, of type C{"x11"}. This
667 is just an alias for C{open_channel('x11', src_addr=src_addr)}.
668
669 @param src_addr: the source address of the x11 server (port is the
670 x11 port, ie. 6010)
671 @type src_addr: (str, int)
672 @return: a new L{Channel}
673 @rtype: L{Channel}
674
675 @raise SSHException: if the request is rejected or the session ends
676 prematurely
677 """
678 return self.open_channel('x11', src_addr=src_addr)
679
681 """
682 Request a new channel to the client, of type
683 C{"auth-agent@openssh.com"}.
684
685 This is just an alias for C{open_channel('auth-agent@openssh.com')}.
686 @return: a new L{Channel}
687 @rtype: L{Channel}
688
689 @raise SSHException: if the request is rejected or the session ends
690 prematurely
691 """
692 return self.open_channel('auth-agent@openssh.com')
693
695 """
696 Request a new channel back to the client, of type C{"forwarded-tcpip"}.
697 This is used after a client has requested port forwarding, for sending
698 incoming connections back to the client.
699
700 @param src_addr: originator's address
701 @param src_port: originator's port
702 @param dest_addr: local (server) connected address
703 @param dest_port: local (server) connected port
704 """
705 return self.open_channel('forwarded-tcpip', (dest_addr, dest_port), (src_addr, src_port))
706
707 - def open_channel(self, kind, dest_addr=None, src_addr=None):
708 """
709 Request a new channel to the server. L{Channel}s are socket-like
710 objects used for the actual transfer of data across the session.
711 You may only request a channel after negotiating encryption (using
712 L{connect} or L{start_client}) and authenticating.
713
714 @param kind: the kind of channel requested (usually C{"session"},
715 C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"})
716 @type kind: str
717 @param dest_addr: the destination address of this port forwarding,
718 if C{kind} is C{"forwarded-tcpip"} or C{"direct-tcpip"} (ignored
719 for other channel types)
720 @type dest_addr: (str, int)
721 @param src_addr: the source address of this port forwarding, if
722 C{kind} is C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"}
723 @type src_addr: (str, int)
724 @return: a new L{Channel} on success
725 @rtype: L{Channel}
726
727 @raise SSHException: if the request is rejected or the session ends
728 prematurely
729 """
730 if not self.active:
731 raise SSHException('SSH session not active')
732 self.lock.acquire()
733 try:
734 chanid = self._next_channel()
735 m = Message()
736 m.add_byte(chr(MSG_CHANNEL_OPEN))
737 m.add_string(kind)
738 m.add_int(chanid)
739 m.add_int(self.window_size)
740 m.add_int(self.max_packet_size)
741 if (kind == 'forwarded-tcpip') or (kind == 'direct-tcpip'):
742 m.add_string(dest_addr[0])
743 m.add_int(dest_addr[1])
744 m.add_string(src_addr[0])
745 m.add_int(src_addr[1])
746 elif kind == 'x11':
747 m.add_string(src_addr[0])
748 m.add_int(src_addr[1])
749 chan = Channel(chanid)
750 self._channels.put(chanid, chan)
751 self.channel_events[chanid] = event = threading.Event()
752 self.channels_seen[chanid] = True
753 chan._set_transport(self)
754 chan._set_window(self.window_size, self.max_packet_size)
755 finally:
756 self.lock.release()
757 self._send_user_message(m)
758 while True:
759 event.wait(0.1);
760 if not self.active:
761 e = self.get_exception()
762 if e is None:
763 e = SSHException('Unable to open channel.')
764 raise e
765 if event.isSet():
766 break
767 chan = self._channels.get(chanid)
768 if chan is not None:
769 return chan
770 e = self.get_exception()
771 if e is None:
772 e = SSHException('Unable to open channel.')
773 raise e
774
776 """
777 Ask the server to forward TCP connections from a listening port on
778 the server, across this SSH session.
779
780 If a handler is given, that handler is called from a different thread
781 whenever a forwarded connection arrives. The handler parameters are::
782
783 handler(channel, (origin_addr, origin_port), (server_addr, server_port))
784
785 where C{server_addr} and C{server_port} are the address and port that
786 the server was listening on.
787
788 If no handler is set, the default behavior is to send new incoming
789 forwarded connections into the accept queue, to be picked up via
790 L{accept}.
791
792 @param address: the address to bind when forwarding
793 @type address: str
794 @param port: the port to forward, or 0 to ask the server to allocate
795 any port
796 @type port: int
797 @param handler: optional handler for incoming forwarded connections
798 @type handler: function(Channel, (str, int), (str, int))
799 @return: the port # allocated by the server
800 @rtype: int
801
802 @raise SSHException: if the server refused the TCP forward request
803 """
804 if not self.active:
805 raise SSHException('SSH session not active')
806 address = str(address)
807 port = int(port)
808 response = self.global_request('tcpip-forward', (address, port), wait=True)
809 if response is None:
810 raise SSHException('TCP forwarding request denied')
811 if port == 0:
812 port = response.get_int()
813 if handler is None:
814 def default_handler(channel, (src_addr, src_port), (dest_addr, dest_port)):
815 self._queue_incoming_channel(channel)
816 handler = default_handler
817 self._tcp_handler = handler
818 return port
819
821 """
822 Ask the server to cancel a previous port-forwarding request. No more
823 connections to the given address & port will be forwarded across this
824 ssh connection.
825
826 @param address: the address to stop forwarding
827 @type address: str
828 @param port: the port to stop forwarding
829 @type port: int
830 """
831 if not self.active:
832 return
833 self._tcp_handler = None
834 self.global_request('cancel-tcpip-forward', (address, port), wait=True)
835
837 """
838 Create an SFTP client channel from an open transport. On success,
839 an SFTP session will be opened with the remote host, and a new
840 SFTPClient object will be returned.
841
842 @return: a new L{SFTPClient} object, referring to an sftp session
843 (channel) across this transport
844 @rtype: L{SFTPClient}
845 """
846 return SFTPClient.from_transport(self)
847
849 """
850 Send a junk packet across the encrypted link. This is sometimes used
851 to add "noise" to a connection to confuse would-be attackers. It can
852 also be used as a keep-alive for long lived connections traversing
853 firewalls.
854
855 @param bytes: the number of random bytes to send in the payload of the
856 ignored packet -- defaults to a random number from 10 to 41.
857 @type bytes: int
858 """
859 m = Message()
860 m.add_byte(chr(MSG_IGNORE))
861 if bytes is None:
862 bytes = (ord(rng.read(1)) % 32) + 10
863 m.add_bytes(rng.read(bytes))
864 self._send_user_message(m)
865
867 """
868 Force this session to switch to new keys. Normally this is done
869 automatically after the session hits a certain number of packets or
870 bytes sent or received, but this method gives you the option of forcing
871 new keys whenever you want. Negotiating new keys causes a pause in
872 traffic both ways as the two sides swap keys and do computations. This
873 method returns when the session has switched to new keys.
874
875 @raise SSHException: if the key renegotiation failed (which causes the
876 session to end)
877 """
878 self.completion_event = threading.Event()
879 self._send_kex_init()
880 while True:
881 self.completion_event.wait(0.1)
882 if not self.active:
883 e = self.get_exception()
884 if e is not None:
885 raise e
886 raise SSHException('Negotiation failed.')
887 if self.completion_event.isSet():
888 break
889 return
890
892 """
893 Turn on/off keepalive packets (default is off). If this is set, after
894 C{interval} seconds without sending any data over the connection, a
895 "keepalive" packet will be sent (and ignored by the remote host). This
896 can be useful to keep connections alive over a NAT, for example.
897
898 @param interval: seconds to wait before sending a keepalive packet (or
899 0 to disable keepalives).
900 @type interval: int
901 """
902 self.packetizer.set_keepalive(interval,
903 lambda x=weakref.proxy(self): x.global_request('keepalive@lag.net', wait=False))
904
906 """
907 Make a global request to the remote host. These are normally
908 extensions to the SSH2 protocol.
909
910 @param kind: name of the request.
911 @type kind: str
912 @param data: an optional tuple containing additional data to attach
913 to the request.
914 @type data: tuple
915 @param wait: C{True} if this method should not return until a response
916 is received; C{False} otherwise.
917 @type wait: bool
918 @return: a L{Message} containing possible additional data if the
919 request was successful (or an empty L{Message} if C{wait} was
920 C{False}); C{None} if the request was denied.
921 @rtype: L{Message}
922 """
923 if wait:
924 self.completion_event = threading.Event()
925 m = Message()
926 m.add_byte(chr(MSG_GLOBAL_REQUEST))
927 m.add_string(kind)
928 m.add_boolean(wait)
929 if data is not None:
930 m.add(*data)
931 self._log(DEBUG, 'Sending global request "%s"' % kind)
932 self._send_user_message(m)
933 if not wait:
934 return None
935 while True:
936 self.completion_event.wait(0.1)
937 if not self.active:
938 return None
939 if self.completion_event.isSet():
940 break
941 return self.global_response
942
943 - def accept(self, timeout=None):
944 """
945 Return the next channel opened by the client over this transport, in
946 server mode. If no channel is opened before the given timeout, C{None}
947 is returned.
948
949 @param timeout: seconds to wait for a channel, or C{None} to wait
950 forever
951 @type timeout: int
952 @return: a new Channel opened by the client
953 @rtype: L{Channel}
954 """
955 self.lock.acquire()
956 try:
957 if len(self.server_accepts) > 0:
958 chan = self.server_accepts.pop(0)
959 else:
960 self.server_accept_cv.wait(timeout)
961 if len(self.server_accepts) > 0:
962 chan = self.server_accepts.pop(0)
963 else:
964
965 chan = None
966 finally:
967 self.lock.release()
968 return chan
969
970 - def connect(self, hostkey=None, username='', password=None, pkey=None):
971 """
972 Negotiate an SSH2 session, and optionally verify the server's host key
973 and authenticate using a password or private key. This is a shortcut
974 for L{start_client}, L{get_remote_server_key}, and
975 L{Transport.auth_password} or L{Transport.auth_publickey}. Use those
976 methods if you want more control.
977
978 You can use this method immediately after creating a Transport to
979 negotiate encryption with a server. If it fails, an exception will be
980 thrown. On success, the method will return cleanly, and an encrypted
981 session exists. You may immediately call L{open_channel} or
982 L{open_session} to get a L{Channel} object, which is used for data
983 transfer.
984
985 @note: If you fail to supply a password or private key, this method may
986 succeed, but a subsequent L{open_channel} or L{open_session} call may
987 fail because you haven't authenticated yet.
988
989 @param hostkey: the host key expected from the server, or C{None} if
990 you don't want to do host key verification.
991 @type hostkey: L{PKey<pkey.PKey>}
992 @param username: the username to authenticate as.
993 @type username: str
994 @param password: a password to use for authentication, if you want to
995 use password authentication; otherwise C{None}.
996 @type password: str
997 @param pkey: a private key to use for authentication, if you want to
998 use private key authentication; otherwise C{None}.
999 @type pkey: L{PKey<pkey.PKey>}
1000
1001 @raise SSHException: if the SSH2 negotiation fails, the host key
1002 supplied by the server is incorrect, or authentication fails.
1003 """
1004 if hostkey is not None:
1005 self._preferred_keys = [ hostkey.get_name() ]
1006
1007 self.start_client()
1008
1009
1010 if (hostkey is not None):
1011 key = self.get_remote_server_key()
1012 if (key.get_name() != hostkey.get_name()) or (str(key) != str(hostkey)):
1013 self._log(DEBUG, 'Bad host key from server')
1014 self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(str(hostkey))))
1015 self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(str(key))))
1016 raise SSHException('Bad host key from server')
1017 self._log(DEBUG, 'Host key verified (%s)' % hostkey.get_name())
1018
1019 if (pkey is not None) or (password is not None):
1020 if password is not None:
1021 self._log(DEBUG, 'Attempting password auth...')
1022 self.auth_password(username, password)
1023 else:
1024 self._log(DEBUG, 'Attempting public-key auth...')
1025 self.auth_publickey(username, pkey)
1026
1027 return
1028
1030 """
1031 Return any exception that happened during the last server request.
1032 This can be used to fetch more specific error information after using
1033 calls like L{start_client}. The exception (if any) is cleared after
1034 this call.
1035
1036 @return: an exception, or C{None} if there is no stored exception.
1037 @rtype: Exception
1038
1039 @since: 1.1
1040 """
1041 self.lock.acquire()
1042 try:
1043 e = self.saved_exception
1044 self.saved_exception = None
1045 return e
1046 finally:
1047 self.lock.release()
1048
1050 """
1051 Set the handler class for a subsystem in server mode. If a request
1052 for this subsystem is made on an open ssh channel later, this handler
1053 will be constructed and called -- see L{SubsystemHandler} for more
1054 detailed documentation.
1055
1056 Any extra parameters (including keyword arguments) are saved and
1057 passed to the L{SubsystemHandler} constructor later.
1058
1059 @param name: name of the subsystem.
1060 @type name: str
1061 @param handler: subclass of L{SubsystemHandler} that handles this
1062 subsystem.
1063 @type handler: class
1064 """
1065 try:
1066 self.lock.acquire()
1067 self.subsystem_table[name] = (handler, larg, kwarg)
1068 finally:
1069 self.lock.release()
1070
1072 """
1073 Return true if this session is active and authenticated.
1074
1075 @return: True if the session is still open and has been authenticated
1076 successfully; False if authentication failed and/or the session is
1077 closed.
1078 @rtype: bool
1079 """
1080 return self.active and (self.auth_handler is not None) and self.auth_handler.is_authenticated()
1081
1083 """
1084 Return the username this connection is authenticated for. If the
1085 session is not authenticated (or authentication failed), this method
1086 returns C{None}.
1087
1088 @return: username that was authenticated, or C{None}.
1089 @rtype: string
1090 """
1091 if not self.active or (self.auth_handler is None):
1092 return None
1093 return self.auth_handler.get_username()
1094
1096 """
1097 Try to authenticate to the server using no authentication at all.
1098 This will almost always fail. It may be useful for determining the
1099 list of authentication types supported by the server, by catching the
1100 L{BadAuthenticationType} exception raised.
1101
1102 @param username: the username to authenticate as
1103 @type username: string
1104 @return: list of auth types permissible for the next stage of
1105 authentication (normally empty)
1106 @rtype: list
1107
1108 @raise BadAuthenticationType: if "none" authentication isn't allowed
1109 by the server for this user
1110 @raise SSHException: if the authentication failed due to a network
1111 error
1112
1113 @since: 1.5
1114 """
1115 if (not self.active) or (not self.initial_kex_done):
1116 raise SSHException('No existing session')
1117 my_event = threading.Event()
1118 self.auth_handler = AuthHandler(self)
1119 self.auth_handler.auth_none(username, my_event)
1120 return self.auth_handler.wait_for_response(my_event)
1121
1122 - def auth_password(self, username, password, event=None, fallback=True):
1123 """
1124 Authenticate to the server using a password. The username and password
1125 are sent over an encrypted link.
1126
1127 If an C{event} is passed in, this method will return immediately, and
1128 the event will be triggered once authentication succeeds or fails. On
1129 success, L{is_authenticated} will return C{True}. On failure, you may
1130 use L{get_exception} to get more detailed error information.
1131
1132 Since 1.1, if no event is passed, this method will block until the
1133 authentication succeeds or fails. On failure, an exception is raised.
1134 Otherwise, the method simply returns.
1135
1136 Since 1.5, if no event is passed and C{fallback} is C{True} (the
1137 default), if the server doesn't support plain password authentication
1138 but does support so-called "keyboard-interactive" mode, an attempt
1139 will be made to authenticate using this interactive mode. If it fails,
1140 the normal exception will be thrown as if the attempt had never been
1141 made. This is useful for some recent Gentoo and Debian distributions,
1142 which turn off plain password authentication in a misguided belief
1143 that interactive authentication is "more secure". (It's not.)
1144
1145 If the server requires multi-step authentication (which is very rare),
1146 this method will return a list of auth types permissible for the next
1147 step. Otherwise, in the normal case, an empty list is returned.
1148
1149 @param username: the username to authenticate as
1150 @type username: str
1151 @param password: the password to authenticate with
1152 @type password: str or unicode
1153 @param event: an event to trigger when the authentication attempt is
1154 complete (whether it was successful or not)
1155 @type event: threading.Event
1156 @param fallback: C{True} if an attempt at an automated "interactive"
1157 password auth should be made if the server doesn't support normal
1158 password auth
1159 @type fallback: bool
1160 @return: list of auth types permissible for the next stage of
1161 authentication (normally empty)
1162 @rtype: list
1163
1164 @raise BadAuthenticationType: if password authentication isn't
1165 allowed by the server for this user (and no event was passed in)
1166 @raise AuthenticationException: if the authentication failed (and no
1167 event was passed in)
1168 @raise SSHException: if there was a network error
1169 """
1170 if (not self.active) or (not self.initial_kex_done):
1171
1172 raise SSHException('No existing session')
1173 if event is None:
1174 my_event = threading.Event()
1175 else:
1176 my_event = event
1177 self.auth_handler = AuthHandler(self)
1178 self.auth_handler.auth_password(username, password, my_event)
1179 if event is not None:
1180
1181 return []
1182 try:
1183 return self.auth_handler.wait_for_response(my_event)
1184 except BadAuthenticationType, x:
1185
1186 if not fallback or ('keyboard-interactive' not in x.allowed_types):
1187 raise
1188 try:
1189 def handler(title, instructions, fields):
1190 if len(fields) > 1:
1191 raise SSHException('Fallback authentication failed.')
1192 if len(fields) == 0:
1193
1194
1195
1196
1197 return []
1198 return [ password ]
1199 return self.auth_interactive(username, handler)
1200 except SSHException, ignored:
1201
1202 raise x
1203 return None
1204
1206 """
1207 Authenticate to the server using a private key. The key is used to
1208 sign data from the server, so it must include the private part.
1209
1210 If an C{event} is passed in, this method will return immediately, and
1211 the event will be triggered once authentication succeeds or fails. On
1212 success, L{is_authenticated} will return C{True}. On failure, you may
1213 use L{get_exception} to get more detailed error information.
1214
1215 Since 1.1, if no event is passed, this method will block until the
1216 authentication succeeds or fails. On failure, an exception is raised.
1217 Otherwise, the method simply returns.
1218
1219 If the server requires multi-step authentication (which is very rare),
1220 this method will return a list of auth types permissible for the next
1221 step. Otherwise, in the normal case, an empty list is returned.
1222
1223 @param username: the username to authenticate as
1224 @type username: string
1225 @param key: the private key to authenticate with
1226 @type key: L{PKey <pkey.PKey>}
1227 @param event: an event to trigger when the authentication attempt is
1228 complete (whether it was successful or not)
1229 @type event: threading.Event
1230 @return: list of auth types permissible for the next stage of
1231 authentication (normally empty)
1232 @rtype: list
1233
1234 @raise BadAuthenticationType: if public-key authentication isn't
1235 allowed by the server for this user (and no event was passed in)
1236 @raise AuthenticationException: if the authentication failed (and no
1237 event was passed in)
1238 @raise SSHException: if there was a network error
1239 """
1240 if (not self.active) or (not self.initial_kex_done):
1241
1242 raise SSHException('No existing session')
1243 if event is None:
1244 my_event = threading.Event()
1245 else:
1246 my_event = event
1247 self.auth_handler = AuthHandler(self)
1248 self.auth_handler.auth_publickey(username, key, my_event)
1249 if event is not None:
1250
1251 return []
1252 return self.auth_handler.wait_for_response(my_event)
1253
1255 """
1256 Authenticate to the server interactively. A handler is used to answer
1257 arbitrary questions from the server. On many servers, this is just a
1258 dumb wrapper around PAM.
1259
1260 This method will block until the authentication succeeds or fails,
1261 peroidically calling the handler asynchronously to get answers to
1262 authentication questions. The handler may be called more than once
1263 if the server continues to ask questions.
1264
1265 The handler is expected to be a callable that will handle calls of the
1266 form: C{handler(title, instructions, prompt_list)}. The C{title} is
1267 meant to be a dialog-window title, and the C{instructions} are user
1268 instructions (both are strings). C{prompt_list} will be a list of
1269 prompts, each prompt being a tuple of C{(str, bool)}. The string is
1270 the prompt and the boolean indicates whether the user text should be
1271 echoed.
1272
1273 A sample call would thus be:
1274 C{handler('title', 'instructions', [('Password:', False)])}.
1275
1276 The handler should return a list or tuple of answers to the server's
1277 questions.
1278
1279 If the server requires multi-step authentication (which is very rare),
1280 this method will return a list of auth types permissible for the next
1281 step. Otherwise, in the normal case, an empty list is returned.
1282
1283 @param username: the username to authenticate as
1284 @type username: string
1285 @param handler: a handler for responding to server questions
1286 @type handler: callable
1287 @param submethods: a string list of desired submethods (optional)
1288 @type submethods: str
1289 @return: list of auth types permissible for the next stage of
1290 authentication (normally empty).
1291 @rtype: list
1292
1293 @raise BadAuthenticationType: if public-key authentication isn't
1294 allowed by the server for this user
1295 @raise AuthenticationException: if the authentication failed
1296 @raise SSHException: if there was a network error
1297
1298 @since: 1.5
1299 """
1300 if (not self.active) or (not self.initial_kex_done):
1301
1302 raise SSHException('No existing session')
1303 my_event = threading.Event()
1304 self.auth_handler = AuthHandler(self)
1305 self.auth_handler.auth_interactive(username, handler, my_event, submethods)
1306 return self.auth_handler.wait_for_response(my_event)
1307
1309 """
1310 Set the channel for this transport's logging. The default is
1311 C{"paramiko.transport"} but it can be set to anything you want.
1312 (See the C{logging} module for more info.) SSH Channels will log
1313 to a sub-channel of the one specified.
1314
1315 @param name: new channel name for logging
1316 @type name: str
1317
1318 @since: 1.1
1319 """
1320 self.log_name = name
1321 self.logger = util.get_logger(name)
1322 self.packetizer.set_log(self.logger)
1323
1325 """
1326 Return the channel name used for this transport's logging.
1327
1328 @return: channel name.
1329 @rtype: str
1330
1331 @since: 1.2
1332 """
1333 return self.log_name
1334
1336 """
1337 Turn on/off logging a hex dump of protocol traffic at DEBUG level in
1338 the logs. Normally you would want this off (which is the default),
1339 but if you are debugging something, it may be useful.
1340
1341 @param hexdump: C{True} to log protocol traffix (in hex) to the log;
1342 C{False} otherwise.
1343 @type hexdump: bool
1344 """
1345 self.packetizer.set_hexdump(hexdump)
1346
1348 """
1349 Return C{True} if the transport is currently logging hex dumps of
1350 protocol traffic.
1351
1352 @return: C{True} if hex dumps are being logged
1353 @rtype: bool
1354
1355 @since: 1.4
1356 """
1357 return self.packetizer.get_hexdump()
1358
1360 """
1361 Turn on/off compression. This will only have an affect before starting
1362 the transport (ie before calling L{connect}, etc). By default,
1363 compression is off since it negatively affects interactive sessions.
1364
1365 @param compress: C{True} to ask the remote client/server to compress
1366 traffic; C{False} to refuse compression
1367 @type compress: bool
1368
1369 @since: 1.5.2
1370 """
1371 if compress:
1372 self._preferred_compression = ( 'zlib@openssh.com', 'zlib', 'none' )
1373 else:
1374 self._preferred_compression = ( 'none', )
1375
1377 """
1378 Return the address of the remote side of this Transport, if possible.
1379 This is effectively a wrapper around C{'getpeername'} on the underlying
1380 socket. If the socket-like object has no C{'getpeername'} method,
1381 then C{("unknown", 0)} is returned.
1382
1383 @return: the address if the remote host, if known
1384 @rtype: tuple(str, int)
1385 """
1386 gp = getattr(self.sock, 'getpeername', None)
1387 if gp is None:
1388 return ('unknown', 0)
1389 return gp()
1390
1392 self.active = False
1393 self.packetizer.close()
1394 while self.isAlive():
1395 self.join(10)
1396
1397
1398
1399
1400
1401 - def _log(self, level, msg, *args):
1402 if issubclass(type(msg), list):
1403 for m in msg:
1404 self.logger.log(level, m)
1405 else:
1406 self.logger.log(level, msg, *args)
1407
1409 "used by KexGex to find primes for group exchange"
1410 return self._modulus_pack
1411
1413 "you are holding the lock"
1414 chanid = self._channel_counter
1415 while self._channels.get(chanid) is not None:
1416 self._channel_counter = (self._channel_counter + 1) & 0xffffff
1417 chanid = self._channel_counter
1418 self._channel_counter = (self._channel_counter + 1) & 0xffffff
1419 return chanid
1420
1422 "used by a Channel to remove itself from the active channel list"
1423 self._channels.delete(chanid)
1424
1426 self.packetizer.send_message(data)
1427
1429 """
1430 send a message, but block if we're in key negotiation. this is used
1431 for user-initiated requests.
1432 """
1433 start = time.time()
1434 while True:
1435 self.clear_to_send.wait(0.1)
1436 if not self.active:
1437 self._log(DEBUG, 'Dropping user packet because connection is dead.')
1438 return
1439 self.clear_to_send_lock.acquire()
1440 if self.clear_to_send.isSet():
1441 break
1442 self.clear_to_send_lock.release()
1443 if time.time() > start + self.clear_to_send_timeout:
1444 raise SSHException('Key-exchange timed out waiting for key negotiation')
1445 try:
1446 self._send_message(data)
1447 finally:
1448 self.clear_to_send_lock.release()
1449
1451 "used by a kex object to set the K (root key) and H (exchange hash)"
1452 self.K = k
1453 self.H = h
1454 if self.session_id == None:
1455 self.session_id = h
1456
1458 "used by a kex object to register the next packet type it expects to see"
1459 self._expected_packet = tuple(ptypes)
1460
1468
1470 "id is 'A' - 'F' for the various keys used by ssh"
1471 m = Message()
1472 m.add_mpint(self.K)
1473 m.add_bytes(self.H)
1474 m.add_byte(id)
1475 m.add_bytes(self.session_id)
1476 out = sofar = SHA.new(str(m)).digest()
1477 while len(out) < nbytes:
1478 m = Message()
1479 m.add_mpint(self.K)
1480 m.add_bytes(self.H)
1481 m.add_bytes(sofar)
1482 digest = SHA.new(str(m)).digest()
1483 out += digest
1484 sofar += digest
1485 return out[:nbytes]
1486
1503
1505 if handler is None:
1506 def default_handler(channel):
1507 self._queue_incoming_channel(channel)
1508 self._forward_agent_handler = default_handler
1509 else:
1510 self._forward_agent_handler = handler
1511
1513
1514 if handler is None:
1515
1516 def default_handler(channel, (src_addr, src_port)):
1517 self._queue_incoming_channel(channel)
1518 self._x11_handler = default_handler
1519 else:
1520 self._x11_handler = handler
1521
1523 self.lock.acquire()
1524 try:
1525 self.server_accepts.append(channel)
1526 self.server_accept_cv.notify()
1527 finally:
1528 self.lock.release()
1529
1531
1532
1533
1534
1535
1536
1537
1538 self.sys = sys
1539
1540
1541
1542 Random.atfork()
1543
1544
1545
1546 self.sys = sys
1547
1548
1549 _active_threads.append(self)
1550 if self.server_mode:
1551 self._log(DEBUG, 'starting thread (server mode): %s' % hex(long(id(self)) & 0xffffffffL))
1552 else:
1553 self._log(DEBUG, 'starting thread (client mode): %s' % hex(long(id(self)) & 0xffffffffL))
1554 try:
1555 try:
1556 self.packetizer.write_all(self.local_version + '\r\n')
1557 self._check_banner()
1558 self._send_kex_init()
1559 self._expect_packet(MSG_KEXINIT)
1560
1561 while self.active:
1562 if self.packetizer.need_rekey() and not self.in_kex:
1563 self._send_kex_init()
1564 try:
1565 ptype, m = self.packetizer.read_message()
1566 except NeedRekeyException:
1567 continue
1568 if ptype == MSG_IGNORE:
1569 continue
1570 elif ptype == MSG_DISCONNECT:
1571 self._parse_disconnect(m)
1572 self.active = False
1573 self.packetizer.close()
1574 break
1575 elif ptype == MSG_DEBUG:
1576 self._parse_debug(m)
1577 continue
1578 if len(self._expected_packet) > 0:
1579 if ptype not in self._expected_packet:
1580 raise SSHException('Expecting packet from %r, got %d' % (self._expected_packet, ptype))
1581 self._expected_packet = tuple()
1582 if (ptype >= 30) and (ptype <= 39):
1583 self.kex_engine.parse_next(ptype, m)
1584 continue
1585
1586 if ptype in self._handler_table:
1587 self._handler_table[ptype](self, m)
1588 elif ptype in self._channel_handler_table:
1589 chanid = m.get_int()
1590 chan = self._channels.get(chanid)
1591 if chan is not None:
1592 self._channel_handler_table[ptype](chan, m)
1593 elif chanid in self.channels_seen:
1594 self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid)
1595 else:
1596 self._log(ERROR, 'Channel request for unknown channel %d' % chanid)
1597 self.active = False
1598 self.packetizer.close()
1599 elif (self.auth_handler is not None) and (ptype in self.auth_handler._handler_table):
1600 self.auth_handler._handler_table[ptype](self.auth_handler, m)
1601 else:
1602 self._log(WARNING, 'Oops, unhandled type %d' % ptype)
1603 msg = Message()
1604 msg.add_byte(chr(MSG_UNIMPLEMENTED))
1605 msg.add_int(m.seqno)
1606 self._send_message(msg)
1607 except SSHException, e:
1608 self._log(ERROR, 'Exception: ' + str(e))
1609 self._log(ERROR, util.tb_strings())
1610 self.saved_exception = e
1611 except EOFError, e:
1612 self._log(DEBUG, 'EOF in transport thread')
1613
1614 self.saved_exception = e
1615 except socket.error, e:
1616 if type(e.args) is tuple:
1617 emsg = '%s (%d)' % (e.args[1], e.args[0])
1618 else:
1619 emsg = e.args
1620 self._log(ERROR, 'Socket exception: ' + emsg)
1621 self.saved_exception = e
1622 except Exception, e:
1623 self._log(ERROR, 'Unknown exception: ' + str(e))
1624 self._log(ERROR, util.tb_strings())
1625 self.saved_exception = e
1626 _active_threads.remove(self)
1627 for chan in self._channels.values():
1628 chan._unlink()
1629 if self.active:
1630 self.active = False
1631 self.packetizer.close()
1632 if self.completion_event != None:
1633 self.completion_event.set()
1634 if self.auth_handler is not None:
1635 self.auth_handler.abort()
1636 for event in self.channel_events.values():
1637 event.set()
1638 try:
1639 self.lock.acquire()
1640 self.server_accept_cv.notify()
1641 finally:
1642 self.lock.release()
1643 self.sock.close()
1644 except:
1645
1646
1647
1648
1649 if self.sys.modules is not None:
1650 raise
1651
1652
1653
1654
1655
1657
1658 self.clear_to_send_lock.acquire()
1659 try:
1660 self.clear_to_send.clear()
1661 finally:
1662 self.clear_to_send_lock.release()
1663 if self.local_kex_init == None:
1664
1665 self._send_kex_init()
1666 self._parse_kex_init(m)
1667 self.kex_engine.start_kex()
1668
1670
1671 for i in range(100):
1672
1673
1674 if i == 0:
1675 timeout = self.banner_timeout
1676 else:
1677 timeout = 2
1678 try:
1679 buf = self.packetizer.readline(timeout)
1680 except ProxyCommandFailure:
1681 raise
1682 except Exception, x:
1683 raise SSHException('Error reading SSH protocol banner' + str(x))
1684 if buf[:4] == 'SSH-':
1685 break
1686 self._log(DEBUG, 'Banner: ' + buf)
1687 if buf[:4] != 'SSH-':
1688 raise SSHException('Indecipherable protocol version "' + buf + '"')
1689
1690 self.remote_version = buf
1691
1692 comment = ''
1693 i = string.find(buf, ' ')
1694 if i >= 0:
1695 comment = buf[i+1:]
1696 buf = buf[:i]
1697
1698 segs = buf.split('-', 2)
1699 if len(segs) < 3:
1700 raise SSHException('Invalid SSH banner')
1701 version = segs[1]
1702 client = segs[2]
1703 if version != '1.99' and version != '2.0':
1704 raise SSHException('Incompatible version (%s instead of 2.0)' % (version,))
1705 self._log(INFO, 'Connected (version %s, client %s)' % (version, client))
1706
1747
1749 cookie = m.get_bytes(16)
1750 kex_algo_list = m.get_list()
1751 server_key_algo_list = m.get_list()
1752 client_encrypt_algo_list = m.get_list()
1753 server_encrypt_algo_list = m.get_list()
1754 client_mac_algo_list = m.get_list()
1755 server_mac_algo_list = m.get_list()
1756 client_compress_algo_list = m.get_list()
1757 server_compress_algo_list = m.get_list()
1758 client_lang_list = m.get_list()
1759 server_lang_list = m.get_list()
1760 kex_follows = m.get_boolean()
1761 unused = m.get_int()
1762
1763 self._log(DEBUG, 'kex algos:' + str(kex_algo_list) + ' server key:' + str(server_key_algo_list) + \
1764 ' client encrypt:' + str(client_encrypt_algo_list) + \
1765 ' server encrypt:' + str(server_encrypt_algo_list) + \
1766 ' client mac:' + str(client_mac_algo_list) + \
1767 ' server mac:' + str(server_mac_algo_list) + \
1768 ' client compress:' + str(client_compress_algo_list) + \
1769 ' server compress:' + str(server_compress_algo_list) + \
1770 ' client lang:' + str(client_lang_list) + \
1771 ' server lang:' + str(server_lang_list) + \
1772 ' kex follows?' + str(kex_follows))
1773
1774
1775
1776 if self.server_mode:
1777 agreed_kex = filter(self._preferred_kex.__contains__, kex_algo_list)
1778 else:
1779 agreed_kex = filter(kex_algo_list.__contains__, self._preferred_kex)
1780 if len(agreed_kex) == 0:
1781 raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)')
1782 self.kex_engine = self._kex_info[agreed_kex[0]](self)
1783
1784 if self.server_mode:
1785 available_server_keys = filter(self.server_key_dict.keys().__contains__,
1786 self._preferred_keys)
1787 agreed_keys = filter(available_server_keys.__contains__, server_key_algo_list)
1788 else:
1789 agreed_keys = filter(server_key_algo_list.__contains__, self._preferred_keys)
1790 if len(agreed_keys) == 0:
1791 raise SSHException('Incompatible ssh peer (no acceptable host key)')
1792 self.host_key_type = agreed_keys[0]
1793 if self.server_mode and (self.get_server_key() is None):
1794 raise SSHException('Incompatible ssh peer (can\'t match requested host key type)')
1795
1796 if self.server_mode:
1797 agreed_local_ciphers = filter(self._preferred_ciphers.__contains__,
1798 server_encrypt_algo_list)
1799 agreed_remote_ciphers = filter(self._preferred_ciphers.__contains__,
1800 client_encrypt_algo_list)
1801 else:
1802 agreed_local_ciphers = filter(client_encrypt_algo_list.__contains__,
1803 self._preferred_ciphers)
1804 agreed_remote_ciphers = filter(server_encrypt_algo_list.__contains__,
1805 self._preferred_ciphers)
1806 if (len(agreed_local_ciphers) == 0) or (len(agreed_remote_ciphers) == 0):
1807 raise SSHException('Incompatible ssh server (no acceptable ciphers)')
1808 self.local_cipher = agreed_local_ciphers[0]
1809 self.remote_cipher = agreed_remote_ciphers[0]
1810 self._log(DEBUG, 'Ciphers agreed: local=%s, remote=%s' % (self.local_cipher, self.remote_cipher))
1811
1812 if self.server_mode:
1813 agreed_remote_macs = filter(self._preferred_macs.__contains__, client_mac_algo_list)
1814 agreed_local_macs = filter(self._preferred_macs.__contains__, server_mac_algo_list)
1815 else:
1816 agreed_local_macs = filter(client_mac_algo_list.__contains__, self._preferred_macs)
1817 agreed_remote_macs = filter(server_mac_algo_list.__contains__, self._preferred_macs)
1818 if (len(agreed_local_macs) == 0) or (len(agreed_remote_macs) == 0):
1819 raise SSHException('Incompatible ssh server (no acceptable macs)')
1820 self.local_mac = agreed_local_macs[0]
1821 self.remote_mac = agreed_remote_macs[0]
1822
1823 if self.server_mode:
1824 agreed_remote_compression = filter(self._preferred_compression.__contains__, client_compress_algo_list)
1825 agreed_local_compression = filter(self._preferred_compression.__contains__, server_compress_algo_list)
1826 else:
1827 agreed_local_compression = filter(client_compress_algo_list.__contains__, self._preferred_compression)
1828 agreed_remote_compression = filter(server_compress_algo_list.__contains__, self._preferred_compression)
1829 if (len(agreed_local_compression) == 0) or (len(agreed_remote_compression) == 0):
1830 raise SSHException('Incompatible ssh server (no acceptable compression) %r %r %r' % (agreed_local_compression, agreed_remote_compression, self._preferred_compression))
1831 self.local_compression = agreed_local_compression[0]
1832 self.remote_compression = agreed_remote_compression[0]
1833
1834 self._log(DEBUG, 'using kex %s; server key type %s; cipher: local %s, remote %s; mac: local %s, remote %s; compression: local %s, remote %s' %
1835 (agreed_kex[0], self.host_key_type, self.local_cipher, self.remote_cipher, self.local_mac,
1836 self.remote_mac, self.local_compression, self.remote_compression))
1837
1838
1839
1840
1841
1842
1843 self.remote_kex_init = chr(MSG_KEXINIT) + m.get_so_far()
1844
1846 "switch on newly negotiated encryption parameters for inbound traffic"
1847 block_size = self._cipher_info[self.remote_cipher]['block-size']
1848 if self.server_mode:
1849 IV_in = self._compute_key('A', block_size)
1850 key_in = self._compute_key('C', self._cipher_info[self.remote_cipher]['key-size'])
1851 else:
1852 IV_in = self._compute_key('B', block_size)
1853 key_in = self._compute_key('D', self._cipher_info[self.remote_cipher]['key-size'])
1854 engine = self._get_cipher(self.remote_cipher, key_in, IV_in)
1855 mac_size = self._mac_info[self.remote_mac]['size']
1856 mac_engine = self._mac_info[self.remote_mac]['class']
1857
1858
1859 if self.server_mode:
1860 mac_key = self._compute_key('E', mac_engine.digest_size)
1861 else:
1862 mac_key = self._compute_key('F', mac_engine.digest_size)
1863 self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
1864 compress_in = self._compression_info[self.remote_compression][1]
1865 if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
1866 self._log(DEBUG, 'Switching on inbound compression ...')
1867 self.packetizer.set_inbound_compressor(compress_in())
1868
1870 "switch on newly negotiated encryption parameters for outbound traffic"
1871 m = Message()
1872 m.add_byte(chr(MSG_NEWKEYS))
1873 self._send_message(m)
1874 block_size = self._cipher_info[self.local_cipher]['block-size']
1875 if self.server_mode:
1876 IV_out = self._compute_key('B', block_size)
1877 key_out = self._compute_key('D', self._cipher_info[self.local_cipher]['key-size'])
1878 else:
1879 IV_out = self._compute_key('A', block_size)
1880 key_out = self._compute_key('C', self._cipher_info[self.local_cipher]['key-size'])
1881 engine = self._get_cipher(self.local_cipher, key_out, IV_out)
1882 mac_size = self._mac_info[self.local_mac]['size']
1883 mac_engine = self._mac_info[self.local_mac]['class']
1884
1885
1886 if self.server_mode:
1887 mac_key = self._compute_key('F', mac_engine.digest_size)
1888 else:
1889 mac_key = self._compute_key('E', mac_engine.digest_size)
1890 sdctr = self.local_cipher.endswith('-ctr')
1891 self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key, sdctr)
1892 compress_out = self._compression_info[self.local_compression][0]
1893 if (compress_out is not None) and ((self.local_compression != 'zlib@openssh.com') or self.authenticated):
1894 self._log(DEBUG, 'Switching on outbound compression ...')
1895 self.packetizer.set_outbound_compressor(compress_out())
1896 if not self.packetizer.need_rekey():
1897 self.in_kex = False
1898
1899 self._expect_packet(MSG_NEWKEYS)
1900
1902 self.authenticated = True
1903
1904 if self.local_compression == 'zlib@openssh.com':
1905 compress_out = self._compression_info[self.local_compression][0]
1906 self._log(DEBUG, 'Switching on outbound compression ...')
1907 self.packetizer.set_outbound_compressor(compress_out())
1908 if self.remote_compression == 'zlib@openssh.com':
1909 compress_in = self._compression_info[self.remote_compression][1]
1910 self._log(DEBUG, 'Switching on inbound compression ...')
1911 self.packetizer.set_inbound_compressor(compress_in())
1912
1914 self._log(DEBUG, 'Switch to new keys ...')
1915 self._activate_inbound()
1916
1917 self.local_kex_init = self.remote_kex_init = None
1918 self.K = None
1919 self.kex_engine = None
1920 if self.server_mode and (self.auth_handler is None):
1921
1922 self.auth_handler = AuthHandler(self)
1923 if not self.initial_kex_done:
1924
1925 self.initial_kex_done = True
1926
1927 if self.completion_event != None:
1928 self.completion_event.set()
1929
1930 if not self.packetizer.need_rekey():
1931 self.in_kex = False
1932 self.clear_to_send_lock.acquire()
1933 try:
1934 self.clear_to_send.set()
1935 finally:
1936 self.clear_to_send_lock.release()
1937 return
1938
1943
1976
1978 self._log(DEBUG, 'Global request successful.')
1979 self.global_response = m
1980 if self.completion_event is not None:
1981 self.completion_event.set()
1982
1984 self._log(DEBUG, 'Global request denied.')
1985 self.global_response = None
1986 if self.completion_event is not None:
1987 self.completion_event.set()
1988
1990 chanid = m.get_int()
1991 server_chanid = m.get_int()
1992 server_window_size = m.get_int()
1993 server_max_packet_size = m.get_int()
1994 chan = self._channels.get(chanid)
1995 if chan is None:
1996 self._log(WARNING, 'Success for unrequested channel! [??]')
1997 return
1998 self.lock.acquire()
1999 try:
2000 chan._set_remote_channel(server_chanid, server_window_size, server_max_packet_size)
2001 self._log(INFO, 'Secsh channel %d opened.' % chanid)
2002 if chanid in self.channel_events:
2003 self.channel_events[chanid].set()
2004 del self.channel_events[chanid]
2005 finally:
2006 self.lock.release()
2007 return
2008
2010 chanid = m.get_int()
2011 reason = m.get_int()
2012 reason_str = m.get_string()
2013 lang = m.get_string()
2014 reason_text = CONNECTION_FAILED_CODE.get(reason, '(unknown code)')
2015 self._log(INFO, 'Secsh channel %d open FAILED: %s: %s' % (chanid, reason_str, reason_text))
2016 self.lock.acquire()
2017 try:
2018 self.saved_exception = ChannelException(reason, reason_text)
2019 if chanid in self.channel_events:
2020 self._channels.delete(chanid)
2021 if chanid in self.channel_events:
2022 self.channel_events[chanid].set()
2023 del self.channel_events[chanid]
2024 finally:
2025 self.lock.release()
2026 return
2027
2029 kind = m.get_string()
2030 chanid = m.get_int()
2031 initial_window_size = m.get_int()
2032 max_packet_size = m.get_int()
2033 reject = False
2034 if (kind == 'auth-agent@openssh.com') and (self._forward_agent_handler is not None):
2035 self._log(DEBUG, 'Incoming forward agent connection')
2036 self.lock.acquire()
2037 try:
2038 my_chanid = self._next_channel()
2039 finally:
2040 self.lock.release()
2041 elif (kind == 'x11') and (self._x11_handler is not None):
2042 origin_addr = m.get_string()
2043 origin_port = m.get_int()
2044 self._log(DEBUG, 'Incoming x11 connection from %s:%d' % (origin_addr, origin_port))
2045 self.lock.acquire()
2046 try:
2047 my_chanid = self._next_channel()
2048 finally:
2049 self.lock.release()
2050 elif (kind == 'forwarded-tcpip') and (self._tcp_handler is not None):
2051 server_addr = m.get_string()
2052 server_port = m.get_int()
2053 origin_addr = m.get_string()
2054 origin_port = m.get_int()
2055 self._log(DEBUG, 'Incoming tcp forwarded connection from %s:%d' % (origin_addr, origin_port))
2056 self.lock.acquire()
2057 try:
2058 my_chanid = self._next_channel()
2059 finally:
2060 self.lock.release()
2061 elif not self.server_mode:
2062 self._log(DEBUG, 'Rejecting "%s" channel request from server.' % kind)
2063 reject = True
2064 reason = OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
2065 else:
2066 self.lock.acquire()
2067 try:
2068 my_chanid = self._next_channel()
2069 finally:
2070 self.lock.release()
2071 if kind == 'direct-tcpip':
2072
2073 dest_addr = m.get_string()
2074 dest_port = m.get_int()
2075 origin_addr = m.get_string()
2076 origin_port = m.get_int()
2077 reason = self.server_object.check_channel_direct_tcpip_request(
2078 my_chanid, (origin_addr, origin_port),
2079 (dest_addr, dest_port))
2080 else:
2081 reason = self.server_object.check_channel_request(kind, my_chanid)
2082 if reason != OPEN_SUCCEEDED:
2083 self._log(DEBUG, 'Rejecting "%s" channel request from client.' % kind)
2084 reject = True
2085 if reject:
2086 msg = Message()
2087 msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
2088 msg.add_int(chanid)
2089 msg.add_int(reason)
2090 msg.add_string('')
2091 msg.add_string('en')
2092 self._send_message(msg)
2093 return
2094
2095 chan = Channel(my_chanid)
2096 self.lock.acquire()
2097 try:
2098 self._channels.put(my_chanid, chan)
2099 self.channels_seen[my_chanid] = True
2100 chan._set_transport(self)
2101 chan._set_window(self.window_size, self.max_packet_size)
2102 chan._set_remote_channel(chanid, initial_window_size, max_packet_size)
2103 finally:
2104 self.lock.release()
2105 m = Message()
2106 m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
2107 m.add_int(chanid)
2108 m.add_int(my_chanid)
2109 m.add_int(self.window_size)
2110 m.add_int(self.max_packet_size)
2111 self._send_message(m)
2112 self._log(INFO, 'Secsh channel %d (%s) opened.', my_chanid, kind)
2113 if kind == 'auth-agent@openssh.com':
2114 self._forward_agent_handler(chan)
2115 elif kind == 'x11':
2116 self._x11_handler(chan, (origin_addr, origin_port))
2117 elif kind == 'forwarded-tcpip':
2118 chan.origin_addr = (origin_addr, origin_port)
2119 self._tcp_handler(chan, (origin_addr, origin_port), (server_addr, server_port))
2120 else:
2121 self._queue_incoming_channel(chan)
2122
2128
2130 try:
2131 self.lock.acquire()
2132 if name not in self.subsystem_table:
2133 return (None, [], {})
2134 return self.subsystem_table[name]
2135 finally:
2136 self.lock.release()
2137
2138 _handler_table = {
2139 MSG_NEWKEYS: _parse_newkeys,
2140 MSG_GLOBAL_REQUEST: _parse_global_request,
2141 MSG_REQUEST_SUCCESS: _parse_request_success,
2142 MSG_REQUEST_FAILURE: _parse_request_failure,
2143 MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
2144 MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
2145 MSG_CHANNEL_OPEN: _parse_channel_open,
2146 MSG_KEXINIT: _negotiate_keys,
2147 }
2148
2149 _channel_handler_table = {
2150 MSG_CHANNEL_SUCCESS: Channel._request_success,
2151 MSG_CHANNEL_FAILURE: Channel._request_failed,
2152 MSG_CHANNEL_DATA: Channel._feed,
2153 MSG_CHANNEL_EXTENDED_DATA: Channel._feed_extended,
2154 MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
2155 MSG_CHANNEL_REQUEST: Channel._handle_request,
2156 MSG_CHANNEL_EOF: Channel._handle_eof,
2157 MSG_CHANNEL_CLOSE: Channel._handle_close,
2158 }
2159