8212217: JGSS: Don't dispose() of creds too eagerly
authorweijun
Thu, 01 Nov 2018 22:41:32 +0800
changeset 52370 cb06c2248720
parent 52369 52f892f43a05
child 52371 ae4967993e17
8212217: JGSS: Don't dispose() of creds too eagerly Reviewed-by: mullan, weijun Contributed-by: Nico Williams <nico@twosigma.com>
src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java
--- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Thu Nov 01 14:15:35 2018 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	Thu Nov 01 22:41:32 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,12 +63,14 @@
     private GSSNameElement srcName;
     private GSSNameElement targetName;
     private GSSCredElement cred;
+    private GSSCredElement disposeCred;
     private boolean isInitiator;
     private boolean isEstablished;
     private Oid actualMech; // Assigned during context establishment
 
     private ChannelBinding cb;
     private GSSCredElement delegatedCred;
+    private GSSCredElement disposeDelegatedCred;
     private int flags;
     private int lifetime = GSSCredential.DEFAULT_LIFETIME;
     private final GSSLibStub cStub;
@@ -192,6 +194,7 @@
         }
         cStub = stub;
         cred = myCred;
+        disposeCred = null;
         targetName = peer;
         isInitiator = true;
         lifetime = time;
@@ -199,8 +202,9 @@
         if (GSSUtil.isKerberosMech(cStub.getMech())) {
             doServicePermCheck();
             if (cred == null) {
-                cred = new GSSCredElement(null, lifetime,
-                                          GSSCredential.INITIATE_ONLY, cStub);
+                disposeCred = cred =
+                    new GSSCredElement(null, lifetime,
+                            GSSCredential.INITIATE_ONLY, cStub);
             }
             srcName = cred.getName();
         }
@@ -211,6 +215,7 @@
         throws GSSException {
         cStub = stub;
         cred = myCred;
+        disposeCred = null;
 
         if (cred != null) targetName = cred.getName();
 
@@ -297,9 +302,9 @@
                         (cStub.getContextName(pContext, true), cStub);
                 }
                 if (cred == null) {
-                    cred = new GSSCredElement(srcName, lifetime,
-                                              GSSCredential.INITIATE_ONLY,
-                                              cStub);
+                    disposeCred = cred =
+                        new GSSCredElement(srcName, lifetime,
+                                GSSCredential.INITIATE_ONLY, cStub);
                 }
             }
         }
@@ -315,6 +320,7 @@
                                     inToken.length);
             long pCred = (cred == null? 0 : cred.pCred);
             outToken = cStub.acceptContext(pCred, cb, inToken, this);
+            disposeDelegatedCred = delegatedCred;
             SunNativeProvider.debug("acceptSecContext=> outToken len=" +
                                     (outToken == null? 0 : outToken.length));
 
@@ -323,9 +329,12 @@
                     (cStub.getContextName(pContext, false), cStub);
                 // Replace the current default acceptor cred now that
                 // the context acceptor name is available
-                if (cred != null) cred.dispose();
-                cred = new GSSCredElement(targetName, lifetime,
-                                          GSSCredential.ACCEPT_ONLY, cStub);
+                if (disposeCred != null) {
+                    disposeCred.dispose();
+                }
+                disposeCred = cred =
+                    new GSSCredElement(targetName, lifetime,
+                            GSSCredential.ACCEPT_ONLY, cStub);
             }
 
             // Only inspect token when the permission check has not
@@ -346,9 +355,15 @@
     }
 
     public void dispose() throws GSSException {
+        if (disposeCred != null) {
+            disposeCred.dispose();
+        }
+        if (disposeDelegatedCred != null) {
+            disposeDelegatedCred.dispose();
+        }
+        disposeDelegatedCred = disposeCred = cred = null;
         srcName = null;
         targetName = null;
-        cred = null;
         delegatedCred = null;
         if (pContext != 0) {
             pContext = cStub.deleteContext(pContext);
@@ -612,6 +627,7 @@
         }
     }
     public GSSCredentialSpi getDelegCred() throws GSSException {
+        disposeDelegatedCred = null;
         return delegatedCred;
     }
     public boolean isInitiator() {