From af815d39e022f097182b8b83caef3c0517b0182b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ondrej=20Slint=C3=A1k?= Date: Tue, 31 Oct 2023 17:25:52 +0100 Subject: [PATCH 1/3] Add support for `native-tls` when using websocket transport --- rumqttc/src/eventloop.rs | 14 ++++++++++++-- rumqttc/src/lib.rs | 38 ++++++++++++++++++++++++++++++++----- rumqttc/src/v5/eventloop.rs | 13 +++++++++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/rumqttc/src/eventloop.rs b/rumqttc/src/eventloop.rs index e6d96861a..b0a762de8 100644 --- a/rumqttc/src/eventloop.rs +++ b/rumqttc/src/eventloop.rs @@ -360,7 +360,10 @@ async fn network_connect( let (domain, port) = match options.transport() { #[cfg(feature = "websocket")] Transport::Ws => split_url(&options.broker_addr)?, - #[cfg(all(feature = "use-rustls", feature = "websocket"))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] Transport::Wss(_) => split_url(&options.broker_addr)?, _ => options.broker_address(), }; @@ -407,14 +410,20 @@ async fn network_connect( Network::new(WsStream::new(socket), options.max_incoming_packet_size) } - #[cfg(all(feature = "use-rustls", feature = "websocket"))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] Transport::Wss(tls_config) => { let mut request = options.broker_addr.as_str().into_client_request()?; request .headers_mut() .insert("Sec-WebSocket-Protocol", "mqtt".parse().unwrap()); + #[cfg(feature = "use-rustls")] let connector = tls::rustls_connector(&tls_config).await?; + #[cfg(feature = "use-native-tls")] + let connector = tls::native_tls_connector(&tls_config).await?; let (socket, response) = async_tungstenite::tokio::client_async_tls_with_connector( request, @@ -422,6 +431,7 @@ async fn network_connect( Some(connector), ) .await?; + validate_response_headers(response)?; Network::new(WsStream::new(socket), options.max_incoming_packet_size) diff --git a/rumqttc/src/lib.rs b/rumqttc/src/lib.rs index f293c7223..c70bdafe2 100644 --- a/rumqttc/src/lib.rs +++ b/rumqttc/src/lib.rs @@ -240,7 +240,10 @@ pub enum Transport { #[cfg(feature = "websocket")] #[cfg_attr(docsrs, doc(cfg(feature = "websocket")))] Ws, - #[cfg(all(feature = "use-rustls", feature = "websocket"))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] #[cfg_attr(docsrs, doc(cfg(all(feature = "use-rustls", feature = "websocket"))))] Wss(TlsConfiguration), } @@ -312,14 +315,32 @@ impl Transport { Self::wss_with_config(config) } - #[cfg(all(feature = "use-rustls", feature = "websocket"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "use-rustls", feature = "websocket"))))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))) + )] pub fn wss_with_config(tls_config: TlsConfiguration) -> Self { Self::Wss(tls_config) } - #[cfg(all(feature = "use-rustls", feature = "websocket"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "use-rustls", feature = "websocket"))))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))) + )] pub fn wss_with_default_config() -> Self { Self::Wss(Default::default()) } @@ -370,6 +391,13 @@ impl Default for TlsConfiguration { } } +#[cfg(feature = "use-native-tls")] +impl Default for TlsConfiguration { + fn default() -> Self { + Self::Native + } +} + #[cfg(feature = "use-rustls")] impl From for TlsConfiguration { fn from(config: ClientConfig) -> Self { diff --git a/rumqttc/src/v5/eventloop.rs b/rumqttc/src/v5/eventloop.rs index fc15fa0d9..b44efbd5d 100644 --- a/rumqttc/src/v5/eventloop.rs +++ b/rumqttc/src/v5/eventloop.rs @@ -290,7 +290,10 @@ async fn network_connect(options: &MqttOptions) -> Result split_url(&options.broker_addr)?, - #[cfg(all(feature = "use-rustls", feature = "websocket"))] + #[cfg(all( + any(feature = "use-rustls", feature = "use-native-tls"), + feature = "websocket" + ))] Transport::Wss(_) => split_url(&options.broker_addr)?, _ => options.broker_address(), }; @@ -345,7 +348,10 @@ async fn network_connect(options: &MqttOptions) -> Result { let mut request = options.broker_addr.as_str().into_client_request()?; request @@ -356,7 +362,10 @@ async fn network_connect(options: &MqttOptions) -> Result Date: Thu, 7 Dec 2023 23:10:35 +0530 Subject: [PATCH 2/3] feat: turn on async-tungstenite features based feature flags --- Cargo.lock | 3 +++ rumqttc/Cargo.toml | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 603a78ada..5feaf770c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,9 +180,11 @@ dependencies = [ "futures-io", "futures-util", "log", + "native-tls", "pin-project-lite", "rustls-native-certs", "tokio", + "tokio-native-tls", "tokio-rustls", "tungstenite", ] @@ -2545,6 +2547,7 @@ dependencies = [ "http", "httparse", "log", + "native-tls", "rand", "rustls", "sha1", diff --git a/rumqttc/Cargo.toml b/rumqttc/Cargo.toml index 1a3e1f703..f97818121 100644 --- a/rumqttc/Cargo.toml +++ b/rumqttc/Cargo.toml @@ -17,8 +17,8 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["use-rustls"] -use-rustls = ["dep:tokio-rustls", "dep:rustls-webpki", "dep:rustls-pemfile", "dep:rustls-native-certs"] -use-native-tls = ["dep:tokio-native-tls", "dep:native-tls"] +use-rustls = ["dep:tokio-rustls", "dep:rustls-webpki", "dep:rustls-pemfile", "dep:rustls-native-certs", "async-tungstenite?/tokio-rustls-native-certs"] +use-native-tls = ["dep:tokio-native-tls", "dep:native-tls", "async-tungstenite?/tokio-native-tls"] websocket = ["dep:async-tungstenite", "dep:ws_stream_tungstenite", "dep:http"] proxy = ["dep:async-http-proxy"] @@ -37,7 +37,7 @@ rustls-webpki = { version = "0.101.6", optional = true } rustls-pemfile = { version = "1", optional = true } rustls-native-certs = { version = "0.6", optional = true } # websockets -async-tungstenite = { version = "0.23", default-features = false, features = ["tokio-rustls-native-certs"], optional = true } +async-tungstenite = { version = "0.23", default-features = false, features = ["tokio-runtime"], optional = true } ws_stream_tungstenite = { version= "0.11", default-features = false, features = ["tokio_io"], optional = true } http = { version = "0.2", optional = true } # native-tls From 346f39ca79cedd6c1ad6ada7b2608f52bd39e0aa Mon Sep 17 00:00:00 2001 From: swanandx <73115739+swanandx@users.noreply.github.com> Date: Thu, 7 Dec 2023 23:30:01 +0530 Subject: [PATCH 3/3] feat: enable tokio-rustls-webpki-roots as well --- Cargo.lock | 7 +++++++ rumqttc/Cargo.toml | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5feaf770c..835b68c6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,7 @@ dependencies = [ "tokio-native-tls", "tokio-rustls", "tungstenite", + "webpki-roots", ] [[package]] @@ -2727,6 +2728,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + [[package]] name = "which" version = "4.4.2" diff --git a/rumqttc/Cargo.toml b/rumqttc/Cargo.toml index f97818121..07e76957f 100644 --- a/rumqttc/Cargo.toml +++ b/rumqttc/Cargo.toml @@ -17,7 +17,8 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["use-rustls"] -use-rustls = ["dep:tokio-rustls", "dep:rustls-webpki", "dep:rustls-pemfile", "dep:rustls-native-certs", "async-tungstenite?/tokio-rustls-native-certs"] +use-rustls = ["dep:tokio-rustls", "dep:rustls-webpki", "dep:rustls-pemfile", "dep:rustls-native-certs", +"async-tungstenite?/tokio-rustls-webpki-roots", "async-tungstenite?/tokio-rustls-native-certs"] use-native-tls = ["dep:tokio-native-tls", "dep:native-tls", "async-tungstenite?/tokio-native-tls"] websocket = ["dep:async-tungstenite", "dep:ws_stream_tungstenite", "dep:http"] proxy = ["dep:async-http-proxy"]