mirror of
https://github.com/zellij-org/zellij.git
synced 2026-10-11 22:50:07 +00:00
allow dangerously disabling certificate on non-localhost (#5694)
* allow dangerously disabling certificate on non-localhost * add pr
This commit is contained in:
@@ -1034,6 +1034,9 @@ pub fn start_client(
|
||||
let has_certificate =
|
||||
config_options.web_server_cert.is_some() && config_options.web_server_key.is_some();
|
||||
let enforce_https_for_localhost = config_options.enforce_https_for_localhost.unwrap_or(false);
|
||||
let dangerously_allow_web_serving_without_a_certificate = config_options
|
||||
.dangerously_allow_web_serving_without_a_certificate
|
||||
.unwrap_or(false);
|
||||
|
||||
let terminal_teardown = TerminalTeardown {
|
||||
include_kitty_exit: !explicitly_disable_kitty_keyboard_protocol,
|
||||
@@ -1504,6 +1507,7 @@ pub fn start_client(
|
||||
web_server_port,
|
||||
has_certificate,
|
||||
enforce_https_for_localhost,
|
||||
dangerously_allow_web_serving_without_a_certificate,
|
||||
);
|
||||
match spawn_web_server(&cli_args) {
|
||||
Ok(_) => {
|
||||
|
||||
@@ -101,13 +101,26 @@ pub fn start_web_client(
|
||||
let web_server_key = custom_server_key.or_else(|| config.options.web_server_key.clone());
|
||||
let has_https_certificate = web_server_cert.is_some() && web_server_key.is_some();
|
||||
|
||||
if let Err(e) = should_use_https(
|
||||
match should_use_https(
|
||||
web_server_ip,
|
||||
has_https_certificate,
|
||||
config.options.enforce_https_for_localhost.unwrap_or(false),
|
||||
config
|
||||
.options
|
||||
.dangerously_allow_web_serving_without_a_certificate
|
||||
.unwrap_or(false),
|
||||
) {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(2);
|
||||
Ok(false) if !web_server_ip.is_loopback() => {
|
||||
eprintln!(
|
||||
"WARNING: serving the web client on {} over plain HTTP without an SSL certificate (dangerously_allow_web_serving_without_a_certificate is enabled). Traffic, including login tokens, is not encrypted.",
|
||||
web_server_ip
|
||||
);
|
||||
},
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
std::process::exit(2);
|
||||
},
|
||||
};
|
||||
let (runtime, listener, tls_config) = if run_daemonized {
|
||||
daemonize_web_server(
|
||||
|
||||
@@ -24,18 +24,19 @@ pub fn should_use_https(
|
||||
ip: IpAddr,
|
||||
has_certificate: bool,
|
||||
enforce_https_for_localhost: bool,
|
||||
dangerously_allow_web_serving_without_a_certificate: bool,
|
||||
) -> Result<bool, String> {
|
||||
let is_loopback = match ip {
|
||||
IpAddr::V4(ipv4) => ipv4.is_loopback(),
|
||||
IpAddr::V6(ipv6) => ipv6.is_loopback(),
|
||||
};
|
||||
|
||||
if is_loopback && !enforce_https_for_localhost {
|
||||
Ok(has_certificate)
|
||||
} else if is_loopback {
|
||||
Err(format!("Cannot bind without an SSL certificate."))
|
||||
} else if has_certificate {
|
||||
if has_certificate {
|
||||
Ok(true)
|
||||
} else if is_loopback && enforce_https_for_localhost {
|
||||
Err(format!("Cannot bind without an SSL certificate."))
|
||||
} else if is_loopback || dangerously_allow_web_serving_without_a_certificate {
|
||||
Ok(false)
|
||||
} else {
|
||||
Err(format!(
|
||||
"Cannot bind to non-loopback IP: {} without an SSL certificate.",
|
||||
@@ -74,3 +75,87 @@ pub fn terminal_init_messages() -> Vec<&'static str> {
|
||||
enable_mouse_mode,
|
||||
]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod should_use_https_tests {
|
||||
use super::should_use_https;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
fn localhost() -> IpAddr {
|
||||
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))
|
||||
}
|
||||
|
||||
fn remote_v4() -> IpAddr {
|
||||
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))
|
||||
}
|
||||
|
||||
fn remote_v6() -> IpAddr {
|
||||
IpAddr::V6(Ipv6Addr::UNSPECIFIED)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_loopback_ipv4_without_certificate_is_refused_by_default() {
|
||||
assert!(should_use_https(remote_v4(), false, false, false).is_err());
|
||||
assert!(should_use_https(remote_v4(), false, true, false).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_loopback_ipv6_without_certificate_is_refused_by_default() {
|
||||
assert!(should_use_https(remote_v6(), false, false, false).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_loopback_with_certificate_uses_https() {
|
||||
assert_eq!(should_use_https(remote_v4(), true, false, false), Ok(true));
|
||||
assert_eq!(should_use_https(remote_v6(), true, false, false), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loopback_without_certificate_uses_http() {
|
||||
assert_eq!(
|
||||
should_use_https(localhost(), false, false, false),
|
||||
Ok(false)
|
||||
);
|
||||
assert_eq!(
|
||||
should_use_https(IpAddr::V6(Ipv6Addr::LOCALHOST), false, false, false),
|
||||
Ok(false)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loopback_with_certificate_uses_https() {
|
||||
assert_eq!(should_use_https(localhost(), true, false, false), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loopback_with_enforced_https_and_certificate_uses_https() {
|
||||
assert_eq!(should_use_https(localhost(), true, true, false), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loopback_with_enforced_https_without_certificate_is_refused() {
|
||||
assert!(should_use_https(localhost(), false, true, false).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_loopback_without_certificate_uses_http_when_dangerously_allowed() {
|
||||
assert_eq!(should_use_https(remote_v4(), false, false, true), Ok(false));
|
||||
assert_eq!(should_use_https(remote_v6(), false, false, true), Ok(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_loopback_with_certificate_still_uses_https_when_dangerously_allowed() {
|
||||
assert_eq!(should_use_https(remote_v4(), true, false, true), Ok(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enforced_https_for_localhost_wins_over_dangerous_allowance() {
|
||||
assert!(should_use_https(localhost(), false, true, true).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangerous_allowance_does_not_change_loopback_behavior() {
|
||||
assert_eq!(should_use_https(localhost(), false, false, true), Ok(false));
|
||||
assert_eq!(should_use_https(localhost(), true, false, true), Ok(true));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user