diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c index aa05c9e24a5ace4dbc36baf9489e218b915e4bca..b52222c569a342ebeb5d19caf62868d200f84f49 100644 --- a/pressure-vessel/runtime.c +++ b/pressure-vessel/runtime.c @@ -3425,6 +3425,72 @@ bind_runtime_base (PvRuntime *self, } } + if (self->flags & PV_RUNTIME_FLAGS_IMPORT_CA_CERTS) + { + g_auto(SrtDirIter) iter = SRT_DIR_ITER_CLEARED; + glnx_autofd int dirfd = -1; + struct dirent *dent; + + flatpak_bwrap_add_args (bwrap, + "--tmpfs", "/etc/ssl/certs", + NULL); + + /* This is a developer-facing rather than end-user-facing flag, so + * for simplicity this assumes that the runtime is Debian-based, and + * that the host OS has also been set up to be compatible with + * Debian's layout for CA certificates (like Arch is). */ + dirfd = _srt_sysroot_open (self->host_root, + "/etc/ssl/certs", + (SRT_RESOLVE_FLAGS_MUST_BE_DIRECTORY + | SRT_RESOLVE_FLAGS_READABLE), + NULL, + error); + + if (dirfd < 0) + return FALSE; + + if (!_srt_dir_iter_init_take_fd (&iter, &dirfd, + SRT_DIR_ITER_FLAGS_NONE, + self->arbitrary_dirent_order, + error)) + return FALSE; + + while (_srt_dir_iter_next_dent (&iter, &dent, NULL, NULL) && dent != NULL) + { + const char *member = dent->d_name; + + if (g_str_equal (member, "ca-certificates.crt") + || g_str_has_suffix (member, ".0")) + { + g_autoptr(GError) local_error = NULL; + g_autofree gchar *logical_path = NULL; + g_autofree gchar *resolved = NULL; + glnx_autofd int fd = -1; + + logical_path = g_build_filename ("/etc/ssl/certs", member, NULL); + fd = _srt_sysroot_open (self->host_root, + logical_path, + (SRT_RESOLVE_FLAGS_READABLE + | SRT_RESOLVE_FLAGS_RETURN_ABSOLUTE), + &resolved, + &local_error); + + if (fd < 0) + { + g_warning ("%s", local_error->message); + continue; + } + + if (!pv_runtime_bind_into_container (self, bwrap, + resolved, NULL, 0, + logical_path, + PV_RUNTIME_EMULATION_ROOTS_BOTH, + error)) + return FALSE; + } + } + } + return TRUE; } diff --git a/pressure-vessel/runtime.h b/pressure-vessel/runtime.h index 2ac21d8eeb59a5180baabc5419bb9013eabc7304..6af7e725569177d3366ac7747e9ef94f1d0605d2 100644 --- a/pressure-vessel/runtime.h +++ b/pressure-vessel/runtime.h @@ -50,6 +50,8 @@ * root filesystem overlay for an interpreter like FEX-Emu * @PV_RUNTIME_FLAGS_DETERMINISTIC: Try harder to achieve deterministic * order, even where it shouldn't matter functionally + * @PV_RUNTIME_FLAGS_IMPORT_CA_CERTS: Try to import CA certificates from + * the host system, which is assumed to be Debian-compatible * @PV_RUNTIME_FLAGS_NONE: None of the above * * Flags affecting how we set up the runtime. @@ -66,6 +68,7 @@ typedef enum PV_RUNTIME_FLAGS_FLATPAK_SUBSANDBOX = (1 << 7), PV_RUNTIME_FLAGS_INTERPRETER_ROOT = (1 << 8), PV_RUNTIME_FLAGS_DETERMINISTIC = (1 << 9), + PV_RUNTIME_FLAGS_IMPORT_CA_CERTS = (1 << 10), PV_RUNTIME_FLAGS_NONE = 0 } PvRuntimeFlags; @@ -86,6 +89,7 @@ typedef enum | PV_RUNTIME_FLAGS_FLATPAK_SUBSANDBOX \ | PV_RUNTIME_FLAGS_INTERPRETER_ROOT \ | PV_RUNTIME_FLAGS_DETERMINISTIC \ + | PV_RUNTIME_FLAGS_IMPORT_CA_CERTS \ ) typedef enum diff --git a/pressure-vessel/wrap-context.c b/pressure-vessel/wrap-context.c index 6e83c03bb60efda0a697ac4f2a7e51e4619fd21e..3b26215767e1f76f7f9bb80d76f47c417cfb791d 100644 --- a/pressure-vessel/wrap-context.c +++ b/pressure-vessel/wrap-context.c @@ -56,6 +56,7 @@ pv_wrap_options_init (PvWrapOptions *self) self->gc_runtimes = TRUE; self->generate_locales = TRUE; self->graphics_provider = FALSE; + self->import_ca_certs = FALSE; self->import_vulkan_layers = TRUE; self->launcher = FALSE; self->only_prepare = FALSE; @@ -537,6 +538,8 @@ pv_wrap_options_parse_environment (PvWrapOptions *self, self->remove_game_overlay); self->systemd_scope = _srt_boolean_environment ("PRESSURE_VESSEL_SYSTEMD_SCOPE", self->systemd_scope); + self->import_ca_certs = _srt_boolean_environment ("PRESSURE_VESSEL_IMPORT_CA_CERTS", + self->import_ca_certs); self->import_vulkan_layers = _srt_boolean_environment ("PRESSURE_VESSEL_IMPORT_VULKAN_LAYERS", self->import_vulkan_layers); diff --git a/pressure-vessel/wrap-context.h b/pressure-vessel/wrap-context.h index 644194da3603f0cb4b3304b537961852bf82dbc1..56d5bcfd7e3ffce142bfb117903903050bbd3ccd 100644 --- a/pressure-vessel/wrap-context.h +++ b/pressure-vessel/wrap-context.h @@ -79,6 +79,7 @@ typedef struct gboolean devel; gboolean gc_runtimes; gboolean generate_locales; + gboolean import_ca_certs; gboolean import_vulkan_layers; gboolean launcher; gboolean only_prepare; diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index 1411570e695a15aa0bc2789992f12177d45a8000..8657f904cf4147aa2e116e849b2de6c984e8bfe2 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -629,6 +629,9 @@ main (int argc, if (_srt_util_is_debugging ()) flags |= PV_RUNTIME_FLAGS_VERBOSE; + if (self->options.import_ca_certs) + flags |= PV_RUNTIME_FLAGS_IMPORT_CA_CERTS; + if (self->options.import_vulkan_layers) flags |= PV_RUNTIME_FLAGS_IMPORT_VULKAN_LAYERS;