Skip to content

Commit db4d6c3

Browse files
committed
Catalog: add migration for mock_authentication_nonce setting
The (SASL/SCRAM)[#33468] PR introduces the need for some stable, cluster wide, cryptographically random key material. We use this material to be able to present deterministic challenges for even users that don't exist to guard against enumeration attacks. However that PR made a bad assumption that the initialize step of catalog opening would always add this new key. But old versions that have already been initialized wouldn't have it! This PR add code to generate it for old versions
1 parent 474411f commit db4d6c3

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/catalog/src/durable/persist.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ use timely::progress::{Antichain, Timestamp as TimelyTimestamp};
4545
use tracing::{debug, info, warn};
4646
use uuid::Uuid;
4747

48+
use crate::durable::MOCK_AUTHENTICATION_NONCE_KEY;
4849
use crate::durable::debug::{Collection, CollectionType, DebugCatalogState, Trace};
4950
use crate::durable::error::FenceError;
5051
use crate::durable::initialize::{
5152
ENABLE_0DT_DEPLOYMENT_PANIC_AFTER_TIMEOUT, SYSTEM_CONFIG_SYNCED_KEY, USER_VERSION_KEY,
5253
WITH_0DT_DEPLOYMENT_DDL_CHECK_INTERVAL, WITH_0DT_DEPLOYMENT_MAX_WAIT,
5354
};
5455
use crate::durable::metrics::Metrics;
56+
use crate::durable::objects::serialization::proto;
5557
use crate::durable::objects::state_update::{
5658
IntoStateUpdateKindJson, StateUpdate, StateUpdateKind, StateUpdateKindJson,
5759
TryIntoStateUpdateKind,
@@ -65,6 +67,8 @@ use crate::durable::{
6567
ReadOnlyDurableCatalogState, Transaction, initialize,
6668
};
6769
use crate::memory;
70+
use base64::Engine as _;
71+
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD_ENGINE;
6872

6973
/// New-type used to represent timestamps in persist.
7074
pub(crate) type Timestamp = mz_repr::Timestamp;
@@ -971,6 +975,35 @@ pub(crate) type UnopenedPersistCatalogState =
971975
PersistHandle<StateUpdateKindJson, UnopenedCatalogStateInner>;
972976

973977
impl UnopenedPersistCatalogState {
978+
/// Generate setting backfill updates for settings that are part of the
979+
/// always-deserializable `Setting` collection. These cannot be handled by the
980+
/// versioned migrations, so we insert them here during open.
981+
fn setting_migration_updates(&self) -> Vec<(StateUpdateKindJson, Diff)> {
982+
let mut updates = Vec::new();
983+
984+
let mut ensure_setting = |name: &str, value_fn: &mut dyn FnMut() -> String| {
985+
if !self.update_applier.settings.contains_key(name) {
986+
let key = proto::SettingKey {
987+
name: name.to_string(),
988+
};
989+
let value = proto::SettingValue { value: value_fn() };
990+
let kind = StateUpdateKind::Setting(key, value);
991+
updates.push((kind.into(), Diff::ONE));
992+
}
993+
};
994+
995+
// Backfill MOCK_AUTHENTICATION_NONCE_KEY if missing.
996+
{
997+
let mut mk_nonce = || {
998+
let mut nonce = [0u8; 24];
999+
let _ = openssl::rand::rand_bytes(&mut nonce); // best-effort
1000+
BASE64_STANDARD_ENGINE.encode(nonce)
1001+
};
1002+
ensure_setting(MOCK_AUTHENTICATION_NONCE_KEY, &mut mk_nonce);
1003+
}
1004+
1005+
updates
1006+
}
9741007
/// Create a new [`UnopenedPersistCatalogState`] to the catalog state associated with
9751008
/// `organization_id`.
9761009
///
@@ -1231,6 +1264,17 @@ impl UnopenedPersistCatalogState {
12311264
commit_ts = upgrade(&mut self, commit_ts).await?;
12321265
}
12331266

1267+
// Perform setting backfills
1268+
if !read_only {
1269+
let setting_updates = self.setting_migration_updates();
1270+
if !setting_updates.is_empty() {
1271+
commit_ts = self
1272+
.compare_and_append(setting_updates, commit_ts)
1273+
.await
1274+
.map_err(|e| CatalogError::from(e.unwrap_fence_error()))?;
1275+
}
1276+
}
1277+
12341278
debug!(
12351279
?is_initialized,
12361280
?self.upper,

0 commit comments

Comments
 (0)