/*
 * Copyright (c) 2000, 2010, 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.sasl.gsskerb;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.security.sasl.*;

// JAAS
import javax.security.auth.callback.CallbackHandler;

// JGSS
import org.ietf.jgss.*;

/**
  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
  * It uses the Java Bindings for GSSAPI
  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
  * for getting GSSAPI/Kerberos V5 support.
  *
  * The client/server interactions are:
  * C0: bind (GSSAPI, initial response)
  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
  * S2: bind success response
  *
  * Expects the client's credentials to be supplied from the
  * javax.security.sasl.credentials property or from the thread's Subject.
  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
  * by logging into Kerberos (via default TextCallbackHandler).
  * These creds will be used for exchange with server.
  *
  * Required callbacks: none.
  *
  * Environment properties that affect behavior of implementation:
  *
  * javax.security.sasl.qop
  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
  * javax.security.sasl.maxbuf
  * - max receive buffer size; default is 65536
  * javax.security.sasl.sendmaxbuffer
  * - max send buffer size; default is 65536; (min with server max recv size)
  *
  * javax.security.sasl.server.authentication
  * - "true" means require mutual authentication; default is "false"
  *
  * javax.security.sasl.credentials
  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
  *
  * @author Rosanna Lee
  */

final class GssKrb5Client extends GssKrb5Base implements SaslClient {
    // ---------------- Constants -----------------
    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();

    private boolean finalHandshake = false;
    private boolean mutual = false;       // default false
    private byte[] authzID;

    /**
     * Creates a SASL mechanism with client credentials that it needs
     * to participate in GSS-API/Kerberos v5 authentication exchange
     * with the server.
     */
    GssKrb5Client(String authzID, String protocol, String serverName,
        Map props, CallbackHandler cbh) throws SaslException {

        super(props, MY_CLASS_NAME);

        String service = protocol + "@" + serverName;
        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
            service);

        try {
            GSSManager mgr = GSSManager.getInstance();

            // Create the name for the requested service entity for Krb5 mech
            GSSName acceptorName = mgr.createName(service,
                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);

            // Parse properties to check for supplied credentials
            GSSCredential credentials = null;
            if (props != null) {
                Object prop = props.get(Sasl.CREDENTIALS);
                if (prop != null && prop instanceof GSSCredential) {
                    credentials = (GSSCredential) prop;
                    logger.log(Level.FINE,
                        "KRB5CLNT01:Using the credentials supplied in " +
                        "javax.security.sasl.credentials");
                }
            }

            // Create a context using credentials for Krb5 mech
            secCtx = mgr.createContext(acceptorName,
                KRB5_OID,   /* mechanism */
                credentials, /* credentials */
                GSSContext.INDEFINITE_LIFETIME);

            // Request credential delegation when credentials have been supplied
            if (credentials != null) {
                secCtx.requestCredDeleg(true);
            }

            // Parse properties  to set desired context options
            if (props != null) {
                // Mutual authentication
                String prop = (String)props.get(Sasl.SERVER_AUTH);
                if (prop != null) {
                    mutual = "true".equalsIgnoreCase(prop);
                }
            }
            secCtx.requestMutualAuth(mutual);

            // Always specify potential need for integrity and confidentiality
            // Decision will be made during final handshake
            secCtx.requestConf(true);
            secCtx.requestInteg(true);

        } catch (GSSException e) {
            throw new SaslException("Failure to initialize security context", e);
        }

        if (authzID != null && authzID.length() > 0) {
            try {
                this.authzID = authzID.getBytes("UTF8");
            } catch (IOException e) {
                throw new SaslException("Cannot encode authorization ID", e);
            }
        }
    }

    public boolean hasInitialResponse() {
        return true;
    }

    /**
     * Processes the challenge data.
     *
     * The server sends a challenge data using which the client must
     * process using GSS_Init_sec_context.
     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
     * an extra handshake to determine the negotiated security protection
     * and buffer sizes.
     *
     * @param challengeData A non-null byte array containing the
     * challenge data from the server.
     * @return A non-null byte array containing the response to be
     * sent to the server.
     */
    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
        if (completed) {
            throw new IllegalStateException(
                "GSSAPI authentication already complete");
        }

        if (finalHandshake) {
            return doFinalHandshake(challengeData);
        } else {

            // Security context not established yet; continue with init

            try {
                byte[] gssOutToken = secCtx.initSecContext(challengeData,
                    0, challengeData.length);
                if (logger.isLoggable(Level.FINER)) {
                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
                        "KRB5CLNT02:Challenge: [raw]", challengeData);
                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
                }

                if (secCtx.isEstablished()) {
                    finalHandshake = true;
                    if (gssOutToken == null) {
                        // RFC 2222 7.2.1:  Client responds with no data
                        return EMPTY;
                    }
                }

                return gssOutToken;
            } catch (GSSException e) {
                throw new SaslException("GSS initiate failed", e);
            }
        }
    }

    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
        try {
            // Security context already established. challengeData
            // should contain security layers and server's maximum buffer size

            if (logger.isLoggable(Level.FINER)) {
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
                    "KRB5CLNT04:Challenge [raw]:", challengeData);
            }

            if (challengeData.length == 0) {
                // Received S0, should return []
                return EMPTY;
            }

            // Received S1 (security layer, server max recv size)

            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
                challengeData.length, new MessageProp(0, false));

            // First octet is a bit-mask specifying the protections
            // supported by the server
            if (logger.isLoggable(Level.FINE)) {
                if (logger.isLoggable(Level.FINER)) {
                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
                }
                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
                    new Byte(gssOutToken[0]));
            }

            // Client selects preferred protection
            // qop is ordered list of qop values
            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
            if (selectedQop == 0) {
                throw new SaslException(
                    "No common protection layer between client and server");
            }

            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
                privacy = true;
                integrity = true;
            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
                integrity = true;
            }

            // 2nd-4th octets specifies maximum buffer size expected by
            // server (in network byte order)
            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);

            // Determine the max send buffer size based on what the
            // server is able to receive and our specified max
            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
                Math.min(sendMaxBufSize, srvMaxBufSize);

            // Update context to limit size of returned buffer
            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
                sendMaxBufSize);

            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE,
"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
                    new Object[] {new Integer(recvMaxBufSize),
                                  new Integer(srvMaxBufSize),
                                  new Integer(rawSendSize)});
            }

            // Construct negotiated security layers and client's max
            // receive buffer size and authzID
            int len = 4;
            if (authzID != null) {
                len += authzID.length;
            }

            byte[] gssInToken = new byte[len];
            gssInToken[0] = selectedQop;

            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE,
            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
                    new Object[]{new Byte(selectedQop),
                                 Boolean.valueOf(privacy),
                                 Boolean.valueOf(integrity)});
            }

            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
            if (authzID != null) {
                // copy authorization id
                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
            }

            if (logger.isLoggable(Level.FINER)) {
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
                    "KRB5CLNT10:Response [raw]", gssInToken);
            }

            gssOutToken = secCtx.wrap(gssInToken,
                0, gssInToken.length,
                new MessageProp(0 /* qop */, false /* privacy */));

            if (logger.isLoggable(Level.FINER)) {
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
            }

            completed = true;  // server authenticated

            return gssOutToken;
        } catch (GSSException e) {
            throw new SaslException("Final handshake failed", e);
        }
    }
}
