]> granicus.if.org Git - p11-kit/commitdiff
modules: Add option to control module visibility from proxy
authorDaiki Ueno <dueno@redhat.com>
Thu, 5 Apr 2018 09:14:39 +0000 (11:14 +0200)
committerDaiki Ueno <ueno@gnu.org>
Fri, 6 Apr 2018 08:59:44 +0000 (10:59 +0200)
This enables to control whether a module will be loaded from the proxy
module.  The configuration reuses the "enable-in" and "disable-in"
options, with a special literal "p11-kit-proxy" as the value.

doc/manual/pkcs11.conf.xml
p11-kit/modules.c
p11-kit/p11-kit.h
p11-kit/private.h
p11-kit/proxy.c
p11-kit/test-proxy.c

index e94f9d186378db12c49d09b739d9b256134999c4..c1e2cab3ed806ac5283f326d049df798fa497758 100644 (file)
@@ -115,6 +115,7 @@ x-custom : text
                        for other programs using p11-kit. The base name of the process executable
                        should be used here, for example
                        <literal>seahorse, ssh</literal>.</para>
+                       <para>This option can also be used to control whether the module will be loaded by <link linkend="sharing">the proxy module</link>.  To enable loading only from the proxy module, specify <literal>p11-kit-proxy</literal> as the value.</para>
                        <para>This is not a security feature. The argument is optional. If
                        not present, then any process will load the module.</para>
                </listitem>
@@ -127,6 +128,7 @@ x-custom : text
                        other programs using p11-kit. The base name of the process
                        executable should be used here, for example
                        <literal>firefox, thunderbird-bin</literal>.</para>
+                       <para>This option can also be used to control whether the module will be loaded by <link linkend="sharing">the proxy module</link>.  To disable loading from the proxy module, specify <literal>p11-kit-proxy</literal> as the value.</para>
                        <para>This is not a security feature. The argument is optional. If
                        not present, then any process will load the module.</para>
                </listitem>
index da36e6bd7106d6a6770b34bcec59acd8a5af37db..4604e6ecfcf176c438a788396c3fec8d99b899d1 100644 (file)
@@ -510,7 +510,8 @@ is_string_in_list (const char *list,
 
 static bool
 is_module_enabled_unlocked (const char *name,
-                            p11_dict *config)
+                            p11_dict *config,
+                            int flags)
 {
        const char *progname;
        const char *enable_in;
@@ -527,10 +528,17 @@ is_module_enabled_unlocked (const char *name,
        progname = _p11_get_progname_unlocked ();
        if (enable_in && disable_in)
                p11_message ("module '%s' has both enable-in and disable-in options", name);
-       if (enable_in)
-               enable = (progname != NULL && is_string_in_list (enable_in, progname));
-       else if (disable_in)
-               enable = (progname == NULL || !is_string_in_list (disable_in, progname));
+       if (enable_in) {
+               enable = (progname != NULL &&
+                         is_string_in_list (enable_in, progname)) ||
+                       ((flags & P11_KIT_MODULE_LOADED_FROM_PROXY) != 0 &&
+                        is_string_in_list (enable_in, "p11-kit-proxy"));
+       } else if (disable_in) {
+               enable = (progname == NULL ||
+                         !is_string_in_list (disable_in, progname)) &&
+                       ((flags & P11_KIT_MODULE_LOADED_FROM_PROXY) == 0 ||
+                        !is_string_in_list (disable_in, "p11-kit-proxy"));
+       }
 
        p11_debug ("%s module '%s' running in '%s'",
                    enable ? "enabled" : "disabled",
@@ -554,7 +562,7 @@ take_config_and_load_module_inlock (char **name,
        assert (config);
        assert (*config);
 
-       if (!is_module_enabled_unlocked (*name, *config))
+       if (!is_module_enabled_unlocked (*name, *config, 0))
                goto out;
 
        remote = p11_dict_get (*config, "remote");
@@ -856,7 +864,7 @@ initialize_registered_inlock_reentrant (void)
                while (rv == CKR_OK && p11_dict_next (&iter, NULL, (void **)&mod)) {
 
                        /* Skip all modules that aren't registered or enabled */
-                       if (mod->name == NULL || !is_module_enabled_unlocked (mod->name, mod->config))
+                       if (mod->name == NULL || !is_module_enabled_unlocked (mod->name, mod->config, 0))
                                continue;
 
                        rv = initialize_module_inlock_reentrant (mod, NULL);
@@ -1116,7 +1124,7 @@ list_registered_modules_inlock (void)
                         * sure to cover it.
                         */
                        if (mod->ref_count && mod->name && mod->init_count &&
-                           is_module_enabled_unlocked (mod->name, mod->config)) {
+                           is_module_enabled_unlocked (mod->name, mod->config, 0)) {
                                result[i++] = funcs;
                        }
                }
@@ -1971,7 +1979,7 @@ p11_modules_load_inlock_reentrant (int flags,
                 * having initialized. This is a corner case, but want to make
                 * sure to cover it.
                 */
-               if (!mod->name || !is_module_enabled_unlocked (mod->name, mod->config))
+               if (!mod->name || !is_module_enabled_unlocked (mod->name, mod->config, flags))
                        continue;
 
                rv = prepare_module_inlock_reentrant (mod, flags, modules + at);
@@ -2044,6 +2052,9 @@ p11_kit_modules_load (const char *reserved,
        /* WARNING: This function must be reentrant */
        p11_debug ("in");
 
+       /* mask out internal flags */
+       flags &= P11_KIT_MODULE_MASK;
+
        p11_lock ();
 
                p11_message_clear ();
@@ -2170,6 +2181,9 @@ p11_kit_modules_load_and_initialize (int flags)
        CK_FUNCTION_LIST **modules;
        CK_RV rv;
 
+       /* mask out internal flags */
+       flags &= P11_KIT_MODULE_MASK;
+
        modules = p11_kit_modules_load (NULL, flags);
        if (modules == NULL)
                return NULL;
@@ -2465,6 +2479,9 @@ p11_kit_module_load (const char *module_path,
        /* WARNING: This function must be reentrant for the same arguments */
        p11_debug ("in: %s", module_path);
 
+       /* mask out internal flags */
+       flags &= P11_KIT_MODULE_MASK;
+
        p11_lock ();
 
                p11_message_clear ();
index 2a3a7404436f66addde8b71da8edcef4bc2f47a8..abf618b4ddfd37a62744c2ff7c51e76ffb63135c 100644 (file)
@@ -57,6 +57,7 @@ enum {
        P11_KIT_MODULE_UNMANAGED = 1 << 0,
        P11_KIT_MODULE_CRITICAL = 1 << 1,
        P11_KIT_MODULE_TRUSTED = 1 << 2,
+       P11_KIT_MODULE_MASK = (1 << 3) - 1
 };
 
 typedef void        (* p11_kit_destroyer)                   (void *data);
index b363b1735e60cd6d39fb446f69e7f8854e3d6748..4ef63ea5a6fcfc0648f00d62806fb78914aeb894 100644 (file)
@@ -45,6 +45,11 @@ extern const char *p11_config_package_modules;
 extern const char *p11_config_system_modules;
 extern const char *p11_config_user_modules;
 
+/* These are flags used only internally */
+enum {
+       P11_KIT_MODULE_LOADED_FROM_PROXY = 1 << 16
+};
+
 CK_RV       _p11_load_config_files_unlocked                     (const char *system_conf,
                                                                  const char *user_conf,
                                                                  int *user_mode);
index a52fe638788bac054bab0ee74a3c3c0d5fe0db42..22de32e4588695eb20fd6c0694a8f09645186f89 100644 (file)
@@ -1670,7 +1670,7 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
 
        if (all_modules == NULL) {
                /* WARNING: Reentrancy can occur here */
-               rv = p11_modules_load_inlock_reentrant (0, &loaded);
+               rv = p11_modules_load_inlock_reentrant (P11_KIT_MODULE_LOADED_FROM_PROXY, &loaded);
                if (rv == CKR_OK) {
                        if (all_modules == NULL)
                                all_modules = loaded;
index c34415b05a65dee8d39f57bcbb7601ff2ad42882..d33922e27aac8b7371c26735eee6c8f94a2e29f3 100644 (file)
@@ -190,6 +190,86 @@ test_initialize_child (void)
 }
 #endif
 
+struct {
+       char *directory;
+       const char *system_file;
+       const char *system_modules;
+} test;
+
+extern const char *p11_config_system_file;
+extern const char *p11_config_system_modules;
+
+static void
+setup (void *unused)
+{
+       test.directory = p11_test_directory ("test-proxy");
+       test.system_file = p11_config_system_file;
+       p11_config_system_file = SRCDIR "/p11-kit/fixtures/test-system-none.conf";
+       test.system_modules = p11_config_system_modules;
+       p11_config_system_modules = test.directory;
+}
+
+static void
+teardown (void *unused)
+{
+       p11_test_directory_delete (test.directory);
+       free (test.directory);
+       p11_config_system_file = test.system_file;
+       p11_config_system_modules = test.system_modules;
+}
+
+#define ONE_MODULE "module: mock-one" SHLEXT "\n"
+#define TWO_MODULE "module: mock-two" SHLEXT "\n"
+#define ENABLED "enable-in: test-proxy, p11-kit-proxy\n"
+#define DISABLED "disable-in: p11-kit-proxy\n"
+
+static CK_ULONG
+load_modules_and_count_slots (void)
+{
+       CK_FUNCTION_LIST_PTR proxy;
+       CK_ULONG count;
+       CK_RV rv;
+
+       rv = C_GetFunctionList (&proxy);
+       assert (rv == CKR_OK);
+
+       assert (p11_proxy_module_check (proxy));
+
+       rv = proxy->C_Initialize (NULL);
+       assert (rv == CKR_OK);
+
+       rv = proxy->C_GetSlotList (CK_TRUE, NULL, &count);
+       assert (rv == CKR_OK);
+
+       rv = proxy->C_Finalize (NULL);
+       assert_num_eq (rv, CKR_OK);
+
+       p11_proxy_module_cleanup ();
+
+       return count;
+}
+
+static void
+test_disable (void)
+{
+       CK_ULONG count, enabled, disabled;
+
+       p11_test_file_write (test.directory, "one.module", ONE_MODULE, strlen (ONE_MODULE));
+       p11_test_file_write (test.directory, "two.module", TWO_MODULE, strlen (TWO_MODULE));
+       count = load_modules_and_count_slots ();
+       assert_num_cmp (count, >, 1);
+
+       p11_test_file_write (test.directory, "one.module", ONE_MODULE ENABLED, strlen (ONE_MODULE ENABLED));
+       p11_test_file_write (test.directory, "two.module", TWO_MODULE, strlen (TWO_MODULE));
+       enabled = load_modules_and_count_slots ();
+       assert_num_eq (enabled, count);
+
+       p11_test_file_write (test.directory, "one.module", ONE_MODULE, strlen (ONE_MODULE));
+       p11_test_file_write (test.directory, "two.module", TWO_MODULE DISABLED, strlen (TWO_MODULE DISABLED));
+       disabled = load_modules_and_count_slots ();
+       assert_num_cmp (disabled, <, count);
+}
+
 static CK_FUNCTION_LIST_PTR
 setup_mock_module (CK_SESSION_HANDLE *session)
 {
@@ -272,6 +352,9 @@ main (int argc,
        p11_test (test_initialize_child, "/proxy/initialize-child");
 #endif
 
+       p11_fixture (setup, teardown);
+       p11_test (test_disable, "/proxy/disable");
+
        test_mock_add_tests ("/proxy");
 
        return p11_test_run (argc, argv);