From 5ffc10b5856060ffafeddbb7a35d8bb502068145 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Mon, 1 Nov 2021 22:11:44 +0000 Subject: [PATCH 1/4] Introduce `meshtls` facade to hide rustls crate In #1351, we add an alternate identity/mtls implementation that uses `boring`. To setup for that, this change introduces a new `meshtls` crate that serves as a facade for application crates to depend on, independently of the actual crypto implementation. This change does not change any runtime logic and sets up for #1351 to enable an alternate TLS implementation as a build-time configuration. --- Cargo.lock | 53 +++-- Cargo.toml | 3 +- linkerd/app/core/Cargo.toml | 7 +- linkerd/app/core/src/lib.rs | 8 +- linkerd/app/inbound/Cargo.toml | 2 +- linkerd/app/inbound/fuzz/Cargo.toml | 2 +- linkerd/app/inbound/src/test_util.rs | 6 +- linkerd/app/outbound/Cargo.toml | 2 +- linkerd/app/outbound/src/test_util.rs | 4 +- linkerd/app/src/env.rs | 10 +- linkerd/app/src/identity.rs | 16 +- linkerd/meshtls/Cargo.toml | 22 ++ .../default => meshtls/rustls}/Cargo.toml | 4 +- .../default => meshtls/rustls}/src/client.rs | 0 .../default => meshtls/rustls}/src/creds.rs | 0 .../rustls}/src/creds/receiver.rs | 0 .../rustls}/src/creds/store.rs | 0 .../default => meshtls/rustls}/src/lib.rs | 1 - .../default => meshtls/rustls}/src/server.rs | 0 .../default => meshtls/rustls}/src/tests.rs | 0 .../rustls}/tests/tls_accept.rs | 29 ++- linkerd/meshtls/src/client.rs | 200 +++++++++++++++++ linkerd/meshtls/src/creds.rs | 91 ++++++++ linkerd/meshtls/src/lib.rs | 51 +++++ linkerd/meshtls/src/server.rs | 204 ++++++++++++++++++ linkerd/proxy/tap/Cargo.toml | 2 +- linkerd/proxy/tap/src/accept.rs | 4 +- 27 files changed, 652 insertions(+), 69 deletions(-) create mode 100644 linkerd/meshtls/Cargo.toml rename linkerd/{identity/default => meshtls/rustls}/Cargo.toml (91%) rename linkerd/{identity/default => meshtls/rustls}/src/client.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/src/creds.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/src/creds/receiver.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/src/creds/store.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/src/lib.rs (88%) rename linkerd/{identity/default => meshtls/rustls}/src/server.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/src/tests.rs (100%) rename linkerd/{identity/default => meshtls/rustls}/tests/tls_accept.rs (94%) create mode 100644 linkerd/meshtls/src/client.rs create mode 100644 linkerd/meshtls/src/creds.rs create mode 100644 linkerd/meshtls/src/lib.rs create mode 100644 linkerd/meshtls/src/server.rs diff --git a/Cargo.lock b/Cargo.lock index 587f224cfb..3456620272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,8 +674,9 @@ dependencies = [ "linkerd-http-classify", "linkerd-http-metrics", "linkerd-http-retry", - "linkerd-identity-default", + "linkerd-identity", "linkerd-io", + "linkerd-meshtls", "linkerd-metrics", "linkerd-opencensus", "linkerd-proxy-api-resolve", @@ -743,8 +744,8 @@ dependencies = [ "libfuzzer-sys", "linkerd-app-core", "linkerd-app-test", - "linkerd-identity-default", "linkerd-io", + "linkerd-meshtls-rustls", "linkerd-server-policy", "linkerd-tonic-watch", "linkerd-tracing", @@ -799,8 +800,8 @@ dependencies = [ "linkerd-app-test", "linkerd-http-retry", "linkerd-identity", - "linkerd-identity-default", "linkerd-io", + "linkerd-meshtls-rustls", "linkerd-tracing", "parking_lot", "pin-project", @@ -1000,7 +1001,35 @@ dependencies = [ ] [[package]] -name = "linkerd-identity-default" +name = "linkerd-io" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "futures", + "linkerd-errno", + "pin-project", + "tokio", + "tokio-test", + "tokio-util", +] + +[[package]] +name = "linkerd-meshtls" +version = "0.1.0" +dependencies = [ + "futures", + "linkerd-error", + "linkerd-identity", + "linkerd-io", + "linkerd-meshtls-rustls", + "linkerd-stack", + "linkerd-tls", + "pin-project", +] + +[[package]] +name = "linkerd-meshtls-rustls" version = "0.1.0" dependencies = [ "futures", @@ -1022,20 +1051,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "linkerd-io" -version = "0.1.0" -dependencies = [ - "async-trait", - "bytes", - "futures", - "linkerd-errno", - "pin-project", - "tokio", - "tokio-test", - "tokio-util", -] - [[package]] name = "linkerd-metrics" version = "0.1.0" @@ -1202,8 +1217,8 @@ dependencies = [ "ipnet", "linkerd-conditional", "linkerd-error", - "linkerd-identity-default", "linkerd-io", + "linkerd-meshtls", "linkerd-proxy-http", "linkerd-stack", "linkerd-tls", diff --git a/Cargo.toml b/Cargo.toml index 5d6f81c998..eb20c52303 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,8 +29,9 @@ members = [ "linkerd/http-metrics", "linkerd/http-retry", "linkerd/identity", - "linkerd/identity/default", "linkerd/io", + "linkerd/meshtls", + "linkerd/meshtls/rustls", "linkerd/metrics", "linkerd/opencensus", "linkerd/proxy/api-resolve", diff --git a/linkerd/app/core/Cargo.toml b/linkerd/app/core/Cargo.toml index 3d5c1327e1..20aa7b59b4 100644 --- a/linkerd/app/core/Cargo.toml +++ b/linkerd/app/core/Cargo.toml @@ -12,6 +12,10 @@ This crate conglomerates proxy configuration, runtime administration, etc, independently of the inbound and outbound proxy logic. """ +[features] +default = ["meshtls-rustls"] +meshtls-rustls = ["linkerd-meshtls/rustls"] + [dependencies] bytes = "1" drain = { version = "0.1.0", features = ["retain"] } @@ -33,8 +37,9 @@ linkerd-exp-backoff = { path = "../../exp-backoff" } linkerd-http-classify = { path = "../../http-classify" } linkerd-http-metrics = { path = "../../http-metrics" } linkerd-http-retry = { path = "../../http-retry" } -linkerd-identity-default = { path = "../../identity/default" } +linkerd-identity = { path = "../../identity" } linkerd-io = { path = "../../io" } +linkerd-meshtls = { path = "../../meshtls", default-features = false } linkerd-metrics = { path = "../../metrics", features = ["linkerd-stack"] } linkerd-opencensus = { path = "../../opencensus" } linkerd-proxy-core = { path = "../../proxy/core" } diff --git a/linkerd/app/core/src/lib.rs b/linkerd/app/core/src/lib.rs index faa9d425e8..5c418cdd5c 100644 --- a/linkerd/app/core/src/lib.rs +++ b/linkerd/app/core/src/lib.rs @@ -20,10 +20,8 @@ pub use linkerd_dns; pub use linkerd_error::{is_error, Error, Infallible, Recover, Result}; pub use linkerd_exp_backoff as exp_backoff; pub use linkerd_http_metrics as http_metrics; -pub use linkerd_identity_default as identity; pub use linkerd_io as io; pub use linkerd_opencensus as opencensus; -pub use linkerd_proxy_identity_client as identity_client; pub use linkerd_service_profiles as profiles; pub use linkerd_stack_metrics as stack_metrics; pub use linkerd_stack_tracing as stack_tracing; @@ -51,6 +49,12 @@ pub mod transport; pub use self::addr_match::{AddrMatch, IpMatch, NameMatch}; +pub mod identity { + pub use linkerd_identity::*; + pub use linkerd_meshtls::*; + pub use linkerd_proxy_identity_client as client; +} + pub const CANONICAL_DST_HEADER: &str = "l5d-dst-canonical"; const DEFAULT_PORT: u16 = 80; diff --git a/linkerd/app/inbound/Cargo.toml b/linkerd/app/inbound/Cargo.toml index d9f3fdb6ea..e378a777f2 100644 --- a/linkerd/app/inbound/Cargo.toml +++ b/linkerd/app/inbound/Cargo.toml @@ -34,7 +34,7 @@ libfuzzer-sys = { version = "0.4.2", features = ["arbitrary-derive"] } hyper = { version = "0.14.14", features = ["http1", "http2"] } linkerd-app-test = { path = "../test" } linkerd-io = { path = "../../io", features = ["tokio-test"] } -linkerd-identity-default = { path = "../../identity/default", features = ["test-util"] } +linkerd-meshtls-rustls = { path = "../../meshtls/rustls", features = ["test-util"] } linkerd-tracing = { path = "../../tracing", features = ["ansi"] } tokio = { version = "1", features = ["full", "macros"] } tokio-test = "0.4" diff --git a/linkerd/app/inbound/fuzz/Cargo.toml b/linkerd/app/inbound/fuzz/Cargo.toml index 9ae622f451..eb83bcf975 100644 --- a/linkerd/app/inbound/fuzz/Cargo.toml +++ b/linkerd/app/inbound/fuzz/Cargo.toml @@ -17,7 +17,7 @@ libfuzzer-sys = { version = "0.4.2", features = ["arbitrary-derive"] } linkerd-app-core = { path = "../../core" } linkerd-app-inbound = { path = ".." } linkerd-app-test = { path = "../../test" } -linkerd-identity-default = { path = "../../../identity/default", features = ["test-util"] } +linkerd-meshtls-rustls = { path = "../../../meshtls/rustls", features = ["test-util"] } linkerd-tracing = { path = "../../../tracing", features = ["ansi"] } tokio = { version = "1", features = ["full"] } tracing = "0.1" diff --git a/linkerd/app/inbound/src/test_util.rs b/linkerd/app/inbound/src/test_util.rs index d77fd87568..35d1ae9757 100644 --- a/linkerd/app/inbound/src/test_util.rs +++ b/linkerd/app/inbound/src/test_util.rs @@ -3,7 +3,9 @@ pub use futures::prelude::*; use linkerd_app_core::{ config, dns::Suffix, - drain, exp_backoff, identity, metrics, + drain, exp_backoff, + identity::rustls, + metrics, proxy::{ http::{h1, h2}, tap, @@ -73,7 +75,7 @@ pub fn runtime() -> (ProxyRuntime, drain::Signal) { let (tap, _) = tap::new(); let (metrics, _) = metrics::Metrics::new(std::time::Duration::from_secs(10)); let runtime = ProxyRuntime { - identity: identity::creds::default_for_test().1, + identity: rustls::creds::default_for_test().1.into(), metrics: metrics.proxy, tap, span_sink: None, diff --git a/linkerd/app/outbound/Cargo.toml b/linkerd/app/outbound/Cargo.toml index 796c25003c..fc2a51e2a1 100644 --- a/linkerd/app/outbound/Cargo.toml +++ b/linkerd/app/outbound/Cargo.toml @@ -32,7 +32,7 @@ pin-project = "1" hyper = { version = "0.14.14", features = ["http1", "http2"] } linkerd-app-test = { path = "../test" } linkerd-io = { path = "../../io", features = ["tokio-test"] } -linkerd-identity-default = { path = "../../identity/default", features = ["test-util"] } +linkerd-meshtls-rustls = { path = "../../meshtls/rustls", features = ["test-util"] } linkerd-tracing = { path = "../../tracing", features = ["ansi"] } parking_lot = "0.11" tokio = { version = "1", features = ["time", "macros"] } diff --git a/linkerd/app/outbound/src/test_util.rs b/linkerd/app/outbound/src/test_util.rs index 5da08b586c..4afd5c5a88 100644 --- a/linkerd/app/outbound/src/test_util.rs +++ b/linkerd/app/outbound/src/test_util.rs @@ -1,7 +1,7 @@ use crate::Config; pub use futures::prelude::*; use linkerd_app_core::{ - config, drain, exp_backoff, identity, metrics, + config, drain, exp_backoff, metrics, proxy::{ http::{h1, h2}, tap, @@ -53,7 +53,7 @@ pub(crate) fn runtime() -> (ProxyRuntime, drain::Signal) { let (tap, _) = tap::new(); let (metrics, _) = metrics::Metrics::new(std::time::Duration::from_secs(10)); let runtime = ProxyRuntime { - identity: identity::creds::default_for_test().1, + identity: linkerd_meshtls_rustls::creds::default_for_test().1.into(), metrics: metrics.proxy, tap, span_sink: None, diff --git a/linkerd/app/src/env.rs b/linkerd/app/src/env.rs index ec1e086197..00069a6038 100644 --- a/linkerd/app/src/env.rs +++ b/linkerd/app/src/env.rs @@ -2,7 +2,6 @@ use crate::core::{ addr, config::*, control::{Config as ControlConfig, ControlAddr}, - identity_client, proxy::http::{h1, h2}, tls, transport::{Keepalive, ListenAddr}, @@ -1102,14 +1101,7 @@ pub fn parse_control_addr( pub fn parse_identity_config( strings: &S, -) -> Result< - ( - ControlAddr, - identity_client::certify::Config, - identity::Documents, - ), - EnvError, -> { +) -> Result<(ControlAddr, identity::certify::Config, identity::Documents), EnvError> { let control = parse_control_addr(strings, ENV_IDENTITY_SVC_BASE); let ta = parse(strings, ENV_IDENTITY_TRUST_ANCHORS, |s| { if s.is_empty() { diff --git a/linkerd/app/src/identity.rs b/linkerd/app/src/identity.rs index b6c635c289..040bd06516 100644 --- a/linkerd/app/src/identity.rs +++ b/linkerd/app/src/identity.rs @@ -1,15 +1,17 @@ +pub use linkerd_app_core::identity::{ + client::{certify, TokenSource}, + InvalidName, LocalId, Name, +}; use linkerd_app_core::{ control, dns, exp_backoff::{ExponentialBackoff, ExponentialBackoffStream}, - identity::{creds, Credentials, DerX509}, - identity_client::{Certify, Metrics as IdentityMetrics}, + identity::{ + client::{Certify, Metrics as IdentityMetrics}, + creds, Credentials, DerX509, Mode, + }, metrics::ControlHttp as ClientMetrics, Error, Result, }; -pub use linkerd_app_core::{ - identity::{InvalidName, LocalId, Name}, - identity_client::{certify, TokenSource}, -}; use std::{future::Future, pin::Pin}; use tokio::sync::watch; use tracing::Instrument; @@ -53,7 +55,7 @@ struct NotifyReady { impl Config { pub fn build(self, dns: dns::Resolver, client_metrics: ClientMetrics) -> Result { - let (store, receiver) = creds::watch( + let (store, receiver) = Mode::default().watch( (*self.documents.id).clone(), &self.documents.trust_anchors_pem, &self.documents.key_pkcs8, diff --git a/linkerd/meshtls/Cargo.toml b/linkerd/meshtls/Cargo.toml new file mode 100644 index 0000000000..1ea25bf229 --- /dev/null +++ b/linkerd/meshtls/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "linkerd-meshtls" +version = "0.1.0" +authors = ["Linkerd Developers "] +license = "Apache-2.0" +edition = "2018" +publish = false + +[features] +default = ["rustls"] +rustls = ["linkerd-meshtls-rustls"] + + +[dependencies] +futures = { version = "0.3", default-features = false } +linkerd-error = { path = "../error" } +linkerd-identity = { path = "../identity" } +linkerd-io = { path = "../io" } +linkerd-meshtls-rustls = { path = "rustls", optional = true } +linkerd-stack = { path = "../stack" } +linkerd-tls = { path = "../tls" } +pin-project = "1" diff --git a/linkerd/identity/default/Cargo.toml b/linkerd/meshtls/rustls/Cargo.toml similarity index 91% rename from linkerd/identity/default/Cargo.toml rename to linkerd/meshtls/rustls/Cargo.toml index eedb64872e..6b5b030c11 100644 --- a/linkerd/identity/default/Cargo.toml +++ b/linkerd/meshtls/rustls/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "linkerd-identity-default" +name = "linkerd-meshtls-rustls" version = "0.1.0" authors = ["Linkerd Developers "] license = "Apache-2.0" @@ -19,7 +19,7 @@ linkerd-tls = { path = "../../tls" } linkerd-tls-test-util = { path = "../../tls/test-util", optional = true } ring = { version = "0.16.19", features = ["std"] } thiserror = "1" -tokio = { version = "1", features = ["macros", "sync"] } +tokio = { version = "1", features = ["macros", "rt", "sync"] } tokio-rustls = "0.22" tracing = "0.1" webpki = "0.21" diff --git a/linkerd/identity/default/src/client.rs b/linkerd/meshtls/rustls/src/client.rs similarity index 100% rename from linkerd/identity/default/src/client.rs rename to linkerd/meshtls/rustls/src/client.rs diff --git a/linkerd/identity/default/src/creds.rs b/linkerd/meshtls/rustls/src/creds.rs similarity index 100% rename from linkerd/identity/default/src/creds.rs rename to linkerd/meshtls/rustls/src/creds.rs diff --git a/linkerd/identity/default/src/creds/receiver.rs b/linkerd/meshtls/rustls/src/creds/receiver.rs similarity index 100% rename from linkerd/identity/default/src/creds/receiver.rs rename to linkerd/meshtls/rustls/src/creds/receiver.rs diff --git a/linkerd/identity/default/src/creds/store.rs b/linkerd/meshtls/rustls/src/creds/store.rs similarity index 100% rename from linkerd/identity/default/src/creds/store.rs rename to linkerd/meshtls/rustls/src/creds/store.rs diff --git a/linkerd/identity/default/src/lib.rs b/linkerd/meshtls/rustls/src/lib.rs similarity index 88% rename from linkerd/identity/default/src/lib.rs rename to linkerd/meshtls/rustls/src/lib.rs index 0f37758c91..bcc6cc0461 100644 --- a/linkerd/identity/default/src/lib.rs +++ b/linkerd/meshtls/rustls/src/lib.rs @@ -9,4 +9,3 @@ pub use self::{ client::{ClientIo, Connect, ConnectFuture, NewClient}, server::{Server, ServerIo, TerminateFuture}, }; -pub use linkerd_identity::*; diff --git a/linkerd/identity/default/src/server.rs b/linkerd/meshtls/rustls/src/server.rs similarity index 100% rename from linkerd/identity/default/src/server.rs rename to linkerd/meshtls/rustls/src/server.rs diff --git a/linkerd/identity/default/src/tests.rs b/linkerd/meshtls/rustls/src/tests.rs similarity index 100% rename from linkerd/identity/default/src/tests.rs rename to linkerd/meshtls/rustls/src/tests.rs diff --git a/linkerd/identity/default/tests/tls_accept.rs b/linkerd/meshtls/rustls/tests/tls_accept.rs similarity index 94% rename from linkerd/identity/default/tests/tls_accept.rs rename to linkerd/meshtls/rustls/tests/tls_accept.rs index 5f014cb228..9357688ee1 100644 --- a/linkerd/identity/default/tests/tls_accept.rs +++ b/linkerd/meshtls/rustls/tests/tls_accept.rs @@ -8,8 +8,9 @@ use futures::prelude::*; use linkerd_conditional::Conditional; use linkerd_error::Infallible; -use linkerd_identity_default::{self as identity, Credentials, DerX509, Name}; +use linkerd_identity::{Credentials, DerX509, Name}; use linkerd_io::{self as io, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use linkerd_meshtls_rustls as meshtls; use linkerd_proxy_transport::{ addrs::*, listen::{Addrs, Bind, BindTcp}, @@ -28,18 +29,12 @@ use tracing::instrument::Instrument; type ServerConn = ( (tls::ConditionalServerTls, T), - io::EitherIo>, tls::server::DetectIo>, + io::EitherIo>, tls::server::DetectIo>, ); -fn load( - ent: &test_util::Entity, -) -> ( - identity::creds::Store, - identity::NewClient, - identity::Server, -) { +fn load(ent: &test_util::Entity) -> (meshtls::creds::Store, meshtls::NewClient, meshtls::Server) { let roots_pem = std::str::from_utf8(ent.trust_anchors).expect("valid PEM"); - let (mut store, rx) = identity::creds::watch( + let (mut store, rx) = meshtls::creds::watch( ent.name.parse().unwrap(), roots_pem, ent.key, @@ -152,19 +147,19 @@ struct Transported { #[derive(Clone)] struct ServerParams { - identity: identity::Server, + identity: meshtls::Server, } -type ClientIo = io::EitherIo, identity::ClientIo>>; +type ClientIo = io::EitherIo, meshtls::ClientIo>>; /// Runs a test for a single TCP connection. `client` processes the connection /// on the client side and `server` processes the connection on the server /// side. async fn run_test( - client_tls: identity::NewClient, + client_tls: meshtls::NewClient, client_server_id: Conditional, client: C, - server_id: identity::Server, + server_id: meshtls::Server, server: S, ) -> ( Transported, @@ -187,7 +182,7 @@ where // Saves the result of every connection. let (sender, receiver) = mpsc::channel::>(); - let detect = tls::NewDetectTls::::new( + let detect = tls::NewDetectTls::::new( ServerParams { identity: server_id, }, @@ -375,8 +370,8 @@ impl ExtractParam for ServerParams { } } -impl ExtractParam for ServerParams { - fn extract_param(&self, _: &T) -> identity::Server { +impl ExtractParam for ServerParams { + fn extract_param(&self, _: &T) -> meshtls::Server { self.identity.clone() } } diff --git a/linkerd/meshtls/src/client.rs b/linkerd/meshtls/src/client.rs new file mode 100644 index 0000000000..6a03c23fca --- /dev/null +++ b/linkerd/meshtls/src/client.rs @@ -0,0 +1,200 @@ +use linkerd_io as io; +use linkerd_stack::{NewService, Service}; +use linkerd_tls::{ClientTls, HasNegotiatedProtocol, NegotiatedProtocolRef}; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + +#[cfg(feature = "rustls")] +use crate::rustls; + +#[derive(Clone, Debug)] +pub enum NewClient { + #[cfg(feature = "rustls")] + Rustls(rustls::NewClient), +} + +#[derive(Clone)] +pub enum Connect { + #[cfg(feature = "rustls")] + Rustls(rustls::Connect), +} + +#[pin_project::pin_project(project = ConnectFutureProj)] +pub enum ConnectFuture { + #[cfg(feature = "rustls")] + Rustls(#[pin] rustls::ConnectFuture), +} + +#[pin_project::pin_project(project = ClientIoProj)] +#[derive(Debug)] +pub enum ClientIo { + #[cfg(feature = "rustls")] + Rustls(#[pin] rustls::ClientIo), +} + +// === impl NewClient === + +impl NewService for NewClient { + type Service = Connect; + + fn new_service(&self, target: ClientTls) -> Self::Service { + #[cfg(feature = "rustls")] + if let Self::Rustls(new_client) = self { + return Connect::Rustls(new_client.new_service(target)); + } + + unreachable!() + } +} + +// === impl Connect === + +impl Service for Connect +where + I: io::AsyncRead + io::AsyncWrite + Send + Unpin + 'static, +{ + type Response = ClientIo; + type Error = io::Error; + type Future = ConnectFuture; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + #[cfg(feature = "rustls")] + if let Self::Rustls(connect) = self { + return >::poll_ready(connect, cx); + } + + unreachable!() + } + + #[inline] + fn call(&mut self, io: I) -> Self::Future { + #[cfg(feature = "rustls")] + if let Self::Rustls(connect) = self { + return ConnectFuture::Rustls(connect.call(io)); + } + + unreachable!() + } +} + +// === impl ConnectFuture === + +impl Future for ConnectFuture +where + I: io::AsyncRead + io::AsyncWrite + Unpin, +{ + type Output = io::Result>; + + fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ConnectFutureProj::Rustls(f) = this { + let res = futures::ready!(f.poll(cx)); + return Poll::Ready(res.map(ClientIo::Rustls)); + } + + unreachable!() + } +} + +// === impl ClientIo === + +impl io::AsyncRead for ClientIo { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut io::ReadBuf<'_>, + ) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ClientIoProj::Rustls(io) = this { + return io.poll_read(cx, buf); + } + + unreachable!() + } +} + +impl io::AsyncWrite for ClientIo { + #[inline] + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ClientIoProj::Rustls(io) = this { + return io.poll_flush(cx); + } + + unreachable!() + } + + #[inline] + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ClientIoProj::Rustls(io) = this { + return io.poll_shutdown(cx); + } + + unreachable!() + } + + #[inline] + fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> io::Poll { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ClientIoProj::Rustls(io) = this { + return io.poll_write(cx, buf); + } + + unreachable!() + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ClientIoProj::Rustls(io) = this { + return io.poll_write_vectored(cx, bufs); + } + + unreachable!() + } + + #[inline] + fn is_write_vectored(&self) -> bool { + unimplemented!() + } +} + +impl HasNegotiatedProtocol for ClientIo { + #[inline] + fn negotiated_protocol(&self) -> Option> { + unimplemented!() + } +} + +impl io::PeerAddr for ClientIo { + #[inline] + fn peer_addr(&self) -> io::Result { + #[cfg(feature = "rustls")] + if let Self::Rustls(io) = self { + return io.peer_addr(); + } + + unreachable!() + } +} diff --git a/linkerd/meshtls/src/creds.rs b/linkerd/meshtls/src/creds.rs new file mode 100644 index 0000000000..20017bec69 --- /dev/null +++ b/linkerd/meshtls/src/creds.rs @@ -0,0 +1,91 @@ +use crate::{NewClient, Server}; +use linkerd_error::Result; +use linkerd_identity::{Credentials, DerX509, Name}; + +#[cfg(feature = "rustls")] +pub use crate::rustls; + +pub enum Store { + #[cfg(feature = "rustls")] + Rustls(rustls::creds::Store), +} + +#[derive(Clone, Debug)] +pub enum Receiver { + #[cfg(feature = "rustls")] + Rustls(rustls::creds::Receiver), +} + +// === impl Store === + +impl Credentials for Store { + fn dns_name(&self) -> &Name { + #[cfg(feature = "rustls")] + if let Self::Rustls(store) = self { + return store.dns_name(); + } + + unreachable!() + } + + fn gen_certificate_signing_request(&mut self) -> DerX509 { + #[cfg(feature = "rustls")] + if let Self::Rustls(store) = self { + return store.gen_certificate_signing_request(); + } + + unreachable!() + } + + fn set_certificate( + &mut self, + leaf: DerX509, + chain: Vec, + expiry: std::time::SystemTime, + ) -> Result<()> { + #[cfg(feature = "rustls")] + if let Self::Rustls(store) = self { + return store.set_certificate(leaf, chain, expiry); + } + + unreachable!() + } +} + +// === impl Receiver === + +#[cfg(feature = "rustls")] +impl From for Receiver { + fn from(rx: rustls::creds::Receiver) -> Self { + Self::Rustls(rx) + } +} + +impl Receiver { + pub fn name(&self) -> &Name { + #[cfg(feature = "rustls")] + if let Self::Rustls(receiver) = self { + return receiver.name(); + } + + unreachable!() + } + + pub fn new_client(&self) -> NewClient { + #[cfg(feature = "rustls")] + if let Self::Rustls(receiver) = self { + return NewClient::Rustls(receiver.new_client()); + } + + unreachable!() + } + + pub fn server(&self) -> Server { + #[cfg(feature = "rustls")] + if let Self::Rustls(receiver) = self { + return Server::Rustls(receiver.server()); + } + + unreachable!() + } +} diff --git a/linkerd/meshtls/src/lib.rs b/linkerd/meshtls/src/lib.rs new file mode 100644 index 0000000000..6600507d31 --- /dev/null +++ b/linkerd/meshtls/src/lib.rs @@ -0,0 +1,51 @@ +#![allow(irrefutable_let_patterns)] + +mod client; +pub mod creds; +mod server; + +pub use self::{ + client::{ClientIo, Connect, ConnectFuture, NewClient}, + server::{Server, ServerIo, TerminateFuture}, +}; +use linkerd_error::Result; +use linkerd_identity::Name; + +#[cfg(feature = "rustls")] +pub use linkerd_meshtls_rustls as rustls; + +#[derive(Copy, Clone, Debug)] +pub enum Mode { + #[cfg(feature = "rustls")] + Rustls, +} + +// === impl Mode === + +#[cfg(feature = "rustls")] +impl Default for Mode { + fn default() -> Self { + Self::Rustls + } +} + +impl Mode { + pub fn watch( + self, + identity: Name, + roots_pem: &str, + key_pkcs8: &[u8], + csr: &[u8], + ) -> Result<(creds::Store, creds::Receiver)> { + #[cfg(feature = "rustls")] + if let Self::Rustls = self { + let (store, receiver) = rustls::creds::watch(identity, roots_pem, key_pkcs8, csr)?; + return Ok(( + creds::Store::Rustls(store), + creds::Receiver::Rustls(receiver), + )); + } + + unreachable!() + } +} diff --git a/linkerd/meshtls/src/server.rs b/linkerd/meshtls/src/server.rs new file mode 100644 index 0000000000..d8e66771a3 --- /dev/null +++ b/linkerd/meshtls/src/server.rs @@ -0,0 +1,204 @@ +use linkerd_error::Result; +use linkerd_identity::LocalId; +use linkerd_io as io; +use linkerd_stack::{Param, Service}; +use linkerd_tls::ServerTls; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + +#[cfg(feature = "rustls")] +use crate::rustls; + +#[derive(Clone)] +pub enum Server { + #[cfg(feature = "rustls")] + Rustls(rustls::Server), +} + +#[pin_project::pin_project(project = TerminateFutureProj)] +pub enum TerminateFuture { + #[cfg(feature = "rustls")] + Rustls(#[pin] rustls::TerminateFuture), +} + +#[pin_project::pin_project(project = ServerIoProj)] +#[derive(Debug)] +pub enum ServerIo { + #[cfg(feature = "rustls")] + Rustls(#[pin] rustls::ServerIo), +} + +// === impl Server === + +impl Param for Server { + fn param(&self) -> LocalId { + #[cfg(feature = "rustls")] + if let Self::Rustls(srv) = self { + return srv.param(); + } + + unreachable!() + } +} + +impl Server { + pub fn spawn_with_alpn(self, alpn_protocols: Vec>) -> Result { + #[cfg(feature = "rustls")] + if let Self::Rustls(srv) = self { + return srv + .spawn_with_alpn(alpn_protocols) + .map(Self::Rustls) + .map_err(Into::into); + } + + unreachable!() + } +} + +impl Service for Server +where + I: io::AsyncRead + io::AsyncWrite + Send + Sync + Unpin + 'static, +{ + type Response = (ServerTls, ServerIo); + type Error = io::Error; + type Future = TerminateFuture; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + #[cfg(feature = "rustls")] + if let Self::Rustls(svc) = self { + return >::poll_ready(svc, cx); + } + + unreachable!() + } + + #[inline] + fn call(&mut self, io: I) -> Self::Future { + #[cfg(feature = "rustls")] + if let Self::Rustls(svc) = self { + return TerminateFuture::Rustls(svc.call(io)); + } + + unreachable!() + } +} + +// === impl TerminateFuture === + +impl Future for TerminateFuture +where + I: io::AsyncRead + io::AsyncWrite + Unpin, +{ + type Output = io::Result<(ServerTls, ServerIo)>; + + fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let TerminateFutureProj::Rustls(f) = this { + let res = futures::ready!(f.poll(cx)); + return Poll::Ready(res.map(|(tls, io)| (tls, ServerIo::Rustls(io)))); + } + + unreachable!() + } +} + +// === impl ServerIo === + +impl io::AsyncRead for ServerIo { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut io::ReadBuf<'_>, + ) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ServerIoProj::Rustls(io) = this { + return io.poll_read(cx, buf); + } + + unreachable!() + } +} + +impl io::AsyncWrite for ServerIo { + #[inline] + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ServerIoProj::Rustls(io) = this { + return io.poll_flush(cx); + } + + unreachable!() + } + + #[inline] + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ServerIoProj::Rustls(io) = this { + return io.poll_shutdown(cx); + } + + unreachable!() + } + + #[inline] + fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> io::Poll { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ServerIoProj::Rustls(io) = this { + return io.poll_write(cx, buf); + } + + unreachable!() + } + + #[inline] + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + let this = self.project(); + + #[cfg(feature = "rustls")] + if let ServerIoProj::Rustls(io) = this { + return io.poll_write_vectored(cx, bufs); + } + + unreachable!() + } + + #[inline] + fn is_write_vectored(&self) -> bool { + #[cfg(feature = "rustls")] + if let Self::Rustls(io) = self { + return io.is_write_vectored(); + } + + unreachable!() + } +} + +impl io::PeerAddr for ServerIo { + #[inline] + fn peer_addr(&self) -> io::Result { + #[cfg(feature = "rustls")] + if let Self::Rustls(io) = self { + return io.peer_addr(); + } + + unreachable!() + } +} diff --git a/linkerd/proxy/tap/Cargo.toml b/linkerd/proxy/tap/Cargo.toml index 1aa9732a40..8d59bc0511 100644 --- a/linkerd/proxy/tap/Cargo.toml +++ b/linkerd/proxy/tap/Cargo.toml @@ -17,7 +17,7 @@ ipnet = "2.3" linkerd2-proxy-api = { version = "0.3", features = ["tap", "server"] } linkerd-conditional = { path = "../../conditional" } linkerd-error = { path = "../../error" } -linkerd-identity-default = { path = "../../identity/default" } +linkerd-meshtls = { path = "../../meshtls" } linkerd-io = { path = "../../io" } linkerd-proxy-http = { path = "../http" } linkerd-stack = { path = "../../stack" } diff --git a/linkerd/proxy/tap/src/accept.rs b/linkerd/proxy/tap/src/accept.rs index 4d414b6ae9..5bcb50c862 100644 --- a/linkerd/proxy/tap/src/accept.rs +++ b/linkerd/proxy/tap/src/accept.rs @@ -3,8 +3,8 @@ use futures::future; use linkerd2_proxy_api::tap::tap_server::{Tap, TapServer}; use linkerd_conditional::Conditional; use linkerd_error::Error; -use linkerd_identity_default as identity; use linkerd_io as io; +use linkerd_meshtls as meshtls; use linkerd_proxy_http::{trace, HyperServerSvc}; use linkerd_tls as tls; use std::{ @@ -24,7 +24,7 @@ pub struct AcceptPermittedClients { type Connection = ( (tls::ConditionalServerTls, T), - io::EitherIo>, tls::server::DetectIo>, + io::EitherIo>, tls::server::DetectIo>, ); pub type ServeFuture = Pin> + Send + 'static>>; From ef049c4850af4a3c89f22483116056514b5d44c8 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Wed, 3 Nov 2021 21:58:27 +0000 Subject: [PATCH 2/4] fill in missing impls --- linkerd/meshtls/src/client.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/linkerd/meshtls/src/client.rs b/linkerd/meshtls/src/client.rs index 6a03c23fca..06c4e9c28b 100644 --- a/linkerd/meshtls/src/client.rs +++ b/linkerd/meshtls/src/client.rs @@ -176,14 +176,24 @@ impl io::AsyncWrite for ClientIo { #[inline] fn is_write_vectored(&self) -> bool { - unimplemented!() + #[cfg(feature = "rustls")] + if let Self::Rustls(io) = self { + return io.is_write_vectored(); + } + + unreachable!() } } impl HasNegotiatedProtocol for ClientIo { #[inline] fn negotiated_protocol(&self) -> Option> { - unimplemented!() + #[cfg(feature = "rustls")] + if let Self::Rustls(io) = self { + return io.negotiated_protocol(); + } + + unreachable!() } } From 4d07551d86bd1cc7798bc2d1283523c1552029d4 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Wed, 3 Nov 2021 22:16:00 +0000 Subject: [PATCH 3/4] Add a build.rs file for meshtls to ensure that a feature is present --- linkerd/meshtls/build.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 linkerd/meshtls/build.rs diff --git a/linkerd/meshtls/build.rs b/linkerd/meshtls/build.rs new file mode 100644 index 0000000000..2103566aa6 --- /dev/null +++ b/linkerd/meshtls/build.rs @@ -0,0 +1,16 @@ +fn main() -> Result<(), Box> { + // Ensure that at least one TLS implementation feature is enabled. + static TLS_FEATURES: &[&'static str] = &["rustls"]; + if !TLS_FEATURES + .iter() + .any(|f| std::env::var_os(&*format!("CARGO_FEATURE_{}", f.to_ascii_uppercase())).is_some()) + { + return Err(format!( + "at least one of the following TLS implementations must be enabled: '{}'", + TLS_FEATURES.join("', '"), + ) + .into()); + } + + Ok(()) +} From 9b46f02c5b4b6def023a1ffbc0fe7fe19eb41e90 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Wed, 3 Nov 2021 22:30:48 +0000 Subject: [PATCH 4/4] Use match instead of if-let --- linkerd/meshtls/build.rs | 2 +- linkerd/meshtls/src/client.rs | 112 ++++++++++++--------------------- linkerd/meshtls/src/creds.rs | 48 ++++++-------- linkerd/meshtls/src/lib.rs | 21 ++++--- linkerd/meshtls/src/server.rs | 114 ++++++++++++---------------------- 5 files changed, 109 insertions(+), 188 deletions(-) diff --git a/linkerd/meshtls/build.rs b/linkerd/meshtls/build.rs index 2103566aa6..222161cbc4 100644 --- a/linkerd/meshtls/build.rs +++ b/linkerd/meshtls/build.rs @@ -1,6 +1,6 @@ fn main() -> Result<(), Box> { // Ensure that at least one TLS implementation feature is enabled. - static TLS_FEATURES: &[&'static str] = &["rustls"]; + static TLS_FEATURES: &[&str] = &["rustls"]; if !TLS_FEATURES .iter() .any(|f| std::env::var_os(&*format!("CARGO_FEATURE_{}", f.to_ascii_uppercase())).is_some()) diff --git a/linkerd/meshtls/src/client.rs b/linkerd/meshtls/src/client.rs index 06c4e9c28b..0a27293f88 100644 --- a/linkerd/meshtls/src/client.rs +++ b/linkerd/meshtls/src/client.rs @@ -41,12 +41,10 @@ impl NewService for NewClient { type Service = Connect; fn new_service(&self, target: ClientTls) -> Self::Service { - #[cfg(feature = "rustls")] - if let Self::Rustls(new_client) = self { - return Connect::Rustls(new_client.new_service(target)); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(new_client) => Connect::Rustls(new_client.new_service(target)), } - - unreachable!() } } @@ -61,22 +59,18 @@ where type Future = ConnectFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - #[cfg(feature = "rustls")] - if let Self::Rustls(connect) = self { - return >::poll_ready(connect, cx); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(connect) => >::poll_ready(connect, cx), } - - unreachable!() } #[inline] fn call(&mut self, io: I) -> Self::Future { - #[cfg(feature = "rustls")] - if let Self::Rustls(connect) = self { - return ConnectFuture::Rustls(connect.call(io)); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(connect) => ConnectFuture::Rustls(connect.call(io)), } - - unreachable!() } } @@ -89,15 +83,13 @@ where type Output = io::Result>; fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ConnectFutureProj::Rustls(f) = this { - let res = futures::ready!(f.poll(cx)); - return Poll::Ready(res.map(ClientIo::Rustls)); + match self.project() { + #[cfg(feature = "rustls")] + ConnectFutureProj::Rustls(f) => { + let res = futures::ready!(f.poll(cx)); + Poll::Ready(res.map(ClientIo::Rustls)) + } } - - unreachable!() } } @@ -110,52 +102,36 @@ impl io::AsyncRead for ClientIo { cx: &mut Context<'_>, buf: &mut io::ReadBuf<'_>, ) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ClientIoProj::Rustls(io) = this { - return io.poll_read(cx, buf); + match self.project() { + #[cfg(feature = "rustls")] + ClientIoProj::Rustls(io) => io.poll_read(cx, buf), } - - unreachable!() } } impl io::AsyncWrite for ClientIo { #[inline] fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ClientIoProj::Rustls(io) = this { - return io.poll_flush(cx); + match self.project() { + #[cfg(feature = "rustls")] + ClientIoProj::Rustls(io) => io.poll_flush(cx), } - - unreachable!() } #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ClientIoProj::Rustls(io) = this { - return io.poll_shutdown(cx); + match self.project() { + #[cfg(feature = "rustls")] + ClientIoProj::Rustls(io) => io.poll_shutdown(cx), } - - unreachable!() } #[inline] fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> io::Poll { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ClientIoProj::Rustls(io) = this { - return io.poll_write(cx, buf); + match self.project() { + #[cfg(feature = "rustls")] + ClientIoProj::Rustls(io) => io.poll_write(cx, buf), } - - unreachable!() } #[inline] @@ -164,47 +140,37 @@ impl io::AsyncWrite for ClientIo { cx: &mut Context<'_>, bufs: &[io::IoSlice<'_>], ) -> Poll> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ClientIoProj::Rustls(io) = this { - return io.poll_write_vectored(cx, bufs); + match self.project() { + #[cfg(feature = "rustls")] + ClientIoProj::Rustls(io) => io.poll_write_vectored(cx, bufs), } - - unreachable!() } #[inline] fn is_write_vectored(&self) -> bool { - #[cfg(feature = "rustls")] - if let Self::Rustls(io) = self { - return io.is_write_vectored(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(io) => io.is_write_vectored(), } - - unreachable!() } } impl HasNegotiatedProtocol for ClientIo { #[inline] fn negotiated_protocol(&self) -> Option> { - #[cfg(feature = "rustls")] - if let Self::Rustls(io) = self { - return io.negotiated_protocol(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(io) => io.negotiated_protocol(), } - - unreachable!() } } impl io::PeerAddr for ClientIo { #[inline] fn peer_addr(&self) -> io::Result { - #[cfg(feature = "rustls")] - if let Self::Rustls(io) = self { - return io.peer_addr(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(io) => io.peer_addr(), } - - unreachable!() } } diff --git a/linkerd/meshtls/src/creds.rs b/linkerd/meshtls/src/creds.rs index 20017bec69..f3ec69e5d5 100644 --- a/linkerd/meshtls/src/creds.rs +++ b/linkerd/meshtls/src/creds.rs @@ -20,21 +20,17 @@ pub enum Receiver { impl Credentials for Store { fn dns_name(&self) -> &Name { - #[cfg(feature = "rustls")] - if let Self::Rustls(store) = self { - return store.dns_name(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(store) => store.dns_name(), } - - unreachable!() } fn gen_certificate_signing_request(&mut self) -> DerX509 { - #[cfg(feature = "rustls")] - if let Self::Rustls(store) = self { - return store.gen_certificate_signing_request(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(store) => store.gen_certificate_signing_request(), } - - unreachable!() } fn set_certificate( @@ -43,12 +39,10 @@ impl Credentials for Store { chain: Vec, expiry: std::time::SystemTime, ) -> Result<()> { - #[cfg(feature = "rustls")] - if let Self::Rustls(store) = self { - return store.set_certificate(leaf, chain, expiry); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(store) => store.set_certificate(leaf, chain, expiry), } - - unreachable!() } } @@ -63,29 +57,23 @@ impl From for Receiver { impl Receiver { pub fn name(&self) -> &Name { - #[cfg(feature = "rustls")] - if let Self::Rustls(receiver) = self { - return receiver.name(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(receiver) => receiver.name(), } - - unreachable!() } pub fn new_client(&self) -> NewClient { - #[cfg(feature = "rustls")] - if let Self::Rustls(receiver) = self { - return NewClient::Rustls(receiver.new_client()); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(receiver) => NewClient::Rustls(receiver.new_client()), } - - unreachable!() } pub fn server(&self) -> Server { - #[cfg(feature = "rustls")] - if let Self::Rustls(receiver) = self { - return Server::Rustls(receiver.server()); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(receiver) => Server::Rustls(receiver.server()), } - - unreachable!() } } diff --git a/linkerd/meshtls/src/lib.rs b/linkerd/meshtls/src/lib.rs index 6600507d31..71cb68efa4 100644 --- a/linkerd/meshtls/src/lib.rs +++ b/linkerd/meshtls/src/lib.rs @@ -1,4 +1,5 @@ -#![allow(irrefutable_let_patterns)] +#![deny(warnings, rust_2018_idioms)] +#![forbid(unsafe_code)] mod client; pub mod creds; @@ -37,15 +38,15 @@ impl Mode { key_pkcs8: &[u8], csr: &[u8], ) -> Result<(creds::Store, creds::Receiver)> { - #[cfg(feature = "rustls")] - if let Self::Rustls = self { - let (store, receiver) = rustls::creds::watch(identity, roots_pem, key_pkcs8, csr)?; - return Ok(( - creds::Store::Rustls(store), - creds::Receiver::Rustls(receiver), - )); + match self { + #[cfg(feature = "rustls")] + Self::Rustls => { + let (store, receiver) = rustls::creds::watch(identity, roots_pem, key_pkcs8, csr)?; + Ok(( + creds::Store::Rustls(store), + creds::Receiver::Rustls(receiver), + )) + } } - - unreachable!() } } diff --git a/linkerd/meshtls/src/server.rs b/linkerd/meshtls/src/server.rs index d8e66771a3..9792167b75 100644 --- a/linkerd/meshtls/src/server.rs +++ b/linkerd/meshtls/src/server.rs @@ -35,26 +35,22 @@ pub enum ServerIo { impl Param for Server { fn param(&self) -> LocalId { - #[cfg(feature = "rustls")] - if let Self::Rustls(srv) = self { - return srv.param(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(srv) => srv.param(), } - - unreachable!() } } impl Server { pub fn spawn_with_alpn(self, alpn_protocols: Vec>) -> Result { - #[cfg(feature = "rustls")] - if let Self::Rustls(srv) = self { - return srv + match self { + #[cfg(feature = "rustls")] + Self::Rustls(srv) => srv .spawn_with_alpn(alpn_protocols) .map(Self::Rustls) - .map_err(Into::into); + .map_err(Into::into), } - - unreachable!() } } @@ -67,22 +63,18 @@ where type Future = TerminateFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - #[cfg(feature = "rustls")] - if let Self::Rustls(svc) = self { - return >::poll_ready(svc, cx); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(svc) => >::poll_ready(svc, cx), } - - unreachable!() } #[inline] fn call(&mut self, io: I) -> Self::Future { - #[cfg(feature = "rustls")] - if let Self::Rustls(svc) = self { - return TerminateFuture::Rustls(svc.call(io)); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(svc) => TerminateFuture::Rustls(svc.call(io)), } - - unreachable!() } } @@ -95,15 +87,13 @@ where type Output = io::Result<(ServerTls, ServerIo)>; fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let TerminateFutureProj::Rustls(f) = this { - let res = futures::ready!(f.poll(cx)); - return Poll::Ready(res.map(|(tls, io)| (tls, ServerIo::Rustls(io)))); + match self.project() { + #[cfg(feature = "rustls")] + TerminateFutureProj::Rustls(f) => { + let res = futures::ready!(f.poll(cx)); + Poll::Ready(res.map(|(tls, io)| (tls, ServerIo::Rustls(io)))) + } } - - unreachable!() } } @@ -116,52 +106,36 @@ impl io::AsyncRead for ServerIo { cx: &mut Context<'_>, buf: &mut io::ReadBuf<'_>, ) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ServerIoProj::Rustls(io) = this { - return io.poll_read(cx, buf); + match self.project() { + #[cfg(feature = "rustls")] + ServerIoProj::Rustls(io) => io.poll_read(cx, buf), } - - unreachable!() } } impl io::AsyncWrite for ServerIo { #[inline] fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ServerIoProj::Rustls(io) = this { - return io.poll_flush(cx); + match self.project() { + #[cfg(feature = "rustls")] + ServerIoProj::Rustls(io) => io.poll_flush(cx), } - - unreachable!() } #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> io::Poll<()> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ServerIoProj::Rustls(io) = this { - return io.poll_shutdown(cx); + match self.project() { + #[cfg(feature = "rustls")] + ServerIoProj::Rustls(io) => io.poll_shutdown(cx), } - - unreachable!() } #[inline] fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> io::Poll { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ServerIoProj::Rustls(io) = this { - return io.poll_write(cx, buf); + match self.project() { + #[cfg(feature = "rustls")] + ServerIoProj::Rustls(io) => io.poll_write(cx, buf), } - - unreachable!() } #[inline] @@ -170,35 +144,27 @@ impl io::AsyncWrite for ServerIo { cx: &mut Context<'_>, bufs: &[io::IoSlice<'_>], ) -> Poll> { - let this = self.project(); - - #[cfg(feature = "rustls")] - if let ServerIoProj::Rustls(io) = this { - return io.poll_write_vectored(cx, bufs); + match self.project() { + #[cfg(feature = "rustls")] + ServerIoProj::Rustls(io) => io.poll_write_vectored(cx, bufs), } - - unreachable!() } #[inline] fn is_write_vectored(&self) -> bool { - #[cfg(feature = "rustls")] - if let Self::Rustls(io) = self { - return io.is_write_vectored(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(io) => io.is_write_vectored(), } - - unreachable!() } } impl io::PeerAddr for ServerIo { #[inline] fn peer_addr(&self) -> io::Result { - #[cfg(feature = "rustls")] - if let Self::Rustls(io) = self { - return io.peer_addr(); + match self { + #[cfg(feature = "rustls")] + Self::Rustls(io) => io.peer_addr(), } - - unreachable!() } }