From 6b16b67cd4dbf8633e58c1950ced3626ff7ac92b Mon Sep 17 00:00:00 2001 From: Stefan Miklosovic Date: Wed, 29 Sep 2021 07:39:29 +0200 Subject: [PATCH] update jBCrypt dependency to version 0.4 patch by Stefan Miklosovic; reviewed by Dinesh Joshi for CASSANDRA-9384 --- CHANGES.txt | 1 + NEWS.txt | 10 +++++ build.xml | 2 +- .../cassandra/auth/CassandraRoleManager.java | 8 ++-- .../auth/PasswordAuthenticatorTest.java | 39 +++++++++++++++++-- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 89aaea0249..b1ab34a7e8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0.26: + * CVE-2015-0886 Security vulnerability in jbcrypt is addressed (CASSANDRA-9384) * Avoid useless SSTable reads during single partition queries (CASSANDRA-16944) * Debian init respects CASSANDRA_HEAPDUMP_DIR (CASSANDRA-13843) * Catch UnsatisfiedLinkError in WindowsTimer (CASSANDRA-16085) diff --git a/NEWS.txt b/NEWS.txt index 889943bfe0..d0b9ae6a9a 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -42,6 +42,16 @@ restore snapshots created with the previous major version using the 'sstableloader' tool. You can upgrade the file format of your snapshots using the provided 'sstableupgrade' tool. +3.0.26 +====== + +Upgrading +--------- + - Before you upgrade, if you are using `cassandra.auth_bcrypt_gensalt_log2_rounds` property, + confirm it is set to value lower than 31 otherwise Cassandra will fail to start. See CASSANDRA-9384 + for further details. You also need to regenerate passwords for users for who the password + was created while the above property was set to be more than 30 otherwise they will not be able to log in. + 3.0.25 ====== diff --git a/build.xml b/build.xml index 3e77a957ec..c30d5963ca 100644 --- a/build.xml +++ b/build.xml @@ -382,7 +382,7 @@ - + diff --git a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java index aa98b7e7cf..897e9eb278 100644 --- a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java +++ b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java @@ -21,6 +21,7 @@ import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.*; import com.google.common.base.Objects; import com.google.common.collect.ImmutableSet; @@ -118,15 +119,16 @@ public class CassandraRoleManager implements IRoleManager }; // 2 ** GENSALT_LOG2_ROUNDS rounds of hashing will be performed. - private static final String GENSALT_LOG2_ROUNDS_PROPERTY = Config.PROPERTY_PREFIX + "auth_bcrypt_gensalt_log2_rounds"; + @VisibleForTesting + public static final String GENSALT_LOG2_ROUNDS_PROPERTY = Config.PROPERTY_PREFIX + "auth_bcrypt_gensalt_log2_rounds"; private static final int GENSALT_LOG2_ROUNDS = getGensaltLogRounds(); static int getGensaltLogRounds() { int rounds = Integer.getInteger(GENSALT_LOG2_ROUNDS_PROPERTY, 10); - if (rounds < 4 || rounds > 31) + if (rounds < 4 || rounds > 30) throw new ConfigurationException(String.format("Bad value for system property -D%s." + - "Please use a value between 4 and 31 inclusively", + "Please use a value between 4 and 30 inclusively", GENSALT_LOG2_ROUNDS_PROPERTY)); return rounds; } diff --git a/test/unit/org/apache/cassandra/auth/PasswordAuthenticatorTest.java b/test/unit/org/apache/cassandra/auth/PasswordAuthenticatorTest.java index 02850499cf..3909642b23 100644 --- a/test/unit/org/apache/cassandra/auth/PasswordAuthenticatorTest.java +++ b/test/unit/org/apache/cassandra/auth/PasswordAuthenticatorTest.java @@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets; import com.google.common.collect.Iterables; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -31,6 +32,7 @@ import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.exceptions.AuthenticationException; +import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.schema.KeyspaceParams; import static org.apache.cassandra.auth.CassandraRoleManager.*; @@ -46,17 +48,17 @@ public class PasswordAuthenticatorTest extends CQLTester private static PasswordAuthenticator authenticator = new PasswordAuthenticator(); @Test - public void testCheckpw() throws Exception + public void testCheckpw() { // Valid and correct assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(getGensaltLogRounds())))); assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(4)))); - assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(31)))); + assertTrue(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw(DEFAULT_SUPERUSER_PASSWORD, gensalt(12)))); // Valid but incorrect hashes assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect0", gensalt(4)))); assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect1", gensalt(10)))); - assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect2", gensalt(31)))); + assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, hashpw("incorrect2", gensalt(12)))); // Invalid hash values, the jBCrypt library implementation // throws an exception which we catch and treat as a failure @@ -78,6 +80,37 @@ public class PasswordAuthenticatorTest extends CQLTester assertFalse(checkpw(DEFAULT_SUPERUSER_PASSWORD, "$2a$6$abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ01234")); } + @Test(expected = ConfigurationException.class) + public void testInvalidUpperBoundHashingRoundsValue() + { + executeSaltRoundsPropertyTest(31); + } + + @Test(expected = ConfigurationException.class) + public void testInvalidLowerBoundHashingRoundsValue() + { + executeSaltRoundsPropertyTest(3); + } + + private void executeSaltRoundsPropertyTest(Integer rounds) + { + String oldProperty = System.getProperty(GENSALT_LOG2_ROUNDS_PROPERTY); + try + { + System.setProperty(GENSALT_LOG2_ROUNDS_PROPERTY, rounds.toString()); + getGensaltLogRounds(); + Assert.fail("Property " + GENSALT_LOG2_ROUNDS_PROPERTY + " must be in interval [4,30]"); + } + finally + { + if (oldProperty != null) + System.setProperty(GENSALT_LOG2_ROUNDS_PROPERTY, oldProperty); + else + System.clearProperty(GENSALT_LOG2_ROUNDS_PROPERTY); + } + } + + @Test(expected = AuthenticationException.class) public void testEmptyUsername() {