summaryrefslogtreecommitdiffstats
path: root/base/server/cmscore/src
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2015-04-16 22:26:03 -0400
committerAde Lee <alee@redhat.com>2015-04-22 00:01:47 -0400
commit2c171ca8fafc1d688b9b965d1255a81aba6aa7ee (patch)
tree52ba5ee52e94789e7d9aebe690ee5e9e96a4f1bd /base/server/cmscore/src
parent922e237279fcf8ce9827f0e3cbed904758ad5123 (diff)
downloadpki-2c171ca8fafc1d688b9b965d1255a81aba6aa7ee.tar.gz
pki-2c171ca8fafc1d688b9b965d1255a81aba6aa7ee.tar.xz
pki-2c171ca8fafc1d688b9b965d1255a81aba6aa7ee.zip
Add nuxwdog functionality to Dogtag
This is the first of several commits. This adds a LifecycleListener to call init() on the nuxwdog client before any connectors or webapps start up, and call sendEndInit() once initialization completes. Code is also added to prompt for and test required passwords on startup. All that is required to use nuxwdog is to start the server using nuxwdog. An environment variable will be set that will trigger creation of the NuxwdogPasswordStore. We expect tags for the required passwords to be in cms.passwordList
Diffstat (limited to 'base/server/cmscore/src')
-rw-r--r--base/server/cmscore/src/CMakeLists.txt9
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java189
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java6
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java1
4 files changed, 179 insertions, 26 deletions
diff --git a/base/server/cmscore/src/CMakeLists.txt b/base/server/cmscore/src/CMakeLists.txt
index 94f5f138c..ef1293865 100644
--- a/base/server/cmscore/src/CMakeLists.txt
+++ b/base/server/cmscore/src/CMakeLists.txt
@@ -118,6 +118,14 @@ find_file(HTTPCORE_JAR
/usr/share/java/httpcomponents
)
+find_file(NUXWDOG_JAR
+ NAMES
+ nuxwdog.jar
+ PATHS
+ ${JAVA_LIB_INSTALL_DIR}
+ /usr/share/java
+)
+
# build pki-cmscore
javac(pki-cmscore-classes
SOURCES
@@ -130,6 +138,7 @@ javac(pki-cmscore-classes
${TOMCAT_CATALINA_JAR} ${TOMCAT_UTIL_JAR} ${SYMKEY_JAR}
${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${RESTEASY_ATOM_PROVIDER_JAR}
${HTTPCLIENT_JAR} ${HTTPCORE_JAR}
+ ${NUXWDOG_JAR}
OUTPUT_DIR
${CMAKE_BINARY_DIR}/classes
DEPENDS
diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
index b682130dd..b6750c615 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -58,6 +58,7 @@ import netscape.security.x509.X509CRLImpl;
import netscape.security.x509.X509CertImpl;
import netscape.security.x509.X509CertInfo;
+import org.apache.commons.lang.StringUtils;
import org.apache.xerces.parsers.DOMParser;
import org.mozilla.jss.CryptoManager.CertificateUsage;
import org.mozilla.jss.util.PasswordCallback;
@@ -174,6 +175,7 @@ import com.netscape.cmscore.usrgrp.UGSubsystem;
import com.netscape.cmscore.util.Debug;
import com.netscape.cmsutil.net.ISocketFactory;
import com.netscape.cmsutil.password.IPasswordStore;
+import com.netscape.cmsutil.password.NuxwdogPasswordStore;
import com.netscape.cmsutil.util.Utils;
public class CMSEngine implements ICMSEngine {
@@ -260,6 +262,14 @@ public class CMSEngine implements ICMSEngine {
{ null, null, null } //ssl_clientauth_EE
};
+ private static final int PW_OK =0;
+ private static final int PW_BAD_SETUP = 1;
+ private static final int PW_INVALID_PASSWORD = 2;
+ private static final int PW_CANNOT_CONNECT = 3;
+ private static final int PW_NO_USER = 4;
+ private static final int PW_MAX_ATTEMPTS = 3;
+
+
/**
* private constructor.
*/
@@ -281,41 +291,166 @@ public class CMSEngine implements ICMSEngine {
}
/**
- * Retrieves the instance roort path of this server.
+ * Retrieves the instance root path of this server.
*/
public String getInstanceDir() {
return instanceDir;
}
- public synchronized IPasswordStore getPasswordStore() {
- // initialize the PasswordReader and PasswordWriter
- try {
- String pwdPath = mConfig.getString("passwordFile");
- if (mPasswordStore == null) {
- CMS.debug("CMSEngine: getPasswordStore(): password store not initialized before.");
- String pwdClass = mConfig.getString("passwordClass");
+ public boolean startedByNuxwdog() {
+ String wdPipeName = System.getenv("WD_PIPE_NAME");
+ if (StringUtils.isNotEmpty(wdPipeName)) {
+ return true;
+ }
+ return false;
+ }
- try {
- mPasswordStore = (IPasswordStore) Class.forName(pwdClass).newInstance();
- } catch (Exception e) {
- CMS.debug("CMSEngine: getPasswordStore(): password store initialization failure:"
- + e.toString());
- throw e;
- }
+ public synchronized IPasswordStore getPasswordStore() throws EBaseException {
+ if (mPasswordStore == null) {
+ String pwdClass = null;
+ String pwdPath = null;
+
+ if (startedByNuxwdog()) {
+ pwdClass = NuxwdogPasswordStore.class.getName();
+ // note: pwdPath is expected to be null in this case
} else {
- CMS.debug("CMSEngine: getPasswordStore(): password store initialized before.");
+ pwdClass = mConfig.getString("passwordClass");
+ pwdPath = mConfig.getString("passwordFile", null);
}
- // have to initialize it because other places don't always
- mPasswordStore.init(pwdPath);
- CMS.debug("CMSEngine: getPasswordStore(): password store initialized.");
- } catch (Exception e) {
- CMS.debug("CMSEngine: getPasswordStore(): failure:" + e.toString());
+ try {
+ mPasswordStore = (IPasswordStore) Class.forName(pwdClass).newInstance();
+ mPasswordStore.init(pwdPath);
+ } catch (Exception e) {
+ System.out.println("Cannot get password store: " + e);
+ throw new EBaseException(e);
+ }
}
-
return mPasswordStore;
}
+ public void initializePasswordStore(IConfigStore config) throws EBaseException, IOException {
+ // create and initialize mPasswordStore
+ getPasswordStore();
+
+ boolean skipPublishingCheck = config.getBoolean(
+ "cms.password.ignore.publishing.failure", true);
+ String pwList = config.getString("cms.passwordlist", "internaldb,replicationdb");
+ String tags[] = StringUtils.split(pwList, ",");
+
+ for (String tag : tags) {
+ int iteration = 0;
+ int result = PW_INVALID_PASSWORD;
+ String binddn;
+ String authType;
+ LdapConnInfo connInfo = null;
+
+ if (tag.equals("internaldb")) {
+ authType = config.getString("internaldb.ldapauth.authtype", "BasicAuth");
+ if (!authType.equals("BasicAuth"))
+ continue;
+
+ connInfo = new LdapConnInfo(
+ config.getString("internaldb.ldapconn.host"),
+ config.getInteger("internaldb.ldapconn.port"),
+ config.getBoolean("internaldb.ldapconn.secureConn"));
+
+ binddn = config.getString("internaldb.ldapauth.bindDN");
+ } else if (tag.equals("replicationdb")) {
+ authType = config.getString("internaldb.ldapauth.authtype", "BasicAuth");
+ if (!authType.equals("BasicAuth"))
+ continue;
+
+ connInfo = new LdapConnInfo(
+ config.getString("internaldb.ldapconn.host"),
+ config.getInteger("internaldb.ldapconn.port"),
+ config.getBoolean("internaldb.ldapconn.secureConn"));
+
+ binddn = "cn=Replication Manager masterAgreement1-" + config.getString("machineName", "") + "-" +
+ config.getString("instanceId", "") + ",cn=config";
+ } else if (tags.equals("CA LDAP Publishing")) {
+ authType = config.getString("ca.publish.ldappublish.ldap.ldapauth.authtype", "BasicAuth");
+ if (!authType.equals("BasicAuth"))
+ continue;
+
+ connInfo = new LdapConnInfo(
+ config.getString("ca.publish.ldappublish.ldap.ldapconn.host"),
+ config.getInteger("ca.publish.ldappublish.ldap.ldapconn.port"),
+ config.getBoolean("ca.publish.ldappublish.ldap.ldapconn.secureConn"));
+
+ binddn = config.getString("ca.publish.ldappublish.ldap.ldapauth.bindDN");
+
+ } else {
+ // ignore any others for now
+ continue;
+ }
+
+ do {
+ String passwd = mPasswordStore.getPassword(tag, iteration);
+ result = testLDAPConnection(tag, connInfo, binddn, passwd);
+ iteration++;
+ } while ((result == PW_INVALID_PASSWORD) && (iteration < PW_MAX_ATTEMPTS));
+
+ if (result != PW_OK) {
+ if ((result == PW_NO_USER) && (tag.equals("replicationdb"))) {
+ System.out.println(
+ "CMSEngine: init(): password test execution failed for replicationdb" +
+ "with NO_SUCH_USER. This may not be a latest instance. Ignoring ..");
+ } else if (skipPublishingCheck && (result == PW_CANNOT_CONNECT) && (tag.equals("CA LDAP Publishing"))) {
+ System.out.println(
+ "Unable to connect to the publishing database to check password, " +
+ "but continuing to start up. Please check if publishing is operational.");
+ } else {
+ // password test failed
+ System.out.println("CMSEngine: init(): password test execution failed: " + result);
+ throw new EBaseException("Password test execution failed. Is the database up?");
+ }
+ }
+ }
+ }
+
+ public int testLDAPConnection(String name, LdapConnInfo info, String binddn, String pwd) {
+ int ret = PW_OK;
+
+ if (StringUtils.isEmpty(pwd))
+ return PW_INVALID_PASSWORD;
+
+ String host = info.getHost();
+ int port = info.getPort();
+
+ LDAPConnection conn = info.getSecure() ?
+ new LDAPConnection(CMS.getLdapJssSSLSocketFactory()) :
+ new LDAPConnection();
+
+ System.out.println("testLDAPConnection connecting to " + host + ":" + port);
+
+ try {
+ conn.connect(host, port, binddn, pwd);
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ System.out.println("testLDAPConnection: The specified user " + binddn + " does not exist");
+ ret = PW_NO_USER;
+ break;
+ case LDAPException.INVALID_CREDENTIALS:
+ System.out.println("testLDAPConnection: Invalid Password");
+ ret = PW_INVALID_PASSWORD;
+ break;
+ default:
+ System.out.println("testLDAPConnection: Unable to connect to " + name + ": " + e);
+ ret = PW_CANNOT_CONNECT;
+ break;
+ }
+ } finally {
+ try {
+ if (conn != null)
+ conn.disconnect();
+ } catch (Exception e) {
+ }
+ }
+ return ret;
+ }
+
/**
* initialize all static, dynamic and final static subsystems.
*
@@ -332,6 +467,16 @@ public class CMSEngine implements ICMSEngine {
serverStatus = "starting";
+ if (state == 1) {
+ // configuration is complete, initialize password store
+ try {
+ initializePasswordStore(config);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new EBaseException("Exception while initializing password store: " + e);
+ }
+ }
+
// my default is 1 day
String flush_timeout = config.getString("securitydomain.flushinterval", "86400000");
String secdomain_source = config.getString("securitydomain.source", "memory");
diff --git a/base/server/cmscore/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java b/base/server/cmscore/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
index eb3fde26c..4fd09a711 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/ldapconn/LdapAuthInfo.java
@@ -62,7 +62,7 @@ public class LdapAuthInfo implements ILdapAuthInfo {
init(config, host, port, secure);
}
- public String getPasswordFromStore(String prompt) {
+ public String getPasswordFromStore(String prompt) throws EBaseException {
String pwd = null;
CMS.debug("LdapAuthInfo: getPasswordFromStore: try to get it from password store");
@@ -82,7 +82,7 @@ public class LdapAuthInfo implements ILdapAuthInfo {
// Finally, interactively obtain the password from the user
if (pwdStore != null) {
CMS.debug("LdapAuthInfo: getPasswordFromStore: password store available");
- pwd = pwdStore.getPassword(prompt);
+ pwd = pwdStore.getPassword(prompt, 0);
// pwd = pstore.getString(prompt);
if (pwd == null) {
CMS.debug("LdapAuthInfo: getPasswordFromStore: password for " + prompt +
@@ -90,7 +90,7 @@ public class LdapAuthInfo implements ILdapAuthInfo {
// pwd = pstore.getString("internaldb");
- pwd = pwdStore.getPassword("internaldb"); // last resort
+ pwd = pwdStore.getPassword("internaldb", 0); // last resort
} else
CMS.debug("LdapAuthInfo: getPasswordFromStore: password found for prompt in password store");
} else
diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java
index 642f60232..8125dfac9 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java
@@ -34,7 +34,6 @@ public abstract class AbstractProfileSubsystem implements IProfileSubsystem {
protected static final String PROP_ENABLE_BY = "enableBy";
protected IConfigStore mConfig = null;
- @SuppressWarnings("unused")
protected ISubsystem mOwner;
protected Hashtable<String, IProfile> mProfiles;
protected Hashtable<String, String> mProfileClassIds;