/**
   * Target and initiator should successfully connect to a "remote" SOCKS5 proxy and the initiator
   * activates the bytestream.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldSuccessfullyEstablishConnectionAndActivateSocks5Proxy() throws Exception {

    // build activation confirmation response
    IQ activationResponse =
        new IQ() {

          @Override
          public String getChildElementXML() {
            return null;
          }
        };
    activationResponse.setFrom(proxyJID);
    activationResponse.setTo(initiatorJID);
    activationResponse.setType(IQ.Type.RESULT);

    protocol.addResponse(
        activationResponse,
        Verification.correspondingSenderReceiver,
        Verification.requestTypeSET,
        new Verification<Bytestream, IQ>() {

          public void verify(Bytestream request, IQ response) {
            // verify that the correct stream should be activated
            assertNotNull(request.getToActivate());
            assertEquals(targetJID, request.getToActivate().getTarget());
          }
        });

    // start a local SOCKS5 proxy
    Socks5TestProxy socks5Proxy = Socks5TestProxy.getProxy(proxyPort);
    socks5Proxy.start();

    StreamHost streamHost = new StreamHost(proxyJID, socks5Proxy.getAddress());
    streamHost.setPort(socks5Proxy.getPort());

    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    Socket initiatorSocket = socks5Client.getSocket(10000);
    InputStream in = initiatorSocket.getInputStream();

    Socket targetSocket = socks5Proxy.getSocket(digest);
    OutputStream out = targetSocket.getOutputStream();

    // verify test data
    for (int i = 0; i < 10; i++) {
      out.write(i);
      assertEquals(i, in.read());
    }

    protocol.verifyAll();

    initiatorSocket.close();
    targetSocket.close();
    socks5Proxy.stop();
  }
  private void handleRayoIQ(RayoIqProvider.DialIq dialIq) {
    String from = dialIq.getFrom();

    JitsiMeetConference conference = getConferenceForMucJid(from);

    if (conference == null) {
      logger.debug("Mute error: room not found for JID: " + from);
      return;
    }

    ChatRoomMemberRole role = conference.getRoleForMucJid(from);

    if (role == null) {
      // Only room members are allowed to send requests
      IQ error = createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.forbidden));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    if (ChatRoomMemberRole.MODERATOR.compareTo(role) < 0) {
      // Moderator permission is required
      IQ error = createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.not_allowed));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    // Check if Jigasi is available
    String jigasiJid = conference.getServices().getSipGateway();

    if (StringUtils.isNullOrEmpty(jigasiJid)) {
      // Not available
      IQ error =
          createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.service_unavailable));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    // Redirect original request to Jigasi component
    String originalPacketId = dialIq.getPacketID();

    dialIq.setFrom(null);
    dialIq.setTo(jigasiJid);
    dialIq.setPacketID(IQ.nextID());

    IQ reply = (IQ) smackXmpp.getXmppConnection().sendPacketAndGetReply(dialIq);

    // Send Jigasi response back to the client
    reply.setFrom(null);
    reply.setTo(from);
    reply.setPacketID(originalPacketId);

    smackXmpp.getXmppConnection().sendPacket(reply);
  }
  /**
   * A convenience method to create an IQ packet.
   *
   * @param ID The packet ID of the
   * @param to To whom the packet is addressed.
   * @param from From whom the packet is sent.
   * @param type The IQ type of the packet.
   * @return The created IQ packet.
   */
  public static IQ createIQ(
      final String ID, final String to, final String from, final IQ.Type type) {
    final IQ iqPacket =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return null;
          }
        };
    iqPacket.setPacketID(ID);
    iqPacket.setTo(to);
    iqPacket.setFrom(from);
    iqPacket.setType(type);

    return iqPacket;
  }
Example #4
0
 /**
  * Convenience method to create a new empty {@link Type#RESULT IQ.Type.RESULT} IQ based on a
  * {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ. The new packet will be
  * initialized with:
  *
  * <ul>
  *   <li>The sender set to the recipient of the originating IQ.
  *   <li>The recipient set to the sender of the originating IQ.
  *   <li>The type set to {@link Type#RESULT IQ.Type.RESULT}.
  *   <li>The id set to the id of the originating IQ.
  *   <li>No child element of the IQ element.
  * </ul>
  *
  * @param iq the {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ packet.
  * @throws IllegalArgumentException if the IQ packet does not have a type of {@link Type#GET
  *     IQ.Type.GET} or {@link Type#SET IQ.Type.SET}.
  * @return a new {@link Type#RESULT IQ.Type.RESULT} IQ based on the originating IQ.
  */
 public static IQ createResultIQ(final IQ request) {
   if (!(request.getType() == Type.GET || request.getType() == Type.SET)) {
     throw new IllegalArgumentException(
         "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
   }
   final IQ result =
       new IQ() {
         public String getChildElementXML() {
           return null;
         }
       };
   result.setType(Type.RESULT);
   result.setPacketID(request.getPacketID());
   result.setFrom(request.getTo());
   result.setTo(request.getFrom());
   return result;
 }
  /**
   * If the initiator can connect to a SOCKS5 proxy but activating the stream fails an exception
   * should be thrown.
   *
   * @throws Exception should not happen
   */
  @Test
  public void shouldFailIfActivateSocks5ProxyFails() throws Exception {

    // build error response as reply to the stream activation
    XMPPError xmppError = new XMPPError(XMPPError.Condition.internal_server_error);
    IQ error =
        new IQ() {

          public String getChildElementXML() {
            return null;
          }
        };
    error.setType(Type.ERROR);
    error.setFrom(proxyJID);
    error.setTo(initiatorJID);
    error.setError(xmppError);

    protocol.addResponse(
        error, Verification.correspondingSenderReceiver, Verification.requestTypeSET);

    // start a local SOCKS5 proxy
    Socks5TestProxy socks5Proxy = Socks5TestProxy.getProxy(proxyPort);
    socks5Proxy.start();

    StreamHost streamHost = new StreamHost(proxyJID, socks5Proxy.getAddress());
    streamHost.setPort(socks5Proxy.getPort());

    // create digest to get the socket opened by target
    String digest = Socks5Utils.createDigest(sessionID, initiatorJID, targetJID);

    Socks5ClientForInitiator socks5Client =
        new Socks5ClientForInitiator(streamHost, digest, connection, sessionID, targetJID);

    try {

      socks5Client.getSocket(10000);

      fail("exception should be thrown");
    } catch (XMPPErrorException e) {
      assertTrue(XMPPError.Condition.internal_server_error.equals(e.getXMPPError().getCondition()));
      protocol.verifyAll();
    }

    socks5Proxy.stop();
  }
Example #6
0
 /**
  * Convenience method to create a new {@link Type#ERROR IQ.Type.ERROR} IQ based on a {@link
  * Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ. The new packet will be initialized
  * with:
  *
  * <ul>
  *   <li>The sender set to the recipient of the originating IQ.
  *   <li>The recipient set to the sender of the originating IQ.
  *   <li>The type set to {@link Type#ERROR IQ.Type.ERROR}.
  *   <li>The id set to the id of the originating IQ.
  *   <li>The child element contained in the associated originating IQ.
  *   <li>The provided {@link XMPPError XMPPError}.
  * </ul>
  *
  * @param iq the {@link Type#GET IQ.Type.GET} or {@link Type#SET IQ.Type.SET} IQ packet.
  * @param error the error to associate with the created IQ packet.
  * @throws IllegalArgumentException if the IQ packet does not have a type of {@link Type#GET
  *     IQ.Type.GET} or {@link Type#SET IQ.Type.SET}.
  * @return a new {@link Type#ERROR IQ.Type.ERROR} IQ based on the originating IQ.
  */
 public static IQ createErrorResponse(final IQ request, final XMPPError error) {
   if (!(request.getType() == Type.GET || request.getType() == Type.SET)) {
     throw new IllegalArgumentException(
         "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
   }
   final IQ result =
       new IQ() {
         public String getChildElementXML() {
           return request.getChildElementXML();
         }
       };
   result.setType(Type.ERROR);
   result.setPacketID(request.getPacketID());
   result.setFrom(request.getTo());
   result.setTo(request.getFrom());
   result.setError(error);
   return result;
 }
  /**
   * FIXME: replace with IQ.createErrorResponse Prosody does not allow to include request body in
   * error response. Replace this method with IQ.createErrorResponse once fixed.
   */
  private IQ createErrorResponse(IQ request, XMPPError error) {
    IQ.Type requestType = request.getType();
    if (!(requestType == IQ.Type.GET || requestType == IQ.Type.SET)) {
      throw new IllegalArgumentException(
          "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
    }

    final IQ result =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return "";
          }
        };
    result.setType(IQ.Type.ERROR);
    result.setPacketID(request.getPacketID());
    result.setFrom(request.getTo());
    result.setTo(request.getFrom());
    result.setError(error);
    return result;
  }
  /**
   * Sends enable or disable carbon packet to the server.
   *
   * @param enable if <tt>true</tt> sends enable packet otherwise sends disable packet.
   */
  private void enableDisableCarbon(final boolean enable) {
    IQ iq =
        new IQ() {

          @Override
          public String getChildElementXML() {
            return "<" + (enable ? "enable" : "disable") + " xmlns='urn:xmpp:carbons:2' />";
          }
        };

    Packet response = null;
    try {
      PacketCollector packetCollector =
          jabberProvider
              .getConnection()
              .createPacketCollector(new PacketIDFilter(iq.getPacketID()));
      iq.setFrom(jabberProvider.getOurJID());
      iq.setType(IQ.Type.SET);
      jabberProvider.getConnection().sendPacket(iq);
      response = packetCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());

      packetCollector.cancel();
    } catch (Exception e) {
      logger.error("Failed to enable carbon.", e);
    }

    isCarbonEnabled = false;

    if (response == null) {
      logger.error("Failed to enable carbon. No response is received.");
    } else if (response.getError() != null) {
      logger.error("Failed to enable carbon: " + response.getError());
    } else if (!(response instanceof IQ) || !((IQ) response).getType().equals(IQ.Type.RESULT)) {
      logger.error("Failed to enable carbon. The response is not correct.");
    } else {
      isCarbonEnabled = true;
    }
  }
  /**
   * Parses an IQ packet.
   *
   * @param parser the XML parser, positioned at the start of an IQ packet.
   * @return an IQ object.
   * @throws Exception if an exception occurs while parsing the packet.
   */
  public static IQ parseIQ(XmlPullParser parser, Connection connection) throws Exception {
    IQ iqPacket = null;

    String id = parser.getAttributeValue("", "id");
    String to = parser.getAttributeValue("", "to");
    String from = parser.getAttributeValue("", "from");
    IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type"));
    XMPPError error = null;

    boolean done = false;
    while (!done) {
      int eventType = parser.next();

      if (eventType == XmlPullParser.START_TAG) {
        String elementName = parser.getName();
        String namespace = parser.getNamespace();
        if (elementName.equals("error")) {
          error = PacketParserUtils.parseError(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:auth")) {
          iqPacket = parseAuthentication(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:roster")) {
          iqPacket = parseRoster(parser);
        } else if (elementName.equals("query") && namespace.equals("jabber:iq:register")) {
          iqPacket = parseRegistration(parser);
        } else if (elementName.equals("bind")
            && namespace.equals("urn:ietf:params:xml:ns:xmpp-bind")) {
          iqPacket = parseResourceBinding(parser);
        }
        // Otherwise, see if there is a registered provider for
        // this element name and namespace.
        else {
          Object provider = ProviderManager.getInstance().getIQProvider(elementName, namespace);
          if (provider != null) {
            if (provider instanceof IQProvider) {
              iqPacket = ((IQProvider) provider).parseIQ(parser);
            } else if (provider instanceof Class) {
              iqPacket =
                  (IQ)
                      PacketParserUtils.parseWithIntrospection(
                          elementName, (Class<?>) provider, parser);
            }
          }
          // Only handle unknown IQs of type result. Types of 'get' and 'set' which are not
          // understood
          // have to be answered with an IQ error response. See the code a few lines below
          else if (IQ.Type.RESULT == type) {
            // No Provider found for the IQ stanza, parse it to an UnparsedIQ instance
            // so that the content of the IQ can be examined later on
            iqPacket = new UnparsedResultIQ(parseContent(parser));
          }
        }
      } else if (eventType == XmlPullParser.END_TAG) {
        if (parser.getName().equals("iq")) {
          done = true;
        }
      }
    }
    // Decide what to do when an IQ packet was not understood
    if (iqPacket == null) {
      if (IQ.Type.GET == type || IQ.Type.SET == type) {
        // If the IQ stanza is of type "get" or "set" containing a child element
        // qualified by a namespace it does not understand, then answer an IQ of
        // type "error" with code 501 ("feature-not-implemented")
        iqPacket =
            new IQ() {
              @Override
              public String getChildElementXML() {
                return null;
              }
            };
        iqPacket.setPacketID(id);
        iqPacket.setTo(from);
        iqPacket.setFrom(to);
        iqPacket.setType(IQ.Type.ERROR);
        iqPacket.setError(new XMPPError(XMPPError.Condition.feature_not_implemented));
        connection.sendPacket(iqPacket);
        return null;
      } else {
        // If an IQ packet wasn't created above, create an empty IQ packet.
        iqPacket =
            new IQ() {
              @Override
              public String getChildElementXML() {
                return null;
              }
            };
      }
    }

    // Set basic values on the iq packet.
    iqPacket.setPacketID(id);
    iqPacket.setTo(to);
    iqPacket.setFrom(from);
    iqPacket.setType(type);
    iqPacket.setError(error);

    return iqPacket;
  }
Example #10
0
 public static IQ parseIQ(XmlPullParser xmlPullParser)
     throws XmlPullParserException, IOException, SmackException {
   XMPPError xMPPError = null;
   ParserUtils.assertAtStartTag(xmlPullParser);
   int depth = xmlPullParser.getDepth();
   String attributeValue = xmlPullParser.getAttributeValue("", "id");
   String attributeValue2 = xmlPullParser.getAttributeValue("", PrivacyItem.SUBSCRIPTION_TO);
   String attributeValue3 = xmlPullParser.getAttributeValue("", PrivacyItem.SUBSCRIPTION_FROM);
   Type fromString = Type.fromString(xmlPullParser.getAttributeValue("", "type"));
   IQ iq = null;
   while (true) {
     switch (xmlPullParser.next()) {
       case VideoSize.HVGA /*2*/:
         XMPPError parseError;
         IQ iq2;
         String name = xmlPullParser.getName();
         String namespace = xmlPullParser.getNamespace();
         Object obj = -1;
         switch (name.hashCode()) {
           case 96784904:
             if (name.equals(XMPPError.ERROR)) {
               obj = null;
               break;
             }
             break;
         }
         switch (obj) {
           case VideoSize.QCIF /*0*/:
             parseError = parseError(xmlPullParser);
             iq2 = iq;
             break;
           default:
             IQProvider iQProvider = ProviderManager.getIQProvider(name, namespace);
             XMPPError xMPPError2;
             if (iQProvider == null) {
               xMPPError2 = xMPPError;
               iq2 = new UnparsedIQ(name, namespace, parseElement(xmlPullParser));
               parseError = xMPPError2;
               break;
             }
             xMPPError2 = xMPPError;
             iq2 = (IQ) iQProvider.parse(xmlPullParser);
             parseError = xMPPError2;
             break;
         }
         iq = iq2;
         xMPPError = parseError;
         break;
       case Version.API03_CUPCAKE_15 /*3*/:
         if (xmlPullParser.getDepth() != depth) {
           break;
         }
         if (iq == null) {
           switch (C01861.$SwitchMap$org$jivesoftware$smack$packet$IQ$Type[fromString.ordinal()]) {
             case VideoSize.CIF /*1*/:
               iq = new ErrorIQ(xMPPError);
               break;
             case VideoSize.HVGA /*2*/:
               iq = new EmptyResultIQ();
               break;
           }
         }
         iq.setStanzaId(attributeValue);
         iq.setTo(attributeValue2);
         iq.setFrom(attributeValue3);
         iq.setType(fromString);
         iq.setError(xMPPError);
         return iq;
       default:
         break;
     }
   }
 }