Replace em dashes with hyphens across docs and comments
This commit is contained in:
+25
-25
@@ -4,19 +4,19 @@ use std::time::Duration;
|
||||
|
||||
use super::{GenericPrinter, PrinterBase, PrinterError};
|
||||
|
||||
/// Bambu's shared LAN-mode root CA ("BBL CA2 RSA") — see certs/README.md
|
||||
/// Bambu's shared LAN-mode root CA ("BBL CA2 RSA") - see certs/README.md
|
||||
/// for how this was obtained and verified. `include_bytes!` embeds it into
|
||||
/// the compiled binary at build time, so there's no file to ship alongside
|
||||
/// the executable.
|
||||
const BUNDLED_CA: &[u8] = include_bytes!("../../certs/bambu_ca2.pem");
|
||||
|
||||
/// Which certificate to trust when connecting to a Bambu printer's MQTTS
|
||||
/// port (8883 — Bambu's LAN mode is TLS-only, there's no unencrypted
|
||||
/// port (8883 - Bambu's LAN mode is TLS-only, there's no unencrypted
|
||||
/// fallback).
|
||||
pub enum BambuTls {
|
||||
/// Bambu's shared root CA. Correct for current-generation printers.
|
||||
BundledCa,
|
||||
/// A specific certificate instead — for a printer whose firmware
|
||||
/// A specific certificate instead - for a printer whose firmware
|
||||
/// doesn't chain to the shared CA (P1P, at least).
|
||||
Custom(Vec<u8>),
|
||||
/// Skip certificate verification entirely. The least safe option, only
|
||||
@@ -26,7 +26,7 @@ pub enum BambuTls {
|
||||
|
||||
impl BambuTls {
|
||||
/// Resolves the trust mode for *one* printer. Call this per printer,
|
||||
/// passing `config.bambu_ca_cert_overrides.get(printer_id)` — there's
|
||||
/// passing `config.bambu_ca_cert_overrides.get(printer_id)` - there's
|
||||
/// no single override for the whole fleet, because not every Bambu
|
||||
/// model chains to the same CA. `require_valid_cert = false` always
|
||||
/// means `Insecure`, regardless of whether that printer also has an
|
||||
@@ -41,7 +41,7 @@ impl BambuTls {
|
||||
}
|
||||
}
|
||||
|
||||
/// The CA certificate bytes to hand to the TLS layer — empty when
|
||||
/// The CA certificate bytes to hand to the TLS layer - empty when
|
||||
/// `Insecure`, since there's nothing to verify against.
|
||||
pub fn ca_bytes(&self) -> &[u8] {
|
||||
match self {
|
||||
@@ -57,12 +57,12 @@ impl BambuTls {
|
||||
let mut builder = native_tls::TlsConnector::builder();
|
||||
|
||||
// Bambu printer certificates don't carry their LAN IP as a Subject
|
||||
// Alternative Name — it's DHCP-assigned, so baking it in at
|
||||
// Alternative Name - it's DHCP-assigned, so baking it in at
|
||||
// manufacture time wouldn't make sense. Hostname verification has
|
||||
// to be off regardless of trust mode: what matters is whether the
|
||||
// certificate chains to a CA we trust, not whether its SAN matches
|
||||
// the specific IP we happened to dial today. Chain verification
|
||||
// itself stays fully enforced below for BundledCa/Custom — this
|
||||
// itself stays fully enforced below for BundledCa/Custom - this
|
||||
// narrows *what* gets checked, it doesn't turn checking off.
|
||||
builder.danger_accept_invalid_hostnames(true);
|
||||
|
||||
@@ -81,7 +81,7 @@ fn resolve_addr(host: &str) -> anyhow::Result<SocketAddr> {
|
||||
}
|
||||
|
||||
/// Minimal DER -> PEM encoder (base64, 64-char lines, standard
|
||||
/// header/footer) — just enough to save a fetched certificate in the same
|
||||
/// header/footer) - just enough to save a fetched certificate in the same
|
||||
/// format as the bundled one.
|
||||
fn der_to_pem(der: &[u8]) -> Vec<u8> {
|
||||
use base64::Engine;
|
||||
@@ -103,7 +103,7 @@ fn pem_to_der(pem: &[u8]) -> anyhow::Result<Vec<u8>> {
|
||||
}
|
||||
|
||||
/// Fields and behavior every Bambu printer shares, regardless of protocol
|
||||
/// generation — the layer between `GenericPrinter` and the version-specific
|
||||
/// generation - the layer between `GenericPrinter` and the version-specific
|
||||
/// `BambuV1Printer`/`BambuV2Printer` leaves below. Those two *have* one of
|
||||
/// these (composition) rather than a deeper inheritance chain; because
|
||||
/// Rust's field/method privacy is scoped to the *module* (this whole file),
|
||||
@@ -131,22 +131,22 @@ impl BambuGenericPrinter {
|
||||
&self.base
|
||||
}
|
||||
|
||||
/// Not part of the `GenericPrinter` trait — Prusa/Klipper have no
|
||||
/// Not part of the `GenericPrinter` trait - Prusa/Klipper have no
|
||||
/// equivalent, since FTPS gcode transfer is a Bambu-specific thing.
|
||||
pub fn dispatch_gcode(&self, file_name: &str) {
|
||||
println!("[{}] uploading {file_name} over FTPS", self.base.name);
|
||||
}
|
||||
|
||||
/// A real (blocking, one-shot) TLS handshake to port 8883 — no MQTT
|
||||
/// A real (blocking, one-shot) TLS handshake to port 8883 - no MQTT
|
||||
/// protocol, just "does the certificate verify" against this printer's
|
||||
/// configured trust mode.
|
||||
///
|
||||
/// `BundledCa` verifies normally (Bambu's shared CA is a proper,
|
||||
/// well-formed root — OpenSSL's usual chain validation handles it
|
||||
/// well-formed root - OpenSSL's usual chain validation handles it
|
||||
/// fine). `Custom` does something different: *fingerprint pinning*,
|
||||
/// not chain validation. A device's own leaf certificate often isn't a
|
||||
/// well-formed CA (no `CA:TRUE`), and the device may present it
|
||||
/// alongside a separate self-signed root you never captured — asking
|
||||
/// alongside a separate self-signed root you never captured - asking
|
||||
/// OpenSSL's normal path-building to accept an arbitrary leaf as a
|
||||
/// trust anchor is unreliable for exactly that reason (this is a real
|
||||
/// bug that shipped and failed against a real P1P: `add_root_certificate`
|
||||
@@ -154,7 +154,7 @@ impl BambuGenericPrinter {
|
||||
/// certificate chain` / `unable to get local issuer certificate` on
|
||||
/// the very next connection). So instead: connect with verification
|
||||
/// off, then compare the certificate actually presented against the
|
||||
/// exact bytes pinned, byte for byte. A mismatch is a hard failure —
|
||||
/// exact bytes pinned, byte for byte. A mismatch is a hard failure -
|
||||
/// no PKI judgment call, just "is this the same certificate as before."
|
||||
pub fn test_tls_handshake(&self) -> anyhow::Result<()> {
|
||||
let addr = resolve_addr(&self.base.host)?;
|
||||
@@ -169,7 +169,7 @@ impl BambuGenericPrinter {
|
||||
|
||||
if presented != pem_to_der(pinned_pem)? {
|
||||
anyhow::bail!(
|
||||
"{} presented a certificate different from the one pinned — could be a legitimate \
|
||||
"{} presented a certificate different from the one pinned - could be a legitimate \
|
||||
certificate rotation, could be something worse; re-run fetch_bambu_cert deliberately \
|
||||
if you're sure it's the former",
|
||||
self.base.name
|
||||
@@ -187,7 +187,7 @@ impl BambuGenericPrinter {
|
||||
/// presents, and returns it as PEM bytes.
|
||||
///
|
||||
/// This is meaningfully weaker than verifying against a CA you already
|
||||
/// trust — anyone on the network at the exact moment you run this gets
|
||||
/// trust - anyone on the network at the exact moment you run this gets
|
||||
/// trusted forever after. That's why it's a method you call once, by
|
||||
/// hand (see `examples/fetch_bambu_cert.rs`), rather than something
|
||||
/// `connect()` falls back to silently. Save the result to a file and
|
||||
@@ -205,15 +205,15 @@ impl BambuGenericPrinter {
|
||||
}
|
||||
|
||||
/// Makes sure this printer has a *working* trust configuration,
|
||||
/// auto-pinning a certificate via trust-on-first-connect if needed —
|
||||
/// auto-pinning a certificate via trust-on-first-connect if needed -
|
||||
/// the "smooth, no manual steps" version of the fetch_bambu_cert
|
||||
/// workflow, built the way SSH handles host keys:
|
||||
///
|
||||
/// - A pinned certificate already on disk (`cert_dir/<sn>.pem`) is used
|
||||
/// directly. No new trust decision gets made on every run — that
|
||||
/// directly. No new trust decision gets made on every run - that
|
||||
/// already happened once, this just re-verifies against it. Keyed by
|
||||
/// *serial number*, not `id`: `id` is just an arbitrary label you
|
||||
/// picked in printers.toml — rename a printer's `id` and the pin
|
||||
/// picked in printers.toml - rename a printer's `id` and the pin
|
||||
/// should still find it, because a pin certifies "this physical
|
||||
/// printer", and the serial number is the one thing about it that
|
||||
/// can't change.
|
||||
@@ -224,10 +224,10 @@ impl BambuGenericPrinter {
|
||||
/// produces a working connection, and saves it to `cert_dir/<sn>.pem`
|
||||
/// for every run after this one. This is the one moment a MITM
|
||||
/// active on your network *right now* could plant a certificate that
|
||||
/// gets trusted from then on — the same tradeoff SSH accepts on a
|
||||
/// gets trusted from then on - the same tradeoff SSH accepts on a
|
||||
/// first connection.
|
||||
/// - A printer with an *explicit* pin (you set `ca_cert_path` yourself
|
||||
/// in printers.toml) never auto-pins over it — a verification
|
||||
/// in printers.toml) never auto-pins over it - a verification
|
||||
/// failure there is a real error, not something to paper over,
|
||||
/// since that's exactly the signal pinning exists to give you (the
|
||||
/// cert rotated, or something worse).
|
||||
@@ -252,7 +252,7 @@ impl BambuGenericPrinter {
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared by both `BambuV1Printer` and `BambuV2Printer` — same MQTT
|
||||
/// Shared by both `BambuV1Printer` and `BambuV2Printer` - same MQTT
|
||||
/// gcode-injection mechanism regardless of protocol generation. Real
|
||||
/// version would publish
|
||||
/// `{"print":{"command":"gcode_line","param":"M106 P1 S<pwm>"}}` to
|
||||
@@ -263,7 +263,7 @@ impl BambuGenericPrinter {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Shared "connect" logic both V1 and V2 delegate to — the real
|
||||
/// Shared "connect" logic both V1 and V2 delegate to - the real
|
||||
/// version would open the MQTTS session here. Still a stub, but no
|
||||
/// longer duplicated across two structs.
|
||||
async fn connect_impl(&mut self) -> Result<(), PrinterError> {
|
||||
@@ -278,7 +278,7 @@ impl BambuGenericPrinter {
|
||||
}
|
||||
|
||||
/// Older Bambu MQTT report schema (P1P, P1S, original X1 firmware).
|
||||
/// No V1-only fields yet — add them here as you learn what differs.
|
||||
/// No V1-only fields yet - add them here as you learn what differs.
|
||||
pub struct BambuV1Printer {
|
||||
generic: BambuGenericPrinter,
|
||||
}
|
||||
@@ -320,7 +320,7 @@ impl GenericPrinter for BambuV1Printer {
|
||||
}
|
||||
|
||||
/// Current-generation Bambu MQTT report schema (X1 Carbon/X1E, H2 series).
|
||||
/// No V2-only fields yet (e.g. AMS slot state) — add them here as you build
|
||||
/// No V2-only fields yet (e.g. AMS slot state) - add them here as you build
|
||||
/// out real report parsing.
|
||||
pub struct BambuV2Printer {
|
||||
generic: BambuGenericPrinter,
|
||||
|
||||
Reference in New Issue
Block a user