summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2017-03-10 09:53:50 +0100
committerDaiki Ueno <ueno@gnu.org>2017-05-25 14:13:01 +0200
commitda7f0d65355089f4919bcdffca98bd833258db04 (patch)
tree3cf2b350b3d9a8c32f3ae4a24ff898a8a9be80de
parent7310d92af3b0291ab627fcf3e07800cd5b2983c8 (diff)
rpc: New p11_kit_remote_serve_tokens function
-rw-r--r--doc/manual/p11-kit-sections.txt1
-rw-r--r--p11-kit/remote.c118
-rw-r--r--p11-kit/remote.h14
-rw-r--r--p11-kit/rpc-server.c142
-rw-r--r--p11-kit/server.c74
5 files changed, 248 insertions, 101 deletions
diff --git a/doc/manual/p11-kit-sections.txt b/doc/manual/p11-kit-sections.txt
index c1c1df1..cb0cb1c 100644
--- a/doc/manual/p11-kit-sections.txt
+++ b/doc/manual/p11-kit-sections.txt
@@ -141,6 +141,7 @@ P11KitIterKind
P11KitIterBehavior
p11_kit_remote_serve_module
p11_kit_remote_serve_token
+p11_kit_remote_serve_tokens
</SECTION>
<SECTION>
diff --git a/p11-kit/remote.c b/p11-kit/remote.c
index d524bbd..1642c7b 100644
--- a/p11-kit/remote.c
+++ b/p11-kit/remote.c
@@ -49,89 +49,30 @@
#include <string.h>
#include <unistd.h>
-static int
-serve_module_from_uri (const char *uri_string)
-{
- CK_FUNCTION_LIST **modules;
- CK_FUNCTION_LIST *module;
- P11KitIter *iter = NULL;
- P11KitUri *uri;
- CK_TOKEN_INFO *token;
- int ret = 1;
- CK_RV rv;
-
- modules = p11_kit_modules_load_and_initialize (0);
- if (modules == NULL)
- return 1;
-
- uri = p11_kit_uri_new ();
- if (uri == NULL)
- goto out;
- ret = p11_kit_uri_parse (uri_string, P11_KIT_URI_FOR_TOKEN, uri);
- if (ret != P11_KIT_URI_OK) {
- p11_kit_uri_free (uri);
- goto out;
- }
-
- iter = p11_kit_iter_new (uri, P11_KIT_ITER_WITH_TOKENS | P11_KIT_ITER_WITHOUT_OBJECTS);
- p11_kit_uri_free (uri);
- if (iter == NULL)
- goto out;
-
- p11_kit_iter_begin (iter, modules);
- rv = p11_kit_iter_next (iter);
- if (rv != CKR_OK)
- goto out;
-
- module = p11_kit_iter_get_module (iter);
- token = p11_kit_iter_get_token (iter);
- p11_kit_modules_finalize (modules);
-
- ret = p11_kit_remote_serve_token (module, token, 0, 1);
-
- out:
- p11_kit_iter_free (iter);
- p11_kit_modules_release (modules);
-
- return ret;
-}
-
-static int
-serve_module_from_file (const char *file)
-{
- CK_FUNCTION_LIST *module;
- int ret;
-
- module = p11_kit_module_load (file, 0);
- if (module == NULL)
- return 1;
-
- ret = p11_kit_remote_serve_module (module, 0, 1);
- p11_kit_module_release (module);
-
- return ret;
-}
-
int
main (int argc,
char *argv[])
{
int opt;
- int ret;
+ char *provider = NULL;
enum {
opt_verbose = 'v',
opt_help = 'h',
+ opt_provider = 'p'
};
struct option options[] = {
{ "verbose", no_argument, NULL, opt_verbose },
{ "help", no_argument, NULL, opt_help },
+ { "provider", required_argument, NULL, opt_provider },
{ 0 },
};
p11_tool_desc usages[] = {
- { 0, "usage: p11-kit remote <module-or-token>" },
+ { 0, "usage: p11-kit remote <module>\n"
+ " p11-kit remote [-p <provider>] <token> ..." },
+ { opt_provider, "specify the module to use" },
{ 0 },
};
@@ -144,6 +85,9 @@ main (int argc,
case '?':
p11_tool_usage (usages, options);
return 0;
+ case opt_provider:
+ provider = optarg;
+ break;
default:
assert_not_reached ();
break;
@@ -153,8 +97,8 @@ main (int argc,
argc -= optind;
argv += optind;
- if (argc != 1) {
- p11_message ("specify the module or token URI to remote");
+ if (argc < 1) {
+ p11_message ("specify a module or tokens to remote");
return 2;
}
@@ -163,10 +107,40 @@ main (int argc,
return 2;
}
- if (strncmp (argv[0], "pkcs11:", 7) == 0)
- ret = serve_module_from_uri (argv[0]);
- else
- ret = serve_module_from_file (argv[0]);
+ if (strncmp (argv[0], "pkcs11:", 7) == 0) {
+ CK_FUNCTION_LIST *module = NULL;
+ int ret;
+
+ if (provider) {
+ module = p11_kit_module_load (provider, 0);
+ if (module == NULL)
+ return 1;
+ }
+
+ ret = p11_kit_remote_serve_tokens ((const char **)argv, argc,
+ module,
+ STDIN_FILENO, STDOUT_FILENO);
+ if (module)
+ p11_kit_module_release (module);
- return ret;
+ return ret;
+ } else {
+ CK_FUNCTION_LIST *module;
+ int ret;
+
+ if (argc != 1) {
+ p11_message ("only one module can be specified");
+ return 2;
+ }
+
+ module = p11_kit_module_load (argv[0], 0);
+ if (module == NULL)
+ return 1;
+
+ ret = p11_kit_remote_serve_module (module,
+ STDIN_FILENO, STDOUT_FILENO);
+ p11_kit_module_release (module);
+
+ return ret;
+ }
}
diff --git a/p11-kit/remote.h b/p11-kit/remote.h
index 899f070..3c84736 100644
--- a/p11-kit/remote.h
+++ b/p11-kit/remote.h
@@ -47,11 +47,25 @@ int p11_kit_remote_serve_module (CK_FUNCTION_LIST *m
int in_fd,
int out_fd);
+#ifndef P11_KIT_DISABLE_DEPRECATED
+
int p11_kit_remote_serve_token (CK_FUNCTION_LIST *module,
CK_TOKEN_INFO *token,
int in_fd,
int out_fd);
+#endif /* P11_KIT_DISABLE_DEPRECATED */
+
+int p11_kit_remote_serve_tokens (const char **tokens,
+ size_t n_tokens,
+ CK_FUNCTION_LIST *module,
+ int in_fd,
+ int out_fd);
+
+int p11_kit_remote_serve (const char *module_or_token,
+ int in_fd,
+ int out_fd);
+
#endif
#ifdef __cplusplus
diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c
index 47beed0..fcf837b 100644
--- a/p11-kit/rpc-server.c
+++ b/p11-kit/rpc-server.c
@@ -38,6 +38,7 @@
#define P11_DEBUG_FLAG P11_DEBUG_RPC
#include "debug.h"
#include "filter.h"
+#include "iter.h"
#include "pkcs11.h"
#include "library.h"
#include "private.h"
@@ -45,6 +46,7 @@
#include "remote.h"
#include "rpc.h"
#include "rpc-message.h"
+#include "uri.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -1924,6 +1926,16 @@ p11_rpc_server_handle (CK_X_FUNCTION_LIST *self,
return true;
}
+/**
+ * p11_kit_remote_serve_module:
+ * @module: a pointer to a loaded module
+ * @in_fd: input fd
+ * @out_fd: output fd
+ *
+ * Run a module on a given pair of input/output FDs.
+ *
+ * Returns: 0 if success, non-zero otherwise.
+ */
int
p11_kit_remote_serve_module (CK_FUNCTION_LIST *module,
int in_fd,
@@ -2024,6 +2036,19 @@ out:
return ret;
}
+/**
+ * p11_kit_remote_serve_token:
+ * @module: a pointer to a loaded module
+ * @token: a token info
+ * @in_fd: input fd
+ * @out_fd: output fd
+ *
+ * Run a token wrapped in a module on a given pair of input/output FDs.
+ *
+ * Returns: 0 if success, non-zero otherwise.
+ *
+ * Deprecated: use p11_kit_remote_serve_tokens()
+ */
int
p11_kit_remote_serve_token (CK_FUNCTION_LIST *module,
CK_TOKEN_INFO *token,
@@ -2059,3 +2084,120 @@ p11_kit_remote_serve_token (CK_FUNCTION_LIST *module,
return ret;
}
+
+/* Find a module providing a token */
+static CK_FUNCTION_LIST *
+find_module (const char *token)
+{
+ CK_FUNCTION_LIST **modules = NULL, *module = NULL;
+ P11KitUri *uri = NULL;
+ P11KitIter *iter = NULL;
+ CK_RV rv;
+
+ modules = p11_kit_modules_load_and_initialize (0);
+ if (modules == NULL)
+ goto out;
+
+ uri = p11_kit_uri_new ();
+ if (uri == NULL)
+ goto out;
+
+ if (p11_kit_uri_parse (token, P11_KIT_URI_FOR_TOKEN, uri) !=
+ P11_KIT_URI_OK)
+ goto out;
+
+ iter = p11_kit_iter_new (uri,
+ P11_KIT_ITER_WITH_TOKENS |
+ P11_KIT_ITER_WITHOUT_OBJECTS);
+ p11_kit_uri_free (uri);
+ uri = NULL;
+ if (iter == NULL)
+ goto out;
+
+ p11_kit_iter_begin (iter, modules);
+ rv = p11_kit_iter_next (iter);
+ if (rv != CKR_OK)
+ goto out;
+
+ module = p11_kit_iter_get_module (iter);
+
+ out:
+ p11_kit_iter_free (iter);
+ p11_kit_modules_release (modules);
+
+ return module;
+}
+
+/**
+ * p11_kit_remote_serve_tokens:
+ * @tokens: a list of token URIs
+ * @n_tokens: the length of @tokens
+ * @module: (nullable): a PKCS\#11 module that provides the tokens
+ * @in_fd: input fd
+ * @out_fd: output fd
+ *
+ * Expose tokens on a given pair of input/output FDs. All the tokens
+ * must be provided by the same module.
+ *
+ * Returns: 0 if success, non-zero otherwise.
+ */
+int
+p11_kit_remote_serve_tokens (const char **tokens,
+ size_t n_tokens,
+ CK_FUNCTION_LIST *module,
+ int in_fd,
+ int out_fd)
+{
+ p11_virtual virt;
+ p11_virtual *filter = NULL;
+ CK_FUNCTION_LIST *filtered = NULL;
+ int ret = 1;
+ size_t i;
+
+ return_val_if_fail (tokens != NULL, 2);
+ return_val_if_fail (n_tokens > 0, 2);
+ return_val_if_fail (in_fd >= 0, 2);
+ return_val_if_fail (out_fd >= 0, 2);
+
+ if (!module)
+ module = find_module (tokens[0]);
+
+ /* Create a virtual module that provides only the specified tokens */
+ p11_virtual_init (&virt, &p11_virtual_base, module, NULL);
+ filter = p11_filter_subclass (&virt, NULL);
+ if (filter == NULL)
+ goto out;
+
+ for (i = 0; i < n_tokens; i++) {
+ P11KitUri *uri;
+ CK_TOKEN_INFO *token;
+
+ uri = p11_kit_uri_new ();
+ if (uri == NULL)
+ goto out;
+
+ if (p11_kit_uri_parse (tokens[i], P11_KIT_URI_FOR_TOKEN, uri) !=
+ P11_KIT_URI_OK) {
+ p11_kit_uri_free (uri);
+ goto out;
+ }
+
+ token = p11_kit_uri_get_token_info (uri);
+ p11_filter_allow_token (filter, token);
+ p11_kit_uri_free (uri);
+ }
+
+ filtered = p11_virtual_wrap (filter, (p11_destroyer)p11_virtual_uninit);
+ if (filtered == NULL)
+ goto out;
+
+ ret = p11_kit_remote_serve_module (filtered, in_fd, out_fd);
+
+ out:
+ if (filtered != NULL)
+ p11_virtual_unwrap (filtered);
+ if (filter != NULL)
+ p11_filter_release (filter);
+
+ return ret;
+}
diff --git a/p11-kit/server.c b/p11-kit/server.c
index 1d9f469..ce7900a 100644
--- a/p11-kit/server.c
+++ b/p11-kit/server.c
@@ -75,9 +75,11 @@ static unsigned children_avail = 0;
static bool quiet = false;
typedef struct {
- char *module_or_token;
- char *socket_name;
+ const char **tokens;
+ size_t n_tokens;
+ const char *provider;
+ const char *socket_name;
uid_t uid;
gid_t gid;
@@ -243,17 +245,14 @@ server_free (Server *server)
{
if (server == NULL)
return;
- if (server->module_or_token)
- free (server->module_or_token);
- if (server->socket_name)
- free (server->socket_name);
if (server->socket >= 0)
close (server->socket);
free (server);
}
static Server *
-server_new (const char *module_or_token, const char *socket_name)
+server_new (const char **tokens, size_t n_tokens, const char *provider,
+ const char *socket_name)
{
Server *server;
@@ -262,18 +261,9 @@ server_new (const char *module_or_token, const char *socket_name)
if (server == NULL)
return NULL;
- server->module_or_token = strdup (module_or_token);
- if (server->module_or_token == NULL) {
- server_free (server);
- return NULL;
- }
-
- server->socket_name = strdup (socket_name);
- if (server->socket_name == NULL) {
- server_free (server);
- return NULL;
- }
-
+ server->tokens = tokens;
+ server->n_tokens = n_tokens;
+ server->socket_name = socket_name;
server->socket = -1;
return server;
@@ -291,7 +281,8 @@ server_loop (Server *server,
struct sockaddr_un sa;
fd_set rd_set;
sigset_t emptyset, blockset;
- char *args[] = { "p11-kit-remote", NULL, NULL };
+ char **args;
+ size_t n_args, i;
int max_fd;
int errn;
@@ -396,11 +387,32 @@ server_loop (Server *server,
fdwalk (set_cloexec_on_fd, &max_fd);
/* Execute 'p11-kit remote'; this shouldn't return */
- args[1] = (char *) server->module_or_token;
- exec_external (2, args);
+ args = calloc (3 + server->n_tokens + 1, sizeof (char *));
+ if (args == NULL) {
+ errn = errno;
+ p11_message_err (errn, "couldn't allocate memory for 'p11-kit remote' arguments");
+ _exit (errn);
+ }
+
+ n_args = 0;
+ args[n_args] = "p11-kit-remote";
+ n_args++;
+
+ if (server->provider) {
+ args[n_args] = "--provider";
+ n_args++;
+ args[n_args] = (char *)server->provider;
+ n_args++;
+ }
+
+ for (i = 0; i < server->n_tokens; i++, n_args++)
+ args[n_args] = (char *)server->tokens[i];
+
+ exec_external (n_args, args);
+ free (args);
errn = errno;
- p11_message_err (errn, "couldn't execute 'p11-kit remote' for module '%s'", server->module_or_token);
+ p11_message_err (errn, "couldn't execute 'p11-kit remote'");
_exit (errn);
default:
children_avail++;
@@ -419,7 +431,6 @@ int
main (int argc,
char *argv[])
{
- char *module_or_token;
char *socket_base = NULL, *socket_name = NULL;
uid_t uid = -1, run_as_uid = -1;
gid_t gid = -1, run_as_gid = -1;
@@ -429,6 +440,7 @@ main (int argc,
bool foreground = false;
struct timespec *timeout = NULL, ts;
char *name = NULL;
+ char *provider = NULL;
Server *server = NULL;
int ret = 0;
@@ -443,6 +455,7 @@ main (int argc,
opt_foreground = 'f',
opt_timeout = 't',
opt_name = 'n',
+ opt_provider = 'p'
};
struct option options[] = {
@@ -456,11 +469,12 @@ main (int argc,
{ "run-as-group", required_argument, NULL, opt_run_as_group },
{ "timeout", required_argument, NULL, opt_timeout },
{ "name", required_argument, NULL, opt_name },
+ { "provider", required_argument, NULL, opt_provider },
{ 0 },
};
p11_tool_desc usages[] = {
- { 0, "usage: p11-kit server <module-or-token>" },
+ { 0, "usage: p11-kit server <token> ..." },
{ opt_foreground, "run the server in foreground" },
{ opt_user, "specify user who can connect to the socket" },
{ opt_group, "specify group who can connect to the socket" },
@@ -468,6 +482,7 @@ main (int argc,
{ opt_run_as_group, "specify group who runs the server" },
{ opt_timeout, "exit if no connection until the given timeout" },
{ opt_name, "specify name of the socket (default: pkcs11-<pid>)" },
+ { opt_provider, "specify the module to use" },
{ 0 },
};
@@ -522,6 +537,9 @@ main (int argc,
case opt_foreground:
foreground = true;
break;
+ case opt_provider:
+ provider = optarg;
+ break;
case opt_help:
case '?':
p11_tool_usage (usages, options);
@@ -535,13 +553,11 @@ main (int argc,
argc -= optind;
argv += optind;
- if (argc != 1) {
+ if (argc < 1) {
p11_tool_usage (usages, options);
return 2;
}
- module_or_token = argv[0];
-
if (run_as_gid != -1) {
if (setgid (run_as_gid) == -1) {
p11_message_err (errno, "cannot set gid to %u", (unsigned)run_as_gid);
@@ -598,7 +614,7 @@ main (int argc,
socket_name = strdup (name);
}
- server = server_new (module_or_token, socket_name);
+ server = server_new ((const char **)argv, argc, provider, socket_name);
free (socket_name);
if (server == NULL) {
ret = 1;