mirror of
https://github.com/fafhrd91/actix-net
synced 2025-03-20 16:05:18 +01:00
fix rustls panic when generating dns name from ip (#296)
* fix rustls panic when generating dns name from ip * Update rustls.rs * update changelog Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
b7bfff2b32
commit
a3c9ebc7fa
@ -1,6 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
* Changed `connect::ssl::rustls::RustlsConnectorService` to return error when `DNSNameRef`
|
||||||
|
generation failed instead of panic. [#296]
|
||||||
|
|
||||||
|
[#296]: https://github.com/actix/actix-net/pull/296
|
||||||
|
|
||||||
|
|
||||||
## 3.0.0-beta.4 - 2021-02-24
|
## 3.0.0-beta.4 - 2021-02-24
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fmt,
|
|
||||||
future::Future,
|
future::Future,
|
||||||
|
io,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
@ -10,7 +10,7 @@ pub use tokio_rustls::rustls::Session;
|
|||||||
pub use tokio_rustls::{client::TlsStream, rustls::ClientConfig};
|
pub use tokio_rustls::{client::TlsStream, rustls::ClientConfig};
|
||||||
pub use webpki_roots::TLS_SERVER_ROOTS;
|
pub use webpki_roots::TLS_SERVER_ROOTS;
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
use actix_rt::net::ActixStream;
|
||||||
use actix_service::{Service, ServiceFactory};
|
use actix_service::{Service, ServiceFactory};
|
||||||
use futures_core::{future::LocalBoxFuture, ready};
|
use futures_core::{future::LocalBoxFuture, ready};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
@ -44,12 +44,13 @@ impl Clone for RustlsConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address, U> ServiceFactory<Connection<T, U>> for RustlsConnector
|
impl<T, U> ServiceFactory<Connection<T, U>> for RustlsConnector
|
||||||
where
|
where
|
||||||
U: AsyncRead + AsyncWrite + Unpin + fmt::Debug,
|
T: Address,
|
||||||
|
U: ActixStream,
|
||||||
{
|
{
|
||||||
type Response = Connection<T, TlsStream<U>>;
|
type Response = Connection<T, TlsStream<U>>;
|
||||||
type Error = std::io::Error;
|
type Error = io::Error;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
type Service = RustlsConnectorService;
|
type Service = RustlsConnectorService;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
@ -76,43 +77,55 @@ impl Clone for RustlsConnectorService {
|
|||||||
impl<T, U> Service<Connection<T, U>> for RustlsConnectorService
|
impl<T, U> Service<Connection<T, U>> for RustlsConnectorService
|
||||||
where
|
where
|
||||||
T: Address,
|
T: Address,
|
||||||
U: AsyncRead + AsyncWrite + Unpin + fmt::Debug,
|
U: ActixStream,
|
||||||
{
|
{
|
||||||
type Response = Connection<T, TlsStream<U>>;
|
type Response = Connection<T, TlsStream<U>>;
|
||||||
type Error = std::io::Error;
|
type Error = io::Error;
|
||||||
type Future = ConnectAsyncExt<T, U>;
|
type Future = RustlsConnectorServiceFuture<T, U>;
|
||||||
|
|
||||||
actix_service::always_ready!();
|
actix_service::always_ready!();
|
||||||
|
|
||||||
fn call(&self, stream: Connection<T, U>) -> Self::Future {
|
fn call(&self, connection: Connection<T, U>) -> Self::Future {
|
||||||
trace!("SSL Handshake start for: {:?}", stream.host());
|
trace!("SSL Handshake start for: {:?}", connection.host());
|
||||||
let (io, stream) = stream.replace_io(());
|
let (stream, connection) = connection.replace_io(());
|
||||||
let host = DNSNameRef::try_from_ascii_str(stream.host())
|
|
||||||
.expect("rustls currently only handles hostname-based connections. See https://github.com/briansmith/webpki/issues/54");
|
match DNSNameRef::try_from_ascii_str(connection.host()) {
|
||||||
ConnectAsyncExt {
|
Ok(host) => RustlsConnectorServiceFuture::Future {
|
||||||
fut: TlsConnector::from(self.connector.clone()).connect(host, io),
|
connect: TlsConnector::from(self.connector.clone()).connect(host, stream),
|
||||||
stream: Some(stream),
|
connection: Some(connection),
|
||||||
|
},
|
||||||
|
Err(_) => RustlsConnectorServiceFuture::InvalidDns,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConnectAsyncExt<T, U> {
|
pub enum RustlsConnectorServiceFuture<T, U> {
|
||||||
fut: Connect<U>,
|
/// See issue https://github.com/briansmith/webpki/issues/54
|
||||||
stream: Option<Connection<T, ()>>,
|
InvalidDns,
|
||||||
|
Future {
|
||||||
|
connect: Connect<U>,
|
||||||
|
connection: Option<Connection<T, ()>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> Future for ConnectAsyncExt<T, U>
|
impl<T, U> Future for RustlsConnectorServiceFuture<T, U>
|
||||||
where
|
where
|
||||||
T: Address,
|
T: Address,
|
||||||
U: AsyncRead + AsyncWrite + Unpin + fmt::Debug,
|
U: ActixStream,
|
||||||
{
|
{
|
||||||
type Output = Result<Connection<T, TlsStream<U>>, std::io::Error>;
|
type Output = Result<Connection<T, TlsStream<U>>, io::Error>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let this = self.get_mut();
|
match self.get_mut() {
|
||||||
let stream = ready!(Pin::new(&mut this.fut).poll(cx))?;
|
Self::InvalidDns => Poll::Ready(Err(
|
||||||
let s = this.stream.take().unwrap();
|
io::Error::new(io::ErrorKind::Other, "rustls currently only handles hostname-based connections. See https://github.com/briansmith/webpki/issues/54")
|
||||||
trace!("SSL Handshake success: {:?}", s.host());
|
)),
|
||||||
Poll::Ready(Ok(s.replace_io(stream).1))
|
Self::Future { connect, connection } => {
|
||||||
|
let stream = ready!(Pin::new(connect).poll(cx))?;
|
||||||
|
let connection = connection.take().unwrap();
|
||||||
|
trace!("SSL Handshake success: {:?}", connection.host());
|
||||||
|
Poll::Ready(Ok(connection.replace_io(stream).1))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user