feat: make crypto and TLS certificate verify backends opt-in (#1054)
This commit is contained in:
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@@ -57,12 +57,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup cache
|
- name: Setup cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
- name: Install cargo hack
|
- name: Install cargo hack
|
||||||
run: cargo install cargo-hack --debug
|
run: cargo install cargo-hack --debug
|
||||||
|
|
||||||
- name: Check with cargo hack
|
- name: Check with cargo hack
|
||||||
run: cargo hack check --feature-powerset --depth 3
|
run: cargo hack check --feature-powerset --depth 3 --at-least-one-of aws-lc-rs,ring --at-least-one-of rustls-native-certs,webpki-roots
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: test / ${{ matrix.name }}
|
name: test / ${{ matrix.name }}
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
- name: Setup cache
|
- name: Setup cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
- name: Install postfix
|
- name: Install postfix
|
||||||
run: |
|
run: |
|
||||||
DEBIAN_FRONTEND=noninteractive sudo apt-get update
|
DEBIAN_FRONTEND=noninteractive sudo apt-get update
|
||||||
DEBIAN_FRONTEND=noninteractive sudo apt-get -y install postfix
|
DEBIAN_FRONTEND=noninteractive sudo apt-get -y install postfix
|
||||||
@@ -119,10 +119,10 @@ jobs:
|
|||||||
run: cargo test
|
run: cargo test
|
||||||
|
|
||||||
- name: Test with all features (-native-tls)
|
- name: Test with all features (-native-tls)
|
||||||
run: cargo test --no-default-features --features async-std1,async-std1-rustls-tls,boring-tls,builder,dkim,file-transport,file-transport-envelope,hostname,mime03,pool,rustls-native-certs,rustls-tls,sendmail-transport,smtp-transport,tokio1,tokio1-boring-tls,tokio1-rustls-tls,tracing
|
run: cargo test --no-default-features --features async-std1,async-std1-rustls,aws-lc-rs,rustls-native-certs,boring-tls,builder,dkim,file-transport,file-transport-envelope,hostname,mime03,pool,rustls-native-certs,rustls,sendmail-transport,smtp-transport,tokio1,tokio1-boring-tls,tokio1-rustls,tracing
|
||||||
|
|
||||||
- name: Test with all features (-boring-tls)
|
- name: Test with all features (-boring-tls)
|
||||||
run: cargo test --no-default-features --features async-std1,async-std1-rustls-tls,builder,dkim,file-transport,file-transport-envelope,hostname,mime03,native-tls,pool,rustls-native-certs,rustls-tls,sendmail-transport,smtp-transport,tokio1,tokio1-native-tls,tokio1-rustls-tls,tracing
|
run: cargo test --no-default-features --features async-std1,async-std1-rustls,aws-lc-rs,rustls-native-certs,builder,dkim,file-transport,file-transport-envelope,hostname,mime03,native-tls,pool,rustls-native-certs,rustls,sendmail-transport,smtp-transport,tokio1,tokio1-native-tls,tokio1-rustls,tracing
|
||||||
|
|
||||||
# coverage:
|
# coverage:
|
||||||
# name: Coverage
|
# name: Coverage
|
||||||
|
|||||||
128
Cargo.lock
generated
128
Cargo.lock
generated
@@ -241,6 +241,47 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-fips-sys"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29003a681b2b9465c1139bfb726da452a841a8b025f35953f3bce71139f10b21"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen 0.69.5",
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
"dunce",
|
||||||
|
"fs_extra",
|
||||||
|
"paste",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-rs"
|
||||||
|
version = "1.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4cd755adf9707cf671e31d944a189be3deaaeee11c8bc1d669bb8022ac90fbd0"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-fips-sys",
|
||||||
|
"aws-lc-sys",
|
||||||
|
"paste",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-sys"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f9dd2e03ee80ca2822dd6ea431163d2ef259f2066a4d6ccaca6d9dcb386aa43"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen 0.69.5",
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
"dunce",
|
||||||
|
"fs_extra",
|
||||||
|
"paste",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.74"
|
version = "0.3.74"
|
||||||
@@ -268,6 +309,29 @@ version = "1.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.69.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"itertools 0.10.5",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
"shlex",
|
||||||
|
"syn 2.0.89",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.70.1"
|
version = "0.70.1"
|
||||||
@@ -335,7 +399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "777cf31ea10f7eb87d46b30848f8d7acbd65cb4a25cd51bee1808ef601de0416"
|
checksum = "777cf31ea10f7eb87d46b30848f8d7acbd65cb4a25cd51bee1808ef601de0416"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bindgen",
|
"bindgen 0.70.1",
|
||||||
"cmake",
|
"cmake",
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"fslock",
|
"fslock",
|
||||||
@@ -371,6 +435,8 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -664,6 +730,12 @@ dependencies = [
|
|||||||
"syn 2.0.89",
|
"syn 2.0.89",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dunce"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ed25519"
|
name = "ed25519"
|
||||||
version = "2.2.3"
|
version = "2.2.3"
|
||||||
@@ -969,6 +1041,15 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "home"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hostname"
|
name = "hostname"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -1160,6 +1241,15 @@ version = "1.0.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.72"
|
version = "0.3.72"
|
||||||
@@ -1187,6 +1277,12 @@ dependencies = [
|
|||||||
"spin",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lettre"
|
name = "lettre"
|
||||||
version = "0.11.13"
|
version = "0.11.13"
|
||||||
@@ -1509,6 +1605,12 @@ version = "2.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -1636,6 +1738,16 @@ dependencies = [
|
|||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.89",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -1845,6 +1957,7 @@ version = "0.23.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f"
|
checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
@@ -1878,6 +1991,7 @@ version = "0.102.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
@@ -2460,6 +2574,18 @@ dependencies = [
|
|||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"home",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|||||||
22
Cargo.toml
22
Cargo.toml
@@ -48,7 +48,7 @@ percent-encoding = { version = "2.3", optional = true }
|
|||||||
|
|
||||||
## tls
|
## tls
|
||||||
native-tls = { version = "0.2.9", optional = true } # feature
|
native-tls = { version = "0.2.9", optional = true } # feature
|
||||||
rustls = { version = "0.23.5", default-features = false, features = ["ring", "logging", "std", "tls12"], optional = true }
|
rustls = { version = "0.23.5", default-features = false, features = ["logging", "std", "tls12"], optional = true }
|
||||||
rustls-native-certs = { version = "0.8", optional = true }
|
rustls-native-certs = { version = "0.8", optional = true }
|
||||||
webpki-roots = { version = "0.26", optional = true }
|
webpki-roots = { version = "0.26", optional = true }
|
||||||
boring = { version = "4", optional = true }
|
boring = { version = "4", optional = true }
|
||||||
@@ -60,12 +60,12 @@ async-trait = { version = "0.1", optional = true }
|
|||||||
|
|
||||||
## async-std
|
## async-std
|
||||||
async-std = { version = "1.8", optional = true }
|
async-std = { version = "1.8", optional = true }
|
||||||
futures-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "ring"], optional = true }
|
futures-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12"], optional = true }
|
||||||
|
|
||||||
## tokio
|
## tokio
|
||||||
tokio1_crate = { package = "tokio", version = "1", optional = true }
|
tokio1_crate = { package = "tokio", version = "1", optional = true }
|
||||||
tokio1_native_tls_crate = { package = "tokio-native-tls", version = "0.3", optional = true }
|
tokio1_native_tls_crate = { package = "tokio-native-tls", version = "0.3", optional = true }
|
||||||
tokio1_rustls = { package = "tokio-rustls", version = "0.26", default-features = false, features = ["logging", "tls12", "ring"], optional = true }
|
tokio1_rustls = { package = "tokio-rustls", version = "0.26", default-features = false, features = ["logging", "tls12"], optional = true }
|
||||||
tokio1_boring = { package = "tokio-boring", version = "4", optional = true }
|
tokio1_boring = { package = "tokio-boring", version = "4", optional = true }
|
||||||
|
|
||||||
## dkim
|
## dkim
|
||||||
@@ -109,16 +109,26 @@ smtp-transport = ["dep:base64", "dep:nom", "dep:socket2", "dep:url", "dep:percen
|
|||||||
|
|
||||||
pool = ["dep:futures-util"]
|
pool = ["dep:futures-util"]
|
||||||
|
|
||||||
rustls-tls = ["dep:webpki-roots", "dep:rustls"]
|
rustls = ["dep:rustls"]
|
||||||
|
aws-lc-rs = ["rustls?/aws-lc-rs"]
|
||||||
|
fips = ["aws-lc-rs", "rustls?/fips"]
|
||||||
|
ring = ["rustls?/ring"]
|
||||||
|
webpki-roots = ["dep:webpki-roots"]
|
||||||
|
# deprecated
|
||||||
|
rustls-tls = ["webpki-roots", "rustls", "ring"]
|
||||||
|
|
||||||
boring-tls = ["dep:boring"]
|
boring-tls = ["dep:boring"]
|
||||||
|
|
||||||
# async
|
# async
|
||||||
async-std1 = ["dep:async-std", "dep:async-trait", "dep:futures-io", "dep:futures-util"]
|
async-std1 = ["dep:async-std", "dep:async-trait", "dep:futures-io", "dep:futures-util"]
|
||||||
async-std1-rustls-tls = ["async-std1", "rustls-tls", "dep:futures-rustls"]
|
async-std1-rustls = ["async-std1", "rustls", "dep:futures-rustls"]
|
||||||
|
# deprecated
|
||||||
|
async-std1-rustls-tls = ["async-std1-rustls", "rustls-tls"]
|
||||||
tokio1 = ["dep:tokio1_crate", "dep:async-trait", "dep:futures-io", "dep:futures-util"]
|
tokio1 = ["dep:tokio1_crate", "dep:async-trait", "dep:futures-io", "dep:futures-util"]
|
||||||
tokio1-native-tls = ["tokio1", "native-tls", "dep:tokio1_native_tls_crate"]
|
tokio1-native-tls = ["tokio1", "native-tls", "dep:tokio1_native_tls_crate"]
|
||||||
tokio1-rustls-tls = ["tokio1", "rustls-tls", "dep:tokio1_rustls"]
|
tokio1-rustls = ["tokio1", "rustls", "dep:tokio1_rustls"]
|
||||||
|
# deprecated
|
||||||
|
tokio1-rustls-tls = ["tokio1-rustls", "rustls-tls"]
|
||||||
tokio1-boring-tls = ["tokio1", "boring-tls", "dep:tokio1_boring"]
|
tokio1-boring-tls = ["tokio1", "boring-tls", "dep:tokio1_boring"]
|
||||||
|
|
||||||
dkim = ["dep:base64", "dep:sha2", "dep:rsa", "dep:ed25519-dalek"]
|
dkim = ["dep:base64", "dep:sha2", "dep:rsa", "dep:ed25519-dalek"]
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ impl Executor for Tokio1Executor {
|
|||||||
) -> Result<AsyncSmtpConnection, Error> {
|
) -> Result<AsyncSmtpConnection, Error> {
|
||||||
#[allow(clippy::match_single_binding)]
|
#[allow(clippy::match_single_binding)]
|
||||||
let tls_parameters = match tls {
|
let tls_parameters = match tls {
|
||||||
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))]
|
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls"))]
|
||||||
Tls::Wrapper(tls_parameters) => Some(tls_parameters.clone()),
|
Tls::Wrapper(tls_parameters) => Some(tls_parameters.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
@@ -147,7 +147,7 @@ impl Executor for Tokio1Executor {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls-tls"))]
|
#[cfg(any(feature = "tokio1-native-tls", feature = "tokio1-rustls"))]
|
||||||
match tls {
|
match tls {
|
||||||
Tls::Opportunistic(tls_parameters) => {
|
Tls::Opportunistic(tls_parameters) => {
|
||||||
if conn.can_starttls() {
|
if conn.can_starttls() {
|
||||||
@@ -230,7 +230,7 @@ impl Executor for AsyncStd1Executor {
|
|||||||
) -> Result<AsyncSmtpConnection, Error> {
|
) -> Result<AsyncSmtpConnection, Error> {
|
||||||
#[allow(clippy::match_single_binding)]
|
#[allow(clippy::match_single_binding)]
|
||||||
let tls_parameters = match tls {
|
let tls_parameters = match tls {
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
Tls::Wrapper(tls_parameters) => Some(tls_parameters.clone()),
|
Tls::Wrapper(tls_parameters) => Some(tls_parameters.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
@@ -243,7 +243,7 @@ impl Executor for AsyncStd1Executor {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
match tls {
|
match tls {
|
||||||
Tls::Opportunistic(tls_parameters) => {
|
Tls::Opportunistic(tls_parameters) => {
|
||||||
if conn.can_starttls() {
|
if conn.can_starttls() {
|
||||||
|
|||||||
94
src/lib.rs
94
src/lib.rs
@@ -64,13 +64,46 @@
|
|||||||
//!
|
//!
|
||||||
//! #### SMTP over TLS via the rustls crate
|
//! #### SMTP over TLS via the rustls crate
|
||||||
//!
|
//!
|
||||||
//! _Secure SMTP connections using TLS from the `rustls-tls` crate_
|
//! _Secure SMTP connections using TLS from the `rustls` crate_
|
||||||
//!
|
//!
|
||||||
//! Rustls uses [ring] as the cryptography implementation. As a result, [not all Rust's targets are supported][ring-support].
|
//! * **rustls**: TLS support for the synchronous version of the API
|
||||||
|
//! * **tokio1-rustls**: TLS support for the `tokio1` async version of the API
|
||||||
|
//! * **async-std1-rustls**: TLS support for the `async-std1` async version of the API
|
||||||
//!
|
//!
|
||||||
//! * **rustls-tls**: TLS support for the synchronous version of the API
|
//! ##### rustls crypto backends
|
||||||
//! * **tokio1-rustls-tls**: TLS support for the `tokio1` async version of the API
|
//!
|
||||||
//! * **async-std1-rustls-tls**: TLS support for the `async-std1` async version of the API
|
//! _The crypto implementation to use with rustls_
|
||||||
|
//!
|
||||||
|
//! When the `rustls` feature is enabled, one of the following crypto backends MUST also
|
||||||
|
//! be enabled.
|
||||||
|
//!
|
||||||
|
//! * **aws-lc-rs**: use [AWS-LC] (via [`aws-lc-rs`]) as the `rustls` crypto backend
|
||||||
|
//! * **ring**: use [`ring`] as the `rustls` crypto backend
|
||||||
|
//!
|
||||||
|
//! When enabling `aws-lc-rs`, the `fips` feature can also be enabled to have
|
||||||
|
//! rustls use the FIPS certified module of AWS-LC.
|
||||||
|
//!
|
||||||
|
//! `aws-lc-rs` may require cmake on some platforms to compile.
|
||||||
|
//! `fips` always requires cmake and the Go compiler to compile.
|
||||||
|
//!
|
||||||
|
//! ##### rustls certificate verification backend
|
||||||
|
//!
|
||||||
|
//! _The TLS certificate verification backend to use with rustls_
|
||||||
|
//!
|
||||||
|
//! When the `rustls` feature is enabled, one of the following verification backends
|
||||||
|
//! MUST also be enabled.
|
||||||
|
//!
|
||||||
|
//! * **rustls-native-certs**: verify TLS certificates using the platform's native certificate store (see [`rustls-native-certs`])
|
||||||
|
//! * **webpki-roots**: verify TLS certificates against Mozilla's root certificates (see [`webpki-roots`])
|
||||||
|
//!
|
||||||
|
//! For the `rustls-native-certs` backend to work correctly, the following packages
|
||||||
|
//! will need to be installed in order for the build stage and the compiled program
|
||||||
|
//! to run properly.
|
||||||
|
//!
|
||||||
|
//! | Distro | Build-time packages | Runtime packages |
|
||||||
|
//! | ------------ | -------------------------- | ---------------------------- |
|
||||||
|
//! | Debian | none | `ca-certificates` |
|
||||||
|
//! | Alpine Linux | none | `ca-certificates` |
|
||||||
//!
|
//!
|
||||||
//! ### Sendmail transport
|
//! ### Sendmail transport
|
||||||
//!
|
//!
|
||||||
@@ -115,8 +148,11 @@
|
|||||||
//! [`ContentType`]: crate::message::header::ContentType
|
//! [`ContentType`]: crate::message::header::ContentType
|
||||||
//! [tokio]: https://docs.rs/tokio/1
|
//! [tokio]: https://docs.rs/tokio/1
|
||||||
//! [async-std]: https://docs.rs/async-std/1
|
//! [async-std]: https://docs.rs/async-std/1
|
||||||
//! [ring]: https://github.com/briansmith/ring#ring
|
//! [AWS-LC]: https://github.com/aws/aws-lc
|
||||||
//! [ring-support]: https://github.com/briansmith/ring#online-automated-testing
|
//! [`aws-lc-rs`]: https://crates.io/crates/aws-lc-rs
|
||||||
|
//! [`ring`]: https://crates.io/crates/ring
|
||||||
|
//! [`rustls-native-certs`]: https://crates.io/crates/rustls-native-certs
|
||||||
|
//! [`webpki-roots`]: https://crates.io/crates/webpki-roots
|
||||||
//! [Tokio 1.x]: https://docs.rs/tokio/1
|
//! [Tokio 1.x]: https://docs.rs/tokio/1
|
||||||
//! [async-std 1.x]: https://docs.rs/async-std/1
|
//! [async-std 1.x]: https://docs.rs/async-std/1
|
||||||
//! [mime 0.3]: https://docs.rs/mime/0.3
|
//! [mime 0.3]: https://docs.rs/mime/0.3
|
||||||
@@ -163,6 +199,22 @@
|
|||||||
|
|
||||||
#[cfg(not(lettre_ignore_tls_mismatch))]
|
#[cfg(not(lettre_ignore_tls_mismatch))]
|
||||||
mod compiletime_checks {
|
mod compiletime_checks {
|
||||||
|
#[cfg(all(feature = "rustls", not(feature = "aws-lc-rs"), not(feature = "ring")))]
|
||||||
|
compile_error!(
|
||||||
|
"feature `rustls` also requires either the `aws-lc-rs` or the `ring` feature to
|
||||||
|
be enabled"
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "rustls",
|
||||||
|
not(feature = "rustls-native-certs"),
|
||||||
|
not(feature = "webpki-roots")
|
||||||
|
))]
|
||||||
|
compile_error!(
|
||||||
|
"feature `rustls` also requires either the `rustls-native-certs` or the `webpki-roots` feature to
|
||||||
|
be enabled"
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(all(feature = "native-tls", feature = "boring-tls"))]
|
#[cfg(all(feature = "native-tls", feature = "boring-tls"))]
|
||||||
compile_error!("feature \"native-tls\" and feature \"boring-tls\" cannot be enabled at the same time, otherwise
|
compile_error!("feature \"native-tls\" and feature \"boring-tls\" cannot be enabled at the same time, otherwise
|
||||||
the executable will fail to link.");
|
the executable will fail to link.");
|
||||||
@@ -173,16 +225,12 @@ mod compiletime_checks {
|
|||||||
not(feature = "tokio1-native-tls")
|
not(feature = "tokio1-native-tls")
|
||||||
))]
|
))]
|
||||||
compile_error!("Lettre is being built with the `tokio1` and the `native-tls` features, but the `tokio1-native-tls` feature hasn't been turned on.
|
compile_error!("Lettre is being built with the `tokio1` and the `native-tls` features, but the `tokio1-native-tls` feature hasn't been turned on.
|
||||||
If you were trying to opt into `rustls-tls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
|
If you were trying to opt into `rustls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
|
||||||
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(feature = "tokio1", feature = "rustls", not(feature = "tokio1-rustls")))]
|
||||||
feature = "tokio1",
|
compile_error!("Lettre is being built with the `tokio1` and the `rustls` features, but the `tokio1-rustls` feature hasn't been turned on.
|
||||||
feature = "rustls-tls",
|
If you'd like to use `native-tls` make sure that the `rustls` feature hasn't been enabled by mistake.
|
||||||
not(feature = "tokio1-rustls-tls")
|
|
||||||
))]
|
|
||||||
compile_error!("Lettre is being built with the `tokio1` and the `rustls-tls` features, but the `tokio1-rustls-tls` feature hasn't been turned on.
|
|
||||||
If you'd like to use `native-tls` make sure that the `rustls-tls` feature hasn't been enabled by mistake.
|
|
||||||
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
@@ -191,22 +239,22 @@ mod compiletime_checks {
|
|||||||
not(feature = "tokio1-boring-tls")
|
not(feature = "tokio1-boring-tls")
|
||||||
))]
|
))]
|
||||||
compile_error!("Lettre is being built with the `tokio1` and the `boring-tls` features, but the `tokio1-boring-tls` feature hasn't been turned on.
|
compile_error!("Lettre is being built with the `tokio1` and the `boring-tls` features, but the `tokio1-boring-tls` feature hasn't been turned on.
|
||||||
If you'd like to use `boring-tls` make sure that the `rustls-tls` feature hasn't been enabled by mistake.
|
If you'd like to use `boring-tls` make sure that the `rustls` feature hasn't been enabled by mistake.
|
||||||
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
||||||
|
|
||||||
#[cfg(all(feature = "async-std1", feature = "native-tls",))]
|
#[cfg(all(feature = "async-std1", feature = "native-tls"))]
|
||||||
compile_error!("Lettre is being built with the `async-std1` and the `native-tls` features, but the async-std integration doesn't support native-tls yet.
|
compile_error!("Lettre is being built with the `async-std1` and the `native-tls` features, but the async-std integration doesn't support native-tls yet.
|
||||||
If you'd like to work on the issue please take a look at https://github.com/lettre/lettre/issues/576.
|
If you'd like to work on the issue please take a look at https://github.com/lettre/lettre/issues/576.
|
||||||
If you were trying to opt into `rustls-tls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
|
If you were trying to opt into `rustls` and did not activate `native-tls`, disable the default-features of lettre in `Cargo.toml` and manually add the required features.
|
||||||
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "async-std1",
|
feature = "async-std1",
|
||||||
feature = "rustls-tls",
|
feature = "rustls",
|
||||||
not(feature = "async-std1-rustls-tls")
|
not(feature = "async-std1-rustls")
|
||||||
))]
|
))]
|
||||||
compile_error!("Lettre is being built with the `async-std1` and the `rustls-tls` features, but the `async-std1-rustls-tls` feature hasn't been turned on.
|
compile_error!("Lettre is being built with the `async-std1` and the `rustls` features, but the `async-std1-rustls` feature hasn't been turned on.
|
||||||
If you'd like to use `native-tls` make sure that the `rustls-tls` hasn't been enabled by mistake.
|
If you'd like to use `native-tls` make sure that the `rustls` hasn't been enabled by mistake.
|
||||||
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
Make sure to apply the same to any of your crate dependencies that use the `lettre` crate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +267,8 @@ mod executor;
|
|||||||
#[cfg(feature = "builder")]
|
#[cfg(feature = "builder")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "builder")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "builder")))]
|
||||||
pub mod message;
|
pub mod message;
|
||||||
|
#[cfg(feature = "rustls")]
|
||||||
|
mod rustls_crypto;
|
||||||
mod time;
|
mod time;
|
||||||
pub mod transport;
|
pub mod transport;
|
||||||
|
|
||||||
|
|||||||
14
src/rustls_crypto.rs
Normal file
14
src/rustls_crypto.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rustls::crypto::CryptoProvider;
|
||||||
|
|
||||||
|
pub(crate) fn crypto_provider() -> Arc<CryptoProvider> {
|
||||||
|
CryptoProvider::get_default().cloned().unwrap_or_else(|| {
|
||||||
|
#[cfg(feature = "aws-lc-rs")]
|
||||||
|
let provider = rustls::crypto::aws_lc_rs::default_provider();
|
||||||
|
#[cfg(not(feature = "aws-lc-rs"))]
|
||||||
|
let provider = rustls::crypto::ring::default_provider();
|
||||||
|
|
||||||
|
Arc::new(provider)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -14,8 +14,8 @@ use super::pool::async_impl::Pool;
|
|||||||
use super::PoolConfig;
|
use super::PoolConfig;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
))]
|
))]
|
||||||
use super::Tls;
|
use super::Tls;
|
||||||
use super::{
|
use super::{
|
||||||
@@ -111,15 +111,15 @@ where
|
|||||||
/// to validate TLS certificates.
|
/// to validate TLS certificates.
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
))]
|
))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
)))
|
)))
|
||||||
)]
|
)]
|
||||||
pub fn relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
pub fn relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
||||||
@@ -145,15 +145,15 @@ where
|
|||||||
/// or emails will be sent to the server, protecting from downgrade attacks.
|
/// or emails will be sent to the server, protecting from downgrade attacks.
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
))]
|
))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
)))
|
)))
|
||||||
)]
|
)]
|
||||||
pub fn starttls_relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
pub fn starttls_relay(relay: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
||||||
@@ -288,10 +288,10 @@ where
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn from_url(connection_url: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
pub fn from_url(connection_url: &str) -> Result<AsyncSmtpTransportBuilder, Error> {
|
||||||
super::connection_url::from_connection_url(connection_url)
|
super::connection_url::from_connection_url(connection_url)
|
||||||
@@ -416,15 +416,15 @@ impl AsyncSmtpTransportBuilder {
|
|||||||
/// lead to hard to debug IO errors coming from the TLS library.
|
/// lead to hard to debug IO errors coming from the TLS library.
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
))]
|
))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(
|
doc(cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
)))
|
)))
|
||||||
)]
|
)]
|
||||||
pub fn tls(mut self, tls: Tls) -> Self {
|
pub fn tls(mut self, tls: Tls) -> Self {
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ impl AsyncSmtpConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The X509 certificate of the server (DER encoded)
|
/// The X509 certificate of the server (DER encoded)
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
||||||
self.stream.get_ref().peer_certificate()
|
self.stream.get_ref().peer_certificate()
|
||||||
}
|
}
|
||||||
@@ -397,7 +397,7 @@ impl AsyncSmtpConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// All the X509 certificates of the chain (DER encoded)
|
/// All the X509 certificates of the chain (DER encoded)
|
||||||
#[cfg(any(feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
||||||
self.stream.get_ref().certificate_chain()
|
self.stream.get_ref().certificate_chain()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ use futures_io::{
|
|||||||
AsyncRead as FuturesAsyncRead, AsyncWrite as FuturesAsyncWrite, Error as IoError, ErrorKind,
|
AsyncRead as FuturesAsyncRead, AsyncWrite as FuturesAsyncWrite, Error as IoError, ErrorKind,
|
||||||
Result as IoResult,
|
Result as IoResult,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
use futures_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
|
use futures_rustls::client::TlsStream as AsyncStd1RustlsTlsStream;
|
||||||
#[cfg(any(feature = "tokio1-rustls-tls", feature = "async-std1-rustls-tls"))]
|
#[cfg(any(feature = "tokio1-rustls", feature = "async-std1-rustls"))]
|
||||||
use rustls::pki_types::ServerName;
|
use rustls::pki_types::ServerName;
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
use tokio1_boring::SslStream as Tokio1SslStream;
|
use tokio1_boring::SslStream as Tokio1SslStream;
|
||||||
@@ -27,14 +27,14 @@ use tokio1_crate::net::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream;
|
use tokio1_native_tls_crate::TlsStream as Tokio1TlsStream;
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream;
|
use tokio1_rustls::client::TlsStream as Tokio1RustlsTlsStream;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "tokio1-boring-tls",
|
feature = "tokio1-boring-tls",
|
||||||
feature = "async-std1-rustls-tls"
|
feature = "async-std1-rustls"
|
||||||
))]
|
))]
|
||||||
use super::InnerTlsParameters;
|
use super::InnerTlsParameters;
|
||||||
use super::TlsParameters;
|
use super::TlsParameters;
|
||||||
@@ -78,7 +78,7 @@ enum InnerAsyncNetworkStream {
|
|||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
Tokio1NativeTls(Tokio1TlsStream<Box<dyn AsyncTokioStream>>),
|
Tokio1NativeTls(Tokio1TlsStream<Box<dyn AsyncTokioStream>>),
|
||||||
/// Encrypted Tokio 1.x TCP stream
|
/// Encrypted Tokio 1.x TCP stream
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
Tokio1RustlsTls(Tokio1RustlsTlsStream<Box<dyn AsyncTokioStream>>),
|
Tokio1RustlsTls(Tokio1RustlsTlsStream<Box<dyn AsyncTokioStream>>),
|
||||||
/// Encrypted Tokio 1.x TCP stream
|
/// Encrypted Tokio 1.x TCP stream
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
@@ -87,7 +87,7 @@ enum InnerAsyncNetworkStream {
|
|||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
AsyncStd1Tcp(AsyncStd1TcpStream),
|
AsyncStd1Tcp(AsyncStd1TcpStream),
|
||||||
/// Encrypted Tokio 1.x TCP stream
|
/// Encrypted Tokio 1.x TCP stream
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
AsyncStd1RustlsTls(AsyncStd1RustlsTlsStream<AsyncStd1TcpStream>),
|
AsyncStd1RustlsTls(AsyncStd1RustlsTlsStream<AsyncStd1TcpStream>),
|
||||||
/// Can't be built
|
/// Can't be built
|
||||||
None,
|
None,
|
||||||
@@ -112,13 +112,13 @@ impl AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::Tokio1NativeTls(s) => {
|
InnerAsyncNetworkStream::Tokio1NativeTls(s) => {
|
||||||
s.get_ref().get_ref().get_ref().peer_addr()
|
s.get_ref().get_ref().get_ref().peer_addr()
|
||||||
}
|
}
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => s.get_ref().0.peer_addr(),
|
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => s.get_ref().0.peer_addr(),
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(s) => s.get_ref().peer_addr(),
|
InnerAsyncNetworkStream::Tokio1BoringTls(s) => s.get_ref().peer_addr(),
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => s.peer_addr(),
|
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => s.peer_addr(),
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => s.get_ref().0.peer_addr(),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => s.get_ref().0.peer_addr(),
|
||||||
InnerAsyncNetworkStream::None => {
|
InnerAsyncNetworkStream::None => {
|
||||||
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
||||||
@@ -258,18 +258,18 @@ impl AsyncNetworkStream {
|
|||||||
feature = "tokio1",
|
feature = "tokio1",
|
||||||
not(any(
|
not(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "tokio1-boring-tls"
|
feature = "tokio1-boring-tls"
|
||||||
))
|
))
|
||||||
))]
|
))]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(_) => {
|
InnerAsyncNetworkStream::Tokio1Tcp(_) => {
|
||||||
let _ = tls_parameters;
|
let _ = tls_parameters;
|
||||||
panic!("Trying to upgrade an AsyncNetworkStream without having enabled either the tokio1-native-tls or the tokio1-rustls-tls feature");
|
panic!("Trying to upgrade an AsyncNetworkStream without having enabled either the tokio1-native-tls or the tokio1-rustls feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "tokio1-boring-tls"
|
feature = "tokio1-boring-tls"
|
||||||
))]
|
))]
|
||||||
InnerAsyncNetworkStream::Tokio1Tcp(_) => {
|
InnerAsyncNetworkStream::Tokio1Tcp(_) => {
|
||||||
@@ -284,13 +284,13 @@ impl AsyncNetworkStream {
|
|||||||
.map_err(error::connection)?;
|
.map_err(error::connection)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(all(feature = "async-std1", not(feature = "async-std1-rustls-tls")))]
|
#[cfg(all(feature = "async-std1", not(feature = "async-std1-rustls")))]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
||||||
let _ = tls_parameters;
|
let _ = tls_parameters;
|
||||||
panic!("Trying to upgrade an AsyncNetworkStream without having enabled the async-std1-rustls-tls feature");
|
panic!("Trying to upgrade an AsyncNetworkStream without having enabled the async-std1-rustls feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
||||||
// get owned TcpStream
|
// get owned TcpStream
|
||||||
let tcp_stream = mem::replace(&mut self.inner, InnerAsyncNetworkStream::None);
|
let tcp_stream = mem::replace(&mut self.inner, InnerAsyncNetworkStream::None);
|
||||||
@@ -310,7 +310,7 @@ impl AsyncNetworkStream {
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "tokio1-native-tls",
|
feature = "tokio1-native-tls",
|
||||||
feature = "tokio1-rustls-tls",
|
feature = "tokio1-rustls",
|
||||||
feature = "tokio1-boring-tls"
|
feature = "tokio1-boring-tls"
|
||||||
))]
|
))]
|
||||||
async fn upgrade_tokio1_tls(
|
async fn upgrade_tokio1_tls(
|
||||||
@@ -337,12 +337,12 @@ impl AsyncNetworkStream {
|
|||||||
Ok(InnerAsyncNetworkStream::Tokio1NativeTls(stream))
|
Ok(InnerAsyncNetworkStream::Tokio1NativeTls(stream))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerTlsParameters::RustlsTls(config) => {
|
InnerTlsParameters::RustlsTls(config) => {
|
||||||
#[cfg(not(feature = "tokio1-rustls-tls"))]
|
#[cfg(not(feature = "tokio1-rustls"))]
|
||||||
panic!("built without the tokio1-rustls-tls feature");
|
panic!("built without the tokio1-rustls feature");
|
||||||
|
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
return {
|
return {
|
||||||
use tokio1_rustls::TlsConnector;
|
use tokio1_rustls::TlsConnector;
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ impl AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
async fn upgrade_asyncstd1_tls(
|
async fn upgrade_asyncstd1_tls(
|
||||||
tcp_stream: AsyncStd1TcpStream,
|
tcp_stream: AsyncStd1TcpStream,
|
||||||
mut tls_parameters: TlsParameters,
|
mut tls_parameters: TlsParameters,
|
||||||
@@ -389,12 +389,12 @@ impl AsyncNetworkStream {
|
|||||||
InnerTlsParameters::NativeTls(connector) => {
|
InnerTlsParameters::NativeTls(connector) => {
|
||||||
panic!("native-tls isn't supported with async-std yet. See https://github.com/lettre/lettre/pull/531#issuecomment-757893531");
|
panic!("native-tls isn't supported with async-std yet. See https://github.com/lettre/lettre/pull/531#issuecomment-757893531");
|
||||||
}
|
}
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerTlsParameters::RustlsTls(config) => {
|
InnerTlsParameters::RustlsTls(config) => {
|
||||||
#[cfg(not(feature = "async-std1-rustls-tls"))]
|
#[cfg(not(feature = "async-std1-rustls"))]
|
||||||
panic!("built without the async-std1-rustls-tls feature");
|
panic!("built without the async-std1-rustls feature");
|
||||||
|
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
return {
|
return {
|
||||||
use futures_rustls::TlsConnector;
|
use futures_rustls::TlsConnector;
|
||||||
|
|
||||||
@@ -422,13 +422,13 @@ impl AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::Tokio1Tcp(_) => false,
|
InnerAsyncNetworkStream::Tokio1Tcp(_) => false,
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(_) => true,
|
InnerAsyncNetworkStream::Tokio1NativeTls(_) => true,
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(_) => true,
|
InnerAsyncNetworkStream::Tokio1RustlsTls(_) => true,
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(_) => true,
|
InnerAsyncNetworkStream::Tokio1BoringTls(_) => true,
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => false,
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => false,
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(_) => true,
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(_) => true,
|
||||||
InnerAsyncNetworkStream::None => false,
|
InnerAsyncNetworkStream::None => false,
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ impl AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(_) => panic!("Unsupported"),
|
InnerAsyncNetworkStream::Tokio1NativeTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(_) => panic!("Unsupported"),
|
InnerAsyncNetworkStream::Tokio1RustlsTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(stream) => {
|
InnerAsyncNetworkStream::Tokio1BoringTls(stream) => {
|
||||||
@@ -453,7 +453,7 @@ impl AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
||||||
Err(error::client("Connection is not encrypted"))
|
Err(error::client("Connection is not encrypted"))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(_) => panic!("Unsupported"),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(_) => panic!("Unsupported"),
|
||||||
InnerAsyncNetworkStream::None => panic!("InnerNetworkStream::None must never be built"),
|
InnerAsyncNetworkStream::None => panic!("InnerNetworkStream::None must never be built"),
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ impl AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(_) => panic!("Unsupported"),
|
InnerAsyncNetworkStream::Tokio1NativeTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(stream) => Ok(stream
|
InnerAsyncNetworkStream::Tokio1RustlsTls(stream) => Ok(stream
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
@@ -487,7 +487,7 @@ impl AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
||||||
Err(error::client("Connection is not encrypted"))
|
Err(error::client("Connection is not encrypted"))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(stream) => Ok(stream
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(stream) => Ok(stream
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
@@ -514,7 +514,7 @@ impl AsyncNetworkStream {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_der()
|
.to_der()
|
||||||
.map_err(error::tls)?),
|
.map_err(error::tls)?),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(stream) => Ok(stream
|
InnerAsyncNetworkStream::Tokio1RustlsTls(stream) => Ok(stream
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
@@ -534,7 +534,7 @@ impl AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
InnerAsyncNetworkStream::AsyncStd1Tcp(_) => {
|
||||||
Err(error::client("Connection is not encrypted"))
|
Err(error::client("Connection is not encrypted"))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(stream) => Ok(stream
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(stream) => Ok(stream
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.1
|
.1
|
||||||
@@ -574,7 +574,7 @@ impl FuturesAsyncRead for AsyncNetworkStream {
|
|||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => {
|
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => {
|
||||||
let mut b = Tokio1ReadBuf::new(buf);
|
let mut b = Tokio1ReadBuf::new(buf);
|
||||||
match Pin::new(s).poll_read(cx, &mut b) {
|
match Pin::new(s).poll_read(cx, &mut b) {
|
||||||
@@ -594,7 +594,7 @@ impl FuturesAsyncRead for AsyncNetworkStream {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_read(cx, buf),
|
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_read(cx, buf),
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_read(cx, buf),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_read(cx, buf),
|
||||||
InnerAsyncNetworkStream::None => {
|
InnerAsyncNetworkStream::None => {
|
||||||
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
||||||
@@ -616,13 +616,13 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_write(cx, buf),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_write(cx, buf),
|
||||||
InnerAsyncNetworkStream::None => {
|
InnerAsyncNetworkStream::None => {
|
||||||
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
||||||
@@ -637,13 +637,13 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_flush(cx),
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_flush(cx),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_flush(cx),
|
||||||
InnerAsyncNetworkStream::None => {
|
InnerAsyncNetworkStream::None => {
|
||||||
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
||||||
@@ -658,13 +658,13 @@ impl FuturesAsyncWrite for AsyncNetworkStream {
|
|||||||
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_shutdown(cx),
|
InnerAsyncNetworkStream::Tokio1Tcp(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
#[cfg(feature = "tokio1-native-tls")]
|
#[cfg(feature = "tokio1-native-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_shutdown(cx),
|
InnerAsyncNetworkStream::Tokio1NativeTls(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
#[cfg(feature = "tokio1-rustls-tls")]
|
#[cfg(feature = "tokio1-rustls")]
|
||||||
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_shutdown(cx),
|
InnerAsyncNetworkStream::Tokio1RustlsTls(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
#[cfg(feature = "tokio1-boring-tls")]
|
#[cfg(feature = "tokio1-boring-tls")]
|
||||||
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_shutdown(cx),
|
InnerAsyncNetworkStream::Tokio1BoringTls(s) => Pin::new(s).poll_shutdown(cx),
|
||||||
#[cfg(feature = "async-std1")]
|
#[cfg(feature = "async-std1")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_close(cx),
|
InnerAsyncNetworkStream::AsyncStd1Tcp(s) => Pin::new(s).poll_close(cx),
|
||||||
#[cfg(feature = "async-std1-rustls-tls")]
|
#[cfg(feature = "async-std1-rustls")]
|
||||||
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_close(cx),
|
InnerAsyncNetworkStream::AsyncStd1RustlsTls(s) => Pin::new(s).poll_close(cx),
|
||||||
InnerAsyncNetworkStream::None => {
|
InnerAsyncNetworkStream::None => {
|
||||||
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
debug_assert!(false, "InnerAsyncNetworkStream::None must never be built");
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ impl SmtpConnection {
|
|||||||
hello_name: &ClientId,
|
hello_name: &ClientId,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if self.server_info.supports_feature(Extension::StartTls) {
|
if self.server_info.supports_feature(Extension::StartTls) {
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
{
|
{
|
||||||
try_smtp!(self.command(Starttls), self);
|
try_smtp!(self.command(Starttls), self);
|
||||||
self.stream.get_mut().upgrade_tls(tls_parameters)?;
|
self.stream.get_mut().upgrade_tls(tls_parameters)?;
|
||||||
@@ -153,11 +153,7 @@ impl SmtpConnection {
|
|||||||
try_smtp!(self.ehlo(hello_name), self);
|
try_smtp!(self.ehlo(hello_name), self);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))]
|
||||||
feature = "native-tls",
|
|
||||||
feature = "rustls-tls",
|
|
||||||
feature = "boring-tls"
|
|
||||||
)))]
|
|
||||||
// This should never happen as `Tls` can only be created
|
// This should never happen as `Tls` can only be created
|
||||||
// when a TLS library is enabled
|
// when a TLS library is enabled
|
||||||
unreachable!("TLS support required but not supported");
|
unreachable!("TLS support required but not supported");
|
||||||
@@ -303,7 +299,7 @@ impl SmtpConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The X509 certificate of the server (DER encoded)
|
/// The X509 certificate of the server (DER encoded)
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
||||||
self.stream.get_ref().peer_certificate()
|
self.stream.get_ref().peer_certificate()
|
||||||
}
|
}
|
||||||
@@ -325,7 +321,7 @@ impl SmtpConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// All the X509 certificates of the chain (DER encoded)
|
/// All the X509 certificates of the chain (DER encoded)
|
||||||
#[cfg(any(feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
||||||
self.stream.get_ref().certificate_chain()
|
self.stream.get_ref().certificate_chain()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ pub use self::async_net::AsyncNetworkStream;
|
|||||||
#[cfg(feature = "tokio1")]
|
#[cfg(feature = "tokio1")]
|
||||||
pub use self::async_net::AsyncTokioStream;
|
pub use self::async_net::AsyncTokioStream;
|
||||||
use self::net::NetworkStream;
|
use self::net::NetworkStream;
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub(super) use self::tls::InnerTlsParameters;
|
pub(super) use self::tls::InnerTlsParameters;
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub use self::tls::TlsVersion;
|
pub use self::tls::TlsVersion;
|
||||||
pub use self::{
|
pub use self::{
|
||||||
connection::SmtpConnection,
|
connection::SmtpConnection,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{
|
use std::{
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
@@ -11,11 +11,11 @@ use std::{
|
|||||||
use boring::ssl::SslStream;
|
use boring::ssl::SslStream;
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
use native_tls::TlsStream;
|
use native_tls::TlsStream;
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
use rustls::{pki_types::ServerName, ClientConnection, StreamOwned};
|
use rustls::{pki_types::ServerName, ClientConnection, StreamOwned};
|
||||||
use socket2::{Domain, Protocol, Type};
|
use socket2::{Domain, Protocol, Type};
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
use super::InnerTlsParameters;
|
use super::InnerTlsParameters;
|
||||||
use super::TlsParameters;
|
use super::TlsParameters;
|
||||||
use crate::transport::smtp::{error, Error};
|
use crate::transport::smtp::{error, Error};
|
||||||
@@ -36,7 +36,7 @@ enum InnerNetworkStream {
|
|||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
NativeTls(TlsStream<TcpStream>),
|
NativeTls(TlsStream<TcpStream>),
|
||||||
/// Encrypted TCP stream
|
/// Encrypted TCP stream
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
RustlsTls(StreamOwned<ClientConnection, TcpStream>),
|
RustlsTls(StreamOwned<ClientConnection, TcpStream>),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
BoringTls(SslStream<TcpStream>),
|
BoringTls(SslStream<TcpStream>),
|
||||||
@@ -59,7 +59,7 @@ impl NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(s) => s.peer_addr(),
|
InnerNetworkStream::Tcp(s) => s.peer_addr(),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(s) => s.get_ref().peer_addr(),
|
InnerNetworkStream::NativeTls(s) => s.get_ref().peer_addr(),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(s) => s.get_ref().peer_addr(),
|
InnerNetworkStream::RustlsTls(s) => s.get_ref().peer_addr(),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(s) => s.get_ref().peer_addr(),
|
InnerNetworkStream::BoringTls(s) => s.get_ref().peer_addr(),
|
||||||
@@ -79,7 +79,7 @@ impl NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(s) => s.shutdown(how),
|
InnerNetworkStream::Tcp(s) => s.shutdown(how),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(s) => s.get_ref().shutdown(how),
|
InnerNetworkStream::NativeTls(s) => s.get_ref().shutdown(how),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(s) => s.get_ref().shutdown(how),
|
InnerNetworkStream::RustlsTls(s) => s.get_ref().shutdown(how),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(s) => s.get_ref().shutdown(how),
|
InnerNetworkStream::BoringTls(s) => s.get_ref().shutdown(how),
|
||||||
@@ -146,17 +146,13 @@ impl NetworkStream {
|
|||||||
|
|
||||||
pub fn upgrade_tls(&mut self, tls_parameters: &TlsParameters) -> Result<(), Error> {
|
pub fn upgrade_tls(&mut self, tls_parameters: &TlsParameters) -> Result<(), Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))]
|
||||||
feature = "native-tls",
|
|
||||||
feature = "rustls-tls",
|
|
||||||
feature = "boring-tls"
|
|
||||||
)))]
|
|
||||||
InnerNetworkStream::Tcp(_) => {
|
InnerNetworkStream::Tcp(_) => {
|
||||||
let _ = tls_parameters;
|
let _ = tls_parameters;
|
||||||
panic!("Trying to upgrade an NetworkStream without having enabled either the native-tls or the rustls-tls feature");
|
panic!("Trying to upgrade an NetworkStream without having enabled either the `native-tls` or the `rustls` feature");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
InnerNetworkStream::Tcp(_) => {
|
InnerNetworkStream::Tcp(_) => {
|
||||||
// get owned TcpStream
|
// get owned TcpStream
|
||||||
let tcp_stream = mem::replace(&mut self.inner, InnerNetworkStream::None);
|
let tcp_stream = mem::replace(&mut self.inner, InnerNetworkStream::None);
|
||||||
@@ -171,7 +167,7 @@ impl NetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
fn upgrade_tls_impl(
|
fn upgrade_tls_impl(
|
||||||
tcp_stream: TcpStream,
|
tcp_stream: TcpStream,
|
||||||
tls_parameters: &TlsParameters,
|
tls_parameters: &TlsParameters,
|
||||||
@@ -184,7 +180,7 @@ impl NetworkStream {
|
|||||||
.map_err(error::connection)?;
|
.map_err(error::connection)?;
|
||||||
InnerNetworkStream::NativeTls(stream)
|
InnerNetworkStream::NativeTls(stream)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerTlsParameters::RustlsTls(connector) => {
|
InnerTlsParameters::RustlsTls(connector) => {
|
||||||
let domain = ServerName::try_from(tls_parameters.domain())
|
let domain = ServerName::try_from(tls_parameters.domain())
|
||||||
.map_err(|_| error::connection("domain isn't a valid DNS name"))?;
|
.map_err(|_| error::connection("domain isn't a valid DNS name"))?;
|
||||||
@@ -211,7 +207,7 @@ impl NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(_) => false,
|
InnerNetworkStream::Tcp(_) => false,
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(_) => true,
|
InnerNetworkStream::NativeTls(_) => true,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(_) => true,
|
InnerNetworkStream::RustlsTls(_) => true,
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(_) => true,
|
InnerNetworkStream::BoringTls(_) => true,
|
||||||
@@ -228,7 +224,7 @@ impl NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(_) => panic!("Unsupported"),
|
InnerNetworkStream::NativeTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(_) => panic!("Unsupported"),
|
InnerNetworkStream::RustlsTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(stream) => {
|
InnerNetworkStream::BoringTls(stream) => {
|
||||||
@@ -238,13 +234,13 @@ impl NetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
pub fn certificate_chain(&self) -> Result<Vec<Vec<u8>>, Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(_) => panic!("Unsupported"),
|
InnerNetworkStream::NativeTls(_) => panic!("Unsupported"),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(stream) => Ok(stream
|
InnerNetworkStream::RustlsTls(stream) => Ok(stream
|
||||||
.conn
|
.conn
|
||||||
.peer_certificates()
|
.peer_certificates()
|
||||||
@@ -264,7 +260,7 @@ impl NetworkStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
pub fn peer_certificate(&self) -> Result<Vec<u8>, Error> {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
InnerNetworkStream::Tcp(_) => Err(error::client("Connection is not encrypted")),
|
||||||
@@ -275,7 +271,7 @@ impl NetworkStream {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.to_der()
|
.to_der()
|
||||||
.map_err(error::tls)?),
|
.map_err(error::tls)?),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(stream) => Ok(stream
|
InnerNetworkStream::RustlsTls(stream) => Ok(stream
|
||||||
.conn
|
.conn
|
||||||
.peer_certificates()
|
.peer_certificates()
|
||||||
@@ -299,7 +295,7 @@ impl NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(stream) => stream.set_read_timeout(duration),
|
InnerNetworkStream::Tcp(stream) => stream.set_read_timeout(duration),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(stream) => stream.get_ref().set_read_timeout(duration),
|
InnerNetworkStream::NativeTls(stream) => stream.get_ref().set_read_timeout(duration),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(stream) => stream.get_ref().set_read_timeout(duration),
|
InnerNetworkStream::RustlsTls(stream) => stream.get_ref().set_read_timeout(duration),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(stream) => stream.get_ref().set_read_timeout(duration),
|
InnerNetworkStream::BoringTls(stream) => stream.get_ref().set_read_timeout(duration),
|
||||||
@@ -317,7 +313,7 @@ impl NetworkStream {
|
|||||||
|
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(stream) => stream.get_ref().set_write_timeout(duration),
|
InnerNetworkStream::NativeTls(stream) => stream.get_ref().set_write_timeout(duration),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(stream) => stream.get_ref().set_write_timeout(duration),
|
InnerNetworkStream::RustlsTls(stream) => stream.get_ref().set_write_timeout(duration),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(stream) => stream.get_ref().set_write_timeout(duration),
|
InnerNetworkStream::BoringTls(stream) => stream.get_ref().set_write_timeout(duration),
|
||||||
@@ -335,7 +331,7 @@ impl Read for NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(s) => s.read(buf),
|
InnerNetworkStream::Tcp(s) => s.read(buf),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(s) => s.read(buf),
|
InnerNetworkStream::NativeTls(s) => s.read(buf),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(s) => s.read(buf),
|
InnerNetworkStream::RustlsTls(s) => s.read(buf),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(s) => s.read(buf),
|
InnerNetworkStream::BoringTls(s) => s.read(buf),
|
||||||
@@ -353,7 +349,7 @@ impl Write for NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(s) => s.write(buf),
|
InnerNetworkStream::Tcp(s) => s.write(buf),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(s) => s.write(buf),
|
InnerNetworkStream::NativeTls(s) => s.write(buf),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(s) => s.write(buf),
|
InnerNetworkStream::RustlsTls(s) => s.write(buf),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(s) => s.write(buf),
|
InnerNetworkStream::BoringTls(s) => s.write(buf),
|
||||||
@@ -369,7 +365,7 @@ impl Write for NetworkStream {
|
|||||||
InnerNetworkStream::Tcp(s) => s.flush(),
|
InnerNetworkStream::Tcp(s) => s.flush(),
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
InnerNetworkStream::NativeTls(s) => s.flush(),
|
InnerNetworkStream::NativeTls(s) => s.flush(),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
InnerNetworkStream::RustlsTls(s) => s.flush(),
|
InnerNetworkStream::RustlsTls(s) => s.flush(),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
InnerNetworkStream::BoringTls(s) => s.flush(),
|
InnerNetworkStream::BoringTls(s) => s.flush(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
@@ -10,7 +10,7 @@ use boring::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
use native_tls::{Protocol, TlsConnector};
|
use native_tls::{Protocol, TlsConnector};
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
use rustls::{
|
use rustls::{
|
||||||
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||||
crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider},
|
crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider},
|
||||||
@@ -19,13 +19,13 @@ use rustls::{
|
|||||||
ClientConfig, DigitallySignedStruct, Error as TlsError, RootCertStore, SignatureScheme,
|
ClientConfig, DigitallySignedStruct, Error as TlsError, RootCertStore, SignatureScheme,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
use crate::transport::smtp::{error, Error};
|
use crate::transport::smtp::{error, Error};
|
||||||
|
|
||||||
/// TLS protocol versions.
|
/// TLS protocol versions.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub enum TlsVersion {
|
pub enum TlsVersion {
|
||||||
/// TLS 1.0
|
/// TLS 1.0
|
||||||
///
|
///
|
||||||
@@ -85,10 +85,10 @@ pub enum Tls {
|
|||||||
///
|
///
|
||||||
/// Warning: A malicious intermediary could intercept the `STARTTLS` flag,
|
/// Warning: A malicious intermediary could intercept the `STARTTLS` flag,
|
||||||
/// causing lettre to believe the server only supports plaintext connections.
|
/// causing lettre to believe the server only supports plaintext connections.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
Opportunistic(TlsParameters),
|
Opportunistic(TlsParameters),
|
||||||
/// Begin with a plaintext connection and require `STARTTLS` for security.
|
/// Begin with a plaintext connection and require `STARTTLS` for security.
|
||||||
@@ -100,10 +100,10 @@ pub enum Tls {
|
|||||||
/// Unlike [`Tls::Opportunistic`], this option is secure against MITM attacks.
|
/// Unlike [`Tls::Opportunistic`], this option is secure against MITM attacks.
|
||||||
/// For optimal security and performance, consider using [`Tls::Wrapper`] instead,
|
/// For optimal security and performance, consider using [`Tls::Wrapper`] instead,
|
||||||
/// as it requires fewer roundtrips to establish a secure connection.
|
/// as it requires fewer roundtrips to establish a secure connection.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
Required(TlsParameters),
|
Required(TlsParameters),
|
||||||
/// Establish a connection wrapped in TLS from the start.
|
/// Establish a connection wrapped in TLS from the start.
|
||||||
@@ -113,10 +113,10 @@ pub enum Tls {
|
|||||||
/// transmitting any sensitive data.
|
/// transmitting any sensitive data.
|
||||||
///
|
///
|
||||||
/// This is the fastest and most secure option for establishing a connection.
|
/// This is the fastest and most secure option for establishing a connection.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
Wrapper(TlsParameters),
|
Wrapper(TlsParameters),
|
||||||
}
|
}
|
||||||
@@ -125,11 +125,11 @@ impl Debug for Tls {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match &self {
|
match &self {
|
||||||
Self::None => f.pad("None"),
|
Self::None => f.pad("None"),
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Self::Opportunistic(_) => f.pad("Opportunistic"),
|
Self::Opportunistic(_) => f.pad("Opportunistic"),
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Self::Required(_) => f.pad("Required"),
|
Self::Required(_) => f.pad("Required"),
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Self::Wrapper(_) => f.pad("Wrapper"),
|
Self::Wrapper(_) => f.pad("Wrapper"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ pub enum CertificateStore {
|
|||||||
/// Use a hardcoded set of Mozilla roots via the `webpki-roots` crate.
|
/// Use a hardcoded set of Mozilla roots via the `webpki-roots` crate.
|
||||||
///
|
///
|
||||||
/// This option is only available in the rustls backend.
|
/// This option is only available in the rustls backend.
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(all(feature = "rustls", feature = "webpki-roots"))]
|
||||||
WebpkiRoots,
|
WebpkiRoots,
|
||||||
/// Don't use any system certificates.
|
/// Don't use any system certificates.
|
||||||
None,
|
None,
|
||||||
@@ -178,7 +178,7 @@ pub struct TlsParametersBuilder {
|
|||||||
identity: Option<Identity>,
|
identity: Option<Identity>,
|
||||||
accept_invalid_hostnames: bool,
|
accept_invalid_hostnames: bool,
|
||||||
accept_invalid_certs: bool,
|
accept_invalid_certs: bool,
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
min_tls_version: TlsVersion,
|
min_tls_version: TlsVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ impl TlsParametersBuilder {
|
|||||||
identity: None,
|
identity: None,
|
||||||
accept_invalid_hostnames: false,
|
accept_invalid_hostnames: false,
|
||||||
accept_invalid_certs: false,
|
accept_invalid_certs: false,
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
min_tls_version: TlsVersion::Tlsv12,
|
min_tls_version: TlsVersion::Tlsv12,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,10 +230,10 @@ impl TlsParametersBuilder {
|
|||||||
/// including those from other sites, are trusted.
|
/// including those from other sites, are trusted.
|
||||||
///
|
///
|
||||||
/// This method introduces significant vulnerabilities to man-in-the-middle attacks.
|
/// This method introduces significant vulnerabilities to man-in-the-middle attacks.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn dangerous_accept_invalid_hostnames(mut self, accept_invalid_hostnames: bool) -> Self {
|
pub fn dangerous_accept_invalid_hostnames(mut self, accept_invalid_hostnames: bool) -> Self {
|
||||||
self.accept_invalid_hostnames = accept_invalid_hostnames;
|
self.accept_invalid_hostnames = accept_invalid_hostnames;
|
||||||
@@ -243,7 +243,7 @@ impl TlsParametersBuilder {
|
|||||||
/// Controls which minimum TLS version is allowed
|
/// Controls which minimum TLS version is allowed
|
||||||
///
|
///
|
||||||
/// Defaults to [`Tlsv12`][TlsVersion::Tlsv12].
|
/// Defaults to [`Tlsv12`][TlsVersion::Tlsv12].
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub fn set_min_tls_version(mut self, min_tls_version: TlsVersion) -> Self {
|
pub fn set_min_tls_version(mut self, min_tls_version: TlsVersion) -> Self {
|
||||||
self.min_tls_version = min_tls_version;
|
self.min_tls_version = min_tls_version;
|
||||||
self
|
self
|
||||||
@@ -272,17 +272,17 @@ impl TlsParametersBuilder {
|
|||||||
|
|
||||||
/// Creates a new `TlsParameters` using native-tls, boring-tls or rustls
|
/// Creates a new `TlsParameters` using native-tls, boring-tls or rustls
|
||||||
/// depending on which one is available
|
/// depending on which one is available
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn build(self) -> Result<TlsParameters, Error> {
|
pub fn build(self) -> Result<TlsParameters, Error> {
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
return self.build_rustls();
|
return self.build_rustls();
|
||||||
#[cfg(all(not(feature = "rustls-tls"), feature = "native-tls"))]
|
#[cfg(all(not(feature = "rustls"), feature = "native-tls"))]
|
||||||
return self.build_native();
|
return self.build_native();
|
||||||
#[cfg(all(not(feature = "rustls-tls"), feature = "boring-tls"))]
|
#[cfg(all(not(feature = "rustls"), feature = "boring-tls"))]
|
||||||
return self.build_boring();
|
return self.build_boring();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,8 +396,8 @@ impl TlsParametersBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `TlsParameters` using rustls with the provided configuration
|
/// Creates a new `TlsParameters` using rustls with the provided configuration
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
|
||||||
pub fn build_rustls(self) -> Result<TlsParameters, Error> {
|
pub fn build_rustls(self) -> Result<TlsParameters, Error> {
|
||||||
let just_version3 = &[&rustls::version::TLS13];
|
let just_version3 = &[&rustls::version::TLS13];
|
||||||
let supported_versions = match self.min_tls_version {
|
let supported_versions = match self.min_tls_version {
|
||||||
@@ -411,9 +411,7 @@ impl TlsParametersBuilder {
|
|||||||
TlsVersion::Tlsv13 => just_version3,
|
TlsVersion::Tlsv13 => just_version3,
|
||||||
};
|
};
|
||||||
|
|
||||||
let crypto_provider = CryptoProvider::get_default()
|
let crypto_provider = crate::rustls_crypto::crypto_provider();
|
||||||
.cloned()
|
|
||||||
.unwrap_or_else(|| Arc::new(rustls::crypto::ring::default_provider()));
|
|
||||||
let tls = ClientConfig::builder_with_provider(Arc::clone(&crypto_provider))
|
let tls = ClientConfig::builder_with_provider(Arc::clone(&crypto_provider))
|
||||||
.with_protocol_versions(supported_versions)
|
.with_protocol_versions(supported_versions)
|
||||||
.map_err(error::tls)?;
|
.map_err(error::tls)?;
|
||||||
@@ -436,7 +434,7 @@ impl TlsParametersBuilder {
|
|||||||
let _ = (errors_len, added, ignored);
|
let _ = (errors_len, added, ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(all(feature = "rustls", feature = "webpki-roots"))]
|
||||||
fn load_webpki_roots(store: &mut RootCertStore) {
|
fn load_webpki_roots(store: &mut RootCertStore) {
|
||||||
store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||||
}
|
}
|
||||||
@@ -445,10 +443,10 @@ impl TlsParametersBuilder {
|
|||||||
CertificateStore::Default => {
|
CertificateStore::Default => {
|
||||||
#[cfg(feature = "rustls-native-certs")]
|
#[cfg(feature = "rustls-native-certs")]
|
||||||
load_native_roots(&mut root_cert_store);
|
load_native_roots(&mut root_cert_store);
|
||||||
#[cfg(not(feature = "rustls-native-certs"))]
|
#[cfg(all(not(feature = "rustls-native-certs"), feature = "webpki-roots"))]
|
||||||
load_webpki_roots(&mut root_cert_store);
|
load_webpki_roots(&mut root_cert_store);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(all(feature = "rustls", feature = "webpki-roots"))]
|
||||||
CertificateStore::WebpkiRoots => {
|
CertificateStore::WebpkiRoots => {
|
||||||
load_webpki_roots(&mut root_cert_store);
|
load_webpki_roots(&mut root_cert_store);
|
||||||
}
|
}
|
||||||
@@ -495,7 +493,7 @@ impl TlsParametersBuilder {
|
|||||||
pub enum InnerTlsParameters {
|
pub enum InnerTlsParameters {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
NativeTls(TlsConnector),
|
NativeTls(TlsConnector),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
RustlsTls(Arc<ClientConfig>),
|
RustlsTls(Arc<ClientConfig>),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
BoringTls(SslConnector),
|
BoringTls(SslConnector),
|
||||||
@@ -504,10 +502,10 @@ pub enum InnerTlsParameters {
|
|||||||
impl TlsParameters {
|
impl TlsParameters {
|
||||||
/// Creates a new `TlsParameters` using native-tls or rustls
|
/// Creates a new `TlsParameters` using native-tls or rustls
|
||||||
/// depending on which one is available
|
/// depending on which one is available
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn new(domain: String) -> Result<Self, Error> {
|
pub fn new(domain: String) -> Result<Self, Error> {
|
||||||
TlsParametersBuilder::new(domain).build()
|
TlsParametersBuilder::new(domain).build()
|
||||||
@@ -526,8 +524,8 @@ impl TlsParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `TlsParameters` using rustls
|
/// Creates a new `TlsParameters` using rustls
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "rustls-tls")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
|
||||||
pub fn new_rustls(domain: String) -> Result<Self, Error> {
|
pub fn new_rustls(domain: String) -> Result<Self, Error> {
|
||||||
TlsParametersBuilder::new(domain).build_rustls()
|
TlsParametersBuilder::new(domain).build_rustls()
|
||||||
}
|
}
|
||||||
@@ -550,13 +548,13 @@ impl TlsParameters {
|
|||||||
pub struct Certificate {
|
pub struct Certificate {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: native_tls::Certificate,
|
native_tls: native_tls::Certificate,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls: Vec<CertificateDer<'static>>,
|
rustls: Vec<CertificateDer<'static>>,
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: boring::x509::X509,
|
boring_tls: boring::x509::X509,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
impl Certificate {
|
impl Certificate {
|
||||||
/// Create a `Certificate` from a DER encoded certificate
|
/// Create a `Certificate` from a DER encoded certificate
|
||||||
pub fn from_der(der: Vec<u8>) -> Result<Self, Error> {
|
pub fn from_der(der: Vec<u8>) -> Result<Self, Error> {
|
||||||
@@ -569,7 +567,7 @@ impl Certificate {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: native_tls_cert,
|
native_tls: native_tls_cert,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls: vec![der.into()],
|
rustls: vec![der.into()],
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: boring_tls_cert,
|
boring_tls: boring_tls_cert,
|
||||||
@@ -584,7 +582,7 @@ impl Certificate {
|
|||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
let boring_tls_cert = boring::x509::X509::from_pem(pem).map_err(error::tls)?;
|
let boring_tls_cert = boring::x509::X509::from_pem(pem).map_err(error::tls)?;
|
||||||
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
let rustls_cert = {
|
let rustls_cert = {
|
||||||
CertificateDer::pem_slice_iter(pem)
|
CertificateDer::pem_slice_iter(pem)
|
||||||
.collect::<Result<Vec<_>, pki_types::pem::Error>>()
|
.collect::<Result<Vec<_>, pki_types::pem::Error>>()
|
||||||
@@ -594,7 +592,7 @@ impl Certificate {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: native_tls_cert,
|
native_tls: native_tls_cert,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls: rustls_cert,
|
rustls: rustls_cert,
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: boring_tls_cert,
|
boring_tls: boring_tls_cert,
|
||||||
@@ -613,7 +611,7 @@ impl Debug for Certificate {
|
|||||||
pub struct Identity {
|
pub struct Identity {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: native_tls::Identity,
|
native_tls: native_tls::Identity,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls_tls: (Vec<CertificateDer<'static>>, PrivateKeyDer<'static>),
|
rustls_tls: (Vec<CertificateDer<'static>>, PrivateKeyDer<'static>),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: (boring::x509::X509, PKey<boring::pkey::Private>),
|
boring_tls: (boring::x509::X509, PKey<boring::pkey::Private>),
|
||||||
@@ -630,7 +628,7 @@ impl Clone for Identity {
|
|||||||
Identity {
|
Identity {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: self.native_tls.clone(),
|
native_tls: self.native_tls.clone(),
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls_tls: (self.rustls_tls.0.clone(), self.rustls_tls.1.clone_key()),
|
rustls_tls: (self.rustls_tls.0.clone(), self.rustls_tls.1.clone_key()),
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: (self.boring_tls.0.clone(), self.boring_tls.1.clone()),
|
boring_tls: (self.boring_tls.0.clone(), self.boring_tls.1.clone()),
|
||||||
@@ -638,13 +636,13 @@ impl Clone for Identity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
impl Identity {
|
impl Identity {
|
||||||
pub fn from_pem(pem: &[u8], key: &[u8]) -> Result<Self, Error> {
|
pub fn from_pem(pem: &[u8], key: &[u8]) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
#[cfg(feature = "native-tls")]
|
#[cfg(feature = "native-tls")]
|
||||||
native_tls: Identity::from_pem_native_tls(pem, key)?,
|
native_tls: Identity::from_pem_native_tls(pem, key)?,
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
rustls_tls: Identity::from_pem_rustls_tls(pem, key)?,
|
rustls_tls: Identity::from_pem_rustls_tls(pem, key)?,
|
||||||
#[cfg(feature = "boring-tls")]
|
#[cfg(feature = "boring-tls")]
|
||||||
boring_tls: Identity::from_pem_boring_tls(pem, key)?,
|
boring_tls: Identity::from_pem_boring_tls(pem, key)?,
|
||||||
@@ -656,7 +654,7 @@ impl Identity {
|
|||||||
native_tls::Identity::from_pkcs8(pem, key).map_err(error::tls)
|
native_tls::Identity::from_pkcs8(pem, key).map_err(error::tls)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
fn from_pem_rustls_tls(
|
fn from_pem_rustls_tls(
|
||||||
pem: &[u8],
|
pem: &[u8],
|
||||||
key: &[u8],
|
key: &[u8],
|
||||||
@@ -683,7 +681,7 @@ impl Identity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct InvalidCertsVerifier {
|
struct InvalidCertsVerifier {
|
||||||
ignore_invalid_hostnames: bool,
|
ignore_invalid_hostnames: bool,
|
||||||
@@ -692,7 +690,7 @@ struct InvalidCertsVerifier {
|
|||||||
crypto_provider: Arc<CryptoProvider>,
|
crypto_provider: Arc<CryptoProvider>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls-tls")]
|
#[cfg(feature = "rustls")]
|
||||||
impl ServerCertVerifier for InvalidCertsVerifier {
|
impl ServerCertVerifier for InvalidCertsVerifier {
|
||||||
fn verify_server_cert(
|
fn verify_server_cert(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
use super::client::{Tls, TlsParameters};
|
use super::client::{Tls, TlsParameters};
|
||||||
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
#[cfg(any(feature = "tokio1", feature = "async-std1"))]
|
||||||
use super::AsyncSmtpTransportBuilder;
|
use super::AsyncSmtpTransportBuilder;
|
||||||
@@ -82,19 +82,19 @@ pub(crate) fn from_connection_url<B: TransportBuilder>(connection_url: &str) ->
|
|||||||
("smtp", None) => {
|
("smtp", None) => {
|
||||||
builder = builder.port(connection_url.port().unwrap_or(SMTP_PORT));
|
builder = builder.port(connection_url.port().unwrap_or(SMTP_PORT));
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
("smtp", Some("required")) => {
|
("smtp", Some("required")) => {
|
||||||
builder = builder
|
builder = builder
|
||||||
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
|
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
|
||||||
.tls(Tls::Required(TlsParameters::new(host.into())?));
|
.tls(Tls::Required(TlsParameters::new(host.into())?));
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
("smtp", Some("opportunistic")) => {
|
("smtp", Some("opportunistic")) => {
|
||||||
builder = builder
|
builder = builder
|
||||||
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
|
.port(connection_url.port().unwrap_or(SUBMISSION_PORT))
|
||||||
.tls(Tls::Opportunistic(TlsParameters::new(host.into())?));
|
.tls(Tls::Opportunistic(TlsParameters::new(host.into())?));
|
||||||
}
|
}
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
("smtps", _) => {
|
("smtps", _) => {
|
||||||
builder = builder
|
builder = builder
|
||||||
.port(connection_url.port().unwrap_or(SUBMISSIONS_PORT))
|
.port(connection_url.port().unwrap_or(SUBMISSIONS_PORT))
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the error is from TLS
|
/// Returns true if the error is from TLS
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn is_tls(&self) -> bool {
|
pub fn is_tls(&self) -> bool {
|
||||||
matches!(self.inner.kind, Kind::Tls)
|
matches!(self.inner.kind, Kind::Tls)
|
||||||
@@ -107,9 +107,9 @@ pub(crate) enum Kind {
|
|||||||
/// TLS error
|
/// TLS error
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Tls,
|
Tls,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ impl fmt::Display for Error {
|
|||||||
Kind::Client => f.write_str("internal client error")?,
|
Kind::Client => f.write_str("internal client error")?,
|
||||||
Kind::Network => f.write_str("network error")?,
|
Kind::Network => f.write_str("network error")?,
|
||||||
Kind::Connection => f.write_str("Connection error")?,
|
Kind::Connection => f.write_str("Connection error")?,
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Kind::Tls => f.write_str("tls error")?,
|
Kind::Tls => f.write_str("tls error")?,
|
||||||
Kind::Transient(code) => {
|
Kind::Transient(code) => {
|
||||||
write!(f, "transient error ({code})")?;
|
write!(f, "transient error ({code})")?;
|
||||||
@@ -185,7 +185,7 @@ pub(crate) fn connection<E: Into<BoxError>>(e: E) -> Error {
|
|||||||
Error::new(Kind::Connection, Some(e))
|
Error::new(Kind::Connection, Some(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
pub(crate) fn tls<E: Into<BoxError>>(e: E) -> Error {
|
pub(crate) fn tls<E: Into<BoxError>>(e: E) -> Error {
|
||||||
Error::new(Kind::Tls, Some(e))
|
Error::new(Kind::Tls, Some(e))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
//! do the following:
|
//! do the following:
|
||||||
//!
|
//!
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))]
|
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls")))]
|
||||||
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! use lettre::{
|
//! use lettre::{
|
||||||
//! message::header::ContentType,
|
//! message::header::ContentType,
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
//! For more information take a look at [`SmtpTransport::from_url`] or [`AsyncSmtpTransport::from_url`].
|
//! For more information take a look at [`SmtpTransport::from_url`] or [`AsyncSmtpTransport::from_url`].
|
||||||
//!
|
//!
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))]
|
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls")))]
|
||||||
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! use lettre::{
|
//! use lettre::{
|
||||||
//! message::header::ContentType,
|
//! message::header::ContentType,
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
//! #### Advanced configuration with custom TLS settings
|
//! #### Advanced configuration with custom TLS settings
|
||||||
//!
|
//!
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))]
|
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls")))]
|
||||||
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn test() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! use std::fs;
|
//! use std::fs;
|
||||||
//!
|
//!
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
//! In a webserver context it may go about this:
|
//! In a webserver context it may go about this:
|
||||||
//!
|
//!
|
||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls-tls")))]
|
//! # #[cfg(all(feature = "builder", any(feature = "native-tls", feature = "rustls")))]
|
||||||
//! # fn test() {
|
//! # fn test() {
|
||||||
//! use lettre::{
|
//! use lettre::{
|
||||||
//! message::header::ContentType,
|
//! message::header::ContentType,
|
||||||
@@ -199,7 +199,7 @@ pub use self::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
transport::{SmtpTransport, SmtpTransportBuilder},
|
transport::{SmtpTransport, SmtpTransportBuilder},
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
use crate::transport::smtp::client::TlsParameters;
|
use crate::transport::smtp::client::TlsParameters;
|
||||||
use crate::transport::smtp::{
|
use crate::transport::smtp::{
|
||||||
authentication::{Credentials, Mechanism, DEFAULT_MECHANISMS},
|
authentication::{Credentials, Mechanism, DEFAULT_MECHANISMS},
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use super::pool::sync_impl::Pool;
|
|||||||
#[cfg(feature = "pool")]
|
#[cfg(feature = "pool")]
|
||||||
use super::PoolConfig;
|
use super::PoolConfig;
|
||||||
use super::{ClientId, Credentials, Error, Mechanism, Response, SmtpConnection, SmtpInfo};
|
use super::{ClientId, Credentials, Error, Mechanism, Response, SmtpConnection, SmtpInfo};
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
use super::{Tls, TlsParameters, SUBMISSIONS_PORT, SUBMISSION_PORT};
|
use super::{Tls, TlsParameters, SUBMISSIONS_PORT, SUBMISSION_PORT};
|
||||||
use crate::{address::Envelope, Transport};
|
use crate::{address::Envelope, Transport};
|
||||||
|
|
||||||
@@ -77,10 +77,10 @@ impl SmtpTransport {
|
|||||||
///
|
///
|
||||||
/// Creates an encrypted transport over submissions port, using the provided domain
|
/// Creates an encrypted transport over submissions port, using the provided domain
|
||||||
/// to validate TLS certificates.
|
/// to validate TLS certificates.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn relay(relay: &str) -> Result<SmtpTransportBuilder, Error> {
|
pub fn relay(relay: &str) -> Result<SmtpTransportBuilder, Error> {
|
||||||
let tls_parameters = TlsParameters::new(relay.into())?;
|
let tls_parameters = TlsParameters::new(relay.into())?;
|
||||||
@@ -101,10 +101,10 @@ impl SmtpTransport {
|
|||||||
///
|
///
|
||||||
/// An error is returned if the connection can't be upgraded. No credentials
|
/// An error is returned if the connection can't be upgraded. No credentials
|
||||||
/// or emails will be sent to the server, protecting from downgrade attacks.
|
/// or emails will be sent to the server, protecting from downgrade attacks.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn starttls_relay(relay: &str) -> Result<SmtpTransportBuilder, Error> {
|
pub fn starttls_relay(relay: &str) -> Result<SmtpTransportBuilder, Error> {
|
||||||
let tls_parameters = TlsParameters::new(relay.into())?;
|
let tls_parameters = TlsParameters::new(relay.into())?;
|
||||||
@@ -230,10 +230,10 @@ impl SmtpTransport {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn from_url(connection_url: &str) -> Result<SmtpTransportBuilder, Error> {
|
pub fn from_url(connection_url: &str) -> Result<SmtpTransportBuilder, Error> {
|
||||||
super::connection_url::from_connection_url(connection_url)
|
super::connection_url::from_connection_url(connection_url)
|
||||||
@@ -333,10 +333,10 @@ impl SmtpTransportBuilder {
|
|||||||
///
|
///
|
||||||
/// Using the wrong [`Tls`] and [`Self::port`] combination may
|
/// Using the wrong [`Tls`] and [`Self::port`] combination may
|
||||||
/// lead to hard to debug IO errors coming from the TLS library.
|
/// lead to hard to debug IO errors coming from the TLS library.
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
docsrs,
|
docsrs,
|
||||||
doc(cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls")))
|
doc(cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls")))
|
||||||
)]
|
)]
|
||||||
pub fn tls(mut self, tls: Tls) -> Self {
|
pub fn tls(mut self, tls: Tls) -> Self {
|
||||||
self.info.tls = tls;
|
self.info.tls = tls;
|
||||||
@@ -380,7 +380,7 @@ impl SmtpClient {
|
|||||||
pub fn connection(&self) -> Result<SmtpConnection, Error> {
|
pub fn connection(&self) -> Result<SmtpConnection, Error> {
|
||||||
#[allow(clippy::match_single_binding)]
|
#[allow(clippy::match_single_binding)]
|
||||||
let tls_parameters = match &self.info.tls {
|
let tls_parameters = match &self.info.tls {
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
Tls::Wrapper(tls_parameters) => Some(tls_parameters),
|
Tls::Wrapper(tls_parameters) => Some(tls_parameters),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
@@ -394,7 +394,7 @@ impl SmtpClient {
|
|||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
#[cfg(any(feature = "native-tls", feature = "rustls-tls", feature = "boring-tls"))]
|
#[cfg(any(feature = "native-tls", feature = "rustls", feature = "boring-tls"))]
|
||||||
match &self.info.tls {
|
match &self.info.tls {
|
||||||
Tls::Opportunistic(tls_parameters) => {
|
Tls::Opportunistic(tls_parameters) => {
|
||||||
if conn.can_starttls() {
|
if conn.can_starttls() {
|
||||||
|
|||||||
Reference in New Issue
Block a user