Use TLS-Dialback even if no feature is returned by remote server

If a TLS-handshake is done to a remote server it should respond with features how the authentication could be done. Some servers don’t send features back and the protocoll specification is a inpresice how the initiating server should handle this.

See XEP-0178 Point 3.9:

Server2 advertises SASL mechanisms. If the ‘from’ attribute of the stream header sent by Server1 can be matched against one of the identifiers provided in the certificate following the matching rules from RFC 6125, Server2 SHOULD advertise the SASL EXTERNAL mechanism. If no match is found, Server2 MAY either close Server1’s TCP connection or continue with aServer Dialback (XEP-0220) [8] negotiation.

So we could close the connection (what OF do until now/3.9.1) or switch back to server dialback over TLS and try it.

The patch is really simple (but doesn’t clean up the log-message):

Index: src/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java          (revision 13927)
+++ src/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java          (revision )
@@ -446,7 +446,7 @@
             String id = xpp.getAttributeValue("", "id");
             // Get new stream features
             features = reader.parseDocument().getRootElement();
-            if (features != null && (features.element("mechanisms") != null || features.element("dialback") != null)) {
+            if (features != null) {
                 // Check if we can use stream compression
                 String policyName = JiveGlobals.getProperty("xmpp.server.compression.policy", Connection.CompressionPolicy.disabled.toString());
                 Connection.CompressionPolicy compressionPolicy = Connection.CompressionPolicy.valueOf(policyName);
@@ -486,7 +486,7 @@
                                 }
                                 // Get new stream features
                                 features = reader.parseDocument().getRootElement();
-                                if (features == null || features.element("mechanisms") == null) {
+                                if (features == null) {
                                     log.debug("Error, EXTERNAL SASL was not offered.");
                                     return null;
                                 }

My proposed behavior is also more plausible because if SASL EXTERNAL is offered but it doesn’t auth the domain there is also a silent fallback to dialback regardless it is offered by the remote server. With my change there is also a TLS-dialback if no SASL EXTERNAL is offered and it’s enabled by the server.

I built a SNAPSHOT version and tried it. The encrypted connections very greatly increased to a high level. The member Moonchild tried the same version on his server and reported the same good news.

I would be very glad if you raise a ticket, I provide a simple patch file and you integrate very soon.

Thanks in advance,

Sven

There is also a discussion in the openfire support board: Server dialback issue over TLS - #13 by Moonchild - Openfire Support - Ignite Realtime Community Forums

1 Like

I can confirm that this solves massive issues on outbound connections for me where the responses in the logs would be the dreaded “unexpected answer” and as a result being unable to communicate with encryption because of plaintext dialback.

With this SNAPSHOT build, Openfire is able to communicate properly with ejabberd and prosody now, the two most-used server applications for Jabber. I’ve put this on my production server without a hitch, and this patch should probably be pushed out to OF as soon as possible, considering S2S encryption will be required on the XMPP network before long (as discussed on the XMPP operators mailing list).

After the server is adding compression to the connection a similar if-statement take place. So I removed a second feature-check to the patch above.

(I also got a refactored version of the class and reduced the amount of code duplication. If you (an OF commiter) is interested drop me an private message.)

This patch should be integrated into mainline as soon as possible, with the original Openfire I only had 3 out of 12 outgoing sessions encrypted, now it’s 10/12.

Filed as OF-745

Until the patch is applied and OpenFire 3.9.2 is released I’ve provided a jar-patch for Openfire 3.9.1:

Just add the attached aa-LocalOutgoingServerSession.jar into your lib folder of the current 3.9.1 installation.

SHA-256 sum: c9208158e7c4bb5d79abccf7fb3fdc353ffadb53f8369b19eb734cb488051d88

How it works: By default the java classloader picks jar files in alphabetically order. If the class is already loaded other classes with same name/package gets skipped.

Just a little step to get ready for https://github.com/stpeter/manifesto/blob/master/manifesto.txt

1 Like