From c9116830c27baf0c547a1524d33363fd5e42295a Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Mon, 15 Jul 2024 08:09:45 -0700 Subject: [PATCH] mux: augment PKI SAN list with getaddrinfo AI_CANONNAME This should hopefully make things a bit easier to consume for remote clients. refs: https://github.com/wez/wezterm/issues/5543 --- Cargo.lock | 14 +++++++++++ docs/changelog.md | 3 +++ wezterm-mux-server-impl/Cargo.toml | 2 ++ wezterm-mux-server-impl/src/pki.rs | 39 ++++++++++++++++++++++++------ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6f6f1fb3..3ee07bae9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1302,6 +1302,18 @@ dependencies = [ "libloading 0.8.4", ] +[[package]] +name = "dns-lookup" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc" +dependencies = [ + "cfg-if", + "libc", + "socket2", + "windows-sys 0.48.0", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -6415,9 +6427,11 @@ dependencies = [ "async_ossl", "codec", "config", + "dns-lookup", "futures", "hostname", "lazy_static", + "libc", "log", "mux", "portable-pty", diff --git a/docs/changelog.md b/docs/changelog.md index 398724268..d3afceb21 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -95,6 +95,9 @@ As features stabilize some brief notes about them will accumulate here. with an ssh session. Thanks to @daaku! #5494 #5479 * `default_ssh_domains()` didn't use the default local echo threshold for ssh domains. #5547 +* multiplexer: internal PKI certificate now supplements its list of + "Subject Alternative Names" with the list of canonical hostnames returned + for the local system via `getaddrinfo`. #5543 #### Updated * Bundled conpty.dll and OpenConsole.exe to build 1.19.240130002.nupkg diff --git a/wezterm-mux-server-impl/Cargo.toml b/wezterm-mux-server-impl/Cargo.toml index 228931e42..fba5c8f03 100644 --- a/wezterm-mux-server-impl/Cargo.toml +++ b/wezterm-mux-server-impl/Cargo.toml @@ -13,9 +13,11 @@ async_ossl = { path = "../async_ossl" } async-io = "2.3" codec = { path = "../codec" } config = { path = "../config" } +dns-lookup = "2.0" futures = "0.3" hostname = "0.4" lazy_static = "1.4" +libc = "0.2" log = "0.4" mux = { path = "../mux" } portable-pty = { path = "../pty", features = ["serde_support"]} diff --git a/wezterm-mux-server-impl/src/pki.rs b/wezterm-mux-server-impl/src/pki.rs index ff3de9d81..817c6d31f 100644 --- a/wezterm-mux-server-impl/src/pki.rs +++ b/wezterm-mux-server-impl/src/pki.rs @@ -1,6 +1,10 @@ use anyhow::{anyhow, Context as _}; +#[cfg(unix)] +use libc::{AF_UNSPEC, AI_CANONNAME, SOCK_DGRAM}; use rcgen::{BasicConstraints, Certificate, CertificateParams, DistinguishedName, DnType, IsCa}; use std::path::PathBuf; +#[cfg(windows)] +use winapi::shared::ws2def::{AF_UNSPEC, AI_CANONNAME, SOCK_DGRAM}; /// A helper for managing keys for the TLS server component. /// Each time the server is started, a new CA is generated @@ -22,14 +26,35 @@ impl Pki { pub fn init() -> anyhow::Result { let pki_dir = config::pki_dir()?; std::fs::create_dir_all(&pki_dir)?; - log::error!("runtime dir is {}", pki_dir.display()); + log::debug!("pki dir is {}", pki_dir.display()); + + let hostname = hostname::get()? + .into_string() + .map_err(|_| anyhow!("hostname is not representable as unicode"))?; + + let mut alt_names = vec![hostname.clone(), "localhost".to_owned()]; + + let hints = dns_lookup::AddrInfoHints { + flags: AI_CANONNAME, + address: AF_UNSPEC, + socktype: SOCK_DGRAM, + protocol: 0, + }; + + if let Ok(iter) = dns_lookup::getaddrinfo(Some(&hostname), None, Some(hints)) { + for entry in iter { + if let Ok(entry) = entry { + if let Some(canon) = entry.canonname { + alt_names.push(canon); + } + } + } + } + + alt_names.sort(); + alt_names.dedup(); + log::debug!("generating cert with alt_names={alt_names:?}"); - let alt_names = vec![ - hostname::get()? - .into_string() - .map_err(|_| anyhow!("hostname is not representable as unicode"))?, - "localhost".to_owned(), - ]; let unix_name = config::username_from_env()?; // Create the CA certificate