public void completeRegistration(TransportSession session) {
    final IQ result = IQ.createResultIQ(session.getRegistrationPacket());
    if (!session.getFailureStatus().equals(ConnectionFailureReason.NO_ISSUE)) {
      // Ooh there was a connection issue, we're going to report that back!
      if (session
          .getFailureStatus()
          .equals(ConnectionFailureReason.USERNAME_OR_PASSWORD_INCORRECT)) {
        result.setError(Condition.not_authorized);
      } else if (session.getFailureStatus().equals(ConnectionFailureReason.CAN_NOT_CONNECT)) {
        result.setError(Condition.service_unavailable);
      } else if (session.getFailureStatus().equals(ConnectionFailureReason.LOCKED_OUT)) {
        result.setError(Condition.forbidden);
      } else {
        result.setError(Condition.undefined_condition);
      }
      result.setType(IQ.Type.error);
    }
    parent.sendPacket(result);

    session.setRegistrationPacket(null);

    // Lets ask them what their presence is, maybe log them in immediately.
    final Presence p = new Presence(Presence.Type.probe);
    p.setTo(session.getJID());
    p.setFrom(parent.getJID());
    parent.sendPacket(p);
  }
  /**
   * Processes an IQ-register request that is expressing the wish to deregister from a gateway.
   *
   * @param packet the IQ-register stanza.
   */
  private void handleDeregister(final IQ packet) {
    final IQ result = IQ.createResultIQ(packet);

    if (packet.getChildElement().elements().size() != 1) {
      Log.debug(
          "Cannot process this stanza - exactly one"
              + " childelement of <remove> expected:"
              + packet.toXML());
      final IQ error = IQ.createResultIQ(packet);
      error.setError(Condition.bad_request);
      parent.sendPacket(error);
      return;
    }

    final JID from = packet.getFrom();
    final JID to = packet.getTo();

    // Tell the end user the transport went byebye.
    final Presence unavailable = new Presence(Presence.Type.unavailable);
    unavailable.setTo(from);
    unavailable.setFrom(to);
    this.parent.sendPacket(unavailable);

    try {
      deleteRegistration(from);
    } catch (UserNotFoundException e) {
      Log.debug("Error cleaning up contact list of: " + from);
      result.setError(Condition.registration_required);
    }
    parent.sendPacket(result);
  }
 /**
  * 退出群
  *
  * @param iq
  * @return
  */
 private IQ quitGroup(IQ iq) {
   String member_jid = iq.getFrom().toBareJID();
   JID group = iq.getTo();
   IQ reply = IQ.createResultIQ(iq);
   long group_id = -1;
   LocalGroup localGroup = null;
   try {
     group_id = Long.parseLong(group.getNode());
     localGroup = service.getGroup(group_id);
   } catch (Exception e) {
     reply.setError(PacketError.Condition.bad_request);
     return reply;
   }
   // 删除群成员
   try {
     Map<String, LocalGroupRole> members = localGroup.getGroupMembers();
     if (members != null && !members.isEmpty()) {
       int delete = groupDbManager.deleteGroupMember(group_id, member_jid);
       // 有记录被删除,通知群成员
       if (delete > 0) {
         // 如果群主退出,删除群
         if (localGroup.isOwner(member_jid)) groupDbManager.deleteGroupById(group_id);
         // 发送消息
         sendPacket(members.keySet(), packetUtil.createQuitPresence(member_jid, group_id));
       }
     }
     localGroup.removeMember(member_jid);
   } catch (SQLException e) {
     reply.setError(PacketError.Condition.internal_server_error);
     return reply;
   }
   return null;
 }
 /**
  * 审批入群申请
  *
  * @param iq
  * @return
  */
 private IQ processGroupApply(IQ iq) {
   IQ reply = IQ.createResultIQ(iq);
   // 发送者
   String creator = iq.getFrom().toBareJID();
   Element query = iq.getChildElement();
   // 申请人
   String applier = query.elementText("applier");
   // 审批结果
   String result = query.elementText("result");
   if (result == null
       || applier == null
       || (!GroupApply.STATUS_ACCEPT.equals(result) && !GroupApply.STATUS_DENIED.equals(result))) {
     reply.setError(PacketError.Condition.bad_request);
     return reply;
   }
   long group_id = -1;
   LocalGroup localGroup = null;
   try {
     group_id = Long.parseLong(iq.getTo().getNode());
     localGroup = service.getGroup(group_id);
   } catch (Exception e) {
     reply.setError(PacketError.Condition.bad_request);
     return reply;
   }
   try {
     // 检查是否已经处理过这条请求
     GroupApply apply = groupDbManager.getGroupApplyByUserGroupId(group_id, applier);
     if (apply == null && !localGroup.isOwner(creator)) {
       reply.setError(PacketError.Condition.bad_request);
       return reply;
     }
     // 处理请求
     apply.setStatus(result);
     groupDbManager.processGroupApply(apply);
     // 如果申请人在线,发送消息通知
     Message applier_msg =
         packetUtil.createGroupApplyResponseMessage(apply, localGroup.getGroup());
     boolean sent = sendPacketIfOnline(applier_msg, apply.getApply_user());
     // 未发送,保存到数据库
     if (!sent) {
       GroupSysMessage sysMessage =
           new GroupSysMessage(apply.getApply_user(), applier_msg.toXML());
       groupDbManager.insertGroupSysMessage(sysMessage);
     }
     // 如果是同意,发送presence给群成员
     if (GroupApply.STATUS_ACCEPT.equals(apply.getStatus())) {
       // 发送消息
       sendPacket(
           localGroup.getGroupMembers().keySet(), packetUtil.createNewMemberPresence(apply));
     }
     // 处理完成
   } catch (SQLException e) {
     reply.setError(PacketError.Condition.internal_server_error);
   }
   return reply;
 }
Example #5
0
  private void processIQ(Element doc) {
    log.debug("processIQ()...");
    IQ packet;
    try {
      packet = getIQ(doc);
    } catch (IllegalArgumentException e) {
      log.debug("Rejecting packet. JID malformed", e);
      IQ reply = new IQ();
      if (!doc.elements().isEmpty()) {
        reply.setChildElement(((Element) doc.elements().get(0)).createCopy());
      }
      reply.setID(doc.attributeValue("id"));
      reply.setTo(session.getAddress());
      String to = doc.attributeValue("to");
      if (to != null) {
        reply.getElement().addAttribute("from", to);
      }
      reply.setError(PacketError.Condition.jid_malformed);
      session.process(reply);
      return;
    }

    //        if (packet.getID() == null) {
    //            // IQ packets MUST have an 'id' attribute
    //            StreamError error = new StreamError(
    //                    StreamError.Condition.invalid_xml);
    //            session.deliverRawText(error.toXML());
    //            session.close();
    //            return;
    //        }

    packet.setFrom(session.getAddress());
    router.route(packet);
    session.incrementClientPacketCount();
  }
 private void fail(IQ request, Condition condition, org.xmpp.packet.PacketError.Type type)
     throws InterruptedException {
   IQ reply = IQ.createResultIQ(request);
   reply.setType(Type.error);
   PacketError pe = new PacketError(condition, type);
   reply.setError(pe);
   outQueue.put(reply);
 }
  protected IQ error(Packet packet, PacketError.Condition condition) {
    IQ reply;

    reply = new IQ(IQ.Type.error, packet.getID());
    reply.setFrom(packet.getTo());
    reply.setTo(packet.getFrom());
    reply.setError(condition);
    return reply;
  }
Example #8
0
  public void executeSet(IQ packet, Workgroup workgroup) {
    IQ reply = null;
    Element iq = packet.getChildElement();

    try {
      JID from = packet.getFrom();
      String bareJID = from.toBareJID();
      if (!isOwner(bareJID, workgroup)) {
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(packet.getChildElement().createCopy());
        reply.setError(new PacketError(PacketError.Condition.forbidden));
        workgroup.send(reply);
        return;
      }

      // Verify that an agent is requesting this information.
      WorkgroupManager workgroupManager = WorkgroupManager.getInstance();
      if (iq.element("makeOwner") != null) {
        String sessionID = iq.element("makeOwner").attributeValue("sessionID");
        final String serviceName = workgroupManager.getMUCServiceName();
        final String roomName = sessionID + "@" + serviceName;
        // final String roomJID = roomName + "/" + workgroup.getJID().getNode();

        IQ iqPacket = new IQ(IQ.Type.set);
        iqPacket.setTo(roomName);
        iqPacket.setFrom(workgroup.getFullJID());

        Element query = iqPacket.setChildElement("query", "http://jabber.org/protocol/muc#admin");
        Element item = query.addElement("item");
        item.addAttribute("affiliation", "owner");
        item.addAttribute("jid", packet.getFrom().toBareJID());
        workgroup.send(iqPacket);
      }

      reply = IQ.createResultIQ(packet);
    } catch (Exception e) {
      reply = IQ.createResultIQ(packet);
      reply.setChildElement(packet.getChildElement().createCopy());
      reply.setError(new PacketError(PacketError.Condition.item_not_found));
    }
    workgroup.send(reply);
  }
Example #9
0
  /**
   * Handles the IQ packet sent by an owner of the room. Possible actions are:
   *
   * <ul>
   *   <li>Return the list of owners
   *   <li>Return the list of admins
   *   <li>Change user's affiliation to owner
   *   <li>Change user's affiliation to admin
   *   <li>Change user's affiliation to member
   *   <li>Change user's affiliation to none
   *   <li>Destroy the room
   *   <li>Return the room configuration within a dataform
   *   <li>Update the room configuration based on the sent dataform
   * </ul>
   *
   * @param packet the IQ packet sent by an owner of the room.
   * @param role the role of the user that sent the packet.
   * @throws ForbiddenException if the user does not have enough permissions (ie. is not an owner).
   * @throws ConflictException If the room was going to lose all of its owners.
   */
  @SuppressWarnings("unchecked")
  public void handleIQ(IQ packet, MUCRole role)
      throws ForbiddenException, ConflictException, CannotBeInvitedException {
    // Only owners can send packets with the namespace "http://jabber.org/protocol/muc#owner"
    if (MUCRole.Affiliation.owner != role.getAffiliation()) {
      throw new ForbiddenException();
    }

    IQ reply = IQ.createResultIQ(packet);
    Element element = packet.getChildElement();

    // Analyze the action to perform based on the included element
    Element formElement = element.element(QName.get("x", "jabber:x:data"));
    if (formElement != null) {
      handleDataFormElement(role, formElement);
    } else {
      Element destroyElement = element.element("destroy");
      if (destroyElement != null) {
        if (((MultiUserChatServiceImpl) room.getMUCService()).getMUCDelegate() != null) {
          if (!((MultiUserChatServiceImpl) room.getMUCService())
              .getMUCDelegate()
              .destroyingRoom(room.getName(), role.getUserAddress())) {
            // Delegate said no, reject destroy request.
            throw new ForbiddenException();
          }
        }

        JID alternateJID = null;
        final String jid = destroyElement.attributeValue("jid");
        if (jid != null) {
          alternateJID = new JID(jid);
        }
        room.destroyRoom(alternateJID, destroyElement.elementTextTrim("reason"));
      } else {
        // If no element was included in the query element then answer the
        // configuration form
        if (!element.elementIterator().hasNext()) {
          refreshConfigurationFormValues();
          reply.setChildElement(probeResult.createCopy());
        }
        // An unknown and possibly incorrect element was included in the query
        // element so answer a BAD_REQUEST error
        else {
          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)
      router.route(reply);
    }
  }
Example #10
0
  /**
   * Handles all roster queries. There are two major types of queries:
   *
   * <ul>
   *   <li>Roster remove - A forced removal of items from a roster. Roster removals are the only
   *       roster queries allowed to directly affect the roster from another user.
   *   <li>Roster management - A local user looking up or updating their roster.
   * </ul>
   *
   * @param packet The update packet
   * @return The reply or null if no reply
   */
  public IQ handleIQ(IQ packet) throws UnauthorizedException, PacketException {
    try {
      IQ returnPacket = null;
      org.xmpp.packet.Roster roster = (org.xmpp.packet.Roster) packet;

      JID recipientJID = packet.getTo();

      // The packet is bound for the server and must be roster management
      if (recipientJID == null
          || recipientJID.getNode() == null
          || !UserManager.getInstance().isRegisteredUser(recipientJID.getNode())) {
        returnPacket = manageRoster(roster);
      }
      // The packet must be a roster removal from a foreign domain user.
      else {
        removeRosterItem(roster);
      }
      return returnPacket;
    } catch (SharedGroupException e) {
      IQ result = IQ.createResultIQ(packet);
      result.setChildElement(packet.getChildElement().createCopy());
      result.setError(PacketError.Condition.not_acceptable);
      return result;
    } catch (Exception e) {
      if (e.getCause() instanceof IDNAException) {
        Log.warn(LocaleUtils.getLocalizedString("admin.error"), e);
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.jid_malformed);
        return result;
      } else {
        Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.internal_server_error);
        return result;
      }
    }
  }
  public void process(IQ packet) throws UnauthorizedException, PacketException {

    // sanitize the input
    if (packet == null) {
      throw new IllegalArgumentException("Argument 'packet' cannot be null.");
    }

    final String xmlns;
    final Element child = (packet).getChildElement();
    if (child != null) {
      xmlns = child.getNamespaceURI();
    } else {
      xmlns = null;
    }

    if (xmlns == null) {
      // No namespace defined.
      Log.debug("Cannot process this stanza, as it has no namespace:" + packet.toXML());
      final IQ error = IQ.createResultIQ(packet);
      error.setError(Condition.bad_request);
      parent.sendPacket(error);
      return;
    }

    // done sanitizing, start processing.
    final Element remove = packet.getChildElement().element("remove");
    if (remove != null) {
      // User wants to unregister. =(
      // this.convinceNotToLeave() ... kidding.
      handleDeregister(packet);
    } else {
      // handle the request
      switch (packet.getType()) {
        case get:
          // client requests registration form
          getRegistrationForm(packet);
          break;

        case set:
          // client is providing (filled out) registration form
          setRegistrationForm(packet);
          break;

        default:
          // ignore result and error stanzas.
          break;
      }
    }
  }
  /**
   * Creates an error response for a given IQ request.
   *
   * @param request
   * @param message
   * @param condition
   * @param type
   * @return
   */
  public static IQ createErrorResponse(
      final IQ request, final String message, Condition condition, Type type) {
    final IQ result = request.createCopy();
    result.setID(request.getID());
    result.setFrom(request.getTo());
    result.setTo(request.getFrom());

    PacketError e = new PacketError(condition, type);
    if (message != null) {
      e.setText(message);
    }
    result.setError(e);

    return result;
  }
  public void process(Packet packet) throws ComponentException {

    logger.debug("Packet payload " + packet.toXML() + " going to federation.");

    String to = packet.getTo().toString();

    String uniqueId = generateUniqueId(packet);
    idMap.put(uniqueId, packet.getID());
    packet.setID(uniqueId);

    sentRemotePackets.put(uniqueId, packet.getFrom());
    try {
      extractNodeDetails(packet);
      // Do we have a map already?
      if (discoveredServers.containsKey(to)) {
        packet.setTo(new JID(discoveredServers.get(to)));
        sendPacket(packet.createCopy());
        return;
      }
      // Are we already discovering a remote server?
      if (!remoteChannelDiscoveryStatus.containsKey(to)) {
        discoverRemoteChannelServer(to, packet.getID());
      } else if (remoteChannelDiscoveryStatus.get(to).equals(NO_CHANNEL_SERVER)) {
        logger.error("No remote channel server for " + to);
        IQ reply = IQ.createResultIQ((IQ) packet);
        reply.setError(
            new PacketError(
                PacketError.Condition.remote_server_not_found, PacketError.Type.cancel));
        component.sendPacket(reply);
        return;
      }
      // Add packet to list
      if (!waitingStanzas.containsKey(to)) {
        waitingStanzas.put(to, new ArrayList<Packet>());
      }
      waitingStanzas.get(to).add(packet);
      logger.debug(
          "Adding packet to waiting stanza list for "
              + to
              + " (size "
              + waitingStanzas.get(to).size()
              + ")");
    } catch (Exception e) {
      logger.error(e);
    }
  }
  @Override
  public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ reply = IQ.createResultIQ(packet);
    Element offlineRequest = packet.getChildElement();

    JID from = packet.getFrom();
    if (offlineRequest.element("purge") != null) {
      // User requested to delete all offline messages
      messageStore.deleteMessages(from.getNode());
    } else if (offlineRequest.element("fetch") != null) {
      // Mark that offline messages shouldn't be sent when the user becomes available
      stopOfflineFlooding(from);
      // User requested to receive all offline messages
      for (OfflineMessage offlineMessage : messageStore.getMessages(from.getNode(), false)) {
        sendOfflineMessage(from, offlineMessage);
      }
    } else {
      for (Iterator it = offlineRequest.elementIterator("item"); it.hasNext(); ) {
        Element item = (Element) it.next();
        Date creationDate = null;
        try {
          creationDate = xmppDateTime.parseString(item.attributeValue("node"));
        } catch (ParseException e) {
          Log.error("Error parsing date", e);
        }
        if ("view".equals(item.attributeValue("action"))) {
          // User requested to receive specific message
          OfflineMessage offlineMsg = messageStore.getMessage(from.getNode(), creationDate);
          if (offlineMsg != null) {
            sendOfflineMessage(from, offlineMsg);
          }
        } else if ("remove".equals(item.attributeValue("action"))) {
          // User requested to delete specific message
          if (messageStore.getMessage(from.getNode(), creationDate) != null) {
            messageStore.deleteMessage(from.getNode(), creationDate);
          } else {
            // If the requester is authorized but the node does not exist, the server MUST return a
            // <item-not-found/> error.
            reply.setError(PacketError.Condition.item_not_found);
          }
        }
      }
    }
    return reply;
  }
 public void process(Packet packet) {
   // Check that the requested packet can be processed
   if (canProcess(packet)) {
     // Perform the actual processing of the packet. This usually implies sending
     // the packet to the entity
     try {
       // Invoke the interceptors before we send the packet
       InterceptorManager.getInstance().invokeInterceptors(packet, this, false, false);
       deliver(packet);
       // Invoke the interceptors after we have sent the packet
       InterceptorManager.getInstance().invokeInterceptors(packet, this, false, true);
     } catch (PacketRejectedException e) {
       // An interceptor rejected the packet so do nothing
     } catch (Exception e) {
       Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
     }
   } else {
     // http://xmpp.org/extensions/xep-0016.html#protocol-error
     if (packet instanceof Message) {
       // For message stanzas, the server SHOULD return an error, which SHOULD be
       // <service-unavailable/>.
       Message message = (Message) packet;
       Message result = message.createCopy();
       result.setTo(message.getFrom());
       result.setError(PacketError.Condition.service_unavailable);
       XMPPServer.getInstance().getRoutingTable().routePacket(message.getFrom(), result, true);
     } else if (packet instanceof IQ) {
       // For IQ stanzas of type "get" or "set", the server MUST return an error, which SHOULD be
       // <service-unavailable/>.
       // IQ stanzas of other types MUST be silently dropped by the server.
       IQ iq = (IQ) packet;
       if (iq.getType() == IQ.Type.get || iq.getType() == IQ.Type.set) {
         IQ result = IQ.createResultIQ(iq);
         result.setError(PacketError.Condition.service_unavailable);
         XMPPServer.getInstance().getRoutingTable().routePacket(iq.getFrom(), result, true);
       }
     }
   }
 }
  @Override
  public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ result = IQ.createResultIQ(packet);
    String username = packet.getFrom().getNode();
    if (!serverName.equals(packet.getFrom().getDomain()) || username == null) {
      // Users of remote servers are not allowed to get their "shared groups". Users of
      // remote servers cannot have shared groups in this server.
      // Besides, anonymous users do not belong to shared groups so answer an error
      result.setChildElement(packet.getChildElement().createCopy());
      result.setError(PacketError.Condition.not_allowed);
      return result;
    }

    Collection<Group> groups = rosterManager.getSharedGroups(username);
    Element sharedGroups =
        result.setChildElement("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup");
    for (Group sharedGroup : groups) {
      String displayName = sharedGroup.getProperties().get("sharedRoster.displayName");
      if (displayName != null) {
        sharedGroups.addElement("group").setText(displayName);
      }
    }
    return result;
  }
 protected void setErrorCondition(Type type, Condition condition) {
   if (null == response) response = IQ.createResultIQ(request);
   response.setType(IQ.Type.error);
   PacketError error = new PacketError(condition, type);
   response.setError(error);
 }
  /**
   * Handles the received IQ packet.
   *
   * @param packet the packet
   * @return the response to send back
   * @throws UnauthorizedException if the user is not authorized
   */
  public IQ handleIQ(IQ packet) throws UnauthorizedException {
    IQ reply = null;

    ClientSession session = sessionManager.getSession(packet.getFrom());
    if (session == null) {
      log.error("Session not found for key " + packet.getFrom());
      reply = IQ.createResultIQ(packet);
      reply.setChildElement(packet.getChildElement().createCopy());
      reply.setError(PacketError.Condition.internal_server_error);
      return reply;
    }

    try {
      Element iq = packet.getElement();
      Element query = iq.element("query");
      Element queryResponse = probeResponse.createCopy();

      if (IQ.Type.get == packet.getType()) { // get query
        String username = query.elementText("username");
        if (username != null) {
          queryResponse.element("username").setText(username);
        }
        reply = IQ.createResultIQ(packet);
        reply.setChildElement(queryResponse);
        if (session.getStatus() != Session.STATUS_AUTHENTICATED) {
          reply.setTo((JID) null);
        }
      } else { // set query
        String resource = query.elementText("resource");
        String username = query.elementText("username");
        String password = query.elementText("password");
        String digest = null;
        if (query.element("digest") != null) {
          digest = query.elementText("digest").toLowerCase();
        }

        // Verify the resource
        if (resource != null) {
          try {
            resource = JID.resourceprep(resource);
          } catch (StringprepException e) {
            throw new UnauthorizedException("Invalid resource: " + resource, e);
          }
        } else {
          throw new IllegalArgumentException("Invalid resource (empty or null).");
        }

        // Verify the username
        if (username == null || username.trim().length() == 0) {
          throw new UnauthorizedException("Invalid username (empty or null).");
        }
        try {
          Stringprep.nodeprep(username);
        } catch (StringprepException e) {
          throw new UnauthorizedException("Invalid username: " + username, e);
        }
        username = username.toLowerCase();

        // Verify that username and password are correct
        AuthToken token = null;
        if (password != null && AuthManager.isPlainSupported()) {
          token = AuthManager.authenticate(username, password);
        } else if (digest != null && AuthManager.isDigestSupported()) {
          token = AuthManager.authenticate(username, session.getStreamID().toString(), digest);
        }

        if (token == null) {
          throw new UnauthenticatedException();
        }

        // Set the session authenticated successfully
        session.setAuthToken(token, resource);
        packet.setFrom(session.getAddress());
        reply = IQ.createResultIQ(packet);
      }
    } catch (Exception ex) {
      log.error(ex);
      reply = IQ.createResultIQ(packet);
      reply.setChildElement(packet.getChildElement().createCopy());
      if (ex instanceof IllegalArgumentException) {
        reply.setError(PacketError.Condition.not_acceptable);
      } else if (ex instanceof UnauthorizedException) {
        reply.setError(PacketError.Condition.not_authorized);
      } else if (ex instanceof UnauthenticatedException) {
        reply.setError(PacketError.Condition.not_authorized);
      } else {
        reply.setError(PacketError.Condition.internal_server_error);
      }
    }

    // Send the response directly to the session
    if (reply != null) {
      session.process(reply);
    }
    return null;
  }
  @SuppressWarnings("deprecation")
  @Override
  public IQ handleIQ(IQ packet) throws UnauthorizedException {
    final JID sender = packet.getFrom();
    final JID recipient = packet.getTo();

    // Process the request inside a try/catch so that unhandled exceptions
    // (oufofbounds etc...) can trigger a server error and we can send a
    // error result packet
    try {

      // A valid request is an IQ of type set,
      if (!packet.getType().equals(IQ.Type.set)) {
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.bad_request);
        return result;
      }

      // If a recipient is specified, it must be equal to the sender
      // bareJID
      if (recipient != null && !recipient.toString().equals(sender.toBareJID())) {
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.not_authorized);
        return result;
      }

      // Only a local user can publish its profile
      if (!userManager.isRegisteredUser(sender.getNode())) {
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.not_authorized);
        return result;
      }

      // A valid submit requets must contain a vcard4 entry
      Element request = packet.getChildElement();
      Element e_profile = request.element(QName.get(VCard4.VCARD_ELEMENT, VCard4.NAMESPACE));
      if (e_profile == null) {
        IQ result = IQ.createResultIQ(packet);
        result.setChildElement(packet.getChildElement().createCopy());
        result.setError(PacketError.Condition.bad_request);
        return result;
      }

      // Parse the profile
      VCard4DomReader reader = new PersistentVCard4DomReader();
      Profile profile = reader.readProfile(new ElementAdapter(e_profile));

      // Commit the profile (this will also trigger the messages)
      try {
        ProfileManager.getInstance().publishProfile(sender.toBareJID(), profile);
      } catch (UserNotFoundException e) {
        // We know this cannot happen
      }

      // Send a success result
      // TODO should this contain more, like the ID of the new activities ?
      IQ result = IQ.createResultIQ(packet);
      return result;

    } catch (Exception e) {
      Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
      IQ result = IQ.createResultIQ(packet);
      result.setChildElement(packet.getChildElement().createCopy());
      result.setError(PacketError.Condition.internal_server_error);
      return result;
    }
  }
  /**
   * Handles a IQ-register 'set' request, which is to be interpreted as a request to create a new
   * registration.
   *
   * @param packet the IQ-register 'set' stanza.
   * @throws UnauthorizedException if the user isn't allowed to register.
   */
  private void setRegistrationForm(IQ packet) throws UnauthorizedException {
    final JID from = packet.getFrom();

    final boolean registered;
    Collection<Registration> registrations =
        RegistrationManager.getInstance().getRegistrations(from, parent.transportType);
    if (registrations.iterator().hasNext()) {
      registered = true;
    } else {
      registered = false;
    }

    if (!registered && !parent.permissionManager.hasAccess(from)) {
      // User does not have permission to register with transport.
      // We want to allow them to change settings if they are already
      // registered.
      throw new UnauthorizedException(
          LocaleUtils.getLocalizedString("gateway.base.registrationdeniedbyacls", "kraken"));
    }

    // Parse the input variables
    String username = null;
    String password = null;
    String nickname = null;
    try {
      if (packet.getChildElement().element("x") != null) {
        final DataForm form = new DataForm(packet.getChildElement().element("x"));
        final List<FormField> fields = form.getFields();
        for (final FormField field : fields) {
          final String var = field.getVariable();
          if (var.equals("username")) {
            username = field.getValues().get(0);
          } else if (var.equals("password")) {
            password = field.getValues().get(0);
          } else if (var.equals("nick")) {
            nickname = field.getValues().get(0);
          }
        }
      }
    }
    // TODO: This shouldn't be done by catching an Exception - check for the
    // existence of elements instead. If we insist doing this with an
    // exception handler, prevent catching a generic Exception (catch more
    // specific subclasses instead).
    catch (Exception ex) {
      // No with data form apparently
      Log.info("Most likely, no dataform was present " + "in the IQ-register request.", ex);
    }

    // input variables could also exist in the non-extended elements
    final Element userEl = packet.getChildElement().element("username");
    final Element passEl = packet.getChildElement().element("password");
    final Element nickEl = packet.getChildElement().element("nick");
    if (userEl != null) {
      username = userEl.getTextTrim();
    }
    if (passEl != null) {
      password = passEl.getTextTrim();
    }
    if (nickEl != null) {
      nickname = nickEl.getTextTrim();
    }

    username = (username == null || username.equals("")) ? null : username;
    password = (password == null || password.equals("")) ? null : password;
    nickname = (nickname == null || nickname.equals("")) ? null : nickname;

    // verify that we've got wat we need.
    if (username == null
        || (parent.isPasswordRequired() && password == null)
        || (parent.isNicknameRequired() && nickname == null)) {
      // Invalid information from stanza, lets yell.
      Log.info(
          "Cannot process IQ register request, as it "
              + "fails to provide all data that's required: "
              + packet.toXML());
      final IQ result = IQ.createResultIQ(packet);
      result.setError(Condition.bad_request);
      parent.sendPacket(result);
      return;
    }

    // Check if the client supports our proprietary 'rosterless' mode.
    final boolean rosterlessMode;
    final Element x = packet.getChildElement().element("x");
    if (x != null
        && x.getNamespaceURI() != null
        && x.getNamespaceURI().equals(NameSpace.IQ_GATEWAY_REGISTER)) {
      rosterlessMode = true;
      Log.info("Registering " + packet.getFrom() + " as " + username + " in rosterless mode.");
    } else {
      rosterlessMode = false;
      Log.info(
          "Registering "
              + packet.getFrom()
              + " as "
              + username
              + " (without making use of rosterless mode).");
    }

    // Here's where the true magic lies: create the registration!
    try {
      addNewRegistration(from, username, password, nickname, rosterlessMode);

      registrations =
          RegistrationManager.getInstance().getRegistrations(from, parent.transportType);
      Registration registration = registrations.iterator().next();
      TransportSession session =
          parent.registrationLoggedIn(registration, from, PresenceType.available, "", -1);
      session.setRegistrationPacket(packet);
      session.detachSession();
      parent.getSessionManager().storeSession(from, session);

      // final IQ result = IQ.createResultIQ(packet);
      // I believe this shouldn't be included. Leaving it around just in
      // case.
      // Element response =
      // DocumentHelper.createElement(QName.get("query", IQ_REGISTER));
      // result.setChildElement(response);
      // parent.sendPacket(result);
    } catch (UserNotFoundException e) {
      Log.warn(
          "Someone attempted to register with the gateway "
              + "who is not registered with the server: "
              + from);
      final IQ eresult = IQ.createResultIQ(packet);
      eresult.setError(Condition.forbidden);
      parent.sendPacket(eresult);
      final Message em = new Message();
      em.setType(Message.Type.error);
      em.setTo(packet.getFrom());
      em.setFrom(packet.getTo());
      em.setBody(LocaleUtils.getLocalizedString("gateway.base.registrationdeniednoacct", "kraken"));
      parent.sendPacket(em);
    } catch (IllegalAccessException e) {
      Log.warn(
          "Someone who is not a user of this server "
              + "tried to register with the transport: "
              + from);
      final IQ eresult = IQ.createResultIQ(packet);
      eresult.setError(Condition.forbidden);
      parent.sendPacket(eresult);
      final Message em = new Message();
      em.setType(Message.Type.error);
      em.setTo(packet.getFrom());
      em.setFrom(packet.getTo());
      em.setBody(LocaleUtils.getLocalizedString("gateway.base.registrationdeniedbyhost", "kraken"));
      parent.sendPacket(em);
    } catch (IllegalArgumentException e) {
      Log.warn(
          "Someone attempted to register with the " + "gateway with an invalid username: "******"gateway.base.registrationdeniedbadusername", "kraken"));
      parent.sendPacket(em);
    }
  }