Sorry it took me so long to post this, but Wordpress 2.5 doesn’t seem to like me trying to upload gz/zip files, so I had to upload the source manually.

Well, it’s been months since I promised to post some usable socket policy service code, so I will.

The script here is meant to serve as a good starting point for people whose servers need to allow flash clients to make socket connections. I have not actually used this exact code in a production environment, but I have been using code that is 99% identical for a while now. I am confident that any blatant flaws are the result of simple copy-paste errors as I compiled the package. Please let me know if you find any.

I have however, stress tested the heck out of this service. One instance successfully served up over 16000 policy file requests fed into it as rapidly as I could send them. The same networking code has also handled requests from at least 100 different hosts at roughly the same time.

Everything has been combined into a single cli php script that requires no special installation. Just plop it down on the server and run it as root. It will take care of the rest. The config defaults should be safe, but you probably want to specify them more clearly – just to be safe.

The daemon is made of three classes:

  • Logger – A rudimentary log file management class that I copy from project to project in one form or another. The included version is stripped down from some of the other versions I’ve written, and I’m planning on releasing a more feature-rich version in the future.
  • Daemon – A simple class for daemonizing a process. Adapted and re-adapted countless times from an original php4 class I found on the net a few years ago by some guy named Seth (whose email domain no longer exists).
  • FlashPolicyService – The meat and potatoes, a child of Daemon. Mostly, this is just the requisite networking code and glue to make everything work together.

As with any of my other code, this is licensed under CC Attribution 3.0.

Download:

Source code after the jump.

#!/usr/local/bin/php
<?php
/**
 * Flash Policy Service v0.9.c
 *
 * This script listens for <policy-file-request/> on port 843 and serves up
 * an xml crossdomain policy file. This sort of service is necessary if any
 * flash content is going to connect to sockets on the running host.
 *
 * I have made every effort to package everything you need into a single
 * file here, even though it could easily have been split into 3 or more
 * scripts.
 *
 * Requirements:
 *  - PHP 5 with sockets, pcntl, and posix extensions
 *  - Root access (to bind to a <1024 port)
 *
 * Use:
 *  Simply execute the script from the command line as root:
 *    # ./FlashPolicyService.php
 *  You can enable debug mode by invoking the script with '-d' as a parameter:
 *    # ./FlashPolicyService.php -d
 *  To stop the daemon, simply send it a SIGTERM and it should attempt to
 *  exit cleanly.
 *
 *  If you get 'bad interpreter' errors or the like, change the #! line to
 *  reflect the actual installed location of your php cli.
 *
 * Configuration:
 *  At present, there aren't very many config options. Simply edit the
 *  section immediately following this header. Options are commented.
 *
 * License:
 *  This code is made available under a Creative Commons Attribution 3.0
 *  License. Basically, you can use it however you like, but I would
 *  appreciate some credit when you do.
 *
 * Disclaimer:
 *  I make no guarantees that this code won't make your server explode in a
 *  shower of blue flames. However, I don't expect that it will. I am actually
 *  confident that this code will be helpful.
 *
 *  That said, this is still my beta release. If you find any bugs, please
 *  let me know so I can fix them.
 *
 * - Ammon Lauritzen [Apr 21, '08]
 *   http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/
 *
 * Changelog
 * 0.9.c
 *   - Fixed some typoes that were the result of how I combined everything
 *     into a single file. Thanks Alex!
 * 0.9.b
 *   - Original version to be posted at this url.
 * 0.9.a
 *   - Original proof of concept code posted online.
 */

/*** Config ***/

// where should we save the log output?
$log_filename = "/tmp/flash-policy.log";

// uncomment these lines to choose which user to run the daemon as
// default behavior is to look up and attempt to run as 'nobody'
# $daemon_uid = 99;
# $daemon_gid = 99;

// set this if you want to use an external file in stead of the default
$xml_filename = "";
$default_xml =
	'<'.'?xml version="1.0" encoding="UTF-8"?'.'>'.
    '<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd">'.
        '<allow-access-from domain="*" to-ports="*" secure="false" />'.
        '<site-control permitted-cross-domain-policies="all" />'.
    '</cross-domain-policy>';

/*** You shouldn't have to edit anything below here ***/

/////////////////////////////////////////////////////////////////////////////
class Logger {
	public function __construct( $logfile ) {
        $this->logfile = $logfile;
        $this->open_log();
    }// end: constructor

    public function __destruct() {
        @fflush( $this->fh );
        @fclose( $this->fh );
    }// end: destructor

    public function log( $msg ) {
		// deal with redundant log spam
		if( $msg == $this->last_msg ) {
			$this->last_msg_count++;
			return;
		} else if( $this->last_msg_count ) {
			$this->write( "Last message repeated ".$this->last_msg_count." times." );
		}
		$this->lasg_msg = $msg;
		$this->last_msg_count = 0;

		// actually write the log message out
		$this->write( $msg );
	}// end: log

	private function write( $msg ) {
        $msg = sprintf("[%s] %s\\n",date("y-m-d H:i:s"),$msg);
        $succ = @fwrite( $this->fh, $msg );
        if( $succ === FALSE ) {
            echo $msg;
        }
    }// end: write

	private function open_log() {
        if( !file_exists($this->logfile) ) {
            touch( $this->logfile );
            chmod( $this->logfile, 0664 );
        }
        $this->fh = @fopen( $this->logfile, "a" );
    }
}// end: logger class

/////////////////////////////////////////////////////////////////////////////
class Daemon {
	public function __construct() {
		error_reporting(0);
		set_time_limit(0);

		global $log_filename, $pid_filename;
		$this->logger = new Logger( $log_filename );
		$this->pid_filename = $pid_filename;

		$this->log_tag = $this->daemon_tag = "launcher";
		$this->debug( "constructed", $this->daemon_tag );
	}// end: constructor

	public function __destruct() {
		$this->debug( "destructing", $this->daemon_tag );
	}// end: destructor

	protected function log( $msg, $tag = false ) {
		if( $tag == false )
			$tag = $this->log_tag;
		$this->logger->log( $tag.": ".$msg );
	}// end: log
	protected function debug( $msg, $tag = false ) {
		if( DEBUG )
			$this->log( $msg, $tag );
	}// end: debug

	protected function main() {
		$this->log( "override main() in daemon subclass", $this->daemon_tag );
		$this->stop();
	}// end: main

	public function start() {
		$this->log( "starting daemon", $this->daemon_tag );
		if( !$this->_start() ) {
			$this->log( "unable to start daemon", $this->daemon_tag );
			return;
		}

		// report execution details
		$this->log( "uid = ".posix_getuid().", gid = ".posix_getgid() );
		$this->log( "cwd = ".getcwd() );

		// invoke main loop
		$this->running = true;
		while( $this->running ) {
			$this->main();
		}
	}// end: start
	private function _start() {
		if( !$this->_fork() ) {
			return false;
		}// end: try to fork

		if( !posix_setsid() ) {
			$this->log( "unable to setsid()", $this->daemon_tag );
			return false;
		}// end: try to set sid

		if( !$this->_suid() ) {
			return false;
		}// end: try to set uid

		// register signal handler
		declare(ticks = 1);
		pcntl_signal( SIGTERM, array(&$this, "on_sigterm") );
		// chdir somewhere moderately safe by default
		chdir( '/tmp' );
		return true;
	}// end: _start
	private function _fork() {
		$this->log( "forking...", $this->daemon_tag );
		$pid = pcntl_fork();
		if( $pid == -1 ) {
			// error
			$this->log( "unable to fork", $this->daemon_tag );
			return false;
		} else if( $pid ) {
			// parent
			$this->debug( "done with parent", $this->daemon_tag );
			exit( 0 );
		} else {
			// child
			$this->daemon_tag = "daemon";
			$this->child = true;
			$this->pid = posix_getpid();
			$this->debug( "child pid = ".$this->pid );
			return true;
		}
	}// end: _fork
	private function _suid() {
		global $daemon_uid, $daemon_gid;
		if( !isset($daemon_uid) || !isset($daemon_gid) ) {
			// we didn't get a uid/gid, try to make one up
			$this->debug( "searching for info on 'nobody'", $this->daemon_tag );
			$res = posix_getpwnam("nobody");
			if( $res !== FALSE ) {
				$uid = $res['uid'];
				$gid = $res['gid'];
			} else {
				// the 'nobody' user doesn't exist on this system, refuse
				// to daemonize as root
				$this->log( "unable to find info on 'nobody' user", $this->daemon_tag );
				return false;
			}
		} else {
			$this->debug( "got uid/gid of $daemon_uid/$daemon_gid", $this->daemon_tag );
			$uid = $daemon_uid;
			$gid = $daemon_gid;
		}
		// actually try to switch now
		if( !posix_setgid($gid) ) {
			$this->log( "unable to set gid to ".$gid, $this->daemon_tag );
			return false;
		} else if( !posix_setuid($uid) ) {
			$this->log( "unable to set uid to ".$uid, $this->daemon_tag );
			return false;
		} else {
			return true;
		}
	}// end: _suid

	public function stop() {
		$this->log( "stopping daemon", $this->daemon_tag );
		$this->running = false;
	}// end: stop

	protected function on_sigterm( $sig ) {
		if( $sig == SIGTERM ) {
			$this->log( "got SIGTERM", $this->daemon_tag );
			$this->stop();
			exit( 0 );
		}
	}// end: on_sigterm
}// end: daemon class

/////////////////////////////////////////////////////////////////////////////
class FlashPolicyService extends Daemon {
	public function __construct() {
		parent::__construct();
		$this->log_tag = "fps";
		$this->debug( "constructing" );

		$this->connections = array();
		$this->request_str = "<policy-file-request/>";
		$this->port = 843;

		// get our xml
		global $xml_filename, $default_xml;
		if( strlen($xml_filename) == 0 || !file_exists($xml_filename) ) {
			$this->log( "unable to read xml from '$xml_filename', using default" );
			$this->xml = $default_xml;
		} else {
			$this->log( "reading policy xml from $xml_filename" );
			$this->xml = file_get_contents( $xml_filename );
		}
		$this->debug( "policy xml: ".$this->xml );
		// make sure we're null terminated
		$this->xml = trim($this->xml)."\\n\\0";

		// and get going
		$this->init();
	}// end: constructor

	public function __destruct() {
		parent::__destruct();
		if( $this->sock )
			@fclose($this->sock);
	}// end: destructor

	private function init() {
		$this->debug( "init..." );
		if( $this->check_socket() ) {
			parent::start();
		} else {
			$this->log( "not starting daemon" );
		}
	}// end: init

	protected function main() {
		if( $this->sock ) {
			while( true ) {
				$this->accept_socket();
			}
		} else {
			$this->log( "server socket is closed?!" );
			parent::stop();
		}
		// paranoia to keep from absolutely hosing cpu if something goes wrong
		usleep( 10000 );	// 10ms
	}// end: main

	private function check_socket() {
		$this->sock = @socket_create( AF_INET, SOCK_STREAM, SOL_TCP );
		if( !$this->sock ) {
			$this->log( "unable to create socket" );
		} else {
			$succ = @socket_bind( $this->sock, "0.0.0.0", $this->port );
			if( !$succ ) {
				$this->log( "unable to bind to port ".$this->port );
			} else {
				$backlog = 100;
				$succ = @socket_listen( $this->sock, $backlog );
				if( !$succ ) {
					$this->log( "unable to listen with backlog of $backlog" );
				} else {
					// everything's good
					return true;
				}
			}// end: able to bind
		}// end: able to create socket

		// if we got here, it's an error. abort.
		$errno = socket_last_error( $this->sock );
		$errstr = socket_strerror( $errno );
		$this->log( "socket error: $errno: $errstr" );
		return false;
	}// end: check_socket

	private function accept_socket() {
		$r_socks = array_merge( array($this->sock), $this->connections );
		$this->debug( "selecting on ".count($r_socks)." sockets" );

		// block until something interesting happens
		$select = @socket_select( $r_socks, $w_socks = NULL, $e_socks = NULL, NULL );
		if( !$select )
			return;

		// did we get a new connection?
		if( in_array($this->sock, $r_socks) ) {
			$conn = @socket_accept( $this->sock );
			if( $conn !== false )
				@socket_getpeername( $conn, $addr );
			$this->log( "connection accepted from $addr, $conn" );
			$this->connections[] = $conn;
		}// end: got a new connection

		// check for policy requests
		foreach( $r_socks as $conn ) {
			// ignore the server socket
			if( $conn == $this->sock )
				continue;

			// read from the client
			$data = @socket_read( $conn, 1024 );
			if( $data === FALSE ) {
				$this->log( "got disconnect from $conn" );
			}// end: client closed connection
			else {
				$this->debug( "read '".trim($data)."' from $conn" );
				if( strpos($data, $this->request_str) !== FALSE ) {
					$this->log( "sending policy xml to $conn" );
					@socket_write( $conn, $this->xml );
				} else {
					$this->log( "got invalid request from $conn" );
				}
			}// end: got data from the client

			// and always disconnect after having read something, whether
			// it was a valid request or not - especially if it wasn't ;)
			@socket_close( $conn );
			$key = array_search( $conn, $this->connections );
			if( $key !== FALSE )
				unset( $this->connections[$key] );
		}// end: foreach socket
	}// end: accept_socket

}// end: flash policy service class

/////////////////////////////////////////////////////////////////////////////
/**
 * Actual execution code here. This checks if the php install has all of our
 * requisite extensions, makes sure we're launching as root, and checks if
 * debug mode was requested before actually starting the daemon.
 */

// make sure we have required extensions
$required_extensions = array( "sockets", "posix", "pcntl" );
$missing_extension = false;
foreach( $required_extensions as $ext ) {
	if( !extension_loaded($ext) ) {
		echo "Missing required php extension '$ext'.\n";
		$missing_extension = true;
	}
}
if( $missing_extension ) {
	exit( 1 );
}

// make sure we launch as root, otherwise we can't bind to 843
if( posix_getuid() != 0 || posix_getgid() != 0 ) {
	echo "Policy service must be started as root.\n";
	exit( 1 );
}

// see if we're in debug mode
define( "DEBUG", in_array('-d',$argv) );

// start the daemon
$fps = new FlashPolicyService();
?>

43 Responses to “flash policy service daemon”

  1. [...] 0.9.b is available now. Share and Enjoy: These icons link to social bookmarking sites where readers can share and [...]

  2. [...] April 22nd, 2008, I released a much better, much more reliable version of this daemon. Head over there for more details and source code. Share and Enjoy: These icons link to social bookmarking sites [...]

  3. Kee says:

    Thanks,
    I have a PHP Parse error when I run ./FlashPolicyService.php.
    The message is:
    PHP Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUCTION or T_VAR or ‘}’ in /root/flashpolicyd/FlashPolicyService.php on line 73
    Content-type: text/html
    X-Powered-By: PHP/4.3.9

    Does anybody know how to run this?
    Thanks in advance.

  4. Ammon says:

    Yeah, this class requires PHP5 to work – I even said so in the requirements.

    PHP 5.0.0 is almost four years old now, there’s really not any good reason to continue running PHP4 on production servers – especially something so old as 4.3.9.

  5. Kee says:

    I didn’t even noticed the requirements from code.
    Thanks, Ammon.

  6. Markus says:

    Hi….I know this is a little late to be adding a comment…I have a socket connecting to a Java server and I added the code to send the xml response to the swf….everything works fine in IE7 but not in FF. It just seems to sit there waiting. Any ideas?
    Thanks.

  7. Ammon says:

    Curious. Normally the IE client has harder times connecting to things than the FF one does. I’d make sure you have the same version of the player for each browser (since they are separate installs).

    You might also want to try with debug players and policy file logging turned on. There are instructions available at http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security_05.html

    Good luck, eh?

  8. [...] serves the aproppriate Policy File, the PHP Daemon solution that is provided on the ASSQL page (http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/) is not an option as it needs certain php extensions that are not available on a windows system, [...]

  9. lee says:

    I can’t find a php4 alternative solution to the System Daemon, but a quick rip to some php4 friendly syntax, and I’ve finally managed to establish a socket connection since the security update!! Thank you Ammon, I would love php5, but server admin refuses to update, agh.

  10. Ammon says:

    lee: Sorry, the php4 version of the daemon that you’d pasted in here didn’t come through cleanly – wordpress chopped it all to pieces :(

  11. alejandro says:

    Hello there!, have anyone tried to run this in a chroot? is getting rather complicated and i’m not sure what i’m missing… if anyone have, could you please send me some pointers?

    regards,

  12. Ammon says:

    alejandro: There are two ways of handling chroot.

    1) The easy way, write the program to chroot() once it’s finished launching. Unfortunately, my daemon doesn’t handle this yet. It’s on the list of things I’d like to support in a future version.

    2) The complicated way, works with software that doesn’t have native jail support. There is a lot of effort involved in setting up the environment. Personally, I’ve always had bad luck trying to configure jails by hand. I like jailkit, it takes most of the pain for you.

  13. Alex says:

    Well, I in fact found a typo: Due to a typo, the posix_setuid() call is useless and the daemon always runs at root *cough*:

    } else if( !posix_setuid($this->uid) ) {

    and $this->uid is unset, defaulting to int 0.

    Simply remove the “this->” part and you are fine, since the local variable $uid holds “nobody”’s uid.

    nobody 42313 0.0 0.3 10732 6556 ?? SsJ 4:36PM 0:00.00 /usr/local/bin/php /usr/local/www/data/flash-policy/FlashPolicyService.php -d

  14. Alex says:

    Another one:
    $this->trace() is nonexistent, should be replaced by $this->log()

  15. Ammon says:

    Doh! You’re right. Those typos went unnoticed for months. Fixed. Thanks.

  16. luke says:

    hey there,

    i’m a flash designer/developer but don’t know anything about servers and running things as root. i’ve got WAMP on my machine so i can test stuff, could you step me through how to setup this script. it’d be a lifesaver. thanks.

    luke

  17. Ammon says:

    luke: Unfortunately, this sort of script doesn’t work under windows. It is very Unix-specific. To make things work under Unix, you literally just download the script, make sure it’s executable, and run it. Making something run 24×7 on a server is beyond the scope of a comment here, and is rather specific to your individual unix distro.

  18. Mike A says:

    Two fixes…
    both from the zip file.
    1) The log function has \\n, rather than just \n – this doesn’t seem to be the case for the code that isn’t in the zip :( Was causing the log to all appear on one line.
    2) The line
    if( strlen($xml_filename) || !file_exists($xml_filename) ) {
    Should be
    if( strlen($xml_filename)==0 || !file_exists($xml_filename) ) {
    This one is in both version of the code.
    This was causing reading the XML from file to fail.

    Thanks.

  19. Ammon says:

    Mike A: Yeah, the \n vs \\n is a problem I bump into all the time trying to get code to appear correctly formatted on Wordpress. It looks like I put the wrong file in the zip after making my Jan 10th update. As far as the strlen() being backwards… oops! I’ll correct things as soon as I can tonight.

  20. Sampath says:

    We got following Error messages…

    Error: Connection to socket server failed (Flash Security Error).

    how to fix this issue.. please help me..

    Thanks
    SR

  21. Ammon says:

    Unfortunately, the only way to get any meaningful detail from flash about WHY a socket connection failed is to use a debug player with security logging enabled.

    The most common reasons for a socket security error are:
    1) no socket policy server at all
    2) firewall is preventing your connection
    3) policy xml being served isn’t correct

  22. Sampath says:

    We got following Error messages…
    only client side (Chat Window)..
    Error: Connection to socket server failed (Flash Security Error).

    how to fix this issue.. please give some extra tips..

    by
    SR

  23. Ramar says:

    Push based mechanism is working fine, but one client chatting message another client didn’t get message. once he/she entered some other text.plz help me..

  24. Ramar says:

    Socket server is working fine.. but Ajax chat is not working properly. one person chatting means another person won’t get message… anybody help me..

  25. Luiz says:

    Where to download extensions and pcntl posix?

  26. Ammon says:

    pcntl and posix are standard extensions that ship with php. They are not available on Windows, but are generally included by default in most Linux distro builds.

    http://www.php.net/manual/en/pcntl.installation.php
    http://www.php.net/manual/en/posix.installation.php

  27. lf says:

    I was considering using this on a web-server, until the PHP warning scared that idea away.

    http://us3.php.net/manual/en/intro.pcntl.php
    Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

  28. Ammon says:

    @lf:

    They are correct, but you misunderstand them. You generally don’t want to invoke pcntl calls from a web server “environment”. Ie, you probably don’t want Apache spawning other daemons.

    I’ll repeat it again, this sort of script should NOT be launched by your web server software.

    But there’s absolutely no reason not to (and often many reasons TO) run this sort of script on the web server hardware.

  29. Nizzy says:

    Dear Ammon,

    I have php5.2.12, posix is enabled, and I run the script as root. It tells me saying that posix is missing.

    When I execute your file from CLI, posix is not available.

    if (function_exists(‘posix_getuid’)) {
    echo “posix_getuid available”;
    } else {
    echo “posix_getuid not available”;
    }

    I think safe_mode needs to be enabled to run your file. Do you know why it didn’t run in my server?

    thank you.
    Nizzy

  30. Nizzy says:

    Ammon, I am second question. I had a flash debug version and I log the xdomain requests. I see this warning there. how can I get rid of this warning? thank you in advanced.

    ————————————————
    OK: Root-level SWF loaded: http://www.example.com/Chat.swf
    OK: Searching for in policy files to authorize data loading from resource at xmlsocket://www.example.com:8000 by requestor from http://www.example.com/Chat.swf
    Warning: Found secure=’true’ in policy file from xmlsocket://www.example.com:843, but host http://www.example.com does not appear to refer to the local machine. This may be insecure. See http://www.adobe.com/go/strict_policy_files for details.
    OK: Policy file accepted: xmlsocket://www.example.com:843
    OK: Request for resource at xmlsocket://www.example.com:8000 by requestor from http://www.example.com/Chat.swf is permitted due to policy file at xmlsocket://www.example.com:843
    ————————————————

  31. Ammon says:

    “Safe mode” never worked as intended in the first place. It is deprecated as of php 5.3 and entirely removed in 6.0. That said, it shouldn’t have anything to do with scripts run from CLI, it should only give things running from a web server trouble. I never run any of my servers in safe mode and have never had a problem with it as a result.

    The documentation does not list the posix methods I use as being explicitly restricted by safe mode:
    http://www.php.net/manual/en/features.safe-mode.functions.php

    Run a ‘php -m’ in the same environment you’re launching the daemon, it should list the posix module if it is available.

  32. Ammon says:

    Try setting “secure” to false in the socket policy file that you are serving.

  33. Nizzy says:

    Ammon, posix does not appear when I run php -m cmd, however, I see it from the phpinfo() ‘–enable-posix=shared’

    [PHP Modules]
    bz2
    calendar
    ctype
    curl
    date
    dbase
    dom
    exif
    fileinfo
    filter
    ftp
    gd
    geoip
    gettext
    gmp
    hash
    iconv
    imap
    ionCube Loader
    json
    libxml
    mbstring
    mcrypt
    memcache
    mhash
    mysql
    mysqli
    openssl
    pcntl
    pcre
    PDO
    pdo_mysql
    pdo_sqlite
    readline
    Reflection
    session
    shmop
    SimpleXML
    sockets
    SPL
    sqlite
    standard
    tokenizer
    wddx
    xml
    xmlreader
    xmlwriter
    xsl
    zip
    zlib

  34. Nizzy says:

    Ammon, regarding security warning, I already used secure=”false”, actually I am using your file to deliver xdomain policy. I still see that warning in the policy log file. Do you have any more idea how to resolve this? thank you

    // define the xml policy “file”
    $policy_file =
    ”.
    ”.
    ”.
    ”.
    ”;

  35. Nizzy says:

    Ammon,

    I think I don’t have posix installed although phpinfo shows it’s enabled. I tried to install it on Plesk, and it shows that it’s installed.

    yum -y install php-posix
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
    * atomic: www5.atomicorp.com
    Excluding Packages from Plesk Server Administrator
    Finished
    Setting up Install Process
    Package php-common-5.2.12-2.el5.art.x86_64 already installed and latest version
    Package php-common-5.2.12-2.el5.art.i386 already installed and latest version
    Nothing to do

    Could you please show me how to install posix? thank you

  36. [...] Working PHP Cli Socket Policy File Server [...]

  37. Nizzy says:

    If you don’t have posix running in your server, you can activate it by installing the following cmd. I have plesk 9 on linux.

    yum install php-process

  38. Nizzy says:

    Dear Ammon, I ran your script and I get this in the /tmp/flash-policy.log,

    Last line shows that it got invalid request. is this normal? How can I fix that? thank you.

    [10-02-04 01:55:42] fps: connection accepted from XX.XX.XX.XX, Resource id #13
    [10-02-04 01:55:42] fps: sending policy xml to Resource id #13
    [10-02-04 01:55:43] fps: connection accepted from XX.XX.XX.XX, Resource id #14
    [10-02-04 01:55:43] fps: got invalid request from Resource id #14

  39. Nizzy says:

    to run this script correctly, make sure:

    1) convert the format to unix. because this file has CR|LF at the end of lines. You need LF only.
    2) chmod +x FlashPolicyService.php
    3) then you can run as in ./FlashPolicyService.php

  40. Ammon says:

    Flash likes making repeat connections on the policy port. I’ve had various degrees of success with making it behave. One thing I seem to recall helping in this case is null terminating the policy data you send – ie, append “\0″ to the xml.

    My production servers currently each average about 12k policy xml requests a day and while they have long since evolved from the code I’m sharing here, the core logic is very similar. See if the \0 makes it less likely to re-request the data.

    I’m sorry I can’t be more helpful right now, I’m too busy banging out new code to look over this old class tonight.

  41. James says:

    I’m having some sort of strange blockage with the p-r-f. I can call it up through my socket in the browsers with http://192.168.1.100:843/crossdomain.xml and also have configured my C# chat server to respond with the same file if the request header regex = . I have also validated that the server is sending out the entire file including the terminating null character ().

    According to adobe, there has been some changes to the policy schema and the crossdomain.xml file should include:

    and for socket connections your header need to include:
    Content-Type: text/x-cross-domain-policy

    In AS I added the command:
    Security.loadPolicyFile(“xmlsocket://192.168.1.100:843);
    …yet I still get:

    Error: Request for resource at xmlsocket://192.168.1.100:843 by requestor from http://192.168.1.100:843/chat.swf is denied due to lack of policy file permissions.

    This has been a 2.5 week journey of frustation for me. Is there someone I can pay to debug my code so I can get on with my life?

  42. James says:

    Sorry I forget to escape characters for HTML on my last post.

    I’m having some sort of strange blockage with the p-r-f. I can call it up through my socket in the browsers with http://192.168.1.100:843/crossdomain.xml and also have configured my C# chat server to respond with the same file if the request header regex = policy-file-request. I have also validated that the server is sending out the entire file including the terminating null character (0).

    According to adobe, there has been some changes to the policy schema and the crossdomain.xml file should include:

    >site-control permitted-cross-domain-policies=”all”/<

    and for socket connections your header need to include:
    Content-Type: text/x-cross-domain-policy

    In AS I added the command:
    Security.loadPolicyFile(“xmlsocket://192.168.1.100:843);
    …yet I still get:

    Error: Request for resource at xmlsocket://192.168.1.100:843 by requestor from http://192.168.1.100:843/chat.swf is denied due to lack of policy file permissions.

    This has been a 2.5 week journey of frustation for me. Is there someone I can pay to debug my code so I can get on with my life?

  43. Ammon says:

    Unfortunately, you cannot use http to serve up socket policy files at all – you can only serve policies for http via http. If you want to serve a socket policy, it needs to come from a socket server so you either have to modify your existing socket server or you have to run something like the daemon I have here.

Leave a Reply