From 4e9e18444c56e8d4a71d389d8b28bca82813f52c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=A4fer?= Date: Sat, 10 May 2025 09:54:01 +0200 Subject: [PATCH] Avoid enabling multiple rustls backends by accident For this, we had to: - Make the choice(s) of backend explicit in tokio-xmpp features - Avoid picking a backend through transitive dependencies in xmpp (reqwest->hyper->rustls). In addition, we choose the default rustls backend by default and adapt the examples so that they can cope with either situation. --- tokio-xmpp/Cargo.toml | 6 ++++-- tokio-xmpp/ChangeLog | 7 +++++++ tokio-xmpp/examples/contact_addr.rs | 18 ++++++++++++++++-- tokio-xmpp/examples/download_avatars.rs | 18 ++++++++++++++++-- tokio-xmpp/examples/echo_bot.rs | 18 ++++++++++++++++-- tokio-xmpp/examples/echo_component.rs | 18 ++++++++++++++++-- tokio-xmpp/examples/echo_server.rs | 17 +++++++++++++++-- tokio-xmpp/examples/keep_connection.rs | 17 +++++++++++++++-- xmpp/Cargo.toml | 4 +++- xmpp/ChangeLog | 7 +++++++ xmpp/examples/hello_bot.rs | 19 +++++++++++++++++++ 11 files changed, 134 insertions(+), 15 deletions(-) diff --git a/tokio-xmpp/Cargo.toml b/tokio-xmpp/Cargo.toml index e8d79d67a6a60b0a02146f46d493c535a2eeda5b..26d7ef18aa99dca4842b53274da875c30106840b 100644 --- a/tokio-xmpp/Cargo.toml +++ b/tokio-xmpp/Cargo.toml @@ -33,7 +33,7 @@ hickory-resolver = { version = "0.24", optional = true} idna = { version = "1.0", optional = true} native-tls = { version = "0.2", optional = true } tokio-native-tls = { version = "0.3", optional = true } -tokio-rustls = { version = "0.26", optional = true } +tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["logging", "tls12"] } ktls = { version = "6", optional = true } [dev-dependencies] @@ -43,9 +43,11 @@ tokio = { version = "1", features = ["signal", "test-util"] } tokio-xmpp = { path = ".", features = ["insecure-tcp"]} [features] -default = ["starttls-rust", "rustls-native-certs"] +default = ["starttls-rust", "rustls-native-certs", "tls-rust-aws_lc_rs"] starttls = ["dns"] tls-rust = ["tokio-rustls"] +tls-rust-aws_lc_rs = ["tokio-rustls?/aws_lc_rs"] +tls-rust-ring = ["tokio-rustls?/ring"] tls-rust-ktls = ["tls-rust", "ktls"] tls-rust-native-certs = ["tls-rust", "rustls-native-certs"] tls-rust-webpki-roots = ["tls-rust", "webpki-roots"] diff --git a/tokio-xmpp/ChangeLog b/tokio-xmpp/ChangeLog index e3c10152d92f2c3f301ac104474ecbb1193311c8..bb249cefc1815713a387af4d54b81a7a4559c6c6 100644 --- a/tokio-xmpp/ChangeLog +++ b/tokio-xmpp/ChangeLog @@ -25,6 +25,13 @@ XXXX-YY-ZZ RELEASER - `Component` is now gated behind `insecure-tcp` feature flag - `XMPPStream` and `XmppCodec` were removed in favour of the newly implemented `tokio_xmpp::xmlstream module. + - The `starttls-rust`, `tls-rust` and `tls-rust-ktls` feature flags do + not automatically enable a `rustls` crypto provider anymore. This is + to avoid conflict between two crypto providers and to avoid linking + unnecessary code. The `aws_lc_rs` crypto provider is still built by + default, however, applications which use `tokio_xmpp` without default + features will have to adapt their feature flags to explicitly enable + the `tls-rust-aws_lc_rs` or `tls-rust-ring` features. (!581) * Added: - Support for sending IQ requests while tracking their responses in a Future. diff --git a/tokio-xmpp/examples/contact_addr.rs b/tokio-xmpp/examples/contact_addr.rs index 0b9bc9ac5c3cb47d4f0bf56005add6fe07f06513..1171dece3828a68afc2bf979dbd3aa3c54dfff5b 100644 --- a/tokio-xmpp/examples/contact_addr.rs +++ b/tokio-xmpp/examples/contact_addr.rs @@ -2,7 +2,12 @@ use futures::stream::StreamExt; use std::env::args; use std::process::exit; use std::str::FromStr; -use tokio_xmpp::{rustls, Client, IqRequest, IqResponse}; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; +use tokio_xmpp::{Client, IqRequest, IqResponse}; use xmpp_parsers::{ disco::{DiscoInfoQuery, DiscoInfoResult}, jid::{BareJid, Jid}, @@ -14,11 +19,20 @@ use xmpp_parsers::{ async fn main() { env_logger::init(); - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() != 4 { println!("Usage: {} ", args[0]); diff --git a/tokio-xmpp/examples/download_avatars.rs b/tokio-xmpp/examples/download_avatars.rs index 25d714e85c9fe425cfa2331c85fd3fa920036a98..aa6da1defed6936ee75c1113ad561efb8051dcda 100644 --- a/tokio-xmpp/examples/download_avatars.rs +++ b/tokio-xmpp/examples/download_avatars.rs @@ -4,7 +4,12 @@ use std::fs::{create_dir_all, File}; use std::io::{self, Write}; use std::process::exit; use std::str::FromStr; -use tokio_xmpp::{rustls, Client, Stanza}; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; +use tokio_xmpp::{Client, Stanza}; use xmpp_parsers::{ avatar::{Data as AvatarData, Metadata as AvatarMetadata}, caps::{compute_disco, hash_caps, Caps}, @@ -26,11 +31,20 @@ use xmpp_parsers::{ async fn main() { env_logger::init(); - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() != 3 { println!("Usage: {} ", args[0]); diff --git a/tokio-xmpp/examples/echo_bot.rs b/tokio-xmpp/examples/echo_bot.rs index 45c4b1d7025b3ec611b279da0009ca52b48477a5..bff3f4d0cd8477f8acc49652c248f91c64e7dca6 100644 --- a/tokio-xmpp/examples/echo_bot.rs +++ b/tokio-xmpp/examples/echo_bot.rs @@ -2,7 +2,12 @@ use futures::stream::StreamExt; use std::env::args; use std::process::exit; use std::str::FromStr; -use tokio_xmpp::{rustls, Client}; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; +use tokio_xmpp::Client; use xmpp_parsers::jid::{BareJid, Jid}; use xmpp_parsers::message::{Lang, Message, MessageType}; use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType}; @@ -11,11 +16,20 @@ use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceTyp async fn main() { env_logger::init(); - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() != 3 { println!("Usage: {} ", args[0]); diff --git a/tokio-xmpp/examples/echo_component.rs b/tokio-xmpp/examples/echo_component.rs index ff43758f766e2adc0835586a8442c02b201996b1..43c601daafd4a108ffe4d6f70f129b5dfcee787e 100644 --- a/tokio-xmpp/examples/echo_component.rs +++ b/tokio-xmpp/examples/echo_component.rs @@ -6,17 +6,31 @@ use xmpp_parsers::jid::Jid; use xmpp_parsers::message::{Lang, Message, MessageType}; use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType}; -use tokio_xmpp::{connect::DnsConfig, rustls, Component}; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; +use tokio_xmpp::{connect::DnsConfig, Component}; #[tokio::main] async fn main() { env_logger::init(); - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() < 3 || args.len() > 4 { println!("Usage: {} [server:port]", args[0]); diff --git a/tokio-xmpp/examples/echo_server.rs b/tokio-xmpp/examples/echo_server.rs index a4729d1b942bcb97b0f053f4f09aa28a508b0e65..6a5ee89d899c1330998febe09726a38dbe07df5f 100644 --- a/tokio-xmpp/examples/echo_server.rs +++ b/tokio-xmpp/examples/echo_server.rs @@ -1,20 +1,33 @@ use futures::{SinkExt, StreamExt}; use tokio::{self, io, net::TcpSocket}; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; use tokio_xmpp::{ minidom::Element, parsers::stream_features::StreamFeatures, - rustls, xmlstream::{accept_stream, StreamHeader, Timeouts}, }; #[tokio::main] async fn main() -> Result<(), io::Error> { - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + // TCP socket let address = "127.0.0.1:5222".parse().unwrap(); let socket = TcpSocket::new_v4()?; diff --git a/tokio-xmpp/examples/keep_connection.rs b/tokio-xmpp/examples/keep_connection.rs index 8ba77250537a39a4221257cf61b71af2ec341474..18d1841552485b2360eee07ad7ad79acec1f8c23 100644 --- a/tokio-xmpp/examples/keep_connection.rs +++ b/tokio-xmpp/examples/keep_connection.rs @@ -19,6 +19,11 @@ use rand::{thread_rng, Rng}; use futures::StreamExt; +#[cfg(all( + feature = "tls-rust", + any(feature = "tls-rust-aws_lc_rs", feature = "tls-rust-ring") +))] +use tokio_xmpp::rustls; use tokio_xmpp::{ connect::{DnsConfig, StartTlsServerConnector}, parsers::{ @@ -26,7 +31,6 @@ use tokio_xmpp::{ jid::{BareJid, Jid}, ping, }, - rustls, stanzastream::StanzaStream, xmlstream::Timeouts, }; @@ -35,11 +39,20 @@ use tokio_xmpp::{ async fn main() { env_logger::init(); - #[cfg(feature = "tls-rust")] + #[cfg(all(feature = "tls-rust", feature = "tls-rust-aws_lc_rs"))] rustls::crypto::aws_lc_rs::default_provider() .install_default() .expect("failed to install rustls crypto provider"); + #[cfg(all( + feature = "tls-rust", + feature = "tls-rust-ring", + not(feature = "tls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() != 3 { println!("Usage: {} ", args[0]); diff --git a/xmpp/Cargo.toml b/xmpp/Cargo.toml index 7d75069ab92cff917383ade593887f28c261d3de..0732cbc477576d580f2a045fb2057cf0c517e4b2 100644 --- a/xmpp/Cargo.toml +++ b/xmpp/Cargo.toml @@ -33,7 +33,9 @@ required-features = ["avatars"] [features] default = ["avatars", "starttls-rust"] starttls-native = ["tokio-xmpp/starttls", "tokio-xmpp/tls-native", "reqwest/native-tls"] -starttls-rust = ["tokio-xmpp/starttls", "tokio-xmpp/tls-rust", "reqwest/rustls-tls"] +starttls-rust = ["tokio-xmpp/starttls", "tokio-xmpp/tls-rust", "reqwest/rustls-tls-no-provider", "tokio-xmpp/tls-rust-webpki-roots"] +starttls-rust-aws_lc_rs = ["tokio-xmpp/tls-rust-aws_lc_rs", "starttls-rust"] +starttls-rust-ring = ["tokio-xmpp/tls-rust-ring", "starttls-rust"] avatars = [] escape-hatch = [] syntax-highlighting = [ "tokio-xmpp/syntax-highlighting" ] diff --git a/xmpp/ChangeLog b/xmpp/ChangeLog index 4202c29bd1c6c35bccafa6b23e588ae9ac0260ff..33236c7bfb2d7ce8ea8d9fa8aed3d6a8534ee8bf 100644 --- a/xmpp/ChangeLog +++ b/xmpp/ChangeLog @@ -15,6 +15,13 @@ XXXX-YY-ZZ [ RELEASER ] - Agent::send_room_private_message now takes RoomPrivateMessageSettings (!487) - Event now exposes Option for incoming messages, and MessageId for incoming message corrections; type alias Id has been removed (!504) + - The `starttls-rust` feature flag does not automatically enable a + `rustls` crypto provider anymore. This is to avoid conflict between + two crypto providers and to avoid linking unnecessary code. The + `aws_lc_rs` crypto provider is still built by default, however, + applications which use `xmpp` without default features will have to + adapt their feature flags to explicitly enable the + `starttls-rust-aws_lc_rs` or `starttls-rust-ring` features. (!581) * Added: - Agent::send_room_message takes RoomMessageSettings argument (!483) - Agent::send_raw_message takes RawMessageSettings for any message type (!487) diff --git a/xmpp/examples/hello_bot.rs b/xmpp/examples/hello_bot.rs index e826ebb5bb5ec35bcde120b8454ff84fdfb20563..8cc00c6e53b94e56d72a7eb7f7f15160ef78a40f 100644 --- a/xmpp/examples/hello_bot.rs +++ b/xmpp/examples/hello_bot.rs @@ -4,6 +4,11 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#[cfg(all( + feature = "starttls-rust", + any(feature = "starttls-rust-aws_lc_rs", feature = "starttls-rust-ring") +))] +use xmpp::tokio_xmpp::rustls; use xmpp::{ jid::BareJid, muc::room::{JoinRoomSettings, RoomMessageSettings}, @@ -19,6 +24,20 @@ use std::str::FromStr; async fn main() -> Result<(), Option<()>> { env_logger::init(); + #[cfg(all(feature = "starttls-rust", feature = "starttls-rust-aws_lc_rs"))] + rustls::crypto::aws_lc_rs::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + + #[cfg(all( + feature = "starttls-rust", + feature = "starttls-rust-ring", + not(feature = "starttls-rust-aws_lc_rs") + ))] + rustls::crypto::ring::default_provider() + .install_default() + .expect("failed to install rustls crypto provider"); + let args: Vec = args().collect(); if args.len() < 3 { println!("Usage: {} [ROOM...]", args[0]);