Use WebKitGTK TLS exceptions for remote windows so Linux no longer depends on system CA installation or sudo-managed trust stores.
89 lines
2.5 KiB
Rust
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
|
|
}
|