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