/*
 * Copyright (c) 2000, 2011, 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.security.auth.module;

import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
import javax.naming.*;
import javax.naming.directory.*;

import java.io.IOException;
import java.util.Map;
import java.util.LinkedList;
import java.util.ResourceBundle;

import com.sun.security.auth.UnixPrincipal;
import com.sun.security.auth.UnixNumericUserPrincipal;
import com.sun.security.auth.UnixNumericGroupPrincipal;

import sun.security.util.AuthResources;

/**
 * <p> The module prompts for a username and password
 * and then verifies the password against the password stored in
 * a directory service configured under JNDI.
 *
 * <p> This <code>LoginModule</code> interoperates with
 * any conformant JNDI service provider.  To direct this
 * <code>LoginModule</code> to use a specific JNDI service provider,
 * two options must be specified in the login <code>Configuration</code>
 * for this <code>LoginModule</code>.
 * <pre>
 *      user.provider.url=<b>name_service_url</b>
 *      group.provider.url=<b>name_service_url</b>
 * </pre>
 *
 * <b>name_service_url</b> specifies
 * the directory service and path where this <code>LoginModule</code>
 * can access the relevant user and group information.  Because this
 * <code>LoginModule</code> only performs one-level searches to
 * find the relevant user information, the <code>URL</code>
 * must point to a directory one level above where the user and group
 * information is stored in the directory service.
 * For example, to instruct this <code>LoginModule</code>
 * to contact a NIS server, the following URLs must be specified:
 * <pre>
 *    user.provider.url="nis://<b>NISServerHostName</b>/<b>NISDomain</b>/user"
 *    group.provider.url="nis://<b>NISServerHostName</b>/<b>NISDomain</b>/system/group"
 * </pre>
 *
 * <b>NISServerHostName</b> specifies the server host name of the
 * NIS server (for example, <i>nis.sun.com</i>, and <b>NISDomain</b>
 * specifies the domain for that NIS server (for example, <i>jaas.sun.com</i>.
 * To contact an LDAP server, the following URLs must be specified:
 * <pre>
 *    user.provider.url="ldap://<b>LDAPServerHostName</b>/<b>LDAPName</b>"
 *    group.provider.url="ldap://<b>LDAPServerHostName</b>/<b>LDAPName</b>"
 * </pre>
 *
 * <b>LDAPServerHostName</b> specifies the server host name of the
 * LDAP server, which may include a port number
 * (for example, <i>ldap.sun.com:389</i>),
 * and <b>LDAPName</b> specifies the entry name in the LDAP directory
 * (for example, <i>ou=People,o=Sun,c=US</i> and <i>ou=Groups,o=Sun,c=US</i>
 * for user and group information, respectively).
 *
 * <p> The format in which the user's information must be stored in
 * the directory service is specified in RFC 2307.  Specifically,
 * this <code>LoginModule</code> will search for the user's entry in the
 * directory service using the user's <i>uid</i> attribute,
 * where <i>uid=<b>username</b></i>.  If the search succeeds,
 * this <code>LoginModule</code> will then
 * obtain the user's encrypted password from the retrieved entry
 * using the <i>userPassword</i> attribute.
 * This <code>LoginModule</code> assumes that the password is stored
 * as a byte array, which when converted to a <code>String</code>,
 * has the following format:
 * <pre>
 *      "{crypt}<b>encrypted_password</b>"
 * </pre>
 *
 * The LDAP directory server must be configured
 * to permit read access to the userPassword attribute.
 * If the user entered a valid username and password,
 * this <code>LoginModule</code> associates a
 * <code>UnixPrincipal</code>, <code>UnixNumericUserPrincipal</code>,
 * and the relevant UnixNumericGroupPrincipals with the
 * <code>Subject</code>.
 *
 * <p> This LoginModule also recognizes the following <code>Configuration</code>
 * options:
 * <pre>
 *    debug          if, true, debug messages are output to System.out.
 *
 *    useFirstPass   if, true, this LoginModule retrieves the
 *                   username and password from the module's shared state,
 *                   using "javax.security.auth.login.name" and
 *                   "javax.security.auth.login.password" as the respective
 *                   keys.  The retrieved values are used for authentication.
 *                   If authentication fails, no attempt for a retry is made,
 *                   and the failure is reported back to the calling
 *                   application.
 *
 *    tryFirstPass   if, true, this LoginModule retrieves the
 *                   the username and password from the module's shared state,
 *                   using "javax.security.auth.login.name" and
 *                   "javax.security.auth.login.password" as the respective
 *                   keys.  The retrieved values are used for authentication.
 *                   If authentication fails, the module uses the
 *                   CallbackHandler to retrieve a new username and password,
 *                   and another attempt to authenticate is made.
 *                   If the authentication fails, the failure is reported
 *                   back to the calling application.
 *
 *    storePass      if, true, this LoginModule stores the username and password
 *                   obtained from the CallbackHandler in the module's
 *                   shared state, using "javax.security.auth.login.name" and
 *                   "javax.security.auth.login.password" as the respective
 *                   keys.  This is not performed if existing values already
 *                   exist for the username and password in the shared state,
 *                   or if authentication fails.
 *
 *    clearPass     if, true, this <code>LoginModule</code> clears the
 *                  username and password stored in the module's shared state
 *                  after both phases of authentication (login and commit)
 *                  have completed.
 * </pre>
 *
 */
public class JndiLoginModule implements LoginModule {

    static final java.util.ResourceBundle rb =
        java.util.ResourceBundle.getBundle("sun.security.util.AuthResources");

    /** JNDI Provider */
    public final String USER_PROVIDER = "user.provider.url";
    public final String GROUP_PROVIDER = "group.provider.url";

    // configurable options
    private boolean debug = false;
    private boolean strongDebug = false;
    private String userProvider;
    private String groupProvider;
    private boolean useFirstPass = false;
    private boolean tryFirstPass = false;
    private boolean storePass = false;
    private boolean clearPass = false;

    // the authentication status
    private boolean succeeded = false;
    private boolean commitSucceeded = false;

    // username, password, and JNDI context
    private String username;
    private char[] password;
    DirContext ctx;

    // the user (assume it is a UnixPrincipal)
    private UnixPrincipal userPrincipal;
    private UnixNumericUserPrincipal UIDPrincipal;
    private UnixNumericGroupPrincipal GIDPrincipal;
    private LinkedList<UnixNumericGroupPrincipal> supplementaryGroups =
                                new LinkedList<>();

    // initial state
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map<String, ?> options;

    private static final String CRYPT = "{crypt}";
    private static final String USER_PWD = "userPassword";
    private static final String USER_UID = "uidNumber";
    private static final String USER_GID = "gidNumber";
    private static final String GROUP_ID = "gidNumber";
    private static final String NAME = "javax.security.auth.login.name";
    private static final String PWD = "javax.security.auth.login.password";

    /**
     * Initialize this <code>LoginModule</code>.
     *
     * <p>
     *
     * @param subject the <code>Subject</code> to be authenticated. <p>
     *
     * @param callbackHandler a <code>CallbackHandler</code> for communicating
     *                  with the end user (prompting for usernames and
     *                  passwords, for example). <p>
     *
     * @param sharedState shared <code>LoginModule</code> state. <p>
     *
     * @param options options specified in the login
     *                  <code>Configuration</code> for this particular
     *                  <code>LoginModule</code>.
     */
    public void initialize(Subject subject, CallbackHandler callbackHandler,
                           Map<String,?> sharedState,
                           Map<String,?> options) {

        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;

        // initialize any configured options
        debug = "true".equalsIgnoreCase((String)options.get("debug"));
        strongDebug =
                "true".equalsIgnoreCase((String)options.get("strongDebug"));
        userProvider = (String)options.get(USER_PROVIDER);
        groupProvider = (String)options.get(GROUP_PROVIDER);
        tryFirstPass =
                "true".equalsIgnoreCase((String)options.get("tryFirstPass"));
        useFirstPass =
                "true".equalsIgnoreCase((String)options.get("useFirstPass"));
        storePass =
                "true".equalsIgnoreCase((String)options.get("storePass"));
        clearPass =
                "true".equalsIgnoreCase((String)options.get("clearPass"));
    }

    /**
     * <p> Prompt for username and password.
     * Verify the password against the relevant name service.
     *
     * <p>
     *
     * @return true always, since this <code>LoginModule</code>
     *          should not be ignored.
     *
     * @exception FailedLoginException if the authentication fails. <p>
     *
     * @exception LoginException if this <code>LoginModule</code>
     *          is unable to perform the authentication.
     */
    public boolean login() throws LoginException {

        if (userProvider == null) {
            throw new LoginException
                ("Error: Unable to locate JNDI user provider");
        }
        if (groupProvider == null) {
            throw new LoginException
                ("Error: Unable to locate JNDI group provider");
        }

        if (debug) {
            System.out.println("\t\t[JndiLoginModule] user provider: " +
                                userProvider);
            System.out.println("\t\t[JndiLoginModule] group provider: " +
                                groupProvider);
        }

        // attempt the authentication
        if (tryFirstPass) {

            try {
                // attempt the authentication by getting the
                // username and password from shared state
                attemptAuthentication(true);

                // authentication succeeded
                succeeded = true;
                if (debug) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "tryFirstPass succeeded");
                }
                return true;
            } catch (LoginException le) {
                // authentication failed -- try again below by prompting
                cleanState();
                if (debug) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "tryFirstPass failed with:" +
                                le.toString());
                }
            }

        } else if (useFirstPass) {

            try {
                // attempt the authentication by getting the
                // username and password from shared state
                attemptAuthentication(true);

                // authentication succeeded
                succeeded = true;
                if (debug) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "useFirstPass succeeded");
                }
                return true;
            } catch (LoginException le) {
                // authentication failed
                cleanState();
                if (debug) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "useFirstPass failed");
                }
                throw le;
            }
        }

        // attempt the authentication by prompting for the username and pwd
        try {
            attemptAuthentication(false);

            // authentication succeeded
           succeeded = true;
            if (debug) {
                System.out.println("\t\t[JndiLoginModule] " +
                                "regular authentication succeeded");
            }
            return true;
        } catch (LoginException le) {
            cleanState();
            if (debug) {
                System.out.println("\t\t[JndiLoginModule] " +
                                "regular authentication failed");
            }
            throw le;
        }
    }

    /**
     * Abstract method to commit the authentication process (phase 2).
     *
     * <p> This method is called if the LoginContext's
     * overall authentication succeeded
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * succeeded).
     *
     * <p> If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * <code>login</code> method), then this method associates a
     * <code>UnixPrincipal</code>
     * with the <code>Subject</code> located in the
     * <code>LoginModule</code>.  If this LoginModule's own
     * authentication attempted failed, then this method removes
     * any state that was originally saved.
     *
     * <p>
     *
     * @exception LoginException if the commit fails
     *
     * @return true if this LoginModule's own login and commit
     *          attempts succeeded, or false otherwise.
     */
    public boolean commit() throws LoginException {

        if (succeeded == false) {
            return false;
        } else {
            if (subject.isReadOnly()) {
                cleanState();
                throw new LoginException ("Subject is Readonly");
            }
            // add Principals to the Subject
            if (!subject.getPrincipals().contains(userPrincipal))
                subject.getPrincipals().add(userPrincipal);
            if (!subject.getPrincipals().contains(UIDPrincipal))
                subject.getPrincipals().add(UIDPrincipal);
            if (!subject.getPrincipals().contains(GIDPrincipal))
                subject.getPrincipals().add(GIDPrincipal);
            for (int i = 0; i < supplementaryGroups.size(); i++) {
                if (!subject.getPrincipals().contains
                        (supplementaryGroups.get(i)))
                    subject.getPrincipals().add(supplementaryGroups.get(i));
            }

            if (debug) {
                System.out.println("\t\t[JndiLoginModule]: " +
                                   "added UnixPrincipal,");
                System.out.println("\t\t\t\tUnixNumericUserPrincipal,");
                System.out.println("\t\t\t\tUnixNumericGroupPrincipal(s),");
                System.out.println("\t\t\t to Subject");
            }
        }
        // in any case, clean out state
        cleanState();
        commitSucceeded = true;
        return true;
    }

    /**
     * <p> This method is called if the LoginContext's
     * overall authentication failed.
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * did not succeed).
     *
     * <p> If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * <code>login</code> and <code>commit</code> methods),
     * then this method cleans up any state that was originally saved.
     *
     * <p>
     *
     * @exception LoginException if the abort fails.
     *
     * @return false if this LoginModule's own login and/or commit attempts
     *          failed, and true otherwise.
     */
    public boolean abort() throws LoginException {
        if (debug)
            System.out.println("\t\t[JndiLoginModule]: " +
                "aborted authentication failed");

        if (succeeded == false) {
            return false;
        } else if (succeeded == true && commitSucceeded == false) {

            // Clean out state
            succeeded = false;
            cleanState();

            userPrincipal = null;
            UIDPrincipal = null;
            GIDPrincipal = null;
            supplementaryGroups = new LinkedList<UnixNumericGroupPrincipal>();
        } else {
            // overall authentication succeeded and commit succeeded,
            // but someone else's commit failed
            logout();
        }
        return true;
    }

    /**
     * Logout a user.
     *
     * <p> This method removes the Principals
     * that were added by the <code>commit</code> method.
     *
     * <p>
     *
     * @exception LoginException if the logout fails.
     *
     * @return true in all cases since this <code>LoginModule</code>
     *          should not be ignored.
     */
    public boolean logout() throws LoginException {
        if (subject.isReadOnly()) {
            cleanState();
            throw new LoginException ("Subject is Readonly");
        }
        subject.getPrincipals().remove(userPrincipal);
        subject.getPrincipals().remove(UIDPrincipal);
        subject.getPrincipals().remove(GIDPrincipal);
        for (int i = 0; i < supplementaryGroups.size(); i++) {
            subject.getPrincipals().remove(supplementaryGroups.get(i));
        }


        // clean out state
        cleanState();
        succeeded = false;
        commitSucceeded = false;

        userPrincipal = null;
        UIDPrincipal = null;
        GIDPrincipal = null;
        supplementaryGroups = new LinkedList<UnixNumericGroupPrincipal>();

        if (debug) {
            System.out.println("\t\t[JndiLoginModule]: " +
                "logged out Subject");
        }
        return true;
    }

    /**
     * Attempt authentication
     *
     * <p>
     *
     * @param getPasswdFromSharedState boolean that tells this method whether
     *          to retrieve the password from the sharedState.
     */
    private void attemptAuthentication(boolean getPasswdFromSharedState)
    throws LoginException {

        String encryptedPassword = null;

        // first get the username and password
        getUsernamePassword(getPasswdFromSharedState);

        try {

            // get the user's passwd entry from the user provider URL
            InitialContext iCtx = new InitialContext();
            ctx = (DirContext)iCtx.lookup(userProvider);

            /*
            SearchControls controls = new SearchControls
                                        (SearchControls.ONELEVEL_SCOPE,
                                        0,
                                        5000,
                                        new String[] { USER_PWD },
                                        false,
                                        false);
            */

            SearchControls controls = new SearchControls();
            NamingEnumeration<SearchResult> ne = ctx.search("",
                                        "(uid=" + username + ")",
                                        controls);
            if (ne.hasMore()) {
                SearchResult result = ne.next();
                Attributes attributes = result.getAttributes();

                // get the password

                // this module works only if the LDAP directory server
                // is configured to permit read access to the userPassword
                // attribute. The directory administrator need to grant
                // this access.
                //
                // A workaround would be to make the server do authentication
                // by setting the Context.SECURITY_PRINCIPAL
                // and Context.SECURITY_CREDENTIALS property.
                // However, this would make it not work with systems that
                // don't do authentication at the server (like NIS).
                //
                // Setting the SECURITY_* properties and using "simple"
                // authentication for LDAP is recommended only for secure
                // channels. For nonsecure channels, SSL is recommended.

                Attribute pwd = attributes.get(USER_PWD);
                String encryptedPwd = new String((byte[])pwd.get(), "UTF8");
                encryptedPassword = encryptedPwd.substring(CRYPT.length());

                // check the password
                if (verifyPassword
                    (encryptedPassword, new String(password)) == true) {

                    // authentication succeeded
                    if (debug)
                        System.out.println("\t\t[JndiLoginModule] " +
                                "attemptAuthentication() succeeded");

                } else {
                    // authentication failed
                    if (debug)
                        System.out.println("\t\t[JndiLoginModule] " +
                                "attemptAuthentication() failed");
                    throw new FailedLoginException("Login incorrect");
                }

                // save input as shared state only if
                // authentication succeeded
                if (storePass &&
                    !sharedState.containsKey(NAME) &&
                    !sharedState.containsKey(PWD)) {
                    sharedState.put(NAME, username);
                    sharedState.put(PWD, password);
                }

                // create the user principal
                userPrincipal = new UnixPrincipal(username);

                // get the UID
                Attribute uid = attributes.get(USER_UID);
                String uidNumber = (String)uid.get();
                UIDPrincipal = new UnixNumericUserPrincipal(uidNumber);
                if (debug && uidNumber != null) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "user: '" + username + "' has UID: " +
                                uidNumber);
                }

                // get the GID
                Attribute gid = attributes.get(USER_GID);
                String gidNumber = (String)gid.get();
                GIDPrincipal = new UnixNumericGroupPrincipal
                                (gidNumber, true);
                if (debug && gidNumber != null) {
                    System.out.println("\t\t[JndiLoginModule] " +
                                "user: '" + username + "' has GID: " +
                                gidNumber);
                }

                // get the supplementary groups from the group provider URL
                ctx = (DirContext)iCtx.lookup(groupProvider);
                ne = ctx.search("", new BasicAttributes("memberUid", username));

                while (ne.hasMore()) {
                    result = ne.next();
                    attributes = result.getAttributes();

                    gid = attributes.get(GROUP_ID);
                    String suppGid = (String)gid.get();
                    if (!gidNumber.equals(suppGid)) {
                        UnixNumericGroupPrincipal suppPrincipal =
                            new UnixNumericGroupPrincipal(suppGid, false);
                        supplementaryGroups.add(suppPrincipal);
                        if (debug && suppGid != null) {
                            System.out.println("\t\t[JndiLoginModule] " +
                                "user: '" + username +
                                "' has Supplementary Group: " +
                                suppGid);
                        }
                    }
                }

            } else {
                // bad username
                if (debug) {
                    System.out.println("\t\t[JndiLoginModule]: User not found");
                }
                throw new FailedLoginException("User not found");
            }
        } catch (NamingException ne) {
            // bad username
            if (debug) {
                System.out.println("\t\t[JndiLoginModule]:  User not found");
                ne.printStackTrace();
            }
            throw new FailedLoginException("User not found");
        } catch (java.io.UnsupportedEncodingException uee) {
            // password stored in incorrect format
            if (debug) {
                System.out.println("\t\t[JndiLoginModule]:  " +
                                "password incorrectly encoded");
                uee.printStackTrace();
            }
            throw new LoginException("Login failure due to incorrect " +
                                "password encoding in the password database");
        }

        // authentication succeeded
    }

    /**
     * Get the username and password.
     * This method does not return any value.
     * Instead, it sets global name and password variables.
     *
     * <p> Also note that this method will set the username and password
     * values in the shared state in case subsequent LoginModules
     * want to use them via use/tryFirstPass.
     *
     * <p>
     *
     * @param getPasswdFromSharedState boolean that tells this method whether
     *          to retrieve the password from the sharedState.
     */
    private void getUsernamePassword(boolean getPasswdFromSharedState)
    throws LoginException {

        if (getPasswdFromSharedState) {
            // use the password saved by the first module in the stack
            username = (String)sharedState.get(NAME);
            password = (char[])sharedState.get(PWD);
            return;
        }

        // prompt for a username and password
        if (callbackHandler == null)
            throw new LoginException("Error: no CallbackHandler available " +
                "to garner authentication information from the user");

        String protocol = userProvider.substring(0, userProvider.indexOf(":"));

        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback(protocol + " "
                                            + rb.getString("username."));
        callbacks[1] = new PasswordCallback(protocol + " " +
                                                rb.getString("password."),
                                            false);

        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback)callbacks[0]).getName();
            char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword();
            password = new char[tmpPassword.length];
            System.arraycopy(tmpPassword, 0,
                                password, 0, tmpPassword.length);
            ((PasswordCallback)callbacks[1]).clearPassword();

        } catch (java.io.IOException ioe) {
            throw new LoginException(ioe.toString());
        } catch (UnsupportedCallbackException uce) {
            throw new LoginException("Error: " + uce.getCallback().toString() +
                        " not available to garner authentication information " +
                        "from the user");
        }

        // print debugging information
        if (strongDebug) {
            System.out.println("\t\t[JndiLoginModule] " +
                                "user entered username: " +
                                username);
            System.out.print("\t\t[JndiLoginModule] " +
                                "user entered password: ");
            for (int i = 0; i < password.length; i++)
                System.out.print(password[i]);
            System.out.println();
        }
    }

    /**
     * Verify a password against the encrypted passwd from /etc/shadow
     */
    private boolean verifyPassword(String encryptedPassword, String password) {

        if (encryptedPassword == null)
            return false;

        Crypt c = new Crypt();
        try {
            byte oldCrypt[] = encryptedPassword.getBytes("UTF8");
            byte newCrypt[] = c.crypt(password.getBytes("UTF8"),
                                      oldCrypt);
            if (newCrypt.length != oldCrypt.length)
                return false;
            for (int i = 0; i < newCrypt.length; i++) {
                if (oldCrypt[i] != newCrypt[i])
                    return false;
            }
        } catch (java.io.UnsupportedEncodingException uee) {
            // cannot happen, but return false just to be safe
            return false;
        }
        return true;
    }

    /**
     * Clean out state because of a failed authentication attempt
     */
    private void cleanState() {
        username = null;
        if (password != null) {
            for (int i = 0; i < password.length; i++)
                password[i] = ' ';
            password = null;
        }
        ctx = null;

        if (clearPass) {
            sharedState.remove(NAME);
            sharedState.remove(PWD);
        }
    }
}
