src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java
changeset 47216 71c04702a3d5
parent 44534 a076dffbc2c1
child 52370 cb06c2248720
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package sun.security.jgss.wrapper;
       
    27 
       
    28 import org.ietf.jgss.*;
       
    29 import java.security.Provider;
       
    30 import sun.security.jgss.GSSHeader;
       
    31 import sun.security.jgss.GSSUtil;
       
    32 import sun.security.jgss.GSSExceptionImpl;
       
    33 import sun.security.jgss.spi.*;
       
    34 import sun.security.util.DerValue;
       
    35 import sun.security.util.ObjectIdentifier;
       
    36 import sun.security.jgss.spnego.NegTokenInit;
       
    37 import sun.security.jgss.spnego.NegTokenTarg;
       
    38 import javax.security.auth.kerberos.DelegationPermission;
       
    39 import java.io.*;
       
    40 
       
    41 
       
    42 /**
       
    43  * This class is essentially a wrapper class for the gss_ctx_id_t
       
    44  * structure of the native GSS library.
       
    45  * @author Valerie Peng
       
    46  * @since 1.6
       
    47  */
       
    48 class NativeGSSContext implements GSSContextSpi {
       
    49 
       
    50     private static final int GSS_C_DELEG_FLAG = 1;
       
    51     private static final int GSS_C_MUTUAL_FLAG = 2;
       
    52     private static final int GSS_C_REPLAY_FLAG = 4;
       
    53     private static final int GSS_C_SEQUENCE_FLAG = 8;
       
    54     private static final int GSS_C_CONF_FLAG = 16;
       
    55     private static final int GSS_C_INTEG_FLAG = 32;
       
    56     private static final int GSS_C_ANON_FLAG = 64;
       
    57     private static final int GSS_C_PROT_READY_FLAG = 128;
       
    58     private static final int GSS_C_TRANS_FLAG = 256;
       
    59 
       
    60     private static final int NUM_OF_INQUIRE_VALUES = 6;
       
    61 
       
    62     private long pContext = 0; // Pointer to the gss_ctx_id_t structure
       
    63     private GSSNameElement srcName;
       
    64     private GSSNameElement targetName;
       
    65     private GSSCredElement cred;
       
    66     private boolean isInitiator;
       
    67     private boolean isEstablished;
       
    68     private Oid actualMech; // Assigned during context establishment
       
    69 
       
    70     private ChannelBinding cb;
       
    71     private GSSCredElement delegatedCred;
       
    72     private int flags;
       
    73     private int lifetime = GSSCredential.DEFAULT_LIFETIME;
       
    74     private final GSSLibStub cStub;
       
    75 
       
    76     private boolean skipDelegPermCheck;
       
    77     private boolean skipServicePermCheck;
       
    78 
       
    79     // Retrieve the (preferred) mech out of SPNEGO tokens, i.e.
       
    80     // NegTokenInit & NegTokenTarg
       
    81     private static Oid getMechFromSpNegoToken(byte[] token,
       
    82                                               boolean isInitiator)
       
    83         throws GSSException {
       
    84         Oid mech = null;
       
    85         if (isInitiator) {
       
    86             GSSHeader header = null;
       
    87             try {
       
    88                 header = new GSSHeader(new ByteArrayInputStream(token));
       
    89             } catch (IOException ioe) {
       
    90                 throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
    91             }
       
    92             int negTokenLen = header.getMechTokenLength();
       
    93             byte[] negToken = new byte[negTokenLen];
       
    94             System.arraycopy(token, token.length-negTokenLen,
       
    95                              negToken, 0, negToken.length);
       
    96 
       
    97             NegTokenInit ntok = new NegTokenInit(negToken);
       
    98             if (ntok.getMechToken() != null) {
       
    99                 Oid[] mechList = ntok.getMechTypeList();
       
   100                 mech = mechList[0];
       
   101             }
       
   102         } else {
       
   103             NegTokenTarg ntok = new NegTokenTarg(token);
       
   104             mech = ntok.getSupportedMech();
       
   105         }
       
   106         return mech;
       
   107     }
       
   108 
       
   109     // Perform the Service permission check
       
   110     private void doServicePermCheck() throws GSSException {
       
   111         if (System.getSecurityManager() != null) {
       
   112             String action = (isInitiator? "initiate" : "accept");
       
   113             // Need to check Service permission for accessing
       
   114             // initiator cred for SPNEGO during context establishment
       
   115             if (GSSUtil.isSpNegoMech(cStub.getMech()) && isInitiator
       
   116                 && !isEstablished) {
       
   117                 if (srcName == null) {
       
   118                     // Check by creating default initiator KRB5 cred
       
   119                     GSSCredElement tempCred =
       
   120                         new GSSCredElement(null, lifetime,
       
   121                                            GSSCredential.INITIATE_ONLY,
       
   122                                            GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID));
       
   123                     tempCred.dispose();
       
   124                 } else {
       
   125                     String tgsName = Krb5Util.getTGSName(srcName);
       
   126                     Krb5Util.checkServicePermission(tgsName, action);
       
   127                 }
       
   128             }
       
   129             String targetStr = targetName.getKrbName();
       
   130             Krb5Util.checkServicePermission(targetStr, action);
       
   131             skipServicePermCheck = true;
       
   132         }
       
   133     }
       
   134 
       
   135     // Perform the Delegation permission check
       
   136     private void doDelegPermCheck() throws GSSException {
       
   137         SecurityManager sm = System.getSecurityManager();
       
   138         if (sm != null) {
       
   139             String targetStr = targetName.getKrbName();
       
   140             String tgsStr = Krb5Util.getTGSName(targetName);
       
   141             StringBuilder sb = new StringBuilder("\"");
       
   142             sb.append(targetStr).append("\" \"");
       
   143             sb.append(tgsStr).append('\"');
       
   144             String krbPrincPair = sb.toString();
       
   145             SunNativeProvider.debug("Checking DelegationPermission (" +
       
   146                                     krbPrincPair + ")");
       
   147             DelegationPermission perm =
       
   148                 new DelegationPermission(krbPrincPair);
       
   149             sm.checkPermission(perm);
       
   150             skipDelegPermCheck = true;
       
   151         }
       
   152     }
       
   153 
       
   154     private byte[] retrieveToken(InputStream is, int mechTokenLen)
       
   155         throws GSSException {
       
   156         try {
       
   157             byte[] result = null;
       
   158             if (mechTokenLen != -1) {
       
   159                 // Need to add back the GSS header for a complete GSS token
       
   160                 SunNativeProvider.debug("Precomputed mechToken length: " +
       
   161                                          mechTokenLen);
       
   162                 GSSHeader gssHeader = new GSSHeader
       
   163                     (new ObjectIdentifier(cStub.getMech().toString()),
       
   164                      mechTokenLen);
       
   165                 ByteArrayOutputStream baos = new ByteArrayOutputStream(600);
       
   166 
       
   167                 byte[] mechToken = new byte[mechTokenLen];
       
   168                 int len = is.read(mechToken);
       
   169                 assert(mechTokenLen == len);
       
   170                 gssHeader.encode(baos);
       
   171                 baos.write(mechToken);
       
   172                 result = baos.toByteArray();
       
   173             } else {
       
   174                 // Must be unparsed GSS token or SPNEGO's NegTokenTarg token
       
   175                 assert(mechTokenLen == -1);
       
   176                 DerValue dv = new DerValue(is);
       
   177                 result = dv.toByteArray();
       
   178             }
       
   179             SunNativeProvider.debug("Complete Token length: " +
       
   180                                     result.length);
       
   181             return result;
       
   182         } catch (IOException ioe) {
       
   183             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   184         }
       
   185     }
       
   186 
       
   187     // Constructor for context initiator
       
   188     NativeGSSContext(GSSNameElement peer, GSSCredElement myCred,
       
   189                      int time, GSSLibStub stub) throws GSSException {
       
   190         if (peer == null) {
       
   191             throw new GSSException(GSSException.FAILURE, 1, "null peer");
       
   192         }
       
   193         cStub = stub;
       
   194         cred = myCred;
       
   195         targetName = peer;
       
   196         isInitiator = true;
       
   197         lifetime = time;
       
   198 
       
   199         if (GSSUtil.isKerberosMech(cStub.getMech())) {
       
   200             doServicePermCheck();
       
   201             if (cred == null) {
       
   202                 cred = new GSSCredElement(null, lifetime,
       
   203                                           GSSCredential.INITIATE_ONLY, cStub);
       
   204             }
       
   205             srcName = cred.getName();
       
   206         }
       
   207     }
       
   208 
       
   209     // Constructor for context acceptor
       
   210     NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)
       
   211         throws GSSException {
       
   212         cStub = stub;
       
   213         cred = myCred;
       
   214 
       
   215         if (cred != null) targetName = cred.getName();
       
   216 
       
   217         isInitiator = false;
       
   218         // Defer Service permission check for default acceptor cred
       
   219         // to acceptSecContext()
       
   220         if (GSSUtil.isKerberosMech(cStub.getMech()) && targetName != null) {
       
   221             doServicePermCheck();
       
   222         }
       
   223 
       
   224         // srcName and potentially targetName (when myCred is null)
       
   225         // will be set in GSSLibStub.acceptContext(...)
       
   226     }
       
   227 
       
   228     // Constructor for imported context
       
   229     NativeGSSContext(long pCtxt, GSSLibStub stub) throws GSSException {
       
   230         assert(pContext != 0);
       
   231         pContext = pCtxt;
       
   232         cStub = stub;
       
   233 
       
   234         // Set everything except cred, cb, delegatedCred
       
   235         long[] info = cStub.inquireContext(pContext);
       
   236         if (info.length != NUM_OF_INQUIRE_VALUES) {
       
   237             throw new RuntimeException("Bug w/ GSSLibStub.inquireContext()");
       
   238         }
       
   239         srcName = new GSSNameElement(info[0], cStub);
       
   240         targetName = new GSSNameElement(info[1], cStub);
       
   241         isInitiator = (info[2] != 0);
       
   242         isEstablished = (info[3] != 0);
       
   243         flags = (int) info[4];
       
   244         lifetime = (int) info[5];
       
   245 
       
   246         // Do Service Permission check when importing SPNEGO context
       
   247         // just to be safe
       
   248         Oid mech = cStub.getMech();
       
   249         if (GSSUtil.isSpNegoMech(mech) || GSSUtil.isKerberosMech(mech)) {
       
   250             doServicePermCheck();
       
   251         }
       
   252     }
       
   253 
       
   254     public Provider getProvider() {
       
   255         return SunNativeProvider.INSTANCE;
       
   256     }
       
   257 
       
   258     public byte[] initSecContext(InputStream is, int mechTokenLen)
       
   259         throws GSSException {
       
   260         byte[] outToken = null;
       
   261         if ((!isEstablished) && (isInitiator)) {
       
   262             byte[] inToken = null;
       
   263             // Ignore the specified input stream on the first call
       
   264             if (pContext != 0) {
       
   265                 inToken = retrieveToken(is, mechTokenLen);
       
   266                 SunNativeProvider.debug("initSecContext=> inToken len=" +
       
   267                     inToken.length);
       
   268             }
       
   269 
       
   270             if (!getCredDelegState()) skipDelegPermCheck = true;
       
   271 
       
   272             if (GSSUtil.isKerberosMech(cStub.getMech()) && !skipDelegPermCheck) {
       
   273                 doDelegPermCheck();
       
   274             }
       
   275 
       
   276             long pCred = (cred == null? 0 : cred.pCred);
       
   277             outToken = cStub.initContext(pCred, targetName.pName,
       
   278                                          cb, inToken, this);
       
   279             SunNativeProvider.debug("initSecContext=> outToken len=" +
       
   280                 (outToken == null ? 0 : outToken.length));
       
   281 
       
   282             // Only inspect the token when the permission check
       
   283             // has not been performed
       
   284             if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) {
       
   285                 // WORKAROUND for SEAM bug#6287358
       
   286                 actualMech = getMechFromSpNegoToken(outToken, true);
       
   287 
       
   288                 if (GSSUtil.isKerberosMech(actualMech)) {
       
   289                     if (!skipServicePermCheck) doServicePermCheck();
       
   290                     if (!skipDelegPermCheck) doDelegPermCheck();
       
   291                 }
       
   292             }
       
   293 
       
   294             if (isEstablished) {
       
   295                 if (srcName == null) {
       
   296                     srcName = new GSSNameElement
       
   297                         (cStub.getContextName(pContext, true), cStub);
       
   298                 }
       
   299                 if (cred == null) {
       
   300                     cred = new GSSCredElement(srcName, lifetime,
       
   301                                               GSSCredential.INITIATE_ONLY,
       
   302                                               cStub);
       
   303                 }
       
   304             }
       
   305         }
       
   306         return outToken;
       
   307     }
       
   308 
       
   309     public byte[] acceptSecContext(InputStream is, int mechTokenLen)
       
   310         throws GSSException {
       
   311         byte[] outToken = null;
       
   312         if ((!isEstablished) && (!isInitiator)) {
       
   313             byte[] inToken = retrieveToken(is, mechTokenLen);
       
   314             SunNativeProvider.debug("acceptSecContext=> inToken len=" +
       
   315                                     inToken.length);
       
   316             long pCred = (cred == null? 0 : cred.pCred);
       
   317             outToken = cStub.acceptContext(pCred, cb, inToken, this);
       
   318             SunNativeProvider.debug("acceptSecContext=> outToken len=" +
       
   319                                     (outToken == null? 0 : outToken.length));
       
   320 
       
   321             if (targetName == null) {
       
   322                 targetName = new GSSNameElement
       
   323                     (cStub.getContextName(pContext, false), cStub);
       
   324                 // Replace the current default acceptor cred now that
       
   325                 // the context acceptor name is available
       
   326                 if (cred != null) cred.dispose();
       
   327                 cred = new GSSCredElement(targetName, lifetime,
       
   328                                           GSSCredential.ACCEPT_ONLY, cStub);
       
   329             }
       
   330 
       
   331             // Only inspect token when the permission check has not
       
   332             // been performed
       
   333             if (GSSUtil.isSpNegoMech(cStub.getMech()) &&
       
   334                 (outToken != null) && !skipServicePermCheck) {
       
   335                 if (GSSUtil.isKerberosMech(getMechFromSpNegoToken
       
   336                                            (outToken, false))) {
       
   337                     doServicePermCheck();
       
   338                 }
       
   339             }
       
   340         }
       
   341         return outToken;
       
   342     }
       
   343 
       
   344     public boolean isEstablished() {
       
   345         return isEstablished;
       
   346     }
       
   347 
       
   348     public void dispose() throws GSSException {
       
   349         srcName = null;
       
   350         targetName = null;
       
   351         cred = null;
       
   352         delegatedCred = null;
       
   353         if (pContext != 0) {
       
   354             pContext = cStub.deleteContext(pContext);
       
   355             pContext = 0;
       
   356         }
       
   357     }
       
   358 
       
   359     public int getWrapSizeLimit(int qop, boolean confReq,
       
   360                                 int maxTokenSize)
       
   361         throws GSSException {
       
   362         return cStub.wrapSizeLimit(pContext, (confReq? 1:0), qop,
       
   363                                    maxTokenSize);
       
   364     }
       
   365 
       
   366     public byte[] wrap(byte[] inBuf, int offset, int len,
       
   367                        MessageProp msgProp) throws GSSException {
       
   368         byte[] data = inBuf;
       
   369         if ((offset != 0) || (len != inBuf.length)) {
       
   370             data = new byte[len];
       
   371             System.arraycopy(inBuf, offset, data, 0, len);
       
   372         }
       
   373         return cStub.wrap(pContext, data, msgProp);
       
   374     }
       
   375     public void wrap(byte[] inBuf, int offset, int len,
       
   376                      OutputStream os, MessageProp msgProp)
       
   377         throws GSSException {
       
   378         try {
       
   379         byte[] result = wrap(inBuf, offset, len, msgProp);
       
   380         os.write(result);
       
   381         } catch (IOException ioe) {
       
   382             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   383         }
       
   384     }
       
   385     public int wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf,
       
   386                     int outOffset, MessageProp msgProp)
       
   387         throws GSSException {
       
   388         byte[] result = wrap(inBuf, inOffset, len, msgProp);
       
   389         System.arraycopy(result, 0, outBuf, outOffset, result.length);
       
   390         return result.length;
       
   391     }
       
   392     public void wrap(InputStream inStream, OutputStream outStream,
       
   393                      MessageProp msgProp) throws GSSException {
       
   394         try {
       
   395             byte[] data = new byte[inStream.available()];
       
   396             int length = inStream.read(data);
       
   397             byte[] token = wrap(data, 0, length, msgProp);
       
   398             outStream.write(token);
       
   399         } catch (IOException ioe) {
       
   400             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   401         }
       
   402     }
       
   403 
       
   404     public byte[] unwrap(byte[] inBuf, int offset, int len,
       
   405                          MessageProp msgProp)
       
   406         throws GSSException {
       
   407         if ((offset != 0) || (len != inBuf.length)) {
       
   408             byte[] temp = new byte[len];
       
   409             System.arraycopy(inBuf, offset, temp, 0, len);
       
   410             return cStub.unwrap(pContext, temp, msgProp);
       
   411         } else {
       
   412             return cStub.unwrap(pContext, inBuf, msgProp);
       
   413         }
       
   414     }
       
   415     public int unwrap(byte[] inBuf, int inOffset, int len,
       
   416                       byte[] outBuf, int outOffset,
       
   417                       MessageProp msgProp) throws GSSException {
       
   418         byte[] result = null;
       
   419         if ((inOffset != 0) || (len != inBuf.length)) {
       
   420             byte[] temp = new byte[len];
       
   421             System.arraycopy(inBuf, inOffset, temp, 0, len);
       
   422             result = cStub.unwrap(pContext, temp, msgProp);
       
   423         } else {
       
   424             result = cStub.unwrap(pContext, inBuf, msgProp);
       
   425         }
       
   426         System.arraycopy(result, 0, outBuf, outOffset, result.length);
       
   427         return result.length;
       
   428     }
       
   429     public void unwrap(InputStream inStream, OutputStream outStream,
       
   430                        MessageProp msgProp) throws GSSException {
       
   431         try {
       
   432             byte[] wrapped = new byte[inStream.available()];
       
   433             int wLength = inStream.read(wrapped);
       
   434             byte[] data = unwrap(wrapped, 0, wLength, msgProp);
       
   435             outStream.write(data);
       
   436             outStream.flush();
       
   437         } catch (IOException ioe) {
       
   438             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   439         }
       
   440     }
       
   441 
       
   442     public int unwrap(InputStream inStream,
       
   443                       byte[] outBuf, int outOffset,
       
   444                       MessageProp msgProp) throws GSSException {
       
   445         byte[] wrapped = null;
       
   446         int wLength = 0;
       
   447         try {
       
   448             wrapped = new byte[inStream.available()];
       
   449             wLength = inStream.read(wrapped);
       
   450             byte[] result = unwrap(wrapped, 0, wLength, msgProp);
       
   451         } catch (IOException ioe) {
       
   452             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   453         }
       
   454         byte[] result = unwrap(wrapped, 0, wLength, msgProp);
       
   455         System.arraycopy(result, 0, outBuf, outOffset, result.length);
       
   456         return result.length;
       
   457     }
       
   458 
       
   459     public byte[] getMIC(byte[] in, int offset, int len,
       
   460                          MessageProp msgProp) throws GSSException {
       
   461         int qop = (msgProp == null? 0:msgProp.getQOP());
       
   462         byte[] inMsg = in;
       
   463         if ((offset != 0) || (len != in.length)) {
       
   464             inMsg = new byte[len];
       
   465             System.arraycopy(in, offset, inMsg, 0, len);
       
   466         }
       
   467         return cStub.getMic(pContext, qop, inMsg);
       
   468     }
       
   469 
       
   470     public void getMIC(InputStream inStream, OutputStream outStream,
       
   471                        MessageProp msgProp) throws GSSException {
       
   472         try {
       
   473             int length = 0;
       
   474             byte[] msg = new byte[inStream.available()];
       
   475             length = inStream.read(msg);
       
   476 
       
   477             byte[] msgToken = getMIC(msg, 0, length, msgProp);
       
   478             if ((msgToken != null) && msgToken.length != 0) {
       
   479                 outStream.write(msgToken);
       
   480             }
       
   481         } catch (IOException ioe) {
       
   482             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   483         }
       
   484     }
       
   485 
       
   486     public void verifyMIC(byte[] inToken, int tOffset, int tLen,
       
   487                           byte[] inMsg, int mOffset, int mLen,
       
   488                           MessageProp msgProp) throws GSSException {
       
   489         byte[] token = inToken;
       
   490         byte[] msg = inMsg;
       
   491         if ((tOffset != 0) || (tLen != inToken.length)) {
       
   492             token = new byte[tLen];
       
   493             System.arraycopy(inToken, tOffset, token, 0, tLen);
       
   494         }
       
   495         if ((mOffset != 0) || (mLen != inMsg.length)) {
       
   496             msg = new byte[mLen];
       
   497             System.arraycopy(inMsg, mOffset, msg, 0, mLen);
       
   498         }
       
   499         cStub.verifyMic(pContext, token, msg, msgProp);
       
   500     }
       
   501 
       
   502     public void verifyMIC(InputStream tokStream, InputStream msgStream,
       
   503                           MessageProp msgProp) throws GSSException {
       
   504         try {
       
   505             byte[] msg = new byte[msgStream.available()];
       
   506             int mLength = msgStream.read(msg);
       
   507             byte[] tok = new byte[tokStream.available()];
       
   508             int tLength = tokStream.read(tok);
       
   509             verifyMIC(tok, 0, tLength, msg, 0, mLength, msgProp);
       
   510         } catch (IOException ioe) {
       
   511             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
       
   512         }
       
   513     }
       
   514 
       
   515     public byte[] export() throws GSSException {
       
   516         byte[] result = cStub.exportContext(pContext);
       
   517         pContext = 0;
       
   518         return result;
       
   519     }
       
   520 
       
   521     private void changeFlags(int flagMask, boolean isEnable) {
       
   522         if (isInitiator && pContext == 0) {
       
   523             if (isEnable) {
       
   524                 flags |= flagMask;
       
   525             } else {
       
   526                 flags &= ~flagMask;
       
   527             }
       
   528         }
       
   529     }
       
   530     public void requestMutualAuth(boolean state) throws GSSException {
       
   531         changeFlags(GSS_C_MUTUAL_FLAG, state);
       
   532     }
       
   533     public void requestReplayDet(boolean state) throws GSSException {
       
   534         changeFlags(GSS_C_REPLAY_FLAG, state);
       
   535     }
       
   536     public void requestSequenceDet(boolean state) throws GSSException {
       
   537         changeFlags(GSS_C_SEQUENCE_FLAG, state);
       
   538     }
       
   539     public void requestCredDeleg(boolean state) throws GSSException {
       
   540         changeFlags(GSS_C_DELEG_FLAG, state);
       
   541     }
       
   542     public void requestAnonymity(boolean state) throws GSSException {
       
   543         changeFlags(GSS_C_ANON_FLAG, state);
       
   544     }
       
   545     public void requestConf(boolean state) throws GSSException {
       
   546         changeFlags(GSS_C_CONF_FLAG, state);
       
   547     }
       
   548     public void requestInteg(boolean state) throws GSSException {
       
   549         changeFlags(GSS_C_INTEG_FLAG, state);
       
   550     }
       
   551     public void requestDelegPolicy(boolean state) throws GSSException {
       
   552         // Not supported, ignore
       
   553     }
       
   554     public void requestLifetime(int lifetime) throws GSSException {
       
   555         if (isInitiator && pContext == 0) {
       
   556             this.lifetime = lifetime;
       
   557         }
       
   558     }
       
   559     public void setChannelBinding(ChannelBinding cb) throws GSSException {
       
   560         if (pContext == 0) {
       
   561             this.cb = cb;
       
   562         }
       
   563     }
       
   564 
       
   565     private boolean checkFlags(int flagMask) {
       
   566         return ((flags & flagMask) != 0);
       
   567     }
       
   568     public boolean getCredDelegState() {
       
   569         return checkFlags(GSS_C_DELEG_FLAG);
       
   570     }
       
   571     public boolean getMutualAuthState() {
       
   572         return checkFlags(GSS_C_MUTUAL_FLAG);
       
   573     }
       
   574     public boolean getReplayDetState() {
       
   575         return checkFlags(GSS_C_REPLAY_FLAG);
       
   576     }
       
   577     public boolean getSequenceDetState() {
       
   578         return checkFlags(GSS_C_SEQUENCE_FLAG);
       
   579     }
       
   580     public boolean getAnonymityState() {
       
   581         return checkFlags(GSS_C_ANON_FLAG);
       
   582     }
       
   583     public boolean isTransferable() throws GSSException {
       
   584         return checkFlags(GSS_C_TRANS_FLAG);
       
   585     }
       
   586     public boolean isProtReady() {
       
   587         return checkFlags(GSS_C_PROT_READY_FLAG);
       
   588     }
       
   589     public boolean getConfState() {
       
   590         return checkFlags(GSS_C_CONF_FLAG);
       
   591     }
       
   592     public boolean getIntegState() {
       
   593         return checkFlags(GSS_C_INTEG_FLAG);
       
   594     }
       
   595     public boolean getDelegPolicyState() {
       
   596         return false;
       
   597     }
       
   598     public int getLifetime() {
       
   599         return cStub.getContextTime(pContext);
       
   600     }
       
   601     public GSSNameSpi getSrcName() throws GSSException {
       
   602         return srcName;
       
   603     }
       
   604     public GSSNameSpi getTargName() throws GSSException {
       
   605         return targetName;
       
   606     }
       
   607     public Oid getMech() throws GSSException {
       
   608         if (isEstablished && actualMech != null) {
       
   609             return actualMech;
       
   610         } else {
       
   611             return cStub.getMech();
       
   612         }
       
   613     }
       
   614     public GSSCredentialSpi getDelegCred() throws GSSException {
       
   615         return delegatedCred;
       
   616     }
       
   617     public boolean isInitiator() {
       
   618         return isInitiator;
       
   619     }
       
   620 
       
   621     @SuppressWarnings("deprecation")
       
   622     protected void finalize() throws Throwable {
       
   623         dispose();
       
   624     }
       
   625 
       
   626     public Object inquireSecContext(String type)
       
   627             throws GSSException {
       
   628         throw new GSSException(GSSException.UNAVAILABLE, -1,
       
   629                 "Inquire type not supported.");
       
   630     }
       
   631 }