/usr/lib/python2.7/dist-packages/eventlet/backdoor.py is in python-eventlet 0.20.0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | from __future__ import print_function
from code import InteractiveConsole
import errno
import socket
import sys
import errno
import traceback
import eventlet
from eventlet import hubs
from eventlet.support import greenlets, get_errno
try:
sys.ps1
except AttributeError:
sys.ps1 = '>>> '
try:
sys.ps2
except AttributeError:
sys.ps2 = '... '
class FileProxy(object):
def __init__(self, f):
self.f = f
def isatty(self):
return True
def flush(self):
pass
def write(self, data, *a, **kw):
self.f.write(data, *a, **kw)
self.f.flush()
def readline(self, *a):
return self.f.readline(*a).replace('\r\n', '\n')
def __getattr__(self, attr):
return getattr(self.f, attr)
# @@tavis: the `locals` args below mask the built-in function. Should
# be renamed.
class SocketConsole(greenlets.greenlet):
def __init__(self, desc, hostport, locals):
self.hostport = hostport
self.locals = locals
# mangle the socket
self.desc = FileProxy(desc)
greenlets.greenlet.__init__(self)
def run(self):
try:
console = InteractiveConsole(self.locals)
console.interact()
finally:
self.switch_out()
self.finalize()
def switch(self, *args, **kw):
self.saved = sys.stdin, sys.stderr, sys.stdout
sys.stdin = sys.stdout = sys.stderr = self.desc
greenlets.greenlet.switch(self, *args, **kw)
def switch_out(self):
sys.stdin, sys.stderr, sys.stdout = self.saved
def finalize(self):
# restore the state of the socket
self.desc = None
if len(self.hostport) >= 2:
host = self.hostport[0]
port = self.hostport[1]
print("backdoor closed to %s:%s" % (host, port,))
else:
print('backdoor closed')
def backdoor_server(sock, locals=None):
""" Blocking function that runs a backdoor server on the socket *sock*,
accepting connections and running backdoor consoles for each client that
connects.
The *locals* argument is a dictionary that will be included in the locals()
of the interpreters. It can be convenient to stick important application
variables in here.
"""
listening_on = sock.getsockname()
if sock.family == socket.AF_INET:
# Expand result to IP + port
listening_on = '%s:%s' % listening_on
elif sock.family == socket.AF_INET6:
ip, port, _, _ = listening_on
listening_on = '%s:%s' % (ip, port,)
# No action needed if sock.family == socket.AF_UNIX
print("backdoor server listening on %s" % (listening_on,))
try:
try:
while True:
socketpair = sock.accept()
backdoor(socketpair, locals)
except socket.error as e:
# Broken pipe means it was shutdown
if get_errno(e) != errno.EPIPE:
raise
finally:
sock.close()
def backdoor(conn_info, locals=None):
"""Sets up an interactive console on a socket with a single connected
client. This does not block the caller, as it spawns a new greenlet to
handle the console. This is meant to be called from within an accept loop
(such as backdoor_server).
"""
conn, addr = conn_info
if conn.family == socket.AF_INET:
host, port = addr
print("backdoor to %s:%s" % (host, port))
elif conn.family == socket.AF_INET6:
host, port, _, _ = addr
print("backdoor to %s:%s" % (host, port))
else:
print('backdoor opened')
fl = conn.makefile("rw")
console = SocketConsole(fl, addr, locals)
hub = hubs.get_hub()
hub.schedule_call_global(0, console.switch)
if __name__ == '__main__':
backdoor_server(eventlet.listen(('127.0.0.1', 9000)), {})
|