Search in sources :

Example 1 with LocalComponentSession

use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.

the class SessionManager method createComponentSession.

public LocalComponentSession createComponentSession(JID address, Connection conn) {
    if (serverName == null) {
        throw new IllegalStateException("Server not initialized");
    }
    StreamID id = nextStreamID();
    LocalComponentSession session = new LocalComponentSession(serverName, conn, id);
    conn.init(session);
    // Register to receive close notification on this session so we can
    // remove the external component from the list of components
    conn.registerCloseListener(componentSessionListener, session);
    // Set the bind address as the address of the session
    session.setAddress(address);
    // Add to component session.
    localSessionManager.getComponentsSessions().add(session);
    // Keep track of the cluster node hosting the new external component
    componentSessionsCache.put(address.toString(), server.getNodeID().toByteArray());
    return session;
}
Also used : LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession)

Example 2 with LocalComponentSession

use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.

the class ComponentStanzaHandler method processUnknowPacket.

@Override
boolean processUnknowPacket(Element doc) throws UnauthorizedException {
    String tag = doc.getName();
    if ("handshake".equals(tag)) {
        // External component is trying to authenticate
        if (!((LocalComponentSession) session).authenticate(doc.getStringValue())) {
            Log.debug("Closing session that failed to authenticate: {}", session);
            session.close();
        }
        return true;
    } else if ("error".equals(tag) && "stream".equals(doc.getNamespacePrefix())) {
        Log.debug("Closing session because of received stream error {}. Affected session: {}", doc.asXML(), session);
        session.close();
        return true;
    } else if ("bind".equals(tag)) {
        // Handle subsequent bind packets
        LocalComponentSession componentSession = (LocalComponentSession) session;
        // Get the external component of this session
        ComponentSession.ExternalComponent component = componentSession.getExternalComponent();
        String initialDomain = component.getInitialSubdomain();
        String extraDomain = doc.attributeValue("name");
        String allowMultiple = doc.attributeValue("allowMultiple");
        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.equals(initialDomain)) {
            // Component is binding initial domain that is already registered
            // Send confirmation that the new domain has been registered
            connection.deliverRawText("<bind/>");
        } else if (extraDomain.endsWith(initialDomain)) {
            // Only accept subdomains under the initial registered domain
            if (allowMultiple != null && 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 {
                    // Get the requested subdomain
                    final String subdomain;
                    int index = extraDomain.indexOf(XMPPServer.getInstance().getServerInfo().getXMPPDomain());
                    if (index > -1) {
                        subdomain = extraDomain.substring(0, index - 1);
                    } else {
                        subdomain = extraDomain;
                    }
                    InternalComponentManager.getInstance().addComponent(subdomain, component);
                    session.getConnection().registerCloseListener(handback -> InternalComponentManager.getInstance().removeComponent(subdomain, (ComponentSession.ExternalComponent) handback), component);
                    // 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;
    }
    return false;
}
Also used : Element(org.dom4j.Element) ComponentException(org.xmpp.component.ComponentException) LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession) ComponentSession(org.jivesoftware.openfire.session.ComponentSession) PacketError(org.xmpp.packet.PacketError) LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession)

Example 3 with LocalComponentSession

use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.

the class ComponentStanzaHandler method processIQ.

@Override
protected void processIQ(IQ packet) throws UnauthorizedException {
    if (session.getStatus() != Session.STATUS_AUTHENTICATED) {
        // Session is not authenticated so return error
        IQ reply = new IQ();
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setID(packet.getID());
        reply.setTo(packet.getFrom());
        reply.setFrom(packet.getTo());
        reply.setError(PacketError.Condition.not_authorized);
        session.process(reply);
        return;
    }
    // Keep track of the component that sent an IQ get/set
    if (packet.getType() == IQ.Type.get || packet.getType() == IQ.Type.set) {
        // Handle subsequent bind packets
        LocalComponentSession componentSession = (LocalComponentSession) session;
        // Get the external component of this session
        LocalComponentSession.LocalExternalComponent component = (LocalComponentSession.LocalExternalComponent) componentSession.getExternalComponent();
        component.track(packet);
    }
    super.processIQ(packet);
}
Also used : IQ(org.xmpp.packet.IQ) LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession)

Example 4 with LocalComponentSession

use of org.jivesoftware.openfire.session.LocalComponentSession in project Openfire by igniterealtime.

the class InternalComponentManager method process.

/**
 * Processes packets that were sent to this service. Currently only packets that were sent from
 * registered components are being processed. In the future, we may also process packet of
 * trusted clients. Trusted clients may be able to execute ad-hoc commands such as adding or
 * removing components.
 *
 * @param packet the packet to process.
 */
@Override
public void process(Packet packet) throws PacketException {
    List<Component> components = getComponents(packet.getFrom());
    // Only process packets that were sent by registered components
    if (!components.isEmpty()) {
        if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) {
            IQ iq = (IQ) packet;
            Element childElement = iq.getChildElement();
            if (childElement != null) {
                String namespace = childElement.getNamespaceURI();
                if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
                    // Add a disco item to the server for the component that supports disco
                    Element identity = childElement.element("identity");
                    if (identity == null) {
                        // Do nothing since there are no identities in the disco#info packet
                        return;
                    }
                    try {
                        XMPPServer.getInstance().getIQDiscoItemsHandler().addComponentItem(packet.getFrom().toBareJID(), identity.attributeValue("name"));
                        for (Component component : components) {
                            if (component instanceof ComponentSession.ExternalComponent) {
                                ComponentSession.ExternalComponent externalComponent = (ComponentSession.ExternalComponent) component;
                                externalComponent.setName(identity.attributeValue("name"));
                                externalComponent.setType(identity.attributeValue("type"));
                                externalComponent.setCategory(identity.attributeValue("category"));
                            }
                        }
                    } catch (Exception e) {
                        Log.error("Error processing disco packet of components: " + components + " - " + packet.toXML(), e);
                    }
                    // Store the IQ disco#info returned by the component
                    addComponentInfo(iq);
                    // Notify listeners that a component answered the disco#info request
                    notifyComponentInfo(iq);
                    // Alert other cluster nodes
                    CacheFactory.doClusterTask(new NotifyComponentInfo(iq));
                } else if ("query".equals(childElement.getQName().getName()) && "jabber:iq:version".equals(namespace)) {
                    try {
                        List<Element> elements = childElement.elements();
                        for (Component component : components) {
                            if (component instanceof LocalComponentSession.LocalExternalComponent) {
                                LocalComponentSession.LocalExternalComponent externalComponent = (LocalComponentSession.LocalExternalComponent) component;
                                LocalComponentSession session = externalComponent.getSession();
                                if (session != null && session.getAddress() == iq.getFrom()) {
                                    if (elements.size() > 0) {
                                        for (Element element : elements) {
                                            session.setSoftwareVersionData(element.getName(), element.getStringValue());
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        Log.error(e.getMessage(), e);
                    }
                } else if ("query".equals(childElement.getQName().getName()) && "http://jabber.org/protocol/disco#info".equals(namespace)) {
                    // XEP-0232 if responses service discovery can include detailed information about the software application
                    for (Component component : components) {
                        if (component instanceof LocalComponentSession.LocalExternalComponent) {
                            LocalComponentSession.LocalExternalComponent externalComponent = (LocalComponentSession.LocalExternalComponent) component;
                            LocalComponentSession session = externalComponent.getSession();
                            if (session != null && session.getAddress() == iq.getFrom()) {
                                IQDiscoInfoHandler.setSoftwareVersionDataFormFromDiscoInfo(childElement, session);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession) ComponentSession(org.jivesoftware.openfire.session.ComponentSession) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) LocalComponentSession(org.jivesoftware.openfire.session.LocalComponentSession)

Aggregations

LocalComponentSession (org.jivesoftware.openfire.session.LocalComponentSession)4 Element (org.dom4j.Element)2 ComponentSession (org.jivesoftware.openfire.session.ComponentSession)2 IQ (org.xmpp.packet.IQ)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 ComponentException (org.xmpp.component.ComponentException)1 PacketError (org.xmpp.packet.PacketError)1