1 from __future__ import print_function
3 from code import InteractiveConsole
9 from eventlet import hubs
10 from eventlet.support import greenlets, get_errno
14 except AttributeError:
18 except AttributeError:
22 class FileProxy(object):
23 def __init__(self, f):
32 def write(self, data, *a, **kw):
33 self.f.write(data, *a, **kw)
36 def readline(self, *a):
37 return self.f.readline(*a).replace('\r\n', '\n')
39 def __getattr__(self, attr):
40 return getattr(self.f, attr)
43 # @@tavis: the `locals` args below mask the built-in function. Should
45 class SocketConsole(greenlets.greenlet):
46 def __init__(self, desc, hostport, locals):
47 self.hostport = hostport
50 self.desc = FileProxy(desc)
51 greenlets.greenlet.__init__(self)
55 console = InteractiveConsole(self.locals)
61 def switch(self, *args, **kw):
62 self.saved = sys.stdin, sys.stderr, sys.stdout
63 sys.stdin = sys.stdout = sys.stderr = self.desc
64 greenlets.greenlet.switch(self, *args, **kw)
67 sys.stdin, sys.stderr, sys.stdout = self.saved
70 # restore the state of the socket
72 print("backdoor closed to %s:%s" % self.hostport)
75 def backdoor_server(sock, locals=None):
76 """ Blocking function that runs a backdoor server on the socket *sock*,
77 accepting connections and running backdoor consoles for each client that
80 The *locals* argument is a dictionary that will be included in the locals()
81 of the interpreters. It can be convenient to stick important application
84 print("backdoor server listening on %s:%s" % sock.getsockname())
88 socketpair = sock.accept()
89 backdoor(socketpair, locals)
90 except socket.error as e:
91 # Broken pipe means it was shutdown
92 if get_errno(e) != errno.EPIPE:
98 def backdoor(conn_info, locals=None):
99 """Sets up an interactive console on a socket with a single connected
100 client. This does not block the caller, as it spawns a new greenlet to
101 handle the console. This is meant to be called from within an accept loop
102 (such as backdoor_server).
104 conn, addr = conn_info
106 print("backdoor to %s:%s" % (host, port))
107 fl = conn.makefile("rw")
108 console = SocketConsole(fl, (host, port), locals)
110 hub.schedule_call_global(0, console.switch)
113 if __name__ == '__main__':
114 backdoor_server(eventlet.listen(('127.0.0.1', 9000)), {})