⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 localclientsession.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * $RCSfile$
 * $Revision: 3187 $
 * $Date: 2005-12-11 13:34:34 -0300 (Sun, 11 Dec 2005) $
 *
 * Copyright (C) 2008 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution, or a commercial license
 * agreement with Jive.
 */

package org.jivesoftware.openfire.session;

import org.jivesoftware.openfire.Connection;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.StreamID;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.AuthToken;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.net.SSLConfig;
import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.privacy.PrivacyList;
import org.jivesoftware.openfire.privacy.PrivacyListManager;
import org.jivesoftware.openfire.user.PresenceEventDispatcher;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.cache.Cache;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
import org.xmpp.packet.StreamError;

import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Represents a session between the server and a client.
 *
 * @author Gaston Dombiak
 */
public class LocalClientSession extends LocalSession implements ClientSession {

    private static final String ETHERX_NAMESPACE = "http://etherx.jabber.org/streams";
    private static final String FLASH_NAMESPACE = "http://www.jabber.com/streams/flash";

    /**
     * Keep the list of IP address that are allowed to connect to the server. If the list is
     * empty then anyone is allowed to connect to the server.<p>
     *
     * Note: Key = IP address or IP range; Value = empty string. A hash map is being used for
     * performance reasons.
     */
    private static Map<String,String> allowedIPs = new HashMap<String,String>();

    /**
     * The authentication token for this session.
     */
    protected AuthToken authToken;

    /**
     * Flag indicating if this session has been initialized yet (upon first available transition).
     */
    private boolean initialized;

    /**
     * Flag that indicates if the session was available ever.
     */
    private boolean wasAvailable = false;

    /**
     * Flag indicating if the user requested to not receive offline messages when sending
     * an available presence. The user may send a disco request with node
     * "http://jabber.org/protocol/offline" so that no offline messages are sent to the
     * user when he becomes online. If the user is connected from many resources then
     * if one of the sessions stopped the flooding then no session should flood the user.
     */
    private boolean offlineFloodStopped = false;

    private Presence presence = null;

    private int conflictCount = 0;

    /**
     * Privacy list that overrides the default privacy list. This list affects only this
     * session and only for the duration of the session.
     */
    private String activeList;
    /**
     * Default privacy list used for the session's user. This list is processed if there
     * is no active list set for the session.
     */
    private String defaultList;

    static {
        // Fill out the allowedIPs with the system property
        String allowed = JiveGlobals.getProperty("xmpp.client.login.allowed", "");
        StringTokenizer tokens = new StringTokenizer(allowed, ", ");
        while (tokens.hasMoreTokens()) {
            String address = tokens.nextToken().trim();
            allowedIPs.put(address, "");
        }
    }

    /**
     * Returns the list of IP address that are allowed to connect to the server. If the list is
     * empty then anyone is allowed to connect to the server.
     *
     * @return the list of IP address that are allowed to connect to the server.
     */
    public static Map<String, String> getAllowedIPs() {
        return allowedIPs;
    }

    /**
     * Returns a newly created session between the server and a client. The session will
     * be created and returned only if correct name/prefix (i.e. 'stream' or 'flash')
     * and namespace were provided by the client.
     *
     * @param serverName the name of the server where the session is connecting to.
     * @param xpp the parser that is reading the provided XML through the connection.
     * @param connection the connection with the client.
     * @return a newly created session between the server and a client.
     * @throws org.xmlpull.v1.XmlPullParserException if an error occurs while parsing incoming data.
     */
    public static LocalClientSession createSession(String serverName, XmlPullParser xpp, Connection connection)
            throws XmlPullParserException {
        boolean isFlashClient = xpp.getPrefix().equals("flash");
        connection.setFlashClient(isFlashClient);

        // Conduct error checking, the opening tag should be 'stream'
        // in the 'etherx' namespace
        if (!xpp.getName().equals("stream") && !isFlashClient) {
            throw new XmlPullParserException(
                    LocaleUtils.getLocalizedString("admin.error.bad-stream"));
        }

        if (!xpp.getNamespace(xpp.getPrefix()).equals(ETHERX_NAMESPACE) &&
                !(isFlashClient && xpp.getNamespace(xpp.getPrefix()).equals(FLASH_NAMESPACE)))
        {
            throw new XmlPullParserException(LocaleUtils.getLocalizedString(
                    "admin.error.bad-namespace"));
        }

        if (!allowedIPs.isEmpty()) {
            boolean forbidAccess = false;
            String hostAddress = "Unknown";
            // The server is using a whitelist so check that the IP address of the client
            // is authorized to connect to the server
            try {
               hostAddress = connection.getHostAddress();
                if (!allowedIPs.containsKey(hostAddress)) {
                    byte[] address = connection.getAddress();
                    String range1 = (address[0] & 0xff) + "." + (address[1] & 0xff) + "." +
                            (address[2] & 0xff) +
                            ".*";
                    String range2 = (address[0] & 0xff) + "." + (address[1] & 0xff) + ".*.*";
                    String range3 = (address[0] & 0xff) + ".*.*.*";
                    if (!allowedIPs.containsKey(range1) && !allowedIPs.containsKey(range2) &&
                            !allowedIPs.containsKey(range3)) {
                        forbidAccess = true;
                    }
                }
            } catch (UnknownHostException e) {
                forbidAccess = true;
            }
            if (forbidAccess) {
                // Client cannot connect from this IP address so end the stream and
                // TCP connection
                Log.debug("LocalClientSession: Closed connection to client attempting to connect from: " + hostAddress);
                // Include the not-authorized error in the response
                StreamError error = new StreamError(StreamError.Condition.not_authorized);
                connection.deliverRawText(error.toXML());
                // Close the underlying connection
                connection.close();
                return null;
            }
        }

        // Default language is English ("en").
        String language = "en";
        // Default to a version of "0.0". Clients written before the XMPP 1.0 spec may
        // not report a version in which case "0.0" should be assumed (per rfc3920
        // section 4.4.1).
        int majorVersion = 0;
        int minorVersion = 0;
        for (int i = 0; i < xpp.getAttributeCount(); i++) {
            if ("lang".equals(xpp.getAttributeName(i))) {
                language = xpp.getAttributeValue(i);
            }
            if ("version".equals(xpp.getAttributeName(i))) {
                try {
                    int[] version = decodeVersion(xpp.getAttributeValue(i));
                    majorVersion = version[0];
                    minorVersion = version[1];
                }
                catch (Exception e) {
                    Log.error(e);
                }
            }
        }

        // If the client supports a greater major version than the server,
        // set the version to the highest one the server supports.
        if (majorVersion > MAJOR_VERSION) {
            majorVersion = MAJOR_VERSION;
            minorVersion = MINOR_VERSION;
        }
        else if (majorVersion == MAJOR_VERSION) {
            // If the client supports a greater minor version than the
            // server, set the version to the highest one that the server
            // supports.
            if (minorVersion > MINOR_VERSION) {
                minorVersion = MINOR_VERSION;
            }
        }

        // Store language and version information in the connection.
        connection.setLanaguage(language);
        connection.setXMPPVersion(majorVersion, minorVersion);

        // Indicate the TLS policy to use for this connection
        if (!connection.isSecure()) {
            boolean hasCertificates = false;
            try {
                hasCertificates = SSLConfig.getKeyStore().size() > 0;
            }
            catch (Exception e) {
                Log.error(e);
            }
            Connection.TLSPolicy tlsPolicy = getTLSPolicy();
            if (Connection.TLSPolicy.required == tlsPolicy && !hasCertificates) {
                Log.error("Client session rejected. TLS is required but no certificates " +
                        "were created.");
                return null;
            }
            // Set default TLS policy
            connection.setTlsPolicy(hasCertificates ? tlsPolicy : Connection.TLSPolicy.disabled);
        } else {
            // Set default TLS policy
            connection.setTlsPolicy(Connection.TLSPolicy.disabled);
        }

        // Indicate the compression policy to use for this connection
        connection.setCompressionPolicy(getCompressionPolicy());

        // Create a ClientSession for this user.
        LocalClientSession session = SessionManager.getInstance().createClientSession(connection);

        // Build the start packet response
        StringBuilder sb = new StringBuilder(200);
        sb.append("<?xml version='1.0' encoding='");
        sb.append(CHARSET);
        sb.append("'?>");
        if (isFlashClient) {
            sb.append("<flash:stream xmlns:flash=\"http://www.jabber.com/streams/flash\" ");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -