Commit 4f2ccfe4 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Allow external components to bind many domains. JM-624

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3689 b35dd754-fafc-0310-a699-88a17e54d16e
parent 8f401fe8
......@@ -12,11 +12,11 @@ package org.jivesoftware.wildfire.component;
import org.dom4j.Element;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.*;
import org.jivesoftware.wildfire.auth.AuthFactory;
import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.component.Component;
......@@ -27,6 +27,8 @@ import org.xmpp.packet.StreamError;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
/**
* Represents a session between the server and a component.
......@@ -180,7 +182,7 @@ public class ComponentSession extends Session {
writer.flush();
// Bind the domain to this component
ExternalComponent component = ((ComponentSession) session).getExternalComponent();
component.setSubdomain(subdomain);
component.setInitialSubdomain(subdomain);
InternalComponentManager.getInstance().addComponent(subdomain, component);
Log.debug("[ExComp] External component was registered SUCCESSFULLY with domain: " +
domain);
......@@ -229,7 +231,15 @@ public class ComponentSession extends Session {
private String name = "";
private String type = "";
private String category = "";
private String subdomain;
/**
* Subdomain used when creating the initial connection.
*/
private String initialSubdomain;
/**
* List of subdomains that were binded for this component. The list will include
* the initial subdomain.
*/
private Collection<String> subdomains = new ArrayList<String>();
public void processPacket(Packet packet) {
if (conn != null && !conn.isClosed()) {
......@@ -271,12 +281,21 @@ public class ComponentSession extends Session {
this.category = category;
}
public String getSubdomain() {
return subdomain;
public String getInitialSubdomain() {
return initialSubdomain;
}
public void setInitialSubdomain(String initialSubdomain) {
this.initialSubdomain = initialSubdomain;
addSubdomain(initialSubdomain);
}
public void setSubdomain(String subdomain) {
this.subdomain = subdomain;
public void addSubdomain(String subdomain) {
subdomains.add(subdomain);
}
public Collection<String> getSubdomains() {
return subdomains;
}
public void initialize(JID jid, ComponentManager componentManager) {
......@@ -287,5 +306,9 @@ public class ComponentSession extends Session {
public void shutdown() {
}
public String toString() {
return super.toString() + " - subdomains: " + subdomains;
}
}
}
\ No newline at end of file
package org.jivesoftware.wildfire.component;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.Session;
import org.jivesoftware.wildfire.SessionManager;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.component.ExternalComponentConfiguration.Permission;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -325,10 +325,13 @@ public class ExternalComponentManager {
*/
public static void setPermissionPolicy(PermissionPolicy policy) {
JiveGlobals.setProperty("xmpp.component.permission", policy.toString());
// Check if the connected component can remain connected to the server
// Check if connected components can remain connected to the server
for (ComponentSession session : SessionManager.getInstance().getComponentSessions()) {
if (!canAccess(session.getExternalComponent().getSubdomain())) {
for (String domain : session.getExternalComponent().getSubdomains()) {
if (!canAccess(domain)) {
session.getConnection().close();
break;
}
}
}
}
......@@ -357,6 +360,6 @@ public class ExternalComponentManager {
* Only the XMPP entities listed in the <b>allowed list</b> are able to connect to
* the server.
*/
whitelist;
whitelist
}
}
......@@ -12,10 +12,14 @@
package org.jivesoftware.wildfire.net;
import org.dom4j.Element;
import org.jivesoftware.wildfire.component.ComponentSession;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.PacketRouter;
import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.jivesoftware.wildfire.component.ComponentSession;
import org.jivesoftware.wildfire.component.InternalComponentManager;
import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.component.ComponentException;
import org.xmpp.packet.PacketError;
import java.io.IOException;
import java.net.Socket;
......@@ -34,13 +38,63 @@ public class ComponentSocketReader extends SocketReader {
}
/**
* Only packets of type Message, Presence and IQ can be processed by this class. Any other
* type of packet is unknown and thus rejected generating the connection to be closed.
* Only <tt>bind<tt> packets will be processed by this class to bind more domains
* to existing external components. Any other type of packet is unknown and thus
* rejected generating the connection to be closed.
*
* @param doc the unknown DOM element that was received
* @return always false.
* @return false if packet is unknown otherwise true.
*/
protected boolean processUnknowPacket(Element doc) {
// Handle subsequent bind packets
if ("bind".equals(doc.getName())) {
ComponentSession componentSession = (ComponentSession) session;
// Get the external component of this session
ComponentSession.ExternalComponent component = componentSession.getExternalComponent();
String initialDomain = component.getInitialSubdomain();
String extraDomain = doc.attributeValue("name");
if (extraDomain == null || "".equals(extraDomain)) {
// No new bind domain was specified so return a bad_request error
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.bad_request).getElement());
connection.deliverRawText(reply.asXML());
}
else if (extraDomain.endsWith(initialDomain)) {
// Only accept subdomains under the initial registered domain
if (component.getSubdomains().contains(extraDomain)) {
// Domain already in use so return a conflict error
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.conflict).getElement());
connection.deliverRawText(reply.asXML());
}
else {
try {
InternalComponentManager.getInstance().addComponent(extraDomain, component);
component.addSubdomain(extraDomain);
// Send confirmation that the new domain has been registered
connection.deliverRawText("<bind/>");
}
catch (ComponentException e) {
Log.error("Error binding extra domain: " + extraDomain + " to component: " +
component, e);
// Return internal server error
Element reply = doc.createCopy();
reply.add(new PacketError(
PacketError.Condition.internal_server_error).getElement());
connection.deliverRawText(reply.asXML());
}
}
}
else {
// Return forbidden error since we only allow subdomains of the intial domain
// to be used by the same external component
Element reply = doc.createCopy();
reply.add(new PacketError(PacketError.Condition.forbidden).getElement());
connection.deliverRawText(reply.asXML());
}
return true;
}
// This is an unknown packet so return false (and close the connection)
return false;
}
......
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