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);
        }
      }
    }
  }
示例#2
0
  private void processIQ(IQ iq) {
    long start = System.currentTimeMillis();
    Element childElement = iq.getChildElement();
    String namespace = childElement.getNamespaceURI();

    // 构造返回dom
    IQ reply = IQ.createResultIQ(iq);
    Element childElementCopy = childElement.createCopy();
    reply.setChildElement(childElementCopy);

    if (XConstants.PROTOCOL_DISCO_INFO.equals(namespace)) {
      generateDisco(childElementCopy); // 构造disco反馈信息
      if (LOG.isInfoEnabled()) {
        LOG.info(
            "[spend time:{}ms],reqId: {},IRComponent服务发现,response:{}",
            System.currentTimeMillis() - start,
            iq.getID(),
            reply.toXML());
      }
    }

    try {
      ComponentManagerFactory.getComponentManager().sendPacket(this, reply);
    } catch (Throwable t) {
      LOG.error(
          "[spend time:{}ms],reqId: {},IRComponent IQ处理异常! iq:{},replay:{}",
          System.currentTimeMillis() - start,
          iq.getID(),
          reply.toXML(),
          t);
    }
  }
    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);
            }
          }
        }
      }
    }
示例#4
0
  /**
   * Sets an application-specific error condition. Optionally, a application-specific namespace can
   * be specified to define its own application-specific error .
   *
   * @param name the name of the application-specific error condition.
   * @param namespaceURI the namespace of the application.
   */
  @SuppressWarnings("unchecked")
  public void setApplicationCondition(String name, String namespaceURI) {

    if (ERROR_NAMESPACE.equals(namespaceURI)) {
      throw new IllegalArgumentException();
    }

    // TODO: Remove this dependency on getElement()
    Element applicationError = null;
    for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) {

      Element el = i.next();
      if (!el.getNamespaceURI().equals(ERROR_NAMESPACE)) {
        applicationError = el;
      }
    }

    if (applicationError != null) {
      getElement().remove(applicationError);
    }

    // If name is null, clear the application condition.
    if (name == null) {
      return;
    }

    if (namespaceURI == null) {
      // Set fallback namespace (see XEP-0182)
      namespaceURI = "urn:xmpp:errors";
    }
    set(name, null, namespaceURI);
  }
 private IQ getIQ(Element doc) {
   Element query = doc.element("query");
   if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
     return new Roster(doc);
   } else {
     return new IQ(doc);
   }
 }
示例#6
0
  public static String setXPathNamespace(Element ele, String xpath) {
    // 进行命名空间处理
    if (!StringUtils.isEmptyString(ele.getNamespaceURI())) {
      // 将xpath中增加命名空间
      xpath = xpath.replaceAll(XPATH_NAMESPACE_REGEX, XPATH_REPLACE_NAMESPACE);
    }

    return xpath;
  }
示例#7
0
 /* 526:    */
 /* 527:    */ protected void startElement(Element element, AttributesImpl namespaceAttributes)
     /* 528:    */ throws SAXException
       /* 529:    */ {
   /* 530:810 */ this.contentHandler.startElement(
       element.getNamespaceURI(),
       element.getName(),
       element.getQualifiedName(),
       createAttributes(element, namespaceAttributes));
   /* 531:    */ }
  @SuppressWarnings("unchecked")
  @Test
  @Ignore
  public void testCanControlGatheredEntriesUsingRsm() throws Exception {

    NodeItem item1 = new NodeItemImpl(TEST_NODE_1, "node1:1", new Date(0), "<entry>item1</entry>");
    NodeItem item2 = new NodeItemImpl(TEST_NODE_2, "node2:1", new Date(10), "<entry>item2</entry>");
    NodeItem item3 = new NodeItemImpl(TEST_NODE_1, "node1:2", new Date(20), "<entry>item3</entry>");
    NodeItem item4 = new NodeItemImpl(TEST_NODE_1, "node1:3", new Date(30), "<entry>item4</entry>");

    ArrayList<NodeItem> results = new ArrayList<NodeItem>();
    results.add(item1);
    results.add(item2);
    results.add(item3);
    results.add(item4);

    Mockito.when(
            channelManager.getUserFeedItems(
                Mockito.any(JID.class),
                Mockito.any(Date.class),
                Mockito.anyInt(),
                Mockito.any(GlobalItemID.class),
                Mockito.anyBoolean()))
        .thenReturn(new ClosableIteratorImpl<NodeItem>(results.iterator()));
    Mockito.when(
            channelManager.getCountUserFeedItems(
                Mockito.any(JID.class), Mockito.any(Date.class), Mockito.anyBoolean()))
        .thenReturn(results.size());

    Element rsm = request.getElement().addElement("rsm");
    rsm.addNamespace("", PubSubElementProcessorAbstract.NS_RSM);
    rsm.addElement("max").addText("2");
    rsm.addElement("after").addText("node1:1");

    userItemsGet.process(element, jid, request, null);
    IQ response = (IQ) queue.poll();

    Assert.assertEquals(IQ.Type.result, response.getType());
    Element pubsub = response.getChildElement();
    Assert.assertEquals("pubsub", pubsub.getName());
    Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI());

    List<Element> items = pubsub.elements("items");
    Assert.assertEquals(2, items.size());

    Assert.assertEquals(TEST_NODE_2, items.get(0).attributeValue("node"));
    Assert.assertEquals(TEST_NODE_1, items.get(1).attributeValue("node"));
    Assert.assertEquals(1, items.get(0).elements("item").size());
    Assert.assertEquals(1, items.get(1).elements("item").size());

    Element rsmResult = pubsub.element("set");
    Assert.assertEquals("2", rsmResult.element("count").getText());
    Assert.assertEquals("node2:1", rsmResult.element("first").getText());
    Assert.assertEquals("node1:2", rsmResult.element("last").getText());
  }
  /**
   * Decide whether a message should be stored offline according to XEP-0160 and XEP-0334.
   *
   * @param message
   * @return <code>true</code> if the message should be stored offline, <code>false</code>
   *     otherwise.
   */
  static boolean shouldStoreMessage(final Message message) {
    // XEP-0334: Implement the <no-store/> hint to override offline storage
    if (message.getChildElement("no-store", "urn:xmpp:hints") != null) {
      return false;
    }

    switch (message.getType()) {
      case chat:
        // XEP-0160: Messages with a 'type' attribute whose value is "chat" SHOULD be stored
        // offline, with the exception of messages that contain only Chat State Notifications
        // (XEP-0085) [7] content

        // Iterate through the child elements to see if we can find anything that's not a chat state
        // notification or
        // real time text notification
        Iterator<?> it = message.getElement().elementIterator();

        while (it.hasNext()) {
          Object item = it.next();

          if (item instanceof Element) {
            Element el = (Element) item;
            if (Namespace.NO_NAMESPACE.equals(el.getNamespace())) {
              continue;
            }
            if (!el.getNamespaceURI().equals("http://jabber.org/protocol/chatstates")
                && !(el.getQName().equals(QName.get("rtt", "urn:xmpp:rtt:0")))) {
              return true;
            }
          }
        }

        return message.getBody() != null && !message.getBody().isEmpty();

      case groupchat:
      case headline:
        // XEP-0160: "groupchat" message types SHOULD NOT be stored offline
        // XEP-0160: "headline" message types SHOULD NOT be stored offline
        return false;

      case error:
        // XEP-0160: "error" message types SHOULD NOT be stored offline,
        // although a server MAY store advanced message processing errors offline
        if (message.getChildElement("amp", "http://jabber.org/protocol/amp") == null) {
          return false;
        }
        break;

      default:
        // XEP-0160: Messages with a 'type' attribute whose value is "normal" (or messages with no
        // 'type' attribute) SHOULD be stored offline.
        break;
    }
    return true;
  }
示例#10
0
  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;
      }
    }
  }
 /**
  * Processes packets that were sent to this service. Currently only packets that were sent from
  * registered components are being processed. In the future, we may also process packet of trusted
  * clients. Trusted clients may be able to execute ad-hoc commands such as adding or removing
  * components.
  *
  * @param packet the packet to process.
  */
 @Override
 public void process(Packet packet) throws PacketException {
   List<Component> components = getComponents(packet.getFrom());
   // Only process packets that were sent by registered components
   if (!components.isEmpty()) {
     if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) {
       IQ iq = (IQ) packet;
       Element childElement = iq.getChildElement();
       if (childElement != null) {
         String namespace = childElement.getNamespaceURI();
         if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
           // Add a disco item to the server for the component that supports disco
           Element identity = childElement.element("identity");
           if (identity == null) {
             // Do nothing since there are no identities in the disco#info packet
             return;
           }
           try {
             XMPPServer.getInstance()
                 .getIQDiscoItemsHandler()
                 .addComponentItem(packet.getFrom().toBareJID(), identity.attributeValue("name"));
             for (Component component : components) {
               if (component instanceof ComponentSession.ExternalComponent) {
                 ComponentSession.ExternalComponent externalComponent =
                     (ComponentSession.ExternalComponent) component;
                 externalComponent.setName(identity.attributeValue("name"));
                 externalComponent.setType(identity.attributeValue("type"));
                 externalComponent.setCategory(identity.attributeValue("category"));
               }
             }
           } catch (Exception e) {
             Log.error(
                 "Error processing disco packet of components: "
                     + components
                     + " - "
                     + packet.toXML(),
                 e);
           }
           // Store the IQ disco#info returned by the component
           addComponentInfo(iq);
           // Notify listeners that a component answered the disco#info request
           notifyComponentInfo(iq);
           // Alert other cluster nodes
           CacheFactory.doClusterTask(new NotifyComponentInfo(iq));
         }
       }
     }
   }
 }
  protected static Element getChildElement(Element element, String namespace) {
    //noinspection unchecked
    List<Element> elements = element.elements();
    if (elements.isEmpty()) {
      return null;
    }
    for (Element childElement : elements) {
      String childNamespace = childElement.getNamespaceURI();
      if (namespace.equals(childNamespace)) {
        return childElement;
      }
    }

    return null;
  }
  @SuppressWarnings("unchecked")
  @Test
  public void testOutgoingStanzaFormattedAsExpected() throws Exception {

    NodeItem item1 = new NodeItemImpl(TEST_NODE_1, "1", new Date(), "<entry>item1</entry>");
    NodeItem item2 = new NodeItemImpl(TEST_NODE_2, "1", new Date(), "<entry>item2</entry>");
    NodeItem item3 = new NodeItemImpl(TEST_NODE_1, "2", new Date(), "<entry>item3</entry>");
    NodeItem item4 = new NodeItemImpl(TEST_NODE_1, "3", new Date(), "<entry>item4</entry>");

    ArrayList<NodeItem> results = new ArrayList<NodeItem>();
    results.add(item1);
    results.add(item2);
    results.add(item3);
    results.add(item4);

    Mockito.when(
            channelManager.getUserFeedItems(
                Mockito.any(JID.class),
                Mockito.any(Date.class),
                Mockito.anyInt(),
                Mockito.any(GlobalItemID.class),
                Mockito.anyBoolean()))
        .thenReturn(new ClosableIteratorImpl<NodeItem>(results.iterator()));

    userItemsGet.process(element, jid, request, null);
    IQ response = (IQ) queue.poll();

    Assert.assertEquals(IQ.Type.result, response.getType());
    Element pubsub = response.getChildElement();
    Assert.assertEquals("pubsub", pubsub.getName());
    Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI());

    List<Element> items = pubsub.elements("items");
    Assert.assertEquals(3, items.size());

    Assert.assertEquals(TEST_NODE_1, items.get(0).attributeValue("node"));
    Assert.assertEquals(TEST_NODE_2, items.get(1).attributeValue("node"));
    Assert.assertEquals(TEST_NODE_1, items.get(2).attributeValue("node"));

    Assert.assertEquals(1, items.get(0).elements("item").size());
    Assert.assertEquals(2, items.get(2).elements("item").size());
  }
  @Test
  public void testNoUserItemsReturnsEmptyStanza() throws Exception {

    Mockito.when(
            channelManager.getUserFeedItems(
                Mockito.any(JID.class),
                Mockito.any(Date.class),
                Mockito.anyInt(),
                Mockito.any(GlobalItemID.class),
                Mockito.anyBoolean()))
        .thenReturn(new ClosableIteratorImpl<NodeItem>(new ArrayList<NodeItem>().iterator()));

    userItemsGet.process(element, jid, request, null);
    IQ response = (IQ) queue.poll();

    Assert.assertEquals(IQ.Type.result, response.getType());
    Element pubsub = response.getChildElement();
    Assert.assertEquals("pubsub", pubsub.getName());
    Assert.assertEquals(JabberPubsub.NAMESPACE_URI, pubsub.getNamespaceURI());
  }
示例#15
0
  /**
   * Returns the error condition.
   *
   * @return the error condition.
   * @see Condition
   */
  @SuppressWarnings("unchecked")
  public Condition getCondition() {

    // TODO: Remote this dependency on getElement()
    for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) {
      Element el = i.next();
      if (el.getNamespaceURI().equals(ERROR_NAMESPACE) && !el.getName().equals("text")) {
        return Condition.fromXMPP(el.getName());
      }
    }
    // Looking for XMPP condition failed. See if a legacy error code exists,
    // which can be mapped into an XMPP error condition.
    String code = attribute("code");
    if (code != null) {
      try {
        return Condition.fromLegacyCode(Integer.parseInt(code));
      } catch (Exception e) {
        // Ignore -- unable to map legacy code into a valid condition
        // so return null.
      }
    }
    return null;
  }
示例#16
0
  /**
   * Sets the error condition.
   *
   * @param condition the error condition.
   * @see Condition
   */
  @SuppressWarnings("unchecked")
  public void setCondition(Condition condition) {

    if (condition == null) {
      throw new NullPointerException("Condition cannot be null");
    }

    // Set the error code for legacy support.
    setAttribute("code", Integer.toString(condition.getLegacyCode()));

    // TODO: Remove this dependencies on getElement()
    Element conditionElement = null;
    for (Iterator<Element> i = getElement().elementIterator(); i.hasNext(); ) {
      Element el = i.next();
      if (el.getNamespaceURI().equals(ERROR_NAMESPACE) && !el.getName().equals("text")) {
        conditionElement = el;
      }
    }
    if (conditionElement != null) {
      getElement().remove(conditionElement);
    }

    set(condition.toXMPP(), null, ERROR_NAMESPACE);
  }
示例#17
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);
    }
  }
示例#18
0
 /* 532:    */
 /* 533:    */ protected void endElement(Element element) /* 534:    */ throws SAXException
       /* 535:    */ {
   /* 536:816 */ this.contentHandler.endElement(
       element.getNamespaceURI(), element.getName(), element.getQualifiedName());
   /* 537:    */ }