Issue #2756 added security toggle to collaboration
security on HTTP server can be disabled for legacy clients from openfire settings added xmpp connection retry to http server so servers can be started in any order Former-commit-id:7b085f62de
[formerly7b085f62de
[formerly 1e52606fe709f2cf27f835363ca5ab2bf6ada912]] Former-commit-id:f44f1212dd
Former-commit-id:0790849f03
This commit is contained in:
parent
c427ff8471
commit
8b1a00fb2f
12 changed files with 593 additions and 12 deletions
|
@ -34,6 +34,7 @@ import com.raytheon.uf.common.xmpp.XmlBuilder;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 26, 2014 2756 bclement Initial creation
|
||||
* Mar 04, 2014 2756 bclement fixed null return from getChildElementXML
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -80,7 +81,7 @@ public class HttpInfo extends IQ {
|
|||
builder.endTag(URL_ELEMENT);
|
||||
builder.endTag(INFO_ELEMENT);
|
||||
builder.endTag(PacketConstants.QUERY_ELEMENT_NAME);
|
||||
return null;
|
||||
return builder.toXml();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import com.raytheon.uf.common.xmpp.BaseProvider;
|
||||
import com.raytheon.uf.common.xmpp.PacketConstants;
|
||||
|
||||
/**
|
||||
* Custom XMPP IQ packet parser for HTTP configuration
|
||||
|
@ -38,6 +39,7 @@ import com.raytheon.uf.common.xmpp.BaseProvider;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 26, 2014 2756 bclement Initial creation
|
||||
* Mar 03, 2014 2756 bclement fixed call to super constructor
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -51,7 +53,7 @@ public class HttpInfoProvider extends BaseProvider<HttpInfo> implements
|
|||
* @param extensionTagName
|
||||
*/
|
||||
public HttpInfoProvider() {
|
||||
super(HttpInfo.QUERY_XMLNS);
|
||||
super(PacketConstants.QUERY_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.xmpp.iq;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
import com.raytheon.uf.common.xmpp.PacketConstants;
|
||||
import com.raytheon.uf.common.xmpp.XmlBuilder;
|
||||
import com.raytheon.uf.common.xmpp.XmlBuilder.Pair;
|
||||
|
||||
/**
|
||||
* Custom IQ packet for remote security settings control. XMPP clients can query
|
||||
* the server for security status at any time. The XMPP server can also send out
|
||||
* update packets that signal the client to requery the server for an updated
|
||||
* security status.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 03, 2014 2756 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SecurityToggle extends IQ {
|
||||
|
||||
public static final String TOGGLE_QUERY_XMLNS = "urn:uf:viz:collaboration:iq:security:toggle";
|
||||
|
||||
public static final String MODE_ATTRIBUTE = "mode";
|
||||
|
||||
public static enum Mode {
|
||||
ENABLED, DISABLED, UPDATED
|
||||
}
|
||||
|
||||
private Mode mode;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SecurityToggle() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mode
|
||||
*/
|
||||
public SecurityToggle(Mode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iq
|
||||
*/
|
||||
public SecurityToggle(IQ iq) {
|
||||
super(iq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a query packet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static SecurityToggle createGet() {
|
||||
SecurityToggle rval = new SecurityToggle();
|
||||
rval.setType(Type.GET);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a setter packet
|
||||
*
|
||||
* @param m
|
||||
* @return
|
||||
*/
|
||||
public static SecurityToggle createSet(Mode m) {
|
||||
SecurityToggle rval = new SecurityToggle(m);
|
||||
rval.setType(Type.SET);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.jivesoftware.smack.packet.IQ#getChildElementXML()
|
||||
*/
|
||||
@Override
|
||||
public String getChildElementXML() {
|
||||
XmlBuilder builder = new XmlBuilder();
|
||||
List<Pair> attributes;
|
||||
if ( mode != null){
|
||||
attributes = Arrays.asList(new Pair(MODE_ATTRIBUTE, mode.toString()));
|
||||
} else {
|
||||
attributes = Collections.<Pair>emptyList();
|
||||
}
|
||||
builder.appendTag(PacketConstants.QUERY_ELEMENT_NAME,
|
||||
TOGGLE_QUERY_XMLNS, attributes, true);
|
||||
return builder.toXml();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mode
|
||||
*/
|
||||
public Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mode
|
||||
* the mode to set
|
||||
*/
|
||||
public void setMode(Mode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.xmpp.iq;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import com.raytheon.uf.common.xmpp.BaseProvider;
|
||||
import com.raytheon.uf.common.xmpp.PacketConstants;
|
||||
import com.raytheon.uf.common.xmpp.iq.SecurityToggle.Mode;
|
||||
|
||||
/**
|
||||
* Custom XMPP IQ packet parser for security toggle
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 03, 2014 2756 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SecurityToggleProvider extends BaseProvider<SecurityToggle>
|
||||
implements IQProvider {
|
||||
|
||||
/**
|
||||
* @param tagName
|
||||
*/
|
||||
public SecurityToggleProvider() {
|
||||
super(PacketConstants.QUERY_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.raytheon.uf.common.xmpp.BaseProvider#parseInternal(org.xmlpull.v1.XmlPullParser)
|
||||
*/
|
||||
@Override
|
||||
protected SecurityToggle parseInternal(XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
Mode mode = null;
|
||||
|
||||
do {
|
||||
String tagName = parser.getName();
|
||||
switch (parser.getEventType()) {
|
||||
case XmlPullParser.START_TAG:
|
||||
if (PacketConstants.QUERY_ELEMENT_NAME.equals(tagName)) {
|
||||
String modeStr = parser.getAttributeValue(null,
|
||||
SecurityToggle.MODE_ATTRIBUTE);
|
||||
if (modeStr != null && !modeStr.trim().isEmpty()) {
|
||||
mode = Mode.valueOf(modeStr.trim().toUpperCase());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
parser.next();
|
||||
} while (!atEndOfPacket(parser));
|
||||
return new SecurityToggle(mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.provider.IQProvider#parseIQ(org.xmlpull.v1.
|
||||
* XmlPullParser)
|
||||
*/
|
||||
@Override
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
return super.parse(parser);
|
||||
}
|
||||
|
||||
}
|
|
@ -68,4 +68,10 @@
|
|||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="org.apache.commons.codec"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"/>
|
||||
|
||||
</feature>
|
||||
|
|
|
@ -36,6 +36,7 @@ import java.util.Properties;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 5, 2014 2756 bclement Initial creation
|
||||
* Feb 28, 2014 2756 bclement added auth cache size
|
||||
* Mar 04, 2014 2756 bclement added xmpp server retry
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -82,6 +83,11 @@ public class Config{
|
|||
|
||||
public static final int AUTH_CACHE_SIZE_DEFAULT = 64;
|
||||
|
||||
public static final String XMPP_SERVER_RETRY_PERIOD_KEY = "xmpp.server.retry.period";
|
||||
|
||||
// 5 seconds
|
||||
public static final int XMPP_SERVER_RETRY_PERIOD_DEFAULT = 5000;
|
||||
|
||||
public static final String config = System.getProperty(
|
||||
"collaboration.dataserver.config", "config/settings.properties");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.net.UnknownHostException;
|
|||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
|
@ -34,6 +35,8 @@ import com.raytheon.uf.common.xmpp.PacketConstants;
|
|||
import com.raytheon.uf.common.xmpp.iq.AuthInfo;
|
||||
import com.raytheon.uf.common.xmpp.iq.AuthInfoProvider;
|
||||
import com.raytheon.uf.common.xmpp.iq.HttpInfo;
|
||||
import com.raytheon.uf.common.xmpp.iq.SecurityToggle;
|
||||
import com.raytheon.uf.common.xmpp.iq.SecurityToggleProvider;
|
||||
|
||||
/**
|
||||
* Starts and runs XMPP client thread for communication with XMPP server
|
||||
|
@ -43,9 +46,10 @@ import com.raytheon.uf.common.xmpp.iq.HttpInfo;
|
|||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 14, 2014 2756 bclement Initial creation
|
||||
* Feb 28, 2014 2756 bclement added custom IQ packet support
|
||||
* Mar 04, 2014 2756 bclement added xmpp server retry
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -58,6 +62,8 @@ public class XmppServerConnection implements Runnable {
|
|||
ProviderManager pm = ProviderManager.getInstance();
|
||||
pm.addIQProvider(PacketConstants.QUERY_ELEMENT_NAME,
|
||||
AuthInfo.AUTH_QUERY_XMLNS, new AuthInfoProvider());
|
||||
pm.addIQProvider(PacketConstants.QUERY_ELEMENT_NAME,
|
||||
SecurityToggle.TOGGLE_QUERY_XMLNS, new SecurityToggleProvider());
|
||||
}
|
||||
|
||||
private static final int PACKET_SEND_TIMEOUT = 5000; // 5 seconds
|
||||
|
@ -87,11 +93,73 @@ public class XmppServerConnection implements Runnable {
|
|||
this.xmppServerAddress = Config.getProp(Config.XMPP_SERVER_KEY,
|
||||
Config.XMPP_SERVER_DEFAULT);
|
||||
this.conn = new XMPPConnection(xmppServerAddress);
|
||||
retryingConnect(conn);
|
||||
registerListeners(conn);
|
||||
this.conn.connect();
|
||||
this.conn.login(user, password);
|
||||
log.debug("Connected to XMPP server at address: " + xmppServerAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register XMPP packet and event listeners with connection
|
||||
*
|
||||
* @param conn
|
||||
*/
|
||||
private void registerListeners(final XMPPConnection conn) {
|
||||
conn.addConnectionListener(new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void reconnectionSuccessful() {
|
||||
log.info("XMPP reconnection successful");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionFailed(Exception e) {
|
||||
log.warn("XMPP reconnection failed", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectingIn(int seconds) {
|
||||
log.info("Attempting XMPP reconnect in " + seconds + " seconds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
log.warn("XMPP connection closed on error", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
log.info("XMPP connection closed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection retry loop. Does not return until connected.
|
||||
*
|
||||
* @param conn
|
||||
*/
|
||||
private void retryingConnect(XMPPConnection conn) {
|
||||
int period = Config.getInt(Config.XMPP_SERVER_RETRY_PERIOD_KEY,
|
||||
Config.XMPP_SERVER_RETRY_PERIOD_DEFAULT);
|
||||
while (!conn.isConnected()) {
|
||||
try {
|
||||
conn.connect();
|
||||
} catch (XMPPException e) {
|
||||
log.warn("Problem connecting to XMPP server", e);
|
||||
try {
|
||||
Thread.sleep(period);
|
||||
} catch (InterruptedException e1) {
|
||||
log.warn("Interrupted while waiting for XMPP connection",
|
||||
e1);
|
||||
break;
|
||||
}
|
||||
log.warn("Retrying XMPP connection...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
|
|
|
@ -30,8 +30,10 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.apache.commons.collections.map.LRUMap;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
import org.jivesoftware.smack.packet.XMPPError.Condition;
|
||||
|
@ -44,6 +46,8 @@ import com.raytheon.uf.common.http.auth.ServerSignatureAuth;
|
|||
import com.raytheon.uf.common.http.auth.SignedCredential;
|
||||
import com.raytheon.uf.common.xmpp.BaseProvider;
|
||||
import com.raytheon.uf.common.xmpp.iq.AuthInfo;
|
||||
import com.raytheon.uf.common.xmpp.iq.SecurityToggle;
|
||||
import com.raytheon.uf.common.xmpp.iq.SecurityToggle.Mode;
|
||||
|
||||
/**
|
||||
* Manages authentication credentials for HTTP data server which are stored on
|
||||
|
@ -56,6 +60,7 @@ import com.raytheon.uf.common.xmpp.iq.AuthInfo;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 25, 2014 2756 bclement Initial creation
|
||||
* Mar 04, 2014 2756 bclement added security toggle
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -70,7 +75,7 @@ public class ServerAuthManager {
|
|||
|
||||
private final ServerSignatureAuth sigAuth = new ServerSignatureAuth();
|
||||
|
||||
private final boolean isEnabled;
|
||||
private boolean isEnabled;
|
||||
|
||||
private final Map<String, Signature> sigCache;
|
||||
|
||||
|
@ -81,14 +86,85 @@ public class ServerAuthManager {
|
|||
@SuppressWarnings("unchecked")
|
||||
public ServerAuthManager(XmppServerConnection xmppServer)
|
||||
throws XMPPException {
|
||||
isEnabled = BaseProvider.serverSupportsFeature(
|
||||
xmppServer.getConnection(), AuthInfo.AUTH_QUERY_XMLNS);
|
||||
this.xmppServer = xmppServer;
|
||||
XMPPConnection conn = xmppServer.getConnection();
|
||||
registerListeners(conn);
|
||||
isEnabled = isEnabledOnServer(conn);
|
||||
int cacheSize = Config.getInt(Config.AUTH_CACHE_SIZE_KEY,
|
||||
Config.AUTH_CACHE_SIZE_DEFAULT);
|
||||
this.sigCache = Collections.synchronizedMap(new LRUMap(cacheSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register XMPP packet and event listeners with connection
|
||||
*
|
||||
* @param conn
|
||||
*/
|
||||
private void registerListeners(final XMPPConnection conn) {
|
||||
conn.addPacketListener(new PacketListener() {
|
||||
@Override
|
||||
public void processPacket(Packet packet) {
|
||||
/*
|
||||
* XMPP server doesn't send disable/enable message, only update
|
||||
* messages that signal the client to query for the new state
|
||||
*/
|
||||
if (packet instanceof SecurityToggle) {
|
||||
if (((SecurityToggle) packet).getMode()
|
||||
.equals(Mode.UPDATED)) {
|
||||
try {
|
||||
isEnabled = querySecurityToggle(conn);
|
||||
} catch (XMPPException e) {
|
||||
log.warn(
|
||||
"Problem getting updated security settings",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, new PacketTypeFilter(SecurityToggle.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param conn
|
||||
* @return true if security is enabled on the server
|
||||
* @throws XMPPException
|
||||
*/
|
||||
public boolean isEnabledOnServer(XMPPConnection conn) throws XMPPException {
|
||||
boolean rval = BaseProvider.serverSupportsFeature(conn,
|
||||
AuthInfo.AUTH_QUERY_XMLNS);
|
||||
if (rval) {
|
||||
// assume enabled if server doesn't support toggle
|
||||
if (BaseProvider.serverSupportsFeature(conn,
|
||||
SecurityToggle.TOGGLE_QUERY_XMLNS)) {
|
||||
rval = querySecurityToggle(conn);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for security enabled toggle on server. This allows for the xmpp
|
||||
* server to run the public key auth service with new clients without
|
||||
* enforcing security; allowing compatibility with legacy clients
|
||||
*
|
||||
* @param conn
|
||||
* @return true if security toggle is set to enabled
|
||||
* @throws XMPPException
|
||||
*/
|
||||
private boolean querySecurityToggle(XMPPConnection conn)
|
||||
throws XMPPException {
|
||||
boolean rval = false;
|
||||
SecurityToggle query = SecurityToggle.createGet();
|
||||
Packet response = SyncPacketSend.getReply(conn, query);
|
||||
if (response instanceof SecurityToggle) {
|
||||
rval = ((SecurityToggle) response).getMode().equals(Mode.ENABLED);
|
||||
} else {
|
||||
log.warn("Unexpected response from security toggle query: "
|
||||
+ response.toXML());
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cached signature verification for credential.
|
||||
*
|
||||
|
|
|
@ -20,27 +20,34 @@
|
|||
package com.raytheon.openfire.plugin.configuration.collaboration;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.openfire.IQRouter;
|
||||
import org.jivesoftware.openfire.RoutingTable;
|
||||
import org.jivesoftware.openfire.XMPPServer;
|
||||
import org.jivesoftware.openfire.container.Plugin;
|
||||
import org.jivesoftware.openfire.container.PluginManager;
|
||||
import org.jivesoftware.openfire.disco.IQDiscoInfoHandler;
|
||||
import org.jivesoftware.openfire.event.SessionEventDispatcher;
|
||||
import org.jivesoftware.openfire.session.ClientSession;
|
||||
import org.jivesoftware.util.JiveGlobals;
|
||||
import org.jivesoftware.util.TaskEngine;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xmpp.packet.IQ;
|
||||
import org.xmpp.packet.JID;
|
||||
import org.xmpp.packet.Packet;
|
||||
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.configuration.ConfigurationPacket;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.http.HttpStatusMonitor;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.iq.AbstractConfigHandler;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.iq.DataAuthHandler;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.iq.HttpAddressHandler;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.iq.SecurityToggleHandler;
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.listener.CollaborationSessionEventListener;
|
||||
|
||||
/**
|
||||
|
@ -58,6 +65,7 @@ import com.raytheon.openfire.plugin.configuration.collaboration.listener.Collabo
|
|||
* added legacy format setter/accessor
|
||||
* Feb 14, 2013 2756 bclement rename and refactor for operation with generic http
|
||||
* server configured over XMPP
|
||||
* Mar 04, 2014 2756 bclement added dataserver security toggle update to setLegacySupport
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -80,6 +88,8 @@ public class HttpConfigurationPlugin implements Plugin {
|
|||
|
||||
private HttpStatusMonitor httpStatusMonitor;
|
||||
|
||||
private JID serverId;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -142,11 +152,12 @@ public class HttpConfigurationPlugin implements Plugin {
|
|||
|
||||
DataAuthHandler authHandler = new DataAuthHandler();
|
||||
HttpAddressHandler addressHandler = new HttpAddressHandler();
|
||||
SecurityToggleHandler secTogHandler = new SecurityToggleHandler();
|
||||
registerConfigHandlers(server,
|
||||
Arrays.asList(authHandler, addressHandler));
|
||||
Arrays.asList(authHandler, addressHandler, secTogHandler));
|
||||
|
||||
/* Retrieve openfire components. */
|
||||
JID serverId = new JID(server.getServerInfo().getXMPPDomain());
|
||||
serverId = new JID(server.getServerInfo().getXMPPDomain());
|
||||
|
||||
/* The http status monitor */
|
||||
this.httpStatusMonitor = new HttpStatusMonitor(addressHandler, serverId);
|
||||
|
@ -179,6 +190,50 @@ public class HttpConfigurationPlugin implements Plugin {
|
|||
MONITOR_DELAY_MS, this.getHttpMonitorInterval());
|
||||
}
|
||||
|
||||
/**
|
||||
* Send packet to all available client sessions for the primary dataserver
|
||||
* user
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
private void sendPacketToDataserver(final Packet p) {
|
||||
String primary = AbstractConfigHandler.getPrimaryDataServer();
|
||||
if ( primary != null){
|
||||
JID to = new JID(primary);
|
||||
p.setTo(to);
|
||||
p.setFrom(serverId);
|
||||
Collection<ClientSession> sessions = getSessions(to);
|
||||
if (sessions.isEmpty()) {
|
||||
logger.warn("No sessions found for dataserver user");
|
||||
}
|
||||
for (ClientSession session : sessions) {
|
||||
session.process(p);
|
||||
}
|
||||
} else {
|
||||
logger.warn("No dataserver user configured in settings");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of client sessions with server for a user
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
private Collection<ClientSession> getSessions(JID id) {
|
||||
XMPPServer server = XMPPServer.getInstance();
|
||||
RoutingTable routingTable = server.getRoutingTable();
|
||||
List<JID> routes = routingTable.getRoutes(id, serverId);
|
||||
List<ClientSession> rval = new ArrayList<ClientSession>(routes.size());
|
||||
for (JID route : routes) {
|
||||
ClientSession session = routingTable.getClientRoute(route);
|
||||
if (session != null) {
|
||||
rval.add(session);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the scheduled http collaboration status monitor if it has been
|
||||
* scheduled.
|
||||
|
@ -226,6 +281,8 @@ public class HttpConfigurationPlugin implements Plugin {
|
|||
public void setLegacySupport(boolean legacy) {
|
||||
JiveGlobals.setProperty(ConfigurationPacket.LEGACY_KEY,
|
||||
Boolean.toString(legacy));
|
||||
IQ update = SecurityToggleHandler.createUpdatePacket();
|
||||
sendPacketToDataserver(update);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.xmpp.packet.PacketError.Condition;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 12, 2014 2756 bclement Initial creation
|
||||
* Feb 28, 2014 2756 bclement reordered retrieve method operations for clarity
|
||||
* Mar 04, 2014 2756 bclement public createError(), trimmed getPrimaryDataServer() return
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -161,7 +162,7 @@ public abstract class AbstractConfigHandler extends IQHandler implements
|
|||
* @param error
|
||||
* @return
|
||||
*/
|
||||
protected static IQ createError(IQ request, PacketError error) {
|
||||
public static IQ createError(IQ request, PacketError error) {
|
||||
Element child = request.getChildElement();
|
||||
child.setParent(null);
|
||||
IQ rval = IQ.createResultIQ(request);
|
||||
|
@ -249,7 +250,7 @@ public abstract class AbstractConfigHandler extends IQHandler implements
|
|||
return null;
|
||||
}
|
||||
// primary server is the only one or first in list
|
||||
return users[0];
|
||||
return users[0].trim();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.openfire.plugin.configuration.collaboration.iq;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.tree.DefaultAttribute;
|
||||
import org.jivesoftware.openfire.IQHandlerInfo;
|
||||
import org.jivesoftware.openfire.auth.UnauthorizedException;
|
||||
import org.jivesoftware.util.JiveGlobals;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xmpp.packet.IQ;
|
||||
import org.xmpp.packet.IQ.Type;
|
||||
|
||||
import com.raytheon.openfire.plugin.configuration.collaboration.configuration.ConfigurationPacket;
|
||||
|
||||
/**
|
||||
* IQ handler for dataservers to query for security enforcing status
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 4, 2014 2756 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SecurityToggleHandler extends AbstractConfigHandler {
|
||||
|
||||
public static enum Mode {
|
||||
// the openfire build requires the semicolon or it won't compile
|
||||
ENABLED, DISABLED, UPDATED;
|
||||
}
|
||||
|
||||
public static final String TOGGLE_QUERY_XMLNS = "urn:uf:viz:collaboration:iq:security:toggle";
|
||||
|
||||
public static final String MODE_ATTRIBUTE = "mode";
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(SecurityToggleHandler.class);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SecurityToggleHandler() {
|
||||
super("Security Toggle Status Handler", Arrays
|
||||
.asList(TOGGLE_QUERY_XMLNS), new IQHandlerInfo(
|
||||
AbstractConfigHandler.QUERY_ELEMENT_NAME, TOGGLE_QUERY_XMLNS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a packet to send to dataservers when security toggle updates. The
|
||||
* client should respond by querying for the new toggle status.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static IQ createUpdatePacket() {
|
||||
Element query = AbstractConfigHandler.createElement("query",
|
||||
TOGGLE_QUERY_XMLNS);
|
||||
query.add(new DefaultAttribute(MODE_ATTRIBUTE, Mode.UPDATED.toString()));
|
||||
IQ rval = new IQ();
|
||||
rval.setChildElement(query);
|
||||
rval.setType(Type.set);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.openfire.plugin.configuration.collaboration.iq.
|
||||
* AbstractConfigHandler#handleGet(org.xmpp.packet.IQ)
|
||||
*/
|
||||
@Override
|
||||
protected IQ handleGet(IQ packet) throws UnauthorizedException {
|
||||
boolean legacyEnabled = JiveGlobals.getBooleanProperty(
|
||||
ConfigurationPacket.LEGACY_KEY, true);
|
||||
|
||||
Mode mode;
|
||||
if (legacyEnabled) {
|
||||
// legacy mode does not support security
|
||||
mode = Mode.DISABLED;
|
||||
} else {
|
||||
mode = Mode.ENABLED;
|
||||
}
|
||||
Element query = packet.getChildElement();
|
||||
query.setParent(null);
|
||||
query.add(new DefaultAttribute(MODE_ATTRIBUTE, mode.toString()));
|
||||
IQ rval = IQ.createResultIQ(packet);
|
||||
rval.setChildElement(query);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.openfire.plugin.configuration.collaboration.iq.
|
||||
* AbstractConfigHandler#handleSet(org.xmpp.packet.IQ)
|
||||
*/
|
||||
@Override
|
||||
protected IQ handleSet(IQ packet) throws UnauthorizedException {
|
||||
log.debug("Received unsupported packet type: " + packet.getType());
|
||||
throw new UnauthorizedException(
|
||||
"Security toggle status can only be queried");
|
||||
}
|
||||
|
||||
}
|
|
@ -138,13 +138,13 @@
|
|||
</table>
|
||||
</br></br></br>
|
||||
<p>
|
||||
Legacy message format support. If enabled, configuration is sent in chat message to support clients older than version 14.3.
|
||||
Legacy client support. If enabled, HTTP server security is disabled and configuration is sent in chat messages to support clients older than version 14.3.
|
||||
</p>
|
||||
|
||||
<table cellpadding="3" cellspacing="0" border="0" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="15%" valign="top">legacy message format: </td>
|
||||
<td width="15%" valign="top">legacy mode: </td>
|
||||
<td width="85%">
|
||||
<input type="checkbox" id="chkLegacy" name="chkLegacy" value="true" <%= legacyChkValue %> >
|
||||
</td>
|
||||
|
|
Loading…
Add table
Reference in a new issue