diff --git a/crates/tor-socksproto/semver.md b/crates/tor-socksproto/semver.md new file mode 100644 index 000000000..01bd85d0d --- /dev/null +++ b/crates/tor-socksproto/semver.md @@ -0,0 +1 @@ +BREAKING: changes to Error type. diff --git a/crates/tor-socksproto/src/err.rs b/crates/tor-socksproto/src/err.rs index 3f90ab7ad..57faa287a 100644 --- a/crates/tor-socksproto/src/err.rs +++ b/crates/tor-socksproto/src/err.rs @@ -1,4 +1,6 @@ //! Declare an error type for tor_socksproto +use std::borrow::Cow; + use thiserror::Error; use tor_error::{ErrorKind, HasKind}; @@ -14,7 +16,7 @@ pub enum Error { Syntax, /// Failed to decode a SOCKS message. - #[error("Error decoding message")] + #[error("Error decoding SOCKS message")] Decode(#[from] tor_bytes::Error), /// The SOCKS client declared a SOCKS version number that isn't @@ -27,8 +29,8 @@ pub enum Error { /// The SOCKS client tried to use a SOCKS feature that we don't /// support at all. - #[error("SOCKS feature not implemented")] - NotImplemented, + #[error("SOCKS feature ({0}) not implemented")] + NotImplemented(Cow<'static, str>), /// Tried to progress the SOCKS handshake when it was already /// finished. This is a programming error. @@ -54,7 +56,7 @@ impl HasKind for Error { EK::Internal } E::Syntax | E::Decode(_) | E::BadProtocol(_) => EK::LocalProtocolViolation, - E::NotImplemented => EK::NotImplemented, + E::NotImplemented(_) => EK::NotImplemented, E::AlreadyFinished(e) => e.kind(), E::Bug(e) => e.kind(), } diff --git a/crates/tor-socksproto/src/handshake.rs b/crates/tor-socksproto/src/handshake.rs index 5bbf4ec6d..5d419f4f7 100644 --- a/crates/tor-socksproto/src/handshake.rs +++ b/crates/tor-socksproto/src/handshake.rs @@ -173,7 +173,7 @@ impl SocksHandshake { (State::Socks5Wait, [5, NO_AUTHENTICATION]) } else { // In theory we should reply with "NO ACCEPTABLE METHODS". - return Err(Error::NotImplemented); + return Err(Error::NotImplemented("authentication methods".into())); }; self.state = next; @@ -190,7 +190,9 @@ impl SocksHandshake { let ver = r.take_u8()?; if ver != 1 { - return Err(Error::NotImplemented); + return Err(Error::NotImplemented( + format!("username/password version {}", ver).into(), + )); } let ulen = r.take_u8()?; @@ -437,7 +439,7 @@ mod test { fn socks5_init_nothing_works() { let mut h = SocksHandshake::new(); let a = h.handshake(&hex!("05 02 9988")[..]); - assert!(matches!(a, Ok(Err(Error::NotImplemented)))); + assert!(matches!(a, Ok(Err(Error::NotImplemented(_))))); } #[test] diff --git a/crates/tor-socksproto/src/msg.rs b/crates/tor-socksproto/src/msg.rs index 8a0a9790e..9d4e742cf 100644 --- a/crates/tor-socksproto/src/msg.rs +++ b/crates/tor-socksproto/src/msg.rs @@ -186,7 +186,9 @@ impl SocksRequest { auth: SocksAuth, ) -> Result { if !cmd.recognized() { - return Err(Error::NotImplemented); + return Err(Error::NotImplemented( + format!("SOCKS command {}", cmd).into(), + )); } if port == 0 && cmd.requires_port() { return Err(Error::Syntax); @@ -283,7 +285,7 @@ mod test { 1024, SocksAuth::NoAuth, ); - assert!(matches!(e, Err(Error::NotImplemented))); + assert!(matches!(e, Err(Error::NotImplemented(_)))); let e = SocksRequest::new( SocksVersion::V4,