/usr/lib/cgi-bin/fp-registrar.cgi is in flashproxy-facilitator 1.7-4.
This file is owned by root:root, with mode 0o755.
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 | #!/usr/bin/env python
import cgi
import os
import socket
import sys
import urllib
from flashproxy import fac
FACILITATOR_ADDR = ("127.0.0.1", 9002)
def output_status(status):
print """\
Status: %d\r
\r""" % status
def exit_error(status):
output_status(status)
sys.exit()
# Send a base64-encoded client address to the registration daemon.
def send_url_reg(reg):
# Translate from url-safe base64 alphabet to the standard alphabet.
reg = reg.replace('-', '+').replace('_', '/')
return fac.put_reg_proc(["fp-reg-decrypt"], reg)
method = os.environ.get("REQUEST_METHOD")
remote_addr = (os.environ.get("REMOTE_ADDR"), None)
path_info = os.environ.get("PATH_INFO") or "/"
if not method or not remote_addr[0]:
exit_error(400)
# Print the HEAD part of a URL-based registration response, or exit with an
# error if appropriate.
def url_reg(reg):
try:
if send_url_reg(reg):
output_status(204)
else:
exit_error(400)
except Exception:
exit_error(500)
def do_head():
path_parts = [x for x in path_info.split("/") if x]
if len(path_parts) == 2 and path_parts[0] == "reg":
url_reg(path_parts[1])
else:
exit_error(400)
def do_get():
"""Parses flashproxy polls.
Example: GET /?r=1&client=7.1.43.21&client=1.2.3.4&transport=webrtc&transport=websocket
"""
fs = cgi.FieldStorage()
path_parts = [x for x in path_info.split("/") if x]
if len(path_parts) == 2 and path_parts[0] == "reg":
url_reg(path_parts[1])
elif len(path_parts) == 0:
# Check for recent enough flash proxy protocol.
r = fs.getlist("r")
if len(r) != 1 or r[0] != "1":
exit_error(400)
# 'transports' (optional) can be repeated and carries
# transport names.
transport_list = fs.getlist("transport")
if not transport_list:
transport_list = ["websocket"]
try:
reg = fac.get_reg(FACILITATOR_ADDR, remote_addr, transport_list) or ""
except Exception:
exit_error(500)
# Allow XMLHttpRequest from any domain. http://www.w3.org/TR/cors/.
print """\
Status: 200\r
Content-Type: application/x-www-form-urlencoded\r
Cache-Control: no-cache\r
Access-Control-Allow-Origin: *\r
\r"""
sys.stdout.write(urllib.urlencode(reg))
else:
exit_error(400)
def do_post():
"""Parse client registration."""
if path_info != "/":
exit_error(400)
# We treat sys.stdin as being a bunch of newline-separated query strings. I
# think that this is technically a violation of the
# application/x-www-form-urlencoded content-type the client likely used, but
# it at least matches the standard multiline registration format used by
# fp-reg-decryptd.
try:
regs = list(fac.read_client_registrations(sys.stdin.read(), defhost=remote_addr[0]))
except ValueError:
exit_error(400)
for reg in regs:
# XXX need to link these registrations together, so that
# when one is answerered (or errors) the rest are invalidated.
if not fac.put_reg(FACILITATOR_ADDR, reg.addr, reg.transport):
exit_error(500)
print """\
Status: 200\r
\r"""
if method == "HEAD":
do_head()
elif method == "GET":
do_get()
elif method == "POST":
do_post()
else:
exit_error(405)
|