[PATCH] Support addiitional 'progname' tags

David Woodhouse dwmw2 at infradead.org
Thu Dec 11 07:52:01 PST 2014


There are cases where we want to use enable-in/disable-in options for a
whole *class* of programs. Such as 'python' or 'p11-kit-proxy.so'.

This adds an internal API for managing extra prognames, and fixes the
enable-in/disable-in processing to handle them.

The proxy module now sets an additional progname of 'p11-kit-proxy.so',
and this can be used to control visibility of modules via the proxy
regardless of the actual program name in argv[0].

I'd also like p11-kit-proxy.so to take addtional 'extra prognames' via
the init_args.pReserved pointer in C_Initialize(). But unfortunately we
already processed the configuration in C_GetFunctionList() and decided
which modules to load, so it's too late by then. We'll need some
refactoring to make that possible.

That was my primary aim — I want NSS to load the proxy with 'nss' as an
additional progname tag, and then we can use that to *disable* the
p11-kit-trust tokens, since in the NSS case those are loaded via a
symlink from libnssckbi.so

diff --git a/p11-kit/modules.c b/p11-kit/modules.c
index 38c752b..53ff8a7 100644
--- a/p11-kit/modules.c
+++ b/p11-kit/modules.c
@@ -453,6 +453,7 @@ is_module_enabled_unlocked (const char *name,
 	const char *enable_in;
 	const char *disable_in;
 	bool enable = false;
+	int i = 0;
 
 	enable_in = p11_dict_get (config, "enable-in");
 	disable_in = p11_dict_get (config, "disable-in");
@@ -461,13 +462,23 @@ is_module_enabled_unlocked (const char *name,
 	if (!enable_in && !disable_in)
 		return true;
 
-	progname = _p11_get_progname_unlocked ();
-	if (enable_in && disable_in)
+	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));
+		return false;
+	}
+
+	if (disable_in)
+		enable = true;
+
+	while ((progname = _p11_get_progname_unlocked (i++))) {
+		if (enable_in && is_string_in_list (enable_in, progname)) {
+			enable = true;
+			break;
+		} else if (disable_in && is_string_in_list (disable_in, progname)) {
+			enable = false;
+			break;
+		}
+	}
 
 	p11_debug ("%s module '%s' running in '%s'",
 	            enable ? "enabled" : "disabled",
diff --git a/p11-kit/private.h b/p11-kit/private.h
index 1de61eb..cdbb870 100644
--- a/p11-kit/private.h
+++ b/p11-kit/private.h
@@ -51,8 +51,9 @@ CK_RV       _p11_load_config_files_unlocked                     (const char *sys
 
 void        _p11_kit_default_message                            (CK_RV rv);
 
-const char * _p11_get_progname_unlocked                         (void);
+const char * _p11_get_progname_unlocked                         (int idx);
 
+int         _p11_add_progname_unlocked                          (const char *progname);
 void        _p11_set_progname_unlocked                          (const char *progname);
 
 int          p11_match_uri_module_info                          (CK_INFO_PTR one,
diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c
index db2acb8..777268e 100644
--- a/p11-kit/proxy.c
+++ b/p11-kit/proxy.c
@@ -2346,6 +2346,8 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
 	p11_library_init_once ();
 	p11_lock ();
 
+	_p11_add_progname_unlocked ("p11-kit-proxy.so");
+
 	if (all_modules == NULL) {
 		/* WARNING: Reentrancy can occur here */
 		rv = p11_modules_load_inlock_reentrant (0, &loaded);
diff --git a/p11-kit/test-progname.c b/p11-kit/test-progname.c
index 76b136d..14a18d0 100644
--- a/p11-kit/test-progname.c
+++ b/p11-kit/test-progname.c
@@ -51,7 +51,7 @@ test_progname_default (void)
 {
 	const char *progname;
 
-	progname = _p11_get_progname_unlocked ();
+	progname = _p11_get_progname_unlocked (0);
 	assert_str_eq ("test-progname", progname);
 }
 
@@ -62,12 +62,12 @@ test_progname_set (void)
 
 	p11_kit_set_progname ("love-generation");
 
-	progname = _p11_get_progname_unlocked ();
+	progname = _p11_get_progname_unlocked (0);
 	assert_str_eq ("love-generation", progname);
 
 	_p11_set_progname_unlocked (NULL);
 
-	progname = _p11_get_progname_unlocked ();
+	progname = _p11_get_progname_unlocked (0);
 	assert_str_eq ("test-progname", progname);
 }
 
diff --git a/p11-kit/util.c b/p11-kit/util.c
index 1124876..722229d 100644
--- a/p11-kit/util.c
+++ b/p11-kit/util.c
@@ -197,6 +197,11 @@ _p11_kit_default_message (CK_RV rv)
 /* This is the progname that we think of this process as. */
 char p11_my_progname[256] = { 0, };
 
+static struct p11_progname {
+	struct p11_progname *next;
+	char name[1];
+} *p11_extra_prognames = NULL;
+
 /**
  * p11_kit_set_progname:
  * @progname: the program base name
@@ -220,22 +225,62 @@ p11_kit_set_progname (const char *progname)
 void
 _p11_set_progname_unlocked (const char *progname)
 {
+	struct p11_progname *p;
+
 	/* We can be called with NULL */
 	if (progname == NULL)
 		progname = "";
 
 	strncpy (p11_my_progname, progname, sizeof (p11_my_progname));
 	p11_my_progname[sizeof (p11_my_progname) - 1] = 0;
+
+	/* Clear any additional progname 'tags' which may be set */
+	while (p11_extra_prognames) {
+		p = p11_extra_prognames;
+		free (p11_extra_prognames);
+		p11_extra_prognames = p;
+	}
 }
 
-const char *
-_p11_get_progname_unlocked (void)
+int
+_p11_add_progname_unlocked (const char *progname)
 {
+	struct p11_progname *p;
+
+	/* Do this now so it doesn't clear the additional ones later. */
 	if (p11_my_progname[0] == '\0')
 		_p11_set_progname_unlocked (getprogname ());
+
+	p = malloc(sizeof(*p) + strlen(progname));
+	if (!p)
+		return -1;
+	p->next = p11_extra_prognames;
+	strcpy(p->name, progname);
+	p11_extra_prognames = p;
+
+	return 0;
+}
+
+const char *
+_p11_get_progname_unlocked (int idx)
+{
+	struct p11_progname *p;
+	
 	if (p11_my_progname[0] == '\0')
-		return NULL;
-	return p11_my_progname;
+		_p11_set_progname_unlocked (getprogname ());
+	if (p11_my_progname[0] != '\0') {
+		if (idx == 0)
+			return p11_my_progname;
+		else
+			idx--;
+	}
+	p = p11_extra_prognames;
+	while (idx && p)
+		p = p->next;
+	if (p)
+		return p->name;
+
+	return NULL;
 }
 
 #ifdef OS_UNIX


-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse at intel.com                              Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/p11-glue/attachments/20141211/aa3a3150/attachment-0001.bin>


More information about the p11-glue mailing list