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 _active_threads.append(self)
1546 if self.server_mode:
1547 self._log(DEBUG, 'starting thread (server mode): %s' % hex(long(id(self)) & 0xffffffffL))
1548 else:
1549 self._log(DEBUG, 'starting thread (client mode): %s' % hex(long(id(self)) & 0xffffffffL))
1550 try:
1551 try:
1552 self.packetizer.write_all(self.local_version + '\r\n')
1553 self._check_banner()
1554 self._send_kex_init()
1555 self._expect_packet(MSG_KEXINIT)
1556
1557 while self.active:
1558 if self.packetizer.need_rekey() and not self.in_kex:
1559 self._send_kex_init()
1560 try:
1561 ptype, m = self.packetizer.read_message()
1562 except NeedRekeyException:
1563 continue
1564 if ptype == MSG_IGNORE:
1565 continue
1566 elif ptype == MSG_DISCONNECT:
1567 self._parse_disconnect(m)
1568 self.active = False
1569 self.packetizer.close()
1570 break
1571 elif ptype == MSG_DEBUG:
1572 self._parse_debug(m)
1573 continue
1574 if len(self._expected_packet) > 0:
1575 if ptype not in self._expected_packet:
1576 raise SSHException('Expecting packet from %r, got %d' % (self._expected_packet, ptype))
1577 self._expected_packet = tuple()
1578 if (ptype >= 30) and (ptype <= 39):
1579 self.kex_engine.parse_next(ptype, m)
1580 continue
1581
1582 if ptype in self._handler_table:
1583 self._handler_table[ptype](self, m)
1584 elif ptype in self._channel_handler_table:
1585 chanid = m.get_int()
1586 chan = self._channels.get(chanid)
1587 if chan is not None:
1588 self._channel_handler_table[ptype](chan, m)
1589 elif chanid in self.channels_seen:
1590 self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid)
1591 else:
1592 self._log(ERROR, 'Channel request for unknown channel %d' % chanid)
1593 self.active = False
1594 self.packetizer.close()
1595 elif (self.auth_handler is not None) and (ptype in self.auth_handler._handler_table):
1596 self.auth_handler._handler_table[ptype](self.auth_handler, m)
1597 else:
1598 self._log(WARNING, 'Oops, unhandled type %d' % ptype)
1599 msg = Message()
1600 msg.add_byte(chr(MSG_UNIMPLEMENTED))
1601 msg.add_int(m.seqno)
1602 self._send_message(msg)
1603 except SSHException, e:
1604 self._log(ERROR, 'Exception: ' + str(e))
1605 self._log(ERROR, util.tb_strings())
1606 self.saved_exception = e
1607 except EOFError, e:
1608 self._log(DEBUG, 'EOF in transport thread')
1609
1610 self.saved_exception = e
1611 except socket.error, e:
1612 if type(e.args) is tuple:
1613 if e.args:
1614 emsg = '%s (%d)' % (e.args[1], e.args[0])
1615 else:
1616 emsg = str(e) or repr(e)
1617 else:
1618 emsg = e.args
1619 self._log(ERROR, 'Socket exception: ' + emsg)
1620 self.saved_exception = e
1621 except Exception, e:
1622 self._log(ERROR, 'Unknown exception: ' + str(e))
1623 self._log(ERROR, util.tb_strings())
1624 self.saved_exception = e
1625 _active_threads.remove(self)
1626 for chan in self._channels.values():
1627 chan._unlink()
1628 if self.active:
1629 self.active = False
1630 self.packetizer.close()
1631 if self.completion_event != None:
1632 self.completion_event.set()
1633 if self.auth_handler is not None:
1634 self.auth_handler.abort()
1635 for event in self.channel_events.values():
1636 event.set()
1637 try:
1638 self.lock.acquire()
1639 self.server_accept_cv.notify()
1640 finally:
1641 self.lock.release()
1642 self.sock.close()
1643 except:
1644
1645
1646
1647
1648 if self.sys.modules is not None:
1649 raise
1650
1651
1652
1653
1654
1656
1657 self.clear_to_send_lock.acquire()
1658 try:
1659 self.clear_to_send.clear()
1660 finally:
1661 self.clear_to_send_lock.release()
1662 if self.local_kex_init == None:
1663
1664 self._send_kex_init()
1665 self._parse_kex_init(m)
1666 self.kex_engine.start_kex()
1667
1669
1670 for i in range(100):
1671
1672
1673 if i == 0:
1674 timeout = self.banner_timeout
1675 else:
1676 timeout = 2
1677 try:
1678 buf = self.packetizer.readline(timeout)
1679 except ProxyCommandFailure:
1680 raise
1681 except Exception, x:
1682 raise SSHException('Error reading SSH protocol banner' + str(x))
1683 if buf[:4] == 'SSH-':
1684 break
1685 self._log(DEBUG, 'Banner: ' + buf)
1686 if buf[:4] != 'SSH-':
1687 raise SSHException('Indecipherable protocol version "' + buf + '"')
1688
1689 self.remote_version = buf
1690
1691 comment = ''
1692 i = string.find(buf, ' ')
1693 if i >= 0:
1694 comment = buf[i+1:]
1695 buf = buf[:i]
1696
1697 segs = buf.split('-', 2)
1698 if len(segs) < 3:
1699 raise SSHException('Invalid SSH banner')
1700 version = segs[1]
1701 client = segs[2]
1702 if version != '1.99' and version != '2.0':
1703 raise SSHException('Incompatible version (%s instead of 2.0)' % (version,))
1704 self._log(INFO, 'Connected (version %s, client %s)' % (version, client))
1705
1746
1748 cookie = m.get_bytes(16)
1749 kex_algo_list = m.get_list()
1750 server_key_algo_list = m.get_list()
1751 client_encrypt_algo_list = m.get_list()
1752 server_encrypt_algo_list = m.get_list()
1753 client_mac_algo_list = m.get_list()
1754 server_mac_algo_list = m.get_list()
1755 client_compress_algo_list = m.get_list()
1756 server_compress_algo_list = m.get_list()
1757 client_lang_list = m.get_list()
1758 server_lang_list = m.get_list()
1759 kex_follows = m.get_boolean()
1760 unused = m.get_int()
1761
1762 self._log(DEBUG, 'kex algos:' + str(kex_algo_list) + ' server key:' + str(server_key_algo_list) + \
1763 ' client encrypt:' + str(client_encrypt_algo_list) + \
1764 ' server encrypt:' + str(server_encrypt_algo_list) + \
1765 ' client mac:' + str(client_mac_algo_list) + \
1766 ' server mac:' + str(server_mac_algo_list) + \
1767 ' client compress:' + str(client_compress_algo_list) + \
1768 ' server compress:' + str(server_compress_algo_list) + \
1769 ' client lang:' + str(client_lang_list) + \
1770 ' server lang:' + str(server_lang_list) + \
1771 ' kex follows?' + str(kex_follows))
1772
1773
1774
1775 if self.server_mode:
1776 agreed_kex = filter(self._preferred_kex.__contains__, kex_algo_list)
1777 else:
1778 agreed_kex = filter(kex_algo_list.__contains__, self._preferred_kex)
1779 if len(agreed_kex) == 0:
1780 raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)')
1781 self.kex_engine = self._kex_info[agreed_kex[0]](self)
1782
1783 if self.server_mode:
1784 available_server_keys = filter(self.server_key_dict.keys().__contains__,
1785 self._preferred_keys)
1786 agreed_keys = filter(available_server_keys.__contains__, server_key_algo_list)
1787 else:
1788 agreed_keys = filter(server_key_algo_list.__contains__, self._preferred_keys)
1789 if len(agreed_keys) == 0:
1790 raise SSHException('Incompatible ssh peer (no acceptable host key)')
1791 self.host_key_type = agreed_keys[0]
1792 if self.server_mode and (self.get_server_key() is None):
1793 raise SSHException('Incompatible ssh peer (can\'t match requested host key type)')
1794
1795 if self.server_mode:
1796 agreed_local_ciphers = filter(self._preferred_ciphers.__contains__,
1797 server_encrypt_algo_list)
1798 agreed_remote_ciphers = filter(self._preferred_ciphers.__contains__,
1799 client_encrypt_algo_list)
1800 else:
1801 agreed_local_ciphers = filter(client_encrypt_algo_list.__contains__,
1802 self._preferred_ciphers)
1803 agreed_remote_ciphers = filter(server_encrypt_algo_list.__contains__,
1804 self._preferred_ciphers)
1805 if (len(agreed_local_ciphers) == 0) or (len(agreed_remote_ciphers) == 0):
1806 raise SSHException('Incompatible ssh server (no acceptable ciphers)')
1807 self.local_cipher = agreed_local_ciphers[0]
1808 self.remote_cipher = agreed_remote_ciphers[0]
1809 self._log(DEBUG, 'Ciphers agreed: local=%s, remote=%s' % (self.local_cipher, self.remote_cipher))
1810
1811 if self.server_mode:
1812 agreed_remote_macs = filter(self._preferred_macs.__contains__, client_mac_algo_list)
1813 agreed_local_macs = filter(self._preferred_macs.__contains__, server_mac_algo_list)
1814 else:
1815 agreed_local_macs = filter(client_mac_algo_list.__contains__, self._preferred_macs)
1816 agreed_remote_macs = filter(server_mac_algo_list.__contains__, self._preferred_macs)
1817 if (len(agreed_local_macs) == 0) or (len(agreed_remote_macs) == 0):
1818 raise SSHException('Incompatible ssh server (no acceptable macs)')
1819 self.local_mac = agreed_local_macs[0]
1820 self.remote_mac = agreed_remote_macs[0]
1821
1822 if self.server_mode:
1823 agreed_remote_compression = filter(self._preferred_compression.__contains__, client_compress_algo_list)
1824 agreed_local_compression = filter(self._preferred_compression.__contains__, server_compress_algo_list)
1825 else:
1826 agreed_local_compression = filter(client_compress_algo_list.__contains__, self._preferred_compression)
1827 agreed_remote_compression = filter(server_compress_algo_list.__contains__, self._preferred_compression)
1828 if (len(agreed_local_compression) == 0) or (len(agreed_remote_compression) == 0):
1829 raise SSHException('Incompatible ssh server (no acceptable compression) %r %r %r' % (agreed_local_compression, agreed_remote_compression, self._preferred_compression))
1830 self.local_compression = agreed_local_compression[0]
1831 self.remote_compression = agreed_remote_compression[0]
1832
1833 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' %
1834 (agreed_kex[0], self.host_key_type, self.local_cipher, self.remote_cipher, self.local_mac,
1835 self.remote_mac, self.local_compression, self.remote_compression))
1836
1837
1838
1839
1840
1841
1842 self.remote_kex_init = chr(MSG_KEXINIT) + m.get_so_far()
1843
1845 "switch on newly negotiated encryption parameters for inbound traffic"
1846 block_size = self._cipher_info[self.remote_cipher]['block-size']
1847 if self.server_mode:
1848 IV_in = self._compute_key('A', block_size)
1849 key_in = self._compute_key('C', self._cipher_info[self.remote_cipher]['key-size'])
1850 else:
1851 IV_in = self._compute_key('B', block_size)
1852 key_in = self._compute_key('D', self._cipher_info[self.remote_cipher]['key-size'])
1853 engine = self._get_cipher(self.remote_cipher, key_in, IV_in)
1854 mac_size = self._mac_info[self.remote_mac]['size']
1855 mac_engine = self._mac_info[self.remote_mac]['class']
1856
1857
1858 if self.server_mode:
1859 mac_key = self._compute_key('E', mac_engine.digest_size)
1860 else:
1861 mac_key = self._compute_key('F', mac_engine.digest_size)
1862 self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
1863 compress_in = self._compression_info[self.remote_compression][1]
1864 if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
1865 self._log(DEBUG, 'Switching on inbound compression ...')
1866 self.packetizer.set_inbound_compressor(compress_in())
1867
1869 "switch on newly negotiated encryption parameters for outbound traffic"
1870 m = Message()
1871 m.add_byte(chr(MSG_NEWKEYS))
1872 self._send_message(m)
1873 block_size = self._cipher_info[self.local_cipher]['block-size']
1874 if self.server_mode:
1875 IV_out = self._compute_key('B', block_size)
1876 key_out = self._compute_key('D', self._cipher_info[self.local_cipher]['key-size'])
1877 else:
1878 IV_out = self._compute_key('A', block_size)
1879 key_out = self._compute_key('C', self._cipher_info[self.local_cipher]['key-size'])
1880 engine = self._get_cipher(self.local_cipher, key_out, IV_out)
1881 mac_size = self._mac_info[self.local_mac]['size']
1882 mac_engine = self._mac_info[self.local_mac]['class']
1883
1884
1885 if self.server_mode:
1886 mac_key = self._compute_key('F', mac_engine.digest_size)
1887 else:
1888 mac_key = self._compute_key('E', mac_engine.digest_size)
1889 sdctr = self.local_cipher.endswith('-ctr')
1890 self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key, sdctr)
1891 compress_out = self._compression_info[self.local_compression][0]
1892 if (compress_out is not None) and ((self.local_compression != 'zlib@openssh.com') or self.authenticated):
1893 self._log(DEBUG, 'Switching on outbound compression ...')
1894 self.packetizer.set_outbound_compressor(compress_out())
1895 if not self.packetizer.need_rekey():
1896 self.in_kex = False
1897
1898 self._expect_packet(MSG_NEWKEYS)
1899
1901 self.authenticated = True
1902
1903 if self.local_compression == 'zlib@openssh.com':
1904 compress_out = self._compression_info[self.local_compression][0]
1905 self._log(DEBUG, 'Switching on outbound compression ...')
1906 self.packetizer.set_outbound_compressor(compress_out())
1907 if self.remote_compression == 'zlib@openssh.com':
1908 compress_in = self._compression_info[self.remote_compression][1]
1909 self._log(DEBUG, 'Switching on inbound compression ...')
1910 self.packetizer.set_inbound_compressor(compress_in())
1911
1913 self._log(DEBUG, 'Switch to new keys ...')
1914 self._activate_inbound()
1915
1916 self.local_kex_init = self.remote_kex_init = None
1917 self.K = None
1918 self.kex_engine = None
1919 if self.server_mode and (self.auth_handler is None):
1920
1921 self.auth_handler = AuthHandler(self)
1922 if not self.initial_kex_done:
1923
1924 self.initial_kex_done = True
1925
1926 if self.completion_event != None:
1927 self.completion_event.set()
1928
1929 if not self.packetizer.need_rekey():
1930 self.in_kex = False
1931 self.clear_to_send_lock.acquire()
1932 try:
1933 self.clear_to_send.set()
1934 finally:
1935 self.clear_to_send_lock.release()
1936 return
1937
1942
1975
1977 self._log(DEBUG, 'Global request successful.')
1978 self.global_response = m
1979 if self.completion_event is not None:
1980 self.completion_event.set()
1981
1983 self._log(DEBUG, 'Global request denied.')
1984 self.global_response = None
1985 if self.completion_event is not None:
1986 self.completion_event.set()
1987
1989 chanid = m.get_int()
1990 server_chanid = m.get_int()
1991 server_window_size = m.get_int()
1992 server_max_packet_size = m.get_int()
1993 chan = self._channels.get(chanid)
1994 if chan is None:
1995 self._log(WARNING, 'Success for unrequested channel! [??]')
1996 return
1997 self.lock.acquire()
1998 try:
1999 chan._set_remote_channel(server_chanid, server_window_size, server_max_packet_size)
2000 self._log(INFO, 'Secsh channel %d opened.' % chanid)
2001 if chanid in self.channel_events:
2002 self.channel_events[chanid].set()
2003 del self.channel_events[chanid]
2004 finally:
2005 self.lock.release()
2006 return
2007
2009 chanid = m.get_int()
2010 reason = m.get_int()
2011 reason_str = m.get_string()
2012 lang = m.get_string()
2013 reason_text = CONNECTION_FAILED_CODE.get(reason, '(unknown code)')
2014 self._log(INFO, 'Secsh channel %d open FAILED: %s: %s' % (chanid, reason_str, reason_text))
2015 self.lock.acquire()
2016 try:
2017 self.saved_exception = ChannelException(reason, reason_text)
2018 if chanid in self.channel_events:
2019 self._channels.delete(chanid)
2020 if chanid in self.channel_events:
2021 self.channel_events[chanid].set()
2022 del self.channel_events[chanid]
2023 finally:
2024 self.lock.release()
2025 return
2026
2028 kind = m.get_string()
2029 chanid = m.get_int()
2030 initial_window_size = m.get_int()
2031 max_packet_size = m.get_int()
2032 reject = False
2033 if (kind == 'auth-agent@openssh.com') and (self._forward_agent_handler is not None):
2034 self._log(DEBUG, 'Incoming forward agent connection')
2035 self.lock.acquire()
2036 try:
2037 my_chanid = self._next_channel()
2038 finally:
2039 self.lock.release()
2040 elif (kind == 'x11') and (self._x11_handler is not None):
2041 origin_addr = m.get_string()
2042 origin_port = m.get_int()
2043 self._log(DEBUG, 'Incoming x11 connection from %s:%d' % (origin_addr, origin_port))
2044 self.lock.acquire()
2045 try:
2046 my_chanid = self._next_channel()
2047 finally:
2048 self.lock.release()
2049 elif (kind == 'forwarded-tcpip') and (self._tcp_handler is not None):
2050 server_addr = m.get_string()
2051 server_port = m.get_int()
2052 origin_addr = m.get_string()
2053 origin_port = m.get_int()
2054 self._log(DEBUG, 'Incoming tcp forwarded connection from %s:%d' % (origin_addr, origin_port))
2055 self.lock.acquire()
2056 try:
2057 my_chanid = self._next_channel()
2058 finally:
2059 self.lock.release()
2060 elif not self.server_mode:
2061 self._log(DEBUG, 'Rejecting "%s" channel request from server.' % kind)
2062 reject = True
2063 reason = OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
2064 else:
2065 self.lock.acquire()
2066 try:
2067 my_chanid = self._next_channel()
2068 finally:
2069 self.lock.release()
2070 if kind == 'direct-tcpip':
2071
2072 dest_addr = m.get_string()
2073 dest_port = m.get_int()
2074 origin_addr = m.get_string()
2075 origin_port = m.get_int()
2076 reason = self.server_object.check_channel_direct_tcpip_request(
2077 my_chanid, (origin_addr, origin_port),
2078 (dest_addr, dest_port))
2079 else:
2080 reason = self.server_object.check_channel_request(kind, my_chanid)
2081 if reason != OPEN_SUCCEEDED:
2082 self._log(DEBUG, 'Rejecting "%s" channel request from client.' % kind)
2083 reject = True
2084 if reject:
2085 msg = Message()
2086 msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
2087 msg.add_int(chanid)
2088 msg.add_int(reason)
2089 msg.add_string('')
2090 msg.add_string('en')
2091 self._send_message(msg)
2092 return
2093
2094 chan = Channel(my_chanid)
2095 self.lock.acquire()
2096 try:
2097 self._channels.put(my_chanid, chan)
2098 self.channels_seen[my_chanid] = True
2099 chan._set_transport(self)
2100 chan._set_window(self.window_size, self.max_packet_size)
2101 chan._set_remote_channel(chanid, initial_window_size, max_packet_size)
2102 finally:
2103 self.lock.release()
2104 m = Message()
2105 m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
2106 m.add_int(chanid)
2107 m.add_int(my_chanid)
2108 m.add_int(self.window_size)
2109 m.add_int(self.max_packet_size)
2110 self._send_message(m)
2111 self._log(INFO, 'Secsh channel %d (%s) opened.', my_chanid, kind)
2112 if kind == 'auth-agent@openssh.com':
2113 self._forward_agent_handler(chan)
2114 elif kind == 'x11':
2115 self._x11_handler(chan, (origin_addr, origin_port))
2116 elif kind == 'forwarded-tcpip':
2117 chan.origin_addr = (origin_addr, origin_port)
2118 self._tcp_handler(chan, (origin_addr, origin_port), (server_addr, server_port))
2119 else:
2120 self._queue_incoming_channel(chan)
2121
2127
2129 try:
2130 self.lock.acquire()
2131 if name not in self.subsystem_table:
2132 return (None, [], {})
2133 return self.subsystem_table[name]
2134 finally:
2135 self.lock.release()
2136
2137 _handler_table = {
2138 MSG_NEWKEYS: _parse_newkeys,
2139 MSG_GLOBAL_REQUEST: _parse_global_request,
2140 MSG_REQUEST_SUCCESS: _parse_request_success,
2141 MSG_REQUEST_FAILURE: _parse_request_failure,
2142 MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
2143 MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
2144 MSG_CHANNEL_OPEN: _parse_channel_open,
2145 MSG_KEXINIT: _negotiate_keys,
2146 }
2147
2148 _channel_handler_table = {
2149 MSG_CHANNEL_SUCCESS: Channel._request_success,
2150 MSG_CHANNEL_FAILURE: Channel._request_failed,
2151 MSG_CHANNEL_DATA: Channel._feed,
2152 MSG_CHANNEL_EXTENDED_DATA: Channel._feed_extended,
2153 MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
2154 MSG_CHANNEL_REQUEST: Channel._handle_request,
2155 MSG_CHANNEL_EOF: Channel._handle_eof,
2156 MSG_CHANNEL_CLOSE: Channel._handle_close,
2157 }
2158