Commit 66eb733e authored by Dave Cridland's avatar Dave Cridland Committed by GitHub

Merge pull request #705 from guusdk/OF-477

OF-477: Improve default XMPP domain name and FQDN
parents 6c67e99e 4ba3e173
......@@ -1037,8 +1037,8 @@ index.version=Version:
index.home=Server Directory:
index.certificate-warning=Found RSA certificate that is not valid for the server domain.
index.certificate-error=Unable to access certificate store. The keystore may be corrupt.
index.server_name=Server Name:
index.host_name=Host Name:
index.server_name=XMPP Domain Name:
index.host_name=Server Host Name (FQDN):
index.server_port=Server Ports
index.server_ip=IP:Port, Security:
index.port_type=NORMAL
......@@ -1520,7 +1520,7 @@ server.props.update.norestart=Server properties updated successfully
server.props.update=Server properties updated successfully. You'll need to
server.props.update2=the server to have the changes take effect (see
server.props.property=Server Properties
server.props.name=Server Name:
server.props.name=Server Host Name (FQDN):
server.props.valid_hostname=Please enter a valid server host name or
server.props.valid_hostname1=restore the default
server.props.server_port=Server-to-Server Port:
......@@ -2116,11 +2116,13 @@ setup.finished.wait=Please wait, finishing setup...
# Setup host settings Page
setup.host.settings.title=Server Settings
setup.host.settings.info=Below are host settings for this server. Note: the suggested value for the \
domain is based on the network settings of this machine.
setup.host.settings.domain=Domain:
setup.host.settings.info=Below are network settings for this server.
setup.host.settings.domain=XMPP Domain Name:
setup.host.settings.domain.help=The name of the XMPP domain that this server will be part of (for example: example.org). If this server will be part of an Openfire cluster, each server must have the same XMPP domain name.
setup.host.settings.invalid_domain=Invalid domain.
setup.host.settings.hostname=Hostname or IP address of this server.
setup.host.settings.fqdn=Server Host Name (FQDN):
setup.host.settings.fqdn.help=The fully qualified domain name of this server (for example: openfire.example.org). If this server will be part of an Openfire cluster, each server must have the same host name.
setup.host.settings.invalid_fqdn=Invalid host name.
setup.host.settings.port=Admin Console Port:
setup.host.settings.secure_port=Secure Admin Console Port:
setup.host.settings.invalid_port=Invalid port number
......
......@@ -61,8 +61,6 @@ import org.xmpp.packet.JID;
import java.io.*;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -104,10 +102,6 @@ public class XMPPServer {
private static XMPPServer instance;
private String name;
private String host;
private Version version;
private Date startDate;
private boolean initialized = false;
private boolean started = false;
private NodeID nodeID;
......@@ -189,12 +183,9 @@ public class XMPPServer {
* @param jid the JID to check.
* @return true if the address is a local address to this server.
*/
public boolean isLocal(JID jid) {
boolean local = false;
if (jid != null && name != null && name.equals(jid.getDomain())) {
local = true;
}
return local;
public boolean isLocal( JID jid )
{
return jid != null && jid.getDomain().equals( xmppServerInfo.getXMPPDomain() );
}
/**
......@@ -205,13 +196,11 @@ public class XMPPServer {
* @return true if the given address does not match the local server hostname and does not
* match a component service JID.
*/
public boolean isRemote(JID jid) {
if (jid != null) {
if (!name.equals(jid.getDomain()) && !componentManager.hasComponent(jid)) {
return true;
}
}
return false;
public boolean isRemote( JID jid )
{
return jid != null
&& !jid.getDomain().equals( xmppServerInfo.getXMPPDomain() )
&& !componentManager.hasComponent( jid );
}
/**
......@@ -242,8 +231,11 @@ public class XMPPServer {
* @param jid the JID to check.
* @return true if the given address matches a component service JID.
*/
public boolean matchesComponent(JID jid) {
return jid != null && !name.equals(jid.getDomain()) && componentManager.hasComponent(jid);
public boolean matchesComponent( JID jid )
{
return jid != null
&& !jid.getDomain().equals( xmppServerInfo.getXMPPDomain() )
&& componentManager.hasComponent( jid );
}
/**
......@@ -254,7 +246,7 @@ public class XMPPServer {
* @return an XMPPAddress for the server.
*/
public JID createJID(String username, String resource) {
return new JID(username, name, resource);
return new JID(username, xmppServerInfo.getXMPPDomain(), resource);
}
/**
......@@ -267,7 +259,7 @@ public class XMPPServer {
* @return an XMPPAddress for the server.
*/
public JID createJID(String username, String resource, boolean skipStringprep) {
return new JID(username, name, resource, skipStringprep);
return new JID(username, xmppServerInfo.getXMPPDomain(), resource, skipStringprep);
}
/**
......@@ -303,19 +295,6 @@ public class XMPPServer {
private void initialize() throws FileNotFoundException {
locateOpenfire();
startDate = new Date();
try {
host = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ex) {
logger.warn("Unable to determine local hostname.", ex);
}
if (host == null) {
host = "127.0.0.1";
}
version = new Version(4, 1, 0, Version.ReleaseStatus.Beta, -1);
if ("true".equals(JiveGlobals.getXMLProperty("setup"))) {
setupMode = false;
}
......@@ -336,13 +315,12 @@ public class XMPPServer {
}
JiveGlobals.migrateProperty("xmpp.domain");
name = JiveGlobals.getProperty("xmpp.domain", host).toLowerCase();
JiveGlobals.migrateProperty(Log.LOG_DEBUG_ENABLED);
Log.setDebugEnabled(JiveGlobals.getBooleanProperty(Log.LOG_DEBUG_ENABLED, false));
// Update server info
xmppServerInfo = new XMPPServerInfoImpl(name, host, version, startDate);
xmppServerInfo = new XMPPServerInfoImpl(new Date());
initialized = true;
}
......@@ -358,10 +336,6 @@ public class XMPPServer {
}
// Make sure that setup finished correctly.
if ("true".equals(JiveGlobals.getXMLProperty("setup"))) {
// Set the new server domain assigned during the setup process
name = JiveGlobals.getProperty("xmpp.domain").toLowerCase();
xmppServerInfo.setXMPPDomain(name);
// Iterate through all the provided XML properties and set the ones that haven't
// already been touched by setup prior to this method being called.
for (String propName : JiveGlobals.getXMLPropertyNames()) {
......@@ -461,7 +435,7 @@ public class XMPPServer {
pluginManager.start();
// Log that the server has been started
String startupBanner = LocaleUtils.getLocalizedString("short.title") + " " + version.getVersionString() +
String startupBanner = LocaleUtils.getLocalizedString("short.title") + " " + xmppServerInfo.getVersion().getVersionString() +
" [" + JiveGlobals.formatDateTime(new Date()) + "]";
logger.info(startupBanner);
System.out.println(startupBanner);
......
......@@ -42,28 +42,31 @@ public interface XMPPServerInfo {
Version getVersion();
/**
* Obtain the host name (IP address or hostname) of this server node.
* Obtain the fully qualified domain name (hostname or IP address) of this server node.
*
* @return the server's host name as an IP address or host name.
* @return the server's host name.
*/
String getHostname();
/**
* Obtain the server XMPP domain name. Note that, if unconfigured, the
* returned value will equal the hostname or IP address of the server.
* Sets the fully qualified domain name of this server node. Preferrably, this is a network name, but can be an
* IP address.
*
* @return the name of the XMPP domain that this server is part of.
* Note that some SASL implementations depend on the client sending the same FQDN value as the one that is
* configured in the server.
*
* When setting a new host name, the server note must be restarted.
*
* @param fqdn The hostname. When null or empty, a system default will be used instead.
*/
String getXMPPDomain();
void setHostname( String fqdn );
/**
* Set the server XMPP domain name. The server must be
* restarted for this change to take effect.
* Obtain the server XMPP domain name, which is equal for all server nodes in an Openfire cluster.
*
* @param domainName
* the XMPP domain that this server is part of.
* @return the name of the XMPP domain that this server is part of.
*/
void setXMPPDomain(String domainName);
String getXMPPDomain();
/**
* Obtain the date when the server was last started.
......@@ -71,11 +74,4 @@ public interface XMPPServerInfo {
* @return the date the server was started or null if server has not been started.
*/
Date getLastStarted();
/**
* Obtain the server ports active on this server.
*
* @return an iterator over the server ports for this server.
*/
Collection<ServerPort> getServerPorts();
}
\ No newline at end of file
......@@ -20,16 +20,8 @@
package org.jivesoftware.openfire.net;
import java.io.IOException;
import java.util.Map;
import java.util.TimerTask;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;
import org.jivesoftware.openfire.ServerPort;
import org.jivesoftware.openfire.ConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.XMPPServerInfo;
import org.jivesoftware.openfire.container.BasicModule;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
......@@ -38,6 +30,12 @@ import org.jivesoftware.util.TaskEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;
import java.io.IOException;
import java.util.Map;
import java.util.TimerTask;
/**
* Publishes Openfire information as a service using the Multicast DNS (marketed by Apple
* as Rendezvous) protocol. This lets other nodes on the local network to discover
......@@ -107,16 +105,13 @@ public class MulticastDNSService extends BasicModule {
TimerTask startService = new TimerTask() {
@Override
public void run() {
XMPPServerInfo info = XMPPServer.getInstance().getServerInfo();
int clientPortNum = -1;
int componentPortNum = -1;
for (ServerPort port : info.getServerPorts()) {
if (port.isClientPort()) {
clientPortNum = port.getPort();
}
else if (port.isComponentPort()) {
componentPortNum = port.getPort();
}
final ConnectionManager connectionManager = XMPPServer.getInstance().getConnectionManager();
if ( connectionManager != null )
{
clientPortNum = connectionManager.getClientListenerPort();
componentPortNum = connectionManager.getComponentListenerPort();
}
try {
if (jmdns == null) {
......
......@@ -27,6 +27,7 @@ import org.dom4j.Namespace;
import org.dom4j.QName;
import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.XMPPServerInfo;
import org.jivesoftware.openfire.auth.AuthFactory;
import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.keystore.CertificateStoreManager;
......@@ -265,15 +266,14 @@ public class SASLAuthentication {
// OF-477: The SASL implementation requires the fully qualified host name (not the domain name!) of this server,
// yet, most of the XMPP implemenations of DIGEST-MD5 will actually use the domain name. To account for that,
// here, we'll use the host name, unless DIGEST-MD5 is being negotiated!
final String fqhn = JiveGlobals.getProperty( "xmpp.fqdn", XMPPServer.getInstance().getServerInfo().getHostname() );
final String fqdn = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
final String serverName = ( mechanismName.equals( "DIGEST-MD5" ) ? fqdn : fqhn );
final XMPPServerInfo serverInfo = XMPPServer.getInstance().getServerInfo();
final String serverName = ( mechanismName.equals( "DIGEST-MD5" ) ? serverInfo.getXMPPDomain() : serverInfo.getHostname() );
// Construct the configuration properties
final Map<String, Object> props = new HashMap<>();
props.put( LocalSession.class.getCanonicalName(), session );
props.put( Sasl.POLICY_NOANONYMOUS, Boolean.toString( !JiveGlobals.getBooleanProperty( "xmpp.auth.anonymous" ) ) );
props.put( "com.sun.security.sasl.digest.realm", fqdn );
props.put( "com.sun.security.sasl.digest.realm", serverInfo.getXMPPDomain() );
SaslServer saslServer = Sasl.createSaslServer( mechanismName, "xmpp", serverName, props, new XMPPCallbackHandler() );
if ( saslServer == null )
......
......@@ -20,15 +20,14 @@
package org.jivesoftware.openfire.spi;
import org.jivesoftware.openfire.ConnectionManager;
import org.jivesoftware.openfire.ServerPort;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.XMPPServerInfo;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
/**
......@@ -39,69 +38,62 @@ import java.util.Date;
*/
public class XMPPServerInfoImpl implements XMPPServerInfo {
private Date startDate;
private String xmppDomain;
private String hostname;
private Version ver;
private ConnectionManager connectionManager;
private static final Logger Log = LoggerFactory.getLogger( XMPPServerInfoImpl.class );
private final Date startDate;
public static final Version VERSION = new Version(4, 1, 0, Version.ReleaseStatus.Beta, -1 );
/**
* Simple constructor
*
* @param xmppDomain the server's XMPP domain name (e.g. example.org).
* @param hostname the server's host name (e.g. server1.example.org).
* @param version the server's version number.
* @param startDate the server's last start time (can be null indicating
* it hasn't been started).
*/
public XMPPServerInfoImpl(String xmppDomain, String hostname, Version version, Date startDate) {
this.xmppDomain = xmppDomain;
this.hostname = hostname;
this.ver = version;
public XMPPServerInfoImpl(Date startDate) {
this.startDate = startDate;
}
@Override
public Version getVersion() {
return ver;
return VERSION;
}
@Override
public String getHostname()
{
return hostname;
try
{
return JiveGlobals.getProperty( "xmpp.fqdn", InetAddress.getLocalHost().getCanonicalHostName() ).toLowerCase();
}
@Override
public String getXMPPDomain()
catch (UnknownHostException ex)
{
return xmppDomain;
Log.warn( "Unable to determine local hostname.", ex );
return "localhost";
}
}
@Override
public void setXMPPDomain(String domainName)
public void setHostname( String fqdn )
{
if ( fqdn == null || fqdn.isEmpty() )
{
this.xmppDomain = domainName;
if (domainName == null) {
JiveGlobals.deleteProperty("xmpp.domain");
JiveGlobals.deleteProperty( "xmpp.fqdn" );
}
else {
JiveGlobals.setProperty("xmpp.domain", domainName);
else
{
JiveGlobals.setProperty( "xmpp.fqdn", fqdn.toLowerCase() );
}
}
@Override
public Date getLastStarted() {
return startDate;
public String getXMPPDomain()
{
return JiveGlobals.getProperty("xmpp.domain", getHostname() ).toLowerCase();
}
@Override
public Collection<ServerPort> getServerPorts() {
if (connectionManager == null) {
connectionManager = XMPPServer.getInstance().getConnectionManager();
}
return connectionManager == null ?
Collections.<ServerPort>emptyList() :
connectionManager.getPorts();
public Date getLastStarted() {
return startDate;
}
}
\ No newline at end of file
......@@ -133,7 +133,7 @@
if (errors.size() == 0) {
boolean needRestart = false;
if (!serverName.equals(server.getServerInfo().getXMPPDomain())) {
server.getServerInfo().setXMPPDomain(serverName);
server.getServerInfo().setHostname(serverName);
needRestart = true;
}
connectionManager.setClientListenerPort(port);
......@@ -163,7 +163,7 @@
return;
}
} else {
serverName = server.getServerInfo().getXMPPDomain();
serverName = server.getServerInfo().getHostname();
sslEnabled = connectionManager.isClientSSLListenerEnabled();
port = connectionManager.getClientListenerPort();
sslPort = connectionManager.getClientSSLListenerPort();
......
......@@ -26,6 +26,7 @@
<% // Get parameters
String domain = ParamUtils.getParameter(request, "domain");
String fqdn = ParamUtils.getParameter(request, "fqdn");
int embeddedPort = ParamUtils.getIntParameter(request, "embeddedPort", Integer.MIN_VALUE);
int securePort = ParamUtils.getIntParameter(request, "securePort", Integer.MIN_VALUE);
boolean sslEnabled = ParamUtils.getBooleanParameter(request, "sslEnabled", true);
......@@ -39,9 +40,12 @@
Map<String, String> errors = new HashMap<String, String>();
if (doContinue) {
// Validate parameters
if (domain == null) {
if (domain == null || domain.isEmpty()) {
errors.put("domain", "domain");
}
if (fqdn == null || fqdn.isEmpty()) {
errors.put("fqdn", "fqdn");
}
if (XMPPServer.getInstance().isStandAlone()) {
if (embeddedPort == Integer.MIN_VALUE) {
errors.put("embeddedPort", "embeddedPort");
......@@ -75,6 +79,7 @@
Map<String, String> xmppSettings = new HashMap<String, String>();
xmppSettings.put("xmpp.domain", domain);
xmppSettings.put("xmpp.fqdn", fqdn);
xmppSettings.put("xmpp.socket.ssl.active", "" + sslEnabled);
xmppSettings.put("xmpp.auth.anonymous", "" + anonymousAuthentication);
session.setAttribute("xmppSettings", xmppSettings);
......@@ -96,18 +101,29 @@
// Load the current values:
if (!doContinue) {
domain = JiveGlobals.getXMLProperty("xmpp.domain");
fqdn = JiveGlobals.getXMLProperty("xmpp.fqdn");
embeddedPort = JiveGlobals.getXMLProperty("adminConsole.port", 9090);
securePort = JiveGlobals.getXMLProperty("adminConsole.securePort", 9091);
sslEnabled = JiveGlobals.getXMLProperty("xmpp.socket.ssl.active", true);
// If the domain is still blank, guess at the value:
if (domain == null) {
try {
domain = InetAddress.getLocalHost().getHostName().toLowerCase();
} catch (UnknownHostException e) {
e.printStackTrace();
domain = "127.0.0.1";
// If the fqdn (server name) is still blank, guess:
if (fqdn == null || fqdn.isEmpty())
{
try
{
fqdn = InetAddress.getLocalHost().getCanonicalHostName();
}
catch (UnknownHostException ex)
{
System.err.println( "Unable to determine the fully qualified domain name (canonical hostname) of this server." );
ex.printStackTrace();
fqdn = "localhost";
}
}
// If the domain is still blank, use the host name.
if (domain == null) {
domain = fqdn;
}
}
%>
......@@ -141,7 +157,7 @@
<td width="99%">
<input type="text" size="30" maxlength="150" name="domain"
value="<%= ((domain != null) ? domain : "") %>">
<span class="jive-setup-helpicon" onmouseover="domTT_activate(this, event, 'content', '<fmt:message key="setup.host.settings.hostname" />', 'styleClass', 'jiveTooltip', 'trail', true, 'delay', 300, 'lifetime', 8000);"></span>
<span class="jive-setup-helpicon" onmouseover="domTT_activate(this, event, 'content', '<fmt:message key="setup.host.settings.domain.help" />', 'styleClass', 'jiveTooltip', 'trail', true, 'delay', 300, 'lifetime', 8000);"></span>
<% if (errors.get("domain") != null) { %>
<span class="jive-error-text">
<fmt:message key="setup.host.settings.invalid_domain" />
......@@ -149,6 +165,22 @@
<% } %>
</td>
</tr>
<tr valign="top">
<td width="1%" nowrap align="right">
<fmt:message key="setup.host.settings.fqdn" />
</td>
<td width="99%">
<input type="text" size="30" maxlength="150" name="fqdn"
value="<%= ((fqdn != null) ? fqdn : "") %>">
<span class="jive-setup-helpicon" onmouseover="domTT_activate(this, event, 'content', '<fmt:message key="setup.host.settings.fqdn.help" />', 'styleClass', 'jiveTooltip', 'trail', true, 'delay', 300, 'lifetime', 8000);"></span>
<% if (errors.get("fqdn") != null) { %>
<span class="jive-error-text">
<fmt:message key="setup.host.settings.invalid_fqdn" />
</span>
<% } %>
</td>
</tr>
<% if (XMPPServer.getInstance().isStandAlone()){ %>
<tr valign="top">
<td width="1%" nowrap align="right">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment