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
getMechFromSpNegoToken(byte[] token, boolean isInitiator)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
doServicePermCheck()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
doDelegPermCheck()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 
retrieveToken(InputStream is, int mechTokenLen)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
NativeGSSContext(GSSNameElement peer, GSSCredElement myCred, int time, GSSLibStub stub)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
NativeGSSContext(GSSCredElement myCred, GSSLibStub stub)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
NativeGSSContext(long pCtxt, GSSLibStub stub)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 
getProvider()254     public Provider getProvider() {
255         return SunNativeProvider.INSTANCE;
256     }
257 
initSecContext(InputStream is, int mechTokenLen)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 
acceptSecContext(InputStream is, int mechTokenLen)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 
isEstablished()344     public boolean isEstablished() {
345         return isEstablished;
346     }
347 
dispose()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 
getWrapSizeLimit(int qop, boolean confReq, int maxTokenSize)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 
wrap(byte[] inBuf, int offset, int len, MessageProp msgProp)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     }
wrap(byte[] inBuf, int offset, int len, OutputStream os, MessageProp msgProp)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     }
wrap(byte[] inBuf, int inOffset, int len, byte[] outBuf, int outOffset, MessageProp msgProp)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     }
wrap(InputStream inStream, OutputStream outStream, MessageProp msgProp)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 
unwrap(byte[] inBuf, int offset, int len, MessageProp msgProp)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     }
unwrap(byte[] inBuf, int inOffset, int len, byte[] outBuf, int outOffset, MessageProp msgProp)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     }
unwrap(InputStream inStream, OutputStream outStream, MessageProp msgProp)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 
unwrap(InputStream inStream, byte[] outBuf, int outOffset, MessageProp msgProp)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 
getMIC(byte[] in, int offset, int len, MessageProp msgProp)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 
getMIC(InputStream inStream, OutputStream outStream, MessageProp msgProp)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 
verifyMIC(byte[] inToken, int tOffset, int tLen, byte[] inMsg, int mOffset, int mLen, MessageProp msgProp)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 
verifyMIC(InputStream tokStream, InputStream msgStream, MessageProp msgProp)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 
export()515     public byte[] export() throws GSSException {
516         byte[] result = cStub.exportContext(pContext);
517         pContext = 0;
518         return result;
519     }
520 
changeFlags(int flagMask, boolean isEnable)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     }
requestMutualAuth(boolean state)530     public void requestMutualAuth(boolean state) throws GSSException {
531         changeFlags(GSS_C_MUTUAL_FLAG, state);
532     }
requestReplayDet(boolean state)533     public void requestReplayDet(boolean state) throws GSSException {
534         changeFlags(GSS_C_REPLAY_FLAG, state);
535     }
requestSequenceDet(boolean state)536     public void requestSequenceDet(boolean state) throws GSSException {
537         changeFlags(GSS_C_SEQUENCE_FLAG, state);
538     }
requestCredDeleg(boolean state)539     public void requestCredDeleg(boolean state) throws GSSException {
540         changeFlags(GSS_C_DELEG_FLAG, state);
541     }
requestAnonymity(boolean state)542     public void requestAnonymity(boolean state) throws GSSException {
543         changeFlags(GSS_C_ANON_FLAG, state);
544     }
requestConf(boolean state)545     public void requestConf(boolean state) throws GSSException {
546         changeFlags(GSS_C_CONF_FLAG, state);
547     }
requestInteg(boolean state)548     public void requestInteg(boolean state) throws GSSException {
549         changeFlags(GSS_C_INTEG_FLAG, state);
550     }
requestDelegPolicy(boolean state)551     public void requestDelegPolicy(boolean state) throws GSSException {
552         // Not supported, ignore
553     }
requestLifetime(int lifetime)554     public void requestLifetime(int lifetime) throws GSSException {
555         if (isInitiator && pContext == 0) {
556             this.lifetime = lifetime;
557         }
558     }
setChannelBinding(ChannelBinding cb)559     public void setChannelBinding(ChannelBinding cb) throws GSSException {
560         if (pContext == 0) {
561             this.cb = cb;
562         }
563     }
564 
checkFlags(int flagMask)565     private boolean checkFlags(int flagMask) {
566         return ((flags & flagMask) != 0);
567     }
getCredDelegState()568     public boolean getCredDelegState() {
569         return checkFlags(GSS_C_DELEG_FLAG);
570     }
getMutualAuthState()571     public boolean getMutualAuthState() {
572         return checkFlags(GSS_C_MUTUAL_FLAG);
573     }
getReplayDetState()574     public boolean getReplayDetState() {
575         return checkFlags(GSS_C_REPLAY_FLAG);
576     }
getSequenceDetState()577     public boolean getSequenceDetState() {
578         return checkFlags(GSS_C_SEQUENCE_FLAG);
579     }
getAnonymityState()580     public boolean getAnonymityState() {
581         return checkFlags(GSS_C_ANON_FLAG);
582     }
isTransferable()583     public boolean isTransferable() throws GSSException {
584         return checkFlags(GSS_C_TRANS_FLAG);
585     }
isProtReady()586     public boolean isProtReady() {
587         return checkFlags(GSS_C_PROT_READY_FLAG);
588     }
getConfState()589     public boolean getConfState() {
590         return checkFlags(GSS_C_CONF_FLAG);
591     }
getIntegState()592     public boolean getIntegState() {
593         return checkFlags(GSS_C_INTEG_FLAG);
594     }
getDelegPolicyState()595     public boolean getDelegPolicyState() {
596         return false;
597     }
getLifetime()598     public int getLifetime() {
599         return cStub.getContextTime(pContext);
600     }
getSrcName()601     public GSSNameSpi getSrcName() throws GSSException {
602         return srcName;
603     }
getTargName()604     public GSSNameSpi getTargName() throws GSSException {
605         return targetName;
606     }
getMech()607     public Oid getMech() throws GSSException {
608         if (isEstablished && actualMech != null) {
609             return actualMech;
610         } else {
611             return cStub.getMech();
612         }
613     }
getDelegCred()614     public GSSCredentialSpi getDelegCred() throws GSSException {
615         return delegatedCred;
616     }
isInitiator()617     public boolean isInitiator() {
618         return isInitiator;
619     }
620 
621     @SuppressWarnings("deprecation")
finalize()622     protected void finalize() throws Throwable {
623         dispose();
624     }
625 
inquireSecContext(String type)626     public Object inquireSecContext(String type)
627             throws GSSException {
628         throw new GSSException(GSSException.UNAVAILABLE, -1,
629                 "Inquire type not supported.");
630     }
631 }
632