1 /*
2  * Copyright (c) 2005, 2018, 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 GSSCredElement disposeCred;
67     private boolean isInitiator;
68     private boolean isEstablished;
69     private Oid actualMech; // Assigned during context establishment
70 
71     private ChannelBinding cb;
72     private GSSCredElement delegatedCred;
73     private GSSCredElement disposeDelegatedCred;
74     private int flags;
75     private int lifetime = GSSCredential.DEFAULT_LIFETIME;
76     private final GSSLibStub cStub;
77 
78     private boolean skipDelegPermCheck;
79     private boolean skipServicePermCheck;
80 
81     // Retrieve the (preferred) mech out of SPNEGO tokens, i.e.
82     // NegTokenInit & NegTokenTarg
getMechFromSpNegoToken(byte[] token, boolean isInitiator)83     private static Oid getMechFromSpNegoToken(byte[] token,
84                                               boolean isInitiator)
85         throws GSSException {
86         Oid mech = null;
87         if (isInitiator) {
88             GSSHeader header = null;
89             try {
90                 header = new GSSHeader(new ByteArrayInputStream(token));
91             } catch (IOException ioe) {
92                 throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
93             }
94             int negTokenLen = header.getMechTokenLength();
95             byte[] negToken = new byte[negTokenLen];
96             System.arraycopy(token, token.length-negTokenLen,
97                              negToken, 0, negToken.length);
98 
99             NegTokenInit ntok = new NegTokenInit(negToken);
100             if (ntok.getMechToken() != null) {
101                 Oid[] mechList = ntok.getMechTypeList();
102                 mech = mechList[0];
103             }
104         } else {
105             NegTokenTarg ntok = new NegTokenTarg(token);
106             mech = ntok.getSupportedMech();
107         }
108         return mech;
109     }
110 
111     // Perform the Service permission check
doServicePermCheck()112     private void doServicePermCheck() throws GSSException {
113         if (System.getSecurityManager() != null) {
114             String action = (isInitiator? "initiate" : "accept");
115             // Need to check Service permission for accessing
116             // initiator cred for SPNEGO during context establishment
117             if (GSSUtil.isSpNegoMech(cStub.getMech()) && isInitiator
118                 && !isEstablished) {
119                 if (srcName == null) {
120                     // Check by creating default initiator KRB5 cred
121                     GSSCredElement tempCred =
122                         new GSSCredElement(null, lifetime,
123                                            GSSCredential.INITIATE_ONLY,
124                                            GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID));
125                     tempCred.dispose();
126                 } else {
127                     String tgsName = Krb5Util.getTGSName(srcName);
128                     Krb5Util.checkServicePermission(tgsName, action);
129                 }
130             }
131             String targetStr = targetName.getKrbName();
132             Krb5Util.checkServicePermission(targetStr, action);
133             skipServicePermCheck = true;
134         }
135     }
136 
137     // Perform the Delegation permission check
doDelegPermCheck()138     private void doDelegPermCheck() throws GSSException {
139         SecurityManager sm = System.getSecurityManager();
140         if (sm != null) {
141             String targetStr = targetName.getKrbName();
142             String tgsStr = Krb5Util.getTGSName(targetName);
143             StringBuilder sb = new StringBuilder("\"");
144             sb.append(targetStr).append("\" \"");
145             sb.append(tgsStr).append('\"');
146             String krbPrincPair = sb.toString();
147             SunNativeProvider.debug("Checking DelegationPermission (" +
148                                     krbPrincPair + ")");
149             DelegationPermission perm =
150                 new DelegationPermission(krbPrincPair);
151             sm.checkPermission(perm);
152             skipDelegPermCheck = true;
153         }
154     }
155 
retrieveToken(InputStream is, int mechTokenLen)156     private byte[] retrieveToken(InputStream is, int mechTokenLen)
157         throws GSSException {
158         try {
159             byte[] result = null;
160             if (mechTokenLen != -1) {
161                 // Need to add back the GSS header for a complete GSS token
162                 SunNativeProvider.debug("Precomputed mechToken length: " +
163                                          mechTokenLen);
164                 GSSHeader gssHeader = new GSSHeader
165                     (new ObjectIdentifier(cStub.getMech().toString()),
166                      mechTokenLen);
167                 ByteArrayOutputStream baos = new ByteArrayOutputStream(600);
168 
169                 byte[] mechToken = new byte[mechTokenLen];
170                 int len = is.read(mechToken);
171                 assert(mechTokenLen == len);
172                 gssHeader.encode(baos);
173                 baos.write(mechToken);
174                 result = baos.toByteArray();
175             } else {
176                 // Must be unparsed GSS token or SPNEGO's NegTokenTarg token
177                 assert(mechTokenLen == -1);
178                 DerValue dv = new DerValue(is);
179                 result = dv.toByteArray();
180             }
181             SunNativeProvider.debug("Complete Token length: " +
182                                     result.length);
183             return result;
184         } catch (IOException ioe) {
185             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
186         }
187     }
188 
189     // Constructor for context initiator
NativeGSSContext(GSSNameElement peer, GSSCredElement myCred, int time, GSSLibStub stub)190     NativeGSSContext(GSSNameElement peer, GSSCredElement myCred,
191                      int time, GSSLibStub stub) throws GSSException {
192         if (peer == null) {
193             throw new GSSException(GSSException.FAILURE, 1, "null peer");
194         }
195         cStub = stub;
196         cred = myCred;
197         disposeCred = null;
198         targetName = peer;
199         isInitiator = true;
200         lifetime = time;
201 
202         if (GSSUtil.isKerberosMech(cStub.getMech())) {
203             doServicePermCheck();
204             if (cred == null) {
205                 disposeCred = cred =
206                     new GSSCredElement(null, lifetime,
207                             GSSCredential.INITIATE_ONLY, cStub);
208             }
209             srcName = cred.getName();
210         }
211     }
212 
213     // Constructor for context acceptor
NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)214     NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)
215         throws GSSException {
216         cStub = stub;
217         cred = myCred;
218         disposeCred = null;
219 
220         if (cred != null) targetName = cred.getName();
221 
222         isInitiator = false;
223         // Defer Service permission check for default acceptor cred
224         // to acceptSecContext()
225         if (GSSUtil.isKerberosMech(cStub.getMech()) && targetName != null) {
226             doServicePermCheck();
227         }
228 
229         // srcName and potentially targetName (when myCred is null)
230         // will be set in GSSLibStub.acceptContext(...)
231     }
232 
233     // Constructor for imported context
NativeGSSContext(long pCtxt, GSSLibStub stub)234     NativeGSSContext(long pCtxt, GSSLibStub stub) throws GSSException {
235         assert(pContext != 0);
236         pContext = pCtxt;
237         cStub = stub;
238 
239         // Set everything except cred, cb, delegatedCred
240         long[] info = cStub.inquireContext(pContext);
241         if (info.length != NUM_OF_INQUIRE_VALUES) {
242             throw new RuntimeException("Bug w/ GSSLibStub.inquireContext()");
243         }
244         srcName = new GSSNameElement(info[0], cStub);
245         targetName = new GSSNameElement(info[1], cStub);
246         isInitiator = (info[2] != 0);
247         isEstablished = (info[3] != 0);
248         flags = (int) info[4];
249         lifetime = (int) info[5];
250 
251         // Do Service Permission check when importing SPNEGO context
252         // just to be safe
253         Oid mech = cStub.getMech();
254         if (GSSUtil.isSpNegoMech(mech) || GSSUtil.isKerberosMech(mech)) {
255             doServicePermCheck();
256         }
257     }
258 
getProvider()259     public Provider getProvider() {
260         return SunNativeProvider.INSTANCE;
261     }
262 
initSecContext(InputStream is, int mechTokenLen)263     public byte[] initSecContext(InputStream is, int mechTokenLen)
264         throws GSSException {
265         byte[] outToken = null;
266         if ((!isEstablished) && (isInitiator)) {
267             byte[] inToken = null;
268             // Ignore the specified input stream on the first call
269             if (pContext != 0) {
270                 inToken = retrieveToken(is, mechTokenLen);
271                 SunNativeProvider.debug("initSecContext=> inToken len=" +
272                     inToken.length);
273             }
274 
275             if (!getCredDelegState()) skipDelegPermCheck = true;
276 
277             if (GSSUtil.isKerberosMech(cStub.getMech()) && !skipDelegPermCheck) {
278                 doDelegPermCheck();
279             }
280 
281             long pCred = (cred == null? 0 : cred.pCred);
282             outToken = cStub.initContext(pCred, targetName.pName,
283                                          cb, inToken, this);
284             SunNativeProvider.debug("initSecContext=> outToken len=" +
285                 (outToken == null ? 0 : outToken.length));
286 
287             // Only inspect the token when the permission check
288             // has not been performed
289             if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) {
290                 // WORKAROUND for SEAM bug#6287358
291                 actualMech = getMechFromSpNegoToken(outToken, true);
292 
293                 if (GSSUtil.isKerberosMech(actualMech)) {
294                     if (!skipServicePermCheck) doServicePermCheck();
295                     if (!skipDelegPermCheck) doDelegPermCheck();
296                 }
297             }
298 
299             if (isEstablished) {
300                 if (srcName == null) {
301                     srcName = new GSSNameElement
302                         (cStub.getContextName(pContext, true), cStub);
303                 }
304                 if (cred == null) {
305                     disposeCred = cred =
306                         new GSSCredElement(srcName, lifetime,
307                                 GSSCredential.INITIATE_ONLY, cStub);
308                 }
309             }
310         }
311         return outToken;
312     }
313 
acceptSecContext(InputStream is, int mechTokenLen)314     public byte[] acceptSecContext(InputStream is, int mechTokenLen)
315         throws GSSException {
316         byte[] outToken = null;
317         if ((!isEstablished) && (!isInitiator)) {
318             byte[] inToken = retrieveToken(is, mechTokenLen);
319             SunNativeProvider.debug("acceptSecContext=> inToken len=" +
320                                     inToken.length);
321             long pCred = (cred == null? 0 : cred.pCred);
322             outToken = cStub.acceptContext(pCred, cb, inToken, this);
323             disposeDelegatedCred = delegatedCred;
324             SunNativeProvider.debug("acceptSecContext=> outToken len=" +
325                                     (outToken == null? 0 : outToken.length));
326 
327             if (targetName == null) {
328                 targetName = new GSSNameElement
329                     (cStub.getContextName(pContext, false), cStub);
330                 // Replace the current default acceptor cred now that
331                 // the context acceptor name is available
332                 if (disposeCred != null) {
333                     disposeCred.dispose();
334                 }
335                 disposeCred = cred =
336                     new GSSCredElement(targetName, lifetime,
337                             GSSCredential.ACCEPT_ONLY, cStub);
338             }
339 
340             // Only inspect token when the permission check has not
341             // been performed
342             if (GSSUtil.isSpNegoMech(cStub.getMech()) &&
343                 (outToken != null) && !skipServicePermCheck) {
344                 if (GSSUtil.isKerberosMech(getMechFromSpNegoToken
345                                            (outToken, false))) {
346                     doServicePermCheck();
347                 }
348             }
349         }
350         return outToken;
351     }
352 
isEstablished()353     public boolean isEstablished() {
354         return isEstablished;
355     }
356 
dispose()357     public void dispose() throws GSSException {
358         if (disposeCred != null) {
359             disposeCred.dispose();
360         }
361         if (disposeDelegatedCred != null) {
362             disposeDelegatedCred.dispose();
363         }
364         disposeDelegatedCred = disposeCred = cred = null;
365         srcName = null;
366         targetName = null;
367         delegatedCred = null;
368         if (pContext != 0) {
369             pContext = cStub.deleteContext(pContext);
370             pContext = 0;
371         }
372     }
373 
getWrapSizeLimit(int qop, boolean confReq, int maxTokenSize)374     public int getWrapSizeLimit(int qop, boolean confReq,
375                                 int maxTokenSize)
376         throws GSSException {
377         return cStub.wrapSizeLimit(pContext, (confReq? 1:0), qop,
378                                    maxTokenSize);
379     }
380 
wrap(byte[] inBuf, int offset, int len, MessageProp msgProp)381     public byte[] wrap(byte[] inBuf, int offset, int len,
382                        MessageProp msgProp) throws GSSException {
383         byte[] data = inBuf;
384         if ((offset != 0) || (len != inBuf.length)) {
385             data = new byte[len];
386             System.arraycopy(inBuf, offset, data, 0, len);
387         }
388         return cStub.wrap(pContext, data, msgProp);
389     }
wrap(byte[] inBuf, int offset, int len, OutputStream os, MessageProp msgProp)390     public void wrap(byte[] inBuf, int offset, int len,
391                      OutputStream os, MessageProp msgProp)
392         throws GSSException {
393         try {
394         byte[] result = wrap(inBuf, offset, len, msgProp);
395         os.write(result);
396         } catch (IOException ioe) {
397             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
398         }
399     }
wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf, int outOffset, MessageProp msgProp)400     public int wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf,
401                     int outOffset, MessageProp msgProp)
402         throws GSSException {
403         byte[] result = wrap(inBuf, inOffset, len, msgProp);
404         System.arraycopy(result, 0, outBuf, outOffset, result.length);
405         return result.length;
406     }
wrap(InputStream inStream, OutputStream outStream, MessageProp msgProp)407     public void wrap(InputStream inStream, OutputStream outStream,
408                      MessageProp msgProp) throws GSSException {
409         try {
410             byte[] data = new byte[inStream.available()];
411             int length = inStream.read(data);
412             byte[] token = wrap(data, 0, length, msgProp);
413             outStream.write(token);
414         } catch (IOException ioe) {
415             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
416         }
417     }
418 
unwrap(byte[] inBuf, int offset, int len, MessageProp msgProp)419     public byte[] unwrap(byte[] inBuf, int offset, int len,
420                          MessageProp msgProp)
421         throws GSSException {
422         if ((offset != 0) || (len != inBuf.length)) {
423             byte[] temp = new byte[len];
424             System.arraycopy(inBuf, offset, temp, 0, len);
425             return cStub.unwrap(pContext, temp, msgProp);
426         } else {
427             return cStub.unwrap(pContext, inBuf, msgProp);
428         }
429     }
unwrap(byte[] inBuf, int inOffset, int len, byte[] outBuf, int outOffset, MessageProp msgProp)430     public int unwrap(byte[] inBuf, int inOffset, int len,
431                       byte[] outBuf, int outOffset,
432                       MessageProp msgProp) throws GSSException {
433         byte[] result = null;
434         if ((inOffset != 0) || (len != inBuf.length)) {
435             byte[] temp = new byte[len];
436             System.arraycopy(inBuf, inOffset, temp, 0, len);
437             result = cStub.unwrap(pContext, temp, msgProp);
438         } else {
439             result = cStub.unwrap(pContext, inBuf, msgProp);
440         }
441         System.arraycopy(result, 0, outBuf, outOffset, result.length);
442         return result.length;
443     }
unwrap(InputStream inStream, OutputStream outStream, MessageProp msgProp)444     public void unwrap(InputStream inStream, OutputStream outStream,
445                        MessageProp msgProp) throws GSSException {
446         try {
447             byte[] wrapped = new byte[inStream.available()];
448             int wLength = inStream.read(wrapped);
449             byte[] data = unwrap(wrapped, 0, wLength, msgProp);
450             outStream.write(data);
451             outStream.flush();
452         } catch (IOException ioe) {
453             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
454         }
455     }
456 
unwrap(InputStream inStream, byte[] outBuf, int outOffset, MessageProp msgProp)457     public int unwrap(InputStream inStream,
458                       byte[] outBuf, int outOffset,
459                       MessageProp msgProp) throws GSSException {
460         byte[] wrapped = null;
461         int wLength = 0;
462         try {
463             wrapped = new byte[inStream.available()];
464             wLength = inStream.read(wrapped);
465             byte[] result = unwrap(wrapped, 0, wLength, msgProp);
466         } catch (IOException ioe) {
467             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
468         }
469         byte[] result = unwrap(wrapped, 0, wLength, msgProp);
470         System.arraycopy(result, 0, outBuf, outOffset, result.length);
471         return result.length;
472     }
473 
getMIC(byte[] in, int offset, int len, MessageProp msgProp)474     public byte[] getMIC(byte[] in, int offset, int len,
475                          MessageProp msgProp) throws GSSException {
476         int qop = (msgProp == null? 0:msgProp.getQOP());
477         byte[] inMsg = in;
478         if ((offset != 0) || (len != in.length)) {
479             inMsg = new byte[len];
480             System.arraycopy(in, offset, inMsg, 0, len);
481         }
482         return cStub.getMic(pContext, qop, inMsg);
483     }
484 
getMIC(InputStream inStream, OutputStream outStream, MessageProp msgProp)485     public void getMIC(InputStream inStream, OutputStream outStream,
486                        MessageProp msgProp) throws GSSException {
487         try {
488             int length = 0;
489             byte[] msg = new byte[inStream.available()];
490             length = inStream.read(msg);
491 
492             byte[] msgToken = getMIC(msg, 0, length, msgProp);
493             if ((msgToken != null) && msgToken.length != 0) {
494                 outStream.write(msgToken);
495             }
496         } catch (IOException ioe) {
497             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
498         }
499     }
500 
verifyMIC(byte[] inToken, int tOffset, int tLen, byte[] inMsg, int mOffset, int mLen, MessageProp msgProp)501     public void verifyMIC(byte[] inToken, int tOffset, int tLen,
502                           byte[] inMsg, int mOffset, int mLen,
503                           MessageProp msgProp) throws GSSException {
504         byte[] token = inToken;
505         byte[] msg = inMsg;
506         if ((tOffset != 0) || (tLen != inToken.length)) {
507             token = new byte[tLen];
508             System.arraycopy(inToken, tOffset, token, 0, tLen);
509         }
510         if ((mOffset != 0) || (mLen != inMsg.length)) {
511             msg = new byte[mLen];
512             System.arraycopy(inMsg, mOffset, msg, 0, mLen);
513         }
514         cStub.verifyMic(pContext, token, msg, msgProp);
515     }
516 
verifyMIC(InputStream tokStream, InputStream msgStream, MessageProp msgProp)517     public void verifyMIC(InputStream tokStream, InputStream msgStream,
518                           MessageProp msgProp) throws GSSException {
519         try {
520             byte[] msg = new byte[msgStream.available()];
521             int mLength = msgStream.read(msg);
522             byte[] tok = new byte[tokStream.available()];
523             int tLength = tokStream.read(tok);
524             verifyMIC(tok, 0, tLength, msg, 0, mLength, msgProp);
525         } catch (IOException ioe) {
526             throw new GSSExceptionImpl(GSSException.FAILURE, ioe);
527         }
528     }
529 
export()530     public byte[] export() throws GSSException {
531         byte[] result = cStub.exportContext(pContext);
532         pContext = 0;
533         return result;
534     }
535 
changeFlags(int flagMask, boolean isEnable)536     private void changeFlags(int flagMask, boolean isEnable) {
537         if (isInitiator && pContext == 0) {
538             if (isEnable) {
539                 flags |= flagMask;
540             } else {
541                 flags &= ~flagMask;
542             }
543         }
544     }
requestMutualAuth(boolean state)545     public void requestMutualAuth(boolean state) throws GSSException {
546         changeFlags(GSS_C_MUTUAL_FLAG, state);
547     }
requestReplayDet(boolean state)548     public void requestReplayDet(boolean state) throws GSSException {
549         changeFlags(GSS_C_REPLAY_FLAG, state);
550     }
requestSequenceDet(boolean state)551     public void requestSequenceDet(boolean state) throws GSSException {
552         changeFlags(GSS_C_SEQUENCE_FLAG, state);
553     }
requestCredDeleg(boolean state)554     public void requestCredDeleg(boolean state) throws GSSException {
555         changeFlags(GSS_C_DELEG_FLAG, state);
556     }
requestAnonymity(boolean state)557     public void requestAnonymity(boolean state) throws GSSException {
558         changeFlags(GSS_C_ANON_FLAG, state);
559     }
requestConf(boolean state)560     public void requestConf(boolean state) throws GSSException {
561         changeFlags(GSS_C_CONF_FLAG, state);
562     }
requestInteg(boolean state)563     public void requestInteg(boolean state) throws GSSException {
564         changeFlags(GSS_C_INTEG_FLAG, state);
565     }
requestDelegPolicy(boolean state)566     public void requestDelegPolicy(boolean state) throws GSSException {
567         // Not supported, ignore
568     }
requestLifetime(int lifetime)569     public void requestLifetime(int lifetime) throws GSSException {
570         if (isInitiator && pContext == 0) {
571             this.lifetime = lifetime;
572         }
573     }
setChannelBinding(ChannelBinding cb)574     public void setChannelBinding(ChannelBinding cb) throws GSSException {
575         if (pContext == 0) {
576             this.cb = cb;
577         }
578     }
579 
checkFlags(int flagMask)580     private boolean checkFlags(int flagMask) {
581         return ((flags & flagMask) != 0);
582     }
getCredDelegState()583     public boolean getCredDelegState() {
584         return checkFlags(GSS_C_DELEG_FLAG);
585     }
getMutualAuthState()586     public boolean getMutualAuthState() {
587         return checkFlags(GSS_C_MUTUAL_FLAG);
588     }
getReplayDetState()589     public boolean getReplayDetState() {
590         return checkFlags(GSS_C_REPLAY_FLAG);
591     }
getSequenceDetState()592     public boolean getSequenceDetState() {
593         return checkFlags(GSS_C_SEQUENCE_FLAG);
594     }
getAnonymityState()595     public boolean getAnonymityState() {
596         return checkFlags(GSS_C_ANON_FLAG);
597     }
isTransferable()598     public boolean isTransferable() throws GSSException {
599         return checkFlags(GSS_C_TRANS_FLAG);
600     }
isProtReady()601     public boolean isProtReady() {
602         return checkFlags(GSS_C_PROT_READY_FLAG);
603     }
getConfState()604     public boolean getConfState() {
605         return checkFlags(GSS_C_CONF_FLAG);
606     }
getIntegState()607     public boolean getIntegState() {
608         return checkFlags(GSS_C_INTEG_FLAG);
609     }
getDelegPolicyState()610     public boolean getDelegPolicyState() {
611         return false;
612     }
getLifetime()613     public int getLifetime() {
614         return cStub.getContextTime(pContext);
615     }
getSrcName()616     public GSSNameSpi getSrcName() throws GSSException {
617         return srcName;
618     }
getTargName()619     public GSSNameSpi getTargName() throws GSSException {
620         return targetName;
621     }
getMech()622     public Oid getMech() throws GSSException {
623         if (isEstablished && actualMech != null) {
624             return actualMech;
625         } else {
626             return cStub.getMech();
627         }
628     }
getDelegCred()629     public GSSCredentialSpi getDelegCred() throws GSSException {
630         disposeDelegatedCred = null;
631         return delegatedCred;
632     }
isInitiator()633     public boolean isInitiator() {
634         return isInitiator;
635     }
636 
637     @SuppressWarnings("deprecation")
finalize()638     protected void finalize() throws Throwable {
639         dispose();
640     }
641 
inquireSecContext(String type)642     public Object inquireSecContext(String type)
643             throws GSSException {
644         throw new GSSException(GSSException.UNAVAILABLE, -1,
645                 "Inquire type not supported.");
646     }
647 }
648