Serving a Flash Socket Policy File From Processing

 Mar, 26 - 2010   3 comments   How To

Last night I spent way too long trying to get AS3 to communicate with a simple socket server I wrote in Processing. I’ve done this kind of thing before and seemed to recall that it was pretty simple. But in the meantime, Adobe, in an effort to be more secure, has changed the Flash player to require a “socket policy file“. The socket policy file is very similar to the familiar crossdomain.xml file that defines security permissions for HTTP access. Unfortunately, the socket policy file must either be sent on demand from the sockets that the player is attempting to access, or from port 843 on the host that the player is attempting to connect to. If all you want to do is run a quick and dirty socket server and have Flash clients connect to it, this is all a huge PITA.

Since ports below 1024 require root permissions in order for processes to use them on OS X, and I didn’t want to run some other server process just to serve policy files, I needed to kludge a way to send the policy file from my nice, elegant socket server every time a client connected and requested a policy file. The example below is a simplified version, as it only listens on one port – the project I was working on was basically a proxy from one SWF to another, so I had two socket servers that needed to listen for the requests for a policy file and respond. In this example, the server listens for connections on port 5208, and simply echoes incoming data from the client to System.out, and has some visual feedback in the window. When the incoming message contains the string “policy-file-request” (the entire message from Flash will be terminated with a null char), we simply spit back the XML for a wide-open socket policy, followed by a null char (This is required, or the Flash player will not accept the policy file. This is what tied me in knots last night. RTFM!)

import processing.net.*;

int bgLevel = 0;
int port = 5208;
Server server;

String flashDomainPolicy = "<?xml version=\"1.0\"?>"
                              +"<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>";

void setup ()
{
  size(200, 200);        
  server = new Server(this, port);
  background(bgLevel);
}

void draw ()
{
  Client client = server.available();
  
  if (client !=null)
  {
    String message = trim(client.readString());
    
    if (message != null)
    {
      if (match(message,"policy-file-request") != null)
      {
        sendFlashPolicy(server);
      }
      else
      {
        server.write(message);
        System.out.println(message);
      
        // Change the background color to indicate message activity
        bgLevel = 255;
      }      
    } 
  }
  
  // Fade to black
  if (bgLevel>1)
  {
    bgLevel-=2;
    background(bgLevel);
  }
}

void sendFlashPolicy(Server socketServer)
{
    socketServer.write(flashDomainPolicy+char(0));
    System.out.println("Sending Flash policy file");
}

You can test this without a Flash client by firing up the sketch and telnetting to the port. Any strings you send will be echoed to System.out, unless you send the string “policy-file-request” in your message, which will result in the server sending the policy XML to you. You should be able to connect a Flash client to this server and start communicating right away.


Related articles

 Comments 3 comments

  • PedroHLC says:

    Hi, I don’t know if I’ve got it right, well, I have a C++ TCP server and a Flash AS3 client, when I connect the client to the server, the server receives:
    “<policy-file-request/>”
    than I just send to the client:
    “<?xml version=\”1.0\”?>\n<cross-domain-policy xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” xsi:noNamespaceSchemaLocation=\”http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd\”>\n<allow-access-from domain=\”*\” to-ports=\”*\” secure=\”false\” />\n<site-control permitted-cross-domain-policies=\”all\” />\n</cross-domain-policy>\n”
    and then the client closes the connection, I imagine it’s normal that the problem only happens when the swf file isn’t in my computer, but I don’t know more what to do…
    Thanks for reading, please reply if anyone knows the solution…

    ReplyReply
  • Rob Ruchte Rob Ruchte says:

    @Pedro, Make sure you terminate your socket policy string with the null character (it’s ‘\0’ in C++ if I recall correctly). The Flash player will not accept the policy file without the null character.

    ReplyReply
  • PedroHLC says:

    @Rob, it worked! I’m really grateful for your answer 😀

    ReplyReply

  • Leave a Reply

    Your email address will not be published. Fields with * are mandatory.