blob: bda8afe5f1faee0f4a41cce4ecc3b77d8c5ccc75 [file] [log] [blame]
#!/usr/bin/env python
"""
Flash Socket Policy Server.
- Starts Flash socket policy file server.
- Defaults to port 843.
- NOTE: Most operating systems require administrative privileges to use
ports under 1024.
$ ./policyserver.py [options]
"""
"""
Also consider Adobe's solutions:
http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
"""
from multiprocessing import Process
from optparse import OptionParser
import SocketServer
import logging
# Set address reuse for all TCPServers
SocketServer.TCPServer.allow_reuse_address = True
# Static socket policy file string.
# NOTE: This format is very strict. Edit with care.
socket_policy_file = """\
<?xml version="1.0"?>\
<!DOCTYPE cross-domain-policy\
SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">\
<cross-domain-policy>\
<allow-access-from domain="*" to-ports="*"/>\
</cross-domain-policy>\0"""
class PolicyHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
Returns a policy file when requested.
"""
def handle(self):
"""Send policy string if proper request string is received."""
# get some data
# TODO: make this more robust (while loop, etc)
self.data = self.request.recv(1024).rstrip('\0')
logging.debug("%s wrote:%s" % (self.client_address[0], repr(self.data)))
# if policy file request, send the file.
if self.data == "<policy-file-request/>":
logging.info("Policy server request from %s." % (self.client_address[0]))
self.request.send(socket_policy_file)
else:
logging.info("Policy server received junk from %s: \"%s\"" % \
(self.client_address[0], repr(self.data)))
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def serve_forever(self):
"""Handle one request at a time until shutdown or keyboard interrupt."""
try:
SocketServer.BaseServer.serve_forever(self)
except KeyboardInterrupt:
return
def main():
"""Run socket policy file servers."""
usage = "Usage: %prog [options]"
parser = OptionParser(usage=usage)
parser.add_option("", "--host", dest="host", metavar="HOST",
default="localhost", help="bind to HOST")
parser.add_option("-p", "--port", dest="port", metavar="PORT",
default=843, type="int", help="serve on PORT")
parser.add_option("-d", "--debug", dest="debug", action="store_true",
default=False, help="debugging output")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
default=False, help="verbose output")
(options, args) = parser.parse_args()
# setup logging
if options.debug:
lvl = logging.DEBUG
elif options.verbose:
lvl = logging.INFO
else:
lvl = logging.WARNING
logging.basicConfig(level=lvl, format="%(levelname)-8s %(message)s")
# log basic info
logging.info("Flash Socket Policy Server. Use ctrl-c to exit.")
# create policy server
logging.info("Socket policy serving on %s:%d." % (options.host, options.port))
policyd = ThreadedTCPServer((options.host, options.port), PolicyHandler)
# start server
policy_p = Process(target=policyd.serve_forever)
policy_p.start()
while policy_p.is_alive():
try:
policy_p.join(1)
except KeyboardInterrupt:
logging.info("Stopping test server...")
if __name__ == "__main__":
main()