| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package sun.security.jgss.spnego;  | 
 | 
 | 
 | 
import com.sun.security.jgss.ExtendedGSSContext;  | 
 | 
import com.sun.security.jgss.InquireType;  | 
 | 
import java.io.*;  | 
 | 
import java.security.Provider;  | 
 | 
import org.ietf.jgss.*;  | 
 | 
import sun.security.jgss.*;  | 
 | 
import sun.security.jgss.spi.*;  | 
 | 
import sun.security.util.*;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class SpNegoContext implements GSSContextSpi { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private static final int STATE_NEW = 1;  | 
 | 
    private static final int STATE_IN_PROCESS = 2;  | 
 | 
    private static final int STATE_DONE = 3;  | 
 | 
    private static final int STATE_DELETED = 4;  | 
 | 
 | 
 | 
    private int state = STATE_NEW;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private boolean credDelegState = false;  | 
 | 
    private boolean mutualAuthState = true;  | 
 | 
    private boolean replayDetState = true;  | 
 | 
    private boolean sequenceDetState = true;  | 
 | 
    private boolean confState = true;  | 
 | 
    private boolean integState = true;  | 
 | 
    private boolean delegPolicyState = false;  | 
 | 
 | 
 | 
    private GSSNameSpi peerName = null;  | 
 | 
    private GSSNameSpi myName = null;  | 
 | 
    private SpNegoCredElement myCred = null;  | 
 | 
 | 
 | 
    private GSSContext mechContext = null;  | 
 | 
    private byte[] DER_mechTypes = null;  | 
 | 
 | 
 | 
    private int lifetime;  | 
 | 
    private ChannelBinding channelBinding;  | 
 | 
    private boolean initiator;  | 
 | 
 | 
 | 
      | 
 | 
    private Oid internal_mech = null;  | 
 | 
 | 
 | 
      | 
 | 
    final private SpNegoMechFactory factory;  | 
 | 
 | 
 | 
      | 
 | 
    static final boolean DEBUG =  | 
 | 
        java.security.AccessController.doPrivileged(  | 
 | 
            new sun.security.action.GetBooleanAction  | 
 | 
            ("sun.security.spnego.debug")).booleanValue(); | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public SpNegoContext(SpNegoMechFactory factory, GSSNameSpi peerName,  | 
 | 
                        GSSCredentialSpi myCred,  | 
 | 
                        int lifetime) throws GSSException { | 
 | 
 | 
 | 
        if (peerName == null)  | 
 | 
            throw new IllegalArgumentException("Cannot have null peer name"); | 
 | 
        if ((myCred != null) && !(myCred instanceof SpNegoCredElement)) { | 
 | 
            throw new IllegalArgumentException("Wrong cred element type"); | 
 | 
        }  | 
 | 
        this.peerName = peerName;  | 
 | 
        this.myCred = (SpNegoCredElement) myCred;  | 
 | 
        this.lifetime = lifetime;  | 
 | 
        this.initiator = true;  | 
 | 
        this.factory = factory;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public SpNegoContext(SpNegoMechFactory factory, GSSCredentialSpi myCred)  | 
 | 
            throws GSSException { | 
 | 
        if ((myCred != null) && !(myCred instanceof SpNegoCredElement)) { | 
 | 
            throw new IllegalArgumentException("Wrong cred element type"); | 
 | 
        }  | 
 | 
        this.myCred = (SpNegoCredElement) myCred;  | 
 | 
        this.initiator = false;  | 
 | 
        this.factory = factory;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public SpNegoContext(SpNegoMechFactory factory, byte [] interProcessToken)  | 
 | 
        throws GSSException { | 
 | 
        throw new GSSException(GSSException.UNAVAILABLE,  | 
 | 
                               -1, "GSS Import Context not available");  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestConf(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            confState  = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getConfState() { | 
 | 
        return confState;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestInteg(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            integState  = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestDelegPolicy(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            delegPolicyState = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getIntegState() { | 
 | 
        return integState;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getDelegPolicyState() { | 
 | 
        if (isInitiator() && mechContext != null &&  | 
 | 
                mechContext instanceof ExtendedGSSContext &&  | 
 | 
                (state == STATE_IN_PROCESS || state == STATE_DONE)) { | 
 | 
            return ((ExtendedGSSContext)mechContext).getDelegPolicyState();  | 
 | 
        } else { | 
 | 
            return delegPolicyState;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestCredDeleg(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            credDelegState  = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getCredDelegState() { | 
 | 
        if (isInitiator() && mechContext != null &&  | 
 | 
                (state == STATE_IN_PROCESS || state == STATE_DONE)) { | 
 | 
            return mechContext.getCredDelegState();  | 
 | 
        } else { | 
 | 
            return credDelegState;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestMutualAuth(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator()) { | 
 | 
            mutualAuthState  = value;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getMutualAuthState() { | 
 | 
        return mutualAuthState;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final Oid getMech() { | 
 | 
        if (isEstablished()) { | 
 | 
            return getNegotiatedMech();  | 
 | 
        }  | 
 | 
        return (SpNegoMechFactory.GSS_SPNEGO_MECH_OID);  | 
 | 
    }  | 
 | 
 | 
 | 
    public final Oid getNegotiatedMech() { | 
 | 
        return (internal_mech);  | 
 | 
    }  | 
 | 
 | 
 | 
    public final Provider getProvider() { | 
 | 
        return SpNegoMechFactory.PROVIDER;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void dispose() throws GSSException { | 
 | 
        mechContext = null;  | 
 | 
        state = STATE_DELETED;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean isInitiator() { | 
 | 
        return initiator;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean isProtReady() { | 
 | 
        return (state == STATE_DONE);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final byte[] initSecContext(InputStream is, int mechTokenSize)  | 
 | 
        throws GSSException { | 
 | 
 | 
 | 
        byte[] retVal = null;  | 
 | 
        NegTokenInit initToken = null;  | 
 | 
        byte[] mechToken = null;  | 
 | 
        int errorCode = GSSException.FAILURE;  | 
 | 
 | 
 | 
        if (DEBUG) { | 
 | 
            System.out.println("Entered SpNego.initSecContext with " + | 
 | 
                                "state=" + printState(state));  | 
 | 
        }  | 
 | 
        if (!isInitiator()) { | 
 | 
            throw new GSSException(GSSException.FAILURE, -1,  | 
 | 
                "initSecContext on an acceptor GSSContext");  | 
 | 
        }  | 
 | 
 | 
 | 
        try { | 
 | 
            if (state == STATE_NEW) { | 
 | 
                state = STATE_IN_PROCESS;  | 
 | 
 | 
 | 
                errorCode = GSSException.NO_CRED;  | 
 | 
 | 
 | 
                  | 
 | 
                Oid[] mechList = getAvailableMechs();  | 
 | 
                DER_mechTypes = getEncodedMechs(mechList);  | 
 | 
 | 
 | 
                  | 
 | 
                internal_mech = mechList[0];  | 
 | 
 | 
 | 
                  | 
 | 
                mechToken = GSS_initSecContext(null);  | 
 | 
 | 
 | 
                errorCode = GSSException.DEFECTIVE_TOKEN;  | 
 | 
                  | 
 | 
                initToken = new NegTokenInit(DER_mechTypes, getContextFlags(),  | 
 | 
                                        mechToken, null);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.initSecContext: " + | 
 | 
                                "sending token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(initToken.getType()));  | 
 | 
                }  | 
 | 
                  | 
 | 
                retVal = initToken.getEncoded();  | 
 | 
 | 
 | 
            } else if (state == STATE_IN_PROCESS) { | 
 | 
 | 
 | 
                errorCode = GSSException.FAILURE;  | 
 | 
                if (is == null) { | 
 | 
                    throw new GSSException(errorCode, -1,  | 
 | 
                                "No token received from peer!");  | 
 | 
                }  | 
 | 
 | 
 | 
                errorCode = GSSException.DEFECTIVE_TOKEN;  | 
 | 
                byte[] server_token = new byte[is.available()];  | 
 | 
                SpNegoToken.readFully(is, server_token);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.initSecContext: " + | 
 | 
                                        "process received token = " +  | 
 | 
                                        SpNegoToken.getHexBytes(server_token));  | 
 | 
                }  | 
 | 
 | 
 | 
                // read the SPNEGO token  | 
 | 
                  | 
 | 
                NegTokenTarg targToken = new NegTokenTarg(server_token);  | 
 | 
 | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.initSecContext: " + | 
 | 
                                "received token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(targToken.getType()));  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                internal_mech = targToken.getSupportedMech();  | 
 | 
                if (internal_mech == null) { | 
 | 
                      | 
 | 
                    throw new GSSException(errorCode, -1,  | 
 | 
                                "supported mechanism from server is null");  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                SpNegoToken.NegoResult negoResult = null;  | 
 | 
                int result = targToken.getNegotiatedResult();  | 
 | 
                switch (result) { | 
 | 
                    case 0:  | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;  | 
 | 
                        state = STATE_DONE;  | 
 | 
                        break;  | 
 | 
                    case 1:  | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;  | 
 | 
                        state = STATE_IN_PROCESS;  | 
 | 
                        break;  | 
 | 
                    case 2:  | 
 | 
                        negoResult = SpNegoToken.NegoResult.REJECT;  | 
 | 
                        state = STATE_DELETED;  | 
 | 
                        break;  | 
 | 
                    default:  | 
 | 
                        state = STATE_DONE;  | 
 | 
                        break;  | 
 | 
                }  | 
 | 
 | 
 | 
                errorCode = GSSException.BAD_MECH;  | 
 | 
 | 
 | 
                if (negoResult == SpNegoToken.NegoResult.REJECT) { | 
 | 
                    throw new GSSException(errorCode, -1,  | 
 | 
                                        internal_mech.toString());  | 
 | 
                }  | 
 | 
 | 
 | 
                errorCode = GSSException.DEFECTIVE_TOKEN;  | 
 | 
 | 
 | 
                if ((negoResult == SpNegoToken.NegoResult.ACCEPT_COMPLETE) ||  | 
 | 
                    (negoResult == SpNegoToken.NegoResult.ACCEPT_INCOMPLETE)) { | 
 | 
 | 
 | 
                      | 
 | 
                    byte[] accept_token = targToken.getResponseToken();  | 
 | 
                    if (accept_token == null) { | 
 | 
                        if (!isMechContextEstablished()) { | 
 | 
                              | 
 | 
                            throw new GSSException(errorCode, -1,  | 
 | 
                                    "mechanism token from server is null");  | 
 | 
                        }  | 
 | 
                    } else { | 
 | 
                        mechToken = GSS_initSecContext(accept_token);  | 
 | 
                    }  | 
 | 
                      | 
 | 
                    if (!GSSUtil.useMSInterop()) { | 
 | 
                        byte[] micToken = targToken.getMechListMIC();  | 
 | 
                        if (!verifyMechListMIC(DER_mechTypes, micToken)) { | 
 | 
                            throw new GSSException(errorCode, -1,  | 
 | 
                                "verification of MIC on MechList Failed!");  | 
 | 
                        }  | 
 | 
                    }  | 
 | 
                    if (isMechContextEstablished()) { | 
 | 
                        state = STATE_DONE;  | 
 | 
                        retVal = mechToken;  | 
 | 
                        if (DEBUG) { | 
 | 
                            System.out.println("SPNEGO Negotiated Mechanism = " | 
 | 
                                + internal_mech + " " +  | 
 | 
                                GSSUtil.getMechStr(internal_mech));  | 
 | 
                        }  | 
 | 
                    } else { | 
 | 
                          | 
 | 
                        initToken = new NegTokenInit(null, null,  | 
 | 
                                                mechToken, null);  | 
 | 
                        if (DEBUG) { | 
 | 
                            System.out.println("SpNegoContext.initSecContext:" + | 
 | 
                                " continue sending token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(initToken.getType()));  | 
 | 
                        }  | 
 | 
                          | 
 | 
                        retVal = initToken.getEncoded();  | 
 | 
                    }  | 
 | 
                }  | 
 | 
 | 
 | 
            } else { | 
 | 
                  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println(state);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            if (DEBUG) { | 
 | 
                if (retVal != null) { | 
 | 
                    System.out.println("SNegoContext.initSecContext: " + | 
 | 
                        "sending token = " + SpNegoToken.getHexBytes(retVal));  | 
 | 
                }  | 
 | 
            }  | 
 | 
        } catch (GSSException e) { | 
 | 
            GSSException gssException =  | 
 | 
                        new GSSException(errorCode, -1, e.getMessage());  | 
 | 
            gssException.initCause(e);  | 
 | 
            throw gssException;  | 
 | 
        } catch (IOException e) { | 
 | 
            GSSException gssException =  | 
 | 
                new GSSException(GSSException.FAILURE, -1, e.getMessage());  | 
 | 
            gssException.initCause(e);  | 
 | 
            throw gssException;  | 
 | 
        }  | 
 | 
 | 
 | 
        return retVal;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final byte[] acceptSecContext(InputStream is, int mechTokenSize)  | 
 | 
        throws GSSException { | 
 | 
 | 
 | 
        byte[] retVal = null;  | 
 | 
        SpNegoToken.NegoResult negoResult;  | 
 | 
        boolean valid = true;  | 
 | 
 | 
 | 
        if (DEBUG) { | 
 | 
            System.out.println("Entered SpNegoContext.acceptSecContext with " + | 
 | 
                               "state=" +  printState(state));  | 
 | 
        }  | 
 | 
 | 
 | 
        if (isInitiator()) { | 
 | 
            throw new GSSException(GSSException.FAILURE, -1,  | 
 | 
                                   "acceptSecContext on an initiator " +  | 
 | 
                                   "GSSContext");  | 
 | 
        }  | 
 | 
        try { | 
 | 
            if (state == STATE_NEW) { | 
 | 
                state = STATE_IN_PROCESS;  | 
 | 
 | 
 | 
                  | 
 | 
                byte[] token = new byte[is.available()];  | 
 | 
                SpNegoToken.readFully(is, token);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                        "receiving token = " +  | 
 | 
                                        SpNegoToken.getHexBytes(token));  | 
 | 
                }  | 
 | 
 | 
 | 
                // read the SPNEGO token  | 
 | 
                  | 
 | 
                NegTokenInit initToken = new NegTokenInit(token);  | 
 | 
 | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "received token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(initToken.getType()));  | 
 | 
                }  | 
 | 
 | 
 | 
                Oid[] mechList = initToken.getMechTypeList();  | 
 | 
                DER_mechTypes = initToken.getMechTypes();  | 
 | 
                if (DER_mechTypes == null) { | 
 | 
                    valid = false;  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
                 */  | 
 | 
                Oid[] supported_mechSet = getAvailableMechs();  | 
 | 
                Oid mech_wanted =  | 
 | 
                        negotiate_mech_type(supported_mechSet, mechList);  | 
 | 
                if (mech_wanted == null) { | 
 | 
                    valid = false;  | 
 | 
                }  | 
 | 
                  | 
 | 
                internal_mech = mech_wanted;  | 
 | 
 | 
 | 
                  | 
 | 
                byte[] accept_token;  | 
 | 
 | 
 | 
                if (mechList[0].equals(mech_wanted) ||  | 
 | 
                        (GSSUtil.isKerberosMech(mechList[0]) &&  | 
 | 
                         GSSUtil.isKerberosMech(mech_wanted))) { | 
 | 
                      | 
 | 
                    if (DEBUG && !mech_wanted.equals(mechList[0])) { | 
 | 
                        System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "negotiated mech adjusted to " + mechList[0]);  | 
 | 
                    }  | 
 | 
                    byte[] mechToken = initToken.getMechToken();  | 
 | 
                    if (mechToken == null) { | 
 | 
                        throw new GSSException(GSSException.FAILURE, -1,  | 
 | 
                                "mechToken is missing");  | 
 | 
                    }  | 
 | 
                    accept_token = GSS_acceptSecContext(mechToken);  | 
 | 
                    mech_wanted = mechList[0];  | 
 | 
                } else { | 
 | 
                    accept_token = null;  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                if (!GSSUtil.useMSInterop() && valid) { | 
 | 
                    valid = verifyMechListMIC(DER_mechTypes,  | 
 | 
                                                initToken.getMechListMIC());  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                if (valid) { | 
 | 
                    if (isMechContextEstablished()) { | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;  | 
 | 
                        state = STATE_DONE;  | 
 | 
                          | 
 | 
                        setContextFlags();  | 
 | 
                          | 
 | 
                        if (DEBUG) { | 
 | 
                            System.out.println("SPNEGO Negotiated Mechanism = " | 
 | 
                                + internal_mech + " " +  | 
 | 
                                GSSUtil.getMechStr(internal_mech));  | 
 | 
                        }  | 
 | 
                    } else { | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;  | 
 | 
                        state = STATE_IN_PROCESS;  | 
 | 
                    }  | 
 | 
                } else { | 
 | 
                    negoResult = SpNegoToken.NegoResult.REJECT;  | 
 | 
                    state = STATE_DONE;  | 
 | 
                }  | 
 | 
 | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "mechanism wanted = " + mech_wanted);  | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "negotiated result = " + negoResult);  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),  | 
 | 
                                mech_wanted, accept_token, null);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "sending token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(targToken.getType()));  | 
 | 
                }  | 
 | 
                  | 
 | 
                retVal = targToken.getEncoded();  | 
 | 
 | 
 | 
            } else if (state == STATE_IN_PROCESS) { | 
 | 
                  | 
 | 
                byte[] token = new byte[is.available()];  | 
 | 
                SpNegoToken.readFully(is, token);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                            "receiving token = " +  | 
 | 
                            SpNegoToken.getHexBytes(token));  | 
 | 
                }  | 
 | 
 | 
 | 
                // read the SPNEGO token  | 
 | 
                  | 
 | 
                NegTokenTarg inputToken = new NegTokenTarg(token);  | 
 | 
 | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                            "received token of type = " +  | 
 | 
                            SpNegoToken.getTokenName(inputToken.getType()));  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                byte[] client_token = inputToken.getResponseToken();  | 
 | 
                byte[] accept_token = GSS_acceptSecContext(client_token);  | 
 | 
                if (accept_token == null) { | 
 | 
                    valid = false;  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                if (valid) { | 
 | 
                    if (isMechContextEstablished()) { | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_COMPLETE;  | 
 | 
                        state = STATE_DONE;  | 
 | 
                    } else { | 
 | 
                        negoResult = SpNegoToken.NegoResult.ACCEPT_INCOMPLETE;  | 
 | 
                        state = STATE_IN_PROCESS;  | 
 | 
                    }  | 
 | 
                } else { | 
 | 
                    negoResult = SpNegoToken.NegoResult.REJECT;  | 
 | 
                    state = STATE_DONE;  | 
 | 
                }  | 
 | 
 | 
 | 
                  | 
 | 
                NegTokenTarg targToken = new NegTokenTarg(negoResult.ordinal(),  | 
 | 
                                null, accept_token, null);  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                                "sending token of type = " +  | 
 | 
                                SpNegoToken.getTokenName(targToken.getType()));  | 
 | 
                }  | 
 | 
                  | 
 | 
                retVal = targToken.getEncoded();  | 
 | 
 | 
 | 
            } else { | 
 | 
                  | 
 | 
                if (DEBUG) { | 
 | 
                    System.out.println("AcceptSecContext: state = " + state); | 
 | 
                }  | 
 | 
            }  | 
 | 
            if (DEBUG) { | 
 | 
                    System.out.println("SpNegoContext.acceptSecContext: " + | 
 | 
                        "sending token = " + SpNegoToken.getHexBytes(retVal));  | 
 | 
            }  | 
 | 
        } catch (IOException e) { | 
 | 
            GSSException gssException =  | 
 | 
                new GSSException(GSSException.FAILURE, -1, e.getMessage());  | 
 | 
            gssException.initCause(e);  | 
 | 
            throw gssException;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (state == STATE_DONE) { | 
 | 
              | 
 | 
            setContextFlags();  | 
 | 
        }  | 
 | 
        return retVal;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private Oid[] getAvailableMechs() { | 
 | 
        if (myCred != null) { | 
 | 
            Oid[] mechs = new Oid[1];  | 
 | 
            mechs[0] = myCred.getInternalMech();  | 
 | 
            return mechs;  | 
 | 
        } else { | 
 | 
            return factory.availableMechs;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private byte[] getEncodedMechs(Oid[] mechSet)  | 
 | 
        throws IOException, GSSException { | 
 | 
 | 
 | 
        DerOutputStream mech = new DerOutputStream();  | 
 | 
        for (int i = 0; i < mechSet.length; i++) { | 
 | 
            byte[] mechType = mechSet[i].getDER();  | 
 | 
            mech.write(mechType);  | 
 | 
        }  | 
 | 
          | 
 | 
        DerOutputStream mechTypeList = new DerOutputStream();  | 
 | 
        mechTypeList.write(DerValue.tag_Sequence, mech);  | 
 | 
        byte[] encoded = mechTypeList.toByteArray();  | 
 | 
        return encoded;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private BitArray getContextFlags() { | 
 | 
        BitArray out = new BitArray(7);  | 
 | 
 | 
 | 
        if (getCredDelegState()) out.set(0, true);  | 
 | 
        if (getMutualAuthState()) out.set(1, true);  | 
 | 
        if (getReplayDetState()) out.set(2, true);  | 
 | 
        if (getSequenceDetState()) out.set(3, true);  | 
 | 
        if (getConfState()) out.set(5, true);  | 
 | 
        if (getIntegState()) out.set(6, true);  | 
 | 
 | 
 | 
        return out;  | 
 | 
    }  | 
 | 
 | 
 | 
    // Only called on acceptor side. On the initiator side, most flags  | 
 | 
    // are already set at request. For those that might get chanegd,  | 
 | 
      | 
 | 
    private void setContextFlags() { | 
 | 
 | 
 | 
        if (mechContext != null) { | 
 | 
              | 
 | 
            if (mechContext.getCredDelegState()) { | 
 | 
                credDelegState = true;  | 
 | 
            }  | 
 | 
              | 
 | 
            if (!mechContext.getMutualAuthState()) { | 
 | 
                mutualAuthState = false;  | 
 | 
            }  | 
 | 
            if (!mechContext.getReplayDetState()) { | 
 | 
                replayDetState = false;  | 
 | 
            }  | 
 | 
            if (!mechContext.getSequenceDetState()) { | 
 | 
                sequenceDetState = false;  | 
 | 
            }  | 
 | 
            if (!mechContext.getIntegState()) { | 
 | 
                integState = false;  | 
 | 
            }  | 
 | 
            if (!mechContext.getConfState()) { | 
 | 
                confState = false;  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
     * generate MIC on mechList. Not used at the moment.  | 
 | 
     */  | 
 | 
    /*private byte[] generateMechListMIC(byte[] mechTypes)  | 
 | 
        throws GSSException { | 
 | 
 | 
 | 
        // sanity check the required input  | 
 | 
        if (mechTypes == null) { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: no MIC token included"); | 
 | 
            }  | 
 | 
            return null;  | 
 | 
        }  | 
 | 
 | 
 | 
        // check if mechanism supports integrity  | 
 | 
        if (!mechContext.getIntegState()) { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: no MIC token included" + | 
 | 
                        " - mechanism does not support integrity");  | 
 | 
            }  | 
 | 
            return null;  | 
 | 
        }  | 
 | 
 | 
 | 
        // compute MIC on DER encoded mechanism list  | 
 | 
        byte[] mic = null;  | 
 | 
        try { | 
 | 
            MessageProp prop = new MessageProp(0, true);  | 
 | 
            mic = getMIC(mechTypes, 0, mechTypes.length, prop);  | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: getMIC = " + | 
 | 
                                        SpNegoToken.getHexBytes(mic));  | 
 | 
            }  | 
 | 
        } catch (GSSException e) { | 
 | 
            mic = null;  | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: no MIC token included" + | 
 | 
                        " - getMIC failed : " + e.getMessage());  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return mic;  | 
 | 
    }*/  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private boolean verifyMechListMIC(byte[] mechTypes, byte[] token)  | 
 | 
        throws GSSException { | 
 | 
 | 
 | 
          | 
 | 
        if (token == null) { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: no MIC token validation"); | 
 | 
            }  | 
 | 
            return true;  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        if (!mechContext.getIntegState()) { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: no MIC token validation" + | 
 | 
                        " - mechanism does not support integrity");  | 
 | 
            }  | 
 | 
            return true;  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        boolean valid = false;  | 
 | 
        try { | 
 | 
            MessageProp prop = new MessageProp(0, true);  | 
 | 
            verifyMIC(token, 0, token.length, mechTypes,  | 
 | 
                        0, mechTypes.length, prop);  | 
 | 
            valid = true;  | 
 | 
        } catch (GSSException e) { | 
 | 
            valid = false;  | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("SpNegoContext: MIC validation failed! " + | 
 | 
                                        e.getMessage());  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return valid;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private byte[] GSS_initSecContext(byte[] token) throws GSSException { | 
 | 
        byte[] tok = null;  | 
 | 
 | 
 | 
        if (mechContext == null) { | 
 | 
              | 
 | 
            GSSName serverName =  | 
 | 
                factory.manager.createName(peerName.toString(),  | 
 | 
                    peerName.getStringNameType(), internal_mech);  | 
 | 
            GSSCredential cred = null;  | 
 | 
            if (myCred != null) { | 
 | 
                  | 
 | 
                cred = new GSSCredentialImpl(factory.manager,  | 
 | 
                    myCred.getInternalCred());  | 
 | 
            }  | 
 | 
            mechContext =  | 
 | 
                factory.manager.createContext(serverName,  | 
 | 
                    internal_mech, cred, GSSContext.DEFAULT_LIFETIME);  | 
 | 
            mechContext.requestConf(confState);  | 
 | 
            mechContext.requestInteg(integState);  | 
 | 
            mechContext.requestCredDeleg(credDelegState);  | 
 | 
            mechContext.requestMutualAuth(mutualAuthState);  | 
 | 
            mechContext.requestReplayDet(replayDetState);  | 
 | 
            mechContext.requestSequenceDet(sequenceDetState);  | 
 | 
            if (mechContext instanceof ExtendedGSSContext) { | 
 | 
                ((ExtendedGSSContext)mechContext).requestDelegPolicy(  | 
 | 
                        delegPolicyState);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        if (token != null) { | 
 | 
            tok = token;  | 
 | 
        } else { | 
 | 
            tok = new byte[0];  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        byte[] init_token = mechContext.initSecContext(tok, 0, tok.length);  | 
 | 
 | 
 | 
        return init_token;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private byte[] GSS_acceptSecContext(byte[] token) throws GSSException { | 
 | 
 | 
 | 
        if (mechContext == null) { | 
 | 
              | 
 | 
            GSSCredential cred = null;  | 
 | 
            if (myCred != null) { | 
 | 
                  | 
 | 
                cred = new GSSCredentialImpl(factory.manager,  | 
 | 
                myCred.getInternalCred());  | 
 | 
            }  | 
 | 
            mechContext =  | 
 | 
                factory.manager.createContext(cred);  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        byte[] accept_token =  | 
 | 
                mechContext.acceptSecContext(token, 0, token.length);  | 
 | 
 | 
 | 
        return accept_token;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private static Oid negotiate_mech_type(Oid[] supported_mechSet,  | 
 | 
                                        Oid[] mechSet) { | 
 | 
        for (int i = 0; i < supported_mechSet.length; i++) { | 
 | 
            for (int j = 0; j < mechSet.length; j++) { | 
 | 
                if (mechSet[j].equals(supported_mechSet[i])) { | 
 | 
                    if (DEBUG) { | 
 | 
                        System.out.println("SpNegoContext: " + | 
 | 
                                "negotiated mechanism = " + mechSet[j]);  | 
 | 
                    }  | 
 | 
                    return (mechSet[j]);  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return null;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final boolean isEstablished() { | 
 | 
        return (state == STATE_DONE);  | 
 | 
    }  | 
 | 
 | 
 | 
    public final boolean isMechContextEstablished() { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.isEstablished();  | 
 | 
        } else { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("The underlying mechanism context has " + | 
 | 
                                        "not been initialized");  | 
 | 
            }  | 
 | 
            return false;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final byte [] export() throws GSSException { | 
 | 
        throw new GSSException(GSSException.UNAVAILABLE, -1,  | 
 | 
                               "GSS Export Context not available");  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void setChannelBinding(ChannelBinding channelBinding)  | 
 | 
        throws GSSException { | 
 | 
        this.channelBinding = channelBinding;  | 
 | 
    }  | 
 | 
 | 
 | 
    final ChannelBinding getChannelBinding() { | 
 | 
        return channelBinding;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestAnonymity(boolean value) throws GSSException { | 
 | 
        // Ignore silently. Application will check back with  | 
 | 
        // getAnonymityState.  | 
 | 
    }  | 
 | 
 | 
 | 
    // RFC 2853 actually calls for this to be called after context  | 
 | 
    // establishment to get the right answer, but that is  | 
 | 
    // incorrect. The application may not want to send over any  | 
 | 
      | 
 | 
    public final boolean getAnonymityState() { | 
 | 
        return false;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void requestLifetime(int lifetime) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            this.lifetime = lifetime;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public final int getLifetime() { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.getLifetime();  | 
 | 
        } else { | 
 | 
            return GSSContext.INDEFINITE_LIFETIME;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final boolean isTransferable() throws GSSException { | 
 | 
        return false;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestSequenceDet(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            sequenceDetState  = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getSequenceDetState() { | 
 | 
        return sequenceDetState || replayDetState;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final void requestReplayDet(boolean value) throws GSSException { | 
 | 
        if (state == STATE_NEW && isInitiator())  | 
 | 
            replayDetState  = value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final boolean getReplayDetState() { | 
 | 
        return replayDetState || sequenceDetState;  | 
 | 
    }  | 
 | 
 | 
 | 
    public final GSSNameSpi getTargName() throws GSSException { | 
 | 
        // fill-in the GSSName  | 
 | 
          | 
 | 
        if (mechContext != null) { | 
 | 
            GSSNameImpl targName = (GSSNameImpl)mechContext.getTargName();  | 
 | 
            peerName = targName.getElement(internal_mech);  | 
 | 
            return peerName;  | 
 | 
        } else { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("The underlying mechanism context has " + | 
 | 
                                        "not been initialized");  | 
 | 
            }  | 
 | 
            return null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final GSSNameSpi getSrcName() throws GSSException { | 
 | 
        // fill-in the GSSName  | 
 | 
          | 
 | 
        if (mechContext != null) { | 
 | 
            GSSNameImpl srcName = (GSSNameImpl)mechContext.getSrcName();  | 
 | 
            myName = srcName.getElement(internal_mech);  | 
 | 
            return myName;  | 
 | 
        } else { | 
 | 
            if (DEBUG) { | 
 | 
                System.out.println("The underlying mechanism context has " + | 
 | 
                                        "not been initialized");  | 
 | 
            }  | 
 | 
            return null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public final GSSCredentialSpi getDelegCred() throws GSSException { | 
 | 
        if (state != STATE_IN_PROCESS && state != STATE_DONE)  | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT);  | 
 | 
        if (mechContext != null) { | 
 | 
            GSSCredentialImpl delegCred =  | 
 | 
                        (GSSCredentialImpl)mechContext.getDelegCred();  | 
 | 
            if (delegCred == null) { | 
 | 
                return null;  | 
 | 
            }  | 
 | 
              | 
 | 
            boolean initiate = false;  | 
 | 
            if (delegCred.getUsage() == GSSCredential.INITIATE_ONLY) { | 
 | 
                initiate = true;  | 
 | 
            }  | 
 | 
            GSSCredentialSpi mechCred =  | 
 | 
                    delegCred.getElement(internal_mech, initiate);  | 
 | 
            SpNegoCredElement cred = new SpNegoCredElement(mechCred);  | 
 | 
            return cred.getInternalCred();  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "getDelegCred called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final int getWrapSizeLimit(int qop, boolean confReq,  | 
 | 
                                       int maxTokSize) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.getWrapSizeLimit(qop, confReq, maxTokSize);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "getWrapSizeLimit called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final byte[] wrap(byte inBuf[], int offset, int len,  | 
 | 
                             MessageProp msgProp) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.wrap(inBuf, offset, len, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "Wrap called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void wrap(InputStream is, OutputStream os,  | 
 | 
                            MessageProp msgProp) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            mechContext.wrap(is, os, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "Wrap called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final byte[] unwrap(byte inBuf[], int offset, int len,  | 
 | 
                               MessageProp msgProp)  | 
 | 
        throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.unwrap(inBuf, offset, len, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "UnWrap called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void unwrap(InputStream is, OutputStream os,  | 
 | 
                             MessageProp msgProp) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            mechContext.unwrap(is, os, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "UnWrap called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final byte[] getMIC(byte []inMsg, int offset, int len,  | 
 | 
                               MessageProp msgProp)  | 
 | 
        throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            return mechContext.getMIC(inMsg, offset, len, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "getMIC called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void getMIC(InputStream is, OutputStream os,  | 
 | 
                              MessageProp msgProp) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            mechContext.getMIC(is, os, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "getMIC called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void verifyMIC(byte []inTok, int tokOffset, int tokLen,  | 
 | 
                                byte[] inMsg, int msgOffset, int msgLen,  | 
 | 
                                MessageProp msgProp)  | 
 | 
        throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            mechContext.verifyMIC(inTok, tokOffset, tokLen, inMsg, msgOffset,  | 
 | 
                                msgLen,  msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "verifyMIC called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final void verifyMIC(InputStream is, InputStream msgStr,  | 
 | 
                                 MessageProp msgProp) throws GSSException { | 
 | 
        if (mechContext != null) { | 
 | 
            mechContext.verifyMIC(is, msgStr, msgProp);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                                "verifyMIC called in invalid state!");  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private static String printState(int state) { | 
 | 
        switch (state) { | 
 | 
          case STATE_NEW:  | 
 | 
                return ("STATE_NEW"); | 
 | 
          case STATE_IN_PROCESS:  | 
 | 
                return ("STATE_IN_PROCESS"); | 
 | 
          case STATE_DONE:  | 
 | 
                return ("STATE_DONE"); | 
 | 
          case STATE_DELETED:  | 
 | 
                return ("STATE_DELETED"); | 
 | 
          default:  | 
 | 
                return ("Unknown state " + state); | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    public Object inquireSecContext(InquireType type)  | 
 | 
            throws GSSException { | 
 | 
        if (mechContext == null) { | 
 | 
            throw new GSSException(GSSException.NO_CONTEXT, -1,  | 
 | 
                    "Underlying mech not established.");  | 
 | 
        }  | 
 | 
        if (mechContext instanceof ExtendedGSSContext) { | 
 | 
            return ((ExtendedGSSContext)mechContext).inquireSecContext(type);  | 
 | 
        } else { | 
 | 
            throw new GSSException(GSSException.BAD_MECH, -1,  | 
 | 
                    "inquireSecContext not supported by underlying mech.");  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  | 
 | 
 |