From d336dda1123af0c272c69e42b6214577e30447e1 Mon Sep 17 00:00:00 2001 From: Stefan Miklosovic Date: Mon, 10 Jun 2024 17:28:39 +0200 Subject: [PATCH] CEP-24 Password validation / generation patch by Stefan Miklosovic; reviewed by Dinesh Joshi, Francisco Guerrero for CASSANDRA-17457 --- .build/cassandra-deps-template.xml | 4 + .build/parent-pom-template.xml | 5 + CHANGES.txt | 1 + NEWS.txt | 4 + README.asc | 2 +- conf/cassandra.yaml | 61 +++ doc/cql3/CQL.textile | 38 +- .../pages/developing/cql/changes.adoc | 1 + pylib/cqlshlib/cql3handling.py | 5 +- pylib/cqlshlib/cqlshmain.py | 10 +- pylib/cqlshlib/test/test_cqlsh_completion.py | 7 +- src/antlr/Lexer.g | 1 + src/antlr/Parser.g | 35 ++ .../cassandra/audit/AuditLogManager.java | 5 + .../cassandra/auth/CassandraRoleManager.java | 4 +- .../apache/cassandra/auth/IRoleManager.java | 2 +- .../apache/cassandra/auth/RoleOptions.java | 13 + .../config/CassandraRelevantProperties.java | 4 + .../org/apache/cassandra/config/Config.java | 4 + .../cassandra/config/DatabaseDescriptor.java | 5 + .../cassandra/config/GuardrailsOptions.java | 27 +- .../cql3/statements/AlterRoleStatement.java | 31 +- .../statements/AuthenticationStatement.java | 32 ++ .../cql3/statements/CreateRoleStatement.java | 32 +- .../CassandraPasswordConfiguration.java | 269 +++++++++++ .../CassandraPasswordGenerator.java | 100 ++++ .../CassandraPasswordValidator.java | 439 ++++++++++++++++++ .../db/guardrails/CustomGuardrail.java | 186 ++++++++ .../db/guardrails/CustomGuardrailConfig.java | 103 ++++ .../cassandra/db/guardrails/Guardrail.java | 2 +- .../cassandra/db/guardrails/Guardrails.java | 22 +- .../db/guardrails/GuardrailsConfig.java | 5 + .../db/guardrails/GuardrailsMBean.java | 13 + .../db/guardrails/NoOpGenerator.java | 63 +++ .../db/guardrails/NoOpValidator.java | 63 +++ .../db/guardrails/PasswordGuardrail.java | 99 ++++ .../db/guardrails/ValueGenerator.java | 133 ++++++ .../db/guardrails/ValueValidator.java | 155 +++++++ .../guardrails/GuardrailPasswordTest.java | 97 ++++ .../cassandra/auth/RoleOptionsTest.java | 10 + .../config/DatabaseDescriptorRefTest.java | 1 + .../org/apache/cassandra/cql3/CQLTester.java | 6 + .../CassandraPasswordGeneratorTest.java | 135 ++++++ .../CassandraPasswordValidatorTest.java | 369 +++++++++++++++ .../db/guardrails/GuardrailPasswordTest.java | 265 +++++++++++ .../db/guardrails/GuardrailTester.java | 68 ++- .../db/guardrails/ValueGeneratorTest.java | 110 +++++ .../db/guardrails/ValueValidatorTest.java | 122 +++++ 48 files changed, 3127 insertions(+), 41 deletions(-) create mode 100644 src/java/org/apache/cassandra/db/guardrails/CassandraPasswordConfiguration.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/CassandraPasswordGenerator.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/CassandraPasswordValidator.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/CustomGuardrail.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/CustomGuardrailConfig.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/NoOpGenerator.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/NoOpValidator.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/PasswordGuardrail.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/ValueGenerator.java create mode 100644 src/java/org/apache/cassandra/db/guardrails/ValueValidator.java create mode 100644 test/distributed/org/apache/cassandra/distributed/test/guardrails/GuardrailPasswordTest.java create mode 100644 test/unit/org/apache/cassandra/db/guardrails/CassandraPasswordGeneratorTest.java create mode 100644 test/unit/org/apache/cassandra/db/guardrails/CassandraPasswordValidatorTest.java create mode 100644 test/unit/org/apache/cassandra/db/guardrails/GuardrailPasswordTest.java create mode 100644 test/unit/org/apache/cassandra/db/guardrails/ValueGeneratorTest.java create mode 100644 test/unit/org/apache/cassandra/db/guardrails/ValueValidatorTest.java diff --git a/.build/cassandra-deps-template.xml b/.build/cassandra-deps-template.xml index f0b0a5defc..a7c27ee126 100644 --- a/.build/cassandra-deps-template.xml +++ b/.build/cassandra-deps-template.xml @@ -376,5 +376,9 @@ com.vdurmont semver4j + + org.passay + passay + diff --git a/.build/parent-pom-template.xml b/.build/parent-pom-template.xml index 455a0adac8..fd503030e0 100644 --- a/.build/parent-pom-template.xml +++ b/.build/parent-pom-template.xml @@ -1252,6 +1252,11 @@ semver4j 3.1.0 + + org.passay + passay + 1.6.4 + diff --git a/CHANGES.txt b/CHANGES.txt index 0011fbd995..e56329be91 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * CEP-24 Password validation / generation (CASSANDRA-17457) * Reconfigure CMS after replacement, bootstrap and move operations (CASSANDRA-19705) * Support querying LocalStrategy tables with any partitioner (CASSANDRA-19692) * Relax slow_query_log_timeout for MultiNodeSAITest (CASSANDRA-19693) diff --git a/NEWS.txt b/NEWS.txt index 9968918d8f..202290c574 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -84,6 +84,10 @@ New features - Authentication mode is exposed in system_views.clients table, nodetool clientstats and ClientMetrics to help operators identify which authentication modes are being used. nodetool clientstats introduces --verbose flag behind which this information is visible. + - CEP-24 - Password validation / generation. When built-in 'password_validator' guardrail is enabled, it will + generate a password of configured password strength policy upon role creation or alteration + when 'GENERATED PASSWORD' clause is used. Character sets supported are: English, Cyrillic, modern Cyrillic, + German, Polish and Czech. Upgrading diff --git a/README.asc b/README.asc index cd12f6537e..8493407054 100644 --- a/README.asc +++ b/README.asc @@ -42,7 +42,7 @@ be sitting in front of a prompt: ---- Connected to Test Cluster at localhost:9160. -[cqlsh 6.3.0 | Cassandra 5.0-SNAPSHOT | CQL spec 3.4.7 | Native protocol v5] +[cqlsh 6.3.0 | Cassandra 5.0-SNAPSHOT | CQL spec 3.4.8 | Native protocol v5] Use HELP for help. cqlsh> ---- diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index 9a4a41fbc5..e49e9db172 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -2148,6 +2148,67 @@ drop_compact_storage_enabled: false # This would also apply to system keyspaces. # maximum_replication_factor_warn_threshold: -1 # maximum_replication_factor_fail_threshold: -1 +# +# Guardrail to warn or fail when setting / altering a password. +# Supported character sets are (both upper and lower-case): English, Cyrillic and modern Cyrillic, Czech, German, Polish. +# Password is invalid if all characters are from non-supported character set. If a password is otherwise valid, +# but it contains characters from unsupported language, these characters contribute only to password length rule. +# All digits and all following special characters are supported too: !"#$%&()*+,-./:;<=>?@[\]^_`{|}~ +#password_validator: +# # Implementation class of a validator. When not in form of FQCN, the +# # package name org.apache.cassandra.db.guardrails.validators is prepended. +# # By default, there is no validator. +# class_name: CassandraPasswordValidator +# # Implementation class of related generator which generates values which are valid when +# # tested against this validator. When not in form of FQCN, the +# # package name org.apache.cassandra.db.guardrails.generators is prepended. +# # By default, there is no generator. +# generator_class_name: CassandraPasswordGenerator +# # There are four characteristics: +# # upper-case, lower-case, special character and digit. +# # If this value is set e.g. to 3, a password has to consist of 3 out of 4 characteristics. +# # For example, it has to contain at least 2 upper-case characters, 2 lower-case, and 2 digits to pass, +# # but it does not have to contain any special characters. +# # If number of characteristics found in the password is less than or equal to this number, it will emit warning. +# characteristic_warn: 3 +# # If number of characteristics found in the password is less than or equal to this number, it will emit failure. +# characteristic_fail: 2 +# # Maximum length of a password. Defaults to 1000. +# max_length: 1000 +# # If password is shorter than this value, the validator will emit a warning. +# length_warn: 12 +# # If a password is shorter than this value, the validator will emit a failure. +# length_fail: 8 +# # If a password does not contain at least n upper-case characters, the validator will emit a warning. +# upper_case_warn: 2 +# # If a password does not contain at least n upper-case characters, the validator will emit a failure. +# upper_case_fail: 1 +# # If a password does not contain at least n lower-case characters, the validator will emit a warning. +# lower_case_warn: 2 +# # If a password does not contain at least n lower-case characters, the validator will emit a failure. +# lower_case_fail: 1 +# # If a password does not contain at least n digits, the validator will emit a warning. +# digit_warn: 2 +# # If a password does not contain at least n digits, the validator will emit a failure. +# digit_fail: 1 +# # If a password does not contain at least n special characters, the validator will emit a warning. +# special_warn: 2 +# # If a password does not contain at least n special characters, the validator will emit a failure. +# special_fail: 1 +# # If a password contain illegal sequences that at least this long, it is invalid. +# # Illegal sequences might be either alphabetical (form 'abcde'), +# # numerical (form '34567'), or US qwerty (form 'asdfg') as well as sequencies from supported character sets. +# # The minimum value for this property is 3, by default it is set to 5. +# illegal_sequence_length: 5 +# # If set to true, a user will be informed what policies a suggested password is missing in order to be valid. +# # Defaults to true. +# detailed_messages: true + +# If this is set to false, then it is not possible to call reconfiguration +# method in GuardrailsMBean. It will effectively forbid the reconfiguration of password validator in runtime. +# You would need to stop the node, change the configuration in cassandra.yaml and start the node again. +# Defaults to true, which means that reconfiguration of password validator via JMX is possible. +# password_validator_reconfiguration_enabled: true # Guardrail to enable a CREATE or ALTER TABLE statement when default_time_to_live is set to 0 # and the table is using TimeWindowCompactionStrategy compaction or a subclass of it. diff --git a/doc/cql3/CQL.textile b/doc/cql3/CQL.textile index c85fef5ab5..d60b4d476f 100644 --- a/doc/cql3/CQL.textile +++ b/doc/cql3/CQL.textile @@ -18,7 +18,7 @@ # --> -h1. Cassandra Query Language (CQL) v3.4.7 +h1. Cassandra Query Language (CQL) v3.4.8 @@ -1280,6 +1280,7 @@ bc(syntax).. ::= CREATE ROLE ( IF NOT EXISTS )? ( WITH