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