public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
        throws PacketRejectedException {
      // We only want packets recieved by the server
      if (!processed && incoming && packet instanceof IQ) {
        IQ iq = (IQ) packet;
        Element childElement = iq.getChildElement();
        if (childElement == null) {
          return;
        }

        String namespace = childElement.getNamespaceURI();
        String profile = childElement.attributeValue("profile");
        // Check that the SI is about file transfer and try creating a file transfer
        if (NAMESPACE_SI.equals(namespace) && NAMESPACE_SI_FILETRANSFER.equals(profile)) {
          // If this is a set, check the feature offer
          if (iq.getType().equals(IQ.Type.set)) {
            JID from = iq.getFrom();
            JID to = iq.getTo();

            FileTransfer transfer = createFileTransfer(from, to, childElement);

            try {
              if (transfer == null || !acceptIncomingFileTransferRequest(transfer)) {
                throw new PacketRejectedException();
              }
            } catch (FileTransferRejectedException e) {
              throw new PacketRejectedException(e);
            }
          }
        }
      }
    }
예제 #2
0
  /**
   * 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);
  }
예제 #3
0
 /**
  * 退出群
  *
  * @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;
 }
예제 #4
0
  public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
      throws PacketRejectedException {
    if (!processed && packet instanceof IQ && !incoming) {

      // Check for the Bookmark Storage element and hand off to the Bookmark engine.
      IQ iq = (IQ) packet;
      Element childElement = iq.getChildElement();
      if (childElement == null || iq.getType() != IQ.Type.result) {
        return;
      }

      String namespace = childElement.getNamespaceURI();
      if ("jabber:iq:private".equals(namespace)) {
        // In private data, when a user is attempting to retrieve bookmark
        // information, there will be a storage:bookmarks namespace.
        Element storageElement = childElement.element("storage");
        if (storageElement == null) {
          return;
        }

        namespace = storageElement.getNamespaceURI();
        if ("storage:bookmarks".equals(namespace)) {
          // Append Server defined bookmarks for user.
          JID toJID = iq.getTo();
          addBookmarks(toJID, storageElement);
        }
      }
    }
  }
예제 #5
0
 /**
  * 审批入群申请
  *
  * @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;
 }
예제 #6
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);
    }
  }
예제 #7
0
 public IQ handleIQ(IQ iq) {
   Type type = iq.getType();
   String group_id = iq.getTo().getNode();
   if (group_id == null) return null;
   // 申请入群
   if (Type.get == type) return applyUserGroup(iq);
   else if (Type.set == type) {
     Element element = iq.getChildElement();
     Element quit = element.element("quit");
     if (quit != null) return quitGroup(iq);
     else return processGroupApply(iq);
   }
   return null;
 }
예제 #8
0
  /**
   * 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;
  }
예제 #9
0
  /**
   * 用户申请入群
   *
   * @param iq
   * @return
   */
  private IQ applyUserGroup(IQ iq) {
    JID from = iq.getFrom();
    JID to = iq.getTo();
    long group_id = -1;
    // 取群id
    try {
      group_id = Long.parseLong(to.getNode());
    } catch (Exception e) {
      return packetUtil.createErrorIq(iq, GroupError.Condition.bad_request);
    }
    try {
      // 申请理由
      String reason = iq.getChildElement().elementText("reason");
      // 申请人
      String member_jid = from.toBareJID();
      Group group = groupDbManager.getGroupById(group_id);
      // 群不存在
      if (group == null) return packetUtil.createErrorIq(iq, GroupError.Condition.group_not_exsist);
      // 已经是群成员
      if (groupDbManager.isGroupMember(group_id, member_jid))
        return packetUtil.createErrorIq(iq, GroupError.Condition.alread_in_group);
      // 已经提交了申请
      if (groupDbManager.getGroupApplyByUserGroupId(group_id, member_jid) != null)
        return packetUtil.createErrorIq(iq, GroupError.Condition.alread_applied);

      // 新建入群申请
      GroupApply apply = new GroupApply(group_id, member_jid);
      groupDbManager.insertGroupApply(apply);

      // 生成需要发送给群主的消息
      IQ to_admin = packetUtil.createGroupApplyMessage(group, member_jid, reason);
      // 插入系统消息
      GroupSysMessage sysMessage =
          new GroupSysMessage(group_id, member_jid, group.getCreator(), to_admin.toXML());
      groupDbManager.insertGroupSysMessage(sysMessage);

      // 如果群主在线,发送审核消息
      sendPacketIfOnline(to_admin, group.getCreator());

      return IQ.createResultIQ(iq);

    } catch (SQLException e) {
      e.printStackTrace();
      return packetUtil.createErrorIq(iq, GroupError.Condition.server_error);
    }
  }
예제 #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;
      }
    }
  }
예제 #11
0
  @Override
  public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed)
      throws PacketRejectedException {
    if (!processed && incoming) {
      if (packet instanceof IQ) {
        Log.debug(
            "Incomping unprocessed package i might be interested in. Package: \n"
                + packet.toString()
                + "\n");
        IQ myPacket = (IQ) packet;
        if (myPacket.getFrom() == null || myPacket.getTo() == null) {
          /*
           * If getTo() == null this is maybe a roster update from the
           * Client to the Server, check if we should mirror this
           * package to external component
           */
          if (myPacket.getFrom() != null
              && myPacket.getType().equals(IQ.Type.set)
              && myPacket.getTo() == null) {
            if (XpathHelper.findNodesInDocument(
                        myPacket.getChildElement().getDocument(), "//roster:item")
                    .size()
                > 0) {
              _packetProcessor.get("clientToComponentUpdate").process(myPacket);
            }
          }
          return;
        }
        @SuppressWarnings("unused")
        String to = myPacket.getTo().toString();
        String from = myPacket.getFrom().toString();

        if (myPacket.getType().equals(IQ.Type.get) && from.equals(_mySubdomain)) {
          if (XpathHelper.findNodesInDocument(myPacket.getElement().getDocument(), "//roster:*")
                  .size()
              == 1) {
            // This Package is a roster request by remote component
            _packetProcessor.get("sendRoster").process(packet);
          }
        } else if (myPacket.getType().equals(IQ.Type.set) && from.equals(_mySubdomain)) {
          if (XpathHelper.findNodesInDocument(myPacket.getElement().getDocument(), "//roster:item")
                  .size()
              >= 1) {
            // Component sends roster update
            _packetProcessor.get("receiveChanges").process(packet);
          }
        } else if (myPacket.getType().equals(IQ.Type.get)
            && myPacket.toString().contains("http://jabber.org/protocol/disco#info")
            && myPacket.getTo().toString().equals(_mySubdomain)) {
          /*
           * modify the disco#info for spark clients if enabled in
           * admin panel
           */
          _packetProcessor.get("sparkIQRegistered").process(packet);
        } else if (myPacket.getType().equals(IQ.Type.set)
            && myPacket.getTo().toString().equals(_mySubdomain)) {
          System.out.println("war das ein remove an mich????");
          _packetProcessor.get("handleCleanUp").process(packet);
        }
      }
      // else if (packet instanceof Presence) {
      // if (packet.getFrom().toString().equals(_mySubdomain)
      // &&
      // !JiveGlobals.getBooleanProperty("plugin.remoteroster.persistent",
      // false)) {
      // System.out.println("MACH EIN CLEANUP!!!!!!");
      // _packetProcessor.get("handleCleanUp").process(packet);
      // }
      // }
    }
  }
예제 #12
0
  /**
   * 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);
    }
  }
  @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;
    }
  }