/** * 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 IQ error(Packet packet, PacketError.Condition condition) { IQ reply; reply = new IQ(IQ.Type.error, packet.getID()); reply.setFrom(packet.getTo()); reply.setTo(packet.getFrom()); reply.setError(condition); return reply; }
@Override public void sendPacket(Component component, Packet packet) { if (packet != null && packet.getFrom() == null) { throw new IllegalArgumentException( "Packet with no FROM address was received from component."); } PacketRouter router = XMPPServer.getInstance().getPacketRouter(); if (router != null) { router.route(packet); } }
/** * Make sure that the received packet has a TO and FROM values defined and that it was sent from a * previously validated domain. If the packet does not matches any of the above conditions then a * PacketRejectedException will be thrown. * * @param packet the received packet. * @throws PacketRejectedException if the packet does not include a TO or FROM or if the packet * was sent from a domain that was not previously validated. */ private void packetReceived(Packet packet) throws PacketRejectedException { if (packet.getTo() == null || packet.getFrom() == null) { Log.debug( "Closing IncomingServerSession due to packet with no TO or FROM: " + packet.toXML()); // Send a stream error saying that the packet includes no TO or FROM StreamError error = new StreamError(StreamError.Condition.improper_addressing); connection.deliverRawText(error.toXML()); // Close the underlying connection connection.close(); open = false; throw new PacketRejectedException("Packet with no TO or FROM attributes"); } else if (!((IncomingServerSession) session).isValidDomain(packet.getFrom().getDomain())) { Log.debug( "Closing IncomingServerSession due to packet with invalid domain: " + packet.toXML()); // Send a stream error saying that the packet includes an invalid FROM StreamError error = new StreamError(StreamError.Condition.invalid_from); connection.deliverRawText(error.toXML()); // Close the underlying connection connection.close(); open = false; throw new PacketRejectedException("Packet with no TO or FROM attributes"); } }
public Packet doAction(Packet packet) throws PacketRejectedException { SessionManager sessionManager = SessionManager.getInstance(); ClientSession clientSession = sessionManager.getSession(packet.getFrom()); Packet rejectPacket; String pfFrom = JiveGlobals.getProperty("pf.From", "packetfilter"); if (packet instanceof Message) { Message in = (Message) packet.createCopy(); if (clientSession != null && in.getBody() != null) { in.setFrom(new JID(pfFrom)); String rejectMessage = JiveGlobals.getProperty( "pf.rejectMessage", "Your message was rejected by the packet filter"); in.setBody(rejectMessage); in.setType(Message.Type.error); in.setTo(packet.getFrom()); String rejectSubject = JiveGlobals.getProperty("pf.rejectSubject", "Rejected"); in.setSubject(rejectSubject); clientSession.process(in); } } else if (packet instanceof Presence) { rejectPacket = new Presence(); rejectPacket.setTo(packet.getFrom()); rejectPacket.setError(PacketError.Condition.forbidden); } else if (packet instanceof IQ) { rejectPacket = new IQ(); rejectPacket.setTo(packet.getFrom()); rejectPacket.setError(PacketError.Condition.forbidden); } if (doLog()) { Log.info("Rejecting packet from " + packet.getFrom() + " to " + packet.getTo()); } throw new PacketRejectedException(); }
@Override boolean canProcess(Packet packet) { String senderDomain = packet.getFrom().getDomain(); if (!getAuthenticatedDomains().contains(senderDomain)) { synchronized (senderDomain.intern()) { if (!getAuthenticatedDomains().contains(senderDomain) && !authenticateSubdomain(senderDomain, packet.getTo().getDomain())) { // Return error since sender domain was not validated by remote server LocalSession.returnErrorToSender(packet); return false; } } } return true; }
public void process(Packet packet) throws ComponentException { logger.debug("Packet payload " + packet.toXML() + " going to federation."); String to = packet.getTo().toString(); String uniqueId = generateUniqueId(packet); idMap.put(uniqueId, packet.getID()); packet.setID(uniqueId); sentRemotePackets.put(uniqueId, packet.getFrom()); try { extractNodeDetails(packet); // Do we have a map already? if (discoveredServers.containsKey(to)) { packet.setTo(new JID(discoveredServers.get(to))); sendPacket(packet.createCopy()); return; } // Are we already discovering a remote server? if (!remoteChannelDiscoveryStatus.containsKey(to)) { discoverRemoteChannelServer(to, packet.getID()); } else if (remoteChannelDiscoveryStatus.get(to).equals(NO_CHANNEL_SERVER)) { logger.error("No remote channel server for " + to); IQ reply = IQ.createResultIQ((IQ) packet); reply.setError( new PacketError( PacketError.Condition.remote_server_not_found, PacketError.Type.cancel)); component.sendPacket(reply); return; } // Add packet to list if (!waitingStanzas.containsKey(to)) { waitingStanzas.put(to, new ArrayList<Packet>()); } waitingStanzas.get(to).add(packet); logger.debug( "Adding packet to waiting stanza list for " + to + " (size " + waitingStanzas.get(to).size() + ")"); } catch (Exception e) { logger.error(e); } }
/** * Returns true if the specified packet must be blocked based on this privacy list rules. Rules * are going to be analyzed based on their order (in ascending order). When a rule is matched then * communication will be blocked or allowed based on that rule. No more further analysis is going * to be made. * * @param packet the packet to analyze if it must be blocked. * @return true if the specified packet must be blocked based on this privacy list rules. */ public boolean shouldBlockPacket(Packet packet) { if (packet.getFrom() == null) { // Sender is the server so it's not denied return false; } // Iterate over the rules and check each rule condition Roster roster = getRoster(); for (PrivacyItem item : items) { if (item.matchesCondition(packet, roster, userJID)) { if (item.isAllow()) { return false; } if (Log.isDebugEnabled()) { Log.debug("PrivacyList: Packet was blocked: " + packet); } return true; } } // If no rule blocked the communication then allow the packet to flow return false; }
/** * Generate a unique ID for a packet * * <p>Supplied packet IDs might not be unique so we use the ID and the FROM values to create a * hash which we map back to the original packet ID. * * @param packet * @return unique ID for the packet */ private String generateUniqueId(Packet packet) { return generateMd5(packet.getID() + packet.getFrom()); }