/*
 * 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 sun.security.jgss.krb5;

import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.spi.*;
import javax.security.auth.kerberos.ServicePermission;
import java.security.Provider;
import sun.security.util.DerOutputStream;
import sun.security.util.ObjectIdentifier;
import java.io.IOException;
import java.util.Vector;

/**
 * Krb5 Mechanism plug in for JGSS
 * This is the properties object required by the JGSS framework.
 * All mechanism specific information is defined here.
 *
 * @author Mayank Upadhyay
 */

public final class Krb5MechFactory implements MechanismFactory {

    private static final boolean DEBUG = Krb5Util.DEBUG;

    static final Provider PROVIDER =
        new sun.security.jgss.SunProvider();

    static final Oid GSS_KRB5_MECH_OID =
        createOid("1.2.840.113554.1.2.2");

    static final Oid NT_GSS_KRB5_PRINCIPAL =
        createOid("1.2.840.113554.1.2.2.1");

    private static Oid[] nameTypes =
        new Oid[] { GSSName.NT_USER_NAME,
                        GSSName.NT_HOSTBASED_SERVICE,
                        GSSName.NT_EXPORT_NAME,
                        NT_GSS_KRB5_PRINCIPAL};

    final private int caller;

    private static Krb5CredElement getCredFromSubject(GSSNameSpi name,
                                                      boolean initiate)
        throws GSSException {
        Vector<Krb5CredElement> creds =
            GSSUtil.searchSubject(name, GSS_KRB5_MECH_OID, initiate,
                                  (initiate ?
                                   Krb5InitCredential.class :
                                   Krb5AcceptCredential.class));

        Krb5CredElement result = ((creds == null || creds.isEmpty()) ?
                                  null : creds.firstElement());

        // Force permission check before returning the cred to caller
        if (result != null) {
            if (initiate) {
                checkInitCredPermission((Krb5NameElement) result.getName());
            } else {
                checkAcceptCredPermission
                    ((Krb5NameElement) result.getName(), name);
            }
        }
        return result;
    }

    public Krb5MechFactory(int caller) {
        this.caller = caller;
    }

    public GSSNameSpi getNameElement(String nameStr, Oid nameType)
        throws GSSException {
        return Krb5NameElement.getInstance(nameStr, nameType);
    }

    public GSSNameSpi getNameElement(byte[] name, Oid nameType)
        throws GSSException {
        // At this point, even an exported name is stripped down to safe
        // bytes only
        // XXX Use encoding here
        return Krb5NameElement.getInstance(new String(name), nameType);
    }

    public GSSCredentialSpi getCredentialElement(GSSNameSpi name,
           int initLifetime, int acceptLifetime,
           int usage) throws GSSException {

        if (name != null && !(name instanceof Krb5NameElement)) {
            name = Krb5NameElement.getInstance(name.toString(),
                                       name.getStringNameType());
        }

        Krb5CredElement credElement = getCredFromSubject
            (name, (usage != GSSCredential.ACCEPT_ONLY));

        if (credElement == null) {
            if (usage == GSSCredential.INITIATE_ONLY ||
                usage == GSSCredential.INITIATE_AND_ACCEPT) {
                credElement = Krb5InitCredential.getInstance
                    (caller, (Krb5NameElement) name, initLifetime);
                checkInitCredPermission
                    ((Krb5NameElement) credElement.getName());
            } else if (usage == GSSCredential.ACCEPT_ONLY) {
                credElement =
                    Krb5AcceptCredential.getInstance(caller,
                                                     (Krb5NameElement) name);
                checkAcceptCredPermission
                    ((Krb5NameElement) credElement.getName(), name);
            } else
                throw new GSSException(GSSException.FAILURE, -1,
                                       "Unknown usage mode requested");
        }
        return credElement;
    }

    public static void checkInitCredPermission(Krb5NameElement name) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            String realm = (name.getKrb5PrincipalName()).getRealmAsString();
            String tgsPrincipal =
                new String("krbtgt/" + realm + '@' + realm);
            ServicePermission perm =
                new ServicePermission(tgsPrincipal, "initiate");
            try {
                sm.checkPermission(perm);
            } catch (SecurityException e) {
                if (DEBUG) {
                    System.out.println("Permission to initiate" +
                        "kerberos init credential" + e.getMessage());
                }
                throw e;
            }
        }
    }

    public static void checkAcceptCredPermission(Krb5NameElement name,
                                           GSSNameSpi originalName) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ServicePermission perm = new ServicePermission
                (name.getKrb5PrincipalName().getName(), "accept");
            try {
                sm.checkPermission(perm);
            } catch (SecurityException e) {
                if (originalName == null) {
                    // Don't disclose the name of the principal
                    e = new SecurityException("No permission to acquire "
                                      + "Kerberos accept credential");
                    // Don't call e.initCause() with caught exception
                }
                throw e;
            }
        }
    }

    public GSSContextSpi getMechanismContext(GSSNameSpi peer,
                             GSSCredentialSpi myInitiatorCred, int lifetime)
        throws GSSException {
        if (peer != null && !(peer instanceof Krb5NameElement)) {
            peer = Krb5NameElement.getInstance(peer.toString(),
                                       peer.getStringNameType());
        }
        // XXX Convert myInitiatorCred to Krb5CredElement
        if (myInitiatorCred == null) {
            myInitiatorCred = getCredentialElement(null, lifetime, 0,
                GSSCredential.INITIATE_ONLY);
        }
        return new Krb5Context(caller, (Krb5NameElement)peer,
                               (Krb5CredElement)myInitiatorCred, lifetime);
    }

    public GSSContextSpi getMechanismContext(GSSCredentialSpi myAcceptorCred)
        throws GSSException {
        // XXX Convert myAcceptorCred to Krb5CredElement
        if (myAcceptorCred == null) {
            myAcceptorCred = getCredentialElement(null, 0,
                GSSCredential.INDEFINITE_LIFETIME, GSSCredential.ACCEPT_ONLY);
        }
        return new Krb5Context(caller, (Krb5CredElement)myAcceptorCred);
    }

    public GSSContextSpi getMechanismContext(byte[] exportedContext)
        throws GSSException {
        return new Krb5Context(caller, exportedContext);
    }


    public final Oid getMechanismOid() {
        return GSS_KRB5_MECH_OID;
    }

    public Provider getProvider() {
        return PROVIDER;
    }

    public Oid[] getNameTypes() {
        // nameTypes is cloned in GSSManager.getNamesForMech
        return nameTypes;
    }

    private static Oid createOid(String oidStr) {
        Oid retVal = null;
        try {
            retVal = new Oid(oidStr);
        } catch (GSSException e) {
            // Should not happen!
        }
        return retVal;
    }
}
