From d31490a2a9c7e8a0fb3811a8aebb926547c5558f Mon Sep 17 00:00:00 2001 From: Paolo Barbolini Date: Fri, 2 May 2025 07:20:20 +0200 Subject: [PATCH] Make this all internal only for now --- examples/smtp_selfsigned.rs | 9 +-- src/transport/smtp/client/mod.rs | 10 ++-- src/transport/smtp/client/tls/boring_tls.rs | 14 ++--- .../client/tls/{deprecated.rs => current.rs} | 43 +------------- src/transport/smtp/client/tls/mod.rs | 56 ++++++++++--------- src/transport/smtp/client/tls/native_tls.rs | 14 ++--- src/transport/smtp/client/tls/rustls.rs | 24 +++++--- src/transport/smtp/mod.rs | 13 ++--- 8 files changed, 72 insertions(+), 111 deletions(-) rename src/transport/smtp/client/tls/{deprecated.rs => current.rs} (94%) diff --git a/examples/smtp_selfsigned.rs b/examples/smtp_selfsigned.rs index 67779d1..f45ec42 100644 --- a/examples/smtp_selfsigned.rs +++ b/examples/smtp_selfsigned.rs @@ -4,10 +4,7 @@ use lettre::{ message::header::ContentType, transport::smtp::{ authentication::Credentials, - client::{ - tls::{native_tls::Certificate, NativeTls, TlsParametersBuilder}, - Tls, - }, + client::{Certificate, Tls, TlsParameters}, }, Message, SmtpTransport, Transport, }; @@ -27,9 +24,9 @@ fn main() { // Use a custom certificate stored on disk to securely verify the server's certificate let pem_cert = fs::read("certificate.pem").unwrap(); let cert = Certificate::from_pem(&pem_cert).unwrap(); - let tls = TlsParametersBuilder::::new("smtp.server.com".to_owned()) + let tls = TlsParameters::builder("smtp.server.com".to_owned()) .add_root_certificate(cert) - .build_legacy() + .build() .unwrap(); let creds = Credentials::new("smtp_username".to_owned(), "smtp_password".to_owned()); diff --git a/src/transport/smtp/client/mod.rs b/src/transport/smtp/client/mod.rs index bd79d64..a01b7b7 100644 --- a/src/transport/smtp/client/mod.rs +++ b/src/transport/smtp/client/mod.rs @@ -34,14 +34,12 @@ pub use self::async_net::AsyncNetworkStream; pub use self::async_net::AsyncTokioStream; use self::net::NetworkStream; #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] -pub(super) use self::tls::deprecated::InnerTlsParameters; +pub(super) use self::tls::current::InnerTlsParameters; #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] -#[allow(deprecated)] -pub use self::tls::deprecated::TlsVersion; -#[allow(deprecated)] +pub use self::tls::current::TlsVersion; pub use self::{ connection::SmtpConnection, - tls::deprecated::{Certificate, Identity, Tls, TlsParameters, TlsParametersBuilder}, + tls::current::{Certificate, Identity, Tls, TlsParameters, TlsParametersBuilder}, }; #[cfg(any(feature = "tokio1", feature = "async-std1"))] @@ -50,7 +48,7 @@ mod async_connection; mod async_net; mod connection; mod net; -pub mod tls; +mod tls; /// The codec used for transparency #[derive(Debug)] diff --git a/src/transport/smtp/client/tls/boring_tls.rs b/src/transport/smtp/client/tls/boring_tls.rs index 7fabce1..4e92eba 100644 --- a/src/transport/smtp/client/tls/boring_tls.rs +++ b/src/transport/smtp/client/tls/boring_tls.rs @@ -55,21 +55,21 @@ pub(super) fn build_connector( #[derive(Debug, Clone, Default)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub enum CertificateStore { +pub(super) enum CertificateStore { #[default] System, None, } #[derive(Clone)] -pub struct Certificate(pub(super) boring::x509::X509); +pub(super) struct Certificate(pub(super) boring::x509::X509); impl Certificate { - pub fn from_pem(pem: &[u8]) -> Result { + pub(super) fn from_pem(pem: &[u8]) -> Result { Ok(Self(boring::x509::X509::from_pem(pem).map_err(error::tls)?)) } - pub fn from_der(der: &[u8]) -> Result { + pub(super) fn from_der(der: &[u8]) -> Result { Ok(Self(boring::x509::X509::from_der(der).map_err(error::tls)?)) } } @@ -81,13 +81,13 @@ impl Debug for Certificate { } #[derive(Clone)] -pub struct Identity { +pub(super) struct Identity { pub(super) chain: boring::x509::X509, pub(super) key: boring::pkey::PKey, } impl Identity { - pub fn from_pem(pem: &[u8], key: &[u8]) -> Result { + pub(super) fn from_pem(pem: &[u8], key: &[u8]) -> Result { let chain = boring::x509::X509::from_pem(pem).map_err(error::tls)?; let key = boring::pkey::PKey::private_key_from_pem(key).map_err(error::tls)?; Ok(Self { chain, key }) @@ -102,7 +102,7 @@ impl Debug for Identity { #[derive(Debug, Copy, Clone, Default)] #[non_exhaustive] -pub enum MinTlsVersion { +pub(super) enum MinTlsVersion { Tlsv10, Tlsv11, #[default] diff --git a/src/transport/smtp/client/tls/deprecated.rs b/src/transport/smtp/client/tls/current.rs similarity index 94% rename from src/transport/smtp/client/tls/deprecated.rs rename to src/transport/smtp/client/tls/current.rs index 14989f5..8166012 100644 --- a/src/transport/smtp/client/tls/deprecated.rs +++ b/src/transport/smtp/client/tls/current.rs @@ -7,7 +7,6 @@ use crate::transport::smtp::{error, Error}; #[derive(Debug, Copy, Clone)] #[non_exhaustive] #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] -#[deprecated] pub enum TlsVersion { /// TLS 1.0 /// @@ -120,8 +119,6 @@ impl Debug for Tls { /// Source for the base set of root certificates to trust. #[allow(missing_copy_implementations)] #[derive(Clone, Debug, Default)] -#[deprecated] -#[allow(deprecated)] pub enum CertificateStore { /// Use the default for the TLS backend. /// @@ -153,29 +150,22 @@ pub struct TlsParameters { /// Builder for `TlsParameters` #[derive(Debug, Clone)] -#[deprecated] pub struct TlsParametersBuilder { domain: String, - #[allow(deprecated)] cert_store: CertificateStore, - #[allow(deprecated)] root_certs: Vec, - #[allow(deprecated)] identity: Option, accept_invalid_hostnames: bool, accept_invalid_certs: bool, #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] - #[allow(deprecated)] min_tls_version: TlsVersion, } -#[allow(deprecated)] impl TlsParametersBuilder { /// Creates a new builder for `TlsParameters` pub fn new(domain: String) -> Self { Self { domain, - #[allow(deprecated)] cert_store: CertificateStore::Default, root_certs: Vec::new(), identity: None, @@ -187,8 +177,6 @@ impl TlsParametersBuilder { } /// Set the source for the base set of root certificates to trust. - #[deprecated] - #[allow(deprecated)] pub fn certificate_store(mut self, cert_store: CertificateStore) -> Self { self.cert_store = cert_store; self @@ -272,7 +260,6 @@ impl TlsParametersBuilder { docsrs, doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))) )] - #[deprecated] pub fn build(self) -> Result { #[cfg(feature = "rustls")] return self.build_rustls(); @@ -286,7 +273,6 @@ impl TlsParametersBuilder { #[cfg(feature = "native-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] pub fn build_native(self) -> Result { - #[allow(deprecated)] let cert_store = match self.cert_store { CertificateStore::Default => super::native_tls::CertificateStore::System, CertificateStore::None => super::native_tls::CertificateStore::None, @@ -330,7 +316,6 @@ impl TlsParametersBuilder { #[cfg(feature = "boring-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "boring-tls")))] pub fn build_boring(self) -> Result { - #[allow(deprecated)] let cert_store = match self.cert_store { CertificateStore::Default => super::boring_tls::CertificateStore::System, CertificateStore::None => super::boring_tls::CertificateStore::None, @@ -367,7 +352,6 @@ impl TlsParametersBuilder { #[cfg(feature = "rustls")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))] pub fn build_rustls(self) -> Result { - #[allow(deprecated)] let cert_store = match self.cert_store { #[cfg(feature = "rustls-native-certs")] CertificateStore::Default => super::rustls::CertificateStore::NativeCerts, @@ -430,14 +414,11 @@ impl TlsParameters { docsrs, doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))) )] - #[allow(deprecated)] pub fn new(domain: String) -> Result { TlsParametersBuilder::new(domain).build() } /// Creates a new `TlsParameters` builder - #[deprecated] - #[allow(deprecated)] pub fn builder(domain: String) -> TlsParametersBuilder { TlsParametersBuilder::new(domain) } @@ -445,8 +426,6 @@ impl TlsParameters { /// Creates a new `TlsParameters` using native-tls #[cfg(feature = "native-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] - #[deprecated] - #[allow(deprecated)] pub fn new_native(domain: String) -> Result { TlsParametersBuilder::new(domain).build_native() } @@ -454,8 +433,6 @@ impl TlsParameters { /// Creates a new `TlsParameters` using rustls #[cfg(feature = "rustls")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))] - #[deprecated] - #[allow(deprecated)] pub fn new_rustls(domain: String) -> Result { TlsParametersBuilder::new(domain).build_rustls() } @@ -463,8 +440,6 @@ impl TlsParameters { /// Creates a new `TlsParameters` using boring #[cfg(feature = "boring-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "boring-tls")))] - #[deprecated] - #[allow(deprecated)] pub fn new_boring(domain: String) -> Result { TlsParametersBuilder::new(domain).build_boring() } @@ -477,7 +452,6 @@ impl TlsParameters { /// A certificate that can be used with [`TlsParametersBuilder::add_root_certificate`] #[derive(Clone)] #[allow(missing_copy_implementations)] -#[deprecated] pub struct Certificate { #[cfg(feature = "native-tls")] native_tls: super::native_tls::Certificate, @@ -488,7 +462,6 @@ pub struct Certificate { } #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] -#[allow(deprecated)] impl Certificate { /// Create a `Certificate` from a DER encoded certificate pub fn from_der(der: Vec) -> Result { @@ -504,28 +477,17 @@ impl Certificate { /// Create a `Certificate` from a PEM encoded certificate pub fn from_pem(pem: &[u8]) -> Result { - #[cfg(feature = "rustls")] - let rustls_cert = { - use rustls::pki_types::{self, pem::PemObject as _, CertificateDer}; - - CertificateDer::pem_slice_iter(pem) - .map(|cert| Ok(super::rustls::Certificate(cert?))) - .collect::, pki_types::pem::Error>>() - .map_err(|_| error::tls("invalid certificates"))? - }; - Ok(Self { #[cfg(feature = "native-tls")] native_tls: super::native_tls::Certificate::from_pem(pem)?, #[cfg(feature = "rustls")] - rustls: rustls_cert, + rustls: super::rustls::Certificate::from_pem_bundle(pem)?, #[cfg(feature = "boring-tls")] boring_tls: super::boring_tls::Certificate::from_pem(pem)?, }) } } -#[allow(deprecated)] impl Debug for Certificate { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Certificate").finish() @@ -535,7 +497,6 @@ impl Debug for Certificate { /// An identity that can be used with [`TlsParametersBuilder::identify_with`] #[derive(Clone)] #[allow(missing_copy_implementations)] -#[deprecated] pub struct Identity { #[cfg(feature = "native-tls")] native_tls: super::native_tls::Identity, @@ -545,7 +506,6 @@ pub struct Identity { boring_tls: super::boring_tls::Identity, } -#[allow(deprecated)] impl Debug for Identity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Identity").finish() @@ -553,7 +513,6 @@ impl Debug for Identity { } #[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))] -#[allow(deprecated)] impl Identity { pub fn from_pem(pem: &[u8], key: &[u8]) -> Result { Ok(Self { diff --git a/src/transport/smtp/client/tls/mod.rs b/src/transport/smtp/client/tls/mod.rs index f640368..0c5cc44 100644 --- a/src/transport/smtp/client/tls/mod.rs +++ b/src/transport/smtp/client/tls/mod.rs @@ -2,17 +2,17 @@ use crate::transport::smtp::Error; #[cfg(feature = "boring-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "boring-tls")))] -pub mod boring_tls; -pub(super) mod deprecated; +pub(super) mod boring_tls; +pub(super) mod current; #[cfg(feature = "native-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] -pub mod native_tls; +pub(super) mod native_tls; #[cfg(feature = "rustls")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))] -pub mod rustls; +pub(super) mod rustls; #[derive(Debug)] -pub struct TlsParametersBuilder { +struct TlsParametersBuilder { domain: String, cert_store: B::CertificateStore, root_certs: Vec, @@ -23,7 +23,7 @@ pub struct TlsParametersBuilder { } impl TlsParametersBuilder { - pub fn new(domain: String) -> Self { + fn new(domain: String) -> Self { Self { domain, cert_store: Default::default(), @@ -35,44 +35,44 @@ impl TlsParametersBuilder { } } - pub fn certificate_store(mut self, cert_store: B::CertificateStore) -> Self { + fn certificate_store(mut self, cert_store: B::CertificateStore) -> Self { self.cert_store = cert_store; self } - pub fn add_root_certificate(mut self, cert: B::Certificate) -> Self { + fn add_root_certificate(mut self, cert: B::Certificate) -> Self { self.root_certs.push(cert); self } - pub fn identify_with(mut self, identity: B::Identity) -> Self { + fn identify_with(mut self, identity: B::Identity) -> Self { self.identity = Some(identity); self } - pub fn min_tls_version(mut self, min_tls_version: B::MinTlsVersion) -> Self { + fn min_tls_version(mut self, min_tls_version: B::MinTlsVersion) -> Self { self.min_tls_version = min_tls_version; self } - pub fn dangerous_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> Self { + fn dangerous_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> Self { self.accept_invalid_certs = accept_invalid_certs; self } - pub fn dangerous_accept_invalid_hostnames(mut self, accept_invalid_hostnames: bool) -> Self { + fn dangerous_accept_invalid_hostnames(mut self, accept_invalid_hostnames: bool) -> Self { self.accept_invalid_hostnames = accept_invalid_hostnames; self } - pub fn build_legacy(self) -> Result { + fn build_legacy(self) -> Result { let domain = self.domain.clone(); let connector = B::__build_legacy_connector(self)?; - Ok(self::deprecated::TlsParameters { connector, domain }) + Ok(self::current::TlsParameters { connector, domain }) } } -pub trait TlsBackend: private::SealedTlsBackend { +trait TlsBackend: private::SealedTlsBackend { type CertificateStore: Default; type Certificate; type Identity; @@ -85,7 +85,7 @@ pub trait TlsBackend: private::SealedTlsBackend { #[allow(private_interfaces)] fn __build_legacy_connector( builder: TlsParametersBuilder, - ) -> Result; + ) -> Result; } #[cfg(feature = "boring-tls")] @@ -93,7 +93,7 @@ pub trait TlsBackend: private::SealedTlsBackend { #[derive(Debug)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub struct BoringTls; +pub(super) struct BoringTls; #[cfg(feature = "boring-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "boring-tls")))] @@ -103,6 +103,7 @@ impl TlsBackend for BoringTls { type Identity = self::boring_tls::Identity; type MinTlsVersion = self::boring_tls::MinTlsVersion; + #[allow(private_interfaces)] fn __build_connector(builder: TlsParametersBuilder) -> Result { self::boring_tls::build_connector(builder) } @@ -110,10 +111,10 @@ impl TlsBackend for BoringTls { #[allow(private_interfaces)] fn __build_legacy_connector( builder: TlsParametersBuilder, - ) -> Result { + ) -> Result { let accept_invalid_hostnames = builder.accept_invalid_hostnames; Self::__build_connector(builder).map(|connector| { - self::deprecated::InnerTlsParameters::BoringTls { + self::current::InnerTlsParameters::BoringTls { connector, accept_invalid_hostnames, } @@ -126,7 +127,7 @@ impl TlsBackend for BoringTls { #[derive(Debug)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub struct NativeTls; +pub(super) struct NativeTls; #[cfg(feature = "native-tls")] #[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))] @@ -136,6 +137,7 @@ impl TlsBackend for NativeTls { type Identity = self::native_tls::Identity; type MinTlsVersion = self::native_tls::MinTlsVersion; + #[allow(private_interfaces)] fn __build_connector(builder: TlsParametersBuilder) -> Result { self::native_tls::build_connector(builder) } @@ -143,9 +145,9 @@ impl TlsBackend for NativeTls { #[allow(private_interfaces)] fn __build_legacy_connector( builder: TlsParametersBuilder, - ) -> Result { + ) -> Result { Self::__build_connector(builder) - .map(|connector| self::deprecated::InnerTlsParameters::NativeTls { connector }) + .map(|connector| self::current::InnerTlsParameters::NativeTls { connector }) } } @@ -154,7 +156,7 @@ impl TlsBackend for NativeTls { #[derive(Debug)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub struct Rustls; +pub(super) struct Rustls; #[cfg(feature = "rustls")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))] @@ -164,6 +166,7 @@ impl TlsBackend for Rustls { type Identity = self::rustls::Identity; type MinTlsVersion = self::rustls::MinTlsVersion; + #[allow(private_interfaces)] fn __build_connector(builder: TlsParametersBuilder) -> Result { self::rustls::build_connector(builder) } @@ -171,15 +174,14 @@ impl TlsBackend for Rustls { #[allow(private_interfaces)] fn __build_legacy_connector( builder: TlsParametersBuilder, - ) -> Result { + ) -> Result { Self::__build_connector(builder) - .map(|config| self::deprecated::InnerTlsParameters::Rustls { config }) + .map(|config| self::current::InnerTlsParameters::Rustls { config }) } } mod private { - // FIXME: this should be `pub(super)` but the `private_bounds` lint doesn't like it - pub trait SealedTlsBackend: Sized { + pub(super) trait SealedTlsBackend: Sized { type Connector; } diff --git a/src/transport/smtp/client/tls/native_tls.rs b/src/transport/smtp/client/tls/native_tls.rs index 928ae4e..53a53da 100644 --- a/src/transport/smtp/client/tls/native_tls.rs +++ b/src/transport/smtp/client/tls/native_tls.rs @@ -38,23 +38,23 @@ pub(super) fn build_connector( #[derive(Debug, Clone, Default)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub enum CertificateStore { +pub(super) enum CertificateStore { #[default] System, None, } #[derive(Clone)] -pub struct Certificate(pub(super) native_tls::Certificate); +pub(super) struct Certificate(pub(super) native_tls::Certificate); impl Certificate { - pub fn from_pem(pem: &[u8]) -> Result { + pub(super) fn from_pem(pem: &[u8]) -> Result { Ok(Self( native_tls::Certificate::from_pem(pem).map_err(error::tls)?, )) } - pub fn from_der(der: &[u8]) -> Result { + pub(super) fn from_der(der: &[u8]) -> Result { Ok(Self( native_tls::Certificate::from_der(der).map_err(error::tls)?, )) @@ -68,10 +68,10 @@ impl Debug for Certificate { } #[derive(Clone)] -pub struct Identity(pub(super) native_tls::Identity); +pub(super) struct Identity(pub(super) native_tls::Identity); impl Identity { - pub fn from_pem(pem: &[u8], key: &[u8]) -> Result { + pub(super) fn from_pem(pem: &[u8], key: &[u8]) -> Result { Ok(Self( native_tls::Identity::from_pkcs8(pem, key).map_err(error::tls)?, )) @@ -86,7 +86,7 @@ impl Debug for Identity { #[derive(Debug, Copy, Clone, Default)] #[non_exhaustive] -pub enum MinTlsVersion { +pub(super) enum MinTlsVersion { Tlsv10, Tlsv11, #[default] diff --git a/src/transport/smtp/client/tls/rustls.rs b/src/transport/smtp/client/tls/rustls.rs index b85eee2..5ce6ff9 100644 --- a/src/transport/smtp/client/tls/rustls.rs +++ b/src/transport/smtp/client/tls/rustls.rs @@ -80,7 +80,7 @@ pub(super) fn build_connector( #[derive(Debug, Clone, Default)] #[allow(missing_copy_implementations)] #[non_exhaustive] -pub enum CertificateStore { +pub(super) enum CertificateStore { #[cfg(feature = "rustls-native-certs")] #[cfg_attr(docsrs, doc(cfg(feature = "rustls-native-certs")))] #[cfg_attr(feature = "rustls-native-certs", default)] @@ -100,10 +100,11 @@ pub enum CertificateStore { } #[derive(Clone)] -pub struct Certificate(pub(super) pki_types::CertificateDer<'static>); +pub(super) struct Certificate(pub(super) pki_types::CertificateDer<'static>); impl Certificate { - pub fn from_pem(pem: &[u8]) -> Result { + #[allow(dead_code)] + pub(super) fn from_pem(pem: &[u8]) -> Result { use rustls::pki_types::pem::PemObject as _; Ok(Self( @@ -112,7 +113,16 @@ impl Certificate { )) } - pub fn from_der(der: Vec) -> Result { + pub(super) fn from_pem_bundle(pem: &[u8]) -> Result, Error> { + use rustls::pki_types::pem::PemObject as _; + + pki_types::CertificateDer::pem_slice_iter(pem) + .map(|cert| Ok(Self(cert?))) + .collect::, pki_types::pem::Error>>() + .map_err(|_| error::tls("invalid certificate")) + } + + pub(super) fn from_der(der: Vec) -> Result { Ok(Self(der.into())) } } @@ -123,13 +133,13 @@ impl Debug for Certificate { } } -pub struct Identity { +pub(super) struct Identity { pub(super) chain: Vec>, pub(super) key: pki_types::PrivateKeyDer<'static>, } impl Identity { - pub fn from_pem(pem: &[u8], key: &[u8]) -> Result { + pub(super) fn from_pem(pem: &[u8], key: &[u8]) -> Result { use rustls::pki_types::pem::PemObject as _; let key = match pki_types::PrivateKeyDer::from_pem_slice(key) { @@ -164,7 +174,7 @@ impl Debug for Identity { #[derive(Debug, Copy, Clone, Default)] #[non_exhaustive] -pub enum MinTlsVersion { +pub(super) enum MinTlsVersion { #[default] Tlsv12, Tlsv13, diff --git a/src/transport/smtp/mod.rs b/src/transport/smtp/mod.rs index affd7ab..2037314 100644 --- a/src/transport/smtp/mod.rs +++ b/src/transport/smtp/mod.rs @@ -107,10 +107,7 @@ //! //! use lettre::{ //! message::header::ContentType, -//! transport::smtp::client::{ -//! tls::{native_tls::Certificate, NativeTls, TlsParametersBuilder}, -//! Tls, -//! }, +//! transport::smtp::client::{Certificate, Tls, TlsParameters}, //! Message, SmtpTransport, Transport, //! }; //! @@ -125,11 +122,9 @@ //! // Custom TLS configuration - Use a self signed certificate //! let cert = fs::read("self-signed.crt")?; //! let cert = Certificate::from_pem(&cert)?; -//! let tls = TlsParametersBuilder::::new( -//! /* TLS SNI value */ "smtp.example.com".to_owned(), -//! ) -//! .add_root_certificate(cert) -//! .build_legacy()?; +//! let tls = TlsParameters::builder(/* TLS SNI value */ "smtp.example.com".to_owned()) +//! .add_root_certificate(cert) +//! .build()?; //! //! // Create the SMTPS transport //! let sender = SmtpTransport::relay("smtp.example.com")?