History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/jgss/wrapper/NativeGSSContext.java (1 of 18352 files). Show all

Unified · Split

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