summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2018-04-05 11:14:39 +0200
committerDaiki Ueno <ueno@gnu.org>2018-04-06 10:59:44 +0200
commita6d0e490209638605b17b0bdc66ad03d36909dae (patch)
treeac139785aaedd85f53bbad79d90adf8c7c9cf733
parentde963b96929b9da61916a0c43b4ac4c34a39e238 (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.xml2
-rw-r--r--p11-kit/modules.c35
-rw-r--r--p11-kit/p11-kit.h1
-rw-r--r--p11-kit/private.h5
-rw-r--r--p11-kit/proxy.c2
-rw-r--r--p11-kit/test-proxy.c83
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);