67
75
# TODO: Figure out the host name the console server is running on.
68
76
host = req.hostname
70
# Find an available port on the server.
78
# Start the console server (port, magic)
79
# trampoline usage: tramp uid jail_dir working_dir script_path args
80
# console usage: python-console port magic
81
# TODO: Cleanup (don't use os.system)
82
# TODO: Pass working_dir as argument, let console cd to it
83
# Use "&" to run as a background process
84
cmd = ' '.join([trampoline_path, str(uid), jail_path, console_dir,
85
python_path, console_path, str(port), str(magic), "&"])
86
#req.write(cmd + '\n')
80
magic = md5.new(uuid.uuid4().bytes).digest().encode('hex')
82
# Try to find a free port on the server.
83
# Just try some random ports in the range [3000,8000)
84
# until we either succeed, or give up. If you think this
85
# sounds risky, it isn't:
86
# For N ports (e.g. 5000) with k (e.g. 100) in use, the
87
# probability of failing to find a free port in t (e.g. 5) tries
88
# is (k / N) ** t (e.g. 3.2*10e-9).
92
port = int(random.uniform(3000, 8000))
94
# Start the console server (port, magic)
95
# trampoline usage: tramp uid jail_dir working_dir script_path args
96
# console usage: python-console port magic
97
# TODO: Pass working_dir as argument, let console cd to it
98
cmd = ' '.join([trampoline_path, str(uid), jail_path,
99
console_dir, python_path, console_path,
100
str(port), str(magic)])
102
print >> sys.stderr, cmd
104
print >> sys.stderr, res
113
raise Exception, "unable to find a free port!"
89
115
# Return port, magic
90
116
req.write(cjson.encode({"host": host, "port": port, "magic": magic}))
99
125
fields = req.get_fieldstorage()
101
127
host = fields.getfirst("host").value
102
port = fields.getfirst("port").value
128
port = int(fields.getfirst("port").value)
103
129
digest = fields.getfirst("digest").value
104
130
except AttributeError:
105
131
# Any of the getfirsts returned None
110
136
except AttributeError:
113
# Open an HTTP connection
114
url = ("http://" + urllib.quote(host) + ":" + urllib.quote(port)
116
body = ("digest=" + urllib.quote(digest)
117
+ "&text=" + urllib.quote(text))
118
headers = {"Content-Type": "application/x-www-form-urlencoded"}
120
conn = httplib.HTTPConnection(host, port)
122
req.throw_error(req.HTTP_BAD_REQUEST)
123
conn.request("POST", url, body, headers)
125
response = conn.getresponse()
139
msg = {'cmd':'chat', 'text':text, 'digest':digest}
141
sok = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
142
sok.connect((host, port))
143
sok.send(cjson.encode(msg))
145
buf = cStringIO.StringIO()
150
blk = conn.recv(1024, socket.MSG_DONTWAIT)
152
# Exception thrown if it WOULD block (but we
153
# told it not to wait) - ie. we are done
127
req.status = response.status
128
# NOTE: Ignoring arbitrary headers returned by the server
129
# Probably not necessary to proxy them
130
req.content_type = response.getheader("Content-Type", "text/plain")
131
req.write(response.read())
159
req.content_type = "text/plain"