From 877d31246f316e486179c3122572cb7d7ea020ae Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Wed, 23 Sep 2026 04:11:52 +0000 Subject: [PATCH] Correct the BLE comments in the shipped configs The example configs said BLE needs "the 'ble' feature", but no such cargo feature exists: the BLE transport is compiled for glibc Linux and Android by build.rs and nowhere else. Say which builds have it in the common config, and drop the BLE example from the OpenWrt config, whose musl builds never include the transport. Correct the same claim in the BleConfig doc comment. Add lib tests that the shipped configs name only cargo features that exist and that the OpenWrt config offers no BLE block. --- packaging/common/fips.yaml | 3 +- .../openwrt-ipk/files/etc/fips/fips.yaml | 9 +- src/config/transport.rs | 2 +- src/packaging_tests.rs | 101 ++++++++++++++++++ 4 files changed, 105 insertions(+), 10 deletions(-) diff --git a/packaging/common/fips.yaml b/packaging/common/fips.yaml index c8ea17ce..e23b4bf1 100644 --- a/packaging/common/fips.yaml +++ b/packaging/common/fips.yaml @@ -103,7 +103,8 @@ transports: # auto_connect: true # accept_connections: true - # Bluetooth Low Energy transport — requires BlueZ and the 'ble' feature. + # Bluetooth Low Energy transport: Linux (glibc) builds only, with BlueZ + # (bluetoothd) running. Not available on macOS, FreeBSD, Windows or OpenWrt. # ble: # adapter: "hci0" # mtu: 2048 diff --git a/packaging/openwrt-ipk/files/etc/fips/fips.yaml b/packaging/openwrt-ipk/files/etc/fips/fips.yaml index a12db9b8..2f15160d 100644 --- a/packaging/openwrt-ipk/files/etc/fips/fips.yaml +++ b/packaging/openwrt-ipk/files/etc/fips/fips.yaml @@ -162,14 +162,7 @@ transports: # auto_connect: true # accept_connections: true - # Bluetooth Low Energy transport — requires BlueZ and the 'ble' feature. - # ble: - # adapter: "hci0" - # mtu: 2048 - # advertise: true - # scan: true - # auto_connect: true - # accept_connections: true + # No BLE transport: OpenWrt builds target musl, which has no BlueZ backend. # Outbound LAN gateway. dnsmasq forwards .fips queries to listen=[::1]:5353 # while it runs (configured by the fips-gateway init script). Requires IPv6 diff --git a/src/config/transport.rs b/src/config/transport.rs index 6bc3d380..b035b302 100644 --- a/src/config/transport.rs +++ b/src/config/transport.rs @@ -702,7 +702,7 @@ const DEFAULT_BLE_PROBE_COOLDOWN_SECS: u64 = 30; /// BLE transport instance configuration. /// /// BleConfig is always compiled (for config parsing on any platform), -/// but the transport runtime requires Linux and the `ble` feature. +/// but the transport runtime is compiled only for glibc Linux and Android. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct BleConfig { diff --git a/src/packaging_tests.rs b/src/packaging_tests.rs index 6716cac1..7812c7d1 100644 --- a/src/packaging_tests.rs +++ b/src/packaging_tests.rs @@ -188,6 +188,53 @@ fn case_branch(sh: &str, label: &str) -> Vec { lines[start..start + len].to_vec() } +/// Returns the feature names declared in the `[features]` table of a +/// Cargo.toml. +fn cargo_features(cargo_toml: &str) -> Vec { + toml_section(cargo_toml, "[features]") + .into_iter() + .map(str::trim) + .filter(|l| !l.is_empty() && !l.starts_with('#')) + .filter_map(|l| l.split_once('=').map(|(key, _)| key.trim().to_string())) + .collect() +} + +/// Returns the cargo feature names a config file's comments mention: on each +/// `#` comment line, the token before the word `feature` or `features` when +/// that token is wrapped in `'`, `"` or `` ` ``. +fn feature_mentions(text: &str) -> Vec { + let mut found = Vec::new(); + for line in text.lines().map(str::trim) { + if !line.starts_with('#') { + continue; + } + let words: Vec<&str> = line.split_whitespace().collect(); + for pair in words.windows(2) { + let word = pair[1].trim_end_matches(|c: char| c.is_ascii_punctuation()); + if word != "feature" && word != "features" { + continue; + } + let quoted = ['\'', '"', '`'].iter().find_map(|q| { + pair[0] + .strip_prefix(*q) + .and_then(|rest| rest.strip_suffix(*q)) + }); + if let Some(name) = quoted { + found.push(name.to_string()); + } + } + } + found +} + +/// Whether a config line, commented out or not, starts a `ble:` block. +fn is_ble_key(line: &str) -> bool { + line.trim() + .trim_start_matches('#') + .trim_start() + .starts_with("ble:") +} + #[test] fn deb_and_aur_packages_declare_nftables_for_the_firewall_units_nft() { let unit = repo_file("packaging/debian/fips-firewall.service"); @@ -758,3 +805,57 @@ fn windows_installer_icacls_calls_act_on_links_and_check_exit_codes() { ); } } + +const COMMON_CONFIG: &str = "packaging/common/fips.yaml"; +const OPENWRT_CONFIG: &str = "packaging/openwrt-ipk/files/etc/fips/fips.yaml"; + +#[test] +fn shipped_configs_name_only_cargo_features_that_exist() { + assert_eq!( + feature_mentions( + " # Bluetooth Low Energy transport — requires BlueZ and the 'ble' feature." + ), + ["ble"], + "control: the feature-mention scanner no longer finds a quoted feature name" + ); + let features = cargo_features(&repo_file("Cargo.toml")); + assert!( + features.iter().any(|f| f == "profiling"), + "control: expected the profiling feature in Cargo.toml [features], read {features:?}" + ); + + let mut unknown = Vec::new(); + for rel in [COMMON_CONFIG, OPENWRT_CONFIG] { + for name in feature_mentions(&repo_file(rel)) { + if !features.contains(&name) { + unknown.push(format!("{rel}: '{name}'")); + } + } + } + assert!( + unknown.is_empty(), + "shipped configs name cargo features that Cargo.toml does not define \ + (it defines {features:?}):\n {}", + unknown.join("\n ") + ); +} + +#[test] +fn openwrt_config_offers_no_ble_block_because_musl_builds_have_no_ble() { + assert!( + repo_file(COMMON_CONFIG).lines().any(is_ble_key), + "control: expected the ble: example in {COMMON_CONFIG}" + ); + let text = repo_file(OPENWRT_CONFIG); + let found: Vec<(usize, &str)> = text + .lines() + .enumerate() + .filter(|(_, l)| is_ble_key(l)) + .map(|(i, l)| (i + 1, l.trim_end())) + .collect(); + assert!( + found.is_empty(), + "{OPENWRT_CONFIG} offers a ble: block, but OpenWrt builds target musl, \ + where the BLE transport is not compiled: {found:?}" + ); +}