view j2se/src/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java @ 7:807dfe9c366c trunk

[svn] Load openjdk/jdk7/b19 into jdk/trunk.
author xiomara
date Fri, 31 Aug 2007 00:44:13 +0000
parents a4ed3fb96592
children
line wrap: on
line source

/*
 * Copyright 2005-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.wrapper;

import java.io.UnsupportedEncodingException;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.util.Set;
import java.util.Vector;
import java.util.Iterator;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.*;
import org.ietf.jgss.*;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.GSSExceptionImpl;
import sun.security.jgss.spi.*;

/**
 * JGSS plugin for generic mechanisms provided through native GSS framework.
 *
 * @author Valerie Peng
 * @version 1.17, 08/08/07
 */

public final class NativeGSSFactory implements MechanismFactory {

    GSSLibStub cStub = null;
    private final int caller;

    private GSSCredElement getCredFromSubject(GSSNameElement name,
					      boolean initiate)
	throws GSSException {
	Oid mech = cStub.getMech();
	Vector<GSSCredElement> creds = GSSUtil.searchSubject
	    (name, mech, initiate, GSSCredElement.class);

	// If Subject is present but no native creds available 
	if (creds != null && creds.isEmpty()) { 
	    if (GSSUtil.useSubjectCredsOnly(caller)) { 
		throw new GSSException(GSSException.NO_CRED); 
	    }
	}

	GSSCredElement result = ((creds == null || creds.isEmpty()) ? 
				 null : creds.firstElement());
	// Force permission check before returning the cred to caller
	if (result != null) {
	    result.doServicePermCheck();
	}
	return result;
    }

    public NativeGSSFactory(int caller) {
	this.caller = caller;
	// Have to call setMech(Oid) explicitly before calling other
	// methods. Otherwise, NPE may be thrown unexpectantly
    }

    public void setMech(Oid mech) throws GSSException {
	cStub = GSSLibStub.getInstance(mech);
    }

    public GSSNameSpi getNameElement(String nameStr, Oid nameType)
	throws GSSException {
	try {
	    byte[] nameBytes = 
	        (nameStr == null ? null : nameStr.getBytes("UTF-8"));
	    return new GSSNameElement(nameBytes, nameType, cStub);
        } catch (UnsupportedEncodingException uee) {
            // Shouldn't happen
	    throw new GSSExceptionImpl(GSSException.FAILURE, uee);
        }
    }

    public GSSNameSpi getNameElement(byte[] name, Oid nameType)
	throws GSSException {
	return new GSSNameElement(name, nameType, cStub);
    }

    public GSSCredentialSpi getCredentialElement(GSSNameSpi name,
						 int initLifetime,
						 int acceptLifetime,
						 int usage)
	throws GSSException {
	GSSNameElement nname = null;
	if (name != null && !(name instanceof GSSNameElement)) {
	    nname = (GSSNameElement) 
		getNameElement(name.toString(), name.getStringNameType());
	} else nname = (GSSNameElement) name;

	if (usage == GSSCredential.INITIATE_AND_ACCEPT) {
	    // Force separate acqusition of cred element since
	    // MIT's impl does not correctly report NO_CRED error.
	    usage = GSSCredential.INITIATE_ONLY;
	}

	GSSCredElement credElement = 
	    getCredFromSubject((GSSNameElement) nname, 
			       (usage == GSSCredential.INITIATE_ONLY));

	if (credElement == null) {
	    // No cred in the Subject
	    if (usage == GSSCredential.INITIATE_ONLY) {
		credElement = new GSSCredElement(nname, initLifetime,
						 usage, cStub);
	    } else if (usage == GSSCredential.ACCEPT_ONLY) {
		if (nname == null) {
		    nname = GSSNameElement.DEF_ACCEPTOR;
		}
		credElement = new GSSCredElement(nname, acceptLifetime,
						 usage, cStub);
	    } else {
		throw new GSSException(GSSException.FAILURE, -1,
				       "Unknown usage mode requested");
	    }
	}
	return credElement;
    }

    public GSSContextSpi getMechanismContext(GSSNameSpi peer,
					     GSSCredentialSpi myCred,
					     int lifetime)
	throws GSSException {
	if (peer == null) {
	    throw new GSSException(GSSException.BAD_NAME);
	} else if (!(peer instanceof GSSNameElement)) {
	    peer = (GSSNameElement) 
		getNameElement(peer.toString(), peer.getStringNameType());
	}
	if (myCred == null) {
	    myCred = getCredFromSubject(null, true);
	} else if (!(myCred instanceof GSSCredElement)) {
	    throw new GSSException(GSSException.NO_CRED);
	}
	return new NativeGSSContext((GSSNameElement) peer,
				     (GSSCredElement) myCred,
				     lifetime, cStub);
    }

    public GSSContextSpi getMechanismContext(GSSCredentialSpi myCred)
	throws GSSException {
	if (myCred == null) {
	    myCred = getCredFromSubject(null, false);
	} else if (!(myCred instanceof GSSCredElement)) {
	    throw new GSSException(GSSException.NO_CRED);
	}
	return new NativeGSSContext((GSSCredElement) myCred, cStub);
    }

    public GSSContextSpi getMechanismContext(byte[] exportedContext)
	throws GSSException {
	return cStub.importContext(exportedContext);
    }

    public final Oid getMechanismOid() {
	return cStub.getMech();
    }

    public Provider getProvider() {
	return SunNativeProvider.INSTANCE;
    }

    public Oid[] getNameTypes() throws GSSException {
	return cStub.inquireNamesForMech();
    }
}