diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java b/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java
index f999869532..09d2eaa292 100644
--- a/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java
+++ b/xmppserver/src/main/java/org/jivesoftware/openfire/session/LocalOutgoingServerSession.java
@@ -18,38 +18,24 @@
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.*;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.event.ServerSessionEventDispatcher;
-import org.jivesoftware.openfire.net.MXParser;
-import org.jivesoftware.openfire.net.SASLAuthentication;
-import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.net.SocketUtil;
import org.jivesoftware.openfire.nio.NettySessionInitializer;
import org.jivesoftware.openfire.server.OutgoingServerSocketReader;
import org.jivesoftware.openfire.server.RemoteServerManager;
import org.jivesoftware.openfire.server.ServerDialback;
-import org.jivesoftware.openfire.spi.BasicStreamIDFactory;
-import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.TaskEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.packet.*;
import javax.annotation.Nonnull;
-import java.io.IOException;
-import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketAddress;
-import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -298,202 +284,6 @@ private static LocalOutgoingServerSession createOutgoingSession(@Nonnull final D
}
}
- public static LocalOutgoingServerSession encryptAndAuthenticate(DomainPair domainPair, SocketConnection connection, XMPPPacketReader reader, StringBuilder openingStream) throws Exception {
- final Logger log = LoggerFactory.getLogger(Log.getName() + "[Encrypt connection for: " + domainPair + "]" );
- Element features;
-
- log.debug( "Encrypting and authenticating connection ...");
-
- log.debug( "Indicating we want TLS and wait for response." );
- connection.deliverRawText( "" );
-
- MXParser xpp = reader.getXPPParser();
- // Wait for the response
- Element proceed = reader.parseDocument().getRootElement();
- if (proceed != null && proceed.getName().equals("proceed")) {
- log.debug( "Received 'proceed' from remote server. Negotiating TLS..." );
- try {
-// boolean needed = JiveGlobals.getBooleanProperty(ConnectionSettings.Server.TLS_CERTIFICATE_VERIFY, true) &&
-// JiveGlobals.getBooleanProperty(ConnectionSettings.Server.TLS_CERTIFICATE_CHAIN_VERIFY, true) &&
-// !JiveGlobals.getBooleanProperty(ConnectionSettings.Server.TLS_ACCEPT_SELFSIGNED_CERTS, false);
- connection.startTLS(true, false);
- } catch(Exception e) {
- log.debug("TLS negotiation failed: " + e.getMessage());
- throw e;
- }
- log.debug( "TLS negotiation was successful. Connection encrypted. Proceeding with authentication..." );
- if (!SASLAuthentication.verifyCertificates(connection.getPeerCertificates(), domainPair.getRemote(), true)) {
- if (ServerDialback.isEnabled() || ServerDialback.isEnabledForSelfSigned()) {
- log.debug( "SASL authentication failed. Will continue with dialback." );
- } else {
- log.warn( "Unable to authenticate the connection: SASL authentication failed (and dialback is not available)." );
- return null;
- }
- }
-
- log.debug( "TLS negotiation was successful so initiate a new stream." );
- connection.deliverRawText( openingStream.toString() );
-
- // Reset the parser to use the new secured reader
- xpp.setInput(new InputStreamReader(connection.getTLSStreamHandler().getInputStream(), StandardCharsets.UTF_8));
- // Skip new stream element
- for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
- eventType = xpp.next();
- }
- // Get the stream ID
- String id = xpp.getAttributeValue("", "id");
- // Get new stream features
- features = reader.parseDocument().getRootElement();
- if (features != null) {
- return authenticate( domainPair, connection, reader, openingStream, features, id );
- }
- else {
- log.debug( "Failed to encrypt and authenticate connection: neither SASL mechanisms nor SERVER DIALBACK were offered by the remote host." );
- return null;
- }
- }
- else {
- log.debug( "Failed to encrypt and authenticate connection: was not received!" );
- return null;
- }
- }
-
- private static LocalOutgoingServerSession authenticate( final DomainPair domainPair,
- final SocketConnection connection,
- final XMPPPacketReader reader,
- final StringBuilder openingStream,
- final Element features,
- final String id ) throws DocumentException, IOException, XmlPullParserException
- {
- final Logger log = LoggerFactory.getLogger(Log.getName() + "[Authenticate connection for: " + domainPair + "]" );
-
- MXParser xpp = reader.getXPPParser();
-
- // Bookkeeping: determine what functionality the remote server offers.
- boolean saslEXTERNALoffered = false;
- if (features.element("mechanisms") != null) {
- Iterator it = features.element( "mechanisms").elementIterator();
- while (it.hasNext()) {
- Element mechanism = it.next();
- if ("EXTERNAL".equals(mechanism.getTextTrim())) {
- saslEXTERNALoffered = true;
- break;
- }
- }
- }
- final boolean dialbackOffered = features.element("dialback") != null;
-
- log.debug("Remote server is offering dialback: {}, EXTERNAL SASL: {}", dialbackOffered, saslEXTERNALoffered );
-
- LocalOutgoingServerSession result = null;
-
- // first, try SASL
- if (saslEXTERNALoffered) {
- log.debug( "Trying to authenticate with EXTERNAL SASL." );
- result = attemptSASLexternal(connection, xpp, reader, domainPair, id, openingStream);
- if (result == null) {
- log.debug( "Failed to authenticate with EXTERNAL SASL." );
- } else {
- log.debug( "Successfully authenticated with EXTERNAL SASL." );
- }
- }
-
- // SASL unavailable or failed, try dialback.
- if (result == null) {
- log.debug( "Trying to authenticate with dialback." );
- result = attemptDialbackOverTLS(connection, reader, domainPair, id);
- if (result == null) {
- log.debug( "Failed to authenticate with dialback." );
- } else {
- log.debug( "Successfully authenticated with dialback." );
- }
- }
-
- if ( result != null ) {
- log.debug( "Successfully encrypted and authenticated connection!" );
- return result;
- } else {
- log.warn( "Unable to encrypt and authenticate connection: Exhausted all options." );
- return null;
- }
- }
-
- private static LocalOutgoingServerSession attemptDialbackOverTLS(Connection connection, XMPPPacketReader reader, DomainPair domainPair, String id) {
- final Logger log = LoggerFactory.getLogger( Log.getName() + "[Dialback over TLS for: " + domainPair + " (Stream ID: " + id + ")]" );
-
- if (ServerDialback.isEnabled() || ServerDialback.isEnabledForSelfSigned()) {
- log.debug("Trying to connecting using dialback over TLS.");
- ServerDialback method = new ServerDialback(connection, domainPair);
- OutgoingServerSocketReader newSocketReader = new OutgoingServerSocketReader(reader);
- if (method.authenticateDomain(newSocketReader, id)) {
- log.debug("Dialback over TLS was successful.");
- StreamID streamID = BasicStreamIDFactory.createStreamID(id);
- LocalOutgoingServerSession session = new LocalOutgoingServerSession(domainPair.getLocal(), connection, newSocketReader, streamID);
- connection.init(session);
- // Set the remote domain name as the address of the session.
- session.setAddress(new JID(null, domainPair.getRemote(), null));
- session.setAuthenticationMethod(AuthenticationMethod.DIALBACK);
- return session;
- }
- else {
- log.debug("Dialback over TLS failed");
- return null;
- }
- }
- else {
- log.debug("Skipping server dialback attempt as it has been disabled by local configuration.");
- return null;
- }
- }
-
- private static LocalOutgoingServerSession attemptSASLexternal(SocketConnection connection, MXParser xpp, XMPPPacketReader reader, DomainPair domainPair, String id, StringBuilder openingStream) throws DocumentException, IOException, XmlPullParserException {
- final Logger log = LoggerFactory.getLogger( Log.getName() + "[EXTERNAL SASL for: " + domainPair + " (Stream ID: " + id + ")]" );
-
- log.debug("Starting EXTERNAL SASL.");
- if (doExternalAuthentication(domainPair.getLocal(), connection, reader)) {
- log.debug("EXTERNAL SASL was successful.");
- // SASL was successful so initiate a new stream
- connection.deliverRawText(openingStream.toString());
-
- // Reset the parser
- //xpp.resetInput();
- // // Reset the parser to use the new secured reader
- xpp.setInput(new InputStreamReader(connection.getTLSStreamHandler().getInputStream(), StandardCharsets.UTF_8));
- // Skip the opening stream sent by the server
- for (int eventType = xpp.getEventType(); eventType != XmlPullParser.START_TAG;) {
- eventType = xpp.next();
- }
-
- // SASL authentication was successful so create new OutgoingServerSession
- id = xpp.getAttributeValue("", "id");
- StreamID streamID = BasicStreamIDFactory.createStreamID(id);
- LocalOutgoingServerSession session = new LocalOutgoingServerSession(domainPair.getLocal(), connection, new OutgoingServerSocketReader(reader), streamID);
- connection.init(session);
- // Set the remote domain name as the address of the session
- session.setAddress(new JID(null, domainPair.getRemote(), null));
- // Set that the session was created using TLS+SASL (no server dialback)
- session.setAuthenticationMethod(AuthenticationMethod.SASL_EXTERNAL);
- return session;
- }
- else {
- log.debug("EXTERNAL SASL failed.");
- return null;
- }
- }
-
- private static boolean doExternalAuthentication(String localDomain, SocketConnection connection,
- XMPPPacketReader reader) throws DocumentException, IOException, XmlPullParserException {
-
- StringBuilder sb = new StringBuilder();
- sb.append("");
- sb.append(StringUtils.encodeBase64(localDomain));
- sb.append("");
- connection.deliverRawText(sb.toString());
-
- Element response = reader.parseDocument().getRootElement();
- return response != null && "success".equals(response.getName());
- }
-
public LocalOutgoingServerSession(String localDomain, Connection connection, OutgoingServerSocketReader socketReader, StreamID streamID) {
super(localDomain, connection, streamID);
this.socketReader = socketReader;