/*
 * Copyright (c) 2000, 2012, 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.security.jgss.krb5;

import org.ietf.jgss.*;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;
import sun.security.krb5.*;
import sun.security.krb5.Config;
import javax.security.auth.kerberos.*;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Date;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

/**
 * Implements the krb5 initiator credential element.
 *
 * @author Mayank Upadhyay
 * @author Ram Marti
 * @since 1.4
 */

public class Krb5InitCredential
    extends KerberosTicket
    implements Krb5CredElement {

    private static final long serialVersionUID = 7723415700837898232L;

    private Krb5NameElement name;
    private Credentials krb5Credentials;

    private Krb5InitCredential(Krb5NameElement name,
                               byte[] asn1Encoding,
                               KerberosPrincipal client,
                               KerberosPrincipal server,
                               byte[] sessionKey,
                               int keyType,
                               boolean[] flags,
                               Date authTime,
                               Date startTime,
                               Date endTime,
                               Date renewTill,
                               InetAddress[] clientAddresses)
                               throws GSSException {
        super(asn1Encoding,
              client,
              server,
              sessionKey,
              keyType,
              flags,
              authTime,
              startTime,
              endTime,
              renewTill,
              clientAddresses);

        this.name = name;

        try {
            // Cache this for later use by the sun.security.krb5 package.
            krb5Credentials = new Credentials(asn1Encoding,
                                              client.getName(),
                                              server.getName(),
                                              sessionKey,
                                              keyType,
                                              flags,
                                              authTime,
                                              startTime,
                                              endTime,
                                              renewTill,
                                              clientAddresses);
        } catch (KrbException e) {
            throw new GSSException(GSSException.NO_CRED, -1,
                                   e.getMessage());
        } catch (IOException e) {
            throw new GSSException(GSSException.NO_CRED, -1,
                                   e.getMessage());
        }

    }

    private Krb5InitCredential(Krb5NameElement name,
                               Credentials delegatedCred,
                               byte[] asn1Encoding,
                               KerberosPrincipal client,
                               KerberosPrincipal server,
                               byte[] sessionKey,
                               int keyType,
                               boolean[] flags,
                               Date authTime,
                               Date startTime,
                               Date endTime,
                               Date renewTill,
                               InetAddress[] clientAddresses)
                               throws GSSException {
        super(asn1Encoding,
              client,
              server,
              sessionKey,
              keyType,
              flags,
              authTime,
              startTime,
              endTime,
              renewTill,
              clientAddresses);

        this.name = name;
        // A delegated cred does not have all fields set. So do not try to
        // creat new Credentials out of the delegatedCred.
        this.krb5Credentials = delegatedCred;
    }

    static Krb5InitCredential getInstance(GSSCaller caller, Krb5NameElement name,
                                   int initLifetime)
        throws GSSException {

        KerberosTicket tgt = getTgt(caller, name, initLifetime);
        if (tgt == null)
            throw new GSSException(GSSException.NO_CRED, -1,
                                   "Failed to find any Kerberos tgt");

        if (name == null) {
            String fullName = tgt.getClient().getName();
            name = Krb5NameElement.getInstance(fullName,
                                       Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
        }

        return new Krb5InitCredential(name,
                                      tgt.getEncoded(),
                                      tgt.getClient(),
                                      tgt.getServer(),
                                      tgt.getSessionKey().getEncoded(),
                                      tgt.getSessionKeyType(),
                                      tgt.getFlags(),
                                      tgt.getAuthTime(),
                                      tgt.getStartTime(),
                                      tgt.getEndTime(),
                                      tgt.getRenewTill(),
                                      tgt.getClientAddresses());
    }

    static Krb5InitCredential getInstance(Krb5NameElement name,
                                   Credentials delegatedCred)
        throws GSSException {

        EncryptionKey sessionKey = delegatedCred.getSessionKey();

        /*
         * all of the following data is optional in a KRB-CRED
         * messages. This check for each field.
         */

        PrincipalName cPrinc = delegatedCred.getClient();
        PrincipalName sPrinc = delegatedCred.getServer();

        KerberosPrincipal client = null;
        KerberosPrincipal server = null;

        Krb5NameElement credName = null;

        if (cPrinc != null) {
            String fullName = cPrinc.getName();
            credName = Krb5NameElement.getInstance(fullName,
                               Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
            client =  new KerberosPrincipal(fullName);
        }

        // XXX Compare name to credName

        if (sPrinc != null) {
            server =
                new KerberosPrincipal(sPrinc.getName(),
                                        KerberosPrincipal.KRB_NT_SRV_INST);
        }

        return new Krb5InitCredential(credName,
                                      delegatedCred,
                                      delegatedCred.getEncoded(),
                                      client,
                                      server,
                                      sessionKey.getBytes(),
                                      sessionKey.getEType(),
                                      delegatedCred.getFlags(),
                                      delegatedCred.getAuthTime(),
                                      delegatedCred.getStartTime(),
                                      delegatedCred.getEndTime(),
                                      delegatedCred.getRenewTill(),
                                      delegatedCred.getClientAddresses());
    }

    /**
     * Returns the principal name for this credential. The name
     * is in mechanism specific format.
     *
     * @return GSSNameSpi representing principal name of this credential
     * @exception GSSException may be thrown
     */
    public final GSSNameSpi getName() throws GSSException {
        return name;
    }

    /**
     * Returns the init lifetime remaining.
     *
     * @return the init lifetime remaining in seconds
     * @exception GSSException may be thrown
     */
    public int getInitLifetime() throws GSSException {
        int retVal = 0;
        retVal = (int)(getEndTime().getTime()
                       - (new Date().getTime()));

        return retVal/1000;
    }

    /**
     * Returns the accept lifetime remaining.
     *
     * @return the accept lifetime remaining in seconds
     * @exception GSSException may be thrown
     */
    public int getAcceptLifetime() throws GSSException {
        return 0;
    }

    public boolean isInitiatorCredential() throws GSSException {
        return true;
    }

    public boolean isAcceptorCredential() throws GSSException {
        return false;
    }

    /**
     * Returns the oid representing the underlying credential
     * mechanism oid.
     *
     * @return the Oid for this credential mechanism
     * @exception GSSException may be thrown
     */
    public final Oid getMechanism() {
        return Krb5MechFactory.GSS_KRB5_MECH_OID;
    }

    public final java.security.Provider getProvider() {
        return Krb5MechFactory.PROVIDER;
    }


    /**
     * Returns a sun.security.krb5.Credentials instance so that it maybe
     * used in that package for th Kerberos protocol.
     */
    Credentials getKrb5Credentials() {
        return krb5Credentials;
    }

    /*
     * XXX Call to this.refresh() should refresh the locally cached copy
     * of krb5Credentials also.
     */

    /**
     * Called to invalidate this credential element.
     */
    public void dispose() throws GSSException {
        try {
            destroy();
        } catch (javax.security.auth.DestroyFailedException e) {
            GSSException gssException =
                new GSSException(GSSException.FAILURE, -1,
                 "Could not destroy credentials - " + e.getMessage());
            gssException.initCause(e);
        }
    }

    // XXX call to this.destroy() should destroy the locally cached copy
    // of krb5Credentials and then call super.destroy().

    private static KerberosTicket getTgt(GSSCaller caller, Krb5NameElement name,
                                                 int initLifetime)
        throws GSSException {

        final String clientPrincipal;

        /*
         * Find the TGT for the realm that the client is in. If the client
         * name is not available, then use the default realm.
         */
        if (name != null) {
            clientPrincipal = (name.getKrb5PrincipalName()).getName();
        } else {
            clientPrincipal = null;
        }

        final AccessControlContext acc = AccessController.getContext();

        try {
            final GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN)
                                   ? GSSCaller.CALLER_INITIATE
                                   : caller;
            return AccessController.doPrivileged(
                new PrivilegedExceptionAction<KerberosTicket>() {
                public KerberosTicket run() throws Exception {
                    // It's OK to use null as serverPrincipal. TGT is almost
                    // the first ticket for a principal and we use list.
                    return Krb5Util.getTicket(
                        realCaller,
                        clientPrincipal, null, acc);
                        }});
        } catch (PrivilegedActionException e) {
            GSSException ge =
                new GSSException(GSSException.NO_CRED, -1,
                    "Attempt to obtain new INITIATE credentials failed!" +
                    " (" + e.getMessage() + ")");
            ge.initCause(e.getException());
            throw ge;
        }
    }

    @Override
    public GSSCredentialSpi impersonate(GSSNameSpi name) throws GSSException {
        try {
            Krb5NameElement kname = (Krb5NameElement)name;
            Credentials newCred = Credentials.acquireS4U2selfCreds(
                    kname.getKrb5PrincipalName(), krb5Credentials);
            return new Krb5ProxyCredential(this, kname, newCred.getTicket());
        } catch (IOException | KrbException ke) {
            GSSException ge =
                new GSSException(GSSException.FAILURE, -1,
                    "Attempt to obtain S4U2self credentials failed!");
            ge.initCause(ke);
            throw ge;
        }
    }
}
