RSS LinkedIn Twitter

Flex Socket Connections : Socket Policy File

February 9th, 2010 Categories: Actionscript, Application Servers, client/server, Flex 3, Perl

Starting with certain versions in the 9.0’s of Flash player, socket communication in Flex began adding additional security measures. The one I am going to discuss in the post is the socket policy file. In short, the socket policy file is an XML file that is served by default from port 843 and contains information regarding which ports on _this_ server that Flash may connect to. Additionally it allows you to specify from which domains you wish to allow connections.


Loading the Policy File From Flex

The policy file can be explicitly requested by making the call:

[as3]
Security.loadPolicyFile("host.withpolicyfile.com:843");
[/as3]

Or you can trust it will implicitly make the request when you attempt a socket connection. The policy is valid for a particular IP address over the life of the SWF. A policy request consists of the following line, nothing more:

[xml]<policy-file-request/>[/xml]

And the correct response is the policy file, followed by a null byte. My example policy server file will not be so picky about it’s request, use it at your own risk. Adobe has one that actually checks to see if the request was formatted correctly before sending the response. Furthermore, rather than reading in an actual policy file, my example hard codes it into the policy server.


Policy File Format

Here is a sample policy file, it is provided by Adobe. You can make whatever changes you need to, as I did in mine:

[xml]
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">

<!– Policy file for xmlsocket://socks.example.com –>
<cross-domain-policy>

<!– This is a master socket policy file –>
<!– No other socket policies on the host will be permitted –>
<site-control permitted-cross-domain-policies="master-only"/>

<!– Instead of setting to-ports="*", administrator’s can use ranges and commas –>
<!– This will allow access to ports 123, 456, 457 and 458 –>
<!–allow-access-from domain="swf.example.com" to-ports="123,456-458" /–>
<allow-access-from domain="*" to-ports="80" />
</cross-domain-policy>
[/xml]


Policy File Server

And here is the Perl code that runs the policy server. You can see it is just a basic socket server. Adobe’s version of this (which I based mine off) allows you to pass in the port as well as the path to the policy file. This is a stripped down version of that server, with most of the essentials hard coded.

[perl]
use Socket;

my $NULLBYTE = pack(‘c’, 0);
my $port = 843;
my $content ='<?xml version="1.0"?>’."\n" .
‘<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">’."\n" .
‘<cross-domain-policy>’ . "\n" .
‘<site-control permitted-cross-domain-policies="master-only"/>’."\n" .
‘<allow-access-from domain="*" to-ports="80" />’."\n" .
‘</cross-domain-policy>’."\n";

socket (LISTENSOCK, PF_INET, SOCK_STREAM, getprotobyname(‘tcp’))
or die "socket() error: $!";
setsockopt(LISTENSOCK, SOL_SOCKET, SO_REUSEADDR, pack(‘l’, 1))
or die "setsockopt() error: $!";
bind (LISTENSOCK, sockaddr_in($port, INADDR_ANY))
or die "bind() error: $!";
listen (LISTENSOCK, SOMAXCONN)
or die "listen() error: $!";

while ( my $clientAddr = accept(CONNSOCK, LISTENSOCK)) {
my ($clientPort, $clientIp)= sockaddr_in($clientAddr);
my $clientIpStr = inet_ntoa($clientIp);

# Consume the request
local $/ = $NULLBYTE;
my $request = <CONNSOCK>;
chomp $request;

# Send the policy file
print CONNSOCK $content;
print CONNSOCK $NULLBYTE;
close CONNSOCK;
}
}
[/perl]


Opening A Port

Remember to open port 843 (in Fedora Core) by adding the following line in /etc/sysconfig/iptables :
[bash]-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 843 -j ACCEPT[/bash]

Then reload the iptables:
[bash]/etc/init.d/iptables restart[/bash]

Tags: , ,
No comments yet.

Leave a Comment

*