Search in sources :

Example 16 with UnauthorizedException

use of org.jivesoftware.openfire.auth.UnauthorizedException 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 17 with UnauthorizedException

use of org.jivesoftware.openfire.auth.UnauthorizedException in project Openfire by igniterealtime.

the class IQRosterHandler method manageRoster.

/**
     * The packet is a typical 'set' or 'get' update targeted at the server.
     * Notice that the set could be a roster removal in which case we have to
     * generate a local roster removal update as well as a new roster removal
     * to send to the the roster item's owner.
     *
     * @param packet The packet that triggered this update
     * @return Either a response to the roster update or null if the packet is corrupt and the session was closed down
     */
private IQ manageRoster(org.xmpp.packet.Roster packet) throws UnauthorizedException, UserAlreadyExistsException, SharedGroupException {
    IQ returnPacket = null;
    JID sender = packet.getFrom();
    IQ.Type type = packet.getType();
    try {
        if ((sender.getNode() == null || !RosterManager.isRosterServiceEnabled() || !userManager.isRegisteredUser(sender.getNode())) && IQ.Type.get == type) {
            // If anonymous user asks for his roster or roster service is disabled then
            // return an empty roster
            IQ reply = IQ.createResultIQ(packet);
            reply.setChildElement("query", "jabber:iq:roster");
            return reply;
        }
        if (!localServer.isLocal(sender)) {
            // Sender belongs to a remote server so discard this IQ request
            Log.warn("Discarding IQ roster packet of remote user: " + packet);
            return null;
        }
        Roster cachedRoster = userManager.getUser(sender.getNode()).getRoster();
        if (IQ.Type.get == type) {
            returnPacket = cachedRoster.getReset();
            returnPacket.setType(IQ.Type.result);
            returnPacket.setTo(sender);
            returnPacket.setID(packet.getID());
            // Force delivery of the response because we need to trigger
            // a presence probe from all contacts
            deliverer.deliver(returnPacket);
            returnPacket = null;
        } else if (IQ.Type.set == type) {
            returnPacket = IQ.createResultIQ(packet);
            // The <query/> element contains more than one <item/> child element.
            if (packet.getItems().size() > 1) {
                returnPacket.setError(new PacketError(PacketError.Condition.bad_request, PacketError.Type.modify, "Query contains more than one item"));
            } else {
                for (org.xmpp.packet.Roster.Item item : packet.getItems()) {
                    if (item.getSubscription() == org.xmpp.packet.Roster.Subscription.remove) {
                        if (removeItem(cachedRoster, packet.getFrom(), item) == null) {
                            // RFC 6121 2.5.3.  Error Cases: If the value of the 'jid' attribute specifies an item that is not in the roster, then the server MUST return an <item-not-found/> stanza error.
                            returnPacket.setError(PacketError.Condition.item_not_found);
                        }
                    } else {
                        PacketError error = checkGroups(item.getGroups());
                        if (error != null) {
                            returnPacket.setError(error);
                        } else {
                            if (cachedRoster.isRosterItem(item.getJID())) {
                                // existing item
                                RosterItem cachedItem = cachedRoster.getRosterItem(item.getJID());
                                cachedItem.setAsCopyOf(item);
                                cachedRoster.updateRosterItem(cachedItem);
                            } else {
                                // new item
                                cachedRoster.createRosterItem(item);
                            }
                        }
                    }
                }
            }
        }
    } catch (UserNotFoundException e) {
        throw new UnauthorizedException(e);
    }
    return returnPacket;
}
Also used : UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) RosterItem(org.jivesoftware.openfire.roster.RosterItem) RosterItem(org.jivesoftware.openfire.roster.RosterItem) JID(org.xmpp.packet.JID) Roster(org.jivesoftware.openfire.roster.Roster) IQ(org.xmpp.packet.IQ) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) PacketError(org.xmpp.packet.PacketError)

Example 18 with UnauthorizedException

use of org.jivesoftware.openfire.auth.UnauthorizedException in project Openfire by igniterealtime.

the class IQBindHandler method handleIQ.

@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
    LocalClientSession session = (LocalClientSession) sessionManager.getSession(packet.getFrom());
    // If no session was found then answer an error (if possible)
    if (session == null) {
        Log.error("Error during resource binding. Session not found in " + sessionManager.getPreAuthenticatedKeys() + " for key " + packet.getFrom());
        // This error packet will probably won't make it through
        IQ reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.internal_server_error);
        return reply;
    }
    IQ reply = IQ.createResultIQ(packet);
    Element child = reply.setChildElement("bind", "urn:ietf:params:xml:ns:xmpp-bind");
    // Check if the client specified a desired resource
    String resource = packet.getChildElement().elementTextTrim("resource");
    if (resource == null || resource.length() == 0) {
        // None was defined so use the random generated resource
        resource = session.getAddress().getResource();
    } else {
        // Check that the desired resource is valid
        try {
            resource = JID.resourceprep(resource);
        } catch (StringprepException e) {
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.jid_malformed);
            // Send the error directly since a route does not exist at this point.
            session.process(reply);
            return null;
        }
    }
    // Get the token that was generated during the SASL authentication
    AuthToken authToken = session.getAuthToken();
    if (authToken == null) {
        // User must be authenticated before binding a resource
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(PacketError.Condition.not_authorized);
        // Send the error directly since a route does not exist at this point.
        session.process(reply);
        return reply;
    }
    if (authToken.isAnonymous()) {
        // User used ANONYMOUS SASL so initialize the session as an anonymous login
        session.setAnonymousAuth();
    } else {
        String username = authToken.getUsername().toLowerCase();
        // If a session already exists with the requested JID, then check to see
        // if we should kick it off or refuse the new connection
        ClientSession oldSession = routingTable.getClientRoute(new JID(username, serverName, resource, true));
        if (oldSession != null) {
            try {
                int conflictLimit = sessionManager.getConflictKickLimit();
                if (conflictLimit == SessionManager.NEVER_KICK) {
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.conflict);
                    // Send the error directly since a route does not exist at this point.
                    session.process(reply);
                    return null;
                }
                int conflictCount = oldSession.incrementConflictCount();
                if (conflictCount > conflictLimit) {
                    // Kick out the old connection that is conflicting with the new one
                    StreamError error = new StreamError(StreamError.Condition.conflict);
                    oldSession.deliverRawText(error.toXML());
                    oldSession.close();
                } else {
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.conflict);
                    // Send the error directly since a route does not exist at this point.
                    session.process(reply);
                    return null;
                }
            } catch (Exception e) {
                Log.error("Error during login", e);
            }
        }
        // If the connection was not refused due to conflict, log the user in
        session.setAuthToken(authToken, resource);
    }
    child.addElement("jid").setText(session.getAddress().toString());
    // Send the response directly since a route does not exist at this point.
    session.process(reply);
    // After the client has been informed, inform all listeners as well.
    SessionEventDispatcher.dispatchEvent(session, SessionEventDispatcher.EventType.resource_bound);
    return null;
}
Also used : LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) StringprepException(gnu.inet.encoding.StringprepException) StreamError(org.xmpp.packet.StreamError) JID(org.xmpp.packet.JID) Element(org.dom4j.Element) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) ClientSession(org.jivesoftware.openfire.session.ClientSession) IQ(org.xmpp.packet.IQ) AuthToken(org.jivesoftware.openfire.auth.AuthToken) StringprepException(gnu.inet.encoding.StringprepException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException)

Example 19 with UnauthorizedException

use of org.jivesoftware.openfire.auth.UnauthorizedException in project Openfire by igniterealtime.

the class CrowdAuthProvider method authenticate.

/**
     * Returns if the username and password are valid; otherwise this
     * method throws an UnauthorizedException.<p>
     *
     * @param username the username or full JID.
     * @param password the password
     * @throws UnauthorizedException if the username and password do
     *      not match any existing user.
     * @throws ConnectionException it there is a problem connecting to user and group sytem
     * @throws InternalUnauthenticatedException if there is a problem authentication Openfire itself into the user and group system
     */
@Override
public void authenticate(String username, String password) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException {
    if (manager == null) {
        throw new ConnectionException("Unable to connect to Crowd");
    }
    if (username == null || password == null || "".equals(password.trim())) {
        throw new UnauthorizedException();
    }
    if (username.contains("@")) {
        // Check that the specified domain matches the server's domain
        int index = username.indexOf("@");
        String domain = username.substring(index + 1);
        if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
            username = username.substring(0, index);
        } else {
            // Unknown domain. Return authentication failed.
            throw new UnauthorizedException();
        }
    }
    try {
        manager.authenticate(username, password);
    } catch (RemoteException re) {
        throw new UnauthorizedException();
    }
}
Also used : UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) RemoteException(java.rmi.RemoteException) ConnectionException(org.jivesoftware.openfire.auth.ConnectionException)

Example 20 with UnauthorizedException

use of org.jivesoftware.openfire.auth.UnauthorizedException in project Openfire by igniterealtime.

the class AuthFilter method filter.

/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.sun.jersey.spi.container.ContainerRequestFilter#filter(com.sun.jersey
	 * .spi.container.ContainerRequest)
	 */
@Override
public ContainerRequest filter(ContainerRequest containerRequest) throws WebApplicationException {
    if (!plugin.isEnabled()) {
        throw new WebApplicationException(Status.FORBIDDEN);
    }
    if (!plugin.getAllowedIPs().isEmpty()) {
        // Get client's IP address
        String ipAddress = httpRequest.getHeader("x-forwarded-for");
        if (ipAddress == null) {
            ipAddress = httpRequest.getHeader("X_FORWARDED_FOR");
            if (ipAddress == null) {
                ipAddress = httpRequest.getHeader("X-Forward-For");
                if (ipAddress == null) {
                    ipAddress = httpRequest.getRemoteAddr();
                }
            }
        }
        if (!plugin.getAllowedIPs().contains(ipAddress)) {
            LOG.warn("User service rejected service to IP address: " + ipAddress);
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }
    }
    // To be backwards compatible to userservice 1.*
    if ("userService/userservice".equals(containerRequest.getPath())) {
        return containerRequest;
    }
    // Get the authentification passed in HTTP headers parameters
    String auth = containerRequest.getHeaderValue("authorization");
    if (auth == null) {
        throw new WebApplicationException(Status.UNAUTHORIZED);
    }
    // HTTP Basic Auth or Shared Secret key
    if (plugin.isHttpBasicAuth()) {
        String[] usernameAndPassword = BasicAuth.decode(auth);
        // If username or password fail
        if (usernameAndPassword == null || usernameAndPassword.length != 2) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }
        boolean userAdmin = AdminManager.getInstance().isUserAdmin(usernameAndPassword[0], true);
        if (!userAdmin) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }
        try {
            AuthFactory.authenticate(usernameAndPassword[0], usernameAndPassword[1]);
        } catch (UnauthorizedException e) {
            LOG.warn("Wrong HTTP Basic Auth authorization", e);
            throw new WebApplicationException(Status.UNAUTHORIZED);
        } catch (ConnectionException e) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        } catch (InternalUnauthenticatedException e) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }
    } else {
        if (!auth.equals(plugin.getSecret())) {
            LOG.warn("Wrong secret key authorization. Provided key: " + auth);
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }
    }
    return containerRequest;
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) InternalUnauthenticatedException(org.jivesoftware.openfire.auth.InternalUnauthenticatedException) ConnectionException(org.jivesoftware.openfire.auth.ConnectionException)

Aggregations

UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)30 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)13 Element (org.dom4j.Element)11 IQ (org.xmpp.packet.IQ)10 JID (org.xmpp.packet.JID)10 ConnectionException (org.jivesoftware.openfire.auth.ConnectionException)7 PacketException (org.jivesoftware.openfire.PacketException)6 InternalUnauthenticatedException (org.jivesoftware.openfire.auth.InternalUnauthenticatedException)6 UserAlreadyExistsException (org.jivesoftware.openfire.user.UserAlreadyExistsException)5 IOException (java.io.IOException)4 AuthToken (org.jivesoftware.openfire.auth.AuthToken)4 StreamError (org.xmpp.packet.StreamError)4 StringprepException (gnu.inet.encoding.StringprepException)3 WebApplicationException (javax.ws.rs.WebApplicationException)3 ClientSession (org.jivesoftware.openfire.session.ClientSession)3 LocalClientSession (org.jivesoftware.openfire.session.LocalClientSession)3 User (org.jivesoftware.openfire.user.User)3 NotFoundException (org.jivesoftware.util.NotFoundException)3 DataForm (org.xmpp.forms.DataForm)3 FormField (org.xmpp.forms.FormField)3