Skip to content

Commit 66b2ff4

Browse files
alexlarssonrh-atomic-bot
authored andcommitted
run: Support accessing host trusted certificates
If p11-kit server is installed on the host, we spawn a copy of this, forwarding the access to the p11-kit trust module in a read-only way. We then (if the above worked) bind mount the socket as /run/user/$UID/p11-kit/pkcs11 in the sandbox, which is the default socket path for the p11-kit-client module. We also add a configuration file in /etc/pkcs11/modules/p11-kit-trust.module that makes the trust module actually load the client module instead. This means applications automatically switch to using the host certs for trust if possible, and use the runtime ca-certificates otherwise. Additionally we add a config file that always disables pkcs user config merging, because pkcs11 modules on the host are unlikely to work in a random runtime. Closes: #1757 Approved by: alexlarsson
1 parent b4bb890 commit 66b2ff4

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

common/flatpak-run.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,7 @@ add_monitor_path_args (gboolean use_session_helper,
17051705
{
17061706
g_autoptr(AutoFlatpakSessionHelper) session_helper = NULL;
17071707
g_autofree char *monitor_path = NULL;
1708+
g_autofree char *pkcs11_socket_path = NULL;
17081709
g_autoptr(GVariant) session_data = NULL;
17091710

17101711
if (use_session_helper)
@@ -1730,6 +1731,24 @@ add_monitor_path_args (gboolean use_session_helper,
17301731
"--symlink", "/run/host/monitor/host.conf", "/etc/host.conf",
17311732
"--symlink", "/run/host/monitor/hosts", "/etc/hosts",
17321733
NULL);
1734+
1735+
if (g_variant_lookup (session_data, "pkcs11-socket", "s", &pkcs11_socket_path))
1736+
{
1737+
g_autofree char *sandbox_pkcs11_socket_path = g_strdup_printf ("/run/user/%d/p11-kit/pkcs11", getuid ());
1738+
const char *trusted_module_contents =
1739+
"# This overrides the runtime p11-kit-trusted module with a client one talking to the trust module on the host\n"
1740+
"module: p11-kit-client.so\n";
1741+
1742+
if (flatpak_bwrap_add_args_data (bwrap, "p11-kit-trust.module",
1743+
trusted_module_contents, -1,
1744+
"/etc/pkcs11/modules/p11-kit-trust.module", NULL))
1745+
{
1746+
flatpak_bwrap_add_args (bwrap,
1747+
"--ro-bind", pkcs11_socket_path, sandbox_pkcs11_socket_path,
1748+
NULL);
1749+
flatpak_bwrap_unset_env (bwrap, "P11_KIT_SERVER_ADDRESS");
1750+
}
1751+
}
17331752
}
17341753
else
17351754
{
@@ -2128,6 +2147,7 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap,
21282147
g_autofree char *run_dir = g_strdup_printf ("/run/user/%d", getuid ());
21292148
g_autofree char *passwd_contents = NULL;
21302149
g_autofree char *group_contents = NULL;
2150+
const char *pkcs11_conf_contents = NULL;
21312151
struct group *g = getgrgid (getgid ());
21322152
gulong pers;
21332153

@@ -2146,6 +2166,10 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap,
21462166
g->gr_name,
21472167
getgid (), g_get_user_name ());
21482168

2169+
pkcs11_conf_contents =
2170+
"# Disable user pkcs11 config, because the host modules don't work in the runtime\n"
2171+
"user-config: none\n";
2172+
21492173
flatpak_bwrap_add_args (bwrap,
21502174
"--unshare-pid",
21512175
"--proc", "/proc",
@@ -2179,6 +2203,9 @@ flatpak_run_setup_base_argv (FlatpakBwrap *bwrap,
21792203
if (!flatpak_bwrap_add_args_data (bwrap, "group", group_contents, -1, "/etc/group", error))
21802204
return FALSE;
21812205

2206+
if (!flatpak_bwrap_add_args_data (bwrap, "pkcs11.conf", pkcs11_conf_contents, -1, "/etc/pkcs11/pkcs11.conf", error))
2207+
return FALSE;
2208+
21822209
if (g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS))
21832210
flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/machine-id", "/etc/machine-id", NULL);
21842211
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,
22122239
strcmp (dent->d_name, "resolv.conf") == 0 ||
22132240
strcmp (dent->d_name, "host.conf") == 0 ||
22142241
strcmp (dent->d_name, "hosts") == 0 ||
2215-
strcmp (dent->d_name, "localtime") == 0)
2242+
strcmp (dent->d_name, "localtime") == 0 ||
2243+
strcmp (dent->d_name, "pkcs11") == 0)
22162244
continue;
22172245

22182246
src = g_build_filename (flatpak_file_get_path_cached (etc), dent->d_name, NULL);

session-helper/flatpak-session-helper.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,26 @@
3131
#include "flatpak-utils-private.h"
3232

3333
static char *monitor_dir;
34+
static char *p11_kit_server_socket_path;
35+
static int p11_kit_server_pid = 0;
3436

3537
static GHashTable *client_pid_data_hash = NULL;
3638
static GDBusConnection *session_bus = NULL;
3739

40+
static void
41+
do_atexit (void)
42+
{
43+
if (p11_kit_server_pid != 0)
44+
kill (p11_kit_server_pid, SIGTERM);
45+
}
46+
47+
static void
48+
handle_sigterm (int signum)
49+
{
50+
do_atexit ();
51+
_exit (1);
52+
}
53+
3854
typedef struct {
3955
GPid pid;
4056
char *client;
@@ -70,6 +86,9 @@ handle_request_session (FlatpakSessionHelper *object,
7086

7187
g_variant_builder_add (&builder, "{s@v}", "path",
7288
g_variant_new_variant (g_variant_new_string (monitor_dir)));
89+
if (p11_kit_server_socket_path)
90+
g_variant_builder_add (&builder, "{s@v}", "pkcs11-socket",
91+
g_variant_new_variant (g_variant_new_string (p11_kit_server_socket_path)));
7392

7493
flatpak_session_helper_complete_request_session (object, invocation,
7594
g_variant_builder_end (&builder));
@@ -608,6 +627,15 @@ main (int argc,
608627
{ NULL }
609628
};
610629
g_autoptr(MonitorData) m_resolv_conf = NULL, m_host_conf = NULL, m_hosts = NULL, m_localtime = NULL;
630+
struct sigaction action;
631+
632+
atexit (do_atexit);
633+
634+
memset(&action, 0, sizeof(struct sigaction));
635+
action.sa_handler = handle_sigterm;
636+
sigaction(SIGTERM, &action, NULL);
637+
sigaction(SIGHUP, &action, NULL);
638+
sigaction(SIGINT, &action, NULL);
611639

612640
setlocale (LC_ALL, "");
613641

@@ -664,6 +692,61 @@ main (int argc,
664692
exit (1);
665693
}
666694

695+
if (g_find_program_in_path ("p11-kit"))
696+
{
697+
g_autofree char *socket_basename = g_strdup_printf ("pkcs11-flatpak-%d", getpid ());
698+
g_autofree char *socket_path = g_build_filename (flatpak_dir, socket_basename, NULL);
699+
g_autofree char *p11_kit_stdout = NULL;
700+
gint exit_status;
701+
g_autoptr(GError) local_error = NULL;
702+
char *p11_argv[] = {
703+
"p11-kit", "server",
704+
"-n", socket_path,
705+
"--provider", "p11-kit-trust.so",
706+
"pkcs11:model=p11-kit-trust?write-protected=yes",
707+
NULL
708+
};
709+
if (!g_spawn_sync (NULL,
710+
p11_argv, NULL, G_SPAWN_SEARCH_PATH,
711+
NULL, NULL,
712+
&p11_kit_stdout, NULL,
713+
&exit_status, &local_error))
714+
{
715+
g_warning ("Unable to start p11-kit server: %s\n", local_error->message);
716+
}
717+
else if (exit_status != 0)
718+
{
719+
g_warning ("Unable to start p11-kit server, exited with status %d\n", exit_status);
720+
}
721+
else
722+
{
723+
g_auto(GStrv) stdout_lines = g_strsplit (p11_kit_stdout, "\n", 0);
724+
int i;
725+
726+
/* Output is something like:
727+
P11_KIT_SERVER_ADDRESS=unix:path=/run/user/1000/p11-kit/pkcs11-2603742; export P11_KIT_SERVER_ADDRESS;
728+
P11_KIT_SERVER_PID=2603743; export P11_KIT_SERVER_PID;
729+
*/
730+
for (i = 0; stdout_lines[i] != NULL; i++)
731+
{
732+
char *line = stdout_lines[i];
733+
734+
if (g_str_has_prefix (line, "P11_KIT_SERVER_PID="))
735+
{
736+
char *pid = line + strlen ("P11_KIT_SERVER_PID=");
737+
char *p = pid;
738+
while (g_ascii_isdigit (*p))
739+
p++;
740+
741+
*p = 0;
742+
p11_kit_server_pid = atol (pid);
743+
}
744+
}
745+
746+
p11_kit_server_socket_path = g_steal_pointer (&socket_path);
747+
}
748+
}
749+
667750
monitor_dir = g_build_filename (flatpak_dir, "monitor", NULL);
668751
if (g_mkdir_with_parents (monitor_dir, 0700) != 0)
669752
{

0 commit comments

Comments
 (0)