modules/common/cassandra-ccm/cassandra-ccm-core/src/main/resources/cassandra.properties | 2 modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/AbstractManager.java | 2 modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/UpdateFolder.java | 2 modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/VersionManager.java | 3 modules/common/cassandra-util/pom.xml | 6 + modules/common/cassandra-util/src/main/java/org/rhq/cassandra/util/ClusterBuilder.java | 33 ++++++++++ modules/enterprise/server/data-migration/pom.xml | 6 + modules/enterprise/server/data-migration/src/main/java/org/rhq/server/metrics/migrator/DataMigratorRunner.java | 3 modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java | 24 +++++-- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageNodeOperationsHandlerBean.java | 2 pom.xml | 1 12 files changed, 71 insertions(+), 15 deletions(-)
New commits: commit a72a970f7e44e744a6b13ffc5684cd8be6d195b0 Author: Stefan Negrea snegrea@redhat.com Date: Thu Aug 22 09:23:09 2013 -0500
Fix file paths for running the schema manager from a disk based distribution.
diff --git a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/UpdateFolder.java b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/UpdateFolder.java index 31266ca..3b2056f 100644 --- a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/UpdateFolder.java +++ b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/UpdateFolder.java @@ -117,7 +117,7 @@ class UpdateFolder {
String updateFile; while ((updateFile = reader.readLine()) != null) { - files.add(new UpdateFile(folder + updateFile)); + files.add(new UpdateFile(folder + "/" + updateFile)); } } else if (resourceFolderURL.getProtocol().equals("jar")) { URL jarURL = this.getClass().getClassLoader().getResources(folder).nextElement();
commit 7371e80747cbf082b478c4049f7c57029e2b5554 Author: Stefan Negrea snegrea@redhat.com Date: Thu Aug 22 09:22:34 2013 -0500
[BZ 999555] Add storage node password obfuscation in the server configuration file using the same method applied to SQL database password.
Also, added a more generic argument to the installer to allow users to encode their desired password prior to running the installer.
diff --git a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/resources/cassandra.properties b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/resources/cassandra.properties index ce2be6c..9a1ab75 100644 --- a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/resources/cassandra.properties +++ b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/resources/cassandra.properties @@ -10,7 +10,7 @@ rhq.cassandra.basedir=${rhq.rootDir} rhq.cassandra.username=rhqadmin
# The password with which to authenticate requests to Cassandra. -rhq.cassandra.password=rhqadmin +rhq.cassandra.password=1eeb2f255e832171df8592078de921bc
# Defines the number of tokens randomly assigned to a node on the ring. The more tokens, # relative to other nodes, the larger the proportion of data that this node will store. You diff --git a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/AbstractManager.java b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/AbstractManager.java index 7dcef1b..3a6bf21 100644 --- a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/AbstractManager.java +++ b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/AbstractManager.java @@ -111,7 +111,7 @@ abstract class AbstractManager {
log.info("Initializing storage node session.");
- Cluster cluster = new ClusterBuilder().addContactPoints(nodes).withCredentials(username, password) + Cluster cluster = new ClusterBuilder().addContactPoints(nodes).withCredentialsObfuscated(username, password) .withPort(this.getCqlPort()).withCompression(Compression.NONE).build();
log.info("Cluster connection configured."); diff --git a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/VersionManager.java b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/VersionManager.java index 05cee25..36dc036 100644 --- a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/VersionManager.java +++ b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/VersionManager.java @@ -36,6 +36,7 @@ import org.apache.commons.logging.LogFactory; import org.rhq.cassandra.schema.exception.InstalledSchemaTooAdvancedException; import org.rhq.cassandra.schema.exception.InstalledSchemaTooOldException; import org.rhq.cassandra.schema.exception.SchemaNotInstalledException; +import org.rhq.cassandra.util.ClusterBuilder;
/** * @author Stefan Negrea @@ -106,7 +107,7 @@ class VersionManager extends AbstractManager { properties.put("replication_factor", calculateNewReplicationFactor() + ""); properties.put("cassandra_user_password", UUID.randomUUID() + ""); properties.put("rhq_admin_username", getUsername()); - properties.put("rhq_admin_password", getPassword()); + properties.put("rhq_admin_password", ClusterBuilder.deobfuscatePassword(getPassword()));
/** * NOTE: Before applying any schema, we need to create the rhqadmin user. If we have more diff --git a/modules/common/cassandra-util/pom.xml b/modules/common/cassandra-util/pom.xml index 7e5fff2..fc59154 100644 --- a/modules/common/cassandra-util/pom.xml +++ b/modules/common/cassandra-util/pom.xml @@ -18,6 +18,12 @@ <artifactId>cassandra-driver-core</artifactId> <version>${cassandra.driver.version}</version> </dependency> + + <dependency> + <groupId>org.picketbox</groupId> + <artifactId>picketbox</artifactId> + <version>${picketbox-version}</version> + </dependency> </dependencies>
<profiles> diff --git a/modules/common/cassandra-util/src/main/java/org/rhq/cassandra/util/ClusterBuilder.java b/modules/common/cassandra-util/src/main/java/org/rhq/cassandra/util/ClusterBuilder.java index 14f12e1..9796a59 100644 --- a/modules/common/cassandra-util/src/main/java/org/rhq/cassandra/util/ClusterBuilder.java +++ b/modules/common/cassandra-util/src/main/java/org/rhq/cassandra/util/ClusterBuilder.java @@ -25,6 +25,8 @@
package org.rhq.cassandra.util;
+import java.lang.reflect.Method; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.PoolingOptions; import com.datastax.driver.core.ProtocolOptions; @@ -66,6 +68,14 @@ public class ClusterBuilder { }
/** + * @see Cluster.Builder#withCredentials(String, String) + */ + public ClusterBuilder withCredentialsObfuscated(String username, String obfuscatedPassword) { + builder.withCredentials(username, ClusterBuilder.deobfuscatePassword(obfuscatedPassword)); + return this; + } + + /** * This method will throw an IllegalArgumentException if you try to use snappy * compression while running on an IBM JRE. See <a href="https://bugzilla.redhat.com/show_bug.cgi?id=907485">BZ 907485</a> * for details. @@ -105,4 +115,27 @@ public class ClusterBuilder { return System.getProperty("java.vm.vendor").startsWith("IBM"); }
+ /** + * Use the internal JBossAS mechanism to de-obfuscate a password back to its + * clear text form. This is not true encryption. + * + * @param obfuscatedPassword the obfuscated password + * @return the clear-text password + */ + public static String deobfuscatePassword(String obfuscatedPassword) { + // We need to do some mumbo jumbo, as the interesting method is private + // in SecureIdentityLoginModule + try { + String className = "org.picketbox.datasource.security.SecureIdentityLoginModule"; + Class<?> clazz = Class.forName(className); + Object object = clazz.newInstance(); + Method method = clazz.getDeclaredMethod("decode", String.class); + method.setAccessible(true); + char[] result = (char[]) method.invoke(object, obfuscatedPassword); + return new String(result); + } catch (Exception e) { + throw new RuntimeException("de-obfuscating db password failed: ", e); + } + } + } diff --git a/modules/enterprise/server/data-migration/pom.xml b/modules/enterprise/server/data-migration/pom.xml index ea25952..35d1934 100644 --- a/modules/enterprise/server/data-migration/pom.xml +++ b/modules/enterprise/server/data-migration/pom.xml @@ -43,6 +43,12 @@ </dependency>
<dependency> + <groupId>org.picketbox</groupId> + <artifactId>picketbox</artifactId> + <version>${picketbox-version}</version> + </dependency> + + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.1</version> diff --git a/modules/enterprise/server/data-migration/src/main/java/org/rhq/server/metrics/migrator/DataMigratorRunner.java b/modules/enterprise/server/data-migration/src/main/java/org/rhq/server/metrics/migrator/DataMigratorRunner.java index 8a0f64c..5e0861e 100644 --- a/modules/enterprise/server/data-migration/src/main/java/org/rhq/server/metrics/migrator/DataMigratorRunner.java +++ b/modules/enterprise/server/data-migration/src/main/java/org/rhq/server/metrics/migrator/DataMigratorRunner.java @@ -362,7 +362,8 @@ public class DataMigratorRunner { configuration.put(sqlConnectionUrlOption, serverProperties.getProperty("rhq.server.database.connection-url"));
configuration.put(cassandraUserOption, serverProperties.getProperty("rhq.cassandra.username")); - configuration.put(cassandraPasswordOption, serverProperties.getProperty("rhq.cassandra.password")); + String cassandraPasswordProperty = serverProperties.getProperty("rhq.cassandra.password"); + configuration.put(cassandraPasswordOption, deobfuscatePassword(cassandraPasswordProperty));
if (serverProperties.getProperty("rhq.cassandra.seeds") != null && !serverProperties.getProperty("rhq.cassandra.seeds").trim().isEmpty()) { diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java index 36da859..97b10ce 100644 --- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java +++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/Installer.java @@ -145,8 +145,9 @@ public class Installer { usage.append("\t--force, -f: force the installer to try to install everything").append("\n"); usage.append("\t--listservers, -l: show list of known installed servers (install not performed)").append("\n"); usage.append("\t--setupdb, -b: only perform database schema creation or update").append("\n"); - usage.append("\t--dbpassword, -d: encodes a DB password for rhq-server.properties (install not performed)") - .append("\n"); + usage.append("\t--dbpassword, -d: encodes a DB password for rhq-server.properties (install not performed)"); + usage.append("\t--encodepassword, -e: encodes a password (DB or RHQ Storage Cluster) for rhq-server.properties (install not performed)"); + usage.append("\n"); LOG.info(usage); }
@@ -156,6 +157,7 @@ public class Installer { new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'h'), new LongOpt("port", LongOpt.REQUIRED_ARGUMENT, null, 'p'), new LongOpt("dbpassword", LongOpt.REQUIRED_ARGUMENT, null, 'd'), + new LongOpt("encodepassword", LongOpt.REQUIRED_ARGUMENT, null, 'e'), new LongOpt("setupdb", LongOpt.NO_ARGUMENT, null, 'b'), new LongOpt("listservers", LongOpt.NO_ARGUMENT, null, 'l'), new LongOpt("force", LongOpt.NO_ARGUMENT, null, 'f'), @@ -164,7 +166,7 @@ public class Installer { boolean test = false; boolean listservers = false; boolean setupdb = false; - String dbpassword = null; + String passwordToEncode = null;
Getopt getopt = new Getopt("installer", args, sopts, lopts); int code; @@ -228,8 +230,16 @@ public class Installer { }
case 'd': { - dbpassword = getopt.getOptarg(); - if (dbpassword == null) { + passwordToEncode = getopt.getOptarg(); + if (passwordToEncode == null) { + throw new IllegalArgumentException("Missing password"); + } + break; + } + + case 'e': { + passwordToEncode = getopt.getOptarg(); + if (passwordToEncode == null) { throw new IllegalArgumentException("Missing password"); } break; @@ -258,8 +268,8 @@ public class Installer { }
// if a password was asked to be obfuscated, that's all we are to do - if (dbpassword != null) { - String pw = new InstallerServiceImpl(installerConfig).obfuscatePassword(dbpassword); + if (passwordToEncode != null) { + String pw = new InstallerServiceImpl(installerConfig).obfuscatePassword(passwordToEncode); LOG.info("*** Encoded Password: " + pw); return new WhatToDo[] { WhatToDo.DO_NOTHING }; } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java index 799abcc..09de080 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java @@ -194,7 +194,7 @@ public class StorageClientManagerBean {
Cluster cluster = new ClusterBuilder() .addContactPoints(hostNames.toArray(new String[hostNames.size()])) - .withCredentials(username, password) + .withCredentialsObfuscated(username, password) .withPort(port) .withCompression(compression) .build(); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageNodeOperationsHandlerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageNodeOperationsHandlerBean.java index 943458e..96c22b8 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageNodeOperationsHandlerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageNodeOperationsHandlerBean.java @@ -47,8 +47,6 @@ public class StorageNodeOperationsHandlerBean implements StorageNodeOperationsHa
private static final String STORAGE_NODE_TYPE_NAME = "RHQ Storage Node"; private static final String STORAGE_NODE_PLUGIN_NAME = "RHQStorage"; - private static final String USERNAME_PROPERTY = "rhq.cassandra.username"; - private static final String PASSWORD_PROPERTY = "rhq.cassandra.password"; private final static String RUN_REPAIR_PROPERTY = "runRepair"; private final static String UPDATE_SEEDS_LIST = "updateSeedsList"; private final static String SEEDS_LIST = "seedsList"; diff --git a/pom.xml b/pom.xml index a8cc40d..1f228a2 100644 --- a/pom.xml +++ b/pom.xml @@ -177,6 +177,7 @@
<mockito-core.version>1.9.0</mockito-core.version> <el.version>1.0</el.version> + <picketbox-version>4.0.15.Final</picketbox-version>
<!-- cassandra dependency versions --> <cassandra.version>1.2.4</cassandra.version>