diff --git a/crates/tor-chanmgr/src/transport/proxied.rs b/crates/tor-chanmgr/src/transport/proxied.rs index ccb6fca6b..8845d09c8 100644 --- a/crates/tor-chanmgr/src/transport/proxied.rs +++ b/crates/tor-chanmgr/src/transport/proxied.rs @@ -278,6 +278,12 @@ impl TransportHelper for ExternalProxyPlugin { ))) } ChannelMethod::Pluggable(target) => target, + other => { + return Err(crate::Error::UnusableTarget(bad_api_usage!( + "Used unknown, unsupported, transport {:?} for a TCP connection.", + other, + ))) + } }; let protocol = settings_to_protocol(encode_settings(pt_target.settings()))?; diff --git a/crates/tor-guardmgr/src/bridge/config.rs b/crates/tor-guardmgr/src/bridge/config.rs index a0a52398e..f43d34715 100644 --- a/crates/tor-guardmgr/src/bridge/config.rs +++ b/crates/tor-guardmgr/src/bridge/config.rs @@ -76,7 +76,9 @@ struct Inner { /// Address and transport via which the bridge can be reached, and /// the parameters for those transports. /// - /// Restriction: This `addrs` may NOT contain more than one address. + /// Restriction: This `addrs` may NOT contain more than one address, + /// and it must be a variant supported by the code in this crate: + /// ie, currently, `Direct` or `Pluggable`. addrs: ChannelMethod, /// The RSA identity of the bridge. @@ -366,6 +368,11 @@ impl FromStr for BridgeConfigBuilder { let (transport, addr, settings) = target.into_parts(); (transport.into_inner(), vec![addr], settings.into_inner()) } + other => { + return Err(BridgeParseError::UnsupportedChannelMethod { + method: Box::new(other), + }); + } }; let ids = chain!( @@ -518,6 +525,7 @@ impl FromStr for Inner { source, } })?, + other => panic!("made ourselves an unsupported ChannelMethod {:?}", other), } } @@ -556,6 +564,12 @@ impl Display for BridgeConfig { write!(f, "{} {}", target.transport(), target.addr())?; Some(target.settings()) } + + _ => { + // This shouldn't happen, but panicking seems worse than outputting this + write!(f, "[unsupported channel method, cannot display properly]")?; + return Ok(()); + } }; // * One or more identity key fingerprints, diff --git a/crates/tor-guardmgr/src/bridge/config/err.rs b/crates/tor-guardmgr/src/bridge/config/err.rs index b06286bef..25ec0d97f 100644 --- a/crates/tor-guardmgr/src/bridge/config/err.rs +++ b/crates/tor-guardmgr/src/bridge/config/err.rs @@ -5,6 +5,8 @@ use thiserror::Error; +use tor_linkspec::ChannelMethod; + /// Error when parsing a bridge line from a string #[derive(Error, Clone, Debug)] #[non_exhaustive] @@ -94,6 +96,16 @@ pub enum BridgeParseError { word: String, }, + /// Channel method specified of unsupported type + /// + /// This can only occur with unusual (unsupported) combinations of cargo features, + /// or building an older `tor-guardmgr` against a newer `tor-linkspec`. + #[error("Channel method specified but not of supported type ({method:?})")] + UnsupportedChannelMethod { + /// The not-understood method + method: Box, + }, + /// Parameters may only be specified with a pluggable transport #[cfg(feature = "bridge-client")] #[error("Parameters supplied but not valid without a pluggable transport")] diff --git a/crates/tor-linkspec/semver.md b/crates/tor-linkspec/semver.md index 2484747e6..7522ee3bf 100644 --- a/crates/tor-linkspec/semver.md +++ b/crates/tor-linkspec/semver.md @@ -9,3 +9,4 @@ BREAKING: Replaced functions to strip addresses from ChanMethod. BREAKING: Remove impl Display for OwnedCircTarget. ADDED: Provide deconstructors for PtTargetSettings and PtTarget MODIFIED: Renaming PtTargetAddr to BridgeAddr (in progress, will become BREAKING) +BREAKING: ChannelMethod is now non-exhaustive diff --git a/crates/tor-linkspec/src/transport.rs b/crates/tor-linkspec/src/transport.rs index c62e754dd..679ddfd83 100644 --- a/crates/tor-linkspec/src/transport.rs +++ b/crates/tor-linkspec/src/transport.rs @@ -457,7 +457,7 @@ impl PtTarget { /// pluggable transport, this includes information about the transport, and any /// address and settings information that transport requires. #[derive(Clone, Debug, Eq, PartialEq, Hash)] -#[allow(clippy::exhaustive_enums)] +#[non_exhaustive] pub enum ChannelMethod { /// Connect to the relay directly at one of several addresses. Direct(Vec),