From 3897f253ba3cbcfda615c9233da49def1f71cabd Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Thu, 30 Aug 2007 03:59:38 +0000
Subject: [PATCH] Issue 466 partial.
---
opends/src/ads/org/opends/admin/ads/ADSContext.java | 212 ++++++++++-------------------------
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java | 101 +++++++++++++++-
2 files changed, 151 insertions(+), 162 deletions(-)
diff --git a/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opends/src/ads/org/opends/admin/ads/ADSContext.java
index 4f6a8df..74989dc 100644
--- a/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -80,7 +80,12 @@
/**
* Boolean syntax.
*/
- BOOLEAN
+ BOOLEAN,
+
+ /**
+ * Certificate;binary syntax.
+ */
+ CERTIFICATE_BINARY
}
/**
@@ -156,7 +161,18 @@
/**
* The groups to which this server belongs.
*/
- GROUPS("memberofgroups",ADSPropertySyntax.STRING);
+ GROUPS("memberofgroups",ADSPropertySyntax.STRING),
+ /**
+ * The unique name of the instance key public-key certificate.
+ */
+ INSTANCE_KEY_ID("ds-cfg-key-id", ADSPropertySyntax.STRING),
+ /**
+ * The instance key-pair public-key certificate. Note: This attribute
+ * belongs to an instance key entry, separate from the server entry and
+ * named by the ds-cfg-key-id attribute from the server entry.
+ */
+ INSTANCE_KEY_CERT("ds-cfg-public-key-certificate"/*;binary*/,
+ ADSPropertySyntax.CERTIFICATE_BINARY);
private String attrName;
private ADSPropertySyntax attSyntax;
@@ -393,10 +409,45 @@
{
LdapName dn = makeDNFromServerProperties(serverProperties);
BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
+
+ /* Instance key-pair public-key certificate: generate a key-id attribute
+ for the server entry, then an instance key entry for the key. */
+ LdapName keyDn = null;
+ BasicAttributes keyAttrs = null;
+ if (serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT))
+ {
+ String keyID
+ = (String)serverProperties.get(ServerProperty.INSTANCE_KEY_ID);
+ if (null == keyID)
+ {
+ keyID = java.util.UUID.randomUUID().toString();
+ }
+ attrs.put(new BasicAttribute(
+ ServerProperty.INSTANCE_KEY_ID.getAttributeName(),
+ keyID));
+
+ String rdnStr = Rdn.escapeValue(keyID);
+ keyDn = nameFromDN(ServerProperty.INSTANCE_KEY_ID.getAttributeName()
+ + "=" + rdnStr + "," + getInstanceKeysContainerDN());
+ keyAttrs = new BasicAttributes();
+ Attribute oc = new BasicAttribute("objectclass");
+ oc.add("top");
+ oc.add("ds-cfg-instance-key-OID");
+ keyAttrs.put(oc);
+ keyAttrs.put(new BasicAttribute(
+ ServerProperty.INSTANCE_KEY_ID.getAttributeName(),
+ rdnStr));
+ keyAttrs.put(new BasicAttribute(
+ ServerProperty.INSTANCE_KEY_CERT.getAttributeName() + ";binary",
+ serverProperties.get(ServerProperty.INSTANCE_KEY_CERT)));
+ }
+
try
{
DirContext ctx = dirContext.createSubcontext(dn, attrs);
ctx.close();
+ ctx = dirContext.createSubcontext(keyDn, keyAttrs);
+ ctx.close();
}
catch (NameAlreadyBoundException x)
{
@@ -1303,14 +1354,17 @@
switch(property)
{
- case GROUPS:
- result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName());
+ case INSTANCE_KEY_CERT:
+ result = null; // used in separate instance key entry
+ break;
+ case GROUPS:
+ result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName());
for (Object o : ((Set) value)) {
result.add(o);
}
break;
- default:
- result = new BasicAttribute(property.getAttributeName(), value);
+ default:
+ result = new BasicAttribute(property.getAttributeName(), value);
}
return result;
}
@@ -1873,8 +1927,6 @@
}
helper.createAdministrationSuffix(getDirContext(), ben,
getDbName(), getImportTemp());
-
- retrieveLocalInstanceKeyCertificate();
}
/**
@@ -1909,150 +1961,6 @@
*/
/**
- * The enumeration consisting of properties of the instance-key public-key
- * certificate entries in ADS.
- */
- public enum InstanceKeyProperty
- {
- /**
- * The unique name of the instance key public-key certificate.
- */
- KEY_ID("ds-cfg-key-id",ADSPropertySyntax.STRING),
-
- /**
- * The public-key certificate of the instance key.
- */
- KEY_CERT("ds-cfg-public-key-certificate;binary",ADSPropertySyntax.STRING);
-
- private String attrName;
- private ADSPropertySyntax attrSyntax;
-
- /**
- * Private constructor.
- * @param n the name of the attribute.
- * @param s the name of the syntax.
- */
- private InstanceKeyProperty(String n, ADSPropertySyntax s)
- {
- attrName = n;
- attrSyntax = s ;
- }
-
- /**
- * Returns the attribute name.
- * @return the attribute name.
- */
- public String getAttributeName()
- {
- return attrName;
- }
-
- /**
- * Returns the attribute syntax.
- * @return the attribute syntax.
- */
- public ADSPropertySyntax getAttributeSyntax()
- {
- return attrSyntax;
- }
- }
-
- /*
- * The instance-key public-key certificate from the local truststore of the
- * instance bound by this context.
- */
- private byte[] localInstanceKeyCertificate = null;
-
- /**
- * Updates the instance key public-key certificate value of this context from
- * the local truststore of the instance bound by this context. Any current
- * value of the certificate is overwritten. The intent of this method is to
- * retrieve the instance-key public-key certificate when this context is bound
- * to an instance, and cache it for later use in registering the instance into
- * ADS.
- *
- * @throws ADSContextException if unable to retrieve certificate from bound
- * instance.
- */
- private void retrieveLocalInstanceKeyCertificate() throws ADSContextException
- {
- if( ! isExistingEntry(nameFromDN("cn=ads-truststore")))
- {
- return; /* TODO: Once Andy commits the truststore backend, this case is
- an exceptional condition and will be caught below (i.e., remove
- this code). */
- }
-
- /* TODO: this DN is declared in some core constants file. Create a constants
- file for the installer and import it into the core. */
- final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore";
- localInstanceKeyCertificate = null;
- for (int i = 0; null == localInstanceKeyCertificate && i < 2 ; ++i ) {
- /* If the entry does not exist in the instance's truststore backend, add
- it (which induces the CryptoManager to create the public-key
- certificate attribute), then repeat the search. */
- try {
- final SearchControls sc = new SearchControls();
- sc.setSearchScope(SearchControls.OBJECT_SCOPE);
- final String attrIDs[] = { "ds-cfg-public-key-certificate;binary" };
- sc.setReturningAttributes(attrIDs);
- final SearchResult adsCertEntry
- = dirContext.search(nameFromDN(dnStr), "(objectclass=*)", sc).next();
- final Attribute certAttr = adsCertEntry.getAttributes().get(
- "ds-cfg-public-key-certificate;binary");
- if (null != certAttr) {
- localInstanceKeyCertificate = (byte[])certAttr.get();
- }
- }
- catch (NameNotFoundException x) {
- if (0 == i) {
- /* Poke CryptoManager to initialize truststore. Note that createEntry
- wraps any JNDI exception with an ADSException. */
- final BasicAttributes attrs = new BasicAttributes();
- final Attribute oc = new BasicAttribute("objectclass");
- oc.add("top");
- oc.add("ds-cfg-self-signed-cert-request");
- attrs.put(oc);
- createEntry(dnStr, attrs);
- }
- else {
- throw new ADSContextException(
- ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
- }
- }
- catch (NoPermissionException x) {
- throw new ADSContextException(
- ADSContextException.ErrorType.ACCESS_PERMISSION, x);
- }
- catch (javax.naming.NamingException x) {
- throw new ADSContextException(
- ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
- }
- }
-
- if (null == localInstanceKeyCertificate) {
- throw new ADSContextException(
- ADSContextException.ErrorType.ERROR_UNEXPECTED);
- }
- }
-
- /**
- * Returns the instance-key public-key certificate directly from the
- * truststore backend of the instance referenced through this context.
- *
- * @return The public-key certificate of the instance.
- *
- * @throws ADSContextException if public-key certificate cannot be retrieved.
- */
- public byte[] getLocalInstanceKeyCertificate() throws ADSContextException
- {
- if (null == localInstanceKeyCertificate) {
- retrieveLocalInstanceKeyCertificate();
- }
- return localInstanceKeyCertificate;
- }
-
- /**
* Returns the parent entry of the server key entries in ADS.
* @return the parent entry of the server key entries in ADS.
*/
diff --git a/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
index 1e9061d..a955024 100644
--- a/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
+++ b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -33,11 +33,14 @@
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
-import java.util.logging.Logger;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
@@ -119,10 +122,13 @@
/**
* The associated value is an Integer.
*/
- REPLICATION_SERVER_ID
+ REPLICATION_SERVER_ID,
+ /**
+ * The instance key-pair public-key certificate. The associated value is a
+ * byte[] (ds-cfg-public-key-certificate;binary).
+ */
+ INSTANCE_PUBLIC_KEY_CERTIFICATE
}
- private static final Logger LOG =
- Logger.getLogger(ServerDescriptor.class.getName());
private ServerDescriptor()
{
@@ -353,12 +359,10 @@
ServerProperty.LDAP_PORT, ServerProperty.LDAPS_PORT,
ServerProperty.LDAP_ENABLED, ServerProperty.LDAPS_ENABLED
};
- for (int i=0; i<props.length; i++)
- {
- ArrayList s = (ArrayList)serverProperties.get(props[i]);
- for (Object o : s)
- {
- buf.append(":"+o);
+ for (ServerProperty prop : props) {
+ ArrayList s = (ArrayList) serverProperties.get(prop);
+ for (Object o : s) {
+ buf.append(":").append(o);
}
}
}
@@ -385,6 +389,18 @@
}
/**
+ * Returns the instance-key public-key certificate retrieved from the
+ * truststore backend of the instance referenced through this descriptor.
+ *
+ * @return The public-key certificate of the instance.
+ */
+ public byte[] getInstancePublicKeyCertificate()
+ {
+ return((byte[])
+ serverProperties.get(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE));
+ }
+
+ /**
* Returns the last exception that was encountered reading the configuration
* of the server. Returns null if there was no problem loading the
* configuration of the server.
@@ -466,6 +482,8 @@
}
}
adsProperties.put(ADSContext.ServerProperty.ID, getHostPort(true));
+ adsProperties.put(ADSContext.ServerProperty.INSTANCE_KEY_CERT,
+ getInstancePublicKeyCertificate());
}
/**
@@ -502,6 +520,7 @@
updateJmxConfiguration(desc, ctx);
updateReplicas(desc, ctx);
updateReplication(desc, ctx);
+ updatePublicKeyCertificate(desc, ctx);
desc.serverProperties.put(ServerProperty.HOST_NAME,
ConnectionUtils.getHostName(ctx));
@@ -801,6 +820,68 @@
}
/**
+ * Updates the instance key public-key certificate value of this context from
+ * the local truststore of the instance bound by this context. Any current
+ * value of the certificate is overwritten. The intent of this method is to
+ * retrieve the instance-key public-key certificate when this context is bound
+ * to an instance, and cache it for later use in registering the instance into
+ * ADS.
+ *
+ * @param desc The map to update with the instance key-pair public-key
+ * certificate.
+ * @param ctx The bound server instance.
+ *
+ * @throws NamingException if unable to retrieve certificate from bound
+ * instance.
+ */
+ private static void updatePublicKeyCertificate(ServerDescriptor desc,
+ InitialLdapContext ctx) throws NamingException
+ {
+ /* TODO: this DN is declared in some core constants file. Create a constants
+ file for the installer and import it into the core. */
+ final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore";
+ final LdapName dn = new LdapName(dnStr);
+ byte[] localInstanceKeyCertificate = null;
+ for (int i = 0; null == localInstanceKeyCertificate && i < 2 ; ++i ) {
+ /* If the entry does not exist in the instance's truststore backend, add
+ it (which induces the CryptoManager to create the public-key
+ certificate attribute), then repeat the search. */
+ try {
+ final SearchControls sc = new SearchControls();
+ sc.setSearchScope(SearchControls.OBJECT_SCOPE);
+ final String attrIDs[] = { "ds-cfg-public-key-certificate;binary" };
+ sc.setReturningAttributes(attrIDs);
+ final SearchResult certEntry
+ = ctx.search(dn, "(objectclass=*)", sc).next();
+ final Attribute certAttr = certEntry.getAttributes().get(
+ "ds-cfg-public-key-certificate;binary");
+ if (null != certAttr) {
+ localInstanceKeyCertificate = (byte[])certAttr.get();
+ }
+ }
+ catch (NameNotFoundException x) {
+ if (0 == i) {
+ /* Poke CryptoManager to initialize truststore. Note the special
+ attribute in the request. */
+ final BasicAttributes attrs = new BasicAttributes();
+ final Attribute oc = new BasicAttribute("objectclass");
+ oc.add("top");
+ oc.add("ds-cfg-self-signed-cert-request");
+ attrs.put(oc);
+ DirContext pokeCtx = ctx.createSubcontext(dn, attrs);
+ pokeCtx.close();
+ }
+ else {
+ throw x;
+ }
+ }
+ }
+ desc.serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE,
+ localInstanceKeyCertificate);
+ }
+
+
+ /**
* Returns the number of entries in a given backend using the provided
* InitialLdapContext.
* @param ctx the InitialLdapContext to use to update the configuration.
--
Gitblit v1.10.0