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.sock.close()
404 self.close()
405
407 """
408 Return a L{SecurityOptions} object which can be used to tweak the
409 encryption algorithms this transport will permit, and the order of
410 preference for them.
411
412 @return: an object that can be used to change the preferred algorithms
413 for encryption, digest (hash), public key, and key exchange.
414 @rtype: L{SecurityOptions}
415 """
416 return SecurityOptions(self)
417
419 """
420 Negotiate a new SSH2 session as a client. This is the first step after
421 creating a new L{Transport}. A separate thread is created for protocol
422 negotiation.
423
424 If an event is passed in, this method returns immediately. When
425 negotiation is done (successful or not), the given C{Event} will
426 be triggered. On failure, L{is_active} will return C{False}.
427
428 (Since 1.4) If C{event} is C{None}, this method will not return until
429 negotation is done. On success, the method returns normally.
430 Otherwise an SSHException is raised.
431
432 After a successful negotiation, you will usually want to authenticate,
433 calling L{auth_password <Transport.auth_password>} or
434 L{auth_publickey <Transport.auth_publickey>}.
435
436 @note: L{connect} is a simpler method for connecting as a client.
437
438 @note: After calling this method (or L{start_server} or L{connect}),
439 you should no longer directly read from or write to the original
440 socket object.
441
442 @param event: an event to trigger when negotiation is complete
443 (optional)
444 @type event: threading.Event
445
446 @raise SSHException: if negotiation fails (and no C{event} was passed
447 in)
448 """
449 self.active = True
450 if event is not None:
451
452 self.completion_event = event
453 self.start()
454 return
455
456
457 self.completion_event = event = threading.Event()
458 self.start()
459 Random.atfork()
460 while True:
461 event.wait(0.1)
462 if not self.active:
463 e = self.get_exception()
464 if e is not None:
465 raise e
466 raise SSHException('Negotiation failed.')
467 if event.isSet():
468 break
469
471 """
472 Negotiate a new SSH2 session as a server. This is the first step after
473 creating a new L{Transport} and setting up your server host key(s). A
474 separate thread is created for protocol negotiation.
475
476 If an event is passed in, this method returns immediately. When
477 negotiation is done (successful or not), the given C{Event} will
478 be triggered. On failure, L{is_active} will return C{False}.
479
480 (Since 1.4) If C{event} is C{None}, this method will not return until
481 negotation is done. On success, the method returns normally.
482 Otherwise an SSHException is raised.
483
484 After a successful negotiation, the client will need to authenticate.
485 Override the methods
486 L{get_allowed_auths <ServerInterface.get_allowed_auths>},
487 L{check_auth_none <ServerInterface.check_auth_none>},
488 L{check_auth_password <ServerInterface.check_auth_password>}, and
489 L{check_auth_publickey <ServerInterface.check_auth_publickey>} in the
490 given C{server} object to control the authentication process.
491
492 After a successful authentication, the client should request to open
493 a channel. Override
494 L{check_channel_request <ServerInterface.check_channel_request>} in the
495 given C{server} object to allow channels to be opened.
496
497 @note: After calling this method (or L{start_client} or L{connect}),
498 you should no longer directly read from or write to the original
499 socket object.
500
501 @param event: an event to trigger when negotiation is complete.
502 @type event: threading.Event
503 @param server: an object used to perform authentication and create
504 L{Channel}s.
505 @type server: L{server.ServerInterface}
506
507 @raise SSHException: if negotiation fails (and no C{event} was passed
508 in)
509 """
510 if server is None:
511 server = ServerInterface()
512 self.server_mode = True
513 self.server_object = server
514 self.active = True
515 if event is not None:
516
517 self.completion_event = event
518 self.start()
519 return
520
521
522 self.completion_event = event = threading.Event()
523 self.start()
524 while True:
525 event.wait(0.1)
526 if not self.active:
527 e = self.get_exception()
528 if e is not None:
529 raise e
530 raise SSHException('Negotiation failed.')
531 if event.isSet():
532 break
533
535 """
536 Add a host key to the list of keys used for server mode. When behaving
537 as a server, the host key is used to sign certain packets during the
538 SSH2 negotiation, so that the client can trust that we are who we say
539 we are. Because this is used for signing, the key must contain private
540 key info, not just the public half. Only one key of each type (RSA or
541 DSS) is kept.
542
543 @param key: the host key to add, usually an L{RSAKey <rsakey.RSAKey>} or
544 L{DSSKey <dsskey.DSSKey>}.
545 @type key: L{PKey <pkey.PKey>}
546 """
547 self.server_key_dict[key.get_name()] = key
548
550 """
551 Return the active host key, in server mode. After negotiating with the
552 client, this method will return the negotiated host key. If only one
553 type of host key was set with L{add_server_key}, that's the only key
554 that will ever be returned. But in cases where you have set more than
555 one type of host key (for example, an RSA key and a DSS key), the key
556 type will be negotiated by the client, and this method will return the
557 key of the type agreed on. If the host key has not been negotiated
558 yet, C{None} is returned. In client mode, the behavior is undefined.
559
560 @return: host key of the type negotiated by the client, or C{None}.
561 @rtype: L{PKey <pkey.PKey>}
562 """
563 try:
564 return self.server_key_dict[self.host_key_type]
565 except KeyError:
566 pass
567 return None
568
570 """
571 I{(optional)}
572 Load a file of prime moduli for use in doing group-exchange key
573 negotiation in server mode. It's a rather obscure option and can be
574 safely ignored.
575
576 In server mode, the remote client may request "group-exchange" key
577 negotiation, which asks the server to send a random prime number that
578 fits certain criteria. These primes are pretty difficult to compute,
579 so they can't be generated on demand. But many systems contain a file
580 of suitable primes (usually named something like C{/etc/ssh/moduli}).
581 If you call C{load_server_moduli} and it returns C{True}, then this
582 file of primes has been loaded and we will support "group-exchange" in
583 server mode. Otherwise server mode will just claim that it doesn't
584 support that method of key negotiation.
585
586 @param filename: optional path to the moduli file, if you happen to
587 know that it's not in a standard location.
588 @type filename: str
589 @return: True if a moduli file was successfully loaded; False
590 otherwise.
591 @rtype: bool
592
593 @note: This has no effect when used in client mode.
594 """
595 Transport._modulus_pack = ModulusPack(rng)
596
597 file_list = [ '/etc/ssh/moduli', '/usr/local/etc/moduli' ]
598 if filename is not None:
599 file_list.insert(0, filename)
600 for fn in file_list:
601 try:
602 Transport._modulus_pack.read_file(fn)
603 return True
604 except IOError:
605 pass
606
607 Transport._modulus_pack = None
608 return False
609 load_server_moduli = staticmethod(load_server_moduli)
610
612 """
613 Close this session, and any open channels that are tied to it.
614 """
615 if not self.active:
616 return
617 self.active = False
618 self.packetizer.close()
619 self.join()
620 for chan in self._channels.values():
621 chan._unlink()
622
624 """
625 Return the host key of the server (in client mode).
626
627 @note: Previously this call returned a tuple of (key type, key string).
628 You can get the same effect by calling
629 L{PKey.get_name <pkey.PKey.get_name>} for the key type, and
630 C{str(key)} for the key string.
631
632 @raise SSHException: if no session is currently active.
633
634 @return: public key of the remote server
635 @rtype: L{PKey <pkey.PKey>}
636 """
637 if (not self.active) or (not self.initial_kex_done):
638 raise SSHException('No existing session')
639 return self.host_key
640
642 """
643 Return true if this session is active (open).
644
645 @return: True if the session is still active (open); False if the
646 session is closed
647 @rtype: bool
648 """
649 return self.active
650
652 """
653 Request a new channel to the server, of type C{"session"}. This
654 is just an alias for C{open_channel('session')}.
655
656 @return: a new L{Channel}
657 @rtype: L{Channel}
658
659 @raise SSHException: if the request is rejected or the session ends
660 prematurely
661 """
662 return self.open_channel('session')
663
665 """
666 Request a new channel to the client, of type C{"x11"}. This
667 is just an alias for C{open_channel('x11', src_addr=src_addr)}.
668
669 @param src_addr: the source address of the x11 server (port is the
670 x11 port, ie. 6010)
671 @type src_addr: (str, int)
672 @return: a new L{Channel}
673 @rtype: L{Channel}
674
675 @raise SSHException: if the request is rejected or the session ends
676 prematurely
677 """
678 return self.open_channel('x11', src_addr=src_addr)
679
681 """
682 Request a new channel to the client, of type
683 C{"auth-agent@openssh.com"}.
684
685 This is just an alias for C{open_channel('auth-agent@openssh.com')}.
686 @return: a new L{Channel}
687 @rtype: L{Channel}
688
689 @raise SSHException: if the request is rejected or the session ends
690 prematurely
691 """
692 return self.open_channel('auth-agent@openssh.com')
693
695 """
696 Request a new channel back to the client, of type C{"forwarded-tcpip"}.
697 This is used after a client has requested port forwarding, for sending
698 incoming connections back to the client.
699
700 @param src_addr: originator's address
701 @param src_port: originator's port
702 @param dest_addr: local (server) connected address
703 @param dest_port: local (server) connected port
704 """
705 return self.open_channel('forwarded-tcpip', (dest_addr, dest_port), (src_addr, src_port))
706
707 - def open_channel(self, kind, dest_addr=None, src_addr=None):
708 """
709 Request a new channel to the server. L{Channel}s are socket-like
710 objects used for the actual transfer of data across the session.
711 You may only request a channel after negotiating encryption (using
712 L{connect} or L{start_client}) and authenticating.
713
714 @param kind: the kind of channel requested (usually C{"session"},
715 C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"})
716 @type kind: str
717 @param dest_addr: the destination address of this port forwarding,
718 if C{kind} is C{"forwarded-tcpip"} or C{"direct-tcpip"} (ignored
719 for other channel types)
720 @type dest_addr: (str, int)
721 @param src_addr: the source address of this port forwarding, if
722 C{kind} is C{"forwarded-tcpip"}, C{"direct-tcpip"}, or C{"x11"}
723 @type src_addr: (str, int)
724 @return: a new L{Channel} on success
725 @rtype: L{Channel}
726
727 @raise SSHException: if the request is rejected or the session ends
728 prematurely
729 """
730 if not self.active:
731 raise SSHException('SSH session not active')
732 self.lock.acquire()
733 try:
734 chanid = self._next_channel()
735 m = Message()
736 m.add_byte(chr(MSG_CHANNEL_OPEN))
737 m.add_string(kind)
738 m.add_int(chanid)
739 m.add_int(self.window_size)
740 m.add_int(self.max_packet_size)
741 if (kind == 'forwarded-tcpip') or (kind == 'direct-tcpip'):
742 m.add_string(dest_addr[0])
743 m.add_int(dest_addr[1])
744 m.add_string(src_addr[0])
745 m.add_int(src_addr[1])
746 elif kind == 'x11':
747 m.add_string(src_addr[0])
748 m.add_int(src_addr[1])
749 chan = Channel(chanid)
750 self._channels.put(chanid, chan)
751 self.channel_events[chanid] = event = threading.Event()
752 self.channels_seen[chanid] = True
753 chan._set_transport(self)
754 chan._set_window(self.window_size, self.max_packet_size)
755 finally:
756 self.lock.release()
757 self._send_user_message(m)
758 while True:
759 event.wait(0.1);
760 if not self.active:
761 e = self.get_exception()
762 if e is None:
763 e = SSHException('Unable to open channel.')
764 raise e
765 if event.isSet():
766 break
767 chan = self._channels.get(chanid)
768 if chan is not None:
769 return chan
770 e = self.get_exception()
771 if e is None:
772 e = SSHException('Unable to open channel.')
773 raise e
774
776 """
777 Ask the server to forward TCP connections from a listening port on
778 the server, across this SSH session.
779
780 If a handler is given, that handler is called from a different thread
781 whenever a forwarded connection arrives. The handler parameters are::
782
783 handler(channel, (origin_addr, origin_port), (server_addr, server_port))
784
785 where C{server_addr} and C{server_port} are the address and port that
786 the server was listening on.
787
788 If no handler is set, the default behavior is to send new incoming
789 forwarded connections into the accept queue, to be picked up via
790 L{accept}.
791
792 @param address: the address to bind when forwarding
793 @type address: str
794 @param port: the port to forward, or 0 to ask the server to allocate
795 any port
796 @type port: int
797 @param handler: optional handler for incoming forwarded connections
798 @type handler: function(Channel, (str, int), (str, int))
799 @return: the port # allocated by the server
800 @rtype: int
801
802 @raise SSHException: if the server refused the TCP forward request
803 """
804 if not self.active:
805 raise SSHException('SSH session not active')
806 address = str(address)
807 port = int(port)
808 response = self.global_request('tcpip-forward', (address, port), wait=True)
809 if response is None:
810 raise SSHException('TCP forwarding request denied')
811 if port == 0:
812 port = response.get_int()
813 if handler is None:
814 def default_handler(channel, (src_addr, src_port), (dest_addr, dest_port)):
815 self._queue_incoming_channel(channel)
816 handler = default_handler
817 self._tcp_handler = handler
818 return port
819
821 """
822 Ask the server to cancel a previous port-forwarding request. No more
823 connections to the given address & port will be forwarded across this
824 ssh connection.
825
826 @param address: the address to stop forwarding
827 @type address: str
828 @param port: the port to stop forwarding
829 @type port: int
830 """
831 if not self.active:
832 return
833 self._tcp_handler = None
834 self.global_request('cancel-tcpip-forward', (address, port), wait=True)
835
837 """
838 Create an SFTP client channel from an open transport. On success,
839 an SFTP session will be opened with the remote host, and a new
840 SFTPClient object will be returned.
841
842 @return: a new L{SFTPClient} object, referring to an sftp session
843 (channel) across this transport
844 @rtype: L{SFTPClient}
845 """
846 return SFTPClient.from_transport(self)
847
849 """
850 Send a junk packet across the encrypted link. This is sometimes used
851 to add "noise" to a connection to confuse would-be attackers. It can
852 also be used as a keep-alive for long lived connections traversing
853 firewalls.
854
855 @param bytes: the number of random bytes to send in the payload of the
856 ignored packet -- defaults to a random number from 10 to 41.
857 @type bytes: int
858 """
859 m = Message()
860 m.add_byte(chr(MSG_IGNORE))
861 if bytes is None:
862 bytes = (ord(rng.read(1)) % 32) + 10
863 m.add_bytes(rng.read(bytes))
864 self._send_user_message(m)
865
867 """
868 Force this session to switch to new keys. Normally this is done
869 automatically after the session hits a certain number of packets or
870 bytes sent or received, but this method gives you the option of forcing
871 new keys whenever you want. Negotiating new keys causes a pause in
872 traffic both ways as the two sides swap keys and do computations. This
873 method returns when the session has switched to new keys.
874
875 @raise SSHException: if the key renegotiation failed (which causes the
876 session to end)
877 """
878 self.completion_event = threading.Event()
879 self._send_kex_init()
880 while True:
881 self.completion_event.wait(0.1)
882 if not self.active:
883 e = self.get_exception()
884 if e is not None:
885 raise e
886 raise SSHException('Negotiation failed.')
887 if self.completion_event.isSet():
888 break
889 return
890
892 """
893 Turn on/off keepalive packets (default is off). If this is set, after
894 C{interval} seconds without sending any data over the connection, a
895 "keepalive" packet will be sent (and ignored by the remote host). This
896 can be useful to keep connections alive over a NAT, for example.
897
898 @param interval: seconds to wait before sending a keepalive packet (or
899 0 to disable keepalives).
900 @type interval: int
901 """
902 self.packetizer.set_keepalive(interval,
903 lambda x=weakref.proxy(self): x.global_request('keepalive@lag.net', wait=False))
904
906 """
907 Make a global request to the remote host. These are normally
908 extensions to the SSH2 protocol.
909
910 @param kind: name of the request.
911 @type kind: str
912 @param data: an optional tuple containing additional data to attach
913 to the request.
914 @type data: tuple
915 @param wait: C{True} if this method should not return until a response
916 is received; C{False} otherwise.
917 @type wait: bool
918 @return: a L{Message} containing possible additional data if the
919 request was successful (or an empty L{Message} if C{wait} was
920 C{False}); C{None} if the request was denied.
921 @rtype: L{Message}
922 """
923 if wait:
924 self.completion_event = threading.Event()
925 m = Message()
926 m.add_byte(chr(MSG_GLOBAL_REQUEST))
927 m.add_string(kind)
928 m.add_boolean(wait)
929 if data is not None:
930 m.add(*data)
931 self._log(DEBUG, 'Sending global request "%s"' % kind)
932 self._send_user_message(m)
933 if not wait:
934 return None
935 while True:
936 self.completion_event.wait(0.1)
937 if not self.active:
938 return None
939 if self.completion_event.isSet():
940 break
941 return self.global_response
942
943 - def accept(self, timeout=None):
944 """
945 Return the next channel opened by the client over this transport, in
946 server mode. If no channel is opened before the given timeout, C{None}
947 is returned.
948
949 @param timeout: seconds to wait for a channel, or C{None} to wait
950 forever
951 @type timeout: int
952 @return: a new Channel opened by the client
953 @rtype: L{Channel}
954 """
955 self.lock.acquire()
956 try:
957 if len(self.server_accepts) > 0:
958 chan = self.server_accepts.pop(0)
959 else:
960 self.server_accept_cv.wait(timeout)
961 if len(self.server_accepts) > 0:
962 chan = self.server_accepts.pop(0)
963 else:
964
965 chan = None
966 finally:
967 self.lock.release()
968 return chan
969
970 - def connect(self, hostkey=None, username='', password=None, pkey=None):
971 """
972 Negotiate an SSH2 session, and optionally verify the server's host key
973 and authenticate using a password or private key. This is a shortcut
974 for L{start_client}, L{get_remote_server_key}, and
975 L{Transport.auth_password} or L{Transport.auth_publickey}. Use those
976 methods if you want more control.
977
978 You can use this method immediately after creating a Transport to
979 negotiate encryption with a server. If it fails, an exception will be
980 thrown. On success, the method will return cleanly, and an encrypted
981 session exists. You may immediately call L{open_channel} or
982 L{open_session} to get a L{Channel} object, which is used for data
983 transfer.
984
985 @note: If you fail to supply a password or private key, this method may
986 succeed, but a subsequent L{open_channel} or L{open_session} call may
987 fail because you haven't authenticated yet.
988
989 @param hostkey: the host key expected from the server, or C{None} if
990 you don't want to do host key verification.
991 @type hostkey: L{PKey<pkey.PKey>}
992 @param username: the username to authenticate as.
993 @type username: str
994 @param password: a password to use for authentication, if you want to
995 use password authentication; otherwise C{None}.
996 @type password: str
997 @param pkey: a private key to use for authentication, if you want to
998 use private key authentication; otherwise C{None}.
999 @type pkey: L{PKey<pkey.PKey>}
1000
1001 @raise SSHException: if the SSH2 negotiation fails, the host key
1002 supplied by the server is incorrect, or authentication fails.
1003 """
1004 if hostkey is not None:
1005 self._preferred_keys = [ hostkey.get_name() ]
1006
1007 self.start_client()
1008
1009
1010 if (hostkey is not None):
1011 key = self.get_remote_server_key()
1012 if (key.get_name() != hostkey.get_name()) or (str(key) != str(hostkey)):
1013 self._log(DEBUG, 'Bad host key from server')
1014 self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(str(hostkey))))
1015 self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(str(key))))
1016 raise SSHException('Bad host key from server')
1017 self._log(DEBUG, 'Host key verified (%s)' % hostkey.get_name())
1018
1019 if (pkey is not None) or (password is not None):
1020 if password is not None:
1021 self._log(DEBUG, 'Attempting password auth...')
1022 self.auth_password(username, password)
1023 else:
1024 self._log(DEBUG, 'Attempting public-key auth...')
1025 self.auth_publickey(username, pkey)
1026
1027 return
1028
1030 """
1031 Return any exception that happened during the last server request.
1032 This can be used to fetch more specific error information after using
1033 calls like L{start_client}. The exception (if any) is cleared after
1034 this call.
1035
1036 @return: an exception, or C{None} if there is no stored exception.
1037 @rtype: Exception
1038
1039 @since: 1.1
1040 """
1041 self.lock.acquire()
1042 try:
1043 e = self.saved_exception
1044 self.saved_exception = None
1045 return e
1046 finally:
1047 self.lock.release()
1048
1050 """
1051 Set the handler class for a subsystem in server mode. If a request
1052 for this subsystem is made on an open ssh channel later, this handler
1053 will be constructed and called -- see L{SubsystemHandler} for more
1054 detailed documentation.
1055
1056 Any extra parameters (including keyword arguments) are saved and
1057 passed to the L{SubsystemHandler} constructor later.
1058
1059 @param name: name of the subsystem.
1060 @type name: str
1061 @param handler: subclass of L{SubsystemHandler} that handles this
1062 subsystem.
1063 @type handler: class
1064 """
1065 try:
1066 self.lock.acquire()
1067 self.subsystem_table[name] = (handler, larg, kwarg)
1068 finally:
1069 self.lock.release()
1070
1072 """
1073 Return true if this session is active and authenticated.
1074
1075 @return: True if the session is still open and has been authenticated
1076 successfully; False if authentication failed and/or the session is
1077 closed.
1078 @rtype: bool
1079 """
1080 return self.active and (self.auth_handler is not None) and self.auth_handler.is_authenticated()
1081
1083 """
1084 Return the username this connection is authenticated for. If the
1085 session is not authenticated (or authentication failed), this method
1086 returns C{None}.
1087
1088 @return: username that was authenticated, or C{None}.
1089 @rtype: string
1090 """
1091 if not self.active or (self.auth_handler is None):
1092 return None
1093 return self.auth_handler.get_username()
1094
1096 """
1097 Try to authenticate to the server using no authentication at all.
1098 This will almost always fail. It may be useful for determining the
1099 list of authentication types supported by the server, by catching the
1100 L{BadAuthenticationType} exception raised.
1101
1102 @param username: the username to authenticate as
1103 @type username: string
1104 @return: list of auth types permissible for the next stage of
1105 authentication (normally empty)
1106 @rtype: list
1107
1108 @raise BadAuthenticationType: if "none" authentication isn't allowed
1109 by the server for this user
1110 @raise SSHException: if the authentication failed due to a network
1111 error
1112
1113 @since: 1.5
1114 """
1115 if (not self.active) or (not self.initial_kex_done):
1116 raise SSHException('No existing session')
1117 my_event = threading.Event()
1118 self.auth_handler = AuthHandler(self)
1119 self.auth_handler.auth_none(username, my_event)
1120 return self.auth_handler.wait_for_response(my_event)
1121
1122 - def auth_password(self, username, password, event=None, fallback=True):
1123 """
1124 Authenticate to the server using a password. The username and password
1125 are sent over an encrypted link.
1126
1127 If an C{event} is passed in, this method will return immediately, and
1128 the event will be triggered once authentication succeeds or fails. On
1129 success, L{is_authenticated} will return C{True}. On failure, you may
1130 use L{get_exception} to get more detailed error information.
1131
1132 Since 1.1, if no event is passed, this method will block until the
1133 authentication succeeds or fails. On failure, an exception is raised.
1134 Otherwise, the method simply returns.
1135
1136 Since 1.5, if no event is passed and C{fallback} is C{True} (the
1137 default), if the server doesn't support plain password authentication
1138 but does support so-called "keyboard-interactive" mode, an attempt
1139 will be made to authenticate using this interactive mode. If it fails,
1140 the normal exception will be thrown as if the attempt had never been
1141 made. This is useful for some recent Gentoo and Debian distributions,
1142 which turn off plain password authentication in a misguided belief
1143 that interactive authentication is "more secure". (It's not.)
1144
1145 If the server requires multi-step authentication (which is very rare),
1146 this method will return a list of auth types permissible for the next
1147 step. Otherwise, in the normal case, an empty list is returned.
1148
1149 @param username: the username to authenticate as
1150 @type username: str
1151 @param password: the password to authenticate with
1152 @type password: str or unicode
1153 @param event: an event to trigger when the authentication attempt is
1154 complete (whether it was successful or not)
1155 @type event: threading.Event
1156 @param fallback: C{True} if an attempt at an automated "interactive"
1157 password auth should be made if the server doesn't support normal
1158 password auth
1159 @type fallback: bool
1160 @return: list of auth types permissible for the next stage of
1161 authentication (normally empty)
1162 @rtype: list
1163
1164 @raise BadAuthenticationType: if password authentication isn't
1165 allowed by the server for this user (and no event was passed in)
1166 @raise AuthenticationException: if the authentication failed (and no
1167 event was passed in)
1168 @raise SSHException: if there was a network error
1169 """
1170 if (not self.active) or (not self.initial_kex_done):
1171
1172 raise SSHException('No existing session')
1173 if event is None:
1174 my_event = threading.Event()
1175 else:
1176 my_event = event
1177 self.auth_handler = AuthHandler(self)
1178 self.auth_handler.auth_password(username, password, my_event)
1179 if event is not None:
1180
1181 return []
1182 try:
1183 return self.auth_handler.wait_for_response(my_event)
1184 except BadAuthenticationType, x:
1185
1186 if not fallback or ('keyboard-interactive' not in x.allowed_types):
1187 raise
1188 try:
1189 def handler(title, instructions, fields):
1190 if len(fields) > 1:
1191 raise SSHException('Fallback authentication failed.')
1192 if len(fields) == 0:
1193
1194
1195
1196
1197 return []
1198 return [ password ]
1199 return self.auth_interactive(username, handler)
1200 except SSHException, ignored:
1201
1202 raise x
1203 return None
1204
1206 """
1207 Authenticate to the server using a private key. The key is used to
1208 sign data from the server, so it must include the private part.
1209
1210 If an C{event} is passed in, this method will return immediately, and
1211 the event will be triggered once authentication succeeds or fails. On
1212 success, L{is_authenticated} will return C{True}. On failure, you may
1213 use L{get_exception} to get more detailed error information.
1214
1215 Since 1.1, if no event is passed, this method will block until the
1216 authentication succeeds or fails. On failure, an exception is raised.
1217 Otherwise, the method simply returns.
1218
1219 If the server requires multi-step authentication (which is very rare),
1220 this method will return a list of auth types permissible for the next
1221 step. Otherwise, in the normal case, an empty list is returned.
1222
1223 @param username: the username to authenticate as
1224 @type username: string
1225 @param key: the private key to authenticate with
1226 @type key: L{PKey <pkey.PKey>}
1227 @param event: an event to trigger when the authentication attempt is
1228 complete (whether it was successful or not)
1229 @type event: threading.Event
1230 @return: list of auth types permissible for the next stage of
1231 authentication (normally empty)
1232 @rtype: list
1233
1234 @raise BadAuthenticationType: if public-key authentication isn't
1235 allowed by the server for this user (and no event was passed in)
1236 @raise AuthenticationException: if the authentication failed (and no
1237 event was passed in)
1238 @raise SSHException: if there was a network error
1239 """
1240 if (not self.active) or (not self.initial_kex_done):
1241
1242 raise SSHException('No existing session')
1243 if event is None:
1244 my_event = threading.Event()
1245 else:
1246 my_event = event
1247 self.auth_handler = AuthHandler(self)
1248 self.auth_handler.auth_publickey(username, key, my_event)
1249 if event is not None:
1250
1251 return []
1252 return self.auth_handler.wait_for_response(my_event)
1253
1255 """
1256 Authenticate to the server interactively. A handler is used to answer
1257 arbitrary questions from the server. On many servers, this is just a
1258 dumb wrapper around PAM.
1259
1260 This method will block until the authentication succeeds or fails,
1261 peroidically calling the handler asynchronously to get answers to
1262 authentication questions. The handler may be called more than once
1263 if the server continues to ask questions.
1264
1265 The handler is expected to be a callable that will handle calls of the
1266 form: C{handler(title, instructions, prompt_list)}. The C{title} is
1267 meant to be a dialog-window title, and the C{instructions} are user
1268 instructions (both are strings). C{prompt_list} will be a list of
1269 prompts, each prompt being a tuple of C{(str, bool)}. The string is
1270 the prompt and the boolean indicates whether the user text should be
1271 echoed.
1272
1273 A sample call would thus be:
1274 C{handler('title', 'instructions', [('Password:', False)])}.
1275
1276 The handler should return a list or tuple of answers to the server's
1277 questions.
1278
1279 If the server requires multi-step authentication (which is very rare),
1280 this method will return a list of auth types permissible for the next
1281 step. Otherwise, in the normal case, an empty list is returned.
1282
1283 @param username: the username to authenticate as
1284 @type username: string
1285 @param handler: a handler for responding to server questions
1286 @type handler: callable
1287 @param submethods: a string list of desired submethods (optional)
1288 @type submethods: str
1289 @return: list of auth types permissible for the next stage of
1290 authentication (normally empty).
1291 @rtype: list
1292
1293 @raise BadAuthenticationType: if public-key authentication isn't
1294 allowed by the server for this user
1295 @raise AuthenticationException: if the authentication failed
1296 @raise SSHException: if there was a network error
1297
1298 @since: 1.5
1299 """
1300 if (not self.active) or (not self.initial_kex_done):
1301
1302 raise SSHException('No existing session')
1303 my_event = threading.Event()
1304 self.auth_handler = AuthHandler(self)
1305 self.auth_handler.auth_interactive(username, handler, my_event, submethods)
1306 return self.auth_handler.wait_for_response(my_event)
1307
1309 """
1310 Set the channel for this transport's logging. The default is
1311 C{"paramiko.transport"} but it can be set to anything you want.
1312 (See the C{logging} module for more info.) SSH Channels will log
1313 to a sub-channel of the one specified.
1314
1315 @param name: new channel name for logging
1316 @type name: str
1317
1318 @since: 1.1
1319 """
1320 self.log_name = name
1321 self.logger = util.get_logger(name)
1322 self.packetizer.set_log(self.logger)
1323
1325 """
1326 Return the channel name used for this transport's logging.
1327
1328 @return: channel name.
1329 @rtype: str
1330
1331 @since: 1.2
1332 """
1333 return self.log_name
1334
1336 """
1337 Turn on/off logging a hex dump of protocol traffic at DEBUG level in
1338 the logs. Normally you would want this off (which is the default),
1339 but if you are debugging something, it may be useful.
1340
1341 @param hexdump: C{True} to log protocol traffix (in hex) to the log;
1342 C{False} otherwise.
1343 @type hexdump: bool
1344 """
1345 self.packetizer.set_hexdump(hexdump)
1346
1348 """
1349 Return C{True} if the transport is currently logging hex dumps of
1350 protocol traffic.
1351
1352 @return: C{True} if hex dumps are being logged
1353 @rtype: bool
1354
1355 @since: 1.4
1356 """
1357 return self.packetizer.get_hexdump()
1358
1360 """
1361 Turn on/off compression. This will only have an affect before starting
1362 the transport (ie before calling L{connect}, etc). By default,
1363 compression is off since it negatively affects interactive sessions.
1364
1365 @param compress: C{True} to ask the remote client/server to compress
1366 traffic; C{False} to refuse compression
1367 @type compress: bool
1368
1369 @since: 1.5.2
1370 """
1371 if compress:
1372 self._preferred_compression = ( 'zlib@openssh.com', 'zlib', 'none' )
1373 else:
1374 self._preferred_compression = ( 'none', )
1375
1377 """
1378 Return the address of the remote side of this Transport, if possible.
1379 This is effectively a wrapper around C{'getpeername'} on the underlying
1380 socket. If the socket-like object has no C{'getpeername'} method,
1381 then C{("unknown", 0)} is returned.
1382
1383 @return: the address if the remote host, if known
1384 @rtype: tuple(str, int)
1385 """
1386 gp = getattr(self.sock, 'getpeername', None)
1387 if gp is None:
1388 return ('unknown', 0)
1389 return gp()
1390
1392 self.active = False
1393 self.packetizer.close()
1394
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
1565
1567
1568
1569
1570
1571
1572
1573
1574 self.sys = sys
1575
1576
1577
1578 Random.atfork()
1579
1580
1581
1582 self.sys = sys
1583
1584
1585 _active_threads.append(self)
1586 if self.server_mode:
1587 self._log(DEBUG, 'starting thread (server mode): %s' % hex(long(id(self)) & 0xffffffffL))
1588 else:
1589 self._log(DEBUG, 'starting thread (client mode): %s' % hex(long(id(self)) & 0xffffffffL))
1590 try:
1591 try:
1592 self.packetizer.write_all(self.local_version + '\r\n')
1593 self._check_banner()
1594 self._send_kex_init()
1595 self._expect_packet(MSG_KEXINIT)
1596
1597 while self.active:
1598 if self.packetizer.need_rekey() and not self.in_kex:
1599 self._send_kex_init()
1600 try:
1601 ptype, m = self.packetizer.read_message()
1602 except NeedRekeyException:
1603 continue
1604 if ptype == MSG_IGNORE:
1605 continue
1606 elif ptype == MSG_DISCONNECT:
1607 self._parse_disconnect(m)
1608 self.active = False
1609 self.packetizer.close()
1610 break
1611 elif ptype == MSG_DEBUG:
1612 self._parse_debug(m)
1613 continue
1614 if len(self._expected_packet) > 0:
1615 if ptype not in self._expected_packet:
1616 raise SSHException('Expecting packet from %r, got %d' % (self._expected_packet, ptype))
1617 self._expected_packet = tuple()
1618 if (ptype >= 30) and (ptype <= 39):
1619 self.kex_engine.parse_next(ptype, m)
1620 continue
1621
1622 if ptype in self._handler_table:
1623 error_msg = self._ensure_authed(ptype, m)
1624 if error_msg:
1625 self._send_message(error_msg)
1626 else:
1627 self._handler_table[ptype](self, m)
1628 elif ptype in self._channel_handler_table:
1629 chanid = m.get_int()
1630 chan = self._channels.get(chanid)
1631 if chan is not None:
1632 self._channel_handler_table[ptype](chan, m)
1633 elif chanid in self.channels_seen:
1634 self._log(DEBUG, 'Ignoring message for dead channel %d' % chanid)
1635 else:
1636 self._log(ERROR, 'Channel request for unknown channel %d' % chanid)
1637 self.active = False
1638 self.packetizer.close()
1639 elif (self.auth_handler is not None) and (ptype in self.auth_handler._handler_table):
1640 self.auth_handler._handler_table[ptype](self.auth_handler, m)
1641 else:
1642
1643
1644
1645
1646 name = MSG_NAMES[ptype]
1647 self._log(
1648 WARNING,
1649 "Oops, unhandled type {} ({!r})".format(
1650 ptype, name
1651 ),
1652 )
1653 if ptype != MSG_UNIMPLEMENTED:
1654 msg = Message()
1655 msg.add_byte(chr(MSG_UNIMPLEMENTED))
1656 msg.add_int(m.seqno)
1657 self._send_message(msg)
1658 except SSHException, e:
1659 self._log(ERROR, 'Exception: ' + str(e))
1660 self._log(ERROR, util.tb_strings())
1661 self.saved_exception = e
1662 except EOFError, e:
1663 self._log(DEBUG, 'EOF in transport thread')
1664
1665 self.saved_exception = e
1666 except socket.error, e:
1667 if type(e.args) is tuple:
1668 emsg = '%s (%d)' % (e.args[1], e.args[0])
1669 else:
1670 emsg = e.args
1671 self._log(ERROR, 'Socket exception: ' + emsg)
1672 self.saved_exception = e
1673 except Exception, e:
1674 self._log(ERROR, 'Unknown exception: ' + str(e))
1675 self._log(ERROR, util.tb_strings())
1676 self.saved_exception = e
1677 _active_threads.remove(self)
1678 for chan in self._channels.values():
1679 chan._unlink()
1680 if self.active:
1681 self.active = False
1682 self.packetizer.close()
1683 if self.completion_event != None:
1684 self.completion_event.set()
1685 if self.auth_handler is not None:
1686 self.auth_handler.abort()
1687 for event in self.channel_events.values():
1688 event.set()
1689 try:
1690 self.lock.acquire()
1691 self.server_accept_cv.notify()
1692 finally:
1693 self.lock.release()
1694 self.sock.close()
1695 except:
1696
1697
1698
1699
1700 if self.sys.modules is not None:
1701 raise
1702
1703
1704
1705
1706
1708
1709 self.clear_to_send_lock.acquire()
1710 try:
1711 self.clear_to_send.clear()
1712 finally:
1713 self.clear_to_send_lock.release()
1714 if self.local_kex_init == None:
1715
1716 self._send_kex_init()
1717 self._parse_kex_init(m)
1718 self.kex_engine.start_kex()
1719
1721
1722 for i in range(100):
1723
1724
1725 if i == 0:
1726 timeout = self.banner_timeout
1727 else:
1728 timeout = 2
1729 try:
1730 buf = self.packetizer.readline(timeout)
1731 except ProxyCommandFailure:
1732 raise
1733 except Exception, x:
1734 raise SSHException('Error reading SSH protocol banner' + str(x))
1735 if buf[:4] == 'SSH-':
1736 break
1737 self._log(DEBUG, 'Banner: ' + buf)
1738 if buf[:4] != 'SSH-':
1739 raise SSHException('Indecipherable protocol version "' + buf + '"')
1740
1741 self.remote_version = buf
1742
1743 comment = ''
1744 i = string.find(buf, ' ')
1745 if i >= 0:
1746 comment = buf[i+1:]
1747 buf = buf[:i]
1748
1749 segs = buf.split('-', 2)
1750 if len(segs) < 3:
1751 raise SSHException('Invalid SSH banner')
1752 version = segs[1]
1753 client = segs[2]
1754 if version != '1.99' and version != '2.0':
1755 raise SSHException('Incompatible version (%s instead of 2.0)' % (version,))
1756 self._log(INFO, 'Connected (version %s, client %s)' % (version, client))
1757
1798
1800 cookie = m.get_bytes(16)
1801 kex_algo_list = m.get_list()
1802 server_key_algo_list = m.get_list()
1803 client_encrypt_algo_list = m.get_list()
1804 server_encrypt_algo_list = m.get_list()
1805 client_mac_algo_list = m.get_list()
1806 server_mac_algo_list = m.get_list()
1807 client_compress_algo_list = m.get_list()
1808 server_compress_algo_list = m.get_list()
1809 client_lang_list = m.get_list()
1810 server_lang_list = m.get_list()
1811 kex_follows = m.get_boolean()
1812 unused = m.get_int()
1813
1814 self._log(DEBUG, 'kex algos:' + str(kex_algo_list) + ' server key:' + str(server_key_algo_list) + \
1815 ' client encrypt:' + str(client_encrypt_algo_list) + \
1816 ' server encrypt:' + str(server_encrypt_algo_list) + \
1817 ' client mac:' + str(client_mac_algo_list) + \
1818 ' server mac:' + str(server_mac_algo_list) + \
1819 ' client compress:' + str(client_compress_algo_list) + \
1820 ' server compress:' + str(server_compress_algo_list) + \
1821 ' client lang:' + str(client_lang_list) + \
1822 ' server lang:' + str(server_lang_list) + \
1823 ' kex follows?' + str(kex_follows))
1824
1825
1826
1827 if self.server_mode:
1828 agreed_kex = filter(self._preferred_kex.__contains__, kex_algo_list)
1829 else:
1830 agreed_kex = filter(kex_algo_list.__contains__, self._preferred_kex)
1831 if len(agreed_kex) == 0:
1832 raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)')
1833 self.kex_engine = self._kex_info[agreed_kex[0]](self)
1834
1835 if self.server_mode:
1836 available_server_keys = filter(self.server_key_dict.keys().__contains__,
1837 self._preferred_keys)
1838 agreed_keys = filter(available_server_keys.__contains__, server_key_algo_list)
1839 else:
1840 agreed_keys = filter(server_key_algo_list.__contains__, self._preferred_keys)
1841 if len(agreed_keys) == 0:
1842 raise SSHException('Incompatible ssh peer (no acceptable host key)')
1843 self.host_key_type = agreed_keys[0]
1844 if self.server_mode and (self.get_server_key() is None):
1845 raise SSHException('Incompatible ssh peer (can\'t match requested host key type)')
1846
1847 if self.server_mode:
1848 agreed_local_ciphers = filter(self._preferred_ciphers.__contains__,
1849 server_encrypt_algo_list)
1850 agreed_remote_ciphers = filter(self._preferred_ciphers.__contains__,
1851 client_encrypt_algo_list)
1852 else:
1853 agreed_local_ciphers = filter(client_encrypt_algo_list.__contains__,
1854 self._preferred_ciphers)
1855 agreed_remote_ciphers = filter(server_encrypt_algo_list.__contains__,
1856 self._preferred_ciphers)
1857 if (len(agreed_local_ciphers) == 0) or (len(agreed_remote_ciphers) == 0):
1858 raise SSHException('Incompatible ssh server (no acceptable ciphers)')
1859 self.local_cipher = agreed_local_ciphers[0]
1860 self.remote_cipher = agreed_remote_ciphers[0]
1861 self._log(DEBUG, 'Ciphers agreed: local=%s, remote=%s' % (self.local_cipher, self.remote_cipher))
1862
1863 if self.server_mode:
1864 agreed_remote_macs = filter(self._preferred_macs.__contains__, client_mac_algo_list)
1865 agreed_local_macs = filter(self._preferred_macs.__contains__, server_mac_algo_list)
1866 else:
1867 agreed_local_macs = filter(client_mac_algo_list.__contains__, self._preferred_macs)
1868 agreed_remote_macs = filter(server_mac_algo_list.__contains__, self._preferred_macs)
1869 if (len(agreed_local_macs) == 0) or (len(agreed_remote_macs) == 0):
1870 raise SSHException('Incompatible ssh server (no acceptable macs)')
1871 self.local_mac = agreed_local_macs[0]
1872 self.remote_mac = agreed_remote_macs[0]
1873
1874 if self.server_mode:
1875 agreed_remote_compression = filter(self._preferred_compression.__contains__, client_compress_algo_list)
1876 agreed_local_compression = filter(self._preferred_compression.__contains__, server_compress_algo_list)
1877 else:
1878 agreed_local_compression = filter(client_compress_algo_list.__contains__, self._preferred_compression)
1879 agreed_remote_compression = filter(server_compress_algo_list.__contains__, self._preferred_compression)
1880 if (len(agreed_local_compression) == 0) or (len(agreed_remote_compression) == 0):
1881 raise SSHException('Incompatible ssh server (no acceptable compression) %r %r %r' % (agreed_local_compression, agreed_remote_compression, self._preferred_compression))
1882 self.local_compression = agreed_local_compression[0]
1883 self.remote_compression = agreed_remote_compression[0]
1884
1885 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' %
1886 (agreed_kex[0], self.host_key_type, self.local_cipher, self.remote_cipher, self.local_mac,
1887 self.remote_mac, self.local_compression, self.remote_compression))
1888
1889
1890
1891
1892
1893
1894 self.remote_kex_init = chr(MSG_KEXINIT) + m.get_so_far()
1895
1897 "switch on newly negotiated encryption parameters for inbound traffic"
1898 block_size = self._cipher_info[self.remote_cipher]['block-size']
1899 if self.server_mode:
1900 IV_in = self._compute_key('A', block_size)
1901 key_in = self._compute_key('C', self._cipher_info[self.remote_cipher]['key-size'])
1902 else:
1903 IV_in = self._compute_key('B', block_size)
1904 key_in = self._compute_key('D', self._cipher_info[self.remote_cipher]['key-size'])
1905 engine = self._get_cipher(self.remote_cipher, key_in, IV_in)
1906 mac_size = self._mac_info[self.remote_mac]['size']
1907 mac_engine = self._mac_info[self.remote_mac]['class']
1908
1909
1910 if self.server_mode:
1911 mac_key = self._compute_key('E', mac_engine.digest_size)
1912 else:
1913 mac_key = self._compute_key('F', mac_engine.digest_size)
1914 self.packetizer.set_inbound_cipher(engine, block_size, mac_engine, mac_size, mac_key)
1915 compress_in = self._compression_info[self.remote_compression][1]
1916 if (compress_in is not None) and ((self.remote_compression != 'zlib@openssh.com') or self.authenticated):
1917 self._log(DEBUG, 'Switching on inbound compression ...')
1918 self.packetizer.set_inbound_compressor(compress_in())
1919
1921 "switch on newly negotiated encryption parameters for outbound traffic"
1922 m = Message()
1923 m.add_byte(chr(MSG_NEWKEYS))
1924 self._send_message(m)
1925 block_size = self._cipher_info[self.local_cipher]['block-size']
1926 if self.server_mode:
1927 IV_out = self._compute_key('B', block_size)
1928 key_out = self._compute_key('D', self._cipher_info[self.local_cipher]['key-size'])
1929 else:
1930 IV_out = self._compute_key('A', block_size)
1931 key_out = self._compute_key('C', self._cipher_info[self.local_cipher]['key-size'])
1932 engine = self._get_cipher(self.local_cipher, key_out, IV_out)
1933 mac_size = self._mac_info[self.local_mac]['size']
1934 mac_engine = self._mac_info[self.local_mac]['class']
1935
1936
1937 if self.server_mode:
1938 mac_key = self._compute_key('F', mac_engine.digest_size)
1939 else:
1940 mac_key = self._compute_key('E', mac_engine.digest_size)
1941 sdctr = self.local_cipher.endswith('-ctr')
1942 self.packetizer.set_outbound_cipher(engine, block_size, mac_engine, mac_size, mac_key, sdctr)
1943 compress_out = self._compression_info[self.local_compression][0]
1944 if (compress_out is not None) and ((self.local_compression != 'zlib@openssh.com') or self.authenticated):
1945 self._log(DEBUG, 'Switching on outbound compression ...')
1946 self.packetizer.set_outbound_compressor(compress_out())
1947 if not self.packetizer.need_rekey():
1948 self.in_kex = False
1949
1950 self._expect_packet(MSG_NEWKEYS)
1951
1953 self.authenticated = True
1954
1955 if self.local_compression == 'zlib@openssh.com':
1956 compress_out = self._compression_info[self.local_compression][0]
1957 self._log(DEBUG, 'Switching on outbound compression ...')
1958 self.packetizer.set_outbound_compressor(compress_out())
1959 if self.remote_compression == 'zlib@openssh.com':
1960 compress_in = self._compression_info[self.remote_compression][1]
1961 self._log(DEBUG, 'Switching on inbound compression ...')
1962 self.packetizer.set_inbound_compressor(compress_in())
1963
1965 self._log(DEBUG, 'Switch to new keys ...')
1966 self._activate_inbound()
1967
1968 self.local_kex_init = self.remote_kex_init = None
1969 self.K = None
1970 self.kex_engine = None
1971 if self.server_mode and (self.auth_handler is None):
1972
1973 self.auth_handler = AuthHandler(self)
1974 if not self.initial_kex_done:
1975
1976 self.initial_kex_done = True
1977
1978 if self.completion_event != None:
1979 self.completion_event.set()
1980
1981 if not self.packetizer.need_rekey():
1982 self.in_kex = False
1983 self.clear_to_send_lock.acquire()
1984 try:
1985 self.clear_to_send.set()
1986 finally:
1987 self.clear_to_send_lock.release()
1988 return
1989
1991 code = m.get_int()
1992 desc = m.get_string()
1993 self._log(INFO, 'Disconnect (code %d): %s' % (code, desc))
1994
2027
2029 self._log(DEBUG, 'Global request successful.')
2030 self.global_response = m
2031 if self.completion_event is not None:
2032 self.completion_event.set()
2033
2035 self._log(DEBUG, 'Global request denied.')
2036 self.global_response = None
2037 if self.completion_event is not None:
2038 self.completion_event.set()
2039
2041 chanid = m.get_int()
2042 server_chanid = m.get_int()
2043 server_window_size = m.get_int()
2044 server_max_packet_size = m.get_int()
2045 chan = self._channels.get(chanid)
2046 if chan is None:
2047 self._log(WARNING, 'Success for unrequested channel! [??]')
2048 return
2049 self.lock.acquire()
2050 try:
2051 chan._set_remote_channel(server_chanid, server_window_size, server_max_packet_size)
2052 self._log(INFO, 'Secsh channel %d opened.' % chanid)
2053 if chanid in self.channel_events:
2054 self.channel_events[chanid].set()
2055 del self.channel_events[chanid]
2056 finally:
2057 self.lock.release()
2058 return
2059
2061 chanid = m.get_int()
2062 reason = m.get_int()
2063 reason_str = m.get_string()
2064 lang = m.get_string()
2065 reason_text = CONNECTION_FAILED_CODE.get(reason, '(unknown code)')
2066 self._log(INFO, 'Secsh channel %d open FAILED: %s: %s' % (chanid, reason_str, reason_text))
2067 self.lock.acquire()
2068 try:
2069 self.saved_exception = ChannelException(reason, reason_text)
2070 if chanid in self.channel_events:
2071 self._channels.delete(chanid)
2072 if chanid in self.channel_events:
2073 self.channel_events[chanid].set()
2074 del self.channel_events[chanid]
2075 finally:
2076 self.lock.release()
2077 return
2078
2080 kind = m.get_string()
2081 chanid = m.get_int()
2082 initial_window_size = m.get_int()
2083 max_packet_size = m.get_int()
2084 reject = False
2085 if (kind == 'auth-agent@openssh.com') and (self._forward_agent_handler is not None):
2086 self._log(DEBUG, 'Incoming forward agent connection')
2087 self.lock.acquire()
2088 try:
2089 my_chanid = self._next_channel()
2090 finally:
2091 self.lock.release()
2092 elif (kind == 'x11') and (self._x11_handler is not None):
2093 origin_addr = m.get_string()
2094 origin_port = m.get_int()
2095 self._log(DEBUG, 'Incoming x11 connection from %s:%d' % (origin_addr, origin_port))
2096 self.lock.acquire()
2097 try:
2098 my_chanid = self._next_channel()
2099 finally:
2100 self.lock.release()
2101 elif (kind == 'forwarded-tcpip') and (self._tcp_handler is not None):
2102 server_addr = m.get_string()
2103 server_port = m.get_int()
2104 origin_addr = m.get_string()
2105 origin_port = m.get_int()
2106 self._log(DEBUG, 'Incoming tcp forwarded connection from %s:%d' % (origin_addr, origin_port))
2107 self.lock.acquire()
2108 try:
2109 my_chanid = self._next_channel()
2110 finally:
2111 self.lock.release()
2112 elif not self.server_mode:
2113 self._log(DEBUG, 'Rejecting "%s" channel request from server.' % kind)
2114 reject = True
2115 reason = OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
2116 else:
2117 self.lock.acquire()
2118 try:
2119 my_chanid = self._next_channel()
2120 finally:
2121 self.lock.release()
2122 if kind == 'direct-tcpip':
2123
2124 dest_addr = m.get_string()
2125 dest_port = m.get_int()
2126 origin_addr = m.get_string()
2127 origin_port = m.get_int()
2128 reason = self.server_object.check_channel_direct_tcpip_request(
2129 my_chanid, (origin_addr, origin_port),
2130 (dest_addr, dest_port))
2131 else:
2132 reason = self.server_object.check_channel_request(kind, my_chanid)
2133 if reason != OPEN_SUCCEEDED:
2134 self._log(DEBUG, 'Rejecting "%s" channel request from client.' % kind)
2135 reject = True
2136 if reject:
2137 msg = Message()
2138 msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
2139 msg.add_int(chanid)
2140 msg.add_int(reason)
2141 msg.add_string('')
2142 msg.add_string('en')
2143 self._send_message(msg)
2144 return
2145
2146 chan = Channel(my_chanid)
2147 self.lock.acquire()
2148 try:
2149 self._channels.put(my_chanid, chan)
2150 self.channels_seen[my_chanid] = True
2151 chan._set_transport(self)
2152 chan._set_window(self.window_size, self.max_packet_size)
2153 chan._set_remote_channel(chanid, initial_window_size, max_packet_size)
2154 finally:
2155 self.lock.release()
2156 m = Message()
2157 m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
2158 m.add_int(chanid)
2159 m.add_int(my_chanid)
2160 m.add_int(self.window_size)
2161 m.add_int(self.max_packet_size)
2162 self._send_message(m)
2163 self._log(INFO, 'Secsh channel %d (%s) opened.', my_chanid, kind)
2164 if kind == 'auth-agent@openssh.com':
2165 self._forward_agent_handler(chan)
2166 elif kind == 'x11':
2167 self._x11_handler(chan, (origin_addr, origin_port))
2168 elif kind == 'forwarded-tcpip':
2169 chan.origin_addr = (origin_addr, origin_port)
2170 self._tcp_handler(chan, (origin_addr, origin_port), (server_addr, server_port))
2171 else:
2172 self._queue_incoming_channel(chan)
2173
2179
2181 try:
2182 self.lock.acquire()
2183 if name not in self.subsystem_table:
2184 return (None, [], {})
2185 return self.subsystem_table[name]
2186 finally:
2187 self.lock.release()
2188
2189 _handler_table = {
2190 MSG_NEWKEYS: _parse_newkeys,
2191 MSG_GLOBAL_REQUEST: _parse_global_request,
2192 MSG_REQUEST_SUCCESS: _parse_request_success,
2193 MSG_REQUEST_FAILURE: _parse_request_failure,
2194 MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
2195 MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
2196 MSG_CHANNEL_OPEN: _parse_channel_open,
2197 MSG_KEXINIT: _negotiate_keys,
2198 }
2199
2200 _channel_handler_table = {
2201 MSG_CHANNEL_SUCCESS: Channel._request_success,
2202 MSG_CHANNEL_FAILURE: Channel._request_failed,
2203 MSG_CHANNEL_DATA: Channel._feed,
2204 MSG_CHANNEL_EXTENDED_DATA: Channel._feed_extended,
2205 MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
2206 MSG_CHANNEL_REQUEST: Channel._handle_request,
2207 MSG_CHANNEL_EOF: Channel._handle_eof,
2208 MSG_CHANNEL_CLOSE: Channel._handle_close,
2209 }
2210