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