Simple socket cross-domain policies Neko server

10.28.2012 3552 0

In a previous post it was question about Flash Player security and we've seen that we need a cross-domain policies server in order to connect a socket on another domain.
We gonna see how to quickly write this kind of server using Neko, that is one of Haxe's "server side" plateform. It means that common Haxe "client-side" developers as flash, javascript or NME developers can easily write their servers using the same language. Quite a good thing, isn't it ?


First we need a socket connection that listen on a host to a given port.

var socket = new sys.net.Socket();
socket.bind( new sys.net.Host( "myDomain.com" ), 843 );
socket.listen( 10 ); // number of pending connections before they get refused

Here we listen for incomming connections to myDomain.com on the default cross-domain policies socket port : 843
Next step is to accept an incomming connection and check its request : the Flash Player sends us <policy-file-request/> and have to send its back our cross-domain policies :

var cnx = socket.accept();
if ( cnx.input.readString( 22 ) == "<policy-file-request/>" )
{
    var sbuf = '<cross-domain-policy>
                    <allow-access-from="requestingDomain.com" to-ports="2010" />
                </cross-domain-policy>';
    sbuf.addChar( 0 );  // Flash Player needs a null char at the end
    cnx.output.writeString( sbuf.toString() );
    cnx.output.flush();
}

That's all !
Let's see how we can add some features in order to make this server generic. We gonna take 4 arguments :

  • listening host
  • listening post
  • authorized domains
  • authorized ports

And here comes our generic cross-domain policies server:

class CDSS {
    static function main(){
        var args     = neko.Sys.args();
        var host     = args[ 0 ];
        var port     = args[ 1 ];
        var domains  = args[ 2 ].split( "," );
        var to_ports = args[ 3 ];
        var s	     = new Socket();
        s.bind( new Host( host), port );
        s.listen( 10 );
	var c	     = null;
	var req	     = null;
	var sbuf     = new StringBuf();
	while ( true ) {
	    c	= s.accept();
            try{
		req = c.input.readString( 22 );
		c.input.readByte();  // Flash Player ends with a null char
	    }catch ( e : Eof ) {}
	    if ( req == "<policy-file-request/>" )
	    {
                trace( "sending policies to " + c.peer().host );
		sbuf.add( "<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy>" );
		for ( domain in domains )
		    sbuf.add( "<allow-access-from domain=\"" + domain + "\" to-ports=\"" + to_ports + "\" />" );
		sbuf.add( "</cross-domain-policy>" );
		sbuf.addChar( 0 );
								
		try {
		    c.output.writeString( sbuf.toString() );
		    c.output.flush();
		    c.close();
		}catch ( e : Eof ) { trace( e ); }
	    }
	}
    }
}

The command-line to build the server :

haxe -main CDSS -neko cdss.n

And the command line to run the server on myDomain, port 843, allowing all google and yahoo subdomains to connect myDomain on the port range : 2000-2100 :

neko cdss.n myDomain 843 *.google.com,*.yahoo.fr 2000-2100

Here you can see and download the whole CDSS.hx class.

Comments

Write a comment

http://
×