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

📄 saslauthentication.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                                sendChallenge(session, challenge);
                                status = Status.needResponse;
                            }
                            session.setSessionData("SaslServer", ss);
                        }
                        catch (SaslException e) {
                            Log.warn("SaslException", e);
                            authenticationFailed(session);
                            status = Status.failed;
                        }
                    }
                    else {
                        Log.warn("Client wants to do a MECH we don't support: '" +
                                mechanism + "'");
                        authenticationFailed(session);
                        status = Status.failed;
                    }
                    break;
                case RESPONSE:
                    // Store the requested SASL mechanism by the client
                    mechanism = (String) session.getSessionData("SaslMechanism");
                    if (mechanism.equalsIgnoreCase("EXTERNAL")) {
                        status = doExternalAuthentication(session, doc);
                    }
                    else if (mechanism.equalsIgnoreCase("JIVE-SHAREDSECRET")) {
                        status = doSharedSecretAuthentication(session, doc);
                    }
                    else if (mechanisms.contains(mechanism)) {
                        SaslServer ss = (SaslServer) session.getSessionData("SaslServer");
                        if (ss != null) {
                            boolean ssComplete = ss.isComplete();
                            String response = doc.getTextTrim();
                            try {
                                if (ssComplete) {
                                    authenticationSuccessful(session, ss.getAuthorizationID(),
                                            null);
                                    status = Status.authenticated;
                                }
                                else {
                                    byte[] data = StringUtils.decodeBase64(response);
                                    if (data == null) {
                                        data = new byte[0];
                                    }
                                    byte[] challenge = ss.evaluateResponse(data);
                                    if (ss.isComplete()) {
                                        authenticationSuccessful(session, ss.getAuthorizationID(),
                                                challenge);
                                        status = Status.authenticated;
                                    }
                                    else {
                                        // Send the challenge
                                        sendChallenge(session, challenge);
                                        status = Status.needResponse;
                                    }
                                }
                            }
                            catch (SaslException e) {
                                Log.debug("SASLAuthentication: SaslException", e);
                                authenticationFailed(session);
                                status = Status.failed;
                            }
                        }
                        else {
                            Log.fatal("SaslServer is null, should be valid object instead.");
                            authenticationFailed(session);
                            status = Status.failed;
                        }
                    }
                    else {
                        Log.warn(
                                "Client responded to a MECH we don't support: '" + mechanism + "'");
                        authenticationFailed(session);
                        status = Status.failed;
                    }
                    break;
                default:
                    authenticationFailed(session);
                    status = Status.failed;
                    // Ignore
                    break;
            }
        }
        else {
            Log.debug("SASLAuthentication: Unknown namespace sent in auth element: " + doc.asXML());
            authenticationFailed(session);
            status = Status.failed;
        }
        // Check if SASL authentication has finished so we can clean up temp information
        if (status == Status.failed || status == Status.authenticated) {
            // Remove the SaslServer from the Session
            session.removeSessionData("SaslServer");
            // Remove the requested SASL mechanism by the client
            session.removeSessionData("SaslMechanism");
        }
        return status;
    }

    /**
     * Returns true if shared secret authentication is enabled. Shared secret
     * authentication creates an anonymous session, but requires that the authenticating
     * entity know a shared secret key. The client sends a digest of the secret key,
     * which is compared against a digest of the local shared key.
     *
     * @return true if shared secret authentication is enabled.
     */
    public static boolean isSharedSecretAllowed() {
        return JiveGlobals.getBooleanProperty("xmpp.auth.sharedSecretEnabled");
    }

    /**
     * Sets whether shared secret authentication is enabled. Shared secret
     * authentication creates an anonymous session, but requires that the authenticating
     * entity know a shared secret key. The client sends a digest of the secret key,
     * which is compared against a digest of the local shared key.
     *
     * @param sharedSecretAllowed true if shared secret authentication should be enabled.
     */
    public static void setSharedSecretAllowed(boolean sharedSecretAllowed) {
        JiveGlobals.setProperty("xmpp.auth.sharedSecretEnabled", sharedSecretAllowed ? "true" : "false");
    }

    /**
     * Returns the shared secret value, or <tt>null</tt> if shared secret authentication is
     * disabled. If this is the first time the shared secret value has been requested (and
     * shared secret auth is enabled), the key will be randomly generated and stored in the
     * property <tt>xmpp.auth.sharedSecret</tt>.
     *
     * @return the shared secret value.
     */
    public static String getSharedSecret() {
        if (!isSharedSecretAllowed()) {
            return null;
        }
        String sharedSecret = JiveGlobals.getProperty("xmpp.auth.sharedSecret");
        if (sharedSecret == null) {
            sharedSecret = StringUtils.randomString(8);
            JiveGlobals.setProperty("xmpp.auth.sharedSecret", sharedSecret);
        }
        return sharedSecret;
    }

    /**
     * Returns true if the supplied digest matches the shared secret value. The digest
     * must be an MD5 hash of the secret key, encoded as hex. This value is supplied
     * by clients attempting shared secret authentication.
     *
     * @param digest the MD5 hash of the secret key, encoded as hex.
     * @return true if authentication succeeds.
     */
    public static boolean authenticateSharedSecret(String digest) {
        if (!isSharedSecretAllowed()) {
            return false;
        }
        String sharedSecert = getSharedSecret();
        return StringUtils.hash(sharedSecert).equals(digest);
    }


    private static Status doAnonymousAuthentication(LocalSession session) {
        if (XMPPServer.getInstance().getIQAuthHandler().isAnonymousAllowed()) {
            // Just accept the authentication :)
            authenticationSuccessful(session, null, null);
            return Status.authenticated;
        }
        else {
            // anonymous login is disabled so close the connection
            authenticationFailed(session);
            return Status.failed;
        }
    }

    private static Status doExternalAuthentication(LocalSession session, Element doc)
            throws UnsupportedEncodingException {
        // At this point the connection has already been secured using TLS

        if (session instanceof IncomingServerSession) {

            String hostname = doc.getTextTrim();
            if (hostname == null || hostname.length() == 0) {
                // No hostname was provided so send a challenge to get it
                sendChallenge(session, new byte[0]);
                return Status.needResponse;
            }
    
            hostname = new String(StringUtils.decodeBase64(hostname), CHARSET);
            // Check if cerificate validation is disabled for s2s
            // Flag that indicates if certificates of the remote server should be validated.
            // Disabling certificate validation is not recommended for production environments.
            boolean verify =
                    JiveGlobals.getBooleanProperty("xmpp.server.certificate.verify", true);
            if (!verify) {
                authenticationSuccessful(session, hostname, null);
                return Status.authenticated;
            }
            // Check that hostname matches the one provided in a certificate
            SocketConnection connection = (SocketConnection) session.getConnection();
            try {
                for (Certificate certificate : connection.getSSLSession().getPeerCertificates()) {
                    for (String identity : CertificateManager.getPeerIdentities((X509Certificate) certificate)) {
                        if (identity.equals(hostname) || identity.equals("*." + hostname)) {
                            authenticationSuccessful(session, hostname, null);
                            return Status.authenticated;
                        }
                    }
                }
            }
            catch (SSLPeerUnverifiedException e) {
                Log.warn("Error retrieving client certificates of: " + session, e);
            }
        }
        else if (session instanceof LocalClientSession) {
            // Client EXTERNALL login
            Log.debug("SASLAuthentication: EXTERNAL authentication via SSL certs for c2s connection");
            
            // This may be null, we will deal with that later
            String username = new String(StringUtils.decodeBase64(doc.getTextTrim()), CHARSET); 
            String principal = "";
            ArrayList<String> principals = new ArrayList<String>();
            Connection connection = session.getConnection();
            if (connection.getSSLSession() == null) {
                Log.debug("SASLAuthentication: EXTERNAL authentication requested, but no SSL/TLS connection found.");
                authenticationFailed(session);
                return Status.failed; 
            }
            try {
                for (Certificate certificate : connection.getSSLSession().getPeerCertificates()) {
                    principals.addAll(CertificateManager.getPeerIdentities((X509Certificate)certificate));
                }
            }
            catch (SSLPeerUnverifiedException e) {
                Log.warn("Error retrieving client certificates of: " + session, e);
            }


            principal = principals.get(0);

            if (username == null || username.length() == 0) {
                // No username was provided, according to XEP-0178 we need to:

⌨️ 快捷键说明

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