8059009: LDAPCertStore fails to retrieve CRL after LDAP server closes idle connection
authorvinnie
Thu, 15 Jan 2015 17:57:52 +0000
changeset 28429 be279feaeb8b
parent 28428 55242c4e5b0a
child 28430 a4f35c6aa3cc
8059009: LDAPCertStore fails to retrieve CRL after LDAP server closes idle connection Reviewed-by: vinnie Contributed-by: Artem Smotrakov <artem.smotrakov@oracle.com>
jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java
jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java
--- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java	Thu Jan 15 17:05:06 2015 +0000
+++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java	Thu Jan 15 17:57:52 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -224,6 +224,7 @@
     String hostname = null;             // host name of server (no brackets
                                         //   for IPv6 literals)
     LdapClient clnt = null;             // connection handle
+    private boolean reconnect = false;  // indicates that re-connect requested
     Hashtable<String, java.lang.Object> envprops = null; // environment properties of context
     int handleReferrals = DEFAULT_REFERRAL_MODE; // how referral is handled
     boolean hasLdapsScheme = false;     // true if the context was created
@@ -2663,6 +2664,7 @@
         }
 
         sharable = false;  // can't share with existing contexts
+        reconnect = true;
         ensureOpen();      // open or reauthenticated
     }
 
@@ -2739,7 +2741,7 @@
         try {
             boolean initial = (clnt == null);
 
-            if (initial) {
+            if (initial || reconnect) {
                 ldapVersion = (ver != null) ? Integer.parseInt(ver) :
                     DEFAULT_LDAP_VERSION;
 
@@ -2767,6 +2769,7 @@
                     // Required for SASL client identity
                     envprops);
 
+                reconnect = false;
 
                 /**
                  * Pooled connections are preauthenticated;
--- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java	Thu Jan 15 17:05:06 2015 +0000
+++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java	Thu Jan 15 17:57:52 2015 +0000
@@ -37,12 +37,13 @@
 import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
 
 import java.security.*;
 import java.security.cert.Certificate;
 import java.security.cert.*;
+import javax.naming.CommunicationException;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
 import javax.security.auth.x500.X500Principal;
 
 import sun.misc.HexDumpEncoder;
@@ -160,7 +161,12 @@
     /**
      * The JNDI directory context.
      */
-    private DirContext ctx;
+    private LdapContext ctx;
+
+    /**
+     * Flag indicating that communication error occurred.
+     */
+    private boolean communicationError = false;
 
     /**
      * Flag indicating whether we should prefetch CRLs.
@@ -218,6 +224,11 @@
         certStoreCache = Cache.newSoftMemoryCache(185);
     static synchronized CertStore getInstance(LDAPCertStoreParameters params)
         throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+        // if necessary, convert params to SunLDAPCertStoreParameters because
+        // LDAPCertStoreParameters does not override equals() and hashCode()
+        if (! (params instanceof SunLDAPCertStoreParameters)) {
+            params = new SunLDAPCertStoreParameters(params.getServerName(), params.getPort());
+        }
         CertStore lcs = certStoreCache.get(params);
         if (lcs == null) {
             lcs = CertStore.getInstance("LDAP", params);
@@ -256,7 +267,7 @@
         }
 
         try {
-            ctx = new InitialDirContext(env);
+            ctx = new InitialLdapContext(env, null);
             /*
              * By default, follow referrals unless application has
              * overridden property in an application resource file.
@@ -369,8 +380,17 @@
             valueMap = new HashMap<>(8);
             String[] attrIds = requestedAttributes.toArray(STRING0);
             Attributes attrs;
+
+            if (communicationError) {
+                ctx.reconnect(null);
+                communicationError = false;
+            }
+
             try {
                 attrs = ctx.getAttributes(name, attrIds);
+            } catch (CommunicationException ce) {
+                communicationError = true;
+                throw ce;
             } catch (NameNotFoundException e) {
                 // name does not exist on this LDAP server
                 // treat same as not attributes found
@@ -884,7 +904,12 @@
         SunLDAPCertStoreParameters() {
             super();
         }
+        @Override
         public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+
             if (!(obj instanceof LDAPCertStoreParameters)) {
                 return false;
             }
@@ -892,6 +917,7 @@
             return (getPort() == params.getPort() &&
                     getServerName().equalsIgnoreCase(params.getServerName()));
         }
+        @Override
         public int hashCode() {
             if (hashCode == 0) {
                 int result = 17;