/**
   * 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);
  }
    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);
            }
          }
        }
      }
    }
Exemple #3
0
  public void executeGet(IQ packet, Workgroup workgroup) {
    IQ reply = IQ.createResultIQ(packet);

    JID from = packet.getFrom();
    String bareJID = from.toBareJID();

    boolean isMonitor = false;

    // Retrieve the sound settings.
    String monitors = workgroup.getProperties().getProperty("monitors");
    if (monitors != null) {
      StringTokenizer tkn = new StringTokenizer(monitors, ",");
      while (tkn.hasMoreTokens()) {
        String agent = tkn.nextToken();
        if (agent.equalsIgnoreCase(bareJID)) {
          isMonitor = true;
        }
      }
    }

    Element monitorElement =
        reply.setChildElement("monitor", "http://jivesoftware.com/protocol/workgroup");

    if (!isMonitor) {
      monitorElement.addElement("isMonitor").setText("false");
    } else {
      monitorElement.addElement("isMonitor").setText("true");
    }

    workgroup.send(reply);
  }
 /**
  * 退出群
  *
  * @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;
 }
  public void receivedAnswer(IQ packet) {
    String packetId = packet.getID();

    if (isValid(packet)) {
      // The packet was validated, so it can be added to the Entity
      // Capabilities cache map.

      // Add the resolved identities and features to the entity
      // EntityCapabilitiesManager.capabilities object and add it
      // to the cache map...
      EntityCapabilities caps = verAttributes.get(packetId);

      // Store identities.
      List<String> identities = getIdentitiesFrom(packet);
      for (String identity : identities) {
        caps.addIdentity(identity);
      }

      // Store features.
      List<String> features = getFeaturesFrom(packet);
      for (String feature : features) {
        caps.addFeature(feature);
      }

      entityCapabilitiesMap.put(caps.getVerAttribute(), caps);
      entityCapabilitiesUserMap.put(packet.getFrom(), caps.getVerAttribute());
    }

    // Remove cached 'ver' attribute.
    verAttributes.remove(packetId);
  }
 /*
  * (non-Javadoc)
  *
  * @see
  * com.buddycloud.pusher.handler.AbstractQueryHandler#handleQuery(org.xmpp
  * .packet.IQ)
  */
 @Override
 protected IQ handleQuery(IQ iq) {
   String userJid = iq.getFrom().toBareJID();
   Element queryElement = iq.getElement().element("query");
   Element typeEl = queryElement.element("type");
   NotificationSettings notificationSettings =
       NotificationUtils.getNotificationSettingsByType(userJid, typeEl.getText(), getDataSource());
   return createResponse(iq, userJid, notificationSettings);
 }
  private void unregister(IQ request, JID actorJID, boolean isRemote) throws Exception {
    LOGGER.debug("Processing unregister request from " + request.getFrom());

    if (!validateSingleChildElement(request)) {
      failBadRequest(request);
      return;
    }
    if (!isRemote && !userRegistered(actorJID)) {
      failRegistrationRequired(request);
      return;
    }

    Transaction t = null;
    try {
      t = channelManager.beginTransaction();

      List<Packet> notifications = new LinkedList<Packet>();
      Set<String> remoteDomains = getRemoteDomains();

      ResultSet<NodeMembership> userMemberships = channelManager.getUserMemberships(actorJID);
      for (NodeMembership userMembership : userMemberships) {
        String nodeId = userMembership.getNodeId();
        if (isPersonal(nodeId) || isSingleOwner(nodeId, actorJID)) {
          channelManager.deleteNode(nodeId);
          if (Configuration.getInstance().isLocalNode(nodeId)) {
            addDeleteNodeNotifications(nodeId, notifications);
          }
        }
        if (!isRemote) {
          addUnsubscribeFromNodeNotifications(actorJID, userMembership.getNodeId(), notifications);
        }
      }

      ResultSet<NodeItem> userItems = channelManager.getUserPublishedItems(actorJID);
      for (NodeItem userItem : userItems) {
        if (Configuration.getInstance().isLocalNode(userItem.getNodeId())) {
          addDeleteItemNotifications(userItem.getNodeId(), userItem.getId(), notifications);
        }
      }

      channelManager.deleteUserItems(actorJID);
      channelManager.deleteUserSubscriptions(actorJID);
      channelManager.deleteUserAffiliations(actorJID);

      outQueue.put(IQ.createResultIQ(request));
      if (!isRemote) {
        makeRemoteRequests(request, remoteDomains);
      }
      sendNotifications(notifications);

      t.commit();
    } finally {
      if (t != null) {
        t.close();
      }
    }
  }
 /**
  * 审批入群申请
  *
  * @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;
 }
 private boolean checkDomain(IQ request, JID actorJID) throws InterruptedException {
   if (!request.getFrom().getDomain().contains(actorJID.getDomain())) {
     fail(
         request,
         org.xmpp.packet.PacketError.Condition.bad_request,
         org.xmpp.packet.PacketError.Type.cancel);
     return false;
   }
   return true;
 }
Exemple #10
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);
  }
  @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;
  }
  /**
   * 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;
  }
 private void makeRemoteRequests(IQ request, Set<String> remoteDomains) throws Exception {
   for (String remoteDomain : remoteDomains) {
     IQ remoteRequest = request.createCopy();
     remoteRequest.getElement().addAttribute("remote-server-discover", "false");
     remoteRequest.setTo(remoteDomain);
     Element actor =
         remoteRequest
             .getElement()
             .element("query")
             .element("remove")
             .addElement("actor", Buddycloud.NS);
     actor.addText(request.getFrom().toBareJID());
     outQueue.put(remoteRequest);
   }
 }
 public void componentInfoReceived(IQ iq) {
   // Check if it's a Clearspace component
   boolean isClearspace = false;
   Element childElement = iq.getChildElement();
   for (Iterator it = childElement.elementIterator("identity"); it.hasNext(); ) {
     Element identity = (Element) it.next();
     if ("component".equals(identity.attributeValue("category"))
         && "clearspace".equals(identity.attributeValue("type"))) {
       isClearspace = true;
     }
   }
   // If component is Clearspace then keep track of the component
   if (isClearspace) {
     clearspaces.add(iq.getFrom().getDomain());
   }
 }
  /**
   * 用户申请入群
   *
   * @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);
    }
  }
  @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;
  }
  @Override
  public void process(IQ request) throws Exception {
    JID actorJID = null;
    Element removeEl = request.getElement().element("query").element("remove");
    Element actorEl = removeEl.element("actor");
    boolean isRemote = actorEl != null;

    if (isRemote) {
      actorJID = new JID(actorEl.getTextTrim());
      if (!checkDomain(request, actorJID)) {
        return;
      }
    } else {
      actorJID = new JID(request.getFrom().toBareJID());
    }

    unregister(request, actorJID, isRemote);
  }
  @Override
  public IQ handleIQ(IQ packet) throws UnauthorizedException {
    Log.debug("handling IQ packet " + packet);
    IQ reply = IQ.createResultIQ(packet);
    Element iq = packet.getChildElement();
    String method = iq.attributeValue("name");
    List<String> args = new ArrayList<String>();

    // TODO Don't look this up each time
    // We currently do this to avoid problems during development
    // from reloading Jive - later we probably want to move this to
    // constructor
    XMPPMethods methods = EJBUtil.defaultLookup(XMPPMethods.class);
    SimpleAnnotatedInvoker xmppInvoker =
        new SimpleAnnotatedInvoker(XMPPRemoted.class, methods, new PersonArgumentPrepender());

    for (Object argObj : iq.elements()) {
      Node arg = (Node) argObj;
      Log.debug("parsing expected arg node " + arg);
      if (arg.getNodeType() == Node.ELEMENT_NODE) {
        String argValue = arg.getText();
        Log.debug("Adding arg value" + argValue);
        args.add(argValue);
      }
    }

    try {
      Log.debug(
          "invoking method "
              + method
              + " with ("
              + args.size()
              + ") args "
              + Arrays.toString(args.toArray()));
      @SuppressWarnings("unused")
      String replyStr = xmppInvoker.invoke(method, args, packet.getFrom());
      // Don't do anything with this yet
    } catch (Exception e) {
      Log.debug("Caught exception during client method invocation", e);
    }
    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);
       }
     }
   }
 }
  /**
   * Sends an IQ packet to the Clearspace external component and returns the IQ packet returned by
   * CS or <tt>null</tt> if no answer was received before the specified timeout.
   *
   * @param packet IQ packet to send.
   * @param timeout milliseconds to wait before timing out.
   * @return IQ packet returned by Clearspace responsing the packet we sent.
   */
  public IQ query(final IQ packet, int timeout) {
    // Complain if FROM is empty
    if (packet.getFrom() == null) {
      throw new IllegalStateException("IQ packets with no FROM cannot be sent to Clearspace");
    }
    // If CS is not connected then return null
    if (clearspaces.isEmpty()) {
      return null;
    }
    // Set the target address to the IQ packet. Roate list so we distribute load
    String component;
    synchronized (clearspaces) {
      component = clearspaces.get(0);
      Collections.rotate(clearspaces, 1);
    }
    packet.setTo(component);
    final LinkedBlockingQueue<IQ> answer = new LinkedBlockingQueue<IQ>(8);
    final IQRouter router = XMPPServer.getInstance().getIQRouter();
    router.addIQResultListener(
        packet.getID(),
        new IQResultListener() {
          public void receivedAnswer(IQ packet) {
            answer.offer(packet);
          }

          public void answerTimeout(String packetId) {
            Log.warn("No answer from Clearspace was received for IQ stanza: " + packet);
          }
        });
    XMPPServer.getInstance().getIQRouter().route(packet);
    IQ reply = null;
    try {
      reply = answer.poll(timeout, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      // Ignore
    }
    return reply;
  }
 void addComponentInfo(IQ iq) {
   componentInfo.put(iq.getFrom().getDomain(), iq);
 }
  /**
   * 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;
  }
Exemple #23
0
  /**
   * Reads a history request off the wire, sends it to the WS with a new callback for returning the
   * response.
   *
   * @param request the history request
   * @param responseCallback the callback to send the response back
   */
  void processHistoryRequest(final IQ request, final PacketCallback responseCallback) {
    Element items = null, historyDelta = null;
    Element pubsubRequest = request.getElement().element("pubsub");
    if (pubsubRequest != null) {
      items = pubsubRequest.element("items");
      if (items != null) {
        historyDelta = items.element("delta-history");
      }
    }
    if (items == null
        || historyDelta == null
        || historyDelta.attribute("start-version") == null
        || historyDelta.attribute("start-version-hash") == null
        || historyDelta.attribute("end-version") == null
        || historyDelta.attribute("end-version-hash") == null
        || historyDelta.attribute("wavelet-name") == null) {
      responseCallback.error(FederationErrors.badRequest("Malformed history request"));
      return;
    }

    final ProtocolHashedVersion startVersion;
    try {
      startVersion =
          parseFromUnsafe(
              historyDelta.attributeValue("start-version"),
              historyDelta.attributeValue("start-version-hash"));
    } catch (IllegalArgumentException e) {
      responseCallback.error(FederationErrors.badRequest("Invalid format of start version"));
      return;
    }

    final ProtocolHashedVersion endVersion;
    try {
      endVersion =
          parseFromUnsafe(
              historyDelta.attributeValue("end-version"),
              historyDelta.attributeValue("end-version-hash"));
    } catch (IllegalArgumentException e) {
      responseCallback.error(FederationErrors.badRequest("Invalid format of end version"));
      return;
    }

    final long responseLengthLimit;
    if (historyDelta.attribute("response-length-limit") != null) {
      try {
        responseLengthLimit = Long.parseLong(historyDelta.attributeValue("response-length-limit"));
      } catch (NumberFormatException e) {
        responseCallback.error(FederationErrors.badRequest("Invalid response length limit"));
        return;
      }
    } else {
      responseLengthLimit = 0;
    }

    final WaveletName waveletName;
    try {
      waveletName =
          XmppUtil.waveletNameCodec.uriToWaveletName(historyDelta.attributeValue("wavelet-name"));
    } catch (EncodingException e) {
      responseCallback.error(
          FederationErrors.badRequest(
              "Malformed wavelet name: " + historyDelta.attributeValue("wavelet-name")));
      return;
    }

    // Construct a new response listener inline.
    WaveletFederationProvider.HistoryResponseListener listener =
        new WaveletFederationProvider.HistoryResponseListener() {
          @Override
          public void onFailure(FederationError error) {
            responseCallback.error(error);
          }

          @Override
          public void onSuccess(
              List<ByteString> appliedDeltaSet,
              ProtocolHashedVersion lastCommittedVersion,
              long versionTruncatedAt) {
            IQ response = IQ.createResultIQ(request);

            Element pubsub = response.setChildElement("pubsub", XmppNamespace.NAMESPACE_PUBSUB);
            Element items = pubsub.addElement("items");

            // Add each delta to the outgoing response.
            for (ByteString appliedDelta : appliedDeltaSet) {
              items
                  .addElement("item")
                  .addElement("applied-delta", XmppNamespace.NAMESPACE_WAVE_SERVER)
                  .addCDATA(Base64Util.encode(appliedDelta.toByteArray()));
            }

            // Set the LCV history-hash, if provided.
            // TODO(thorogood): We don't set the hashed version, which is wrong,
            // but it's not part of the current spec (Feb 2010).
            if (lastCommittedVersion != null && lastCommittedVersion.hasVersion()) {
              String version = String.valueOf(lastCommittedVersion.getVersion());
              items
                  .addElement("item")
                  .addElement("commit-notice", XmppNamespace.NAMESPACE_WAVE_SERVER)
                  .addAttribute("version", version);
            }

            // Set the version truncated at, if provided.
            if (versionTruncatedAt > 0) {
              String version = String.valueOf(versionTruncatedAt);
              items
                  .addElement("item")
                  .addElement("history-truncated", XmppNamespace.NAMESPACE_WAVE_SERVER)
                  .addAttribute("version", version);
            }

            // Send the message to the source.
            responseCallback.run(response);
          }
        };

    // Hand off a history request to the waveletProvider.
    // TODO(thorogood,arb): Note that the following remote domain is going to be
    // the Wave component JID (e.g. wave.foo.com), and *not* the actual remote domain.
    String remoteDomain = request.getFrom().getDomain();
    waveletProvider.requestHistory(
        waveletName, remoteDomain, startVersion, endVersion, responseLengthLimit, listener);
  }
  @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);
      // }
      // }
    }
  }
  /**
   * Handles a IQ-register 'get' request, which is to be interpreted as a request for a registration
   * form template. The template will be prefilled with data, if the requestee has a current
   * registration with the gateway.
   *
   * @param packet the IQ-register 'get' stanza.
   * @throws UnauthorizedException if the user is not allowed to make use of the gateway.
   */
  private void getRegistrationForm(IQ packet) throws UnauthorizedException {
    final JID from = packet.getFrom();
    final IQ result = IQ.createResultIQ(packet);

    // search for existing registrations
    String curUsername = null;
    String curPassword = null;
    String curNickname = null;
    Boolean registered = false;
    final Collection<Registration> registrations =
        RegistrationManager.getInstance().getRegistrations(from, parent.transportType);
    if (registrations.iterator().hasNext()) {
      Registration registration = registrations.iterator().next();
      curUsername = registration.getUsername();
      curPassword = registration.getPassword();
      curNickname = registration.getNickname();
      registered = true;
    }

    // Verify that the user is allowed to make use of the gateway.
    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"));
    }

    // generate a template registration form.
    final Element response =
        DocumentHelper.createElement(QName.get("query", NameSpace.IQ_REGISTER));
    final DataForm form = new DataForm(DataForm.Type.form);
    form.addInstruction(parent.getTerminologyRegistration());

    final FormField usernameField = form.addField();
    usernameField.setLabel(parent.getTerminologyUsername());
    usernameField.setVariable("username");
    usernameField.setType(FormField.Type.text_single);
    if (curUsername != null) {
      usernameField.addValue(curUsername);
    }

    final FormField passwordField = form.addField();
    passwordField.setLabel(parent.getTerminologyPassword());
    passwordField.setVariable("password");
    passwordField.setType(FormField.Type.text_private);
    if (curPassword != null) {
      passwordField.addValue(curPassword);
    }

    final String nicknameTerm = parent.getTerminologyNickname();
    if (nicknameTerm != null) {
      FormField nicknameField = form.addField();
      nicknameField.setLabel(nicknameTerm);
      nicknameField.setVariable("nick");
      nicknameField.setType(FormField.Type.text_single);
      if (curNickname != null) {
        nicknameField.addValue(curNickname);
      }
    }

    response.add(form.getElement());
    response.addElement("instructions").addText(parent.getTerminologyRegistration());

    // prefill the template with existing data if a registration already
    // exists.
    if (registered) {
      response.addElement("registered");
      response.addElement("username").addText(curUsername);
      if (curPassword == null) {
        response.addElement("password");
      } else {
        response.addElement("password").addText(curPassword);
      }
      if (nicknameTerm != null) {
        if (curNickname == null) {
          response.addElement("nick");
        } else {
          response.addElement("nick").addText(curNickname);
        }
      }
    } else {
      response.addElement("username");
      response.addElement("password");
      if (nicknameTerm != null) {
        response.addElement("nick");
      }
    }

    // Add special indicator for rosterless gateway handling.
    response.addElement("x").addNamespace("", NameSpace.IQ_GATEWAY_REGISTER);

    result.setChildElement(response);

    parent.sendPacket(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);
    }
  }
  @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;
    }
  }