Search in sources :

Example 6 with PacketRejectedException

use of org.jivesoftware.openfire.interceptor.PacketRejectedException in project Openfire by igniterealtime.

the class MessageRouter method route.

/**
 * <p>Performs the actual packet routing.</p>
 * <p>You routing is considered 'quick' and implementations may not take
 * excessive amounts of time to complete the routing. If routing will take
 * a long amount of time, the actual routing should be done in another thread
 * so this method returns quickly.</p>
 * <h2>Warning</h2>
 * <p>Be careful to enforce concurrency DbC of concurrent by synchronizing
 * any accesses to class resources.</p>
 *
 * @param packet The packet to route
 * @throws NullPointerException If the packet is null
 */
public void route(Message packet) {
    if (packet == null) {
        throw new NullPointerException();
    }
    ClientSession session = sessionManager.getSession(packet.getFrom());
    try {
        // Invoke the interceptors before we process the read packet
        InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
        if (session == null || session.getStatus() == Session.STATUS_AUTHENTICATED) {
            JID recipientJID = packet.getTo();
            // If the server receives a message stanza with no 'to' attribute, it MUST treat the message as if the 'to' address were the bare JID <localpart@domainpart> of the sending entity.
            if (recipientJID == null) {
                recipientJID = packet.getFrom().asBareJID();
            }
            // Check if the message was sent to the server hostname
            if (recipientJID.getNode() == null && recipientJID.getResource() == null && serverName.equals(recipientJID.getDomain())) {
                if (packet.getElement().element("addresses") != null) {
                    // Message includes multicast processing instructions. Ask the multicastRouter
                    // to route this packet
                    multicastRouter.route(packet);
                } else {
                    // Message was sent to the server hostname so forward it to a configurable
                    // set of JID's (probably admin users)
                    sendMessageToAdmins(packet);
                }
                return;
            }
            boolean isAcceptable = true;
            if (session instanceof LocalClientSession) {
                // Check if we could process messages from the recipient.
                // If not, return a not-acceptable error as per XEP-0016:
                // If the user attempts to send an outbound stanza to a contact and that stanza type is blocked, the user's server MUST NOT route the stanza to the contact but instead MUST return a <not-acceptable/> error
                Message dummyMessage = packet.createCopy();
                dummyMessage.setFrom(packet.getTo());
                dummyMessage.setTo(packet.getFrom());
                if (!((LocalClientSession) session).canProcess(dummyMessage)) {
                    packet.setTo(session.getAddress());
                    packet.setFrom((JID) null);
                    packet.setError(PacketError.Condition.not_acceptable);
                    session.process(packet);
                    isAcceptable = false;
                }
            }
            if (isAcceptable) {
                boolean isPrivate = packet.getElement().element(QName.get("private", "urn:xmpp:carbons:2")) != null;
                try {
                    // Deliver stanza to requested route
                    routingTable.routePacket(recipientJID, packet, false);
                } catch (Exception e) {
                    log.error("Failed to route packet: " + packet.toXML(), e);
                    routingFailed(recipientJID, packet);
                }
                // When a client sends a <message/> of type "chat"
                if (packet.getType() == Message.Type.chat && !isPrivate && session != null) {
                    // && session.isMessageCarbonsEnabled() ??? // must the own session also be carbon enabled?
                    List<JID> routes = routingTable.getRoutes(packet.getFrom().asBareJID(), null);
                    for (JID route : routes) {
                        // The sending server SHOULD NOT send a forwarded copy to the sending full JID if it is a Carbons-enabled resource.
                        if (!route.equals(session.getAddress())) {
                            ClientSession clientSession = sessionManager.getSession(route);
                            if (clientSession != null && clientSession.isMessageCarbonsEnabled()) {
                                Message message = new Message();
                                // The wrapping message SHOULD maintain the same 'type' attribute value
                                message.setType(packet.getType());
                                // the 'from' attribute MUST be the Carbons-enabled user's bare JID
                                message.setFrom(packet.getFrom().asBareJID());
                                // and the 'to' attribute SHOULD be the full JID of the resource receiving the copy
                                message.setTo(route);
                                // The content of the wrapping message MUST contain a <sent/> element qualified by the namespace "urn:xmpp:carbons:2", which itself contains a <forwarded/> qualified by the namespace "urn:xmpp:forward:0" that contains the original <message/> stanza.
                                message.addExtension(new Sent(new Forwarded(packet)));
                                clientSession.process(message);
                            }
                        }
                    }
                }
            }
        } else {
            packet.setTo(session.getAddress());
            packet.setFrom((JID) null);
            packet.setError(PacketError.Condition.not_authorized);
            session.process(packet);
        }
        // Invoke the interceptors after we have processed the read packet
        InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
    } catch (PacketRejectedException e) {
        // An interceptor rejected this packet
        if (session != null && e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
            // A message for the rejection will be sent to the sender of the rejected packet
            Message reply = new Message();
            reply.setID(packet.getID());
            reply.setTo(session.getAddress());
            reply.setFrom(packet.getTo());
            reply.setType(packet.getType());
            reply.setThread(packet.getThread());
            reply.setBody(e.getRejectionMessage());
            session.process(reply);
        }
    }
}
Also used : LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) JID(org.xmpp.packet.JID) Message(org.xmpp.packet.Message) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) ClientSession(org.jivesoftware.openfire.session.ClientSession) Forwarded(org.jivesoftware.openfire.forward.Forwarded) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException) Sent(org.jivesoftware.openfire.carbons.Sent)

Example 7 with PacketRejectedException

use of org.jivesoftware.openfire.interceptor.PacketRejectedException in project Openfire by igniterealtime.

the class PresenceRouter method route.

/**
 * Routes presence packets.
 *
 * @param packet the packet to route.
 * @throws NullPointerException if the packet is null.
 */
public void route(Presence packet) {
    if (packet == null) {
        throw new NullPointerException();
    }
    ClientSession session = sessionManager.getSession(packet.getFrom());
    try {
        // Invoke the interceptors before we process the read packet
        InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
        if (session == null || session.getStatus() != Session.STATUS_CONNECTED) {
            handle(packet);
        } else {
            packet.setTo(session.getAddress());
            packet.setFrom((JID) null);
            packet.setError(PacketError.Condition.not_authorized);
            session.process(packet);
        }
        // Invoke the interceptors after we have processed the read packet
        InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
    } catch (PacketRejectedException e) {
        if (session != null) {
            // An interceptor rejected this packet so answer a not_allowed error
            Presence reply = new Presence();
            reply.setID(packet.getID());
            reply.setTo(session.getAddress());
            reply.setFrom(packet.getTo());
            reply.setError(PacketError.Condition.not_allowed);
            session.process(reply);
            // Check if a message notifying the rejection should be sent
            if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
                // A message for the rejection will be sent to the sender of the rejected packet
                Message notification = new Message();
                notification.setTo(session.getAddress());
                notification.setFrom(packet.getTo());
                notification.setBody(e.getRejectionMessage());
                session.process(notification);
            }
        }
    }
}
Also used : ClientSession(org.jivesoftware.openfire.session.ClientSession) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException)

Example 8 with PacketRejectedException

use of org.jivesoftware.openfire.interceptor.PacketRejectedException in project Openfire by igniterealtime.

the class ServerSocketReader method packetReceived.

/**
 * 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 (!((LocalIncomingServerSession) 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");
    }
}
Also used : LocalIncomingServerSession(org.jivesoftware.openfire.session.LocalIncomingServerSession) StreamError(org.xmpp.packet.StreamError) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException)

Example 9 with PacketRejectedException

use of org.jivesoftware.openfire.interceptor.PacketRejectedException in project Openfire by igniterealtime.

the class CallbackOnOffline method interceptPacket.

public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
    if (processed && incoming && packet instanceof Message && packet.getTo() != null) {
        Message msg = (Message) packet;
        if (msg.getType() != Message.Type.chat) {
            return;
        }
        try {
            JID to = packet.getTo();
            User userTo = userManager.getUser(to.getNode());
            boolean available = presenceManager.isAvailable(userTo);
            if (debug) {
                Log.debug("intercepted message from {} to {}, recipient is available {}", packet.getFrom().toBareJID(), to.toBareJID(), available);
            }
            if (!available) {
                JID from = packet.getFrom();
                WebTarget target = client.target(url).queryParam("token", token).queryParam("from", from.toBareJID()).queryParam("to", to.toBareJID());
                if (debug) {
                    Log.debug("sending request to url='{}'", target);
                }
                Future<Response> responseFuture = target.request().async().get();
                if (debug) {
                    try {
                        Response response = responseFuture.get();
                        Log.debug("got response status url='{}' status='{}'", target, response.getStatus());
                    } catch (Exception e) {
                        Log.debug("can't get response status url='{}'", target, e);
                    }
                }
            }
        } catch (UserNotFoundException e) {
        }
    }
}
Also used : Response(javax.ws.rs.core.Response) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) User(org.jivesoftware.openfire.user.User) Message(org.xmpp.packet.Message) JID(org.xmpp.packet.JID) WebTarget(javax.ws.rs.client.WebTarget) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException)

Example 10 with PacketRejectedException

use of org.jivesoftware.openfire.interceptor.PacketRejectedException in project Openfire by igniterealtime.

the class MainInterceptor method interceptPacket.

/**
	 * This Interceptor tests if GoJara needs to process this package. We decided to do one global Interceptor so we
	 * would'nt redundantly test for cases we already checked in previous Interceptors, also we have only one big ugly
	 * If Structure to maintain instead of several.
	 * 
	 * @see org.jivesoftware.openfire.interceptor.PacketInterceptor#interceptPacket (org.xmpp.packet.Packet,
	 *      org.jivesoftware.openfire.session.Session, boolean, boolean)
	 */
public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
    if (frozen)
        return;
    String from = "";
    String to = "";
    if (!processed || (incoming && processed)) {
        try {
            if (packet.getFrom() != null)
                from = packet.getFrom().toString();
            if (packet.getTo() != null)
                to = packet.getTo().toString();
        } catch (IllegalArgumentException e) {
            Log.debug("There was an illegal JID while intercepting Message for GoJara. Not Intercepting it! " + e.getMessage());
            return;
        }
    }
    if (incoming && !processed) {
        if (packet instanceof IQ) {
            IQ iqPacket = (IQ) packet;
            Element query = iqPacket.getChildElement();
            if (query == null)
                return;
            else // Jabber:IQ:roster Indicates Client to Component update or Rosterpush
            if (query.getNamespaceURI().equals("jabber:iq:roster")) {
                if (!activeTransports.contains(from) && to.length() == 0 && iqPacket.getType().equals(IQ.Type.set))
                    packetProcessors.get("clientToComponentUpdate").process(packet, "", to, from);
                else if (from.length() > 0 && activeTransports.contains(from))
                    packetProcessors.get("iqRosterPayload").process(packet, from, to, from);
            } else // SPARK IQ REGISTERED Feature
            if (query.getNamespaceURI().equals("http://jabber.org/protocol/disco#info") && to.length() > 0 && activeTransports.contains(to) && iqPacket.getType().equals(IQ.Type.get)) {
                packetProcessors.get("sparkIQRegistered").process(packet, to, to, from);
            } else // JABBER:IQ:LAST - Autoresponse Feature
            if (JiveGlobals.getBooleanProperty("plugin.remoteroster.iqLastFilter", false) && query.getNamespaceURI().equals("jabber:iq:last")) {
                String to_s = searchJIDforSubdomain(to);
                if (to_s.length() > 0 && iqPacket.getType().equals(IQ.Type.get))
                    throw new PacketRejectedException();
            }
        } else // Gojara Admin Manager Feature - Intercept responses to ADHOC commands sent via AdminManager
        if (packet instanceof Message && activeTransports.contains(from) && to.contains("gojaraadmin")) {
            packetProcessors.get("gojaraAdminProcessor").process(packet, from, to, from);
        } else // NONPERSISTANT Feature
        {
            if (!JiveGlobals.getBooleanProperty("plugin.remoteroster.persistent", false)) {
                if (packet instanceof Presence && activeTransports.contains(from))
                    packetProcessors.get("handleNonPersistant").process(packet, from, to, from);
            }
        }
    } else if (incoming && processed) {
        // We ignore Pings from S2 to S2 itself.
        // STATISTICS - Feature
        String from_searched = searchJIDforSubdomain(from);
        String to_searched = searchJIDforSubdomain(to);
        String subdomain = from_searched.length() == 0 ? to_searched : from_searched;
        if (!from.equals(to) && subdomain.length() > 0)
            packetProcessors.get("statisticsProcessor").process(packet, subdomain, to, from);
        // TransportSession Feature
        if (packet instanceof Presence && activeTransports.contains(from)) {
            Presence presence_packet = (Presence) packet;
            if (presence_packet.getType() == null) {
                tSessionManager.connectUserTo(from, packet.getTo().getNode().toString());
            } else if (presence_packet.getType() != null && presence_packet.getType().equals(Presence.Type.unavailable)) {
                tSessionManager.disconnectUserFrom(from, packet.getTo().getNode().toString());
            }
        } else // TransportSession Feature - track Registrations and unregistrations so we can reset unsuccesfull ones
        if (packet instanceof IQ && activeTransports.contains(to)) {
            IQ iqPacket = (IQ) packet;
            Element query = iqPacket.getChildElement();
            if (query == null)
                return;
            /*
				 * Okay, so now we have a IQ Packet with a query xmlns: jabber:iq:register Spark sends registrations and
				 * unregistrations in such a query, register has a x xmls jabber:iq:gateway:register, unregister is just
				 * a <remove/> element Gajim sends the whole form with x xmlns jabber:x:data type="submit", where a
				 * field var=unregister value of 0 is a registration, and unregister = 1 is unregistration
				 */
            if (query.getNamespaceURI().equals("jabber:iq:register") && iqPacket.getType().equals(IQ.Type.set)) {
                // spark + gajim unregister
                if (query.element("remove") != null)
                    tSessionManager.removeRegistrationOfUserFromDB(to, iqPacket.getFrom().getNode().toString());
                else if (query.element("x") != null) {
                    Element xElem = query.element("x");
                    String xNamespace = xElem.getNamespaceURI();
                    // spark register
                    if (xNamespace.equals("jabber:iq:gateway:register"))
                        tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString());
                    else // Gajim register + presence push
                    if (xNamespace.equals("jabber:x:data") && xElem.attribute("type").getText().equals("submit")) {
                        tSessionManager.registerUserTo(to, iqPacket.getFrom().getNode().toString());
                        presencePush(packet.getTo(), packet.getFrom(), 150);
                    }
                }
            }
        }
    } else if (!incoming && !processed) {
        if (packet instanceof IQ) {
            IQ iqPacket = (IQ) packet;
            Element query = iqPacket.getChildElement();
            if (query == null)
                return;
            // DISCO#ITEMS - Whitelisting Feature
            if (query.getNamespaceURI().equals("http://jabber.org/protocol/disco#items"))
                packetProcessors.get("whitelistProcessor").process(packet, "", to, from);
            else // DISCO#INFO - MUC-Filter-Feature
            if (JiveGlobals.getBooleanProperty("plugin.remoteroster.mucFilter", false) && query.getNamespaceURI().equals("http://jabber.org/protocol/disco#info") && from.length() > 0 && activeTransports.contains(from))
                packetProcessors.get("mucfilterProcessor").process(packet, from, to, from);
            else // pushed by OF anyways
            if (JiveGlobals.getBooleanProperty("plugin.remoteroster.gajimBroadcast", false)) {
                if (to.contains("Gajim") && query.getNamespaceURI().equals("jabber:iq:roster") && iqPacket.getType().equals(IQ.Type.result)) {
                    List<Node> nodes = XpathHelper.findNodesInDocument(iqPacket.getElement().getDocument(), "//roster:item");
                    for (Node n : nodes) {
                        String jid = n.valueOf("@jid");
                        if (activeTransports.contains(jid)) {
                            JID pushTo = new JID(jid);
                            presencePush(pushTo, iqPacket.getTo(), 3000);
                        }
                    }
                }
            }
        } else if (JiveGlobals.getBooleanProperty("plugin.remoteroster.blockPresences", true) && packet instanceof Presence) {
            /*
				 * We block Presences to users of a subdomain (except transport itself) so OF/S2 wont log you in
				 * automatically if you have a subdomain user in your roster. This prevents some clients from logging
				 * automatically, as the clients dont send a specific presence to the transport. We could do a presence
				 * push if we see them come online, but that would do the same as just not intercepting these presences,
				 * as the problem is really the client
				 */
            String to_s = searchJIDforSubdomain(to);
            if (to_s.length() > 0 && !activeTransports.contains(to))
                throw new PacketRejectedException();
        }
    }
}
Also used : Message(org.xmpp.packet.Message) JID(org.xmpp.packet.JID) Element(org.dom4j.Element) Node(org.dom4j.Node) IQ(org.xmpp.packet.IQ) PacketRejectedException(org.jivesoftware.openfire.interceptor.PacketRejectedException) Presence(org.xmpp.packet.Presence)

Aggregations

PacketRejectedException (org.jivesoftware.openfire.interceptor.PacketRejectedException)11 JID (org.xmpp.packet.JID)5 ClientSession (org.jivesoftware.openfire.session.ClientSession)4 IQ (org.xmpp.packet.IQ)4 Message (org.xmpp.packet.Message)4 Element (org.dom4j.Element)3 Packet (org.xmpp.packet.Packet)3 Presence (org.xmpp.packet.Presence)3 Node (org.dom4j.Node)2 Roster (org.jivesoftware.openfire.roster.Roster)2 RosterItem (org.jivesoftware.openfire.roster.RosterItem)2 LocalClientSession (org.jivesoftware.openfire.session.LocalClientSession)2 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)2 ArrayList (java.util.ArrayList)1 Timer (java.util.Timer)1 TimerTask (java.util.TimerTask)1 WebTarget (javax.ws.rs.client.WebTarget)1 Response (javax.ws.rs.core.Response)1 Attribute (org.dom4j.Attribute)1 DefaultAttribute (org.dom4j.tree.DefaultAttribute)1