summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/core/dbutils/pom.xml2
-rw-r--r--modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ConfigurationObfuscationCorrectionUpgradeTask.java62
-rw-r--r--modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml6
-rw-r--r--modules/core/util/src/main/java/org/rhq/core/util/obfuscation/Obfuscator.java29
-rw-r--r--modules/core/util/src/test/java/org/rhq/core/util/obfuscation/ObfuscatorTest.java57
5 files changed, 150 insertions, 6 deletions
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index e0ceba4..700e079 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -17,7 +17,7 @@
<description>Database schema setup, upgrade and other utilities</description>
<properties>
- <db.schema.version>2.124</db.schema.version>
+ <db.schema.version>2.125</db.schema.version>
<rhq.ds.type-mapping>${rhq.test.ds.type-mapping}</rhq.ds.type-mapping>
<rhq.ds.server-name>${rhq.test.ds.server-name}</rhq.ds.server-name>
<rhq.ds.db-name>${rhq.test.ds.db-name}</rhq.ds.db-name>
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ConfigurationObfuscationCorrectionUpgradeTask.java b/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ConfigurationObfuscationCorrectionUpgradeTask.java
new file mode 100644
index 0000000..bb393c9
--- /dev/null
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ConfigurationObfuscationCorrectionUpgradeTask.java
@@ -0,0 +1,62 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.db.upgrade;
+
+import org.rhq.core.db.DatabaseType;
+import org.rhq.core.util.obfuscation.Obfuscator;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * We had a buggy version of the password obfuscation code borrowed from JBoss AS.
+ * It was susceptible to these two issues:
+ * https://issues.jboss.org/browse/SECURITY-344
+ * https://issues.jboss.org/browse/SECURITY-563
+ *
+ * Unfortunately this means an information loss in the encoded value and therefore we have no way of recovering the
+ * original passwords. This upgrade task therefore checks if an obfuscated value in a database can be decoded and if not,
+ * it clears it out.
+ *
+ * @author Lukas Krejci
+ */
+public class ConfigurationObfuscationCorrectionUpgradeTask implements DatabaseUpgradeTask {
+
+ @Override
+ public void execute(DatabaseType type, Connection connection) throws SQLException {
+ String sql = "SELECT id, string_value FROM rhq_config_property WHERE dtype = 'obfuscated'";
+
+ List<Object[]> results = type.executeSelectSql(connection, sql);
+
+ for(Object[] row : results) {
+ String value = (String) row[1];
+
+ //try to decode the value
+ try {
+ Obfuscator.decode(value);
+ } catch (Exception e) {
+ int id = ((Number) row[0]).intValue();
+
+ type.executeSql(connection, "UPDATE rhq_config_property SET string_value = NULL WHERE id = " + id);
+ }
+ }
+ }
+}
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 84fbf5e..7154129 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -4058,6 +4058,12 @@
</schemaSpec>
+ <schemaSpec version="2.125">
+ <!-- We were using a buggy version of password obfuscation from JBoss AS. This task sets the affected
+ passwords to NULL. Fortunately, this currently affects only CSP content sources, so the damage
+ is not huge from the user perspective. -->
+ <schema-javaTask className="org.rhq.core.db.upgrade.ConfigurationObfuscationCorrectionUpgradeTask" />
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/obfuscation/Obfuscator.java b/modules/core/util/src/main/java/org/rhq/core/util/obfuscation/Obfuscator.java
index f626235..3112a55 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/obfuscation/Obfuscator.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/obfuscation/Obfuscator.java
@@ -42,7 +42,8 @@ import javax.crypto.spec.SecretKeySpec;
public final class Obfuscator {
private static final byte[] KEY = "jaas is the way".getBytes();
-
+ public static final String ALGORITHM = "Blowfish";
+
//no instances, please
private Obfuscator() {
@@ -62,9 +63,9 @@ public final class Obfuscator {
*/
public static String encode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
- SecretKeySpec key = new SecretKeySpec(KEY, "Blowfish");
+ SecretKeySpec key = new SecretKeySpec(KEY, ALGORITHM);
- Cipher cipher = Cipher.getInstance("Blowfish");
+ Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encoding = cipher.doFinal(secret.getBytes());
BigInteger n = new BigInteger(encoding);
@@ -88,12 +89,30 @@ public final class Obfuscator {
*/
public static String decode(String secret) throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
- SecretKeySpec key = new SecretKeySpec(KEY, "Blowfish");
+ SecretKeySpec key = new SecretKeySpec(KEY, ALGORITHM);
BigInteger n = new BigInteger(secret, 16);
byte[] encoding = n.toByteArray();
- Cipher cipher = Cipher.getInstance("Blowfish");
+ //SECURITY-344: fix leading zeros
+ if (encoding.length % 8 != 0) {
+ int length = encoding.length;
+ int newLength = ((length / 8) + 1) * 8;
+ int pad = newLength - length; //number of leading zeros
+ byte[] old = encoding;
+ encoding = new byte[newLength];
+ for (int i = old.length - 1; i >= 0; i--) {
+ encoding[i + pad] = old[i];
+ }
+ //SECURITY-563: handle negative numbers
+ if (n.signum() == -1) {
+ for (int i = 0; i < newLength - length; i++) {
+ encoding[i] = (byte) -1;
+ }
+ }
+ }
+
+ Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decode = cipher.doFinal(encoding);
return new String(decode);
diff --git a/modules/core/util/src/test/java/org/rhq/core/util/obfuscation/ObfuscatorTest.java b/modules/core/util/src/test/java/org/rhq/core/util/obfuscation/ObfuscatorTest.java
new file mode 100644
index 0000000..ae71bd7
--- /dev/null
+++ b/modules/core/util/src/test/java/org/rhq/core/util/obfuscation/ObfuscatorTest.java
@@ -0,0 +1,57 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2012 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.core.util.obfuscation;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lukas Krejci
+ */
+@Test
+public class ObfuscatorTest {
+
+ public void testCanDecodePassword() throws Exception {
+ testEncodeDecode("0_[");
+ }
+
+ /**
+ * @link https://issues.jboss.org/browse/SECURITY-344
+ * @throws Exception
+ */
+ public void testResilienceAgainstZeroPadding() throws Exception {
+ testEncodeDecode("dv");
+ }
+
+ /**
+ * @link https://issues.jboss.org/browse/SECURITY-563
+ * @throws Exception
+ */
+ public void testResilienceAgainstMinusOnePadding() throws Exception {
+ testEncodeDecode("aan2o1Y%");
+ }
+
+ private void testEncodeDecode(String pass) throws Exception {
+ String encoded = Obfuscator.encode(pass);
+ String decoded = Obfuscator.decode(encoded);
+
+ Assert.assertEquals(decoded, pass, "The password doesn't match after decoding it.");
+ }
+}