1 from __future__ import print_function
3 from code import InteractiveConsole
9 from eventlet import hubs
10 from eventlet.support import greenlets, get_errno, six
14 except AttributeError:
18 except AttributeError:
22 class FileProxy(object):
23 def __init__(self, f):
32 def write(self, data, *a, **kw):
34 self.f.write(data, *a, **kw)
37 def readline(self, *a):
38 line = self.f.readline(*a).replace(b'\r\n', b'\n')
41 def __getattr__(self, attr):
42 return getattr(self.f, attr)
45 # @@tavis: the `locals` args below mask the built-in function. Should
47 class SocketConsole(greenlets.greenlet):
48 def __init__(self, desc, hostport, locals):
49 self.hostport = hostport
52 self.desc = FileProxy(desc)
53 greenlets.greenlet.__init__(self)
57 console = InteractiveConsole(self.locals)
63 def switch(self, *args, **kw):
64 self.saved = sys.stdin, sys.stderr, sys.stdout
65 sys.stdin = sys.stdout = sys.stderr = self.desc
66 greenlets.greenlet.switch(self, *args, **kw)
69 sys.stdin, sys.stderr, sys.stdout = self.saved
72 # restore the state of the socket
74 print("backdoor closed to %s:%s" % self.hostport)
77 def backdoor_server(sock, locals=None):
78 """ Blocking function that runs a backdoor server on the socket *sock*,
79 accepting connections and running backdoor consoles for each client that
82 The *locals* argument is a dictionary that will be included in the locals()
83 of the interpreters. It can be convenient to stick important application
86 print("backdoor server listening on %s:%s" % sock.getsockname())
90 socketpair = sock.accept()
91 backdoor(socketpair, locals)
92 except socket.error as e:
93 # Broken pipe means it was shutdown
94 if get_errno(e) != errno.EPIPE:
100 def backdoor(conn_info, locals=None):
101 """Sets up an interactive console on a socket with a single connected
102 client. This does not block the caller, as it spawns a new greenlet to
103 handle the console. This is meant to be called from within an accept loop
104 (such as backdoor_server).
106 conn, addr = conn_info
108 print("backdoor to %s:%s" % (host, port))
109 fl = conn.makefile("rw")
110 console = SocketConsole(fl, (host, port), locals)
112 hub.schedule_call_global(0, console.switch)
115 if __name__ == '__main__':
116 backdoor_server(eventlet.listen(('127.0.0.1', 9000)), {})