ComponentSocketReader.java 5.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/**
 * $RCSfile: ComponentSocketReader.java,v $
 * $Revision: 3174 $
 * $Date: 2005-12-08 17:41:00 -0300 (Thu, 08 Dec 2005) $
 *
 * Copyright (C) 2004 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.wildfire.net;

import org.dom4j.Element;
15
import org.jivesoftware.util.Log;
16
import org.jivesoftware.wildfire.PacketRouter;
Gaston Dombiak's avatar
Gaston Dombiak committed
17
import org.jivesoftware.wildfire.RoutingTable;
18
import org.jivesoftware.wildfire.auth.UnauthorizedException;
19 20
import org.jivesoftware.wildfire.component.ComponentSession;
import org.jivesoftware.wildfire.component.InternalComponentManager;
21
import org.xmlpull.v1.XmlPullParserException;
22 23
import org.xmpp.component.ComponentException;
import org.xmpp.packet.PacketError;
24 25 26 27 28 29 30 31 32 33 34 35

import java.io.IOException;
import java.net.Socket;

/**
 * A SocketReader specialized for component connections. This reader will be used when the open
 * stream contains a jabber:component:accept namespace.
 *
 * @author Gaston Dombiak
 */
public class ComponentSocketReader extends SocketReader {

Gaston Dombiak's avatar
Gaston Dombiak committed
36 37 38
    public ComponentSocketReader(PacketRouter router, RoutingTable routingTable, String serverName,
            Socket socket, SocketConnection connection, boolean useBlockingMode) {
        super(router, routingTable, serverName, socket, connection, useBlockingMode);
39 40 41
    }

    /**
42 43 44
     * 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.
45 46
     *
     * @param doc the unknown DOM element that was received
47
     * @return false if packet is unknown otherwise true.
48 49
     */
    protected boolean processUnknowPacket(Element doc) {
50 51 52 53 54 55 56 57 58 59 60 61 62
        // 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());
            }
63 64 65 66 67
            else if (extraDomain.equals(initialDomain)) {
                // Component is binding initial domain that is already registered
                // Send confirmation that the new domain has been registered
                connection.deliverRawText("<bind/>");
            }
68 69 70 71 72 73 74 75 76 77
            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 {
78 79 80 81 82 83 84
                        // Get the requested subdomain
                        String subdomain = extraDomain;
                        int index = extraDomain.indexOf(serverName);
                        if (index > -1) {
                            subdomain = extraDomain.substring(0, index -1);
                        }
                        InternalComponentManager.getInstance().addComponent(subdomain, component);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
                        // 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)
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        return false;
    }

    boolean createSession(String namespace) throws UnauthorizedException, XmlPullParserException,
            IOException {
        if ("jabber:component:accept".equals(namespace)) {
            // The connected client is a component so create a ComponentSession
            session = ComponentSession.createSession(serverName, reader, connection);
            return true;
        }
        return false;
    }

    String getNamespace() {
        return "jabber:component:accept";
    }

126 127 128 129
    String getName() {
        return "Component SR - " + hashCode();
    }

130 131 132 133
    boolean validateHost() {
        return false;
    }
}