Search in sources :

Example 1 with LocalClientSession

use of org.jivesoftware.openfire.session.LocalClientSession 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 2 with LocalClientSession

use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.

the class MultiplexerPacketHandler method route.

/**
     * Processes a route packet that is wrapping a stanza sent by a client that is connected
     * to the connection manager.
     *
     * @param route the route packet.
     */
public void route(Route route) {
    StreamID streamID = route.getStreamID();
    if (streamID == null) {
        // No stream ID was included so return a bad_request error
        Element extraError = DocumentHelper.createElement(QName.get("id-required", "http://jabber.org/protocol/connectionmanager#errors"));
        sendErrorPacket(route, PacketError.Condition.bad_request, extraError);
    }
    LocalClientSession session = multiplexerManager.getClientSession(connectionManagerDomain, streamID);
    if (session == null) {
        // Specified Client Session does not exist
        sendErrorPacket(route, PacketError.Condition.item_not_found, null);
        return;
    }
    SessionPacketRouter router = new SessionPacketRouter(session);
    // Connection Manager already validate JIDs so just skip this expensive operation
    router.setSkipJIDValidation(true);
    try {
        router.route(route.getChildElement());
    } catch (UnknownStanzaException use) {
        Element extraError = DocumentHelper.createElement(QName.get("unknown-stanza", "http://jabber.org/protocol/connectionmanager#errors"));
        sendErrorPacket(route, PacketError.Condition.bad_request, extraError);
    } catch (Exception e) {
        Log.error("Error processing wrapped packet: " + route.getChildElement().asXML(), e);
        sendErrorPacket(route, PacketError.Condition.internal_server_error, null);
    }
}
Also used : LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) StreamID(org.jivesoftware.openfire.StreamID) Element(org.dom4j.Element) SessionPacketRouter(org.jivesoftware.openfire.SessionPacketRouter)

Example 3 with LocalClientSession

use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.

the class SessionManager method createClientSession.

/**
     * Creates a new <tt>ClientSession</tt> with the specified streamID.
     *
     * @param conn the connection to create the session from.
     * @param id the streamID to use for the new session.
     * @param language The language to use for the new session.
     * @return a newly created session.
     */
public LocalClientSession createClientSession(Connection conn, StreamID id, Locale language) {
    if (serverName == null) {
        throw new IllegalStateException("Server not initialized");
    }
    LocalClientSession session = new LocalClientSession(serverName, conn, id, language);
    conn.init(session);
    // Register to receive close notification on this session so we can
    // remove  and also send an unavailable presence if it wasn't
    // sent before
    conn.registerCloseListener(clientSessionListener, session);
    // Add to pre-authenticated sessions.
    localSessionManager.getPreAuthenticatedSessions().put(session.getAddress().getResource(), session);
    // Increment the counter of user sessions
    connectionsCounter.incrementAndGet();
    return session;
}
Also used : LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession)

Example 4 with LocalClientSession

use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.

the class SessionManager method broadcastPresenceOfOtherResource.

/**
     * Sends the presences of other connected resources to the resource that just connected.
     *
     * @param session the newly created session.
     */
private void broadcastPresenceOfOtherResource(LocalClientSession session) {
    if (!SessionManager.isOtherResourcePresenceEnabled()) {
        return;
    }
    Presence presence;
    // Get list of sessions of the same user
    JID searchJID = new JID(session.getAddress().getNode(), session.getAddress().getDomain(), null);
    List<JID> addresses = routingTable.getRoutes(searchJID, null);
    for (JID address : addresses) {
        if (address.equals(session.getAddress())) {
            continue;
        }
        // Send the presence of an existing session to the session that has just changed
        // the presence
        ClientSession userSession = routingTable.getClientRoute(address);
        presence = userSession.getPresence().createCopy();
        presence.setTo(session.getAddress());
        session.process(presence);
    }
}
Also used : JID(org.xmpp.packet.JID) LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) ClientSession(org.jivesoftware.openfire.session.ClientSession) Presence(org.xmpp.packet.Presence)

Example 5 with LocalClientSession

use of org.jivesoftware.openfire.session.LocalClientSession in project Openfire by igniterealtime.

the class SaslServerFactoryImpl method createSaslServer.

@Override
public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map<String, ?> props, CallbackHandler cbh) throws SaslException {
    if (!Arrays.asList(getMechanismNames(props)).contains(mechanism)) {
        Log.debug("This implementation is unable to create a SaslServer instance for the {} mechanism using the provided properties.", mechanism);
        return null;
    }
    switch(mechanism.toUpperCase()) {
        case "PLAIN":
            if (cbh == null) {
                Log.debug("Unable to instantiate {} SaslServer: A callbackHandler with support for Password, Name, and AuthorizeCallback required.", mechanism);
                return null;
            }
            return new SaslServerPlainImpl(protocol, serverName, props, cbh);
        case "SCRAM-SHA-1":
            return new ScramSha1SaslServer();
        case "ANONYMOUS":
            if (!props.containsKey(LocalSession.class.getCanonicalName())) {
                Log.debug("Unable to instantiate {} SaslServer: Provided properties do not contain a LocalSession instance.", mechanism);
                return null;
            } else {
                final LocalSession session = (LocalSession) props.get(LocalSession.class.getCanonicalName());
                return new AnonymousSaslServer(session);
            }
        case "EXTERNAL":
            if (!props.containsKey(LocalSession.class.getCanonicalName())) {
                Log.debug("Unable to instantiate {} SaslServer: Provided properties do not contain a LocalSession instance.", mechanism);
                return null;
            } else {
                final Object session = props.get(LocalSession.class.getCanonicalName());
                if (session instanceof LocalClientSession) {
                    return new ExternalClientSaslServer((LocalClientSession) session);
                }
                if (session instanceof LocalIncomingServerSession) {
                    return new ExternalServerSaslServer((LocalIncomingServerSession) session);
                }
                Log.debug("Unable to instantiate {} Sasl Server: Provided properties contains neither LocalClientSession nor LocalIncomingServerSession instance.", mechanism);
                return null;
            }
        case JiveSharedSecretSaslServer.NAME:
            return new JiveSharedSecretSaslServer();
        default:
            // Fail fast - this should not be possible, as the first check in this method already verifies wether the mechanism is supported.
            throw new IllegalStateException();
    }
}
Also used : LocalClientSession(org.jivesoftware.openfire.session.LocalClientSession) LocalIncomingServerSession(org.jivesoftware.openfire.session.LocalIncomingServerSession) LocalSession(org.jivesoftware.openfire.session.LocalSession)

Aggregations

LocalClientSession (org.jivesoftware.openfire.session.LocalClientSession)14 ClientSession (org.jivesoftware.openfire.session.ClientSession)7 JID (org.xmpp.packet.JID)6 Element (org.dom4j.Element)4 StreamID (org.jivesoftware.openfire.StreamID)4 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)3 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)3 IQ (org.xmpp.packet.IQ)3 StringprepException (gnu.inet.encoding.StringprepException)2 UnknownHostException (java.net.UnknownHostException)2 AuthToken (org.jivesoftware.openfire.auth.AuthToken)2 ConnectionException (org.jivesoftware.openfire.auth.ConnectionException)2 InternalUnauthenticatedException (org.jivesoftware.openfire.auth.InternalUnauthenticatedException)2 PacketRejectedException (org.jivesoftware.openfire.interceptor.PacketRejectedException)2 Message (org.xmpp.packet.Message)2 Presence (org.xmpp.packet.Presence)2 StreamError (org.xmpp.packet.StreamError)2 ArrayList (java.util.ArrayList)1 Connection (org.jivesoftware.openfire.Connection)1 PacketException (org.jivesoftware.openfire.PacketException)1