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