/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.catalina.realm;

import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.catalina.LifecycleException;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSName;

/**
 * This class extends the CombinedRealm (hence it can wrap other Realms) to
 * provide a user lock out mechanism if there are too many failed
 * authentication attempts in a given period of time. To ensure correct
 * operation, there is a reasonable degree of synchronisation in this Realm.
 * This Realm does not require modification to the underlying Realms or the
 * associated user storage mechanisms. It achieves this by recording all failed
 * logins, including those for users that do not exist. To prevent a DOS by
 * deliberating making requests with invalid users (and hence causing this cache
 * to grow) the size of the list of users that have failed authentication is
 * limited.
 */
public class LockOutRealm extends CombinedRealm {

    private static final Log log = LogFactory.getLog(LockOutRealm.class);

    /**
     * Descriptive information about this Realm implementation.
     */
    protected static final String name = "LockOutRealm";

    /**
     * The number of times in a row a user has to fail authentication to be
     * locked out. Defaults to 5.
     */
    protected int failureCount = 5;

    /**
     * The time (in seconds) a user is locked out for after too many
     * authentication failures. Defaults to 300 (5 minutes).
     */
    protected int lockOutTime = 300;

    /**
     * Number of users that have failed authentication to keep in cache. Over
     * time the cache will grow to this size and may not shrink. Defaults to
     * 1000.
     */
    protected int cacheSize = 1000;

    /**
     * If a failed user is removed from the cache because the cache is too big
     * before it has been in the cache for at least this period of time (in
     * seconds) a warning message will be logged. Defaults to 3600 (1 hour).
     */
    protected int cacheRemovalWarningTime = 3600;

    /**
     * Users whose last authentication attempt failed. Entries will be ordered
     * in access order from least recent to most recent.
     */
    protected Map<String,LockRecord> failedUsers = null;


    /**
     * Prepare for the beginning of active use of the public methods of this
     * component and implement the requirements of
     * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents this component from being used
     */
    @Override
    protected void startInternal() throws LifecycleException {
        // Configure the list of failed users to delete the oldest entry once it
        // exceeds the specified size
        failedUsers = new LinkedHashMap<String, LockRecord>(cacheSize, 0.75f,
                true) {
            private static final long serialVersionUID = 1L;
            @Override
            protected boolean removeEldestEntry(
                    Map.Entry<String, LockRecord> eldest) {
                if (size() > cacheSize) {
                    // Check to see if this element has been removed too quickly
                    long timeInCache = (System.currentTimeMillis() -
                            eldest.getValue().getLastFailureTime())/1000;

                    if (timeInCache < cacheRemovalWarningTime) {
                        log.warn(sm.getString("lockOutRealm.removeWarning",
                                eldest.getKey(), Long.valueOf(timeInCache)));
                    }
                    return true;
                }
                return false;
            }
        };

        super.startInternal();
    }


    /**
     * Return the Principal associated with the specified username, which
     * matches the digest calculated using the given parameters using the
     * method described in RFC 2069; otherwise return <code>null</code>.
     *
     * @param username Username of the Principal to look up
     * @param clientDigest Digest which has been submitted by the client
     * @param nonce Unique (or supposedly unique) token which has been used
     * for this request
     * @param realmName Realm name
     * @param md5a2 Second MD5 digest used to calculate the digest :
     * MD5(Method + ":" + uri)
     */
    @Override
    public Principal authenticate(String username, String clientDigest,
            String nonce, String nc, String cnonce, String qop,
            String realmName, String md5a2) {

        if (isLocked(username)) {
            // Trying to authenticate a locked user is an automatic failure
            registerAuthFailure(username);

            log.warn(sm.getString("lockOutRealm.authLockedUser", username));
            return null;
        }

        Principal authenticatedUser = super.authenticate(username, clientDigest,
                nonce, nc, cnonce, qop, realmName, md5a2);

        if (authenticatedUser == null) {
            registerAuthFailure(username);
        } else {
            registerAuthSuccess(username);
        }
        return authenticatedUser;
    }


    /**
     * Return the Principal associated with the specified username and
     * credentials, if there is one; otherwise return <code>null</code>.
     *
     * @param username Username of the Principal to look up
     * @param credentials Password or other credentials to use in
     *  authenticating this username
     */
    @Override
    public Principal authenticate(String username, String credentials) {
        if (isLocked(username)) {
            // Trying to authenticate a locked user is an automatic failure
            registerAuthFailure(username);

            log.warn(sm.getString("lockOutRealm.authLockedUser", username));
            return null;
        }

        Principal authenticatedUser = super.authenticate(username, credentials);

        if (authenticatedUser == null) {
            registerAuthFailure(username);
        } else {
            registerAuthSuccess(username);
        }
        return authenticatedUser;
    }


    /**
     * Return the Principal associated with the specified chain of X509
     * client certificates.  If there is none, return <code>null</code>.
     *
     * @param certs Array of client certificates, with the first one in
     *  the array being the certificate of the client itself.
     */
    @Override
    public Principal authenticate(X509Certificate[] certs) {
        String username = null;
        if (certs != null && certs.length >0) {
            username = certs[0].getSubjectDN().getName();
        }

        if (isLocked(username)) {
            // Trying to authenticate a locked user is an automatic failure
            registerAuthFailure(username);

            log.warn(sm.getString("lockOutRealm.authLockedUser", username));
            return null;
        }

        Principal authenticatedUser = super.authenticate(certs);

        if (authenticatedUser == null) {
            registerAuthFailure(username);
        } else {
            registerAuthSuccess(username);
        }
        return authenticatedUser;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public Principal authenticate(GSSContext gssContext, boolean storeCreds) {
        if (gssContext.isEstablished()) {
            String username = null;
            GSSName name = null;
            try {
                name = gssContext.getSrcName();
            } catch (GSSException e) {
                log.warn(sm.getString("realmBase.gssNameFail"), e);
                return null;
            }

            username = name.toString();

            if (isLocked(username)) {
                // Trying to authenticate a locked user is an automatic failure
                registerAuthFailure(username);

                log.warn(sm.getString("lockOutRealm.authLockedUser", username));
                return null;
            }

            Principal authenticatedUser =
                    super.authenticate(gssContext, storeCreds);

            if (authenticatedUser == null) {
                registerAuthFailure(username);
            } else {
                registerAuthSuccess(username);
            }
            return authenticatedUser;
        }

        // Fail in all other cases
        return null;
    }


    /**
     * Unlock the specified username. This will remove all records of
     * authentication failures for this user.
     *
     * @param username The user to unlock
     */
    public void unlock(String username) {
        // Auth success clears the lock record so...
        registerAuthSuccess(username);
    }

    /*
     * Checks to see if the current user is locked. If this is associated with
     * a login attempt, then the last access time will be recorded and any
     * attempt to authenticated a locked user will log a warning.
     */
    private boolean isLocked(String username) {
        LockRecord lockRecord = null;
        synchronized (this) {
            lockRecord = failedUsers.get(username);
        }

        // No lock record means user can't be locked
        if (lockRecord == null) {
            return false;
        }

        // Check to see if user is locked
        if (lockRecord.getFailures() >= failureCount &&
                (System.currentTimeMillis() -
                        lockRecord.getLastFailureTime())/1000 < lockOutTime) {
            return true;
        }

        // User has not, yet, exceeded lock thresholds
        return false;
    }


    /*
     * After successful authentication, any record of previous authentication
     * failure is removed.
     */
    private synchronized void registerAuthSuccess(String username) {
        // Successful authentication means removal from the list of failed users
        failedUsers.remove(username);
    }


    /*
     * After a failed authentication, add the record of the failed
     * authentication.
     */
    private void registerAuthFailure(String username) {
        LockRecord lockRecord = null;
        synchronized (this) {
            if (!failedUsers.containsKey(username)) {
                lockRecord = new LockRecord();
                failedUsers.put(username, lockRecord);
            } else {
                lockRecord = failedUsers.get(username);
                if (lockRecord.getFailures() >= failureCount &&
                        ((System.currentTimeMillis() -
                                lockRecord.getLastFailureTime())/1000)
                                > lockOutTime) {
                    // User was previously locked out but lockout has now
                    // expired so reset failure count
                    lockRecord.setFailures(0);
                }
            }
        }
        lockRecord.registerFailure();
    }


    /**
     * Get the number of failed authentication attempts required to lock the
     * user account.
     * @return the failureCount
     */
    public int getFailureCount() {
        return failureCount;
    }


    /**
     * Set the number of failed authentication attempts required to lock the
     * user account.
     * @param failureCount the failureCount to set
     */
    public void setFailureCount(int failureCount) {
        this.failureCount = failureCount;
    }


    /**
     * Get the period for which an account will be locked.
     * @return the lockOutTime
     */
    public int getLockOutTime() {
        return lockOutTime;
    }


    @Override
    protected String getName() {
        return name;
    }


    /**
     * Set the period for which an account will be locked.
     * @param lockOutTime the lockOutTime to set
     */
    public void setLockOutTime(int lockOutTime) {
        this.lockOutTime = lockOutTime;
    }


    /**
     * Get the maximum number of users for which authentication failure will be
     * kept in the cache.
     * @return the cacheSize
     */
    public int getCacheSize() {
        return cacheSize;
    }


    /**
     * Set the maximum number of users for which authentication failure will be
     * kept in the cache.
     * @param cacheSize the cacheSize to set
     */
    public void setCacheSize(int cacheSize) {
        this.cacheSize = cacheSize;
    }


    /**
     * Get the minimum period a failed authentication must remain in the cache
     * to avoid generating a warning if it is removed from the cache to make
     * space for a new entry.
     * @return the cacheRemovalWarningTime
     */
    public int getCacheRemovalWarningTime() {
        return cacheRemovalWarningTime;
    }


    /**
     * Set the minimum period a failed authentication must remain in the cache
     * to avoid generating a warning if it is removed from the cache to make
     * space for a new entry.
     * @param cacheRemovalWarningTime the cacheRemovalWarningTime to set
     */
    public void setCacheRemovalWarningTime(int cacheRemovalWarningTime) {
        this.cacheRemovalWarningTime = cacheRemovalWarningTime;
    }


    protected static class LockRecord {
        private final AtomicInteger failures = new AtomicInteger(0);
        private long lastFailureTime = 0;

        public int getFailures() {
            return failures.get();
        }

        public void setFailures(int theFailures) {
            failures.set(theFailures);
        }

        public long getLastFailureTime() {
            return lastFailureTime;
        }

        public void registerFailure() {
            failures.incrementAndGet();
            lastFailureTime = System.currentTimeMillis();
        }
    }
}
