8059009: LDAPCertStore fails to retrieve CRL after LDAP server closes idle connection
Reviewed-by: vinnie
Contributed-by: Artem Smotrakov <artem.smotrakov@oracle.com>
--- 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;