/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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<UnixNumericGroupPrincipal>();

    // 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);
        }
    }
}
