/*
 * Copyright (c) 1995, 2016, 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 sun.net.www.protocol.http;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.HashMap;
import java.util.Objects;

import sun.net.www.HeaderParser;


/**
 * AuthenticationInfo: Encapsulate the information needed to
 * authenticate a user to a server.
 *
 * @author Jon Payne
 * @author Herb Jellinek
 * @author Bill Foote
 */
// REMIND:  It would be nice if this class understood about partial matching.
//      If you're authorized for foo.com, chances are high you're also
//      authorized for baz.foo.com.
// NB:  When this gets implemented, be careful about the uncaching
//      policy in HttpURLConnection.  A failure on baz.foo.com shouldn't
//      uncache foo.com!

public abstract class AuthenticationInfo extends AuthCacheValue implements Cloneable {

    static final long serialVersionUID = -2588378268010453259L;

    // Constants saying what kind of authroization this is.  This determines
    // the namespace in the hash table lookup.
    public static final char SERVER_AUTHENTICATION = 's';
    public static final char PROXY_AUTHENTICATION = 'p';

    /**
     * If true, then simultaneous authentication requests to the same realm/proxy
     * are serialized, in order to avoid a user having to type the same username/passwords
     * repeatedly, via the Authenticator. Default is false, which means that this
     * behavior is switched off.
     */
    static final boolean serializeAuth;
    static {
        serializeAuth = java.security.AccessController.doPrivileged(
            new sun.security.action.GetBooleanAction(
                "http.auth.serializeRequests")).booleanValue();
    }

    /* AuthCacheValue: */

    protected transient PasswordAuthentication pw;

    public PasswordAuthentication credentials() {
        return pw;
    }

    public AuthCacheValue.Type getAuthType() {
        return type == SERVER_AUTHENTICATION ?
            AuthCacheValue.Type.Server:
            AuthCacheValue.Type.Proxy;
    }

    AuthScheme getAuthScheme() {
        return authScheme;
    }

    public String getHost() {
        return host;
    }
    public int getPort() {
        return port;
    }
    public String getRealm() {
        return realm;
    }
    public String getPath() {
        return path;
    }
    public String getProtocolScheme() {
        return protocol;
    }
    /**
     * Whether we should cache this instance in the AuthCache.
     * This method returns {@code true} by default.
     * Subclasses may override this method to add
     * additional restrictions.
     * @return {@code true} by default.
     */
    protected boolean useAuthCache() {
        return true;
    }

    /**
     * requests is used to ensure that interaction with the
     * Authenticator for a particular realm is single threaded.
     * ie. if multiple threads need to get credentials from the user
     * at the same time, then all but the first will block until
     * the first completes its authentication.
     */
    private static HashMap<String,Thread> requests = new HashMap<>();

    /* check if a request for this destination is in progress
     * return false immediately if not. Otherwise block until
     * request is finished and return true
     */
    private static boolean requestIsInProgress (String key) {
        if (!serializeAuth) {
            /* behavior is disabled. Revert to concurrent requests */
            return false;
        }
        synchronized (requests) {
            Thread t, c;
            c = Thread.currentThread();
            if ((t = requests.get(key)) == null) {
                requests.put (key, c);
                return false;
            }
            if (t == c) {
                return false;
            }
            while (requests.containsKey(key)) {
                try {
                    requests.wait ();
                } catch (InterruptedException e) {}
            }
        }
        /* entry may be in cache now. */
        return true;
    }

    /* signal completion of an authentication (whether it succeeded or not)
     * so that other threads can continue.
     */
    private static void requestCompleted (String key) {
        synchronized (requests) {
            Thread thread = requests.get(key);
            if (thread != null && thread == Thread.currentThread()) {
                boolean waspresent = requests.remove(key) != null;
                assert waspresent;
            }
            requests.notifyAll();
        }
    }

    //public String toString () {
        //return ("{"+type+":"+authScheme+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
    //}

    // REMIND:  This cache just grows forever.  We should put in a bounded
    //          cache, or maybe something using WeakRef's.

    /** The type (server/proxy) of authentication this is.  Used for key lookup */
    char type;

    /** The authentication scheme (basic/digest). Also used for key lookup */
    AuthScheme authScheme;

    /** The protocol/scheme (i.e. http or https ). Need to keep the caches
     *  logically separate for the two protocols. This field is only used
     *  when constructed with a URL (the normal case for server authentication)
     *  For proxy authentication the protocol is not relevant.
     */
    String protocol;

    /** The host we're authenticating against. */
    String host;

    /** The port on the host we're authenticating against. */
    int port;

    /** The realm we're authenticating against. */
    String realm;

    /** The shortest path from the URL we authenticated against. */
    String path;

    /**
     * A key identifying the authenticator from which the credentials
     * were obtained.
     * {@link AuthenticatorKeys#DEFAULT} identifies the {@linkplain
     * java.net.Authenticator#setDefault(java.net.Authenticator) default}
     * authenticator.
     */
     String authenticatorKey;

    /** Use this constructor only for proxy entries */
    public AuthenticationInfo(char type, AuthScheme authScheme, String host,
                              int port, String realm, String authenticatorKey) {
        this.type = type;
        this.authScheme = authScheme;
        this.protocol = "";
        this.host = host.toLowerCase();
        this.port = port;
        this.realm = realm;
        this.path = null;
        this.authenticatorKey = Objects.requireNonNull(authenticatorKey);
    }

    public Object clone() {
        try {
            return super.clone ();
        } catch (CloneNotSupportedException e) {
            // Cannot happen because Cloneable implemented by AuthenticationInfo
            return null;
        }
    }

    /*
     * Constructor used to limit the authorization to the path within
     * the URL. Use this constructor for origin server entries.
     */
    public AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm,
                              String authenticatorKey) {
        this.type = type;
        this.authScheme = authScheme;
        this.protocol = url.getProtocol().toLowerCase();
        this.host = url.getHost().toLowerCase();
        this.port = url.getPort();
        if (this.port == -1) {
            this.port = url.getDefaultPort();
        }
        this.realm = realm;

        String urlPath = url.getPath();
        if (urlPath.length() == 0)
            this.path = urlPath;
        else {
            this.path = reducePath (urlPath);
        }
        this.authenticatorKey = Objects.requireNonNull(authenticatorKey);
    }

    /**
     * The {@linkplain java.net.Authenticator#getKey(java.net.Authenticator) key}
     * of the authenticator that was used to obtain the credentials.
     * @return The authenticator's key.
     */
    public final String getAuthenticatorKey() {
        return authenticatorKey;
    }

    /*
     * reduce the path to the root of where we think the
     * authorization begins. This could get shorter as
     * the url is traversed up following a successful challenge.
     */
    static String reducePath (String urlPath) {
        int sepIndex = urlPath.lastIndexOf('/');
        int targetSuffixIndex = urlPath.lastIndexOf('.');
        if (sepIndex != -1)
            if (sepIndex < targetSuffixIndex)
                return urlPath.substring(0, sepIndex+1);
            else
                return urlPath;
        else
            return urlPath;
    }

    /**
     * Returns info for the URL, for an HTTP server auth.  Used when we
     * don't yet know the realm
     * (i.e. when we're preemptively setting the auth).
     */
    static AuthenticationInfo getServerAuth(URL url, String authenticatorKey) {
        int port = url.getPort();
        if (port == -1) {
            port = url.getDefaultPort();
        }
        String key = SERVER_AUTHENTICATION + ":" + url.getProtocol().toLowerCase()
                + ":" + url.getHost().toLowerCase() + ":" + port
                + ";auth=" + authenticatorKey;
        return getAuth(key, url);
    }

    /**
     * Returns info for the URL, for an HTTP server auth.  Used when we
     * do know the realm (i.e. when we're responding to a challenge).
     * In this case we do not use the path because the protection space
     * is identified by the host:port:realm only
     */
    static String getServerAuthKey(URL url, String realm, AuthScheme scheme,
                                   String authenticatorKey) {
        int port = url.getPort();
        if (port == -1) {
            port = url.getDefaultPort();
        }
        String key = SERVER_AUTHENTICATION + ":" + scheme + ":"
                     + url.getProtocol().toLowerCase()
                     + ":" + url.getHost().toLowerCase()
                     + ":" + port + ":" + realm
                     + ";auth=" + authenticatorKey;
        return key;
    }

    static AuthenticationInfo getServerAuth(String key) {
        AuthenticationInfo cached = getAuth(key, null);
        if ((cached == null) && requestIsInProgress (key)) {
            /* check the cache again, it might contain an entry */
            cached = getAuth(key, null);
        }
        return cached;
    }


    /**
     * Return the AuthenticationInfo object from the cache if it's path is
     * a substring of the supplied URLs path.
     */
    static AuthenticationInfo getAuth(String key, URL url) {
        if (url == null) {
            return (AuthenticationInfo)cache.get (key, null);
        } else {
            return (AuthenticationInfo)cache.get (key, url.getPath());
        }
    }

    /**
     * Returns a firewall authentication, for the given host/port.  Used
     * for preemptive header-setting. Note, the protocol field is always
     * blank for proxies.
     */
    static AuthenticationInfo getProxyAuth(String host, int port,
                                           String authenticatorKey) {
        String key = PROXY_AUTHENTICATION + "::" + host.toLowerCase() + ":" + port
                     + ";auth=" + authenticatorKey;
        AuthenticationInfo result = (AuthenticationInfo) cache.get(key, null);
        return result;
    }

    /**
     * Returns a firewall authentication, for the given host/port and realm.
     * Used in response to a challenge. Note, the protocol field is always
     * blank for proxies.
     */
    static String getProxyAuthKey(String host, int port, String realm,
                                  AuthScheme scheme, String authenticatorKey) {
        String key = PROXY_AUTHENTICATION + ":" + scheme
                        + "::" + host.toLowerCase()
                        + ":" + port + ":" + realm
                        + ";auth=" + authenticatorKey;
        return key;
    }

    static AuthenticationInfo getProxyAuth(String key) {
        AuthenticationInfo cached = (AuthenticationInfo) cache.get(key, null);
        if ((cached == null) && requestIsInProgress (key)) {
            /* check the cache again, it might contain an entry */
            cached = (AuthenticationInfo) cache.get(key, null);
        }
        return cached;
    }


    /**
     * Add this authentication to the cache
     */
    void addToCache() {
        String key = cacheKey(true);
        if (useAuthCache()) {
            cache.put(key, this);
            if (supportsPreemptiveAuthorization()) {
                cache.put(cacheKey(false), this);
            }
        }
        endAuthRequest(key);
    }

    static void endAuthRequest (String key) {
        if (!serializeAuth) {
            return;
        }
        synchronized (requests) {
            requestCompleted(key);
        }
    }

    /**
     * Remove this authentication from the cache
     */
    void removeFromCache() {
        cache.remove(cacheKey(true), this);
        if (supportsPreemptiveAuthorization()) {
            cache.remove(cacheKey(false), this);
        }
    }

    /**
     * @return true if this authentication supports preemptive authorization
     */
    public abstract boolean supportsPreemptiveAuthorization();

    /**
     * @return the name of the HTTP header this authentication wants set.
     *          This is used for preemptive authorization.
     */
    public String getHeaderName() {
        if (type == SERVER_AUTHENTICATION) {
            return "Authorization";
        } else {
            return "Proxy-authorization";
        }
    }

    /**
     * Calculates and returns the authentication header value based
     * on the stored authentication parameters. If the calculation does not depend
     * on the URL or the request method then these parameters are ignored.
     * @param url The URL
     * @param method The request method
     * @return the value of the HTTP header this authentication wants set.
     *          Used for preemptive authorization.
     */
    public abstract String getHeaderValue(URL url, String method);

    /**
     * Set header(s) on the given connection.  Subclasses must override
     * This will only be called for
     * definitive (i.e. non-preemptive) authorization.
     * @param conn The connection to apply the header(s) to
     * @param p A source of header values for this connection, if needed.
     * @param raw The raw header field (if needed)
     * @return true if all goes well, false if no headers were set.
     */
    public abstract boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw);

    /**
     * Check if the header indicates that the current auth. parameters are stale.
     * If so, then replace the relevant field with the new value
     * and return true. Otherwise return false.
     * returning true means the request can be retried with the same userid/password
     * returning false means we have to go back to the user to ask for a new
     * username password.
     */
    public abstract boolean isAuthorizationStale (String header);

    /**
     * Give a key for hash table lookups.
     * @param includeRealm if you want the realm considered.  Preemptively
     *          setting an authorization is done before the realm is known.
     */
    String cacheKey(boolean includeRealm) {
        // This must be kept in sync with the getXXXAuth() methods in this
        // class.
        String authenticatorKey = getAuthenticatorKey();
        if (includeRealm) {
            return type + ":" + authScheme + ":" + protocol + ":"
                        + host + ":" + port + ":" + realm
                     + ";auth=" + authenticatorKey;
        } else {
            return type + ":" + protocol + ":" + host + ":" + port
                     + ";auth=" + authenticatorKey;
        }
    }

    String s1, s2;  /* used for serialization of pw */

    private synchronized void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException
    {
        s.defaultReadObject ();
        pw = new PasswordAuthentication (s1, s2.toCharArray());
        s1 = null; s2= null;
        if (authenticatorKey == null) {
            authenticatorKey = AuthenticatorKeys.DEFAULT;
        }
    }

    private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        Objects.requireNonNull(authenticatorKey);
        s1 = pw.getUserName();
        s2 = new String (pw.getPassword());
        s.defaultWriteObject ();
    }
}
