This is an automated email from the ASF dual-hosted git repository.

mck pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit 1defa0851f7c1a557ebf76a566070308c222fa16
Merge: b9f900947a 2dea5c7588
Author: mck <[email protected]>
AuthorDate: Wed Oct 9 13:52:22 2024 +0200

    Merge branch 'cassandra-5.0' into trunk
    
    * cassandra-5.0:
      Use ParameterizedClass for all auth-related implementations

 CHANGES.txt                                        |  1 +
 conf/cassandra.yaml                                | 32 +++++++++--
 conf/cassandra_latest.yaml                         | 32 +++++++++--
 src/java/org/apache/cassandra/auth/AuthConfig.java | 64 ++++++++++++----------
 .../org/apache/cassandra/auth/ICIDRAuthorizer.java | 17 ------
 src/java/org/apache/cassandra/config/Config.java   |  6 +-
 .../org/apache/cassandra/utils/FBUtilities.java    | 39 -------------
 test/data/config/version=5.0-alpha1.yml            | 14 +++--
 ...rsion=5.0-alpha1.yml => version=5.1-alpha1.yml} | 17 ++++--
 .../cassandra/audit/AuditLoggerAuthTest.java       |  4 +-
 .../cassandra/config/ConfigCompatibilityTest.java  | 16 +++++-
 .../cassandra/transport/CQLUserAuditTest.java      |  2 +-
 .../apache/cassandra/transport/TlsTestUtils.java   |  4 +-
 13 files changed, 136 insertions(+), 112 deletions(-)

diff --cc CHANGES.txt
index 54dbbe1cf5,27d68e9c80..33aae06b4e
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,92 -1,16 +1,93 @@@
 -5.0.2
 +5.1
 + * Add total space used for a keyspace to nodetool tablestats 
(CASSANDRA-19671)
 + * Ensure Relation#toRestriction() handles ReversedType properly 
(CASSANDRA-19950)
 + * Add JSON and YAML output option to nodetool gcstats (CASSANDRA-19771)
 + * Introduce metadata serialization version V4 (CASSANDRA-19970)
 + * Allow CMS reconfiguration to work around DOWN nodes (CASSANDRA-19943)
 + * Make TableParams.Serializer set allowAutoSnapshots and incrementalBackups 
(CASSANDRA-19954)
 + * Make sstabledump possible to show tombstones only (CASSANDRA-19939)
 + * Ensure that RFP queries potentially stale replicas even with only key 
columns in the row filter (CASSANDRA-19938)
 + * Allow nodes to change IP address while upgrading to TCM (CASSANDRA-19921)
 + * Retain existing keyspace params on system tables after upgrade 
(CASSANDRA-19916)
 + * Deprecate use of gossip state for paxos electorate verification 
(CASSANDRA-19904)
 + * Update dtest-api to 0.0.17 to fix jvm17 crash in jvm-dtests 
(CASSANDRA-19239)
 + * Add resource leak test and Update Netty to 4.1.113.Final to fix leak 
(CASSANDRA-19783)
 + * Fix incorrect nodetool suggestion when gossip mode is running 
(CASSANDRA-19905)
 + * SAI support for BETWEEN operator (CASSANDRA-19688)
 + * Fix BETWEEN filtering for reversed clustering columns (CASSANDRA-19878)
 + * Retry if node leaves CMS while committing a transformation 
(CASSANDRA-19872)
 + * Add support for NOT operators in WHERE clauses. Fixed Three Valued Logic 
(CASSANDRA-18584)
 + * Allow getendpoints for system tables and make sure getNaturalReplicas work 
for MetaStrategy (CASSANDRA-19846)
 + * On upgrade, handle pre-existing tables with unexpected table ids 
(CASSANDRA-19845)
 + * Reconfigure CMS before assassinate (CASSANDRA-19768)
 + * Warn about unqualified prepared statement only if it is select or 
modification statement (CASSANDRA-18322)
 + * Update legacy peers tables during node replacement (CASSANDRA-19782)
 + * Refactor ColumnCondition (CASSANDRA-19620)
 + * Allow configuring log format for Audit Logs (CASSANDRA-19792)
 + * Support for noboolean rpm (centos7 compatible) packages removed 
(CASSANDRA-19787)
 + * Allow threads waiting for the metadata log follower to be interrupted 
(CASSANDRA-19761)
 + * Support dictionary lookup for CassandraPasswordValidator (CASSANDRA-19762)
 + * Disallow denylisting keys in system_cluster_metadata (CASSANDRA-19713)
 + * Fix gossip status after replacement (CASSANDRA-19712)
 + * Ignore repair requests for system_cluster_metadata (CASSANDRA-19711)
 + * Avoid ClassCastException when verifying tables with reversed partitioner 
(CASSANDRA-19710)
 + * Always repair the full range when repairing system_cluster_metadata 
(CASSANDRA-19709)
 + * Use table-specific partitioners during Paxos repair (CASSANDRA-19714)
 + * Expose current compaction throughput in nodetool (CASSANDRA-13890)
 + * 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)
 + * Audit Log entries are missing identity for mTLS connections 
(CASSANDRA-19669)
 + * Add support for the BETWEEN operator in WHERE clauses (CASSANDRA-19604)
 + * Replace Stream iteration with for-loop for 
SimpleRestriction::bindAndGetClusteringElements (CASSANDRA-19679)
 + * Consolidate logging on trace level (CASSANDRA-19632)
 + * Expand DDL statements on coordinator before submission to the CMS 
(CASSANDRA-19592)
 + * Fix number of arguments of String.format() in various classes 
(CASSANDRA-19645)
 + * Remove unused fields from config (CASSANDRA-19599)
 + * Refactor Relation and Restriction hierarchies (CASSANDRA-19341)
 + * Raise priority of TCM internode messages during critical operations 
(CASSANDRA-19517)
 + * Add nodetool command to unregister LEFT nodes (CASSANDRA-19581)
 + * Add cluster metadata id to gossip syn messages (CASSANDRA-19613)
 + * Reduce heap usage occupied by the metrics (CASSANDRA-19567)
 + * Improve handling of transient replicas during range movements 
(CASSANDRA-19344)
 + * Enable debounced internode log requests to be cancelled at shutdown 
(CASSANDRA-19514)
 + * Correctly set last modified epoch when combining multistep operations into 
a single step (CASSANDRA-19538)
 + * Add new TriggersPolicy configuration to allow operators to disable 
triggers (CASSANDRA-19532)
 + * Use Transformation.Kind.id in local and distributed log tables 
(CASSANDRA-19516)
 + * Remove period field from ClusterMetadata and metadata log tables 
(CASSANDRA-19482)
 + * Enrich system_views.pending_hints vtable with hints sizes (CASSANDRA-19486)
 + * Expose all dropwizard metrics in virtual tables (CASSANDRA-14572)
 + * Ensured that PropertyFileSnitchTest do not overwrite 
cassandra-toploogy.properties (CASSANDRA-19502)
 + * Add option for MutualTlsAuthenticator to restrict the certificate validity 
period (CASSANDRA-18951)
 + * Fix StorageService::constructRangeToEndpointMap for non-distributed 
keyspaces (CASSANDRA-19255)
 + * Group nodetool cms commands into single command group (CASSANDRA-19393)
 + * Register the measurements of the bootstrap process as Dropwizard metrics 
(CASSANDRA-19447)
 + * Add LIST SUPERUSERS CQL statement (CASSANDRA-19417)
 + * Modernize CQLSH datetime conversions (CASSANDRA-18879)
 + * Harry model and in-JVM tests for partition-restricted 2i queries 
(CASSANDRA-18275)
 + * Refactor cqlshmain global constants (CASSANDRA-19201)
 + * Remove native_transport_port_ssl (CASSANDRA-19397)
 + * Make nodetool reconfigurecms sync by default and add --cancel to be able 
to cancel ongoing reconfigurations (CASSANDRA-19216)
 + * Expose auth mode in system_views.clients, nodetool clientstats, metrics 
(CASSANDRA-19366)
 + * Remove sealed_periods and last_sealed_period tables (CASSANDRA-19189)
 + * Improve setup and initialisation of LocalLog/LogSpec (CASSANDRA-19271)
 + * Refactor structure of caching metrics and expose auth cache metrics via 
JMX (CASSANDRA-17062)
 + * Allow CQL client certificate authentication to work without sending an 
AUTHENTICATE request (CASSANDRA-18857)
 + * Extend nodetool tpstats and system_views.thread_pools with detailed pool 
parameters (CASSANDRA-19289)
 + * Remove dependency on Sigar in favor of OSHI (CASSANDRA-16565)
 + * Simplify the bind marker and Term logic (CASSANDRA-18813)
 + * Limit cassandra startup to supported JDKs, allow higher JDKs by setting 
CASSANDRA_JDK_UNSUPPORTED (CASSANDRA-18688)
 + * Standardize nodetool tablestats formatting of data units (CASSANDRA-19104)
 + * Make nodetool tablestats use number of significant digits for time and 
average values consistently (CASSANDRA-19015)
 + * Upgrade jackson to 2.15.3 and snakeyaml to 2.1 (CASSANDRA-18875)
 + * Transactional Cluster Metadata [CEP-21] (CASSANDRA-18330)
 + * Add ELAPSED command to cqlsh (CASSANDRA-18861)
 + * Add the ability to disable bulk loading of SSTables (CASSANDRA-18781)
 + * Clean up obsolete functions and simplify cql_version handling in cqlsh 
(CASSANDRA-18787)
 +Merged from 5.0:
+  * Use ParameterizedClass for all auth-related implementations 
(CASSANDRA-19946)
   * Correct out-of-date metrics and configuration documentation for SAI 
(CASSANDRA-19898)
 -Merged from 4.1:
 - * Fix race condition in DecayingEstimatedHistogramReservoir during rescale 
(CASSANDRA-19365)
 -Merged from 4.0:
 - * Ensure thread-safety for CommitLogArchiver in CommitLog (CASSANDRA-19960)
 - * Fix text containing "/*" being interpreted as multiline comment in cqlsh 
(CASSANDRA-17667)
 - * Fix indexing of a frozen collection that is the clustering key and 
reversed (CASSANDRA-19889)
 - * Emit error when altering a table with non-frozen UDTs with nested 
non-frozen collections the same way as done upon table creation 
(CASSANDRA-19925)
 -
 -
 -5.0.1
   * Make configuration entries in memtable section order-independent 
(CASSANDRA-19906)
   * Add guardrail for enabling usage of VectorType (CASSANDRA-19903)
   * Set executable flag for shell scripts in .build directory for source 
artifact (CASSANDRA-19896)
diff --cc conf/cassandra.yaml
index 546333dfcf,5562a2c156..1c53401057
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@@ -165,8 -169,7 +169,8 @@@ batchlog_replay_throttle: 1024Ki
  #   users. It keeps usernames and hashed passwords in system_auth.roles table.
  #   Please increase system_auth keyspace replication factor if you use this 
authenticator.
  #   If using PasswordAuthenticator, CassandraRoleManager must also be used 
(see below)
 -authenticator: AllowAllAuthenticator
 +authenticator:
-   class_name : org.apache.cassandra.auth.AllowAllAuthenticator
++  class_name : AllowAllAuthenticator
  # MutualTlsAuthenticator can be configured using the following configuration. 
One can add their own validator
  # which implements MutualTlsCertificateValidator class and provide logic for 
extracting identity out of certificates
  # and validating certificates.
@@@ -181,7 -188,7 +189,8 @@@
  # - AllowAllAuthorizer allows any action to any user - set it to disable 
authorization.
  # - CassandraAuthorizer stores permissions in system_auth.role_permissions 
table. Please
  #   increase system_auth keyspace replication factor if you use this 
authorizer.
--authorizer: AllowAllAuthorizer
++authorizer:
++  class_name: AllowAllAuthorizer
  
  # Part of the Authentication & Authorization backend, implementing 
IRoleManager; used
  # to maintain grants and memberships between roles.
@@@ -192,7 -203,7 +205,8 @@@
  #
  # - CassandraRoleManager stores role data in the system_auth keyspace. Please
  #   increase system_auth keyspace replication factor if you use this role 
manager.
--role_manager: CassandraRoleManager
++role_manager:
++  class_name: CassandraRoleManager
  
  # Network authorization backend, implementing INetworkAuthorizer; used to 
restrict user
  # access to certain DCs
@@@ -202,7 -217,7 +220,8 @@@
  # - AllowAllNetworkAuthorizer allows access to any DC to any user - set it to 
disable authorization.
  # - CassandraNetworkAuthorizer stores permissions in 
system_auth.network_permissions table. Please
  #   increase system_auth keyspace replication factor if you use this 
authorizer.
--network_authorizer: AllowAllNetworkAuthorizer
++network_authorizer:
++  class_name: AllowAllNetworkAuthorizer
  
  # CIDR authorization backend, implementing ICIDRAuthorizer; used to restrict 
user
  # access from certain CIDRs
diff --cc test/data/config/version=5.1-alpha1.yml
index ce1da70bd9,0000000000..e730adcdb9
mode 100644,000000..100644
--- a/test/data/config/version=5.1-alpha1.yml
+++ b/test/data/config/version=5.1-alpha1.yml
@@@ -1,490 -1,0 +1,495 @@@
 +# Licensed to the Apache Software Foundation (ASF) under one
 +# or more contributor license agreements.  See the NOTICE file
 +# distributed with this work for additional information
 +# regarding copyright ownership.  The ASF licenses this file
 +# to you under the Apache License, Version 2.0 (the
 +# "License"); you may not use this file except in compliance
 +# with the License.  You may obtain a copy of the License at
 +#
 +#     http://www.apache.org/licenses/LICENSE-2.0
 +#
 +# Unless required by applicable law or agreed to in writing, software
 +# distributed under the License is distributed on an "AS IS" BASIS,
 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +# See the License for the specific language governing permissions and
 +# limitations under the License.
 +#
 +#
 +---
 +columns_per_table_warn_threshold: "java.lang.Integer"
 +repaired_data_tracking_for_range_reads_enabled: "java.lang.Boolean"
 +cdc_block_writes: "java.lang.Boolean"
 +block_for_peers_timeout_in_secs: "java.lang.Integer"
 +flush_compression: "org.apache.cassandra.config.Config.FlushCompression"
 +commitlog_total_space: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +audit_logging_options:
 +  audit_logs_dir: "java.lang.String"
 +  included_users: "java.lang.String"
 +  logger:
 +    class_name: "java.lang.String"
 +    parameters: "java.util.Map"
 +  excluded_categories: "java.lang.String"
 +  roll_cycle: "java.lang.String"
 +  enabled: "java.lang.Boolean"
 +  included_categories: "java.lang.String"
 +  max_archive_retries: "java.lang.Integer"
 +  excluded_keyspaces: "java.lang.String"
 +  archive_command: "java.lang.String"
 +  included_keyspaces: "java.lang.String"
 +  max_log_size: "java.lang.Long"
 +  allow_nodetool_archive_command: "java.lang.Boolean"
 +  block: "java.lang.Boolean"
 +  excluded_users: "java.lang.String"
 +  max_queue_weight: "java.lang.Integer"
 +row_cache_save_period: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +snapshot_links_per_second: "java.lang.Long"
 +disk_optimization_estimate_percentile: "java.lang.Double"
 +roles_update_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +hinted_handoff_disabled_datacenters: "java.util.Set"
 +cdc_enabled: "java.lang.Boolean"
 +internode_application_receive_queue_reserve_endpoint_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +roles_validity: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +coordinator_read_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +scripted_user_defined_functions_enabled: "java.lang.Boolean"
 +auth_cache_warming_enabled: "java.lang.Boolean"
 +alter_table_enabled: "java.lang.Boolean"
 +client_request_size_metrics_enabled: "java.lang.Boolean"
 +cdc_on_repair_enabled: "java.lang.Boolean"
 +entire_sstable_stream_throughput_outbound: 
"org.apache.cassandra.config.DataRateSpec.LongBytesPerSecondBound"
 +partition_tombstones_warn_threshold: "java.lang.Long"
 +roles_cache_active_update: "java.lang.Boolean"
 +commitlog_sync: "org.apache.cassandra.config.Config.CommitLogSync"
 +paxos_repair_parallelism: "java.lang.Integer"
 +dynamic_snitch_reset_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +dynamic_snitch_update_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +native_transport_idle_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +internode_application_send_queue_reserve_global_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +concurrent_materialized_view_writes: "java.lang.Integer"
 +read_before_write_list_operations_enabled: "java.lang.Boolean"
 +table_properties_ignored: "java.util.Set"
 +maximum_timestamp_warn_threshold: 
"org.apache.cassandra.config.DurationSpec.LongMicrosecondsBound"
 +hints_directory: "java.lang.String"
 +dump_heap_on_uncaught_exception: "java.lang.Boolean"
 +native_transport_max_concurrent_connections_per_ip: "java.lang.Long"
 +secondary_indexes_per_table_fail_threshold: "java.lang.Integer"
 +vector_dimensions_warn_threshold: "java.lang.Integer"
 +auto_snapshot_ttl: "java.lang.String"
 +rpc_interface_prefer_ipv6: "java.lang.Boolean"
 +check_for_duplicate_rows_during_compaction: "java.lang.Boolean"
 +gc_log_threshold: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +secondary_indexes_enabled: "java.lang.Boolean"
 +user_function_timeout_policy: 
"org.apache.cassandra.config.Config.UserFunctionTimeoutPolicy"
 +memtable_allocation_type: 
"org.apache.cassandra.config.Config.MemtableAllocationType"
 +hints_flush_period: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +default_keyspace_rf: "java.lang.Integer"
 +tombstone_warn_threshold: "java.lang.Integer"
 +write_consistency_levels_warned: "java.util.Set"
 +full_query_logging_options:
 +  log_dir: "java.lang.String"
 +  archive_command: "java.lang.String"
 +  max_log_size: "java.lang.Long"
 +  allow_nodetool_archive_command: "java.lang.Boolean"
 +  block: "java.lang.Boolean"
 +  roll_cycle: "java.lang.String"
 +  max_queue_weight: "java.lang.Integer"
 +  max_archive_retries: "java.lang.Integer"
 +streaming_keep_alive_period: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +auto_optimise_inc_repair_streams: "java.lang.Boolean"
 +user_defined_functions_fail_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +write_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +min_tracked_partition_tombstone_count: "java.lang.Long"
 +sasi_indexes_enabled: "java.lang.Boolean"
 +disk_failure_policy: "org.apache.cassandra.config.Config.DiskFailurePolicy"
 +heap_dump_path: "java.lang.String"
 +tombstone_failure_threshold: "java.lang.Integer"
 +native_transport_max_request_data_in_flight: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +initial_token: "java.lang.String"
 +keyspaces_warn_threshold: "java.lang.Integer"
 +dynamic_snitch_badness_threshold: "java.lang.Double"
 +transient_replication_enabled: "java.lang.Boolean"
 +allocate_tokens_for_local_replication_factor: "java.lang.Integer"
 +native_transport_max_requests_per_second: "java.lang.Integer"
 +counter_cache_keys_to_save: "java.lang.Integer"
 +disk_optimization_page_cross_chance: "java.lang.Double"
 +in_select_cartesian_product_fail_threshold: "java.lang.Integer"
 +listen_on_broadcast_address: "java.lang.Boolean"
 +row_cache_class_name: "java.lang.String"
 +permissions_update_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +denylist_initial_load_retry: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +trace_type_query_ttl: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +disk_optimization_strategy: 
"org.apache.cassandra.config.Config.DiskOptimizationStrategy"
 +drop_keyspace_enabled: "java.lang.Boolean"
 +otc_backlog_expiration_interval_ms: "java.lang.Integer"
 +native_transport_max_request_data_in_flight_per_ip: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +counter_cache_save_period: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +tables_fail_threshold: "java.lang.Integer"
 +trace_type_repair_ttl: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +minimum_replication_factor_warn_threshold: "java.lang.Integer"
 +page_size_warn_threshold: "java.lang.Integer"
- role_manager: "java.lang.String"
++role_manager:
++  class_name: "java.lang.String"
++  parameters: "java.util.Map"
 +counter_write_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +denylist_writes_enabled: "java.lang.Boolean"
 +block_for_peers_in_remote_dcs: "java.lang.Boolean"
 +inter_dc_stream_throughput_outbound: 
"org.apache.cassandra.config.DataRateSpec.LongBytesPerSecondBound"
 +repair_command_pool_size: "java.lang.Integer"
 +denylist_consistency_level: "org.apache.cassandra.db.ConsistencyLevel"
 +table_properties_warned: "java.util.Set"
 +entire_sstable_inter_dc_stream_throughput_outbound: 
"org.apache.cassandra.config.DataRateSpec.LongBytesPerSecondBound"
 +data_file_directories: "java.util.List"
 +default_secondary_index: "java.lang.String"
 +networking_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +fields_per_udt_fail_threshold: "java.lang.Integer"
 +key_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +max_hint_window: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +sai_options:
 +  segment_write_buffer_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +vector_dimensions_fail_threshold: "java.lang.Integer"
 +max_hints_size_per_host: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +partition_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +maximum_timestamp_fail_threshold: 
"org.apache.cassandra.config.DurationSpec.LongMicrosecondsBound"
 +minimum_timestamp_warn_threshold: 
"org.apache.cassandra.config.DurationSpec.LongMicrosecondsBound"
 +client_error_reporting_exclusions:
 +  subnets: "java.util.Set"
 +seed_provider:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +check_for_duplicate_rows_during_reads: "java.lang.Boolean"
 +internode_max_message_size: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +items_per_collection_warn_threshold: "java.lang.Integer"
 +key_cache_migrate_during_compaction: "java.lang.Boolean"
 +sstable_read_rate_persistence_enabled: "java.lang.Boolean"
- network_authorizer: "java.lang.String"
++network_authorizer:
++  class_name: "java.lang.String"
++  parameters: "java.util.Map"
 +data_disk_usage_max_disk_size: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +memtable_offheap_space: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +prepared_statements_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +paxos_contention_wait_randomizer: "java.lang.String"
 +commitlog_compression:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +broadcast_address: "java.lang.String"
 +repair_session_space: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +partition_denylist_enabled: "java.lang.Boolean"
 +paxos_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +snapshot_before_compaction: "java.lang.Boolean"
 +back_pressure_strategy:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
- native_transport_port_ssl: "java.lang.Integer"
 +allocate_tokens_for_keyspace: "java.lang.String"
 +uuid_sstable_identifiers_enabled: "java.lang.Boolean"
 +credentials_cache_active_update: "java.lang.Boolean"
 +diagnostic_events_enabled: "java.lang.Boolean"
 +failure_detector: "java.lang.String"
 +storage_port: "java.lang.Integer"
 +drop_compact_storage_enabled: "java.lang.Boolean"
 +uncompressed_tables_enabled: "java.lang.Boolean"
 +commitlog_sync_group_window: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +auth_read_consistency_level: "java.lang.String"
 +autocompaction_on_startup_enabled: "java.lang.Boolean"
 +items_per_collection_fail_threshold: "java.lang.Integer"
 +paxos_state_purging: "org.apache.cassandra.config.Config.PaxosStatePurging"
 +column_index_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +commit_failure_policy: 
"org.apache.cassandra.config.Config.CommitFailurePolicy"
 +concurrent_writes: "java.lang.Integer"
 +max_value_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +read_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +hinted_handoff_enabled: "java.lang.Boolean"
 +automatic_sstable_upgrade: "java.lang.Boolean"
 +memtable_flush_writers: "java.lang.Integer"
 +otc_coalescing_strategy: "java.lang.String"
 +snapshot_on_repaired_data_mismatch: "java.lang.Boolean"
 +cidr_authorizer:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +commitlog_max_compression_buffers_in_pool: "java.lang.Integer"
 +zero_ttl_on_twcs_enabled: "java.lang.Boolean"
 +cdc_free_space_check_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +roles_cache_max_entries: "java.lang.Integer"
 +allow_filtering_enabled: "java.lang.Boolean"
 +columns_per_table_fail_threshold: "java.lang.Integer"
 +start_native_transport: "java.lang.Boolean"
 +ssl_storage_port: "java.lang.Integer"
 +cluster_name: "java.lang.String"
 +credentials_update_interval: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +incremental_backups: "java.lang.Boolean"
 +internode_socket_send_buffer_size: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +default_compaction:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +min_tracked_partition_size: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +cas_contention_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +key_cache_save_period: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +windows_timer_interval: "java.lang.Integer"
 +rpc_interface: "java.lang.String"
 +row_cache_keys_to_save: "java.lang.Integer"
 +compact_tables_enabled: "java.lang.Boolean"
 +partition_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +minimum_timestamp_fail_threshold: 
"org.apache.cassandra.config.DurationSpec.LongMicrosecondsBound"
 +repair_command_pool_full_strategy: 
"org.apache.cassandra.config.Config.RepairCommandPoolFullStrategy"
 +drop_truncate_table_enabled: "java.lang.Boolean"
 +max_top_size_partition_count: "java.lang.Integer"
 +client_encryption_options:
 +  optional: "java.lang.Boolean"
 +  store_type: "java.lang.String"
 +  cipher_suites: "java.util.List"
 +  enabled: "java.lang.Boolean"
 +  require_endpoint_verification: "java.lang.Boolean"
 +  accepted_protocols: "java.util.List"
 +  keystore_password: "java.lang.String"
 +  protocol: "java.lang.String"
-   require_client_auth: "java.lang.Boolean"
++  require_client_auth: "java.lang.String"
 +  ssl_context_factory:
 +    class_name: "java.lang.String"
 +    parameters: "java.util.Map"
 +  truststore_password: "java.lang.String"
 +  keystore: "java.lang.String"
 +  truststore: "java.lang.String"
 +  algorithm: "java.lang.String"
 +concurrent_validations: "java.lang.Integer"
 +ideal_consistency_level: "org.apache.cassandra.db.ConsistencyLevel"
 +partition_keys_in_select_warn_threshold: "java.lang.Integer"
 +consecutive_message_errors_threshold: "java.lang.Integer"
 +read_thresholds_enabled: "java.lang.Boolean"
 +internode_application_send_queue_reserve_endpoint_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +partition_keys_in_select_fail_threshold: "java.lang.Integer"
 +trickle_fsync: "java.lang.Boolean"
 +group_by_enabled: "java.lang.Boolean"
 +reject_repair_compaction_threshold: "java.lang.Integer"
 +request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +cdc_total_space: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +default_secondary_index_enabled: "java.lang.Boolean"
 +paxos_variant: "org.apache.cassandra.config.Config.PaxosVariant"
 +index_summary_resize_interval: 
"org.apache.cassandra.config.DurationSpec.IntMinutesBound"
 +max_top_tombstone_partition_count: "java.lang.Integer"
 +data_disk_usage_percentage_fail_threshold: "java.lang.Integer"
 +max_streaming_retries: "java.lang.Integer"
 +internode_timeout: "java.lang.Boolean"
 +native_transport_flush_in_batches_legacy: "java.lang.Boolean"
 +rpc_address: "java.lang.String"
 +trickle_fsync_interval: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +file_cache_enabled: "java.lang.Boolean"
 +cdc_raw_directory: "java.lang.String"
 +num_tokens: "java.lang.Integer"
 +native_transport_max_frame_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +user_timestamps_enabled: "java.lang.Boolean"
 +paxos_topology_repair_no_dc_checks: "java.lang.Boolean"
 +repaired_data_tracking_for_partition_reads_enabled: "java.lang.Boolean"
 +internode_streaming_tcp_user_timeout: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +file_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +denylist_max_keys_per_table: "java.lang.Integer"
 +commitlog_directory: "java.lang.String"
 +unlogged_batch_across_partitions_warn_threshold: "java.lang.Integer"
 +write_consistency_levels_disallowed: "java.util.Set"
 +auto_bootstrap: "java.lang.Boolean"
- authorizer: "java.lang.String"
++authorizer:
++  class_name: "java.lang.String"
++  parameters: "java.util.Map"
 +auth_write_consistency_level: "java.lang.String"
 +counter_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +denylist_range_reads_enabled: "java.lang.Boolean"
 +batchlog_replay_throttle: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +compaction_throughput: 
"org.apache.cassandra.config.DataRateSpec.LongBytesPerSecondBound"
 +stream_throughput_outbound: 
"org.apache.cassandra.config.DataRateSpec.LongBytesPerSecondBound"
 +streaming_state_expires: 
"org.apache.cassandra.config.DurationSpec.LongNanosecondsBound"
 +broadcast_rpc_address: "java.lang.String"
 +listen_interface_prefer_ipv6: "java.lang.Boolean"
 +repair_session_max_tree_depth: "java.lang.Integer"
 +auto_optimise_preview_repair_streams: "java.lang.Boolean"
 +column_value_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +internode_tcp_connect_timeout: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +paxos_purge_grace_period: 
"org.apache.cassandra.config.DurationSpec.LongSecondsBound"
 +commitlog_sync_period: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +concurrent_compactors: "java.lang.Integer"
 +hint_window_persistent_enabled: "java.lang.Boolean"
 +buffer_pool_use_heap_if_exhausted: "java.lang.Boolean"
 +paxos_contention_max_wait: "java.lang.String"
 +native_transport_receive_queue_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +concurrent_index_builders: "java.lang.Integer"
 +in_select_cartesian_product_warn_threshold: "java.lang.Integer"
 +local_system_data_file_directory: "java.lang.String"
 +stream_entire_sstables: "java.lang.Boolean"
 +stream_transfer_task_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +internode_tcp_user_timeout: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +corrupted_tombstone_strategy: 
"org.apache.cassandra.config.Config.CorruptedTombstoneStrategy"
 +paxos_topology_repair_strict_each_quorum: "java.lang.Boolean"
 +listen_address: "java.lang.String"
 +top_partitions_enabled: "java.lang.Boolean"
 +sstable_preemptive_open_interval: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +rpc_keepalive: "java.lang.Boolean"
 +min_free_space_per_drive: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +read_consistency_levels_warned: "java.util.Set"
 +allow_extra_insecure_udfs: "java.lang.Boolean"
 +batch_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +disk_access_mode: "org.apache.cassandra.config.Config.DiskAccessMode"
 +concurrent_counter_writes: "java.lang.Integer"
 +internode_error_reporting_exclusions:
 +  subnets: "java.util.Set"
 +paxos_contention_min_delta: "java.lang.String"
 +simplestrategy_enabled: "java.lang.Boolean"
 +dynamic_snitch: "java.lang.Boolean"
 +use_deterministic_table_id: "java.lang.Boolean"
 +phi_convict_threshold: "java.lang.Double"
 +max_hints_file_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +native_transport_max_threads: "java.lang.Integer"
 +sstable:
 +  selected_format: "java.lang.String"
 +  format: "java.util.Map"
 +minimum_replication_factor_fail_threshold: "java.lang.Integer"
 +table_properties_disallowed: "java.util.Set"
 +collection_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +memtable:
 +  configurations: "java.util.LinkedHashMap"
 +authenticator:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +internode_socket_receive_buffer_size: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +allow_insecure_udfs: "java.lang.Boolean"
 +internode_application_receive_queue_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +user_defined_functions_enabled: "java.lang.Boolean"
 +user_defined_functions_threads_enabled: "java.lang.Boolean"
 +streaming_slow_events_log_timeout: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +truncate_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +severity_during_decommission: "java.lang.Double"
 +periodic_commitlog_sync_lag_block: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +repair_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +auto_optimise_full_repair_streams: "java.lang.Boolean"
 +commitlog_segment_size: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +batch_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +streaming_state_size: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +denylist_max_keys_total: "java.lang.Integer"
 +dynamic_data_masking_enabled: "java.lang.Boolean"
 +storage_compatibility_mode: 
"org.apache.cassandra.utils.StorageCompatibilityMode"
 +repair_state_expires: 
"org.apache.cassandra.config.DurationSpec.LongNanosecondsBound"
 +native_transport_allow_older_protocols: "java.lang.Boolean"
 +otc_coalescing_enough_coalesced_messages: "java.lang.Integer"
 +transfer_hints_on_decommission: "java.lang.Boolean"
 +report_unconfirmed_repaired_data_mismatches: "java.lang.Boolean"
 +fields_per_udt_warn_threshold: "java.lang.Integer"
 +paxos_on_linearizability_violations: 
"org.apache.cassandra.config.Config.PaxosOnLinearizabilityViolation"
 +read_consistency_levels_disallowed: "java.util.Set"
 +use_offheap_merkle_trees: "java.lang.Boolean"
 +concurrent_materialized_view_builders: "java.lang.Integer"
 +server_encryption_options:
 +  outbound_keystore: "java.lang.String"
 +  optional: "java.lang.Boolean"
 +  store_type: "java.lang.String"
 +  cipher_suites: "java.util.List"
 +  enabled: "java.lang.Boolean"
 +  outbound_keystore_password: "java.lang.String"
 +  require_endpoint_verification: "java.lang.Boolean"
 +  accepted_protocols: "java.util.List"
 +  keystore_password: "java.lang.String"
 +  protocol: "java.lang.String"
-   require_client_auth: "java.lang.Boolean"
++  require_client_auth: "java.lang.String"
 +  internode_encryption: 
"org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.InternodeEncryption"
 +  ssl_context_factory:
 +    class_name: "java.lang.String"
 +    parameters: "java.util.Map"
 +  legacy_ssl_storage_port_enabled: "java.lang.Boolean"
 +  truststore_password: "java.lang.String"
 +  keystore: "java.lang.String"
 +  truststore: "java.lang.String"
 +  algorithm: "java.lang.String"
 +  max_certificate_validity_period: 
"org.apache.cassandra.config.DurationSpec.IntMinutesBound"
 +  certificate_validity_warn_threshold: 
"org.apache.cassandra.config.DurationSpec.IntMinutesBound"
 +partition_tombstones_fail_threshold: "java.lang.Long"
 +traverse_auth_from_root: "java.lang.Boolean"
 +denylist_refresh: "org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +max_hints_delivery_threads: "java.lang.Integer"
 +permissions_validity: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +materialized_views_enabled: "java.lang.Boolean"
 +saved_caches_directory: "java.lang.String"
 +internode_application_send_queue_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +memtable_heap_space: 
"org.apache.cassandra.config.DataStorageSpec.IntMebibytesBound"
 +max_concurrent_automatic_sstable_upgrades: "java.lang.Integer"
 +maximum_replication_factor_warn_threshold: "java.lang.Integer"
 +denylist_reads_enabled: "java.lang.Boolean"
 +permissions_cache_active_update: "java.lang.Boolean"
 +available_processors: "java.lang.Integer"
 +file_cache_round_up: "java.lang.Boolean"
 +secondary_indexes_per_table_warn_threshold: "java.lang.Integer"
 +tables_warn_threshold: "java.lang.Integer"
 +column_value_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +snapshot_on_duplicate_row_detection: "java.lang.Boolean"
 +internode_application_receive_queue_reserve_global_capacity: 
"org.apache.cassandra.config.DataStorageSpec.IntBytesBound"
 +internode_compression: 
"org.apache.cassandra.config.Config.InternodeCompression"
 +range_request_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +streaming_stats_enabled: "java.lang.Boolean"
 +local_read_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +otc_coalescing_window_us: "java.lang.Integer"
 +page_size_fail_threshold: "java.lang.Integer"
 +credentials_cache_max_entries: "java.lang.Integer"
 +coordinator_read_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +row_index_read_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +index_summary_capacity: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +collection_size_fail_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +column_index_size: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +validation_preview_purge_head_start: 
"org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +skip_paxos_repair_on_topology_change_keyspaces: "java.util.Set"
 +materialized_views_per_table_fail_threshold: "java.lang.Integer"
 +max_mutation_size: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +keyspaces_fail_threshold: "java.lang.Integer"
 +data_disk_usage_percentage_warn_threshold: "java.lang.Integer"
 +slow_query_log_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +paxos_contention_min_wait: "java.lang.String"
 +repair_state_size: "java.lang.Integer"
 +user_defined_functions_warn_timeout: 
"org.apache.cassandra.config.DurationSpec.LongMillisecondsBound"
 +zero_ttl_on_twcs_warned: "java.lang.Boolean"
 +native_transport_port: "java.lang.Integer"
 +permissions_cache_max_entries: "java.lang.Integer"
 +hinted_handoff_throttle: 
"org.apache.cassandra.config.DataStorageSpec.IntKibibytesBound"
 +row_index_read_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +hints_compression:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +native_transport_max_auth_threads: "java.lang.Integer"
 +force_new_prepared_statement_behaviour: "java.lang.Boolean"
 +back_pressure_enabled: "java.lang.Boolean"
 +materialized_views_per_table_warn_threshold: "java.lang.Integer"
 +transparent_data_encryption_options:
 +  cipher: "java.lang.String"
 +  chunk_length_kb: "java.lang.Integer"
 +  iv_length: "java.lang.Integer"
 +  key_alias: "java.lang.String"
 +  key_provider:
 +    class_name: "java.lang.String"
 +    parameters: "java.util.Map"
 +  enabled: "java.lang.Boolean"
 +initial_range_tombstone_list_allocation_size: "java.lang.Integer"
 +partitioner: "java.lang.String"
 +gc_warn_threshold: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +listen_interface: "java.lang.String"
 +row_cache_size: 
"org.apache.cassandra.config.DataStorageSpec.LongMebibytesBound"
 +skip_stream_disk_space_check: "java.lang.Boolean"
 +paxos_repair_enabled: "java.lang.Boolean"
 +inter_dc_tcp_nodelay: "java.lang.Boolean"
 +internode_authenticator:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +key_cache_keys_to_save: "java.lang.Integer"
 +crypto_provider:
 +  class_name: "java.lang.String"
 +  parameters: "java.util.Map"
 +local_read_size_warn_threshold: 
"org.apache.cassandra.config.DataStorageSpec.LongBytesBound"
 +replica_filtering_protection:
 +  cached_rows_fail_threshold: "java.lang.Integer"
 +  cached_rows_warn_threshold: "java.lang.Integer"
 +range_tombstone_list_growth_factor: "java.lang.Double"
 +startup_checks: "java.util.Map"
 +max_space_usable_for_compactions_in_percentage: "java.lang.Double"
 +native_transport_max_concurrent_connections: "java.lang.Long"
 +maximum_replication_factor_fail_threshold: "java.lang.Integer"
 +memtable_cleanup_threshold: "java.lang.Float"
 +concurrent_reads: "java.lang.Integer"
 +credentials_validity: 
"org.apache.cassandra.config.DurationSpec.IntMillisecondsBound"
 +streaming_connections_per_host: "java.lang.Integer"
 +cache_load_timeout: "org.apache.cassandra.config.DurationSpec.IntSecondsBound"
 +native_transport_rate_limiting_enabled: "java.lang.Boolean"
 +use_statements_enabled: "java.lang.Boolean"
 +auto_hints_cleanup_enabled: "java.lang.Boolean"
 +auto_snapshot: "java.lang.Boolean"
 +skip_paxos_repair_on_topology_change: "java.lang.Boolean"
 +endpoint_snitch: "java.lang.String"
diff --cc test/unit/org/apache/cassandra/config/ConfigCompatibilityTest.java
index 19d7f17d76,d94cb57920..f5d10a6b52
--- a/test/unit/org/apache/cassandra/config/ConfigCompatibilityTest.java
+++ b/test/unit/org/apache/cassandra/config/ConfigCompatibilityTest.java
@@@ -110,9 -102,14 +110,15 @@@ public class ConfigCompatibilityTes
                                                                     // 
Switched to a parameterized class that can construct from a bare string
                                                                     
.add("internode_authenticator types do not match; 
org.apache.cassandra.config.ParameterizedClass != java.lang.String")
                                                                     
.add("authenticator types do not match; 
org.apache.cassandra.config.ParameterizedClass != java.lang.String")
+                                                                    
.add("authorizer types do not match; 
org.apache.cassandra.config.ParameterizedClass != java.lang.String")
+                                                                    
.add("network_authorizer types do not match; 
org.apache.cassandra.config.ParameterizedClass != java.lang.String")
+                                                                    
.add("role_manager types do not match; 
org.apache.cassandra.config.ParameterizedClass != java.lang.String")
                                                                     
.add("Property internode_authenticator used to be a value-type, but now is 
nested type class org.apache.cassandra.config.ParameterizedClass")
                                                                     
.add("Property authenticator used to be a value-type, but now is nested type 
class org.apache.cassandra.config.ParameterizedClass")
+                                                                    
.add("Property authorizer used to be a value-type, but now is nested type class 
org.apache.cassandra.config.ParameterizedClass")
+                                                                    
.add("Property role_manager used to be a value-type, but now is nested type 
class org.apache.cassandra.config.ParameterizedClass")
+                                                                    
.add("Property network_authorizer used to be a value-type, but now is nested 
type class org.apache.cassandra.config.ParameterizedClass")
 +                                                                   
.add("require_client_auth types do not match; java.lang.String != 
java.lang.Boolean")
                                                                     .build();
  
      /**
@@@ -154,10 -151,10 +160,18 @@@
      @Test
      public void diff_5_0() throws IOException
      {
-         diff(TEST_DIR + "/version=5.0-alpha1.yml", 
ImmutableSet.<String>builder().addAll(REMOVED_IN_51)
+         diff(TEST_DIR + "/version=5.0-alpha1.yml", 
ImmutableSet.<String>builder()
++                                                               
.addAll(REMOVED_IN_51)
 +                                                               .build(), 
EXPECTED_FOR_50);
 +    }
 +
++    @Test
++    public void diff_5_1() throws IOException
++    {
++        diff(TEST_DIR + "/version=5.1-alpha1.yml", 
ImmutableSet.<String>builder()
+                                                                .build(), 
ImmutableSet.of());
+     }
+ 
      private void diff(String original, Set<String> ignore, Set<String> 
expectedErrors) throws IOException
      {
          Class<Config> type = Config.class;
diff --cc test/unit/org/apache/cassandra/transport/TlsTestUtils.java
index 6e6425c77b,0000000000..24f3124f86
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/transport/TlsTestUtils.java
+++ b/test/unit/org/apache/cassandra/transport/TlsTestUtils.java
@@@ -1,222 -1,0 +1,222 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.cassandra.transport;
 +
 +import java.io.File;
 +import java.net.InetAddress;
 +import java.net.InetSocketAddress;
 +import java.nio.file.Path;
 +import java.time.Instant;
 +import java.time.temporal.ChronoUnit;
 +import java.util.Collections;
 +import java.util.Map;
 +import java.util.function.Consumer;
 +import java.util.function.Function;
 +import javax.net.ssl.SSLException;
 +
 +import com.google.common.collect.ImmutableMap;
 +
 +import com.datastax.driver.core.PlainTextAuthProvider;
 +import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions;
 +import com.datastax.driver.core.SSLOptions;
 +import com.datastax.driver.core.Session;
 +import com.datastax.driver.core.policies.LoadBalancingPolicy;
 +import org.apache.cassandra.config.Config;
 +import org.apache.cassandra.config.EncryptionOptions;
 +import org.apache.cassandra.config.ParameterizedClass;
 +import org.apache.cassandra.distributed.api.ICluster;
 +import org.apache.cassandra.distributed.api.IInvokableInstance;
 +import org.apache.cassandra.distributed.shared.ClusterUtils;
 +import org.apache.cassandra.distributed.util.Auth;
 +import org.apache.cassandra.distributed.util.SingleHostLoadBalancingPolicy;
 +import org.apache.cassandra.security.ISslContextFactory;
 +import org.apache.cassandra.utils.tls.CertificateBuilder;
 +import org.apache.cassandra.utils.tls.CertificateBundle;
 +
 +import static 
org.apache.cassandra.auth.CassandraRoleManager.DEFAULT_SUPERUSER_NAME;
 +import static 
org.apache.cassandra.auth.CassandraRoleManager.DEFAULT_SUPERUSER_PASSWORD;
 +
 +public class TlsTestUtils
 +{
 +    public static String SERVER_KEYSTORE_PATH = 
"test/conf/cassandra_ssl_test.keystore";
 +    public static String SERVER_KEYSTORE_PATH_PEM = 
"test/conf/cassandra_ssl_test.keystore.pem";
 +    public static String SERVER_KEYSTORE_PATH_UNENCRYPTED_PEM = 
"test/conf/cassandra_ssl_test.unencrypted_keystore.pem";
 +    public static String SERVER_KEYSTORE_PASSWORD = "cassandra";
 +
 +    public static String SERVER_KEYSTORE_ENDPOINT_VERIFY_PATH = 
"test/conf/cassandra_ssl_test_endpoint_verify.keystore";
 +    public static String SERVER_KEYSTORE_ENDPOINT_VERIFY_PASSWORD = 
"cassandra";
 +
 +    public static String SERVER_OUTBOUND_KEYSTORE_PATH = 
"test/conf/cassandra_ssl_test_outbound.keystore";
 +    public static String SERVER_OUTBOUND_KEYSTORE_PASSWORD = "cassandra";
 +
 +    public static String SERVER_TRUSTSTORE_PATH = 
"test/conf/cassandra_ssl_test.truststore";
 +    public static String SERVER_TRUSTSTORE_PEM_PATH = 
"test/conf/cassandra_ssl_test.truststore.pem";
 +    public static String SERVER_TRUSTSTORE_PASSWORD = "cassandra";
 +
 +    // To regenerate:
 +    // 1. generate keystore
 +    //    keytool -genkeypair -keystore 
test/conf/cassandra_ssl_test_spiffe.keystore -validity 100000 -keyalg RSA 
-dname "CN=Apache Cassandra, OU=ssl_test, O=Unknown, L=Unknown, ST=Unknown, 
C=Unknown" -keypass cassandra -storepass cassandra -alias spiffecert -ext 
SAN=URI:spiffe://test.cassandra.apache.org/unitTest/mtls -storetype jks
 +    // 2. export cert
 +    //    keytool -export -alias spiffecert -file spiffecert.cer -keystore 
test/conf/cassandra_ssl_test_spiffe.keystore
 +    // 3. import cert into truststore
 +    //    keytool -import -v -trustcacerts -alias spiffecert -file 
spiffecert.cer -keystore test/conf/cassandra_ssl_test.truststore
 +    public static String CLIENT_SPIFFE_KEYSTORE_PATH = 
"test/conf/cassandra_ssl_test_spiffe.keystore";
 +    public static String CLIENT_SPIFFE_KEYSTORE_PASSWORD = "cassandra";
 +    public static String CLIENT_SPIFFE_IDENTITY = 
"spiffe://test.cassandra.apache.org/unitTest/mtls";
 +
 +    public static String CLIENT_TRUSTSTORE_PATH = 
"test/conf/cassandra_ssl_test.truststore";
 +    public static String CLIENT_TRUSTSTORE_PASSWORD = "cassandra";
 +
 +    public static EncryptionOptions getClientEncryptionOptions()
 +    {
 +        return new EncryptionOptions(new EncryptionOptions()
 +                              .withEnabled(true)
 +                              
.withRequireClientAuth(EncryptionOptions.ClientAuth.OPTIONAL)
 +                              .withOptional(true)
 +                              .withKeyStore(SERVER_KEYSTORE_PATH)
 +                              .withKeyStorePassword(SERVER_KEYSTORE_PASSWORD)
 +                              .withTrustStore(SERVER_TRUSTSTORE_PATH)
 +                              
.withTrustStorePassword(SERVER_TRUSTSTORE_PASSWORD)
 +                              .withRequireEndpointVerification(false));
 +    }
 +
 +    public static void 
configureWithMutualTlsWithPasswordFallbackAuthenticator(Config config)
 +    {
 +        // Configure an authenticator that supports multiple authentication 
mechanisms.
 +        Map<String, String> parameters = 
Collections.singletonMap("validator_class_name", 
"org.apache.cassandra.auth.SpiffeCertificateValidator");
 +        config.authenticator = new 
ParameterizedClass("MutualTlsWithPasswordFallbackAuthenticator", parameters);
 +        // Configure client encryption such that we can optionally connect 
with SSL.
 +        config.client_encryption_options = 
TlsTestUtils.getClientEncryptionOptions();
-         config.role_manager = "CassandraRoleManager";
-         config.authorizer = "CassandraAuthorizer";
++        config.role_manager = new ParameterizedClass("CassandraRoleManager");
++        config.authorizer = new ParameterizedClass("CassandraAuthorizer");
 +    }
 +
 +    public static ISslContextFactory getClientSslContextFactory(boolean 
provideClientCert)
 +    {
 +        ImmutableMap.Builder<String, Object> params = ImmutableMap.<String, 
Object>builder()
 +                                                                  
.put("truststore", CLIENT_TRUSTSTORE_PATH)
 +                                                                  
.put("truststore_password", CLIENT_TRUSTSTORE_PASSWORD);
 +
 +        if (provideClientCert)
 +        {
 +            params.put("keystore", CLIENT_SPIFFE_KEYSTORE_PATH)
 +                  .put("keystore_password", CLIENT_SPIFFE_KEYSTORE_PASSWORD);
 +        }
 +
 +        return new SimpleClientSslContextFactory(params.build());
 +    }
 +
 +    public static SSLOptions getSSLOptions(boolean provideClientCert) throws 
SSLException
 +    {
 +        return RemoteEndpointAwareJdkSSLOptions.builder()
 +                                               
.withSSLContext(getClientSslContextFactory(provideClientCert)
 +                                                               
.createJSSESslContext(EncryptionOptions.ClientAuth.OPTIONAL))
 +                                               .build();
 +    }
 +
 +    public static SSLOptions getSSLOptions(Path keystorePath, Path 
truststorePath) throws RuntimeException
 +    {
 +        try
 +        {
 +            return RemoteEndpointAwareJdkSSLOptions.builder()
 +                                                   
.withSSLContext(getClientSslContextFactory(keystorePath, truststorePath)
 +                                                                   
.createJSSESslContext(EncryptionOptions.ClientAuth.OPTIONAL))
 +                                                   .build();
 +        }
 +        catch (SSLException e)
 +        {
 +            throw new RuntimeException(e);
 +        }
 +    }
 +
 +    private static ISslContextFactory getClientSslContextFactory(Path 
keystorePath, Path truststorePath)
 +    {
 +        ImmutableMap.Builder<String, Object> params = ImmutableMap.<String, 
Object>builder()
 +                                                                  
.put("truststore", truststorePath.toString())
 +                                                                  
.put("truststore_password", CLIENT_TRUSTSTORE_PASSWORD);
 +
 +        if (keystorePath != null)
 +        {
 +            params.put("keystore", keystorePath.toString())
 +                  .put("keystore_password", "cassandra");
 +        }
 +
 +        return new SimpleClientSslContextFactory(params.build());
 +    }
 +
 +    public static void configureIdentity(ICluster<IInvokableInstance> 
cluster, SSLOptions sslOptions)
 +    {
 +        withAuthenticatedSession(cluster.get(1), DEFAULT_SUPERUSER_NAME, 
DEFAULT_SUPERUSER_PASSWORD, session -> {
 +            session.execute("CREATE ROLE cassandra_ssl_test WITH LOGIN = 
true");
 +            session.execute(String.format("ADD IDENTITY '%s' TO ROLE 
'cassandra_ssl_test'", CLIENT_SPIFFE_IDENTITY));
 +            // GRANT select to cassandra_ssl_test to be able to query the 
system_views.clients virtual table
 +            session.execute("GRANT SELECT ON ALL KEYSPACES to 
cassandra_ssl_test");
 +        }, sslOptions);
 +    }
 +
 +    public static Path 
generateSelfSignedCertificate(Function<CertificateBuilder, CertificateBuilder> 
customizeCertificate, File targetDirectory) throws Exception
 +    {
 +        return generateClientCertificate(customizeCertificate, 
targetDirectory, null);
 +    }
 +
 +    public static Path generateClientCertificate(Function<CertificateBuilder, 
CertificateBuilder> customizeCertificate, File targetDirectory, 
CertificateBundle ca) throws Exception
 +    {
 +        CertificateBuilder builder = new 
CertificateBuilder().subject("CN=Apache Cassandra, OU=ssl_test, O=Unknown, 
L=Unknown, ST=Unknown, C=Unknown")
 +                                                             
.notBefore(Instant.now().minus(1, ChronoUnit.DAYS))
 +                                                             
.notAfter(Instant.now().plus(1, ChronoUnit.DAYS))
 +                                                             
.alias("spiffecert")
 +                                                             
.addSanUriName(CLIENT_SPIFFE_IDENTITY)
 +                                                             
.rsa2048Algorithm();
 +        if (customizeCertificate != null)
 +        {
 +            builder = customizeCertificate.apply(builder);
 +        }
 +        CertificateBundle ssc = ca != null
 +                                ? builder.buildIssuedBy(ca)
 +                                : builder.buildSelfSigned();
 +        return ssc.toTempKeyStorePath(targetDirectory.toPath(), 
SERVER_KEYSTORE_PASSWORD.toCharArray(), SERVER_KEYSTORE_PASSWORD.toCharArray());
 +    }
 +
 +    public static void withAuthenticatedSession(IInvokableInstance instance,
 +                                         String username,
 +                                         String password,
 +                                         Consumer<Session> consumer,
 +                                         SSLOptions sslOptions)
 +    {
 +        // wait for existing roles
 +        Auth.waitForExistingRoles(instance);
 +
 +        InetSocketAddress nativeInetSocketAddress = 
ClusterUtils.getNativeInetSocketAddress(instance);
 +        InetAddress address = nativeInetSocketAddress.getAddress();
 +        LoadBalancingPolicy lbc = new SingleHostLoadBalancingPolicy(address);
 +
 +        com.datastax.driver.core.Cluster.Builder builder = 
com.datastax.driver.core.Cluster.builder()
 +                                                                              
             .withLoadBalancingPolicy(lbc)
 +                                                                              
             .withSSL(sslOptions)
 +                                                                              
             .withAuthProvider(new PlainTextAuthProvider(username, password))
 +                                                                              
             .addContactPoint(address.getHostAddress())
 +                                                                              
             .withPort(nativeInetSocketAddress.getPort());
 +
 +        try (com.datastax.driver.core.Cluster c = builder.build(); Session 
session = c.connect())
 +        {
 +            consumer.accept(session);
 +        }
 +    }
 +
 +}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to