[PATCH] Allow Openfire to serve cross-domain policy on client port for Flash

So, the latest versions of Flash 9.0.115.0 and 9.0.124.0 are much more strict about which sockets you are allowed to connect to. Openfire is configured to serve a policy file on a separate port (5229) than the client port (5222). This works fine, except for some of our users behind strict firewalls do not have port 5229 open, as it is not very common.

This patch allows openfire to recognize a cross-domain policy request in the form of a “policy-file-request” and automatically serve up a cross-domain policy which allows flash to connect to the client port. After the policy is sent, the connection is closed.

I hope this can be accepted into trunk, as it really is a pain to require our users to open two ports in their firewall just to be able to connect. The simple change is inside StanzaHandler.java, at the top of the process function:

public void process(String stanza, XMPPPacketReader reader) throws Exception {
        boolean initialStream = stanza.startsWith("<stream:stream") || stanza.startsWith("<flash:stream");
        if (!sessionCreated || initialStream) {
            if (!initialStream) {
                // Allow requests for flash socket policy files directly on the client listener port
                if( stanza.startsWith("<policy-file-request/>" ) ){
                    String crossDomainText = FlashCrossDomainHandler.CROSS_DOMAIN_TEXT +
                        XMPPServer.getInstance().getConnectionManager().getClientListenerPort() +
                        FlashCrossDomainHandler.CROSS_DOMAIN_END_TEXT + '\0';
                    connection.deliverRawText( crossDomainText );
                    return;
                } else {
                    // Ignore <?xml version="1.0"?>
                    return;
                }
            }

With this code in place, I can remove the call to System.security.loadPolicyFile(“xmlsocket://” + address + “:5229” ) which is currently required.

Here is the output from the flash debugger, which shows that the strict policy rules are being followed properly:

OK: Policy file accepted: xmlsocket://localhost:5222

OK: Request for resource at xmlsocket://localhost:5222 by requestor from http://localhost:3000/flash/chat.swf

I hope this is helpful to others, it is really a lifesaver for us.

Message was edited by: BenV
StanzaHandler.java (29665 Bytes)

Hey Ben,

Excellent improvement. I will see to include it for Openfire 3.5.2 and trunk (3.6.0).

Thanks,

– Gato

One modification that seems to fix some issues I was running into is to remove the call to “connection.close();”, as it seems the flash client is happier closing the connection itself.

Hey Ben,

Do you want me to delete the connection.close() that was included in your added code?

Thanks,

– Gato

Yes, that is correct, I’ll edit my post above to reflect that.

This should also help with another problem we’re seeing which appears to be a timing issue related to the implementation in FlashCrossDomainHandler. As it’s coded, the Handler DOES NOT WAIT for the string to come in and just sends the policy stream back as soon as the socket is connected. Under unpredictable circumstances we see the Flash player opening the socket and getting the policy file back from the server BEFORE it requests it. When this happens the System.security.loadPolicyFile() call fails, presumably because it needs to get it AFTER the request is made.

I’m also assuming that Ben’s patch benefits from NIO since it’s inside the regular stanza handler (is that the case?). The FlashCrossDomainHandler was a single threaded socket listener suffering from scalability issues. Of course they weren’t apparent until recently when the new, stricter Flash Players became available.

Thanks for this patch Ben!

Ike

Great work!

I just would like to confirm your suggested update.

Some of our users have had problems with our implementation of a group chat client.

We’ve been using the 5229 for serving the policy file, and even though some of our users are

not using firewalls, they were not able to connect…

After applying your patch and removing the ‘loadPolicyFile’, our users are able to connect.

Thanks!

I just installed this patch and it solved a heap of issues we are having.

I look forward to this being in the next release of Openfire!

Thanks

Daniel

Hey Ben,

Thanks for contributing this enhancement. I filed it as JM-1361 and checked it in for Openfire 3.6.0.

Regards,

– Gato

I think this patch has been implemented with the 3.6.0 Alpha version. I have downloaded and installed the same and is working absolutely fine. I am very thankful to all of you in openfire team.

Now it never fails to connect because of crossdomain.xml. I dont need to load policy file from 5229 port.

Thanks and regard,

Prasanta Saha

http://www.labymaze.co.in

Hey Ben,

Excellent improvement.

I hope to see it in next Openfire versions (3.5.2 and 3.6.0).

Thanks!!!

I was able to run this in the 6/5/2008 nightly build successfully. Is there any prespective date this functionality this will be released. I noticed this particular nightly build was 3.6.0 Alpha. Is Jive going to release a 3.5.2 version with this particular piece or no 3.5.2 version at all?

Hey Andrew,

Being a new feature we initially decided to leave it for Openfire 3.6.0. However, I think that there is no risk in moving it to Openfire 3.5.2 that will be released next week. If you want us to move it just let us know.

Thanks,

– Gato

Hey Andrew,

Done. The patch was moved to 3.5.2 so it will be available next week.

Regards,

– Gato

I would be most appreciative if this functionality could be incorporated into the 3.5.2 version for next week’s release. Is there any official channel or person I need to get in contact with to make this happen?

-Andy

Wow, you’re fast! Before I could reply you already had the fix in place. I look forward to the release next week.

We have been using the latest builds in the live environment just because of this patch as it solves a bunch of firewall issues.

Since we have recently upgraded to use the XIFF flash libraries rather than the old third party jabberflash javascript libraries it has meant that we could BIND direct from a client to the Openfire server on port 80! (whereas before we had to use ISAPI rewrite as you couldn’t bind to a different domain using JavaScript - due to security but it works in Flash).

We have Openfire setup to listen on port 80 for BOSH connections - and do not run any other web servers on that computer.

This is heaps better for scalability / reliability etc and the firewalls don’t block port 80. And no need to proxy the bind requests through the web servers.

Now the question is - do you think you should also add the binding port to the recent patch that serves the crossdomain.xml file as it is only allowing the port for socket connections currently?

<?xml version=“1.0” ?> <!DOCTYPE cross-domain-policy (View Source for full doctype…)> - <cross-domain-policy> <allow-access-from domain="****" to-ports=“5222” secure="*true" /> </cross-domain-policy>

So the ports= both the socket and binding ports as set in openfire.

Please let me know if this makes sense or maybe I am confusing how Flash security works - they couldn’t make it more complicated if they tried!

Thanks

Daniel