Search in sources :

Example 6 with PacketException

use of org.jivesoftware.openfire.PacketException in project Openfire by igniterealtime.

the class IQRegisterHandler method handleIQ.

@Override
public IQ handleIQ(IQ packet) throws PacketException, UnauthorizedException {
    ClientSession session = sessionManager.getSession(packet.getFrom());
    IQ reply = null;
    // If no session was found then answer an error (if possible)
    if (session == null) {
        Log.error("Error during registration. Session not found in " + sessionManager.getPreAuthenticatedKeys() + " for key " + packet.getFrom());
        // This error packet will probably won't make it through
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.internal_server_error);
        return reply;
    }
    if (IQ.Type.get.equals(packet.getType())) {
        // If inband registration is not allowed, return an error.
        if (!registrationEnabled) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.forbidden);
        } else {
            reply = IQ.createResultIQ(packet);
            if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                try {
                    User user = userManager.getUser(session.getUsername());
                    Element currentRegistration = probeResult.createCopy();
                    currentRegistration.addElement("registered");
                    currentRegistration.element("username").setText(user.getUsername());
                    currentRegistration.element("password").setText("");
                    currentRegistration.element("email").setText(user.getEmail() == null ? "" : user.getEmail());
                    currentRegistration.element("name").setText(user.getName());
                    Element form = currentRegistration.element(QName.get("x", "jabber:x:data"));
                    Iterator fields = form.elementIterator("field");
                    Element field;
                    while (fields.hasNext()) {
                        field = (Element) fields.next();
                        if ("username".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getUsername());
                        } else if ("name".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getName());
                        } else if ("email".equals(field.attributeValue("var"))) {
                            field.addElement("value").addText(user.getEmail() == null ? "" : user.getEmail());
                        }
                    }
                    reply.setChildElement(currentRegistration);
                } catch (UserNotFoundException e) {
                    reply.setChildElement(probeResult.createCopy());
                }
            } else {
                // This is a workaround. Since we don't want to have an incorrect TO attribute
                // value we need to clean up the TO attribute. The TO attribute will contain an
                // incorrect value since we are setting a fake JID until the user actually
                // authenticates with the server.
                reply.setTo((JID) null);
                reply.setChildElement(probeResult.createCopy());
            }
        }
    } else if (IQ.Type.set.equals(packet.getType())) {
        try {
            Element iqElement = packet.getChildElement();
            if (iqElement.element("remove") != null) {
                // If inband registration is not allowed, return an error.
                if (!registrationEnabled) {
                    reply = IQ.createResultIQ(packet);
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.forbidden);
                } else {
                    if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                        User user = userManager.getUser(session.getUsername());
                        // Delete the user
                        userManager.deleteUser(user);
                        // Delete the roster of the user
                        rosterManager.deleteRoster(session.getAddress());
                        // Delete the user from all the Groups
                        GroupManager.getInstance().deleteUser(user);
                        reply = IQ.createResultIQ(packet);
                        session.process(reply);
                        // Take a quick nap so that the client can process the result
                        Thread.sleep(10);
                        // Close the user's connection
                        final StreamError error = new StreamError(StreamError.Condition.not_authorized);
                        for (ClientSession sess : sessionManager.getSessions(user.getUsername())) {
                            sess.deliverRawText(error.toXML());
                            sess.close();
                        }
                        // The reply has been sent so clean up the variable
                        reply = null;
                    } else {
                        throw new UnauthorizedException();
                    }
                }
            } else {
                String username;
                String password = null;
                String email = null;
                String name = null;
                User newUser;
                DataForm registrationForm;
                FormField field;
                Element formElement = iqElement.element("x");
                // Check if a form was used to provide the registration info
                if (formElement != null) {
                    // Get the sent form
                    registrationForm = new DataForm(formElement);
                    // Get the username sent in the form
                    List<String> values = registrationForm.getField("username").getValues();
                    username = (!values.isEmpty() ? values.get(0) : " ");
                    // Get the password sent in the form
                    field = registrationForm.getField("password");
                    if (field != null) {
                        values = field.getValues();
                        password = (!values.isEmpty() ? values.get(0) : " ");
                    }
                    // Get the email sent in the form
                    field = registrationForm.getField("email");
                    if (field != null) {
                        values = field.getValues();
                        email = (!values.isEmpty() ? values.get(0) : " ");
                    }
                    // Get the name sent in the form
                    field = registrationForm.getField("name");
                    if (field != null) {
                        values = field.getValues();
                        name = (!values.isEmpty() ? values.get(0) : " ");
                    }
                } else {
                    // Get the registration info from the query elements
                    username = iqElement.elementText("username");
                    password = iqElement.elementText("password");
                    email = iqElement.elementText("email");
                    name = iqElement.elementText("name");
                }
                if (email != null && email.matches("\\s*")) {
                    email = null;
                }
                if (name != null && name.matches("\\s*")) {
                    name = null;
                }
                // stringprep validity now.
                if (username != null) {
                    Stringprep.nodeprep(username);
                }
                if (session.getStatus() == Session.STATUS_AUTHENTICATED) {
                    // Flag that indicates if the user is *only* changing his password
                    boolean onlyPassword = false;
                    if (iqElement.elements().size() == 2 && iqElement.element("username") != null && iqElement.element("password") != null) {
                        onlyPassword = true;
                    }
                    // If users are not allowed to change their password, return an error.
                    if (password != null && !canChangePassword) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else // If inband registration is not allowed, return an error.
                    if (!onlyPassword && !registrationEnabled) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else {
                        User user = userManager.getUser(session.getUsername());
                        if (user.getUsername().equalsIgnoreCase(username)) {
                            if (password != null && password.trim().length() > 0) {
                                user.setPassword(password);
                            }
                            if (!onlyPassword) {
                                user.setEmail(email);
                            }
                            newUser = user;
                        } else if (password != null && password.trim().length() > 0) {
                            // An admin can create new accounts when logged in.
                            newUser = userManager.createUser(username, password, null, email);
                        } else {
                            // Deny registration of users with no password
                            reply = IQ.createResultIQ(packet);
                            reply.setChildElement(packet.getChildElement().createCopy());
                            reply.setError(PacketError.Condition.not_acceptable);
                            return reply;
                        }
                    }
                } else {
                    // If inband registration is not allowed, return an error.
                    if (!registrationEnabled) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.forbidden);
                        return reply;
                    } else // information was not provided
                    if (password == null || password.trim().length() == 0) {
                        reply = IQ.createResultIQ(packet);
                        reply.setChildElement(packet.getChildElement().createCopy());
                        reply.setError(PacketError.Condition.not_acceptable);
                        return reply;
                    } else {
                        // Create the new account
                        newUser = userManager.createUser(username, password, name, email);
                    }
                }
                // Set and save the extra user info (e.g. full name, etc.)
                if (newUser != null && name != null && !name.equals(newUser.getName())) {
                    newUser.setName(name);
                }
                reply = IQ.createResultIQ(packet);
            }
        } catch (UserAlreadyExistsException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.conflict);
        } catch (UserNotFoundException e) {
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.bad_request);
        } catch (StringprepException e) {
            // The specified username is not correct according to the stringprep specs
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.jid_malformed);
        } catch (IllegalArgumentException e) {
            // At least one of the fields passed in is not valid
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.not_acceptable);
            Log.warn(e.getMessage(), e);
        } catch (UnsupportedOperationException e) {
            // The User provider is read-only so this operation is not allowed
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.not_allowed);
        } catch (Exception e) {
            // Some unexpected error happened so return an internal_server_error
            reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.internal_server_error);
            Log.error(e.getMessage(), e);
        }
    }
    if (reply != null) {
        // why is this done here instead of letting the iq handler do it?
        session.process(reply);
    }
    return null;
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) User(org.jivesoftware.openfire.user.User) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) StringprepException(gnu.inet.encoding.StringprepException) PacketException(org.jivesoftware.openfire.PacketException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) StringprepException(gnu.inet.encoding.StringprepException) StreamError(org.xmpp.packet.StreamError) ClientSession(org.jivesoftware.openfire.session.ClientSession) Iterator(java.util.Iterator) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) DataForm(org.xmpp.forms.DataForm) List(java.util.List) FormField(org.xmpp.forms.FormField)

Example 7 with PacketException

use of org.jivesoftware.openfire.PacketException in project Openfire by igniterealtime.

the class IQHandler method process.

@Override
public void process(Packet packet) throws PacketException {
    IQ iq = (IQ) packet;
    try {
        IQ reply = handleIQ(iq);
        if (reply != null) {
            deliverer.deliver(reply);
        }
    } catch (org.jivesoftware.openfire.auth.UnauthorizedException e) {
        if (iq != null) {
            try {
                IQ response = IQ.createResultIQ(iq);
                response.setChildElement(iq.getChildElement().createCopy());
                response.setError(PacketError.Condition.not_authorized);
                sessionManager.getSession(iq.getFrom()).process(response);
            } catch (Exception de) {
                Log.error(LocaleUtils.getLocalizedString("admin.error"), de);
                sessionManager.getSession(iq.getFrom()).close();
            }
        }
    } catch (Exception e) {
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        try {
            IQ response = IQ.createResultIQ(iq);
            response.setChildElement(iq.getChildElement().createCopy());
            response.setError(PacketError.Condition.internal_server_error);
            sessionManager.getSession(iq.getFrom()).process(response);
        } catch (Exception e1) {
        // Do nothing
        }
    }
}
Also used : IQ(org.xmpp.packet.IQ) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) PacketException(org.jivesoftware.openfire.PacketException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException)

Example 8 with PacketException

use of org.jivesoftware.openfire.PacketException in project Openfire by igniterealtime.

the class PresenceUpdateHandler method broadcastUpdate.

/**
     * Broadcast the given update to all subscribers. We need to:
     * <ul>
     * <li>Query the roster table for subscribers</li>
     * <li>Iterate through the list and send the update to each subscriber</li>
     * </ul>
     * <p/>
     * Is there a safe way to cache the query results while maintaining
     * integrity with roster changes?
     *
     * @param update The update to broadcast
     */
private void broadcastUpdate(Presence update) {
    if (update.getFrom() == null) {
        return;
    }
    if (localServer.isLocal(update.getFrom())) {
        // Do nothing if roster service is disabled
        if (!RosterManager.isRosterServiceEnabled()) {
            return;
        }
        // Local updates can simply run through the roster of the local user
        String name = update.getFrom().getNode();
        try {
            if (name != null && !"".equals(name)) {
                Roster roster = rosterManager.getRoster(name);
                roster.broadcastPresence(update);
            }
        } catch (UserNotFoundException e) {
            Log.warn("Presence being sent from unknown user " + name, e);
        } catch (PacketException e) {
            Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        }
    } else {
        // Foreign updates will do a reverse lookup of entries in rosters
        // on the server
        Log.warn("Presence requested from server " + localServer.getServerInfo().getXMPPDomain() + " by unknown user: " + update.getFrom());
    }
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) Roster(org.jivesoftware.openfire.roster.Roster) PacketException(org.jivesoftware.openfire.PacketException)

Example 9 with PacketException

use of org.jivesoftware.openfire.PacketException in project Openfire by igniterealtime.

the class PresenceUpdateHandler method directedPresenceSent.

/**
     * Notification method sent to this handler when a user has sent a directed
     * presence to an entity. If the sender of the presence is local (to this server)
     * and the target entity does not belong to the user's roster then update the
     * registry of sent directed presences by the user.
     *
     * @param update  the directed Presence sent by the user to an entity.
     * @param handlerJID the JID of the handler that will receive/handle/process the sent packet.
     * @param jid     the receipient specified in the packet to handle.
     */
public void directedPresenceSent(Presence update, JID handlerJID, String jid) {
    if (update.getFrom() == null) {
        return;
    }
    if (localServer.isLocal(update.getFrom())) {
        boolean keepTrack = false;
        String name = update.getFrom().getNode();
        if (name != null && !"".equals(name)) {
            // Keep track of all directed presences if roster service is disabled
            if (!RosterManager.isRosterServiceEnabled()) {
                keepTrack = true;
            } else {
                try {
                    Roster roster = rosterManager.getRoster(name);
                    // If the directed presence was sent to an entity that is not in the user's
                    // roster, keep a registry of this so that when the user goes offline we
                    // will be able to send the unavailable presence to the entity
                    RosterItem rosterItem = null;
                    try {
                        rosterItem = roster.getRosterItem(update.getTo());
                    } catch (UserNotFoundException e) {
                    // Ignore
                    }
                    if (rosterItem == null || RosterItem.SUB_NONE == rosterItem.getSubStatus() || RosterItem.SUB_TO == rosterItem.getSubStatus()) {
                        keepTrack = true;
                    }
                } catch (UserNotFoundException e) {
                    Log.warn("Presence being sent from unknown user " + name, e);
                } catch (PacketException e) {
                    Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
                }
            }
        } else if (update.getFrom().getResource() != null) {
            // Keep always track of anonymous users directed presences
            keepTrack = true;
        }
        if (keepTrack) {
            String sender = update.getFrom().toString();
            Lock lock = CacheFactory.getLock(sender, directedPresencesCache);
            try {
                lock.lock();
                Collection<DirectedPresence> directedPresences = directedPresencesCache.get(sender);
                if (Presence.Type.unavailable.equals(update.getType())) {
                    if (directedPresences != null) {
                        // It's a directed unavailable presence
                        if (routingTable.hasClientRoute(handlerJID)) {
                            // address of the session) so remove the handler from the map
                            for (DirectedPresence directedPresence : directedPresences) {
                                if (directedPresence.getHandler().equals(handlerJID)) {
                                    directedPresences.remove(directedPresence);
                                    break;
                                }
                            }
                        } else {
                            // unavailable presence
                            for (DirectedPresence directedPresence : directedPresences) {
                                if (directedPresence.getHandler().equals(handlerJID)) {
                                    directedPresence.removeReceiver(jid);
                                    if (directedPresence.isEmpty()) {
                                        directedPresences.remove(directedPresence);
                                    }
                                    break;
                                }
                            }
                        }
                        if (directedPresences.isEmpty()) {
                            // Remove the user from the registry since the list of directed
                            // presences is empty
                            directedPresencesCache.remove(sender);
                            localDirectedPresences.remove(sender);
                        } else {
                            directedPresencesCache.put(sender, directedPresences);
                            localDirectedPresences.put(sender, directedPresences);
                        }
                    }
                } else {
                    if (directedPresences == null) {
                        // We are using a set to avoid duplicate jids in case the user
                        // sends several directed presences to the same handler. The Map also
                        // ensures that if the user sends several presences to the same handler
                        // we will have only one entry in the Map
                        directedPresences = new ConcurrentLinkedQueue<>();
                    }
                    // Add the handler to the list of handler that processed the directed
                    // presence sent by the user. This handler will be used to send
                    // the unavailable presence when the user goes offline
                    DirectedPresence affectedDirectedPresence = null;
                    for (DirectedPresence directedPresence : directedPresences) {
                        if (directedPresence.getHandler().equals(handlerJID)) {
                            affectedDirectedPresence = directedPresence;
                            break;
                        }
                    }
                    if (affectedDirectedPresence == null) {
                        affectedDirectedPresence = new DirectedPresence(handlerJID);
                        directedPresences.add(affectedDirectedPresence);
                    }
                    affectedDirectedPresence.addReceiver(jid);
                    directedPresencesCache.put(sender, directedPresences);
                    localDirectedPresences.put(sender, directedPresences);
                }
            } finally {
                lock.unlock();
            }
        }
    }
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) Roster(org.jivesoftware.openfire.roster.Roster) PacketException(org.jivesoftware.openfire.PacketException) Lock(java.util.concurrent.locks.Lock)

Aggregations

PacketException (org.jivesoftware.openfire.PacketException)9 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)6 IQ (org.xmpp.packet.IQ)5 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)4 Roster (org.jivesoftware.openfire.roster.Roster)4 JID (org.xmpp.packet.JID)4 Element (org.dom4j.Element)3 UserAlreadyExistsException (org.jivesoftware.openfire.user.UserAlreadyExistsException)3 Iterator (java.util.Iterator)2 SharedGroupException (org.jivesoftware.openfire.SharedGroupException)2 RosterItem (org.jivesoftware.openfire.roster.RosterItem)2 User (org.jivesoftware.openfire.user.User)2 IDNAException (gnu.inet.encoding.IDNAException)1 StringprepException (gnu.inet.encoding.StringprepException)1 List (java.util.List)1 Lock (java.util.concurrent.locks.Lock)1 ClientSession (org.jivesoftware.openfire.session.ClientSession)1 ComponentSession (org.jivesoftware.openfire.session.ComponentSession)1 VCardManager (org.jivesoftware.openfire.vcard.VCardManager)1 Component (org.xmpp.component.Component)1