Files
CodeNomad/packages/tauri-app/src-tauri/src/linux_tls.rs
pascalandr be4f383602 fix(desktop): allow self-signed remote HTTPS on Linux
Use WebKitGTK TLS exceptions for remote windows so Linux no longer depends on system CA installation or sudo-managed trust stores.
2026-04-18 09:30:38 +02:00

89 lines
2.5 KiB
Rust

use crate::AppState;
use tauri::{AppHandle, Manager, WebviewWindow};
use url::Url;
use webkit2gtk::{WebContextExt, WebView, WebViewExt};
pub fn should_bootstrap_tls_navigation(target_url: &Url, skip_tls_verify: bool) -> bool {
skip_tls_verify && target_url.scheme() == "https"
}
pub fn ensure_remote_window_tls_handler(
window: &WebviewWindow,
app_handle: &AppHandle,
window_label: &str,
) -> Result<(), String> {
{
let state = app_handle.state::<AppState>();
let mut handlers = state
.remote_tls_handlers
.lock()
.map_err(|err| err.to_string())?;
if !handlers.insert(window_label.to_string()) {
return Ok(());
}
}
let app_handle = app_handle.clone();
let window_label = window_label.to_string();
window
.with_webview(move |platform_webview| {
let webview = platform_webview.inner();
let app_handle = app_handle.clone();
let window_label = window_label.clone();
webview.connect_load_failed_with_tls_errors(move |view, failing_uri, certificate, _| {
allow_remote_tls_certificate(
&app_handle,
&window_label,
view,
failing_uri,
certificate,
)
});
})
.map_err(|err| err.to_string())
}
fn allow_remote_tls_certificate(
app_handle: &AppHandle,
window_label: &str,
view: &WebView,
failing_uri: &str,
certificate: &webkit2gtk::gio::TlsCertificate,
) -> bool {
let Ok(parsed_uri) = Url::parse(failing_uri) else {
return false;
};
let Some(host) = parsed_uri.host_str() else {
return false;
};
let state = app_handle.state::<AppState>();
let skip_tls_verify = state
.remote_skip_tls_verify
.lock()
.ok()
.and_then(|values| values.get(window_label).copied())
.unwrap_or(false);
if !skip_tls_verify {
return false;
}
let expected_origin = state
.remote_origins
.lock()
.ok()
.and_then(|origins| origins.get(window_label).cloned());
let parsed_origin = parsed_uri.origin().ascii_serialization();
if expected_origin.as_deref() != Some(parsed_origin.as_str()) {
return false;
}
let Some(context) = view.context() else {
return false;
};
context.allow_tls_certificate_for_host(certificate, host);
view.load_uri(failing_uri);
true
}