Search in sources :

Example 76 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class IQMUCvCardHandler method handleIQ.

@Override
public IQ handleIQ(IQ packet) throws PacketException {
    IQ result = IQ.createResultIQ(packet);
    IQ.Type type = packet.getType();
    if (type.equals(IQ.Type.set)) {
        Log.debug("vCard update request received from: '{}', for: '{}'", packet.getFrom(), packet.getTo());
        try {
            String roomName = packet.getTo().getNode();
            // If no TO was specified then return an error.
            if (roomName == null) {
                Log.debug("vCard update request from: '{}', for: '{}' is invalid: it does not refer to a specific room.", packet.getFrom(), packet.getTo());
                result.setChildElement(packet.getChildElement().createCopy());
                result.setError(PacketError.Condition.not_acceptable);
                result.getError().setText("Request 'to' attribute has no node-part. The request should be addressed to a room of a MUC service.");
            } else {
                final Lock lock = mucService.getChatRoomLock(roomName);
                lock.lock();
                try {
                    final MUCRoom room = mucService.getChatRoom(roomName);
                    Log.debug("vCard update request from: '{}', for: '{}' relates to room: {}", packet.getFrom(), packet.getTo(), room);
                    if (room == null || !room.getOwners().contains(packet.getFrom().asBareJID())) {
                        Log.debug("vCard update request from: '{}', for: '{}' is invalid: room does not exist, or sender is not allowed to discover the room.", packet.getFrom(), packet.getTo());
                        result.setChildElement(packet.getChildElement().createCopy());
                        result.setError(PacketError.Condition.forbidden);
                        result.getError().setText("You are not an owner of this room.");
                    } else {
                        Element vcard = packet.getChildElement();
                        if (vcard != null) {
                            try {
                                VCardManager.getInstance().setVCard(room.getJID().toString(), vcard);
                                // This is what EJabberd does. Mimic it, for compatibility.
                                sendConfigChangeNotification(room);
                                // Mimic a client that broadcasts a vCard update. Converse seems to need this.
                                final String hash = calculatePhotoHash(vcard);
                                sendVCardUpdateNotification(room, hash);
                                Log.debug("vCard update request from: '{}', for: '{}' processed successfully.", packet.getFrom(), packet.getTo());
                            } catch (UnsupportedOperationException e) {
                                Log.debug("Entity '{}' tried to set VCard, but the configured VCard provider is read-only. An IQ error will be returned to sender.", packet.getFrom());
                                // VCards can include binary data. Let's not echo that back in the error.
                                // result.setChildElement( packet.getChildElement().createCopy() );
                                result.setError(PacketError.Condition.not_allowed);
                                // default to server locale.
                                Locale locale = JiveGlobals.getLocale();
                                final Session session = SessionManager.getInstance().getSession(result.getTo());
                                if (session != null && session.getLanguage() != null) {
                                    // use client locale if one is available.
                                    locale = session.getLanguage();
                                }
                                result.getError().setText(LocaleUtils.getLocalizedString("vcard.read_only", locale), locale.getLanguage());
                            }
                        }
                    }
                // No need to ensure that other cluster nodes see the changes applied above, as this code does not apply changes.
                // mucService.syncChatRoom(room);
                } finally {
                    lock.unlock();
                }
            }
        } catch (UserNotFoundException e) {
            // VCards can include binary data. Let's not echo that back in the error.
            // result.setChildElement( packet.getChildElement().createCopy() );
            result.setError(PacketError.Condition.item_not_found);
        } catch (Exception e) {
            Log.error(e.getMessage(), e);
            result.setError(PacketError.Condition.internal_server_error);
        }
    } else if (type.equals(IQ.Type.get)) {
        Log.debug("vCard retrieve request received from: '{}', for: '{}'", packet.getFrom(), packet.getTo());
        String roomName = packet.getTo().getNode();
        // If no TO was specified then return an error.
        if (roomName == null) {
            Log.debug("vCard retrieve request from: '{}', for: '{}' is invalid: it does not refer to a specific room.", packet.getFrom(), packet.getTo());
            result.setChildElement(packet.getChildElement().createCopy());
            result.setError(PacketError.Condition.not_acceptable);
            result.getError().setText("Request 'to' attribute has no node-part. The request should be addressed to a room of a MUC service.");
        } else {
            // By default return an empty vCard
            result.setChildElement(RESPONSE_ELEMENT_NAME, NAMESPACE);
            // Only try to get the vCard values of rooms that can be discovered
            // Answer the room occupants as items if that info is publicly available
            final Lock lock = mucService.getChatRoomLock(roomName);
            lock.lock();
            try {
                final MUCRoom room = mucService.getChatRoom(roomName);
                Log.debug("vCard retrieve request from: '{}', for: '{}' relates to room: {}", packet.getFrom(), packet.getTo(), room);
                if (room != null && mucService.canDiscoverRoom(room, packet.getFrom())) {
                    VCardManager vManager = VCardManager.getInstance();
                    Element userVCard = vManager.getVCard(room.getJID().toString());
                    if (userVCard != null) {
                        // Check if the requester wants to ignore some vCard's fields
                        Element filter = packet.getChildElement().element(QName.get("filter", "vcard-temp-filter"));
                        if (filter != null) {
                            // Create a copy so we don't modify the original vCard
                            userVCard = userVCard.createCopy();
                            // Ignore fields requested by the user
                            for (Iterator<Element> toFilter = filter.elementIterator(); toFilter.hasNext(); ) {
                                Element field = toFilter.next();
                                Element fieldToRemove = userVCard.element(field.getName());
                                if (fieldToRemove != null) {
                                    fieldToRemove.detach();
                                }
                            }
                        }
                        result.setChildElement(userVCard);
                        Log.debug("vCard retrieve request from: '{}', for: '{}' processed successfully.", packet.getFrom(), packet.getTo());
                    }
                } else {
                    Log.debug("vCard retrieve request from: '{}', for: '{}' is invalid: room does not exist, or sender is not allowed to discover the room.", packet.getFrom(), packet.getTo());
                    result = IQ.createResultIQ(packet);
                    result.setChildElement(packet.getChildElement().createCopy());
                    result.setError(PacketError.Condition.item_not_found);
                    result.getError().setText("Request 'to' references a room that cannot be found (or is not discoverable by you).");
                }
            // No need to ensure that other cluster nodes see the changes applied above, as this code does not apply changes.
            // mucService.syncChatRoom(room);
            } finally {
                lock.unlock();
            }
        }
    } else {
        // Ignore non-request IQs
        return null;
    }
    return result;
}
Also used : Locale(java.util.Locale) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) VCardManager(org.jivesoftware.openfire.vcard.VCardManager) PacketException(org.jivesoftware.openfire.PacketException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) Lock(java.util.concurrent.locks.Lock) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) Iterator(java.util.Iterator) Session(org.jivesoftware.openfire.session.Session)

Example 77 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class IQAdminHandler method handleIQ.

/**
 * Handles the IQ packet sent by an owner or admin of the room. Possible actions are:
 * <ul>
 * <li>Return the list of participants</li>
 * <li>Return the list of moderators</li>
 * <li>Return the list of members</li>
 * <li>Return the list of outcasts</li>
 * <li>Change user's affiliation to member</li>
 * <li>Change user's affiliation to outcast</li>
 * <li>Change user's affiliation to none</li>
 * <li>Change occupant's affiliation to moderator</li>
 * <li>Change occupant's affiliation to participant</li>
 * <li>Change occupant's affiliation to visitor</li>
 * <li>Kick occupants from the room</li>
 * </ul>
 *
 * @param packet the IQ packet sent by an owner or admin of the room.
 * @param role the role of the user that sent the request packet.
 * @throws ForbiddenException If the user is not allowed to perform his request.
 * @throws ConflictException If the desired room nickname is already reserved for the room or
 *                           if the room was going to lose all of its owners.
 * @throws NotAllowedException Thrown if trying to ban an owner or an administrator.
 * @throws CannotBeInvitedException If the user being invited as a result of being added to a members-only room still does not have permission
 */
public void handleIQ(IQ packet, MUCRole role) throws ForbiddenException, ConflictException, NotAllowedException, CannotBeInvitedException {
    IQ reply = IQ.createResultIQ(packet);
    Element element = packet.getChildElement();
    // Analyze the action to perform based on the included element
    @SuppressWarnings("unchecked") List<Element> itemsList = element.elements("item");
    if (!itemsList.isEmpty()) {
        handleItemsElement(role, itemsList, reply);
    } else {
        // An unknown and possibly incorrect element was included in the query
        // element so answer a BAD_REQUEST error
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.bad_request);
    }
    if (reply.getTo() != null) {
        // Send a reply only if the sender of the original packet was from a real JID. (i.e. not
        // a packet generated locally)
        XMPPServer.getInstance().getPacketRouter().route(reply);
    }
}
Also used : Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ)

Example 78 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class MultiplexerPacketDeliverer method handleUnprocessedPacket.

private void handleUnprocessedPacket(Packet packet) {
    if (!ClientConnectionHandler.BACKUP_PACKET_DELIVERY_ENABLED.getValue()) {
        Log.trace("Discarding packet that was due to be delivered on closed connection {}, for which no other multiplex connections are available, and no client backup deliverer was configured.", this);
        return;
    }
    if (packet instanceof Message) {
        messageStrategy.storeOffline((Message) packet);
    } else if (packet instanceof Presence) {
    // presence packets are dropped silently
    // dropPacket(packet);
    } else if (packet instanceof IQ) {
        IQ iq = (IQ) packet;
        // Check if we need to unwrap the packet
        Element child = iq.getChildElement();
        if (child != null && "session".equals(child.getName()) && "http://jabber.org/protocol/connectionmanager".equals(child.getNamespacePrefix())) {
            Element send = child.element("send");
            if (send != null) {
                // Unwrap packet
                Element wrappedElement = (Element) send.elements().get(0);
                if ("message".equals(wrappedElement.getName())) {
                    handleUnprocessedPacket(new Message(wrappedElement));
                }
            }
        } else {
            // IQ packets are logged but dropped
            Log.warn(LocaleUtils.getLocalizedString("admin.error.routing") + "\n" + packet.toString());
        }
    }
}
Also used : Message(org.xmpp.packet.Message) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) Presence(org.xmpp.packet.Presence)

Example 79 with IQ

use of org.xmpp.packet.IQ in project Openfire by igniterealtime.

the class MultiplexerPacketHandler method handle.

/**
 * Process IQ packet sent by a connection manager indicating that a new session has
 * been created, should be closed or that a packet was failed to be delivered.
 *
 * @param packet the IQ packet.
 */
public void handle(Packet packet) {
    if (packet instanceof IQ) {
        IQ iq = (IQ) packet;
        if (iq.getType() == IQ.Type.result) {
        // Do nothing with result packets
        } else if (iq.getType() == IQ.Type.error) {
            // Log the IQ error packet that the connection manager failed to process
            Log.warn("Connection Manager failed to process IQ packet: " + packet.toXML());
        } else if (iq.getType() == IQ.Type.set) {
            Element child = iq.getChildElement();
            String streamIDValue = child.attributeValue("id");
            if (streamIDValue == null) {
                // No stream ID was included so return a bad_request error
                Element extraError = DocumentHelper.createElement(QName.get("id-required", "http://jabber.org/protocol/connectionmanager#errors"));
                sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
            } else if ("session".equals(child.getName())) {
                StreamID streamID = BasicStreamIDFactory.createStreamID(streamIDValue);
                Element create = child.element("create");
                if (create != null) {
                    // Get the InetAddress of the client
                    Element hostElement = create.element("host");
                    String hostName = hostElement != null ? hostElement.attributeValue("name") : null;
                    String hostAddress = hostElement != null ? hostElement.attributeValue("address") : null;
                    // Connection Manager wants to create a Client Session
                    boolean created = multiplexerManager.createClientSession(connectionManagerDomain, streamID, hostName, hostAddress);
                    if (created) {
                        sendResultPacket(iq);
                    } else {
                        // Send error to CM. The CM should close the new-born connection
                        sendErrorPacket(iq, PacketError.Condition.not_allowed, null);
                    }
                } else {
                    ClientSession session = multiplexerManager.getClientSession(connectionManagerDomain, streamID);
                    if (session == null) {
                        // Specified Client Session does not exist
                        sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
                    } else if (child.element("close") != null) {
                        // Connection Manager wants to close a Client Session
                        multiplexerManager.closeClientSession(connectionManagerDomain, streamID);
                        sendResultPacket(iq);
                    } else if (child.element("failed") != null) {
                        // Connection Manager failed to deliver a message
                        // Connection Manager wrapped a packet from a Client Session.
                        List wrappedElements = child.element("failed").elements();
                        if (wrappedElements.size() != 1) {
                            // Wrapper element is wrapping 0 or many items
                            Element extraError = DocumentHelper.createElement(QName.get("invalid-payload", "http://jabber.org/protocol/connectionmanager#errors"));
                            sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
                        } else {
                            Element wrappedElement = (Element) wrappedElements.get(0);
                            String tag = wrappedElement.getName();
                            if ("message".equals(tag)) {
                                XMPPServer.getInstance().getOfflineMessageStrategy().storeOffline(new Message(wrappedElement));
                                sendResultPacket(iq);
                            } else {
                                Element extraError = DocumentHelper.createElement(QName.get("unknown-stanza", "http://jabber.org/protocol/connectionmanager#errors"));
                                sendErrorPacket(iq, PacketError.Condition.bad_request, extraError);
                            }
                        }
                    } else {
                        // Unknown IQ packet received so return error to sender
                        sendErrorPacket(iq, PacketError.Condition.bad_request, null);
                    }
                }
            } else {
                // Unknown IQ packet received so return error to sender
                sendErrorPacket(iq, PacketError.Condition.bad_request, null);
            }
        } else {
            // Unknown IQ packet received so return error to sender
            sendErrorPacket(iq, PacketError.Condition.bad_request, null);
        }
    }
}
Also used : StreamID(org.jivesoftware.openfire.StreamID) Message(org.xmpp.packet.Message) Element(org.dom4j.Element) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) ClientSession(org.jivesoftware.openfire.session.ClientSession) IQ(org.xmpp.packet.IQ) List(java.util.List)

Example 80 with IQ

use of org.xmpp.packet.IQ 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)

Aggregations

IQ (org.xmpp.packet.IQ)208 Element (org.dom4j.Element)141 JID (org.xmpp.packet.JID)49 PacketError (org.xmpp.packet.PacketError)35 Presence (org.xmpp.packet.Presence)19 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)18 Message (org.xmpp.packet.Message)17 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)16 ClientSession (org.jivesoftware.openfire.session.ClientSession)14 DataForm (org.xmpp.forms.DataForm)13 ArrayList (java.util.ArrayList)11 AgentNotFoundException (org.jivesoftware.xmpp.workgroup.AgentNotFoundException)10 Packet (org.xmpp.packet.Packet)10 PacketException (org.jivesoftware.openfire.PacketException)9 User (org.jivesoftware.openfire.user.User)8 List (java.util.List)7 PrivacyList (org.jivesoftware.openfire.privacy.PrivacyList)7 Iterator (java.util.Iterator)6 Test (org.junit.Test)6 FormField (org.xmpp.forms.FormField)6