Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jgss/wrapper/GSSNameElement.java
38923 views
/*1* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.jgss.wrapper;2627import org.ietf.jgss.*;28import java.security.Provider;29import java.security.Security;30import java.io.IOException;31import java.io.UnsupportedEncodingException;32import sun.security.krb5.Realm;33import sun.security.jgss.GSSUtil;34import sun.security.util.ObjectIdentifier;35import sun.security.util.DerInputStream;36import sun.security.util.DerOutputStream;37import sun.security.jgss.GSSUtil;38import sun.security.jgss.GSSExceptionImpl;39import sun.security.jgss.spi.GSSNameSpi;4041import javax.security.auth.kerberos.ServicePermission;4243/**44* This class is essentially a wrapper class for the gss_name_t45* structure of the native GSS library.46* @author Valerie Peng47* @since 1.648*/4950public class GSSNameElement implements GSSNameSpi {5152long pName = 0; // Pointer to the gss_name_t structure53private String printableName;54private Oid printableType;55private GSSLibStub cStub;5657static final GSSNameElement DEF_ACCEPTOR = new GSSNameElement();5859private static Oid getNativeNameType(Oid nameType, GSSLibStub stub) {60if (GSSUtil.NT_GSS_KRB5_PRINCIPAL.equals(nameType)) {61Oid[] supportedNTs = null;62try {63supportedNTs = stub.inquireNamesForMech();64} catch (GSSException ge) {65if (ge.getMajor() == GSSException.BAD_MECH &&66GSSUtil.isSpNegoMech(stub.getMech())) {67// Workaround known Heimdal issue and retry with KRB568try {69stub = GSSLibStub.getInstance70(GSSUtil.GSS_KRB5_MECH_OID);71supportedNTs = stub.inquireNamesForMech();72} catch (GSSException ge2) {73// Should never happen74SunNativeProvider.debug("Name type list unavailable: " +75ge2.getMajorString());76}77} else {78SunNativeProvider.debug("Name type list unavailable: " +79ge.getMajorString());80}81}82if (supportedNTs != null) {83for (int i = 0; i < supportedNTs.length; i++) {84if (supportedNTs[i].equals(nameType)) return nameType;85}86// Special handling the specified name type87SunNativeProvider.debug("Override " + nameType +88" with mechanism default(null)");89return null; // Use mechanism specific default90}91}92return nameType;93}9495private GSSNameElement() {96printableName = "<DEFAULT ACCEPTOR>";97}9899GSSNameElement(long pNativeName, GSSLibStub stub) throws GSSException {100assert(stub != null);101if (pNativeName == 0) {102throw new GSSException(GSSException.BAD_NAME);103}104// Note: pNativeName is assumed to be a MN.105pName = pNativeName;106cStub = stub;107setPrintables();108}109110GSSNameElement(byte[] nameBytes, Oid nameType, GSSLibStub stub)111throws GSSException {112assert(stub != null);113if (nameBytes == null) {114throw new GSSException(GSSException.BAD_NAME);115}116cStub = stub;117byte[] name = nameBytes;118119if (nameType != null) {120// Special handling the specified name type if121// necessary122nameType = getNativeNameType(nameType, stub);123124if (GSSName.NT_EXPORT_NAME.equals(nameType)) {125// Need to add back the mech Oid portion (stripped126// off by GSSNameImpl class prior to calling this127// method) for "NT_EXPORT_NAME"128byte[] mechBytes = null;129DerOutputStream dout = new DerOutputStream();130Oid mech = cStub.getMech();131try {132dout.putOID(new ObjectIdentifier(mech.toString()));133} catch (IOException e) {134throw new GSSExceptionImpl(GSSException.FAILURE, e);135}136mechBytes = dout.toByteArray();137name = new byte[2 + 2 + mechBytes.length + 4 + nameBytes.length];138int pos = 0;139name[pos++] = 0x04;140name[pos++] = 0x01;141name[pos++] = (byte) (mechBytes.length>>>8);142name[pos++] = (byte) mechBytes.length;143System.arraycopy(mechBytes, 0, name, pos, mechBytes.length);144pos += mechBytes.length;145name[pos++] = (byte) (nameBytes.length>>>24);146name[pos++] = (byte) (nameBytes.length>>>16);147name[pos++] = (byte) (nameBytes.length>>>8);148name[pos++] = (byte) nameBytes.length;149System.arraycopy(nameBytes, 0, name, pos, nameBytes.length);150}151}152pName = cStub.importName(name, nameType);153setPrintables();154155SecurityManager sm = System.getSecurityManager();156if (sm != null && !Realm.AUTODEDUCEREALM) {157String krbName = getKrbName();158int atPos = krbName.lastIndexOf('@');159if (atPos != -1) {160String atRealm = krbName.substring(atPos);161// getNativeNameType() can modify NT_GSS_KRB5_PRINCIPAL to null162if ((nameType == null163|| nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))164&& new String(nameBytes).endsWith(atRealm)) {165// Created from Kerberos name with realm, no need to check166} else {167try {168sm.checkPermission(new ServicePermission(atRealm, "-"));169} catch (SecurityException se) {170// Do not chain the actual exception to hide info171throw new GSSException(GSSException.FAILURE);172}173}174}175}176177SunNativeProvider.debug("Imported " + printableName + " w/ type " +178printableType);179}180181private void setPrintables() throws GSSException {182Object[] printables = null;183printables = cStub.displayName(pName);184assert((printables != null) && (printables.length == 2));185printableName = (String) printables[0];186assert(printableName != null);187printableType = (Oid) printables[1];188if (printableType == null) {189printableType = GSSName.NT_USER_NAME;190}191}192193// Need to be public for GSSUtil.getSubject()194public String getKrbName() throws GSSException {195long mName = 0;196GSSLibStub stub = cStub;197if (!GSSUtil.isKerberosMech(cStub.getMech())) {198stub = GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID);199}200mName = stub.canonicalizeName(pName);201Object[] printables2 = stub.displayName(mName);202stub.releaseName(mName);203SunNativeProvider.debug("Got kerberized name: " + printables2[0]);204return (String) printables2[0];205}206207public Provider getProvider() {208return SunNativeProvider.INSTANCE;209}210211public boolean equals(GSSNameSpi other) throws GSSException {212if (!(other instanceof GSSNameElement)) {213return false;214}215return cStub.compareName(pName, ((GSSNameElement)other).pName);216}217218public boolean equals(Object other) {219if (!(other instanceof GSSNameElement)) {220return false;221}222try {223return equals((GSSNameElement) other);224} catch (GSSException ex) {225return false;226}227}228229public int hashCode() {230return new Long(pName).hashCode();231}232233public byte[] export() throws GSSException {234byte[] nameVal = cStub.exportName(pName);235236// Need to strip off the mech Oid portion of the exported237// bytes since GSSNameImpl class will subsequently add it.238int pos = 0;239if ((nameVal[pos++] != 0x04) ||240(nameVal[pos++] != 0x01))241throw new GSSException(GSSException.BAD_NAME);242243int mechOidLen = (((0xFF & nameVal[pos++]) << 8) |244(0xFF & nameVal[pos++]));245ObjectIdentifier temp = null;246try {247DerInputStream din = new DerInputStream(nameVal, pos,248mechOidLen);249temp = new ObjectIdentifier(din);250} catch (IOException e) {251throw new GSSExceptionImpl(GSSException.BAD_NAME, e);252}253Oid mech2 = new Oid(temp.toString());254assert(mech2.equals(getMechanism()));255pos += mechOidLen;256int mechPortionLen = (((0xFF & nameVal[pos++]) << 24) |257((0xFF & nameVal[pos++]) << 16) |258((0xFF & nameVal[pos++]) << 8) |259(0xFF & nameVal[pos++]));260if (mechPortionLen < 0) {261throw new GSSException(GSSException.BAD_NAME);262}263byte[] mechPortion = new byte[mechPortionLen];264System.arraycopy(nameVal, pos, mechPortion, 0, mechPortionLen);265return mechPortion;266}267268public Oid getMechanism() {269return cStub.getMech();270}271272public String toString() {273return printableName;274}275276public Oid getStringNameType() {277return printableType;278}279280public boolean isAnonymousName() {281return (GSSName.NT_ANONYMOUS.equals(printableType));282}283284public void dispose() {285if (pName != 0) {286cStub.releaseName(pName);287pName = 0;288}289}290291protected void finalize() throws Throwable {292dispose();293}294}295296297