summaryrefslogtreecommitdiff
path: root/p11-kit/rpc-transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'p11-kit/rpc-transport.c')
-rw-r--r--p11-kit/rpc-transport.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/p11-kit/rpc-transport.c b/p11-kit/rpc-transport.c
index 5902157..d8f0cda 100644
--- a/p11-kit/rpc-transport.c
+++ b/p11-kit/rpc-transport.c
@@ -44,6 +44,7 @@
#include "private.h"
#include "rpc.h"
#include "rpc-message.h"
+#include "path.h"
#include <sys/types.h>
@@ -1043,6 +1044,84 @@ rpc_exec_init (const char *remote,
return &rex->base;
}
+#ifdef OS_UNIX
+
+typedef struct {
+ p11_rpc_transport base;
+ struct sockaddr_un sa;
+} rpc_unix;
+
+static CK_RV
+rpc_unix_connect (p11_rpc_client_vtable *vtable,
+ void *init_reserved)
+{
+ rpc_unix *run = (rpc_unix *)vtable;
+ int fd;
+
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ p11_message_err (errno, "failed to create socket for remote");
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (connect (fd, (struct sockaddr *)&run->sa, sizeof (run->sa)) < 0) {
+ p11_message_err (errno, "failed to connect to socket");
+ close (fd);
+ return CKR_DEVICE_REMOVED;
+ }
+
+ run->base.socket = rpc_socket_new (fd);
+ return_val_if_fail (run->base.socket != NULL, CKR_GENERAL_ERROR);
+
+ return CKR_OK;
+}
+
+static void
+rpc_unix_disconnect (p11_rpc_client_vtable *vtable,
+ void *fini_reserved)
+{
+ rpc_unix *run = (rpc_unix *)vtable;
+
+ if (run->base.socket)
+ rpc_socket_close (run->base.socket);
+
+ /* Do the common disconnect stuff */
+ rpc_transport_disconnect (vtable, fini_reserved);
+}
+
+static void
+rpc_unix_free (void *data)
+{
+ rpc_unix *run = data;
+ rpc_unix_disconnect (data, NULL);
+ rpc_transport_uninit (&run->base);
+ free (run);
+}
+
+static p11_rpc_transport *
+rpc_unix_init (const char *remote,
+ const char *name)
+{
+ rpc_unix *run;
+
+ run = calloc (1, sizeof (rpc_unix));
+ return_val_if_fail (run != NULL, NULL);
+
+ memset (&run->sa, 0, sizeof (run->sa));
+ run->sa.sun_family = AF_UNIX;
+ snprintf (run->sa.sun_path, sizeof (run->sa.sun_path), "%s", remote);
+
+ run->base.vtable.connect = rpc_unix_connect;
+ run->base.vtable.disconnect = rpc_unix_disconnect;
+ run->base.vtable.transport = rpc_transport_buffer;
+ rpc_transport_init (&run->base, name, rpc_unix_free);
+
+ p11_debug ("initialized rpc socket: %s", remote);
+ return &run->base;
+}
+
+#endif /* OS_UNIX */
+
p11_rpc_transport *
p11_rpc_transport_new (p11_virtual *virt,
const char *remote,
@@ -1058,6 +1137,16 @@ p11_rpc_transport_new (p11_virtual *virt,
if (remote[0] == '|') {
rpc = rpc_exec_init (remote + 1, name);
+#ifdef OS_UNIX
+ } else if (strncmp (remote, "unix:path=/", 11) == 0) {
+ /* Only absolute path is supported */
+ char *path;
+
+ path = p11_path_decode (remote + 10);
+ return_val_if_fail (path != NULL, NULL);
+ rpc = rpc_unix_init (path, name);
+ free (path);
+#endif /* OS_UNIX */
} else {
p11_message ("remote not supported: %s", remote);
return NULL;