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.woodho...@intel.com                              Intel Corporation

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
p11-glue mailing list
p11-glue@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/p11-glue

Reply via email to