fix(transport): Fix warnings ans test both TLS options

This commit is contained in:
Alexis Mousset
2019-12-08 23:16:44 +01:00
parent b379adec28
commit a90b548b4f
4 changed files with 32 additions and 20 deletions

View File

@@ -24,7 +24,11 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features=native-tls
- uses: actions-rs/cargo@v1
with:
command: test
check:
name: Check
runs-on: ubuntu-latest

View File

@@ -109,8 +109,11 @@ impl<S: Connector + Write + Read + Timeout> InnerClient<S> {
}
/// Upgrades the underlying connection to SSL/TLS
#[cfg(feature = "native-tls")]
pub fn upgrade_tls_stream(&mut self, tls_parameters: &ClientTlsParameters) -> io::Result<()> {
#[cfg(any(feature = "native-tls", feature = "rustls"))]
pub fn upgrade_tls_stream(
&mut self,
tls_parameters: &ClientTlsParameters,
) -> Result<(), Error> {
match self.stream {
Some(ref mut stream) => stream.get_mut().upgrade_tls(tls_parameters),
None => Ok(()),

View File

@@ -19,12 +19,13 @@ use std::time::Duration;
pub struct ClientTlsParameters {
/// A connector from `native-tls`
#[cfg(feature = "native-tls")]
pub connector: TlsConnector,
connector: TlsConnector,
/// A client from `rustls`
#[cfg(feature = "rustls")]
pub connector: ClientConfig,
// TODO use the same in all transports of the client
connector: Box<ClientConfig>,
/// The domain name which is expected in the TLS certificate from the server
pub domain: String,
domain: String,
}
impl ClientTlsParameters {
@@ -37,14 +38,18 @@ impl ClientTlsParameters {
/// Creates a `ClientTlsParameters`
#[cfg(feature = "rustls")]
pub fn new(domain: String, connector: ClientConfig) -> Self {
ClientTlsParameters { connector, domain }
ClientTlsParameters {
connector: Box::new(connector),
domain,
}
}
}
/// Accepted protocols by default.
/// This removes TLS 1.0 and 1.1 compared to tls-native defaults.
/// This is also rustls' default behavior
#[cfg(feature = "native-tls")]
pub const DEFAULT_TLS_MIN_PROTOCOL: Protocol = Protocol::Tlsv12;
const DEFAULT_TLS_MIN_PROTOCOL: Protocol = Protocol::Tlsv12;
/// Represents the different types of underlying network streams
pub enum NetworkStream {
@@ -54,7 +59,7 @@ pub enum NetworkStream {
#[cfg(feature = "native-tls")]
Tls(Box<TlsStream<TcpStream>>),
#[cfg(feature = "rustls")]
Tls(rustls::StreamOwned<ClientSession, TcpStream>),
Tls(Box<rustls::StreamOwned<ClientSession, TcpStream>>),
/// Mock stream
Mock(MockStream),
}
@@ -161,10 +166,10 @@ impl Connector for NetworkStream {
Some(context) => {
let domain = webpki::DNSNameRef::try_from_ascii_str(&context.domain)?;
Ok(NetworkStream::Tls(rustls::StreamOwned::new(
ClientSession::new(&Arc::new(context.connector.clone()), domain),
Ok(NetworkStream::Tls(Box::new(rustls::StreamOwned::new(
ClientSession::new(&Arc::new(*context.connector.clone()), domain),
tcp_stream,
)))
))))
}
None => Ok(NetworkStream::Tcp(tcp_stream)),
}
@@ -184,10 +189,10 @@ impl Connector for NetworkStream {
NetworkStream::Tcp(ref mut stream) => {
let domain = webpki::DNSNameRef::try_from_ascii_str(&tls_parameters.domain)?;
NetworkStream::Tls(rustls::StreamOwned::new(
ClientSession::new(&Arc::new(tls_parameters.connector.clone()), domain),
NetworkStream::Tls(Box::new(rustls::StreamOwned::new(
ClientSession::new(&Arc::new(*tls_parameters.connector.clone()), domain),
stream.try_clone().unwrap(),
))
)))
}
NetworkStream::Tls(_) | NetworkStream::Mock(_) => return Ok(()),
};

View File

@@ -18,7 +18,6 @@ use crate::smtp::authentication::{
};
use crate::smtp::client::net::ClientTlsParameters;
#[cfg(feature = "native-tls")]
// TODO RUSTLS
use crate::smtp::client::net::DEFAULT_TLS_MIN_PROTOCOL;
use crate::smtp::client::InnerClient;
use crate::smtp::commands::*;
@@ -306,7 +305,7 @@ impl<'a> SmtpTransport {
(&ClientSecurity::Opportunistic(_), false) => (),
(&ClientSecurity::None, _) => (),
(&ClientSecurity::Wrapper(_), _) => (),
#[cfg(feature = "native-tls")]
#[cfg(any(feature = "native-tls", feature = "rustls"))]
(&ClientSecurity::Opportunistic(ref tls_parameters), true)
| (&ClientSecurity::Required(ref tls_parameters), true) => {
try_smtp!(self.client.command(StarttlsCommand), self);
@@ -315,10 +314,11 @@ impl<'a> SmtpTransport {
// Send EHLO again
self.ehlo()?;
}
#[cfg(not(feature = "native-tls"))]
#[cfg(not(any(feature = "native-tls", feature = "rustls")))]
(&ClientSecurity::Opportunistic(_), true) | (&ClientSecurity::Required(_), true) => {
// FIXME dedicated error variant
return Err(From::from("Encryption required but no TLS support enabled"));
// This should never happen as `ClientSecurity` can only be created
// when a TLS library is enabled
unreachable!("TLS support required but not supported");
}
}