p11_kit_iter_destroy_object
p11_kit_iter_free
P11KitIterBehavior
+p11_kit_remote_serve_module
</SECTION>
<SECTION>
iter.h \
p11-kit.h \
pin.h \
+ remote.h \
uri.h \
$(NULL)
proxy.c proxy.h \
private.h \
messages.c \
+ remote.c \
rpc-transport.c rpc.h \
rpc-message.c rpc-message.h \
rpc-client.c rpc-server.c \
#include "debug.h"
#include "message.h"
#include "path.h"
+#include "p11-kit.h"
+#include "remote.h"
#include <assert.h>
#include <ctype.h>
int p11_kit_external (int argc,
char *argv[]);
+int p11_kit_remote (int argc,
+ char *argv[]);
+
static const p11_tool_command commands[] = {
{ "list-modules", p11_kit_list_modules, "List modules and tokens" },
+ { "remote", p11_kit_remote, "Run a specific PKCS#11 module remotely" },
{ P11_TOOL_FALLBACK, p11_kit_external, NULL },
{ 0, }
};
return 2;
}
+int
+p11_kit_remote (int argc,
+ char *argv[])
+{
+ CK_FUNCTION_LIST *module;
+ int opt;
+ int ret;
+
+ enum {
+ opt_verbose = 'v',
+ opt_help = 'h',
+ };
+
+ struct option options[] = {
+ { "verbose", no_argument, NULL, opt_verbose },
+ { "help", no_argument, NULL, opt_help },
+ { 0 },
+ };
+
+ p11_tool_desc usages[] = {
+ { 0, "usage: p11-kit remote <module>" },
+ { 0 },
+ };
+
+ while ((opt = p11_tool_getopt (argc, argv, options)) != -1) {
+ switch (opt) {
+ case opt_verbose:
+ p11_kit_be_loud ();
+ break;
+ case opt_help:
+ case '?':
+ p11_tool_usage (usages, options);
+ return 0;
+ default:
+ assert_not_reached ();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ p11_message ("specify the module to remote");
+ return 2;
+ }
+
+ if (isatty (0)) {
+ p11_message ("the 'remote' tool is not meant to be run from a terminal");
+ return 2;
+ }
+
+ module = p11_kit_module_load (argv[0], 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[])
/*
- * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2014 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "buffer.h"
#include "compat.h"
#include "debug.h"
-#include "p11-kit.h"
+#include "message.h"
#include "rpc.h"
+#include "remote.h"
#include "virtual.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
int
-main (int argc,
- char *argv[])
+p11_kit_remote_serve_module (CK_FUNCTION_LIST *module,
+ int in_fd,
+ int out_fd)
{
- CK_FUNCTION_LIST *funcs;
- CK_C_GetFunctionList gfl;
p11_rpc_status status;
unsigned char version;
p11_virtual virt;
p11_buffer options;
p11_buffer buffer;
- dl_module_t dl;
size_t state;
+ int ret = 1;
int code;
- CK_RV rv;
- p11_debug_init ();
+ return_val_if_fail (module != NULL, 1);
- if (argc != 2) {
- fprintf (stderr, "usage: frob-server module\n");
- exit (2);
- }
-
- dl = p11_dl_open (argv[1]);
- if (dl == NULL) {
- fprintf (stderr, "couldn't load module: %s: %s\n",
- argv[1], p11_dl_error ());
- exit (1);
- }
-
- gfl = p11_dl_symbol (dl, "C_GetFunctionList");
- if (!gfl) {
- fprintf (stderr, "couldn't find C_GetFunctionList entry point in module: %s: %s\n",
- argv[1], p11_dl_error ());
- exit (1);
- }
-
- rv = gfl (&funcs);
- if (rv != CKR_OK) {
- fprintf (stderr, "call to C_GetFunctiontList failed in module: %s: %s\n",
- argv[1], p11_kit_strerror (rv));
- exit (1);
- }
-
- p11_virtual_init (&virt, &p11_virtual_base, funcs, NULL);
p11_buffer_init (&options, 0);
p11_buffer_init (&buffer, 0);
- switch (read (0, &version, 1)) {
+ p11_virtual_init (&virt, &p11_virtual_base, module, NULL);
+
+ switch (read (in_fd, &version, 1)) {
case 0:
status = P11_RPC_EOF;
break;
case 1:
if (version != 0) {
- fprintf (stderr, "unspported version received: %d", (int)version);
- exit (1);
+ p11_message ("unspported version received: %d", (int)version);
+ goto out;
}
break;
default:
- fprintf (stderr, "couldn't read creds: %s", strerror (errno));
- exit (1);
+ p11_message_err (errno, "couldn't read credential byte");
+ goto out;
}
version = 0;
- switch (write (1, &version, 1)) {
+ switch (write (out_fd, &version, out_fd)) {
case 1:
break;
default:
- fprintf (stderr, "couldn't read creds: %s", strerror (errno));
- exit (1);
+ p11_message_err (errno, "couldn't write credential byte");
+ goto out;
}
status = P11_RPC_OK;
code = 0;
do {
- status = p11_rpc_transport_read (0, &state, &code,
+ status = p11_rpc_transport_read (in_fd, &state, &code,
&options, &buffer);
} while (status == P11_RPC_AGAIN);
case P11_RPC_OK:
break;
case P11_RPC_EOF:
+ ret = 0;
continue;
case P11_RPC_AGAIN:
assert_not_reached ();
case P11_RPC_ERROR:
- fprintf (stderr, "failed to read rpc message: %s\n", strerror (errno));
- exit (1);
+ p11_message_err (errno, "failed to read rpc message");
+ goto out;
}
if (!p11_rpc_server_handle (&virt.funcs, &buffer, &buffer)) {
- fprintf (stderr, "unexpected error handling rpc message\n");
- exit (1);
+ p11_message ("unexpected error handling rpc message");
+ goto out;
}
state = 0;
options.len = 0;
do {
- status = p11_rpc_transport_write (1, &state, code,
+ status = p11_rpc_transport_write (out_fd, &state, code,
&options, &buffer);
} while (status == P11_RPC_AGAIN);
case P11_RPC_AGAIN:
assert_not_reached ();
case P11_RPC_ERROR:
- fprintf (stderr, "failed to write rpc message: %s\n", strerror (errno));
- exit (1);
+ p11_message_err (errno, "failed to write rpc message");
+ goto out;
}
}
+out:
p11_buffer_uninit (&buffer);
p11_buffer_uninit (&options);
- p11_dl_close (dl);
- return 0;
+ p11_virtual_uninit (&virt);
+
+ return ret;
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#ifndef __P11_KIT_REMOTE_H__
+#define __P11_KIT_REMOTE_H__
+
+#include "p11-kit/p11-kit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef P11_KIT_FUTURE_UNSTABLE_API
+
+int p11_kit_remote_serve_module (CK_FUNCTION_LIST *module,
+ int in_fd,
+ int out_fd);
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* __P11_KIT_REMOTE_H__ */
test-transport \
$(NULL)
-noinst_PROGRAMS += \
- frob-server
-
endif
TESTS = $(CHECK_PROGS)
test.user_config = p11_path_build (test.directory, "pkcs11.conf", NULL);
p11_test_file_write (NULL, test.user_config, data, strlen (data));
- data = "remote: " BUILDDIR "/frob-server " BUILDDIR "/.libs/mock-two.so\n";
+ data = "remote: " BUILDDIR "/../p11-kit remote " BUILDDIR "/.libs/mock-two.so\n";
p11_test_file_write (test.user_modules, "remote.module", data, strlen (data));
p11_config_user_modules = test.user_modules;