feat: add handling of tls cert for delegated hosts

This commit is contained in:
Gabriel Souza Franco 2021-04-15 22:07:27 -03:00
parent 18398e1f17
commit 0b56589dce
5 changed files with 82 additions and 128 deletions

View file

@ -5,6 +5,6 @@ $ sudo usermod -aG docker $USER
$ exec sudo su -l $USER
$ sudo systemctl start docker
$ cargo install cross
$ cross build --release --features tls_vendored --target armv7-unknown-linux-musleabihf
$ cross build --release --target armv7-unknown-linux-musleabihf
```
The cross-compiled binary is at target/armv7-unknown-linux-musleabihf/release/conduit

151
Cargo.lock generated
View file

@ -198,6 +198,8 @@ dependencies = [
"rocket",
"ruma",
"rust-argon2",
"rustls",
"rustls-native-certs",
"serde",
"serde_json",
"serde_yaml",
@ -209,6 +211,7 @@ dependencies = [
"tracing-opentelemetry",
"tracing-subscriber",
"trust-dns-resolver",
"webpki",
]
[[package]]
@ -420,21 +423,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.0.1"
@ -716,16 +704,18 @@ dependencies = [
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
name = "hyper-rustls"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64"
dependencies = [
"bytes",
"futures-util",
"hyper",
"native-tls",
"log",
"rustls",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"webpki",
]
[[package]]
@ -1001,24 +991,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "native-tls"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ntapi"
version = "0.3.6"
@ -1096,49 +1068,12 @@ version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "openssl"
version = "0.10.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-sys",
]
[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
[[package]]
name = "openssl-src"
version = "111.15.0+1.1.1k"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
dependencies = [
"autocfg",
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "opentelemetry"
version = "0.12.0"
@ -1280,12 +1215,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "png"
version = "0.16.8"
@ -1486,15 +1415,6 @@ version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "reqwest"
version = "0.11.3"
@ -1509,19 +1429,20 @@ dependencies = [
"http",
"http-body",
"hyper",
"hyper-tls",
"hyper-rustls",
"ipnet",
"js-sys",
"lazy_static",
"log",
"mime",
"native-tls",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-native-certs",
"serde",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
@ -1886,6 +1807,18 @@ dependencies = [
"webpki",
]
[[package]]
name = "rustls-native-certs"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092"
dependencies = [
"openssl-probe",
"rustls",
"schannel",
"security-framework",
]
[[package]]
name = "ryu"
version = "1.0.5"
@ -2191,20 +2124,6 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tempfile"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall 0.2.5",
"remove_dir_all",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.1.2"
@ -2358,16 +2277,6 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.22.0"
@ -2613,12 +2522,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "vcpkg"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
[[package]]
name = "version_check"
version = "0.9.3"

View file

@ -49,7 +49,11 @@ rand = "0.8.3"
# Used to hash passwords
rust-argon2 = "0.8.3"
# Used to send requests
reqwest = { version = "0.11.1" }
reqwest = { version = "0.11.3", default-features = false, features = ["rustls-tls-native-roots"] }
# Custom TLS verifier
rustls = { version = "0.19", features = ["dangerous_configuration"] }
rustls-native-certs = "0.5.0"
webpki = "0.21.0"
# Used for conduit::Error type
thiserror = "1.0.24"
# Used to generate thumbnails for images
@ -75,7 +79,6 @@ pretty_env_logger = "0.4.0"
[features]
default = ["conduit_bin"]
conduit_bin = [] # TODO: add rocket to this when it is optional
tls_vendored = ["reqwest/native-tls-vendored"]
[[bin]]
name = "conduit"

View file

@ -10,13 +10,16 @@ use std::{
time::Duration,
};
use trust_dns_resolver::TokioAsyncResolver;
use rustls::{ServerCertVerifier, WebPKIVerifier};
pub const COUNTER: &str = "c";
type WellKnownMap = HashMap<Box<ServerName>, (String, String)>;
type TlsNameMap = HashMap<String, webpki::DNSName>;
#[derive(Clone)]
pub struct Globals {
pub actual_destination_cache: Arc<RwLock<WellKnownMap>>, // actual_destination, host
pub tls_name_override: Arc<RwLock<TlsNameMap>>,
pub(super) globals: sled::Tree,
config: Config,
keypair: Arc<ruma::signatures::Ed25519KeyPair>,
@ -26,6 +29,33 @@ pub struct Globals {
pub(super) servertimeout_signingkey: sled::Tree, // ServerName + Timeout Timestamp -> algorithm:key + pubkey
}
struct MatrixServerVerifier {
inner: WebPKIVerifier,
tls_name_override: Arc<RwLock<TlsNameMap>>,
}
impl ServerCertVerifier for MatrixServerVerifier {
fn verify_server_cert(
&self,
roots: &rustls::RootCertStore,
presented_certs: &[rustls::Certificate],
dns_name: webpki::DNSNameRef<'_>,
ocsp_response: &[u8],
) -> std::result::Result<rustls::ServerCertVerified, rustls::TLSError> {
let cache = self.tls_name_override.read().unwrap();
log::debug!("Searching for override for {:?}", dns_name);
log::debug!("Cache: {:?}", cache);
let override_name = match cache.get(dns_name.into()) {
Some(host) => {
log::debug!("Override found! {:?}", host);
host.as_ref()
},
None => dns_name
};
self.inner.verify_server_cert(roots, presented_certs, override_name, ocsp_response)
}
}
impl Globals {
pub fn load(
globals: sled::Tree,
@ -66,10 +96,17 @@ impl Globals {
}
};
let tls_name_override = Arc::new(RwLock::new(TlsNameMap::new()));
let verifier = Arc::new(MatrixServerVerifier { inner: WebPKIVerifier::new(), tls_name_override: tls_name_override.clone() });
let mut tlsconfig = rustls::ClientConfig::new();
tlsconfig.dangerous().set_certificate_verifier(verifier);
tlsconfig.root_store = rustls_native_certs::load_native_certs().expect("Error loading system certificates");
let reqwest_client = reqwest::Client::builder()
.connect_timeout(Duration::from_secs(30))
.timeout(Duration::from_secs(60 * 3))
.pool_max_idle_per_host(1)
.use_preconfigured_tls(tlsconfig)
.build()
.unwrap();
@ -86,7 +123,8 @@ impl Globals {
dns_resolver: TokioAsyncResolver::tokio_from_system_conf().map_err(|_| {
Error::bad_config("Failed to set up trust dns resolver with system config.")
})?,
actual_destination_cache: Arc::new(RwLock::new(HashMap::new())),
actual_destination_cache: Arc::new(RwLock::new(WellKnownMap::new())),
tls_name_override,
servertimeout_signingkey,
jwt_decoding_key,
})

View file

@ -74,6 +74,16 @@ where
.write()
.unwrap()
.insert(Box::<ServerName>::from(destination), result.clone());
let actual_destination = result.0.strip_prefix("https://").unwrap().splitn(2, ':').next().unwrap();
let host = result.1.splitn(2, ':').next().unwrap_or(&result.1);
if actual_destination != host {
globals.tls_name_override.write().unwrap().insert(
actual_destination.to_owned(),
webpki::DNSNameRef::try_from_ascii_str(&host)
.unwrap()
.to_owned(),
);
}
result
};