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); } } } } }
/** * Processes an IQ-register request that is expressing the wish to deregister from a gateway. * * @param packet the IQ-register stanza. */ private void handleDeregister(final IQ packet) { final IQ result = IQ.createResultIQ(packet); if (packet.getChildElement().elements().size() != 1) { Log.debug( "Cannot process this stanza - exactly one" + " childelement of <remove> expected:" + packet.toXML()); final IQ error = IQ.createResultIQ(packet); error.setError(Condition.bad_request); parent.sendPacket(error); return; } final JID from = packet.getFrom(); final JID to = packet.getTo(); // Tell the end user the transport went byebye. final Presence unavailable = new Presence(Presence.Type.unavailable); unavailable.setTo(from); unavailable.setFrom(to); this.parent.sendPacket(unavailable); try { deleteRegistration(from); } catch (UserNotFoundException e) { Log.debug("Error cleaning up contact list of: " + from); result.setError(Condition.registration_required); } parent.sendPacket(result); }
/** * 退出群 * * @param iq * @return */ private IQ quitGroup(IQ iq) { String member_jid = iq.getFrom().toBareJID(); JID group = iq.getTo(); IQ reply = IQ.createResultIQ(iq); long group_id = -1; LocalGroup localGroup = null; try { group_id = Long.parseLong(group.getNode()); localGroup = service.getGroup(group_id); } catch (Exception e) { reply.setError(PacketError.Condition.bad_request); return reply; } // 删除群成员 try { Map<String, LocalGroupRole> members = localGroup.getGroupMembers(); if (members != null && !members.isEmpty()) { int delete = groupDbManager.deleteGroupMember(group_id, member_jid); // 有记录被删除,通知群成员 if (delete > 0) { // 如果群主退出,删除群 if (localGroup.isOwner(member_jid)) groupDbManager.deleteGroupById(group_id); // 发送消息 sendPacket(members.keySet(), packetUtil.createQuitPresence(member_jid, group_id)); } } localGroup.removeMember(member_jid); } catch (SQLException e) { reply.setError(PacketError.Condition.internal_server_error); return reply; } return null; }
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); } } } }
/** * 审批入群申请 * * @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; }
/** * Handles the IQ packet sent by an owner of the room. Possible actions are: * * <ul> * <li>Return the list of owners * <li>Return the list of admins * <li>Change user's affiliation to owner * <li>Change user's affiliation to admin * <li>Change user's affiliation to member * <li>Change user's affiliation to none * <li>Destroy the room * <li>Return the room configuration within a dataform * <li>Update the room configuration based on the sent dataform * </ul> * * @param packet the IQ packet sent by an owner of the room. * @param role the role of the user that sent the packet. * @throws ForbiddenException if the user does not have enough permissions (ie. is not an owner). * @throws ConflictException If the room was going to lose all of its owners. */ @SuppressWarnings("unchecked") public void handleIQ(IQ packet, MUCRole role) throws ForbiddenException, ConflictException, CannotBeInvitedException { // Only owners can send packets with the namespace "http://jabber.org/protocol/muc#owner" if (MUCRole.Affiliation.owner != role.getAffiliation()) { throw new ForbiddenException(); } IQ reply = IQ.createResultIQ(packet); Element element = packet.getChildElement(); // Analyze the action to perform based on the included element Element formElement = element.element(QName.get("x", "jabber:x:data")); if (formElement != null) { handleDataFormElement(role, formElement); } else { Element destroyElement = element.element("destroy"); if (destroyElement != null) { if (((MultiUserChatServiceImpl) room.getMUCService()).getMUCDelegate() != null) { if (!((MultiUserChatServiceImpl) room.getMUCService()) .getMUCDelegate() .destroyingRoom(room.getName(), role.getUserAddress())) { // Delegate said no, reject destroy request. throw new ForbiddenException(); } } JID alternateJID = null; final String jid = destroyElement.attributeValue("jid"); if (jid != null) { alternateJID = new JID(jid); } room.destroyRoom(alternateJID, destroyElement.elementTextTrim("reason")); } else { // If no element was included in the query element then answer the // configuration form if (!element.elementIterator().hasNext()) { refreshConfigurationFormValues(); reply.setChildElement(probeResult.createCopy()); } // An unknown and possibly incorrect element was included in the query // element so answer a BAD_REQUEST error else { reply.setChildElement(packet.getChildElement().createCopy()); reply.setError(PacketError.Condition.bad_request); } } } if (reply.getTo() != null) { // Send a reply only if the sender of the original packet was from a real JID. (i.e. not // a packet generated locally) router.route(reply); } }
public IQ handleIQ(IQ iq) { Type type = iq.getType(); String group_id = iq.getTo().getNode(); if (group_id == null) return null; // 申请入群 if (Type.get == type) return applyUserGroup(iq); else if (Type.set == type) { Element element = iq.getChildElement(); Element quit = element.element("quit"); if (quit != null) return quitGroup(iq); else return processGroupApply(iq); } return null; }
/** * 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; }
/** * 用户申请入群 * * @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); } }
/** * Handles all roster queries. There are two major types of queries: * * <ul> * <li>Roster remove - A forced removal of items from a roster. Roster removals are the only * roster queries allowed to directly affect the roster from another user. * <li>Roster management - A local user looking up or updating their roster. * </ul> * * @param packet The update packet * @return The reply or null if no reply */ public IQ handleIQ(IQ packet) throws UnauthorizedException, PacketException { try { IQ returnPacket = null; org.xmpp.packet.Roster roster = (org.xmpp.packet.Roster) packet; JID recipientJID = packet.getTo(); // The packet is bound for the server and must be roster management if (recipientJID == null || recipientJID.getNode() == null || !UserManager.getInstance().isRegisteredUser(recipientJID.getNode())) { returnPacket = manageRoster(roster); } // The packet must be a roster removal from a foreign domain user. else { removeRosterItem(roster); } return returnPacket; } catch (SharedGroupException e) { IQ result = IQ.createResultIQ(packet); result.setChildElement(packet.getChildElement().createCopy()); result.setError(PacketError.Condition.not_acceptable); return result; } catch (Exception e) { if (e.getCause() instanceof IDNAException) { Log.warn(LocaleUtils.getLocalizedString("admin.error"), e); IQ result = IQ.createResultIQ(packet); result.setChildElement(packet.getChildElement().createCopy()); result.setError(PacketError.Condition.jid_malformed); return result; } else { Log.error(LocaleUtils.getLocalizedString("admin.error"), e); IQ result = IQ.createResultIQ(packet); result.setChildElement(packet.getChildElement().createCopy()); result.setError(PacketError.Condition.internal_server_error); return result; } } }
@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 '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; } }