summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src
diff options
context:
space:
mode:
authorvakwetu <vakwetu@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2010-12-22 18:18:37 +0000
committervakwetu <vakwetu@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2010-12-22 18:18:37 +0000
commite4be104deeed238f176050dc6c0db1504d9253da (patch)
treeaa20d329fd3ee951626f24edda416a84a669ee97 /pki/base/common/src
parent5a467a1aa4e26db85e25a35275c5dfd0d320d7b2 (diff)
downloadpki-e4be104deeed238f176050dc6c0db1504d9253da.tar.gz
pki-e4be104deeed238f176050dc6c0db1504d9253da.tar.xz
pki-e4be104deeed238f176050dc6c0db1504d9253da.zip
Bugzilla Bug 491183 - rhcs rfe - add rfc 4523 support for pkiUser and pkiCA, obsolete 2252 and 2256
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@1663 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
Diffstat (limited to 'pki/base/common/src')
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java34
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java129
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java128
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java177
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java128
5 files changed, 510 insertions, 86 deletions
diff --git a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
index 0734e5d7f..6bf4ca8d5 100644
--- a/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
+++ b/pki/base/common/src/com/netscape/cms/publish/mappers/LdapCaSimpleMap.java
@@ -47,7 +47,6 @@ import com.netscape.certsrv.publish.*;
public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
protected static final String PROP_DNPATTERN = "dnPattern";
protected static final String PROP_CREATECA = "createCAEntry";
- protected static final String PROP_CA_V2 = "CAEntryV2";
protected String mDnPattern = null;
protected boolean mCreateCAEntry = true;
@@ -97,7 +96,6 @@ public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
"$subj means: take the attribute from the certificate subject name. " +
"$ext means: take the attribute from the certificate extension",
"createCAEntry;boolean;If checked, CA entry will be created automatically",
- "CAEntryV2;boolean;If checked, CA entry will be created using certificationAuthority-v2",
IExtendedPluginInfo.HELP_TOKEN + ";configuration-ldappublish-mapper-casimplemapper",
IExtendedPluginInfo.HELP_TEXT + ";Describes how to form the LDAP DN of the entry to publish to"
};
@@ -250,26 +248,10 @@ public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
throws LDAPException {
LDAPAttributeSet attrs = new LDAPAttributeSet();
// OID 2.5.6.16
- String caOc[] = null;
- boolean isV2 = false;
- try {
- isV2 = mConfig.getBoolean(PROP_CA_V2, false);
- } catch (EBaseException e) {
- // do nothing; default false
- }
- if (isV2) {
- caOc = new String[] {"top",
+ String caOc[] = new String[] {"top",
"person",
"organizationalPerson",
- "inetOrgPerson",
- "certificationAuthority-v2"};
- } else {
- caOc = new String[] {"top",
- "person",
- "organizationalPerson",
- "inetOrgPerson",
- "certificationAuthority"};
- }
+ "inetOrgPerson"};
String oOc[] = {"top",
"organization"};
@@ -282,16 +264,6 @@ public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
attrs.add(new LDAPAttribute("cn", attrval[0]));
attrs.add(new LDAPAttribute("sn", attrval[0]));
attrs.add(new LDAPAttribute("objectclass", caOc));
- attrs.add(new LDAPAttribute(
- "authorityRevocationList;binary", ""));
- attrs.add(new LDAPAttribute(
- "cACertificate;binary", ""));
- attrs.add(new LDAPAttribute(
- "certificateRevocationList;binary", ""));
- if (isV2) {
- attrs.add(new LDAPAttribute(
- "deltaRevocationList;binary", ""));
- }
LDAPEntry entry = new LDAPEntry(dn, attrs);
conn.add(entry);
@@ -366,7 +338,6 @@ public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
v.addElement(PROP_DNPATTERN + "=");
v.addElement(PROP_CREATECA + "=true");
- v.addElement(PROP_CA_V2 + "=false");
return v;
}
@@ -381,7 +352,6 @@ public class LdapCaSimpleMap implements ILdapMapper, IExtendedPluginInfo {
mConfig.getString(PROP_DNPATTERN));
}
v.addElement(PROP_CREATECA + "=" + mConfig.getBoolean(PROP_CREATECA, true));
- v.addElement(PROP_CA_V2 + "=" + mConfig.getBoolean(PROP_CA_V2, false));
} catch (Exception e) {
}
return v;
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
index d0c2e5efd..9f39f736d 100644
--- a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCaCertPublisher.java
@@ -39,9 +39,13 @@ public class LdapCaCertPublisher
implements ILdapPublisher, IExtendedPluginInfo {
public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
public static final String LDAP_CA_OBJECTCLASS = "certificationAuthority";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
protected String mCaCertAttr = LDAP_CACERT_ATTR;
protected String mCaObjectclass = LDAP_CA_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
private ILogger mLogger = CMS.getLogger();
private boolean mInited = false;
@@ -58,13 +62,14 @@ public class LdapCaCertPublisher
public String[] getExtendedPluginInfo(Locale locale) {
String s[] = {
"caCertAttr;string;Name of Ldap attribute in which to store certificate",
- "caObjectClass;string;The name of the objectclass which should be " +
- "added to this entry, if it does not already exist",
+ "caObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be " +
+ "'certificationAuthority' (if using RFC 2256) or 'pkiCA' (if using RFC 4523)",
IExtendedPluginInfo.HELP_TOKEN +
";configuration-ldappublish-publisher-cacertpublisher",
IExtendedPluginInfo.HELP_TEXT +
";This plugin knows how to publish the CA cert to " +
- "'certificateAuthority'-type entries"
+ "'certificateAuthority' and 'pkiCA' -type entries"
};
return s;
@@ -104,8 +109,10 @@ public class LdapCaCertPublisher
return;
mConfig = config;
mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
- mCaObjectclass = mConfig.getString("caObjectclass",
+ mCaObjectclass = mConfig.getString("caObjectClass",
LDAP_CA_OBJECTCLASS);
+ mObjAdded = mConfig.getString("caObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("caObjectClassDeleted", "");
mInited = true;
}
@@ -146,6 +153,12 @@ public class LdapCaCertPublisher
return;
}
+ try {
+ mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
// Bugscape #56124 - support multiple publishing directory
// see if we should create local connection
LDAPConnection altConn = null;
@@ -183,28 +196,30 @@ public class LdapCaCertPublisher
try {
byte[] certEnc = cert.getEncoded();
- // check if entry has CA objectclass. If not use modify set.
+ /* search for attribute names to determine existence of attributes */
LDAPSearchResults res =
conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
- new String[] { "objectclass", mCaCertAttr }, false);
+ new String[] { LDAP_CRL_ATTR, LDAP_ARL_ATTR }, true);
LDAPEntry entry = res.next();
- LDAPAttribute ocs = entry.getAttribute("objectclass");
- LDAPAttribute certs = entry.getAttribute(mCaCertAttr);
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
+
+ /* search for objectclass and caCert values */
+ LDAPSearchResults res1 =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass", mCaCertAttr }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+ LDAPAttribute certs = entry1.getAttribute(mCaCertAttr);
boolean hasCert =
LdapUserCertPublisher.ByteValueExists(certs, certEnc);
- boolean hasoc =
- LdapUserCertPublisher.StringValueExists(ocs, mCaObjectclass);
LDAPModificationSet modSet = new LDAPModificationSet();
if (hasCert) {
log(ILogger.LL_INFO, "publish: CA " + dn + " already has Cert");
- //throw new ELdapException(
- // LdapResources.ALREADY_PUBLISHED_1, dn);
- return;
- } else {
-
+ } else {
/*
fix for 360458 - if no cert, use add, if has cert but
not equal, use replace
@@ -218,13 +233,69 @@ public class LdapCaCertPublisher
new LDAPAttribute(mCaCertAttr, certEnc));
log(ILogger.LL_INFO, "CA cert replaced");
}
+ }
+
+ String[] oclist = mCaObjectclass.split(",");
+
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
if (!hasoc) {
- log(ILogger.LL_INFO, "adding CA objectclass to " + dn);
+ log(ILogger.LL_INFO, "adding CA objectclass " + oc + " to " + dn);
modSet.add(LDAPModification.ADD,
- new LDAPAttribute("objectclass", mCaObjectclass));
+ new LDAPAttribute("objectclass", oc));
+
+ if ((!attrsAdded) &&
+ (oc.equalsIgnoreCase("certificationAuthority") ||
+ oc.equalsIgnoreCase("certificationAuthority-V2"))) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (crls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ attrsAdded = true;
+ }
}
}
- conn.modify(dn, modSet);
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CA objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("caObjectClassAdded", "");
+ mConfig.putString("caObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
+
+ if (modSet.size() > 0) conn.modify(dn, modSet);
} catch (CertificateEncodingException e) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_CANT_DECODE_CERT", dn));
throw new ELdapException(CMS.getUserMessage("CMS_LDAP_GET_DER_ENCODED_CERT_FAILED", e.toString()));
@@ -265,6 +336,12 @@ public class LdapCaCertPublisher
X509Certificate cert = (X509Certificate) certObj;
try {
+ mCaCertAttr = mConfig.getString("caCertAttr", LDAP_CACERT_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ try {
byte[] certEnc = cert.getEncoded();
LDAPSearchResults res =
@@ -277,8 +354,6 @@ public class LdapCaCertPublisher
boolean hasCert =
LdapUserCertPublisher.ByteValueExists(certs, certEnc);
- boolean hasOC =
- LdapUserCertPublisher.StringValueExists(ocs, mCaObjectclass);
if (!hasCert) {
log(ILogger.LL_INFO, "unpublish: " + dn + " has not cert already");
@@ -293,9 +368,17 @@ public class LdapCaCertPublisher
new LDAPAttribute(mCaCertAttr, certEnc));
if (certs.size() == 1) {
// if last ca cert, remove oc also.
- log(ILogger.LL_INFO, "unpublish: deleting CA oc from " + dn);
- modSet.add(LDAPModification.DELETE,
- new LDAPAttribute("objectclass", mCaObjectclass));
+
+ String[] oclist = mCaObjectclass.split(",");
+ for (int i =0 ; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasOC = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (hasOC) {
+ log(ILogger.LL_INFO, "unpublish: deleting CA oc" + oc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", oc));
+ }
+ }
}
conn.modify(dn, modSet);
} catch (CertificateEncodingException e) {
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
index 1fa786706..1ef14fb96 100644
--- a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCertificatePairPublisher.java
@@ -40,9 +40,14 @@ public class LdapCertificatePairPublisher
implements ILdapPublisher, IExtendedPluginInfo {
public static final String LDAP_CROSS_CERT_PAIR_ATTR = "crossCertificatePair;binary";
public static final String LDAP_CA_OBJECTCLASS = "certificationAuthority";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
+ public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
protected String mCrossCertPairAttr = LDAP_CROSS_CERT_PAIR_ATTR;
protected String mCaObjectclass = LDAP_CA_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
private ILogger mLogger = CMS.getLogger();
private boolean mInited = false;
@@ -57,13 +62,14 @@ public class LdapCertificatePairPublisher
public String[] getExtendedPluginInfo(Locale locale) {
String s[] = {
"crossCertPairAttr;string;Name of Ldap attribute in which to store cross certificates",
- "caObjectClass;string;The name of the objectclass which should be " +
- "added to this entry, if it does not already exist",
+ "caObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be " +
+ "'certificationAuthority' (if using RFC 2256) or 'pkiCA' (if using RFC 4523)",
IExtendedPluginInfo.HELP_TOKEN +
";configuration-ldappublish-publisher-crosscertpairpublisher",
IExtendedPluginInfo.HELP_TEXT +
";This plugin knows how to publish the CA cert to " +
- "'certificateAuthority'-type entries"
+ "'certificateAuthority' and 'pkiCA' -type entries"
};
return s;
@@ -85,6 +91,10 @@ public class LdapCertificatePairPublisher
return v;
}
+ public Vector getInstanceParamsWithExtras() {
+ return getInstanceParams();
+ }
+
public Vector getDefaultParams() {
Vector v = new Vector();
@@ -103,8 +113,11 @@ public class LdapCertificatePairPublisher
return;
mConfig = config;
mCrossCertPairAttr = mConfig.getString("crossCertPairAttr", LDAP_CROSS_CERT_PAIR_ATTR);
- mCaObjectclass = mConfig.getString("caObjectclass",
+ mCaObjectclass = mConfig.getString("caObjectClass",
LDAP_CA_OBJECTCLASS);
+ mObjAdded = mConfig.getString("caObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("caObjectClassDeleted", "");
+
mInited = true;
}
@@ -158,27 +171,108 @@ public class LdapCertificatePairPublisher
}
try {
- // check to see if already published
- LDAPSearchResults res =
- conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
- new String[] { "objectclass", "crosscertificatepair;binary" }, false);
+ mCrossCertPairAttr = mConfig.getString("crossCertPairAttr", LDAP_CROSS_CERT_PAIR_ATTR);
+ mCaObjectclass = mConfig.getString("caObjectClass", LDAP_CA_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+ try {
+ // search for attributes to determine if they exist
+ LDAPSearchResults res =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CACERT_ATTR, LDAP_CRL_ATTR, LDAP_ARL_ATTR }, true);
LDAPEntry entry = res.next();
- LDAPAttribute certPairs = entry.getAttribute("crosscertificatepair;binary");
+ LDAPAttribute certs = entry.getAttribute(LDAP_CACERT_ATTR);
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
- if (LdapUserCertPublisher.ByteValueExists(certPairs, pair)
- == true) {
+ // search for objectclass and crosscertpair attributes and values
+ LDAPSearchResults res1 =
+ conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass", mCrossCertPairAttr }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+ LDAPAttribute certPairs = entry1.getAttribute("crosscertificatepair;binary");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ boolean hasCert = LdapUserCertPublisher.ByteValueExists(certPairs, pair);
+ if (LdapUserCertPublisher.ByteValueExists(certPairs, pair)) {
CMS.debug("LdapCertificatePairPublisher: cross cert pair bytes exist in publishing directory, do not publish again.");
return;
}
+ if (hasCert) {
+ log(ILogger.LL_INFO, "publish: CA " + dn + " already has cross cert pair bytes");
+ } else {
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(mCrossCertPairAttr, pair));
+ log(ILogger.LL_INFO, "cross cert pair published with dn=" + dn);
+ }
- // publish certificatePair
- LDAPModificationSet modSet = new LDAPModificationSet();
+ String[] oclist = mCaObjectclass.split(",");
+
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (!hasoc) {
+ log(ILogger.LL_INFO, "adding CA objectclass " + oc + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute("objectclass", oc));
- modSet.add(LDAPModification.ADD,
- new LDAPAttribute(mCrossCertPairAttr, pair));
- CMS.debug("LdapCertificatePairPublisher: in publish() about to publish with dn=" + dn);
+ if ((!attrsAdded) &&
+ (oc.equalsIgnoreCase("certificationAuthority") ||
+ oc.equalsIgnoreCase("certificationAuthority-V2"))) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (crls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ if (certs == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CACERT_ATTR, ""));
+ attrsAdded = true;
+ }
+ }
+ }
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CRL objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("caObjectClassAdded", "");
+ mConfig.putString("caObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
- conn.modify(dn, modSet);
+ if (modSet.size() > 0) conn.modify(dn, modSet);
CMS.debug("LdapCertificatePairPublisher: in publish() just published");
} catch (LDAPException e) {
if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) {
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
index 6327291ed..ebe86ad91 100644
--- a/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/LdapCrlPublisher.java
@@ -41,10 +41,16 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
protected IConfigStore mConfig = null;
boolean mInited = false;
- public static final String
- LDAP_CRL_ATTR = "certificateRevocationList;binary";
+ public static final String LDAP_CACERT_ATTR = "caCertificate;binary";
+ public static final String LDAP_ARL_ATTR = "authorityRevocationList;binary";
+ public static final String LDAP_CRL_ATTR = "certificateRevocationList;binary";
+ public static final String LDAP_CRL_OBJECTCLASS = "certificationAuthority,certficationAuthority-V2";
- String mCrlAttr = LDAP_CRL_ATTR;
+
+ protected String mCrlAttr = LDAP_CRL_ATTR;
+ protected String mCrlObjectClass = LDAP_CRL_OBJECTCLASS;
+ protected String mObjAdded = "";
+ protected String mObjDeleted = "";
/**
* constructs ldap crl publisher with default values
@@ -63,10 +69,15 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
public String[] getExtendedPluginInfo(Locale locale) {
String[] params = {
"crlAttr;string;Name of Ldap attribute in which to store the CRL",
+ "crlObjectClass;string;The name of the objectclasses which should be " +
+ "added to this entry, if they do not already exist. This can be a comma-" +
+ "separated list such as 'certificationAuthority,certificationAuthority-V2' " +
+ "(if using RFC 2256) or 'pkiCA, deltaCRL' (if using RFC 4523)",
IExtendedPluginInfo.HELP_TOKEN +
";configuration-ldappublish-publisher-crlpublisher",
IExtendedPluginInfo.HELP_TEXT +
- ";This plugin knows how to publish CRL's to an LDAP directory"
+ ";This plugin knows how to publish CRL's to " +
+ "'certificateAuthority' and 'pkiCA' -type entries"
};
return params;
@@ -76,6 +87,7 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
Vector v = new Vector();
v.addElement("crlAttr=" + mCrlAttr);
+ v.addElement("crlObjectClass=" + mCrlObjectClass);
return v;
}
@@ -83,6 +95,7 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
Vector v = new Vector();
v.addElement("crlAttr=" + mCrlAttr);
+ v.addElement("crlObjectClass=" + mCrlObjectClass);
return v;
}
@@ -96,11 +109,24 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
return;
mConfig = config;
mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass",
+ LDAP_CRL_OBJECTCLASS);
+ mObjAdded = mConfig.getString("crlObjectClassAdded", "");
+ mObjDeleted = mConfig.getString("crlObjectClassDeleted", "");
+
mInited = true;
}
- public LdapCrlPublisher(String crlAttr) {
+ public LdapCrlPublisher(String crlAttr, String crlObjectClass) {
mCrlAttr = crlAttr;
+ mCrlObjectClass = crlObjectClass;
+ }
+
+ /**
+ * Gets the CA object class to convert to.
+ */
+ public String getCRLObjectclass() {
+ return mCrlObjectClass;
}
/**
@@ -114,6 +140,12 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
return;
}
+ try {
+ mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass", LDAP_CRL_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
// Bugscape #56124 - support multiple publishing directory
// see if we should create local connection
LDAPConnection altConn = null;
@@ -144,10 +176,98 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
try {
byte[] crlEnc = ((X509CRL) crlObj).getEncoded();
-
log(ILogger.LL_INFO, "publish CRL: " + dn);
- conn.modify(dn, new LDAPModification(LDAPModification.REPLACE,
- new LDAPAttribute(mCrlAttr, crlEnc)));
+
+ /* search for attribute names to determine existence of attributes */
+ LDAPSearchResults res = null;
+ if (mCrlAttr.equals(LDAP_CRL_ATTR)) {
+ res = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CACERT_ATTR, LDAP_ARL_ATTR }, true);
+ } else {
+ res = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { LDAP_CRL_ATTR, LDAP_CACERT_ATTR, LDAP_ARL_ATTR }, true);
+ }
+
+ LDAPEntry entry = res.next();
+ LDAPAttribute crls = entry.getAttribute(LDAP_CRL_ATTR);
+ LDAPAttribute certs = entry.getAttribute(LDAP_CACERT_ATTR);
+ LDAPAttribute arls = entry.getAttribute(LDAP_ARL_ATTR);
+
+ /* get object class values */
+ LDAPSearchResults res1 = null;
+ res1 = conn.search(dn, LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ new String[] { "objectclass" }, false);
+ LDAPEntry entry1 = res1.next();
+ LDAPAttribute ocs = entry1.getAttribute("objectclass");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ String[] oclist = mCrlObjectClass.split(",");
+ boolean attrsAdded = false;
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, oc);
+ if (!hasoc) {
+ log(ILogger.LL_INFO, "adding CRL objectclass " + oc + " to " + dn);
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute("objectclass", oc));
+
+ if ((!attrsAdded) &&
+ (oc.equalsIgnoreCase("certificationAuthority") ||
+ oc.equalsIgnoreCase("certificationAuthority-V2"))) {
+ // add MUST attributes
+ if (arls == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_ARL_ATTR, ""));
+ if (certs == null)
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CACERT_ATTR, ""));
+
+ if ((crls == null) && (!mCrlAttr.equals(LDAP_CRL_ATTR)))
+ modSet.add(LDAPModification.ADD,
+ new LDAPAttribute(LDAP_CRL_ATTR, ""));
+ attrsAdded = true;
+ }
+ }
+ }
+
+ modSet.add(LDAPModification.REPLACE, new LDAPAttribute(mCrlAttr, crlEnc));
+
+ // delete objectclasses that have been deleted from config
+ String[] delList = mObjDeleted.split(",");
+ if (delList.length > 0) {
+ for (int i=0; i< delList.length; i++) {
+ String deloc = delList[i].trim();
+ boolean hasoc = LdapUserCertPublisher.StringValueExists(ocs, deloc);
+ boolean match = false;
+ for (int j=0; j< oclist.length; j++) {
+ if ((oclist[j].trim()).equals(deloc)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match && hasoc) {
+ log(ILogger.LL_INFO, "deleting CRL objectclass " + deloc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectclass", deloc));
+ }
+ }
+ }
+
+ // reset mObjAdded and mObjDeleted, if needed
+ if ((!mObjAdded.equals("")) || (!mObjDeleted.equals(""))) {
+ mObjAdded = "";
+ mObjDeleted = "";
+ mConfig.putString("crlObjectClassAdded", "");
+ mConfig.putString("crlObjectClassDeleted", "");
+ try {
+ mConfig.commit(false);
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, "Failure in updating mObjAdded and mObjDeleted");
+ }
+ }
+
+ conn.modify(dn, modSet);
} catch (CRLException e) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_PUBLISH_ERROR", e.toString()));
throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CRL_ERROR", e.toString()));
@@ -184,18 +304,47 @@ public class LdapCrlPublisher implements ILdapPublisher, IExtendedPluginInfo {
try {
byte[] crlEnc = ((X509CRL) crlObj).getEncoded();
+ try {
+ mCrlAttr = mConfig.getString("crlAttr", LDAP_CRL_ATTR);
+ mCrlObjectClass = mConfig.getString("crlObjectClass", LDAP_CRL_OBJECTCLASS);
+ } catch (EBaseException e) {
+ }
+
+
LDAPSearchResults res = conn.search(dn, LDAPv2.SCOPE_BASE,
- "(objectclass=*)", new String[] { mCrlAttr }, false);
+ "(objectclass=*)", new String[] { mCrlAttr, "objectclass" }, false);
LDAPEntry e = res.next();
LDAPAttribute crls = e.getAttribute(mCrlAttr);
+ LDAPAttribute ocs = e.getAttribute("objectclass");
+
+ LDAPModificationSet modSet = new LDAPModificationSet();
+
+ boolean hasOC = false;
+ boolean hasCRL =
+ LdapUserCertPublisher.ByteValueExists(crls, crlEnc);
- if (!LdapUserCertPublisher.ByteValueExists(crls, crlEnc)) {
- log(ILogger.LL_INFO,
+ if (hasCRL) {
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute(mCrlAttr, crlEnc));
+ }
+
+ String[] oclist = mCrlObjectClass.split(",");
+ for (int i=0; i < oclist.length; i++) {
+ String oc = oclist[i].trim();
+ if (LdapUserCertPublisher.StringValueExists(ocs, oc)) {
+ log(ILogger.LL_INFO, "unpublish: deleting CRL object class " + oc + " from " + dn);
+ modSet.add(LDAPModification.DELETE,
+ new LDAPAttribute("objectClass", oc));
+ hasOC = true;
+ }
+ }
+
+ if (hasCRL || hasOC) {
+ conn.modify(dn, modSet);
+ } else {
+ log(ILogger.LL_INFO,
"unpublish: " + dn + " already has not CRL");
- return;
}
- conn.modify(dn, new LDAPModification(LDAPModification.DELETE,
- new LDAPAttribute(mCrlAttr, crlEnc)));
} catch (CRLException e) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_UNPUBLISH_ERROR", e.toString()));
throw new ELdapException(CMS.getUserMessage("CMS_LDAP_PUBLISH_CRL_ERROR", e.toString()));
diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java b/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
index cec42e7a7..4e0132e36 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/PublisherAdminServlet.java
@@ -2777,6 +2777,16 @@ public class PublisherAdminServlet extends AdminServlet {
mConfig.getSubStore(mAuth.getId() + ".publish.publisher");
IConfigStore instancesConfig = destStore.getSubStore("instance");
+ // get objects added and deleted
+ String pubType = instancesConfig.getString(id + ".pubtype", "");
+ if (pubType.equals("cacert")) {
+ saveParams.add("caObjectClassAdded", instancesConfig.getString(id + ".caObjectClassAdded", ""));
+ saveParams.add("caObjectClassDeleted", instancesConfig.getString(id + ".caObjectClassDeleted", ""));
+ } else if (pubType.equals("crl")) {
+ saveParams.add("crlObjectClassAdded", instancesConfig.getString(id + ".crlObjectClassAdded", ""));
+ saveParams.add("crlObjectClassDeleted", instancesConfig.getString(id + ".crlObjectClassDeleted", ""));
+ }
+
// create new substore.
Vector configParams = mProcessor.getPublisherInstanceParams(id);
@@ -2799,6 +2809,17 @@ public class PublisherAdminServlet extends AdminServlet {
}
}
+ // process any changes to the ldap object class definitions
+ if (pubType.equals("cacert")) {
+ processChangedOC(saveParams, substore, "caObjectClass");
+ substore.put("pubtype", "cacert");
+ }
+
+ if (pubType.equals("crl")) {
+ processChangedOC(saveParams, substore, "crlObjectClass");
+ substore.put("pubtype", "crl");
+ }
+
// Instantiate an object for new implementation
String className = plugin.getClassPath();
@@ -2868,6 +2889,113 @@ public class PublisherAdminServlet extends AdminServlet {
return;
}
+ // convenience function - takes list1, list2. Returns what is in list1
+ // but not in list2
+ private String[] getExtras(String[] list1, String[] list2) {
+ Vector <String> extras = new Vector<String>();
+ for (int i=0; i< list1.length; i++) {
+ boolean match=false;
+ for (int j=0; j < list2.length; j++) {
+ if ((list1[i].trim()).equalsIgnoreCase(list2[j].trim())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) extras.add(list1[i].trim());
+ }
+
+ return (String[])extras.toArray(new String[extras.size()]);
+ }
+
+ // convenience function - takes list1, list2. Concatenates the two
+ // lists removing duplicates
+ private String[] joinLists(String[] list1, String[] list2) {
+ Vector <String> sum = new Vector<String>();
+ for (int i=0; i< list1.length; i++) {
+ sum.add(list1[i]);
+ }
+
+ for (int i=0; i < list2.length; i++) {
+ boolean match=false;
+ for (int j=0; j < list1.length; j++) {
+ if ((list2[i].trim()).equalsIgnoreCase(list1[j].trim())) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) sum.add(list2[i].trim());
+ }
+
+ return (String[])sum.toArray(new String[sum.size()]);
+ }
+
+ // convenience funtion. Takes a string array and delimiter
+ // and returns a String with the concatenation
+ private static String join(String[] s, String delimiter) {
+ if (s.length == 0) return "";
+
+ StringBuffer buffer = new StringBuffer(s[0]);
+ if (s.length > 1) {
+ for (int i=1; i< s.length; i++) {
+ buffer.append(delimiter).append(s[i].trim());
+ }
+ }
+ return buffer.toString();
+ }
+
+ private void processChangedOC(NameValuePairs saveParams, IConfigStore newstore, String objName) {
+ String newOC = null, oldOC = null;
+ String oldAdded = null, oldDeleted = null;
+
+ try {
+ newOC = newstore.getString(objName);
+ } catch (Exception e) {
+ }
+
+ oldOC = saveParams.getValue(objName);
+ oldAdded = saveParams.getValue(objName + "Added");
+ oldDeleted = saveParams.getValue(objName + "Deleted");
+
+ if ((oldOC == null) || (newOC == null)) return;
+ if (oldOC.equalsIgnoreCase(newOC)) return;
+
+ String [] oldList = oldOC.split(",");
+ String [] newList = newOC.split(",");
+ String [] deletedList = getExtras(oldList, newList);
+ String [] addedList = getExtras(newList, oldList);
+
+ // CMS.debug("addedList = " + join(addedList, ","));
+ // CMS.debug("deletedList = " + join(deletedList, ","));
+
+ if ((addedList.length ==0) && (deletedList.length == 0))
+ return; // no changes
+
+ if (oldAdded != null) {
+ // CMS.debug("oldAdded is " + oldAdded);
+ String [] oldAddedList = oldAdded.split(",");
+ addedList = joinLists(addedList, oldAddedList);
+ }
+
+ if (oldDeleted != null) {
+ // CMS.debug("oldDeleted is " + oldDeleted);
+ String [] oldDeletedList = oldDeleted.split(",");
+ deletedList = joinLists(deletedList, oldDeletedList);
+ }
+
+ String[] addedList1 = getExtras(addedList, deletedList);
+ String[] deletedList1 = getExtras(deletedList, addedList);
+
+ //create the final strings and write to config
+ String addedListStr = join(addedList1, ",");
+ String deletedListStr = join(deletedList1, ",");
+
+ CMS.debug("processChangedOC: added list is " + addedListStr);
+ CMS.debug("processChangedOC: deleted list is " + deletedListStr);
+
+ newstore.put(objName + "Added", addedListStr);
+ newstore.put(objName + "Deleted", deletedListStr);
+ }
+
// convenience routine.
private static void restore(IConfigStore store,
String id, NameValuePairs saveParams) {