/*
 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.jmx.remote.security;

import java.io.IOException;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.management.remote.JMXPrincipal;
import javax.management.remote.JMXAuthenticator;
import javax.security.auth.AuthPermission;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp;

/**
 * <p>This class represents a
 * <a href="{@docRoot}/../guide/security/jaas/JAASRefGuide.html">JAAS</a>
 * based implementation of the {@link JMXAuthenticator} interface.</p>
 *
 * <p>Authentication is performed by passing the supplied user's credentials
 * to one or more authentication mechanisms ({@link LoginModule}) for
 * verification. An authentication mechanism acquires the user's credentials
 * by calling {@link NameCallback} and/or {@link PasswordCallback}.
 * If authentication is successful then an authenticated {@link Subject}
 * filled in with a {@link Principal} is returned.  Authorization checks
 * will then be performed based on this <code>Subject</code>.</p>
 *
 * <p>By default, a single file-based authentication mechanism
 * {@link FileLoginModule} is configured (<code>FileLoginConfig</code>).</p>
 *
 * <p>To override the default configuration use the
 * <code>com.sun.management.jmxremote.login.config</code> management property
 * described in the JRE/lib/management/management.properties file.
 * Set this property to the name of a JAAS configuration entry and ensure that
 * the entry is loaded by the installed {@link Configuration}. In addition,
 * ensure that the authentication mechanisms specified in the entry acquire
 * the user's credentials by calling {@link NameCallback} and
 * {@link PasswordCallback} and that they return a {@link Subject} filled-in
 * with a {@link Principal}, for those users that are successfully
 * authenticated.</p>
 */
public final class JMXPluggableAuthenticator implements JMXAuthenticator {

    /**
     * Creates an instance of <code>JMXPluggableAuthenticator</code>
     * and initializes it with a {@link LoginContext}.
     *
     * @param env the environment containing configuration properties for the
     *            authenticator. Can be null, which is equivalent to an empty
     *            Map.
     * @exception SecurityException if the authentication mechanism cannot be
     *            initialized.
     */
    public JMXPluggableAuthenticator(Map<?, ?> env) {

        String loginConfigName = null;
        String passwordFile = null;

        if (env != null) {
            loginConfigName = (String) env.get(LOGIN_CONFIG_PROP);
            passwordFile = (String) env.get(PASSWORD_FILE_PROP);
        }

        try {

            if (loginConfigName != null) {
                // use the supplied JAAS login configuration
                loginContext =
                    new LoginContext(loginConfigName, new JMXCallbackHandler());

            } else {
                // use the default JAAS login configuration (file-based)
                SecurityManager sm = System.getSecurityManager();
                if (sm != null) {
                    sm.checkPermission(
                            new AuthPermission("createLoginContext." +
                                               LOGIN_CONFIG_NAME));
                }

                final String pf = passwordFile;
                try {
                    loginContext = AccessController.doPrivileged(
                        new PrivilegedExceptionAction<LoginContext>() {
                            public LoginContext run() throws LoginException {
                                return new LoginContext(
                                                LOGIN_CONFIG_NAME,
                                                null,
                                                new JMXCallbackHandler(),
                                                new FileLoginConfig(pf));
                            }
                        });
                } catch (PrivilegedActionException pae) {
                    throw (LoginException) pae.getException();
                }
            }

        } catch (LoginException le) {
            authenticationFailure("authenticate", le);

        } catch (SecurityException se) {
            authenticationFailure("authenticate", se);
        }
    }

    /**
     * Authenticate the <code>MBeanServerConnection</code> client
     * with the given client credentials.
     *
     * @param credentials the user-defined credentials to be passed in
     * to the server in order to authenticate the user before creating
     * the <code>MBeanServerConnection</code>.  This parameter must
     * be a two-element <code>String[]</code> containing the client's
     * username and password in that order.
     *
     * @return the authenticated subject containing a
     * <code>JMXPrincipal(username)</code>.
     *
     * @exception SecurityException if the server cannot authenticate the user
     * with the provided credentials.
     */
    public Subject authenticate(Object credentials) {
        // Verify that credentials is of type String[].
        //
        if (!(credentials instanceof String[])) {
            // Special case for null so we get a more informative message
            if (credentials == null)
                authenticationFailure("authenticate", "Credentials required");

            final String message =
                "Credentials should be String[] instead of " +
                 credentials.getClass().getName();
            authenticationFailure("authenticate", message);
        }
        // Verify that the array contains two elements.
        //
        final String[] aCredentials = (String[]) credentials;
        if (aCredentials.length != 2) {
            final String message =
                "Credentials should have 2 elements not " +
                aCredentials.length;
            authenticationFailure("authenticate", message);
        }
        // Verify that username exists and the associated
        // password matches the one supplied by the client.
        //
        username = aCredentials[0];
        password = aCredentials[1];
        if (username == null || password == null) {
            final String message = "Username or password is null";
            authenticationFailure("authenticate", message);
        }

        // Perform authentication
        try {
            loginContext.login();
            final Subject subject = loginContext.getSubject();
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        subject.setReadOnly();
                        return null;
                    }
                });

            return subject;

        } catch (LoginException le) {
            authenticationFailure("authenticate", le);
        }
        return null;
    }

    private static void authenticationFailure(String method, String message)
        throws SecurityException {
        final String msg = "Authentication failed! " + message;
        final SecurityException e = new SecurityException(msg);
        logException(method, msg, e);
        throw e;
    }

    private static void authenticationFailure(String method,
                                              Exception exception)
        throws SecurityException {
        String msg;
        SecurityException se;
        if (exception instanceof SecurityException) {
            msg = exception.getMessage();
            se = (SecurityException) exception;
        } else {
            msg = "Authentication failed! " + exception.getMessage();
            final SecurityException e = new SecurityException(msg);
            EnvHelp.initCause(e, exception);
            se = e;
        }
        logException(method, msg, se);
        throw se;
    }

    private static void logException(String method,
                                     String message,
                                     Exception e) {
        if (logger.traceOn()) {
            logger.trace(method, message);
        }
        if (logger.debugOn()) {
            logger.debug(method, e);
        }
    }

    private LoginContext loginContext;
    private String username;
    private String password;
    private static final String LOGIN_CONFIG_PROP =
        "jmx.remote.x.login.config";
    private static final String LOGIN_CONFIG_NAME = "JMXPluggableAuthenticator";
    private static final String PASSWORD_FILE_PROP =
        "jmx.remote.x.password.file";
    private static final ClassLogger logger =
        new ClassLogger("javax.management.remote.misc", LOGIN_CONFIG_NAME);

/**
 * This callback handler supplies the username and password (which was
 * originally supplied by the JMX user) to the JAAS login module performing
 * the authentication. No interactive user prompting is required because the
 * credentials are already available to this class (via its enclosing class).
 */
private final class JMXCallbackHandler implements CallbackHandler {

    /**
     * Sets the username and password in the appropriate Callback object.
     */
    public void handle(Callback[] callbacks)
        throws IOException, UnsupportedCallbackException {

        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof NameCallback) {
                ((NameCallback)callbacks[i]).setName(username);

            } else if (callbacks[i] instanceof PasswordCallback) {
                ((PasswordCallback)callbacks[i])
                    .setPassword(password.toCharArray());

            } else {
                throw new UnsupportedCallbackException
                    (callbacks[i], "Unrecognized Callback");
            }
        }
    }
}

/**
 * This class defines the JAAS configuration for file-based authentication.
 * It is equivalent to the following textual configuration entry:
 * <pre>
 *     JMXPluggableAuthenticator {
 *         com.sun.jmx.remote.security.FileLoginModule required;
 *     };
 * </pre>
 */
private static class FileLoginConfig extends Configuration {

    // The JAAS configuration for file-based authentication
    private AppConfigurationEntry[] entries;

    // The classname of the login module for file-based authentication
    private static final String FILE_LOGIN_MODULE =
        FileLoginModule.class.getName();

    // The option that identifies the password file to use
    private static final String PASSWORD_FILE_OPTION = "passwordFile";

    /**
     * Creates an instance of <code>FileLoginConfig</code>
     *
     * @param passwordFile A filepath that identifies the password file to use.
     *                     If null then the default password file is used.
     */
    public FileLoginConfig(String passwordFile) {

        Map<String, String> options;
        if (passwordFile != null) {
            options = new HashMap<String, String>(1);
            options.put(PASSWORD_FILE_OPTION, passwordFile);
        } else {
            options = Collections.emptyMap();
        }

        entries = new AppConfigurationEntry[] {
            new AppConfigurationEntry(FILE_LOGIN_MODULE,
                AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
                    options)
        };
    }

    /**
     * Gets the JAAS configuration for file-based authentication
     */
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {

        return name.equals(LOGIN_CONFIG_NAME) ? entries : null;
    }

    /**
     * Refreshes the configuration.
     */
    public void refresh() {
        // the configuration is fixed
    }
}

}
