diff --git a/common/flatpak-run.c b/common/flatpak-run.c index 5a88f399d..ca7ed0ae6 100644 --- a/common/flatpak-run.c +++ b/common/flatpak-run.c @@ -1705,6 +1705,7 @@ add_monitor_path_args (gboolean use_session_helper, { g_autoptr(AutoFlatpakSessionHelper) session_helper = NULL; g_autofree char *monitor_path = NULL; + g_autofree char *pkcs11_socket_path = NULL; g_autoptr(GVariant) session_data = NULL; if (use_session_helper) @@ -1730,6 +1731,24 @@ add_monitor_path_args (gboolean use_session_helper, "--symlink", "/run/host/monitor/host.conf", "/etc/host.conf", "--symlink", "/run/host/monitor/hosts", "/etc/hosts", NULL); + + if (g_variant_lookup (session_data, "pkcs11-socket", "s", &pkcs11_socket_path)) + { + g_autofree char *sandbox_pkcs11_socket_path = g_strdup_printf ("/run/user/%d/p11-kit/pkcs11", getuid ()); + const char *trusted_module_contents = + "# This overrides the runtime p11-kit-trusted module with a client one talking to the trust module on the host\n" + "module: p11-kit-client.so\n"; + + if (flatpak_bwrap_add_args_data (bwrap, "p11-kit-trust.module", + trusted_module_contents, -1, + "/etc/pkcs11/modules/p11-kit-trust.module", NULL)) + { + flatpak_bwrap_add_args (bwrap, + "--ro-bind", pkcs11_socket_path, sandbox_pkcs11_socket_path, + NULL); + flatpak_bwrap_unset_env (bwrap, "P11_KIT_SERVER_ADDRESS"); + } + } } else { @@ -2128,6 +2147,7 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap, g_autofree char *run_dir = g_strdup_printf ("/run/user/%d", getuid ()); g_autofree char *passwd_contents = NULL; g_autofree char *group_contents = NULL; + const char *pkcs11_conf_contents = NULL; struct group *g = getgrgid (getgid ()); gulong pers; @@ -2146,6 +2166,10 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap, g->gr_name, getgid (), g_get_user_name ()); + pkcs11_conf_contents = + "# Disable user pkcs11 config, because the host modules don't work in the runtime\n" + "user-config: none\n"; + flatpak_bwrap_add_args (bwrap, "--unshare-pid", "--proc", "/proc", @@ -2179,6 +2203,9 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap, if (!flatpak_bwrap_add_args_data (bwrap, "group", group_contents, -1, "/etc/group", error)) return FALSE; + if (!flatpak_bwrap_add_args_data (bwrap, "pkcs11.conf", pkcs11_conf_contents, -1, "/etc/pkcs11/pkcs11.conf", error)) + return FALSE; + if (g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS)) flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/machine-id", "/etc/machine-id", NULL); else if (g_file_test ("/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS)) @@ -2212,7 +2239,8 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap, strcmp (dent->d_name, "resolv.conf") == 0 || strcmp (dent->d_name, "host.conf") == 0 || strcmp (dent->d_name, "hosts") == 0 || - strcmp (dent->d_name, "localtime") == 0) + strcmp (dent->d_name, "localtime") == 0 || + strcmp (dent->d_name, "pkcs11") == 0) continue; src = g_build_filename (flatpak_file_get_path_cached (etc), dent->d_name, NULL); diff --git a/session-helper/flatpak-session-helper.c b/session-helper/flatpak-session-helper.c index f00c5c8d3..52d2829da 100644 --- a/session-helper/flatpak-session-helper.c +++ b/session-helper/flatpak-session-helper.c @@ -31,10 +31,26 @@ #include "flatpak-utils-private.h" static char *monitor_dir; +static char *p11_kit_server_socket_path; +static int p11_kit_server_pid = 0; static GHashTable *client_pid_data_hash = NULL; static GDBusConnection *session_bus = NULL; +static void +do_atexit (void) +{ + if (p11_kit_server_pid != 0) + kill (p11_kit_server_pid, SIGTERM); +} + +static void +handle_sigterm (int signum) +{ + do_atexit (); + _exit (1); +} + typedef struct { GPid pid; char *client; @@ -70,6 +86,9 @@ handle_request_session (FlatpakSessionHelper *object, g_variant_builder_add (&builder, "{s@v}", "path", g_variant_new_variant (g_variant_new_string (monitor_dir))); + if (p11_kit_server_socket_path) + g_variant_builder_add (&builder, "{s@v}", "pkcs11-socket", + g_variant_new_variant (g_variant_new_string (p11_kit_server_socket_path))); flatpak_session_helper_complete_request_session (object, invocation, g_variant_builder_end (&builder)); @@ -608,6 +627,15 @@ main (int argc, { NULL } }; g_autoptr(MonitorData) m_resolv_conf = NULL, m_host_conf = NULL, m_hosts = NULL, m_localtime = NULL; + struct sigaction action; + + atexit (do_atexit); + + memset(&action, 0, sizeof(struct sigaction)); + action.sa_handler = handle_sigterm; + sigaction(SIGTERM, &action, NULL); + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); setlocale (LC_ALL, ""); @@ -664,6 +692,61 @@ main (int argc, exit (1); } + if (g_find_program_in_path ("p11-kit")) + { + g_autofree char *socket_basename = g_strdup_printf ("pkcs11-flatpak-%d", getpid ()); + g_autofree char *socket_path = g_build_filename (flatpak_dir, socket_basename, NULL); + g_autofree char *p11_kit_stdout = NULL; + gint exit_status; + g_autoptr(GError) local_error = NULL; + char *p11_argv[] = { + "p11-kit", "server", + "-n", socket_path, + "--provider", "p11-kit-trust.so", + "pkcs11:model=p11-kit-trust?write-protected=yes", + NULL + }; + if (!g_spawn_sync (NULL, + p11_argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, + &p11_kit_stdout, NULL, + &exit_status, &local_error)) + { + g_warning ("Unable to start p11-kit server: %s\n", local_error->message); + } + else if (exit_status != 0) + { + g_warning ("Unable to start p11-kit server, exited with status %d\n", exit_status); + } + else + { + g_auto(GStrv) stdout_lines = g_strsplit (p11_kit_stdout, "\n", 0); + int i; + + /* Output is something like: + P11_KIT_SERVER_ADDRESS=unix:path=/run/user/1000/p11-kit/pkcs11-2603742; export P11_KIT_SERVER_ADDRESS; + P11_KIT_SERVER_PID=2603743; export P11_KIT_SERVER_PID; + */ + for (i = 0; stdout_lines[i] != NULL; i++) + { + char *line = stdout_lines[i]; + + if (g_str_has_prefix (line, "P11_KIT_SERVER_PID=")) + { + char *pid = line + strlen ("P11_KIT_SERVER_PID="); + char *p = pid; + while (g_ascii_isdigit (*p)) + p++; + + *p = 0; + p11_kit_server_pid = atol (pid); + } + } + + p11_kit_server_socket_path = g_steal_pointer (&socket_path); + } + } + monitor_dir = g_build_filename (flatpak_dir, "monitor", NULL); if (g_mkdir_with_parents (monitor_dir, 0700) != 0) {