##// END OF EJS Templates
Fix import of socketserver on Python 3....
Thomas Kluyver -
Show More
@@ -1,88 +1,91 b''
1 #
1 #
2 # This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1.
2 # This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1.
3 # Original Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
3 # Original Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
4 # Edits Copyright (C) 2010 The IPython Team
4 # Edits Copyright (C) 2010 The IPython Team
5 #
5 #
6 # Paramiko is free software; you can redistribute it and/or modify it under the
6 # Paramiko is free software; you can redistribute it and/or modify it under the
7 # terms of the GNU Lesser General Public License as published by the Free
7 # terms of the GNU Lesser General Public License as published by the Free
8 # Software Foundation; either version 2.1 of the License, or (at your option)
8 # Software Foundation; either version 2.1 of the License, or (at your option)
9 # any later version.
9 # any later version.
10 #
10 #
11 # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
11 # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY
12 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 # details.
14 # details.
15 #
15 #
16 # You should have received a copy of the GNU Lesser General Public License
16 # You should have received a copy of the GNU Lesser General Public License
17 # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
17 # along with Paramiko; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA.
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA.
19
19
20 """
20 """
21 Sample script showing how to do local port forwarding over paramiko.
21 Sample script showing how to do local port forwarding over paramiko.
22
22
23 This script connects to the requested SSH server and sets up local port
23 This script connects to the requested SSH server and sets up local port
24 forwarding (the openssh -L option) from a local port through a tunneled
24 forwarding (the openssh -L option) from a local port through a tunneled
25 connection to a destination reachable from the SSH server machine.
25 connection to a destination reachable from the SSH server machine.
26 """
26 """
27
27
28 from __future__ import print_function
28 from __future__ import print_function
29
29
30 import logging
30 import logging
31 import select
31 import select
32 import SocketServer
32 try: # Python 3
33 import socketserver
34 except ImportError: # Python 2
35 import SocketServer as socketserver
33
36
34 logger = logging.getLogger('ssh')
37 logger = logging.getLogger('ssh')
35
38
36 class ForwardServer (SocketServer.ThreadingTCPServer):
39 class ForwardServer (socketserver.ThreadingTCPServer):
37 daemon_threads = True
40 daemon_threads = True
38 allow_reuse_address = True
41 allow_reuse_address = True
39
42
40
43
41 class Handler (SocketServer.BaseRequestHandler):
44 class Handler (socketserver.BaseRequestHandler):
42
45
43 def handle(self):
46 def handle(self):
44 try:
47 try:
45 chan = self.ssh_transport.open_channel('direct-tcpip',
48 chan = self.ssh_transport.open_channel('direct-tcpip',
46 (self.chain_host, self.chain_port),
49 (self.chain_host, self.chain_port),
47 self.request.getpeername())
50 self.request.getpeername())
48 except Exception as e:
51 except Exception as e:
49 logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host,
52 logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host,
50 self.chain_port,
53 self.chain_port,
51 repr(e)))
54 repr(e)))
52 return
55 return
53 if chan is None:
56 if chan is None:
54 logger.debug('Incoming request to %s:%d was rejected by the SSH server.' %
57 logger.debug('Incoming request to %s:%d was rejected by the SSH server.' %
55 (self.chain_host, self.chain_port))
58 (self.chain_host, self.chain_port))
56 return
59 return
57
60
58 logger.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
61 logger.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
59 chan.getpeername(), (self.chain_host, self.chain_port)))
62 chan.getpeername(), (self.chain_host, self.chain_port)))
60 while True:
63 while True:
61 r, w, x = select.select([self.request, chan], [], [])
64 r, w, x = select.select([self.request, chan], [], [])
62 if self.request in r:
65 if self.request in r:
63 data = self.request.recv(1024)
66 data = self.request.recv(1024)
64 if len(data) == 0:
67 if len(data) == 0:
65 break
68 break
66 chan.send(data)
69 chan.send(data)
67 if chan in r:
70 if chan in r:
68 data = chan.recv(1024)
71 data = chan.recv(1024)
69 if len(data) == 0:
72 if len(data) == 0:
70 break
73 break
71 self.request.send(data)
74 self.request.send(data)
72 chan.close()
75 chan.close()
73 self.request.close()
76 self.request.close()
74 logger.debug('Tunnel closed ')
77 logger.debug('Tunnel closed ')
75
78
76
79
77 def forward_tunnel(local_port, remote_host, remote_port, transport):
80 def forward_tunnel(local_port, remote_host, remote_port, transport):
78 # this is a little convoluted, but lets me configure things for the Handler
81 # this is a little convoluted, but lets me configure things for the Handler
79 # object. (SocketServer doesn't give Handlers any way to access the outer
82 # object. (SocketServer doesn't give Handlers any way to access the outer
80 # server normally.)
83 # server normally.)
81 class SubHander (Handler):
84 class SubHander (Handler):
82 chain_host = remote_host
85 chain_host = remote_host
83 chain_port = remote_port
86 chain_port = remote_port
84 ssh_transport = transport
87 ssh_transport = transport
85 ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever()
88 ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever()
86
89
87
90
88 __all__ = ['forward_tunnel']
91 __all__ = ['forward_tunnel']
General Comments 0
You need to be logged in to leave comments. Login now