| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.security.jgss.wrapper;  | 
 | 
 | 
 | 
import org.ietf.jgss.*;  | 
 | 
import java.security.Provider;  | 
 | 
import java.security.Security;  | 
 | 
import java.io.IOException;  | 
 | 
import java.io.UnsupportedEncodingException;  | 
 | 
import sun.security.krb5.Realm;  | 
 | 
import sun.security.jgss.GSSUtil;  | 
 | 
import sun.security.util.ObjectIdentifier;  | 
 | 
import sun.security.util.DerInputStream;  | 
 | 
import sun.security.util.DerOutputStream;  | 
 | 
import sun.security.jgss.GSSUtil;  | 
 | 
import sun.security.jgss.GSSExceptionImpl;  | 
 | 
import sun.security.jgss.spi.GSSNameSpi;  | 
 | 
 | 
 | 
import javax.security.auth.kerberos.ServicePermission;  | 
 | 
 | 
 | 
/**  | 
 | 
 * This class is essentially a wrapper class for the gss_name_t  | 
 | 
 * structure of the native GSS library.  | 
 | 
 * @author Valerie Peng  | 
 | 
 * @since 1.6  | 
 | 
 */  | 
 | 
 | 
 | 
public class GSSNameElement implements GSSNameSpi { | 
 | 
 | 
 | 
    long pName = 0;   | 
 | 
    private String printableName;  | 
 | 
    private Oid printableType;  | 
 | 
    private GSSLibStub cStub;  | 
 | 
 | 
 | 
    static final GSSNameElement DEF_ACCEPTOR = new GSSNameElement();  | 
 | 
 | 
 | 
    private static Oid getNativeNameType(Oid nameType, GSSLibStub stub) { | 
 | 
        if (GSSUtil.NT_GSS_KRB5_PRINCIPAL.equals(nameType)) { | 
 | 
            Oid[] supportedNTs = null;  | 
 | 
            try { | 
 | 
                supportedNTs = stub.inquireNamesForMech();  | 
 | 
            } catch (GSSException ge) { | 
 | 
                if (ge.getMajor() == GSSException.BAD_MECH &&  | 
 | 
                    GSSUtil.isSpNegoMech(stub.getMech())) { | 
 | 
                      | 
 | 
                    try { | 
 | 
                        stub = GSSLibStub.getInstance  | 
 | 
                            (GSSUtil.GSS_KRB5_MECH_OID);  | 
 | 
                        supportedNTs = stub.inquireNamesForMech();  | 
 | 
                    } catch (GSSException ge2) { | 
 | 
                          | 
 | 
                        SunNativeProvider.debug("Name type list unavailable: " + | 
 | 
                            ge2.getMajorString());  | 
 | 
                    }  | 
 | 
                } else { | 
 | 
                    SunNativeProvider.debug("Name type list unavailable: " + | 
 | 
                        ge.getMajorString());  | 
 | 
                }  | 
 | 
            }  | 
 | 
            if (supportedNTs != null) { | 
 | 
                for (int i = 0; i < supportedNTs.length; i++) { | 
 | 
                    if (supportedNTs[i].equals(nameType)) return nameType;  | 
 | 
                }  | 
 | 
                  | 
 | 
                SunNativeProvider.debug("Override " + nameType + | 
 | 
                    " with mechanism default(null)");  | 
 | 
                return null;   | 
 | 
            }  | 
 | 
        }  | 
 | 
        return nameType;  | 
 | 
    }  | 
 | 
 | 
 | 
    private GSSNameElement() { | 
 | 
        printableName = "<DEFAULT ACCEPTOR>";  | 
 | 
    }  | 
 | 
 | 
 | 
    GSSNameElement(long pNativeName, GSSLibStub stub) throws GSSException { | 
 | 
        assert(stub != null);  | 
 | 
        if (pNativeName == 0) { | 
 | 
            throw new GSSException(GSSException.BAD_NAME);  | 
 | 
        }  | 
 | 
          | 
 | 
        pName = pNativeName;  | 
 | 
        cStub = stub;  | 
 | 
        setPrintables();  | 
 | 
    }  | 
 | 
 | 
 | 
    GSSNameElement(byte[] nameBytes, Oid nameType, GSSLibStub stub)  | 
 | 
        throws GSSException { | 
 | 
        assert(stub != null);  | 
 | 
        if (nameBytes == null) { | 
 | 
            throw new GSSException(GSSException.BAD_NAME);  | 
 | 
        }  | 
 | 
        cStub = stub;  | 
 | 
        byte[] name = nameBytes;  | 
 | 
 | 
 | 
        if (nameType != null) { | 
 | 
            // Special handling the specified name type if  | 
 | 
              | 
 | 
            nameType = getNativeNameType(nameType, stub);  | 
 | 
 | 
 | 
            if (GSSName.NT_EXPORT_NAME.equals(nameType)) { | 
 | 
                // Need to add back the mech Oid portion (stripped  | 
 | 
                // off by GSSNameImpl class prior to calling this  | 
 | 
                  | 
 | 
                byte[] mechBytes = null;  | 
 | 
                DerOutputStream dout = new DerOutputStream();  | 
 | 
                Oid mech = cStub.getMech();  | 
 | 
                try { | 
 | 
                    dout.putOID(new ObjectIdentifier(mech.toString()));  | 
 | 
                } catch (IOException e) { | 
 | 
                    throw new GSSExceptionImpl(GSSException.FAILURE, e);  | 
 | 
                }  | 
 | 
                mechBytes = dout.toByteArray();  | 
 | 
                name = new byte[2 + 2 + mechBytes.length + 4 + nameBytes.length];  | 
 | 
                int pos = 0;  | 
 | 
                name[pos++] = 0x04;  | 
 | 
                name[pos++] = 0x01;  | 
 | 
                name[pos++] = (byte) (mechBytes.length>>>8);  | 
 | 
                name[pos++] = (byte) mechBytes.length;  | 
 | 
                System.arraycopy(mechBytes, 0, name, pos, mechBytes.length);  | 
 | 
                pos += mechBytes.length;  | 
 | 
                name[pos++] = (byte) (nameBytes.length>>>24);  | 
 | 
                name[pos++] = (byte) (nameBytes.length>>>16);  | 
 | 
                name[pos++] = (byte) (nameBytes.length>>>8);  | 
 | 
                name[pos++] = (byte) nameBytes.length;  | 
 | 
                System.arraycopy(nameBytes, 0, name, pos, nameBytes.length);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        pName = cStub.importName(name, nameType);  | 
 | 
        setPrintables();  | 
 | 
 | 
 | 
        SecurityManager sm = System.getSecurityManager();  | 
 | 
        if (sm != null && !Realm.AUTODEDUCEREALM) { | 
 | 
            String krbName = getKrbName();  | 
 | 
            int atPos = krbName.lastIndexOf('@'); | 
 | 
            if (atPos != -1) { | 
 | 
                String atRealm = krbName.substring(atPos);  | 
 | 
                  | 
 | 
                if ((nameType == null  | 
 | 
                            || nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL))  | 
 | 
                        && new String(nameBytes).endsWith(atRealm)) { | 
 | 
                    // Created from Kerberos name with realm, no need to check  | 
 | 
                } else { | 
 | 
                    try { | 
 | 
                        sm.checkPermission(new ServicePermission(atRealm, "-"));  | 
 | 
                    } catch (SecurityException se) { | 
 | 
                          | 
 | 
                        throw new GSSException(GSSException.FAILURE);  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        SunNativeProvider.debug("Imported " + printableName + " w/ type " + | 
 | 
                                printableType);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void setPrintables() throws GSSException { | 
 | 
        Object[] printables = null;  | 
 | 
        printables = cStub.displayName(pName);  | 
 | 
        assert((printables != null) && (printables.length == 2));  | 
 | 
        printableName = (String) printables[0];  | 
 | 
        assert(printableName != null);  | 
 | 
        printableType = (Oid) printables[1];  | 
 | 
        if (printableType == null) { | 
 | 
            printableType = GSSName.NT_USER_NAME;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
    public String getKrbName() throws GSSException { | 
 | 
        long mName = 0;  | 
 | 
        GSSLibStub stub = cStub;  | 
 | 
        if (!GSSUtil.isKerberosMech(cStub.getMech())) { | 
 | 
            stub = GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID);  | 
 | 
        }  | 
 | 
        mName = stub.canonicalizeName(pName);  | 
 | 
        Object[] printables2 = stub.displayName(mName);  | 
 | 
        stub.releaseName(mName);  | 
 | 
        SunNativeProvider.debug("Got kerberized name: " + printables2[0]); | 
 | 
        return (String) printables2[0];  | 
 | 
    }  | 
 | 
 | 
 | 
    public Provider getProvider() { | 
 | 
        return SunNativeProvider.INSTANCE;  | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean equals(GSSNameSpi other) throws GSSException { | 
 | 
        if (!(other instanceof GSSNameElement)) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
        return cStub.compareName(pName, ((GSSNameElement)other).pName);  | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean equals(Object other) { | 
 | 
        if (!(other instanceof GSSNameElement)) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
        try { | 
 | 
            return equals((GSSNameElement) other);  | 
 | 
        } catch (GSSException ex) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public int hashCode() { | 
 | 
        return new Long(pName).hashCode();  | 
 | 
    }  | 
 | 
 | 
 | 
    public byte[] export() throws GSSException { | 
 | 
        byte[] nameVal = cStub.exportName(pName);  | 
 | 
 | 
 | 
        // Need to strip off the mech Oid portion of the exported  | 
 | 
          | 
 | 
        int pos = 0;  | 
 | 
        if ((nameVal[pos++] != 0x04) ||  | 
 | 
            (nameVal[pos++] != 0x01))  | 
 | 
            throw new GSSException(GSSException.BAD_NAME);  | 
 | 
 | 
 | 
        int mechOidLen  = (((0xFF & nameVal[pos++]) << 8) |  | 
 | 
                           (0xFF & nameVal[pos++]));  | 
 | 
        ObjectIdentifier temp = null;  | 
 | 
        try { | 
 | 
            DerInputStream din = new DerInputStream(nameVal, pos,  | 
 | 
                                                    mechOidLen);  | 
 | 
            temp = new ObjectIdentifier(din);  | 
 | 
        } catch (IOException e) { | 
 | 
            throw new GSSExceptionImpl(GSSException.BAD_NAME, e);  | 
 | 
        }  | 
 | 
        Oid mech2 = new Oid(temp.toString());  | 
 | 
        assert(mech2.equals(getMechanism()));  | 
 | 
        pos += mechOidLen;  | 
 | 
        int mechPortionLen = (((0xFF & nameVal[pos++]) << 24) |  | 
 | 
                              ((0xFF & nameVal[pos++]) << 16) |  | 
 | 
                              ((0xFF & nameVal[pos++]) << 8) |  | 
 | 
                              (0xFF & nameVal[pos++]));  | 
 | 
        if (mechPortionLen < 0) { | 
 | 
            throw new GSSException(GSSException.BAD_NAME);  | 
 | 
        }  | 
 | 
        byte[] mechPortion = new byte[mechPortionLen];  | 
 | 
        System.arraycopy(nameVal, pos, mechPortion, 0, mechPortionLen);  | 
 | 
        return mechPortion;  | 
 | 
    }  | 
 | 
 | 
 | 
    public Oid getMechanism() { | 
 | 
        return cStub.getMech();  | 
 | 
    }  | 
 | 
 | 
 | 
    public String toString() { | 
 | 
        return printableName;  | 
 | 
    }  | 
 | 
 | 
 | 
    public Oid getStringNameType() { | 
 | 
        return printableType;  | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean isAnonymousName() { | 
 | 
        return (GSSName.NT_ANONYMOUS.equals(printableType));  | 
 | 
    }  | 
 | 
 | 
 | 
    public void dispose() { | 
 | 
        if (pName != 0) { | 
 | 
            cStub.releaseName(pName);  | 
 | 
            pName = 0;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    protected void finalize() throws Throwable { | 
 | 
        dispose();  | 
 | 
    }  | 
 | 
}  |