Log.debug("Trying to create socket connection to XMPP domain '{}' using remote host: {}:{} (blocks up to {} ms) ...",xmppDomain,realHostname,realPort,socketTimeout);
Log.debug("Successfully created socket connection to XMPP domain '{}' using remote host: {}:{}!",xmppDomain,realHostname,realPort);
returnsocket;
}
catch(Exceptione)
{
Log.debug("An exception occurred while trying to create a socket connection to XMPP domain '{}' using remote host {}:{}",xmppDomain,realHostname,realPort,e);
Log.warn("Unable to create a socket connection to XMPP domain '{}' using remote host: {}:{}. Cause: {} (a full stacktrace is logged on debug level)",xmppDomain,realHostname,realPort,e.getMessage());
try
{
if(socket!=null)
{
socket.close();
socket=null;
}
}
catch(IOExceptionex)
{
Log.debug("An additional exception occurred while trying to close a socket when creating a connection to {}:{} failed.",realHostname,realPort,ex);
}
}
}
Log.warn("Unable to create a socket connection to XMPP domain '{}': Unable to connect to any of its remote hosts.",xmppDomain);
log.debug("Plain socket connection to {}:{} successful!",hostname,realPort);
break;
}
catch(Exceptione){
log.debug("An exception occurred while trying to create a plain socket connection to: {}:{}",hostname,realPort,e);
log.warn("Unable to create plain socket connection to: {}:{}. Cause: {} (a full stacktrace is logged on debug level)",hostname,realPort,e.getMessage());
// TODO should this not stop processing? lots of this code is very similar to the implementation in LocalOutgoingServerSession. Should implementations be merged?
finalLoggerlog=LoggerFactory.getLogger(Log.getName()+"[Acting as Receiving Server: Validate domain:"+recipient+"(id "+streamID+") for OS: "+remoteDomain+"]");
log.debug("Unable to validate domain: An incoming connection already exists from this remote host, and multiple connections are not allowed.");
log.debug("Unable to validate domain: An incoming connection already exists from this remote domain, and multiple connections are not allowed.");
returnfalse;
returnfalse;
}
}
else{
else{
log.debug("Checking to see if the remote host provides stronger authentication based on SASL. If that's the case, dialback-based authentication can be skipped.");
log.debug("Checking to see if the remote server provides stronger authentication based on SASL. If that's the case, dialback-based authentication can be skipped.");
log.debug("Plain socket connection to {}:{} successful!",realHostname,realPort);
break;
}
catch(Exceptione){
log.debug("An exception occurred while trying to create a plain socket connection to: {}",realHostname,e);
log.warn("Unable to create plain socket connection to: {}. Cause: {} (a full stacktrace is logged on debug level)",realHostname,e.getMessage());
}
}
if(!socket.isConnected()){
log.debug("Unable to validate domain: No server available for verifying key of remote server.");
log.debug("Unable to validate domain: No server available for verifying key of remote server.");
dialbackError(recipient,hostname,newPacketError(PacketError.Condition.remote_server_not_found,PacketError.Type.cancel,"Unable to connect to authoritative server"));
dialbackError(recipient,remoteDomain,newPacketError(PacketError.Condition.remote_server_not_found,PacketError.Type.cancel,"Unable to connect to authoritative server"));
@@ -608,11 +570,11 @@ public class ServerDialback {
...
@@ -608,11 +570,11 @@ public class ServerDialback {
break;
break;
}
}
log.debug("Unable to validate domain: key verification did not complete (the AS likely returned an error or a time out occurred).");
log.debug("Unable to validate domain: key verification did not complete (the AS likely returned an error or a time out occurred).");
dialbackError(recipient,hostname,newPacketError(PacketError.Condition.remote_server_timeout,PacketError.Type.cancel,"Authoritative server returned error"));
dialbackError(recipient,remoteDomain,newPacketError(PacketError.Condition.remote_server_timeout,PacketError.Type.cancel,"Authoritative server returned error"));
returnfalse;
returnfalse;
}
}
catch(Exceptione){
catch(Exceptione){
dialbackError(recipient,hostname,newPacketError(PacketError.Condition.remote_server_timeout,PacketError.Type.cancel,"Authoritative server failed"));
dialbackError(recipient,remoteDomain,newPacketError(PacketError.Condition.remote_server_timeout,PacketError.Type.cancel,"Authoritative server failed"));
log.warn("Unable to validate domain: An exception occurred while verifying the dialback key.",e);
log.warn("Unable to validate domain: An exception occurred while verifying the dialback key.",e);
finalLoggerlog=LoggerFactory.getLogger(Log.getName()+"[Verify key with AS: "+hostname+" for: "+recipient+" (id "+streamID+")]");
finalLoggerlog=LoggerFactory.getLogger(Log.getName()+"[Acting as Receiving Server: Verify key with AS: "+remoteDomain+" for OS: "+recipient+" (id "+streamID+")]");
finalLoggerlog=LoggerFactory.getLogger(Log.getName()+"[Verify key with AS: "+hostname+" for: "+recipient+" (id "+streamID+")]");
finalLoggerlog=LoggerFactory.getLogger(Log.getName()+"[Acting as Receiving Server: Verify key with AS: "+remoteDomain+" for OS: "+recipient+" (id "+streamID+")]");
// Do nothing if the target hostname is empty, null or contains whitespaces
// Do nothing if the target domain is empty, null or contains whitespaces
log.warn("Unable to authenticate a domain when an empty hostname is provided!");
log.warn("Unable to authenticate: remote domain is invalid.");
returnfalse;
returnfalse;
}
}
try{
try{
// Check if the remote hostname is in the blacklist
// Check if the remote domain is in the blacklist
if(!RemoteServerManager.canAccess(hostname)){
if(!RemoteServerManager.canAccess(remoteDomain)){
log.info("Unable to authenticate: Hostname is not accessible according to our configuration (typical causes: server federation is disabled, or hostname is blacklisted).");
log.info("Unable to authenticate: Remote domain is not accessible according to our configuration (typical causes: server federation is disabled, or domain is blacklisted).");
returnfalse;
returnfalse;
}
}
log.debug("Searching for a pre-existing session to this hostname... If one exists, it will be re-used to authenticate this domain.");
log.debug("Searching for pre-existing outgoing sessions to the remote domain (if one exists, it will be re-used) ...");
// Server is shutting down while we are trying to create a new s2s connection
// Server is shutting down while we are trying to create a new s2s connection
log.warn("Unable to authenticate: the SessionManager instance is not available. This should not occur unless Openfire is starting up or shutting down.");
log.warn("Unable to authenticate: a SessionManager instance is not available. This should not occur unless Openfire is starting up or shutting down.");
log.debug("There is no pre-existing session to this hostname.");
if(session==null)
{
log.debug("Searching for pre-existing sessions to other hostnames that previously authenticated this domain... If one exists, it will be re-used to authenticate this domain.");
log.debug("There are no pre-existing outgoing sessions to the remote domain itself. Searching for pre-existing outgoing sessions to super- or subdomains of the remote domain (if one exists, it might be re-usable) ...");
// Try locating if the remote server has previously authenticated with this server
log.debug("An outgoing session to a different domain ('{}') hosted on the remote domain was found.",otherRemoteDomain);
// As this sub/superdomain is different from the original remote domain, we need to check if it supports dialback.
if(session.isUsingServerDialback())
{
log.debug("Dialback was used for '{}'. This session can be re-used.",otherRemoteDomain);
break;
break;
}else{
}
else
{
log.debug("Dialback was not used for '{}'. This session cannot be re-used.",otherRemoteDomain);
session=null;
session=null;
}
}
}
}
}
}
}
}
if(session==null){
if(session==null){
log.debug("There are no pre-existing session to other hostnames for this domain.");
log.debug("There are no pre-existing session to other domains hosted on the remote domain.");
}
}
if(session!=null)
{
log.debug("A pre-existing session can be re-used. The session was established using server dialback so it is possible to do piggybacking to authenticate more domains.");
@@ -188,95 +224,42 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
...
@@ -188,95 +224,42 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
returnfalse;
returnfalse;
}
}
}
}
log.debug("A session already exists. The session was established using server dialback so it is possible to do piggybacking to authenticate more domains.");
log.debug("Plain socket connection to {}:{} successful!",realHostname,realPort);
break;
}
catch(Exceptione){
log.debug("An exception occurred while trying to create a plain socket connection to: {}:{}",realHostname,realPort,e);
log.warn("Unable to create plain socket connection to: {}:{}. Cause: {} (a full stacktrace is logged on debug level)",realHostname,realPort,e.getMessage());
try{
if(socket!=null){
socket.close();
}
}
catch(IOExceptionex){
log.debug("Additional exception while trying to close socket when connection to remote server failed.",ex);
}
}
}
if(!socket.isConnected()){
log.info("Unable to create new session: Cannot create a plain socket connection with any applicable host.");
@@ -363,7 +347,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
...
@@ -363,7 +347,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
catch(SSLHandshakeExceptione)
catch(SSLHandshakeExceptione)
{
{
// This is a failure as described in RFC3620, section 5.4.3.2 "STARTTLS Failure".
// This is a failure as described in RFC3620, section 5.4.3.2 "STARTTLS Failure".
log.info("STARTTLS negotiation (with {}:{}) failed. Closing connection (without sending any data such as <failure/> or </stream>).",realHostname,realPort,e);
log.info("STARTTLS negotiation failed. Closing connection (without sending any data such as <failure/> or </stream>).",e);
// The receiving entity is expected to close the socket *without* sending any more data (<failure/> nor </stream>).
// The receiving entity is expected to close the socket *without* sending any more data (<failure/> nor </stream>).
// It is probably (see OF-794) best if we, as the initiating entity, therefor don't send any data either.
// It is probably (see OF-794) best if we, as the initiating entity, therefor don't send any data either.
...
@@ -374,7 +358,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
...
@@ -374,7 +358,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
catch(Exceptione)
catch(Exceptione)
{
{
// This might be RFC3620, section 5.4.2.2 "Failure Case" or even an unrelated problem. Handle 'normally'.
// This might be RFC3620, section 5.4.2.2 "Failure Case" or even an unrelated problem. Handle 'normally'.
log.warn("An exception occurred while creating an encrypted session (with {}:{}). Closing connection.",realHostname,realPort,e);
log.warn("An exception occurred while creating an encrypted session. Closing connection.",e);
if(connection!=null){
if(connection!=null){
connection.close();
connection.close();
...
@@ -386,7 +370,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
...
@@ -386,7 +370,7 @@ public class LocalOutgoingServerSession extends LocalServerSession implements Ou
log.debug("Unable to create a new session. Going to try connecting using server dialback as a fallback.");
log.debug("Unable to create a new session. Going to try connecting using server dialback as a fallback.");
// Use server dialback (pre XMPP 1.0) over a plain connection
// Use server dialback (pre XMPP 1.0) over a plain connection