diff --git a/Cargo.lock b/Cargo.lock index f559241..9ee19c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -181,6 +181,12 @@ dependencies = [ "serde_with", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "bytes" version = "1.5.0" @@ -233,7 +239,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -250,9 +256,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -260,9 +266,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" @@ -320,9 +326,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", ] @@ -340,9 +346,9 @@ dependencies = [ [[package]] name = "fast-socks5" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa6a4a9ab1f87e2d8e9345ce944de7c45d065ee89f5942512f32698e48a8429a" +checksum = "d449e348301d5fb9b0e5781510d8235ffe3bbac3286bd305462736a9e7043039" dependencies = [ "anyhow", "async-trait", @@ -439,7 +445,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -484,20 +490,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "heck" @@ -528,9 +536,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -606,12 +614,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] -name = "jsonwebtoken" -version = "9.1.0" +name = "js-sys" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "9.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" dependencies = [ "base64", + "js-sys", "ring", "serde", "serde_json", @@ -803,7 +821,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -832,9 +850,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -933,9 +951,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "ring" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ "cc", "getrandom", @@ -953,9 +971,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring", @@ -965,25 +983,33 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", "rustls-pemfile", + "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" dependencies = [ "base64", + "rustls-pki-types", ] +[[package]] +name = "rustls-pki-types" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -1065,14 +1091,14 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1158,9 +1184,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" @@ -1213,9 +1239,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1256,7 +1282,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1352,7 +1378,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1402,7 +1428,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1551,6 +1577,60 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + [[package]] name = "winapi" version = "0.3.9" @@ -1655,7 +1735,6 @@ dependencies = [ "futures-util", "hyper", "jsonwebtoken", - "libc", "log", "nix", "once_cell", @@ -1680,20 +1759,20 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.20" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.20" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] diff --git a/Cargo.toml b/Cargo.toml index b56b889..1e5b3cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,54 +3,50 @@ name = "wstunnel" version = "8.1.1" edition = "2021" repository = "https://github.com/erebe/wstunnel.git" - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "4.4.10", features = ["derive"]} -url = "2.5.0" +ahash = { version = "0.8.6", features = [] } anyhow = "1.0.75" +async-trait = "0.1.74" +base64 = "0.21.5" + +bb8 = { version = "0.8", features = [] } +bytes = { version = "1.5.0", features = [] } +clap = { version = "4.4.10", features = ["derive"] } +fast-socks5 = { version = "0.9.1", features = [] } +fastwebsockets = { git = "https://github.com/denoland/fastwebsockets", branch = "main", features = ["upgrade", "simd", "unstable-split"] } +futures-util = { version = "0.3.29" } hyper = { version = "0.14.27", features = ["client", "runtime"] } -fastwebsockets = { git = "https://github.com/denoland/fastwebsockets", branch = "main", features = ["upgrade", "simd", "unstable-split"]} -libc = { version = "0.2.150", features = []} -once_cell = { version = "1.18.0", features = [] } -ahash = { version = "0.8.6", features = []} -pin-project = "1" -scopeguard = "1.2.0" -uuid = { version = "1.6.1", features = ["v7", "serde"] } -jsonwebtoken = { version = "9.1.0", default-features = false } -rustls-pemfile = { version = "1.0.4", features = [] } -bytes = { version = "1.5.0", features = [] } -parking_lot = "0.12.1" -urlencoding = "2.1.3" +jsonwebtoken = { version = "9.1.0", default-features = false } +log = "0.4.20" nix = { version = "0.27.1", features = ["socket", "net", "uio"] } +once_cell = { version = "1.18.0", features = [] } +parking_lot = "0.12.1" +pin-project = "1" -rustls-native-certs = { version = "0.6.3", features = [] } +rustls-native-certs = { version = "0.7.0", features = [] } +rustls-pemfile = { version = "2.0.0", features = [] } +scopeguard = "1.2.0" +serde = { version = "1.0.193", features = ["derive"] } +socket2 = { version = "0.5.5", features = [] } tokio = { version = "1.34.0", features = ["full"] } tokio-rustls = { version = "0.24.1", features = ["tls12", "dangerous_configuration", "early-data"] } tokio-stream = { version = "0.1.14", features = ["net"] } -fast-socks5 = { version = "0.9.1", features = [] } -futures-util = { version = "0.3.29" } tracing = { version = "0.1.40", features = ["log"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter", "fmt", "local-time"] } -base64 = "0.21.5" -serde = { version = "1.0.193", features = ["derive"] } -log = "0.4.20" - -bb8 = { version = "0.8", features = [] } -async-trait = "0.1.74" -socket2 = { version = "0.5.5", features = [] } +url = "2.5.0" +urlencoding = "2.1.3" +uuid = { version = "1.6.1", features = ["v7", "serde"] } [target.'cfg(target_family = "unix")'.dependencies] tokio-fd = "0.3.0" - [dev-dependencies] testcontainers = "0.15.0" - [profile.release] lto = "fat" panic = "abort" diff --git a/src/embedded_certificate.rs b/src/embedded_certificate.rs index 325b1f2..e3c49e4 100644 --- a/src/embedded_certificate.rs +++ b/src/embedded_certificate.rs @@ -1,15 +1,26 @@ +use log::info; use once_cell::sync::Lazy; use tokio_rustls::rustls::{Certificate, PrivateKey}; pub static TLS_PRIVATE_KEY: Lazy = Lazy::new(|| { + info!("Loading embedded tls private key"); + let key = include_bytes!("../certs/key.pem"); - let mut keys = - rustls_pemfile::pkcs8_private_keys(&mut key.as_slice()).expect("failed to load embedded tls private key"); - PrivateKey(keys.remove(0)) + let key = rustls_pemfile::private_key(&mut key.as_slice()) + .expect("failed to load embedded tls private key") + .expect("failed to load embedded tls private key"); + PrivateKey(key.secret_der().to_vec()) }); pub static TLS_CERTIFICATE: Lazy> = Lazy::new(|| { - let cert = include_bytes!("../certs/cert.pem"); - let certs = rustls_pemfile::certs(&mut cert.as_slice()).expect("failed to load embedded tls certificate"); + info!("Loading embedded tls certificate"); - certs.into_iter().map(Certificate).collect() + let cert = include_bytes!("../certs/cert.pem"); + let certs = rustls_pemfile::certs(&mut cert.as_slice()) + .next() + .expect("failed to load embedded tls certificate"); + + certs + .into_iter() + .map(|cert| Certificate(cert.as_ref().to_vec())) + .collect() }); diff --git a/src/main.rs b/src/main.rs index 82cfe5c..56f996c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,7 +77,7 @@ struct Client { /// (linux only) Mark network packet with SO_MARK sockoption with the specified value. /// You need to use {root, sudo, capabilities} to run wstunnel when using this option #[arg(long, value_name = "INT", verbatim_doc_comment)] - socket_so_mark: Option, + socket_so_mark: Option, /// Client will maintain a pool of open connection to the server, in order to speed up the connection process. /// This option set the maximum number of connection that will be kept open. @@ -141,7 +141,7 @@ struct Server { /// (linux only) Mark network packet with SO_MARK sockoption with the specified value. /// You need to use {root, sudo, capabilities} to run wstunnel when using this option #[arg(long, value_name = "INT", verbatim_doc_comment)] - socket_so_mark: Option, + socket_so_mark: Option, /// Frequency at which the server will send websocket ping to client. #[arg(long, value_name = "seconds", value_parser = parse_duration_sec, verbatim_doc_comment)] @@ -438,7 +438,7 @@ pub struct TlsServerConfig { #[derive(Clone)] pub struct WsServerConfig { - pub socket_so_mark: Option, + pub socket_so_mark: Option, pub bind: SocketAddr, pub restrict_to: Option>, pub restrict_http_upgrade_path_prefix: Option>, @@ -465,7 +465,7 @@ impl Debug for WsServerConfig { #[derive(Clone, Debug)] pub struct WsClientConfig { pub remote_addr: (Host, u16), - pub socket_so_mark: Option, + pub socket_so_mark: Option, pub tls: Option, pub http_upgrade_path_prefix: String, pub http_upgrade_credentials: Option, diff --git a/src/stdio.rs b/src/stdio.rs index c9ee40c..ddf5ba2 100644 --- a/src/stdio.rs +++ b/src/stdio.rs @@ -3,8 +3,8 @@ use tokio_fd::AsyncFd; pub async fn run_server() -> Result<(AsyncFd, AsyncFd), anyhow::Error> { eprintln!("Starting STDIO server"); - let stdin = AsyncFd::try_from(libc::STDIN_FILENO)?; - let stdout = AsyncFd::try_from(libc::STDOUT_FILENO)?; + let stdin = AsyncFd::try_from(nix::libc::STDIN_FILENO)?; + let stdout = AsyncFd::try_from(nix::libc::STDOUT_FILENO)?; Ok((stdin, stdout)) } diff --git a/src/tcp.rs b/src/tcp.rs index d957366..710b99d 100644 --- a/src/tcp.rs +++ b/src/tcp.rs @@ -14,27 +14,22 @@ use tracing::debug; use tracing::log::info; use url::{Host, Url}; -fn configure_socket(socket: &mut TcpSocket, so_mark: &Option) -> Result<(), anyhow::Error> { +fn configure_socket(socket: &mut TcpSocket, so_mark: &Option) -> Result<(), anyhow::Error> { socket .set_nodelay(true) .with_context(|| format!("cannot set no_delay on socket: {}", io::Error::last_os_error()))?; #[cfg(target_os = "linux")] if let Some(so_mark) = so_mark { - use std::os::fd::AsRawFd; - unsafe { - let optval: libc::c_int = *so_mark; - let ret = libc::setsockopt( - socket.as_raw_fd(), - libc::SOL_SOCKET, - libc::SO_MARK, - &optval as *const _ as *const libc::c_void, - std::mem::size_of_val(&optval) as libc::socklen_t, - ); + use std::os::fd::AsFd; - if ret != 0 { - return Err(anyhow!("Cannot set SO_MARK on the connection {:?}", io::Error::last_os_error())); - } + let ret = nix::sys::socket::setsockopt(&socket.as_fd(), nix::sys::socket::sockopt::Mark, so_mark); + if let Err(err) = ret { + return Err(anyhow!( + "Cannot set SO_MARK on the connection {:?} {:?}", + err, + io::Error::last_os_error() + )); } } @@ -44,7 +39,7 @@ fn configure_socket(socket: &mut TcpSocket, so_mark: &Option) -> Result<(), pub async fn connect( host: &Host, port: u16, - so_mark: Option, + so_mark: Option, connect_timeout: Duration, ) -> Result { info!("Opening TCP connection to {}:{}", host, port); @@ -103,7 +98,7 @@ pub async fn connect_with_http_proxy( proxy: &Url, host: &Host, port: u16, - so_mark: Option, + so_mark: Option, connect_timeout: Duration, ) -> Result { let proxy_host = proxy.host().context("Cannot parse proxy host")?.to_owned(); diff --git a/src/tls.rs b/src/tls.rs index b700d25..c343c36 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -2,6 +2,7 @@ use crate::{TlsClientConfig, TlsServerConfig, WsClientConfig}; use anyhow::{anyhow, Context}; use std::fs::File; +use log::warn; use std::io::BufReader; use std::path::Path; use std::sync::Arc; @@ -30,23 +31,35 @@ impl ServerCertVerifier for NullVerifier { } pub fn load_certificates_from_pem(path: &Path) -> anyhow::Result> { + info!("Loading tls certificate from {:?}", path); + let file = File::open(path)?; let mut reader = BufReader::new(file); - let certs = rustls_pemfile::certs(&mut reader)?; + let certs = rustls_pemfile::certs(&mut reader); - Ok(certs.into_iter().map(Certificate).collect()) + Ok(certs + .into_iter() + .filter_map(|cert| match cert { + Ok(cert) => Some(Certificate(cert.to_vec())), + Err(err) => { + warn!("Error while parsing tls certificate: {:?}", err); + None + } + }) + .collect()) } pub fn load_private_key_from_file(path: &Path) -> anyhow::Result { + info!("Loading tls private key from {:?}", path); + let file = File::open(path)?; let mut reader = BufReader::new(file); - let mut keys = rustls_pemfile::pkcs8_private_keys(&mut reader)?; - match keys.len() { - 0 => Err(anyhow!("No PKCS8-encoded private key found in {path:?}")), - 1 => Ok(PrivateKey(keys.remove(0))), - _ => Err(anyhow!("More than one PKCS8-encoded private key found in {path:?}")), - } + let Some(private_key) = rustls_pemfile::private_key(&mut reader)? else { + return Err(anyhow!("No private key found in {path:?}")); + }; + + Ok(PrivateKey(private_key.secret_der().to_vec())) } fn tls_connector(tls_cfg: &TlsClientConfig, alpn_protocols: Option>>) -> anyhow::Result { @@ -55,7 +68,7 @@ fn tls_connector(tls_cfg: &TlsClientConfig, alpn_protocols: Option>> // Load system certificates and add them to the root store let certs = rustls_native_certs::load_native_certs().with_context(|| "Cannot load system certificates")?; for cert in certs { - root_store.add(&Certificate(cert.0))?; + root_store.add(&Certificate(cert.as_ref().to_vec()))?; } let mut config = ClientConfig::builder() diff --git a/src/tunnel/client.rs b/src/tunnel/client.rs index fee2ab4..77163bd 100644 --- a/src/tunnel/client.rs +++ b/src/tunnel/client.rs @@ -181,23 +181,19 @@ where ws.set_auto_apply_mask(client_config.websocket_mask_frame); // Connect to endpoint - let remote: (Host, u16) = response + let remote = response .headers() .get(COOKIE) - .and_then(|h| { - h.to_str() - .ok() - .and_then(|s| base64::engine::general_purpose::STANDARD.decode(s).ok()) - .and_then(|s| Url::parse(&String::from_utf8_lossy(&s)).ok()) - .and_then(|url| match (url.host(), url.port()) { - (Some(h), Some(p)) => Some((h.to_owned(), p)), - _ => None, - }) + .and_then(|h| h.to_str().ok()) + .and_then(|h| base64::engine::general_purpose::STANDARD.decode(h).ok()) + .and_then(|h| Url::parse(&String::from_utf8_lossy(&h)).ok()) + .and_then(|url| match (url.host(), url.port()) { + (Some(h), Some(p)) => Some((h.to_owned(), p)), + _ => None, }) .unwrap_or(remote_ori.clone()); - let stream = connect_to_dest(remote.clone()).instrument(span.clone()).await; - let stream = match stream { + let stream = match connect_to_dest(remote.clone()).instrument(span.clone()).await { Ok(s) => s, Err(err) => { error!("Cannot connect to {remote:?}: {err:?}"); diff --git a/src/udp.rs b/src/udp.rs index 11043f0..167fb68 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -377,7 +377,7 @@ pub fn mk_send_socket_tproxy(listener: &Arc) -> anyhow::Result = nix::sys::socket::recvmsg(