diff options
author | Daiki Ueno <dueno@redhat.com> | 2018-04-05 11:14:39 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2018-04-06 10:59:44 +0200 |
commit | a6d0e490209638605b17b0bdc66ad03d36909dae (patch) | |
tree | ac139785aaedd85f53bbad79d90adf8c7c9cf733 | |
parent | de963b96929b9da61916a0c43b4ac4c34a39e238 (diff) |
modules: Add option to control module visibility from proxy
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.
-rw-r--r-- | doc/manual/pkcs11.conf.xml | 2 | ||||
-rw-r--r-- | p11-kit/modules.c | 35 | ||||
-rw-r--r-- | p11-kit/p11-kit.h | 1 | ||||
-rw-r--r-- | p11-kit/private.h | 5 | ||||
-rw-r--r-- | p11-kit/proxy.c | 2 | ||||
-rw-r--r-- | p11-kit/test-proxy.c | 83 |
6 files changed, 118 insertions, 10 deletions
diff --git a/doc/manual/pkcs11.conf.xml b/doc/manual/pkcs11.conf.xml index e94f9d1..c1e2cab 100644 --- a/doc/manual/pkcs11.conf.xml +++ b/doc/manual/pkcs11.conf.xml @@ -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> diff --git a/p11-kit/modules.c b/p11-kit/modules.c index da36e6b..4604e6e 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -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 (); diff --git a/p11-kit/p11-kit.h b/p11-kit/p11-kit.h index 2a3a740..abf618b 100644 --- a/p11-kit/p11-kit.h +++ b/p11-kit/p11-kit.h @@ -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); diff --git a/p11-kit/private.h b/p11-kit/private.h index b363b17..4ef63ea 100644 --- a/p11-kit/private.h +++ b/p11-kit/private.h @@ -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); diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c index a52fe63..22de32e 100644 --- a/p11-kit/proxy.c +++ b/p11-kit/proxy.c @@ -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; diff --git a/p11-kit/test-proxy.c b/p11-kit/test-proxy.c index c34415b..d33922e 100644 --- a/p11-kit/test-proxy.c +++ b/p11-kit/test-proxy.c @@ -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); |