1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-02-01 03:43:09 +01:00
actix-net/actix-server/src/ssl/nativetls.rs

183 lines
5.5 KiB
Rust
Raw Normal View History

2018-09-27 20:23:30 -07:00
use std::io;
use std::marker::PhantomData;
2018-12-09 10:15:49 -08:00
use actix_service::{NewService, Service};
2018-09-27 20:23:30 -07:00
use futures::{future::ok, future::FutureResult, Async, Future, Poll};
use native_tls::{self, Error, HandshakeError, TlsAcceptor};
use tokio_io::{AsyncRead, AsyncWrite};
2018-12-06 14:53:55 -08:00
use crate::counter::{Counter, CounterGuard};
use crate::ssl::MAX_CONN_COUNTER;
2019-03-11 12:01:55 -07:00
use crate::{Io, Protocol, ServerConfig};
2018-09-27 20:23:30 -07:00
/// Support `SSL` connections via native-tls package
///
/// `tls` feature enables `NativeTlsAcceptor` type
2019-03-11 13:48:55 -07:00
pub struct NativeTlsAcceptor<T, P = ()> {
2018-09-27 20:23:30 -07:00
acceptor: TlsAcceptor,
2019-03-11 12:01:55 -07:00
io: PhantomData<(T, P)>,
2018-09-27 20:23:30 -07:00
}
2019-03-11 12:01:55 -07:00
impl<T: AsyncRead + AsyncWrite, P> NativeTlsAcceptor<T, P> {
2018-09-27 20:23:30 -07:00
/// Create `NativeTlsAcceptor` instance
pub fn new(acceptor: TlsAcceptor) -> Self {
NativeTlsAcceptor {
2018-12-09 22:14:29 -08:00
acceptor,
2018-09-27 20:23:30 -07:00
io: PhantomData,
}
}
}
2019-03-11 12:01:55 -07:00
impl<T: AsyncRead + AsyncWrite, P> Clone for NativeTlsAcceptor<T, P> {
2018-09-27 20:23:30 -07:00
fn clone(&self) -> Self {
Self {
acceptor: self.acceptor.clone(),
io: PhantomData,
}
}
}
impl<T: AsyncRead + AsyncWrite, P> NewService for NativeTlsAcceptor<T, P> {
2019-03-11 12:01:55 -07:00
type Request = Io<T, P>;
type Response = Io<TlsStream<T>, P>;
2018-09-27 20:23:30 -07:00
type Error = Error;
type Config = ServerConfig;
2019-03-11 12:01:55 -07:00
type Service = NativeTlsAcceptorService<T, P>;
2018-09-27 20:23:30 -07:00
type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>;
2019-03-09 07:27:56 -08:00
fn new_service(&self, cfg: &ServerConfig) -> Self::Future {
cfg.set_secure();
2018-09-27 20:23:30 -07:00
MAX_CONN_COUNTER.with(|conns| {
ok(NativeTlsAcceptorService {
acceptor: self.acceptor.clone(),
conns: conns.clone(),
io: PhantomData,
})
})
}
}
2019-03-11 12:01:55 -07:00
pub struct NativeTlsAcceptorService<T, P> {
2018-09-27 20:23:30 -07:00
acceptor: TlsAcceptor,
2019-03-11 12:01:55 -07:00
io: PhantomData<(T, P)>,
2018-09-27 20:23:30 -07:00
conns: Counter,
}
2019-03-11 12:01:55 -07:00
impl<T: AsyncRead + AsyncWrite, P> Service for NativeTlsAcceptorService<T, P> {
type Request = Io<T, P>;
type Response = Io<TlsStream<T>, P>;
2018-09-27 20:23:30 -07:00
type Error = Error;
2019-03-11 12:01:55 -07:00
type Future = Accept<T, P>;
2018-09-27 20:23:30 -07:00
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
if self.conns.available() {
Ok(Async::Ready(()))
} else {
Ok(Async::NotReady)
}
}
2019-03-11 12:01:55 -07:00
fn call(&mut self, req: Self::Request) -> Self::Future {
let (io, params, _) = req.into_parts();
2018-09-27 20:23:30 -07:00
Accept {
_guard: self.conns.get(),
2019-03-11 12:01:55 -07:00
inner: Some(self.acceptor.accept(io)),
params: Some(params),
2018-09-27 20:23:30 -07:00
}
}
}
/// A wrapper around an underlying raw stream which implements the TLS or SSL
/// protocol.
///
/// A `TlsStream<S>` represents a handshake that has been completed successfully
/// and both the server and the client are ready for receiving and sending
/// data. Bytes read from a `TlsStream` are decrypted from `S` and bytes written
/// to a `TlsStream` are encrypted when passing through to `S`.
#[derive(Debug)]
pub struct TlsStream<S> {
inner: native_tls::TlsStream<S>,
}
/// Future returned from `NativeTlsAcceptor::accept` which will resolve
/// once the accept handshake has finished.
2019-03-11 12:01:55 -07:00
pub struct Accept<S, P> {
2018-09-27 20:23:30 -07:00
inner: Option<Result<native_tls::TlsStream<S>, HandshakeError<S>>>,
2019-03-11 12:01:55 -07:00
params: Option<P>,
2018-09-27 20:23:30 -07:00
_guard: CounterGuard,
}
2019-03-11 12:01:55 -07:00
impl<T: AsyncRead + AsyncWrite, P> Future for Accept<T, P> {
type Item = Io<TlsStream<T>, P>;
2018-09-27 20:23:30 -07:00
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.inner.take().expect("cannot poll MidHandshake twice") {
2019-03-11 12:01:55 -07:00
Ok(stream) => Ok(Async::Ready(Io::from_parts(
TlsStream { inner: stream },
self.params.take().unwrap(),
Protocol::Unknown,
))),
2018-09-27 20:23:30 -07:00
Err(HandshakeError::Failure(e)) => Err(e),
Err(HandshakeError::WouldBlock(s)) => match s.handshake() {
2019-03-11 12:01:55 -07:00
Ok(stream) => Ok(Async::Ready(Io::from_parts(
TlsStream { inner: stream },
self.params.take().unwrap(),
Protocol::Unknown,
))),
2018-09-27 20:23:30 -07:00
Err(HandshakeError::Failure(e)) => Err(e),
Err(HandshakeError::WouldBlock(s)) => {
self.inner = Some(Err(HandshakeError::WouldBlock(s)));
Ok(Async::NotReady)
}
},
}
}
}
impl<S> TlsStream<S> {
/// Get access to the internal `native_tls::TlsStream` stream which also
/// transitively allows access to `S`.
pub fn get_ref(&self) -> &native_tls::TlsStream<S> {
&self.inner
}
/// Get mutable access to the internal `native_tls::TlsStream` stream which
/// also transitively allows mutable access to `S`.
pub fn get_mut(&mut self) -> &mut native_tls::TlsStream<S> {
&mut self.inner
}
}
impl<S: io::Read + io::Write> io::Read for TlsStream<S> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
impl<S: AsyncRead + AsyncWrite> AsyncRead for TlsStream<S> {}
impl<S: AsyncRead + AsyncWrite> AsyncWrite for TlsStream<S> {
fn shutdown(&mut self) -> Poll<(), io::Error> {
match self.inner.shutdown() {
Ok(_) => (),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => (),
Err(e) => return Err(e),
}
self.inner.get_mut().shutdown()
}
}