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

📄 saslauthentication.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                //    * attempt to get it from the cert first
                //    * have the server assign one

                // There shouldn't be more than a few principals in here. One ideally
                // We set principal to the first one in the list to have a sane default
                // If this list is empty, then the cert had no identity at all, which
                // will cause an authorization failure
                for(String princ : principals) {
                    String u = AuthorizationManager.map(princ);
                    if(!u.equals(princ)) {
                        username = u;
                        principal = princ;
                        break;
                    }
                }
                if (username == null || username.length() == 0) {
                    // Still no username.  Punt.
                    username = principal;
                }
                Log.debug("SASLAuthentication: no username requested, using "+username);
            }

            //Its possible that either/both username and principal are null here
            //The providers should not allow a null authorization
            if (AuthorizationManager.authorize(username,principal)) {
                Log.debug("SASLAuthentication: "+principal+" authorized to "+username);
                authenticationSuccessful(session, username,  null);
                return Status.authenticated;
            }
        } else {
            Log.debug("SASLAuthentication: unknown session type. Cannot perform EXTERNAL authentication");
        }
        authenticationFailed(session);
        return Status.failed;
    }

    private static Status doSharedSecretAuthentication(LocalSession session, Element doc)
            throws UnsupportedEncodingException
    {
        String secretDigest;
        String response = doc.getTextTrim();
        if (response == null || response.length() == 0) {
            // No info was provided so send a challenge to get it
            sendChallenge(session, new byte[0]);
            return Status.needResponse;
        }

        // Parse data and obtain username & password
        String data = new String(StringUtils.decodeBase64(response), CHARSET);
        StringTokenizer tokens = new StringTokenizer(data, "\0");
        tokens.nextToken();
        secretDigest = tokens.nextToken();
        if (authenticateSharedSecret(secretDigest)) {
            authenticationSuccessful(session, null, null);
            return Status.authenticated;
        }
        // Otherwise, authentication failed.
        authenticationFailed(session);
        return Status.failed;
    }

    private static void sendChallenge(Session session, byte[] challenge) {
        StringBuilder reply = new StringBuilder(250);
        if (challenge == null) {
            challenge = new byte[0];
        }
        String challenge_b64 = StringUtils.encodeBase64(challenge).trim();
        if ("".equals(challenge_b64)) {
            challenge_b64 = "="; // Must be padded if null
        }
        reply.append(
                "<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        reply.append(challenge_b64);
        reply.append("</challenge>");
        session.deliverRawText(reply.toString());
    }

    private static void authenticationSuccessful(LocalSession session, String username,
            byte[] successData) {
        if (username != null && LockOutManager.getInstance().isAccountDisabled(username)) {
            // Interception!  This person is locked out, fail instead!
            LockOutManager.getInstance().recordFailedLogin(username);
            authenticationFailed(session);
            return;
        }
        StringBuilder reply = new StringBuilder(80);
        reply.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"");
        if (successData != null) {
            String successData_b64 = StringUtils.encodeBase64(successData).trim();
            reply.append(">").append(successData_b64).append("</success>");
        }
        else {
            reply.append("/>");
        }
        session.deliverRawText(reply.toString());
        // We only support SASL for c2s
        if (session instanceof ClientSession) {
            ((LocalClientSession) session).setAuthToken(new AuthToken(username));
        }
        else if (session instanceof IncomingServerSession) {
            String hostname = username;
            // Set the first validated domain as the address of the session
            session.setAddress(new JID(null, hostname, null));
            // Add the validated domain as a valid domain. The remote server can
            // now send packets from this address
            ((LocalIncomingServerSession) session).addValidatedDomain(hostname);
        }
    }

    private static void authenticationFailed(LocalSession session) {
        StringBuilder reply = new StringBuilder(80);
        reply.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        reply.append("<not-authorized/></failure>");
        session.deliverRawText(reply.toString());
        // Give a number of retries before closing the connection
        Integer retries = (Integer) session.getSessionData("authRetries");
        if (retries == null) {
            retries = 1;
        }
        else {
            retries = retries + 1;
        }
        session.setSessionData("authRetries", retries);
        if (retries >= JiveGlobals.getIntProperty("xmpp.auth.retries", 3) ) {
            // Close the connection
            session.close();
        }
    }

    /**
     * Adds a new SASL mechanism to the list of supported SASL mechanisms by the server. The
     * new mechanism will be offered to clients and connection managers as stream features.<p>
     *
     * Note: this method simply registers the SASL mechanism to be advertised as a supported
     * mechanism by Openfire. Actual SASL handling is done by Java itself, so you must add
     * the provider to Java.
     *
     * @param mechanism the new SASL mechanism.
     */
    public static void addSupportedMechanism(String mechanism) {
        mechanisms.add(mechanism);
    }

    /**
     * Removes a SASL mechanism from the list of supported SASL mechanisms by the server.
     *
     * @param mechanism the SASL mechanism to remove.
     */
    public static void removeSupportedMechanism(String mechanism) {
        mechanisms.remove(mechanism);
    }

    /**
     * Returns the list of supported SASL mechanisms by the server. Note that Java may have
     * support for more mechanisms but some of them may not be returned since a special setup
     * is required that might be missing. Use {@link #addSupportedMechanism(String)} to add
     * new SASL mechanisms.
     *
     * @return the list of supported SASL mechanisms by the server.
     */
    public static Set<String> getSupportedMechanisms() {
        Set<String> answer = new HashSet<String>(mechanisms);
        // Clean up not-available mechanisms
        for (Iterator<String> it=answer.iterator(); it.hasNext();) {
            String mech = it.next();
            if (mech.equals("CRAM-MD5") || mech.equals("DIGEST-MD5")) {
                // Check if the user provider in use supports passwords retrieval. Accessing
                // to the users passwords will be required by the CallbackHandler
                if (!AuthFactory.getAuthProvider().supportsPasswordRetrieval()) {
                    it.remove();
                }
            }
            else if (mech.equals("ANONYMOUS")) {
                // Check anonymous is supported
                if (!XMPPServer.getInstance().getIQAuthHandler().isAnonymousAllowed()) {
                    it.remove();
                }
            }
            else if (mech.equals("JIVE-SHAREDSECRET")) {
                // Check shared secret is supported
                if (!isSharedSecretAllowed()) {
                    it.remove();
                }
            }
        }
        return answer;
    }

    private static void initMechanisms() {
        mechanisms = new HashSet<String>();
        String available = JiveGlobals.getXMLProperty("sasl.mechs");
        if (available == null) {
            mechanisms.add("ANONYMOUS");
            mechanisms.add("PLAIN");
            mechanisms.add("DIGEST-MD5");
            mechanisms.add("CRAM-MD5");
            mechanisms.add("JIVE-SHAREDSECRET");
        }
        else {
            StringTokenizer st = new StringTokenizer(available, " ,\t\n\r\f");
            while (st.hasMoreTokens()) {
                String mech = st.nextToken().toUpperCase();
                // Check that the mech is a supported mechansim. Maybe we shouldnt check this and allow any?
                if (mech.equals("ANONYMOUS") ||
                        mech.equals("PLAIN") ||
                        mech.equals("DIGEST-MD5") ||
                        mech.equals("CRAM-MD5") ||
                        mech.equals("GSSAPI") ||
                        mech.equals("EXTERNAL") ||
                        mech.equals("JIVE-SHAREDSECRET")) 
                {
                    Log.debug("SASLAuthentication: Added " + mech + " to mech list");
                    mechanisms.add(mech);
                }
            }

            if (mechanisms.contains("GSSAPI")) {
                if (JiveGlobals.getXMLProperty("sasl.gssapi.config") != null) {
                    System.setProperty("java.security.krb5.debug",
                            JiveGlobals.getXMLProperty("sasl.gssapi.debug", "false"));
                    System.setProperty("java.security.auth.login.config",
                            JiveGlobals.getXMLProperty("sasl.gssapi.config"));
                    System.setProperty("javax.security.auth.useSubjectCredsOnly",
                            JiveGlobals.getXMLProperty("sasl.gssapi.useSubjectCredsOnly", "false"));
                }
                else {
                    //Not configured, remove the option.
                    Log.debug("SASLAuthentication: Removed GSSAPI from mech list");
                    mechanisms.remove("GSSAPI");
                }
            }
        }
        //Add our providers to the Security class
        Security.addProvider(new org.jivesoftware.openfire.sasl.SaslProvider());
    }
}

⌨️ 快捷键说明

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